Merge branch 'integrator/irq' into next/soc

Picking up one compilation warning fix for integrator.

From Linus Walleij:
* integrator/irq:
  irq: versatile: delete dangling variable

Signed-off-by: Olof Johansson <olof@lixom.net>
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index f54273e..ceb1ff7 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -210,6 +210,8 @@
 	- semantics and behavior of local atomic operations.
 lockdep-design.txt
 	- documentation on the runtime locking correctness validator.
+lockup-watchdogs.txt
+	- info on soft and hard lockup detectors (aka nmi_watchdog).
 logo.gif
 	- full colour GIF image of Linux logo (penguin - Tux).
 logo.txt
@@ -240,8 +242,6 @@
 	- directory with information on the NetLabel subsystem.
 networking/
 	- directory with info on various aspects of networking with Linux.
-nmi_watchdog.txt
-	- info on NMI watchdog for SMP systems.
 nommu-mmap.txt
 	- documentation about no-mmu memory mapping support.
 numastat.txt
diff --git a/Documentation/arm/sunxi/README b/Documentation/arm/sunxi/README
new file mode 100644
index 0000000..87a1e8f
--- /dev/null
+++ b/Documentation/arm/sunxi/README
@@ -0,0 +1,19 @@
+ARM Allwinner SoCs
+==================
+
+This document lists all the ARM Allwinner SoCs that are currently
+supported in mainline by the Linux kernel. This document will also
+provide links to documentation and or datasheet for these SoCs.
+
+SunXi family
+------------
+
+  Flavors:
+        Allwinner A10 (sun4i)
+                Datasheet       : http://dl.linux-sunxi.org/A10/A10%20Datasheet%20-%20v1.21%20%282012-04-06%29.pdf
+
+        Allwinner A13 (sun5i)
+                Datasheet       : http://dl.linux-sunxi.org/A13/A13%20Datasheet%20-%20v1.12%20%282012-03-29%29.pdf
+
+  Core: Cortex A8
+  Linux kernel mach directory: arch/arm/mach-sunxi
\ No newline at end of file
diff --git a/Documentation/arm64/memory.txt b/Documentation/arm64/memory.txt
index dbbdcbb..4110cca 100644
--- a/Documentation/arm64/memory.txt
+++ b/Documentation/arm64/memory.txt
@@ -27,17 +27,17 @@
 -----------------------------------------------------------------------
 0000000000000000	0000007fffffffff	 512GB		user
 
-ffffff8000000000	ffffffbbfffcffff	~240GB		vmalloc
+ffffff8000000000	ffffffbbfffeffff	~240GB		vmalloc
 
-ffffffbbfffd0000	ffffffbcfffdffff	  64KB		[guard page]
-
-ffffffbbfffe0000	ffffffbcfffeffff	  64KB		PCI I/O space
-
-ffffffbbffff0000	ffffffbcffffffff	  64KB		[guard page]
+ffffffbbffff0000	ffffffbbffffffff	  64KB		[guard page]
 
 ffffffbc00000000	ffffffbdffffffff	   8GB		vmemmap
 
-ffffffbe00000000	ffffffbffbffffff	  ~8GB		[guard, future vmmemap]
+ffffffbe00000000	ffffffbffbbfffff	  ~8GB		[guard, future vmmemap]
+
+ffffffbffbe00000	ffffffbffbe0ffff	  64KB		PCI I/O space
+
+ffffffbbffff0000	ffffffbcffffffff	  ~2MB		[guard]
 
 ffffffbffc000000	ffffffbfffffffff	  64MB		modules
 
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index c07f7b4..71c4da4 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -466,6 +466,10 @@
 5.3 swappiness
 
 Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
+Please note that unlike the global swappiness, memcg knob set to 0
+really prevents from any swapping even if there is a swap storage
+available. This might lead to memcg OOM killer if there are no file
+pages to reclaim.
 
 Following cgroups' swappiness can't be changed.
 - root cgroup (uses /proc/sys/vm/swappiness).
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt
index ecc81e3..d187e9f 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt
@@ -8,7 +8,7 @@
   shared across all System Controller members.
 
 TC/TCLIB Timer required properties:
-- compatible: Should be "atmel,<chip>-pit".
+- compatible: Should be "atmel,<chip>-tcb".
   <chip> can be "at91rm9200" or "at91sam9x5"
 - reg: Should contain registers location and length
 - interrupts: Should contain all interrupts for the TC block
diff --git a/Documentation/devicetree/bindings/arm/bcm/bcm11351.txt b/Documentation/devicetree/bindings/arm/bcm/bcm11351.txt
new file mode 100644
index 0000000..fb7b5cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/bcm/bcm11351.txt
@@ -0,0 +1,9 @@
+Broadcom BCM11351 device tree bindings
+-------------------------------------------
+
+Boards with the bcm281xx SoC family (which includes bcm11130, bcm11140,
+bcm11351, bcm28145, bcm28155 SoCs) shall have the following properties:
+
+Required root node property:
+
+compatible = "bcm,bcm11351";
diff --git a/Documentation/devicetree/bindings/arm/calxeda.txt b/Documentation/devicetree/bindings/arm/calxeda.txt
index 4755caa..25fcf96 100644
--- a/Documentation/devicetree/bindings/arm/calxeda.txt
+++ b/Documentation/devicetree/bindings/arm/calxeda.txt
@@ -1,8 +1,15 @@
-Calxeda Highbank Platforms Device Tree Bindings
+Calxeda Platforms Device Tree Bindings
 -----------------------------------------------
 
-Boards with Calxeda Cortex-A9 based Highbank SOC shall have the following
-properties.
+Boards with Calxeda Cortex-A9 based ECX-1000 (Highbank) SOC shall have the
+following properties.
 
 Required root node properties:
     - compatible = "calxeda,highbank";
+
+
+Boards with Calxeda Cortex-A15 based ECX-2000 SOC shall have the following
+properties.
+
+Required root node properties:
+    - compatible = "calxeda,ecx-2000";
diff --git a/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt b/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
new file mode 100644
index 0000000..9cf3f25
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
@@ -0,0 +1,50 @@
+ARM Versatile Express system registers
+--------------------------------------
+
+This is a system control registers block, providing multiple low level
+platform functions like board detection and identification, software
+interrupt generation, MMC and NOR Flash control etc.
+
+Required node properties:
+- compatible value : = "arm,vexpress,sysreg";
+- reg : physical base address and the size of the registers window
+- gpio-controller : specifies that the node is a GPIO controller
+- #gpio-cells : size of the GPIO specifier, should be 2:
+  - first cell is the pseudo-GPIO line number:
+    0 - MMC CARDIN
+    1 - MMC WPROT
+    2 - NOR FLASH WPn
+  - second cell can take standard GPIO flags (currently ignored).
+
+Example:
+	v2m_sysreg: sysreg@10000000 {
+ 		compatible = "arm,vexpress-sysreg";
+ 		reg = <0x10000000 0x1000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+ 	};
+
+This block also can also act a bridge to the platform's configuration
+bus via "system control" interface, addressing devices with site number,
+position in the board stack, config controller, function and device
+numbers - see motherboard's TRM for more details.
+
+The node describing a config device must refer to the sysreg node via
+"arm,vexpress,config-bridge" phandle (can be also defined in the node's
+parent) and relies on the board topology properties - see main vexpress
+node documentation for more details. It must must also define the
+following property:
+- arm,vexpress-sysreg,func : must contain two cells:
+  - first cell defines function number (eg. 1 for clock generator,
+    2 for voltage regulators etc.)
+  - device number (eg. osc 0, osc 1 etc.)
+
+Example:
+	mcc {
+		arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+		osc@0 {
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 0>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/arm/vexpress.txt b/Documentation/devicetree/bindings/arm/vexpress.txt
index ec8b50c..ae49161 100644
--- a/Documentation/devicetree/bindings/arm/vexpress.txt
+++ b/Documentation/devicetree/bindings/arm/vexpress.txt
@@ -11,6 +11,10 @@
 can be initialized in one of two different configurations ("memory
 maps"), care must be taken to include the correct one.
 
+
+Root node
+---------
+
 Required properties in the root node:
 - compatible value:
 	compatible = "arm,vexpress,<model>", "arm,vexpress";
@@ -45,6 +49,10 @@
   - Coretile Express A9x4 (V2P-CA9) HBI-0225:
 	arm,hbi = <0x225>;
 
+
+CPU nodes
+---------
+
 Top-level standard "cpus" node is required. It must contain a node
 with device_type = "cpu" property for every available core, eg.:
 
@@ -59,6 +67,52 @@
 		};
 	};
 
+
+Configuration infrastructure
+----------------------------
+
+The platform has an elaborated configuration system, consisting of
+microcontrollers residing on the mother- and daughterboards known
+as Motherboard/Daughterboard Configuration Controller (MCC and DCC).
+The controllers are responsible for the platform initialization
+(reset generation, flash programming, FPGA bitfiles loading etc.)
+but also control clock generators, voltage regulators, gather
+environmental data like temperature, power consumption etc. Even
+the video output switch (FPGA) is controlled that way.
+
+Nodes describing devices controlled by this infrastructure should
+point at the bridge device node:
+- bridge phandle:
+	arm,vexpress,config-bridge = <phandle>;
+This property can be also defined in a parent node (eg. for a DCC)
+and is effective for all children.
+
+
+Platform topology
+-----------------
+
+As Versatile Express can be configured in number of physically
+different setups, the device tree should describe platform topology.
+Root node and main motherboard node must define the following
+property, describing physical location of the children nodes:
+- site number:
+	arm,vexpress,site = <number>;
+  where 0 means motherboard, 1 or 2 are daugtherboard sites,
+  0xf means "master" site (site containing main CPU tile)
+- when daughterboards are stacked on one site, their position
+  in the stack be be described with:
+	arm,vexpress,position = <number>;
+- when describing tiles consisting more than one DCC, its number
+  can be described with:
+	arm,vexpress,dcc = <number>;
+
+Any of the numbers above defaults to zero if not defined in
+the node or any of its parent.
+
+
+Motherboard
+-----------
+
 The motherboard description file provides a single "motherboard" node
 using 2 address cells corresponding to the Static Memory Bus used
 between the motherboard and the tile. The first cell defines the Chip
@@ -87,22 +141,30 @@
 - SP804 timers:
 	v2m_timer01 and v2m_timer23
 
-Current Linux implementation requires a "arm,v2m_timer" alias
-pointing at one of the motherboard's SP804 timers, if it is to be
-used as the system timer. This alias should be defined in the
-motherboard files.
+The tile description should define a "smb" node, describing the
+Static Memory Bus between the tile and motherboard. It must define
+the following properties:
+- "simple-bus" compatible value (to ensure creation of the children)
+	compatible = "simple-bus";
+- mapping of the SMB CS/offset addresses into main address space:
+	#address-cells = <2>;
+	#size-cells = <1>;
+	ranges = <...>;
+- interrupts mapping:
+	#interrupt-cells = <1>;
+	interrupt-map-mask = <0 0 63>;
+	interrupt-map = <...>;
 
-The tile description must define "ranges", "interrupt-map-mask" and
-"interrupt-map" properties to translate the motherboard's address
-and interrupt space into one used by the tile's processor.
 
-Abbreviated example:
+Example of a VE tile description (simplified)
+---------------------------------------------
 
 /dts-v1/;
 
 / {
 	model = "V2P-CA5s";
 	arm,hbi = <0x225>;
+	arm,vexpress,site = <0xf>;
 	compatible = "arm,vexpress-v2p-ca5s", "arm,vexpress";
 	interrupt-parent = <&gic>;
 	#address-cells = <1>;
@@ -134,13 +196,29 @@
 		      <0x2c000100 0x100>;
 	};
 
-	motherboard {
+	dcc {
+		compatible = "simple-bus";
+		arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+		osc@0 {
+			compatible = "arm,vexpress-osc";
+		};
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
 		/* CS0 is visible at 0x08000000 */
 		ranges = <0 0 0x08000000 0x04000000>;
+
+		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		/* Active high IRQ 0 is connected to GIC's SPI0 */
 		interrupt-map = <0 0 0 &gic 0 0 4>;
+
+		/include/ "vexpress-v2m-rs1.dtsi"
 	};
 };
 
-/include/ "vexpress-v2m-rs1.dtsi"
diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.txt b/Documentation/devicetree/bindings/clock/imx5-clock.txt
new file mode 100644
index 0000000..04ad478
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx5-clock.txt
@@ -0,0 +1,191 @@
+* Clock bindings for Freescale i.MX5
+
+Required properties:
+- compatible: Should be "fsl,<soc>-ccm" , where <soc> can be imx51 or imx53
+- reg: Address and length of the register set
+- interrupts: Should contain CCM interrupt
+- #clock-cells: Should be <1>
+
+The clock consumer should specify the desired clock by having the clock
+ID in its "clocks" phandle cell.  The following is a full list of i.MX5
+clocks and IDs.
+
+	Clock			ID
+	---------------------------
+	dummy			0
+	ckil			1
+	osc			2
+	ckih1			3
+	ckih2			4
+	ahb			5
+	ipg			6
+	axi_a			7
+	axi_b			8
+	uart_pred		9
+	uart_root		10
+	esdhc_a_pred		11
+	esdhc_b_pred		12
+	esdhc_c_s		13
+	esdhc_d_s		14
+	emi_sel			15
+	emi_slow_podf		16
+	nfc_podf		17
+	ecspi_pred		18
+	ecspi_podf		19
+	usboh3_pred		20
+	usboh3_podf		21
+	usb_phy_pred		22
+	usb_phy_podf		23
+	cpu_podf		24
+	di_pred			25
+	tve_di			26
+	tve_s			27
+	uart1_ipg_gate		28
+	uart1_per_gate		29
+	uart2_ipg_gate		30
+	uart2_per_gate		31
+	uart3_ipg_gate		32
+	uart3_per_gate		33
+	i2c1_gate		34
+	i2c2_gate		35
+	gpt_ipg_gate		36
+	pwm1_ipg_gate		37
+	pwm1_hf_gate		38
+	pwm2_ipg_gate		39
+	pwm2_hf_gate		40
+	gpt_hf_gate		41
+	fec_gate		42
+	usboh3_per_gate		43
+	esdhc1_ipg_gate		44
+	esdhc2_ipg_gate		45
+	esdhc3_ipg_gate		46
+	esdhc4_ipg_gate		47
+	ssi1_ipg_gate		48
+	ssi2_ipg_gate		49
+	ssi3_ipg_gate		50
+	ecspi1_ipg_gate		51
+	ecspi1_per_gate		52
+	ecspi2_ipg_gate		53
+	ecspi2_per_gate		54
+	cspi_ipg_gate		55
+	sdma_gate		56
+	emi_slow_gate		57
+	ipu_s			58
+	ipu_gate		59
+	nfc_gate		60
+	ipu_di1_gate		61
+	vpu_s			62
+	vpu_gate		63
+	vpu_reference_gate	64
+	uart4_ipg_gate		65
+	uart4_per_gate		66
+	uart5_ipg_gate		67
+	uart5_per_gate		68
+	tve_gate		69
+	tve_pred		70
+	esdhc1_per_gate		71
+	esdhc2_per_gate		72
+	esdhc3_per_gate		73
+	esdhc4_per_gate		74
+	usb_phy_gate		75
+	hsi2c_gate		76
+	mipi_hsc1_gate		77
+	mipi_hsc2_gate		78
+	mipi_esc_gate		79
+	mipi_hsp_gate		80
+	ldb_di1_div_3_5		81
+	ldb_di1_div		82
+	ldb_di0_div_3_5		83
+	ldb_di0_div		84
+	ldb_di1_gate		85
+	can2_serial_gate	86
+	can2_ipg_gate		87
+	i2c3_gate		88
+	lp_apm			89
+	periph_apm		90
+	main_bus		91
+	ahb_max			92
+	aips_tz1		93
+	aips_tz2		94
+	tmax1			95
+	tmax2			96
+	tmax3			97
+	spba			98
+	uart_sel		99
+	esdhc_a_sel		100
+	esdhc_b_sel		101
+	esdhc_a_podf		102
+	esdhc_b_podf		103
+	ecspi_sel		104
+	usboh3_sel		105
+	usb_phy_sel		106
+	iim_gate		107
+	usboh3_gate		108
+	emi_fast_gate		109
+	ipu_di0_gate		110
+	gpc_dvfs		111
+	pll1_sw			112
+	pll2_sw			113
+	pll3_sw			114
+	ipu_di0_sel		115
+	ipu_di1_sel		116
+	tve_ext_sel		117
+	mx51_mipi		118
+	pll4_sw			119
+	ldb_di1_sel		120
+	di_pll4_podf		121
+	ldb_di0_sel		122
+	ldb_di0_gate		123
+	usb_phy1_gate		124
+	usb_phy2_gate		125
+	per_lp_apm		126
+	per_pred1		127
+	per_pred2		128
+	per_podf		129
+	per_root		130
+	ssi_apm			131
+	ssi1_root_sel		132
+	ssi2_root_sel		133
+	ssi3_root_sel		134
+	ssi_ext1_sel		135
+	ssi_ext2_sel		136
+	ssi_ext1_com_sel	137
+	ssi_ext2_com_sel	138
+	ssi1_root_pred		139
+	ssi1_root_podf		140
+	ssi2_root_pred		141
+	ssi2_root_podf		142
+	ssi_ext1_pred		143
+	ssi_ext1_podf		144
+	ssi_ext2_pred		145
+	ssi_ext2_podf		146
+	ssi1_root_gate		147
+	ssi2_root_gate		148
+	ssi3_root_gate		149
+	ssi_ext1_gate		150
+	ssi_ext2_gate		151
+	epit1_ipg_gate		152
+	epit1_hf_gate		153
+	epit2_ipg_gate		154
+	epit2_hf_gate		155
+	can_sel			156
+	can1_serial_gate	157
+	can1_ipg_gate		158
+
+Examples (for mx53):
+
+clks: ccm@53fd4000{
+	compatible = "fsl,imx53-ccm";
+	reg = <0x53fd4000 0x4000>;
+	interrupts = <0 71 0x04 0 72 0x04>;
+	#clock-cells = <1>;
+};
+
+can1: can@53fc8000 {
+	compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
+	reg = <0x53fc8000 0x4000>;
+	interrupts = <82>;
+	clocks = <&clks 158>, <&clks 157>;
+	clock-names = "ipg", "per";
+	status = "disabled";
+};
diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt
index 492bd99..d77b4e6 100644
--- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt
+++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt
@@ -187,9 +187,9 @@
 	pll3_usb_otg		172
 	pll4_audio		173
 	pll5_video		174
-	pll6_mlb		175
+	pll8_mlb		175
 	pll7_usb_host		176
-	pll8_enet		177
+	pll6_enet		177
 	ssi1_ipg		178
 	ssi2_ipg		179
 	ssi3_ipg		180
@@ -198,6 +198,11 @@
 	usbphy2			183
 	ldb_di0_div_3_5		184
 	ldb_di1_div_3_5		185
+	sata_ref		186
+	sata_ref_100m		187
+	pcie_ref		188
+	pcie_ref_125m		189
+	enet_ref		190
 
 Examples:
 
diff --git a/Documentation/devicetree/bindings/gpio/spear_spics.txt b/Documentation/devicetree/bindings/gpio/spear_spics.txt
new file mode 100644
index 0000000..96c37eb
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/spear_spics.txt
@@ -0,0 +1,50 @@
+=== ST Microelectronics SPEAr SPI CS Driver ===
+
+SPEAr platform provides a provision to control chipselects of ARM PL022 Prime
+Cell spi controller through its system registers, which otherwise remains under
+PL022 control. If chipselect remain under PL022 control then they would be
+released as soon as transfer is over and TxFIFO becomes empty. This is not
+desired by some of the device protocols above spi which expect (multiple)
+transfers without releasing their chipselects.
+
+Chipselects can be controlled by software by turning them as GPIOs. SPEAr
+provides another interface through system registers through which software can
+directly control each PL022 chipselect. Hence, it is natural for SPEAr to export
+the control of this interface as gpio.
+
+Required properties:
+
+  * compatible: should be defined as "st,spear-spics-gpio"
+  * reg: mentioning address range of spics controller
+  * st-spics,peripcfg-reg: peripheral configuration register offset
+  * st-spics,sw-enable-bit: bit offset to enable sw control
+  * st-spics,cs-value-bit: bit offset to drive chipselect low or high
+  * st-spics,cs-enable-mask: chip select number bit mask
+  * st-spics,cs-enable-shift: chip select number program offset
+  * gpio-controller: Marks the device node as gpio controller
+  * #gpio-cells: should be 1 and will mention chip select number
+
+All the above bit offsets are within peripcfg register.
+
+Example:
+-------
+spics: spics@e0700000{
+        compatible = "st,spear-spics-gpio";
+        reg = <0xe0700000 0x1000>;
+        st-spics,peripcfg-reg = <0x3b0>;
+        st-spics,sw-enable-bit = <12>;
+        st-spics,cs-value-bit = <11>;
+        st-spics,cs-enable-mask = <3>;
+        st-spics,cs-enable-shift = <8>;
+        gpio-controller;
+        #gpio-cells = <2>;
+};
+
+
+spi0: spi@e0100000 {
+        status = "okay";
+        num-cs = <3>;
+        cs-gpios = <&gpio1 7 0>, <&spics 0>,
+                   <&spics 1>;
+	...
+}
diff --git a/Documentation/devicetree/bindings/i2c/fsl-imx-i2c.txt b/Documentation/devicetree/bindings/i2c/fsl-imx-i2c.txt
index f3cf43b..3614242 100644
--- a/Documentation/devicetree/bindings/i2c/fsl-imx-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/fsl-imx-i2c.txt
@@ -12,13 +12,13 @@
 Examples:
 
 i2c@83fc4000 { /* I2C2 on i.MX51 */
-	compatible = "fsl,imx51-i2c", "fsl,imx1-i2c";
+	compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
 	reg = <0x83fc4000 0x4000>;
 	interrupts = <63>;
 };
 
 i2c@70038000 { /* HS-I2C on i.MX51 */
-	compatible = "fsl,imx51-i2c", "fsl,imx1-i2c";
+	compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
 	reg = <0x70038000 0x4000>;
 	interrupts = <64>;
 	clock-frequency = <400000>;
diff --git a/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt
new file mode 100644
index 0000000..df70318
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt
@@ -0,0 +1,19 @@
+* EETI eGalax Multiple Touch Controller
+
+Required properties:
+- compatible: must be "eeti,egalax_ts"
+- reg: i2c slave address
+- interrupt-parent: the phandle for the interrupt controller
+- interrupts: touch controller interrupt
+- wakeup-gpios: the gpio pin to be used for waking up the controller
+  as well as uased as irq pin
+
+Example:
+
+	egalax_ts@04 {
+		compatible = "eeti,egalax_ts";
+		reg = <0x04>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <9 2>;
+		wakeup-gpios = <&gpio1 9 0>;
+	};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt
new file mode 100644
index 0000000..7f9fb85
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt
@@ -0,0 +1,104 @@
+Allwinner Sunxi Interrupt Controller
+
+Required properties:
+
+- compatible : should be "allwinner,sunxi-ic"
+- reg : Specifies base physical address and size of the registers.
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+
+The interrupt sources are as follows:
+
+0: ENMI
+1: UART0
+2: UART1
+3: UART2
+4: UART3
+5: IR0
+6: IR1
+7: I2C0
+8: I2C1
+9: I2C2
+10: SPI0
+11: SPI1
+12: SPI2
+13: SPDIF
+14: AC97
+15: TS
+16: I2S
+17: UART4
+18: UART5
+19: UART6
+20: UART7
+21: KEYPAD
+22: TIMER0
+23: TIMER1
+24: TIMER2
+25: TIMER3
+26: CAN
+27: DMA
+28: PIO
+29: TOUCH_PANEL
+30: AUDIO_CODEC
+31: LRADC
+32: SDMC0
+33: SDMC1
+34: SDMC2
+35: SDMC3
+36: MEMSTICK
+37: NAND
+38: USB0
+39: USB1
+40: USB2
+41: SCR
+42: CSI0
+43: CSI1
+44: LCDCTRL0
+45: LCDCTRL1
+46: MP
+47: DEFEBE0
+48: DEFEBE1
+49: PMU
+50: SPI3
+51: TZASC
+52: PATA
+53: VE
+54: SS
+55: EMAC
+56: SATA
+57: GPS
+58: HDMI
+59: TVE
+60: ACE
+61: TVD
+62: PS2_0
+63: PS2_1
+64: USB3
+65: USB4
+66: PLE_PFM
+67: TIMER4
+68: TIMER5
+69: GPU_GP
+70: GPU_GPMMU
+71: GPU_PP0
+72: GPU_PPMMU0
+73: GPU_PMU
+74: GPU_RSV0
+75: GPU_RSV1
+76: GPU_RSV2
+77: GPU_RSV3
+78: GPU_RSV4
+79: GPU_RSV5
+80: GPU_RSV6
+82: SYNC_TIMER0
+83: SYNC_TIMER1
+
+Example:
+
+intc: interrupt-controller {
+	compatible = "allwinner,sunxi-ic";
+	reg = <0x01c20400 0x400>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+};
diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt
index c8e5782..683fde9 100644
--- a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt
+++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt
@@ -93,7 +93,7 @@
 
     With some exceptions, these support nvidia,high-speed-mode,
     nvidia,schmitt, nvidia,low-power-mode, nvidia,pull-down-strength,
-    nvidia,pull-up-strength, nvidia,slew_rate-rising, nvidia,slew_rate-falling.
+    nvidia,pull-up-strength, nvidia,slew-rate-rising, nvidia,slew-rate-falling.
 
     drive_ao1, drive_ao2, drive_at1, drive_at2, drive_cdev1, drive_cdev2,
     drive_csus, drive_dap1, drive_dap2, drive_dap3, drive_dap4, drive_dbg,
diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt
index c275b70..6f426ed 100644
--- a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt
+++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt
@@ -83,7 +83,7 @@
   drive groups:
 
     These all support nvidia,pull-down-strength, nvidia,pull-up-strength,
-    nvidia,slew_rate-rising, nvidia,slew_rate-falling. Most but not all
+    nvidia,slew-rate-rising, nvidia,slew-rate-falling. Most but not all
     support nvidia,high-speed-mode, nvidia,schmitt, nvidia,low-power-mode.
 
     ao1, ao2, at1, at2, at3, at4, at5, cdev1, cdev2, cec, crt, csus, dap1,
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
index 03dee50..e97a278 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
@@ -8,13 +8,20 @@
 Required Properties:
 - compatible: should be one of the following.
   - "samsung,pinctrl-exynos4210": for Exynos4210 compatible pin-controller.
+  - "samsung,pinctrl-exynos4x12": for Exynos4x12 compatible pin-controller.
   - "samsung,pinctrl-exynos5250": for Exynos5250 compatible pin-controller.
 
 - reg: Base address of the pin controller hardware module and length of
   the address space it occupies.
 
-- interrupts: interrupt specifier for the controller. The format and value of
-  the interrupt specifier depends on the interrupt parent for the controller.
+- Pin banks as child nodes: Pin banks of the controller are represented by child
+  nodes of the controller node. Bank name is taken from name of the node. Each
+  bank node must contain following properties:
+
+  - gpio-controller: identifies the node as a gpio controller and pin bank.
+  - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
+    binding is used, the amount of cells must be specified as 2. See generic
+    GPIO binding documentation for description of particular cells.
 
 - Pin mux/config groups as child nodes: The pin mux (selecting pin function
   mode) and pin config (pull up/down, driver strength) settings are represented
@@ -72,16 +79,24 @@
 A. External GPIO Interrupts: For supporting external gpio interrupts, the
    following properties should be specified in the pin-controller device node.
 
-- interrupt-controller: identifies the controller node as interrupt-parent.
-- #interrupt-cells: the value of this property should be 2.
-  - First Cell: represents the external gpio interrupt number local to the
-    external gpio interrupt space of the controller.
-  - Second Cell: flags to identify the type of the interrupt
-    - 1 = rising edge triggered
-    - 2 = falling edge triggered
-    - 3 = rising and falling edge triggered
-    - 4 = high level triggered
-    - 8 = low level triggered
+   - interrupt-parent: phandle of the interrupt parent to which the external
+     GPIO interrupts are forwarded to.
+   - interrupts: interrupt specifier for the controller. The format and value of
+     the interrupt specifier depends on the interrupt parent for the controller.
+
+   In addition, following properties must be present in node of every bank
+   of pins supporting GPIO interrupts:
+
+   - interrupt-controller: identifies the controller node as interrupt-parent.
+   - #interrupt-cells: the value of this property should be 2.
+     - First Cell: represents the external gpio interrupt number local to the
+       external gpio interrupt space of the controller.
+     - Second Cell: flags to identify the type of the interrupt
+       - 1 = rising edge triggered
+       - 2 = falling edge triggered
+       - 3 = rising and falling edge triggered
+       - 4 = high level triggered
+       - 8 = low level triggered
 
 B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
    child node representing the external wakeup interrupt controller should be
@@ -94,6 +109,11 @@
        found on Samsung Exynos4210 SoC.
    - interrupt-parent: phandle of the interrupt parent to which the external
      wakeup interrupts are forwarded to.
+   - interrupts: interrupt used by multiplexed wakeup interrupts.
+
+   In addition, following properties must be present in node of every bank
+   of pins supporting wake-up interrupts:
+
    - interrupt-controller: identifies the node as interrupt-parent.
    - #interrupt-cells: the value of this property should be 2
      - First Cell: represents the external wakeup interrupt number local to
@@ -105,11 +125,63 @@
        - 4 = high level triggered
        - 8 = low level triggered
 
+   Node of every bank of pins supporting direct wake-up interrupts (without
+   multiplexing) must contain following properties:
+
+   - interrupt-parent: phandle of the interrupt parent to which the external
+     wakeup interrupts are forwarded to.
+   - interrupts: interrupts of the interrupt parent which are used for external
+     wakeup interrupts from pins of the bank, must contain interrupts for all
+     pins of the bank.
+
 Aliases:
 
 All the pin controller nodes should be represented in the aliases node using
 the following format 'pinctrl{n}' where n is a unique number for the alias.
 
+Example: A pin-controller node with pin banks:
+
+	pinctrl_0: pinctrl@11400000 {
+		compatible = "samsung,pinctrl-exynos4210";
+		reg = <0x11400000 0x1000>;
+		interrupts = <0 47 0>;
+
+		/* ... */
+
+		/* Pin bank without external interrupts */
+		gpy0: gpy0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		/* ... */
+
+		/* Pin bank with external GPIO or muxed wake-up interrupts */
+		gpj0: gpj0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		/* ... */
+
+		/* Pin bank with external direct wake-up interrupts */
+		gpx0: gpx0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			interrupt-parent = <&gic>;
+			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+			#interrupt-cells = <2>;
+		};
+
+		/* ... */
+	};
+
 Example 1: A pin-controller node with pin groups.
 
 	pinctrl_0: pinctrl@11400000 {
@@ -117,6 +189,8 @@
 		reg = <0x11400000 0x1000>;
 		interrupts = <0 47 0>;
 
+		/* ... */
+
 		uart0_data: uart0-data {
 			samsung,pins = "gpa0-0", "gpa0-1";
 			samsung,pin-function = <2>;
@@ -158,20 +232,14 @@
 	pinctrl_1: pinctrl@11000000 {
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11000000 0x1000>;
-		interrupts = <0 46 0>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
+		interrupts = <0 46 0>
 
-		wakup_eint: wakeup-interrupt-controller {
+		/* ... */
+
+		wakeup-interrupt-controller {
 			compatible = "samsung,exynos4210-wakeup-eint";
 			interrupt-parent = <&gic>;
-			interrupt-controller;
-			#interrupt-cells = <2>;
-			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
-					<0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
-					<0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
-					<0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>,
-					<0 32 0>;
+			interrupts = <0 32 0>;
 		};
 	};
 
@@ -190,7 +258,8 @@
 
 	static int s3c24xx_serial_probe(struct platform_device *pdev) {
 		struct pinctrl *pinctrl;
-		...
-		...
+
+		/* ... */
+
 		pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
 	}
diff --git a/Documentation/devicetree/bindings/timer/allwinner,sunxi-timer.txt b/Documentation/devicetree/bindings/timer/allwinner,sunxi-timer.txt
new file mode 100644
index 0000000..0c7b64e
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/allwinner,sunxi-timer.txt
@@ -0,0 +1,17 @@
+Allwinner A1X SoCs Timer Controller
+
+Required properties:
+
+- compatible : should be "allwinner,sunxi-timer"
+- reg : Specifies base physical address and size of the registers.
+- interrupts : The interrupt of the first timer
+- clocks: phandle to the source clock (usually a 24 MHz fixed clock)
+
+Example:
+
+timer {
+	compatible = "allwinner,sunxi-timer";
+	reg = <0x01c20c00 0x400>;
+	interrupts = <22>;
+	clocks = <&osc>;
+};
diff --git a/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt b/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt
new file mode 100644
index 0000000..d209366
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt
@@ -0,0 +1,13 @@
+BCM2835 Watchdog timer
+
+Required properties:
+
+- compatible : should be "brcm,bcm2835-pm-wdt"
+- reg : Specifies base physical address and size of the registers.
+
+Example:
+
+watchdog {
+	compatible = "brcm,bcm2835-pm-wdt";
+	reg = <0x7e100000 0x28>;
+};
diff --git a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt b/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt
new file mode 100644
index 0000000..0b27177
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt
@@ -0,0 +1,13 @@
+Allwinner sunXi Watchdog timer
+
+Required properties:
+
+- compatible : should be "allwinner,sunxi-wdt"
+- reg : Specifies base physical address and size of the registers.
+
+Example:
+
+wdt: watchdog@01c20c90 {
+	compatible = "allwinner,sunxi-wdt";
+	reg = <0x01c20c90 0x10>;
+};
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index a1793d6..3844d21 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -33,7 +33,7 @@
   2	Modifying System Parameters
 
   3	Per-Process Parameters
-  3.1	/proc/<pid>/oom_score_adj - Adjust the oom-killer
+  3.1	/proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj - Adjust the oom-killer
 								score
   3.2	/proc/<pid>/oom_score - Display current oom-killer score
   3.3	/proc/<pid>/io - Display the IO accounting fields
@@ -1320,10 +1320,10 @@
 CHAPTER 3: PER-PROCESS PARAMETERS
 ------------------------------------------------------------------------------
 
-3.1 /proc/<pid>/oom_score_adj- Adjust the oom-killer score
+3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj- Adjust the oom-killer score
 --------------------------------------------------------------------------------
 
-This file can be used to adjust the badness heuristic used to select which
+These file can be used to adjust the badness heuristic used to select which
 process gets killed in out of memory conditions.
 
 The badness heuristic assigns a value to each candidate task ranging from 0
@@ -1361,6 +1361,12 @@
 equivalent to discounting 50% of the task's allowed memory from being considered
 as scoring against the task.
 
+For backwards compatibility with previous kernels, /proc/<pid>/oom_adj may also
+be used to tune the badness score.  Its acceptable values range from -16
+(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17
+(OOM_DISABLE) to disable oom killing entirely for that task.  Its value is
+scaled linearly with /proc/<pid>/oom_score_adj.
+
 The value of /proc/<pid>/oom_score_adj may be reduced no lower than the last
 value set by a CAP_SYS_RESOURCE process. To reduce the value any lower
 requires CAP_SYS_RESOURCE.
@@ -1375,7 +1381,9 @@
 -------------------------------------------------------------
 
 This file can be used to check the current score used by the oom-killer is for
-any given <pid>.
+any given <pid>. Use it together with /proc/<pid>/oom_score_adj to tune which
+process should be killed in an out-of-memory situation.
+
 
 3.3  /proc/<pid>/io - Display the IO accounting fields
 -------------------------------------------------------
diff --git a/Documentation/firmware_class/README b/Documentation/firmware_class/README
index 7eceaff..815b711 100644
--- a/Documentation/firmware_class/README
+++ b/Documentation/firmware_class/README
@@ -18,32 +18,40 @@
  High level behavior (mixed):
  ============================
 
- kernel(driver): calls request_firmware(&fw_entry, $FIRMWARE, device)
+ 1), kernel(driver):
+	- calls request_firmware(&fw_entry, $FIRMWARE, device)
+	- kernel searchs the fimware image with name $FIRMWARE directly
+	in the below search path of root filesystem:
+		"/lib/firmware/updates/" UTS_RELEASE,
+		"/lib/firmware/updates",
+		"/lib/firmware/" UTS_RELEASE,
+		"/lib/firmware"
+	- If found, goto 7), else goto 2)
 
- userspace:
+ 2), userspace:
  	- /sys/class/firmware/xxx/{loading,data} appear.
 	- hotplug gets called with a firmware identifier in $FIRMWARE
 	  and the usual hotplug environment.
 		- hotplug: echo 1 > /sys/class/firmware/xxx/loading
 
- kernel: Discard any previous partial load.
+ 3), kernel: Discard any previous partial load.
 
- userspace:
+ 4), userspace:
 		- hotplug: cat appropriate_firmware_image > \
 					/sys/class/firmware/xxx/data
 
- kernel: grows a buffer in PAGE_SIZE increments to hold the image as it
+ 5), kernel: grows a buffer in PAGE_SIZE increments to hold the image as it
 	 comes in.
 
- userspace:
+ 6), userspace:
 		- hotplug: echo 0 > /sys/class/firmware/xxx/loading
 
- kernel: request_firmware() returns and the driver has the firmware
+ 7), kernel: request_firmware() returns and the driver has the firmware
 	 image in fw_entry->{data,size}. If something went wrong
 	 request_firmware() returns non-zero and fw_entry is set to
 	 NULL.
 
- kernel(driver): Driver code calls release_firmware(fw_entry) releasing
+ 8), kernel(driver): Driver code calls release_firmware(fw_entry) releasing
 		 the firmware image and any related resource.
 
  High level behavior (driver code):
diff --git a/Documentation/hwmon/fam15h_power b/Documentation/hwmon/fam15h_power
index a92918e..8065481 100644
--- a/Documentation/hwmon/fam15h_power
+++ b/Documentation/hwmon/fam15h_power
@@ -10,7 +10,7 @@
   BIOS and Kernel Developer's Guide (BKDG) For AMD Family 15h Processors
     (not yet published)
 
-Author: Andreas Herrmann <andreas.herrmann3@amd.com>
+Author: Andreas Herrmann <herrmann.der.user@googlemail.com>
 
 Description
 -----------
diff --git a/Documentation/networking/netdev-features.txt b/Documentation/networking/netdev-features.txt
index 4164f5c..f310ede 100644
--- a/Documentation/networking/netdev-features.txt
+++ b/Documentation/networking/netdev-features.txt
@@ -164,4 +164,4 @@
 This requests that the NIC receive all possible frames, including errored
 frames (such as bad FCS, etc).  This can be helpful when sniffing a link with
 bad packets on it.  Some NICs may receive more packets if also put into normal
-PROMISC mdoe.
+PROMISC mode.
diff --git a/Documentation/zh_CN/IRQ.txt b/Documentation/zh_CN/IRQ.txt
new file mode 100644
index 0000000..956026d
--- /dev/null
+++ b/Documentation/zh_CN/IRQ.txt
@@ -0,0 +1,39 @@
+Chinese translated version of Documentation/IRQ.txt
+
+If you have any comment or update to the content, please contact the
+original document maintainer directly.  However, if you have a problem
+communicating in English you can also ask the Chinese maintainer for
+help.  Contact the Chinese maintainer if this translation is outdated
+or if there is a problem with the translation.
+
+Maintainer: Eric W. Biederman <ebiederman@xmission.com>
+Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
+---------------------------------------------------------------------
+Documentation/IRQ.txt 的中文翻译
+
+如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
+交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
+译存在问题,请联系中文版维护者。
+英文版维护者: Eric W. Biederman <ebiederman@xmission.com>
+中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
+中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
+中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
+
+
+以下为正文
+---------------------------------------------------------------------
+何为 IRQ?
+
+一个 IRQ 是来自某个设备的一个中断请求。目前,它们可以来自一个硬件引脚,
+或来自一个数据包。多个设备可能连接到同个硬件引脚,从而共享一个 IRQ。
+
+一个 IRQ 编号是用于告知硬件中断源的内核标识。通常情况下,这是一个
+全局 irq_desc 数组的索引,但是除了在 linux/interrupt.h 中的实现,
+具体的细节是体系结构特定的。
+
+一个 IRQ 编号是设备上某个可能的中断源的枚举。通常情况下,枚举的编号是
+该引脚在系统内中断控制器的所有输入引脚中的编号。对于 ISA 总线中的情况,
+枚举的是在两个 i8259 中断控制器中 16 个输入引脚。
+
+架构可以对 IRQ 编号指定额外的含义,在硬件涉及任何手工配置的情况下,
+是被提倡的。ISA 的 IRQ 是一个分配这类额外含义的典型例子。
diff --git a/Documentation/zh_CN/arm64/booting.txt b/Documentation/zh_CN/arm64/booting.txt
new file mode 100644
index 0000000..28fa325
--- /dev/null
+++ b/Documentation/zh_CN/arm64/booting.txt
@@ -0,0 +1,156 @@
+Chinese translated version of Documentation/arm64/booting.txt
+
+If you have any comment or update to the content, please contact the
+original document maintainer directly.  However, if you have a problem
+communicating in English you can also ask the Chinese maintainer for
+help.  Contact the Chinese maintainer if this translation is outdated
+or if there is a problem with the translation.
+
+Maintainer: Will Deacon <will.deacon@arm.com>
+Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
+---------------------------------------------------------------------
+Documentation/arm64/booting.txt 的中文翻译
+
+如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
+交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
+译存在问题,请联系中文版维护者。
+
+英文版维护者: Will Deacon <will.deacon@arm.com>
+中文版维护者: 傅炜  Fu Wei <tekkamanninja@gmail.com>
+中文版翻译者: 傅炜  Fu Wei <tekkamanninja@gmail.com>
+中文版校译者: 傅炜  Fu Wei <tekkamanninja@gmail.com>
+
+以下为正文
+---------------------------------------------------------------------
+			启动 AArch64 Linux
+			==================
+
+作者: Will Deacon <will.deacon@arm.com>
+日期: 2012 年 09 月 07 日
+
+本文档基于 Russell King 的 ARM 启动文档,且适用于所有公开发布的
+AArch64 Linux 内核代码。
+
+AArch64 异常模型由多个异常级别(EL0 - EL3)组成,对于 EL0 和 EL1
+异常级有对应的安全和非安全模式。EL2 是系统管理级,且仅存在于
+非安全模式下。EL3 是最高特权级,且仅存在于安全模式下。
+
+基于本文档的目的,我们将简单地使用‘引导装载程序’(‘boot loader’)
+这个术语来定义在将控制权交给 Linux 内核前 CPU 上执行的所有软件。
+这可能包含安全监控和系统管理代码,或者它可能只是一些用于准备最小启动
+环境的指令。
+
+基本上,引导装载程序(至少)应实现以下操作:
+
+1、设置和初始化 RAM
+2、设置设备树数据
+3、解压内核映像
+4、调用内核映像
+
+
+1、设置和初始化 RAM
+-----------------
+
+必要性: 强制
+
+引导装载程序应该找到并初始化系统中所有内核用于保持系统变量数据的 RAM。
+这个操作的执行是设备依赖的。(它可能使用内部算法来自动定位和计算所有
+RAM,或可能使用对这个设备已知的 RAM 信息,还可能使用任何引导装载程序
+设计者想到的匹配方法。)
+
+
+2、设置设备树数据
+---------------
+
+必要性: 强制
+
+设备树数据块(dtb)大小必须不大于 2 MB,且位于从内核映像起始算起第一个
+512MB 内的 2MB 边界上。这使得内核可以通过初始页表中的单个节描述符来
+映射此数据块。
+
+
+3、解压内核映像
+-------------
+
+必要性: 可选
+
+AArch64 内核当前没有提供自解压代码,因此如果使用了压缩内核映像文件
+(比如 Image.gz),则需要通过引导装载程序(使用 gzip 等)来进行解压。
+若引导装载程序没有实现这个需求,就要使用非压缩内核映像文件。
+
+
+4、调用内核映像
+-------------
+
+必要性: 强制
+
+已解压的内核映像包含一个 32 字节的头,内容如下:
+
+  u32 magic	= 0x14000008;	/* 跳转到 stext, 小端 */
+  u32 res0	= 0;		/* 保留 */
+  u64 text_offset;		/* 映像装载偏移 */
+  u64 res1	= 0;		/* 保留 */
+  u64 res2	= 0;		/* 保留 */
+
+映像必须位于系统 RAM 起始处的特定偏移(当前是 0x80000)。系统 RAM
+的起始地址必须是以 2MB 对齐的。
+
+在跳转入内核前,必须符合以下状态:
+
+- 停止所有 DMA 设备,这样内存数据就不会因为虚假网络包或磁盘数据而
+  被破坏。这可能可以节省你许多的调试时间。
+
+- 主 CPU 通用寄存器设置
+  x0 = 系统 RAM 中设备树数据块(dtb)的物理地址。
+  x1 = 0 (保留,将来可能使用)
+  x2 = 0 (保留,将来可能使用)
+  x3 = 0 (保留,将来可能使用)
+
+- CPU 模式
+  所有形式的中断必须在 PSTATE.DAIF 中被屏蔽(Debug、SError、IRQ
+  和 FIQ)。
+  CPU 必须处于 EL2(推荐,可访问虚拟化扩展)或非安全 EL1 模式下。
+
+- 高速缓存、MMU
+  MMU 必须关闭。
+  指令缓存开启或关闭都可以。
+  数据缓存必须关闭且无效。
+  外部高速缓存(如果存在)必须配置并禁用。
+
+- 架构计时器
+  CNTFRQ 必须设定为计时器的频率。
+  如果在 EL1 模式下进入内核,则 CNTHCTL_EL2 中的 EL1PCTEN (bit 0)
+  必须置位。
+
+- 一致性
+  通过内核启动的所有 CPU 在内核入口地址上必须处于相同的一致性域中。
+  这可能要根据具体实现来定义初始化过程,以使能每个CPU上对维护操作的
+  接收。
+
+- 系统寄存器
+  在进入内核映像的异常级中,所有构架中可写的系统寄存器必须通过软件
+  在一个更高的异常级别下初始化,以防止在 未知 状态下运行。
+
+引导装载程序必须在每个 CPU 处于以下状态时跳入内核入口:
+
+- 主 CPU 必须直接跳入内核映像的第一条指令。通过此 CPU 传递的设备树
+  数据块必须在每个 CPU 节点中包含以下内容:
+
+    1、‘enable-method’属性。目前,此字段支持的值仅为字符串“spin-table”。
+
+    2、‘cpu-release-addr’标识一个 64-bit、初始化为零的内存位置。
+
+  引导装载程序必须生成这些设备树属性,并在跳入内核入口之前将其插入
+  数据块。
+
+- 任何辅助 CPU 必须在内存保留区(通过设备树中的 /memreserve/ 域传递
+  给内核)中自旋于内核之外,轮询它们的 cpu-release-addr 位置(必须
+  包含在保留区中)。可通过插入 wfe 指令来降低忙循环开销,而主 CPU 将
+  发出 sev 指令。当对 cpu-release-addr 所指位置的读取操作返回非零值
+  时,CPU 必须直接跳入此值所指向的地址。
+
+- 辅助 CPU 通用寄存器设置
+  x0 = 0 (保留,将来可能使用)
+  x1 = 0 (保留,将来可能使用)
+  x2 = 0 (保留,将来可能使用)
+  x3 = 0 (保留,将来可能使用)
diff --git a/Documentation/zh_CN/arm64/memory.txt b/Documentation/zh_CN/arm64/memory.txt
new file mode 100644
index 0000000..83b5193
--- /dev/null
+++ b/Documentation/zh_CN/arm64/memory.txt
@@ -0,0 +1,93 @@
+Chinese translated version of Documentation/arm64/memory.txt
+
+If you have any comment or update to the content, please contact the
+original document maintainer directly.  However, if you have a problem
+communicating in English you can also ask the Chinese maintainer for
+help.  Contact the Chinese maintainer if this translation is outdated
+or if there is a problem with the translation.
+
+Maintainer: Catalin Marinas <catalin.marinas@arm.com>
+Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
+---------------------------------------------------------------------
+Documentation/arm64/memory.txt 的中文翻译
+
+如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
+交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
+译存在问题,请联系中文版维护者。
+
+英文版维护者: Catalin Marinas <catalin.marinas@arm.com>
+中文版维护者: 傅炜  Fu Wei <tekkamanninja@gmail.com>
+中文版翻译者: 傅炜  Fu Wei <tekkamanninja@gmail.com>
+中文版校译者: 傅炜  Fu Wei <tekkamanninja@gmail.com>
+
+以下为正文
+---------------------------------------------------------------------
+		     Linux 在 AArch64 中的内存布局
+		     ===========================
+
+作者: Catalin Marinas <catalin.marinas@arm.com>
+日期: 2012 年 02 月 20 日
+
+本文档描述 AArch64 Linux 内核所使用的虚拟内存布局。此构架可以实现
+页大小为 4KB 的 4 级转换表和页大小为 64KB 的 3 级转换表。
+
+AArch64 Linux 使用页大小为 4KB 的 3 级转换表配置,对于用户和内核
+都有 39-bit (512GB) 的虚拟地址空间。对于页大小为 64KB的配置,仅
+使用 2 级转换表,但内存布局相同。
+
+用户地址空间的 63:39 位为 0,而内核地址空间的相应位为 1。TTBRx 的
+选择由虚拟地址的 63 位给出。swapper_pg_dir 仅包含内核(全局)映射,
+而用户 pgd 仅包含用户(非全局)映射。swapper_pgd_dir 地址被写入
+TTBR1 中,且从不写入 TTBR0。
+
+
+AArch64 Linux 内存布局:
+
+起始地址			结束地址			大小		用途
+-----------------------------------------------------------------------
+0000000000000000	0000007fffffffff	 512GB		用户空间
+
+ffffff8000000000	ffffffbbfffcffff	~240GB		vmalloc
+
+ffffffbbfffd0000	ffffffbcfffdffff	  64KB		[防护页]
+
+ffffffbbfffe0000	ffffffbcfffeffff	  64KB		PCI I/O 空间
+
+ffffffbbffff0000	ffffffbcffffffff	  64KB		[防护页]
+
+ffffffbc00000000	ffffffbdffffffff	   8GB		vmemmap
+
+ffffffbe00000000	ffffffbffbffffff	  ~8GB		[防护页,未来用于 vmmemap]
+
+ffffffbffc000000	ffffffbfffffffff	  64MB		模块
+
+ffffffc000000000	ffffffffffffffff	 256GB		内存空间
+
+
+4KB 页大小的转换表查找:
+
++--------+--------+--------+--------+--------+--------+--------+--------+
+|63    56|55    48|47    40|39    32|31    24|23    16|15     8|7      0|
++--------+--------+--------+--------+--------+--------+--------+--------+
+ |                 |         |         |         |         |
+ |                 |         |         |         |         v
+ |                 |         |         |         |   [11:0]  页内偏移
+ |                 |         |         |         +-> [20:12] L3 索引
+ |                 |         |         +-----------> [29:21] L2 索引
+ |                 |         +---------------------> [38:30] L1 索引
+ |                 +-------------------------------> [47:39] L0 索引 (未使用)
+ +-------------------------------------------------> [63] TTBR0/1
+
+
+64KB 页大小的转换表查找:
+
++--------+--------+--------+--------+--------+--------+--------+--------+
+|63    56|55    48|47    40|39    32|31    24|23    16|15     8|7      0|
++--------+--------+--------+--------+--------+--------+--------+--------+
+ |                 |    |               |              |
+ |                 |    |               |              v
+ |                 |    |               |            [15:0]  页内偏移
+ |                 |    |               +----------> [28:16] L3 索引
+ |                 |    +--------------------------> [41:29] L2 索引 (仅使用 38:29 )
+ |                 +-------------------------------> [47:42] L1 索引 (未使用)
+ +-------------------------------------------------> [63] TTBR0/1
diff --git a/MAINTAINERS b/MAINTAINERS
index 027ec2b..63b7a61 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -503,7 +503,7 @@
 F:	include/linux/altera_jtaguart.h
 
 AMD FAM15H PROCESSOR POWER MONITORING DRIVER
-M:	Andreas Herrmann <andreas.herrmann3@amd.com>
+M:	Andreas Herrmann <herrmann.der.user@googlemail.com>
 L:	lm-sensors@lm-sensors.org
 S:	Maintained
 F:	Documentation/hwmon/fam15h_power
@@ -637,6 +637,13 @@
 S:	Maintained
 F:	arch/arm/
 
+ARM SUB-ARCHITECTURES
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	MAINTAINED
+F:	arch/arm/mach-*/
+F:	arch/arm/plat-*/
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git
+
 ARM PRIMECELL AACI PL041 DRIVER
 M:	Russell King <linux@arm.linux.org.uk>
 S:	Maintained
@@ -678,6 +685,12 @@
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 
+ARM/Allwinner A1X SoC support
+M:	Maxime Ripard <maxime.ripard@free-electrons.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	arch/arm/mach-sunxi/
+
 ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES
 M:	Andrew Victor <linux@maxim.org.za>
 M:	Nicolas Ferre <nicolas.ferre@atmel.com>
@@ -700,6 +713,12 @@
 F:	arch/arm/mach-cns3xxx/
 T:	git git://git.infradead.org/users/cbou/linux-cns3xxx.git
 
+ARM/CIRRUS LOGIC CLPS711X ARM ARCHITECTURE
+M:	Alexander Shiyan <shc_work@mail.ru>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Odd Fixes
+F:	arch/arm/mach-clps711x/
+
 ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
 M:	Hartley Sweeten <hsweeten@visionengravers.com>
 M:	Ryan Mallon <rmallon@gmail.com>
@@ -790,7 +809,6 @@
 S:	Maintained
 T:	git git://git.pengutronix.de/git/imx/linux-2.6.git
 F:	arch/arm/mach-imx/
-F:	arch/arm/plat-mxc/
 F:	arch/arm/configs/imx*_defconfig
 
 ARM/FREESCALE IMX6
@@ -2500,6 +2518,7 @@
 M:	Seung-Woo Kim <sw0312.kim@samsung.com>
 M:	Kyungmin Park <kyungmin.park@samsung.com>
 L:	dri-devel@lists.freedesktop.org
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git
 S:	Supported
 F:	drivers/gpu/drm/exynos
 F:	include/drm/exynos*
@@ -2802,6 +2821,7 @@
 EXTENSIBLE FIRMWARE INTERFACE (EFI)
 M:	Matt Fleming <matt.fleming@intel.com>
 L:	linux-efi@vger.kernel.org
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
 S:	Maintained
 F:	Documentation/x86/efi-stub.txt
 F:	arch/ia64/kernel/efi.c
@@ -3589,6 +3609,49 @@
 F:	drivers/net/hyperv/
 F:	drivers/staging/hv/
 
+I2C OVER PARALLEL PORT
+M:	Jean Delvare <khali@linux-fr.org>
+L:	linux-i2c@vger.kernel.org
+S:	Maintained
+F:	Documentation/i2c/busses/i2c-parport
+F:	Documentation/i2c/busses/i2c-parport-light
+F:	drivers/i2c/busses/i2c-parport.c
+F:	drivers/i2c/busses/i2c-parport-light.c
+
+I2C/SMBUS CONTROLLER DRIVERS FOR PC
+M:	Jean Delvare <khali@linux-fr.org>
+L:	linux-i2c@vger.kernel.org
+S:	Maintained
+F:	Documentation/i2c/busses/i2c-ali1535
+F:	Documentation/i2c/busses/i2c-ali1563
+F:	Documentation/i2c/busses/i2c-ali15x3
+F:	Documentation/i2c/busses/i2c-amd756
+F:	Documentation/i2c/busses/i2c-amd8111
+F:	Documentation/i2c/busses/i2c-i801
+F:	Documentation/i2c/busses/i2c-nforce2
+F:	Documentation/i2c/busses/i2c-piix4
+F:	Documentation/i2c/busses/i2c-sis5595
+F:	Documentation/i2c/busses/i2c-sis630
+F:	Documentation/i2c/busses/i2c-sis96x
+F:	Documentation/i2c/busses/i2c-via
+F:	Documentation/i2c/busses/i2c-viapro
+F:	drivers/i2c/busses/i2c-ali1535.c
+F:	drivers/i2c/busses/i2c-ali1563.c
+F:	drivers/i2c/busses/i2c-ali15x3.c
+F:	drivers/i2c/busses/i2c-amd756.c
+F:	drivers/i2c/busses/i2c-amd756-s4882.c
+F:	drivers/i2c/busses/i2c-amd8111.c
+F:	drivers/i2c/busses/i2c-i801.c
+F:	drivers/i2c/busses/i2c-isch.c
+F:	drivers/i2c/busses/i2c-nforce2.c
+F:	drivers/i2c/busses/i2c-nforce2-s4985.c
+F:	drivers/i2c/busses/i2c-piix4.c
+F:	drivers/i2c/busses/i2c-sis5595.c
+F:	drivers/i2c/busses/i2c-sis630.c
+F:	drivers/i2c/busses/i2c-sis96x.c
+F:	drivers/i2c/busses/i2c-via.c
+F:	drivers/i2c/busses/i2c-viapro.c
+
 I2C/SMBUS STUB DRIVER
 M:	"Mark M. Hoffman" <mhoffman@lightlink.com>
 L:	linux-i2c@vger.kernel.org
@@ -3596,9 +3659,8 @@
 F:	drivers/i2c/busses/i2c-stub.c
 
 I2C SUBSYSTEM
-M:	"Jean Delvare (PC drivers, core)" <khali@linux-fr.org>
+M:	Wolfram Sang <w.sang@pengutronix.de>
 M:	"Ben Dooks (embedded platforms)" <ben-linux@fluff.org>
-M:	"Wolfram Sang (embedded platforms)" <w.sang@pengutronix.de>
 L:	linux-i2c@vger.kernel.org
 W:	http://i2c.wiki.kernel.org/
 T:	quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/
@@ -3609,6 +3671,13 @@
 F:	include/linux/i2c.h
 F:	include/linux/i2c-*.h
 
+I2C-TAOS-EVM DRIVER
+M:	Jean Delvare <khali@linux-fr.org>
+L:	linux-i2c@vger.kernel.org
+S:	Maintained
+F:	Documentation/i2c/busses/i2c-taos-evm
+F:	drivers/i2c/busses/i2c-taos-evm.c
+
 I2C-TINY-USB DRIVER
 M:	Till Harbaum <till@harbaum.org>
 L:	linux-i2c@vger.kernel.org
@@ -5061,7 +5130,13 @@
 S:	Odd Fixes
 F:	drivers/net/
 F:	include/linux/if_*
-F:	include/linux/*device.h
+F:	include/linux/netdevice.h
+F:	include/linux/arcdevice.h
+F:	include/linux/etherdevice.h
+F:	include/linux/fcdevice.h
+F:	include/linux/fddidevice.h
+F:	include/linux/hippidevice.h
+F:	include/linux/inetdevice.h
 
 NETXEN (1/10) GbE SUPPORT
 M:	Sony Chacko <sony.chacko@qlogic.com>
@@ -5633,7 +5708,7 @@
 F:	drivers/pinctrl/spear/
 
 PKTCDVD DRIVER
-M:	Peter Osterlund <petero2@telia.com>
+M:	Jiri Kosina <jkosina@suse.cz>
 S:	Maintained
 F:	drivers/block/pktcdvd.c
 F:	include/linux/pktcdvd.h
@@ -7195,6 +7270,14 @@
 S:	Maintained
 F:	arch/xtensa/
 
+THERMAL
+M:      Zhang Rui <rui.zhang@intel.com>
+L:      linux-pm@vger.kernel.org
+T:      git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git
+S:      Supported
+F:      drivers/thermal/
+F:      include/linux/thermal.h
+
 THINKPAD ACPI EXTRAS DRIVER
 M:	Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br>
 L:	ibm-acpi-devel@lists.sourceforge.net
@@ -7872,13 +7955,6 @@
 S:	Maintained
 F:	drivers/net/ethernet/via/via-rhine.c
 
-VIAPRO SMBUS DRIVER
-M:	Jean Delvare <khali@linux-fr.org>
-L:	linux-i2c@vger.kernel.org
-S:	Maintained
-F:	Documentation/i2c/busses/i2c-viapro
-F:	drivers/i2c/busses/i2c-viapro.c
-
 VIA SD/MMC CARD CONTROLLER DRIVER
 M:	Bruce Chang <brucechang@via.com.tw>
 M:	Harald Welte <HaraldWelte@viatech.com>
diff --git a/Makefile b/Makefile
index 14c93b3..9f6ca12 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 7
 SUBLEVEL = 0
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc6
 NAME = Terrified Chipmunk
 
 # *DOCUMENTATION*
diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
index 4554ecb..1f8c729 100644
--- a/arch/alpha/include/asm/thread_info.h
+++ b/arch/alpha/include/asm/thread_info.h
@@ -7,6 +7,7 @@
 #include <asm/processor.h>
 #include <asm/types.h>
 #include <asm/hwrpb.h>
+#include <asm/sysinfo.h>
 #endif
 
 #ifndef __ASSEMBLY__
@@ -21,6 +22,7 @@
 	mm_segment_t		addr_limit;	/* thread address space */
 	unsigned		cpu;		/* current CPU */
 	int			preempt_count; /* 0 => preemptable, <0 => BUG */
+	unsigned int		status;		/* thread-synchronous flags */
 
 	int bpt_nsaved;
 	unsigned long bpt_addr[2];		/* breakpoint handling  */
@@ -63,8 +65,6 @@
  * - these are process state flags and used from assembly
  * - pending work-to-be-done flags come first and must be assigned to be
  *   within bits 0 to 7 to fit in and immediate operand.
- * - ALPHA_UAC_SHIFT below must be kept consistent with the unaligned
- *   control flags.
  *
  * TIF_SYSCALL_TRACE is known to be 0 via blbs.
  */
@@ -72,18 +72,12 @@
 #define TIF_NOTIFY_RESUME	1	/* callback before returning to user */
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
-#define TIF_POLLING_NRFLAG	8	/* poll_idle is polling NEED_RESCHED */
 #define TIF_DIE_IF_KERNEL	9	/* dik recursion lock */
-#define TIF_UAC_NOPRINT		10	/* ! Preserve sequence of following */
-#define TIF_UAC_NOFIX		11	/* ! flags as they match            */
-#define TIF_UAC_SIGBUS		12	/* ! userspace part of 'osf_sysinfo' */
 #define TIF_MEMDIE		13	/* is terminating due to OOM killer */
-#define TIF_RESTORE_SIGMASK	14	/* restore signal mask in do_signal */
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 
 /* Work to do on interrupt/exception return.  */
@@ -94,29 +88,63 @@
 #define _TIF_ALLWORK_MASK	(_TIF_WORK_MASK		\
 				 | _TIF_SYSCALL_TRACE)
 
-#define ALPHA_UAC_SHIFT		TIF_UAC_NOPRINT
-#define ALPHA_UAC_MASK		(1 << TIF_UAC_NOPRINT | 1 << TIF_UAC_NOFIX | \
-				 1 << TIF_UAC_SIGBUS)
+#define TS_UAC_NOPRINT		0x0001	/* ! Preserve the following three */
+#define TS_UAC_NOFIX		0x0002	/* ! flags as they match          */
+#define TS_UAC_SIGBUS		0x0004	/* ! userspace part of 'osf_sysinfo' */
+#define TS_RESTORE_SIGMASK	0x0008	/* restore signal mask in do_signal() */
+#define TS_POLLING		0x0010	/* idle task polling need_resched,
+					   skip sending interrupt */
 
-#define SET_UNALIGN_CTL(task,value)	({				     \
-	task_thread_info(task)->flags = ((task_thread_info(task)->flags &    \
-		~ALPHA_UAC_MASK)					     \
-		| (((value) << ALPHA_UAC_SHIFT)       & (1<<TIF_UAC_NOPRINT))\
-		| (((value) << (ALPHA_UAC_SHIFT + 1)) & (1<<TIF_UAC_SIGBUS)) \
-		| (((value) << (ALPHA_UAC_SHIFT - 1)) & (1<<TIF_UAC_NOFIX)));\
+#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
+
+#ifndef __ASSEMBLY__
+#define HAVE_SET_RESTORE_SIGMASK	1
+static inline void set_restore_sigmask(void)
+{
+	struct thread_info *ti = current_thread_info();
+	ti->status |= TS_RESTORE_SIGMASK;
+	WARN_ON(!test_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags));
+}
+static inline void clear_restore_sigmask(void)
+{
+	current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+}
+static inline bool test_restore_sigmask(void)
+{
+	return current_thread_info()->status & TS_RESTORE_SIGMASK;
+}
+static inline bool test_and_clear_restore_sigmask(void)
+{
+	struct thread_info *ti = current_thread_info();
+	if (!(ti->status & TS_RESTORE_SIGMASK))
+		return false;
+	ti->status &= ~TS_RESTORE_SIGMASK;
+	return true;
+}
+#endif
+
+#define SET_UNALIGN_CTL(task,value)	({				\
+	__u32 status = task_thread_info(task)->status & ~UAC_BITMASK;	\
+	if (value & PR_UNALIGN_NOPRINT)					\
+		status |= TS_UAC_NOPRINT;				\
+	if (value & PR_UNALIGN_SIGBUS)					\
+		status |= TS_UAC_SIGBUS;				\
+	if (value & 4)	/* alpha-specific */				\
+		status |= TS_UAC_NOFIX;					\
+	task_thread_info(task)->status = status;			\
 	0; })
 
 #define GET_UNALIGN_CTL(task,value)	({				\
-	put_user((task_thread_info(task)->flags & (1 << TIF_UAC_NOPRINT))\
-		  >> ALPHA_UAC_SHIFT					\
-		 | (task_thread_info(task)->flags & (1 << TIF_UAC_SIGBUS))\
-		 >> (ALPHA_UAC_SHIFT + 1)				\
-		 | (task_thread_info(task)->flags & (1 << TIF_UAC_NOFIX))\
-		 >> (ALPHA_UAC_SHIFT - 1),				\
-		 (int __user *)(value));				\
+	__u32 status = task_thread_info(task)->status & ~UAC_BITMASK;	\
+	__u32 res = 0;							\
+	if (status & TS_UAC_NOPRINT)					\
+		res |= PR_UNALIGN_NOPRINT;				\
+	if (status & TS_UAC_SIGBUS)					\
+		res |= PR_UNALIGN_SIGBUS;				\
+	if (status & TS_UAC_NOFIX)					\
+		res |= 4;						\
+	put_user(res, (int __user *)(value));				\
 	})
 
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
-
 #endif /* __KERNEL__ */
 #endif /* _ALPHA_THREAD_INFO_H */
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 9eb0905..1e6956a 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -793,8 +793,7 @@
  	case GSI_UACPROC:
 		if (nbytes < sizeof(unsigned int))
 			return -EINVAL;
-		w = (current_thread_info()->flags >> ALPHA_UAC_SHIFT) &
-			UAC_BITMASK;
+		w = current_thread_info()->status & UAC_BITMASK;
 		if (put_user(w, (unsigned int __user *)buffer))
 			return -EFAULT;
  		return 1;
@@ -904,24 +903,20 @@
 		break;
 
  	case SSI_NVPAIRS: {
-		unsigned long v, w, i;
-		unsigned int old, new;
+		unsigned __user *p = buffer;
+		unsigned i;
 		
- 		for (i = 0; i < nbytes; ++i) {
+		for (i = 0, p = buffer; i < nbytes; ++i, p += 2) {
+			unsigned v, w, status;
 
- 			if (get_user(v, 2*i + (unsigned int __user *)buffer))
- 				return -EFAULT;
- 			if (get_user(w, 2*i + 1 + (unsigned int __user *)buffer))
+			if (get_user(v, p) || get_user(w, p + 1))
  				return -EFAULT;
  			switch (v) {
  			case SSIN_UACPROC:
-			again:
-				old = current_thread_info()->flags;
-				new = old & ~(UAC_BITMASK << ALPHA_UAC_SHIFT);
-				new = new | (w & UAC_BITMASK) << ALPHA_UAC_SHIFT;
-				if (cmpxchg(&current_thread_info()->flags,
-					    old, new) != old)
-					goto again;
+				w &= UAC_BITMASK;
+				status = current_thread_info()->status;
+				status = (status & ~UAC_BITMASK) | w;
+				current_thread_info()->status = status;
  				break;
  
  			default:
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 4054e0f..51987dc 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -49,7 +49,7 @@
 void
 cpu_idle(void)
 {
-	set_thread_flag(TIF_POLLING_NRFLAG);
+	current_thread_info()->status |= TS_POLLING;
 
 	while (1) {
 		/* FIXME -- EV6 and LCA45 know how to power down
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 80d987c..272666d 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -780,17 +780,17 @@
 	/* Check the UAC bits to decide what the user wants us to do
 	   with the unaliged access.  */
 
-	if (!test_thread_flag (TIF_UAC_NOPRINT)) {
+	if (!(current_thread_info()->status & TS_UAC_NOPRINT)) {
 		if (__ratelimit(&ratelimit)) {
 			printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
 			       current->comm, task_pid_nr(current),
 			       regs->pc - 4, va, opcode, reg);
 		}
 	}
-	if (test_thread_flag (TIF_UAC_SIGBUS))
+	if ((current_thread_info()->status & TS_UAC_SIGBUS))
 		goto give_sigbus;
 	/* Not sure why you'd want to use this, but... */
-	if (test_thread_flag (TIF_UAC_NOFIX))
+	if ((current_thread_info()->status & TS_UAC_NOFIX))
 		return;
 
 	/* Don't bother reading ds in the access check since we already
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2205e3eb..33d2887 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -336,7 +336,7 @@
 
 config ARCH_BCM2835
 	bool "Broadcom BCM2835 family"
-	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select ARCH_REQUIRE_GPIOLIB
 	select ARM_AMBA
 	select ARM_ERRATA_411920
 	select ARM_TIMER_SP804
@@ -344,7 +344,10 @@
 	select COMMON_CLK
 	select CPU_V6
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_GPIO
 	select MULTI_IRQ_HANDLER
+	select PINCTRL
+	select PINCTRL_BCM2835
 	select SPARSE_IRQ
 	select USE_OF
 	help
@@ -364,11 +367,16 @@
 
 config ARCH_CLPS711X
 	bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
+	select ARCH_REQUIRE_GPIOLIB
 	select ARCH_USES_GETTIMEOFFSET
+	select AUTO_ZRELADDR
 	select CLKDEV_LOOKUP
 	select COMMON_CLK
 	select CPU_ARM720T
+	select GENERIC_CLOCKEVENTS
+	select MULTI_IRQ_HANDLER
 	select NEED_MACH_MEMORY_H
+	select SPARSE_IRQ
 	help
 	  Support for Cirrus Logic 711x/721x/731x based boards.
 
@@ -433,19 +441,6 @@
 	  Support for systems based on the DC21285 companion chip
 	  ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
 
-config ARCH_MXC
-	bool "Freescale MXC/iMX-based"
-	select ARCH_REQUIRE_GPIOLIB
-	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
-	select GENERIC_CLOCKEVENTS
-	select GENERIC_IRQ_CHIP
-	select MULTI_IRQ_HANDLER
-	select SPARSE_IRQ
-	select USE_OF
-	help
-	  Support for Freescale MXC/iMX-based family of processors
-
 config ARCH_MXS
 	bool "Freescale MXS-based"
 	select ARCH_REQUIRE_GPIOLIB
@@ -1022,6 +1017,8 @@
 
 source "arch/arm/mach-at91/Kconfig"
 
+source "arch/arm/mach-bcm/Kconfig"
+
 source "arch/arm/mach-clps711x/Kconfig"
 
 source "arch/arm/mach-cns3xxx/Kconfig"
@@ -1058,7 +1055,7 @@
 
 source "arch/arm/mach-mv78xx0/Kconfig"
 
-source "arch/arm/plat-mxc/Kconfig"
+source "arch/arm/mach-imx/Kconfig"
 
 source "arch/arm/mach-mxs/Kconfig"
 
@@ -1113,6 +1110,8 @@
 
 source "arch/arm/mach-shmobile/Kconfig"
 
+source "arch/arm/mach-sunxi/Kconfig"
+
 source "arch/arm/mach-prima2/Kconfig"
 
 source "arch/arm/mach-tegra/Kconfig"
@@ -1603,8 +1602,8 @@
 	default "4"
 
 config HOTPLUG_CPU
-	bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
-	depends on SMP && HOTPLUG && EXPERIMENTAL
+	bool "Support for hot-pluggable CPUs"
+	depends on SMP && HOTPLUG
 	help
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
 	  can be controlled through /sys/devices/system/cpu.
@@ -1645,8 +1644,8 @@
 	default 100
 
 config THUMB2_KERNEL
-	bool "Compile the kernel in Thumb-2 mode (EXPERIMENTAL)"
-	depends on CPU_V7 && !CPU_V6 && !CPU_V6K && EXPERIMENTAL
+	bool "Compile the kernel in Thumb-2 mode"
+	depends on CPU_V7 && !CPU_V6 && !CPU_V6K
 	select AEABI
 	select ARM_ASM_UNIFIED
 	select ARM_UNWIND
@@ -1850,6 +1849,7 @@
 config XEN
 	bool "Xen guest support on ARM (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && ARM && OF
+	depends on CPU_V7 && !CPU_V6
 	help
 	  Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
 
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index b0f3857..04a3f0d 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -338,6 +338,17 @@
 		  The uncompressor code port configuration is now handled
 		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
 
+	config DEBUG_S3C_UART3
+		depends on PLAT_SAMSUNG && ARCH_EXYNOS
+		bool "Use S3C UART 3 for low-level debug"
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to UART 3. The port must have been initialised
+		  by the boot-loader before use.
+
+		  The uncompressor code port configuration is now handled
+		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
+
 	config DEBUG_SOCFPGA_UART
 		depends on ARCH_SOCFPGA
 		bool "Use SOCFPGA UART for low-level debug"
@@ -345,6 +356,20 @@
 		  Say Y here if you want kernel low-level debugging support
 		  on SOCFPGA based platforms.
 
+	config DEBUG_SUNXI_UART0
+		bool "Kernel low-level debugging messages via sunXi UART0"
+		depends on ARCH_SUNXI
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on Allwinner A1X based platforms on the UART0.
+
+	config DEBUG_SUNXI_UART1
+		bool "Kernel low-level debugging messages via sunXi UART1"
+		depends on ARCH_SUNXI
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on Allwinner A1X based platforms on the UART1.
+
 	config DEBUG_VEXPRESS_UART0_DETECT
 		bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
 		depends on ARCH_VEXPRESS && CPU_CP15_MMU
@@ -412,10 +437,19 @@
 config DEBUG_LL_INCLUDE
 	string
 	default "debug/icedcc.S" if DEBUG_ICEDCC
+	default "debug/imx.S" if DEBUG_IMX1_UART || \
+				 DEBUG_IMX25_UART || \
+				 DEBUG_IMX21_IMX27_UART || \
+				 DEBUG_IMX31_IMX35_UART || \
+				 DEBUG_IMX51_UART || \
+				 DEBUG_IMX50_IMX53_UART ||\
+				 DEBUG_IMX6Q_UART2 || \
+				 DEBUG_IMX6Q_UART4
 	default "debug/highbank.S" if DEBUG_HIGHBANK_UART
 	default "debug/mvebu.S" if DEBUG_MVEBU_UART
 	default "debug/picoxcell.S" if DEBUG_PICOXCELL_UART
 	default "debug/socfpga.S" if DEBUG_SOCFPGA_UART
+	default "debug/sunxi.S" if DEBUG_SUNXI_UART0 || DEBUG_SUNXI_UART1
 	default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \
 		DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1
 	default "mach/debug-macro.S"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index f023e3a..58afa0d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -21,8 +21,6 @@
 OBJCOPYFLAGS	:=-O binary -R .comment -S
 GZFLAGS		:=-9
 #KBUILD_CFLAGS	+=-pipe
-# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
-KBUILD_CFLAGS	+=$(call cc-option,-marm,)
 
 # Never generate .eh_frame
 KBUILD_CFLAGS	+= $(call cc-option,-fno-dwarf2-cfi-asm)
@@ -105,17 +103,20 @@
 ifeq ($(CONFIG_THUMB2_KERNEL),y)
 AFLAGS_AUTOIT	:=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mauto-it)
 AFLAGS_NOWARN	:=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
-CFLAGS_THUMB2	:=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
-AFLAGS_THUMB2	:=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb
+CFLAGS_ISA	:=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
+AFLAGS_ISA	:=$(CFLAGS_ISA) -Wa$(comma)-mthumb
 # Work around buggy relocation from gas if requested:
 ifeq ($(CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11),y)
 CFLAGS_MODULE	+=-fno-optimize-sibling-calls
 endif
+else
+CFLAGS_ISA	:=$(call cc-option,-marm,)
+AFLAGS_ISA	:=$(CFLAGS_ISA)
 endif
 
 # Need -Uarm for gcc < 3.x
-KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
-KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
+KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
+KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
 
 CHECKFLAGS	+= -D__arm__
 
@@ -136,6 +137,7 @@
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
 machine-$(CONFIG_ARCH_AT91)		+= at91
+machine-$(CONFIG_ARCH_BCM)		+= bcm
 machine-$(CONFIG_ARCH_BCM2835)		+= bcm2835
 machine-$(CONFIG_ARCH_CLPS711X)		+= clps711x
 machine-$(CONFIG_ARCH_CNS3XXX)		+= cns3xxx
@@ -192,10 +194,10 @@
 machine-$(CONFIG_ARCH_SPEAR3XX)		+= spear3xx
 machine-$(CONFIG_MACH_SPEAR600)		+= spear6xx
 machine-$(CONFIG_ARCH_ZYNQ)		+= zynq
+machine-$(CONFIG_ARCH_SUNXI)		+= sunxi
 
 # Platform directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
-plat-$(CONFIG_ARCH_MXC)		+= mxc
 plat-$(CONFIG_ARCH_OMAP)	+= omap
 plat-$(CONFIG_ARCH_S3C64XX)	+= samsung
 plat-$(CONFIG_ARCH_ZYNQ)	+= versatile
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 3fdab01..9137df5 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -33,7 +33,7 @@
 
 $(obj)/xipImage: vmlinux FORCE
 	$(call if_changed,objcopy)
-	@echo '  Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))'
+	@$(kecho) '  Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))'
 
 $(obj)/Image $(obj)/zImage: FORCE
 	@echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)'
@@ -48,14 +48,14 @@
 
 $(obj)/Image: vmlinux FORCE
 	$(call if_changed,objcopy)
-	@echo '  Kernel: $@ is ready'
+	@$(kecho) '  Kernel: $@ is ready'
 
 $(obj)/compressed/vmlinux: $(obj)/Image FORCE
 	$(Q)$(MAKE) $(build)=$(obj)/compressed $@
 
 $(obj)/zImage:	$(obj)/compressed/vmlinux FORCE
 	$(call if_changed,objcopy)
-	@echo '  Kernel: $@ is ready'
+	@$(kecho) '  Kernel: $@ is ready'
 
 endif
 
@@ -90,7 +90,7 @@
 $(obj)/uImage:	$(obj)/zImage FORCE
 	@$(check_for_multiple_loadaddr)
 	$(call if_changed,uimage)
-	@echo '  Image $@ is ready'
+	@$(kecho) '  Image $@ is ready'
 
 $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
 	$(Q)$(MAKE) $(build)=$(obj)/bootp $@
@@ -98,7 +98,7 @@
 
 $(obj)/bootpImage: $(obj)/bootp/bootp FORCE
 	$(call if_changed,objcopy)
-	@echo '  Kernel: $@ is ready'
+	@$(kecho) '  Kernel: $@ is ready'
 
 PHONY += initrd FORCE
 initrd:
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index a517153..3f9e9fe4d 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -45,11 +45,6 @@
 OBJS		+= head-shark.o ofw-shark.o
 endif
 
-ifeq ($(CONFIG_ARCH_P720T),y)
-# Borrow this code from SA1100
-OBJS		+= head-sa1100.o
-endif
-
 ifeq ($(CONFIG_ARCH_SA1100),y)
 OBJS		+= head-sa1100.o
 endif
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f37cf9f..f872edf 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -17,14 +17,17 @@
 	usb_a9263.dtb \
 	usb_a9g20.dtb
 dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
+dtb-$(CONFIG_ARCH_BCM) += bcm11351-brt.dtb
 dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \
 	dove-cubox.dtb \
 	dove-dove-db.dtb
 dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
 	exynos4210-smdkv310.dtb \
 	exynos4210-trats.dtb \
-	exynos5250-smdk5250.dtb
-dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb
+	exynos5250-smdk5250.dtb \
+	exynos5440-ssdk5440.dtb
+dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \
+	ecx-2000.dtb
 dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \
 	integratorcp.dtb
 dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
@@ -84,6 +87,8 @@
 	spear310-evb.dtb \
 	spear320-evb.dtb
 dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun4i-cubieboard.dtb \
+	sun5i-olinuxino.dtb
 dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
 	tegra20-medcom-wide.dtb \
 	tegra20-paz00.dtb \
diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
index b06c0db..e6391a4 100644
--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
@@ -126,14 +126,14 @@
 		#size-cells = <0>;
 
 		btn3 {
-			label = "Buttin 3";
+			label = "Button 3";
 			gpios = <&pioA 30 1>;
 			linux,code = <0x103>;
 			gpio-key,wakeup;
 		};
 
 		btn4 {
-			label = "Buttin 4";
+			label = "Button 4";
 			gpios = <&pioA 31 1>;
 			linux,code = <0x104>;
 			gpio-key,wakeup;
diff --git a/arch/arm/boot/dts/bcm11351-brt.dts b/arch/arm/boot/dts/bcm11351-brt.dts
new file mode 100644
index 0000000..248067c
--- /dev/null
+++ b/arch/arm/boot/dts/bcm11351-brt.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "bcm11351.dtsi"
+
+/ {
+	model = "BCM11351 BRT board";
+	compatible = "bcm,bcm11351-brt", "bcm,bcm11351";
+
+	memory {
+		reg = <0x80000000 0x40000000>; /* 1 GB */
+	};
+
+	uart@3e000000 {
+		status = "okay";
+	};
+
+};
diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi
new file mode 100644
index 0000000..ad13588
--- /dev/null
+++ b/arch/arm/boot/dts/bcm11351.dtsi
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	model = "BCM11351 SoC";
+	compatible = "bcm,bcm11351";
+	interrupt-parent = <&gic>;
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8";
+	};
+
+	gic: interrupt-controller@3ff00100 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x3ff01000 0x1000>,
+		      <0x3ff00100 0x100>;
+	};
+
+	uart@3e000000 {
+		compatible = "bcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
+		status = "disabled";
+		reg = <0x3e000000 0x1000>;
+		clock-frequency = <13000000>;
+		interrupts = <0x0 67 0x4>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+	};
+
+	L2: l2-cache {
+		    compatible = "arm,pl310-cache";
+		    reg = <0x3ff20000 0x1000>;
+		    cache-unified;
+		    cache-level = <2>;
+	};
+};
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index 7dd860f..9b72054 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -10,3 +10,18 @@
 		reg = <0 0x10000000>;
 	};
 };
+
+&gpio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&alt0 &alt3>;
+
+	alt0: alt0 {
+		brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 14 15 40 45>;
+		brcm,function = <4>; /* alt0 */
+	};
+
+	alt3: alt3 {
+		brcm,pins = <48 49 50 51 52 53>;
+		brcm,function = <7>; /* alt3 */
+	};
+};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 0b61939..8917550 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -29,11 +29,39 @@
 			#interrupt-cells = <2>;
 		};
 
+		watchdog {
+			compatible = "brcm,bcm2835-pm-wdt";
+			reg = <0x7e100000 0x28>;
+		};
+
 		uart@20201000 {
 			compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
 			reg = <0x7e201000 0x1000>;
 			interrupts = <2 25>;
 			clock-frequency = <3000000>;
 		};
+
+		gpio: gpio {
+			compatible = "brcm,bcm2835-gpio";
+			reg = <0x7e200000 0xb4>;
+			/*
+			 * The GPIO IP block is designed for 3 banks of GPIOs.
+			 * Each bank has a GPIO interrupt for itself.
+			 * There is an overall "any bank" interrupt.
+			 * In order, these are GIC interrupts 17, 18, 19, 20.
+			 * Since the BCM2835 only has 2 banks, the 2nd bank
+			 * interrupt output appears to be mirrored onto the
+			 * 3rd bank's interrupt signal.
+			 * So, a bank0 interrupt shows up on 17, 20, and
+			 * a bank1 interrupt shows up on 18, 19, 20!
+			 */
+			interrupts = <2 17>, <2 18>, <2 19>, <2 20>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 748ba7a..4b0e0ca 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -483,6 +483,8 @@
 			compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
 			reg = <0x80004000 0x1000>;
 			interrupts = <0 21 0x4>;
+			arm,primecell-periphid = <0x180024>;
+
 			#address-cells = <1>;
 			#size-cells = <0>;
 			v-i2c-supply = <&db8500_vape_reg>;
@@ -494,6 +496,8 @@
 			compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
 			reg = <0x80122000 0x1000>;
 			interrupts = <0 22 0x4>;
+			arm,primecell-periphid = <0x180024>;
+
 			#address-cells = <1>;
 			#size-cells = <0>;
 			v-i2c-supply = <&db8500_vape_reg>;
@@ -505,6 +509,8 @@
 			compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
 			reg = <0x80128000 0x1000>;
 			interrupts = <0 55 0x4>;
+			arm,primecell-periphid = <0x180024>;
+
 			#address-cells = <1>;
 			#size-cells = <0>;
 			v-i2c-supply = <&db8500_vape_reg>;
@@ -516,6 +522,8 @@
 			compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
 			reg = <0x80110000 0x1000>;
 			interrupts = <0 12 0x4>;
+			arm,primecell-periphid = <0x180024>;
+
 			#address-cells = <1>;
 			#size-cells = <0>;
 			v-i2c-supply = <&db8500_vape_reg>;
@@ -527,6 +535,8 @@
 			compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
 			reg = <0x8012a000 0x1000>;
 			interrupts = <0 51 0x4>;
+			arm,primecell-periphid = <0x180024>;
+
 			#address-cells = <1>;
 			#size-cells = <0>;
 			v-i2c-supply = <&db8500_vape_reg>;
@@ -573,33 +583,38 @@
 			interrupts = <0 60 0x4>;
 			status = "disabled";
 		};
+
 		sdi@80118000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80118000 0x1000>;
 			interrupts = <0 50 0x4>;
 			status = "disabled";
 		};
+
 		sdi@80005000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80005000 0x1000>;
 			interrupts = <0 41 0x4>;
 			status = "disabled";
 		};
+
 		sdi@80119000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80119000 0x1000>;
 			interrupts = <0 59 0x4>;
 			status = "disabled";
 		};
+
 		sdi@80114000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80114000 0x1000>;
 			interrupts = <0 99 0x4>;
 			status = "disabled";
 		};
+
 		sdi@80008000 {
 			compatible = "arm,pl18x", "arm,primecell";
-			reg = <0x80114000 0x1000>;
+			reg = <0x80008000 0x1000>;
 			interrupts = <0 100 0x4>;
 			status = "disabled";
 		};
diff --git a/arch/arm/boot/dts/ecx-2000.dts b/arch/arm/boot/dts/ecx-2000.dts
new file mode 100644
index 0000000..46477ac
--- /dev/null
+++ b/arch/arm/boot/dts/ecx-2000.dts
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2011-2012 Calxeda, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+
+/* First 4KB has pen for secondary cores. */
+/memreserve/ 0x00000000 0x0001000;
+
+/ {
+	model = "Calxeda ECX-2000";
+	compatible = "calxeda,ecx-2000";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	clock-ranges;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "arm,cortex-a15";
+			reg = <0>;
+			clocks = <&a9pll>;
+			clock-names = "cpu";
+		};
+
+		cpu@1 {
+			compatible = "arm,cortex-a15";
+			reg = <1>;
+			clocks = <&a9pll>;
+			clock-names = "cpu";
+		};
+
+		cpu@2 {
+			compatible = "arm,cortex-a15";
+			reg = <2>;
+			clocks = <&a9pll>;
+			clock-names = "cpu";
+		};
+
+		cpu@3 {
+			compatible = "arm,cortex-a15";
+			reg = <3>;
+			clocks = <&a9pll>;
+			clock-names = "cpu";
+		};
+	};
+
+	memory@0 {
+		name = "memory";
+		device_type = "memory";
+		reg = <0x00000000 0x00000000 0x00000000 0xff800000>;
+	};
+
+	memory@200000000 {
+		name = "memory";
+		device_type = "memory";
+		reg = <0x00000002 0x00000000 0x00000003 0x00000000>;
+	};
+
+	soc {
+		ranges = <0x00000000 0x00000000 0x00000000 0xffffffff>;
+
+		timer {
+			compatible = "arm,cortex-a15-timer", "arm,armv7-timer"; 			interrupts = <1 13 0xf08>,
+				<1 14 0xf08>,
+				<1 11 0xf08>,
+				<1 10 0xf08>;
+		};
+
+		intc: interrupt-controller@fff11000 {
+			compatible = "arm,cortex-a15-gic";
+			#interrupt-cells = <3>;
+			#size-cells = <0>;
+			#address-cells = <1>;
+			interrupt-controller;
+			interrupts = <1 9 0xf04>;
+			reg = <0xfff11000 0x1000>,
+			      <0xfff12000 0x1000>,
+			      <0xfff14000 0x2000>,
+			      <0xfff16000 0x2000>;
+		};
+
+		pmu {
+			compatible = "arm,cortex-a9-pmu";
+			interrupts = <0 76 4  0 75 4  0 74 4  0 73 4>;
+		};
+	};
+};
+
+/include/ "ecx-common.dtsi"
diff --git a/arch/arm/boot/dts/ecx-common.dtsi b/arch/arm/boot/dts/ecx-common.dtsi
new file mode 100644
index 0000000..d61b535
--- /dev/null
+++ b/arch/arm/boot/dts/ecx-common.dtsi
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2011-2012 Calxeda, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/ {
+	chosen {
+		bootargs = "console=ttyAMA0";
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		interrupt-parent = <&intc>;
+
+		sata@ffe08000 {
+			compatible = "calxeda,hb-ahci";
+			reg = <0xffe08000 0x10000>;
+			interrupts = <0 83 4>;
+			dma-coherent;
+			calxeda,port-phys = <&combophy5 0 &combophy0 0
+					     &combophy0 1 &combophy0 2
+					     &combophy0 3>;
+		};
+
+		sdhci@ffe0e000 {
+			compatible = "calxeda,hb-sdhci";
+			reg = <0xffe0e000 0x1000>;
+			interrupts = <0 90 4>;
+			clocks = <&eclk>;
+			status = "disabled";
+		};
+
+		memory-controller@fff00000 {
+			compatible = "calxeda,hb-ddr-ctrl";
+			reg = <0xfff00000 0x1000>;
+			interrupts = <0 91 4>;
+		};
+
+		ipc@fff20000 {
+			compatible = "arm,pl320", "arm,primecell";
+			reg = <0xfff20000 0x1000>;
+			interrupts = <0 7 4>;
+			clocks = <&pclk>;
+			clock-names = "apb_pclk";
+		};
+
+		gpioe: gpio@fff30000 {
+			#gpio-cells = <2>;
+			compatible = "arm,pl061", "arm,primecell";
+			gpio-controller;
+			reg = <0xfff30000 0x1000>;
+			interrupts = <0 14 4>;
+			clocks = <&pclk>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		gpiof: gpio@fff31000 {
+			#gpio-cells = <2>;
+			compatible = "arm,pl061", "arm,primecell";
+			gpio-controller;
+			reg = <0xfff31000 0x1000>;
+			interrupts = <0 15 4>;
+			clocks = <&pclk>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		gpiog: gpio@fff32000 {
+			#gpio-cells = <2>;
+			compatible = "arm,pl061", "arm,primecell";
+			gpio-controller;
+			reg = <0xfff32000 0x1000>;
+			interrupts = <0 16 4>;
+			clocks = <&pclk>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		gpioh: gpio@fff33000 {
+			#gpio-cells = <2>;
+			compatible = "arm,pl061", "arm,primecell";
+			gpio-controller;
+			reg = <0xfff33000 0x1000>;
+			interrupts = <0 17 4>;
+			clocks = <&pclk>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		timer@fff34000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfff34000 0x1000>;
+			interrupts = <0 18 4>;
+			clocks = <&pclk>;
+			clock-names = "apb_pclk";
+		};
+
+		rtc@fff35000 {
+			compatible = "arm,pl031", "arm,primecell";
+			reg = <0xfff35000 0x1000>;
+			interrupts = <0 19 4>;
+			clocks = <&pclk>;
+			clock-names = "apb_pclk";
+		};
+
+		serial@fff36000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xfff36000 0x1000>;
+			interrupts = <0 20 4>;
+			clocks = <&pclk>;
+			clock-names = "apb_pclk";
+		};
+
+		smic@fff3a000 {
+			compatible = "ipmi-smic";
+			device_type = "ipmi";
+			reg = <0xfff3a000 0x1000>;
+			interrupts = <0 24 4>;
+			reg-size = <4>;
+			reg-spacing = <4>;
+		};
+
+		sregs@fff3c000 {
+			compatible = "calxeda,hb-sregs";
+			reg = <0xfff3c000 0x1000>;
+
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				osc: oscillator {
+					#clock-cells = <0>;
+					compatible = "fixed-clock";
+					clock-frequency = <33333000>;
+				};
+
+				ddrpll: ddrpll {
+					#clock-cells = <0>;
+					compatible = "calxeda,hb-pll-clock";
+					clocks = <&osc>;
+					reg = <0x108>;
+				};
+
+				a9pll: a9pll {
+					#clock-cells = <0>;
+					compatible = "calxeda,hb-pll-clock";
+					clocks = <&osc>;
+					reg = <0x100>;
+				};
+
+				a9periphclk: a9periphclk {
+					#clock-cells = <0>;
+					compatible = "calxeda,hb-a9periph-clock";
+					clocks = <&a9pll>;
+					reg = <0x104>;
+				};
+
+				a9bclk: a9bclk {
+					#clock-cells = <0>;
+					compatible = "calxeda,hb-a9bus-clock";
+					clocks = <&a9pll>;
+					reg = <0x104>;
+				};
+
+				emmcpll: emmcpll {
+					#clock-cells = <0>;
+					compatible = "calxeda,hb-pll-clock";
+					clocks = <&osc>;
+					reg = <0x10C>;
+				};
+
+				eclk: eclk {
+					#clock-cells = <0>;
+					compatible = "calxeda,hb-emmc-clock";
+					clocks = <&emmcpll>;
+					reg = <0x114>;
+				};
+
+				pclk: pclk {
+					#clock-cells = <0>;
+					compatible = "fixed-clock";
+					clock-frequency = <150000000>;
+				};
+			};
+		};
+
+		dma@fff3d000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0xfff3d000 0x1000>;
+			interrupts = <0 92 4>;
+			clocks = <&pclk>;
+			clock-names = "apb_pclk";
+		};
+
+		ethernet@fff50000 {
+			compatible = "calxeda,hb-xgmac";
+			reg = <0xfff50000 0x1000>;
+			interrupts = <0 77 4  0 78 4  0 79 4>;
+			dma-coherent;
+		};
+
+		ethernet@fff51000 {
+			compatible = "calxeda,hb-xgmac";
+			reg = <0xfff51000 0x1000>;
+			interrupts = <0 80 4  0 81 4  0 82 4>;
+			dma-coherent;
+		};
+
+		combophy0: combo-phy@fff58000 {
+			compatible = "calxeda,hb-combophy";
+			#phy-cells = <1>;
+			reg = <0xfff58000 0x1000>;
+			phydev = <5>;
+		};
+
+		combophy5: combo-phy@fff5d000 {
+			compatible = "calxeda,hb-combophy";
+			#phy-cells = <1>;
+			reg = <0xfff5d000 0x1000>;
+			phydev = <31>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index a26c3dd..96d4462 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -244,5 +244,11 @@
 			reg = <0x12690000 0x1000>;
 			interrupts = <0 36 0>;
 		};
+
+		mdma1: mdma@12850000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x12850000 0x1000>;
+			interrupts = <0 34 0>;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
index b12cf27..6a4a1a0 100644
--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
@@ -16,6 +16,134 @@
 
 / {
 	pinctrl@11400000 {
+		gpa0: gpa0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpa1: gpa1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpb: gpb {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc0: gpc0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc1: gpc1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpd0: gpd0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpd1: gpd1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpe0: gpe0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpe1: gpe1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpe2: gpe2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpe3: gpe3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpe4: gpe4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf0: gpf0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf1: gpf1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf2: gpf2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf3: gpf3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
 		uart0_data: uart0-data {
 			samsung,pins = "gpa0-0", "gpa0-1";
 			samsung,pin-function = <0x2>;
@@ -205,6 +333,151 @@
 	};
 
 	pinctrl@11000000 {
+		gpj0: gpj0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpj1: gpj1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpk0: gpk0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpk1: gpk1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpk2: gpk2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpk3: gpk3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpl0: gpl0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpl1: gpl1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpl2: gpl2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpy0: gpy0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy1: gpy1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy2: gpy2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy3: gpy3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy4: gpy4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy5: gpy5 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy6: gpy6 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpx0: gpx0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			interrupt-parent = <&gic>;
+			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+			#interrupt-cells = <2>;
+		};
+
+		gpx1: gpx1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			interrupt-parent = <&gic>;
+			interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+				     <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+			#interrupt-cells = <2>;
+		};
+
+		gpx2: gpx2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpx3: gpx3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
 		sd0_clk: sd0-clk {
 			samsung,pins = "gpk0-0";
 			samsung,pin-function = <2>;
@@ -438,6 +711,11 @@
 	};
 
 	pinctrl@03860000 {
+		gpz: gpz {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
 		i2s0_bus: i2s0-bus {
 			samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
 					"gpz-4", "gpz-5", "gpz-6";
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index 73567b8..a21511c 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -20,8 +20,10 @@
 	compatible = "samsung,trats", "samsung,exynos4210";
 
 	memory {
-		reg =  <0x40000000 0x20000000
-			0x60000000 0x20000000>;
+		reg =  <0x40000000 0x10000000
+			0x50000000 0x10000000
+			0x60000000 0x10000000
+			0x70000000 0x10000000>;
 	};
 
 	chosen {
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 214c557..d877dbe 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -46,27 +46,17 @@
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11400000 0x1000>;
 		interrupts = <0 47 0>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
 	};
 
 	pinctrl_1: pinctrl@11000000 {
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11000000 0x1000>;
 		interrupts = <0 46 0>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
 
 		wakup_eint: wakeup-interrupt-controller {
 			compatible = "samsung,exynos4210-wakeup-eint";
 			interrupt-parent = <&gic>;
-			interrupt-controller;
-			#interrupt-cells = <2>;
-			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
-				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
-				     <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
-				     <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>,
-				     <0 32 0>;
+			interrupts = <0 32 0>;
 		};
 	};
 
@@ -74,233 +64,4 @@
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x03860000 0x1000>;
 	};
-
-	gpio-controllers {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		gpio-controller;
-		ranges;
-
-		gpa0: gpio-controller@11400000 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400000 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpa1: gpio-controller@11400020 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400020 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpb: gpio-controller@11400040 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400040 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpc0: gpio-controller@11400060 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400060 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpc1: gpio-controller@11400080 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400080 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpd0: gpio-controller@114000A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114000A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpd1: gpio-controller@114000C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114000C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe0: gpio-controller@114000E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114000E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe1: gpio-controller@11400100 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400100 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe2: gpio-controller@11400120 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400120 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe3: gpio-controller@11400140 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400140 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpe4: gpio-controller@11400160 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400160 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf0: gpio-controller@11400180 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11400180 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf1: gpio-controller@114001A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114001A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf2: gpio-controller@114001C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114001C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpf3: gpio-controller@114001E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x114001E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpj0: gpio-controller@11000000 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000000 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpj1: gpio-controller@11000020 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000020 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk0: gpio-controller@11000040 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000040 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk1: gpio-controller@11000060 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000060 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk2: gpio-controller@11000080 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000080 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpk3: gpio-controller@110000A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110000A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpl0: gpio-controller@110000C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110000C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpl1: gpio-controller@110000E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110000E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpl2: gpio-controller@11000100 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000100 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy0: gpio-controller@11000120 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000120 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy1: gpio-controller@11000140 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000140 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy2: gpio-controller@11000160 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000160 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy3: gpio-controller@11000180 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000180 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy4: gpio-controller@110001A0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110001A0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy5: gpio-controller@110001C0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110001C0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpy6: gpio-controller@110001E0 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x110001E0 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx0: gpio-controller@11000C00 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C00 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx1: gpio-controller@11000C20 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C20 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx2: gpio-controller@11000C40 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C40 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpx3: gpio-controller@11000C60 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x11000C60 0x20>;
-			#gpio-cells = <4>;
-		};
-
-		gpz: gpio-controller@03860000 {
-			compatible = "samsung,exynos4-gpio";
-			reg = <0x03860000 0x20>;
-			#gpio-cells = <4>;
-		};
-	};
 };
diff --git a/arch/arm/boot/dts/exynos5440-ssdk5440.dts b/arch/arm/boot/dts/exynos5440-ssdk5440.dts
new file mode 100644
index 0000000..921c83c
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5440-ssdk5440.dts
@@ -0,0 +1,46 @@
+/*
+ * SAMSUNG SSDK5440 board device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+/include/ "exynos5440.dtsi"
+
+/ {
+	model = "SAMSUNG SSDK5440 board based on EXYNOS5440";
+	compatible = "samsung,ssdk5440", "samsung,exynos5440";
+
+	memory {
+		reg = <0x80000000 0x80000000>;
+	};
+
+	chosen {
+		bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x81000000,8M console=ttySAC2,115200 init=/linuxrc";
+	};
+
+	spi {
+		status = "disabled";
+	};
+
+	i2c@F0000 {
+		status = "disabled";
+	};
+
+	i2c@100000 {
+		status = "disabled";
+	};
+
+	watchdog {
+		status = "disabled";
+	};
+
+	rtc {
+		status = "disabled";
+	};
+};
diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi
new file mode 100644
index 0000000..024269d
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5440.dtsi
@@ -0,0 +1,159 @@
+/*
+ * SAMSUNG EXYNOS5440 SoC device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "samsung,exynos5440";
+
+	interrupt-parent = <&gic>;
+
+	gic:interrupt-controller@2E0000 {
+		compatible = "arm,cortex-a15-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0x2E1000 0x1000>, <0x2E2000 0x1000>;
+	};
+
+	cpus {
+		cpu@0 {
+			compatible = "arm,cortex-a15";
+			timer {
+				compatible = "arm,armv7-timer";
+				interrupts = <1 13 0xf08>;
+				clock-frequency = <1000000>;
+			};
+		};
+		cpu@1 {
+			compatible = "arm,cortex-a15";
+			timer {
+				compatible = "arm,armv7-timer";
+				interrupts = <1 14 0xf08>;
+				clock-frequency = <1000000>;
+			};
+		};
+		cpu@2 {
+			compatible = "arm,cortex-a15";
+			timer {
+				compatible = "arm,armv7-timer";
+				interrupts = <1 14 0xf08>;
+				clock-frequency = <1000000>;
+			};
+		};
+		cpu@3 {
+			compatible = "arm,cortex-a15";
+			timer {
+				compatible = "arm,armv7-timer";
+				interrupts = <1 14 0xf08>;
+				clock-frequency = <1000000>;
+			};
+		};
+	};
+
+	common {
+		compatible = "samsung,exynos5440";
+
+	};
+
+	serial@B0000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0xB0000 0x1000>;
+		interrupts = <0 2 0>;
+	};
+
+	serial@C0000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0xC0000 0x1000>;
+		interrupts = <0 3 0>;
+	};
+
+	spi {
+		compatible = "samsung,exynos4210-spi";
+		reg = <0xD0000 0x1000>;
+		interrupts = <0 4 0>;
+		tx-dma-channel = <&pdma0 5>; /* preliminary */
+		rx-dma-channel = <&pdma0 4>; /* preliminary */
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	pinctrl {
+		compatible = "samsung,pinctrl-exynos5440";
+		reg = <0xE0000 0x1000>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		#gpio-cells = <2>;
+
+		fan: fan {
+			samsung,exynos5440-pin-function = <1>;
+		};
+
+		hdd_led0: hdd_led0 {
+			samsung,exynos5440-pin-function = <2>;
+		};
+
+		hdd_led1: hdd_led1 {
+			samsung,exynos5440-pin-function = <3>;
+		};
+
+		uart1: uart1 {
+			samsung,exynos5440-pin-function = <4>;
+		};
+	};
+
+	i2c@F0000 {
+		compatible = "samsung,s3c2440-i2c";
+		reg = <0xF0000 0x1000>;
+		interrupts = <0 5 0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	i2c@100000 {
+		compatible = "samsung,s3c2440-i2c";
+		reg = <0x100000 0x1000>;
+		interrupts = <0 6 0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	watchdog {
+		compatible = "samsung,s3c2410-wdt";
+		reg = <0x110000 0x1000>;
+		interrupts = <0 1 0>;
+	};
+
+	amba {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "arm,amba-bus";
+		interrupt-parent = <&gic>;
+		ranges;
+
+		pdma0: pdma@121A0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x120000 0x1000>;
+			interrupts = <0 34 0>;
+		};
+
+		pdma1: pdma@121B0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x121000 0x1000>;
+			interrupts = <0 35 0>;
+		};
+	};
+
+	rtc {
+		compatible = "samsung,s3c6410-rtc";
+		reg = <0x130000 0x1000>;
+		interrupts = <0 16 0>, <0 17 0>;
+	};
+};
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
index 0c6fc34..a9ae5d3 100644
--- a/arch/arm/boot/dts/highbank.dts
+++ b/arch/arm/boot/dts/highbank.dts
@@ -69,16 +69,8 @@
 		reg = <0x00000000 0xff900000>;
 	};
 
-	chosen {
-		bootargs = "console=ttyAMA0";
-	};
-
 	soc {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		compatible = "simple-bus";
-		interrupt-parent = <&intc>;
-		ranges;
+		ranges = <0x00000000 0x00000000 0xffffffff>;
 
 		timer@fff10600 {
 			compatible = "arm,cortex-a9-twd-timer";
@@ -117,173 +109,6 @@
 			interrupts = <0 76 4  0 75 4  0 74 4  0 73 4>;
 		};
 
-		sata@ffe08000 {
-			compatible = "calxeda,hb-ahci";
-			reg = <0xffe08000 0x10000>;
-			interrupts = <0 83 4>;
-			calxeda,port-phys = <&combophy5 0 &combophy0 0
-					     &combophy0 1 &combophy0 2
-					     &combophy0 3>;
-			dma-coherent;
-		};
-
-		sdhci@ffe0e000 {
-			compatible = "calxeda,hb-sdhci";
-			reg = <0xffe0e000 0x1000>;
-			interrupts = <0 90 4>;
-			clocks = <&eclk>;
-		};
-
-		memory-controller@fff00000 {
-			compatible = "calxeda,hb-ddr-ctrl";
-			reg = <0xfff00000 0x1000>;
-			interrupts = <0 91 4>;
-		};
-
-		ipc@fff20000 {
-			compatible = "arm,pl320", "arm,primecell";
-			reg = <0xfff20000 0x1000>;
-			interrupts = <0 7 4>;
-			clocks = <&pclk>;
-			clock-names = "apb_pclk";
-		};
-
-		gpioe: gpio@fff30000 {
-			#gpio-cells = <2>;
-			compatible = "arm,pl061", "arm,primecell";
-			gpio-controller;
-			reg = <0xfff30000 0x1000>;
-			interrupts = <0 14 4>;
-			clocks = <&pclk>;
-			clock-names = "apb_pclk";
-		};
-
-		gpiof: gpio@fff31000 {
-			#gpio-cells = <2>;
-			compatible = "arm,pl061", "arm,primecell";
-			gpio-controller;
-			reg = <0xfff31000 0x1000>;
-			interrupts = <0 15 4>;
-			clocks = <&pclk>;
-			clock-names = "apb_pclk";
-		};
-
-		gpiog: gpio@fff32000 {
-			#gpio-cells = <2>;
-			compatible = "arm,pl061", "arm,primecell";
-			gpio-controller;
-			reg = <0xfff32000 0x1000>;
-			interrupts = <0 16 4>;
-			clocks = <&pclk>;
-			clock-names = "apb_pclk";
-		};
-
-		gpioh: gpio@fff33000 {
-			#gpio-cells = <2>;
-			compatible = "arm,pl061", "arm,primecell";
-			gpio-controller;
-			reg = <0xfff33000 0x1000>;
-			interrupts = <0 17 4>;
-			clocks = <&pclk>;
-			clock-names = "apb_pclk";
-		};
-
-		timer {
-			compatible = "arm,sp804", "arm,primecell";
-			reg = <0xfff34000 0x1000>;
-			interrupts = <0 18 4>;
-			clocks = <&pclk>;
-			clock-names = "apb_pclk";
-		};
-
-		rtc@fff35000 {
-			compatible = "arm,pl031", "arm,primecell";
-			reg = <0xfff35000 0x1000>;
-			interrupts = <0 19 4>;
-			clocks = <&pclk>;
-			clock-names = "apb_pclk";
-		};
-
-		serial@fff36000 {
-			compatible = "arm,pl011", "arm,primecell";
-			reg = <0xfff36000 0x1000>;
-			interrupts = <0 20 4>;
-			clocks = <&pclk>;
-			clock-names = "apb_pclk";
-		};
-
-		smic@fff3a000 {
-			compatible = "ipmi-smic";
-			device_type = "ipmi";
-			reg = <0xfff3a000 0x1000>;
-			interrupts = <0 24 4>;
-			reg-size = <4>;
-			reg-spacing = <4>;
-		};
-
-		sregs@fff3c000 {
-			compatible = "calxeda,hb-sregs";
-			reg = <0xfff3c000 0x1000>;
-
-			clocks {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				osc: oscillator {
-					#clock-cells = <0>;
-					compatible = "fixed-clock";
-					clock-frequency = <33333000>;
-				};
-
-				ddrpll: ddrpll {
-					#clock-cells = <0>;
-					compatible = "calxeda,hb-pll-clock";
-					clocks = <&osc>;
-					reg = <0x108>;
-				};
-
-				a9pll: a9pll {
-					#clock-cells = <0>;
-					compatible = "calxeda,hb-pll-clock";
-					clocks = <&osc>;
-					reg = <0x100>;
-				};
-
-				a9periphclk: a9periphclk {
-					#clock-cells = <0>;
-					compatible = "calxeda,hb-a9periph-clock";
-					clocks = <&a9pll>;
-					reg = <0x104>;
-				};
-
-				a9bclk: a9bclk {
-					#clock-cells = <0>;
-					compatible = "calxeda,hb-a9bus-clock";
-					clocks = <&a9pll>;
-					reg = <0x104>;
-				};
-
-				emmcpll: emmcpll {
-					#clock-cells = <0>;
-					compatible = "calxeda,hb-pll-clock";
-					clocks = <&osc>;
-					reg = <0x10C>;
-				};
-
-				eclk: eclk {
-					#clock-cells = <0>;
-					compatible = "calxeda,hb-emmc-clock";
-					clocks = <&emmcpll>;
-					reg = <0x114>;
-				};
-
-				pclk: pclk {
-					#clock-cells = <0>;
-					compatible = "fixed-clock";
-					clock-frequency = <150000000>;
-				};
-			};
-		};
 
 		sregs@fff3c200 {
 			compatible = "calxeda,hb-sregs-l2-ecc";
@@ -291,38 +116,7 @@
 			interrupts = <0 71 4  0 72 4>;
 		};
 
-		dma@fff3d000 {
-			compatible = "arm,pl330", "arm,primecell";
-			reg = <0xfff3d000 0x1000>;
-			interrupts = <0 92 4>;
-			clocks = <&pclk>;
-			clock-names = "apb_pclk";
-		};
-
-		ethernet@fff50000 {
-			compatible = "calxeda,hb-xgmac";
-			reg = <0xfff50000 0x1000>;
-			interrupts = <0 77 4  0 78 4  0 79 4>;
-		};
-
-		ethernet@fff51000 {
-			compatible = "calxeda,hb-xgmac";
-			reg = <0xfff51000 0x1000>;
-			interrupts = <0 80 4  0 81 4  0 82 4>;
-		};
-
-		combophy0: combo-phy@fff58000 {
-			compatible = "calxeda,hb-combophy";
-			#phy-cells = <1>;
-			reg = <0xfff58000 0x1000>;
-			phydev = <5>;
-		};
-
-		combophy5: combo-phy@fff5d000 {
-			compatible = "calxeda,hb-combophy";
-			#phy-cells = <1>;
-			reg = <0xfff5d000 0x1000>;
-			phydev = <31>;
-		};
 	};
 };
+
+/include/ "ecx-common.dtsi"
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index 9ca4ca7..6d31aa3 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -69,6 +69,7 @@
 				interrupts = <13>, <56>;
 				interrupt-names = "gpmi-dma", "bch";
 				clocks = <&clks 34>;
+				clock-names = "gpmi_io";
 				fsl,gpmi-dma-channel = <4>;
 				status = "disabled";
 			};
diff --git a/arch/arm/boot/dts/imx27-3ds.dts b/arch/arm/boot/dts/imx27-3ds.dts
index 0a8978a..b01c0d7 100644
--- a/arch/arm/boot/dts/imx27-3ds.dts
+++ b/arch/arm/boot/dts/imx27-3ds.dts
@@ -23,10 +23,6 @@
 	soc {
 		aipi@10000000 { /* aipi */
 
-			wdog@10002000 {
-				status = "okay";
-			};
-
 			uart1: serial@1000a000 {
 				fsl,uart-has-rtscts;
 				status = "okay";
diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi
index 3e54f14..67d6727 100644
--- a/arch/arm/boot/dts/imx27.dtsi
+++ b/arch/arm/boot/dts/imx27.dtsi
@@ -113,7 +113,7 @@
 			i2c1: i2c@10012000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx27-i2c", "fsl,imx1-i2c";
+				compatible = "fsl,imx27-i2c", "fsl,imx21-i2c";
 				reg = <0x10012000 0x1000>;
 				interrupts = <12>;
 				status = "disabled";
@@ -205,7 +205,7 @@
 			i2c2: i2c@1001d000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx27-i2c", "fsl,imx1-i2c";
+				compatible = "fsl,imx27-i2c", "fsl,imx21-i2c";
 				reg = <0x1001d000 0x1000>;
 				interrupts = <1>;
 				status = "disabled";
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index e16d631..55c57ea 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -85,6 +85,7 @@
 				interrupts = <88>, <41>;
 				interrupt-names = "gpmi-dma", "bch";
 				clocks = <&clks 50>;
+				clock-names = "gpmi_io";
 				fsl,gpmi-dma-channel = <4>;
 				status = "disabled";
 			};
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
index cbd2b1c..567e7ee 100644
--- a/arch/arm/boot/dts/imx51-babbage.dts
+++ b/arch/arm/boot/dts/imx51-babbage.dts
@@ -22,6 +22,22 @@
 	};
 
 	soc {
+		display@di0 {
+			compatible = "fsl,imx-parallel-display";
+			crtcs = <&ipu 0>;
+			interface-pix-fmt = "rgb24";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_ipu_disp1_1>;
+		};
+
+		display@di1 {
+			compatible = "fsl,imx-parallel-display";
+			crtcs = <&ipu 1>;
+			interface-pix-fmt = "rgb565";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_ipu_disp2_1>;
+		};
+
 		aips@70000000 { /* aips-1 */
 			spba@70000000 {
 				esdhc@70004000 { /* ESDHC1 */
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 75d069f..2781e47 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -62,6 +62,13 @@
 		interrupt-parent = <&tzic>;
 		ranges;
 
+		ipu: ipu@40000000 {
+			#crtc-cells = <1>;
+			compatible = "fsl,imx51-ipu";
+			reg = <0x40000000 0x20000000>;
+			interrupts = <11 10>;
+		};
+
 		aips@70000000 { /* AIPS1 */
 			compatible = "fsl,aips-bus", "simple-bus";
 			#address-cells = <1>;
@@ -80,6 +87,8 @@
 					compatible = "fsl,imx51-esdhc";
 					reg = <0x70004000 0x4000>;
 					interrupts = <1>;
+					clocks = <&clks 44>, <&clks 0>, <&clks 71>;
+					clock-names = "ipg", "ahb", "per";
 					status = "disabled";
 				};
 
@@ -87,6 +96,8 @@
 					compatible = "fsl,imx51-esdhc";
 					reg = <0x70008000 0x4000>;
 					interrupts = <2>;
+					clocks = <&clks 45>, <&clks 0>, <&clks 72>;
+					clock-names = "ipg", "ahb", "per";
 					status = "disabled";
 				};
 
@@ -94,6 +105,8 @@
 					compatible = "fsl,imx51-uart", "fsl,imx21-uart";
 					reg = <0x7000c000 0x4000>;
 					interrupts = <33>;
+					clocks = <&clks 32>, <&clks 33>;
+					clock-names = "ipg", "per";
 					status = "disabled";
 				};
 
@@ -103,6 +116,8 @@
 					compatible = "fsl,imx51-ecspi";
 					reg = <0x70010000 0x4000>;
 					interrupts = <36>;
+					clocks = <&clks 51>, <&clks 52>;
+					clock-names = "ipg", "per";
 					status = "disabled";
 				};
 
@@ -110,6 +125,7 @@
 					compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
 					reg = <0x70014000 0x4000>;
 					interrupts = <30>;
+					clocks = <&clks 49>;
 					fsl,fifo-depth = <15>;
 					fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
 					status = "disabled";
@@ -119,6 +135,8 @@
 					compatible = "fsl,imx51-esdhc";
 					reg = <0x70020000 0x4000>;
 					interrupts = <3>;
+					clocks = <&clks 46>, <&clks 0>, <&clks 73>;
+					clock-names = "ipg", "ahb", "per";
 					status = "disabled";
 				};
 
@@ -126,6 +144,8 @@
 					compatible = "fsl,imx51-esdhc";
 					reg = <0x70024000 0x4000>;
 					interrupts = <4>;
+					clocks = <&clks 47>, <&clks 0>, <&clks 74>;
+					clock-names = "ipg", "ahb", "per";
 					status = "disabled";
 				};
 			};
@@ -202,12 +222,14 @@
 				compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
 				reg = <0x73f98000 0x4000>;
 				interrupts = <58>;
+				clocks = <&clks 0>;
 			};
 
 			wdog@73f9c000 { /* WDOG2 */
 				compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
 				reg = <0x73f9c000 0x4000>;
 				interrupts = <59>;
+				clocks = <&clks 0>;
 				status = "disabled";
 			};
 
@@ -295,6 +317,66 @@
 					};
 				};
 
+				ipu_disp1 {
+					pinctrl_ipu_disp1_1: ipudisp1grp-1 {
+						fsl,pins = <
+							528 0x5 /* MX51_PAD_DISP1_DAT0__DISP1_DAT0 */
+							529 0x5 /* MX51_PAD_DISP1_DAT1__DISP1_DAT1 */
+							530 0x5 /* MX51_PAD_DISP1_DAT2__DISP1_DAT2 */
+							531 0x5 /* MX51_PAD_DISP1_DAT3__DISP1_DAT3 */
+							532 0x5 /* MX51_PAD_DISP1_DAT4__DISP1_DAT4 */
+							533 0x5 /* MX51_PAD_DISP1_DAT5__DISP1_DAT5 */
+							535 0x5 /* MX51_PAD_DISP1_DAT6__DISP1_DAT6 */
+							537 0x5 /* MX51_PAD_DISP1_DAT7__DISP1_DAT7 */
+							539 0x5 /* MX51_PAD_DISP1_DAT8__DISP1_DAT8 */
+							541 0x5 /* MX51_PAD_DISP1_DAT9__DISP1_DAT9 */
+							543 0x5 /* MX51_PAD_DISP1_DAT10__DISP1_DAT10 */
+							545 0x5 /* MX51_PAD_DISP1_DAT11__DISP1_DAT11 */
+							547 0x5 /* MX51_PAD_DISP1_DAT12__DISP1_DAT12 */
+							549 0x5 /* MX51_PAD_DISP1_DAT13__DISP1_DAT13 */
+							551 0x5 /* MX51_PAD_DISP1_DAT14__DISP1_DAT14 */
+							553 0x5 /* MX51_PAD_DISP1_DAT15__DISP1_DAT15 */
+							555 0x5 /* MX51_PAD_DISP1_DAT16__DISP1_DAT16 */
+							557 0x5 /* MX51_PAD_DISP1_DAT17__DISP1_DAT17 */
+							559 0x5 /* MX51_PAD_DISP1_DAT18__DISP1_DAT18 */
+							563 0x5 /* MX51_PAD_DISP1_DAT19__DISP1_DAT19 */
+							567 0x5 /* MX51_PAD_DISP1_DAT20__DISP1_DAT20 */
+							571 0x5 /* MX51_PAD_DISP1_DAT21__DISP1_DAT21 */
+							575 0x5 /* MX51_PAD_DISP1_DAT22__DISP1_DAT22 */
+							579 0x5 /* MX51_PAD_DISP1_DAT23__DISP1_DAT23 */
+							584 0x5 /* MX51_PAD_DI1_PIN2__DI1_PIN2 (hsync) */
+							583 0x5 /* MX51_PAD_DI1_PIN3__DI1_PIN3 (vsync) */
+						>;
+					};
+				};
+
+				ipu_disp2 {
+					pinctrl_ipu_disp2_1: ipudisp2grp-1 {
+						fsl,pins = <
+							603 0x5 /* MX51_PAD_DISP2_DAT0__DISP2_DAT0 */
+							608 0x5 /* MX51_PAD_DISP2_DAT1__DISP2_DAT1 */
+							613 0x5 /* MX51_PAD_DISP2_DAT2__DISP2_DAT2 */
+							614 0x5 /* MX51_PAD_DISP2_DAT3__DISP2_DAT3 */
+							615 0x5 /* MX51_PAD_DISP2_DAT4__DISP2_DAT4 */
+							616 0x5 /* MX51_PAD_DISP2_DAT5__DISP2_DAT5 */
+							617 0x5 /* MX51_PAD_DISP2_DAT6__DISP2_DAT6 */
+							622 0x5 /* MX51_PAD_DISP2_DAT7__DISP2_DAT7 */
+							627 0x5 /* MX51_PAD_DISP2_DAT8__DISP2_DAT8 */
+							633 0x5 /* MX51_PAD_DISP2_DAT9__DISP2_DAT9 */
+							637 0x5 /* MX51_PAD_DISP2_DAT10__DISP2_DAT10 */
+							643 0x5 /* MX51_PAD_DISP2_DAT11__DISP2_DAT11 */
+							648 0x5 /* MX51_PAD_DISP2_DAT12__DISP2_DAT12 */
+							652 0x5 /* MX51_PAD_DISP2_DAT13__DISP2_DAT13 */
+							656 0x5 /* MX51_PAD_DISP2_DAT14__DISP2_DAT14 */
+							661 0x5 /* MX51_PAD_DISP2_DAT15__DISP2_DAT15 */
+							593 0x5 /* MX51_PAD_DI2_PIN2__DI2_PIN2 (hsync) */
+							595 0x5 /* MX51_PAD_DI2_PIN3__DI2_PIN3 (vsync) */
+							597 0x5 /* MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK */
+							599 0x5 /* MX51_PAD_DI_GP4__DI2_PIN15 */
+						>;
+					};
+				};
+
 				uart1 {
 					pinctrl_uart1_1: uart1grp-1 {
 						fsl,pins = <
@@ -327,10 +409,30 @@
 				};
 			};
 
+			pwm1: pwm@73fb4000 {
+				#pwm-cells = <2>;
+				compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
+				reg = <0x73fb4000 0x4000>;
+				clocks = <&clks 37>, <&clks 38>;
+				clock-names = "ipg", "per";
+				interrupts = <61>;
+			};
+
+			pwm2: pwm@73fb8000 {
+				#pwm-cells = <2>;
+				compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
+				reg = <0x73fb8000 0x4000>;
+				clocks = <&clks 39>, <&clks 40>;
+				clock-names = "ipg", "per";
+				interrupts = <94>;
+			};
+
 			uart1: serial@73fbc000 {
 				compatible = "fsl,imx51-uart", "fsl,imx21-uart";
 				reg = <0x73fbc000 0x4000>;
 				interrupts = <31>;
+				clocks = <&clks 28>, <&clks 29>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
 
@@ -338,8 +440,17 @@
 				compatible = "fsl,imx51-uart", "fsl,imx21-uart";
 				reg = <0x73fc0000 0x4000>;
 				interrupts = <32>;
+				clocks = <&clks 30>, <&clks 31>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
+
+			clks: ccm@73fd4000{
+				compatible = "fsl,imx51-ccm";
+				reg = <0x73fd4000 0x4000>;
+				interrupts = <0 71 0x04 0 72 0x04>;
+				#clock-cells = <1>;
+			};
 		};
 
 		aips@80000000 {	/* AIPS2 */
@@ -355,6 +466,8 @@
 				compatible = "fsl,imx51-ecspi";
 				reg = <0x83fac000 0x4000>;
 				interrupts = <37>;
+				clocks = <&clks 53>, <&clks 54>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
 
@@ -362,6 +475,8 @@
 				compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
 				reg = <0x83fb0000 0x4000>;
 				interrupts = <6>;
+				clocks = <&clks 56>, <&clks 56>;
+				clock-names = "ipg", "ahb";
 				fsl,sdma-ram-script-name = "imx/sdma/sdma-imx51.bin";
 			};
 
@@ -371,24 +486,28 @@
 				compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
 				reg = <0x83fc0000 0x4000>;
 				interrupts = <38>;
+				clocks = <&clks 55>, <&clks 0>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
 
 			i2c@83fc4000 { /* I2C2 */
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx51-i2c", "fsl,imx1-i2c";
+				compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
 				reg = <0x83fc4000 0x4000>;
 				interrupts = <63>;
+				clocks = <&clks 35>;
 				status = "disabled";
 			};
 
 			i2c@83fc8000 { /* I2C1 */
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx51-i2c", "fsl,imx1-i2c";
+				compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
 				reg = <0x83fc8000 0x4000>;
 				interrupts = <62>;
+				clocks = <&clks 34>;
 				status = "disabled";
 			};
 
@@ -396,6 +515,7 @@
 				compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
 				reg = <0x83fcc000 0x4000>;
 				interrupts = <29>;
+				clocks = <&clks 48>;
 				fsl,fifo-depth = <15>;
 				fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
 				status = "disabled";
@@ -411,6 +531,7 @@
 				compatible = "fsl,imx51-nand";
 				reg = <0x83fdb000 0x1000 0xcfff0000 0x10000>;
 				interrupts = <8>;
+				clocks = <&clks 60>;
 				status = "disabled";
 			};
 
@@ -418,6 +539,7 @@
 				compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
 				reg = <0x83fe8000 0x4000>;
 				interrupts = <96>;
+				clocks = <&clks 50>;
 				fsl,fifo-depth = <15>;
 				fsl,ssi-dma-events = <47 46 37 35>; /* TX0 RX0 TX1 RX1 */
 				status = "disabled";
@@ -427,6 +549,8 @@
 				compatible = "fsl,imx51-fec", "fsl,imx27-fec";
 				reg = <0x83fec000 0x4000>;
 				interrupts = <87>;
+				clocks = <&clks 42>, <&clks 42>, <&clks 42>;
+				clock-names = "ipg", "ahb", "ptp";
 				status = "disabled";
 			};
 		};
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 76ebb1a..da9a047 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -67,6 +67,13 @@
 		interrupt-parent = <&tzic>;
 		ranges;
 
+		ipu: ipu@18000000 {
+			#crtc-cells = <1>;
+			compatible = "fsl,imx53-ipu";
+			reg = <0x18000000 0x080000000>;
+			interrupts = <11 10>;
+		};
+
 		aips@50000000 { /* AIPS1 */
 			compatible = "fsl,aips-bus", "simple-bus";
 			#address-cells = <1>;
@@ -85,6 +92,8 @@
 					compatible = "fsl,imx53-esdhc";
 					reg = <0x50004000 0x4000>;
 					interrupts = <1>;
+					clocks = <&clks 44>, <&clks 0>, <&clks 71>;
+					clock-names = "ipg", "ahb", "per";
 					status = "disabled";
 				};
 
@@ -92,6 +101,8 @@
 					compatible = "fsl,imx53-esdhc";
 					reg = <0x50008000 0x4000>;
 					interrupts = <2>;
+					clocks = <&clks 45>, <&clks 0>, <&clks 72>;
+					clock-names = "ipg", "ahb", "per";
 					status = "disabled";
 				};
 
@@ -99,6 +110,8 @@
 					compatible = "fsl,imx53-uart", "fsl,imx21-uart";
 					reg = <0x5000c000 0x4000>;
 					interrupts = <33>;
+					clocks = <&clks 32>, <&clks 33>;
+					clock-names = "ipg", "per";
 					status = "disabled";
 				};
 
@@ -108,6 +121,8 @@
 					compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
 					reg = <0x50010000 0x4000>;
 					interrupts = <36>;
+					clocks = <&clks 51>, <&clks 52>;
+					clock-names = "ipg", "per";
 					status = "disabled";
 				};
 
@@ -115,6 +130,7 @@
 					compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
 					reg = <0x50014000 0x4000>;
 					interrupts = <30>;
+					clocks = <&clks 49>;
 					fsl,fifo-depth = <15>;
 					fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
 					status = "disabled";
@@ -124,6 +140,8 @@
 					compatible = "fsl,imx53-esdhc";
 					reg = <0x50020000 0x4000>;
 					interrupts = <3>;
+					clocks = <&clks 46>, <&clks 0>, <&clks 73>;
+					clock-names = "ipg", "ahb", "per";
 					status = "disabled";
 				};
 
@@ -131,6 +149,8 @@
 					compatible = "fsl,imx53-esdhc";
 					reg = <0x50024000 0x4000>;
 					interrupts = <4>;
+					clocks = <&clks 47>, <&clks 0>, <&clks 74>;
+					clock-names = "ipg", "ahb", "per";
 					status = "disabled";
 				};
 			};
@@ -207,12 +227,14 @@
 				compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
 				reg = <0x53f98000 0x4000>;
 				interrupts = <58>;
+				clocks = <&clks 0>;
 			};
 
 			wdog@53f9c000 { /* WDOG2 */
 				compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
 				reg = <0x53f9c000 0x4000>;
 				interrupts = <59>;
+				clocks = <&clks 0>;
 				status = "disabled";
 			};
 
@@ -371,10 +393,30 @@
 				};
 			};
 
+			pwm1: pwm@53fb4000 {
+				#pwm-cells = <2>;
+				compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
+				reg = <0x53fb4000 0x4000>;
+				clocks = <&clks 37>, <&clks 38>;
+				clock-names = "ipg", "per";
+				interrupts = <61>;
+			};
+
+			pwm2: pwm@53fb8000 {
+				#pwm-cells = <2>;
+				compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
+				reg = <0x53fb8000 0x4000>;
+				clocks = <&clks 39>, <&clks 40>;
+				clock-names = "ipg", "per";
+				interrupts = <94>;
+			};
+
 			uart1: serial@53fbc000 {
 				compatible = "fsl,imx53-uart", "fsl,imx21-uart";
 				reg = <0x53fbc000 0x4000>;
 				interrupts = <31>;
+				clocks = <&clks 28>, <&clks 29>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
 
@@ -382,6 +424,8 @@
 				compatible = "fsl,imx53-uart", "fsl,imx21-uart";
 				reg = <0x53fc0000 0x4000>;
 				interrupts = <32>;
+				clocks = <&clks 30>, <&clks 31>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
 
@@ -389,6 +433,8 @@
 				compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
 				reg = <0x53fc8000 0x4000>;
 				interrupts = <82>;
+				clocks = <&clks 158>, <&clks 157>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
 
@@ -396,9 +442,18 @@
 				compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
 				reg = <0x53fcc000 0x4000>;
 				interrupts = <83>;
+				clocks = <&clks 158>, <&clks 157>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
 
+			clks: ccm@53fd4000{
+				compatible = "fsl,imx53-ccm";
+				reg = <0x53fd4000 0x4000>;
+				interrupts = <0 71 0x04 0 72 0x04>;
+				#clock-cells = <1>;
+			};
+
 			gpio5: gpio@53fdc000 {
 				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53fdc000 0x4000>;
@@ -432,9 +487,10 @@
 			i2c@53fec000 { /* I2C3 */
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx53-i2c", "fsl,imx1-i2c";
+				compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
 				reg = <0x53fec000 0x4000>;
 				interrupts = <64>;
+				clocks = <&clks 88>;
 				status = "disabled";
 			};
 
@@ -442,6 +498,8 @@
 				compatible = "fsl,imx53-uart", "fsl,imx21-uart";
 				reg = <0x53ff0000 0x4000>;
 				interrupts = <13>;
+				clocks = <&clks 65>, <&clks 66>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
 		};
@@ -457,6 +515,8 @@
 				compatible = "fsl,imx53-uart", "fsl,imx21-uart";
 				reg = <0x63f90000 0x4000>;
 				interrupts = <86>;
+				clocks = <&clks 67>, <&clks 68>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
 
@@ -466,6 +526,8 @@
 				compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
 				reg = <0x63fac000 0x4000>;
 				interrupts = <37>;
+				clocks = <&clks 53>, <&clks 54>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
 
@@ -473,6 +535,8 @@
 				compatible = "fsl,imx53-sdma", "fsl,imx35-sdma";
 				reg = <0x63fb0000 0x4000>;
 				interrupts = <6>;
+				clocks = <&clks 56>, <&clks 56>;
+				clock-names = "ipg", "ahb";
 				fsl,sdma-ram-script-name = "imx/sdma/sdma-imx53.bin";
 			};
 
@@ -482,24 +546,28 @@
 				compatible = "fsl,imx53-cspi", "fsl,imx35-cspi";
 				reg = <0x63fc0000 0x4000>;
 				interrupts = <38>;
+				clocks = <&clks 55>, <&clks 0>;
+				clock-names = "ipg", "per";
 				status = "disabled";
 			};
 
 			i2c@63fc4000 { /* I2C2 */
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx53-i2c", "fsl,imx1-i2c";
+				compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
 				reg = <0x63fc4000 0x4000>;
 				interrupts = <63>;
+				clocks = <&clks 35>;
 				status = "disabled";
 			};
 
 			i2c@63fc8000 { /* I2C1 */
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx53-i2c", "fsl,imx1-i2c";
+				compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
 				reg = <0x63fc8000 0x4000>;
 				interrupts = <62>;
+				clocks = <&clks 34>;
 				status = "disabled";
 			};
 
@@ -507,6 +575,7 @@
 				compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
 				reg = <0x63fcc000 0x4000>;
 				interrupts = <29>;
+				clocks = <&clks 48>;
 				fsl,fifo-depth = <15>;
 				fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
 				status = "disabled";
@@ -522,6 +591,7 @@
 				compatible = "fsl,imx53-nand";
 				reg = <0x63fdb000 0x1000 0xf7ff0000 0x10000>;
 				interrupts = <8>;
+				clocks = <&clks 60>;
 				status = "disabled";
 			};
 
@@ -529,6 +599,7 @@
 				compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
 				reg = <0x63fe8000 0x4000>;
 				interrupts = <96>;
+				clocks = <&clks 50>;
 				fsl,fifo-depth = <15>;
 				fsl,ssi-dma-events = <47 46 45 44>; /* TX0 RX0 TX1 RX1 */
 				status = "disabled";
@@ -538,6 +609,8 @@
 				compatible = "fsl,imx53-fec", "fsl,imx25-fec";
 				reg = <0x63fec000 0x4000>;
 				interrupts = <87>;
+				clocks = <&clks 42>, <&clks 42>, <&clks 42>;
+				clock-names = "ipg", "ahb", "ptp";
 				status = "disabled";
 			};
 		};
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index f3990b0..d907d06 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -268,23 +268,39 @@
 			};
 
 			pwm@02080000 { /* PWM1 */
+				#pwm-cells = <2>;
+				compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
 				reg = <0x02080000 0x4000>;
 				interrupts = <0 83 0x04>;
+				clocks = <&clks 62>, <&clks 145>;
+				clock-names = "ipg", "per";
 			};
 
 			pwm@02084000 { /* PWM2 */
+				#pwm-cells = <2>;
+				compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
 				reg = <0x02084000 0x4000>;
 				interrupts = <0 84 0x04>;
+				clocks = <&clks 62>, <&clks 146>;
+				clock-names = "ipg", "per";
 			};
 
 			pwm@02088000 { /* PWM3 */
+				#pwm-cells = <2>;
+				compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
 				reg = <0x02088000 0x4000>;
 				interrupts = <0 85 0x04>;
+				clocks = <&clks 62>, <&clks 147>;
+				clock-names = "ipg", "per";
 			};
 
 			pwm@0208c000 { /* PWM4 */
+				#pwm-cells = <2>;
+				compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
 				reg = <0x0208c000 0x4000>;
 				interrupts = <0 86 0x04>;
+				clocks = <&clks 62>, <&clks 148>;
+				clock-names = "ipg", "per";
 			};
 
 			flexcan@02090000 { /* CAN1 */
@@ -882,7 +898,7 @@
 			i2c@021a0000 { /* I2C1 */
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
+				compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
 				reg = <0x021a0000 0x4000>;
 				interrupts = <0 36 0x04>;
 				clocks = <&clks 125>;
@@ -892,7 +908,7 @@
 			i2c@021a4000 { /* I2C2 */
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
+				compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
 				reg = <0x021a4000 0x4000>;
 				interrupts = <0 37 0x04>;
 				clocks = <&clks 126>;
@@ -902,7 +918,7 @@
 			i2c@021a8000 { /* I2C3 */
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
+				compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
 				reg = <0x021a8000 0x4000>;
 				interrupts = <0 38 0x04>;
 				clocks = <&clks 127>;
@@ -1001,5 +1017,23 @@
 				status = "disabled";
 			};
 		};
+
+		ipu1: ipu@02400000 {
+			#crtc-cells = <1>;
+			compatible = "fsl,imx6q-ipu";
+			reg = <0x02400000 0x400000>;
+			interrupts = <0 6 0x4 0 5 0x4>;
+			clocks = <&clks 130>, <&clks 131>, <&clks 132>;
+			clock-names = "bus", "di0", "di1";
+		};
+
+		ipu2: ipu@02800000 {
+			#crtc-cells = <1>;
+			compatible = "fsl,imx6q-ipu";
+			reg = <0x02800000 0x400000>;
+			interrupts = <0 8 0x4 0 7 0x4>;
+			clocks = <&clks 133>, <&clks 134>, <&clks 137>;
+			clock-names = "bus", "di0", "di1";
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index f38ea87..696e929 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -257,7 +257,7 @@
 			interrupt-names = "common", "tx", "rx", "sidetone";
 			interrupt-parent = <&intc>;
 			ti,buffer-size = <1280>;
-			ti,hwmods = "mcbsp2";
+			ti,hwmods = "mcbsp2", "mcbsp2_sidetone";
 		};
 
 		mcbsp3: mcbsp@49024000 {
@@ -272,7 +272,7 @@
 			interrupt-names = "common", "tx", "rx", "sidetone";
 			interrupt-parent = <&intc>;
 			ti,buffer-size = <128>;
-			ti,hwmods = "mcbsp3";
+			ti,hwmods = "mcbsp3", "mcbsp3_sidetone";
 		};
 
 		mcbsp4: mcbsp@49026000 {
diff --git a/arch/arm/boot/dts/sh7377.dtsi b/arch/arm/boot/dts/sh7377.dtsi
deleted file mode 100644
index 767ee07..0000000
--- a/arch/arm/boot/dts/sh7377.dtsi
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Device Tree Source for the sh7377 SoC
- *
- * Copyright (C) 2012 Renesas Solutions Corp.
- *
- * 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/ "skeleton.dtsi"
-
-/ {
-	compatible = "renesas,sh7377";
-
-	cpus {
-		cpu@0 {
-			compatible = "arm,cortex-a8";
-		};
-	};
-};
diff --git a/arch/arm/boot/dts/sun4i-cubieboard.dts b/arch/arm/boot/dts/sun4i-cubieboard.dts
new file mode 100644
index 0000000..f4ca126
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-cubieboard.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2012 Stefan Roese
+ * Stefan Roese <sr@denx.de>
+ *
+ * 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/ "sun4i.dtsi"
+
+/ {
+	model = "Cubietech Cubieboard";
+	compatible = "cubietech,cubieboard", "allwinner,sun4i";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
+	chosen {
+		bootargs = "earlyprintk console=ttyS0,115200";
+	};
+
+	soc {
+		uart0: uart@01c28000 {
+			status = "okay";
+		};
+
+		uart1: uart@01c28400 {
+			status = "okay";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/sun4i.dtsi b/arch/arm/boot/dts/sun4i.dtsi
new file mode 100644
index 0000000..e61fdd4
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i.dtsi
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2012 Stefan Roese
+ * Stefan Roese <sr@denx.de>
+ *
+ * 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/ "sunxi.dtsi"
+
+/ {
+	memory {
+		reg = <0x40000000 0x80000000>;
+	};
+};
diff --git a/arch/arm/boot/dts/sun5i-olinuxino.dts b/arch/arm/boot/dts/sun5i-olinuxino.dts
new file mode 100644
index 0000000..d6ff889
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-olinuxino.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.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/ "sun5i.dtsi"
+
+/ {
+	model = "Olimex A13-Olinuxino";
+	compatible = "olimex,a13-olinuxino", "allwinner,sun5i";
+
+	chosen {
+		bootargs = "earlyprintk console=ttyS0,115200";
+	};
+
+	soc {
+		uart1: uart@01c28400 {
+			status = "okay";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
new file mode 100644
index 0000000..59a2d26
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.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/ "sunxi.dtsi"
+
+/ {
+	memory {
+		reg = <0x40000000 0x20000000>;
+	};
+};
diff --git a/arch/arm/boot/dts/sunxi.dtsi b/arch/arm/boot/dts/sunxi.dtsi
new file mode 100644
index 0000000..8bbc2bf
--- /dev/null
+++ b/arch/arm/boot/dts/sunxi.dtsi
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.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 = <&intc>;
+
+	cpus {
+		cpu@0 {
+			compatible = "arm,cortex-a8";
+		};
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		osc: oscillator {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x01c20000 0x300000>;
+		ranges;
+
+		timer@01c20c00 {
+			compatible = "allwinner,sunxi-timer";
+			reg = <0x01c20c00 0x90>;
+			interrupts = <22>;
+			clocks = <&osc>;
+		};
+
+		wdt: watchdog@01c20c90 {
+			compatible = "allwinner,sunxi-wdt";
+			reg = <0x01c20c90 0x10>;
+		};
+
+		intc: interrupt-controller@01c20400 {
+			compatible = "allwinner,sunxi-ic";
+			reg = <0x01c20400 0x400>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		uart0: uart@01c28000 {
+			compatible = "ns8250";
+			reg = <0x01c28000 0x400>;
+			interrupts = <1>;
+			reg-shift = <2>;
+			clock-frequency = <24000000>;
+			status = "disabled";
+		};
+
+		uart1: uart@01c28400 {
+			compatible = "ns8250";
+			reg = <0x01c28400 0x400>;
+			interrupts = <2>;
+			reg-shift = <2>;
+			clock-frequency = <24000000>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts
index c3ef1ad..74b8a47 100644
--- a/arch/arm/boot/dts/tegra20-harmony.dts
+++ b/arch/arm/boot/dts/tegra20-harmony.dts
@@ -297,131 +297,98 @@
 			vinldo9-supply = <&sm2_reg>;
 
 			regulators {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				sys_reg: regulator@0 {
-					reg = <0>;
-					regulator-compatible = "sys";
+				sys_reg: sys {
 					regulator-name = "vdd_sys";
 					regulator-always-on;
 				};
 
-				regulator@1 {
-					reg = <1>;
-					regulator-compatible = "sm0";
+				sm0 {
 					regulator-name = "vdd_sm0,vdd_core";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 					regulator-always-on;
 				};
 
-				regulator@2 {
-					reg = <2>;
-					regulator-compatible = "sm1";
+				sm1 {
 					regulator-name = "vdd_sm1,vdd_cpu";
 					regulator-min-microvolt = <1000000>;
 					regulator-max-microvolt = <1000000>;
 					regulator-always-on;
 				};
 
-				sm2_reg: regulator@3 {
-					reg = <3>;
-					regulator-compatible = "sm2";
+				sm2_reg: sm2 {
 					regulator-name = "vdd_sm2,vin_ldo*";
 					regulator-min-microvolt = <3700000>;
 					regulator-max-microvolt = <3700000>;
 					regulator-always-on;
 				};
 
-				regulator@4 {
-					reg = <4>;
-					regulator-compatible = "ldo0";
+				ldo0 {
 					regulator-name = "vdd_ldo0,vddio_pex_clk";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 				};
 
-				regulator@5 {
-					reg = <5>;
-					regulator-compatible = "ldo1";
+				ldo1 {
 					regulator-name = "vdd_ldo1,avdd_pll*";
 					regulator-min-microvolt = <1100000>;
 					regulator-max-microvolt = <1100000>;
 					regulator-always-on;
 				};
 
-				regulator@6 {
-					reg = <6>;
-					regulator-compatible = "ldo2";
+				ldo2 {
 					regulator-name = "vdd_ldo2,vdd_rtc";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 				};
 
-				regulator@7 {
-					reg = <7>;
-					regulator-compatible = "ldo3";
+				ldo3 {
 					regulator-name = "vdd_ldo3,avdd_usb*";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 					regulator-always-on;
 				};
 
-				regulator@8 {
-					reg = <8>;
-					regulator-compatible = "ldo4";
+				ldo4 {
 					regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 					regulator-always-on;
 				};
 
-				regulator@9 {
-					reg = <9>;
-					regulator-compatible = "ldo5";
+				ldo5 {
 					regulator-name = "vdd_ldo5,vcore_mmc";
 					regulator-min-microvolt = <2850000>;
 					regulator-max-microvolt = <2850000>;
 					regulator-always-on;
 				};
 
-				regulator@10 {
-					reg = <10>;
-					regulator-compatible = "ldo6";
+				ldo6 {
 					regulator-name = "vdd_ldo6,avdd_vdac";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 				};
 
-				regulator@11 {
-					reg = <11>;
-					regulator-compatible = "ldo7";
+				ldo7 {
 					regulator-name = "vdd_ldo7,avdd_hdmi";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 				};
 
-				regulator@12 {
-					reg = <12>;
-					regulator-compatible = "ldo8";
+				ldo8 {
 					regulator-name = "vdd_ldo8,avdd_hdmi_pll";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 				};
 
-				regulator@13 {
-					reg = <13>;
-					regulator-compatible = "ldo9";
+				ldo9 {
 					regulator-name = "vdd_ldo9,avdd_2v85,vdd_ddr_rx";
 					regulator-min-microvolt = <2850000>;
 					regulator-max-microvolt = <2850000>;
 					regulator-always-on;
 				};
 
-				regulator@14 {
-					reg = <14>;
-					regulator-compatible = "ldo_rtc";
+				ldo_rtc {
 					regulator-name = "vdd_rtc_out,vdd_cell";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts
index ddf287f..6a93d14 100644
--- a/arch/arm/boot/dts/tegra20-paz00.dts
+++ b/arch/arm/boot/dts/tegra20-paz00.dts
@@ -291,37 +291,26 @@
 			vinldo9-supply = <&sm2_reg>;
 
 			regulators {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				sys_reg: regulator@0 {
-					reg = <0>;
-					regulator-compatible = "sys";
+				sys_reg: sys {
 					regulator-name = "vdd_sys";
 					regulator-always-on;
 				};
 
-				regulator@1 {
-					reg = <1>;
-					regulator-compatible = "sm0";
+				sm0 {
 					regulator-name = "+1.2vs_sm0,vdd_core";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 					regulator-always-on;
 				};
 
-				regulator@2 {
-					reg = <2>;
-					regulator-compatible = "sm1";
+				sm1 {
 					regulator-name = "+1.0vs_sm1,vdd_cpu";
 					regulator-min-microvolt = <1000000>;
 					regulator-max-microvolt = <1000000>;
 					regulator-always-on;
 				};
 
-				sm2_reg: regulator@3 {
-					reg = <3>;
-					regulator-compatible = "sm2";
+				sm2_reg: sm2 {
 					regulator-name = "+3.7vs_sm2,vin_ldo*";
 					regulator-min-microvolt = <3700000>;
 					regulator-max-microvolt = <3700000>;
@@ -330,53 +319,41 @@
 
 				/* LDO0 is not connected to anything */
 
-				regulator@5 {
-					reg = <5>;
-					regulator-compatible = "ldo1";
+				ldo1 {
 					regulator-name = "+1.1vs_ldo1,avdd_pll*";
 					regulator-min-microvolt = <1100000>;
 					regulator-max-microvolt = <1100000>;
 					regulator-always-on;
 				};
 
-				regulator@6 {
-					reg = <6>;
-					regulator-compatible = "ldo2";
+				ldo2 {
 					regulator-name = "+1.2vs_ldo2,vdd_rtc";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 				};
 
-				regulator@7 {
-					reg = <7>;
-					regulator-compatible = "ldo3";
+				ldo3 {
 					regulator-name = "+3.3vs_ldo3,avdd_usb*";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 					regulator-always-on;
 				};
 
-				regulator@8 {
-					reg = <8>;
-					regulator-compatible = "ldo4";
+				ldo4 {
 					regulator-name = "+1.8vs_ldo4,avdd_osc,vddio_sys";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 					regulator-always-on;
 				};
 
-				regulator@9 {
-					reg = <9>;
-					regulator-compatible = "ldo5";
+				ldo5 {
 					regulator-name = "+2.85vs_ldo5,vcore_mmc";
 					regulator-min-microvolt = <2850000>;
 					regulator-max-microvolt = <2850000>;
 					regulator-always-on;
 				};
 
-				regulator@10 {
-					reg = <10>;
-					regulator-compatible = "ldo6";
+				ldo6 {
 					/*
 					 * Research indicates this should be
 					 * 1.8v; other boards that use this
@@ -390,34 +367,26 @@
 					regulator-max-microvolt = <1800000>;
 				};
 
-				regulator@11 {
-					reg = <11>;
-					regulator-compatible = "ldo7";
+				ldo7 {
 					regulator-name = "+3.3vs_ldo7,avdd_hdmi";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 				};
 
-				regulator@12 {
-					reg = <12>;
-					regulator-compatible = "ldo8";
+				ldo8 {
 					regulator-name = "+1.8vs_ldo8,avdd_hdmi_pll";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 				};
 
-				regulator@13 {
-					reg = <13>;
-					regulator-compatible = "ldo9";
+				ldo9 {
 					regulator-name = "+2.85vs_ldo9,vdd_ddr_rx";
 					regulator-min-microvolt = <2850000>;
 					regulator-max-microvolt = <2850000>;
 					regulator-always-on;
 				};
 
-				regulator@14 {
-					reg = <14>;
-					regulator-compatible = "ldo_rtc";
+				ldo_rtc {
 					regulator-name = "+3.3vs_rtc";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts
index f0ba901..33ae813 100644
--- a/arch/arm/boot/dts/tegra20-seaboard.dts
+++ b/arch/arm/boot/dts/tegra20-seaboard.dts
@@ -395,37 +395,26 @@
 			vinldo9-supply = <&sm2_reg>;
 
 			regulators {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				sys_reg: regulator@0 {
-					reg = <0>;
-					regulator-compatible = "sys";
+				sys_reg: sys {
 					regulator-name = "vdd_sys";
 					regulator-always-on;
 				};
 
-				regulator@1 {
-					reg = <1>;
-					regulator-compatible = "sm0";
+				sm0 {
 					regulator-name = "vdd_sm0,vdd_core";
 					regulator-min-microvolt = <1300000>;
 					regulator-max-microvolt = <1300000>;
 					regulator-always-on;
 				};
 
-				regulator@2 {
-					reg = <2>;
-					regulator-compatible = "sm1";
+				sm1 {
 					regulator-name = "vdd_sm1,vdd_cpu";
 					regulator-min-microvolt = <1125000>;
 					regulator-max-microvolt = <1125000>;
 					regulator-always-on;
 				};
 
-				sm2_reg: regulator@3 {
-					reg = <3>;
-					regulator-compatible = "sm2";
+				sm2_reg: sm2 {
 					regulator-name = "vdd_sm2,vin_ldo*";
 					regulator-min-microvolt = <3700000>;
 					regulator-max-microvolt = <3700000>;
@@ -434,86 +423,66 @@
 
 				/* LDO0 is not connected to anything */
 
-				regulator@5 {
-					reg = <5>;
-					regulator-compatible = "ldo1";
+				ldo1 {
 					regulator-name = "vdd_ldo1,avdd_pll*";
 					regulator-min-microvolt = <1100000>;
 					regulator-max-microvolt = <1100000>;
 					regulator-always-on;
 				};
 
-				regulator@6 {
-					reg = <6>;
-					regulator-compatible = "ldo2";
+				ldo2 {
 					regulator-name = "vdd_ldo2,vdd_rtc";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 				};
 
-				regulator@7 {
-					reg = <7>;
-					regulator-compatible = "ldo3";
+				ldo3 {
 					regulator-name = "vdd_ldo3,avdd_usb*";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 					regulator-always-on;
 				};
 
-				regulator@8 {
-					reg = <8>;
-					regulator-compatible = "ldo4";
+				ldo4 {
 					regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 					regulator-always-on;
 				};
 
-				regulator@9 {
-					reg = <9>;
-					regulator-compatible = "ldo5";
+				ldo5 {
 					regulator-name = "vdd_ldo5,vcore_mmc";
 					regulator-min-microvolt = <2850000>;
 					regulator-max-microvolt = <2850000>;
 					regulator-always-on;
 				};
 
-				regulator@10 {
-					reg = <10>;
-					regulator-compatible = "ldo6";
+				ldo6 {
 					regulator-name = "vdd_ldo6,avdd_vdac,vddio_vi,vddio_cam";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 				};
 
-				regulator@11 {
-					reg = <11>;
-					regulator-compatible = "ldo7";
+				ldo7 {
 					regulator-name = "vdd_ldo7,avdd_hdmi,vdd_fuse";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 				};
 
-				regulator@12 {
-					reg = <12>;
-					regulator-compatible = "ldo8";
+				ldo8 {
 					regulator-name = "vdd_ldo8,avdd_hdmi_pll";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 				};
 
-				regulator@13 {
-					reg = <13>;
-					regulator-compatible = "ldo9";
+				ldo9 {
 					regulator-name = "vdd_ldo9,avdd_2v85,vdd_ddr_rx";
 					regulator-min-microvolt = <2850000>;
 					regulator-max-microvolt = <2850000>;
 					regulator-always-on;
 				};
 
-				regulator@14 {
-					reg = <14>;
-					regulator-compatible = "ldo_rtc";
+				ldo_rtc {
 					regulator-name = "vdd_rtc_out,vdd_cell";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi b/arch/arm/boot/dts/tegra20-tamonten.dtsi
index f18cec9..5b3d8b1 100644
--- a/arch/arm/boot/dts/tegra20-tamonten.dtsi
+++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi
@@ -271,97 +271,72 @@
 			vinldo9-supply = <&sm2_reg>;
 
 			regulators {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				sys_reg: regulator@0 {
-					reg = <0>;
-					regulator-compatible = "sys";
+				sys_reg: sys {
 					regulator-name = "vdd_sys";
 					regulator-always-on;
 				};
 
-				regulator@1 {
-					reg = <1>;
-					regulator-compatible = "sm0";
+				sm0 {
 					regulator-name = "vdd_sys_sm0,vdd_core";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 					regulator-always-on;
 				};
 
-				regulator@2 {
-					reg = <2>;
-					regulator-compatible = "sm1";
+				sm1 {
 					regulator-name = "vdd_sys_sm1,vdd_cpu";
 					regulator-min-microvolt = <1000000>;
 					regulator-max-microvolt = <1000000>;
 					regulator-always-on;
 				};
 
-				sm2_reg: regulator@3 {
-					reg = <3>;
-					regulator-compatible = "sm2";
+				sm2_reg: sm2 {
 					regulator-name = "vdd_sys_sm2,vin_ldo*";
 					regulator-min-microvolt = <3700000>;
 					regulator-max-microvolt = <3700000>;
 					regulator-always-on;
 				};
 
-				regulator@4 {
-					reg = <4>;
-					regulator-compatible = "ldo0";
+				ldo0 {
 					regulator-name = "vdd_ldo0,vddio_pex_clk";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 				};
 
-				regulator@5 {
-					reg = <5>;
-					regulator-compatible = "ldo1";
+				ldo1 {
 					regulator-name = "vdd_ldo1,avdd_pll*";
 					regulator-min-microvolt = <1100000>;
 					regulator-max-microvolt = <1100000>;
 					regulator-always-on;
 				};
 
-				regulator@6 {
-					reg = <6>;
-					regulator-compatible = "ldo2";
+				ldo2 {
 					regulator-name = "vdd_ldo2,vdd_rtc";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 				};
 
-				regulator@7 {
-					reg = <7>;
-					regulator-compatible = "ldo3";
+				ldo3 {
 					regulator-name = "vdd_ldo3,avdd_usb*";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 					regulator-always-on;
 				};
 
-				regulator@8 {
-					reg = <8>;
-					regulator-compatible = "ldo4";
+				ldo4 {
 					regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 					regulator-always-on;
 				};
 
-				regulator@9 {
-					reg = <9>;
-					regulator-compatible = "ldo5";
+				ldo5 {
 					regulator-name = "vdd_ldo5,vcore_mmc";
 					regulator-min-microvolt = <2850000>;
 					regulator-max-microvolt = <2850000>;
 				};
 
-				regulator@10 {
-					reg = <10>;
-					regulator-compatible = "ldo6";
+				ldo6 {
 					regulator-name = "vdd_ldo6,avdd_vdac";
 					/*
 					 * According to the Tegra 2 Automotive
@@ -373,25 +348,19 @@
 					regulator-max-microvolt = <2850000>;
 				};
 
-				regulator@11 {
-					reg = <11>;
-					regulator-compatible = "ldo7";
+				ldo7 {
 					regulator-name = "vdd_ldo7,avdd_hdmi";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 				};
 
-				regulator@12 {
-					reg = <12>;
-					regulator-compatible = "ldo8";
+				ldo8 {
 					regulator-name = "vdd_ldo8,avdd_hdmi_pll";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 				};
 
-				regulator@13 {
-					reg = <13>;
-					regulator-compatible = "ldo9";
+				ldo9 {
 					regulator-name = "vdd_ldo9,vdd_ddr_rx,avdd_cam";
 					/*
 					 * According to the Tegra 2 Automotive
@@ -404,9 +373,7 @@
 					regulator-always-on;
 				};
 
-				regulator@14 {
-					reg = <14>;
-					regulator-compatible = "ldo_rtc";
+				ldo_rtc {
 					regulator-name = "vdd_rtc_out";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts
index 3e5952f..86854f1 100644
--- a/arch/arm/boot/dts/tegra20-ventana.dts
+++ b/arch/arm/boot/dts/tegra20-ventana.dts
@@ -311,37 +311,26 @@
 			vinldo9-supply = <&sm2_reg>;
 
 			regulators {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				sys_reg: regulator@0 {
-					reg = <0>;
-					regulator-compatible = "sys";
+				sys_reg: sys {
 					regulator-name = "vdd_sys";
 					regulator-always-on;
 				};
 
-				regulator@1 {
-					reg = <1>;
-					regulator-compatible = "sm0";
+				sm0 {
 					regulator-name = "vdd_sm0,vdd_core";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 					regulator-always-on;
 				};
 
-				regulator@2 {
-					reg = <2>;
-					regulator-compatible = "sm1";
+				sm1 {
 					regulator-name = "vdd_sm1,vdd_cpu";
 					regulator-min-microvolt = <1000000>;
 					regulator-max-microvolt = <1000000>;
 					regulator-always-on;
 				};
 
-				sm2_reg: regulator@3 {
-					reg = <3>;
-					regulator-compatible = "sm2";
+				sm2_reg: sm2 {
 					regulator-name = "vdd_sm2,vin_ldo*";
 					regulator-min-microvolt = <3700000>;
 					regulator-max-microvolt = <3700000>;
@@ -350,86 +339,66 @@
 
 				/* LDO0 is not connected to anything */
 
-				regulator@5 {
-					reg = <5>;
-					regulator-compatible = "ldo1";
+				ldo1 {
 					regulator-name = "vdd_ldo1,avdd_pll*";
 					regulator-min-microvolt = <1100000>;
 					regulator-max-microvolt = <1100000>;
 					regulator-always-on;
 				};
 
-				regulator@6 {
-					reg = <6>;
-					regulator-compatible = "ldo2";
+				ldo2 {
 					regulator-name = "vdd_ldo2,vdd_rtc";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 				};
 
-				regulator@7 {
-					reg = <7>;
-					regulator-compatible = "ldo3";
+				ldo3 {
 					regulator-name = "vdd_ldo3,avdd_usb*";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 					regulator-always-on;
 				};
 
-				regulator@8 {
-					reg = <8>;
-					regulator-compatible = "ldo4";
+				ldo4 {
 					regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 					regulator-always-on;
 				};
 
-				regulator@9 {
-					reg = <9>;
-					regulator-compatible = "ldo5";
+				ldo5 {
 					regulator-name = "vdd_ldo5,vcore_mmc";
 					regulator-min-microvolt = <2850000>;
 					regulator-max-microvolt = <2850000>;
 					regulator-always-on;
 				};
 
-				regulator@10 {
-					reg = <10>;
-					regulator-compatible = "ldo6";
+				ldo6 {
 					regulator-name = "vdd_ldo6,avdd_vdac";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 				};
 
-				regulator@11 {
-					reg = <11>;
-					regulator-compatible = "ldo7";
+				ldo7 {
 					regulator-name = "vdd_ldo7,avdd_hdmi,vdd_fuse";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 				};
 
-				regulator@12 {
-					reg = <12>;
-					regulator-compatible = "ldo8";
+				ldo8 {
 					regulator-name = "vdd_ldo8,avdd_hdmi_pll";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 				};
 
-				regulator@13 {
-					reg = <13>;
-					regulator-compatible = "ldo9";
+				ldo9 {
 					regulator-name = "vdd_ldo9,avdd_2v85,vdd_ddr_rx";
 					regulator-min-microvolt = <2850000>;
 					regulator-max-microvolt = <2850000>;
 					regulator-always-on;
 				};
 
-				regulator@14 {
-					reg = <14>;
-					regulator-compatible = "ldo_rtc";
+				ldo_rtc {
 					regulator-name = "vdd_rtc_out,vdd_cell";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/tegra20-whistler.dts b/arch/arm/boot/dts/tegra20-whistler.dts
index c636d00..94a71c9 100644
--- a/arch/arm/boot/dts/tegra20-whistler.dts
+++ b/arch/arm/boot/dts/tegra20-whistler.dts
@@ -295,243 +295,182 @@
 			in20-supply = <&mbatt_reg>;
 
 			regulators {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				mbatt_reg: regulator@0 {
-					reg = <0>;
-					regulator-compatible = "mbatt";
+				mbatt_reg: mbatt {
 					regulator-name = "vbat_pmu";
 					regulator-always-on;
 				};
 
-				regulator@1 {
-					reg = <1>;
-					regulator-compatible = "sd1";
+				sd1 {
 					regulator-name = "nvvdd_sv1,vdd_cpu_pmu";
 					regulator-min-microvolt = <1000000>;
 					regulator-max-microvolt = <1000000>;
 					regulator-always-on;
 				};
 
-				regulator@2 {
-					reg = <2>;
-					regulator-compatible = "sd2";
+				sd2 {
 					regulator-name = "nvvdd_sv2,vdd_core";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 					regulator-always-on;
 				};
 
-				nvvdd_sv3_reg: regulator@3 {
-					reg = <3>;
-					regulator-compatible = "sd3";
+				nvvdd_sv3_reg: sd3 {
 					regulator-name = "nvvdd_sv3";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 					regulator-always-on;
 				};
 
-				regulator@4 {
-					reg = <4>;
-					regulator-compatible = "ldo1";
+				ldo1 {
 					regulator-name = "nvvdd_ldo1,vddio_rx_ddr,vcore_acc";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 					regulator-always-on;
 				};
 
-				regulator@5 {
-					reg = <5>;
-					regulator-compatible = "ldo2";
+				ldo2 {
 					regulator-name = "nvvdd_ldo2,avdd_pll*";
 					regulator-min-microvolt = <1100000>;
 					regulator-max-microvolt = <1100000>;
 					regulator-always-on;
 				};
 
-				regulator@6 {
-					reg = <6>;
-					regulator-compatible = "ldo3";
+				ldo3 {
 					regulator-name = "nvvdd_ldo3,vcom_1v8b";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 					regulator-always-on;
 				};
 
-				regulator@7 {
-					reg = <7>;
-					regulator-compatible = "ldo4";
+				ldo4 {
 					regulator-name = "nvvdd_ldo4,avdd_usb*";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 					regulator-always-on;
 				};
 
-				regulator@8 {
-					reg = <8>;
-					regulator-compatible = "ldo5";
+				ldo5 {
 					regulator-name = "nvvdd_ldo5,vcore_mmc,avdd_lcd1,vddio_1wire";
 					regulator-min-microvolt = <2800000>;
 					regulator-max-microvolt = <2800000>;
 					regulator-always-on;
 				};
 
-				regulator@9 {
-					reg = <9>;
-					regulator-compatible = "ldo6";
+				ldo6 {
 					regulator-name = "nvvdd_ldo6,avdd_hdmi_pll";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 				};
 
-				regulator@10 {
-					reg = <10>;
-					regulator-compatible = "ldo7";
+				ldo7 {
 					regulator-name = "nvvdd_ldo7,avddio_audio";
 					regulator-min-microvolt = <2800000>;
 					regulator-max-microvolt = <2800000>;
 					regulator-always-on;
 				};
 
-				regulator@11 {
-					reg = <11>;
-					regulator-compatible = "ldo8";
+				ldo8 {
 					regulator-name = "nvvdd_ldo8,vcom_3v0,vcore_cmps";
 					regulator-min-microvolt = <3000000>;
 					regulator-max-microvolt = <3000000>;
 				};
 
-				regulator@12 {
-					reg = <12>;
-					regulator-compatible = "ldo9";
+				ldo9 {
 					regulator-name = "nvvdd_ldo9,avdd_cam*";
 					regulator-min-microvolt = <2800000>;
 					regulator-max-microvolt = <2800000>;
 				};
 
-				regulator@13 {
-					reg = <13>;
-					regulator-compatible = "ldo10";
+				ldo10 {
 					regulator-name = "nvvdd_ldo10,avdd_usb_ic_3v0";
 					regulator-min-microvolt = <3000000>;
 					regulator-max-microvolt = <3000000>;
 					regulator-always-on;
 				};
 
-				regulator@14 {
-					reg = <14>;
-					regulator-compatible = "ldo11";
+				ldo11 {
 					regulator-name = "nvvdd_ldo11,vddio_pex_clk,vcom_33,avdd_hdmi";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 				};
 
-				regulator@15 {
-					reg = <15>;
-					regulator-compatible = "ldo12";
+				ldo12 {
 					regulator-name = "nvvdd_ldo12,vddio_sdio";
 					regulator-min-microvolt = <2800000>;
 					regulator-max-microvolt = <2800000>;
 					regulator-always-on;
 				};
 
-				regulator@16 {
-					reg = <16>;
-					regulator-compatible = "ldo13";
+				ldo13 {
 					regulator-name = "nvvdd_ldo13,vcore_phtn,vdd_af";
 					regulator-min-microvolt = <2800000>;
 					regulator-max-microvolt = <2800000>;
 				};
 
-				regulator@17 {
-					reg = <17>;
-					regulator-compatible = "ldo14";
+				ldo14 {
 					regulator-name = "nvvdd_ldo14,avdd_vdac";
 					regulator-min-microvolt = <2800000>;
 					regulator-max-microvolt = <2800000>;
 				};
 
-				regulator@18 {
-					reg = <18>;
-					regulator-compatible = "ldo15";
+				ldo15 {
 					regulator-name = "nvvdd_ldo15,vcore_temp,vddio_hdcp";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 				};
 
-				regulator@19 {
-					reg = <19>;
-					regulator-compatible = "ldo16";
+				ldo16 {
 					regulator-name = "nvvdd_ldo16,vdd_dbrtr";
 					regulator-min-microvolt = <1300000>;
 					regulator-max-microvolt = <1300000>;
 				};
 
-				regulator@20 {
-					reg = <20>;
-					regulator-compatible = "ldo17";
+				ldo17 {
 					regulator-name = "nvvdd_ldo17,vddio_mipi";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 				};
 
-				regulator@21 {
-					reg = <21>;
-					regulator-compatible = "ldo18";
+				ldo18 {
 					regulator-name = "nvvdd_ldo18,vddio_vi,vcore_cam*";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 				};
 
-				regulator@22 {
-					reg = <22>;
-					regulator-compatible = "ldo19";
+				ldo19 {
 					regulator-name = "nvvdd_ldo19,avdd_lcd2,vddio_lx";
 					regulator-min-microvolt = <2800000>;
 					regulator-max-microvolt = <2800000>;
 				};
 
-				regulator@23 {
-					reg = <23>;
-					regulator-compatible = "ldo20";
+				ldo20 {
 					regulator-name = "nvvdd_ldo20,vddio_ddr_1v2,vddio_hsic,vcom_1v2";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 					regulator-always-on;
 				};
 
-				regulator@24 {
-					reg = <24>;
-					regulator-compatible = "out5v";
+				out5v {
 					regulator-name = "usb0_vbus_reg";
 				};
 
-				regulator@25 {
-					reg = <25>;
-					regulator-compatible = "out33v";
+				out33v {
 					regulator-name = "pmu_out3v3";
 				};
 
-				regulator@26 {
-					reg = <26>;
-					regulator-compatible = "bbat";
+				bbat {
 					regulator-name = "pmu_bbat";
 					regulator-min-microvolt = <2400000>;
 					regulator-max-microvolt = <2400000>;
 					regulator-always-on;
 				};
 
-				regulator@27 {
-					reg = <27>;
-					regulator-compatible = "sdby";
+				sdby {
 					regulator-name = "vdd_aon";
 					regulator-always-on;
 				};
 
-				regulator@28 {
-					reg = <28>;
-					regulator-compatible = "vrtc";
+				vrtc {
 					regulator-name = "vrtc,pmu_vccadc";
 					regulator-always-on;
 				};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index f3a09d0..f40cfba 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -4,6 +4,15 @@
 	compatible = "nvidia,tegra20";
 	interrupt-parent = <&intc>;
 
+	cache-controller@50043000 {
+		compatible = "arm,pl310-cache";
+		reg = <0x50043000 0x1000>;
+		arm,data-latency = <5 5 2>;
+		arm,tag-latency = <4 4 2>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
 	intc: interrupt-controller {
 		compatible = "arm,cortex-a9-gic";
 		reg = <0x50041000 0x1000
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
index d10c9c5..b1271a8 100644
--- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
+++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
@@ -171,56 +171,41 @@
 			vccio-supply = <&vdd_ac_bat_reg>;
 
 			regulators {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				vdd1_reg: regulator@0 {
-					reg = <0>;
-					regulator-compatible = "vdd1";
+				vdd1_reg: vdd1 {
 					regulator-name = "vddio_ddr_1v2";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 					regulator-always-on;
 				};
 
-				vdd2_reg: regulator@1 {
-					reg = <1>;
-					regulator-compatible = "vdd2";
+				vdd2_reg: vdd2 {
 					regulator-name = "vdd_1v5_gen";
 					regulator-min-microvolt = <1500000>;
 					regulator-max-microvolt = <1500000>;
 					regulator-always-on;
 				};
 
-				vddctrl_reg: regulator@2 {
-					reg = <2>;
-					regulator-compatible = "vddctrl";
+				vddctrl_reg: vddctrl {
 					regulator-name = "vdd_cpu,vdd_sys";
 					regulator-min-microvolt = <1000000>;
 					regulator-max-microvolt = <1000000>;
 					regulator-always-on;
 				};
 
-				vio_reg: regulator@3 {
-					reg = <3>;
-					regulator-compatible = "vio";
+				vio_reg: vio {
 					regulator-name = "vdd_1v8_gen";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 					regulator-always-on;
 				};
 
-				ldo1_reg: regulator@4 {
-					reg = <4>;
-					regulator-compatible = "ldo1";
+				ldo1_reg: ldo1 {
 					regulator-name = "vdd_pexa,vdd_pexb";
 					regulator-min-microvolt = <1050000>;
 					regulator-max-microvolt = <1050000>;
 				};
 
-				ldo2_reg: regulator@5 {
-					reg = <5>;
-					regulator-compatible = "ldo2";
+				ldo2_reg: ldo2 {
 					regulator-name = "vdd_sata,avdd_plle";
 					regulator-min-microvolt = <1050000>;
 					regulator-max-microvolt = <1050000>;
@@ -228,44 +213,34 @@
 
 				/* LDO3 is not connected to anything */
 
-				ldo4_reg: regulator@7 {
-					reg = <7>;
-					regulator-compatible = "ldo4";
+				ldo4_reg: ldo4 {
 					regulator-name = "vdd_rtc";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 					regulator-always-on;
 				};
 
-				ldo5_reg: regulator@8 {
-					reg = <8>;
-					regulator-compatible = "ldo5";
+				ldo5_reg: ldo5 {
 					regulator-name = "vddio_sdmmc,avdd_vdac";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 					regulator-always-on;
 				};
 
-				ldo6_reg: regulator@9 {
-					reg = <9>;
-					regulator-compatible = "ldo6";
+				ldo6_reg: ldo6 {
 					regulator-name = "avdd_dsi_csi,pwrdet_mipi";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 				};
 
-				ldo7_reg: regulator@10 {
-					reg = <10>;
-					regulator-compatible = "ldo7";
+				ldo7_reg: ldo7 {
 					regulator-name = "vdd_pllm,x,u,a_p_c_s";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 					regulator-always-on;
 				};
 
-				ldo8_reg: regulator@11 {
-					reg = <11>;
-					regulator-compatible = "ldo8";
+				ldo8_reg: ldo8 {
 					regulator-name = "vdd_ddr_hs";
 					regulator-min-microvolt = <1000000>;
 					regulator-max-microvolt = <1000000>;
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index b1497c7..fed8dca 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -4,6 +4,15 @@
 	compatible = "nvidia,tegra30";
 	interrupt-parent = <&intc>;
 
+	cache-controller@50043000 {
+		compatible = "arm,pl310-cache";
+		reg = <0x50043000 0x1000>;
+		arm,data-latency = <6 6 2>;
+		arm,tag-latency = <5 5 2>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
 	intc: interrupt-controller {
 		compatible = "arm,cortex-a9-gic";
 		reg = <0x50041000 0x1000
@@ -73,8 +82,8 @@
 
 	pinmux: pinmux {
 		compatible = "nvidia,tegra30-pinmux";
-		reg = <0x70000868 0xd0    /* Pad control registers */
-		       0x70003000 0x3e0>; /* Mux registers */
+		reg = <0x70000868 0xd4    /* Pad control registers */
+		       0x70003000 0x3e4>; /* Mux registers */
 	};
 
 	serial@70006000 {
diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
index d8a827b..ac870fb 100644
--- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
@@ -17,17 +17,16 @@
  * CHANGES TO vexpress-v2m.dtsi!
  */
 
-/ {
-	aliases {
-		arm,v2m_timer = &v2m_timer01;
-	};
-
 	motherboard {
-		compatible = "simple-bus";
+		model = "V2M-P1";
+		arm,hbi = <0x190>;
+		arm,vexpress,site = <0>;
 		arm,v2m-memory-map = "rs1";
+		compatible = "arm,vexpress,v2m-p1", "simple-bus";
 		#address-cells = <2>; /* SMB chipselect number and offset */
 		#size-cells = <1>;
 		#interrupt-cells = <1>;
+		ranges;
 
 		flash@0,00000000 {
 			compatible = "arm,vexpress-flash", "cfi-flash";
@@ -72,14 +71,20 @@
 			#size-cells = <1>;
 			ranges = <0 3 0 0x200000>;
 
-			sysreg@010000 {
+			v2m_sysreg: sysreg@010000 {
 				compatible = "arm,vexpress-sysreg";
 				reg = <0x010000 0x1000>;
+				gpio-controller;
+				#gpio-cells = <2>;
 			};
 
-			sysctl@020000 {
+			v2m_sysctl: sysctl@020000 {
 				compatible = "arm,sp810", "arm,primecell";
 				reg = <0x020000 0x1000>;
+				clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
+				clock-names = "refclk", "timclk", "apb_pclk";
+				#clock-cells = <1>;
+				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
 			};
 
 			/* PCI-E I2C bus */
@@ -100,66 +105,92 @@
 				compatible = "arm,pl041", "arm,primecell";
 				reg = <0x040000 0x1000>;
 				interrupts = <11>;
+				clocks = <&smbclk>;
+				clock-names = "apb_pclk";
 			};
 
 			mmci@050000 {
 				compatible = "arm,pl180", "arm,primecell";
 				reg = <0x050000 0x1000>;
 				interrupts = <9 10>;
+				cd-gpios = <&v2m_sysreg 0 0>;
+				wp-gpios = <&v2m_sysreg 1 0>;
+				max-frequency = <12000000>;
+				vmmc-supply = <&v2m_fixed_3v3>;
+				clocks = <&v2m_clk24mhz>, <&smbclk>;
+				clock-names = "mclk", "apb_pclk";
 			};
 
 			kmi@060000 {
 				compatible = "arm,pl050", "arm,primecell";
 				reg = <0x060000 0x1000>;
 				interrupts = <12>;
+				clocks = <&v2m_clk24mhz>, <&smbclk>;
+				clock-names = "KMIREFCLK", "apb_pclk";
 			};
 
 			kmi@070000 {
 				compatible = "arm,pl050", "arm,primecell";
 				reg = <0x070000 0x1000>;
 				interrupts = <13>;
+				clocks = <&v2m_clk24mhz>, <&smbclk>;
+				clock-names = "KMIREFCLK", "apb_pclk";
 			};
 
 			v2m_serial0: uart@090000 {
 				compatible = "arm,pl011", "arm,primecell";
 				reg = <0x090000 0x1000>;
 				interrupts = <5>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
 			};
 
 			v2m_serial1: uart@0a0000 {
 				compatible = "arm,pl011", "arm,primecell";
 				reg = <0x0a0000 0x1000>;
 				interrupts = <6>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
 			};
 
 			v2m_serial2: uart@0b0000 {
 				compatible = "arm,pl011", "arm,primecell";
 				reg = <0x0b0000 0x1000>;
 				interrupts = <7>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
 			};
 
 			v2m_serial3: uart@0c0000 {
 				compatible = "arm,pl011", "arm,primecell";
 				reg = <0x0c0000 0x1000>;
 				interrupts = <8>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
 			};
 
 			wdt@0f0000 {
 				compatible = "arm,sp805", "arm,primecell";
 				reg = <0x0f0000 0x1000>;
 				interrupts = <0>;
+				clocks = <&v2m_refclk32khz>, <&smbclk>;
+				clock-names = "wdogclk", "apb_pclk";
 			};
 
 			v2m_timer01: timer@110000 {
 				compatible = "arm,sp804", "arm,primecell";
 				reg = <0x110000 0x1000>;
 				interrupts = <2>;
+				clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
 			};
 
 			v2m_timer23: timer@120000 {
 				compatible = "arm,sp804", "arm,primecell";
 				reg = <0x120000 0x1000>;
 				interrupts = <3>;
+				clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
 			};
 
 			/* DVI I2C bus */
@@ -185,6 +216,8 @@
 				compatible = "arm,pl031", "arm,primecell";
 				reg = <0x170000 0x1000>;
 				interrupts = <4>;
+				clocks = <&smbclk>;
+				clock-names = "apb_pclk";
 			};
 
 			compact-flash@1a0000 {
@@ -198,6 +231,8 @@
 				compatible = "arm,pl111", "arm,primecell";
 				reg = <0x1f0000 0x1000>;
 				interrupts = <14>;
+				clocks = <&v2m_oscclk1>, <&smbclk>;
+				clock-names = "clcdclk", "apb_pclk";
 			};
 		};
 
@@ -208,5 +243,98 @@
 			regulator-max-microvolt = <3300000>;
 			regulator-always-on;
 		};
+
+		v2m_clk24mhz: clk24mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+			clock-output-names = "v2m:clk24mhz";
+		};
+
+		v2m_refclk1mhz: refclk1mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1000000>;
+			clock-output-names = "v2m:refclk1mhz";
+		};
+
+		v2m_refclk32khz: refclk32khz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "v2m:refclk32khz";
+		};
+
+		mcc {
+			compatible = "arm,vexpress,config-bus";
+			arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+			osc@0 {
+				/* MCC static memory clock */
+				compatible = "arm,vexpress-osc";
+				arm,vexpress-sysreg,func = <1 0>;
+				freq-range = <25000000 60000000>;
+				#clock-cells = <0>;
+				clock-output-names = "v2m:oscclk0";
+			};
+
+			v2m_oscclk1: osc@1 {
+				/* CLCD clock */
+				compatible = "arm,vexpress-osc";
+				arm,vexpress-sysreg,func = <1 1>;
+				freq-range = <23750000 63500000>;
+				#clock-cells = <0>;
+				clock-output-names = "v2m:oscclk1";
+			};
+
+			v2m_oscclk2: osc@2 {
+				/* IO FPGA peripheral clock */
+				compatible = "arm,vexpress-osc";
+				arm,vexpress-sysreg,func = <1 2>;
+				freq-range = <24000000 24000000>;
+				#clock-cells = <0>;
+				clock-output-names = "v2m:oscclk2";
+			};
+
+			volt@0 {
+				/* Logic level voltage */
+				compatible = "arm,vexpress-volt";
+				arm,vexpress-sysreg,func = <2 0>;
+				regulator-name = "VIO";
+				regulator-always-on;
+				label = "VIO";
+			};
+
+			temp@0 {
+				/* MCC internal operating temperature */
+				compatible = "arm,vexpress-temp";
+				arm,vexpress-sysreg,func = <4 0>;
+				label = "MCC";
+			};
+
+			reset@0 {
+				compatible = "arm,vexpress-reset";
+				arm,vexpress-sysreg,func = <5 0>;
+			};
+
+			muxfpga@0 {
+				compatible = "arm,vexpress-muxfpga";
+				arm,vexpress-sysreg,func = <7 0>;
+			};
+
+			shutdown@0 {
+				compatible = "arm,vexpress-shutdown";
+				arm,vexpress-sysreg,func = <8 0>;
+			};
+
+			reboot@0 {
+				compatible = "arm,vexpress-reboot";
+				arm,vexpress-sysreg,func = <9 0>;
+			};
+
+			dvimode@0 {
+				compatible = "arm,vexpress-dvimode";
+				arm,vexpress-sysreg,func = <11 0>;
+			};
+		};
 	};
-};
diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi
index dba53fd..f142036 100644
--- a/arch/arm/boot/dts/vexpress-v2m.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m.dtsi
@@ -17,16 +17,15 @@
  * CHANGES TO vexpress-v2m-rs1.dtsi!
  */
 
-/ {
-	aliases {
-		arm,v2m_timer = &v2m_timer01;
-	};
-
 	motherboard {
-		compatible = "simple-bus";
+		model = "V2M-P1";
+		arm,hbi = <0x190>;
+		arm,vexpress,site = <0>;
+		compatible = "arm,vexpress,v2m-p1", "simple-bus";
 		#address-cells = <2>; /* SMB chipselect number and offset */
 		#size-cells = <1>;
 		#interrupt-cells = <1>;
+		ranges;
 
 		flash@0,00000000 {
 			compatible = "arm,vexpress-flash", "cfi-flash";
@@ -71,14 +70,20 @@
 			#size-cells = <1>;
 			ranges = <0 7 0 0x20000>;
 
-			sysreg@00000 {
+			v2m_sysreg: sysreg@00000 {
 				compatible = "arm,vexpress-sysreg";
 				reg = <0x00000 0x1000>;
+				gpio-controller;
+				#gpio-cells = <2>;
 			};
 
-			sysctl@01000 {
+			v2m_sysctl: sysctl@01000 {
 				compatible = "arm,sp810", "arm,primecell";
 				reg = <0x01000 0x1000>;
+				clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
+				clock-names = "refclk", "timclk", "apb_pclk";
+				#clock-cells = <1>;
+				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
 			};
 
 			/* PCI-E I2C bus */
@@ -99,66 +104,92 @@
 				compatible = "arm,pl041", "arm,primecell";
 				reg = <0x04000 0x1000>;
 				interrupts = <11>;
+				clocks = <&smbclk>;
+				clock-names = "apb_pclk";
 			};
 
 			mmci@05000 {
 				compatible = "arm,pl180", "arm,primecell";
 				reg = <0x05000 0x1000>;
 				interrupts = <9 10>;
+				cd-gpios = <&v2m_sysreg 0 0>;
+				wp-gpios = <&v2m_sysreg 1 0>;
+				max-frequency = <12000000>;
+				vmmc-supply = <&v2m_fixed_3v3>;
+				clocks = <&v2m_clk24mhz>, <&smbclk>;
+				clock-names = "mclk", "apb_pclk";
 			};
 
 			kmi@06000 {
 				compatible = "arm,pl050", "arm,primecell";
 				reg = <0x06000 0x1000>;
 				interrupts = <12>;
+				clocks = <&v2m_clk24mhz>, <&smbclk>;
+				clock-names = "KMIREFCLK", "apb_pclk";
 			};
 
 			kmi@07000 {
 				compatible = "arm,pl050", "arm,primecell";
 				reg = <0x07000 0x1000>;
 				interrupts = <13>;
+				clocks = <&v2m_clk24mhz>, <&smbclk>;
+				clock-names = "KMIREFCLK", "apb_pclk";
 			};
 
 			v2m_serial0: uart@09000 {
 				compatible = "arm,pl011", "arm,primecell";
 				reg = <0x09000 0x1000>;
 				interrupts = <5>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
 			};
 
 			v2m_serial1: uart@0a000 {
 				compatible = "arm,pl011", "arm,primecell";
 				reg = <0x0a000 0x1000>;
 				interrupts = <6>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
 			};
 
 			v2m_serial2: uart@0b000 {
 				compatible = "arm,pl011", "arm,primecell";
 				reg = <0x0b000 0x1000>;
 				interrupts = <7>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
 			};
 
 			v2m_serial3: uart@0c000 {
 				compatible = "arm,pl011", "arm,primecell";
 				reg = <0x0c000 0x1000>;
 				interrupts = <8>;
+				clocks = <&v2m_oscclk2>, <&smbclk>;
+				clock-names = "uartclk", "apb_pclk";
 			};
 
 			wdt@0f000 {
 				compatible = "arm,sp805", "arm,primecell";
 				reg = <0x0f000 0x1000>;
 				interrupts = <0>;
+				clocks = <&v2m_refclk32khz>, <&smbclk>;
+				clock-names = "wdogclk", "apb_pclk";
 			};
 
 			v2m_timer01: timer@11000 {
 				compatible = "arm,sp804", "arm,primecell";
 				reg = <0x11000 0x1000>;
 				interrupts = <2>;
+				clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
 			};
 
 			v2m_timer23: timer@12000 {
 				compatible = "arm,sp804", "arm,primecell";
 				reg = <0x12000 0x1000>;
 				interrupts = <3>;
+				clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
 			};
 
 			/* DVI I2C bus */
@@ -184,6 +215,8 @@
 				compatible = "arm,pl031", "arm,primecell";
 				reg = <0x17000 0x1000>;
 				interrupts = <4>;
+				clocks = <&smbclk>;
+				clock-names = "apb_pclk";
 			};
 
 			compact-flash@1a000 {
@@ -197,6 +230,8 @@
 				compatible = "arm,pl111", "arm,primecell";
 				reg = <0x1f000 0x1000>;
 				interrupts = <14>;
+				clocks = <&v2m_oscclk1>, <&smbclk>;
+				clock-names = "clcdclk", "apb_pclk";
 			};
 		};
 
@@ -207,5 +242,98 @@
 			regulator-max-microvolt = <3300000>;
 			regulator-always-on;
 		};
+
+		v2m_clk24mhz: clk24mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+			clock-output-names = "v2m:clk24mhz";
+		};
+
+		v2m_refclk1mhz: refclk1mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1000000>;
+			clock-output-names = "v2m:refclk1mhz";
+		};
+
+		v2m_refclk32khz: refclk32khz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "v2m:refclk32khz";
+		};
+
+		mcc {
+			compatible = "arm,vexpress,config-bus";
+			arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+			osc@0 {
+				/* MCC static memory clock */
+				compatible = "arm,vexpress-osc";
+				arm,vexpress-sysreg,func = <1 0>;
+				freq-range = <25000000 60000000>;
+				#clock-cells = <0>;
+				clock-output-names = "v2m:oscclk0";
+			};
+
+			v2m_oscclk1: osc@1 {
+				/* CLCD clock */
+				compatible = "arm,vexpress-osc";
+				arm,vexpress-sysreg,func = <1 1>;
+				freq-range = <23750000 63500000>;
+				#clock-cells = <0>;
+				clock-output-names = "v2m:oscclk1";
+			};
+
+			v2m_oscclk2: osc@2 {
+				/* IO FPGA peripheral clock */
+				compatible = "arm,vexpress-osc";
+				arm,vexpress-sysreg,func = <1 2>;
+				freq-range = <24000000 24000000>;
+				#clock-cells = <0>;
+				clock-output-names = "v2m:oscclk2";
+			};
+
+			volt@0 {
+				/* Logic level voltage */
+				compatible = "arm,vexpress-volt";
+				arm,vexpress-sysreg,func = <2 0>;
+				regulator-name = "VIO";
+				regulator-always-on;
+				label = "VIO";
+			};
+
+			temp@0 {
+				/* MCC internal operating temperature */
+				compatible = "arm,vexpress-temp";
+				arm,vexpress-sysreg,func = <4 0>;
+				label = "MCC";
+			};
+
+			reset@0 {
+				compatible = "arm,vexpress-reset";
+				arm,vexpress-sysreg,func = <5 0>;
+			};
+
+			muxfpga@0 {
+				compatible = "arm,vexpress-muxfpga";
+				arm,vexpress-sysreg,func = <7 0>;
+			};
+
+			shutdown@0 {
+				compatible = "arm,vexpress-shutdown";
+				arm,vexpress-sysreg,func = <8 0>;
+			};
+
+			reboot@0 {
+				compatible = "arm,vexpress-reboot";
+				arm,vexpress-sysreg,func = <9 0>;
+			};
+
+			dvimode@0 {
+				compatible = "arm,vexpress-dvimode";
+				arm,vexpress-sysreg,func = <11 0>;
+			};
+		};
 	};
-};
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
index d12b34c..a3d37ec 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
@@ -12,6 +12,7 @@
 / {
 	model = "V2P-CA15";
 	arm,hbi = <0x237>;
+	arm,vexpress,site = <0xf>;
 	compatible = "arm,vexpress,v2p-ca15,tc1", "arm,vexpress,v2p-ca15", "arm,vexpress";
 	interrupt-parent = <&gic>;
 	#address-cells = <2>;
@@ -54,17 +55,24 @@
 		compatible = "arm,hdlcd";
 		reg = <0 0x2b000000 0 0x1000>;
 		interrupts = <0 85 4>;
+		clocks = <&oscclk5>;
+		clock-names = "pxlclk";
 	};
 
 	memory-controller@2b0a0000 {
 		compatible = "arm,pl341", "arm,primecell";
 		reg = <0 0x2b0a0000 0 0x1000>;
+		clocks = <&oscclk7>;
+		clock-names = "apb_pclk";
 	};
 
 	wdt@2b060000 {
 		compatible = "arm,sp805", "arm,primecell";
+		status = "disabled";
 		reg = <0 0x2b060000 0 0x1000>;
 		interrupts = <98>;
+		clocks = <&oscclk7>;
+		clock-names = "apb_pclk";
 	};
 
 	gic: interrupt-controller@2c001000 {
@@ -84,6 +92,8 @@
 		reg = <0 0x7ffd0000 0 0x1000>;
 		interrupts = <0 86 4>,
 			     <0 87 4>;
+		clocks = <&oscclk7>;
+		clock-names = "apb_pclk";
 	};
 
 	dma@7ffb0000 {
@@ -94,6 +104,8 @@
 			     <0 89 4>,
 			     <0 90 4>,
 			     <0 91 4>;
+		clocks = <&oscclk7>;
+		clock-names = "apb_pclk";
 	};
 
 	timer {
@@ -110,7 +122,109 @@
 			     <0 69 4>;
 	};
 
-	motherboard {
+	dcc {
+		compatible = "arm,vexpress,config-bus";
+		arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+		osc@0 {
+			/* CPU PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 0>;
+			freq-range = <50000000 60000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk0";
+		};
+
+		osc@4 {
+			/* Multiplexed AXI master clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 4>;
+			freq-range = <20000000 40000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk4";
+		};
+
+		oscclk5: osc@5 {
+			/* HDLCD PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 5>;
+			freq-range = <23750000 165000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk5";
+		};
+
+		smbclk: osc@6 {
+			/* SMB clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 6>;
+			freq-range = <20000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk6";
+		};
+
+		oscclk7: osc@7 {
+			/* SYS PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 7>;
+			freq-range = <20000000 60000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk7";
+		};
+
+		osc@8 {
+			/* DDR2 PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 8>;
+			freq-range = <40000000 40000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk8";
+		};
+
+		volt@0 {
+			/* CPU core voltage */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 0>;
+			regulator-name = "Cores";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-always-on;
+			label = "Cores";
+		};
+
+		amp@0 {
+			/* Total current for the two cores */
+			compatible = "arm,vexpress-amp";
+			arm,vexpress-sysreg,func = <3 0>;
+			label = "Cores";
+		};
+
+		temp@0 {
+			/* DCC internal temperature */
+			compatible = "arm,vexpress-temp";
+			arm,vexpress-sysreg,func = <4 0>;
+			label = "DCC";
+		};
+
+		power@0 {
+			/* Total power */
+			compatible = "arm,vexpress-power";
+			arm,vexpress-sysreg,func = <12 0>;
+			label = "Cores";
+		};
+
+		energy@0 {
+			/* Total energy */
+			compatible = "arm,vexpress-energy";
+			arm,vexpress-sysreg,func = <13 0>;
+			label = "Cores";
+		};
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
 		ranges = <0 0 0 0x08000000 0x04000000>,
 			 <1 0 0 0x14000000 0x04000000>,
 			 <2 0 0 0x18000000 0x04000000>,
@@ -118,6 +232,7 @@
 			 <4 0 0 0x0c000000 0x04000000>,
 			 <5 0 0 0x10000000 0x04000000>;
 
+		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		interrupt-map = <0 0  0 &gic 0  0 4>,
 				<0 0  1 &gic 0  1 4>,
@@ -162,7 +277,7 @@
 				<0 0 40 &gic 0 40 4>,
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
+
+		/include/ "vexpress-v2m-rs1.dtsi"
 	};
 };
-
-/include/ "vexpress-v2m-rs1.dtsi"
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index 4890a81..1fc405a 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -12,6 +12,7 @@
 / {
 	model = "V2P-CA15_CA7";
 	arm,hbi = <0x249>;
+	arm,vexpress,site = <0xf>;
 	compatible = "arm,vexpress,v2p-ca15_a7", "arm,vexpress";
 	interrupt-parent = <&gic>;
 	#address-cells = <2>;
@@ -74,17 +75,23 @@
 		compatible = "arm,sp805", "arm,primecell";
 		reg = <0 0x2a490000 0 0x1000>;
 		interrupts = <98>;
+		clocks = <&oscclk6a>, <&oscclk6a>;
+		clock-names = "wdogclk", "apb_pclk";
 	};
 
 	hdlcd@2b000000 {
 		compatible = "arm,hdlcd";
 		reg = <0 0x2b000000 0 0x1000>;
 		interrupts = <0 85 4>;
+		clocks = <&oscclk5>;
+		clock-names = "pxlclk";
 	};
 
 	memory-controller@2b0a0000 {
 		compatible = "arm,pl341", "arm,primecell";
 		reg = <0 0x2b0a0000 0 0x1000>;
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
 	};
 
 	gic: interrupt-controller@2c001000 {
@@ -104,6 +111,8 @@
 		reg = <0 0x7ffd0000 0 0x1000>;
 		interrupts = <0 86 4>,
 			     <0 87 4>;
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
 	};
 
 	dma@7ff00000 {
@@ -114,6 +123,8 @@
 			     <0 89 4>,
 			     <0 90 4>,
 			     <0 91 4>;
+		clocks = <&oscclk6a>;
+		clock-names = "apb_pclk";
 	};
 
 	timer {
@@ -130,7 +141,175 @@
 			     <0 69 4>;
 	};
 
-	motherboard {
+	oscclk6a: oscclk6a {
+		/* Reference 24MHz clock */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "oscclk6a";
+	};
+
+	dcc {
+		compatible = "arm,vexpress,config-bus";
+		arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+		osc@0 {
+			/* A15 PLL 0 reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 0>;
+			freq-range = <17000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk0";
+		};
+
+		osc@1 {
+			/* A15 PLL 1 reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 1>;
+			freq-range = <17000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk1";
+		};
+
+		osc@2 {
+			/* A7 PLL 0 reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 2>;
+			freq-range = <17000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk2";
+		};
+
+		osc@3 {
+			/* A7 PLL 1 reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 3>;
+			freq-range = <17000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk3";
+		};
+
+		osc@4 {
+			/* External AXI master clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 4>;
+			freq-range = <20000000 40000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk4";
+		};
+
+		oscclk5: osc@5 {
+			/* HDLCD PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 5>;
+			freq-range = <23750000 165000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk5";
+		};
+
+		smbclk: osc@6 {
+			/* Static memory controller clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 6>;
+			freq-range = <20000000 40000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk6";
+		};
+
+		osc@7 {
+			/* SYS PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 7>;
+			freq-range = <17000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk7";
+		};
+
+		osc@8 {
+			/* DDR2 PLL reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 8>;
+			freq-range = <20000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk8";
+		};
+
+		volt@0 {
+			/* A15 CPU core voltage */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 0>;
+			regulator-name = "A15 Vcore";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-always-on;
+			label = "A15 Vcore";
+		};
+
+		volt@1 {
+			/* A7 CPU core voltage */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 1>;
+			regulator-name = "A7 Vcore";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-always-on;
+			label = "A7 Vcore";
+		};
+
+		amp@0 {
+			/* Total current for the two A15 cores */
+			compatible = "arm,vexpress-amp";
+			arm,vexpress-sysreg,func = <3 0>;
+			label = "A15 Icore";
+		};
+
+		amp@1 {
+			/* Total current for the three A7 cores */
+			compatible = "arm,vexpress-amp";
+			arm,vexpress-sysreg,func = <3 1>;
+			label = "A7 Icore";
+		};
+
+		temp@0 {
+			/* DCC internal temperature */
+			compatible = "arm,vexpress-temp";
+			arm,vexpress-sysreg,func = <4 0>;
+			label = "DCC";
+		};
+
+		power@0 {
+			/* Total power for the two A15 cores */
+			compatible = "arm,vexpress-power";
+			arm,vexpress-sysreg,func = <12 0>;
+			label = "A15 Pcore";
+		};
+		power@1 {
+			/* Total power for the three A7 cores */
+			compatible = "arm,vexpress-power";
+			arm,vexpress-sysreg,func = <12 1>;
+			label = "A7 Pcore";
+		};
+
+		energy@0 {
+			/* Total energy for the two A15 cores */
+			compatible = "arm,vexpress-energy";
+			arm,vexpress-sysreg,func = <13 0>;
+			label = "A15 Jcore";
+		};
+
+		energy@2 {
+			/* Total energy for the three A7 cores */
+			compatible = "arm,vexpress-energy";
+			arm,vexpress-sysreg,func = <13 2>;
+			label = "A7 Jcore";
+		};
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
 		ranges = <0 0 0 0x08000000 0x04000000>,
 			 <1 0 0 0x14000000 0x04000000>,
 			 <2 0 0 0x18000000 0x04000000>,
@@ -138,6 +317,7 @@
 			 <4 0 0 0x0c000000 0x04000000>,
 			 <5 0 0 0x10000000 0x04000000>;
 
+		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		interrupt-map = <0 0  0 &gic 0  0 4>,
 				<0 0  1 &gic 0  1 4>,
@@ -182,7 +362,7 @@
 				<0 0 40 &gic 0 40 4>,
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
+
+		/include/ "vexpress-v2m-rs1.dtsi"
 	};
 };
-
-/include/ "vexpress-v2m-rs1.dtsi"
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
index 18917a0..6328cbc 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
@@ -12,6 +12,7 @@
 / {
 	model = "V2P-CA5s";
 	arm,hbi = <0x225>;
+	arm,vexpress,site = <0xf>;
 	compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress";
 	interrupt-parent = <&gic>;
 	#address-cells = <1>;
@@ -56,11 +57,15 @@
 		compatible = "arm,hdlcd";
 		reg = <0x2a110000 0x1000>;
 		interrupts = <0 85 4>;
+		clocks = <&oscclk3>;
+		clock-names = "pxlclk";
 	};
 
 	memory-controller@2a150000 {
 		compatible = "arm,pl341", "arm,primecell";
 		reg = <0x2a150000 0x1000>;
+		clocks = <&oscclk1>;
+		clock-names = "apb_pclk";
 	};
 
 	memory-controller@2a190000 {
@@ -68,6 +73,8 @@
 		reg = <0x2a190000 0x1000>;
 		interrupts = <0 86 4>,
 			     <0 87 4>;
+		clocks = <&oscclk1>;
+		clock-names = "apb_pclk";
 	};
 
 	scu@2c000000 {
@@ -109,7 +116,77 @@
 			     <0 69 4>;
 	};
 
-	motherboard {
+	dcc {
+		compatible = "arm,vexpress,config-bus";
+		arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+		osc@0 {
+			/* CPU and internal AXI reference clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 0>;
+			freq-range = <50000000 100000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk0";
+		};
+
+		oscclk1: osc@1 {
+			/* Multiplexed AXI master clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 1>;
+			freq-range = <5000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk1";
+		};
+
+		osc@2 {
+			/* DDR2 */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 2>;
+			freq-range = <80000000 120000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk2";
+		};
+
+		oscclk3: osc@3 {
+			/* HDLCD */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 3>;
+			freq-range = <23750000 165000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk3";
+		};
+
+		osc@4 {
+			/* Test chip gate configuration */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 4>;
+			freq-range = <80000000 80000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk4";
+		};
+
+		smbclk: osc@5 {
+			/* SMB clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 5>;
+			freq-range = <25000000 60000000>;
+			#clock-cells = <0>;
+			clock-output-names = "oscclk5";
+		};
+
+		temp@0 {
+			/* DCC internal operating temperature */
+			compatible = "arm,vexpress-temp";
+			arm,vexpress-sysreg,func = <4 0>;
+			label = "DCC";
+		};
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
 		ranges = <0 0 0x08000000 0x04000000>,
 			 <1 0 0x14000000 0x04000000>,
 			 <2 0 0x18000000 0x04000000>,
@@ -117,6 +194,7 @@
 			 <4 0 0x0c000000 0x04000000>,
 			 <5 0 0x10000000 0x04000000>;
 
+		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		interrupt-map = <0 0  0 &gic 0  0 4>,
 				<0 0  1 &gic 0  1 4>,
@@ -161,7 +239,7 @@
 				<0 0 40 &gic 0 40 4>,
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
+
+		/include/ "vexpress-v2m-rs1.dtsi"
 	};
 };
-
-/include/ "vexpress-v2m-rs1.dtsi"
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
index 3f0c736..1420bb1 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -12,6 +12,7 @@
 / {
 	model = "V2P-CA9";
 	arm,hbi = <0x191>;
+	arm,vexpress,site = <0xf>;
 	compatible = "arm,vexpress,v2p-ca9", "arm,vexpress";
 	interrupt-parent = <&gic>;
 	#address-cells = <1>;
@@ -70,11 +71,15 @@
 		compatible = "arm,pl111", "arm,primecell";
 		reg = <0x10020000 0x1000>;
 		interrupts = <0 44 4>;
+		clocks = <&oscclk1>, <&oscclk2>;
+		clock-names = "clcdclk", "apb_pclk";
 	};
 
 	memory-controller@100e0000 {
 		compatible = "arm,pl341", "arm,primecell";
 		reg = <0x100e0000 0x1000>;
+		clocks = <&oscclk2>;
+		clock-names = "apb_pclk";
 	};
 
 	memory-controller@100e1000 {
@@ -82,6 +87,8 @@
 		reg = <0x100e1000 0x1000>;
 		interrupts = <0 45 4>,
 			     <0 46 4>;
+		clocks = <&oscclk2>;
+		clock-names = "apb_pclk";
 	};
 
 	timer@100e4000 {
@@ -89,12 +96,16 @@
 		reg = <0x100e4000 0x1000>;
 		interrupts = <0 48 4>,
 			     <0 49 4>;
+		clocks = <&oscclk2>, <&oscclk2>;
+		clock-names = "timclk", "apb_pclk";
 	};
 
 	watchdog@100e5000 {
 		compatible = "arm,sp805", "arm,primecell";
 		reg = <0x100e5000 0x1000>;
 		interrupts = <0 51 4>;
+		clocks = <&oscclk2>, <&oscclk2>;
+		clock-names = "wdogclk", "apb_pclk";
 	};
 
 	scu@1e000000 {
@@ -140,13 +151,132 @@
 			     <0 63 4>;
 	};
 
-	motherboard {
+	dcc {
+		compatible = "arm,vexpress,config-bus";
+		arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+		osc@0 {
+			/* ACLK clock to the AXI master port on the test chip */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 0>;
+			freq-range = <30000000 50000000>;
+			#clock-cells = <0>;
+			clock-output-names = "extsaxiclk";
+		};
+
+		oscclk1: osc@1 {
+			/* Reference clock for the CLCD */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 1>;
+			freq-range = <10000000 80000000>;
+			#clock-cells = <0>;
+			clock-output-names = "clcdclk";
+		};
+
+		smbclk: oscclk2: osc@2 {
+			/* Reference clock for the test chip internal PLLs */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 2>;
+			freq-range = <33000000 100000000>;
+			#clock-cells = <0>;
+			clock-output-names = "tcrefclk";
+		};
+
+		volt@0 {
+			/* Test Chip internal logic voltage */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 0>;
+			regulator-name = "VD10";
+			regulator-always-on;
+			label = "VD10";
+		};
+
+		volt@1 {
+			/* PL310, L2 cache, RAM cell supply (not PL310 logic) */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 1>;
+			regulator-name = "VD10_S2";
+			regulator-always-on;
+			label = "VD10_S2";
+		};
+
+		volt@2 {
+			/* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 2>;
+			regulator-name = "VD10_S3";
+			regulator-always-on;
+			label = "VD10_S3";
+		};
+
+		volt@3 {
+			/* DDR2 SDRAM and Test Chip DDR2 I/O supply */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 3>;
+			regulator-name = "VCC1V8";
+			regulator-always-on;
+			label = "VCC1V8";
+		};
+
+		volt@4 {
+			/* DDR2 SDRAM VTT termination voltage */
+			compatible = "arm,vexpress-volt";
+			arm,vexpress-sysreg,func = <2 4>;
+			regulator-name = "DDR2VTT";
+			regulator-always-on;
+			label = "DDR2VTT";
+		};
+
+		volt@5 {
+			/* Local board supply for miscellaneous logic external to the Test Chip */
+			arm,vexpress-sysreg,func = <2 5>;
+			compatible = "arm,vexpress-volt";
+			regulator-name = "VCC3V3";
+			regulator-always-on;
+			label = "VCC3V3";
+		};
+
+		amp@0 {
+			/* PL310, L2 cache, RAM cell supply (not PL310 logic) */
+			compatible = "arm,vexpress-amp";
+			arm,vexpress-sysreg,func = <3 0>;
+			label = "VD10_S2";
+		};
+
+		amp@1 {
+			/* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
+			compatible = "arm,vexpress-amp";
+			arm,vexpress-sysreg,func = <3 1>;
+			label = "VD10_S3";
+		};
+
+		power@0 {
+			/* PL310, L2 cache, RAM cell supply (not PL310 logic) */
+			compatible = "arm,vexpress-power";
+			arm,vexpress-sysreg,func = <12 0>;
+			label = "PVD10_S2";
+		};
+
+		power@1 {
+			/* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */
+			compatible = "arm,vexpress-power";
+			arm,vexpress-sysreg,func = <12 1>;
+			label = "PVD10_S3";
+		};
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
 		ranges = <0 0 0x40000000 0x04000000>,
 			 <1 0 0x44000000 0x04000000>,
 			 <2 0 0x48000000 0x04000000>,
 			 <3 0 0x4c000000 0x04000000>,
 			 <7 0 0x10000000 0x00020000>;
 
+		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		interrupt-map = <0 0  0 &gic 0  0 4>,
 				<0 0  1 &gic 0  1 4>,
@@ -191,7 +321,7 @@
 				<0 0 40 &gic 0 40 4>,
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
+
+		/include/ "vexpress-v2m.dtsi"
 	};
 };
-
-/include/ "vexpress-v2m.dtsi"
diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig
index f78d259..3d76407 100644
--- a/arch/arm/configs/armadillo800eva_defconfig
+++ b/arch/arm/configs/armadillo800eva_defconfig
@@ -7,6 +7,7 @@
 # CONFIG_IPC_NS is not set
 # CONFIG_PID_NS is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
index 7aea702..74e27f0 100644
--- a/arch/arm/configs/bcm2835_defconfig
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -66,8 +66,6 @@
 # CONFIG_FILE_LOCKING is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY_USER is not set
-# CONFIG_PROC_FS is not set
-# CONFIG_SYSFS is not set
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_PRINTK_TIME=y
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig
new file mode 100644
index 0000000..e3bf2d6
--- /dev/null
+++ b/arch/arm/configs/bcm_defconfig
@@ -0,0 +1,114 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_BLK_CGROUP=y
+CONFIG_NAMESPACES=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_EFI_PARTITION=y
+CONFIG_ARCH_BCM=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_COMPACTION is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_CMDLINE="console=ttyS0,115200n8 mem=128M"
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_BLK_DEV is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_JOYDEV=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_HWMON is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=110
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_LL=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC7=y
+CONFIG_XZ_DEC=y
+CONFIG_AVERAGE=y
diff --git a/arch/arm/configs/clps711x_defconfig b/arch/arm/configs/clps711x_defconfig
new file mode 100644
index 0000000..1cd94c3
--- /dev/null
+++ b/arch/arm/configs/clps711x_defconfig
@@ -0,0 +1,90 @@
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_LZMA=y
+CONFIG_EMBEDDED=y
+CONFIG_SLOB=y
+CONFIG_JUMP_LABEL=y
+# CONFIG_LBDAF is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_CLPS711X=y
+CONFIG_ARCH_AUTCPU12=y
+CONFIG_ARCH_CDB89712=y
+CONFIG_ARCH_CLEP7312=y
+CONFIG_ARCH_EDB7211=y
+CONFIG_ARCH_P720T=y
+CONFIG_ARCH_FORTUNET=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_COREDUMP is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+CONFIG_IRDA=y
+CONFIG_IRTTY_SIR=y
+CONFIG_EP7211_DONGLE=y
+# CONFIG_WIRELESS is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_AUTCPU12=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_GPIO=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+CONFIG_CS89x0=y
+CONFIG_CS89x0_PLATFORM=y
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL 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_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_CLPS711X_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_SPI=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_CLPS711X=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_PLATFORM=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_MINIX_FS=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/edb7211_defconfig b/arch/arm/configs/edb7211_defconfig
deleted file mode 100644
index d52ded35..0000000
--- a/arch/arm/configs/edb7211_defconfig
+++ /dev/null
@@ -1,27 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-# CONFIG_HOTPLUG is not set
-CONFIG_ARCH_CLPS711X=y
-CONFIG_ARCH_EDB7211=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IPV6 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_NETDEVICES=y
-# CONFIG_INPUT is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_VT is not set
-CONFIG_SERIAL_CLPS711X=y
-CONFIG_SERIAL_CLPS711X_CONSOLE=y
-CONFIG_EXT2_FS=y
-CONFIG_MINIX_FS=y
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_MSDOS_PARTITION is not set
-CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/fortunet_defconfig b/arch/arm/configs/fortunet_defconfig
deleted file mode 100644
index 840fced..0000000
--- a/arch/arm/configs/fortunet_defconfig
+++ /dev/null
@@ -1,28 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-# CONFIG_HOTPLUG is not set
-CONFIG_ARCH_CLPS711X=y
-CONFIG_ARCH_FORTUNET=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_FASTFPE=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_NET=y
-CONFIG_UNIX=y
-CONFIG_MTD=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_BLK_DEV_RAM=y
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_CLPS711X=y
-CONFIG_SERIAL_CLPS711X_CONSOLE=y
-CONFIG_EXT2_FS=y
-CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
index 78ed575..f71302c 100644
--- a/arch/arm/configs/imx_v4_v5_defconfig
+++ b/arch/arm/configs/imx_v4_v5_defconfig
@@ -18,7 +18,9 @@
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
 CONFIG_ARCH_MXC=y
-CONFIG_ARCH_IMX_V4_V5=y
+CONFIG_ARCH_MULTI_V4T=y
+CONFIG_ARCH_MULTI_V5=y
+# CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_MX1ADS=y
 CONFIG_MACH_SCB9328=y
 CONFIG_MACH_APF9328=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 66aa7a6..44f117a 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -17,6 +17,8 @@
 CONFIG_MODULE_SRCVERSION_ALL=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_MXC=y
+CONFIG_ARCH_MULTI_V6=y
+CONFIG_ARCH_MULTI_V7=y
 CONFIG_MACH_MX31LILLY=y
 CONFIG_MACH_MX31LITE=y
 CONFIG_MACH_PCM037=y
@@ -139,6 +141,7 @@
 CONFIG_SPI=y
 CONFIG_SPI_IMX=y
 CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_MC9S08DZ60=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_IMX2_WDT=y
@@ -155,6 +158,7 @@
 CONFIG_SOC_CAMERA_OV2640=y
 CONFIG_VIDEO_MX3=y
 CONFIG_FB=y
+CONFIG_LCD_PLATFORM=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_L4F00242T03=y
diff --git a/arch/arm/configs/marzen_defconfig b/arch/arm/configs/marzen_defconfig
index 53382b6..f79b55c 100644
--- a/arch/arm/configs/marzen_defconfig
+++ b/arch/arm/configs/marzen_defconfig
@@ -69,6 +69,8 @@
 CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_RCAR=y
 CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
 CONFIG_THERMAL=y
diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig
index 7bcf850..3458752 100644
--- a/arch/arm/configs/mvebu_defconfig
+++ b/arch/arm/configs/mvebu_defconfig
@@ -1,6 +1,6 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
-CONFIG_NO_HZ=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
@@ -9,10 +9,12 @@
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_MVEBU=y
-CONFIG_MACH_ARMADA_370_XP=y
+CONFIG_MACH_ARMADA_370=y
+CONFIG_MACH_ARMADA_XP=y
+# CONFIG_CACHE_L2X0 is not set
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
-CONFIG_USE_OF=y
+# CONFIG_COMPACTION is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
@@ -23,6 +25,8 @@
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index e2184f6..a7827fd 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -80,6 +80,10 @@
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_CMA=y
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_M25P80=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_AD525X_DPOT=y
@@ -98,12 +102,12 @@
 CONFIG_USB_USBNET=y
 CONFIG_USB_NET_SMSC75XX=y
 CONFIG_USB_NET_SMSC95XX=y
+CONFIG_BRCMFMAC=m
 CONFIG_RT2X00=y
 CONFIG_RT2800USB=m
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MPU3050=y
-# CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
@@ -116,7 +120,8 @@
 CONFIG_I2C_MUX_PINCTRL=y
 CONFIG_I2C_TEGRA=y
 CONFIG_SPI=y
-CONFIG_SPI_TEGRA=y
+CONFIG_SPI_TEGRA20_SFLASH=y
+CONFIG_SPI_TEGRA20_SLINK=y
 CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_TPS6586X=y
 CONFIG_GPIO_TPS65910=y
@@ -138,6 +143,15 @@
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
+CONFIG_DRM=y
+CONFIG_DRM_TEGRA=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 # CONFIG_SND_SUPPORT_OLD_API is not set
@@ -205,6 +219,9 @@
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
 CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
index cdd4d2b..2ba9e63 100644
--- a/arch/arm/configs/versatile_defconfig
+++ b/arch/arm/configs/versatile_defconfig
@@ -1,3 +1,4 @@
+CONFIG_ARCH_VERSATILE=y
 CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h
index 59426a4..e847d23 100644
--- a/arch/arm/include/asm/flat.h
+++ b/arch/arm/include/asm/flat.h
@@ -8,7 +8,7 @@
 #define	flat_argvp_envp_on_stack()		1
 #define	flat_old_ram_flag(flags)		(flags)
 #define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
-#define	flat_get_addr_from_rp(rp, relval, flags, persistent) get_unaligned(rp)
+#define	flat_get_addr_from_rp(rp, relval, flags, persistent) ((void)persistent,get_unaligned(rp))
 #define	flat_put_addr_at_rp(rp, val, relval)	put_unaligned(val,rp)
 #define	flat_get_relocate_addr(rel)		(rel)
 #define	flat_set_persistent(relval, p)		0
diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h
index 6b9b077..6636430 100644
--- a/arch/arm/include/asm/hardware/sp810.h
+++ b/arch/arm/include/asm/hardware/sp810.h
@@ -50,11 +50,7 @@
 #define SCPCELLID2		0xFF8
 #define SCPCELLID3		0xFFC
 
-#define SCCTRL_TIMEREN0SEL_REFCLK	(0 << 15)
-#define SCCTRL_TIMEREN0SEL_TIMCLK	(1 << 15)
-
-#define SCCTRL_TIMEREN1SEL_REFCLK	(0 << 17)
-#define SCCTRL_TIMEREN1SEL_TIMCLK	(1 << 17)
+#define SCCTRL_TIMERENnSEL_SHIFT(n)	(15 + ((n) * 2))
 
 static inline void sysctl_soft_reset(void __iomem *base)
 {
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 35c1ed8..42f042e 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -64,7 +64,7 @@
 static inline void __raw_writew(u16 val, volatile void __iomem *addr)
 {
 	asm volatile("strh %1, %0"
-		     : "+Qo" (*(volatile u16 __force *)addr)
+		     : "+Q" (*(volatile u16 __force *)addr)
 		     : "r" (val));
 }
 
@@ -72,7 +72,7 @@
 {
 	u16 val;
 	asm volatile("ldrh %1, %0"
-		     : "+Qo" (*(volatile u16 __force *)addr),
+		     : "+Q" (*(volatile u16 __force *)addr),
 		       "=r" (val));
 	return val;
 }
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
index 195ac2f..2fe141f 100644
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -40,6 +40,13 @@
 extern void vm_reserve_area_early(unsigned long addr, unsigned long size,
 				  void *caller);
 
+#ifdef CONFIG_DEBUG_LL
+extern void debug_ll_addr(unsigned long *paddr, unsigned long *vaddr);
+extern void debug_ll_io_init(void);
+#else
+static inline void debug_ll_io_init(void) {}
+#endif
+
 struct mem_type;
 extern const struct mem_type *get_mem_type(unsigned int type);
 /*
diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h
index 05b8e82..e3f7572 100644
--- a/arch/arm/include/asm/sched_clock.h
+++ b/arch/arm/include/asm/sched_clock.h
@@ -10,7 +10,5 @@
 
 extern void sched_clock_postinit(void);
 extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate);
-extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits,
-		unsigned long rate);
 
 #endif
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 77bd79f..7e1f760 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -200,8 +200,8 @@
 #define USER_DS			KERNEL_DS
 
 #define segment_eq(a,b)		(1)
-#define __addr_ok(addr)		(1)
-#define __range_ok(addr,size)	(0)
+#define __addr_ok(addr)		((void)(addr),1)
+#define __range_ok(addr,size)	((void)(addr),0)
 #define get_fs()		(KERNEL_DS)
 
 static inline void set_fs(mm_segment_t fs)
diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h
index 6a6f1e4..301c1db 100644
--- a/arch/arm/include/asm/vfpmacros.h
+++ b/arch/arm/include/asm/vfpmacros.h
@@ -27,9 +27,9 @@
 #if __LINUX_ARM_ARCH__ <= 6
 	ldr	\tmp, =elf_hwcap		    @ may not have MVFR regs
 	ldr	\tmp, [\tmp, #0]
-	tst	\tmp, #HWCAP_VFPv3D16
-	ldceql	p11, cr0, [\base],#32*4		    @ FLDMIAD \base!, {d16-d31}
-	addne	\base, \base, #32*4		    @ step over unused register space
+	tst	\tmp, #HWCAP_VFPD32
+	ldcnel	p11, cr0, [\base],#32*4		    @ FLDMIAD \base!, {d16-d31}
+	addeq	\base, \base, #32*4		    @ step over unused register space
 #else
 	VFPFMRX	\tmp, MVFR0			    @ Media and VFP Feature Register 0
 	and	\tmp, \tmp, #MVFR0_A_SIMD_MASK	    @ A_SIMD field
@@ -51,9 +51,9 @@
 #if __LINUX_ARM_ARCH__ <= 6
 	ldr	\tmp, =elf_hwcap		    @ may not have MVFR regs
 	ldr	\tmp, [\tmp, #0]
-	tst	\tmp, #HWCAP_VFPv3D16
-	stceql	p11, cr0, [\base],#32*4		    @ FSTMIAD \base!, {d16-d31}
-	addne	\base, \base, #32*4		    @ step over unused register space
+	tst	\tmp, #HWCAP_VFPD32
+	stcnel	p11, cr0, [\base],#32*4		    @ FSTMIAD \base!, {d16-d31}
+	addeq	\base, \base, #32*4		    @ step over unused register space
 #else
 	VFPFMRX	\tmp, MVFR0			    @ Media and VFP Feature Register 0
 	and	\tmp, \tmp, #MVFR0_A_SIMD_MASK	    @ A_SIMD field
diff --git a/arch/arm/include/asm/xen/interface.h b/arch/arm/include/asm/xen/interface.h
index ae05e56..5000397 100644
--- a/arch/arm/include/asm/xen/interface.h
+++ b/arch/arm/include/asm/xen/interface.h
@@ -29,16 +29,22 @@
 
 #ifndef __ASSEMBLY__
 /* Explicitly size integers that represent pfns in the interface with
- * Xen so that we can have one ABI that works for 32 and 64 bit guests. */
+ * Xen so that we can have one ABI that works for 32 and 64 bit guests.
+ * Note that this means that the xen_pfn_t type may be capable of
+ * representing pfn's which the guest cannot represent in its own pfn
+ * type. However since pfn space is controlled by the guest this is
+ * fine since it simply wouldn't be able to create any sure pfns in
+ * the first place.
+ */
 typedef uint64_t xen_pfn_t;
+#define PRI_xen_pfn "llx"
 typedef uint64_t xen_ulong_t;
+#define PRI_xen_ulong "llx"
 /* Guest handles for primitive C types. */
 __DEFINE_GUEST_HANDLE(uchar, unsigned char);
 __DEFINE_GUEST_HANDLE(uint,  unsigned int);
-__DEFINE_GUEST_HANDLE(ulong, unsigned long);
 DEFINE_GUEST_HANDLE(char);
 DEFINE_GUEST_HANDLE(int);
-DEFINE_GUEST_HANDLE(long);
 DEFINE_GUEST_HANDLE(void);
 DEFINE_GUEST_HANDLE(uint64_t);
 DEFINE_GUEST_HANDLE(uint32_t);
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 1742023..c6b9096 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -10,7 +10,7 @@
 #include <xen/interface/grant_table.h>
 
 #define pfn_to_mfn(pfn)			(pfn)
-#define phys_to_machine_mapping_valid	(1)
+#define phys_to_machine_mapping_valid(pfn) (1)
 #define mfn_to_pfn(mfn)			(mfn)
 #define mfn_to_virt(m)			(__va(mfn_to_pfn(m) << PAGE_SHIFT))
 
@@ -30,6 +30,8 @@
 #define XMADDR(x)	((xmaddr_t) { .maddr = (x) })
 #define XPADDR(x)	((xpaddr_t) { .paddr = (x) })
 
+#define INVALID_P2M_ENTRY      (~0UL)
+
 static inline xmaddr_t phys_to_machine(xpaddr_t phys)
 {
 	unsigned offset = phys.paddr & ~PAGE_MASK;
@@ -74,9 +76,14 @@
 	return 0;
 }
 
+static inline bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+	BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
+	return true;
+}
+
 static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 {
-	BUG();
-	return false;
+	return __set_phys_to_machine(pfn, mfn);
 }
 #endif /* _ASM_ARM_XEN_PAGE_H */
diff --git a/arch/arm/include/debug/8250_32.S b/arch/arm/include/debug/8250_32.S
new file mode 100644
index 0000000..8db01ee
--- /dev/null
+++ b/arch/arm/include/debug/8250_32.S
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Picochip Ltd., Jamie Iles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Derived from arch/arm/mach-davinci/include/mach/debug-macro.S to use 32-bit
+ * accesses to the 8250.
+ */
+
+#include <linux/serial_reg.h>
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #UART_TX << UART_SHIFT]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldr	\rd, [\rx, #UART_LSR << UART_SHIFT]
+		and	\rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
+		teq	\rd, #UART_LSR_TEMT | UART_LSR_THRE
+		bne	1002b
+		.endm
+
+		/* The UART's don't have any flow control IO's wired up. */
+		.macro	waituart,rd,rx
+		.endm
diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S
new file mode 100644
index 0000000..0b65d79
--- /dev/null
+++ b/arch/arm/include/debug/imx.S
@@ -0,0 +1,62 @@
+/* arch/arm/mach-imx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifdef CONFIG_DEBUG_IMX1_UART
+#define UART_PADDR	0x00206000
+#elif defined (CONFIG_DEBUG_IMX25_UART)
+#define UART_PADDR	0x43f90000
+#elif defined (CONFIG_DEBUG_IMX21_IMX27_UART)
+#define UART_PADDR	0x1000a000
+#elif defined (CONFIG_DEBUG_IMX31_IMX35_UART)
+#define UART_PADDR	0x43f90000
+#elif defined (CONFIG_DEBUG_IMX51_UART)
+#define UART_PADDR	0x73fbc000
+#elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
+#define UART_PADDR	0x53fbc000
+#elif defined (CONFIG_DEBUG_IMX6Q_UART2)
+#define UART_PADDR	0x021e8000
+#elif defined (CONFIG_DEBUG_IMX6Q_UART4)
+#define UART_PADDR	0x021f0000
+#endif
+
+/*
+ * FIXME: This is a copy of IMX_IO_P2V in hardware.h, and needs to
+ * stay sync with that.  It's hard to maintain, and should be fixed
+ * globally for multi-platform build to use a fixed virtual address
+ * for low-level debug uart port across platforms.
+ */
+#define IMX_IO_P2V(x)	(						\
+			(((x) & 0x80000000) >> 7) |			\
+			(0xf4000000 +					\
+			(((x) & 0x50000000) >> 6) +			\
+			(((x) & 0x0b000000) >> 4) +			\
+			(((x) & 0x000fffff))))
+
+#define UART_VADDR	IMX_IO_P2V(UART_PADDR)
+
+		.macro	addruart, rp, rv, tmp
+		ldr	\rp, =UART_PADDR	@ physical
+		ldr	\rv, =UART_VADDR	@ virtual
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x40]	@ TXDATA
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldr	\rd, [\rx, #0x98]	@ SR2
+		tst	\rd, #1 << 3		@ TXDC
+		beq	1002b			@ wait until transmit done
+		.endm
diff --git a/arch/arm/include/debug/picoxcell.S b/arch/arm/include/debug/picoxcell.S
index 7419deb..bc1f07c 100644
--- a/arch/arm/include/debug/picoxcell.S
+++ b/arch/arm/include/debug/picoxcell.S
@@ -5,10 +5,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * Derived from arch/arm/mach-davinci/include/mach/debug-macro.S to use 32-bit
- * accesses to the 8250.
  */
-#include <linux/serial_reg.h>
 
 #define UART_SHIFT 2
 #define PICOXCELL_UART1_BASE		0x80230000
@@ -19,17 +16,4 @@
 		ldr	\rp, =PICOXCELL_UART1_BASE
 		.endm
 
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #UART_TX << UART_SHIFT]
-		.endm
-
-		.macro	busyuart,rd,rx
-1002:		ldr	\rd, [\rx, #UART_LSR << UART_SHIFT]
-		and	\rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
-		teq	\rd, #UART_LSR_TEMT | UART_LSR_THRE
-		bne	1002b
-		.endm
-
-		/* The UART's don't have any flow control IO's wired up. */
-		.macro	waituart,rd,rx
-		.endm
+#include "8250_32.S"
diff --git a/arch/arm/include/debug/socfpga.S b/arch/arm/include/debug/socfpga.S
index d6f26d2..966b2f9 100644
--- a/arch/arm/include/debug/socfpga.S
+++ b/arch/arm/include/debug/socfpga.S
@@ -7,6 +7,9 @@
  * published by the Free Software Foundation.
  */
 
+#define UART_SHIFT 2
+#define DEBUG_LL_UART_OFFSET	0x00002000
+
 		.macro	addruart, rp, rv, tmp
 		mov	\rp, #DEBUG_LL_UART_OFFSET
 		orr	\rp, \rp, #0x00c00000
@@ -14,3 +17,5 @@
 		orr	\rp, \rp, #0xff000000	@ physical base
 		.endm
 
+#include "8250_32.S"
+
diff --git a/arch/arm/include/debug/sunxi.S b/arch/arm/include/debug/sunxi.S
new file mode 100644
index 0000000..04eb56d
--- /dev/null
+++ b/arch/arm/include/debug/sunxi.S
@@ -0,0 +1,27 @@
+/*
+ * Early serial output macro for Allwinner A1X SoCs
+ *
+ * Copyright (C) 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#if defined(CONFIG_DEBUG_SUNXI_UART0)
+#define SUNXI_UART_DEBUG_PHYS_BASE 0x01c28000
+#define SUNXI_UART_DEBUG_VIRT_BASE 0xf1c28000
+#elif defined(CONFIG_DEBUG_SUNXI_UART1)
+#define SUNXI_UART_DEBUG_PHYS_BASE 0x01c28400
+#define SUNXI_UART_DEBUG_VIRT_BASE 0xf1c28400
+#endif
+
+	.macro	addruart, rp, rv, tmp
+	ldr	\rp, =SUNXI_UART_DEBUG_PHYS_BASE
+	ldr	\rv, =SUNXI_UART_DEBUG_VIRT_BASE
+	.endm
+
+#define UART_SHIFT	2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/include/uapi/asm/hwcap.h b/arch/arm/include/uapi/asm/hwcap.h
index f254f65..3688fd1 100644
--- a/arch/arm/include/uapi/asm/hwcap.h
+++ b/arch/arm/include/uapi/asm/hwcap.h
@@ -18,11 +18,12 @@
 #define HWCAP_THUMBEE	(1 << 11)
 #define HWCAP_NEON	(1 << 12)
 #define HWCAP_VFPv3	(1 << 13)
-#define HWCAP_VFPv3D16	(1 << 14)
+#define HWCAP_VFPv3D16	(1 << 14)	/* also set for VFPv4-D16 */
 #define HWCAP_TLS	(1 << 15)
 #define HWCAP_VFPv4	(1 << 16)
 #define HWCAP_IDIVA	(1 << 17)
 #define HWCAP_IDIVT	(1 << 18)
+#define HWCAP_VFPD32	(1 << 19)	/* set if VFP has 32 regs (not 16) */
 #define HWCAP_IDIV	(HWCAP_IDIVA | HWCAP_IDIVT)
 
 
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index 66f711b..6809200 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -100,6 +100,13 @@
 		b	1b
 ENDPROC(printch)
 
+ENTRY(debug_ll_addr)
+		addruart r2, r3, ip
+		str	r2, [r0]
+		str	r3, [r1]
+		mov	pc, lr
+ENDPROC(debug_ll_addr)
+
 #else
 
 ENTRY(printascii)
@@ -119,4 +126,11 @@
 		mov	pc, lr
 ENDPROC(printch)
 
+ENTRY(debug_ll_addr)
+		mov	r2, #0
+		str	r2, [r0]
+		str	r2, [r1]
+		mov	pc, lr
+ENDPROC(debug_ll_addr)
+
 #endif
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 16cedb4..8961650 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -34,6 +34,7 @@
 #include <linux/list.h>
 #include <linux/kallsyms.h>
 #include <linux/proc_fs.h>
+#include <linux/export.h>
 
 #include <asm/exception.h>
 #include <asm/mach/arch.h>
@@ -109,6 +110,7 @@
 	/* Order is clear bits in "clr" then set bits in "set" */
 	irq_modify_status(irq, clr, set & ~clr);
 }
+EXPORT_SYMBOL_GPL(set_irq_flags);
 
 void __init init_IRQ(void)
 {
diff --git a/arch/arm/kernel/kprobes-test-arm.c b/arch/arm/kernel/kprobes-test-arm.c
index 38c1a3b..8393129 100644
--- a/arch/arm/kernel/kprobes-test-arm.c
+++ b/arch/arm/kernel/kprobes-test-arm.c
@@ -366,7 +366,9 @@
 	TEST_UNSUPPORTED(".word 0xe04f0392 @ umaal r0, pc, r2, r3")
 	TEST_UNSUPPORTED(".word 0xe0500090 @ undef")
 	TEST_UNSUPPORTED(".word 0xe05fff9f @ undef")
+#endif
 
+#if __LINUX_ARM_ARCH__ >= 7
 	TEST_RRR(  "mls		r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"")
 	TEST_RRR(  "mlshi	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"")
 	TEST_RR(   "mls		lr, r",1, VAL2,", r",2, VAL3,", r13")
@@ -456,6 +458,8 @@
 	TEST_UNSUPPORTED(".word	0xe1700090") /* Unallocated space */
 #if __LINUX_ARM_ARCH__ >= 6
 	TEST_UNSUPPORTED("ldrex	r2, [sp]")
+#endif
+#if (__LINUX_ARM_ARCH__ >= 7) || defined(CONFIG_CPU_32v6K)
 	TEST_UNSUPPORTED("strexd	r0, r2, r3, [sp]")
 	TEST_UNSUPPORTED("ldrexd	r2, r3, [sp]")
 	TEST_UNSUPPORTED("strexb	r0, r2, [sp]")
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index e29c333..8ef8c93 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -45,10 +45,9 @@
 	for (i = 0; i < image->nr_segments; i++) {
 		current_segment = &image->segment[i];
 
-		err = memblock_is_region_memory(current_segment->mem,
-						current_segment->memsz);
-		if (err)
-			return - EINVAL;
+		if (!memblock_is_region_memory(current_segment->mem,
+					       current_segment->memsz))
+			return -EINVAL;
 
 		err = get_user(header, (__be32*)current_segment->buf);
 		if (err)
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 93971b1..53c0304 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -96,6 +96,10 @@
 	s64 period = hwc->sample_period;
 	int ret = 0;
 
+	/* The period may have been changed by PERF_EVENT_IOC_PERIOD */
+	if (unlikely(period != hwc->last_period))
+		left = period - (hwc->last_period - left);
+
 	if (unlikely(left <= -period)) {
 		left = period;
 		local64_set(&hwc->period_left, left);
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
index e21bac2..fc6692e 100644
--- a/arch/arm/kernel/sched_clock.c
+++ b/arch/arm/kernel/sched_clock.c
@@ -107,13 +107,6 @@
 	update_sched_clock();
 }
 
-void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits,
-		unsigned long rate)
-{
-	setup_sched_clock(read, bits, rate);
-	cd.needs_suspend = true;
-}
-
 void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
 {
 	unsigned long r, w;
@@ -189,18 +182,15 @@
 static int sched_clock_suspend(void)
 {
 	sched_clock_poll(sched_clock_timer.data);
-	if (cd.needs_suspend)
-		cd.suspended = true;
+	cd.suspended = true;
 	return 0;
 }
 
 static void sched_clock_resume(void)
 {
-	if (cd.needs_suspend) {
-		cd.epoch_cyc = read_sched_clock();
-		cd.epoch_cyc_copy = cd.epoch_cyc;
-		cd.suspended = false;
-	}
+	cd.epoch_cyc = read_sched_clock();
+	cd.epoch_cyc_copy = cd.epoch_cyc;
+	cd.suspended = false;
 }
 
 static struct syscore_ops sched_clock_ops = {
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 8e20754d..fbc8b26 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -294,18 +294,24 @@
 asmlinkage void __cpuinit secondary_start_kernel(void)
 {
 	struct mm_struct *mm = &init_mm;
-	unsigned int cpu = smp_processor_id();
+	unsigned int cpu;
+
+	/*
+	 * The identity mapping is uncached (strongly ordered), so
+	 * switch away from it before attempting any exclusive accesses.
+	 */
+	cpu_switch_mm(mm->pgd, mm);
+	enter_lazy_tlb(mm, current);
+	local_flush_tlb_all();
 
 	/*
 	 * All kernel threads share the same mm context; grab a
 	 * reference and switch to it.
 	 */
+	cpu = smp_processor_id();
 	atomic_inc(&mm->mm_count);
 	current->active_mm = mm;
 	cpumask_set_cpu(cpu, mm_cpumask(mm));
-	cpu_switch_mm(mm->pgd, mm);
-	enter_lazy_tlb(mm, current);
-	local_flush_tlb_all();
 
 	printk("CPU%u: Booted secondary processor\n", cpu);
 
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index e1f9069..999aa48 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -42,10 +42,10 @@
 
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		/* timer load already set up */
 		ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE
 			| TWD_TIMER_CONTROL_PERIODIC;
-		__raw_writel(twd_timer_rate / HZ, twd_base + TWD_TIMER_LOAD);
+		__raw_writel(DIV_ROUND_CLOSEST(twd_timer_rate, HZ),
+			twd_base + TWD_TIMER_LOAD);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		/* period set, and timer enabled in 'next_event' hook */
@@ -366,10 +366,8 @@
 	int err;
 
 	np = of_find_matching_node(NULL, twd_of_match);
-	if (!np) {
-		err = -ENODEV;
-		goto out;
-	}
+	if (!np)
+		return;
 
 	twd_ppi = irq_of_parse_and_map(np, 0);
 	if (!twd_ppi) {
diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
index 9d0a300..0dc5385 100644
--- a/arch/arm/lib/delay.c
+++ b/arch/arm/lib/delay.c
@@ -45,6 +45,7 @@
 	*timer_val = delay_timer->read_current_timer();
 	return 0;
 }
+EXPORT_SYMBOL_GPL(read_current_timer);
 
 static void __timer_delay(unsigned long cycles)
 {
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index b142071..0436242 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -21,19 +21,13 @@
 	bool
 	select CPU_ARM926T
 	select GENERIC_CLOCKEVENTS
+	select MULTI_IRQ_HANDLER
+	select SPARSE_IRQ
 
 menu "Atmel AT91 System-on-Chip"
 
 comment "Atmel AT91 Processor"
 
-config SOC_AT91SAM9
-	bool
-	select AT91_SAM9_SMC
-	select AT91_SAM9_TIME
-	select CPU_ARM926T
-	select MULTI_IRQ_HANDLER
-	select SPARSE_IRQ
-
 config SOC_AT91RM9200
 	bool "AT91RM9200"
 	select CPU_ARM920T
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index b4f0565..5269825 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -187,7 +187,7 @@
 	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
-	CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200", &twi_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200.0", &twi_clk),
 	/* fake hclk clock */
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
 	CLKDEV_CON_ID("pioA", &pioA_clk),
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index a563189..3cee0e6 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -68,7 +68,7 @@
 
 	/* Enable overcurrent notification */
 	for (i = 0; i < data->ports; i++) {
-		if (data->overcurrent_pin[i])
+		if (gpio_is_valid(data->overcurrent_pin[i]))
 			at91_set_gpio_input(data->overcurrent_pin[i], 1);
 	}
 
@@ -479,7 +479,7 @@
 
 static struct platform_device at91rm9200_twi_device = {
 	.name			= "i2c-gpio",
-	.id			= -1,
+	.id			= 0,
 	.dev.platform_data	= &pdata,
 };
 
@@ -512,7 +512,7 @@
 
 static struct platform_device at91rm9200_twi_device = {
 	.name		= "i2c-at91rm9200",
-	.id		= -1,
+	.id		= 0,
 	.resource	= twi_resources,
 	.num_resources	= ARRAY_SIZE(twi_resources),
 };
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index ad29f93..f820261 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -211,8 +211,8 @@
 	CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk),
 	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk),
-	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk),
-	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20", &twi_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi_clk),
 	/* more usart lookup table for DT entries */
 	CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
 	CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk),
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index a76b868..414bd85 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -72,7 +72,7 @@
 
 	/* Enable overcurrent notification */
 	for (i = 0; i < data->ports; i++) {
-		if (data->overcurrent_pin[i])
+		if (gpio_is_valid(data->overcurrent_pin[i]))
 			at91_set_gpio_input(data->overcurrent_pin[i], 1);
 	}
 
@@ -389,7 +389,7 @@
 
 static struct platform_device at91sam9260_twi_device = {
 	.name			= "i2c-gpio",
-	.id			= -1,
+	.id			= 0,
 	.dev.platform_data	= &pdata,
 };
 
@@ -421,7 +421,7 @@
 };
 
 static struct platform_device at91sam9260_twi_device = {
-	.id		= -1,
+	.id		= 0,
 	.resource	= twi_resources,
 	.num_resources	= ARRAY_SIZE(twi_resources),
 };
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 8d999eb..04295c0 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -178,8 +178,8 @@
 	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0),
-	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261", &twi_clk),
-	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10", &twi_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261.0", &twi_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi_clk),
 	CLKDEV_CON_ID("pioA", &pioA_clk),
 	CLKDEV_CON_ID("pioB", &pioB_clk),
 	CLKDEV_CON_ID("pioC", &pioC_clk),
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 9752f17..cd604aa 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -72,7 +72,7 @@
 
 	/* Enable overcurrent notification */
 	for (i = 0; i < data->ports; i++) {
-		if (data->overcurrent_pin[i])
+		if (gpio_is_valid(data->overcurrent_pin[i]))
 			at91_set_gpio_input(data->overcurrent_pin[i], 1);
 	}
 
@@ -285,7 +285,7 @@
 
 static struct platform_device at91sam9261_twi_device = {
 	.name			= "i2c-gpio",
-	.id			= -1,
+	.id			= 0,
 	.dev.platform_data	= &pdata,
 };
 
@@ -317,7 +317,7 @@
 };
 
 static struct platform_device at91sam9261_twi_device = {
-	.id		= -1,
+	.id		= 0,
 	.resource	= twi_resources,
 	.num_resources	= ARRAY_SIZE(twi_resources),
 };
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 6a01d03..d6f9c23 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -193,7 +193,7 @@
 	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
 	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
 	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
-	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk),
 	/* fake hclk clock */
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
 	CLKDEV_CON_ID("pioA", &pioA_clk),
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 8dde220..9c61e59 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -78,7 +78,7 @@
 
 	/* Enable overcurrent notification */
 	for (i = 0; i < data->ports; i++) {
-		if (data->overcurrent_pin[i])
+		if (gpio_is_valid(data->overcurrent_pin[i]))
 			at91_set_gpio_input(data->overcurrent_pin[i], 1);
 	}
 
@@ -567,7 +567,7 @@
 
 static struct platform_device at91sam9263_twi_device = {
 	.name			= "i2c-gpio",
-	.id			= -1,
+	.id			= 0,
 	.dev.platform_data	= &pdata,
 };
 
@@ -600,7 +600,7 @@
 
 static struct platform_device at91sam9263_twi_device = {
 	.name		= "i2c-at91sam9260",
-	.id		= -1,
+	.id		= 0,
 	.resource	= twi_resources,
 	.num_resources	= ARRAY_SIZE(twi_resources),
 };
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index b159607..fcd233c 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -1841,8 +1841,8 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= AT91SAM9G45_ID_AESTDESSHA,
-		.end	= AT91SAM9G45_ID_AESTDESSHA,
+		.start	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+		.end	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -1874,8 +1874,8 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= AT91SAM9G45_ID_AESTDESSHA,
-		.end	= AT91SAM9G45_ID_AESTDESSHA,
+		.start	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+		.end	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -1910,8 +1910,8 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= AT91SAM9G45_ID_AESTDESSHA,
-		.end	= AT91SAM9G45_ID_AESTDESSHA,
+		.start	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+		.end	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index d6ca054..5047bdc 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -314,7 +314,7 @@
 
 static struct platform_device at91sam9rl_twi_device = {
 	.name			= "i2c-gpio",
-	.id			= -1,
+	.id			= 0,
 	.dev.platform_data	= &pdata,
 };
 
@@ -347,7 +347,7 @@
 
 static struct platform_device at91sam9rl_twi_device = {
 	.name		= "i2c-at91sam9g20",
-	.id		= -1,
+	.id		= 0,
 	.resource	= twi_resources,
 	.num_resources	= ARRAY_SIZE(twi_resources),
 };
diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c
index 6bd7300a..bb7f544 100644
--- a/arch/arm/mach-at91/at91x40.c
+++ b/arch/arm/mach-at91/at91x40.c
@@ -88,6 +88,6 @@
 	if (!priority)
 		priority = at91x40_default_irq_priority;
 
-	at91_aic_init(priority);
+	at91_aic_init(priority, at91_extern_irq);
 }
 
diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c
index 9cda3fd..6960778 100644
--- a/arch/arm/mach-at91/board-neocore926.c
+++ b/arch/arm/mach-at91/board-neocore926.c
@@ -129,7 +129,7 @@
 		.max_speed_hz	= 125000 * 16,
 		.bus_num	= 0,
 		.platform_data	= &ads_info,
-		.irq		= AT91SAM9263_ID_IRQ1,
+		.irq		= NR_IRQS_LEGACY + AT91SAM9263_ID_IRQ1,
 	},
 #endif
 };
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 27b3af1..a9167dd 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -309,7 +309,7 @@
 		.max_speed_hz	= 125000 * 26,	/* (max sample rate @ 3V) * (cmd + data + overhead) */
 		.bus_num	= 0,
 		.platform_data	= &ads_info,
-		.irq		= AT91SAM9261_ID_IRQ0,
+		.irq		= NR_IRQS_LEGACY + AT91SAM9261_ID_IRQ0,
 		.controller_data = (void *) AT91_PIN_PA28,	/* CS pin */
 	},
 #endif
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index 073e174..b87dbe2 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -132,7 +132,7 @@
 		.max_speed_hz	= 125000 * 26,	/* (max sample rate @ 3V) * (cmd + data + overhead) */
 		.bus_num	= 0,
 		.platform_data	= &ads_info,
-		.irq		= AT91SAM9263_ID_IRQ1,
+		.irq		= NR_IRQS_LEGACY + AT91SAM9263_ID_IRQ1,
 	},
 #endif
 };
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index f496506..b62f560e 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -26,7 +26,8 @@
 extern void __init at91_init_irq_default(void);
 extern void __init at91_init_interrupts(unsigned int priority[]);
 extern void __init at91x40_init_interrupts(unsigned int priority[]);
-extern void __init at91_aic_init(unsigned int priority[]);
+extern void __init at91_aic_init(unsigned int priority[],
+				 unsigned int ext_irq_mask);
 extern int  __init at91_aic_of_init(struct device_node *node,
 				    struct device_node *parent);
 extern int  __init at91_aic5_of_init(struct device_node *node,
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
index 1e02c0e..febc2ee 100644
--- a/arch/arm/mach-at91/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -502,14 +502,19 @@
 /*
  * Initialize the AIC interrupt controller.
  */
-void __init at91_aic_init(unsigned int *priority)
+void __init at91_aic_init(unsigned int *priority, unsigned int ext_irq_mask)
 {
 	unsigned int i;
 	int irq_base;
 
-	if (at91_aic_pm_init())
+	at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs)
+				  * sizeof(*at91_extern_irq), GFP_KERNEL);
+
+	if (at91_aic_pm_init() || at91_extern_irq == NULL)
 		panic("Unable to allocate bit maps\n");
 
+	*at91_extern_irq = ext_irq_mask;
+
 	at91_aic_base = ioremap(AT91_AIC, 512);
 	if (!at91_aic_base)
 		panic("Unable to ioremap AIC registers\n");
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index da9881b..0b32c81 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -47,7 +47,7 @@
 void __init at91_init_interrupts(unsigned int *priority)
 {
 	/* Initialize the AIC interrupt controller */
-	at91_aic_init(priority);
+	at91_aic_init(priority, at91_extern_irq);
 
 	/* Enable GPIO interrupts */
 	at91_gpio_irq_setup();
@@ -151,7 +151,7 @@
 	}
 
 	/* at91sam9g10 */
-	if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
+	if ((socid & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
 		at91_soc_initdata.type = AT91_SOC_SAM9G10;
 		at91_boot_soc = at91sam9261_soc;
 	}
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
new file mode 100644
index 0000000..48705c1
--- /dev/null
+++ b/arch/arm/mach-bcm/Kconfig
@@ -0,0 +1,19 @@
+config ARCH_BCM
+	bool "Broadcom SoC" if ARCH_MULTI_V7
+	depends on MMU
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_ERRATA_754322
+	select ARM_ERRATA_764369 if SMP
+	select ARM_GIC
+	select CPU_V7
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_GPIO
+	select GENERIC_TIME
+	select GPIO_BCM
+	select SPARSE_IRQ
+	select TICK_ONESHOT
+	help
+	  This enables support for system based on Broadcom SoCs.
+	  It currently supports the 'BCM281XX' family, which includes
+	  BCM11130, BCM11140, BCM11351, BCM28145 and
+	  BCM28155 variants.
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
new file mode 100644
index 0000000..bbf4122
--- /dev/null
+++ b/arch/arm/mach-bcm/Makefile
@@ -0,0 +1,13 @@
+#
+# Copyright (C) 2012 Broadcom Corporation
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation version 2.
+#
+# This program is distributed "as is" WITHOUT ANY WARRANTY of any
+# kind, whether express or implied; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+obj-$(CONFIG_ARCH_BCM) := board_bcm.o
diff --git a/arch/arm/mach-bcm/board_bcm.c b/arch/arm/mach-bcm/board_bcm.c
new file mode 100644
index 0000000..3a62f1b
--- /dev/null
+++ b/arch/arm/mach-bcm/board_bcm.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/hardware/gic.h>
+
+#include <asm/mach/time.h>
+
+static const struct of_device_id irq_match[] = {
+	{.compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
+	{}
+};
+
+static void timer_init(void)
+{
+}
+
+static struct sys_timer timer = {
+	.init = timer_init,
+};
+
+static void __init init_irq(void)
+{
+	of_irq_init(irq_match);
+}
+
+static void __init board_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL,
+		&platform_bus);
+}
+
+static const char * const bcm11351_dt_compat[] = { "bcm,bcm11351", NULL, };
+
+DT_MACHINE_START(BCM11351_DT, "Broadcom Application Processor")
+	.init_irq = init_irq,
+	.timer = &timer,
+	.init_machine = board_init,
+	.dt_compat = bcm11351_dt_compat,
+	.handle_irq = gic_handle_irq,
+MACHINE_END
diff --git a/arch/arm/mach-bcm2835/bcm2835.c b/arch/arm/mach-bcm2835/bcm2835.c
index f6fea49..c4dd210 100644
--- a/arch/arm/mach-bcm2835/bcm2835.c
+++ b/arch/arm/mach-bcm2835/bcm2835.c
@@ -12,8 +12,10 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/irqchip/bcm2835.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/bcm2835_timer.h>
 #include <linux/clk/bcm2835.h>
@@ -23,6 +25,48 @@
 
 #include <mach/bcm2835_soc.h>
 
+#define PM_RSTC				0x1c
+#define PM_WDOG				0x24
+
+#define PM_PASSWORD			0x5a000000
+#define PM_RSTC_WRCFG_MASK		0x00000030
+#define PM_RSTC_WRCFG_FULL_RESET	0x00000020
+
+static void __iomem *wdt_regs;
+
+/*
+ * The machine restart method can be called from an atomic context so we won't
+ * be able to ioremap the regs then.
+ */
+static void bcm2835_setup_restart(void)
+{
+	struct device_node *np = of_find_compatible_node(NULL, NULL,
+						"brcm,bcm2835-pm-wdt");
+	if (WARN(!np, "unable to setup watchdog restart"))
+		return;
+
+	wdt_regs = of_iomap(np, 0);
+	WARN(!wdt_regs, "failed to remap watchdog regs");
+}
+
+static void bcm2835_restart(char mode, const char *cmd)
+{
+	u32 val;
+
+	if (!wdt_regs)
+		return;
+
+	/* use a timeout of 10 ticks (~150us) */
+	writel_relaxed(10 | PM_PASSWORD, wdt_regs + PM_WDOG);
+	val = readl_relaxed(wdt_regs + PM_RSTC);
+	val &= ~PM_RSTC_WRCFG_MASK;
+	val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
+	writel_relaxed(val, wdt_regs + PM_RSTC);
+
+	/* No sleeping, possibly atomic. */
+	mdelay(1);
+}
+
 static struct map_desc io_map __initdata = {
 	.virtual = BCM2835_PERIPH_VIRT,
 	.pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS),
@@ -39,6 +83,7 @@
 {
 	int ret;
 
+	bcm2835_setup_restart();
 	bcm2835_init_clocks();
 
 	ret = of_platform_populate(NULL, of_default_bus_match_table, NULL,
@@ -60,5 +105,6 @@
 	.handle_irq = bcm2835_handle_irq,
 	.init_machine = bcm2835_init,
 	.timer = &bcm2835_timer,
+	.restart = bcm2835_restart,
 	.dt_compat = bcm2835_compat
 MACHINE_END
diff --git a/arch/arm/mach-bcm2835/include/mach/gpio.h b/arch/arm/mach-bcm2835/include/mach/gpio.h
new file mode 100644
index 0000000..40a8c178
--- /dev/null
+++ b/arch/arm/mach-bcm2835/include/mach/gpio.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
index 263242d..2d00165 100644
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -10,7 +10,6 @@
 
 config ARCH_CDB89712
 	bool "CDB89712"
-	select ISA
 	help
 	  This is an evaluation board from Cirrus for the CS89712 processor.
 	  The board includes 2 serial ports, Ethernet, IRDA, and expansion
@@ -25,7 +24,6 @@
 	bool "EDB7211"
 	select ARCH_SELECT_MEMORY_MODEL
 	select ARCH_SPARSEMEM_ENABLE
-	select ISA
 	help
 	  Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
 	  evaluation board.
diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile
index 6da6940..992995a 100644
--- a/arch/arm/mach-clps711x/Makefile
+++ b/arch/arm/mach-clps711x/Makefile
@@ -9,9 +9,9 @@
 obj-n			:=
 obj-			:=
 
-obj-$(CONFIG_ARCH_AUTCPU12) += autcpu12.o
-obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o
-obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
-obj-$(CONFIG_ARCH_EDB7211)  += edb7211-arch.o edb7211-mm.o
-obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
-obj-$(CONFIG_ARCH_P720T)    += p720t.o
+obj-$(CONFIG_ARCH_AUTCPU12)	+= board-autcpu12.o
+obj-$(CONFIG_ARCH_CDB89712)	+= board-cdb89712.o
+obj-$(CONFIG_ARCH_CLEP7312)	+= board-clep7312.o
+obj-$(CONFIG_ARCH_EDB7211)	+= board-edb7211.o
+obj-$(CONFIG_ARCH_FORTUNET)	+= board-fortunet.o
+obj-$(CONFIG_ARCH_P720T)	+= board-p720t.o
diff --git a/arch/arm/mach-clps711x/Makefile.boot b/arch/arm/mach-clps711x/Makefile.boot
index 9398e85..eba77d3 100644
--- a/arch/arm/mach-clps711x/Makefile.boot
+++ b/arch/arm/mach-clps711x/Makefile.boot
@@ -1,5 +1,4 @@
 # The standard locations for stuff on CLPS711x type processors
-   zreladdr-y				+= 0xc0028000
 params_phys-y				:= 0xc0000100
 # Should probably have some agreement on these...
 initrd_phys-$(CONFIG_ARCH_P720T)	:= 0xc0400000
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
deleted file mode 100644
index 3287191..0000000
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *  linux/arch/arm/mach-clps711x/autcpu12.c
- *
- * (c) 2001 Thomas Gleixner, autronix automation <gleixner@autronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-
-#include <mach/hardware.h>
-#include <asm/sizes.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-
-#include <asm/mach/map.h>
-#include <mach/autcpu12.h>
-
-#include "common.h"
-
-/*
- * The on-chip registers are given a size of 1MB so that a section can
- * be used to map them; this saves a page table.  This is the place to
- * add mappings for ROM, expansion memory, PCMCIA, etc.  (if static
- * mappings are chosen for those areas).
- *
-*/
-
-static struct map_desc autcpu12_io_desc[] __initdata = {
-	/* memory-mapped extra io and CS8900A Ethernet chip */
- 	/* ethernet chip */
- 	{
-		.virtual	= AUTCPU12_VIRT_CS8900A,
-		.pfn		= __phys_to_pfn(AUTCPU12_PHYS_CS8900A),
-		.length		= SZ_1M,
-		.type		= MT_DEVICE
-	}
-};
-
-void __init autcpu12_map_io(void)
-{
-        clps711x_map_io();
-        iotable_init(autcpu12_io_desc, ARRAY_SIZE(autcpu12_io_desc));
-}
-
-static struct resource autcpu12_nvram_resource[] __initdata = {
-	DEFINE_RES_MEM_NAMED(AUTCPU12_PHYS_NVRAM, SZ_128K, "SRAM"),
-};
-
-static struct platform_device autcpu12_nvram_pdev __initdata = {
-	.name		= "autcpu12_nvram",
-	.id		= -1,
-	.resource	= autcpu12_nvram_resource,
-	.num_resources	= ARRAY_SIZE(autcpu12_nvram_resource),
-};
-
-static void __init autcpu12_init(void)
-{
-	platform_device_register(&autcpu12_nvram_pdev);
-}
-
-MACHINE_START(AUTCPU12, "autronix autcpu12")
-	/* Maintainer: Thomas Gleixner */
-	.atag_offset	= 0x20000,
-	.init_machine	= autcpu12_init,
-	.map_io		= autcpu12_map_io,
-	.init_irq	= clps711x_init_irq,
-	.timer		= &clps711x_timer,
-	.restart	= clps711x_restart,
-MACHINE_END
-
diff --git a/arch/arm/mach-clps711x/board-autcpu12.c b/arch/arm/mach-clps711x/board-autcpu12.c
new file mode 100644
index 0000000..3fbf43f
--- /dev/null
+++ b/arch/arm/mach-clps711x/board-autcpu12.c
@@ -0,0 +1,179 @@
+/*
+ *  linux/arch/arm/mach-clps711x/autcpu12.c
+ *
+ * (c) 2001 Thomas Gleixner, autronix automation <gleixner@autronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand-gpio.h>
+#include <linux/platform_device.h>
+#include <linux/basic_mmio_gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/sizes.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+#include <mach/autcpu12.h>
+
+#include "common.h"
+
+#define AUTCPU12_CS8900_BASE	(CS2_PHYS_BASE + 0x300)
+#define AUTCPU12_CS8900_IRQ	(IRQ_EINT3)
+
+#define AUTCPU12_SMC_BASE	(CS1_PHYS_BASE + 0x06000000)
+#define AUTCPU12_SMC_SEL_BASE	(AUTCPU12_SMC_BASE + 0x10)
+
+#define AUTCPU12_MMGPIO_BASE	(CLPS711X_NR_GPIO)
+#define AUTCPU12_SMC_NCE	(AUTCPU12_MMGPIO_BASE + 0) /* Bit 0 */
+#define AUTCPU12_SMC_RDY	CLPS711X_GPIO(1, 2)
+#define AUTCPU12_SMC_ALE	CLPS711X_GPIO(1, 3)
+#define AUTCPU12_SMC_CLE	CLPS711X_GPIO(1, 3)
+
+static struct resource autcpu12_cs8900_resource[] __initdata = {
+	DEFINE_RES_MEM(AUTCPU12_CS8900_BASE, SZ_1K),
+	DEFINE_RES_IRQ(AUTCPU12_CS8900_IRQ),
+};
+
+static struct resource autcpu12_nvram_resource[] __initdata = {
+	DEFINE_RES_MEM_NAMED(AUTCPU12_PHYS_NVRAM, SZ_128K, "SRAM"),
+};
+
+static struct platform_device autcpu12_nvram_pdev __initdata = {
+	.name		= "autcpu12_nvram",
+	.id		= -1,
+	.resource	= autcpu12_nvram_resource,
+	.num_resources	= ARRAY_SIZE(autcpu12_nvram_resource),
+};
+
+static struct resource autcpu12_nand_resource[] __initdata = {
+	DEFINE_RES_MEM(AUTCPU12_SMC_BASE, SZ_16),
+};
+
+static struct mtd_partition autcpu12_nand_parts[] __initdata = {
+	{
+		.name	= "Flash partition 1",
+		.offset	= 0,
+		.size	= SZ_8M,
+	},
+	{
+		.name	= "Flash partition 2",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static void __init autcpu12_adjust_parts(struct gpio_nand_platdata *pdata,
+					 size_t sz)
+{
+	switch (sz) {
+	case SZ_16M:
+	case SZ_32M:
+		break;
+	case SZ_64M:
+	case SZ_128M:
+		pdata->parts[0].size = SZ_16M;
+		break;
+	default:
+		pr_warn("Unsupported SmartMedia device size %u\n", sz);
+		break;
+	}
+}
+
+static struct gpio_nand_platdata autcpu12_nand_pdata __initdata = {
+	.gpio_rdy	= AUTCPU12_SMC_RDY,
+	.gpio_nce	= AUTCPU12_SMC_NCE,
+	.gpio_ale	= AUTCPU12_SMC_ALE,
+	.gpio_cle	= AUTCPU12_SMC_CLE,
+	.gpio_nwp	= -1,
+	.chip_delay	= 20,
+	.parts		= autcpu12_nand_parts,
+	.num_parts	= ARRAY_SIZE(autcpu12_nand_parts),
+	.adjust_parts	= autcpu12_adjust_parts,
+};
+
+static struct platform_device autcpu12_nand_pdev __initdata = {
+	.name		= "gpio-nand",
+	.id		= -1,
+	.resource	= autcpu12_nand_resource,
+	.num_resources	= ARRAY_SIZE(autcpu12_nand_resource),
+	.dev		= {
+		.platform_data = &autcpu12_nand_pdata,
+	},
+};
+
+static struct resource autcpu12_mmgpio_resource[] __initdata = {
+	DEFINE_RES_MEM_NAMED(AUTCPU12_SMC_SEL_BASE, SZ_1, "dat"),
+};
+
+static struct bgpio_pdata autcpu12_mmgpio_pdata __initdata = {
+	.base	= AUTCPU12_MMGPIO_BASE,
+	.ngpio	= 8,
+};
+
+static struct platform_device autcpu12_mmgpio_pdev __initdata = {
+	.name		= "basic-mmio-gpio",
+	.id		= -1,
+	.resource	= autcpu12_mmgpio_resource,
+	.num_resources	= ARRAY_SIZE(autcpu12_mmgpio_resource),
+	.dev		= {
+		.platform_data = &autcpu12_mmgpio_pdata,
+	},
+};
+
+static void __init autcpu12_init(void)
+{
+	platform_device_register_simple("video-clps711x", 0, NULL, 0);
+	platform_device_register_simple("cs89x0", 0, autcpu12_cs8900_resource,
+					ARRAY_SIZE(autcpu12_cs8900_resource));
+	platform_device_register(&autcpu12_mmgpio_pdev);
+	platform_device_register(&autcpu12_nvram_pdev);
+}
+
+static void __init autcpu12_init_late(void)
+{
+	if (IS_ENABLED(MTD_NAND_GPIO) && IS_ENABLED(GPIO_GENERIC_PLATFORM)) {
+		/* We are need both drivers to handle NAND */
+		platform_device_register(&autcpu12_nand_pdev);
+	}
+}
+
+MACHINE_START(AUTCPU12, "autronix autcpu12")
+	/* Maintainer: Thomas Gleixner */
+	.atag_offset	= 0x20000,
+	.nr_irqs	= CLPS711X_NR_IRQS,
+	.map_io		= clps711x_map_io,
+	.init_irq	= clps711x_init_irq,
+	.timer		= &clps711x_timer,
+	.init_machine	= autcpu12_init,
+	.init_late	= autcpu12_init_late,
+	.handle_irq	= clps711x_handle_irq,
+	.restart	= clps711x_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-clps711x/board-cdb89712.c b/arch/arm/mach-clps711x/board-cdb89712.c
new file mode 100644
index 0000000..60900dd
--- /dev/null
+++ b/arch/arm/mach-clps711x/board-cdb89712.c
@@ -0,0 +1,147 @@
+/*
+ *  linux/arch/arm/mach-clps711x/cdb89712.c
+ *
+ *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+
+#define CDB89712_CS8900_BASE	(CS2_PHYS_BASE + 0x300)
+#define CDB89712_CS8900_IRQ	(IRQ_EINT3)
+
+static struct resource cdb89712_cs8900_resource[] __initdata = {
+	DEFINE_RES_MEM(CDB89712_CS8900_BASE, SZ_1K),
+	DEFINE_RES_IRQ(CDB89712_CS8900_IRQ),
+};
+
+static struct mtd_partition cdb89712_flash_partitions[] __initdata = {
+	{
+		.name	= "Flash",
+		.offset	= 0,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data cdb89712_flash_pdata __initdata = {
+	.width		= 4,
+	.probe_type	= "map_rom",
+	.parts		= cdb89712_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(cdb89712_flash_partitions),
+};
+
+static struct resource cdb89712_flash_resources[] __initdata = {
+	DEFINE_RES_MEM(CS0_PHYS_BASE, SZ_8M),
+};
+
+static struct platform_device cdb89712_flash_pdev __initdata = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.resource	= cdb89712_flash_resources,
+	.num_resources	= ARRAY_SIZE(cdb89712_flash_resources),
+	.dev	= {
+		.platform_data	= &cdb89712_flash_pdata,
+	},
+};
+
+static struct mtd_partition cdb89712_bootrom_partitions[] __initdata = {
+	{
+		.name	= "BootROM",
+		.offset	= 0,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data cdb89712_bootrom_pdata __initdata = {
+	.width		= 4,
+	.probe_type	= "map_rom",
+	.parts		= cdb89712_bootrom_partitions,
+	.nr_parts	= ARRAY_SIZE(cdb89712_bootrom_partitions),
+};
+
+static struct resource cdb89712_bootrom_resources[] __initdata = {
+	DEFINE_RES_NAMED(CS7_PHYS_BASE, SZ_128, "BOOTROM", IORESOURCE_MEM |
+			 IORESOURCE_CACHEABLE | IORESOURCE_READONLY),
+};
+
+static struct platform_device cdb89712_bootrom_pdev __initdata = {
+	.name		= "physmap-flash",
+	.id		= 1,
+	.resource	= cdb89712_bootrom_resources,
+	.num_resources	= ARRAY_SIZE(cdb89712_bootrom_resources),
+	.dev	= {
+		.platform_data	= &cdb89712_bootrom_pdata,
+	},
+};
+
+static struct platdata_mtd_ram cdb89712_sram_pdata __initdata = {
+	.bankwidth	= 4,
+};
+
+static struct resource cdb89712_sram_resources[] __initdata = {
+	DEFINE_RES_MEM(CLPS711X_SRAM_BASE, CLPS711X_SRAM_SIZE),
+};
+
+static struct platform_device cdb89712_sram_pdev __initdata = {
+	.name		= "mtd-ram",
+	.id		= 0,
+	.resource	= cdb89712_sram_resources,
+	.num_resources	= ARRAY_SIZE(cdb89712_sram_resources),
+	.dev	= {
+		.platform_data	= &cdb89712_sram_pdata,
+	},
+};
+
+static void __init cdb89712_init(void)
+{
+	platform_device_register(&cdb89712_flash_pdev);
+	platform_device_register(&cdb89712_bootrom_pdev);
+	platform_device_register(&cdb89712_sram_pdev);
+	platform_device_register_simple("cs89x0", 0, cdb89712_cs8900_resource,
+					ARRAY_SIZE(cdb89712_cs8900_resource));
+}
+
+MACHINE_START(CDB89712, "Cirrus-CDB89712")
+	/* Maintainer: Ray Lehtiniemi */
+	.atag_offset	= 0x100,
+	.nr_irqs	= CLPS711X_NR_IRQS,
+	.map_io		= clps711x_map_io,
+	.init_irq	= clps711x_init_irq,
+	.timer		= &clps711x_timer,
+	.init_machine	= cdb89712_init,
+	.handle_irq	= clps711x_handle_irq,
+	.restart	= clps711x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/board-clep7312.c
similarity index 95%
rename from arch/arm/mach-clps711x/clep7312.c
rename to arch/arm/mach-clps711x/board-clep7312.c
index dbc7842..0b32a48 100644
--- a/arch/arm/mach-clps711x/clep7312.c
+++ b/arch/arm/mach-clps711x/board-clep7312.c
@@ -33,14 +33,14 @@
 	mi->bank[0].size = 0x01000000;
 }
 
-
 MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
 	/* Maintainer: Nobody */
 	.atag_offset	= 0x0100,
+	.nr_irqs	= CLPS711X_NR_IRQS,
 	.fixup		= fixup_clep7312,
 	.map_io		= clps711x_map_io,
 	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
+	.handle_irq	= clps711x_handle_irq,
 	.restart	= clps711x_restart,
 MACHINE_END
-
diff --git a/arch/arm/mach-clps711x/board-edb7211.c b/arch/arm/mach-clps711x/board-edb7211.c
new file mode 100644
index 0000000..71aa5cf
--- /dev/null
+++ b/arch/arm/mach-clps711x/board-edb7211.c
@@ -0,0 +1,180 @@
+/*
+ *  Copyright (C) 2000, 2001 Blue Mug, Inc.  All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/memblock.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/setup.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <video/platform_lcd.h>
+
+#include <mach/hardware.h>
+
+#include "common.h"
+
+#define VIDEORAM_SIZE		SZ_128K
+
+#define EDB7211_LCD_DC_DC_EN	CLPS711X_GPIO(3, 1)
+#define EDB7211_LCDEN		CLPS711X_GPIO(3, 2)
+#define EDB7211_LCDBL		CLPS711X_GPIO(3, 3)
+
+#define EDB7211_FLASH0_BASE	(CS0_PHYS_BASE)
+#define EDB7211_FLASH1_BASE	(CS1_PHYS_BASE)
+#define EDB7211_CS8900_BASE	(CS2_PHYS_BASE + 0x300)
+#define EDB7211_CS8900_IRQ	(IRQ_EINT3)
+
+static struct resource edb7211_cs8900_resource[] __initdata = {
+	DEFINE_RES_MEM(EDB7211_CS8900_BASE, SZ_1K),
+	DEFINE_RES_IRQ(EDB7211_CS8900_IRQ),
+};
+
+static struct mtd_partition edb7211_flash_partitions[] __initdata = {
+	{
+		.name	= "Flash",
+		.offset	= 0,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data edb7211_flash_pdata __initdata = {
+	.width		= 4,
+	.parts		= edb7211_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(edb7211_flash_partitions),
+};
+
+static struct resource edb7211_flash_resources[] __initdata = {
+	DEFINE_RES_MEM(EDB7211_FLASH0_BASE, SZ_8M),
+	DEFINE_RES_MEM(EDB7211_FLASH1_BASE, SZ_8M),
+};
+
+static struct platform_device edb7211_flash_pdev __initdata = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.resource	= edb7211_flash_resources,
+	.num_resources	= ARRAY_SIZE(edb7211_flash_resources),
+	.dev	= {
+		.platform_data	= &edb7211_flash_pdata,
+	},
+};
+
+static void edb7211_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
+{
+	if (power) {
+		gpio_set_value(EDB7211_LCDEN, 1);
+		udelay(100);
+		gpio_set_value(EDB7211_LCD_DC_DC_EN, 1);
+	} else {
+		gpio_set_value(EDB7211_LCD_DC_DC_EN, 0);
+		udelay(100);
+		gpio_set_value(EDB7211_LCDEN, 0);
+	}
+}
+
+static struct plat_lcd_data edb7211_lcd_power_pdata = {
+	.set_power	= edb7211_lcd_power_set,
+};
+
+static void edb7211_lcd_backlight_set_intensity(int intensity)
+{
+	gpio_set_value(EDB7211_LCDBL, intensity);
+}
+
+static struct generic_bl_info edb7211_lcd_backlight_pdata = {
+	.name			= "lcd-backlight.0",
+	.default_intensity	= 0x01,
+	.max_intensity		= 0x01,
+	.set_bl_intensity	= edb7211_lcd_backlight_set_intensity,
+};
+
+static struct gpio edb7211_gpios[] __initconst = {
+	{ EDB7211_LCD_DC_DC_EN,	GPIOF_OUT_INIT_LOW,	"LCD DC-DC" },
+	{ EDB7211_LCDEN,	GPIOF_OUT_INIT_LOW,	"LCD POWER" },
+	{ EDB7211_LCDBL,	GPIOF_OUT_INIT_LOW,	"LCD BACKLIGHT" },
+};
+
+static struct map_desc edb7211_io_desc[] __initdata = {
+	{	/* Memory-mapped extra keyboard row */
+		.virtual	= IO_ADDRESS(EP7211_PHYS_EXTKBD),
+		.pfn		= __phys_to_pfn(EP7211_PHYS_EXTKBD),
+		.length		= SZ_1M,
+		.type		= MT_DEVICE,
+	},
+};
+
+void __init edb7211_map_io(void)
+{
+	clps711x_map_io();
+	iotable_init(edb7211_io_desc, ARRAY_SIZE(edb7211_io_desc));
+}
+
+/* Reserve screen memory region at the start of main system memory. */
+static void __init edb7211_reserve(void)
+{
+	memblock_reserve(PHYS_OFFSET, VIDEORAM_SIZE);
+}
+
+static void __init
+fixup_edb7211(struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+	/*
+	 * Bank start addresses are not present in the information
+	 * passed in from the boot loader.  We could potentially
+	 * detect them, but instead we hard-code them.
+	 *
+	 * Banks sizes _are_ present in the param block, but we're
+	 * not using that information yet.
+	 */
+	mi->bank[0].start = 0xc0000000;
+	mi->bank[0].size = SZ_8M;
+	mi->bank[1].start = 0xc1000000;
+	mi->bank[1].size = SZ_8M;
+	mi->nr_banks = 2;
+}
+
+static void __init edb7211_init(void)
+{
+	gpio_request_array(edb7211_gpios, ARRAY_SIZE(edb7211_gpios));
+
+	platform_device_register(&edb7211_flash_pdev);
+	platform_device_register_data(&platform_bus, "platform-lcd", 0,
+				      &edb7211_lcd_power_pdata,
+				      sizeof(edb7211_lcd_power_pdata));
+	platform_device_register_data(&platform_bus, "generic-bl", 0,
+				      &edb7211_lcd_backlight_pdata,
+				      sizeof(edb7211_lcd_backlight_pdata));
+	platform_device_register_simple("video-clps711x", 0, NULL, 0);
+	platform_device_register_simple("cs89x0", 0, edb7211_cs8900_resource,
+					ARRAY_SIZE(edb7211_cs8900_resource));
+}
+
+MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
+	/* Maintainer: Jon McClintock */
+	.atag_offset	= VIDEORAM_SIZE + 0x100,
+	.nr_irqs	= CLPS711X_NR_IRQS,
+	.fixup		= fixup_edb7211,
+	.reserve	= edb7211_reserve,
+	.map_io		= edb7211_map_io,
+	.init_irq	= clps711x_init_irq,
+	.timer		= &clps711x_timer,
+	.init_machine	= edb7211_init,
+	.handle_irq	= clps711x_handle_irq,
+	.restart	= clps711x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/board-fortunet.c
similarity index 96%
rename from arch/arm/mach-clps711x/fortunet.c
rename to arch/arm/mach-clps711x/board-fortunet.c
index 3a3f0b7..7d01255 100644
--- a/arch/arm/mach-clps711x/fortunet.c
+++ b/arch/arm/mach-clps711x/board-fortunet.c
@@ -74,9 +74,11 @@
 
 MACHINE_START(FORTUNET, "ARM-FortuNet")
 	/* Maintainer: FortuNet Inc. */
+	.nr_irqs	= CLPS711X_NR_IRQS,
 	.fixup		= fortunet_fixup,
 	.map_io		= clps711x_map_io,
 	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
+	.handle_irq	= clps711x_handle_irq,
 	.restart	= clps711x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/board-p720t.c b/arch/arm/mach-clps711x/board-p720t.c
new file mode 100644
index 0000000..1518fc8
--- /dev/null
+++ b/arch/arm/mach-clps711x/board-p720t.c
@@ -0,0 +1,232 @@
+/*
+ *  linux/arch/arm/mach-clps711x/p720t.c
+ *
+ *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
+#include <linux/sizes.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand-gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/syspld.h>
+
+#include <video/platform_lcd.h>
+
+#include "common.h"
+
+#define P720T_USERLED		CLPS711X_GPIO(3, 0)
+#define P720T_NAND_CLE		CLPS711X_GPIO(4, 0)
+#define P720T_NAND_ALE		CLPS711X_GPIO(4, 1)
+#define P720T_NAND_NCE		CLPS711X_GPIO(4, 2)
+
+#define P720T_NAND_BASE		(CLPS711X_SDRAM1_BASE)
+
+static struct resource p720t_nand_resource[] __initdata = {
+	DEFINE_RES_MEM(P720T_NAND_BASE, SZ_4),
+};
+
+static struct mtd_partition p720t_nand_parts[] __initdata = {
+	{
+		.name	= "Flash partition 1",
+		.offset	= 0,
+		.size	= SZ_2M,
+	},
+	{
+		.name	= "Flash partition 2",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct gpio_nand_platdata p720t_nand_pdata __initdata = {
+	.gpio_rdy	= -1,
+	.gpio_nce	= P720T_NAND_NCE,
+	.gpio_ale	= P720T_NAND_ALE,
+	.gpio_cle	= P720T_NAND_CLE,
+	.gpio_nwp	= -1,
+	.chip_delay	= 15,
+	.parts		= p720t_nand_parts,
+	.num_parts	= ARRAY_SIZE(p720t_nand_parts),
+};
+
+static struct platform_device p720t_nand_pdev __initdata = {
+	.name		= "gpio-nand",
+	.id		= -1,
+	.resource	= p720t_nand_resource,
+	.num_resources	= ARRAY_SIZE(p720t_nand_resource),
+	.dev		= {
+		.platform_data = &p720t_nand_pdata,
+	},
+};
+
+static void p720t_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
+{
+	if (power) {
+		PLD_LCDEN = PLD_LCDEN_EN;
+		PLD_PWR |= PLD_S4_ON | PLD_S2_ON | PLD_S1_ON;
+	} else {
+		PLD_PWR &= ~(PLD_S4_ON | PLD_S2_ON | PLD_S1_ON);
+		PLD_LCDEN = 0;
+	}
+}
+
+static struct plat_lcd_data p720t_lcd_power_pdata = {
+	.set_power	= p720t_lcd_power_set,
+};
+
+static void p720t_lcd_backlight_set_intensity(int intensity)
+{
+	if (intensity)
+		PLD_PWR |= PLD_S3_ON;
+	else
+		PLD_PWR = 0;
+}
+
+static struct generic_bl_info p720t_lcd_backlight_pdata = {
+	.name			= "lcd-backlight.0",
+	.default_intensity	= 0x01,
+	.max_intensity		= 0x01,
+	.set_bl_intensity	= p720t_lcd_backlight_set_intensity,
+};
+
+/*
+ * Map the P720T system PLD. It occupies two address spaces:
+ * 0x10000000 and 0x10400000. We map both regions as one.
+ */
+static struct map_desc p720t_io_desc[] __initdata = {
+	{
+		.virtual	= SYSPLD_VIRT_BASE,
+		.pfn		= __phys_to_pfn(SYSPLD_PHYS_BASE),
+		.length		= SZ_8M,
+		.type		= MT_DEVICE,
+	},
+};
+
+static void __init
+fixup_p720t(struct tag *tag, char **cmdline, struct meminfo *mi)
+{
+	/*
+	 * Our bootloader doesn't setup any tags (yet).
+	 */
+	if (tag->hdr.tag != ATAG_CORE) {
+		tag->hdr.tag = ATAG_CORE;
+		tag->hdr.size = tag_size(tag_core);
+		tag->u.core.flags = 0;
+		tag->u.core.pagesize = PAGE_SIZE;
+		tag->u.core.rootdev = 0x0100;
+
+		tag = tag_next(tag);
+		tag->hdr.tag = ATAG_MEM;
+		tag->hdr.size = tag_size(tag_mem32);
+		tag->u.mem.size = 4096;
+		tag->u.mem.start = PHYS_OFFSET;
+
+		tag = tag_next(tag);
+		tag->hdr.tag = ATAG_NONE;
+		tag->hdr.size = 0;
+	}
+}
+
+static void __init p720t_map_io(void)
+{
+	clps711x_map_io();
+	iotable_init(p720t_io_desc, ARRAY_SIZE(p720t_io_desc));
+}
+
+static void __init p720t_init_early(void)
+{
+	/*
+	 * Power down as much as possible in case we don't
+	 * have the drivers loaded.
+	 */
+	PLD_LCDEN = 0;
+	PLD_PWR  &= ~(PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON);
+
+	PLD_KBD   = 0;
+	PLD_IO    = 0;
+	PLD_IRDA  = 0;
+	PLD_CODEC = 0;
+	PLD_TCH   = 0;
+	PLD_SPI   = 0;
+	if (!IS_ENABLED(CONFIG_DEBUG_LL)) {
+		PLD_COM2 = 0;
+		PLD_COM1 = 0;
+	}
+}
+
+static struct gpio_led p720t_gpio_leds[] = {
+	{
+		.name			= "User LED",
+		.default_trigger	= "heartbeat",
+		.gpio			= P720T_USERLED,
+	},
+};
+
+static struct gpio_led_platform_data p720t_gpio_led_pdata __initdata = {
+	.leds		= p720t_gpio_leds,
+	.num_leds	= ARRAY_SIZE(p720t_gpio_leds),
+};
+
+static void __init p720t_init(void)
+{
+	platform_device_register(&p720t_nand_pdev);
+	platform_device_register_data(&platform_bus, "platform-lcd", 0,
+				      &p720t_lcd_power_pdata,
+				      sizeof(p720t_lcd_power_pdata));
+	platform_device_register_data(&platform_bus, "generic-bl", 0,
+				      &p720t_lcd_backlight_pdata,
+				      sizeof(p720t_lcd_backlight_pdata));
+	platform_device_register_simple("video-clps711x", 0, NULL, 0);
+}
+
+static void __init p720t_init_late(void)
+{
+	platform_device_register_data(&platform_bus, "leds-gpio", 0,
+				      &p720t_gpio_led_pdata,
+				      sizeof(p720t_gpio_led_pdata));
+}
+
+MACHINE_START(P720T, "ARM-Prospector720T")
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.atag_offset	= 0x100,
+	.nr_irqs	= CLPS711X_NR_IRQS,
+	.fixup		= fixup_p720t,
+	.map_io		= p720t_map_io,
+	.init_early	= p720t_init_early,
+	.init_irq	= clps711x_init_irq,
+	.timer		= &clps711x_timer,
+	.init_machine	= p720t_init,
+	.init_late	= p720t_init_late,
+	.handle_irq	= clps711x_handle_irq,
+	.restart	= clps711x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
deleted file mode 100644
index c314f49..0000000
--- a/arch/arm/mach-clps711x/cdb89712.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  linux/arch/arm/mach-clps711x/cdb89712.c
- *
- *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-
-/*
- * Map the CS89712 Ethernet port.  That should be moved to the
- * ethernet driver, perhaps.
- */
-static struct map_desc cdb89712_io_desc[] __initdata = {
-	{
-		.virtual	= ETHER_BASE,
-		.pfn		=__phys_to_pfn(ETHER_START),
-		.length		= ETHER_SIZE,
-		.type		= MT_DEVICE
-	}
-};
-
-static void __init cdb89712_map_io(void)
-{
-	clps711x_map_io();
-	iotable_init(cdb89712_io_desc, ARRAY_SIZE(cdb89712_io_desc));
-}
-
-MACHINE_START(CDB89712, "Cirrus-CDB89712")
-	/* Maintainer: Ray Lehtiniemi */
-	.atag_offset	= 0x100,
-	.map_io		= cdb89712_map_io,
-	.init_irq	= clps711x_init_irq,
-	.timer		= &clps711x_timer,
-	.restart	= clps711x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c
index 509243d..e046439 100644
--- a/arch/arm/mach-clps711x/common.c
+++ b/arch/arm/mach-clps711x/common.c
@@ -21,13 +21,16 @@
  */
 #include <linux/io.h>
 #include <linux/init.h>
+#include <linux/sizes.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/clockchips.h>
 #include <linux/clk-provider.h>
 
-#include <asm/sizes.h>
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <asm/system_misc.h>
@@ -36,7 +39,6 @@
 
 static struct clk *clk_pll, *clk_bus, *clk_uart, *clk_timerl, *clk_timerh,
 		  *clk_tint, *clk_spi;
-static unsigned long latch;
 
 /*
  * This maps the generic CLPS711x registers
@@ -45,7 +47,7 @@
 	{
 		.virtual	= (unsigned long)CLPS711X_VIRT_BASE,
 		.pfn		= __phys_to_pfn(CLPS711X_PHYS_BASE),
-		.length		= SZ_1M,
+		.length		= SZ_64K,
 		.type		= MT_DEVICE
 	}
 };
@@ -64,7 +66,7 @@
 	clps_writel(intmr1, INTMR1);
 }
 
-static void int1_ack(struct irq_data *d)
+static void int1_eoi(struct irq_data *d)
 {
 	switch (d->irq) {
 	case IRQ_CSINT:  clps_writel(0, COEOI);  break;
@@ -86,7 +88,8 @@
 }
 
 static struct irq_chip int1_chip = {
-	.irq_ack	= int1_ack,
+	.name		= "Interrupt Vector 1",
+	.irq_eoi	= int1_eoi,
 	.irq_mask	= int1_mask,
 	.irq_unmask	= int1_unmask,
 };
@@ -100,7 +103,7 @@
 	clps_writel(intmr2, INTMR2);
 }
 
-static void int2_ack(struct irq_data *d)
+static void int2_eoi(struct irq_data *d)
 {
 	switch (d->irq) {
 	case IRQ_KBDINT: clps_writel(0, KBDEOI); break;
@@ -117,73 +120,160 @@
 }
 
 static struct irq_chip int2_chip = {
-	.irq_ack	= int2_ack,
+	.name		= "Interrupt Vector 2",
+	.irq_eoi	= int2_eoi,
 	.irq_mask	= int2_mask,
 	.irq_unmask	= int2_unmask,
 };
 
+static void int3_mask(struct irq_data *d)
+{
+	u32 intmr3;
+
+	intmr3 = clps_readl(INTMR3);
+	intmr3 &= ~(1 << (d->irq - 32));
+	clps_writel(intmr3, INTMR3);
+}
+
+static void int3_unmask(struct irq_data *d)
+{
+	u32 intmr3;
+
+	intmr3 = clps_readl(INTMR3);
+	intmr3 |= 1 << (d->irq - 32);
+	clps_writel(intmr3, INTMR3);
+}
+
+static struct irq_chip int3_chip = {
+	.name		= "Interrupt Vector 3",
+	.irq_mask	= int3_mask,
+	.irq_unmask	= int3_unmask,
+};
+
+static struct {
+	int			nr;
+	struct irq_chip		*chip;
+	irq_flow_handler_t	handle;
+} clps711x_irqdescs[] __initdata = {
+	{ IRQ_CSINT,	&int1_chip,	handle_fasteoi_irq,	},
+	{ IRQ_EINT1,	&int1_chip,	handle_level_irq,	},
+	{ IRQ_EINT2,	&int1_chip,	handle_level_irq,	},
+	{ IRQ_EINT3,	&int1_chip,	handle_level_irq,	},
+	{ IRQ_TC1OI,	&int1_chip,	handle_fasteoi_irq,	},
+	{ IRQ_TC2OI,	&int1_chip,	handle_fasteoi_irq,	},
+	{ IRQ_RTCMI,	&int1_chip,	handle_fasteoi_irq,	},
+	{ IRQ_TINT,	&int1_chip,	handle_fasteoi_irq,	},
+	{ IRQ_UTXINT1,	&int1_chip,	handle_level_irq,	},
+	{ IRQ_URXINT1,	&int1_chip,	handle_level_irq,	},
+	{ IRQ_UMSINT,	&int1_chip,	handle_fasteoi_irq,	},
+	{ IRQ_SSEOTI,	&int1_chip,	handle_level_irq,	},
+	{ IRQ_KBDINT,	&int2_chip,	handle_fasteoi_irq,	},
+	{ IRQ_SS2RX,	&int2_chip,	handle_level_irq,	},
+	{ IRQ_SS2TX,	&int2_chip,	handle_level_irq,	},
+	{ IRQ_UTXINT2,	&int2_chip,	handle_level_irq,	},
+	{ IRQ_URXINT2,	&int2_chip,	handle_level_irq,	},
+};
+
 void __init clps711x_init_irq(void)
 {
 	unsigned int i;
 
-	for (i = 0; i < NR_IRQS; i++) {
-	        if (INT1_IRQS & (1 << i)) {
-			irq_set_chip_and_handler(i, &int1_chip,
-						 handle_level_irq);
-			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-		}
-		if (INT2_IRQS & (1 << i)) {
-			irq_set_chip_and_handler(i, &int2_chip,
-						 handle_level_irq);
-			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-		}
-	}
-
-	/*
-	 * Disable interrupts
-	 */
+	/* Disable interrupts */
 	clps_writel(0, INTMR1);
 	clps_writel(0, INTMR2);
+	clps_writel(0, INTMR3);
 
-	/*
-	 * Clear down any pending interrupts
-	 */
+	/* Clear down any pending interrupts */
+	clps_writel(0, BLEOI);
+	clps_writel(0, MCEOI);
 	clps_writel(0, COEOI);
 	clps_writel(0, TC1EOI);
 	clps_writel(0, TC2EOI);
 	clps_writel(0, RTCEOI);
 	clps_writel(0, TEOI);
 	clps_writel(0, UMSEOI);
-	clps_writel(0, SYNCIO);
 	clps_writel(0, KBDEOI);
+	clps_writel(0, SRXEOF);
+	clps_writel(0xffffffff, DAISR);
+
+	for (i = 0; i < ARRAY_SIZE(clps711x_irqdescs); i++) {
+		irq_set_chip_and_handler(clps711x_irqdescs[i].nr,
+					 clps711x_irqdescs[i].chip,
+					 clps711x_irqdescs[i].handle);
+		set_irq_flags(clps711x_irqdescs[i].nr,
+			      IRQF_VALID | IRQF_PROBE);
+	}
+
+	if (IS_ENABLED(CONFIG_FIQ)) {
+		init_FIQ(0);
+		irq_set_chip_and_handler(IRQ_DAIINT, &int3_chip,
+					 handle_bad_irq);
+		set_irq_flags(IRQ_DAIINT,
+			      IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN);
+	}
 }
 
-/*
- * gettimeoffset() returns time since last timer tick, in usecs.
- *
- * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
- * 'tick' is usecs per jiffy.
- */
-static unsigned long clps711x_gettimeoffset(void)
+inline u32 fls16(u32 x)
 {
-	unsigned long hwticks;
-	hwticks = latch - (clps_readl(TC2D) & 0xffff);
-	return (hwticks * (tick_nsec / 1000)) / latch;
+	u32 r = 15;
+
+	if (!(x & 0xff00)) {
+		x <<= 8;
+		r -= 8;
+	}
+	if (!(x & 0xf000)) {
+		x <<= 4;
+		r -= 4;
+	}
+	if (!(x & 0xc000)) {
+		x <<= 2;
+		r -= 2;
+	}
+	if (!(x & 0x8000))
+		r--;
+
+	return r;
 }
 
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t p720t_timer_interrupt(int irq, void *dev_id)
+asmlinkage void __exception_irq_entry clps711x_handle_irq(struct pt_regs *regs)
 {
-	timer_tick();
+	u32 irqstat;
+	void __iomem *base = CLPS711X_VIRT_BASE;
+
+	irqstat = readl_relaxed(base + INTSR1) & readl_relaxed(base + INTMR1);
+	if (irqstat) {
+		handle_IRQ(fls16(irqstat), regs);
+		return;
+	}
+
+	irqstat = readl_relaxed(base + INTSR2) & readl_relaxed(base + INTMR2);
+	if (likely(irqstat))
+		handle_IRQ(fls16(irqstat) + 16, regs);
+}
+
+static void clps711x_clockevent_set_mode(enum clock_event_mode mode,
+					 struct clock_event_device *evt)
+{
+}
+
+static struct clock_event_device clockevent_clps711x = {
+	.name		= "CLPS711x Clockevents",
+	.rating		= 300,
+	.features	= CLOCK_EVT_FEAT_PERIODIC,
+	.set_mode	= clps711x_clockevent_set_mode,
+};
+
+static irqreturn_t clps711x_timer_interrupt(int irq, void *dev_id)
+{
+	clockevent_clps711x.event_handler(&clockevent_clps711x);
+
 	return IRQ_HANDLED;
 }
 
 static struct irqaction clps711x_timer_irq = {
 	.name		= "CLPS711x Timer Tick",
 	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= p720t_timer_interrupt,
+	.handler	= clps711x_timer_interrupt,
 };
 
 static void add_fixed_clk(struct clk *clk, const char *name, int rate)
@@ -244,20 +334,19 @@
 
 	pr_info("CPU frequency set at %i Hz.\n", cpu);
 
-	latch = (timh + HZ / 2) / HZ;
+	clps_writew(DIV_ROUND_CLOSEST(timh, HZ), TC2D);
 
 	tmp = clps_readl(SYSCON1);
 	tmp |= SYSCON1_TC2S | SYSCON1_TC2M;
 	clps_writel(tmp, SYSCON1);
 
-	clps_writel(latch - 1, TC2D);
+	clockevents_config_and_register(&clockevent_clps711x, timh, 1, 0xffff);
 
 	setup_irq(IRQ_TC2OI, &clps711x_timer_irq);
 }
 
 struct sys_timer clps711x_timer = {
 	.init		= clps711x_timer_init,
-	.offset		= clps711x_gettimeoffset,
 };
 
 void clps711x_restart(char mode, const char *cmd)
diff --git a/arch/arm/mach-clps711x/common.h b/arch/arm/mach-clps711x/common.h
index fc0f065..b7c0c75 100644
--- a/arch/arm/mach-clps711x/common.h
+++ b/arch/arm/mach-clps711x/common.h
@@ -4,9 +4,14 @@
  * Common bits.
  */
 
+#define CLPS711X_NR_IRQS	(33)
+#define CLPS711X_NR_GPIO	(4 * 8 + 3)
+#define CLPS711X_GPIO(prt, bit)	((prt) * 8 + (bit))
+
 struct sys_timer;
 
 extern void clps711x_map_io(void);
 extern void clps711x_init_irq(void);
-extern struct sys_timer clps711x_timer;
+extern void clps711x_handle_irq(struct pt_regs *regs);
 extern void clps711x_restart(char mode, const char *cmd);
+extern struct sys_timer clps711x_timer;
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
deleted file mode 100644
index 5fad0b4..0000000
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *  linux/arch/arm/mach-clps711x/arch-edb7211.c
- *
- *  Copyright (C) 2000, 2001 Blue Mug, Inc.  All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/init.h>
-#include <linux/memblock.h>
-#include <linux/types.h>
-#include <linux/string.h>
-
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#include "common.h"
-
-extern void edb7211_map_io(void);
-
-/* Reserve screen memory region at the start of main system memory. */
-static void __init edb7211_reserve(void)
-{
-	memblock_reserve(PHYS_OFFSET, 0x00020000);
-}
-
-static void __init
-fixup_edb7211(struct tag *tags, char **cmdline, struct meminfo *mi)
-{
-	/*
-	 * Bank start addresses are not present in the information
-	 * passed in from the boot loader.  We could potentially
-	 * detect them, but instead we hard-code them.
-	 *
-	 * Banks sizes _are_ present in the param block, but we're
-	 * not using that information yet.
-	 */
-	mi->bank[0].start = 0xc0000000;
-	mi->bank[0].size = 8*1024*1024;
-	mi->bank[1].start = 0xc1000000;
-	mi->bank[1].size = 8*1024*1024;
-	mi->nr_banks = 2;
-}
-
-MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
-	/* Maintainer: Jon McClintock */
-	.atag_offset	= 0x20100,	/* 0xc0000000 - 0xc001ffff can be video RAM */
-	.fixup		= fixup_edb7211,
-	.map_io		= edb7211_map_io,
-	.reserve	= edb7211_reserve,
-	.init_irq	= clps711x_init_irq,
-	.timer		= &clps711x_timer,
-	.restart	= clps711x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-clps711x/edb7211-mm.c b/arch/arm/mach-clps711x/edb7211-mm.c
deleted file mode 100644
index 4372f06..0000000
--- a/arch/arm/mach-clps711x/edb7211-mm.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *  linux/arch/arm/mach-clps711x/mm.c
- *
- *  Extra MM routines for the EDB7211 board
- *
- *  Copyright (C) 2000, 2001 Blue Mug, Inc.  All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/bug.h>
-
-#include <mach/hardware.h>
-#include <asm/page.h>
-#include <asm/sizes.h>
- 
-#include <asm/mach/map.h>
-
-extern void clps711x_map_io(void);
-
-/*
- * The on-chip registers are given a size of 1MB so that a section can
- * be used to map them; this saves a page table.  This is the place to
- * add mappings for ROM, expansion memory, PCMCIA, etc.  (if static
- * mappings are chosen for those areas).
- *
- * Here is a physical memory map (to be fleshed out later):
- *
- * Physical Address  Size  Description
- * ----------------- ----- ---------------------------------
- * c0000000-c001ffff 128KB reserved for video RAM [1]
- * c0020000-c0023fff  16KB parameters (see Documentation/arm/Setup)
- * c0024000-c0027fff  16KB swapper_pg_dir (task 0 page directory)
- * c0028000-...            kernel image (TEXTADDR)
- *
- * [1] Unused pages should be given back to the VM; they are not yet.
- *     The parameter block should also be released (not sure if this
- *     happens).
- */
-static struct map_desc edb7211_io_desc[] __initdata = {
- 	{	/* memory-mapped extra keyboard row */
-	 	.virtual 	= EP7211_VIRT_EXTKBD,
-		.pfn		= __phys_to_pfn(EP7211_PHYS_EXTKBD),
-		.length		= SZ_1M,
-		.type		= MT_DEVICE,
-	}, {	/* and CS8900A Ethernet chip */
-		.virtual	= EP7211_VIRT_CS8900A,
-		.pfn		= __phys_to_pfn(EP7211_PHYS_CS8900A),
-		.length		= SZ_1M,
-		.type		= MT_DEVICE,
-	}, { 	/* flash banks */
-		.virtual	= EP7211_VIRT_FLASH1,
-		.pfn		= __phys_to_pfn(EP7211_PHYS_FLASH1),
-		.length		= SZ_8M,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= EP7211_VIRT_FLASH2,
-		.pfn		= __phys_to_pfn(EP7211_PHYS_FLASH2),
-		.length		= SZ_8M,
-		.type		= MT_DEVICE,
-	}
-};
-
-void __init edb7211_map_io(void)
-{
-        clps711x_map_io();
-        iotable_init(edb7211_io_desc, ARRAY_SIZE(edb7211_io_desc));
-}
-
diff --git a/arch/arm/mach-clps711x/include/mach/autcpu12.h b/arch/arm/mach-clps711x/include/mach/autcpu12.h
index 1588a36..0452f5f 100644
--- a/arch/arm/mach-clps711x/include/mach/autcpu12.h
+++ b/arch/arm/mach-clps711x/include/mach/autcpu12.h
@@ -21,24 +21,15 @@
 #define __ASM_ARCH_AUTCPU12_H
 
 /*
- * The CS8900A ethernet chip has its I/O registers wired to chip select 2
- * (nCS2). This is the mapping for it.
- */
-#define AUTCPU12_PHYS_CS8900A		CS2_PHYS_BASE		/* physical */
-#define AUTCPU12_VIRT_CS8900A		(0xfe000000)		/* virtual */
-
-/*
  * The flash bank is wired to chip select 0
  */
 #define AUTCPU12_PHYS_FLASH		CS0_PHYS_BASE		/* physical */
 
 /* offset for device specific information structure */
 #define AUTCPU12_LCDINFO_OFFS		(0x00010000)	
-/*
-* Videomemory is the internal SRAM (CS 6)	
-*/
+
+/* Videomemory in the internal SRAM (CS 6) */
 #define AUTCPU12_PHYS_VIDEO		CS6_PHYS_BASE
-#define AUTCPU12_VIRT_VIDEO		(0xfd000000)
 
 /*
 * All special IO's are tied to CS1
@@ -49,8 +40,6 @@
 
 #define AUTCPU12_PHYS_CSAUX1           	CS1_PHYS_BASE +0x04000000  /* physical */
 
-#define AUTCPU12_PHYS_SMC              	CS1_PHYS_BASE +0x06000000  /* physical */
-
 #define AUTCPU12_PHYS_CAN              	CS1_PHYS_BASE +0x08000000  /* physical */
 
 #define AUTCPU12_PHYS_TOUCH            	CS1_PHYS_BASE +0x0A000000  /* physical */
@@ -59,14 +48,6 @@
 
 #define AUTCPU12_PHYS_LPT              	CS1_PHYS_BASE +0x0E000000  /* physical */
 
-/* 
-* defines for smartmedia card access 
-*/
-#define AUTCPU12_SMC_RDY		(1<<2)
-#define AUTCPU12_SMC_ALE		(1<<3)
-#define AUTCPU12_SMC_CLE  		(1<<4)
-#define AUTCPU12_SMC_PORT_OFFSET	PBDR
-#define AUTCPU12_SMC_SELECT_OFFSET 	0x10
 /*
 * defines for lcd contrast 
 */
diff --git a/arch/arm/mach-clps711x/include/mach/clps711x.h b/arch/arm/mach-clps711x/include/mach/clps711x.h
index c82e21c..01d1b95 100644
--- a/arch/arm/mach-clps711x/include/mach/clps711x.h
+++ b/arch/arm/mach-clps711x/include/mach/clps711x.h
@@ -257,6 +257,9 @@
 #define MEMCFG_BUS_WIDTH_16	(0)
 #define MEMCFG_BUS_WIDTH_8	(3)
 
+#define MEMCFG_SQAEN		(1 << 6)
+#define MEMCFG_CLKENB		(1 << 7)
+
 #define MEMCFG_WAITSTATE_8_3	(0 << 2)
 #define MEMCFG_WAITSTATE_7_3	(1 << 2)
 #define MEMCFG_WAITSTATE_6_3	(2 << 2)
@@ -274,4 +277,28 @@
 #define MEMCFG_WAITSTATE_2_0	(14 << 2)
 #define MEMCFG_WAITSTATE_1_0	(15 << 2)
 
+/* INTSR1 Interrupts */
+#define IRQ_CSINT		(4)
+#define IRQ_EINT1		(5)
+#define IRQ_EINT2		(6)
+#define IRQ_EINT3		(7)
+#define IRQ_TC1OI		(8)
+#define IRQ_TC2OI		(9)
+#define IRQ_RTCMI		(10)
+#define IRQ_TINT		(11)
+#define IRQ_UTXINT1		(12)
+#define IRQ_URXINT1		(13)
+#define IRQ_UMSINT		(14)
+#define IRQ_SSEOTI		(15)
+
+/* INTSR2 Interrupts */
+#define IRQ_KBDINT		(16 + 0)
+#define IRQ_SS2RX		(16 + 1)
+#define IRQ_SS2TX		(16 + 2)
+#define IRQ_UTXINT2		(16 + 12)
+#define IRQ_URXINT2		(16 + 13)
+
+/* INTSR3 Interrupts */
+#define IRQ_DAIINT		(32 + 0)
+
 #endif /* __MACH_CLPS711X_H */
diff --git a/arch/arm/mach-clps711x/include/mach/entry-macro.S b/arch/arm/mach-clps711x/include/mach/entry-macro.S
deleted file mode 100644
index 56e5c2c..0000000
--- a/arch/arm/mach-clps711x/include/mach/entry-macro.S
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * arch/arm/mach-clps711x/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for CLPS711X-based platforms
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <mach/hardware.h>
-
-		.macro	get_irqnr_preamble, base, tmp
-		.endm
-
-#if (INTSR2 - INTSR1) != (INTMR2 - INTMR1)
-#error INTSR stride != INTMR stride
-#endif
-
-		.macro	get_irqnr_and_base, irqnr, stat, base, mask
-		mov	\base, #CLPS711X_VIRT_BASE
-		ldr	\stat, [\base, #INTSR1]
-		ldr	\mask, [\base, #INTMR1]
-		mov	\irqnr, #4
-		mov	\mask, \mask, lsl #16
-		and	\stat, \stat, \mask, lsr #16
-		movs	\stat, \stat, lsr #4
-		bne	1001f
-
-		add	\base, \base, #INTSR2 - INTSR1
-		ldr	\stat, [\base, #INTSR1]
-		ldr	\mask, [\base, #INTMR1]
-		mov	\irqnr, #16
-		mov	\mask, \mask, lsl #16
-		and	\stat, \stat, \mask, lsr #16
-
-1001:		tst	\stat, #255
-		addeq	\irqnr, \irqnr, #8
-		moveq	\stat, \stat, lsr #8
-		tst	\stat, #15
-		addeq	\irqnr, \irqnr, #4
-		moveq	\stat, \stat, lsr #4
-		tst	\stat, #3
-		addeq	\irqnr, \irqnr, #2
-		moveq	\stat, \stat, lsr #2
-		tst	\stat, #1
-		addeq	\irqnr, \irqnr, #1
-		moveq	\stat, \stat, lsr #1
-		tst	\stat, #1			@ bit 0 should be set
-		.endm
-
-
diff --git a/arch/arm/mach-clps711x/include/mach/hardware.h b/arch/arm/mach-clps711x/include/mach/hardware.h
index 8497775..2f23dd5 100644
--- a/arch/arm/mach-clps711x/include/mach/hardware.h
+++ b/arch/arm/mach-clps711x/include/mach/hardware.h
@@ -24,7 +24,10 @@
 
 #include <mach/clps711x.h>
 
-#define CLPS711X_VIRT_BASE	IOMEM(0xff000000)
+#define IO_ADDRESS(x)		(0xdc000000 + (((x) & 0x03ffffff) | \
+				(((x) >> 2) & 0x3c000000)))
+
+#define CLPS711X_VIRT_BASE	IOMEM(IO_ADDRESS(CLPS711X_PHYS_BASE))
 
 #ifndef __ASSEMBLY__
 #define clps_readb(off)		readb(CLPS711X_VIRT_BASE + (off))
@@ -61,67 +64,17 @@
 #define CS7_PHYS_BASE		(0x00000000)
 #endif
 
-#define SYSPLD_VIRT_BASE	0xfe000000
-#define SYSPLD_BASE		SYSPLD_VIRT_BASE
+#define CLPS711X_SRAM_BASE	CS6_PHYS_BASE
+#define CLPS711X_SRAM_SIZE	(48 * 1024)
 
-#if defined (CONFIG_ARCH_CDB89712)
-
-#define ETHER_START      0x20000000
-#define ETHER_SIZE       0x1000
-#define ETHER_BASE       0xfe000000
-
-#endif
-
+#define CLPS711X_SDRAM0_BASE	(0xc0000000)
+#define CLPS711X_SDRAM1_BASE	(0xd0000000)
 
 #if defined (CONFIG_ARCH_EDB7211)
 
-/*
- * The extra 8 lines of the keyboard matrix are wired to chip select 3 (nCS3) 
- * and repeat across it. This is the mapping for it.
- *
- * In jumpered boot mode, nCS3 is mapped to 0x4000000, not 0x3000000. This 
- * was cause for much consternation and headscratching. This should probably
- * be made a compile/run time kernel option.
- */
-#define EP7211_PHYS_EXTKBD		CS3_PHYS_BASE	/* physical */
-
-#define EP7211_VIRT_EXTKBD		(0xfd000000)	/* virtual */
-
-
-/*
- * The CS8900A ethernet chip has its I/O registers wired to chip select 2 
- * (nCS2). This is the mapping for it.
- *
- * In jumpered boot mode, nCS2 is mapped to 0x5000000, not 0x2000000. This 
- * was cause for much consternation and headscratching. This should probably
- * be made a compile/run time kernel option.
- */
-#define EP7211_PHYS_CS8900A		CS2_PHYS_BASE	/* physical */
-
-#define EP7211_VIRT_CS8900A		(0xfc000000)	/* virtual */
-
-
-/*
- * The two flash banks are wired to chip selects 0 and 1. This is the mapping
- * for them.
- *
- * nCS0 and nCS1 are at 0x70000000 and 0x60000000, respectively, when running
- * in jumpered boot mode.
- */
-#define EP7211_PHYS_FLASH1		CS0_PHYS_BASE	/* physical */
-#define EP7211_PHYS_FLASH2		CS1_PHYS_BASE	/* physical */
-
-#define EP7211_VIRT_FLASH1		(0xfa000000)	/* virtual */
-#define EP7211_VIRT_FLASH2		(0xfb000000)	/* virtual */
+/* The extra 8 lines of the keyboard matrix are wired to chip select 3 */
+#define EP7211_PHYS_EXTKBD	CS3_PHYS_BASE
 
 #endif /* CONFIG_ARCH_EDB7211 */
 
-/*
- * Relevant bits in port D, which controls power to the various parts of
- * the LCD on the EDB7211.
- */
-#define EDB_PD1_LCD_DC_DC_EN	(1<<1)
-#define EDB_PD2_LCDEN		(1<<2)
-#define EDB_PD3_LCDBL		(1<<3)
-
 #endif
diff --git a/arch/arm/mach-clps711x/include/mach/irqs.h b/arch/arm/mach-clps711x/include/mach/irqs.h
deleted file mode 100644
index 14d215f..0000000
--- a/arch/arm/mach-clps711x/include/mach/irqs.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  arch/arm/mach-clps711x/include/mach/irqs.h
- *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/*
- * Interrupts from INTSR1
- */
-#define IRQ_CSINT			4
-#define IRQ_EINT1			5
-#define IRQ_EINT2			6
-#define IRQ_EINT3			7
-#define IRQ_TC1OI			8
-#define IRQ_TC2OI			9
-#define IRQ_RTCMI			10
-#define IRQ_TINT			11
-#define IRQ_UTXINT1			12
-#define IRQ_URXINT1			13
-#define IRQ_UMSINT			14
-#define IRQ_SSEOTI			15
-
-#define INT1_IRQS			(0x0000fff0)
-
-/*
- * Interrupts from INTSR2
- */
-#define IRQ_KBDINT			(16+0)	/* bit 0 */
-#define IRQ_SS2RX			(16+1)	/* bit 1 */
-#define IRQ_SS2TX			(16+2)	/* bit 2 */
-#define IRQ_UTXINT2			(16+12)	/* bit 12 */
-#define IRQ_URXINT2			(16+13)	/* bit 13 */
-
-#define INT2_IRQS			(0x30070000)
-
-#define NR_IRQS				30
diff --git a/arch/arm/mach-clps711x/include/mach/syspld.h b/arch/arm/mach-clps711x/include/mach/syspld.h
index f7f4c12..9a43315 100644
--- a/arch/arm/mach-clps711x/include/mach/syspld.h
+++ b/arch/arm/mach-clps711x/include/mach/syspld.h
@@ -23,14 +23,9 @@
 #define __ASM_ARCH_SYSPLD_H
 
 #define SYSPLD_PHYS_BASE	(0x10000000)
+#define SYSPLD_VIRT_BASE	IO_ADDRESS(SYSPLD_PHYS_BASE)
 
-#ifndef __ASSEMBLY__
-#include <asm/types.h>
-
-#define SYSPLD_REG(type,off)	(*(volatile type *)(SYSPLD_BASE + off))
-#else
-#define SYSPLD_REG(type,off)	(off)
-#endif
+#define SYSPLD_REG(type, off)	(*(volatile type *)(SYSPLD_VIRT_BASE + (off)))
 
 #define PLD_INT		SYSPLD_REG(u32, 0x000000)
 #define PLD_INT_PENIRQ		(1 << 5)
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
deleted file mode 100644
index b752b58..0000000
--- a/arch/arm/mach-clps711x/p720t.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- *  linux/arch/arm/mach-clps711x/p720t.c
- *
- *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/leds.h>
-
-#include <mach/hardware.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-#include <asm/sizes.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/syspld.h>
-
-#include <asm/hardware/clps7111.h>
-
-#include "common.h"
-
-/*
- * Map the P720T system PLD.  It occupies two address spaces:
- *  SYSPLD_PHYS_BASE and SYSPLD_PHYS_BASE + 0x00400000
- * We map both here.
- */
-static struct map_desc p720t_io_desc[] __initdata = {
-	{
-		.virtual	= SYSPLD_VIRT_BASE,
-		.pfn		= __phys_to_pfn(SYSPLD_PHYS_BASE),
-		.length		= SZ_1M,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= 0xfe400000,
-		.pfn		= __phys_to_pfn(0x10400000),
-		.length		= SZ_1M,
-		.type		= MT_DEVICE
-	}
-};
-
-static void __init
-fixup_p720t(struct tag *tag, char **cmdline, struct meminfo *mi)
-{
-	/*
-	 * Our bootloader doesn't setup any tags (yet).
-	 */
-	if (tag->hdr.tag != ATAG_CORE) {
-		tag->hdr.tag = ATAG_CORE;
-		tag->hdr.size = tag_size(tag_core);
-		tag->u.core.flags = 0;
-		tag->u.core.pagesize = PAGE_SIZE;
-		tag->u.core.rootdev = 0x0100;
-
-		tag = tag_next(tag);
-		tag->hdr.tag = ATAG_MEM;
-		tag->hdr.size = tag_size(tag_mem32);
-		tag->u.mem.size = 4096;
-		tag->u.mem.start = PHYS_OFFSET;
-
-		tag = tag_next(tag);
-		tag->hdr.tag = ATAG_NONE;
-		tag->hdr.size = 0;
-	}
-}
-
-static void __init p720t_map_io(void)
-{
-	clps711x_map_io();
-	iotable_init(p720t_io_desc, ARRAY_SIZE(p720t_io_desc));
-}
-
-static void __init p720t_init_early(void)
-{
-	/*
-	 * Power down as much as possible in case we don't
-	 * have the drivers loaded.
-	 */
-	PLD_LCDEN = 0;
-	PLD_PWR  &= ~(PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON);
-
-	PLD_KBD   = 0;
-	PLD_IO    = 0;
-	PLD_IRDA  = 0;
-	PLD_CODEC = 0;
-	PLD_TCH   = 0;
-	PLD_SPI   = 0;
-	if (!IS_ENABLED(CONFIG_DEBUG_LL)) {
-		PLD_COM2 = 0;
-		PLD_COM1 = 0;
-	}
-}
-
-/*
- * LED controled by CPLD
- */
-#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
-static void p720t_led_set(struct led_classdev *cdev,
-			      enum led_brightness b)
-{
-	u8 reg = clps_readb(PDDR);
-
-	if (b != LED_OFF)
-		reg |= 0x1;
-	else
-		reg &= ~0x1;
-
-	clps_writeb(reg, PDDR);
-}
-
-static enum led_brightness p720t_led_get(struct led_classdev *cdev)
-{
-	u8 reg = clps_readb(PDDR);
-
-	return (reg & 0x1) ? LED_FULL : LED_OFF;
-}
-
-static int __init p720t_leds_init(void)
-{
-
-	struct led_classdev *cdev;
-	int ret;
-
-	if (!machine_is_p720t())
-		return -ENODEV;
-
-	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
-	if (!cdev)
-		return -ENOMEM;
-
-	cdev->name = "p720t:0";
-	cdev->brightness_set = p720t_led_set;
-	cdev->brightness_get = p720t_led_get;
-	cdev->default_trigger = "heartbeat";
-
-	ret = led_classdev_register(NULL, cdev);
-	if (ret	< 0) {
-		kfree(cdev);
-		return ret;
-	}
-
-	return 0;
-}
-
-/*
- * Since we may have triggers on any subsystem, defer registration
- * until after subsystem_init.
- */
-fs_initcall(p720t_leds_init);
-#endif
-
-MACHINE_START(P720T, "ARM-Prospector720T")
-	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
-	.atag_offset	= 0x100,
-	.fixup		= fixup_p720t,
-	.init_early	= p720t_init_early,
-	.map_io		= p720t_map_io,
-	.init_irq	= clps711x_init_irq,
-	.timer		= &clps711x_timer,
-	.restart	= clps711x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index 88ebea8..cdf8d07 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -324,7 +324,7 @@
 	if (IS_ERR(aemif))
 		WARN("%s: unable to get AEMIF clock\n", __func__);
 	else
-		clk_enable(aemif);
+		clk_prepare_enable(aemif);
 
 	platform_add_devices(davinci_evm_devices,
 			     ARRAY_SIZE(davinci_evm_devices));
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index 2f88103..d419545 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -246,7 +246,7 @@
 	if (IS_ERR(aemif))
 		WARN("%s: unable to get AEMIF clock\n", __func__);
 	else
-		clk_enable(aemif);
+		clk_prepare_enable(aemif);
 
 	platform_add_devices(davinci_leopard_devices,
 			     ARRAY_SIZE(davinci_leopard_devices));
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 1b4a8ad..5d49c75 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -478,7 +478,7 @@
 	aemif_clk = clk_get(NULL, "aemif");
 	if (IS_ERR(aemif_clk))
 		return;
-	clk_enable(aemif_clk);
+	clk_prepare_enable(aemif_clk);
 
 	if (request_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE,
 			"cpld") == NULL)
@@ -489,7 +489,7 @@
 				SECTION_SIZE);
 fail:
 		pr_err("ERROR: can't map CPLD\n");
-		clk_disable(aemif_clk);
+		clk_disable_unprepare(aemif_clk);
 		return;
 	}
 
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index f22572ce..a84dfcb 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -776,7 +776,7 @@
 	struct davinci_soc_info *soc_info = &davinci_soc_info;
 
 	aemif_clk = clk_get(NULL, "aemif");
-	clk_enable(aemif_clk);
+	clk_prepare_enable(aemif_clk);
 
 	if (HAS_ATA) {
 		if (HAS_NAND || HAS_NOR)
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index 144bf31..3e3e3af 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -188,7 +188,7 @@
 	struct davinci_soc_info *soc_info = &davinci_soc_info;
 
 	aemif_clk = clk_get(NULL, "aemif");
-	clk_enable(aemif_clk);
+	clk_prepare_enable(aemif_clk);
 
 	if (HAS_ATA) {
 		if (HAS_NAND)
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index b90c172..68c5fe0 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -212,6 +212,12 @@
 	.flags		= ALWAYS_ENABLED,
 };
 
+static struct clk pruss_clk = {
+	.name		= "pruss",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_PRUSS,
+};
+
 static struct clk uart0_clk = {
 	.name		= "uart0",
 	.parent		= &pll0_sysclk2,
@@ -385,6 +391,7 @@
 	CLK(NULL,		"tptc1",	&tptc1_clk),
 	CLK(NULL,		"tpcc1",	&tpcc1_clk),
 	CLK(NULL,		"tptc2",	&tptc2_clk),
+	CLK("pruss_uio",	"pruss",	&pruss_clk),
 	CLK(NULL,		"uart0",	&uart0_clk),
 	CLK(NULL,		"uart1",	&uart1_clk),
 	CLK(NULL,		"uart2",	&uart2_clk),
@@ -781,12 +788,6 @@
 		.length		= DA8XX_CP_INTC_SIZE,
 		.type		= MT_DEVICE
 	},
-	{
-		.virtual	= SRAM_VIRT,
-		.pfn		= __phys_to_pfn(DA8XX_ARM_RAM_BASE),
-		.length		= SZ_8K,
-		.type		= MT_DEVICE
-	},
 };
 
 static u32 da850_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
@@ -1239,8 +1240,8 @@
 	.gpio_irq		= IRQ_DA8XX_GPIO0,
 	.serial_dev		= &da8xx_serial_device,
 	.emac_pdata		= &da8xx_emac_pdata,
-	.sram_dma		= DA8XX_ARM_RAM_BASE,
-	.sram_len		= SZ_8K,
+	.sram_dma		= DA8XX_SHARED_RAM_BASE,
+	.sram_len		= SZ_128K,
 };
 
 void __init da850_init(void)
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index bd2f72b..46c9a0c 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -22,6 +22,7 @@
 #include <mach/time.h>
 #include <mach/da8xx.h>
 #include <mach/cpuidle.h>
+#include <mach/sram.h>
 
 #include "clock.h"
 #include "asp.h"
@@ -32,6 +33,7 @@
 #define DA8XX_WDOG_BASE			0x01c21000 /* DA8XX_TIMER64P1_BASE */
 #define DA8XX_I2C0_BASE			0x01c22000
 #define DA8XX_RTC_BASE			0x01c23000
+#define DA8XX_PRUSS_MEM_BASE		0x01c30000
 #define DA8XX_MMCSD0_BASE		0x01c40000
 #define DA8XX_SPI0_BASE			0x01c41000
 #define DA830_SPI1_BASE			0x01e12000
@@ -518,6 +520,75 @@
 	}
 }
 
+static struct resource da8xx_pruss_resources[] = {
+	{
+		.start	= DA8XX_PRUSS_MEM_BASE,
+		.end	= DA8XX_PRUSS_MEM_BASE + 0xFFFF,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_DA8XX_EVTOUT0,
+		.end	= IRQ_DA8XX_EVTOUT0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DA8XX_EVTOUT1,
+		.end	= IRQ_DA8XX_EVTOUT1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DA8XX_EVTOUT2,
+		.end	= IRQ_DA8XX_EVTOUT2,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DA8XX_EVTOUT3,
+		.end	= IRQ_DA8XX_EVTOUT3,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DA8XX_EVTOUT4,
+		.end	= IRQ_DA8XX_EVTOUT4,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DA8XX_EVTOUT5,
+		.end	= IRQ_DA8XX_EVTOUT5,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DA8XX_EVTOUT6,
+		.end	= IRQ_DA8XX_EVTOUT6,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DA8XX_EVTOUT7,
+		.end	= IRQ_DA8XX_EVTOUT7,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct uio_pruss_pdata da8xx_uio_pruss_pdata = {
+	.pintc_base	= 0x4000,
+};
+
+static struct platform_device da8xx_uio_pruss_dev = {
+	.name		= "pruss_uio",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(da8xx_pruss_resources),
+	.resource	= da8xx_pruss_resources,
+	.dev		= {
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &da8xx_uio_pruss_pdata,
+	}
+};
+
+int __init da8xx_register_uio_pruss(void)
+{
+	da8xx_uio_pruss_pdata.sram_pool = sram_get_gen_pool();
+	return platform_device_register(&da8xx_uio_pruss_dev);
+}
+
 static const struct display_panel disp_panel = {
 	QVGA,
 	16,
@@ -900,7 +971,7 @@
 	if (IS_ERR(da850_sata_clk))
 		return PTR_ERR(da850_sata_clk);
 
-	ret = clk_enable(da850_sata_clk);
+	ret = clk_prepare_enable(da850_sata_clk);
 	if (ret)
 		goto err0;
 
@@ -931,7 +1002,7 @@
 	return 0;
 
 err1:
-	clk_disable(da850_sata_clk);
+	clk_disable_unprepare(da850_sata_clk);
 err0:
 	clk_put(da850_sata_clk);
 	return ret;
@@ -939,7 +1010,7 @@
 
 static void da850_sata_exit(struct device *dev)
 {
-	clk_disable(da850_sata_clk);
+	clk_disable_unprepare(da850_sata_clk);
 	clk_put(da850_sata_clk);
 }
 
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index a255434..b49c3b7 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -758,12 +758,6 @@
 		.length		= IO_SIZE,
 		.type		= MT_DEVICE
 	},
-	{
-		.virtual	= SRAM_VIRT,
-		.pfn		= __phys_to_pfn(0x00010000),
-		.length		= SZ_32K,
-		.type		= MT_MEMORY_NONCACHED,
-	},
 };
 
 /* Contents of JTAG ID register used to identify exact cpu type */
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index b680c83..6c39805 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -985,12 +985,6 @@
 		.length		= IO_SIZE,
 		.type		= MT_DEVICE
 	},
-	{
-		.virtual	= SRAM_VIRT,
-		.pfn		= __phys_to_pfn(0x00010000),
-		.length		= SZ_32K,
-		.type		= MT_MEMORY_NONCACHED,
-	},
 };
 
 static struct resource dm365_ks_resources[] = {
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index cd0c8b1..9ab1f10 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -786,12 +786,6 @@
 		.length		= IO_SIZE,
 		.type		= MT_DEVICE
 	},
-	{
-		.virtual	= SRAM_VIRT,
-		.pfn		= __phys_to_pfn(0x00008000),
-		.length		= SZ_16K,
-		.type		= MT_MEMORY_NONCACHED,
-	},
 };
 
 /* Contents of JTAG ID register used to identify exact cpu type */
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 97c0f8e..ac7b431 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -756,12 +756,6 @@
 		.length		= IO_SIZE,
 		.type		= MT_DEVICE
 	},
-	{
-		.virtual	= SRAM_VIRT,
-		.pfn		= __phys_to_pfn(0x00010000),
-		.length		= SZ_32K,
-		.type		= MT_MEMORY_NONCACHED,
-	},
 };
 
 /* Contents of JTAG ID register used to identify exact cpu type */
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index bdc4aa8..046c723 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -104,8 +104,6 @@
 static inline int davinci_pm_init(void) { return 0; }
 #endif
 
-/* standard place to map on-chip SRAMs; they *may* support DMA */
-#define SRAM_VIRT	0xfffe0000
 #define SRAM_SIZE	SZ_128K
 
 #endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index aaccdc4..700d311 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -26,6 +26,7 @@
 #include <linux/platform_data/mmc-davinci.h>
 #include <linux/platform_data/usb-davinci.h>
 #include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_data/uio_pruss.h>
 
 #include <media/davinci/vpif_types.h>
 
@@ -72,6 +73,7 @@
 #define DA8XX_AEMIF_CS2_BASE	0x60000000
 #define DA8XX_AEMIF_CS3_BASE	0x62000000
 #define DA8XX_AEMIF_CTL_BASE	0x68000000
+#define DA8XX_SHARED_RAM_BASE	0x80000000
 #define DA8XX_ARM_RAM_BASE	0xffff0000
 
 void __init da830_init(void);
@@ -86,6 +88,7 @@
 int da8xx_register_usb20(unsigned mA, unsigned potpgt);
 int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
 int da8xx_register_emac(void);
+int da8xx_register_uio_pruss(void);
 int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
 int da8xx_register_mmcsd0(struct davinci_mmc_config *config);
 int da850_register_mmcsd1(struct davinci_mmc_config *config);
diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h
index 46b3cd1..2d9d921 100644
--- a/arch/arm/mach-davinci/include/mach/serial.h
+++ b/arch/arm/mach-davinci/include/mach/serial.h
@@ -43,6 +43,7 @@
 };
 
 extern int davinci_serial_init(struct davinci_uart_config *);
+extern int davinci_serial_setup_clk(unsigned instance, unsigned int *rate);
 #endif
 
 #endif /* __ASM_ARCH_SERIAL_H */
diff --git a/arch/arm/mach-davinci/include/mach/sram.h b/arch/arm/mach-davinci/include/mach/sram.h
index 111f7cc..4e5db56 100644
--- a/arch/arm/mach-davinci/include/mach/sram.h
+++ b/arch/arm/mach-davinci/include/mach/sram.h
@@ -24,4 +24,7 @@
 extern void *sram_alloc(size_t len, dma_addr_t *dma);
 extern void sram_free(void *addr, size_t len);
 
+/* Get the struct gen_pool * for use in platform data */
+extern struct gen_pool *sram_get_gen_pool(void);
+
 #endif /* __MACH_SRAM_H */
diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c
index 1875740..f262581 100644
--- a/arch/arm/mach-davinci/serial.c
+++ b/arch/arm/mach-davinci/serial.c
@@ -70,11 +70,33 @@
 				 UART_DM646X_SCR_TX_WATERMARK);
 }
 
+/* Enable UART clock and obtain its rate */
+int __init davinci_serial_setup_clk(unsigned instance, unsigned int *rate)
+{
+	char name[16];
+	struct clk *clk;
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+	struct device *dev = &soc_info->serial_dev->dev;
+
+	sprintf(name, "uart%d", instance);
+	clk = clk_get(dev, name);
+	if (IS_ERR(clk)) {
+		pr_err("%s:%d: failed to get UART%d clock\n",
+					__func__, __LINE__, instance);
+		return PTR_ERR(clk);
+	}
+
+	clk_prepare_enable(clk);
+
+	if (rate)
+		*rate = clk_get_rate(clk);
+
+	return 0;
+}
+
 int __init davinci_serial_init(struct davinci_uart_config *info)
 {
-	int i;
-	char name[16];
-	struct clk *uart_clk;
+	int i, ret;
 	struct davinci_soc_info *soc_info = &davinci_soc_info;
 	struct device *dev = &soc_info->serial_dev->dev;
 	struct plat_serial8250_port *p = dev->platform_data;
@@ -87,16 +109,9 @@
 		if (!(info->enabled_uarts & (1 << i)))
 			continue;
 
-		sprintf(name, "uart%d", i);
-		uart_clk = clk_get(dev, name);
-		if (IS_ERR(uart_clk)) {
-			printk(KERN_ERR "%s:%d: failed to get UART%d clock\n",
-					__func__, __LINE__, i);
+		ret = davinci_serial_setup_clk(i, &p->uartclk);
+		if (ret)
 			continue;
-		}
-
-		clk_enable(uart_clk);
-		p->uartclk = clk_get_rate(uart_clk);
 
 		if (!p->membase && p->mapbase) {
 			p->membase = ioremap(p->mapbase, SZ_4K);
diff --git a/arch/arm/mach-davinci/sram.c b/arch/arm/mach-davinci/sram.c
index db0f778..c5f7ee5 100644
--- a/arch/arm/mach-davinci/sram.c
+++ b/arch/arm/mach-davinci/sram.c
@@ -10,6 +10,7 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/genalloc.h>
 
 #include <mach/common.h>
@@ -17,6 +18,11 @@
 
 static struct gen_pool *sram_pool;
 
+struct gen_pool *sram_get_gen_pool(void)
+{
+	return sram_pool;
+}
+
 void *sram_alloc(size_t len, dma_addr_t *dma)
 {
 	unsigned long vaddr;
@@ -32,7 +38,7 @@
 		return NULL;
 
 	if (dma)
-		*dma = dma_base + (vaddr - SRAM_VIRT);
+		*dma = gen_pool_virt_to_phys(sram_pool, vaddr);
 	return (void *)vaddr;
 
 }
@@ -53,8 +59,10 @@
  */
 static int __init sram_init(void)
 {
+	phys_addr_t phys = davinci_soc_info.sram_dma;
 	unsigned len = davinci_soc_info.sram_len;
 	int status = 0;
+	void *addr;
 
 	if (len) {
 		len = min_t(unsigned, len, SRAM_SIZE);
@@ -62,8 +70,17 @@
 		if (!sram_pool)
 			status = -ENOMEM;
 	}
-	if (sram_pool)
-		status = gen_pool_add(sram_pool, SRAM_VIRT, len, -1);
+
+	if (sram_pool) {
+		addr = ioremap(phys, len);
+		if (!addr)
+			return -ENOMEM;
+		status = gen_pool_add_virt(sram_pool, (unsigned)addr,
+					   phys, len, -1);
+		if (status < 0)
+			iounmap(addr);
+	}
+
 	WARN_ON(status < 0);
 	return status;
 }
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 75da315..9847938 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -379,7 +379,7 @@
 
 	timer_clk = clk_get(NULL, "timer0");
 	BUG_ON(IS_ERR(timer_clk));
-	clk_enable(timer_clk);
+	clk_prepare_enable(timer_clk);
 
 	/* init timer hw */
 	timer_init();
@@ -429,7 +429,7 @@
 	wd_clk = clk_get(&pdev->dev, NULL);
 	if (WARN_ON(IS_ERR(wd_clk)))
 		return;
-	clk_enable(wd_clk);
+	clk_prepare_enable(wd_clk);
 
 	/* disable, internal clock source */
 	__raw_writel(0, base + TCR);
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index da55107..ed17e35 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -67,6 +67,15 @@
 	help
 	  Enable EXYNOS5250 SoC support
 
+config SOC_EXYNOS5440
+	bool "SAMSUNG EXYNOS5440"
+	default y
+	depends on ARCH_EXYNOS5
+	select ARM_ARCH_TIMER
+	select AUTO_ZRELADDR
+	help
+	  Enable EXYNOS5440 SoC support
+
 config EXYNOS4_MCT
 	bool
 	default y
@@ -417,9 +426,9 @@
 
 config MACH_EXYNOS5_DT
 	bool "SAMSUNG EXYNOS5 Machine using device tree"
+	default y
 	depends on ARCH_EXYNOS5
 	select ARM_AMBA
-	select SOC_EXYNOS5250
 	select USE_OF
 	help
 	  Machine support for Samsung EXYNOS5 machine with device tree enabled.
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 9b58024..1a076df0 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -14,9 +14,9 @@
 
 obj-$(CONFIG_ARCH_EXYNOS)	+= common.o
 obj-$(CONFIG_ARCH_EXYNOS4)	+= clock-exynos4.o
-obj-$(CONFIG_ARCH_EXYNOS5)	+= clock-exynos5.o
 obj-$(CONFIG_CPU_EXYNOS4210)	+= clock-exynos4210.o
 obj-$(CONFIG_SOC_EXYNOS4212)	+= clock-exynos4212.o
+obj-$(CONFIG_SOC_EXYNOS5250)	+= clock-exynos5.o
 
 obj-$(CONFIG_PM)		+= pm.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 715b690..68b4b8e 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -18,6 +18,7 @@
 #include <linux/sched.h>
 #include <linux/serial_core.h>
 #include <linux/of.h>
+#include <linux/of_fdt.h>
 #include <linux/of_irq.h>
 #include <linux/export.h>
 #include <linux/irqdomain.h>
@@ -47,6 +48,7 @@
 #include <plat/fimc-core.h>
 #include <plat/iic-core.h>
 #include <plat/tv-core.h>
+#include <plat/spi-core.h>
 #include <plat/regs-serial.h>
 
 #include "common.h"
@@ -57,9 +59,11 @@
 static const char name_exynos4212[] = "EXYNOS4212";
 static const char name_exynos4412[] = "EXYNOS4412";
 static const char name_exynos5250[] = "EXYNOS5250";
+static const char name_exynos5440[] = "EXYNOS5440";
 
 static void exynos4_map_io(void);
 static void exynos5_map_io(void);
+static void exynos5440_map_io(void);
 static void exynos4_init_clocks(int xtal);
 static void exynos5_init_clocks(int xtal);
 static void exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no);
@@ -98,6 +102,12 @@
 		.init_uarts	= exynos_init_uarts,
 		.init		= exynos_init,
 		.name		= name_exynos5250,
+	}, {
+		.idcode		= EXYNOS5440_SOC_ID,
+		.idmask		= EXYNOS5_SOC_MASK,
+		.map_io		= exynos5440_map_io,
+		.init		= exynos_init,
+		.name		= name_exynos5440,
 	},
 };
 
@@ -112,6 +122,17 @@
 	},
 };
 
+#ifdef CONFIG_ARCH_EXYNOS5
+static struct map_desc exynos5440_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_CHIPID,
+		.pfn		= __phys_to_pfn(EXYNOS5440_PA_CHIPID),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+#endif
+
 static struct map_desc exynos4_iodesc[] __initdata = {
 	{
 		.virtual	= (unsigned long)S3C_VA_SYS,
@@ -278,6 +299,15 @@
 	},
 };
 
+static struct map_desc exynos5440_iodesc0[] __initdata = {
+	{
+		.virtual	= (unsigned long)S3C_VA_UART,
+		.pfn		= __phys_to_pfn(EXYNOS5440_PA_UART0),
+		.length		= SZ_512K,
+		.type		= MT_DEVICE,
+	},
+};
+
 void exynos4_restart(char mode, const char *cmd)
 {
 	__raw_writel(0x1, S5P_SWRESET);
@@ -285,11 +315,29 @@
 
 void exynos5_restart(char mode, const char *cmd)
 {
-	__raw_writel(0x1, EXYNOS_SWRESET);
+	u32 val;
+	void __iomem *addr;
+
+	if (of_machine_is_compatible("samsung,exynos5250")) {
+		val = 0x1;
+		addr = EXYNOS_SWRESET;
+	} else if (of_machine_is_compatible("samsung,exynos5440")) {
+		val = (0x10 << 20) | (0x1 << 16);
+		addr = EXYNOS5440_SWRESET;
+	} else {
+		pr_err("%s: cannot support non-DT\n", __func__);
+		return;
+	}
+
+	__raw_writel(val, addr);
 }
 
 void __init exynos_init_late(void)
 {
+	if (of_machine_is_compatible("samsung,exynos5440"))
+		/* to be supported later */
+		return;
+
 	exynos_pm_late_initcall();
 }
 
@@ -301,8 +349,20 @@
 
 void __init exynos_init_io(struct map_desc *mach_desc, int size)
 {
+	struct map_desc *iodesc = exynos_iodesc;
+	int iodesc_sz = ARRAY_SIZE(exynos_iodesc);
+#if defined(CONFIG_OF) && defined(CONFIG_ARCH_EXYNOS5)
+	unsigned long root = of_get_flat_dt_root();
+
 	/* initialize the io descriptors we need for initialization */
-	iotable_init(exynos_iodesc, ARRAY_SIZE(exynos_iodesc));
+	if (of_flat_dt_is_compatible(root, "samsung,exynos5440")) {
+		iodesc = exynos5440_iodesc;
+		iodesc_sz = ARRAY_SIZE(exynos5440_iodesc);
+	}
+#endif
+
+	iotable_init(iodesc, iodesc_sz);
+
 	if (mach_desc)
 		iotable_init(mach_desc, size);
 
@@ -346,6 +406,8 @@
 
 	s5p_fb_setname(0, "exynos4-fb");
 	s5p_hdmi_setname("exynos4-hdmi");
+
+	s3c64xx_spi_setname("exynos4210-spi");
 }
 
 static void __init exynos5_map_io(void)
@@ -366,6 +428,8 @@
 	s3c_i2c0_setname("s3c2440-i2c");
 	s3c_i2c1_setname("s3c2440-i2c");
 	s3c_i2c2_setname("s3c2440-i2c");
+
+	s3c64xx_spi_setname("exynos4210-spi");
 }
 
 static void __init exynos4_init_clocks(int xtal)
@@ -384,6 +448,11 @@
 	exynos4_setup_clocks();
 }
 
+static void __init exynos5440_map_io(void)
+{
+	iotable_init(exynos5440_iodesc0, ARRAY_SIZE(exynos5440_iodesc0));
+}
+
 static void __init exynos5_init_clocks(int xtal)
 {
 	printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
@@ -599,8 +668,9 @@
 	return 0;
 }
 
-static const struct of_device_id exynos4_dt_irq_match[] = {
+static const struct of_device_id exynos_dt_irq_match[] = {
 	{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
+	{ .compatible = "arm,cortex-a15-gic", .data = gic_of_init, },
 	{ .compatible = "samsung,exynos4210-combiner",
 			.data = combiner_of_init, },
 	{},
@@ -617,7 +687,7 @@
 		gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset, NULL);
 #ifdef CONFIG_OF
 	else
-		of_irq_init(exynos4_dt_irq_match);
+		of_irq_init(exynos_dt_irq_match);
 #endif
 
 	if (!of_have_populated_dt())
@@ -634,7 +704,7 @@
 void __init exynos5_init_irq(void)
 {
 #ifdef CONFIG_OF
-	of_irq_init(exynos4_dt_irq_match);
+	of_irq_init(exynos_dt_irq_match);
 #endif
 	/*
 	 * The parameters of s5p_init_irq() are for VIC init.
@@ -664,7 +734,7 @@
 {
 	int ret;
 
-	if (soc_is_exynos5250())
+	if (soc_is_exynos5250() || soc_is_exynos5440())
 		return 0;
 
 	ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
@@ -1005,6 +1075,8 @@
 		}
 	}
 #endif
+	if (soc_is_exynos5440())
+		return 0;
 
 	if (soc_is_exynos5250())
 		exynos_eint_base = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
index 35bced6..f43a96c 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -333,6 +333,11 @@
 #define EXYNOS5_IRQ_FIMC_LITE1		IRQ_SPI(126)
 #define EXYNOS5_IRQ_RP_TIMER		IRQ_SPI(127)
 
+/* EXYNOS5440 */
+
+#define EXYNOS5440_IRQ_UART0		IRQ_SPI(2)
+#define EXYNOS5440_IRQ_UART1		IRQ_SPI(3)
+
 #define EXYNOS5_IRQ_PMU			COMBINER_IRQ(1, 2)
 
 #define EXYNOS5_IRQ_SYSMMU_GSC0_0	COMBINER_IRQ(2, 0)
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 8480849..aa3760e 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -53,6 +53,7 @@
 #define EXYNOS4_PA_ONENAND_DMA		0x0C600000
 
 #define EXYNOS_PA_CHIPID		0x10000000
+#define EXYNOS5440_PA_CHIPID		0x00160000
 
 #define EXYNOS4_PA_SYSCON		0x10010000
 #define EXYNOS5_PA_SYSCON		0x10050100
@@ -281,6 +282,10 @@
 #define EXYNOS5_PA_UART3		0x12C30000
 #define EXYNOS5_SZ_UART			SZ_256
 
+#define EXYNOS5440_PA_UART0		0x000B0000
+#define EXYNOS5440_PA_UART1		0x000C0000
+#define EXYNOS5440_SZ_UART		SZ_256
+
 #define S3C_VA_UARTx(x)			(S3C_VA_UART + ((x) * S3C_UART_OFFSET))
 
 #endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
index d4e392b..c0b74f3 100644
--- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
@@ -31,6 +31,7 @@
 
 #define S5P_SWRESET				S5P_PMUREG(0x0400)
 #define EXYNOS_SWRESET				S5P_PMUREG(0x0400)
+#define EXYNOS5440_SWRESET			S5P_PMUREG(0x00C4)
 
 #define S5P_WAKEUP_STAT				S5P_PMUREG(0x0600)
 #define S5P_EINT_WAKEUP_MASK			S5P_PMUREG(0x0604)
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index e58d786..6df99c0 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -77,6 +77,7 @@
 				"exynos4210-spi.2", NULL),
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
+	OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_MDMA1, "dma-pl330.2", NULL),
 	{},
 };
 
@@ -99,6 +100,7 @@
 
 DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
 	/* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
+	.smp		= smp_ops(exynos_smp_ops),
 	.init_irq	= exynos4_init_irq,
 	.map_io		= exynos4_dt_map_io,
 	.handle_irq	= gic_handle_irq,
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index db1cd8e..f1326be 100644
--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
@@ -10,6 +10,7 @@
 */
 
 #include <linux/of_platform.h>
+#include <linux/of_fdt.h>
 #include <linux/serial_core.h>
 
 #include <asm/mach/arch.h>
@@ -75,20 +76,35 @@
 	{},
 };
 
-static void __init exynos5250_dt_map_io(void)
+static const struct of_dev_auxdata exynos5440_auxdata_lookup[] __initconst = {
+	OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5440_PA_UART0,
+				"exynos4210-uart.0", NULL),
+	{},
+};
+
+static void __init exynos5_dt_map_io(void)
 {
+	unsigned long root = of_get_flat_dt_root();
+
 	exynos_init_io(NULL, 0);
-	s3c24xx_init_clocks(24000000);
+
+	if (of_flat_dt_is_compatible(root, "samsung,exynos5250"))
+		s3c24xx_init_clocks(24000000);
 }
 
-static void __init exynos5250_dt_machine_init(void)
+static void __init exynos5_dt_machine_init(void)
 {
-	of_platform_populate(NULL, of_default_bus_match_table,
-				exynos5250_auxdata_lookup, NULL);
+	if (of_machine_is_compatible("samsung,exynos5250"))
+		of_platform_populate(NULL, of_default_bus_match_table,
+				     exynos5250_auxdata_lookup, NULL);
+	else if (of_machine_is_compatible("samsung,exynos5440"))
+		of_platform_populate(NULL, of_default_bus_match_table,
+				     exynos5440_auxdata_lookup, NULL);
 }
 
-static char const *exynos5250_dt_compat[] __initdata = {
+static char const *exynos5_dt_compat[] __initdata = {
 	"samsung,exynos5250",
+	"samsung,exynos5440",
 	NULL
 };
 
@@ -96,11 +112,11 @@
 	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
 	.init_irq	= exynos5_init_irq,
 	.smp		= smp_ops(exynos_smp_ops),
-	.map_io		= exynos5250_dt_map_io,
+	.map_io		= exynos5_dt_map_io,
 	.handle_irq	= gic_handle_irq,
-	.init_machine	= exynos5250_dt_machine_init,
+	.init_machine	= exynos5_dt_machine_init,
 	.init_late	= exynos_init_late,
 	.timer		= &exynos4_timer,
-	.dt_compat	= exynos5250_dt_compat,
+	.dt_compat	= exynos5_dt_compat,
 	.restart        = exynos5_restart,
 MACHINE_END
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index b601fb8..57668eb 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -19,7 +19,9 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/percpu.h>
+#include <linux/of.h>
 
+#include <asm/arch_timer.h>
 #include <asm/hardware/gic.h>
 #include <asm/localtimer.h>
 
@@ -476,8 +478,13 @@
 #endif /* CONFIG_LOCAL_TIMERS */
 }
 
-static void __init exynos4_timer_init(void)
+static void __init exynos_timer_init(void)
 {
+	if (soc_is_exynos5440()) {
+		arch_timer_of_register();
+		return;
+	}
+
 	if ((soc_is_exynos4210()) || (soc_is_exynos5250()))
 		mct_int_type = MCT_INT_SPI;
 	else
@@ -489,5 +496,5 @@
 }
 
 struct sys_timer exynos4_timer = {
-	.init		= exynos4_timer_init,
+	.init		= exynos_timer_init,
 };
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index f93d820..4ca8ff1 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -36,8 +36,22 @@
 
 extern void exynos4_secondary_startup(void);
 
-#define CPU1_BOOT_REG		(samsung_rev() == EXYNOS4210_REV_1_1 ? \
-				S5P_INFORM5 : S5P_VA_SYSRAM)
+static inline void __iomem *cpu_boot_reg_base(void)
+{
+	if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
+		return S5P_INFORM5;
+	return S5P_VA_SYSRAM;
+}
+
+static inline void __iomem *cpu_boot_reg(int cpu)
+{
+	void __iomem *boot_reg;
+
+	boot_reg = cpu_boot_reg_base();
+	if (soc_is_exynos4412())
+		boot_reg += 4*cpu;
+	return boot_reg;
+}
 
 /*
  * Write pen_release in a way that is guaranteed to be visible to all
@@ -84,6 +98,7 @@
 static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
+	unsigned long phys_cpu = cpu_logical_map(cpu);
 
 	/*
 	 * Set synchronisation state between this boot processor
@@ -99,7 +114,7 @@
 	 * Note that "pen_release" is the hardware CPU ID, whereas
 	 * "cpu" is Linux's internal ID.
 	 */
-	write_pen_release(cpu_logical_map(cpu));
+	write_pen_release(phys_cpu);
 
 	if (!(__raw_readl(S5P_ARM_CORE1_STATUS) & S5P_CORE_LOCAL_PWR_EN)) {
 		__raw_writel(S5P_CORE_LOCAL_PWR_EN,
@@ -133,7 +148,7 @@
 		smp_rmb();
 
 		__raw_writel(virt_to_phys(exynos4_secondary_startup),
-			CPU1_BOOT_REG);
+							cpu_boot_reg(phys_cpu));
 		gic_raise_softirq(cpumask_of(cpu), 0);
 
 		if (pen_release == -1)
@@ -181,6 +196,8 @@
 
 static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 {
+	int i;
+
 	if (!soc_is_exynos5250())
 		scu_enable(scu_base_addr());
 
@@ -190,8 +207,9 @@
 	 * until it receives a soft interrupt, and then the
 	 * secondary CPU branches to this address.
 	 */
-	__raw_writel(virt_to_phys(exynos4_secondary_startup),
-			CPU1_BOOT_REG);
+	for (i = 1; i < max_cpus; ++i)
+		__raw_writel(virt_to_phys(exynos4_secondary_startup),
+					cpu_boot_reg(cpu_logical_map(i)));
 }
 
 struct smp_operations exynos_smp_ops __initdata = {
diff --git a/arch/arm/mach-exynos/setup-i2c0.c b/arch/arm/mach-exynos/setup-i2c0.c
index 5700f23..e2d9dfb 100644
--- a/arch/arm/mach-exynos/setup-i2c0.c
+++ b/arch/arm/mach-exynos/setup-i2c0.c
@@ -20,7 +20,7 @@
 
 void s3c_i2c0_cfg_gpio(struct platform_device *dev)
 {
-	if (soc_is_exynos5250())
+	if (soc_is_exynos5250() || soc_is_exynos5440())
 		/* will be implemented with gpio function */
 		return;
 
diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig
index 0e1d0a4..551c97e 100644
--- a/arch/arm/mach-highbank/Kconfig
+++ b/arch/arm/mach-highbank/Kconfig
@@ -1,5 +1,5 @@
 config ARCH_HIGHBANK
-	bool "Calxeda ECX-1000 (Highbank)" if ARCH_MULTI_V7
+	bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARM_AMBA
 	select ARM_GIC
diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile
index 3ec8bdd..8a1ef57 100644
--- a/arch/arm/mach-highbank/Makefile
+++ b/arch/arm/mach-highbank/Makefile
@@ -3,7 +3,6 @@
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_smc.o				:=-Wa,-march=armv7-a$(plus_sec)
 
-obj-$(CONFIG_DEBUG_HIGHBANK_UART)	+= lluart.o
 obj-$(CONFIG_SMP)			+= platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
 obj-$(CONFIG_PM_SLEEP)			+= pm.o
diff --git a/arch/arm/mach-highbank/core.h b/arch/arm/mach-highbank/core.h
index 286ec82..80235b4 100644
--- a/arch/arm/mach-highbank/core.h
+++ b/arch/arm/mach-highbank/core.h
@@ -1,12 +1,10 @@
+#ifndef __HIGHBANK_CORE_H
+#define __HIGHBANK_CORE_H
+
 extern void highbank_set_cpu_jump(int cpu, void *jump_addr);
 extern void highbank_clocks_init(void);
 extern void highbank_restart(char, const char *);
 extern void __iomem *scu_base_addr;
-#ifdef CONFIG_DEBUG_HIGHBANK_UART
-extern void highbank_lluart_map_io(void);
-#else
-static inline void highbank_lluart_map_io(void) {}
-#endif
 
 #ifdef CONFIG_PM_SLEEP
 extern void highbank_pm_init(void);
@@ -18,3 +16,5 @@
 extern void highbank_cpu_die(unsigned int cpu);
 
 extern struct smp_operations highbank_smp_ops;
+
+#endif
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index 40e36a5..dc24816 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -26,9 +26,9 @@
 #include <linux/smp.h>
 #include <linux/amba/bus.h>
 
+#include <asm/arch_timer.h>
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
-#include <asm/smp_scu.h>
 #include <asm/smp_twd.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/timer-sp.h>
@@ -42,16 +42,7 @@
 #include "sysregs.h"
 
 void __iomem *sregs_base;
-
-#define HB_SCU_VIRT_BASE	0xfee00000
-void __iomem *scu_base_addr = ((void __iomem *)(HB_SCU_VIRT_BASE));
-
-static struct map_desc scu_io_desc __initdata = {
-	.virtual	= HB_SCU_VIRT_BASE,
-	.pfn		= 0, /* run-time */
-	.length		= SZ_4K,
-	.type		= MT_DEVICE,
-};
+void __iomem *scu_base_addr;
 
 static void __init highbank_scu_map_io(void)
 {
@@ -60,14 +51,7 @@
 	/* Get SCU base */
 	asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
 
-	scu_io_desc.pfn = __phys_to_pfn(base);
-	iotable_init(&scu_io_desc, 1);
-}
-
-static void __init highbank_map_io(void)
-{
-	highbank_scu_map_io();
-	highbank_lluart_map_io();
+	scu_base_addr = ioremap(base, SZ_4K);
 }
 
 #define HB_JUMP_TABLE_PHYS(cpu)		(0x40 + (0x10 * (cpu)))
@@ -83,6 +67,7 @@
 }
 
 const static struct of_device_id irq_match[] = {
+	{ .compatible = "arm,cortex-a15-gic", .data = gic_of_init, },
 	{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
 	{}
 };
@@ -99,6 +84,9 @@
 {
 	of_irq_init(irq_match);
 
+	if (of_find_compatible_node(NULL, NULL, "arm,cortex-a9"))
+		highbank_scu_map_io();
+
 #ifdef CONFIG_CACHE_L2X0
 	/* Enable PL310 L2 Cache controller */
 	highbank_smc1(0x102, 0x1);
@@ -136,6 +124,9 @@
 	sp804_clockevents_init(timer_base, irq, "timer0");
 
 	twd_local_timer_of_register();
+
+	arch_timer_of_register();
+	arch_timer_sched_clock_init();
 }
 
 static struct sys_timer highbank_timer = {
@@ -145,7 +136,6 @@
 static void highbank_power_off(void)
 {
 	hignbank_set_pwr_shutdown();
-	scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
 
 	while (1)
 		cpu_do_idle();
@@ -211,12 +201,13 @@
 
 static const char *highbank_match[] __initconst = {
 	"calxeda,highbank",
+	"calxeda,ecx-2000",
 	NULL,
 };
 
 DT_MACHINE_START(HIGHBANK, "Highbank")
 	.smp		= smp_ops(highbank_smp_ops),
-	.map_io		= highbank_map_io,
+	.map_io		= debug_ll_io_init,
 	.init_irq	= highbank_init_irq,
 	.timer		= &highbank_timer,
 	.handle_irq	= gic_handle_irq,
diff --git a/arch/arm/mach-highbank/hotplug.c b/arch/arm/mach-highbank/hotplug.c
index 2c1b8c3..7b60fac 100644
--- a/arch/arm/mach-highbank/hotplug.c
+++ b/arch/arm/mach-highbank/hotplug.c
@@ -14,13 +14,11 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/smp.h>
 
-#include <asm/smp_scu.h>
 #include <asm/cacheflush.h>
 
 #include "core.h"
+#include "sysregs.h"
 
 extern void secondary_startup(void);
 
@@ -33,7 +31,7 @@
 	flush_cache_all();
 
 	highbank_set_cpu_jump(cpu, secondary_startup);
-	scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
+	highbank_set_core_pwr();
 
 	cpu_do_idle();
 
diff --git a/arch/arm/mach-highbank/lluart.c b/arch/arm/mach-highbank/lluart.c
deleted file mode 100644
index 3715750..0000000
--- a/arch/arm/mach-highbank/lluart.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2011 Calxeda, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-#include <linux/init.h>
-#include <asm/page.h>
-#include <asm/sizes.h>
-#include <asm/mach/map.h>
-
-#define HB_DEBUG_LL_PHYS_BASE	0xfff36000
-#define HB_DEBUG_LL_VIRT_BASE	0xfee36000
-
-static struct map_desc lluart_io_desc __initdata = {
-	.virtual	= HB_DEBUG_LL_VIRT_BASE,
-	.pfn		= __phys_to_pfn(HB_DEBUG_LL_PHYS_BASE),
-	.length		= SZ_4K,
-	.type		= MT_DEVICE,
-};
-
-void __init highbank_lluart_map_io(void)
-{
-	iotable_init(&lluart_io_desc, 1);
-}
diff --git a/arch/arm/mach-highbank/platsmp.c b/arch/arm/mach-highbank/platsmp.c
index fa9560e..1129957 100644
--- a/arch/arm/mach-highbank/platsmp.c
+++ b/arch/arm/mach-highbank/platsmp.c
@@ -42,9 +42,7 @@
  */
 static void __init highbank_smp_init_cpus(void)
 {
-	unsigned int i, ncores;
-
-	ncores = scu_get_core_count(scu_base_addr);
+	unsigned int i, ncores = 4;
 
 	/* sanity check */
 	if (ncores > NR_CPUS) {
@@ -65,7 +63,8 @@
 {
 	int i;
 
-	scu_enable(scu_base_addr);
+	if (scu_base_addr)
+		scu_enable(scu_base_addr);
 
 	/*
 	 * Write the address of secondary startup into the jump table
diff --git a/arch/arm/mach-highbank/pm.c b/arch/arm/mach-highbank/pm.c
index de866f2..74aa135 100644
--- a/arch/arm/mach-highbank/pm.c
+++ b/arch/arm/mach-highbank/pm.c
@@ -19,7 +19,6 @@
 #include <linux/suspend.h>
 
 #include <asm/proc-fns.h>
-#include <asm/smp_scu.h>
 #include <asm/suspend.h>
 
 #include "core.h"
@@ -35,8 +34,6 @@
 {
 	hignbank_set_pwr_suspend();
 	highbank_set_cpu_jump(0, cpu_resume);
-
-	scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
 	cpu_suspend(0, highbank_suspend_finish);
 
 	return 0;
diff --git a/arch/arm/mach-highbank/sysregs.h b/arch/arm/mach-highbank/sysregs.h
index 0e91338..e13e8ea 100644
--- a/arch/arm/mach-highbank/sysregs.h
+++ b/arch/arm/mach-highbank/sysregs.h
@@ -17,6 +17,10 @@
 #define _MACH_HIGHBANK__SYSREGS_H_
 
 #include <linux/io.h>
+#include <linux/smp.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+#include "core.h"
 
 extern void __iomem *sregs_base;
 
@@ -29,24 +33,39 @@
 #define HB_PWR_HARD_RESET		2
 #define HB_PWR_SHUTDOWN			3
 
+#define SREG_CPU_PWR_CTRL(c)		(0x200 + ((c) * 4))
+
+static inline void highbank_set_core_pwr(void)
+{
+	int cpu = cpu_logical_map(smp_processor_id());
+	if (scu_base_addr)
+		scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
+	else
+		writel_relaxed(1, sregs_base + SREG_CPU_PWR_CTRL(cpu));
+}
+
 static inline void hignbank_set_pwr_suspend(void)
 {
 	writel(HB_PWR_SUSPEND, sregs_base + HB_SREG_A9_PWR_REQ);
+	highbank_set_core_pwr();
 }
 
 static inline void hignbank_set_pwr_shutdown(void)
 {
 	writel(HB_PWR_SHUTDOWN, sregs_base + HB_SREG_A9_PWR_REQ);
+	highbank_set_core_pwr();
 }
 
 static inline void hignbank_set_pwr_soft_reset(void)
 {
 	writel(HB_PWR_SOFT_RESET, sregs_base + HB_SREG_A9_PWR_REQ);
+	highbank_set_core_pwr();
 }
 
 static inline void hignbank_set_pwr_hard_reset(void)
 {
 	writel(HB_PWR_HARD_RESET, sregs_base + HB_SREG_A9_PWR_REQ);
+	highbank_set_core_pwr();
 }
 
 #endif
diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c
index 82c27230..aed96ad 100644
--- a/arch/arm/mach-highbank/system.c
+++ b/arch/arm/mach-highbank/system.c
@@ -14,7 +14,6 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/io.h>
-#include <asm/smp_scu.h>
 #include <asm/proc-fns.h>
 
 #include "core.h"
@@ -27,7 +26,7 @@
 	else
 		hignbank_set_pwr_soft_reset();
 
-	scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
-	cpu_do_idle();
+	while (1)
+		cpu_do_idle();
 }
 
diff --git a/arch/arm/plat-mxc/3ds_debugboard.c b/arch/arm/mach-imx/3ds_debugboard.c
similarity index 99%
rename from arch/arm/plat-mxc/3ds_debugboard.c
rename to arch/arm/mach-imx/3ds_debugboard.c
index 5c10ad0..1343773 100644
--- a/arch/arm/plat-mxc/3ds_debugboard.c
+++ b/arch/arm/mach-imx/3ds_debugboard.c
@@ -21,7 +21,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
 
-#include <mach/hardware.h>
+#include "hardware.h"
 
 /* LAN9217 ethernet base address */
 #define LAN9217_BASE_ADDR(n)	(n + 0x0)
diff --git a/arch/arm/plat-mxc/include/mach/3ds_debugboard.h b/arch/arm/mach-imx/3ds_debugboard.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/3ds_debugboard.h
rename to arch/arm/mach-imx/3ds_debugboard.h
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 8d27658..4e24b8c 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -1,3 +1,70 @@
+config ARCH_MXC
+	bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_PATCH_PHYS_VIRT
+	select AUTO_ZRELADDR if !ZBOOT_ROM
+	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_IRQ_CHIP
+	select MULTI_IRQ_HANDLER
+	select SPARSE_IRQ
+	select USE_OF
+	help
+	  Support for Freescale MXC/iMX-based family of processors
+
+menu "Freescale i.MX support"
+	depends on ARCH_MXC
+
+config MXC_IRQ_PRIOR
+	bool "Use IRQ priority"
+	help
+	  Select this if you want to use prioritized IRQ handling.
+	  This feature prevents higher priority ISR to be interrupted
+	  by lower priority IRQ even IRQF_DISABLED flag is not set.
+	  This may be useful in embedded applications, where are strong
+	  requirements for timing.
+	  Say N here, unless you have a specialized requirement.
+
+config MXC_TZIC
+	bool
+
+config MXC_AVIC
+	bool
+
+config MXC_DEBUG_BOARD
+	bool "Enable MXC debug board(for 3-stack)"
+	help
+	  The debug board is an integral part of the MXC 3-stack(PDK)
+	  platforms, it can be attached or removed from the peripheral
+	  board. On debug board, several debug devices(ethernet, UART,
+	  buttons, LEDs and JTAG) are implemented. Between the MCU and
+	  these devices, a CPLD is added as a bridge which performs
+	  data/address de-multiplexing and decode, signal level shift,
+	  interrupt control and various board functions.
+
+config HAVE_EPIT
+	bool
+
+config MXC_USE_EPIT
+	bool "Use EPIT instead of GPT"
+	depends on HAVE_EPIT
+	help
+	  Use EPIT as the system timer on systems that have it. Normally you
+	  don't have a reason to do so as the EPIT has the same features and
+	  uses the same clocks as the GPT. Anyway, on some systems the GPT
+	  may be in use for other purposes.
+
+config MXC_ULPI
+	bool
+
+config ARCH_HAS_RNGA
+	bool
+
+config IRAM_ALLOC
+	bool
+	select GENERIC_ALLOCATOR
+
 config HAVE_IMX_GPC
 	bool
 
@@ -5,6 +72,12 @@
 	bool
 
 config HAVE_IMX_SRC
+	def_bool y if SMP
+
+config IMX_HAVE_IOMUX_V1
+	bool
+
+config ARCH_MXC_IOMUX_V3
 	bool
 
 config ARCH_MX1
@@ -104,7 +177,7 @@
 	select PINCTRL_IMX51
 	select SOC_IMX5
 
-if ARCH_IMX_V4_V5
+if ARCH_MULTI_V4T
 
 comment "MX1 platforms:"
 config MACH_MXLADS
@@ -133,6 +206,10 @@
 	help
 	  Say Yes here if you are using the Armadeus APF9328 development board
 
+endif
+
+if ARCH_MULTI_V5
+
 comment "MX21 platforms:"
 
 config MACH_MX21ADS
@@ -317,6 +394,7 @@
 	select IMX_HAVE_PLATFORM_IMX_SSI
 	select IMX_HAVE_PLATFORM_IMX_UART
 	select IMX_HAVE_PLATFORM_MX2_CAMERA
+	select IMX_HAVE_PLATFORM_MX2_EMMA
 	select IMX_HAVE_PLATFORM_MXC_EHCI
 	select IMX_HAVE_PLATFORM_MXC_MMC
 	select LEDS_GPIO_REGISTER
@@ -384,7 +462,7 @@
 
 endif
 
-if ARCH_IMX_V6_V7
+if ARCH_MULTI_V6
 
 comment "MX31 platforms:"
 
@@ -649,6 +727,10 @@
 	  Include support for VPR200 platform. This includes specific
 	  configurations for the board and its peripherals.
 
+endif
+
+if ARCH_MULTI_V7
+
 comment "i.MX5 platforms:"
 
 config MACH_MX50_RDP
@@ -739,6 +821,7 @@
 	select ARCH_MX5
 	select ARCH_MX53
 	select HAVE_CAN_FLEXCAN if CAN
+	select IMX_HAVE_PLATFORM_IMX2_WDT
 	select PINCTRL
 	select PINCTRL_IMX53
 	select SOC_IMX5
@@ -756,7 +839,6 @@
 	select HAVE_CAN_FLEXCAN if CAN
 	select HAVE_IMX_GPC
 	select HAVE_IMX_MMDC
-	select HAVE_IMX_SRC
 	select HAVE_SMP
 	select MFD_SYSCON
 	select PINCTRL
@@ -766,3 +848,7 @@
 	  This enables support for Freescale i.MX6 Quad processor.
 
 endif
+
+source "arch/arm/mach-imx/devices/Kconfig"
+
+endmenu
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 895754a..fe47b71 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,3 +1,5 @@
+obj-y := time.o cpu.o system.o irq-common.o
+
 obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o
 obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o
 
@@ -15,6 +17,24 @@
 obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
 			    clk-pfd.o clk-busy.o clk.o
 
+obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
+obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
+
+obj-$(CONFIG_MXC_TZIC) += tzic.o
+obj-$(CONFIG_MXC_AVIC) += avic.o
+
+obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
+obj-$(CONFIG_MXC_ULPI) += ulpi.o
+obj-$(CONFIG_MXC_USE_EPIT) += epit.o
+obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
+obj-$(CONFIG_CPU_FREQ_IMX)    += cpufreq.o
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+
+ifdef CONFIG_SND_IMX_SOC
+obj-y += ssi-fiq.o
+obj-y += ssi-fiq-ksym.o
+endif
+
 # Support for CMOS sensor interface
 obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
 
@@ -89,3 +109,5 @@
 
 obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o
 obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
+
+obj-y += devices/
diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/mach-imx/avic.c
similarity index 98%
rename from arch/arm/plat-mxc/avic.c
rename to arch/arm/mach-imx/avic.c
index cbd55c3..0eff23e 100644
--- a/arch/arm/plat-mxc/avic.c
+++ b/arch/arm/mach-imx/avic.c
@@ -22,12 +22,11 @@
 #include <linux/irqdomain.h>
 #include <linux/io.h>
 #include <linux/of.h>
-#include <mach/common.h>
 #include <asm/mach/irq.h>
 #include <asm/exception.h>
-#include <mach/hardware.h>
-#include <mach/irqs.h>
 
+#include "common.h"
+#include "hardware.h"
 #include "irq-common.h"
 
 #define AVIC_INTCNTL		0x00	/* int control reg */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lilly.h b/arch/arm/mach-imx/board-mx31lilly.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/board-mx31lilly.h
rename to arch/arm/mach-imx/board-mx31lilly.h
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lite.h b/arch/arm/mach-imx/board-mx31lite.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/board-mx31lite.h
rename to arch/arm/mach-imx/board-mx31lite.h
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h b/arch/arm/mach-imx/board-mx31moboard.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/board-mx31moboard.h
rename to arch/arm/mach-imx/board-mx31moboard.h
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm038.h b/arch/arm/mach-imx/board-pcm038.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/board-pcm038.h
rename to arch/arm/mach-imx/board-pcm038.h
diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c
index 1a7a8dd..1ab91b5 100644
--- a/arch/arm/mach-imx/clk-busy.c
+++ b/arch/arm/mach-imx/clk-busy.c
@@ -108,7 +108,7 @@
 	busy->div.hw.init = &init;
 
 	clk = clk_register(NULL, &busy->div.hw);
-	if (!clk)
+	if (IS_ERR(clk))
 		kfree(busy);
 
 	return clk;
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
index 3c1b8ff..cc49c7a 100644
--- a/arch/arm/mach-imx/clk-gate2.c
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -112,7 +112,7 @@
 
 	clk = clk_register(dev, &gate->hw);
 	if (IS_ERR(clk))
-		kfree(clk);
+		kfree(gate);
 
 	return clk;
 }
diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c
index 516ddee..15f9d22 100644
--- a/arch/arm/mach-imx/clk-imx1.c
+++ b/arch/arm/mach-imx/clk-imx1.c
@@ -22,9 +22,9 @@
 #include <linux/clkdev.h>
 #include <linux/err.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
 #include "clk.h"
+#include "common.h"
+#include "hardware.h"
 
 /* CCM register addresses */
 #define IO_ADDR_CCM(off)	(MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
@@ -82,7 +82,8 @@
 			pr_err("imx1 clk %d: register failed with %ld\n",
 				i, PTR_ERR(clk[i]));
 
-	clk_register_clkdev(clk[dma_gate], "ahb", "imx-dma");
+	clk_register_clkdev(clk[dma_gate], "ahb", "imx1-dma");
+	clk_register_clkdev(clk[hclk], "ipg", "imx1-dma");
 	clk_register_clkdev(clk[csi_gate], NULL, "mx1-camera.0");
 	clk_register_clkdev(clk[mma_gate], "mma", NULL);
 	clk_register_clkdev(clk[usbd_gate], NULL, "imx_udc.0");
@@ -94,18 +95,18 @@
 	clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.1");
 	clk_register_clkdev(clk[per1], "per", "imx1-uart.2");
 	clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.2");
-	clk_register_clkdev(clk[hclk], NULL, "imx-i2c.0");
+	clk_register_clkdev(clk[hclk], NULL, "imx1-i2c.0");
 	clk_register_clkdev(clk[per2], "per", "imx1-cspi.0");
 	clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.0");
 	clk_register_clkdev(clk[per2], "per", "imx1-cspi.1");
 	clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.1");
 	clk_register_clkdev(clk[per2], NULL, "imx-mmc.0");
-	clk_register_clkdev(clk[per2], "per", "imx-fb.0");
-	clk_register_clkdev(clk[dummy], "ipg", "imx-fb.0");
-	clk_register_clkdev(clk[dummy], "ahb", "imx-fb.0");
+	clk_register_clkdev(clk[per2], "per", "imx1-fb.0");
+	clk_register_clkdev(clk[dummy], "ipg", "imx1-fb.0");
+	clk_register_clkdev(clk[dummy], "ahb", "imx1-fb.0");
 	clk_register_clkdev(clk[hclk], "mshc", NULL);
 	clk_register_clkdev(clk[per3], "ssi", NULL);
-	clk_register_clkdev(clk[clk32], NULL, "mxc_rtc.0");
+	clk_register_clkdev(clk[clk32], NULL, "imx1-rtc.0");
 	clk_register_clkdev(clk[clko], "clko", NULL);
 
 	mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT);
diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c
index cf65148..d7ed660 100644
--- a/arch/arm/mach-imx/clk-imx21.c
+++ b/arch/arm/mach-imx/clk-imx21.c
@@ -25,9 +25,9 @@
 #include <linux/module.h>
 #include <linux/err.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
 #include "clk.h"
+#include "common.h"
+#include "hardware.h"
 
 #define IO_ADDR_CCM(off)	(MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
 
@@ -156,16 +156,16 @@
 	clk_register_clkdev(clk[cspi2_ipg_gate], "ipg", "imx21-cspi.1");
 	clk_register_clkdev(clk[per2], "per", "imx21-cspi.2");
 	clk_register_clkdev(clk[cspi3_ipg_gate], "ipg", "imx21-cspi.2");
-	clk_register_clkdev(clk[per3], "per", "imx-fb.0");
-	clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0");
-	clk_register_clkdev(clk[lcdc_hclk_gate], "ahb", "imx-fb.0");
+	clk_register_clkdev(clk[per3], "per", "imx21-fb.0");
+	clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx21-fb.0");
+	clk_register_clkdev(clk[lcdc_hclk_gate], "ahb", "imx21-fb.0");
 	clk_register_clkdev(clk[usb_gate], "per", "imx21-hcd.0");
 	clk_register_clkdev(clk[usb_hclk_gate], "ahb", "imx21-hcd.0");
-	clk_register_clkdev(clk[nfc_gate], NULL, "mxc_nand.0");
-	clk_register_clkdev(clk[dma_hclk_gate], "ahb", "imx-dma");
-	clk_register_clkdev(clk[dma_gate], "ipg", "imx-dma");
+	clk_register_clkdev(clk[nfc_gate], NULL, "imx21-nand.0");
+	clk_register_clkdev(clk[dma_hclk_gate], "ahb", "imx21-dma");
+	clk_register_clkdev(clk[dma_gate], "ipg", "imx21-dma");
 	clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
-	clk_register_clkdev(clk[i2c_gate], NULL, "imx-i2c.0");
+	clk_register_clkdev(clk[i2c_gate], NULL, "imx21-i2c.0");
 	clk_register_clkdev(clk[kpp_gate], NULL, "mxc-keypad");
 	clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0");
 	clk_register_clkdev(clk[brom_gate], "brom", NULL);
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
index d20d479..bc88580 100644
--- a/arch/arm/mach-imx/clk-imx25.c
+++ b/arch/arm/mach-imx/clk-imx25.c
@@ -24,10 +24,10 @@
 #include <linux/clkdev.h>
 #include <linux/err.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/mx25.h>
 #include "clk.h"
+#include "common.h"
+#include "hardware.h"
+#include "mx25.h"
 
 #define CRM_BASE	MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
 
@@ -127,8 +127,8 @@
 	clk[esdhc2_ipg_per] = imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0),  4);
 	clk[gpt_ipg_per] = imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0),  5);
 	clk[i2c_ipg_per] = imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0),  6);
-	clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per8", ccm(CCM_CGCR0),  7);
-	clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "ipg_per", ccm(CCM_CGCR0),  8);
+	clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per7", ccm(CCM_CGCR0),  7);
+	clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "per8", ccm(CCM_CGCR0),  8);
 	clk[ssi1_ipg_per] = imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13);
 	clk[ssi2_ipg_per] = imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14);
 	clk[uart_ipg_per] = imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15);
@@ -197,7 +197,7 @@
 	clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
 	clk_register_clkdev(clk[usbotg_ahb], "ahb", "fsl-usb2-udc");
 	clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
-	clk_register_clkdev(clk[nfc_ipg_per], NULL, "mxc_nand.0");
+	clk_register_clkdev(clk[nfc_ipg_per], NULL, "imx25-nand.0");
 	/* i.mx25 has the i.mx35 type cspi */
 	clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0");
 	clk_register_clkdev(clk[cspi2_ipg], NULL, "imx35-cspi.1");
@@ -212,15 +212,15 @@
 	clk_register_clkdev(clk[per10], "per", "mxc_pwm.3");
 	clk_register_clkdev(clk[kpp_ipg], NULL, "imx-keypad");
 	clk_register_clkdev(clk[tsc_ipg], NULL, "mx25-adc");
-	clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.0");
-	clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.1");
-	clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.2");
+	clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx21-i2c.0");
+	clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx21-i2c.1");
+	clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx21-i2c.2");
 	clk_register_clkdev(clk[fec_ipg], "ipg", "imx25-fec.0");
 	clk_register_clkdev(clk[fec_ahb], "ahb", "imx25-fec.0");
 	clk_register_clkdev(clk[dryice_ipg], NULL, "imxdi_rtc.0");
-	clk_register_clkdev(clk[lcdc_ipg_per], "per", "imx-fb.0");
-	clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx-fb.0");
-	clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx-fb.0");
+	clk_register_clkdev(clk[lcdc_ipg_per], "per", "imx21-fb.0");
+	clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx21-fb.0");
+	clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx21-fb.0");
 	clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0");
 	clk_register_clkdev(clk[ssi1_ipg], NULL, "imx-ssi.0");
 	clk_register_clkdev(clk[ssi2_ipg], NULL, "imx-ssi.1");
@@ -230,9 +230,9 @@
 	clk_register_clkdev(clk[esdhc2_ipg_per], "per", "sdhci-esdhc-imx25.1");
 	clk_register_clkdev(clk[esdhc2_ipg], "ipg", "sdhci-esdhc-imx25.1");
 	clk_register_clkdev(clk[esdhc2_ahb], "ahb", "sdhci-esdhc-imx25.1");
-	clk_register_clkdev(clk[csi_ipg_per], "per", "mx2-camera.0");
-	clk_register_clkdev(clk[csi_ipg], "ipg", "mx2-camera.0");
-	clk_register_clkdev(clk[csi_ahb], "ahb", "mx2-camera.0");
+	clk_register_clkdev(clk[csi_ipg_per], "per", "imx25-camera.0");
+	clk_register_clkdev(clk[csi_ipg], "ipg", "imx25-camera.0");
+	clk_register_clkdev(clk[csi_ahb], "ahb", "imx25-camera.0");
 	clk_register_clkdev(clk[dummy], "audmux", NULL);
 	clk_register_clkdev(clk[can1_ipg], NULL, "flexcan.0");
 	clk_register_clkdev(clk[can2_ipg], NULL, "flexcan.1");
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
index 3b6b640..4c1d1e4 100644
--- a/arch/arm/mach-imx/clk-imx27.c
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -6,9 +6,9 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 
-#include <mach/common.h>
-#include <mach/hardware.h>
 #include "clk.h"
+#include "common.h"
+#include "hardware.h"
 
 #define IO_ADDR_CCM(off)	(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
 
@@ -51,8 +51,10 @@
 
 static const char *vpu_sel_clks[] = { "spll", "mpll_main2", };
 static const char *cpu_sel_clks[] = { "mpll_main2", "mpll", };
+static const char *mpll_sel_clks[] = { "fpm", "mpll_osc_sel", };
+static const char *mpll_osc_sel_clks[] = { "ckih", "ckih_div1p5", };
 static const char *clko_sel_clks[] = {
-	"ckil", "prem", "ckih", "ckih",
+	"ckil", "fpm", "ckih", "ckih",
 	"ckih", "mpll", "spll", "cpu_div",
 	"ahb", "ipg", "per1_div", "per2_div",
 	"per3_div", "per4_div", "ssi1_div", "ssi2_div",
@@ -79,7 +81,8 @@
 	vpu_ahb_gate, fec_ahb_gate, emma_ahb_gate, emi_ahb_gate, dma_ahb_gate,
 	csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate,
 	uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate,
-	uart2_ipg_gate, uart1_ipg_gate, clk_max
+	uart2_ipg_gate, uart1_ipg_gate, ckih_div1p5, fpm, mpll_osc_sel,
+	mpll_sel, clk_max
 };
 
 static struct clk *clk[clk_max];
@@ -91,7 +94,15 @@
 	clk[dummy] = imx_clk_fixed("dummy", 0);
 	clk[ckih] = imx_clk_fixed("ckih", fref);
 	clk[ckil] = imx_clk_fixed("ckil", 32768);
-	clk[mpll] = imx_clk_pllv1("mpll", "ckih", CCM_MPCTL0);
+	clk[fpm] = imx_clk_fixed_factor("fpm", "ckil", 1024, 1);
+	clk[ckih_div1p5] = imx_clk_fixed_factor("ckih_div1p5", "ckih", 2, 3);
+
+	clk[mpll_osc_sel] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1,
+			mpll_osc_sel_clks,
+			ARRAY_SIZE(mpll_osc_sel_clks));
+	clk[mpll_sel] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks,
+			ARRAY_SIZE(mpll_sel_clks));
+	clk[mpll] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0);
 	clk[spll] = imx_clk_pllv1("spll", "ckih", CCM_SPCTL0);
 	clk[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
 
@@ -109,7 +120,7 @@
 	clk[per3_div] = imx_clk_divider("per3_div", "mpll_main2", CCM_PCDR1, 16, 6);
 	clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6);
 	clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks));
-	clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 3);
+	clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 6);
 	clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 28, 3);
 	clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
 	clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
@@ -121,7 +132,7 @@
 	clk[ssi1_sel] = imx_clk_mux("ssi1_sel", CCM_CSCR, 22, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
 	clk[ssi2_sel] = imx_clk_mux("ssi2_sel", CCM_CSCR, 23, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
 	clk[ssi1_div] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
-	clk[ssi2_div] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 3);
+	clk[ssi2_div] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 6);
 	clk[clko_en] = imx_clk_gate("clko_en", "clko_div", CCM_PCCR0, 0);
 	clk[ssi2_ipg_gate] = imx_clk_gate("ssi2_ipg_gate", "ipg", CCM_PCCR0, 0);
 	clk[ssi1_ipg_gate] = imx_clk_gate("ssi1_ipg_gate", "ipg", CCM_PCCR0, 1);
@@ -211,19 +222,20 @@
 	clk_register_clkdev(clk[gpt6_ipg_gate], "ipg", "imx-gpt.5");
 	clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.5");
 	clk_register_clkdev(clk[pwm_ipg_gate], NULL, "mxc_pwm.0");
-	clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.0");
-	clk_register_clkdev(clk[sdhc1_ipg_gate], "ipg", "mxc-mmc.0");
-	clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.1");
-	clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "mxc-mmc.1");
-	clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.2");
-	clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "mxc-mmc.2");
+	clk_register_clkdev(clk[per2_gate], "per", "imx21-mmc.0");
+	clk_register_clkdev(clk[sdhc1_ipg_gate], "ipg", "imx21-mmc.0");
+	clk_register_clkdev(clk[per2_gate], "per", "imx21-mmc.1");
+	clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "imx21-mmc.1");
+	clk_register_clkdev(clk[per2_gate], "per", "imx21-mmc.2");
+	clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "imx21-mmc.2");
 	clk_register_clkdev(clk[cspi1_ipg_gate], NULL, "imx27-cspi.0");
 	clk_register_clkdev(clk[cspi2_ipg_gate], NULL, "imx27-cspi.1");
 	clk_register_clkdev(clk[cspi3_ipg_gate], NULL, "imx27-cspi.2");
-	clk_register_clkdev(clk[per3_gate], "per", "imx-fb.0");
-	clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0");
-	clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx-fb.0");
-	clk_register_clkdev(clk[csi_ahb_gate], "ahb", "mx2-camera.0");
+	clk_register_clkdev(clk[per3_gate], "per", "imx21-fb.0");
+	clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx21-fb.0");
+	clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx21-fb.0");
+	clk_register_clkdev(clk[csi_ahb_gate], "ahb", "imx27-camera.0");
+	clk_register_clkdev(clk[per4_gate], "per", "imx27-camera.0");
 	clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
 	clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc");
 	clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc");
@@ -238,27 +250,27 @@
 	clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.2");
 	clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
 	clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
-	clk_register_clkdev(clk[nfc_baud_gate], NULL, "mxc_nand.0");
+	clk_register_clkdev(clk[nfc_baud_gate], NULL, "imx27-nand.0");
 	clk_register_clkdev(clk[vpu_baud_gate], "per", "coda-imx27.0");
 	clk_register_clkdev(clk[vpu_ahb_gate], "ahb", "coda-imx27.0");
-	clk_register_clkdev(clk[dma_ahb_gate], "ahb", "imx-dma");
-	clk_register_clkdev(clk[dma_ipg_gate], "ipg", "imx-dma");
+	clk_register_clkdev(clk[dma_ahb_gate], "ahb", "imx27-dma");
+	clk_register_clkdev(clk[dma_ipg_gate], "ipg", "imx27-dma");
 	clk_register_clkdev(clk[fec_ipg_gate], "ipg", "imx27-fec.0");
 	clk_register_clkdev(clk[fec_ahb_gate], "ahb", "imx27-fec.0");
 	clk_register_clkdev(clk[wdog_ipg_gate], NULL, "imx2-wdt.0");
-	clk_register_clkdev(clk[i2c1_ipg_gate], NULL, "imx-i2c.0");
-	clk_register_clkdev(clk[i2c2_ipg_gate], NULL, "imx-i2c.1");
+	clk_register_clkdev(clk[i2c1_ipg_gate], NULL, "imx21-i2c.0");
+	clk_register_clkdev(clk[i2c2_ipg_gate], NULL, "imx21-i2c.1");
 	clk_register_clkdev(clk[owire_ipg_gate], NULL, "mxc_w1.0");
 	clk_register_clkdev(clk[kpp_ipg_gate], NULL, "imx-keypad");
-	clk_register_clkdev(clk[emma_ahb_gate], "emma-ahb", "mx2-camera.0");
-	clk_register_clkdev(clk[emma_ipg_gate], "emma-ipg", "mx2-camera.0");
+	clk_register_clkdev(clk[emma_ahb_gate], "emma-ahb", "imx27-camera.0");
+	clk_register_clkdev(clk[emma_ipg_gate], "emma-ipg", "imx27-camera.0");
 	clk_register_clkdev(clk[emma_ahb_gate], "ahb", "m2m-emmaprp.0");
 	clk_register_clkdev(clk[emma_ipg_gate], "ipg", "m2m-emmaprp.0");
 	clk_register_clkdev(clk[iim_ipg_gate], "iim", NULL);
 	clk_register_clkdev(clk[gpio_ipg_gate], "gpio", NULL);
 	clk_register_clkdev(clk[brom_ahb_gate], "brom", NULL);
 	clk_register_clkdev(clk[ata_ahb_gate], "ata", NULL);
-	clk_register_clkdev(clk[rtc_ipg_gate], NULL, "mxc_rtc");
+	clk_register_clkdev(clk[rtc_ipg_gate], NULL, "imx21-rtc");
 	clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL);
 	clk_register_clkdev(clk[cpu_div], "cpu", NULL);
 	clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL);
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c
index 1253af2..8be64e0 100644
--- a/arch/arm/mach-imx/clk-imx31.c
+++ b/arch/arm/mach-imx/clk-imx31.c
@@ -22,12 +22,11 @@
 #include <linux/err.h>
 #include <linux/of.h>
 
-#include <mach/hardware.h>
-#include <mach/mx31.h>
-#include <mach/common.h>
-
 #include "clk.h"
+#include "common.h"
 #include "crmregs-imx3.h"
+#include "hardware.h"
+#include "mx31.h"
 
 static const char *mcu_main_sel[] = { "spll", "mpll", };
 static const char *per_sel[] = { "per_div", "ipg", };
@@ -124,10 +123,10 @@
 	clk_register_clkdev(clk[cspi3_gate], NULL, "imx31-cspi.2");
 	clk_register_clkdev(clk[pwm_gate], "pwm", NULL);
 	clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
-	clk_register_clkdev(clk[rtc_gate], NULL, "mxc_rtc");
+	clk_register_clkdev(clk[rtc_gate], NULL, "imx21-rtc");
 	clk_register_clkdev(clk[epit1_gate], "epit", NULL);
 	clk_register_clkdev(clk[epit2_gate], "epit", NULL);
-	clk_register_clkdev(clk[nfc], NULL, "mxc_nand.0");
+	clk_register_clkdev(clk[nfc], NULL, "imx27-nand.0");
 	clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
 	clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
 	clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad");
@@ -155,12 +154,12 @@
 	clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.3");
 	clk_register_clkdev(clk[uart5_gate], "per", "imx21-uart.4");
 	clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.4");
-	clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
-	clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
-	clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
+	clk_register_clkdev(clk[i2c1_gate], NULL, "imx21-i2c.0");
+	clk_register_clkdev(clk[i2c2_gate], NULL, "imx21-i2c.1");
+	clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2");
 	clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0");
-	clk_register_clkdev(clk[sdhc1_gate], NULL, "mxc-mmc.0");
-	clk_register_clkdev(clk[sdhc2_gate], NULL, "mxc-mmc.1");
+	clk_register_clkdev(clk[sdhc1_gate], NULL, "imx31-mmc.0");
+	clk_register_clkdev(clk[sdhc2_gate], NULL, "imx31-mmc.1");
 	clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0");
 	clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");
 	clk_register_clkdev(clk[firi_gate], "firi", NULL);
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
index 177259b..66f3d65 100644
--- a/arch/arm/mach-imx/clk-imx35.c
+++ b/arch/arm/mach-imx/clk-imx35.c
@@ -14,11 +14,10 @@
 #include <linux/of.h>
 #include <linux/err.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-
 #include "crmregs-imx3.h"
 #include "clk.h"
+#include "common.h"
+#include "hardware.h"
 
 struct arm_ahb_div {
 	unsigned char arm, ahb, sel;
@@ -226,9 +225,9 @@
 	clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0");
 	clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
 	clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
-	clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
-	clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
-	clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
+	clk_register_clkdev(clk[i2c1_gate], NULL, "imx21-i2c.0");
+	clk_register_clkdev(clk[i2c2_gate], NULL, "imx21-i2c.1");
+	clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2");
 	clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
 	clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
 	clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad");
@@ -256,7 +255,7 @@
 	clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
 	clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc");
 	clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
-	clk_register_clkdev(clk[nfc_div], NULL, "mxc_nand.0");
+	clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
 	clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
 
 	clk_prepare_enable(clk[spba_gate]);
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index a0bf848..e8c0473 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -14,11 +14,10 @@
 #include <linux/of.h>
 #include <linux/err.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-
 #include "crm-regs-imx5.h"
 #include "clk.h"
+#include "common.h"
+#include "hardware.h"
 
 /* Low-power Audio Playback Mode clock */
 static const char *lp_apm_sel[] = { "osc", };
@@ -88,6 +87,7 @@
 };
 
 static struct clk *clk[clk_max];
+static struct clk_onecell_data clk_data;
 
 static void __init mx5_clocks_common_init(unsigned long rate_ckil,
 		unsigned long rate_osc, unsigned long rate_ckih1,
@@ -258,8 +258,8 @@
 	clk_register_clkdev(clk[cspi_ipg_gate], NULL, "imx35-cspi.2");
 	clk_register_clkdev(clk[pwm1_ipg_gate], "pwm", "mxc_pwm.0");
 	clk_register_clkdev(clk[pwm2_ipg_gate], "pwm", "mxc_pwm.1");
-	clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
-	clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
+	clk_register_clkdev(clk[i2c1_gate], NULL, "imx21-i2c.0");
+	clk_register_clkdev(clk[i2c2_gate], NULL, "imx21-i2c.1");
 	clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.0");
 	clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.0");
 	clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.0");
@@ -272,7 +272,7 @@
 	clk_register_clkdev(clk[usboh3_per_gate], "per", "fsl-usb2-udc");
 	clk_register_clkdev(clk[usboh3_gate], "ipg", "fsl-usb2-udc");
 	clk_register_clkdev(clk[usboh3_gate], "ahb", "fsl-usb2-udc");
-	clk_register_clkdev(clk[nfc_gate], NULL, "mxc_nand");
+	clk_register_clkdev(clk[nfc_gate], NULL, "imx51-nand");
 	clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
 	clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
 	clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "imx-ssi.2");
@@ -306,6 +306,10 @@
 	clk_prepare_enable(clk[spba]);
 	clk_prepare_enable(clk[emi_fast_gate]); /* fec */
 	clk_prepare_enable(clk[emi_slow_gate]); /* eim */
+	clk_prepare_enable(clk[mipi_hsc1_gate]);
+	clk_prepare_enable(clk[mipi_hsc2_gate]);
+	clk_prepare_enable(clk[mipi_esc_gate]);
+	clk_prepare_enable(clk[mipi_hsp_gate]);
 	clk_prepare_enable(clk[tmax1]);
 	clk_prepare_enable(clk[tmax2]); /* esdhc2, fec */
 	clk_prepare_enable(clk[tmax3]); /* esdhc1, esdhc4 */
@@ -315,6 +319,7 @@
 			unsigned long rate_ckih1, unsigned long rate_ckih2)
 {
 	int i;
+	struct device_node *np;
 
 	clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX51_DPLL1_BASE);
 	clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX51_DPLL2_BASE);
@@ -343,16 +348,20 @@
 			pr_err("i.MX51 clk %d: register failed with %ld\n",
 				i, PTR_ERR(clk[i]));
 
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx51-ccm");
+	clk_data.clks = clk;
+	clk_data.clk_num = ARRAY_SIZE(clk);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
 	mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2);
 
-	clk_register_clkdev(clk[hsi2c_gate], NULL, "imx-i2c.2");
+	clk_register_clkdev(clk[hsi2c_gate], NULL, "imx21-i2c.2");
 	clk_register_clkdev(clk[mx51_mipi], "mipi_hsp", NULL);
 	clk_register_clkdev(clk[vpu_gate], NULL, "imx51-vpu.0");
 	clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0");
-	clk_register_clkdev(clk[ipu_gate], "bus", "imx51-ipu");
-	clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx51-ipu");
-	clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx51-ipu");
-	clk_register_clkdev(clk[ipu_gate], "hsp", "imx51-ipu");
+	clk_register_clkdev(clk[ipu_gate], "bus", "40000000.ipu");
+	clk_register_clkdev(clk[ipu_di0_gate], "di0", "40000000.ipu");
+	clk_register_clkdev(clk[ipu_di1_gate], "di1", "40000000.ipu");
 	clk_register_clkdev(clk[usb_phy_gate], "phy", "mxc-ehci.0");
 	clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx51.0");
 	clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.0");
@@ -366,10 +375,6 @@
 	clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx51.3");
 	clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.3");
 	clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx51.3");
-	clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "83fcc000.ssi");
-	clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "70014000.ssi");
-	clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "83fe8000.ssi");
-	clk_register_clkdev(clk[nfc_gate], NULL, "83fdb000.nand");
 
 	/* set the usboh3 parent to pll2_sw */
 	clk_set_parent(clk[usboh3_sel], clk[pll2_sw]);
@@ -393,6 +398,7 @@
 {
 	int i;
 	unsigned long r;
+	struct device_node *np;
 
 	clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE);
 	clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE);
@@ -437,15 +443,20 @@
 			pr_err("i.MX53 clk %d: register failed with %ld\n",
 				i, PTR_ERR(clk[i]));
 
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx53-ccm");
+	clk_data.clks = clk;
+	clk_data.clk_num = ARRAY_SIZE(clk);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
 	mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2);
 
 	clk_register_clkdev(clk[vpu_gate], NULL, "imx53-vpu.0");
-	clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
+	clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2");
 	clk_register_clkdev(clk[fec_gate], NULL, "imx25-fec.0");
-	clk_register_clkdev(clk[ipu_gate], "bus", "imx53-ipu");
-	clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx53-ipu");
-	clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx53-ipu");
-	clk_register_clkdev(clk[ipu_gate], "hsp", "imx53-ipu");
+	clk_register_clkdev(clk[ipu_gate], "bus", "18000000.ipu");
+	clk_register_clkdev(clk[ipu_di0_gate], "di0", "18000000.ipu");
+	clk_register_clkdev(clk[ipu_di1_gate], "di1", "18000000.ipu");
+	clk_register_clkdev(clk[ipu_gate], "hsp", "18000000.ipu");
 	clk_register_clkdev(clk[usb_phy1_gate], "usb_phy1", "mxc-ehci.0");
 	clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx53.0");
 	clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.0");
@@ -459,14 +470,6 @@
 	clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx53.3");
 	clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.3");
 	clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx53.3");
-	clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "63fcc000.ssi");
-	clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "50014000.ssi");
-	clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "63fd0000.ssi");
-	clk_register_clkdev(clk[nfc_gate], NULL, "63fdb000.nand");
-	clk_register_clkdev(clk[can1_ipg_gate], "ipg", "53fc8000.can");
-	clk_register_clkdev(clk[can1_serial_gate], "per", "53fc8000.can");
-	clk_register_clkdev(clk[can2_ipg_gate], "ipg", "53fcc000.can");
-	clk_register_clkdev(clk[can2_serial_gate], "per", "53fcc000.can");
 
 	/* set SDHC root clock to 200MHZ*/
 	clk_set_rate(clk[esdhc_a_podf], 200000000);
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 3ec242f..4484769 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -19,8 +19,9 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
-#include <mach/common.h>
+
 #include "clk.h"
+#include "common.h"
 
 #define CCGR0				0x68
 #define CCGR1				0x6c
@@ -104,7 +105,7 @@
 static const char *gpu3d_core_sels[]	= { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
 static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", };
 static const char *ipu_sels[]		= { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
-static const char *ldb_di_sels[]	= { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *ldb_di_sels[]	= { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_pfd1_540m", };
 static const char *ipu_di_pre_sels[]	= { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
 static const char *ipu1_di0_sels[]	= { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
 static const char *ipu1_di1_sels[]	= { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
@@ -151,8 +152,9 @@
 	gpmi_bch_apb, gpmi_bch, gpmi_io, gpmi_apb, sata, sdma, spba, ssi1,
 	ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3,
 	usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg,
-	pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg,
+	pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
 	ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
+	sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref,
 	clk_max
 };
 
@@ -163,6 +165,13 @@
 	mmdc_ch0_axi, rom,
 };
 
+static struct clk_div_table clk_enet_ref_table[] = {
+	{ .val = 0, .div = 20, },
+	{ .val = 1, .div = 10, },
+	{ .val = 2, .div = 5, },
+	{ .val = 3, .div = 4, },
+};
+
 int __init mx6q_clocks_init(void)
 {
 	struct device_node *np;
@@ -189,19 +198,29 @@
 	base = of_iomap(np, 0);
 	WARN_ON(!base);
 
-	/*                   type                               name         parent_name  base     gate_mask div_mask */
-	clk[pll1_sys]      = imx_clk_pllv3(IMX_PLLV3_SYS,	"pll1_sys",	"osc", base,        0x2000,   0x7f);
-	clk[pll2_bus]      = imx_clk_pllv3(IMX_PLLV3_GENERIC,	"pll2_bus",	"osc", base + 0x30, 0x2000,   0x1);
-	clk[pll3_usb_otg]  = imx_clk_pllv3(IMX_PLLV3_USB,	"pll3_usb_otg",	"osc", base + 0x10, 0x2000,   0x3);
-	clk[pll4_audio]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"osc", base + 0x70, 0x2000,   0x7f);
-	clk[pll5_video]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"osc", base + 0xa0, 0x2000,   0x7f);
-	clk[pll6_mlb]      = imx_clk_pllv3(IMX_PLLV3_MLB,	"pll6_mlb",	"osc", base + 0xd0, 0x2000,   0x0);
-	clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x2000,   0x3);
-	clk[pll8_enet]     = imx_clk_pllv3(IMX_PLLV3_ENET,	"pll8_enet",	"osc", base + 0xe0, 0x182000, 0x3);
+	/*                   type                               name         parent_name  base     div_mask */
+	clk[pll1_sys]      = imx_clk_pllv3(IMX_PLLV3_SYS,	"pll1_sys",	"osc", base,        0x7f);
+	clk[pll2_bus]      = imx_clk_pllv3(IMX_PLLV3_GENERIC,	"pll2_bus",	"osc", base + 0x30, 0x1);
+	clk[pll3_usb_otg]  = imx_clk_pllv3(IMX_PLLV3_USB,	"pll3_usb_otg",	"osc", base + 0x10, 0x3);
+	clk[pll4_audio]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"osc", base + 0x70, 0x7f);
+	clk[pll5_video]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"osc", base + 0xa0, 0x7f);
+	clk[pll6_enet]     = imx_clk_pllv3(IMX_PLLV3_ENET,	"pll6_enet",	"osc", base + 0xe0, 0x3);
+	clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x3);
+	clk[pll8_mlb]      = imx_clk_pllv3(IMX_PLLV3_MLB,	"pll8_mlb",	"osc", base + 0xd0, 0x0);
 
 	clk[usbphy1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 6);
 	clk[usbphy2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 6);
 
+	clk[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
+	clk[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
+
+	clk[sata_ref_100m] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
+	clk[pcie_ref_125m] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
+
+	clk[enet_ref] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
+			base + 0xe0, 0, 2, 0, clk_enet_ref_table,
+			&imx_ccm_lock);
+
 	/*                                name              parent_name        reg       idx */
 	clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",     base + 0x100, 0);
 	clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus",     base + 0x100, 1);
@@ -357,7 +376,7 @@
 	clk[ldb_di1]      = imx_clk_gate2("ldb_di1",       "ldb_di1_podf",      base + 0x74, 14);
 	clk[ipu2_di1]     = imx_clk_gate2("ipu2_di1",      "ipu2_di1_sel",      base + 0x74, 10);
 	clk[hsi_tx]       = imx_clk_gate2("hsi_tx",        "hsi_tx_podf",       base + 0x74, 16);
-	clk[mlb]          = imx_clk_gate2("mlb",           "pll6_mlb",          base + 0x74, 18);
+	clk[mlb]          = imx_clk_gate2("mlb",           "pll8_mlb",          base + 0x74, 18);
 	clk[mmdc_ch0_axi] = imx_clk_gate2("mmdc_ch0_axi",  "mmdc_ch0_axi_podf", base + 0x74, 20);
 	clk[mmdc_ch1_axi] = imx_clk_gate2("mmdc_ch1_axi",  "mmdc_ch1_axi_podf", base + 0x74, 22);
 	clk[ocram]        = imx_clk_gate2("ocram",         "ahb",               base + 0x74, 28);
diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c
index 02be731..abff350 100644
--- a/arch/arm/mach-imx/clk-pllv1.c
+++ b/arch/arm/mach-imx/clk-pllv1.c
@@ -4,10 +4,10 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/err.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
 
 #include "clk.h"
+#include "common.h"
+#include "hardware.h"
 
 /**
  * pll v1
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
index 36aac94..d09bc3d 100644
--- a/arch/arm/mach-imx/clk-pllv3.c
+++ b/arch/arm/mach-imx/clk-pllv3.c
@@ -31,7 +31,6 @@
  * @clk_hw:	 clock source
  * @base:	 base address of PLL registers
  * @powerup_set: set POWER bit to power up the PLL
- * @gate_mask:	 mask of gate bits
  * @div_mask:	 mask of divider bits
  *
  * IMX PLL clock version 3, found on i.MX6 series.  Divider for pllv3
@@ -41,7 +40,6 @@
 	struct clk_hw	hw;
 	void __iomem	*base;
 	bool		powerup_set;
-	u32		gate_mask;
 	u32		div_mask;
 };
 
@@ -89,7 +87,7 @@
 	u32 val;
 
 	val = readl_relaxed(pll->base);
-	val |= pll->gate_mask;
+	val |= BM_PLL_ENABLE;
 	writel_relaxed(val, pll->base);
 
 	return 0;
@@ -101,7 +99,7 @@
 	u32 val;
 
 	val = readl_relaxed(pll->base);
-	val &= ~pll->gate_mask;
+	val &= ~BM_PLL_ENABLE;
 	writel_relaxed(val, pll->base);
 }
 
@@ -287,66 +285,7 @@
 static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
 						unsigned long parent_rate)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(hw);
-	u32 div = readl_relaxed(pll->base) & pll->div_mask;
-
-	switch (div) {
-	case 0:
-		return 25000000;
-	case 1:
-		return 50000000;
-	case 2:
-		return 100000000;
-	case 3:
-		return 125000000;
-	}
-
-	return 0;
-}
-
-static long clk_pllv3_enet_round_rate(struct clk_hw *hw, unsigned long rate,
-				      unsigned long *prate)
-{
-	if (rate >= 125000000)
-		rate = 125000000;
-	else if (rate >= 100000000)
-		rate = 100000000;
-	else if (rate >= 50000000)
-		rate = 50000000;
-	else
-		rate = 25000000;
-	return rate;
-}
-
-static int clk_pllv3_enet_set_rate(struct clk_hw *hw, unsigned long rate,
-		unsigned long parent_rate)
-{
-	struct clk_pllv3 *pll = to_clk_pllv3(hw);
-	u32 val, div;
-
-	switch (rate) {
-	case 25000000:
-		div = 0;
-		break;
-	case 50000000:
-		div = 1;
-		break;
-	case 100000000:
-		div = 2;
-		break;
-	case 125000000:
-		div = 3;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	val = readl_relaxed(pll->base);
-	val &= ~pll->div_mask;
-	val |= div;
-	writel_relaxed(val, pll->base);
-
-	return 0;
+	return 500000000;
 }
 
 static const struct clk_ops clk_pllv3_enet_ops = {
@@ -355,8 +294,6 @@
 	.enable		= clk_pllv3_enable,
 	.disable	= clk_pllv3_disable,
 	.recalc_rate	= clk_pllv3_enet_recalc_rate,
-	.round_rate	= clk_pllv3_enet_round_rate,
-	.set_rate	= clk_pllv3_enet_set_rate,
 };
 
 static const struct clk_ops clk_pllv3_mlb_ops = {
@@ -368,7 +305,7 @@
 
 struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 			  const char *parent_name, void __iomem *base,
-			  u32 gate_mask, u32 div_mask)
+			  u32 div_mask)
 {
 	struct clk_pllv3 *pll;
 	const struct clk_ops *ops;
@@ -400,7 +337,6 @@
 		ops = &clk_pllv3_ops;
 	}
 	pll->base = base;
-	pll->gate_mask = gate_mask;
 	pll->div_mask = div_mask;
 
 	init.name = name;
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 5f2d8ac..9d1f3b9 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -22,8 +22,7 @@
 };
 
 struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
-		const char *parent_name, void __iomem *base, u32 gate_mask,
-		u32 div_mask);
+		const char *parent_name, void __iomem *base, u32 div_mask);
 
 struct clk *clk_register_gate2(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/mach-imx/common.h
similarity index 98%
rename from arch/arm/plat-mxc/include/mach/common.h
rename to arch/arm/mach-imx/common.h
index ead9018..ef8db6b 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -79,6 +79,7 @@
 extern int mx53_revision(void);
 extern int mx53_display_revision(void);
 extern void imx_set_aips(void __iomem *);
+extern int mxc_device_init(void);
 
 enum mxc_cpu_pwr_mode {
 	WAIT_CLOCKED,		/* wfi only */
diff --git a/arch/arm/mach-imx/cpu-imx25.c b/arch/arm/mach-imx/cpu-imx25.c
index 6914bcb..96ec64b 100644
--- a/arch/arm/mach-imx/cpu-imx25.c
+++ b/arch/arm/mach-imx/cpu-imx25.c
@@ -11,8 +11,9 @@
  */
 #include <linux/module.h>
 #include <linux/io.h>
-#include <mach/hardware.h>
-#include <mach/iim.h>
+
+#include "iim.h"
+#include "hardware.h"
 
 static int mx25_cpu_rev = -1;
 
diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c
index ff38e15..fe8d36f 100644
--- a/arch/arm/mach-imx/cpu-imx27.c
+++ b/arch/arm/mach-imx/cpu-imx27.c
@@ -24,7 +24,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 
-#include <mach/hardware.h>
+#include "hardware.h"
 
 static int mx27_cpu_rev = -1;
 static int mx27_cpu_partnumber;
diff --git a/arch/arm/mach-imx/cpu-imx31.c b/arch/arm/mach-imx/cpu-imx31.c
index 3f2345f..fde1860 100644
--- a/arch/arm/mach-imx/cpu-imx31.c
+++ b/arch/arm/mach-imx/cpu-imx31.c
@@ -11,9 +11,10 @@
 
 #include <linux/module.h>
 #include <linux/io.h>
-#include <mach/hardware.h>
-#include <mach/iim.h>
-#include <mach/common.h>
+
+#include "common.h"
+#include "hardware.h"
+#include "iim.h"
 
 static int mx31_cpu_rev = -1;
 
diff --git a/arch/arm/mach-imx/cpu-imx35.c b/arch/arm/mach-imx/cpu-imx35.c
index 846e46e..ec3aaa0 100644
--- a/arch/arm/mach-imx/cpu-imx35.c
+++ b/arch/arm/mach-imx/cpu-imx35.c
@@ -10,8 +10,9 @@
  */
 #include <linux/module.h>
 #include <linux/io.h>
-#include <mach/hardware.h>
-#include <mach/iim.h>
+
+#include "hardware.h"
+#include "iim.h"
 
 static int mx35_cpu_rev = -1;
 
diff --git a/arch/arm/mach-imx/cpu-imx5.c b/arch/arm/mach-imx/cpu-imx5.c
index 8eb15a2..d887600 100644
--- a/arch/arm/mach-imx/cpu-imx5.c
+++ b/arch/arm/mach-imx/cpu-imx5.c
@@ -15,9 +15,10 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <mach/hardware.h>
 #include <linux/io.h>
 
+#include "hardware.h"
+
 static int mx5_cpu_rev = -1;
 
 #define IIM_SREV 0x24
diff --git a/arch/arm/plat-mxc/cpu.c b/arch/arm/mach-imx/cpu.c
similarity index 97%
rename from arch/arm/plat-mxc/cpu.c
rename to arch/arm/mach-imx/cpu.c
index 220dd6f..03fcbd0 100644
--- a/arch/arm/plat-mxc/cpu.c
+++ b/arch/arm/mach-imx/cpu.c
@@ -1,7 +1,8 @@
 
 #include <linux/module.h>
 #include <linux/io.h>
-#include <mach/hardware.h>
+
+#include "hardware.h"
 
 unsigned int __mxc_cpu_type;
 EXPORT_SYMBOL(__mxc_cpu_type);
diff --git a/arch/arm/mach-imx/cpu_op-mx51.c b/arch/arm/mach-imx/cpu_op-mx51.c
index 7b92cd6..b9ef692 100644
--- a/arch/arm/mach-imx/cpu_op-mx51.c
+++ b/arch/arm/mach-imx/cpu_op-mx51.c
@@ -13,9 +13,10 @@
 
 #include <linux/bug.h>
 #include <linux/types.h>
-#include <mach/hardware.h>
 #include <linux/kernel.h>
 
+#include "hardware.h"
+
 static struct cpu_op mx51_cpu_op[] = {
 	{
 	.cpu_rate = 160000000,},
diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/mach-imx/cpufreq.c
similarity index 99%
rename from arch/arm/plat-mxc/cpufreq.c
rename to arch/arm/mach-imx/cpufreq.c
index b5b6f80..36e8b39 100644
--- a/arch/arm/plat-mxc/cpufreq.c
+++ b/arch/arm/mach-imx/cpufreq.c
@@ -22,7 +22,8 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/slab.h>
-#include <mach/hardware.h>
+
+#include "hardware.h"
 
 #define CLK32_FREQ	32768
 #define NANOSECOND	(1000 * 1000 * 1000)
diff --git a/arch/arm/plat-mxc/cpuidle.c b/arch/arm/mach-imx/cpuidle.c
similarity index 100%
rename from arch/arm/plat-mxc/cpuidle.c
rename to arch/arm/mach-imx/cpuidle.c
diff --git a/arch/arm/plat-mxc/include/mach/cpuidle.h b/arch/arm/mach-imx/cpuidle.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/cpuidle.h
rename to arch/arm/mach-imx/cpuidle.h
diff --git a/arch/arm/mach-imx/devices-imx1.h b/arch/arm/mach-imx/devices-imx1.h
index 3aad1e7..f9b5afc 100644
--- a/arch/arm/mach-imx/devices-imx1.h
+++ b/arch/arm/mach-imx/devices-imx1.h
@@ -6,8 +6,7 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/mx1.h>
-#include <mach/devices-common.h>
+#include "devices/devices-common.h"
 
 extern const struct imx_imx_fb_data imx1_imx_fb_data;
 #define imx1_add_imx_fb(pdata) \
diff --git a/arch/arm/mach-imx/devices-imx21.h b/arch/arm/mach-imx/devices-imx21.h
index 93ece55..bd93932 100644
--- a/arch/arm/mach-imx/devices-imx21.h
+++ b/arch/arm/mach-imx/devices-imx21.h
@@ -6,8 +6,7 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/mx21.h>
-#include <mach/devices-common.h>
+#include "devices/devices-common.h"
 
 extern const struct imx_imx21_hcd_data imx21_imx21_hcd_data;
 #define imx21_add_imx21_hcd(pdata)	\
diff --git a/arch/arm/mach-imx/devices-imx25.h b/arch/arm/mach-imx/devices-imx25.h
index f8e03dd..0d2922b 100644
--- a/arch/arm/mach-imx/devices-imx25.h
+++ b/arch/arm/mach-imx/devices-imx25.h
@@ -6,8 +6,7 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/mx25.h>
-#include <mach/devices-common.h>
+#include "devices/devices-common.h"
 
 extern const struct imx_fec_data imx25_fec_data;
 #define imx25_add_fec(pdata)	\
diff --git a/arch/arm/mach-imx/devices-imx27.h b/arch/arm/mach-imx/devices-imx27.h
index 0482293..1309625 100644
--- a/arch/arm/mach-imx/devices-imx27.h
+++ b/arch/arm/mach-imx/devices-imx27.h
@@ -6,8 +6,7 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/mx27.h>
-#include <mach/devices-common.h>
+#include "devices/devices-common.h"
 
 extern const struct imx_fec_data imx27_fec_data;
 #define imx27_add_fec(pdata)	\
@@ -54,8 +53,10 @@
 extern const struct imx_mx2_camera_data imx27_mx2_camera_data;
 #define imx27_add_mx2_camera(pdata)	\
 	imx_add_mx2_camera(&imx27_mx2_camera_data, pdata)
+
+extern const struct imx_mx2_emma_data imx27_mx2_emmaprp_data;
 #define imx27_add_mx2_emmaprp()	\
-	imx_add_mx2_emmaprp(&imx27_mx2_camera_data)
+	imx_add_mx2_emmaprp(&imx27_mx2_emmaprp_data)
 
 extern const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data;
 #define imx27_add_mxc_ehci_otg(pdata)	\
diff --git a/arch/arm/mach-imx/devices-imx31.h b/arch/arm/mach-imx/devices-imx31.h
index 8b2ceb4..e8d1611 100644
--- a/arch/arm/mach-imx/devices-imx31.h
+++ b/arch/arm/mach-imx/devices-imx31.h
@@ -6,8 +6,7 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/mx31.h>
-#include <mach/devices-common.h>
+#include "devices/devices-common.h"
 
 extern const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data;
 #define imx31_add_fsl_usb2_udc(pdata)	\
diff --git a/arch/arm/mach-imx/devices-imx35.h b/arch/arm/mach-imx/devices-imx35.h
index c3e9f20..e2675f1 100644
--- a/arch/arm/mach-imx/devices-imx35.h
+++ b/arch/arm/mach-imx/devices-imx35.h
@@ -6,8 +6,7 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/mx35.h>
-#include <mach/devices-common.h>
+#include "devices/devices-common.h"
 
 extern const struct imx_fec_data imx35_fec_data;
 #define imx35_add_fec(pdata)	\
diff --git a/arch/arm/mach-imx/devices-imx50.h b/arch/arm/mach-imx/devices-imx50.h
index 7216667..2c29039 100644
--- a/arch/arm/mach-imx/devices-imx50.h
+++ b/arch/arm/mach-imx/devices-imx50.h
@@ -18,8 +18,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <mach/mx50.h>
-#include <mach/devices-common.h>
+#include "devices/devices-common.h"
 
 extern const struct imx_imx_uart_1irq_data imx50_imx_uart_data[];
 #define imx50_add_imx_uart(id, pdata)	\
diff --git a/arch/arm/mach-imx/devices-imx51.h b/arch/arm/mach-imx/devices-imx51.h
index 9f17187..deee5ba 100644
--- a/arch/arm/mach-imx/devices-imx51.h
+++ b/arch/arm/mach-imx/devices-imx51.h
@@ -6,8 +6,7 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/mx51.h>
-#include <mach/devices-common.h>
+#include "devices/devices-common.h"
 
 extern const struct imx_fec_data imx51_fec_data;
 #define imx51_add_fec(pdata)	\
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/mach-imx/devices/Kconfig
similarity index 96%
rename from arch/arm/plat-mxc/devices/Kconfig
rename to arch/arm/mach-imx/devices/Kconfig
index a35d984..9a8f1ca 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/mach-imx/devices/Kconfig
@@ -56,6 +56,9 @@
 config IMX_HAVE_PLATFORM_MX2_CAMERA
 	bool
 
+config IMX_HAVE_PLATFORM_MX2_EMMA
+	bool
+
 config IMX_HAVE_PLATFORM_MXC_EHCI
 	bool
 
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/mach-imx/devices/Makefile
similarity index 95%
rename from arch/arm/plat-mxc/devices/Makefile
rename to arch/arm/mach-imx/devices/Makefile
index 76f3195..6acf37e 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/mach-imx/devices/Makefile
@@ -1,3 +1,5 @@
+obj-y := devices.o
+
 obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o
@@ -28,3 +30,4 @@
 obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) +=  platform-spi_imx.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) +=  platform-ahci-imx.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_EMMA) += platform-mx2-emma.o
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/mach-imx/devices/devices-common.h
similarity index 95%
rename from arch/arm/plat-mxc/include/mach/devices-common.h
rename to arch/arm/mach-imx/devices/devices-common.h
index eaf79d2..6277baf 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/mach-imx/devices/devices-common.h
@@ -108,6 +108,7 @@
 
 #include <linux/platform_data/video-imxfb.h>
 struct imx_imx_fb_data {
+	const char *devid;
 	resource_size_t iobase;
 	resource_size_t iosize;
 	resource_size_t irq;
@@ -118,6 +119,7 @@
 
 #include <linux/platform_data/i2c-imx.h>
 struct imx_imx_i2c_data {
+	const char *devid;
 	int id;
 	resource_size_t iobase;
 	resource_size_t iosize;
@@ -219,6 +221,7 @@
 
 #include <linux/platform_data/camera-mx2.h>
 struct imx_mx2_camera_data {
+	const char *devid;
 	resource_size_t iobasecsi;
 	resource_size_t iosizecsi;
 	resource_size_t irqcsi;
@@ -229,8 +232,15 @@
 struct platform_device *__init imx_add_mx2_camera(
 		const struct imx_mx2_camera_data *data,
 		const struct mx2_camera_platform_data *pdata);
+
+
+struct imx_mx2_emma_data {
+	resource_size_t iobase;
+	resource_size_t iosize;
+	resource_size_t irq;
+};
 struct platform_device *__init imx_add_mx2_emmaprp(
-		const struct imx_mx2_camera_data *data);
+		const struct imx_mx2_emma_data *data);
 
 #include <linux/platform_data/usb-ehci-mxc.h>
 struct imx_mxc_ehci_data {
@@ -244,6 +254,7 @@
 
 #include <linux/platform_data/mmc-mxcmmc.h>
 struct imx_mxc_mmc_data {
+	const char *devid;
 	int id;
 	resource_size_t iobase;
 	resource_size_t iosize;
@@ -256,6 +267,7 @@
 
 #include <linux/platform_data/mtd-mxc_nand.h>
 struct imx_mxc_nand_data {
+	const char *devid;
 	/*
 	 * id is traditionally 0, but -1 is more appropriate.  We use -1 for new
 	 * machines but don't change existing devices as the nand device usually
@@ -290,6 +302,7 @@
 
 /* mxc_rtc */
 struct imx_mxc_rtc_data {
+	const char *devid;
 	resource_size_t iobase;
 	resource_size_t irq;
 };
@@ -326,7 +339,8 @@
 		const struct imx_spi_imx_data *data,
 		const struct spi_imx_master *pdata);
 
-struct platform_device *imx_add_imx_dma(void);
+struct platform_device *imx_add_imx_dma(char *name, resource_size_t iobase,
+					int irq, int irq_err);
 struct platform_device *imx_add_imx_sdma(char *name,
 	resource_size_t iobase, int irq, struct sdma_platform_data *pdata);
 
diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/mach-imx/devices/devices.c
similarity index 92%
rename from arch/arm/plat-mxc/devices.c
rename to arch/arm/mach-imx/devices/devices.c
index 4d55a7a..1b37482 100644
--- a/arch/arm/plat-mxc/devices.c
+++ b/arch/arm/mach-imx/devices/devices.c
@@ -21,7 +21,6 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
-#include <mach/common.h>
 
 struct device mxc_aips_bus = {
 	.init_name	= "mxc_aips",
@@ -33,7 +32,7 @@
 	.parent		= &platform_bus,
 };
 
-static int __init mxc_device_init(void)
+int __init mxc_device_init(void)
 {
 	int ret;
 
@@ -46,4 +45,3 @@
 done:
 	return ret;
 }
-core_initcall(mxc_device_init);
diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/mach-imx/devices/platform-ahci-imx.c
similarity index 98%
rename from arch/arm/plat-mxc/devices/platform-ahci-imx.c
rename to arch/arm/mach-imx/devices/platform-ahci-imx.c
index ade4a1c..3d87dd9 100644
--- a/arch/arm/plat-mxc/devices/platform-ahci-imx.c
+++ b/arch/arm/mach-imx/devices/platform-ahci-imx.c
@@ -24,8 +24,9 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <asm/sizes.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_ahci_imx_data_entry_single(soc, _devid)		\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/mach-imx/devices/platform-fec.c
similarity index 96%
rename from arch/arm/plat-mxc/devices/platform-fec.c
rename to arch/arm/mach-imx/devices/platform-fec.c
index 0bae44e..2cb188a 100644
--- a/arch/arm/plat-mxc/devices/platform-fec.c
+++ b/arch/arm/mach-imx/devices/platform-fec.c
@@ -8,8 +8,9 @@
  */
 #include <linux/dma-mapping.h>
 #include <asm/sizes.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_fec_data_entry_single(soc, _devid)				\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-flexcan.c b/arch/arm/mach-imx/devices/platform-flexcan.c
similarity index 96%
rename from arch/arm/plat-mxc/devices/platform-flexcan.c
rename to arch/arm/mach-imx/devices/platform-flexcan.c
index 4e8497a..1078bf0 100644
--- a/arch/arm/plat-mxc/devices/platform-flexcan.c
+++ b/arch/arm/mach-imx/devices/platform-flexcan.c
@@ -5,8 +5,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_flexcan_data_entry_single(soc, _id, _hwid, _size)		\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c b/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
similarity index 96%
rename from arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
rename to arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
index 848038f..37e4439 100644
--- a/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
+++ b/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
@@ -7,8 +7,9 @@
  * Free Software Foundation.
  */
 #include <linux/dma-mapping.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_fsl_usb2_udc_data_entry_single(soc)				\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c b/arch/arm/mach-imx/devices/platform-gpio-mxc.c
similarity index 95%
rename from arch/arm/plat-mxc/devices/platform-gpio-mxc.c
rename to arch/arm/mach-imx/devices/platform-gpio-mxc.c
index a7919a2..26483fa 100644
--- a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
+++ b/arch/arm/mach-imx/devices/platform-gpio-mxc.c
@@ -6,7 +6,7 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/devices-common.h>
+#include "devices-common.h"
 
 struct platform_device *__init mxc_register_gpio(char *name, int id,
 	resource_size_t iobase, resource_size_t iosize, int irq, int irq_high)
diff --git a/arch/arm/plat-mxc/devices/platform-gpio_keys.c b/arch/arm/mach-imx/devices/platform-gpio_keys.c
similarity index 94%
rename from arch/arm/plat-mxc/devices/platform-gpio_keys.c
rename to arch/arm/mach-imx/devices/platform-gpio_keys.c
index 1c53a53..4862825 100644
--- a/arch/arm/plat-mxc/devices/platform-gpio_keys.c
+++ b/arch/arm/mach-imx/devices/platform-gpio_keys.c
@@ -16,8 +16,9 @@
  * Boston, MA  02110-1301, USA.
  */
 #include <asm/sizes.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+
+#include "../hardware.h"
+#include "devices-common.h"
 
 struct platform_device *__init imx_add_gpio_keys(
 		const struct gpio_keys_platform_data *pdata)
diff --git a/arch/arm/plat-mxc/devices/platform-imx-dma.c b/arch/arm/mach-imx/devices/platform-imx-dma.c
similarity index 63%
rename from arch/arm/plat-mxc/devices/platform-imx-dma.c
rename to arch/arm/mach-imx/devices/platform-imx-dma.c
index 7fa7e9c..ccdb5dc 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-dma.c
+++ b/arch/arm/mach-imx/devices/platform-imx-dma.c
@@ -6,12 +6,29 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/devices-common.h>
+#include "devices-common.h"
 
-struct platform_device __init __maybe_unused *imx_add_imx_dma(void)
+struct platform_device __init __maybe_unused *imx_add_imx_dma(char *name,
+	resource_size_t iobase, int irq, int irq_err)
 {
+	struct resource res[] = {
+		{
+			.start = iobase,
+			.end = iobase + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = irq,
+			.end = irq,
+			.flags = IORESOURCE_IRQ,
+		}, {
+			.start = irq_err,
+			.end = irq_err,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
 	return platform_device_register_resndata(&mxc_ahb_bus,
-			"imx-dma", -1, NULL, 0, NULL, 0);
+			name, -1, res, ARRAY_SIZE(res), NULL, 0);
 }
 
 struct platform_device __init __maybe_unused *imx_add_imx_sdma(char *name,
diff --git a/arch/arm/plat-mxc/devices/platform-imx-fb.c b/arch/arm/mach-imx/devices/platform-imx-fb.c
similarity index 79%
rename from arch/arm/plat-mxc/devices/platform-imx-fb.c
rename to arch/arm/mach-imx/devices/platform-imx-fb.c
index 2b0b5e0..10b0ed3 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-fb.c
+++ b/arch/arm/mach-imx/devices/platform-imx-fb.c
@@ -7,11 +7,13 @@
  * Free Software Foundation.
  */
 #include <linux/dma-mapping.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
 
-#define imx_imx_fb_data_entry_single(soc, _size)			\
+#include "../hardware.h"
+#include "devices-common.h"
+
+#define imx_imx_fb_data_entry_single(soc, _devid, _size)		\
 	{								\
+		.devid = _devid,					\
 		.iobase = soc ## _LCDC_BASE_ADDR,			\
 		.iosize = _size,					\
 		.irq = soc ## _INT_LCDC,				\
@@ -19,22 +21,22 @@
 
 #ifdef CONFIG_SOC_IMX1
 const struct imx_imx_fb_data imx1_imx_fb_data __initconst =
-	imx_imx_fb_data_entry_single(MX1, SZ_4K);
+	imx_imx_fb_data_entry_single(MX1, "imx1-fb", SZ_4K);
 #endif /* ifdef CONFIG_SOC_IMX1 */
 
 #ifdef CONFIG_SOC_IMX21
 const struct imx_imx_fb_data imx21_imx_fb_data __initconst =
-	imx_imx_fb_data_entry_single(MX21, SZ_4K);
+	imx_imx_fb_data_entry_single(MX21, "imx21-fb", SZ_4K);
 #endif /* ifdef CONFIG_SOC_IMX21 */
 
 #ifdef CONFIG_SOC_IMX25
 const struct imx_imx_fb_data imx25_imx_fb_data __initconst =
-	imx_imx_fb_data_entry_single(MX25, SZ_16K);
+	imx_imx_fb_data_entry_single(MX25, "imx21-fb", SZ_16K);
 #endif /* ifdef CONFIG_SOC_IMX25 */
 
 #ifdef CONFIG_SOC_IMX27
 const struct imx_imx_fb_data imx27_imx_fb_data __initconst =
-	imx_imx_fb_data_entry_single(MX27, SZ_4K);
+	imx_imx_fb_data_entry_single(MX27, "imx21-fb", SZ_4K);
 #endif /* ifdef CONFIG_SOC_IMX27 */
 
 struct platform_device *__init imx_add_imx_fb(
diff --git a/arch/arm/plat-mxc/devices/platform-imx-i2c.c b/arch/arm/mach-imx/devices/platform-imx-i2c.c
similarity index 76%
rename from arch/arm/plat-mxc/devices/platform-imx-i2c.c
rename to arch/arm/mach-imx/devices/platform-imx-i2c.c
index 19ad580..8e30e57 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-i2c.c
+++ b/arch/arm/mach-imx/devices/platform-imx-i2c.c
@@ -6,34 +6,35 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
-#define imx_imx_i2c_data_entry_single(soc, _id, _hwid, _size)		\
+#define imx_imx_i2c_data_entry_single(soc, _devid, _id, _hwid, _size)	\
 	{								\
+		.devid = _devid,					\
 		.id = _id,						\
 		.iobase = soc ## _I2C ## _hwid ## _BASE_ADDR,		\
 		.iosize = _size,					\
 		.irq = soc ## _INT_I2C ## _hwid,			\
 	}
 
-#define imx_imx_i2c_data_entry(soc, _id, _hwid, _size)			\
-	[_id] = imx_imx_i2c_data_entry_single(soc, _id, _hwid, _size)
+#define imx_imx_i2c_data_entry(soc, _devid, _id, _hwid, _size)		\
+	[_id] = imx_imx_i2c_data_entry_single(soc, _devid, _id, _hwid, _size)
 
 #ifdef CONFIG_SOC_IMX1
 const struct imx_imx_i2c_data imx1_imx_i2c_data __initconst =
-	imx_imx_i2c_data_entry_single(MX1, 0, , SZ_4K);
+	imx_imx_i2c_data_entry_single(MX1, "imx1-i2c", 0, , SZ_4K);
 #endif /* ifdef CONFIG_SOC_IMX1 */
 
 #ifdef CONFIG_SOC_IMX21
 const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst =
-	imx_imx_i2c_data_entry_single(MX21, 0, , SZ_4K);
+	imx_imx_i2c_data_entry_single(MX21, "imx21-i2c", 0, , SZ_4K);
 #endif /* ifdef CONFIG_SOC_IMX21 */
 
 #ifdef CONFIG_SOC_IMX25
 const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst = {
 #define imx25_imx_i2c_data_entry(_id, _hwid)				\
-	imx_imx_i2c_data_entry(MX25, _id, _hwid, SZ_16K)
+	imx_imx_i2c_data_entry(MX25, "imx21-i2c", _id, _hwid, SZ_16K)
 	imx25_imx_i2c_data_entry(0, 1),
 	imx25_imx_i2c_data_entry(1, 2),
 	imx25_imx_i2c_data_entry(2, 3),
@@ -43,7 +44,7 @@
 #ifdef CONFIG_SOC_IMX27
 const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst = {
 #define imx27_imx_i2c_data_entry(_id, _hwid)				\
-	imx_imx_i2c_data_entry(MX27, _id, _hwid, SZ_4K)
+	imx_imx_i2c_data_entry(MX27, "imx21-i2c", _id, _hwid, SZ_4K)
 	imx27_imx_i2c_data_entry(0, 1),
 	imx27_imx_i2c_data_entry(1, 2),
 };
@@ -52,7 +53,7 @@
 #ifdef CONFIG_SOC_IMX31
 const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst = {
 #define imx31_imx_i2c_data_entry(_id, _hwid)				\
-	imx_imx_i2c_data_entry(MX31, _id, _hwid, SZ_4K)
+	imx_imx_i2c_data_entry(MX31, "imx21-i2c", _id, _hwid, SZ_4K)
 	imx31_imx_i2c_data_entry(0, 1),
 	imx31_imx_i2c_data_entry(1, 2),
 	imx31_imx_i2c_data_entry(2, 3),
@@ -62,7 +63,7 @@
 #ifdef CONFIG_SOC_IMX35
 const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst = {
 #define imx35_imx_i2c_data_entry(_id, _hwid)				\
-	imx_imx_i2c_data_entry(MX35, _id, _hwid, SZ_4K)
+	imx_imx_i2c_data_entry(MX35, "imx21-i2c", _id, _hwid, SZ_4K)
 	imx35_imx_i2c_data_entry(0, 1),
 	imx35_imx_i2c_data_entry(1, 2),
 	imx35_imx_i2c_data_entry(2, 3),
@@ -72,7 +73,7 @@
 #ifdef CONFIG_SOC_IMX50
 const struct imx_imx_i2c_data imx50_imx_i2c_data[] __initconst = {
 #define imx50_imx_i2c_data_entry(_id, _hwid)				\
-	imx_imx_i2c_data_entry(MX50, _id, _hwid, SZ_4K)
+	imx_imx_i2c_data_entry(MX50, "imx21-i2c", _id, _hwid, SZ_4K)
 	imx50_imx_i2c_data_entry(0, 1),
 	imx50_imx_i2c_data_entry(1, 2),
 	imx50_imx_i2c_data_entry(2, 3),
@@ -82,10 +83,11 @@
 #ifdef CONFIG_SOC_IMX51
 const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst = {
 #define imx51_imx_i2c_data_entry(_id, _hwid)				\
-	imx_imx_i2c_data_entry(MX51, _id, _hwid, SZ_4K)
+	imx_imx_i2c_data_entry(MX51, "imx21-i2c", _id, _hwid, SZ_4K)
 	imx51_imx_i2c_data_entry(0, 1),
 	imx51_imx_i2c_data_entry(1, 2),
 	{
+		.devid = "imx21-i2c",
 		.id = 2,
 		.iobase = MX51_HSI2C_DMA_BASE_ADDR,
 		.iosize = SZ_16K,
@@ -97,7 +99,7 @@
 #ifdef CONFIG_SOC_IMX53
 const struct imx_imx_i2c_data imx53_imx_i2c_data[] __initconst = {
 #define imx53_imx_i2c_data_entry(_id, _hwid)				\
-	imx_imx_i2c_data_entry(MX53, _id, _hwid, SZ_4K)
+	imx_imx_i2c_data_entry(MX53, "imx21-i2c", _id, _hwid, SZ_4K)
 	imx53_imx_i2c_data_entry(0, 1),
 	imx53_imx_i2c_data_entry(1, 2),
 	imx53_imx_i2c_data_entry(2, 3),
@@ -120,7 +122,7 @@
 		},
 	};
 
-	return imx_add_platform_device("imx-i2c", data->id,
+	return imx_add_platform_device(data->devid, data->id,
 			res, ARRAY_SIZE(res),
 			pdata, sizeof(*pdata));
 }
diff --git a/arch/arm/plat-mxc/devices/platform-imx-keypad.c b/arch/arm/mach-imx/devices/platform-imx-keypad.c
similarity index 96%
rename from arch/arm/plat-mxc/devices/platform-imx-keypad.c
rename to arch/arm/mach-imx/devices/platform-imx-keypad.c
index 479c3e9..8f22a4c 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-keypad.c
+++ b/arch/arm/mach-imx/devices/platform-imx-keypad.c
@@ -6,8 +6,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_imx_keypad_data_entry_single(soc, _size)			\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-imx-ssi.c b/arch/arm/mach-imx/devices/platform-imx-ssi.c
similarity index 98%
rename from arch/arm/plat-mxc/devices/platform-imx-ssi.c
rename to arch/arm/mach-imx/devices/platform-imx-ssi.c
index 21c6f30..bfcb8f3 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-ssi.c
+++ b/arch/arm/mach-imx/devices/platform-imx-ssi.c
@@ -6,8 +6,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_imx_ssi_data_entry(soc, _id, _hwid, _size)			\
 	[_id] = {							\
diff --git a/arch/arm/plat-mxc/devices/platform-imx-uart.c b/arch/arm/mach-imx/devices/platform-imx-uart.c
similarity index 98%
rename from arch/arm/plat-mxc/devices/platform-imx-uart.c
rename to arch/arm/mach-imx/devices/platform-imx-uart.c
index d390f00..67bf866a 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-uart.c
+++ b/arch/arm/mach-imx/devices/platform-imx-uart.c
@@ -6,8 +6,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_imx_uart_3irq_data_entry(soc, _id, _hwid, _size)		\
 	[_id] = {							\
diff --git a/arch/arm/plat-mxc/devices/platform-imx2-wdt.c b/arch/arm/mach-imx/devices/platform-imx2-wdt.c
similarity index 97%
rename from arch/arm/plat-mxc/devices/platform-imx2-wdt.c
rename to arch/arm/mach-imx/devices/platform-imx2-wdt.c
index 5e07ef2..ec75d64 100644
--- a/arch/arm/plat-mxc/devices/platform-imx2-wdt.c
+++ b/arch/arm/mach-imx/devices/platform-imx2-wdt.c
@@ -7,8 +7,9 @@
  * Free Software Foundation.
  */
 #include <asm/sizes.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_imx2_wdt_data_entry_single(soc, _id, _hwid, _size)		\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-imx21-hcd.c b/arch/arm/mach-imx/devices/platform-imx21-hcd.c
similarity index 94%
rename from arch/arm/plat-mxc/devices/platform-imx21-hcd.c
rename to arch/arm/mach-imx/devices/platform-imx21-hcd.c
index 5770a42..30c8161 100644
--- a/arch/arm/plat-mxc/devices/platform-imx21-hcd.c
+++ b/arch/arm/mach-imx/devices/platform-imx21-hcd.c
@@ -6,8 +6,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_imx21_hcd_data_entry_single(soc)				\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-imx27-coda.c b/arch/arm/mach-imx/devices/platform-imx27-coda.c
similarity index 93%
rename from arch/arm/plat-mxc/devices/platform-imx27-coda.c
rename to arch/arm/mach-imx/devices/platform-imx27-coda.c
index 8b12aac..25bebc2 100644
--- a/arch/arm/plat-mxc/devices/platform-imx27-coda.c
+++ b/arch/arm/mach-imx/devices/platform-imx27-coda.c
@@ -7,8 +7,8 @@
  * Free Software Foundation.
  */
 
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #ifdef CONFIG_SOC_IMX27
 const struct imx_imx27_coda_data imx27_coda_data __initconst = {
diff --git a/arch/arm/plat-mxc/devices/platform-imx_udc.c b/arch/arm/mach-imx/devices/platform-imx_udc.c
similarity index 96%
rename from arch/arm/plat-mxc/devices/platform-imx_udc.c
rename to arch/arm/mach-imx/devices/platform-imx_udc.c
index 6fd675d..5ced7e4 100644
--- a/arch/arm/plat-mxc/devices/platform-imx_udc.c
+++ b/arch/arm/mach-imx/devices/platform-imx_udc.c
@@ -6,8 +6,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_imx_udc_data_entry_single(soc, _size)			\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c b/arch/arm/mach-imx/devices/platform-imxdi_rtc.c
similarity index 94%
rename from arch/arm/plat-mxc/devices/platform-imxdi_rtc.c
rename to arch/arm/mach-imx/devices/platform-imxdi_rtc.c
index 805336f..5bb490d 100644
--- a/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c
+++ b/arch/arm/mach-imx/devices/platform-imxdi_rtc.c
@@ -7,8 +7,9 @@
  * Free Software Foundation.
  */
 #include <asm/sizes.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_imxdi_rtc_data_entry_single(soc)				\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-ipu-core.c b/arch/arm/mach-imx/devices/platform-ipu-core.c
similarity index 97%
rename from arch/arm/plat-mxc/devices/platform-ipu-core.c
rename to arch/arm/mach-imx/devices/platform-ipu-core.c
index d1e33cc..fc4dd7c 100644
--- a/arch/arm/plat-mxc/devices/platform-ipu-core.c
+++ b/arch/arm/mach-imx/devices/platform-ipu-core.c
@@ -7,8 +7,9 @@
  * Free Software Foundation.
  */
 #include <linux/dma-mapping.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_ipu_core_entry_single(soc)					\
 {									\
diff --git a/arch/arm/plat-mxc/devices/platform-mx1-camera.c b/arch/arm/mach-imx/devices/platform-mx1-camera.c
similarity index 94%
rename from arch/arm/plat-mxc/devices/platform-mx1-camera.c
rename to arch/arm/mach-imx/devices/platform-mx1-camera.c
index edcc581..2c67881 100644
--- a/arch/arm/plat-mxc/devices/platform-mx1-camera.c
+++ b/arch/arm/mach-imx/devices/platform-mx1-camera.c
@@ -6,8 +6,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_mx1_camera_data_entry_single(soc, _size)			\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-mx2-camera.c b/arch/arm/mach-imx/devices/platform-mx2-camera.c
similarity index 67%
rename from arch/arm/plat-mxc/devices/platform-mx2-camera.c
rename to arch/arm/mach-imx/devices/platform-mx2-camera.c
index 11eace9..b53e1f3 100644
--- a/arch/arm/plat-mxc/devices/platform-mx2-camera.c
+++ b/arch/arm/mach-imx/devices/platform-mx2-camera.c
@@ -6,17 +6,19 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
-#define imx_mx2_camera_data_entry_single(soc)				\
+#define imx_mx2_camera_data_entry_single(soc, _devid)			\
 	{								\
+		.devid = _devid,					\
 		.iobasecsi = soc ## _CSI_BASE_ADDR,			\
 		.iosizecsi = SZ_4K,					\
 		.irqcsi = soc ## _INT_CSI,				\
 	}
-#define imx_mx2_camera_data_entry_single_emma(soc)			\
+#define imx_mx2_camera_data_entry_single_emma(soc, _devid)		\
 	{								\
+		.devid = _devid,					\
 		.iobasecsi = soc ## _CSI_BASE_ADDR,			\
 		.iosizecsi = SZ_32,					\
 		.irqcsi = soc ## _INT_CSI,				\
@@ -27,12 +29,12 @@
 
 #ifdef CONFIG_SOC_IMX25
 const struct imx_mx2_camera_data imx25_mx2_camera_data __initconst =
-	imx_mx2_camera_data_entry_single(MX25);
+	imx_mx2_camera_data_entry_single(MX25, "imx25-camera");
 #endif /* ifdef CONFIG_SOC_IMX25 */
 
 #ifdef CONFIG_SOC_IMX27
 const struct imx_mx2_camera_data imx27_mx2_camera_data __initconst =
-	imx_mx2_camera_data_entry_single_emma(MX27);
+	imx_mx2_camera_data_entry_single_emma(MX27, "imx27-camera");
 #endif /* ifdef CONFIG_SOC_IMX27 */
 
 struct platform_device *__init imx_add_mx2_camera(
@@ -58,25 +60,8 @@
 			.flags = IORESOURCE_IRQ,
 		},
 	};
-	return imx_add_platform_device_dmamask("mx2-camera", 0,
+	return imx_add_platform_device_dmamask(data->devid, 0,
 			res, data->iobaseemmaprp ? 4 : 2,
 			pdata, sizeof(*pdata), DMA_BIT_MASK(32));
 }
 
-struct platform_device *__init imx_add_mx2_emmaprp(
-		const struct imx_mx2_camera_data *data)
-{
-	struct resource res[] = {
-		{
-			.start = data->iobaseemmaprp,
-			.end = data->iobaseemmaprp + data->iosizeemmaprp - 1,
-			.flags = IORESOURCE_MEM,
-		}, {
-			.start = data->irqemmaprp,
-			.end = data->irqemmaprp,
-			.flags = IORESOURCE_IRQ,
-		},
-	};
-	return imx_add_platform_device_dmamask("m2m-emmaprp", 0,
-			res, 2, NULL, 0, DMA_BIT_MASK(32));
-}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c b/arch/arm/mach-imx/devices/platform-mxc-ehci.c
similarity index 97%
rename from arch/arm/plat-mxc/devices/platform-mxc-ehci.c
rename to arch/arm/mach-imx/devices/platform-mxc-ehci.c
index 35851d8..5d4bbbf 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
+++ b/arch/arm/mach-imx/devices/platform-mxc-ehci.c
@@ -7,8 +7,9 @@
  * Free Software Foundation.
  */
 #include <linux/dma-mapping.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_mxc_ehci_data_entry_single(soc, _id, hs)			\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-mxc-mmc.c b/arch/arm/mach-imx/devices/platform-mxc-mmc.c
similarity index 74%
rename from arch/arm/plat-mxc/devices/platform-mxc-mmc.c
rename to arch/arm/mach-imx/devices/platform-mxc-mmc.c
index 540d3a7..b8203c7 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc-mmc.c
+++ b/arch/arm/mach-imx/devices/platform-mxc-mmc.c
@@ -7,24 +7,26 @@
  * Free Software Foundation.
  */
 #include <linux/dma-mapping.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
 
-#define imx_mxc_mmc_data_entry_single(soc, _id, _hwid, _size)		\
+#include "../hardware.h"
+#include "devices-common.h"
+
+#define imx_mxc_mmc_data_entry_single(soc, _devid, _id, _hwid, _size)	\
 	{								\
+		.devid = _devid,					\
 		.id = _id,						\
 		.iobase = soc ## _SDHC ## _hwid ## _BASE_ADDR,		\
 		.iosize = _size,					\
 		.irq = soc ## _INT_SDHC ## _hwid,			\
 		.dmareq = soc ## _DMA_REQ_SDHC ## _hwid,		\
 	}
-#define imx_mxc_mmc_data_entry(soc, _id, _hwid, _size)			\
-	[_id] = imx_mxc_mmc_data_entry_single(soc, _id, _hwid, _size)
+#define imx_mxc_mmc_data_entry(soc, _devid, _id, _hwid, _size)		\
+	[_id] = imx_mxc_mmc_data_entry_single(soc, _devid, _id, _hwid, _size)
 
 #ifdef CONFIG_SOC_IMX21
 const struct imx_mxc_mmc_data imx21_mxc_mmc_data[] __initconst = {
 #define imx21_mxc_mmc_data_entry(_id, _hwid)				\
-	imx_mxc_mmc_data_entry(MX21, _id, _hwid, SZ_4K)
+	imx_mxc_mmc_data_entry(MX21, "imx21-mmc", _id, _hwid, SZ_4K)
 	imx21_mxc_mmc_data_entry(0, 1),
 	imx21_mxc_mmc_data_entry(1, 2),
 };
@@ -33,7 +35,7 @@
 #ifdef CONFIG_SOC_IMX27
 const struct imx_mxc_mmc_data imx27_mxc_mmc_data[] __initconst = {
 #define imx27_mxc_mmc_data_entry(_id, _hwid)				\
-	imx_mxc_mmc_data_entry(MX27, _id, _hwid, SZ_4K)
+	imx_mxc_mmc_data_entry(MX27, "imx21-mmc", _id, _hwid, SZ_4K)
 	imx27_mxc_mmc_data_entry(0, 1),
 	imx27_mxc_mmc_data_entry(1, 2),
 };
@@ -42,7 +44,7 @@
 #ifdef CONFIG_SOC_IMX31
 const struct imx_mxc_mmc_data imx31_mxc_mmc_data[] __initconst = {
 #define imx31_mxc_mmc_data_entry(_id, _hwid)				\
-	imx_mxc_mmc_data_entry(MX31, _id, _hwid, SZ_16K)
+	imx_mxc_mmc_data_entry(MX31, "imx31-mmc", _id, _hwid, SZ_16K)
 	imx31_mxc_mmc_data_entry(0, 1),
 	imx31_mxc_mmc_data_entry(1, 2),
 };
@@ -55,7 +57,7 @@
 	struct resource res[] = {
 		{
 			.start = data->iobase,
-			.end = data->iobase + SZ_4K - 1,
+			.end = data->iobase + data->iosize - 1,
 			.flags = IORESOURCE_MEM,
 		}, {
 			.start = data->irq,
@@ -67,7 +69,7 @@
 			.flags = IORESOURCE_DMA,
 		},
 	};
-	return imx_add_platform_device_dmamask("mxc-mmc", data->id,
+	return imx_add_platform_device_dmamask(data->devid, data->id,
 			res, ARRAY_SIZE(res),
 			pdata, sizeof(*pdata), DMA_BIT_MASK(32));
 }
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_nand.c b/arch/arm/mach-imx/devices/platform-mxc_nand.c
similarity index 74%
rename from arch/arm/plat-mxc/devices/platform-mxc_nand.c
rename to arch/arm/mach-imx/devices/platform-mxc_nand.c
index 95b75cc..7af1c53 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc_nand.c
+++ b/arch/arm/mach-imx/devices/platform-mxc_nand.c
@@ -7,18 +7,21 @@
  * Free Software Foundation.
  */
 #include <asm/sizes.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
 
-#define imx_mxc_nand_data_entry_single(soc, _size)			\
+#include "../hardware.h"
+#include "devices-common.h"
+
+#define imx_mxc_nand_data_entry_single(soc, _devid, _size)		\
 	{								\
+		.devid = _devid,					\
 		.iobase = soc ## _NFC_BASE_ADDR,			\
 		.iosize = _size,					\
 		.irq = soc ## _INT_NFC					\
 	}
 
-#define imx_mxc_nandv3_data_entry_single(soc, _size)			\
+#define imx_mxc_nandv3_data_entry_single(soc, _devid, _size)		\
 	{								\
+		.devid = _devid,					\
 		.id = -1,						\
 		.iobase = soc ## _NFC_BASE_ADDR,			\
 		.iosize = _size,					\
@@ -28,32 +31,32 @@
 
 #ifdef CONFIG_SOC_IMX21
 const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst =
-	imx_mxc_nand_data_entry_single(MX21, SZ_4K);
+	imx_mxc_nand_data_entry_single(MX21, "imx21-nand", SZ_4K);
 #endif /* ifdef CONFIG_SOC_IMX21 */
 
 #ifdef CONFIG_SOC_IMX25
 const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst =
-	imx_mxc_nand_data_entry_single(MX25, SZ_8K);
+	imx_mxc_nand_data_entry_single(MX25, "imx25-nand", SZ_8K);
 #endif /* ifdef CONFIG_SOC_IMX25 */
 
 #ifdef CONFIG_SOC_IMX27
 const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst =
-	imx_mxc_nand_data_entry_single(MX27, SZ_4K);
+	imx_mxc_nand_data_entry_single(MX27, "imx27-nand", SZ_4K);
 #endif /* ifdef CONFIG_SOC_IMX27 */
 
 #ifdef CONFIG_SOC_IMX31
 const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst =
-	imx_mxc_nand_data_entry_single(MX31, SZ_4K);
+	imx_mxc_nand_data_entry_single(MX31, "imx27-nand", SZ_4K);
 #endif
 
 #ifdef CONFIG_SOC_IMX35
 const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst =
-	imx_mxc_nand_data_entry_single(MX35, SZ_8K);
+	imx_mxc_nand_data_entry_single(MX35, "imx25-nand", SZ_8K);
 #endif
 
 #ifdef CONFIG_SOC_IMX51
 const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst =
-	imx_mxc_nandv3_data_entry_single(MX51, SZ_16K);
+	imx_mxc_nandv3_data_entry_single(MX51, "imx51-nand", SZ_16K);
 #endif
 
 struct platform_device *__init imx_add_mxc_nand(
@@ -76,7 +79,7 @@
 			.flags = IORESOURCE_MEM,
 		},
 	};
-	return imx_add_platform_device("mxc_nand", data->id,
+	return imx_add_platform_device(data->devid, data->id,
 			res, ARRAY_SIZE(res) - !data->axibase,
 			pdata, sizeof(*pdata));
 }
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_pwm.c b/arch/arm/mach-imx/devices/platform-mxc_pwm.c
similarity index 96%
rename from arch/arm/plat-mxc/devices/platform-mxc_pwm.c
rename to arch/arm/mach-imx/devices/platform-mxc_pwm.c
index b0c4ae2..dcd2897 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc_pwm.c
+++ b/arch/arm/mach-imx/devices/platform-mxc_pwm.c
@@ -6,8 +6,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_mxc_pwm_data_entry_single(soc, _id, _hwid, _size)		\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_rnga.c b/arch/arm/mach-imx/devices/platform-mxc_rnga.c
similarity index 95%
rename from arch/arm/plat-mxc/devices/platform-mxc_rnga.c
rename to arch/arm/mach-imx/devices/platform-mxc_rnga.c
index b4b7612..c58404b 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc_rnga.c
+++ b/arch/arm/mach-imx/devices/platform-mxc_rnga.c
@@ -6,8 +6,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 struct imx_mxc_rnga_data {
 	resource_size_t iobase;
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_rtc.c b/arch/arm/mach-imx/devices/platform-mxc_rtc.c
similarity index 77%
rename from arch/arm/plat-mxc/devices/platform-mxc_rtc.c
rename to arch/arm/mach-imx/devices/platform-mxc_rtc.c
index a5c9ad5..c7fffaa 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc_rtc.c
+++ b/arch/arm/mach-imx/devices/platform-mxc_rtc.c
@@ -6,23 +6,24 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
-#define imx_mxc_rtc_data_entry_single(soc)				\
+#define imx_mxc_rtc_data_entry_single(soc, _devid)			\
 	{								\
+		.devid = _devid,					\
 		.iobase = soc ## _RTC_BASE_ADDR,			\
 		.irq = soc ## _INT_RTC,					\
 	}
 
 #ifdef CONFIG_SOC_IMX31
 const struct imx_mxc_rtc_data imx31_mxc_rtc_data __initconst =
-	imx_mxc_rtc_data_entry_single(MX31);
+	imx_mxc_rtc_data_entry_single(MX31, "imx21-rtc");
 #endif /* ifdef CONFIG_SOC_IMX31 */
 
 #ifdef CONFIG_SOC_IMX35
 const struct imx_mxc_rtc_data imx35_mxc_rtc_data __initconst =
-	imx_mxc_rtc_data_entry_single(MX35);
+	imx_mxc_rtc_data_entry_single(MX35, "imx21-rtc");
 #endif /* ifdef CONFIG_SOC_IMX35 */
 
 struct platform_device *__init imx_add_mxc_rtc(
@@ -40,6 +41,6 @@
 		},
 	};
 
-	return imx_add_platform_device("mxc_rtc", -1,
+	return imx_add_platform_device(data->devid, -1,
 			res, ARRAY_SIZE(res), NULL, 0);
 }
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_w1.c b/arch/arm/mach-imx/devices/platform-mxc_w1.c
similarity index 95%
rename from arch/arm/plat-mxc/devices/platform-mxc_w1.c
rename to arch/arm/mach-imx/devices/platform-mxc_w1.c
index 96fa5ea..88c18b7 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc_w1.c
+++ b/arch/arm/mach-imx/devices/platform-mxc_w1.c
@@ -6,8 +6,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_mxc_w1_data_entry_single(soc)				\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-pata_imx.c b/arch/arm/mach-imx/devices/platform-pata_imx.c
similarity index 96%
rename from arch/arm/plat-mxc/devices/platform-pata_imx.c
rename to arch/arm/mach-imx/devices/platform-pata_imx.c
index 70e2f2a..e4ec11c 100644
--- a/arch/arm/plat-mxc/devices/platform-pata_imx.c
+++ b/arch/arm/mach-imx/devices/platform-pata_imx.c
@@ -3,8 +3,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_pata_imx_data_entry_single(soc, _size)			\
 	{								\
diff --git a/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c b/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c
similarity index 97%
rename from arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c
rename to arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c
index 3793e47..e66a4e3 100644
--- a/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c
+++ b/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c
@@ -6,10 +6,11 @@
  * Free Software Foundation.
  */
 
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
 #include <linux/platform_data/mmc-esdhc-imx.h>
 
+#include "../hardware.h"
+#include "devices-common.h"
+
 #define imx_sdhci_esdhc_imx_data_entry_single(soc, _devid, _id, hwid) \
 	{								\
 		.devid = _devid,					\
diff --git a/arch/arm/plat-mxc/devices/platform-spi_imx.c b/arch/arm/mach-imx/devices/platform-spi_imx.c
similarity index 98%
rename from arch/arm/plat-mxc/devices/platform-spi_imx.c
rename to arch/arm/mach-imx/devices/platform-spi_imx.c
index 9c50c14..8880bcb 100644
--- a/arch/arm/plat-mxc/devices/platform-spi_imx.c
+++ b/arch/arm/mach-imx/devices/platform-spi_imx.c
@@ -6,8 +6,8 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+#include "../hardware.h"
+#include "devices-common.h"
 
 #define imx_spi_imx_data_entry_single(soc, type, _devid, _id, hwid, _size) \
 	{								\
diff --git a/arch/arm/mach-imx/ehci-imx25.c b/arch/arm/mach-imx/ehci-imx25.c
index 412c583..134c190 100644
--- a/arch/arm/mach-imx/ehci-imx25.c
+++ b/arch/arm/mach-imx/ehci-imx25.c
@@ -15,10 +15,10 @@
 
 #include <linux/platform_device.h>
 #include <linux/io.h>
-
-#include <mach/hardware.h>
 #include <linux/platform_data/usb-ehci-mxc.h>
 
+#include "hardware.h"
+
 #define USBCTRL_OTGBASE_OFFSET	0x600
 
 #define MX25_OTG_SIC_SHIFT	29
@@ -30,7 +30,7 @@
 #define MX25_H1_SIC_SHIFT	21
 #define MX25_H1_SIC_MASK	(0x3 << MX25_H1_SIC_SHIFT)
 #define MX25_H1_PP_BIT		(1 << 18)
-#define MX25_H1_PM_BIT		(1 << 8)
+#define MX25_H1_PM_BIT		(1 << 16)
 #define MX25_H1_IPPUE_UP_BIT	(1 << 7)
 #define MX25_H1_IPPUE_DOWN_BIT	(1 << 6)
 #define MX25_H1_TLL_BIT		(1 << 5)
diff --git a/arch/arm/mach-imx/ehci-imx27.c b/arch/arm/mach-imx/ehci-imx27.c
index cd6e1f8..448d911 100644
--- a/arch/arm/mach-imx/ehci-imx27.c
+++ b/arch/arm/mach-imx/ehci-imx27.c
@@ -15,10 +15,10 @@
 
 #include <linux/platform_device.h>
 #include <linux/io.h>
-
-#include <mach/hardware.h>
 #include <linux/platform_data/usb-ehci-mxc.h>
 
+#include "hardware.h"
+
 #define USBCTRL_OTGBASE_OFFSET	0x600
 
 #define MX27_OTG_SIC_SHIFT	29
diff --git a/arch/arm/mach-imx/ehci-imx31.c b/arch/arm/mach-imx/ehci-imx31.c
index 9a880c7..05de4e1 100644
--- a/arch/arm/mach-imx/ehci-imx31.c
+++ b/arch/arm/mach-imx/ehci-imx31.c
@@ -15,10 +15,10 @@
 
 #include <linux/platform_device.h>
 #include <linux/io.h>
-
-#include <mach/hardware.h>
 #include <linux/platform_data/usb-ehci-mxc.h>
 
+#include "hardware.h"
+
 #define USBCTRL_OTGBASE_OFFSET	0x600
 
 #define MX31_OTG_SIC_SHIFT	29
diff --git a/arch/arm/mach-imx/ehci-imx35.c b/arch/arm/mach-imx/ehci-imx35.c
index 779e16e..554e7cc 100644
--- a/arch/arm/mach-imx/ehci-imx35.c
+++ b/arch/arm/mach-imx/ehci-imx35.c
@@ -15,10 +15,10 @@
 
 #include <linux/platform_device.h>
 #include <linux/io.h>
-
-#include <mach/hardware.h>
 #include <linux/platform_data/usb-ehci-mxc.h>
 
+#include "hardware.h"
+
 #define USBCTRL_OTGBASE_OFFSET	0x600
 
 #define MX35_OTG_SIC_SHIFT	29
@@ -30,7 +30,7 @@
 #define MX35_H1_SIC_SHIFT	21
 #define MX35_H1_SIC_MASK	(0x3 << MX35_H1_SIC_SHIFT)
 #define MX35_H1_PP_BIT		(1 << 18)
-#define MX35_H1_PM_BIT		(1 << 8)
+#define MX35_H1_PM_BIT		(1 << 16)
 #define MX35_H1_IPPUE_UP_BIT	(1 << 7)
 #define MX35_H1_IPPUE_DOWN_BIT	(1 << 6)
 #define MX35_H1_TLL_BIT		(1 << 5)
diff --git a/arch/arm/mach-imx/ehci-imx5.c b/arch/arm/mach-imx/ehci-imx5.c
index cf8d00e..e49710b 100644
--- a/arch/arm/mach-imx/ehci-imx5.c
+++ b/arch/arm/mach-imx/ehci-imx5.c
@@ -15,10 +15,10 @@
 
 #include <linux/platform_device.h>
 #include <linux/io.h>
-
-#include <mach/hardware.h>
 #include <linux/platform_data/usb-ehci-mxc.h>
 
+#include "hardware.h"
+
 #define MXC_OTG_OFFSET			0
 #define MXC_H1_OFFSET			0x200
 #define MXC_H2_OFFSET			0x400
diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/mach-imx/epit.c
similarity index 98%
rename from arch/arm/plat-mxc/epit.c
rename to arch/arm/mach-imx/epit.c
index 88726f4..04a5961 100644
--- a/arch/arm/plat-mxc/epit.c
+++ b/arch/arm/mach-imx/epit.c
@@ -51,10 +51,10 @@
 #include <linux/clockchips.h>
 #include <linux/clk.h>
 #include <linux/err.h>
-
-#include <mach/hardware.h>
 #include <asm/mach/time.h>
-#include <mach/common.h>
+
+#include "common.h"
+#include "hardware.h"
 
 static struct clock_event_device clockevent_epit;
 static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
diff --git a/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h b/arch/arm/mach-imx/eukrea-baseboards.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/eukrea-baseboards.h
rename to arch/arm/mach-imx/eukrea-baseboards.h
diff --git a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
index 98aef57..b4c7002 100644
--- a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
@@ -29,11 +29,10 @@
 
 #include <asm/mach/arch.h>
 
-#include <mach/common.h>
-#include <mach/iomux-mx27.h>
-#include <mach/hardware.h>
-
+#include "common.h"
 #include "devices-imx27.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
 
 static const int eukrea_mbimx27_pins[] __initconst = {
 	/* UART2 */
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
index 0b84666..e2b70f4c 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
@@ -26,14 +26,14 @@
 #include <linux/spi/spi.h>
 #include <video/platform_lcd.h>
 
-#include <mach/hardware.h>
-#include <mach/iomux-mx25.h>
-#include <mach/common.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/mx25.h>
 
+#include "common.h"
 #include "devices-imx25.h"
+#include "hardware.h"
+#include "iomux-mx25.h"
+#include "mx25.h"
 
 static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
 	/* LCD */
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
index c6532a0..5a2d5ef 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
@@ -36,11 +36,10 @@
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx35.h>
-
+#include "common.h"
 #include "devices-imx35.h"
+#include "hardware.h"
+#include "iomux-mx35.h"
 
 static const struct fb_videomode fb_modedb[] = {
 	{
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c
index 8b0de30..9be6c1e 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c
@@ -36,11 +36,10 @@
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx51.h>
-
+#include "common.h"
 #include "devices-imx51.h"
+#include "hardware.h"
+#include "iomux-mx51.h"
 
 static iomux_v3_cfg_t eukrea_mbimxsd51_pads[] = {
 	/* LED */
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/mach-imx/hardware.h
similarity index 93%
rename from arch/arm/plat-mxc/include/mach/hardware.h
rename to arch/arm/mach-imx/hardware.h
index ebf1065..3ce7fa3 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/mach-imx/hardware.h
@@ -105,20 +105,20 @@
 
 #define IMX_IO_ADDRESS(x)	IOMEM(IMX_IO_P2V(x))
 
-#include <mach/mxc.h>
+#include "mxc.h"
 
-#include <mach/mx6q.h>
-#include <mach/mx50.h>
-#include <mach/mx51.h>
-#include <mach/mx53.h>
-#include <mach/mx3x.h>
-#include <mach/mx31.h>
-#include <mach/mx35.h>
-#include <mach/mx2x.h>
-#include <mach/mx21.h>
-#include <mach/mx27.h>
-#include <mach/mx1.h>
-#include <mach/mx25.h>
+#include "mx6q.h"
+#include "mx50.h"
+#include "mx51.h"
+#include "mx53.h"
+#include "mx3x.h"
+#include "mx31.h"
+#include "mx35.h"
+#include "mx2x.h"
+#include "mx21.h"
+#include "mx27.h"
+#include "mx1.h"
+#include "mx25.h"
 
 #define imx_map_entry(soc, name, _type)	{				\
 	.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR),	\
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c
index b07b778..3dec962 100644
--- a/arch/arm/mach-imx/hotplug.c
+++ b/arch/arm/mach-imx/hotplug.c
@@ -13,7 +13,8 @@
 #include <linux/errno.h>
 #include <asm/cacheflush.h>
 #include <asm/cp15.h>
-#include <mach/common.h>
+
+#include "common.h"
 
 static inline void cpu_enter_lowpower(void)
 {
diff --git a/arch/arm/plat-mxc/include/mach/iim.h b/arch/arm/mach-imx/iim.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/iim.h
rename to arch/arm/mach-imx/iim.h
diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c
index e80d523..ebfae96 100644
--- a/arch/arm/mach-imx/imx27-dt.c
+++ b/arch/arm/mach-imx/imx27-dt.c
@@ -14,21 +14,22 @@
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
-#include <mach/common.h>
-#include <mach/mx27.h>
+
+#include "common.h"
+#include "mx27.h"
 
 static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = {
 	OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART1_BASE_ADDR, "imx21-uart.0", NULL),
 	OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART2_BASE_ADDR, "imx21-uart.1", NULL),
 	OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART3_BASE_ADDR, "imx21-uart.2", NULL),
 	OF_DEV_AUXDATA("fsl,imx27-fec", MX27_FEC_BASE_ADDR, "imx27-fec.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx27-i2c", MX27_I2C1_BASE_ADDR, "imx-i2c.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx27-i2c", MX27_I2C2_BASE_ADDR, "imx-i2c.1", NULL),
+	OF_DEV_AUXDATA("fsl,imx27-i2c", MX27_I2C1_BASE_ADDR, "imx21-i2c.0", NULL),
+	OF_DEV_AUXDATA("fsl,imx27-i2c", MX27_I2C2_BASE_ADDR, "imx21-i2c.1", NULL),
 	OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI1_BASE_ADDR, "imx27-cspi.0", NULL),
 	OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI2_BASE_ADDR, "imx27-cspi.1", NULL),
 	OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI3_BASE_ADDR, "imx27-cspi.2", NULL),
 	OF_DEV_AUXDATA("fsl,imx27-wdt", MX27_WDOG_BASE_ADDR, "imx2-wdt.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx27-nand", MX27_NFC_BASE_ADDR, "mxc_nand.0", NULL),
+	OF_DEV_AUXDATA("fsl,imx27-nand", MX27_NFC_BASE_ADDR, "imx27-nand.0", NULL),
 	{ /* sentinel */ }
 };
 
diff --git a/arch/arm/mach-imx/imx31-dt.c b/arch/arm/mach-imx/imx31-dt.c
index a68ba20..af476de 100644
--- a/arch/arm/mach-imx/imx31-dt.c
+++ b/arch/arm/mach-imx/imx31-dt.c
@@ -14,8 +14,9 @@
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
-#include <mach/common.h>
-#include <mach/mx31.h>
+
+#include "common.h"
+#include "mx31.h"
 
 static const struct of_dev_auxdata imx31_auxdata_lookup[] __initconst = {
 	OF_DEV_AUXDATA("fsl,imx31-uart", MX31_UART1_BASE_ADDR,
diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c
index f233b4b..5ffa40c 100644
--- a/arch/arm/mach-imx/imx51-dt.c
+++ b/arch/arm/mach-imx/imx51-dt.c
@@ -15,38 +15,13 @@
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
-#include <mach/common.h>
-#include <mach/mx51.h>
 
-/*
- * Lookup table for attaching a specific name and platform_data pointer to
- * devices as they get created by of_platform_populate().  Ideally this table
- * would not exist, but the current clock implementation depends on some devices
- * having a specific name.
- */
-static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
-	OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART1_BASE_ADDR, "imx21-uart.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART2_BASE_ADDR, "imx21-uart.1", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART3_BASE_ADDR, "imx21-uart.2", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-fec", MX51_FEC_BASE_ADDR, "imx27-fec.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-esdhc", MX51_ESDHC1_BASE_ADDR, "sdhci-esdhc-imx51.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-esdhc", MX51_ESDHC2_BASE_ADDR, "sdhci-esdhc-imx51.1", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-esdhc", MX51_ESDHC3_BASE_ADDR, "sdhci-esdhc-imx51.2", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-esdhc", MX51_ESDHC4_BASE_ADDR, "sdhci-esdhc-imx51.3", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-ecspi", MX51_ECSPI1_BASE_ADDR, "imx51-ecspi.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-ecspi", MX51_ECSPI2_BASE_ADDR, "imx51-ecspi.1", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-cspi", MX51_CSPI_BASE_ADDR, "imx35-cspi.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-i2c", MX51_I2C1_BASE_ADDR, "imx-i2c.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-i2c", MX51_I2C2_BASE_ADDR, "imx-i2c.1", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-sdma", MX51_SDMA_BASE_ADDR, "imx35-sdma", NULL),
-	OF_DEV_AUXDATA("fsl,imx51-wdt", MX51_WDOG1_BASE_ADDR, "imx2-wdt.0", NULL),
-	{ /* sentinel */ }
-};
+#include "common.h"
+#include "mx51.h"
 
 static void __init imx51_dt_init(void)
 {
-	of_platform_populate(NULL, of_default_bus_match_table,
-			     imx51_auxdata_lookup, NULL);
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
 static void __init imx51_timer_init(void)
diff --git a/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h b/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h
deleted file mode 100644
index df5f522..0000000
--- a/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __MACH_DMA_MX1_MX2_H__
-#define __MACH_DMA_MX1_MX2_H__
-/*
- * Don't use this header in new code, it will go away when all users are
- * converted to mach/dma-v1.h
- */
-
-#include <mach/dma-v1.h>
-
-#endif /* ifndef __MACH_DMA_MX1_MX2_H__ */
diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c
index 82bd440..cabefbc 100644
--- a/arch/arm/mach-imx/iomux-imx31.c
+++ b/arch/arm/mach-imx/iomux-imx31.c
@@ -22,8 +22,9 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx3.h>
+
+#include "hardware.h"
+#include "iomux-mx3.h"
 
 /*
  * IOMUX register (base) addresses
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx1.h b/arch/arm/mach-imx/iomux-mx1.h
similarity index 99%
rename from arch/arm/plat-mxc/include/mach/iomux-mx1.h
rename to arch/arm/mach-imx/iomux-mx1.h
index 6b1507c..95f4681 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx1.h
+++ b/arch/arm/mach-imx/iomux-mx1.h
@@ -18,7 +18,7 @@
 #ifndef __MACH_IOMUX_MX1_H__
 #define __MACH_IOMUX_MX1_H__
 
-#include <mach/iomux-v1.h>
+#include "iomux-v1.h"
 
 #define PA0_AIN_SPI2_CLK	(GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0)
 #define PA0_AF_ETMTRACESYNC	(GPIO_PORTA | GPIO_AF | 0)
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx21.h b/arch/arm/mach-imx/iomux-mx21.h
similarity index 98%
rename from arch/arm/plat-mxc/include/mach/iomux-mx21.h
rename to arch/arm/mach-imx/iomux-mx21.h
index 1495dfd..a70cffc 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx21.h
+++ b/arch/arm/mach-imx/iomux-mx21.h
@@ -18,8 +18,8 @@
 #ifndef __MACH_IOMUX_MX21_H__
 #define __MACH_IOMUX_MX21_H__
 
-#include <mach/iomux-mx2x.h>
-#include <mach/iomux-v1.h>
+#include "iomux-mx2x.h"
+#include "iomux-v1.h"
 
 /* Primary GPIO pin functions */
 
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/mach-imx/iomux-mx25.h
similarity index 99%
rename from arch/arm/plat-mxc/include/mach/iomux-mx25.h
rename to arch/arm/mach-imx/iomux-mx25.h
index c61ec0f..be51e83 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx25.h
+++ b/arch/arm/mach-imx/iomux-mx25.h
@@ -19,7 +19,7 @@
 #ifndef __MACH_IOMUX_MX25_H__
 #define __MACH_IOMUX_MX25_H__
 
-#include <mach/iomux-v3.h>
+#include "iomux-v3.h"
 
 /*
  * IOMUX/PAD Bit field definitions
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx27.h b/arch/arm/mach-imx/iomux-mx27.h
similarity index 99%
rename from arch/arm/plat-mxc/include/mach/iomux-mx27.h
rename to arch/arm/mach-imx/iomux-mx27.h
index d9f9a6e..218e99e 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx27.h
+++ b/arch/arm/mach-imx/iomux-mx27.h
@@ -19,8 +19,8 @@
 #ifndef __MACH_IOMUX_MX27_H__
 #define __MACH_IOMUX_MX27_H__
 
-#include <mach/iomux-mx2x.h>
-#include <mach/iomux-v1.h>
+#include "iomux-mx2x.h"
+#include "iomux-v1.h"
 
 /* Primary GPIO pin functions */
 
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h b/arch/arm/mach-imx/iomux-mx2x.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/iomux-mx2x.h
rename to arch/arm/mach-imx/iomux-mx2x.h
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/mach-imx/iomux-mx3.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/iomux-mx3.h
rename to arch/arm/mach-imx/iomux-mx3.h
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx35.h b/arch/arm/mach-imx/iomux-mx35.h
similarity index 99%
rename from arch/arm/plat-mxc/include/mach/iomux-mx35.h
rename to arch/arm/mach-imx/iomux-mx35.h
index 3117c18..90bfa6b 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx35.h
+++ b/arch/arm/mach-imx/iomux-mx35.h
@@ -19,7 +19,7 @@
 #ifndef __MACH_IOMUX_MX35_H__
 #define __MACH_IOMUX_MX35_H__
 
-#include <mach/iomux-v3.h>
+#include "iomux-v3.h"
 
 /*
  * The naming convention for the pad modes is MX35_PAD_<padname>__<padmode>
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx50.h b/arch/arm/mach-imx/iomux-mx50.h
similarity index 99%
rename from arch/arm/plat-mxc/include/mach/iomux-mx50.h
rename to arch/arm/mach-imx/iomux-mx50.h
index 98e7fd0..00f56e0 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx50.h
+++ b/arch/arm/mach-imx/iomux-mx50.h
@@ -19,7 +19,7 @@
 #ifndef __MACH_IOMUX_MX50_H__
 #define __MACH_IOMUX_MX50_H__
 
-#include <mach/iomux-v3.h>
+#include "iomux-v3.h"
 
 #define MX50_ELCDIF_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_DSE_HIGH)
 
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/mach-imx/iomux-mx51.h
similarity index 99%
rename from arch/arm/plat-mxc/include/mach/iomux-mx51.h
rename to arch/arm/mach-imx/iomux-mx51.h
index 2623e7a..75bbcc4 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
+++ b/arch/arm/mach-imx/iomux-mx51.h
@@ -13,7 +13,7 @@
 #ifndef __MACH_IOMUX_MX51_H__
 #define __MACH_IOMUX_MX51_H__
 
-#include <mach/iomux-v3.h>
+#include "iomux-v3.h"
 #define __NA_	0x000
 
 
diff --git a/arch/arm/plat-mxc/iomux-v1.c b/arch/arm/mach-imx/iomux-v1.c
similarity index 98%
rename from arch/arm/plat-mxc/iomux-v1.c
rename to arch/arm/mach-imx/iomux-v1.c
index 1f73963..2b156d1 100644
--- a/arch/arm/plat-mxc/iomux-v1.c
+++ b/arch/arm/mach-imx/iomux-v1.c
@@ -28,9 +28,10 @@
 #include <linux/string.h>
 #include <linux/gpio.h>
 
-#include <mach/hardware.h>
 #include <asm/mach/map.h>
-#include <mach/iomux-v1.h>
+
+#include "hardware.h"
+#include "iomux-v1.h"
 
 static void __iomem *imx_iomuxv1_baseaddr;
 static unsigned imx_iomuxv1_numports;
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v1.h b/arch/arm/mach-imx/iomux-v1.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/iomux-v1.h
rename to arch/arm/mach-imx/iomux-v1.h
diff --git a/arch/arm/plat-mxc/iomux-v3.c b/arch/arm/mach-imx/iomux-v3.c
similarity index 97%
rename from arch/arm/plat-mxc/iomux-v3.c
rename to arch/arm/mach-imx/iomux-v3.c
index 99a9cdb..9dae74b 100644
--- a/arch/arm/plat-mxc/iomux-v3.c
+++ b/arch/arm/mach-imx/iomux-v3.c
@@ -25,9 +25,10 @@
 #include <linux/string.h>
 #include <linux/gpio.h>
 
-#include <mach/hardware.h>
 #include <asm/mach/map.h>
-#include <mach/iomux-v3.h>
+
+#include "hardware.h"
+#include "iomux-v3.h"
 
 static void __iomem *base;
 
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/mach-imx/iomux-v3.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/iomux-v3.h
rename to arch/arm/mach-imx/iomux-v3.h
diff --git a/arch/arm/plat-mxc/include/mach/iram.h b/arch/arm/mach-imx/iram.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/iram.h
rename to arch/arm/mach-imx/iram.h
diff --git a/arch/arm/plat-mxc/iram_alloc.c b/arch/arm/mach-imx/iram_alloc.c
similarity index 98%
rename from arch/arm/plat-mxc/iram_alloc.c
rename to arch/arm/mach-imx/iram_alloc.c
index 074c386..6c80424 100644
--- a/arch/arm/plat-mxc/iram_alloc.c
+++ b/arch/arm/mach-imx/iram_alloc.c
@@ -22,7 +22,8 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/genalloc.h>
-#include <mach/iram.h>
+
+#include "iram.h"
 
 static unsigned long iram_phys_base;
 static void __iomem *iram_virt_base;
diff --git a/arch/arm/plat-mxc/irq-common.c b/arch/arm/mach-imx/irq-common.c
similarity index 100%
rename from arch/arm/plat-mxc/irq-common.c
rename to arch/arm/mach-imx/irq-common.c
diff --git a/arch/arm/plat-mxc/irq-common.h b/arch/arm/mach-imx/irq-common.h
similarity index 94%
rename from arch/arm/plat-mxc/irq-common.h
rename to arch/arm/mach-imx/irq-common.h
index 6ccb3a1..5b2dabb 100644
--- a/arch/arm/plat-mxc/irq-common.h
+++ b/arch/arm/mach-imx/irq-common.h
@@ -19,6 +19,9 @@
 #ifndef __PLAT_MXC_IRQ_COMMON_H__
 #define __PLAT_MXC_IRQ_COMMON_H__
 
+/* all normal IRQs can be FIQs */
+#define FIQ_START	0
+
 struct mxc_extra_irq
 {
 	int (*set_priority)(unsigned char irq, unsigned char prio);
diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c
index c40a34c..5f15103 100644
--- a/arch/arm/mach-imx/lluart.c
+++ b/arch/arm/mach-imx/lluart.c
@@ -14,7 +14,8 @@
 #include <asm/page.h>
 #include <asm/sizes.h>
 #include <asm/mach/map.h>
-#include <mach/hardware.h>
+
+#include "hardware.h"
 
 static struct map_desc imx_lluart_desc = {
 #ifdef CONFIG_DEBUG_IMX6Q_UART2
diff --git a/arch/arm/mach-imx/mach-apf9328.c b/arch/arm/mach-imx/mach-apf9328.c
index 7b99a79..5c9bd2c 100644
--- a/arch/arm/mach-imx/mach-apf9328.c
+++ b/arch/arm/mach-imx/mach-apf9328.c
@@ -25,11 +25,10 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx1.h>
-
+#include "common.h"
 #include "devices-imx1.h"
+#include "hardware.h"
+#include "iomux-mx1.h"
 
 static const int apf9328_pins[] __initconst = {
 	/* UART1 */
diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c
index 5985ed1..59bd6b0 100644
--- a/arch/arm/mach-imx/mach-armadillo5x0.c
+++ b/arch/arm/mach-imx/mach-armadillo5x0.c
@@ -41,19 +41,18 @@
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/memory.h>
 #include <asm/mach/map.h>
 
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/ulpi.h>
-
+#include "common.h"
 #include "devices-imx31.h"
 #include "crmregs-imx3.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.h"
 
 static int armadillo5x0_pins[] = {
 	/* UART1 */
diff --git a/arch/arm/mach-imx/mach-bug.c b/arch/arm/mach-imx/mach-bug.c
index 9a98977..3a39d5a 100644
--- a/arch/arm/mach-imx/mach-bug.c
+++ b/arch/arm/mach-imx/mach-bug.c
@@ -19,15 +19,14 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 
-#include <mach/iomux-mx3.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-
 #include <asm/mach/time.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
 
 static const struct imxuart_platform_data uart_pdata __initconst = {
 	.flags = IMXUART_HAVE_RTSCTS,
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c
index 2bb9e18..12a3706 100644
--- a/arch/arm/mach-imx/mach-cpuimx27.c
+++ b/arch/arm/mach-imx/mach-cpuimx27.c
@@ -34,13 +34,12 @@
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
 
-#include <mach/eukrea-baseboards.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx27.h>
-#include <mach/ulpi.h>
-
+#include "common.h"
 #include "devices-imx27.h"
+#include "eukrea-baseboards.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
+#include "ulpi.h"
 
 static const int eukrea_cpuimx27_pins[] __initconst = {
 	/* UART1 */
diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c
index d49b0ec..5a31bf8 100644
--- a/arch/arm/mach-imx/mach-cpuimx35.c
+++ b/arch/arm/mach-imx/mach-cpuimx35.c
@@ -37,12 +37,11 @@
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
 
-#include <mach/eukrea-baseboards.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx35.h>
-
+#include "common.h"
 #include "devices-imx35.h"
+#include "eukrea-baseboards.h"
+#include "hardware.h"
+#include "iomux-mx35.h"
 
 static const struct imxuart_platform_data uart_pdata __initconst = {
 	.flags = IMXUART_HAVE_RTSCTS,
diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c
index b87cc49..b727de0 100644
--- a/arch/arm/mach-imx/mach-cpuimx51sd.c
+++ b/arch/arm/mach-imx/mach-cpuimx51sd.c
@@ -26,18 +26,17 @@
 #include <linux/spi/spi.h>
 #include <linux/can/platform/mcp251x.h>
 
-#include <mach/eukrea-baseboards.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx51.h>
-
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 
+#include "common.h"
 #include "devices-imx51.h"
 #include "cpu_op-mx51.h"
+#include "eukrea-baseboards.h"
+#include "hardware.h"
+#include "iomux-mx51.h"
 
 #define USBH1_RST		IMX_GPIO_NR(2, 28)
 #define ETH_RST			IMX_GPIO_NR(2, 31)
diff --git a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c
index 017bbb7..75027a5 100644
--- a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c
+++ b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c
@@ -27,18 +27,18 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
 
-#include <mach/eukrea-baseboards.h>
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/memory.h>
 #include <asm/mach/map.h>
-#include <mach/common.h>
-#include <mach/mx25.h>
-#include <mach/iomux-mx25.h>
 
+#include "common.h"
 #include "devices-imx25.h"
+#include "eukrea-baseboards.h"
+#include "hardware.h"
+#include "iomux-mx25.h"
+#include "mx25.h"
 
 static const struct imxuart_platform_data uart_pdata __initconst = {
 	.flags = IMXUART_HAVE_RTSCTS,
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
index 141756f..b744226 100644
--- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -40,11 +40,11 @@
 #include <asm/mach/time.h>
 #include <asm/system_info.h>
 #include <asm/memblock.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx27.h>
 
+#include "common.h"
 #include "devices-imx27.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
 
 #define TVP5150_RSTN (GPIO_PORTC + 18)
 #define TVP5150_PWDN (GPIO_PORTC + 19)
diff --git a/arch/arm/mach-imx/mach-imx27ipcam.c b/arch/arm/mach-imx/mach-imx27ipcam.c
index 7381387..53a8601 100644
--- a/arch/arm/mach-imx/mach-imx27ipcam.c
+++ b/arch/arm/mach-imx/mach-imx27ipcam.c
@@ -17,11 +17,11 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx27.h>
 
+#include "hardware.h"
+#include "common.h"
 #include "devices-imx27.h"
+#include "iomux-mx27.h"
 
 static const int mx27ipcam_pins[] __initconst = {
 	/* UART1 */
diff --git a/arch/arm/mach-imx/mach-imx27lite.c b/arch/arm/mach-imx/mach-imx27lite.c
index 1f45b91..fc8dce9 100644
--- a/arch/arm/mach-imx/mach-imx27lite.c
+++ b/arch/arm/mach-imx/mach-imx27lite.c
@@ -20,11 +20,11 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx27.h>
 
+#include "common.h"
 #include "devices-imx27.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
 
 static const int mx27lite_pins[] __initconst = {
 	/* UART1 */
diff --git a/arch/arm/mach-imx/mach-imx53.c b/arch/arm/mach-imx/mach-imx53.c
index 29711e9..860284d 100644
--- a/arch/arm/mach-imx/mach-imx53.c
+++ b/arch/arm/mach-imx/mach-imx53.c
@@ -19,36 +19,9 @@
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
-#include <mach/common.h>
-#include <mach/mx53.h>
 
-/*
- * Lookup table for attaching a specific name and platform_data pointer to
- * devices as they get created by of_platform_populate().  Ideally this table
- * would not exist, but the current clock implementation depends on some devices
- * having a specific name.
- */
-static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = {
-	OF_DEV_AUXDATA("fsl,imx53-uart", MX53_UART1_BASE_ADDR, "imx21-uart.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-uart", MX53_UART2_BASE_ADDR, "imx21-uart.1", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-uart", MX53_UART3_BASE_ADDR, "imx21-uart.2", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-uart", MX53_UART4_BASE_ADDR, "imx21-uart.3", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-uart", MX53_UART5_BASE_ADDR, "imx21-uart.4", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-fec", MX53_FEC_BASE_ADDR, "imx25-fec.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-esdhc", MX53_ESDHC1_BASE_ADDR, "sdhci-esdhc-imx53.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-esdhc", MX53_ESDHC2_BASE_ADDR, "sdhci-esdhc-imx53.1", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-esdhc", MX53_ESDHC3_BASE_ADDR, "sdhci-esdhc-imx53.2", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-esdhc", MX53_ESDHC4_BASE_ADDR, "sdhci-esdhc-imx53.3", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-ecspi", MX53_ECSPI1_BASE_ADDR, "imx51-ecspi.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-ecspi", MX53_ECSPI2_BASE_ADDR, "imx51-ecspi.1", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-cspi", MX53_CSPI_BASE_ADDR, "imx35-cspi.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-i2c", MX53_I2C1_BASE_ADDR, "imx-i2c.0", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-i2c", MX53_I2C2_BASE_ADDR, "imx-i2c.1", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-i2c", MX53_I2C3_BASE_ADDR, "imx-i2c.2", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-sdma", MX53_SDMA_BASE_ADDR, "imx35-sdma", NULL),
-	OF_DEV_AUXDATA("fsl,imx53-wdt", MX53_WDOG1_BASE_ADDR, "imx2-wdt.0", NULL),
-	{ /* sentinel */ }
-};
+#include "common.h"
+#include "mx53.h"
 
 static void __init imx53_qsb_init(void)
 {
@@ -68,8 +41,7 @@
 	if (of_machine_is_compatible("fsl,imx53-qsb"))
 		imx53_qsb_init();
 
-	of_platform_populate(NULL, of_default_bus_match_table,
-			     imx53_auxdata_lookup, NULL);
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
 static void __init imx53_timer_init(void)
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 47c91f7..978b6dd 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -33,10 +33,10 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/system_misc.h>
-#include <mach/common.h>
-#include <mach/cpuidle.h>
-#include <mach/hardware.h>
 
+#include "common.h"
+#include "cpuidle.h"
+#include "hardware.h"
 
 void imx6q_restart(char mode, const char *cmd)
 {
diff --git a/arch/arm/mach-imx/mach-kzm_arm11_01.c b/arch/arm/mach-imx/mach-kzm_arm11_01.c
index 0330078..2e536ea5 100644
--- a/arch/arm/mach-imx/mach-kzm_arm11_01.c
+++ b/arch/arm/mach-imx/mach-kzm_arm11_01.c
@@ -36,11 +36,10 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx3.h>
-
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
 
 #define KZM_ARM11_IO_ADDRESS(x) (IOMEM(					\
 	IMX_IO_P2V_MODULE(x, MX31_CS4) ?:				\
diff --git a/arch/arm/mach-imx/mach-mx1ads.c b/arch/arm/mach-imx/mach-mx1ads.c
index 667f359..06b4837 100644
--- a/arch/arm/mach-imx/mach-mx1ads.c
+++ b/arch/arm/mach-imx/mach-mx1ads.c
@@ -23,11 +23,10 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx1.h>
-
+#include "common.h"
 #include "devices-imx1.h"
+#include "hardware.h"
+#include "iomux-mx1.h"
 
 static const int mx1ads_pins[] __initconst = {
 	/* UART1 */
diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c
index ed22e3f..6adb313 100644
--- a/arch/arm/mach-imx/mach-mx21ads.c
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -18,15 +18,15 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/physmap.h>
 #include <linux/gpio.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
-#include <mach/iomux-mx21.h>
 
+#include "common.h"
 #include "devices-imx21.h"
+#include "hardware.h"
+#include "iomux-mx21.h"
 
 /*
  * Memory-mapped I/O on MX21ADS base board
diff --git a/arch/arm/mach-imx/mach-mx25_3ds.c b/arch/arm/mach-imx/mach-mx25_3ds.c
index ce247fd..b1b03aa 100644
--- a/arch/arm/mach-imx/mach-mx25_3ds.c
+++ b/arch/arm/mach-imx/mach-mx25_3ds.c
@@ -31,17 +31,17 @@
 #include <linux/platform_device.h>
 #include <linux/usb/otg.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/memory.h>
 #include <asm/mach/map.h>
-#include <mach/common.h>
-#include <mach/mx25.h>
-#include <mach/iomux-mx25.h>
 
+#include "common.h"
 #include "devices-imx25.h"
+#include "hardware.h"
+#include "iomux-mx25.h"
+#include "mx25.h"
 
 #define MX25PDK_CAN_PWDN	IMX_GPIO_NR(4, 6)
 
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
index 05996f3..d0e547f 100644
--- a/arch/arm/mach-imx/mach-mx27_3ds.c
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -36,13 +36,13 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx27.h>
-#include <mach/ulpi.h>
-#include <mach/3ds_debugboard.h>
 
+#include "3ds_debugboard.h"
+#include "common.h"
 #include "devices-imx27.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
+#include "ulpi.h"
 
 #define SD1_EN_GPIO		IMX_GPIO_NR(2, 25)
 #define OTG_PHY_RESET_GPIO	IMX_GPIO_NR(2, 23)
diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c
index 7dc59ba..3d036f5 100644
--- a/arch/arm/mach-imx/mach-mx27ads.c
+++ b/arch/arm/mach-imx/mach-mx27ads.c
@@ -21,15 +21,15 @@
 #include <linux/mtd/physmap.h>
 #include <linux/i2c.h>
 #include <linux/irq.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
-#include <mach/iomux-mx27.h>
 
+#include "common.h"
 #include "devices-imx27.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
 
 /*
  * Base address of PBC controller, CS4
diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c
index 8915f93..bc301be 100644
--- a/arch/arm/mach-imx/mach-mx31_3ds.c
+++ b/arch/arm/mach-imx/mach-mx31_3ds.c
@@ -30,19 +30,19 @@
 
 #include <media/soc_camera.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/memory.h>
 #include <asm/mach/map.h>
 #include <asm/memblock.h>
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/3ds_debugboard.h>
-#include <mach/ulpi.h>
 
+#include "3ds_debugboard.h"
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.h"
 
 static int mx31_3ds_pins[] = {
 	/* UART1 */
@@ -393,7 +393,7 @@
 };
 
 static struct regulator_consumer_supply vmmc2_consumers[] = {
-	REGULATOR_SUPPLY("vmmc", "mxc-mmc.0"),
+	REGULATOR_SUPPLY("vmmc", "imx31-mmc.0"),
 };
 
 static struct regulator_init_data vmmc2_init = {
diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c
index e774b07..8b56f88 100644
--- a/arch/arm/mach-imx/mach-mx31ads.c
+++ b/arch/arm/mach-imx/mach-mx31ads.c
@@ -28,8 +28,6 @@
 #include <asm/mach/time.h>
 #include <asm/memory.h>
 #include <asm/mach/map.h>
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
 
 #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
 #include <linux/mfd/wm8350/audio.h>
@@ -37,7 +35,10 @@
 #include <linux/mfd/wm8350/pmic.h>
 #endif
 
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
 
 /* Base address of PBC controller */
 #define PBC_BASE_ADDRESS	MX31_CS4_BASE_ADDR_VIRT
diff --git a/arch/arm/mach-imx/mach-mx31lilly.c b/arch/arm/mach-imx/mach-mx31lilly.c
index 34b9bf0..08b9965 100644
--- a/arch/arm/mach-imx/mach-mx31lilly.c
+++ b/arch/arm/mach-imx/mach-mx31lilly.c
@@ -42,13 +42,12 @@
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/board-mx31lilly.h>
-#include <mach/ulpi.h>
-
+#include "board-mx31lilly.h"
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.h"
 
 /*
  * This file contains module-specific initialization routines for LILLY-1131.
diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c
index ef57cff..bdcd92e 100644
--- a/arch/arm/mach-imx/mach-mx31lite.c
+++ b/arch/arm/mach-imx/mach-mx31lite.c
@@ -39,13 +39,12 @@
 #include <asm/page.h>
 #include <asm/setup.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/board-mx31lite.h>
-#include <mach/iomux-mx3.h>
-#include <mach/ulpi.h>
-
+#include "board-mx31lite.h"
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.h"
 
 /*
  * This file contains the module-specific initialization routines.
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c
index 459e754..2517cfa 100644
--- a/arch/arm/mach-imx/mach-mx31moboard.c
+++ b/arch/arm/mach-imx/mach-mx31moboard.c
@@ -42,14 +42,14 @@
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
 #include <asm/memblock.h>
-#include <mach/board-mx31moboard.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx3.h>
-#include <mach/ulpi.h>
 #include <linux/platform_data/asoc-imx-ssi.h>
 
+#include "board-mx31moboard.h"
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.h"
 
 static unsigned int moboard_pins[] = {
 	/* UART0 */
@@ -175,11 +175,11 @@
 
 static struct regulator_consumer_supply sdhc_consumers[] = {
 	{
-		.dev_name = "mxc-mmc.0",
+		.dev_name = "imx31-mmc.0",
 		.supply	= "sdhc0_vcc",
 	},
 	{
-		.dev_name = "mxc-mmc.1",
+		.dev_name = "imx31-mmc.1",
 		.supply	= "sdhc1_vcc",
 	},
 };
diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c
index 504983c..5277da4 100644
--- a/arch/arm/mach-imx/mach-mx35_3ds.c
+++ b/arch/arm/mach-imx/mach-mx35_3ds.c
@@ -43,15 +43,15 @@
 #include <asm/mach/map.h>
 #include <asm/memblock.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx35.h>
-#include <mach/3ds_debugboard.h>
 #include <video/platform_lcd.h>
 
 #include <media/soc_camera.h>
 
+#include "3ds_debugboard.h"
+#include "common.h"
 #include "devices-imx35.h"
+#include "hardware.h"
+#include "iomux-mx35.h"
 
 #define GPIO_MC9S08DZ60_GPS_ENABLE 0
 #define GPIO_MC9S08DZ60_HDD_ENABLE 4
diff --git a/arch/arm/mach-imx/mach-mx50_rdp.c b/arch/arm/mach-imx/mach-mx50_rdp.c
index 42b66e8..0c1f88a 100644
--- a/arch/arm/mach-imx/mach-mx50_rdp.c
+++ b/arch/arm/mach-imx/mach-mx50_rdp.c
@@ -24,17 +24,16 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx50.h>
-
 #include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 
+#include "common.h"
 #include "devices-imx50.h"
+#include "hardware.h"
+#include "iomux-mx50.h"
 
 #define FEC_EN		IMX_GPIO_NR(6, 23)
 #define FEC_RESET_B	IMX_GPIO_NR(4, 12)
diff --git a/arch/arm/mach-imx/mach-mx51_3ds.c b/arch/arm/mach-imx/mach-mx51_3ds.c
index 9ee84a4..abc25bd 100644
--- a/arch/arm/mach-imx/mach-mx51_3ds.c
+++ b/arch/arm/mach-imx/mach-mx51_3ds.c
@@ -19,12 +19,11 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx51.h>
-#include <mach/3ds_debugboard.h>
-
+#include "3ds_debugboard.h"
+#include "common.h"
 #include "devices-imx51.h"
+#include "hardware.h"
+#include "iomux-mx51.h"
 
 #define MX51_3DS_ECSPI2_CS	(GPIO_PORTC + 28)
 
diff --git a/arch/arm/mach-imx/mach-mx51_babbage.c b/arch/arm/mach-imx/mach-mx51_babbage.c
index 7b31cbd..d9a84ca 100644
--- a/arch/arm/mach-imx/mach-mx51_babbage.c
+++ b/arch/arm/mach-imx/mach-mx51_babbage.c
@@ -20,17 +20,16 @@
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
 
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx51.h>
-
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 
+#include "common.h"
 #include "devices-imx51.h"
 #include "cpu_op-mx51.h"
+#include "hardware.h"
+#include "iomux-mx51.h"
 
 #define BABBAGE_USB_HUB_RESET	IMX_GPIO_NR(1, 7)
 #define BABBAGE_USBH1_STP	IMX_GPIO_NR(1, 27)
diff --git a/arch/arm/mach-imx/mach-mxt_td60.c b/arch/arm/mach-imx/mach-mxt_td60.c
index 0bf6d30..f4a8c7e 100644
--- a/arch/arm/mach-imx/mach-mxt_td60.c
+++ b/arch/arm/mach-imx/mach-mxt_td60.c
@@ -21,17 +21,17 @@
 #include <linux/mtd/physmap.h>
 #include <linux/i2c.h>
 #include <linux/irq.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
 #include <linux/gpio.h>
-#include <mach/iomux-mx27.h>
 #include <linux/i2c/pca953x.h>
 
+#include "common.h"
 #include "devices-imx27.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
 
 static const int mxt_td60_pins[] __initconst = {
 	/* UART0 */
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index de8516b..eee369f 100644
--- a/arch/arm/mach-imx/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -32,13 +32,13 @@
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx27.h>
 #include <asm/mach/time.h>
-#include <mach/ulpi.h>
 
+#include "common.h"
 #include "devices-imx27.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
+#include "ulpi.h"
 
 #define OTG_PHY_CS_GPIO (GPIO_PORTB + 23)
 #define USBH2_PHY_CS_GPIO (GPIO_PORTB + 24)
diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c
index e3c4513..547fef1 100644
--- a/arch/arm/mach-imx/mach-pcm037.c
+++ b/arch/arm/mach-imx/mach-pcm037.c
@@ -42,13 +42,13 @@
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
 #include <asm/memblock.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx3.h>
-#include <mach/ulpi.h>
 
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
 #include "pcm037.h"
+#include "ulpi.h"
 
 static enum pcm037_board_variant pcm037_instance = PCM037_PCM970;
 
diff --git a/arch/arm/mach-imx/mach-pcm037_eet.c b/arch/arm/mach-imx/mach-pcm037_eet.c
index 11ffa81..8fd8255 100644
--- a/arch/arm/mach-imx/mach-pcm037_eet.c
+++ b/arch/arm/mach-imx/mach-pcm037_eet.c
@@ -11,13 +11,12 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-
 #include <asm/mach-types.h>
 
 #include "pcm037.h"
+#include "common.h"
 #include "devices-imx31.h"
+#include "iomux-mx3.h"
 
 static unsigned int pcm037_eet_pins[] = {
 	/* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c
index 95f49d9..4aa0d07 100644
--- a/arch/arm/mach-imx/mach-pcm038.c
+++ b/arch/arm/mach-imx/mach-pcm038.c
@@ -33,13 +33,12 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 
-#include <mach/board-pcm038.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx27.h>
-#include <mach/ulpi.h>
-
+#include "board-pcm038.h"
+#include "common.h"
 #include "devices-imx27.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
+#include "ulpi.h"
 
 static const int pcm038_pins[] __initconst = {
 	/* UART1 */
@@ -212,7 +211,7 @@
 
 static struct regulator_consumer_supply sdhc1_consumers[] = {
 	{
-		.dev_name = "mxc-mmc.1",
+		.dev_name = "imx21-mmc.1",
 		.supply	= "sdhc_vcc",
 	},
 };
diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c
index e4bd438..9244544 100644
--- a/arch/arm/mach-imx/mach-pcm043.c
+++ b/arch/arm/mach-imx/mach-pcm043.c
@@ -33,12 +33,11 @@
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx35.h>
-#include <mach/ulpi.h>
-
+#include "common.h"
 #include "devices-imx35.h"
+#include "hardware.h"
+#include "iomux-mx35.h"
+#include "ulpi.h"
 
 static const struct fb_videomode fb_modedb[] = {
 	{
diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c
index fb25fbd..96d9a91 100644
--- a/arch/arm/mach-imx/mach-qong.c
+++ b/arch/arm/mach-imx/mach-qong.c
@@ -21,17 +21,17 @@
 #include <linux/mtd/nand.h>
 #include <linux/gpio.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
-#include <mach/common.h>
 #include <asm/page.h>
 #include <asm/setup.h>
-#include <mach/iomux-mx3.h>
 
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
 
 /* FPGA defines */
 #define QONG_FPGA_VERSION(major, minor, rev)	\
diff --git a/arch/arm/mach-imx/mach-scb9328.c b/arch/arm/mach-imx/mach-scb9328.c
index 67ff38e..fc97040 100644
--- a/arch/arm/mach-imx/mach-scb9328.c
+++ b/arch/arm/mach-imx/mach-scb9328.c
@@ -20,11 +20,10 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx1.h>
-
+#include "common.h"
 #include "devices-imx1.h"
+#include "hardware.h"
+#include "iomux-mx1.h"
 
 /*
  * This scb9328 has a 32MiB flash
diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c
index 39eb796..3aecf91 100644
--- a/arch/arm/mach-imx/mach-vpr200.c
+++ b/arch/arm/mach-imx/mach-vpr200.c
@@ -28,15 +28,14 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx35.h>
-
 #include <linux/i2c.h>
 #include <linux/i2c/at24.h>
 #include <linux/mfd/mc13xxx.h>
 
+#include "common.h"
 #include "devices-imx35.h"
+#include "hardware.h"
+#include "iomux-mx35.h"
 
 #define GPIO_LCDPWR	IMX_GPIO_NR(1, 2)
 #define GPIO_PMIC_INT	IMX_GPIO_NR(2, 0)
diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c
index 6d60d51..7a14667 100644
--- a/arch/arm/mach-imx/mm-imx1.c
+++ b/arch/arm/mach-imx/mm-imx1.c
@@ -22,9 +22,10 @@
 
 #include <asm/mach/map.h>
 
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-v1.h>
+#include "common.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
+#include "iomux-v1.h"
 
 static struct map_desc imx_io_desc[] __initdata = {
 	imx_map_entry(MX1, IO, MT_DEVICE),
@@ -58,5 +59,7 @@
 						MX1_GPIO_INT_PORTC, 0);
 	mxc_register_gpio("imx1-gpio", 3, MX1_GPIO4_BASE_ADDR, SZ_256,
 						MX1_GPIO_INT_PORTD, 0);
+	imx_add_imx_dma("imx1-dma", MX1_DMA_BASE_ADDR,
+			MX1_DMA_INT, MX1_DMA_ERR);
 	pinctrl_provide_dummies();
 }
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
index d056dad..d8ccd3a 100644
--- a/arch/arm/mach-imx/mm-imx21.c
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -21,12 +21,13 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/pinctrl/machine.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/devices-common.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
-#include <mach/iomux-v1.h>
+
+#include "common.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
+#include "iomux-v1.h"
 
 /* MX21 memory map definition */
 static struct map_desc imx21_io_desc[] __initdata = {
@@ -81,6 +82,8 @@
 
 void __init imx21_soc_init(void)
 {
+	mxc_device_init();
+
 	mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
 	mxc_register_gpio("imx21-gpio", 1, MX21_GPIO2_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
 	mxc_register_gpio("imx21-gpio", 2, MX21_GPIO3_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
@@ -89,7 +92,8 @@
 	mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
 
 	pinctrl_provide_dummies();
-	imx_add_imx_dma();
+	imx_add_imx_dma("imx21-dma", MX21_DMA_BASE_ADDR,
+			MX21_INT_DMACH0, 0); /* No ERR irq */
 	platform_device_register_simple("imx21-audmux", 0, imx21_audmux_res,
 					ARRAY_SIZE(imx21_audmux_res));
 }
diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c
index f3f5c65..9357707 100644
--- a/arch/arm/mach-imx/mm-imx25.c
+++ b/arch/arm/mach-imx/mm-imx25.c
@@ -24,11 +24,11 @@
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
 
-#include <mach/common.h>
-#include <mach/devices-common.h>
-#include <mach/hardware.h>
-#include <mach/mx25.h>
-#include <mach/iomux-v3.h>
+#include "common.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
+#include "iomux-v3.h"
+#include "mx25.h"
 
 /*
  * This table defines static virtual address mappings for I/O regions.
@@ -89,6 +89,8 @@
 
 void __init imx25_soc_init(void)
 {
+	mxc_device_init();
+
 	/* i.mx25 has the i.mx35 type gpio */
 	mxc_register_gpio("imx35-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
 	mxc_register_gpio("imx35-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
index e7e24af..4f1be65 100644
--- a/arch/arm/mach-imx/mm-imx27.c
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -21,12 +21,13 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/pinctrl/machine.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/devices-common.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
-#include <mach/iomux-v1.h>
+
+#include "common.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
+#include "iomux-v1.h"
 
 /* MX27 memory map definition */
 static struct map_desc imx27_io_desc[] __initdata = {
@@ -81,6 +82,8 @@
 
 void __init imx27_soc_init(void)
 {
+	mxc_device_init();
+
 	/* i.mx27 has the i.mx21 type gpio */
 	mxc_register_gpio("imx21-gpio", 0, MX27_GPIO1_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
 	mxc_register_gpio("imx21-gpio", 1, MX27_GPIO2_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
@@ -90,7 +93,8 @@
 	mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
 
 	pinctrl_provide_dummies();
-	imx_add_imx_dma();
+	imx_add_imx_dma("imx27-dma", MX27_DMA_BASE_ADDR,
+			MX27_INT_DMACH0, 0); /* No ERR irq */
 	/* imx27 has the imx21 type audmux */
 	platform_device_register_simple("imx21-audmux", 0, imx27_audmux_res,
 					ARRAY_SIZE(imx27_audmux_res));
diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c
index 9d2c843..cefa047 100644
--- a/arch/arm/mach-imx/mm-imx3.c
+++ b/arch/arm/mach-imx/mm-imx3.c
@@ -26,12 +26,11 @@
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/map.h>
 
-#include <mach/common.h>
-#include <mach/devices-common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-v3.h>
-
+#include "common.h"
 #include "crmregs-imx3.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
+#include "iomux-v3.h"
 
 void __iomem *mx3_ccm_base;
 
@@ -108,9 +107,8 @@
 	}
 
 	l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096);
-	if (IS_ERR(l2x0_base)) {
-		printk(KERN_ERR "remapping L2 cache area failed with %ld\n",
-				PTR_ERR(l2x0_base));
+	if (!l2x0_base) {
+		printk(KERN_ERR "remapping L2 cache area failed\n");
 		return;
 	}
 
@@ -176,6 +174,8 @@
 
 	imx3_init_l2x0();
 
+	mxc_device_init();
+
 	mxc_register_gpio("imx31-gpio", 0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0);
 	mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0);
 	mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0);
@@ -272,6 +272,8 @@
 
 	imx3_init_l2x0();
 
+	mxc_device_init();
+
 	mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
 	mxc_register_gpio("imx35-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
 	mxc_register_gpio("imx35-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index acb0aad..79d71cf 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -18,10 +18,10 @@
 
 #include <asm/mach/map.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/devices-common.h>
-#include <mach/iomux-v3.h>
+#include "common.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
+#include "iomux-v3.h"
 
 /*
  * Define the MX50 memory map.
@@ -81,8 +81,28 @@
 	mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR));
 }
 
+/*
+ * The MIPI HSC unit has been removed from the i.MX51 Reference Manual by
+ * the Freescale marketing division. However this did not remove the
+ * hardware from the chip which still needs to be configured for proper
+ * IPU support.
+ */
+static void __init imx51_ipu_mipi_setup(void)
+{
+	void __iomem *hsc_addr;
+	hsc_addr = MX51_IO_ADDRESS(MX51_MIPI_HSC_BASE_ADDR);
+
+	/* setup MIPI module to legacy mode */
+	__raw_writel(0xf00, hsc_addr);
+
+	/* CSI mode: reserved; DI control mode: legacy (from Freescale BSP) */
+	__raw_writel(__raw_readl(hsc_addr + 0x800) | 0x30ff,
+		hsc_addr + 0x800);
+}
+
 void __init imx51_init_early(void)
 {
+	imx51_ipu_mipi_setup();
 	mxc_set_cpu_type(MXC_CPU_MX51);
 	mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
 	mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
@@ -138,6 +158,8 @@
 
 void __init imx50_soc_init(void)
 {
+	mxc_device_init();
+
 	/* i.mx50 has the i.mx35 type gpio */
 	mxc_register_gpio("imx35-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
 	mxc_register_gpio("imx35-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
@@ -153,6 +175,8 @@
 
 void __init imx51_soc_init(void)
 {
+	mxc_device_init();
+
 	/* i.mx51 has the i.mx35 type gpio */
 	mxc_register_gpio("imx35-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH);
 	mxc_register_gpio("imx35-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH);
diff --git a/arch/arm/plat-mxc/include/mach/mx1.h b/arch/arm/mach-imx/mx1.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx1.h
rename to arch/arm/mach-imx/mx1.h
diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/mach-imx/mx21.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx21.h
rename to arch/arm/mach-imx/mx21.h
diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/mach-imx/mx25.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx25.h
rename to arch/arm/mach-imx/mx25.h
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/mach-imx/mx27.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx27.h
rename to arch/arm/mach-imx/mx27.h
diff --git a/arch/arm/plat-mxc/include/mach/mx2x.h b/arch/arm/mach-imx/mx2x.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx2x.h
rename to arch/arm/mach-imx/mx2x.h
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/mach-imx/mx31.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx31.h
rename to arch/arm/mach-imx/mx31.h
diff --git a/arch/arm/mach-imx/mx31lilly-db.c b/arch/arm/mach-imx/mx31lilly-db.c
index 29e890f..d4361b8 100644
--- a/arch/arm/mach-imx/mx31lilly-db.c
+++ b/arch/arm/mach-imx/mx31lilly-db.c
@@ -30,12 +30,11 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/board-mx31lilly.h>
-
+#include "board-mx31lilly.h"
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
 
 /*
  * This file contains board-specific initialization routines for the
diff --git a/arch/arm/mach-imx/mx31lite-db.c b/arch/arm/mach-imx/mx31lite-db.c
index 83d17d9..5a160b7 100644
--- a/arch/arm/mach-imx/mx31lite-db.c
+++ b/arch/arm/mach-imx/mx31lite-db.c
@@ -31,12 +31,11 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/board-mx31lite.h>
-
+#include "board-mx31lite.h"
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
 
 /*
  * This file contains board-specific initialization routines for the
diff --git a/arch/arm/mach-imx/mx31moboard-devboard.c b/arch/arm/mach-imx/mx31moboard-devboard.c
index cc285e5..52d5b15 100644
--- a/arch/arm/mach-imx/mx31moboard-devboard.c
+++ b/arch/arm/mach-imx/mx31moboard-devboard.c
@@ -22,12 +22,11 @@
 
 #include <linux/usb/otg.h>
 
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/hardware.h>
-#include <mach/ulpi.h>
-
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.h"
 
 static unsigned int devboard_pins[] = {
 	/* UART1 */
diff --git a/arch/arm/mach-imx/mx31moboard-marxbot.c b/arch/arm/mach-imx/mx31moboard-marxbot.c
index 135c90e..a4f43e9 100644
--- a/arch/arm/mach-imx/mx31moboard-marxbot.c
+++ b/arch/arm/mach-imx/mx31moboard-marxbot.c
@@ -24,14 +24,13 @@
 
 #include <linux/usb/otg.h>
 
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx3.h>
-#include <mach/ulpi.h>
-
 #include <media/soc_camera.h>
 
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.h"
 
 static unsigned int marxbot_pins[] = {
 	/* SDHC2 */
diff --git a/arch/arm/mach-imx/mx31moboard-smartbot.c b/arch/arm/mach-imx/mx31moboard-smartbot.c
index fabb801..04ae45d 100644
--- a/arch/arm/mach-imx/mx31moboard-smartbot.c
+++ b/arch/arm/mach-imx/mx31moboard-smartbot.c
@@ -23,15 +23,14 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
 
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx3.h>
-#include <mach/board-mx31moboard.h>
-#include <mach/ulpi.h>
-
 #include <media/soc_camera.h>
 
+#include "board-mx31moboard.h"
+#include "common.h"
 #include "devices-imx31.h"
+#include "hardware.h"
+#include "iomux-mx3.h"
+#include "ulpi.h"
 
 static unsigned int smartbot_pins[] = {
 	/* UART1 */
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/mach-imx/mx35.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx35.h
rename to arch/arm/mach-imx/mx35.h
diff --git a/arch/arm/plat-mxc/include/mach/mx3x.h b/arch/arm/mach-imx/mx3x.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx3x.h
rename to arch/arm/mach-imx/mx3x.h
diff --git a/arch/arm/plat-mxc/include/mach/mx50.h b/arch/arm/mach-imx/mx50.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx50.h
rename to arch/arm/mach-imx/mx50.h
diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/mach-imx/mx51.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx51.h
rename to arch/arm/mach-imx/mx51.h
diff --git a/arch/arm/plat-mxc/include/mach/mx53.h b/arch/arm/mach-imx/mx53.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx53.h
rename to arch/arm/mach-imx/mx53.h
diff --git a/arch/arm/plat-mxc/include/mach/mx6q.h b/arch/arm/mach-imx/mx6q.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mx6q.h
rename to arch/arm/mach-imx/mx6q.h
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/mach-imx/mxc.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/mxc.h
rename to arch/arm/mach-imx/mxc.h
diff --git a/arch/arm/mach-imx/pcm970-baseboard.c b/arch/arm/mach-imx/pcm970-baseboard.c
index 9917e2f..51c6082 100644
--- a/arch/arm/mach-imx/pcm970-baseboard.c
+++ b/arch/arm/mach-imx/pcm970-baseboard.c
@@ -23,11 +23,10 @@
 
 #include <asm/mach/arch.h>
 
-#include <mach/common.h>
-#include <mach/iomux-mx27.h>
-#include <mach/hardware.h>
-
+#include "common.h"
 #include "devices-imx27.h"
+#include "hardware.h"
+#include "iomux-mx27.h"
 
 static const int pcm970_pins[] __initconst = {
 	/* SDHC */
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
index 2ac43e1..3777b80 100644
--- a/arch/arm/mach-imx/platsmp.c
+++ b/arch/arm/mach-imx/platsmp.c
@@ -16,8 +16,9 @@
 #include <asm/smp_scu.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach/map.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
+
+#include "common.h"
+#include "hardware.h"
 
 static void __iomem *scu_base;
 
diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c
index 6fcffa7..56d02d0 100644
--- a/arch/arm/mach-imx/pm-imx27.c
+++ b/arch/arm/mach-imx/pm-imx27.c
@@ -10,7 +10,8 @@
 #include <linux/kernel.h>
 #include <linux/suspend.h>
 #include <linux/io.h>
-#include <mach/hardware.h>
+
+#include "hardware.h"
 
 static int mx27_suspend_enter(suspend_state_t state)
 {
diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c
index 822103b..6a07006 100644
--- a/arch/arm/mach-imx/pm-imx3.c
+++ b/arch/arm/mach-imx/pm-imx3.c
@@ -9,10 +9,11 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 #include <linux/io.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/devices-common.h>
+
+#include "common.h"
 #include "crmregs-imx3.h"
+#include "devices/devices-common.h"
+#include "hardware.h"
 
 /*
  * Set cpu low power mode before WFI instruction. This function is called
diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c
index 19621ed1..2e063c2 100644
--- a/arch/arm/mach-imx/pm-imx5.c
+++ b/arch/arm/mach-imx/pm-imx5.c
@@ -16,10 +16,11 @@
 #include <asm/cacheflush.h>
 #include <asm/system_misc.h>
 #include <asm/tlbflush.h>
-#include <mach/common.h>
-#include <mach/cpuidle.h>
-#include <mach/hardware.h>
+
+#include "common.h"
+#include "cpuidle.h"
 #include "crm-regs-imx5.h"
+#include "hardware.h"
 
 /*
  * The WAIT_UNCLOCKED_POWER_OFF state only requires <= 500ns to exit.
diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c
index f7b0c2b..a17543d 100644
--- a/arch/arm/mach-imx/pm-imx6q.c
+++ b/arch/arm/mach-imx/pm-imx6q.c
@@ -18,8 +18,9 @@
 #include <asm/proc-fns.h>
 #include <asm/suspend.h>
 #include <asm/hardware/cache-l2x0.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
+
+#include "common.h"
+#include "hardware.h"
 
 extern unsigned long phys_l2x0_saved_regs;
 
diff --git a/arch/arm/plat-mxc/ssi-fiq-ksym.c b/arch/arm/mach-imx/ssi-fiq-ksym.c
similarity index 100%
rename from arch/arm/plat-mxc/ssi-fiq-ksym.c
rename to arch/arm/mach-imx/ssi-fiq-ksym.c
diff --git a/arch/arm/plat-mxc/ssi-fiq.S b/arch/arm/mach-imx/ssi-fiq.S
similarity index 100%
rename from arch/arm/plat-mxc/ssi-fiq.S
rename to arch/arm/mach-imx/ssi-fiq.S
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/mach-imx/system.c
similarity index 96%
rename from arch/arm/plat-mxc/system.c
rename to arch/arm/mach-imx/system.c
index 3da78cf..695e0d7 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/mach-imx/system.c
@@ -22,12 +22,13 @@
 #include <linux/err.h>
 #include <linux/delay.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
 #include <asm/system_misc.h>
 #include <asm/proc-fns.h>
 #include <asm/mach-types.h>
 
+#include "common.h"
+#include "hardware.h"
+
 static void __iomem *wdog_base;
 
 /*
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/mach-imx/time.c
similarity index 99%
rename from arch/arm/plat-mxc/time.c
rename to arch/arm/mach-imx/time.c
index a17abcf..f017302 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -27,10 +27,11 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 
-#include <mach/hardware.h>
 #include <asm/sched_clock.h>
 #include <asm/mach/time.h>
-#include <mach/common.h>
+
+#include "common.h"
+#include "hardware.h"
 
 /*
  * There are 2 versions of the timer hardware on Freescale MXC hardware.
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/mach-imx/tzic.c
similarity index 98%
rename from arch/arm/plat-mxc/tzic.c
rename to arch/arm/mach-imx/tzic.c
index 3ed1adb..9721161 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/mach-imx/tzic.c
@@ -21,10 +21,8 @@
 #include <asm/mach/irq.h>
 #include <asm/exception.h>
 
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/irqs.h>
-
+#include "common.h"
+#include "hardware.h"
 #include "irq-common.h"
 
 /*
diff --git a/arch/arm/plat-mxc/ulpi.c b/arch/arm/mach-imx/ulpi.c
similarity index 98%
rename from arch/arm/plat-mxc/ulpi.c
rename to arch/arm/mach-imx/ulpi.c
index d296342..0f05195 100644
--- a/arch/arm/plat-mxc/ulpi.c
+++ b/arch/arm/mach-imx/ulpi.c
@@ -24,7 +24,7 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
 
-#include <mach/ulpi.h>
+#include "ulpi.h"
 
 /* ULPIVIEW register bits */
 #define ULPIVW_WU		(1 << 31)	/* Wakeup */
diff --git a/arch/arm/plat-mxc/include/mach/ulpi.h b/arch/arm/mach-imx/ulpi.h
similarity index 100%
rename from arch/arm/plat-mxc/include/mach/ulpi.h
rename to arch/arm/mach-imx/ulpi.h
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
index f48c2e9..dd5d6f5 100644
--- a/arch/arm/mach-lpc32xx/clock.c
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -585,6 +585,13 @@
 	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN,
 	.get_rate	= local_return_parent_rate,
 };
+static struct clk clk_mpwm = {
+	.parent		= &clk_pclk,
+	.enable		= local_onoff_enable,
+	.enable_reg	= LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
+	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_MPWM_EN,
+	.get_rate	= local_return_parent_rate,
+};
 static struct clk clk_wdt = {
 	.parent		= &clk_pclk,
 	.enable		= local_onoff_enable,
@@ -1202,6 +1209,7 @@
 	CLKDEV_INIT("pl08xdmac", NULL, &clk_dma),
 	CLKDEV_INIT("4003c000.watchdog", NULL, &clk_wdt),
 	CLKDEV_INIT("4005c000.pwm", NULL, &clk_pwm),
+	CLKDEV_INIT("400e8000.mpwm", NULL, &clk_mpwm),
 	CLKDEV_INIT(NULL, "uart3_ck", &clk_uart3),
 	CLKDEV_INIT(NULL, "uart4_ck", &clk_uart4),
 	CLKDEV_INIT(NULL, "uart5_ck", &clk_uart5),
diff --git a/arch/arm/mach-lpc32xx/include/mach/platform.h b/arch/arm/mach-lpc32xx/include/mach/platform.h
index acc4aab..b5612a1 100644
--- a/arch/arm/mach-lpc32xx/include/mach/platform.h
+++ b/arch/arm/mach-lpc32xx/include/mach/platform.h
@@ -515,6 +515,7 @@
 /*
  * clkpwr_timers_pwms_clk_ctrl_1 register definitions
  */
+#define LPC32XX_CLKPWR_TMRPWMCLK_MPWM_EN	0x40
 #define LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN	0x20
 #define LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN	0x10
 #define LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN	0x08
diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c
index 3c63327..9ecb8f9 100644
--- a/arch/arm/mach-lpc32xx/irq.c
+++ b/arch/arm/mach-lpc32xx/irq.c
@@ -412,7 +412,6 @@
 void __init lpc32xx_init_irq(void)
 {
 	unsigned int i;
-	int irq_base;
 
 	/* Setup MIC */
 	__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE));
@@ -443,15 +442,6 @@
 	lpc32xx_set_default_mappings(SIC1_APR_DEFAULT, SIC1_ATR_DEFAULT, 32);
 	lpc32xx_set_default_mappings(SIC2_APR_DEFAULT, SIC2_ATR_DEFAULT, 64);
 
-	/* mask all interrupts except SUBIRQ */
-	__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE));
-	__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE));
-	__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE));
-
-	/* MIC SUBIRQx interrupts will route handling to the chain handlers */
-	irq_set_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler);
-	irq_set_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler);
-
 	/* Initially disable all wake events */
 	__raw_writel(0, LPC32XX_CLKPWR_P01_ER);
 	__raw_writel(0, LPC32XX_CLKPWR_INT_ER);
@@ -475,16 +465,13 @@
 
 	of_irq_init(mic_of_match);
 
-	irq_base = irq_alloc_descs(-1, 0, NR_IRQS, 0);
-	if (irq_base < 0) {
-		pr_warn("Cannot allocate irq_descs, assuming pre-allocated\n");
-		irq_base = 0;
-	}
-
 	lpc32xx_mic_domain = irq_domain_add_legacy(lpc32xx_mic_np, NR_IRQS,
-						   irq_base, 0,
-						   &irq_domain_simple_ops,
+						   0, 0, &irq_domain_simple_ops,
 						   NULL);
 	if (!lpc32xx_mic_domain)
 		panic("Unable to add MIC irq domain\n");
+
+	/* MIC SUBIRQx interrupts will route handling to the chain handlers */
+	irq_set_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler);
+	irq_set_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler);
 }
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 2a1a898..d669e22 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -11,7 +11,6 @@
 	select I2C_OMAP
 	select MENELAUS if ARCH_OMAP2
 	select NEON if ARCH_OMAP3 || ARCH_OMAP4 || SOC_OMAP5
-	select PINCTRL
 	select PM_RUNTIME
 	select REGULATOR
 	select SERIAL_OMAP
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 388c431..d41ab98 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -24,6 +24,7 @@
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/opp.h>
+#include <linux/cpu.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -444,27 +445,31 @@
 };
 #endif
 
-static void __init beagle_opp_init(void)
+static int __init beagle_opp_init(void)
 {
 	int r = 0;
 
-	/* Initialize the omap3 opp table */
-	if (omap3_opp_init()) {
+	if (!machine_is_omap3_beagle())
+		return 0;
+
+	/* Initialize the omap3 opp table if not already created. */
+	r = omap3_opp_init();
+	if (IS_ERR_VALUE(r) && (r != -EEXIST)) {
 		pr_err("%s: opp default init failed\n", __func__);
-		return;
+		return r;
 	}
 
 	/* Custom OPP enabled for all xM versions */
 	if (cpu_is_omap3630()) {
 		struct device *mpu_dev, *iva_dev;
 
-		mpu_dev = omap_device_get_by_hwmod_name("mpu");
+		mpu_dev = get_cpu_device(0);
 		iva_dev = omap_device_get_by_hwmod_name("iva");
 
 		if (IS_ERR(mpu_dev) || IS_ERR(iva_dev)) {
 			pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
 				__func__, mpu_dev, iva_dev);
-			return;
+			return -ENODEV;
 		}
 		/* Enable MPU 1GHz and lower opps */
 		r = opp_enable(mpu_dev, 800000000);
@@ -484,8 +489,9 @@
 			opp_disable(iva_dev, 660000000);
 		}
 	}
-	return;
+	return 0;
 }
+device_initcall(beagle_opp_init);
 
 static void __init omap3_beagle_init(void)
 {
@@ -522,8 +528,6 @@
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
 	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
-
-	beagle_opp_init();
 }
 
 MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c
index 114ab4b..1a45d6b 100644
--- a/arch/arm/mach-omap2/clock33xx_data.c
+++ b/arch/arm/mach-omap2/clock33xx_data.c
@@ -1073,6 +1073,8 @@
 	CLK(NULL,	"gfx_fck_div_ck",	&gfx_fck_div_ck,	CK_AM33XX),
 	CLK(NULL,	"sysclkout_pre_ck",	&sysclkout_pre_ck,	CK_AM33XX),
 	CLK(NULL,	"clkout2_ck",		&clkout2_ck,	CK_AM33XX),
+	CLK(NULL,	"timer_32k_ck",		&clkdiv32k_ick,	CK_AM33XX),
+	CLK(NULL,	"timer_sys_ck",		&sys_clkin_ck,	CK_AM33XX),
 };
 
 int __init am33xx_clk_init(void)
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index b56d06b..95192a06 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -359,7 +359,7 @@
 	.clkdm_offs	  = OMAP4430_CM2_CAM_CAM_CDOFFS,
 	.wkdep_srcs	  = iss_wkup_sleep_deps,
 	.sleepdep_srcs	  = iss_wkup_sleep_deps,
-	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+	.flags		  = CLKDM_CAN_SWSUP,
 };
 
 static struct clockdomain l3_dss_44xx_clkdm = {
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index cba60e05..c72b5a7 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -19,6 +19,7 @@
 #include <linux/of.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/platform_data/omap4-keypad.h>
+#include <linux/platform_data/omap_ocp2scp.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
@@ -613,6 +614,83 @@
 static inline void omap_init_vout(void) {}
 #endif
 
+#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE)
+static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev)
+{
+	int cnt	= 0;
+
+	while (ocp2scp_dev->drv_name != NULL) {
+		cnt++;
+		ocp2scp_dev++;
+	}
+
+	return cnt;
+}
+
+static void omap_init_ocp2scp(void)
+{
+	struct omap_hwmod	*oh;
+	struct platform_device	*pdev;
+	int			bus_id = -1, dev_cnt = 0, i;
+	struct omap_ocp2scp_dev	*ocp2scp_dev;
+	const char		*oh_name, *name;
+	struct omap_ocp2scp_platform_data *pdata;
+
+	if (!cpu_is_omap44xx())
+		return;
+
+	oh_name = "ocp2scp_usb_phy";
+	name	= "omap-ocp2scp";
+
+	oh = omap_hwmod_lookup(oh_name);
+	if (!oh) {
+		pr_err("%s: could not find omap_hwmod for %s\n", __func__,
+								oh_name);
+		return;
+	}
+
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		pr_err("%s: No memory for ocp2scp pdata\n", __func__);
+		return;
+	}
+
+	ocp2scp_dev = oh->dev_attr;
+	dev_cnt = count_ocp2scp_devices(ocp2scp_dev);
+
+	if (!dev_cnt) {
+		pr_err("%s: No devices connected to ocp2scp\n", __func__);
+		kfree(pdata);
+		return;
+	}
+
+	pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *)
+					* dev_cnt, GFP_KERNEL);
+	if (!pdata->devices) {
+		pr_err("%s: No memory for ocp2scp pdata devices\n", __func__);
+		kfree(pdata);
+		return;
+	}
+
+	for (i = 0; i < dev_cnt; i++, ocp2scp_dev++)
+		pdata->devices[i] = ocp2scp_dev;
+
+	pdata->dev_cnt	= dev_cnt;
+
+	pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL,
+								0, false);
+	if (IS_ERR(pdev)) {
+		pr_err("Could not build omap_device for %s %s\n",
+						name, oh_name);
+		kfree(pdata->devices);
+		kfree(pdata);
+		return;
+	}
+}
+#else
+static inline void omap_init_ocp2scp(void) { }
+#endif
+
 /*-------------------------------------------------------------------------*/
 
 static int __init omap2_init_devices(void)
@@ -640,6 +718,7 @@
 	omap_init_sham();
 	omap_init_aes();
 	omap_init_vout();
+	omap_init_ocp2scp();
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c
index 17f80e4..c47140b 100644
--- a/arch/arm/mach-omap2/mux34xx.c
+++ b/arch/arm/mach-omap2/mux34xx.c
@@ -614,16 +614,16 @@
 		"sys_off_mode", NULL, NULL, NULL,
 		"gpio_9", NULL, NULL, "safe_mode"),
 	_OMAP3_MUXENTRY(UART1_CTS, 150,
-		"uart1_cts", NULL, NULL, NULL,
+		"uart1_cts", "ssi1_rdy_tx", NULL, NULL,
 		"gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"),
 	_OMAP3_MUXENTRY(UART1_RTS, 149,
-		"uart1_rts", NULL, NULL, NULL,
+		"uart1_rts", "ssi1_flag_tx", NULL, NULL,
 		"gpio_149", NULL, NULL, "safe_mode"),
 	_OMAP3_MUXENTRY(UART1_RX, 151,
-		"uart1_rx", NULL, "mcbsp1_clkr", "mcspi4_clk",
+		"uart1_rx", "ss1_wake_tx", "mcbsp1_clkr", "mcspi4_clk",
 		"gpio_151", NULL, NULL, "safe_mode"),
 	_OMAP3_MUXENTRY(UART1_TX, 148,
-		"uart1_tx", NULL, NULL, NULL,
+		"uart1_tx", "ssi1_dat_tx", NULL, NULL,
 		"gpio_148", NULL, NULL, "safe_mode"),
 	_OMAP3_MUXENTRY(UART2_CTS, 144,
 		"uart2_cts", "mcbsp3_dx", "gpt9_pwm_evt", NULL,
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index b969ab1..87cc6d0 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -422,6 +422,38 @@
 }
 
 /**
+ * _wait_softreset_complete - wait for an OCP softreset to complete
+ * @oh: struct omap_hwmod * to wait on
+ *
+ * Wait until the IP block represented by @oh reports that its OCP
+ * softreset is complete.  This can be triggered by software (see
+ * _ocp_softreset()) or by hardware upon returning from off-mode (one
+ * example is HSMMC).  Waits for up to MAX_MODULE_SOFTRESET_WAIT
+ * microseconds.  Returns the number of microseconds waited.
+ */
+static int _wait_softreset_complete(struct omap_hwmod *oh)
+{
+	struct omap_hwmod_class_sysconfig *sysc;
+	u32 softrst_mask;
+	int c = 0;
+
+	sysc = oh->class->sysc;
+
+	if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
+		omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
+				   & SYSS_RESETDONE_MASK),
+				  MAX_MODULE_SOFTRESET_WAIT, c);
+	else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
+		softrst_mask = (0x1 << sysc->sysc_fields->srst_shift);
+		omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs)
+				    & softrst_mask),
+				  MAX_MODULE_SOFTRESET_WAIT, c);
+	}
+
+	return c;
+}
+
+/**
  * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v
  * @oh: struct omap_hwmod *
  *
@@ -1282,6 +1314,18 @@
 	if (!oh->class->sysc)
 		return;
 
+	/*
+	 * Wait until reset has completed, this is needed as the IP
+	 * block is reset automatically by hardware in some cases
+	 * (off-mode for example), and the drivers require the
+	 * IP to be ready when they access it
+	 */
+	if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+		_enable_optional_clocks(oh);
+	_wait_softreset_complete(oh);
+	if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+		_disable_optional_clocks(oh);
+
 	v = oh->_sysc_cache;
 	sf = oh->class->sysc->sysc_flags;
 
@@ -1804,7 +1848,7 @@
  */
 static int _ocp_softreset(struct omap_hwmod *oh)
 {
-	u32 v, softrst_mask;
+	u32 v;
 	int c = 0;
 	int ret = 0;
 
@@ -1834,19 +1878,7 @@
 	if (oh->class->sysc->srst_udelay)
 		udelay(oh->class->sysc->srst_udelay);
 
-	if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
-		omap_test_timeout((omap_hwmod_read(oh,
-						    oh->class->sysc->syss_offs)
-				   & SYSS_RESETDONE_MASK),
-				  MAX_MODULE_SOFTRESET_WAIT, c);
-	else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
-		softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
-		omap_test_timeout(!(omap_hwmod_read(oh,
-						     oh->class->sysc->sysc_offs)
-				   & softrst_mask),
-				  MAX_MODULE_SOFTRESET_WAIT, c);
-	}
-
+	c = _wait_softreset_complete(oh);
 	if (c == MAX_MODULE_SOFTRESET_WAIT)
 		pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
 			   oh->name, MAX_MODULE_SOFTRESET_WAIT);
@@ -2352,6 +2384,9 @@
 	if (oh->_state != _HWMOD_STATE_INITIALIZED)
 		return -EINVAL;
 
+	if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK)
+		return -EPERM;
+
 	if (oh->rst_lines_cnt == 0) {
 		r = _enable(oh);
 		if (r) {
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 652d028..0b1249e0 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 #include <linux/platform_data/gpio-omap.h>
 #include <linux/power/smartreflex.h>
+#include <linux/platform_data/omap_ocp2scp.h>
 
 #include <plat/omap_hwmod.h>
 #include <plat/i2c.h>
@@ -2125,6 +2126,14 @@
 	.name		= "mcpdm",
 	.class		= &omap44xx_mcpdm_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
+	/*
+	 * It's suspected that the McPDM requires an off-chip main
+	 * functional clock, controlled via I2C.  This IP block is
+	 * currently reset very early during boot, before I2C is
+	 * available, so it doesn't seem that we have any choice in
+	 * the kernel other than to avoid resetting it.
+	 */
+	.flags		= HWMOD_EXT_OPT_MAIN_CLK,
 	.mpu_irqs	= omap44xx_mcpdm_irqs,
 	.sdma_reqs	= omap44xx_mcpdm_sdma_reqs,
 	.main_clk	= "mcpdm_fck",
@@ -2681,6 +2690,32 @@
 	.sysc	= &omap44xx_ocp2scp_sysc,
 };
 
+/* ocp2scp dev_attr */
+static struct resource omap44xx_usb_phy_and_pll_addrs[] = {
+	{
+		.name		= "usb_phy",
+		.start		= 0x4a0ad080,
+		.end		= 0x4a0ae000,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		/* XXX: Remove this once control module driver is in place */
+		.name		= "ctrl_dev",
+		.start		= 0x4a002300,
+		.end		= 0x4a002303,
+		.flags		= IORESOURCE_MEM,
+	},
+	{ }
+};
+
+static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = {
+	{
+		.drv_name       = "omap-usb2",
+		.res		= omap44xx_usb_phy_and_pll_addrs,
+	},
+	{ }
+};
+
 /* ocp2scp_usb_phy */
 static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
 	.name		= "ocp2scp_usb_phy",
@@ -2694,6 +2729,7 @@
 			.modulemode   = MODULEMODE_HWCTRL,
 		},
 	},
+	.dev_attr	= ocp2scp_dev_attr,
 };
 
 /*
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 686137d..67d6613 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -91,6 +91,7 @@
 
 #define PM_RTA_ERRATUM_i608		(1 << 0)
 #define PM_SDRC_WAKEUP_ERRATUM_i583	(1 << 1)
+#define PM_PER_MEMORIES_ERRATUM_i582	(1 << 2)
 
 #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
 extern u16 pm34xx_errata;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index ba670db..3a904de 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -652,14 +652,17 @@
 		/* Enable the l2 cache toggling in sleep logic */
 		enable_omap3630_toggle_l2_on_restore();
 		if (omap_rev() < OMAP3630_REV_ES1_2)
-			pm34xx_errata |= PM_SDRC_WAKEUP_ERRATUM_i583;
+			pm34xx_errata |= (PM_SDRC_WAKEUP_ERRATUM_i583 |
+					  PM_PER_MEMORIES_ERRATUM_i582);
+	} else if (cpu_is_omap34xx()) {
+		pm34xx_errata |= PM_PER_MEMORIES_ERRATUM_i582;
 	}
 }
 
 int __init omap3_pm_init(void)
 {
 	struct power_state *pwrst, *tmp;
-	struct clockdomain *neon_clkdm, *mpu_clkdm;
+	struct clockdomain *neon_clkdm, *mpu_clkdm, *per_clkdm, *wkup_clkdm;
 	int ret;
 
 	if (!omap3_has_io_chain_ctrl())
@@ -711,6 +714,8 @@
 
 	neon_clkdm = clkdm_lookup("neon_clkdm");
 	mpu_clkdm = clkdm_lookup("mpu_clkdm");
+	per_clkdm = clkdm_lookup("per_clkdm");
+	wkup_clkdm = clkdm_lookup("wkup_clkdm");
 
 #ifdef CONFIG_SUSPEND
 	omap_pm_suspend = omap3_pm_suspend;
@@ -727,6 +732,27 @@
 	if (IS_PM34XX_ERRATUM(PM_RTA_ERRATUM_i608))
 		omap3630_ctrl_disable_rta();
 
+	/*
+	 * The UART3/4 FIFO and the sidetone memory in McBSP2/3 are
+	 * not correctly reset when the PER powerdomain comes back
+	 * from OFF or OSWR when the CORE powerdomain is kept active.
+	 * See OMAP36xx Erratum i582 "PER Domain reset issue after
+	 * Domain-OFF/OSWR Wakeup".  This wakeup dependency is not a
+	 * complete workaround.  The kernel must also prevent the PER
+	 * powerdomain from going to OSWR/OFF while the CORE
+	 * powerdomain is not going to OSWR/OFF.  And if PER last
+	 * power state was off while CORE last power state was ON, the
+	 * UART3/4 and McBSP2/3 SIDETONE devices need to run a
+	 * self-test using their loopback tests; if that fails, those
+	 * devices are unusable until the PER/CORE can complete a transition
+	 * from ON to OSWR/OFF and then back to ON.
+	 *
+	 * XXX Technically this workaround is only needed if off-mode
+	 * or OSWR is enabled.
+	 */
+	if (IS_PM34XX_ERRATUM(PM_PER_MEMORIES_ERRATUM_i582))
+		clkdm_add_wkdep(per_clkdm, wkup_clkdm);
+
 	clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
 	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
 		omap3_secure_ram_storage =
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 0405c81..a507cd6 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -329,6 +329,11 @@
 
 	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
 
+	if (console_uart_id == bdata->id) {
+		omap_device_enable(pdev);
+		pm_runtime_set_active(&pdev->dev);
+	}
+
 	oh->dev_attr = uart;
 
 	if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 635e109..44c4205 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -366,7 +366,7 @@
 };
 
 static struct regulator_consumer_supply omap4_vdd1_supply[] = {
-	REGULATOR_SUPPLY("vcc", "mpu.0"),
+	REGULATOR_SUPPLY("vcc", "cpu0"),
 };
 
 static struct regulator_consumer_supply omap4_vdd2_supply[] = {
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 880249b..75878c3 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -264,7 +264,7 @@
 
 	if (initialized) {
 		if (voltdm->pmic->i2c_high_speed != i2c_high_speed)
-			pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).",
+			pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n",
 				__func__, voltdm->name, i2c_high_speed);
 		return;
 	}
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 5ecbd17..e2c6391 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -28,6 +28,7 @@
 #include <linux/mfd/asic3.h>
 #include <linux/mtd/physmap.h>
 #include <linux/pda_power.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/gpio-regulator.h>
@@ -556,7 +557,7 @@
  */
 
 static struct platform_pwm_backlight_data backlight_data = {
-	.pwm_id         = 1,
+	.pwm_id         = -1,	/* Superseded by pwm_lookup */
 	.max_brightness = 200,
 	.dft_brightness = 100,
 	.pwm_period_ns  = 30923,
@@ -571,6 +572,10 @@
 	},
 };
 
+static struct pwm_lookup hx4700_pwm_lookup[] = {
+	PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL),
+};
+
 /*
  * USB "Transceiver"
  */
@@ -872,6 +877,7 @@
 	pxa_set_stuart_info(NULL);
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
+	pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup));
 
 	pxa_set_ficp_info(&ficp_info);
 	pxa27x_set_i2c_power_info(NULL);
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 438f02f..842596d 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -86,10 +86,7 @@
 	gpio_set_value(SPITZ_GPIO_LED_GREEN, on);
 }
 
-static unsigned long gpio18_config[] = {
-	GPIO18_RDY,
-	GPIO18_GPIO,
-};
+static unsigned long gpio18_config = GPIO18_GPIO;
 
 static void spitz_presuspend(void)
 {
@@ -112,7 +109,7 @@
 	PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
 	PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
 
-	pxa2xx_mfp_config(&gpio18_config[0], 1);
+	pxa2xx_mfp_config(&gpio18_config, 1);
 	gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown");
 	gpio_free(18);
 
@@ -131,7 +128,6 @@
 
 static void spitz_postsuspend(void)
 {
-	pxa2xx_mfp_config(&gpio18_config[1], 1);
 }
 
 static int spitz_should_wakeup(unsigned int resume_on_alarm)
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 2b6cb5f..01f70c9 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -405,6 +405,7 @@
 	select NEW_LEDS
 	select S3C_DEV_NAND
 	select S3C_DEV_USB_HOST
+	select S3C_SETUP_CAMIF
 	help
 	  Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
 	  available via various sources. It can come with a 3.5" or 7" touch LCD.
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2440.c b/arch/arm/mach-s3c24xx/clock-s3c2440.c
index 4407b17..04b87ec 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2440.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2440.c
@@ -161,6 +161,7 @@
 	CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
 	CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
 	CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
+	CLKDEV_INIT("s3c2440-camif", "camera", &s3c2440_clk_cam_upll),
 };
 
 static int __init_refok s3c2440_clk_add(struct device *dev, struct subsys_interface *sif)
diff --git a/arch/arm/mach-s3c24xx/s3c2416.c b/arch/arm/mach-s3c24xx/s3c2416.c
index ed5a95ec..77ee0b7 100644
--- a/arch/arm/mach-s3c24xx/s3c2416.c
+++ b/arch/arm/mach-s3c24xx/s3c2416.c
@@ -61,6 +61,7 @@
 #include <plat/nand-core.h>
 #include <plat/adc-core.h>
 #include <plat/rtc-core.h>
+#include <plat/spi-core.h>
 
 static struct map_desc s3c2416_iodesc[] __initdata = {
 	IODESC_ENT(WATCHDOG),
@@ -132,6 +133,7 @@
 	/* initialize device information early */
 	s3c2416_default_sdhci0();
 	s3c2416_default_sdhci1();
+	s3c64xx_spi_setname("s3c2443-spi");
 
 	iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
 }
diff --git a/arch/arm/mach-s3c24xx/s3c2443.c b/arch/arm/mach-s3c24xx/s3c2443.c
index ab648ad..165b6a6 100644
--- a/arch/arm/mach-s3c24xx/s3c2443.c
+++ b/arch/arm/mach-s3c24xx/s3c2443.c
@@ -43,6 +43,7 @@
 #include <plat/nand-core.h>
 #include <plat/adc-core.h>
 #include <plat/rtc-core.h>
+#include <plat/spi-core.h>
 
 static struct map_desc s3c2443_iodesc[] __initdata = {
 	IODESC_ENT(WATCHDOG),
@@ -100,6 +101,9 @@
 	s3c24xx_gpiocfg_default.set_pull = s3c2443_gpio_setpull;
 	s3c24xx_gpiocfg_default.get_pull = s3c2443_gpio_getpull;
 
+	/* initialize device information early */
+	s3c64xx_spi_setname("s3c2443-spi");
+
 	iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
 }
 
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
index 6e6a0a9..111e404 100644
--- a/arch/arm/mach-s5p64x0/common.c
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -44,6 +44,7 @@
 #include <plat/sdhci.h>
 #include <plat/adc-core.h>
 #include <plat/fb-core.h>
+#include <plat/spi-core.h>
 #include <plat/gpio-cfg.h>
 #include <plat/regs-irqtype.h>
 #include <plat/regs-serial.h>
@@ -179,6 +180,7 @@
 	/* initialize any device information early */
 	s3c_adc_setname("s3c64xx-adc");
 	s3c_fb_setname("s5p64x0-fb");
+	s3c64xx_spi_setname("s5p64x0-spi");
 
 	s5p64x0_default_sdhci0();
 	s5p64x0_default_sdhci1();
@@ -193,6 +195,7 @@
 	/* initialize any device information early */
 	s3c_adc_setname("s3c64xx-adc");
 	s3c_fb_setname("s5p64x0-fb");
+	s3c64xx_spi_setname("s5p64x0-spi");
 
 	s5p64x0_default_sdhci0();
 	s5p64x0_default_sdhci1();
diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c
index 6219086..cc6e561 100644
--- a/arch/arm/mach-s5pc100/common.c
+++ b/arch/arm/mach-s5pc100/common.c
@@ -45,6 +45,7 @@
 #include <plat/fb-core.h>
 #include <plat/iic-core.h>
 #include <plat/onenand-core.h>
+#include <plat/spi-core.h>
 #include <plat/regs-serial.h>
 #include <plat/watchdog-reset.h>
 
@@ -165,6 +166,8 @@
 	s3c_onenand_setname("s5pc100-onenand");
 	s3c_fb_setname("s5pc100-fb");
 	s3c_cfcon_setname("s5pc100-pata");
+
+	s3c64xx_spi_setname("s5pc100-spi");
 }
 
 void __init s5pc100_init_clocks(int xtal)
diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
index 4c9e902..a0c50ef 100644
--- a/arch/arm/mach-s5pv210/common.c
+++ b/arch/arm/mach-s5pv210/common.c
@@ -43,6 +43,7 @@
 #include <plat/iic-core.h>
 #include <plat/keypad-core.h>
 #include <plat/tv-core.h>
+#include <plat/spi-core.h>
 #include <plat/regs-serial.h>
 
 #include "common.h"
@@ -196,6 +197,8 @@
 
 	/* setup TV devices */
 	s5p_hdmi_setname("s5pv210-hdmi");
+
+	s3c64xx_spi_setname("s5pv210-spi");
 }
 
 void __init s5pv210_init_clocks(int xtal)
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 8ae100c..546e40a 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -2,18 +2,6 @@
 
 comment "SH-Mobile System Type"
 
-config ARCH_SH7367
-	bool "SH-Mobile G3 (SH7367)"
-	select ARCH_WANT_OPTIONAL_GPIOLIB
-	select CPU_V6
-	select SH_CLK_CPG
-
-config ARCH_SH7377
-	bool "SH-Mobile G4 (SH7377)"
-	select ARCH_WANT_OPTIONAL_GPIOLIB
-	select CPU_V7
-	select SH_CLK_CPG
-
 config ARCH_SH7372
 	bool "SH-Mobile AP4 (SH7372)"
 	select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index fe2c97c..f4fd247 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -6,8 +6,6 @@
 obj-y				:= timer.o console.o clock.o
 
 # CPU objects
-obj-$(CONFIG_ARCH_SH7367)	+= setup-sh7367.o clock-sh7367.o intc-sh7367.o
-obj-$(CONFIG_ARCH_SH7377)	+= setup-sh7377.o clock-sh7377.o intc-sh7377.o
 obj-$(CONFIG_ARCH_SH7372)	+= setup-sh7372.o clock-sh7372.o intc-sh7372.o
 obj-$(CONFIG_ARCH_SH73A0)	+= setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o
 obj-$(CONFIG_ARCH_R8A7740)	+= setup-r8a7740.o clock-r8a7740.o intc-r8a7740.o
@@ -23,16 +21,12 @@
 
 # Pinmux setup
 pfc-y				:=
-pfc-$(CONFIG_ARCH_SH7367)	+= pfc-sh7367.o
-pfc-$(CONFIG_ARCH_SH7377)	+= pfc-sh7377.o
 pfc-$(CONFIG_ARCH_SH7372)	+= pfc-sh7372.o
 pfc-$(CONFIG_ARCH_SH73A0)	+= pfc-sh73a0.o
 pfc-$(CONFIG_ARCH_R8A7740)	+= pfc-r8a7740.o
 pfc-$(CONFIG_ARCH_R8A7779)	+= pfc-r8a7779.o
 
 # IRQ objects
-obj-$(CONFIG_ARCH_SH7367)	+= entry-intc.o
-obj-$(CONFIG_ARCH_SH7377)	+= entry-intc.o
 obj-$(CONFIG_ARCH_SH7372)	+= entry-intc.o
 obj-$(CONFIG_ARCH_R8A7740)	+= entry-intc.o
 
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 790dc68..cefdd03 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -728,7 +728,7 @@
 static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
 {
 	struct clk *fsib_clk;
-	struct clk *fdiv_clk = &sh7372_fsidivb_clk;
+	struct clk *fdiv_clk = clk_get(NULL, "fsidivb");
 	long fsib_rate = 0;
 	long fdiv_rate = 0;
 	int ackmd_bpfmd;
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 0c27c81..c826d77 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -882,7 +882,7 @@
 static int fsi_b_set_rate(struct device *dev, int rate, int enable)
 {
 	struct clk *fsib_clk;
-	struct clk *fdiv_clk = &sh7372_fsidivb_clk;
+	struct clk *fdiv_clk = clk_get(NULL, "fsidivb");
 	long fsib_rate = 0;
 	long fdiv_rate = 0;
 	int ackmd_bpfmd;
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index 6729e00..eac49d5 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -65,6 +65,9 @@
 #define SMSTPCR3	IOMEM(0xe615013c)
 #define SMSTPCR4	IOMEM(0xe6150140)
 
+#define FSIDIVA		IOMEM(0xFE1F8000)
+#define FSIDIVB		IOMEM(0xFE1F8008)
+
 /* Fixed 32 KHz root clock from EXTALR pin */
 static struct clk extalr_clk = {
 	.rate	= 32768,
@@ -188,6 +191,22 @@
 };
 
 /* USB clock */
+/*
+ * USBCKCR is controlling usb24 clock
+ * bit[7] : parent clock
+ * bit[6] : clock divide rate
+ * And this bit[7] is used as a "usb24s" from other devices.
+ * (Video clock / Sub clock / SPU clock)
+ * You can controll this clock as a below.
+ *
+ * struct clk *usb24	= clk_get(dev,  "usb24");
+ * struct clk *usb24s	= clk_get(NULL, "usb24s");
+ * struct clk *system	= clk_get(NULL, "system_clk");
+ * int rate = clk_get_rate(system);
+ *
+ * clk_set_parent(usb24s, system);  // for bit[7]
+ * clk_set_rate(usb24, rate / 2);   // for bit[6]
+ */
 static struct clk *usb24s_parents[] = {
 	[0] = &system_clk,
 	[1] = &extal2_clk
@@ -427,6 +446,14 @@
 	&hdmi2_clk,
 };
 
+/* FSI DIV */
+enum { FSIDIV_A, FSIDIV_B, FSIDIV_REPARENT_NR };
+
+static struct clk fsidivs[] = {
+	[FSIDIV_A] = SH_CLK_FSIDIV(FSIDIVA, &div6_reparent_clks[DIV6_FSIA]),
+	[FSIDIV_B] = SH_CLK_FSIDIV(FSIDIVB, &div6_reparent_clks[DIV6_FSIB]),
+};
+
 /* MSTP */
 enum {
 	DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
@@ -596,6 +623,10 @@
 
 	CLKDEV_ICK_ID("icka", "sh_fsi2",	&div6_reparent_clks[DIV6_FSIA]),
 	CLKDEV_ICK_ID("ickb", "sh_fsi2",	&div6_reparent_clks[DIV6_FSIB]),
+	CLKDEV_ICK_ID("diva", "sh_fsi2",	&fsidivs[FSIDIV_A]),
+	CLKDEV_ICK_ID("divb", "sh_fsi2",	&fsidivs[FSIDIV_B]),
+	CLKDEV_ICK_ID("xcka", "sh_fsi2",	&fsiack_clk),
+	CLKDEV_ICK_ID("xckb", "sh_fsi2",	&fsibck_clk),
 };
 
 void __init r8a7740_clock_init(u8 md_ck)
@@ -641,6 +672,9 @@
 	for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
 		ret = clk_register(late_main_clks[k]);
 
+	if (!ret)
+		ret = sh_clk_fsidiv_register(fsidivs, FSIDIV_REPARENT_NR);
+
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	if (!ret)
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
index 37b2a31..c019609 100644
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -87,8 +87,11 @@
 };
 
 enum { MSTP323, MSTP322, MSTP321, MSTP320,
-	MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
+	MSTP101, MSTP100,
+	MSTP030,
+	MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
 	MSTP016, MSTP015, MSTP014,
+	MSTP007,
 	MSTP_NR };
 
 static struct clk mstp_clks[MSTP_NR] = {
@@ -96,6 +99,12 @@
 	[MSTP322] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 22, 0), /* SDHI1 */
 	[MSTP321] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 21, 0), /* SDHI2 */
 	[MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 20, 0), /* SDHI3 */
+	[MSTP101] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1,  1, 0), /* USB2 */
+	[MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1,  0, 0), /* USB0/1 */
+	[MSTP030] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 30, 0), /* I2C0 */
+	[MSTP029] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 29, 0), /* I2C1 */
+	[MSTP028] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 28, 0), /* I2C2 */
+	[MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0), /* I2C3 */
 	[MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0), /* SCIF0 */
 	[MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0), /* SCIF1 */
 	[MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0), /* SCIF2 */
@@ -105,6 +114,7 @@
 	[MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0), /* TMU0 */
 	[MSTP015] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0), /* TMU1 */
 	[MSTP014] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 14, 0), /* TMU2 */
+	[MSTP007] = SH_CLK_MSTP32(&div4_clks[DIV4_S], MSTPCR0,  7, 0), /* HSPI */
 };
 
 static unsigned long mul4_recalc(struct clk *clk)
@@ -146,14 +156,25 @@
 	CLKDEV_CON_ID("peripheral_clk",	&div4_clks[DIV4_P]),
 
 	/* MSTP32 clocks */
+	CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
+	CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
+	CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
+	CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
 	CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
 	CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */
+	CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
+	CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
+	CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
+	CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
 	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
 	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
 	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
 	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
+	CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
+	CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
+	CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
 	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
 	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
 	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
deleted file mode 100644
index ef0a95e..0000000
--- a/arch/arm/mach-shmobile/clock-sh7367.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * SH7367 clock framework support
- *
- * Copyright (C) 2010  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/sh_clk.h>
-#include <linux/clkdev.h>
-#include <mach/common.h>
-
-/* SH7367 registers */
-#define RTFRQCR    IOMEM(0xe6150000)
-#define SYFRQCR    IOMEM(0xe6150004)
-#define CMFRQCR    IOMEM(0xe61500E0)
-#define VCLKCR1    IOMEM(0xe6150008)
-#define VCLKCR2    IOMEM(0xe615000C)
-#define VCLKCR3    IOMEM(0xe615001C)
-#define SCLKACR    IOMEM(0xe6150010)
-#define SCLKBCR    IOMEM(0xe6150014)
-#define SUBUSBCKCR IOMEM(0xe6158080)
-#define SPUCKCR    IOMEM(0xe6150084)
-#define MSUCKCR    IOMEM(0xe6150088)
-#define MVI3CKCR   IOMEM(0xe6150090)
-#define VOUCKCR    IOMEM(0xe6150094)
-#define MFCK1CR    IOMEM(0xe6150098)
-#define MFCK2CR    IOMEM(0xe615009C)
-#define PLLC1CR    IOMEM(0xe6150028)
-#define PLLC2CR    IOMEM(0xe615002C)
-#define RTMSTPCR0  IOMEM(0xe6158030)
-#define RTMSTPCR2  IOMEM(0xe6158038)
-#define SYMSTPCR0  IOMEM(0xe6158040)
-#define SYMSTPCR2  IOMEM(0xe6158048)
-#define CMMSTPCR0  IOMEM(0xe615804c)
-
-/* Fixed 32 KHz root clock from EXTALR pin */
-static struct clk r_clk = {
-	.rate           = 32768,
-};
-
-/*
- * 26MHz default rate for the EXTALB1 root input clock.
- * If needed, reset this with clk_set_rate() from the platform code.
- */
-struct clk sh7367_extalb1_clk = {
-	.rate		= 26666666,
-};
-
-/*
- * 48MHz default rate for the EXTAL2 root input clock.
- * If needed, reset this with clk_set_rate() from the platform code.
- */
-struct clk sh7367_extal2_clk = {
-	.rate		= 48000000,
-};
-
-/* A fixed divide-by-2 block */
-static unsigned long div2_recalc(struct clk *clk)
-{
-	return clk->parent->rate / 2;
-}
-
-static struct sh_clk_ops div2_clk_ops = {
-	.recalc		= div2_recalc,
-};
-
-/* Divide extalb1 by two */
-static struct clk extalb1_div2_clk = {
-	.ops		= &div2_clk_ops,
-	.parent		= &sh7367_extalb1_clk,
-};
-
-/* Divide extal2 by two */
-static struct clk extal2_div2_clk = {
-	.ops		= &div2_clk_ops,
-	.parent		= &sh7367_extal2_clk,
-};
-
-/* PLLC1 */
-static unsigned long pllc1_recalc(struct clk *clk)
-{
-	unsigned long mult = 1;
-
-	if (__raw_readl(PLLC1CR) & (1 << 14))
-		mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2;
-
-	return clk->parent->rate * mult;
-}
-
-static struct sh_clk_ops pllc1_clk_ops = {
-	.recalc		= pllc1_recalc,
-};
-
-static struct clk pllc1_clk = {
-	.ops		= &pllc1_clk_ops,
-	.flags		= CLK_ENABLE_ON_INIT,
-	.parent		= &extalb1_div2_clk,
-};
-
-/* Divide PLLC1 by two */
-static struct clk pllc1_div2_clk = {
-	.ops		= &div2_clk_ops,
-	.parent		= &pllc1_clk,
-};
-
-/* PLLC2 */
-static unsigned long pllc2_recalc(struct clk *clk)
-{
-	unsigned long mult = 1;
-
-	if (__raw_readl(PLLC2CR) & (1 << 31))
-		mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
-
-	return clk->parent->rate * mult;
-}
-
-static struct sh_clk_ops pllc2_clk_ops = {
-	.recalc		= pllc2_recalc,
-};
-
-static struct clk pllc2_clk = {
-	.ops		= &pllc2_clk_ops,
-	.flags		= CLK_ENABLE_ON_INIT,
-	.parent		= &extalb1_div2_clk,
-};
-
-static struct clk *main_clks[] = {
-	&r_clk,
-	&sh7367_extalb1_clk,
-	&sh7367_extal2_clk,
-	&extalb1_div2_clk,
-	&extal2_div2_clk,
-	&pllc1_clk,
-	&pllc1_div2_clk,
-	&pllc2_clk,
-};
-
-static void div4_kick(struct clk *clk)
-{
-	unsigned long value;
-
-	/* set KICK bit in SYFRQCR to update hardware setting */
-	value = __raw_readl(SYFRQCR);
-	value |= (1 << 31);
-	__raw_writel(value, SYFRQCR);
-}
-
-static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
-			  24, 32, 36, 48, 0, 72, 0, 0 };
-
-static struct clk_div_mult_table div4_div_mult_table = {
-	.divisors = divisors,
-	.nr_divisors = ARRAY_SIZE(divisors),
-};
-
-static struct clk_div4_table div4_table = {
-	.div_mult_table = &div4_div_mult_table,
-	.kick = div4_kick,
-};
-
-enum { DIV4_I, DIV4_G, DIV4_S, DIV4_B,
-       DIV4_ZX, DIV4_ZT, DIV4_Z, DIV4_ZD, DIV4_HP,
-       DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR };
-
-#define DIV4(_reg, _bit, _mask, _flags) \
-  SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
-
-static struct clk div4_clks[DIV4_NR] = {
-	[DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT),
-	[DIV4_G] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT),
-	[DIV4_S] = DIV4(RTFRQCR, 12, 0x6fff, CLK_ENABLE_ON_INIT),
-	[DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT),
-	[DIV4_ZX] = DIV4(SYFRQCR, 20, 0x6fff, 0),
-	[DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0),
-	[DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0),
-	[DIV4_ZD] = DIV4(SYFRQCR, 8, 0x6fff, 0),
-	[DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0),
-	[DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0),
-	[DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0),
-	[DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0),
-	[DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0),
-};
-
-enum { DIV6_SUB, DIV6_SIUA, DIV6_SIUB, DIV6_MSU, DIV6_SPU,
-       DIV6_MVI3, DIV6_MF1, DIV6_MF2,
-       DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VOU,
-       DIV6_NR };
-
-static struct clk div6_clks[DIV6_NR] = {
-	[DIV6_SUB] = SH_CLK_DIV6(&sh7367_extal2_clk, SUBUSBCKCR, 0),
-	[DIV6_SIUA] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKACR, 0),
-	[DIV6_SIUB] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKBCR, 0),
-	[DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0),
-	[DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
-	[DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0),
-	[DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0),
-	[DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0),
-	[DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
-	[DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
-	[DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
-	[DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
-};
-
-enum { RTMSTP001,
-       RTMSTP231, RTMSTP230, RTMSTP229, RTMSTP228, RTMSTP226,
-       RTMSTP216, RTMSTP206, RTMSTP205, RTMSTP201,
-       SYMSTP023, SYMSTP007, SYMSTP006, SYMSTP004,
-       SYMSTP003, SYMSTP002, SYMSTP001, SYMSTP000,
-       SYMSTP231, SYMSTP229, SYMSTP225, SYMSTP223, SYMSTP222,
-       SYMSTP215, SYMSTP214, SYMSTP213, SYMSTP211,
-       CMMSTP003,
-       MSTP_NR };
-
-#define MSTP(_parent, _reg, _bit, _flags) \
-  SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
-
-static struct clk mstp_clks[MSTP_NR] = {
-	[RTMSTP001] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR0, 1, 0), /* IIC2 */
-	[RTMSTP231] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 31, 0), /* VEU3 */
-	[RTMSTP230] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 30, 0), /* VEU2 */
-	[RTMSTP229] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 29, 0), /* VEU1 */
-	[RTMSTP228] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 28, 0), /* VEU0 */
-	[RTMSTP226] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 26, 0), /* VEU2H */
-	[RTMSTP216] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR2, 16, 0), /* IIC0 */
-	[RTMSTP206] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 6, 0), /* JPU */
-	[RTMSTP205] = MSTP(&div6_clks[DIV6_VOU], RTMSTPCR2, 5, 0), /* VOU */
-	[RTMSTP201] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 1, 0), /* VPU */
-	[SYMSTP023] = MSTP(&div6_clks[DIV6_SPU], SYMSTPCR0, 23, 0), /* SPU1 */
-	[SYMSTP007] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 7, 0), /* SCIFA5 */
-	[SYMSTP006] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 6, 0), /* SCIFB */
-	[SYMSTP004] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 4, 0), /* SCIFA0 */
-	[SYMSTP003] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 3, 0), /* SCIFA1 */
-	[SYMSTP002] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 2, 0), /* SCIFA2 */
-	[SYMSTP001] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 1, 0), /* SCIFA3 */
-	[SYMSTP000] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 0, 0), /* SCIFA4 */
-	[SYMSTP231] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 31, 0), /* SIU */
-	[SYMSTP229] = MSTP(&r_clk, SYMSTPCR2, 29, 0), /* CMT10 */
-	[SYMSTP225] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 25, 0), /* IRDA */
-	[SYMSTP223] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 23, 0), /* IIC1 */
-	[SYMSTP222] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 22, 0), /* USBHS */
-	[SYMSTP215] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 15, 0), /* FLCTL */
-	[SYMSTP214] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 14, 0), /* SDHI0 */
-	[SYMSTP213] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 13, 0), /* SDHI1 */
-	[SYMSTP211] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 11, 0), /* SDHI2 */
-	[CMMSTP003] = MSTP(&r_clk, CMMSTPCR0, 3, 0), /* KEYSC */
-};
-
-static struct clk_lookup lookups[] = {
-	/* main clocks */
-	CLKDEV_CON_ID("r_clk", &r_clk),
-	CLKDEV_CON_ID("extalb1", &sh7367_extalb1_clk),
-	CLKDEV_CON_ID("extal2", &sh7367_extal2_clk),
-	CLKDEV_CON_ID("extalb1_div2_clk", &extalb1_div2_clk),
-	CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
-	CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
-	CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
-	CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
-
-	/* DIV4 clocks */
-	CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
-	CLKDEV_CON_ID("g_clk", &div4_clks[DIV4_G]),
-	CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
-	CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
-	CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
-	CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]),
-	CLKDEV_CON_ID("zd_clk", &div4_clks[DIV4_ZD]),
-	CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
-	CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]),
-	CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
-	CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
-	CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
-
-	/* DIV6 clocks */
-	CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
-	CLKDEV_CON_ID("siua_clk", &div6_clks[DIV6_SIUA]),
-	CLKDEV_CON_ID("siub_clk", &div6_clks[DIV6_SIUB]),
-	CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]),
-	CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
-	CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]),
-	CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]),
-	CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]),
-	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
-	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
-	CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
-	CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
-
-	/* MSTP32 clocks */
-	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[RTMSTP001]), /* IIC2 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[RTMSTP231]), /* VEU3 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[RTMSTP230]), /* VEU2 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[RTMSTP229]), /* VEU1 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[RTMSTP228]), /* VEU0 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[RTMSTP226]), /* VEU2H */
-	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[RTMSTP216]), /* IIC0 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[RTMSTP206]), /* JPU */
-	CLKDEV_DEV_ID("sh-vou", &mstp_clks[RTMSTP205]), /* VOU */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[RTMSTP201]), /* VPU */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[SYMSTP023]), /* SPU1 */
-	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[SYMSTP007]), /* SCIFA5 */
-	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[SYMSTP006]), /* SCIFB */
-	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[SYMSTP004]), /* SCIFA0 */
-	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[SYMSTP003]), /* SCIFA1 */
-	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[SYMSTP002]), /* SCIFA2 */
-	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */
-	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */
-	CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */
-	CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[SYMSTP229]), /* CMT10 */
-	CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */
-	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */
-	CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */
-	CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[SYMSTP222]), /* USBHS */
-	CLKDEV_DEV_ID("sh_flctl", &mstp_clks[SYMSTP215]), /* FLCTL */
-	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[SYMSTP214]), /* SDHI0 */
-	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[SYMSTP213]), /* SDHI1 */
-	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[SYMSTP211]), /* SDHI2 */
-	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[CMMSTP003]), /* KEYSC */
-};
-
-void __init sh7367_clock_init(void)
-{
-	int k, ret = 0;
-
-	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
-		ret = clk_register(main_clks[k]);
-
-	if (!ret)
-		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
-
-	if (!ret)
-		ret = sh_clk_div6_register(div6_clks, DIV6_NR);
-
-	if (!ret)
-		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
-
-	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
-	if (!ret)
-		shmobile_clk_init();
-	else
-		panic("failed to setup sh7367 clocks\n");
-}
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 430a90f..4d57e34 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -420,87 +420,11 @@
 };
 
 /* FSI DIV */
-static unsigned long fsidiv_recalc(struct clk *clk)
-{
-	unsigned long value;
+enum { FSIDIV_A, FSIDIV_B, FSIDIV_REPARENT_NR };
 
-	value = __raw_readl(clk->mapping->base);
-
-	value >>= 16;
-	if (value < 2)
-		return 0;
-
-	return clk->parent->rate / value;
-}
-
-static long fsidiv_round_rate(struct clk *clk, unsigned long rate)
-{
-	return clk_rate_div_range_round(clk, 2, 0xffff, rate);
-}
-
-static void fsidiv_disable(struct clk *clk)
-{
-	__raw_writel(0, clk->mapping->base);
-}
-
-static int fsidiv_enable(struct clk *clk)
-{
-	unsigned long value;
-
-	value  = __raw_readl(clk->mapping->base) >> 16;
-	if (value < 2)
-		return -EIO;
-
-	__raw_writel((value << 16) | 0x3, clk->mapping->base);
-
-	return 0;
-}
-
-static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
-{
-	int idx;
-
-	idx = (clk->parent->rate / rate) & 0xffff;
-	if (idx < 2)
-		return -EINVAL;
-
-	__raw_writel(idx << 16, clk->mapping->base);
-	return 0;
-}
-
-static struct sh_clk_ops fsidiv_clk_ops = {
-	.recalc		= fsidiv_recalc,
-	.round_rate	= fsidiv_round_rate,
-	.set_rate	= fsidiv_set_rate,
-	.enable		= fsidiv_enable,
-	.disable	= fsidiv_disable,
-};
-
-static struct clk_mapping fsidiva_clk_mapping = {
-	.phys	= FSIDIVA,
-	.len	= 8,
-};
-
-struct clk sh7372_fsidiva_clk = {
-	.ops		= &fsidiv_clk_ops,
-	.parent		= &div6_reparent_clks[DIV6_FSIA], /* late install */
-	.mapping	= &fsidiva_clk_mapping,
-};
-
-static struct clk_mapping fsidivb_clk_mapping = {
-	.phys	= FSIDIVB,
-	.len	= 8,
-};
-
-struct clk sh7372_fsidivb_clk = {
-	.ops		= &fsidiv_clk_ops,
-	.parent		= &div6_reparent_clks[DIV6_FSIB],  /* late install */
-	.mapping	= &fsidivb_clk_mapping,
-};
-
-static struct clk *late_main_clks[] = {
-	&sh7372_fsidiva_clk,
-	&sh7372_fsidivb_clk,
+static struct clk fsidivs[] = {
+	[FSIDIV_A] = SH_CLK_FSIDIV(FSIDIVA, &div6_reparent_clks[DIV6_FSIA]),
+	[FSIDIV_B] = SH_CLK_FSIDIV(FSIDIVB, &div6_reparent_clks[DIV6_FSIB]),
 };
 
 enum { MSTP001, MSTP000,
@@ -583,6 +507,8 @@
 	CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
 	CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
 	CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
+	CLKDEV_CON_ID("fsidiva", &fsidivs[FSIDIV_A]),
+	CLKDEV_CON_ID("fsidivb", &fsidivs[FSIDIV_B]),
 
 	/* DIV4 clocks */
 	CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
@@ -678,6 +604,10 @@
 	CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
 	CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
 	CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]),
+	CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]),
+	CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]),
+	CLKDEV_ICK_ID("xcka", "sh_fsi2", &sh7372_fsiack_clk),
+	CLKDEV_ICK_ID("xckb", "sh_fsi2", &sh7372_fsibck_clk),
 };
 
 void __init sh7372_clock_init(void)
@@ -706,8 +636,8 @@
 	if (!ret)
 		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
 
-	for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
-		ret = clk_register(late_main_clks[k]);
+	if (!ret)
+		ret = sh_clk_fsidiv_register(fsidivs, FSIDIV_REPARENT_NR);
 
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
deleted file mode 100644
index b8480d1..0000000
--- a/arch/arm/mach-shmobile/clock-sh7377.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * SH7377 clock framework support
- *
- * Copyright (C) 2010 Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/sh_clk.h>
-#include <linux/clkdev.h>
-#include <mach/common.h>
-
-/* SH7377 registers */
-#define RTFRQCR    IOMEM(0xe6150000)
-#define SYFRQCR    IOMEM(0xe6150004)
-#define CMFRQCR    IOMEM(0xe61500E0)
-#define VCLKCR1    IOMEM(0xe6150008)
-#define VCLKCR2    IOMEM(0xe615000C)
-#define VCLKCR3    IOMEM(0xe615001C)
-#define FMSICKCR   IOMEM(0xe6150010)
-#define FMSOCKCR   IOMEM(0xe6150014)
-#define FSICKCR    IOMEM(0xe6150018)
-#define PLLC1CR    IOMEM(0xe6150028)
-#define PLLC2CR    IOMEM(0xe615002C)
-#define SUBUSBCKCR IOMEM(0xe6150080)
-#define SPUCKCR    IOMEM(0xe6150084)
-#define MSUCKCR    IOMEM(0xe6150088)
-#define MVI3CKCR   IOMEM(0xe6150090)
-#define HDMICKCR   IOMEM(0xe6150094)
-#define MFCK1CR    IOMEM(0xe6150098)
-#define MFCK2CR    IOMEM(0xe615009C)
-#define DSITCKCR   IOMEM(0xe6150060)
-#define DSIPCKCR   IOMEM(0xe6150064)
-#define SMSTPCR0   IOMEM(0xe6150130)
-#define SMSTPCR1   IOMEM(0xe6150134)
-#define SMSTPCR2   IOMEM(0xe6150138)
-#define SMSTPCR3   IOMEM(0xe615013C)
-#define SMSTPCR4   IOMEM(0xe6150140)
-
-/* Fixed 32 KHz root clock from EXTALR pin */
-static struct clk r_clk = {
-	.rate           = 32768,
-};
-
-/*
- * 26MHz default rate for the EXTALC1 root input clock.
- * If needed, reset this with clk_set_rate() from the platform code.
- */
-struct clk sh7377_extalc1_clk = {
-	.rate		= 26666666,
-};
-
-/*
- * 48MHz default rate for the EXTAL2 root input clock.
- * If needed, reset this with clk_set_rate() from the platform code.
- */
-struct clk sh7377_extal2_clk = {
-	.rate		= 48000000,
-};
-
-/* A fixed divide-by-2 block */
-static unsigned long div2_recalc(struct clk *clk)
-{
-	return clk->parent->rate / 2;
-}
-
-static struct sh_clk_ops div2_clk_ops = {
-	.recalc		= div2_recalc,
-};
-
-/* Divide extalc1 by two */
-static struct clk extalc1_div2_clk = {
-	.ops		= &div2_clk_ops,
-	.parent		= &sh7377_extalc1_clk,
-};
-
-/* Divide extal2 by two */
-static struct clk extal2_div2_clk = {
-	.ops		= &div2_clk_ops,
-	.parent		= &sh7377_extal2_clk,
-};
-
-/* Divide extal2 by four */
-static struct clk extal2_div4_clk = {
-	.ops		= &div2_clk_ops,
-	.parent		= &extal2_div2_clk,
-};
-
-/* PLLC1 */
-static unsigned long pllc1_recalc(struct clk *clk)
-{
-	unsigned long mult = 1;
-
-	if (__raw_readl(PLLC1CR) & (1 << 14))
-		mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2;
-
-	return clk->parent->rate * mult;
-}
-
-static struct sh_clk_ops pllc1_clk_ops = {
-	.recalc		= pllc1_recalc,
-};
-
-static struct clk pllc1_clk = {
-	.ops		= &pllc1_clk_ops,
-	.flags		= CLK_ENABLE_ON_INIT,
-	.parent		= &extalc1_div2_clk,
-};
-
-/* Divide PLLC1 by two */
-static struct clk pllc1_div2_clk = {
-	.ops		= &div2_clk_ops,
-	.parent		= &pllc1_clk,
-};
-
-/* PLLC2 */
-static unsigned long pllc2_recalc(struct clk *clk)
-{
-	unsigned long mult = 1;
-
-	if (__raw_readl(PLLC2CR) & (1 << 31))
-		mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
-
-	return clk->parent->rate * mult;
-}
-
-static struct sh_clk_ops pllc2_clk_ops = {
-	.recalc		= pllc2_recalc,
-};
-
-static struct clk pllc2_clk = {
-	.ops		= &pllc2_clk_ops,
-	.flags		= CLK_ENABLE_ON_INIT,
-	.parent		= &extalc1_div2_clk,
-};
-
-static struct clk *main_clks[] = {
-	&r_clk,
-	&sh7377_extalc1_clk,
-	&sh7377_extal2_clk,
-	&extalc1_div2_clk,
-	&extal2_div2_clk,
-	&extal2_div4_clk,
-	&pllc1_clk,
-	&pllc1_div2_clk,
-	&pllc2_clk,
-};
-
-static void div4_kick(struct clk *clk)
-{
-	unsigned long value;
-
-	/* set KICK bit in SYFRQCR to update hardware setting */
-	value = __raw_readl(SYFRQCR);
-	value |= (1 << 31);
-	__raw_writel(value, SYFRQCR);
-}
-
-static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
-			  24, 32, 36, 48, 0, 72, 96, 0 };
-
-static struct clk_div_mult_table div4_div_mult_table = {
-	.divisors = divisors,
-	.nr_divisors = ARRAY_SIZE(divisors),
-};
-
-static struct clk_div4_table div4_table = {
-	.div_mult_table = &div4_div_mult_table,
-	.kick = div4_kick,
-};
-
-enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
-       DIV4_ZTR, DIV4_ZT, DIV4_Z, DIV4_HP,
-       DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR };
-
-#define DIV4(_reg, _bit, _mask, _flags) \
-  SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
-
-static struct clk div4_clks[DIV4_NR] = {
-	[DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT),
-	[DIV4_ZG] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT),
-	[DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT),
-	[DIV4_M1] = DIV4(RTFRQCR, 4, 0x6fff, CLK_ENABLE_ON_INIT),
-	[DIV4_CSIR] = DIV4(RTFRQCR, 0, 0x6fff, 0),
-	[DIV4_ZTR] = DIV4(SYFRQCR, 20, 0x6fff, 0),
-	[DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0),
-	[DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0),
-	[DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0),
-	[DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0),
-	[DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0),
-	[DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0),
-	[DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0),
-};
-
-enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
-       DIV6_FSI, DIV6_SUB, DIV6_SPU, DIV6_MSU, DIV6_MVI3, DIV6_HDMI,
-       DIV6_MF1, DIV6_MF2, DIV6_DSIT, DIV6_DSIP,
-       DIV6_NR };
-
-static struct clk div6_clks[] = {
-	[DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
-	[DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
-	[DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
-	[DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
-	[DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
-	[DIV6_FSI] = SH_CLK_DIV6(&pllc1_div2_clk, FSICKCR, 0),
-	[DIV6_SUB] = SH_CLK_DIV6(&sh7377_extal2_clk, SUBUSBCKCR, 0),
-	[DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
-	[DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0),
-	[DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0),
-	[DIV6_HDMI] = SH_CLK_DIV6(&pllc1_div2_clk, HDMICKCR, 0),
-	[DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0),
-	[DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0),
-	[DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
-	[DIV6_DSIP] = SH_CLK_DIV6(&pllc1_div2_clk, DSIPCKCR, 0),
-};
-
-enum { MSTP001,
-       MSTP131, MSTP130, MSTP129, MSTP128, MSTP116, MSTP106, MSTP101,
-       MSTP223, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
-       MSTP331, MSTP329, MSTP325, MSTP323, MSTP322,
-       MSTP315, MSTP314, MSTP313,
-       MSTP403,
-       MSTP_NR };
-
-#define MSTP(_parent, _reg, _bit, _flags) \
-  SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
-
-static struct clk mstp_clks[] = {
-	[MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
-	[MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
-	[MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
-	[MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
-	[MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
-	[MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
-	[MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
-	[MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
-	[MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
-	[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
-	[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
-	[MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
-	[MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
-	[MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
-	[MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
-	[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
-	[MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
-	[MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
-	[MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IRDA */
-	[MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
-	[MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
-	[MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL */
-	[MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
-	[MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
-	[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
-};
-
-static struct clk_lookup lookups[] = {
-	/* main clocks */
-	CLKDEV_CON_ID("r_clk", &r_clk),
-	CLKDEV_CON_ID("extalc1", &sh7377_extalc1_clk),
-	CLKDEV_CON_ID("extal2", &sh7377_extal2_clk),
-	CLKDEV_CON_ID("extalc1_div2_clk", &extalc1_div2_clk),
-	CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
-	CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
-	CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
-	CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
-	CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
-
-	/* DIV4 clocks */
-	CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
-	CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
-	CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
-	CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
-	CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
-	CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
-	CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
-	CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]),
-	CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
-	CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]),
-	CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
-	CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
-	CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
-
-	/* DIV6 clocks */
-	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
-	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
-	CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
-	CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
-	CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
-	CLKDEV_CON_ID("fsi_clk", &div6_clks[DIV6_FSI]),
-	CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
-	CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
-	CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]),
-	CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]),
-	CLKDEV_CON_ID("hdmi_clk", &div6_clks[DIV6_HDMI]),
-	CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]),
-	CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]),
-	CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]),
-	CLKDEV_CON_ID("dsip_clk", &div6_clks[DIV6_DSIP]),
-
-	/* MSTP32 clocks */
-	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
-	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
-	CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
-	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
-	CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP206]), /* SCIFB */
-	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
-	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
-	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
-	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
-	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
-	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
-	CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
-	CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */
-	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
-	CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */
-	CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USBHS */
-	CLKDEV_DEV_ID("sh_flctl", &mstp_clks[MSTP315]), /* FLCTL */
-	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
-	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
-	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
-};
-
-void __init sh7377_clock_init(void)
-{
-	int k, ret = 0;
-
-	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
-		ret = clk_register(main_clks[k]);
-
-	if (!ret)
-		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
-
-	if (!ret)
-		ret = sh_clk_div6_register(div6_clks, DIV6_NR);
-
-	if (!ret)
-		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
-
-	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
-	if (!ret)
-		shmobile_clk_init();
-	else
-		panic("failed to setup sh7377 clocks\n");
-}
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index d47e215..dfeca79 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -18,24 +18,6 @@
 			      struct cpuidle_driver *drv, int index);
 extern void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv);
 
-extern void sh7367_init_irq(void);
-extern void sh7367_map_io(void);
-extern void sh7367_add_early_devices(void);
-extern void sh7367_add_standard_devices(void);
-extern void sh7367_clock_init(void);
-extern void sh7367_pinmux_init(void);
-extern struct clk sh7367_extalb1_clk;
-extern struct clk sh7367_extal2_clk;
-
-extern void sh7377_init_irq(void);
-extern void sh7377_map_io(void);
-extern void sh7377_add_early_devices(void);
-extern void sh7377_add_standard_devices(void);
-extern void sh7377_clock_init(void);
-extern void sh7377_pinmux_init(void);
-extern struct clk sh7377_extalc1_clk;
-extern struct clk sh7377_extal2_clk;
-
 extern void sh7372_init_irq(void);
 extern void sh7372_map_io(void);
 extern void sh7372_add_early_devices(void);
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h
index 499f52d..8ab0cd6 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7779.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h
@@ -71,7 +71,7 @@
 	GPIO_FN_A19,
 
 	/* IPSR0 */
-	GPIO_FN_PENC2, GPIO_FN_SCK0, GPIO_FN_PWM1, GPIO_FN_PWMFSW0,
+	GPIO_FN_USB_PENC2, GPIO_FN_SCK0, GPIO_FN_PWM1, GPIO_FN_PWMFSW0,
 	GPIO_FN_SCIF_CLK, GPIO_FN_TCLK0_C, GPIO_FN_BS, GPIO_FN_SD1_DAT2,
 	GPIO_FN_MMC0_D2, GPIO_FN_FD2, GPIO_FN_ATADIR0, GPIO_FN_SDSELF,
 	GPIO_FN_HCTS1, GPIO_FN_TX4_C, GPIO_FN_A0, GPIO_FN_SD1_DAT3,
diff --git a/arch/arm/mach-shmobile/include/mach/sh7367.h b/arch/arm/mach-shmobile/include/mach/sh7367.h
deleted file mode 100644
index 52d0de6..0000000
--- a/arch/arm/mach-shmobile/include/mach/sh7367.h
+++ /dev/null
@@ -1,332 +0,0 @@
-#ifndef __ASM_SH7367_H__
-#define __ASM_SH7367_H__
-
-/* Pin Function Controller:
- * GPIO_FN_xx - GPIO used to select pin function
- * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
- */
-enum {
-	/* 49-1 -> 49-6 (GPIO) */
-	GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
-	GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
-
-	GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
-	GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
-
-	GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
-	GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
-
-	GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
-	GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
-
-	GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
-	GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
-
-	GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
-	GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
-
-	GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
-	GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
-
-	GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
-	GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
-
-	GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
-	GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
-
-	GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
-	GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
-
-	GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
-	GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
-
-	GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
-	GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119,
-
-	GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124,
-	GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129,
-
-	GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
-	GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
-
-	GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
-	GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
-
-	GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
-	GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
-
-	GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
-	GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169,
-
-	GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174,
-	GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179,
-
-	GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184,
-	GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189,
-
-	GPIO_PORT190, GPIO_PORT191, GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
-	GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
-
-	GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
-	GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
-
-	GPIO_PORT210, GPIO_PORT211, GPIO_PORT212, GPIO_PORT213, GPIO_PORT214,
-	GPIO_PORT215, GPIO_PORT216, GPIO_PORT217, GPIO_PORT218, GPIO_PORT219,
-
-	GPIO_PORT220, GPIO_PORT221, GPIO_PORT222, GPIO_PORT223, GPIO_PORT224,
-	GPIO_PORT225, GPIO_PORT226, GPIO_PORT227, GPIO_PORT228, GPIO_PORT229,
-
-	GPIO_PORT230, GPIO_PORT231, GPIO_PORT232, GPIO_PORT233, GPIO_PORT234,
-	GPIO_PORT235, GPIO_PORT236, GPIO_PORT237, GPIO_PORT238, GPIO_PORT239,
-
-	GPIO_PORT240, GPIO_PORT241, GPIO_PORT242, GPIO_PORT243, GPIO_PORT244,
-	GPIO_PORT245, GPIO_PORT246, GPIO_PORT247, GPIO_PORT248, GPIO_PORT249,
-
-	GPIO_PORT250, GPIO_PORT251, GPIO_PORT252, GPIO_PORT253, GPIO_PORT254,
-	GPIO_PORT255, GPIO_PORT256, GPIO_PORT257, GPIO_PORT258, GPIO_PORT259,
-
-	GPIO_PORT260, GPIO_PORT261, GPIO_PORT262, GPIO_PORT263, GPIO_PORT264,
-	GPIO_PORT265, GPIO_PORT266, GPIO_PORT267, GPIO_PORT268, GPIO_PORT269,
-
-	GPIO_PORT270, GPIO_PORT271, GPIO_PORT272,
-
-	/* Special Pull-up / Pull-down Functions */
-	GPIO_FN_PORT48_KEYIN0_PU, GPIO_FN_PORT49_KEYIN1_PU,
-	GPIO_FN_PORT50_KEYIN2_PU, GPIO_FN_PORT55_KEYIN3_PU,
-	GPIO_FN_PORT56_KEYIN4_PU, GPIO_FN_PORT57_KEYIN5_PU,
-	GPIO_FN_PORT58_KEYIN6_PU,
-
-	/* 49-1 (FN) */
-	GPIO_FN_VBUS0, GPIO_FN_CPORT0, GPIO_FN_CPORT1, GPIO_FN_CPORT2,
-	GPIO_FN_CPORT3, GPIO_FN_CPORT4, GPIO_FN_CPORT5, GPIO_FN_CPORT6,
-	GPIO_FN_CPORT7, GPIO_FN_CPORT8, GPIO_FN_CPORT9, GPIO_FN_CPORT10,
-	GPIO_FN_CPORT11, GPIO_FN_SIN2, GPIO_FN_CPORT12, GPIO_FN_XCTS2,
-	GPIO_FN_CPORT13, GPIO_FN_RFSPO4, GPIO_FN_CPORT14, GPIO_FN_RFSPO5,
-	GPIO_FN_CPORT15, GPIO_FN_CPORT16, GPIO_FN_CPORT17, GPIO_FN_SOUT2,
-	GPIO_FN_CPORT18, GPIO_FN_XRTS2, GPIO_FN_CPORT19, GPIO_FN_CPORT20,
-	GPIO_FN_RFSPO6, GPIO_FN_CPORT21, GPIO_FN_STATUS0, GPIO_FN_CPORT22,
-	GPIO_FN_STATUS1, GPIO_FN_CPORT23, GPIO_FN_STATUS2, GPIO_FN_RFSPO7,
-	GPIO_FN_MPORT0, GPIO_FN_MPORT1, GPIO_FN_B_SYNLD1, GPIO_FN_B_SYNLD2,
-	GPIO_FN_XMAINPS, GPIO_FN_XDIVPS, GPIO_FN_XIDRST, GPIO_FN_IDCLK,
-	GPIO_FN_IDIO, GPIO_FN_SOUT1, GPIO_FN_SCIFA4_TXD,
-	GPIO_FN_M02_BERDAT, GPIO_FN_SIN1, GPIO_FN_SCIFA4_RXD, GPIO_FN_XWUP,
-	GPIO_FN_XRTS1, GPIO_FN_SCIFA4_RTS, GPIO_FN_M03_BERCLK,
-	GPIO_FN_XCTS1, GPIO_FN_SCIFA4_CTS,
-
-	/* 49-2 (FN) */
-	GPIO_FN_HSU_IQ_AGC6, GPIO_FN_MFG2_IN2, GPIO_FN_MSIOF2_MCK0,
-	GPIO_FN_HSU_IQ_AGC5, GPIO_FN_MFG2_IN1, GPIO_FN_MSIOF2_MCK1,
-	GPIO_FN_HSU_IQ_AGC4, GPIO_FN_MSIOF2_RSYNC,
-	GPIO_FN_HSU_IQ_AGC3, GPIO_FN_MFG2_OUT1, GPIO_FN_MSIOF2_RSCK,
-	GPIO_FN_HSU_IQ_AGC2, GPIO_FN_PORT42_KEYOUT0,
-	GPIO_FN_HSU_IQ_AGC1, GPIO_FN_PORT43_KEYOUT1,
-	GPIO_FN_HSU_IQ_AGC0, GPIO_FN_PORT44_KEYOUT2,
-	GPIO_FN_HSU_IQ_AGC_ST, GPIO_FN_PORT45_KEYOUT3,
-	GPIO_FN_HSU_IQ_PDO, GPIO_FN_PORT46_KEYOUT4,
-	GPIO_FN_HSU_IQ_PYO, GPIO_FN_PORT47_KEYOUT5,
-	GPIO_FN_HSU_EN_TXMUX_G3MO, GPIO_FN_PORT48_KEYIN0,
-	GPIO_FN_HSU_I_TXMUX_G3MO, GPIO_FN_PORT49_KEYIN1,
-	GPIO_FN_HSU_Q_TXMUX_G3MO, GPIO_FN_PORT50_KEYIN2,
-	GPIO_FN_HSU_SYO, GPIO_FN_PORT51_MSIOF2_TSYNC,
-	GPIO_FN_HSU_SDO, GPIO_FN_PORT52_MSIOF2_TSCK,
-	GPIO_FN_HSU_TGTTI_G3MO, GPIO_FN_PORT53_MSIOF2_TXD,
-	GPIO_FN_B_TIME_STAMP, GPIO_FN_PORT54_MSIOF2_RXD,
-	GPIO_FN_HSU_SDI, GPIO_FN_PORT55_KEYIN3,
-	GPIO_FN_HSU_SCO, GPIO_FN_PORT56_KEYIN4,
-	GPIO_FN_HSU_DREQ, GPIO_FN_PORT57_KEYIN5,
-	GPIO_FN_HSU_DACK, GPIO_FN_PORT58_KEYIN6,
-	GPIO_FN_HSU_CLK61M, GPIO_FN_PORT59_MSIOF2_SS1,
-	GPIO_FN_HSU_XRST, GPIO_FN_PORT60_MSIOF2_SS2,
-	GPIO_FN_PCMCLKO, GPIO_FN_SYNC8KO, GPIO_FN_DNPCM_A, GPIO_FN_UPPCM_A,
-	GPIO_FN_XTALB1L,
-	GPIO_FN_GPS_AGC1, GPIO_FN_SCIFA0_RTS,
-	GPIO_FN_GPS_AGC2, GPIO_FN_SCIFA0_SCK,
-	GPIO_FN_GPS_AGC3, GPIO_FN_SCIFA0_TXD,
-	GPIO_FN_GPS_AGC4, GPIO_FN_SCIFA0_RXD,
-	GPIO_FN_GPS_PWRD, GPIO_FN_SCIFA0_CTS,
-	GPIO_FN_GPS_IM, GPIO_FN_GPS_IS, GPIO_FN_GPS_QM, GPIO_FN_GPS_QS,
-	GPIO_FN_SIUBOMC, GPIO_FN_TPU2TO0,
-	GPIO_FN_SIUCKB, GPIO_FN_TPU2TO1,
-	GPIO_FN_SIUBOLR, GPIO_FN_BBIF2_TSYNC, GPIO_FN_TPU2TO2,
-	GPIO_FN_SIUBOBT, GPIO_FN_BBIF2_TSCK, GPIO_FN_TPU2TO3,
-	GPIO_FN_SIUBOSLD, GPIO_FN_BBIF2_TXD, GPIO_FN_TPU3TO0,
-	GPIO_FN_SIUBILR, GPIO_FN_TPU3TO1,
-	GPIO_FN_SIUBIBT, GPIO_FN_TPU3TO2,
-	GPIO_FN_SIUBISLD, GPIO_FN_TPU3TO3,
-	GPIO_FN_NMI, GPIO_FN_TPU4TO0,
-	GPIO_FN_DNPCM_M, GPIO_FN_TPU4TO1, GPIO_FN_TPU4TO2, GPIO_FN_TPU4TO3,
-	GPIO_FN_IRQ_TMPB,
-	GPIO_FN_PWEN, GPIO_FN_MFG1_OUT1,
-	GPIO_FN_OVCN, GPIO_FN_MFG1_IN1,
-	GPIO_FN_OVCN2, GPIO_FN_MFG1_IN2,
-
-	/* 49-3 (FN) */
-	GPIO_FN_RFSPO1, GPIO_FN_RFSPO2, GPIO_FN_RFSPO3, GPIO_FN_PORT93_VIO_CKO2,
-	GPIO_FN_USBTERM, GPIO_FN_EXTLP, GPIO_FN_IDIN,
-	GPIO_FN_SCIFA5_CTS, GPIO_FN_MFG0_IN1,
-	GPIO_FN_SCIFA5_RTS, GPIO_FN_MFG0_IN2,
-	GPIO_FN_SCIFA5_RXD,
-	GPIO_FN_SCIFA5_TXD,
-	GPIO_FN_SCIFA5_SCK, GPIO_FN_MFG0_OUT1,
-	GPIO_FN_A0_EA0, GPIO_FN_BS,
-	GPIO_FN_A14_EA14, GPIO_FN_PORT102_KEYOUT0,
-	GPIO_FN_A15_EA15, GPIO_FN_PORT103_KEYOUT1, GPIO_FN_DV_CLKOL,
-	GPIO_FN_A16_EA16, GPIO_FN_PORT104_KEYOUT2,
-	GPIO_FN_DV_VSYNCL, GPIO_FN_MSIOF0_SS1,
-	GPIO_FN_A17_EA17, GPIO_FN_PORT105_KEYOUT3,
-	GPIO_FN_DV_HSYNCL, GPIO_FN_MSIOF0_TSYNC,
-	GPIO_FN_A18_EA18, GPIO_FN_PORT106_KEYOUT4,
-	GPIO_FN_DV_DL0, GPIO_FN_MSIOF0_TSCK,
-	GPIO_FN_A19_EA19, GPIO_FN_PORT107_KEYOUT5,
-	GPIO_FN_DV_DL1, GPIO_FN_MSIOF0_TXD,
-	GPIO_FN_A20_EA20, GPIO_FN_PORT108_KEYIN0,
-	GPIO_FN_DV_DL2, GPIO_FN_MSIOF0_RSCK,
-	GPIO_FN_A21_EA21, GPIO_FN_PORT109_KEYIN1,
-	GPIO_FN_DV_DL3, GPIO_FN_MSIOF0_RSYNC,
-	GPIO_FN_A22_EA22, GPIO_FN_PORT110_KEYIN2,
-	GPIO_FN_DV_DL4, GPIO_FN_MSIOF0_MCK0,
-	GPIO_FN_A23_EA23, GPIO_FN_PORT111_KEYIN3,
-	GPIO_FN_DV_DL5, GPIO_FN_MSIOF0_MCK1,
-	GPIO_FN_A24_EA24, GPIO_FN_PORT112_KEYIN4,
-	GPIO_FN_DV_DL6, GPIO_FN_MSIOF0_RXD,
-	GPIO_FN_A25_EA25, GPIO_FN_PORT113_KEYIN5,
-	GPIO_FN_DV_DL7, GPIO_FN_MSIOF0_SS2,
-	GPIO_FN_A26, GPIO_FN_PORT113_KEYIN6, GPIO_FN_DV_CLKIL,
-	GPIO_FN_D0_ED0_NAF0, GPIO_FN_D1_ED1_NAF1, GPIO_FN_D2_ED2_NAF2,
-	GPIO_FN_D3_ED3_NAF3, GPIO_FN_D4_ED4_NAF4, GPIO_FN_D5_ED5_NAF5,
-	GPIO_FN_D6_ED6_NAF6, GPIO_FN_D7_ED7_NAF7, GPIO_FN_D8_ED8_NAF8,
-	GPIO_FN_D9_ED9_NAF9, GPIO_FN_D10_ED10_NAF10, GPIO_FN_D11_ED11_NAF11,
-	GPIO_FN_D12_ED12_NAF12, GPIO_FN_D13_ED13_NAF13,
-	GPIO_FN_D14_ED14_NAF14, GPIO_FN_D15_ED15_NAF15,
-	GPIO_FN_CS4, GPIO_FN_CS5A, GPIO_FN_CS5B, GPIO_FN_FCE1,
-	GPIO_FN_CS6B, GPIO_FN_XCS2, GPIO_FN_FCE0, GPIO_FN_CS6A,
-	GPIO_FN_DACK0, GPIO_FN_WAIT, GPIO_FN_DREQ0, GPIO_FN_RD_XRD,
-	GPIO_FN_A27, GPIO_FN_RDWR_XWE, GPIO_FN_WE0_XWR0_FWE,
-	GPIO_FN_WE1_XWR1, GPIO_FN_FRB, GPIO_FN_CKO,
-	GPIO_FN_NBRSTOUT, GPIO_FN_NBRST,
-
-	/* 49-4 (FN) */
-	GPIO_FN_RFSPO0, GPIO_FN_PORT146_VIO_CKO2, GPIO_FN_TSTMD,
-	GPIO_FN_VIO_VD, GPIO_FN_VIO_HD,
-	GPIO_FN_VIO_D0, GPIO_FN_VIO_D1, GPIO_FN_VIO_D2,
-	GPIO_FN_VIO_D3, GPIO_FN_VIO_D4, GPIO_FN_VIO_D5,
-	GPIO_FN_VIO_D6, GPIO_FN_VIO_D7, GPIO_FN_VIO_D8,
-	GPIO_FN_VIO_D9, GPIO_FN_VIO_D10, GPIO_FN_VIO_D11,
-	GPIO_FN_VIO_D12, GPIO_FN_VIO_D13, GPIO_FN_VIO_D14,
-	GPIO_FN_VIO_D15, GPIO_FN_VIO_CLK, GPIO_FN_VIO_FIELD,
-	GPIO_FN_VIO_CKO,
-	GPIO_FN_MFG3_IN1, GPIO_FN_MFG3_IN2,
-	GPIO_FN_M9_SLCD_A01, GPIO_FN_MFG3_OUT1, GPIO_FN_TPU0TO0,
-	GPIO_FN_M10_SLCD_CK1, GPIO_FN_MFG4_IN1, GPIO_FN_TPU0TO1,
-	GPIO_FN_M11_SLCD_SO1, GPIO_FN_MFG4_IN2, GPIO_FN_TPU0TO2,
-	GPIO_FN_M12_SLCD_CE1, GPIO_FN_MFG4_OUT1, GPIO_FN_TPU0TO3,
-	GPIO_FN_LCDD0, GPIO_FN_PORT175_KEYOUT0, GPIO_FN_DV_D0,
-	GPIO_FN_SIUCKA, GPIO_FN_MFG0_OUT2,
-	GPIO_FN_LCDD1, GPIO_FN_PORT176_KEYOUT1, GPIO_FN_DV_D1,
-	GPIO_FN_SIUAOLR, GPIO_FN_BBIF2_TSYNC1,
-	GPIO_FN_LCDD2, GPIO_FN_PORT177_KEYOUT2, GPIO_FN_DV_D2,
-	GPIO_FN_SIUAOBT, GPIO_FN_BBIF2_TSCK1,
-	GPIO_FN_LCDD3, GPIO_FN_PORT178_KEYOUT3, GPIO_FN_DV_D3,
-	GPIO_FN_SIUAOSLD, GPIO_FN_BBIF2_TXD1,
-	GPIO_FN_LCDD4, GPIO_FN_PORT179_KEYOUT4, GPIO_FN_DV_D4,
-	GPIO_FN_SIUAISPD, GPIO_FN_MFG1_OUT2,
-	GPIO_FN_LCDD5, GPIO_FN_PORT180_KEYOUT5, GPIO_FN_DV_D5,
-	GPIO_FN_SIUAILR, GPIO_FN_MFG2_OUT2,
-	GPIO_FN_LCDD6, GPIO_FN_DV_D6,
-	GPIO_FN_SIUAIBT, GPIO_FN_MFG3_OUT2, GPIO_FN_XWR2,
-	GPIO_FN_LCDD7, GPIO_FN_DV_D7,
-	GPIO_FN_SIUAISLD, GPIO_FN_MFG4_OUT2, GPIO_FN_XWR3,
-	GPIO_FN_LCDD8, GPIO_FN_DV_D8, GPIO_FN_D16, GPIO_FN_ED16,
-	GPIO_FN_LCDD9, GPIO_FN_DV_D9, GPIO_FN_D17, GPIO_FN_ED17,
-	GPIO_FN_LCDD10, GPIO_FN_DV_D10, GPIO_FN_D18, GPIO_FN_ED18,
-	GPIO_FN_LCDD11, GPIO_FN_DV_D11, GPIO_FN_D19, GPIO_FN_ED19,
-	GPIO_FN_LCDD12, GPIO_FN_DV_D12, GPIO_FN_D20, GPIO_FN_ED20,
-	GPIO_FN_LCDD13, GPIO_FN_DV_D13, GPIO_FN_D21, GPIO_FN_ED21,
-	GPIO_FN_LCDD14, GPIO_FN_DV_D14, GPIO_FN_D22, GPIO_FN_ED22,
-	GPIO_FN_LCDD15, GPIO_FN_DV_D15, GPIO_FN_D23, GPIO_FN_ED23,
-	GPIO_FN_LCDD16, GPIO_FN_DV_HSYNC, GPIO_FN_D24, GPIO_FN_ED24,
-	GPIO_FN_LCDD17, GPIO_FN_DV_VSYNC, GPIO_FN_D25, GPIO_FN_ED25,
-	GPIO_FN_LCDD18, GPIO_FN_DREQ2, GPIO_FN_MSIOF0L_TSCK,
-	GPIO_FN_D26, GPIO_FN_ED26,
-	GPIO_FN_LCDD19, GPIO_FN_MSIOF0L_TSYNC,
-	GPIO_FN_D27, GPIO_FN_ED27,
-	GPIO_FN_LCDD20, GPIO_FN_TS_SPSYNC1, GPIO_FN_MSIOF0L_MCK0,
-	GPIO_FN_D28, GPIO_FN_ED28,
-	GPIO_FN_LCDD21, GPIO_FN_TS_SDAT1, GPIO_FN_MSIOF0L_MCK1,
-	GPIO_FN_D29, GPIO_FN_ED29,
-	GPIO_FN_LCDD22, GPIO_FN_TS_SDEN1, GPIO_FN_MSIOF0L_SS1,
-	GPIO_FN_D30, GPIO_FN_ED30,
-	GPIO_FN_LCDD23, GPIO_FN_TS_SCK1, GPIO_FN_MSIOF0L_SS2,
-	GPIO_FN_D31, GPIO_FN_ED31,
-	GPIO_FN_LCDDCK, GPIO_FN_LCDWR, GPIO_FN_DV_CKO, GPIO_FN_SIUAOSPD,
-	GPIO_FN_LCDRD, GPIO_FN_DACK2, GPIO_FN_MSIOF0L_RSYNC,
-
-
-	/* 49-5 (FN) */
-	GPIO_FN_LCDHSYN, GPIO_FN_LCDCS, GPIO_FN_LCDCS2, GPIO_FN_DACK3,
-	GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_RSCK,
-	GPIO_FN_LCDCSYN, GPIO_FN_LCDCSYN2, GPIO_FN_DV_CKI,
-	GPIO_FN_LCDLCLK, GPIO_FN_DREQ1, GPIO_FN_MSIOF0L_RXD,
-	GPIO_FN_LCDDON, GPIO_FN_LCDDON2, GPIO_FN_DACK1, GPIO_FN_MSIOF0L_TXD,
-	GPIO_FN_VIO_DR0, GPIO_FN_VIO_DR1, GPIO_FN_VIO_DR2, GPIO_FN_VIO_DR3,
-	GPIO_FN_VIO_DR4, GPIO_FN_VIO_DR5, GPIO_FN_VIO_DR6, GPIO_FN_VIO_DR7,
-	GPIO_FN_VIO_VDR, GPIO_FN_VIO_HDR,
-	GPIO_FN_VIO_CLKR, GPIO_FN_VIO_CKOR,
-	GPIO_FN_SCIFA1_TXD, GPIO_FN_GPS_PGFA0,
-	GPIO_FN_SCIFA1_SCK, GPIO_FN_GPS_PGFA1,
-	GPIO_FN_SCIFA1_RTS, GPIO_FN_GPS_EPPSINMON,
-	GPIO_FN_SCIFA1_RXD, GPIO_FN_SCIFA1_CTS,
-	GPIO_FN_MSIOF1_TXD, GPIO_FN_SCIFA1_TXD2, GPIO_FN_GPS_TXD,
-	GPIO_FN_MSIOF1_TSYNC, GPIO_FN_SCIFA1_CTS2, GPIO_FN_I2C_SDA2,
-	GPIO_FN_MSIOF1_TSCK, GPIO_FN_SCIFA1_SCK2,
-	GPIO_FN_MSIOF1_RXD, GPIO_FN_SCIFA1_RXD2, GPIO_FN_GPS_RXD,
-	GPIO_FN_MSIOF1_RSCK, GPIO_FN_SCIFA1_RTS2,
-	GPIO_FN_MSIOF1_RSYNC, GPIO_FN_I2C_SCL2,
-	GPIO_FN_MSIOF1_MCK0, GPIO_FN_MSIOF1_MCK1,
-	GPIO_FN_MSIOF1_SS1, GPIO_FN_EDBGREQ3,
-	GPIO_FN_MSIOF1_SS2,
-	GPIO_FN_PORT236_IROUT, GPIO_FN_IRDA_OUT,
-	GPIO_FN_IRDA_IN, GPIO_FN_IRDA_FIRSEL,
-	GPIO_FN_TPU1TO0, GPIO_FN_TS_SPSYNC3,
-	GPIO_FN_TPU1TO1, GPIO_FN_TS_SDAT3,
-	GPIO_FN_TPU1TO2, GPIO_FN_TS_SDEN3, GPIO_FN_PORT241_MSIOF2_SS1,
-	GPIO_FN_TPU1TO3, GPIO_FN_PORT242_MSIOF2_TSCK,
-	GPIO_FN_M13_BSW, GPIO_FN_PORT243_MSIOF2_TSYNC,
-	GPIO_FN_M14_GSW, GPIO_FN_PORT244_MSIOF2_TXD,
-	GPIO_FN_PORT245_IROUT, GPIO_FN_M15_RSW,
-	GPIO_FN_SOUT3, GPIO_FN_SCIFA2_TXD1,
-	GPIO_FN_SIN3, GPIO_FN_SCIFA2_RXD1,
-	GPIO_FN_XRTS3, GPIO_FN_SCIFA2_RTS1, GPIO_FN_PORT248_MSIOF2_SS2,
-	GPIO_FN_XCTS3, GPIO_FN_SCIFA2_CTS1, GPIO_FN_PORT249_MSIOF2_RXD,
-	GPIO_FN_DINT, GPIO_FN_SCIFA2_SCK1, GPIO_FN_TS_SCK3,
-	GPIO_FN_SDHICLK0, GPIO_FN_TCK2,
-	GPIO_FN_SDHICD0,
-	GPIO_FN_SDHID0_0, GPIO_FN_TMS2,
-	GPIO_FN_SDHID0_1, GPIO_FN_TDO2,
-	GPIO_FN_SDHID0_2, GPIO_FN_TDI2,
-	GPIO_FN_SDHID0_3, GPIO_FN_RTCK2,
-
-	/* 49-6 (FN) */
-	GPIO_FN_SDHICMD0, GPIO_FN_TRST2,
-	GPIO_FN_SDHIWP0, GPIO_FN_EDBGREQ2,
-	GPIO_FN_SDHICLK1, GPIO_FN_TCK3,
-	GPIO_FN_SDHID1_0, GPIO_FN_M11_SLCD_SO2,
-	GPIO_FN_TS_SPSYNC2, GPIO_FN_TMS3,
-	GPIO_FN_SDHID1_1, GPIO_FN_M9_SLCD_AO2,
-	GPIO_FN_TS_SDAT2, GPIO_FN_TDO3,
-	GPIO_FN_SDHID1_2, GPIO_FN_M10_SLCD_CK2,
-	GPIO_FN_TS_SDEN2, GPIO_FN_TDI3,
-	GPIO_FN_SDHID1_3, GPIO_FN_M12_SLCD_CE2,
-	GPIO_FN_TS_SCK2, GPIO_FN_RTCK3,
-	GPIO_FN_SDHICMD1, GPIO_FN_TRST3,
-	GPIO_FN_SDHICLK2, GPIO_FN_SCIFB_SCK,
-	GPIO_FN_SDHID2_0, GPIO_FN_SCIFB_TXD,
-	GPIO_FN_SDHID2_1, GPIO_FN_SCIFB_CTS,
-	GPIO_FN_SDHID2_2, GPIO_FN_SCIFB_RXD,
-	GPIO_FN_SDHID2_3, GPIO_FN_SCIFB_RTS,
-	GPIO_FN_SDHICMD2,
-	GPIO_FN_RESETOUTS,
-	GPIO_FN_DIVLOCK,
-};
-
-#endif /* __ASM_SH7367_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index eb98b45..26cd101 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -452,6 +452,10 @@
 	SHDMA_SLAVE_SCIF5_RX,
 	SHDMA_SLAVE_SCIF6_TX,
 	SHDMA_SLAVE_SCIF6_RX,
+	SHDMA_SLAVE_FLCTL0_TX,
+	SHDMA_SLAVE_FLCTL0_RX,
+	SHDMA_SLAVE_FLCTL1_TX,
+	SHDMA_SLAVE_FLCTL1_RX,
 	SHDMA_SLAVE_SDHI0_RX,
 	SHDMA_SLAVE_SDHI0_TX,
 	SHDMA_SLAVE_SDHI1_RX,
@@ -475,8 +479,6 @@
 extern struct clk sh7372_pllc2_clk;
 extern struct clk sh7372_fsiack_clk;
 extern struct clk sh7372_fsibck_clk;
-extern struct clk sh7372_fsidiva_clk;
-extern struct clk sh7372_fsidivb_clk;
 
 extern void sh7372_intcs_suspend(void);
 extern void sh7372_intcs_resume(void);
diff --git a/arch/arm/mach-shmobile/include/mach/sh7377.h b/arch/arm/mach-shmobile/include/mach/sh7377.h
deleted file mode 100644
index f580e22..0000000
--- a/arch/arm/mach-shmobile/include/mach/sh7377.h
+++ /dev/null
@@ -1,360 +0,0 @@
-#ifndef __ASM_SH7377_H__
-#define __ASM_SH7377_H__
-
-/* Pin Function Controller:
- * GPIO_FN_xx - GPIO used to select pin function
- * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
- */
-enum {
-	/* 55-1 -> 55-5 (GPIO) */
-	GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
-	GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
-
-	GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
-	GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
-
-	GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
-	GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
-
-	GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
-	GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
-
-	GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
-	GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
-
-	GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
-	GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
-
-	GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
-	GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
-
-	GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
-	GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
-
-	GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
-	GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
-
-	GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
-	GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
-
-	GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
-	GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
-
-	GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
-	GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118,
-
-	GPIO_PORT128, GPIO_PORT129,
-
-	GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
-	GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
-
-	GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
-	GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
-
-	GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
-	GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
-
-	GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
-
-	GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
-	GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
-
-	GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
-	GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
-
-	GPIO_PORT210, GPIO_PORT211, GPIO_PORT212, GPIO_PORT213, GPIO_PORT214,
-	GPIO_PORT215, GPIO_PORT216, GPIO_PORT217, GPIO_PORT218, GPIO_PORT219,
-
-	GPIO_PORT220, GPIO_PORT221, GPIO_PORT222, GPIO_PORT223, GPIO_PORT224,
-	GPIO_PORT225, GPIO_PORT226, GPIO_PORT227, GPIO_PORT228, GPIO_PORT229,
-
-	GPIO_PORT230, GPIO_PORT231, GPIO_PORT232, GPIO_PORT233, GPIO_PORT234,
-	GPIO_PORT235, GPIO_PORT236, GPIO_PORT237, GPIO_PORT238, GPIO_PORT239,
-
-	GPIO_PORT240, GPIO_PORT241, GPIO_PORT242, GPIO_PORT243, GPIO_PORT244,
-	GPIO_PORT245, GPIO_PORT246, GPIO_PORT247, GPIO_PORT248, GPIO_PORT249,
-
-	GPIO_PORT250, GPIO_PORT251, GPIO_PORT252, GPIO_PORT253, GPIO_PORT254,
-	GPIO_PORT255, GPIO_PORT256, GPIO_PORT257, GPIO_PORT258, GPIO_PORT259,
-
-	GPIO_PORT260, GPIO_PORT261, GPIO_PORT262, GPIO_PORT263, GPIO_PORT264,
-
-	/* Special Pull-up / Pull-down Functions */
-	GPIO_FN_PORT66_KEYIN0_PU, GPIO_FN_PORT67_KEYIN1_PU,
-	GPIO_FN_PORT68_KEYIN2_PU, GPIO_FN_PORT69_KEYIN3_PU,
-	GPIO_FN_PORT70_KEYIN4_PU, GPIO_FN_PORT71_KEYIN5_PU,
-	GPIO_FN_PORT72_KEYIN6_PU,
-
-	/* 55-1 (FN) */
-	GPIO_FN_VBUS_0,
-	GPIO_FN_CPORT0,
-	GPIO_FN_CPORT1,
-	GPIO_FN_CPORT2,
-	GPIO_FN_CPORT3,
-	GPIO_FN_CPORT4,
-	GPIO_FN_CPORT5,
-	GPIO_FN_CPORT6,
-	GPIO_FN_CPORT7,
-	GPIO_FN_CPORT8,
-	GPIO_FN_CPORT9,
-	GPIO_FN_CPORT10,
-	GPIO_FN_CPORT11, GPIO_FN_SIN2,
-	GPIO_FN_CPORT12, GPIO_FN_XCTS2,
-	GPIO_FN_CPORT13, GPIO_FN_RFSPO4,
-	GPIO_FN_CPORT14, GPIO_FN_RFSPO5,
-	GPIO_FN_CPORT15, GPIO_FN_SCIFA0_SCK, GPIO_FN_GPS_AGC2,
-	GPIO_FN_CPORT16, GPIO_FN_SCIFA0_TXD, GPIO_FN_GPS_AGC3,
-	GPIO_FN_CPORT17_IC_OE, GPIO_FN_SOUT2,
-	GPIO_FN_CPORT18, GPIO_FN_XRTS2, GPIO_FN_PORT19_VIO_CKO2,
-	GPIO_FN_CPORT19_MPORT1,
-	GPIO_FN_CPORT20, GPIO_FN_RFSPO6,
-	GPIO_FN_CPORT21, GPIO_FN_STATUS0,
-	GPIO_FN_CPORT22, GPIO_FN_STATUS1,
-	GPIO_FN_CPORT23, GPIO_FN_STATUS2, GPIO_FN_RFSPO7,
-	GPIO_FN_B_SYNLD1,
-	GPIO_FN_B_SYNLD2, GPIO_FN_SYSENMSK,
-	GPIO_FN_XMAINPS,
-	GPIO_FN_XDIVPS,
-	GPIO_FN_XIDRST,
-	GPIO_FN_IDCLK, GPIO_FN_IC_DP,
-	GPIO_FN_IDIO, GPIO_FN_IC_DM,
-	GPIO_FN_SOUT1, GPIO_FN_SCIFA4_TXD, GPIO_FN_M02_BERDAT,
-	GPIO_FN_SIN1, GPIO_FN_SCIFA4_RXD, GPIO_FN_XWUP,
-	GPIO_FN_XRTS1, GPIO_FN_SCIFA4_RTS, GPIO_FN_M03_BERCLK,
-	GPIO_FN_XCTS1, GPIO_FN_SCIFA4_CTS,
-	GPIO_FN_PCMCLKO,
-	GPIO_FN_SYNC8KO,
-
-	/* 55-2 (FN) */
-	GPIO_FN_DNPCM_A,
-	GPIO_FN_UPPCM_A,
-	GPIO_FN_VACK,
-	GPIO_FN_XTALB1L,
-	GPIO_FN_GPS_AGC1, GPIO_FN_SCIFA0_RTS,
-	GPIO_FN_GPS_AGC4, GPIO_FN_SCIFA0_RXD,
-	GPIO_FN_GPS_PWRDOWN, GPIO_FN_SCIFA0_CTS,
-	GPIO_FN_GPS_IM,
-	GPIO_FN_GPS_IS,
-	GPIO_FN_GPS_QM,
-	GPIO_FN_GPS_QS,
-	GPIO_FN_FMSOCK, GPIO_FN_PORT49_IRDA_OUT, GPIO_FN_PORT49_IROUT,
-	GPIO_FN_FMSOOLR, GPIO_FN_BBIF2_TSYNC2, GPIO_FN_TPU2TO2, GPIO_FN_IPORT3,
-	GPIO_FN_FMSIOLR,
-	GPIO_FN_FMSOOBT, GPIO_FN_BBIF2_TSCK2, GPIO_FN_TPU2TO3, GPIO_FN_OPORT1,
-	GPIO_FN_FMSIOBT,
-	GPIO_FN_FMSOSLD, GPIO_FN_BBIF2_TXD2, GPIO_FN_OPORT2,
-	GPIO_FN_FMSOILR, GPIO_FN_PORT53_IRDA_IN, GPIO_FN_TPU3TO3,
-	GPIO_FN_OPORT3, GPIO_FN_FMSIILR,
-	GPIO_FN_FMSOIBT, GPIO_FN_PORT54_IRDA_FIRSEL, GPIO_FN_TPU3TO2,
-	GPIO_FN_FMSIIBT,
-	GPIO_FN_FMSISLD, GPIO_FN_MFG0_OUT1, GPIO_FN_TPU0TO0,
-	GPIO_FN_A0_EA0, GPIO_FN_BS,
-	GPIO_FN_A12_EA12, GPIO_FN_PORT58_VIO_CKOR, GPIO_FN_TPU4TO2,
-	GPIO_FN_A13_EA13, GPIO_FN_PORT59_IROUT, GPIO_FN_MFG0_OUT2,
-	GPIO_FN_TPU0TO1,
-	GPIO_FN_A14_EA14, GPIO_FN_PORT60_KEYOUT5,
-	GPIO_FN_A15_EA15, GPIO_FN_PORT61_KEYOUT4,
-	GPIO_FN_A16_EA16, GPIO_FN_PORT62_KEYOUT3, GPIO_FN_MSIOF0_SS1,
-	GPIO_FN_A17_EA17, GPIO_FN_PORT63_KEYOUT2, GPIO_FN_MSIOF0_TSYNC,
-	GPIO_FN_A18_EA18, GPIO_FN_PORT64_KEYOUT1, GPIO_FN_MSIOF0_TSCK,
-	GPIO_FN_A19_EA19, GPIO_FN_PORT65_KEYOUT0, GPIO_FN_MSIOF0_TXD,
-	GPIO_FN_A20_EA20, GPIO_FN_PORT66_KEYIN0, GPIO_FN_MSIOF0_RSCK,
-	GPIO_FN_A21_EA21, GPIO_FN_PORT67_KEYIN1, GPIO_FN_MSIOF0_RSYNC,
-	GPIO_FN_A22_EA22, GPIO_FN_PORT68_KEYIN2, GPIO_FN_MSIOF0_MCK0,
-	GPIO_FN_A23_EA23, GPIO_FN_PORT69_KEYIN3, GPIO_FN_MSIOF0_MCK1,
-	GPIO_FN_A24_EA24, GPIO_FN_PORT70_KEYIN4, GPIO_FN_MSIOF0_RXD,
-	GPIO_FN_A25_EA25, GPIO_FN_PORT71_KEYIN5, GPIO_FN_MSIOF0_SS2,
-	GPIO_FN_A26, GPIO_FN_PORT72_KEYIN6,
-	GPIO_FN_D0_ED0_NAF0,
-	GPIO_FN_D1_ED1_NAF1,
-	GPIO_FN_D2_ED2_NAF2,
-	GPIO_FN_D3_ED3_NAF3,
-	GPIO_FN_D4_ED4_NAF4,
-	GPIO_FN_D5_ED5_NAF5,
-	GPIO_FN_D6_ED6_NAF6,
-	GPIO_FN_D7_ED7_NAF7,
-	GPIO_FN_D8_ED8_NAF8,
-	GPIO_FN_D9_ED9_NAF9,
-	GPIO_FN_D10_ED10_NAF10,
-	GPIO_FN_D11_ED11_NAF11,
-	GPIO_FN_D12_ED12_NAF12,
-	GPIO_FN_D13_ED13_NAF13,
-	GPIO_FN_D14_ED14_NAF14,
-	GPIO_FN_D15_ED15_NAF15,
-	GPIO_FN_CS4,
-	GPIO_FN_CS5A, GPIO_FN_FMSICK,
-	GPIO_FN_CS5B, GPIO_FN_FCE1,
-
-	/* 55-3 (FN) */
-	GPIO_FN_CS6B, GPIO_FN_XCS2, GPIO_FN_CS6A, GPIO_FN_DACK0,
-	GPIO_FN_FCE0,
-	GPIO_FN_WAIT, GPIO_FN_DREQ0,
-	GPIO_FN_RD_XRD,
-	GPIO_FN_WE0_XWR0_FWE,
-	GPIO_FN_WE1_XWR1,
-	GPIO_FN_FRB,
-	GPIO_FN_CKO,
-	GPIO_FN_NBRSTOUT,
-	GPIO_FN_NBRST,
-	GPIO_FN_GPS_EPPSIN,
-	GPIO_FN_LATCHPULSE,
-	GPIO_FN_LTESIGNAL,
-	GPIO_FN_LEGACYSTATE,
-	GPIO_FN_TCKON,
-	GPIO_FN_VIO_VD, GPIO_FN_PORT128_KEYOUT0, GPIO_FN_IPORT0,
-	GPIO_FN_VIO_HD, GPIO_FN_PORT129_KEYOUT1, GPIO_FN_IPORT1,
-	GPIO_FN_VIO_D0, GPIO_FN_PORT130_KEYOUT2, GPIO_FN_PORT130_MSIOF2_RXD,
-	GPIO_FN_VIO_D1, GPIO_FN_PORT131_KEYOUT3, GPIO_FN_PORT131_MSIOF2_SS1,
-	GPIO_FN_VIO_D2, GPIO_FN_PORT132_KEYOUT4, GPIO_FN_PORT132_MSIOF2_SS2,
-	GPIO_FN_VIO_D3, GPIO_FN_PORT133_KEYOUT5, GPIO_FN_PORT133_MSIOF2_TSYNC,
-	GPIO_FN_VIO_D4, GPIO_FN_PORT134_KEYIN0, GPIO_FN_PORT134_MSIOF2_TXD,
-	GPIO_FN_VIO_D5, GPIO_FN_PORT135_KEYIN1, GPIO_FN_PORT135_MSIOF2_TSCK,
-	GPIO_FN_VIO_D6, GPIO_FN_PORT136_KEYIN2,
-	GPIO_FN_VIO_D7, GPIO_FN_PORT137_KEYIN3,
-	GPIO_FN_VIO_D8, GPIO_FN_M9_SLCD_A01, GPIO_FN_PORT138_FSIAOMC,
-	GPIO_FN_VIO_D9, GPIO_FN_M10_SLCD_CK1, GPIO_FN_PORT139_FSIAOLR,
-	GPIO_FN_VIO_D10, GPIO_FN_M11_SLCD_SO1, GPIO_FN_TPU0TO2,
-	GPIO_FN_PORT140_FSIAOBT,
-	GPIO_FN_VIO_D11, GPIO_FN_M12_SLCD_CE1, GPIO_FN_TPU0TO3,
-	GPIO_FN_PORT141_FSIAOSLD,
-	GPIO_FN_VIO_D12, GPIO_FN_M13_BSW, GPIO_FN_PORT142_FSIACK,
-	GPIO_FN_VIO_D13, GPIO_FN_M14_GSW, GPIO_FN_PORT143_FSIAILR,
-	GPIO_FN_VIO_D14, GPIO_FN_M15_RSW, GPIO_FN_PORT144_FSIAIBT,
-	GPIO_FN_VIO_D15, GPIO_FN_TPU1TO3, GPIO_FN_PORT145_FSIAISLD,
-	GPIO_FN_VIO_CLK, GPIO_FN_PORT146_KEYIN4, GPIO_FN_IPORT2,
-	GPIO_FN_VIO_FIELD, GPIO_FN_PORT147_KEYIN5,
-	GPIO_FN_VIO_CKO, GPIO_FN_PORT148_KEYIN6,
-	GPIO_FN_A27, GPIO_FN_RDWR_XWE, GPIO_FN_MFG0_IN1,
-	GPIO_FN_MFG0_IN2,
-	GPIO_FN_TS_SPSYNC3, GPIO_FN_MSIOF2_RSCK,
-	GPIO_FN_TS_SDAT3, GPIO_FN_MSIOF2_RSYNC,
-	GPIO_FN_TPU1TO2, GPIO_FN_TS_SDEN3, GPIO_FN_PORT153_MSIOF2_SS1,
-	GPIO_FN_SOUT3, GPIO_FN_SCIFA2_TXD1, GPIO_FN_MSIOF2_MCK0,
-	GPIO_FN_SIN3, GPIO_FN_SCIFA2_RXD1, GPIO_FN_MSIOF2_MCK1,
-	GPIO_FN_XRTS3, GPIO_FN_SCIFA2_RTS1, GPIO_FN_PORT156_MSIOF2_SS2,
-	GPIO_FN_XCTS3, GPIO_FN_SCIFA2_CTS1, GPIO_FN_PORT157_MSIOF2_RXD,
-
-	/* 55-4 (FN) */
-	GPIO_FN_DINT, GPIO_FN_SCIFA2_SCK1, GPIO_FN_TS_SCK3,
-	GPIO_FN_PORT159_SCIFB_SCK, GPIO_FN_PORT159_SCIFA5_SCK, GPIO_FN_NMI,
-	GPIO_FN_PORT160_SCIFB_TXD, GPIO_FN_PORT160_SCIFA5_TXD, GPIO_FN_SOUT0,
-	GPIO_FN_PORT161_SCIFB_CTS, GPIO_FN_PORT161_SCIFA5_CTS, GPIO_FN_XCTS0,
-	GPIO_FN_MFG3_IN2,
-	GPIO_FN_PORT162_SCIFB_RXD, GPIO_FN_PORT162_SCIFA5_RXD, GPIO_FN_SIN0,
-	GPIO_FN_MFG3_IN1,
-	GPIO_FN_PORT163_SCIFB_RTS, GPIO_FN_PORT163_SCIFA5_RTS, GPIO_FN_XRTS0,
-	GPIO_FN_MFG3_OUT1,
-	GPIO_FN_TPU3TO0,
-	GPIO_FN_LCDD0, GPIO_FN_PORT192_KEYOUT0, GPIO_FN_EXT_CKI,
-	GPIO_FN_LCDD1, GPIO_FN_PORT193_KEYOUT1, GPIO_FN_PORT193_SCIFA5_CTS,
-	GPIO_FN_BBIF2_TSYNC1,
-	GPIO_FN_LCDD2, GPIO_FN_PORT194_KEYOUT2, GPIO_FN_PORT194_SCIFA5_RTS,
-	GPIO_FN_BBIF2_TSCK1,
-	GPIO_FN_LCDD3, GPIO_FN_PORT195_KEYOUT3, GPIO_FN_PORT195_SCIFA5_RXD,
-	GPIO_FN_BBIF2_TXD1,
-	GPIO_FN_LCDD4, GPIO_FN_PORT196_KEYOUT4, GPIO_FN_PORT196_SCIFA5_TXD,
-	GPIO_FN_LCDD5, GPIO_FN_PORT197_KEYOUT5, GPIO_FN_PORT197_SCIFA5_SCK,
-	GPIO_FN_MFG2_OUT2, GPIO_FN_TPU2TO1,
-	GPIO_FN_LCDD6, GPIO_FN_XWR2,
-	GPIO_FN_LCDD7, GPIO_FN_TPU4TO1, GPIO_FN_MFG4_OUT2, GPIO_FN_XWR3,
-	GPIO_FN_LCDD8, GPIO_FN_PORT200_KEYIN0, GPIO_FN_VIO_DR0, GPIO_FN_D16,
-	GPIO_FN_ED16,
-	GPIO_FN_LCDD9, GPIO_FN_PORT201_KEYIN1, GPIO_FN_VIO_DR1, GPIO_FN_D17,
-	GPIO_FN_ED17,
-	GPIO_FN_LCDD10, GPIO_FN_PORT202_KEYIN2, GPIO_FN_VIO_DR2, GPIO_FN_D18,
-	GPIO_FN_ED18,
-	GPIO_FN_LCDD11, GPIO_FN_PORT203_KEYIN3, GPIO_FN_VIO_DR3, GPIO_FN_D19,
-	GPIO_FN_ED19,
-	GPIO_FN_LCDD12, GPIO_FN_PORT204_KEYIN4, GPIO_FN_VIO_DR4, GPIO_FN_D20,
-	GPIO_FN_ED20,
-	GPIO_FN_LCDD13, GPIO_FN_PORT205_KEYIN5, GPIO_FN_VIO_DR5, GPIO_FN_D21,
-	GPIO_FN_ED21,
-	GPIO_FN_LCDD14, GPIO_FN_PORT206_KEYIN6, GPIO_FN_VIO_DR6, GPIO_FN_D22,
-	GPIO_FN_ED22,
-	GPIO_FN_LCDD15, GPIO_FN_PORT207_MSIOF0L_SS1, GPIO_FN_PORT207_KEYOUT0,
-	GPIO_FN_VIO_DR7,
-	GPIO_FN_D23, GPIO_FN_ED23,
-	GPIO_FN_LCDD16, GPIO_FN_PORT208_MSIOF0L_SS2, GPIO_FN_PORT208_KEYOUT1,
-	GPIO_FN_VIO_VDR,
-	GPIO_FN_D24, GPIO_FN_ED24,
-	GPIO_FN_LCDD17, GPIO_FN_PORT209_KEYOUT2, GPIO_FN_VIO_HDR, GPIO_FN_D25,
-	GPIO_FN_ED25,
-	GPIO_FN_LCDD18, GPIO_FN_DREQ2, GPIO_FN_PORT210_MSIOF0L_SS1, GPIO_FN_D26,
-	GPIO_FN_ED26,
-	GPIO_FN_LCDD19, GPIO_FN_PORT211_MSIOF0L_SS2, GPIO_FN_D27, GPIO_FN_ED27,
-	GPIO_FN_LCDD20, GPIO_FN_TS_SPSYNC1, GPIO_FN_MSIOF0L_MCK0, GPIO_FN_D28,
-	GPIO_FN_ED28,
-	GPIO_FN_LCDD21, GPIO_FN_TS_SDAT1, GPIO_FN_MSIOF0L_MCK1, GPIO_FN_D29,
-	GPIO_FN_ED29,
-	GPIO_FN_LCDD22, GPIO_FN_TS_SDEN1, GPIO_FN_MSIOF0L_RSCK, GPIO_FN_D30,
-	GPIO_FN_ED30,
-	GPIO_FN_LCDD23, GPIO_FN_TS_SCK1, GPIO_FN_MSIOF0L_RSYNC, GPIO_FN_D31,
-	GPIO_FN_ED31,
-	GPIO_FN_LCDDCK, GPIO_FN_LCDWR, GPIO_FN_PORT216_KEYOUT3,
-	GPIO_FN_VIO_CLKR,
-	GPIO_FN_LCDRD, GPIO_FN_DACK2, GPIO_FN_MSIOF0L_TSYNC,
-	GPIO_FN_LCDHSYN, GPIO_FN_LCDCS, GPIO_FN_LCDCS2, GPIO_FN_DACK3,
-	GPIO_FN_PORT218_VIO_CKOR, GPIO_FN_PORT218_KEYOUT4,
-	GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_TSCK,
-	GPIO_FN_LCDVSYN, GPIO_FN_LCDVSYN2, GPIO_FN_PORT220_KEYOUT5,
-	GPIO_FN_LCDLCLK, GPIO_FN_DREQ1, GPIO_FN_PWEN, GPIO_FN_MSIOF0L_RXD,
-	GPIO_FN_LCDDON, GPIO_FN_LCDDON2, GPIO_FN_DACK1, GPIO_FN_OVCN,
-	GPIO_FN_MSIOF0L_TXD,
-	GPIO_FN_SCIFA1_TXD, GPIO_FN_OVCN2,
-	GPIO_FN_EXTLP, GPIO_FN_SCIFA1_SCK, GPIO_FN_USBTERM,
-	GPIO_FN_PORT226_VIO_CKO2,
-	GPIO_FN_SCIFA1_RTS, GPIO_FN_IDIN,
-	GPIO_FN_SCIFA1_RXD,
-	GPIO_FN_SCIFA1_CTS, GPIO_FN_MFG1_IN1,
-	GPIO_FN_MSIOF1_TXD, GPIO_FN_SCIFA2_TXD2, GPIO_FN_PORT230_FSIAOMC,
-	GPIO_FN_MSIOF1_TSYNC, GPIO_FN_SCIFA2_CTS2, GPIO_FN_PORT231_FSIAOLR,
-	GPIO_FN_MSIOF1_TSCK, GPIO_FN_SCIFA2_SCK2, GPIO_FN_PORT232_FSIAOBT,
-	GPIO_FN_MSIOF1_RXD, GPIO_FN_SCIFA2_RXD2, GPIO_FN_GPS_VCOTRIG,
-	GPIO_FN_PORT233_FSIACK,
-	GPIO_FN_MSIOF1_RSCK, GPIO_FN_SCIFA2_RTS2, GPIO_FN_PORT234_FSIAOSLD,
-	GPIO_FN_MSIOF1_RSYNC, GPIO_FN_OPORT0, GPIO_FN_MFG1_IN2,
-	GPIO_FN_PORT235_FSIAILR,
-	GPIO_FN_MSIOF1_MCK0, GPIO_FN_I2C_SDA2, GPIO_FN_PORT236_FSIAIBT,
-	GPIO_FN_MSIOF1_MCK1, GPIO_FN_I2C_SCL2, GPIO_FN_PORT237_FSIAISLD,
-	GPIO_FN_MSIOF1_SS1, GPIO_FN_EDBGREQ3,
-
-	/* 55-5 (FN) */
-	GPIO_FN_MSIOF1_SS2,
-	GPIO_FN_SCIFA6_TXD,
-	GPIO_FN_PORT241_IRDA_OUT, GPIO_FN_PORT241_IROUT, GPIO_FN_MFG4_OUT1,
-	GPIO_FN_TPU4TO0,
-	GPIO_FN_PORT242_IRDA_IN, GPIO_FN_MFG4_IN2,
-	GPIO_FN_PORT243_IRDA_FIRSEL, GPIO_FN_PORT243_VIO_CKO2,
-	GPIO_FN_PORT244_SCIFA5_CTS, GPIO_FN_MFG2_IN1, GPIO_FN_PORT244_SCIFB_CTS,
-	GPIO_FN_PORT244_MSIOF2_RXD,
-	GPIO_FN_PORT245_SCIFA5_RTS, GPIO_FN_MFG2_IN2, GPIO_FN_PORT245_SCIFB_RTS,
-	GPIO_FN_PORT245_MSIOF2_TXD,
-	GPIO_FN_PORT246_SCIFA5_RXD, GPIO_FN_MFG1_OUT1,
-	GPIO_FN_PORT246_SCIFB_RXD, GPIO_FN_TPU1TO0,
-	GPIO_FN_PORT247_SCIFA5_TXD, GPIO_FN_MFG3_OUT2,
-	GPIO_FN_PORT247_SCIFB_TXD, GPIO_FN_TPU3TO1,
-	GPIO_FN_PORT248_SCIFA5_SCK, GPIO_FN_MFG2_OUT1,
-	GPIO_FN_PORT248_SCIFB_SCK, GPIO_FN_TPU2TO0,
-	GPIO_FN_PORT248_MSIOF2_TSCK,
-	GPIO_FN_PORT249_IROUT, GPIO_FN_MFG4_IN1, GPIO_FN_PORT249_MSIOF2_TSYNC,
-	GPIO_FN_SDHICLK0, GPIO_FN_TCK2_SWCLK_MC0,
-	GPIO_FN_SDHICD0,
-	GPIO_FN_SDHID0_0, GPIO_FN_TMS2_SWDIO_MC0,
-	GPIO_FN_SDHID0_1, GPIO_FN_TDO2_SWO0_MC0,
-	GPIO_FN_SDHID0_2, GPIO_FN_TDI2,
-	GPIO_FN_SDHID0_3, GPIO_FN_RTCK2_SWO1_MC0,
-	GPIO_FN_SDHICMD0, GPIO_FN_TRST2,
-	GPIO_FN_SDHIWP0, GPIO_FN_EDBGREQ2,
-	GPIO_FN_SDHICLK1, GPIO_FN_TCK3_SWCLK_MC1,
-	GPIO_FN_SDHID1_0, GPIO_FN_M11_SLCD_SO2, GPIO_FN_TS_SPSYNC2,
-	GPIO_FN_TMS3_SWDIO_MC1,
-	GPIO_FN_SDHID1_1, GPIO_FN_M9_SLCD_A02, GPIO_FN_TS_SDAT2,
-	GPIO_FN_TDO3_SWO0_MC1,
-	GPIO_FN_SDHID1_2, GPIO_FN_M10_SLCD_CK2, GPIO_FN_TS_SDEN2, GPIO_FN_TDI3,
-	GPIO_FN_SDHID1_3, GPIO_FN_M12_SLCD_CE2, GPIO_FN_TS_SCK2,
-	GPIO_FN_RTCK3_SWO1_MC1,
-	GPIO_FN_SDHICMD1, GPIO_FN_TRST3,
-	GPIO_FN_RESETOUTS,
-};
-
-#endif /* __ASM_SH7377_H__ */
diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c
deleted file mode 100644
index 5bf7764..0000000
--- a/arch/arm/mach-shmobile/intc-sh7367.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * sh7367 processor support - INTC hardware block
- *
- * Copyright (C) 2010  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/sh_intc.h>
-#include <mach/intc.h>
-#include <mach/irqs.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-enum {
-	UNUSED_INTCA = 0,
-	ENABLED,
-	DISABLED,
-
-	/* interrupt sources INTCA */
-	DIRC,
-	CRYPT1_ERR, CRYPT2_STD,
-	IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
-	ARM11_IRQPMU, ARM11_COMMTX, ARM11_COMMRX,
-	ETM11_ACQCMP, ETM11_FULL,
-	MFI_MFIM, MFI_MFIS,
-	BBIF1, BBIF2,
-	USBDMAC_USHDMI,
-	USBHS_USHI0, USBHS_USHI1,
-	CMT1_CMT10, CMT1_CMT11, CMT1_CMT12, CMT1_CMT13, CMT2, CMT3,
-	KEYSC_KEY,
-	SCIFA0, SCIFA1, SCIFA2, SCIFA3,
-	MSIOF2, MSIOF1,
-	SCIFA4, SCIFA5, SCIFB,
-	FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
-	SDHI0,
-	SDHI1,
-	MSU_MSU, MSU_MSU2,
-	IREM,
-	SIU,
-	SPU,
-	IRDA,
-	TPU0, TPU1, TPU2, TPU3, TPU4,
-	LCRC,
-	PINT1, PINT2,
-	TTI20,
-	MISTY,
-	DDM,
-	SDHI2,
-	RWDT0, RWDT1,
-	DMAC_1_DEI0, DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3,
-	DMAC_2_DEI4, DMAC_2_DEI5, DMAC_2_DADERR,
-	DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
-	DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
-	DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
-	DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
-
-	/* interrupt groups INTCA */
-	DMAC_1, DMAC_2,	DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2,
-	ETM11, ARM11, USBHS, FLCTL, IIC1
-};
-
-static struct intc_vect intca_vectors[] __initdata = {
-	INTC_VECT(DIRC, 0x0560),
-	INTC_VECT(CRYPT1_ERR, 0x05e0),
-	INTC_VECT(CRYPT2_STD, 0x0700),
-	INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
-	INTC_VECT(IIC1_WAITI1, 0x07c0), INTC_VECT(IIC1_DTEI1, 0x07e0),
-	INTC_VECT(ARM11_IRQPMU, 0x0800), INTC_VECT(ARM11_COMMTX, 0x0840),
-	INTC_VECT(ARM11_COMMRX, 0x0860),
-	INTC_VECT(ETM11_ACQCMP, 0x0880), INTC_VECT(ETM11_FULL, 0x08a0),
-	INTC_VECT(MFI_MFIM, 0x0900), INTC_VECT(MFI_MFIS, 0x0920),
-	INTC_VECT(BBIF1, 0x0940), INTC_VECT(BBIF2, 0x0960),
-	INTC_VECT(USBDMAC_USHDMI, 0x0a00),
-	INTC_VECT(USBHS_USHI0, 0x0a20), INTC_VECT(USBHS_USHI1, 0x0a40),
-	INTC_VECT(CMT1_CMT10, 0x0b00), INTC_VECT(CMT1_CMT11, 0x0b20),
-	INTC_VECT(CMT1_CMT12, 0x0b40), INTC_VECT(CMT1_CMT13, 0x0b60),
-	INTC_VECT(CMT2, 0x0b80), INTC_VECT(CMT3, 0x0ba0),
-	INTC_VECT(KEYSC_KEY, 0x0be0),
-	INTC_VECT(SCIFA0, 0x0c00), INTC_VECT(SCIFA1, 0x0c20),
-	INTC_VECT(SCIFA2, 0x0c40), INTC_VECT(SCIFA3, 0x0c60),
-	INTC_VECT(MSIOF2, 0x0c80), INTC_VECT(MSIOF1, 0x0d00),
-	INTC_VECT(SCIFA4, 0x0d20), INTC_VECT(SCIFA5, 0x0d40),
-	INTC_VECT(SCIFB, 0x0d60),
-	INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
-	INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
-	INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
-	INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
-	INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
-	INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0),
-	INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40),
-	INTC_VECT(IREM, 0x0f60),
-	INTC_VECT(SIU, 0x0fa0),
-	INTC_VECT(SPU, 0x0fc0),
-	INTC_VECT(IRDA, 0x0480),
-	INTC_VECT(TPU0, 0x04a0), INTC_VECT(TPU1, 0x04c0),
-	INTC_VECT(TPU2, 0x04e0), INTC_VECT(TPU3, 0x0500),
-	INTC_VECT(TPU4, 0x0520),
-	INTC_VECT(LCRC, 0x0540),
-	INTC_VECT(PINT1, 0x1000), INTC_VECT(PINT2, 0x1020),
-	INTC_VECT(TTI20, 0x1100),
-	INTC_VECT(MISTY, 0x1120),
-	INTC_VECT(DDM, 0x1140),
-	INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220),
-	INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260),
-	INTC_VECT(RWDT0, 0x1280), INTC_VECT(RWDT1, 0x12a0),
-	INTC_VECT(DMAC_1_DEI0, 0x2000), INTC_VECT(DMAC_1_DEI1, 0x2020),
-	INTC_VECT(DMAC_1_DEI2, 0x2040), INTC_VECT(DMAC_1_DEI3, 0x2060),
-	INTC_VECT(DMAC_2_DEI4, 0x2080), INTC_VECT(DMAC_2_DEI5, 0x20a0),
-	INTC_VECT(DMAC_2_DADERR, 0x20c0),
-	INTC_VECT(DMAC2_1_DEI0, 0x2100), INTC_VECT(DMAC2_1_DEI1, 0x2120),
-	INTC_VECT(DMAC2_1_DEI2, 0x2140), INTC_VECT(DMAC2_1_DEI3, 0x2160),
-	INTC_VECT(DMAC2_2_DEI4, 0x2180), INTC_VECT(DMAC2_2_DEI5, 0x21a0),
-	INTC_VECT(DMAC2_2_DADERR, 0x21c0),
-	INTC_VECT(DMAC3_1_DEI0, 0x2200), INTC_VECT(DMAC3_1_DEI1, 0x2220),
-	INTC_VECT(DMAC3_1_DEI2, 0x2240), INTC_VECT(DMAC3_1_DEI3, 0x2260),
-	INTC_VECT(DMAC3_2_DEI4, 0x2280), INTC_VECT(DMAC3_2_DEI5, 0x22a0),
-	INTC_VECT(DMAC3_2_DADERR, 0x22c0),
-};
-
-static struct intc_group intca_groups[] __initdata = {
-	INTC_GROUP(DMAC_1, DMAC_1_DEI0,
-		   DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3),
-	INTC_GROUP(DMAC_2, DMAC_2_DEI4,
-		   DMAC_2_DEI5, DMAC_2_DADERR),
-	INTC_GROUP(DMAC2_1, DMAC2_1_DEI0,
-		   DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
-	INTC_GROUP(DMAC2_2, DMAC2_2_DEI4,
-		   DMAC2_2_DEI5, DMAC2_2_DADERR),
-	INTC_GROUP(DMAC3_1, DMAC3_1_DEI0,
-		   DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
-	INTC_GROUP(DMAC3_2, DMAC3_2_DEI4,
-		   DMAC3_2_DEI5, DMAC3_2_DADERR),
-	INTC_GROUP(ETM11, ETM11_ACQCMP, ETM11_FULL),
-	INTC_GROUP(ARM11, ARM11_IRQPMU, ARM11_COMMTX, ARM11_COMMTX),
-	INTC_GROUP(USBHS, USBHS_USHI0, USBHS_USHI1),
-	INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
-		   FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
-	INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
-};
-
-static struct intc_mask_reg intca_mask_registers[] __initdata = {
-	{ 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
-	  { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
-	    ARM11_IRQPMU, 0, ARM11_COMMTX, ARM11_COMMRX } },
-	{ 0xe6940084, 0xe69400c4, 8, /* IMR1A / IMCR1A */
-	  { CRYPT1_ERR, CRYPT2_STD, DIRC, 0,
-	    DMAC_1_DEI3, DMAC_1_DEI2, DMAC_1_DEI1, DMAC_1_DEI0 } },
-	{ 0xe6940088, 0xe69400c8, 8, /* IMR2A / IMCR2A */
-	  { PINT1, PINT2, 0, 0,
-	    BBIF1, BBIF2, MFI_MFIS, MFI_MFIM } },
-	{ 0xe694008c, 0xe69400cc, 8, /* IMR3A / IMCR3A */
-	  { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
-	    DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
-	{ 0xe6940090, 0xe69400d0, 8, /* IMR4A / IMCR4A */
-	  { DDM, 0, 0, 0,
-	    0, 0, ETM11_FULL, ETM11_ACQCMP } },
-	{ 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
-	  { KEYSC_KEY, DMAC_2_DADERR, DMAC_2_DEI5, DMAC_2_DEI4,
-	    SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
-	{ 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
-	  { SCIFB, SCIFA5, SCIFA4, MSIOF1,
-	    0, 0, MSIOF2, 0 } },
-	{ 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
-	  { DISABLED, ENABLED, ENABLED, ENABLED,
-	    FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
-	{ 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
-	  { DISABLED, ENABLED, ENABLED, ENABLED,
-	    TTI20, USBDMAC_USHDMI, SPU, SIU } },
-	{ 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
-	  { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
-	    CMT2, USBHS_USHI1, USBHS_USHI0, 0 } },
-	{ 0xe69400a8, 0xe69400e8, 8, /* IMR10A / IMCR10A */
-	  { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
-	    0, 0, 0, 0 } },
-	{ 0xe69400ac, 0xe69400ec, 8, /* IMR11A / IMCR11A */
-	  { IIC1_DTEI1, IIC1_WAITI1, IIC1_TACKI1, IIC1_ALI1,
-	    LCRC, MSU_MSU2, IREM, MSU_MSU } },
-	{ 0xe69400b0, 0xe69400f0, 8, /* IMR12A / IMCR12A */
-	  { 0, 0, TPU0, TPU1,
-	    TPU2, TPU3, TPU4, 0 } },
-	{ 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
-	  { DISABLED, ENABLED, ENABLED, ENABLED,
-	    MISTY, CMT3, RWDT1, RWDT0 } },
-};
-
-static struct intc_prio_reg intca_prio_registers[] __initdata = {
-	{ 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, LCRC } },
-	{ 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, ETM11, BBIF1, BBIF2 } },
-	{ 0xe6940008, 0, 16, 4, /* IPRCA */ { CRYPT1_ERR, CRYPT2_STD,
-					      CMT1_CMT11, ARM11 } },
-	{ 0xe694000c, 0, 16, 4, /* IPRDA */ { PINT1, PINT2,
-					      CMT1_CMT12, TPU4 } },
-	{ 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC_1, MFI_MFIS,
-					      MFI_MFIM, USBHS } },
-	{ 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC_KEY, DMAC_2,
-					      0, CMT1_CMT10 } },
-	{ 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
-					      SCIFA2, SCIFA3 } },
-	{ 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBDMAC_USHDMI,
-					      FLCTL, SDHI0 } },
-	{ 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4, MSU_MSU, IIC1 } },
-	{ 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2, SIU, TTI20 } },
-	{ 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_CMT13, IREM, SDHI1 } },
-	{ 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, TPU1, TPU2, TPU3 } },
-	{ 0xe6940030, 0, 16, 4, /* IPRMA */ { MISTY, CMT3, RWDT1, RWDT0 } },
-	{ 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, SPU, DDM } },
-	{ 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, SDHI2 } },
-};
-
-static struct intc_desc intca_desc __initdata = {
-	.name = "sh7367-intca",
-	.force_enable = ENABLED,
-	.force_disable = DISABLED,
-	.hw = INTC_HW_DESC(intca_vectors, intca_groups,
-			   intca_mask_registers, intca_prio_registers,
-			   NULL, NULL),
-};
-
-INTC_IRQ_PINS_16(intca_irq_pins, 0xe6900000,
-		 INTC_VECT, "sh7367-intca-irq-pins");
-
-enum {
-	UNUSED_INTCS = 0,
-
-	INTCS,
-
-	/* interrupt sources INTCS */
-	VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3,
-	VIO3_VOU,
-	RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3,
-	VIO1_CEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2,
-	VPU,
-	SGX530,
-	_2DDMAC_2DDM0, _2DDMAC_2DDM1, _2DDMAC_2DDM2, _2DDMAC_2DDM3,
-	IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
-	IPMMU_IPMMUB, IPMMU_IPMMUS,
-	RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR,
-	MSIOF,
-	IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
-	TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
-	CMT,
-	TSIF,
-	IPMMUI,
-	MVI3,
-	ICB,
-	PEP,
-	ASA,
-	BEM,
-	VE2HO,
-	HQE,
-	JPEG,
-	LCDC,
-
-	/* interrupt groups INTCS */
-	_2DDMAC, RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2,
-};
-
-static struct intc_vect intcs_vectors[] = {
-	INTCS_VECT(VIO2_VEU0, 0x700), INTCS_VECT(VIO2_VEU1, 0x720),
-	INTCS_VECT(VIO2_VEU2, 0x740), INTCS_VECT(VIO2_VEU3, 0x760),
-	INTCS_VECT(VIO3_VOU, 0x780),
-	INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820),
-	INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860),
-	INTCS_VECT(VIO1_CEU, 0x880), INTCS_VECT(VIO1_BEU0, 0x8a0),
-	INTCS_VECT(VIO1_BEU1, 0x8c0), INTCS_VECT(VIO1_BEU2, 0x8e0),
-	INTCS_VECT(VPU, 0x980),
-	INTCS_VECT(SGX530, 0x9e0),
-	INTCS_VECT(_2DDMAC_2DDM0, 0xa00), INTCS_VECT(_2DDMAC_2DDM1, 0xa20),
-	INTCS_VECT(_2DDMAC_2DDM2, 0xa40), INTCS_VECT(_2DDMAC_2DDM3, 0xa60),
-	INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0),
-	INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0),
-	INTCS_VECT(IPMMU_IPMMUB, 0xb20), INTCS_VECT(IPMMU_IPMMUS, 0xb60),
-	INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0),
-	INTCS_VECT(RTDMAC_2_DADERR, 0xbc0),
-	INTCS_VECT(MSIOF, 0xd20),
-	INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20),
-	INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60),
-	INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0),
-	INTCS_VECT(TMU_TUNI2, 0xec0),
-	INTCS_VECT(CMT, 0xf00),
-	INTCS_VECT(TSIF, 0xf20),
-	INTCS_VECT(IPMMUI, 0xf60),
-	INTCS_VECT(MVI3, 0x420),
-	INTCS_VECT(ICB, 0x480),
-	INTCS_VECT(PEP, 0x4a0),
-	INTCS_VECT(ASA, 0x4c0),
-	INTCS_VECT(BEM, 0x4e0),
-	INTCS_VECT(VE2HO, 0x520),
-	INTCS_VECT(HQE, 0x540),
-	INTCS_VECT(JPEG, 0x560),
-	INTCS_VECT(LCDC, 0x580),
-
-	INTC_VECT(INTCS, 0xf80),
-};
-
-static struct intc_group intcs_groups[] __initdata = {
-	INTC_GROUP(_2DDMAC, _2DDMAC_2DDM0, _2DDMAC_2DDM1,
-		   _2DDMAC_2DDM2, _2DDMAC_2DDM3),
-	INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1,
-		   RTDMAC_1_DEI2, RTDMAC_1_DEI3),
-	INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR),
-	INTC_GROUP(VEU, VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3),
-	INTC_GROUP(BEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2),
-	INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0),
-	INTC_GROUP(IPMMU, IPMMU_IPMMUS, IPMMU_IPMMUB),
-	INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2),
-};
-
-static struct intc_mask_reg intcs_mask_registers[] = {
-	{ 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */
-	  { VIO1_BEU2, VIO1_BEU1, VIO1_BEU0, VIO1_CEU,
-	    VIO2_VEU3, VIO2_VEU2, VIO2_VEU1, VIO2_VEU0 } },
-	{ 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */
-	  { VIO3_VOU, 0, VE2HO, VPU,
-	    0, 0, 0, 0 } },
-	{ 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */
-	  { _2DDMAC_2DDM3, _2DDMAC_2DDM2, _2DDMAC_2DDM1, _2DDMAC_2DDM0,
-	    BEM, ASA, PEP, ICB } },
-	{ 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */
-	  { 0, 0, MVI3, 0,
-	    JPEG, HQE, 0, LCDC } },
-	{ 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */
-	  { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4,
-	    RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } },
-	{ 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */
-	  { 0, 0, MSIOF, 0,
-	    SGX530, 0, 0, 0 } },
-	{ 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */
-	  { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
-	    0, 0, 0, 0 } },
-	{ 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */
-	  { 0, 0, 0, CMT,
-	    IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } },
-	{ 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */
-	  { IPMMU_IPMMUS, 0, IPMMU_IPMMUB, 0,
-	    0, 0, 0, 0 } },
-	{ 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */
-	  { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0,
-	    0, 0, IPMMUI, TSIF } },
-	{ 0xffd20104, 0, 16, /* INTAMASK */
-	  { 0, 0, 0, 0, 0, 0, 0, 0,
-	    0, 0, 0, 0, 0, 0, 0, INTCS } },
-};
-
-/* Priority is needed for INTCA to receive the INTCS interrupt */
-static struct intc_prio_reg intcs_prio_registers[] = {
-	{ 0xffd20000, 0, 16, 4, /* IPRAS */ { 0, MVI3, _2DDMAC, ICB } },
-	{ 0xffd20004, 0, 16, 4, /* IPRBS */ { JPEG, LCDC, 0, 0 } },
-	{ 0xffd20008, 0, 16, 4, /* IPRCS */ { BBIF2, 0, 0, 0 } },
-	{ 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, VIO1_CEU, 0, VPU } },
-	{ 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT } },
-	{ 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1,
-					      TMU_TUNI2, 0 } },
-	{ 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, VIO3_VOU, VEU, BEU } },
-	{ 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF, IIC0 } },
-	{ 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, SGX530, 0, 0 } },
-	{ 0xffd20028, 0, 16, 4, /* IPRKS */ { BEM, ASA, IPMMUI, PEP } },
-	{ 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, VE2HO, HQE } },
-	{ 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } },
-};
-
-static struct resource intcs_resources[] __initdata = {
-	[0] = {
-		.start	= 0xffd20000,
-		.end	= 0xffd2ffff,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct intc_desc intcs_desc __initdata = {
-	.name = "sh7367-intcs",
-	.resource = intcs_resources,
-	.num_resources = ARRAY_SIZE(intcs_resources),
-	.hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
-			   intcs_prio_registers, NULL, NULL),
-};
-
-static void intcs_demux(unsigned int irq, struct irq_desc *desc)
-{
-	void __iomem *reg = (void *)irq_get_handler_data(irq);
-	unsigned int evtcodeas = ioread32(reg);
-
-	generic_handle_irq(intcs_evt2irq(evtcodeas));
-}
-
-void __init sh7367_init_irq(void)
-{
-	void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
-
-	register_intc_controller(&intca_desc);
-	register_intc_controller(&intca_irq_pins_desc);
-	register_intc_controller(&intcs_desc);
-
-	/* demux using INTEVTSA */
-	irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa);
-	irq_set_chained_handler(evt2irq(0xf80), intcs_demux);
-}
diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c
deleted file mode 100644
index b84a460..0000000
--- a/arch/arm/mach-shmobile/intc-sh7377.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * sh7377 processor support - INTC hardware block
- *
- * Copyright (C) 2010  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/sh_intc.h>
-#include <mach/intc.h>
-#include <mach/irqs.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-enum {
-	UNUSED_INTCA = 0,
-	ENABLED,
-	DISABLED,
-
-	/* interrupt sources INTCA */
-	DIRC,
-	_2DG,
-	CRYPT_STD,
-	IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
-	AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMRX,
-	MFI_MFIM, MFI_MFIS,
-	BBIF1, BBIF2,
-	USBDMAC_USHDMI,
-	USBHS_USHI0, USBHS_USHI1,
-	_3DG_SGX540,
-	CMT1_CMT10, CMT1_CMT11, CMT1_CMT12, CMT1_CMT13, CMT2, CMT3,
-	KEYSC_KEY,
-	SCIFA0, SCIFA1, SCIFA2, SCIFA3,
-	MSIOF2, MSIOF1,
-	SCIFA4, SCIFA5, SCIFB,
-	FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
-	SDHI0,
-	SDHI1,
-	MSU_MSU, MSU_MSU2,
-	IRREM,
-	MSUG,
-	IRDA,
-	TPU0, TPU1, TPU2, TPU3, TPU4,
-	LCRC,
-	PINTCA_PINT1, PINTCA_PINT2,
-	TTI20,
-	MISTY,
-	DDM,
-	RWDT0, RWDT1,
-	DMAC_1_DEI0, DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3,
-	DMAC_2_DEI4, DMAC_2_DEI5, DMAC_2_DADERR,
-	DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
-	DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
-	DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
-	DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
-	SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM,
-	ICUSB_ICUSB0, ICUSB_ICUSB1,
-	ICUDMC_ICUDMC1, ICUDMC_ICUDMC2,
-	SPU2_SPU0, SPU2_SPU1,
-	FSI,
-	FMSI,
-	SCUV,
-	IPMMU_IPMMUB,
-	AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ, AP_ARM_DMAIRQ, AP_ARM_DMASIRQ,
-	MFIS2,
-	CPORTR2S,
-	CMT14, CMT15,
-	SCIFA6,
-
-	/* interrupt groups INTCA */
-	DMAC_1, DMAC_2,	DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
-	AP_ARM1, AP_ARM2, USBHS, SPU2, FLCTL, IIC1,
-	ICUSB, ICUDMC
-};
-
-static struct intc_vect intca_vectors[] __initdata = {
-	INTC_VECT(DIRC, 0x0560),
-	INTC_VECT(_2DG, 0x05e0),
-	INTC_VECT(CRYPT_STD, 0x0700),
-	INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
-	INTC_VECT(IIC1_WAITI1, 0x07c0), INTC_VECT(IIC1_DTEI1, 0x07e0),
-	INTC_VECT(AP_ARM_IRQPMU, 0x0800), INTC_VECT(AP_ARM_COMMTX, 0x0840),
-	INTC_VECT(AP_ARM_COMMRX, 0x0860),
-	INTC_VECT(MFI_MFIM, 0x0900), INTC_VECT(MFI_MFIS, 0x0920),
-	INTC_VECT(BBIF1, 0x0940), INTC_VECT(BBIF2, 0x0960),
-	INTC_VECT(USBDMAC_USHDMI, 0x0a00),
-	INTC_VECT(USBHS_USHI0, 0x0a20), INTC_VECT(USBHS_USHI1, 0x0a40),
-	INTC_VECT(_3DG_SGX540, 0x0a60),
-	INTC_VECT(CMT1_CMT10, 0x0b00), INTC_VECT(CMT1_CMT11, 0x0b20),
-	INTC_VECT(CMT1_CMT12, 0x0b40), INTC_VECT(CMT1_CMT13, 0x0b60),
-	INTC_VECT(CMT2, 0x0b80), INTC_VECT(CMT3, 0x0ba0),
-	INTC_VECT(KEYSC_KEY, 0x0be0),
-	INTC_VECT(SCIFA0, 0x0c00), INTC_VECT(SCIFA1, 0x0c20),
-	INTC_VECT(SCIFA2, 0x0c40), INTC_VECT(SCIFA3, 0x0c60),
-	INTC_VECT(MSIOF2, 0x0c80), INTC_VECT(MSIOF1, 0x0d00),
-	INTC_VECT(SCIFA4, 0x0d20), INTC_VECT(SCIFA5, 0x0d40),
-	INTC_VECT(SCIFB, 0x0d60),
-	INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
-	INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
-	INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
-	INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
-	INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
-	INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0),
-	INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40),
-	INTC_VECT(IRREM, 0x0f60),
-	INTC_VECT(MSUG, 0x0fa0),
-	INTC_VECT(IRDA, 0x0480),
-	INTC_VECT(TPU0, 0x04a0), INTC_VECT(TPU1, 0x04c0),
-	INTC_VECT(TPU2, 0x04e0), INTC_VECT(TPU3, 0x0500),
-	INTC_VECT(TPU4, 0x0520),
-	INTC_VECT(LCRC, 0x0540),
-	INTC_VECT(PINTCA_PINT1, 0x1000), INTC_VECT(PINTCA_PINT2, 0x1020),
-	INTC_VECT(TTI20, 0x1100),
-	INTC_VECT(MISTY, 0x1120),
-	INTC_VECT(DDM, 0x1140),
-	INTC_VECT(RWDT0, 0x1280), INTC_VECT(RWDT1, 0x12a0),
-	INTC_VECT(DMAC_1_DEI0, 0x2000), INTC_VECT(DMAC_1_DEI1, 0x2020),
-	INTC_VECT(DMAC_1_DEI2, 0x2040), INTC_VECT(DMAC_1_DEI3, 0x2060),
-	INTC_VECT(DMAC_2_DEI4, 0x2080), INTC_VECT(DMAC_2_DEI5, 0x20a0),
-	INTC_VECT(DMAC_2_DADERR, 0x20c0),
-	INTC_VECT(DMAC2_1_DEI0, 0x2100), INTC_VECT(DMAC2_1_DEI1, 0x2120),
-	INTC_VECT(DMAC2_1_DEI2, 0x2140), INTC_VECT(DMAC2_1_DEI3, 0x2160),
-	INTC_VECT(DMAC2_2_DEI4, 0x2180), INTC_VECT(DMAC2_2_DEI5, 0x21a0),
-	INTC_VECT(DMAC2_2_DADERR, 0x21c0),
-	INTC_VECT(DMAC3_1_DEI0, 0x2200), INTC_VECT(DMAC3_1_DEI1, 0x2220),
-	INTC_VECT(DMAC3_1_DEI2, 0x2240), INTC_VECT(DMAC3_1_DEI3, 0x2260),
-	INTC_VECT(DMAC3_2_DEI4, 0x2280), INTC_VECT(DMAC3_2_DEI5, 0x22a0),
-	INTC_VECT(DMAC3_2_DADERR, 0x22c0),
-	INTC_VECT(SHWYSTAT_RT, 0x1300), INTC_VECT(SHWYSTAT_HS, 0x1d20),
-	INTC_VECT(SHWYSTAT_COM, 0x1340),
-	INTC_VECT(ICUSB_ICUSB0, 0x1700), INTC_VECT(ICUSB_ICUSB1, 0x1720),
-	INTC_VECT(ICUDMC_ICUDMC1, 0x1780), INTC_VECT(ICUDMC_ICUDMC2, 0x17a0),
-	INTC_VECT(SPU2_SPU0, 0x1800), INTC_VECT(SPU2_SPU1, 0x1820),
-	INTC_VECT(FSI, 0x1840),
-	INTC_VECT(FMSI, 0x1860),
-	INTC_VECT(SCUV, 0x1880),
-	INTC_VECT(IPMMU_IPMMUB, 0x1900),
-	INTC_VECT(AP_ARM_CTIIRQ, 0x1980),
-	INTC_VECT(AP_ARM_DMAEXTERRIRQ, 0x19a0),
-	INTC_VECT(AP_ARM_DMAIRQ, 0x19c0),
-	INTC_VECT(AP_ARM_DMASIRQ, 0x19e0),
-	INTC_VECT(MFIS2, 0x1a00),
-	INTC_VECT(CPORTR2S, 0x1a20),
-	INTC_VECT(CMT14, 0x1a40), INTC_VECT(CMT15, 0x1a60),
-	INTC_VECT(SCIFA6, 0x1a80),
-};
-
-static struct intc_group intca_groups[] __initdata = {
-	INTC_GROUP(DMAC_1, DMAC_1_DEI0,
-		   DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3),
-	INTC_GROUP(DMAC_2, DMAC_2_DEI4,
-		   DMAC_2_DEI5, DMAC_2_DADERR),
-	INTC_GROUP(DMAC2_1, DMAC2_1_DEI0,
-		   DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
-	INTC_GROUP(DMAC2_2, DMAC2_2_DEI4,
-		   DMAC2_2_DEI5, DMAC2_2_DADERR),
-	INTC_GROUP(DMAC3_1, DMAC3_1_DEI0,
-		   DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
-	INTC_GROUP(DMAC3_2, DMAC3_2_DEI4,
-		   DMAC3_2_DEI5, DMAC3_2_DADERR),
-	INTC_GROUP(AP_ARM1, AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMTX),
-	INTC_GROUP(USBHS, USBHS_USHI0, USBHS_USHI1),
-	INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1),
-	INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
-		   FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
-	INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
-	INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
-	INTC_GROUP(ICUSB, ICUSB_ICUSB0, ICUSB_ICUSB1),
-	INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2),
-};
-
-static struct intc_mask_reg intca_mask_registers[] __initdata = {
-	{ 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
-	  { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
-	    AP_ARM_IRQPMU, 0, AP_ARM_COMMTX, AP_ARM_COMMRX } },
-	{ 0xe6940084, 0xe69400c4, 8, /* IMR1A / IMCR1A */
-	  { _2DG, CRYPT_STD, DIRC, 0,
-	    DMAC_1_DEI3, DMAC_1_DEI2, DMAC_1_DEI1, DMAC_1_DEI0 } },
-	{ 0xe6940088, 0xe69400c8, 8, /* IMR2A / IMCR2A */
-	  { PINTCA_PINT1, PINTCA_PINT2, 0, 0,
-	    BBIF1, BBIF2, MFI_MFIS, MFI_MFIM } },
-	{ 0xe694008c, 0xe69400cc, 8, /* IMR3A / IMCR3A */
-	  { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
-	    DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
-	{ 0xe6940090, 0xe69400d0, 8, /* IMR4A / IMCR4A */
-	  { DDM, 0, 0, 0,
-	    0, 0, 0, 0 } },
-	{ 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
-	  { KEYSC_KEY, DMAC_2_DADERR, DMAC_2_DEI5, DMAC_2_DEI4,
-	    SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
-	{ 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
-	  { SCIFB, SCIFA5, SCIFA4, MSIOF1,
-	    0, 0, MSIOF2, 0 } },
-	{ 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
-	  { DISABLED, ENABLED, ENABLED, ENABLED,
-	    FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
-	{ 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
-	  { DISABLED, ENABLED, ENABLED, ENABLED,
-	    TTI20, USBDMAC_USHDMI, 0, MSUG } },
-	{ 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
-	  { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
-	    CMT2, USBHS_USHI1, USBHS_USHI0, _3DG_SGX540 } },
-	{ 0xe69400a8, 0xe69400e8, 8, /* IMR10A / IMCR10A */
-	  { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
-	    0, 0, 0, 0 } },
-	{ 0xe69400ac, 0xe69400ec, 8, /* IMR11A / IMCR11A */
-	  { IIC1_DTEI1, IIC1_WAITI1, IIC1_TACKI1, IIC1_ALI1,
-	    LCRC, MSU_MSU2, IRREM, MSU_MSU } },
-	{ 0xe69400b0, 0xe69400f0, 8, /* IMR12A / IMCR12A */
-	  { 0, 0, TPU0, TPU1,
-	    TPU2, TPU3, TPU4, 0 } },
-	{ 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
-	  { 0, 0, 0, 0,
-	    MISTY, CMT3, RWDT1, RWDT0 } },
-	{ 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */
-	  { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
-	    0, 0, 0, 0 } },
-	{ 0xe6950090, 0xe69500d0, 8, /* IMR4A3 / IMCR4A3 */
-	  { ICUSB_ICUSB0, ICUSB_ICUSB1, 0, 0,
-	    ICUDMC_ICUDMC1, ICUDMC_ICUDMC2, 0, 0 } },
-	{ 0xe6950094, 0xe69500d4, 8, /* IMR5A3 / IMCR5A3 */
-	  { SPU2_SPU0, SPU2_SPU1, FSI, FMSI,
-	    SCUV, 0, 0, 0 } },
-	{ 0xe6950098, 0xe69500d8, 8, /* IMR6A3 / IMCR6A3 */
-	  { IPMMU_IPMMUB, 0, 0, 0,
-	    AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ,
-	    AP_ARM_DMAIRQ, AP_ARM_DMASIRQ } },
-	{ 0xe695009c, 0xe69500dc, 8, /* IMR7A3 / IMCR7A3 */
-	  { MFIS2, CPORTR2S, CMT14, CMT15,
-	    SCIFA6, 0, 0, 0 } },
-};
-
-static struct intc_prio_reg intca_prio_registers[] __initdata = {
-	{ 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, LCRC } },
-	{ 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, 0, BBIF1, BBIF2 } },
-	{ 0xe6940008, 0, 16, 4, /* IPRCA */ { _2DG, CRYPT_STD,
-					      CMT1_CMT11, AP_ARM1 } },
-	{ 0xe694000c, 0, 16, 4, /* IPRDA */ { PINTCA_PINT1, PINTCA_PINT2,
-					      CMT1_CMT12, TPU4 } },
-	{ 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC_1, MFI_MFIS,
-					      MFI_MFIM, USBHS } },
-	{ 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC_KEY, DMAC_2,
-					      _3DG_SGX540, CMT1_CMT10 } },
-	{ 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
-					      SCIFA2, SCIFA3 } },
-	{ 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBDMAC_USHDMI,
-					      FLCTL, SDHI0 } },
-	{ 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4, MSU_MSU, IIC1 } },
-	{ 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2, MSUG, TTI20 } },
-	{ 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_CMT13, IRREM, SDHI1 } },
-	{ 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, TPU1, TPU2, TPU3 } },
-	{ 0xe6940030, 0, 16, 4, /* IPRMA */ { MISTY, CMT3, RWDT1, RWDT0 } },
-	{ 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, 0, DDM } },
-	{ 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, 0 } },
-	{ 0xe6950000, 0, 16, 4, /* IPRAA3 */ { SHWYSTAT, 0, 0, 0 } },
-	{ 0xe6950020, 0, 16, 4, /* IPRIA3 */ { ICUSB, 0, 0, 0 } },
-	{ 0xe6950024, 0, 16, 4, /* IPRJA3 */ { ICUDMC, 0, 0, 0 } },
-	{ 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } },
-	{ 0xe695002c, 0, 16, 4, /* IPRLA3 */ { SCUV, 0, 0, 0 } },
-	{ 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU_IPMMUB, 0, 0, 0 } },
-	{ 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } },
-	{ 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S,
-					       CMT14, CMT15 } },
-	{ 0xe694003c, 0, 16, 4, /* IPRPA3 */ { SCIFA6, 0, 0, 0 } },
-};
-
-static struct intc_desc intca_desc __initdata = {
-	.name = "sh7377-intca",
-	.force_enable = ENABLED,
-	.force_disable = DISABLED,
-	.hw = INTC_HW_DESC(intca_vectors, intca_groups,
-			   intca_mask_registers, intca_prio_registers,
-			   NULL, NULL),
-};
-
-INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000,
-		 INTC_VECT, "sh7377-intca-irq-pins");
-
-/* this macro ignore entry which is also in INTCA */
-#define __IGNORE(a...)
-#define __IGNORE0(a...) 0
-
-enum {
-	UNUSED_INTCS = 0,
-
-	INTCS,
-
-	/* interrupt sources INTCS */
-	VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3,
-	RTDMAC1_1_DEI0, RTDMAC1_1_DEI1, RTDMAC1_1_DEI2, RTDMAC1_1_DEI3,
-	CEU,
-	BEU_BEU0, BEU_BEU1, BEU_BEU2,
-	__IGNORE(MFI)
-	__IGNORE(BBIF2)
-	VPU,
-	TSIF1,
-	__IGNORE(SGX540)
-	_2DDMAC,
-	IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
-	IPMMU_IPMMUR, IPMMU_IPMMUR2,
-	RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR,
-	__IGNORE(KEYSC)
-	__IGNORE(TTI20)
-	__IGNORE(MSIOF)
-	IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
-	TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
-	CMT0,
-	TSIF0,
-	__IGNORE(CMT2)
-	LMB,
-	__IGNORE(MSUG)
-	__IGNORE(MSU_MSU, MSU_MSU2)
-	__IGNORE(CTI)
-	MVI3,
-	__IGNORE(RWDT0)
-	__IGNORE(RWDT1)
-	ICB,
-	PEP,
-	ASA,
-	__IGNORE(_2DG)
-	HQE,
-	JPU,
-	LCDC0,
-	__IGNORE(LCRC)
-	RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3,
-	RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR,
-	FRC,
-	LCDC1,
-	CSIRX,
-	DSITX_DSITX0, DSITX_DSITX1,
-	__IGNORE(SPU2_SPU0, SPU2_SPU1)
-	__IGNORE(FSI)
-	__IGNORE(FMSI)
-	__IGNORE(SCUV)
-	TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12,
-	TSIF2,
-	CMT4,
-	__IGNORE(MFIS2)
-	CPORTS2R,
-
-	/* interrupt groups INTCS */
-	RTDMAC1_1, RTDMAC1_2, VEU, BEU, IIC0, __IGNORE(MSU) IPMMU,
-	IIC2, RTDMAC2_1, RTDMAC2_2, DSITX, __IGNORE(SPU2) TMU1,
-};
-
-#define INTCS_INTVECT 0x0F80
-static struct intc_vect intcs_vectors[] __initdata = {
-	INTCS_VECT(VEU_VEU0, 0x0700), INTCS_VECT(VEU_VEU1, 0x0720),
-	INTCS_VECT(VEU_VEU2, 0x0740), INTCS_VECT(VEU_VEU3, 0x0760),
-	INTCS_VECT(RTDMAC1_1_DEI0, 0x0800), INTCS_VECT(RTDMAC1_1_DEI1, 0x0820),
-	INTCS_VECT(RTDMAC1_1_DEI2, 0x0840), INTCS_VECT(RTDMAC1_1_DEI3, 0x0860),
-	INTCS_VECT(CEU, 0x0880),
-	INTCS_VECT(BEU_BEU0, 0x08A0),
-	INTCS_VECT(BEU_BEU1, 0x08C0),
-	INTCS_VECT(BEU_BEU2, 0x08E0),
-	__IGNORE(INTCS_VECT(MFI, 0x0900))
-	__IGNORE(INTCS_VECT(BBIF2, 0x0960))
-	INTCS_VECT(VPU, 0x0980),
-	INTCS_VECT(TSIF1, 0x09A0),
-	__IGNORE(INTCS_VECT(SGX540, 0x09E0))
-	INTCS_VECT(_2DDMAC, 0x0A00),
-	INTCS_VECT(IIC2_ALI2, 0x0A80), INTCS_VECT(IIC2_TACKI2, 0x0AA0),
-	INTCS_VECT(IIC2_WAITI2, 0x0AC0), INTCS_VECT(IIC2_DTEI2, 0x0AE0),
-	INTCS_VECT(IPMMU_IPMMUR, 0x0B00), INTCS_VECT(IPMMU_IPMMUR2, 0x0B20),
-	INTCS_VECT(RTDMAC1_2_DEI4, 0x0B80),
-	INTCS_VECT(RTDMAC1_2_DEI5, 0x0BA0),
-	INTCS_VECT(RTDMAC1_2_DADERR, 0x0BC0),
-	__IGNORE(INTCS_VECT(KEYSC 0x0BE0))
-	__IGNORE(INTCS_VECT(TTI20, 0x0C80))
-	__IGNORE(INTCS_VECT(MSIOF, 0x0D20))
-	INTCS_VECT(IIC0_ALI0, 0x0E00), INTCS_VECT(IIC0_TACKI0, 0x0E20),
-	INTCS_VECT(IIC0_WAITI0, 0x0E40), INTCS_VECT(IIC0_DTEI0, 0x0E60),
-	INTCS_VECT(TMU_TUNI0, 0x0E80),
-	INTCS_VECT(TMU_TUNI1, 0x0EA0),
-	INTCS_VECT(TMU_TUNI2, 0x0EC0),
-	INTCS_VECT(CMT0, 0x0F00),
-	INTCS_VECT(TSIF0, 0x0F20),
-	__IGNORE(INTCS_VECT(CMT2, 0x0F40))
-	INTCS_VECT(LMB, 0x0F60),
-	__IGNORE(INTCS_VECT(MSUG, 0x0F80))
-	__IGNORE(INTCS_VECT(MSU_MSU, 0x0FA0))
-	__IGNORE(INTCS_VECT(MSU_MSU2, 0x0FC0))
-	__IGNORE(INTCS_VECT(CTI, 0x0400))
-	INTCS_VECT(MVI3, 0x0420),
-	__IGNORE(INTCS_VECT(RWDT0, 0x0440))
-	__IGNORE(INTCS_VECT(RWDT1, 0x0460))
-	INTCS_VECT(ICB, 0x0480),
-	INTCS_VECT(PEP, 0x04A0),
-	INTCS_VECT(ASA, 0x04C0),
-	__IGNORE(INTCS_VECT(_2DG, 0x04E0))
-	INTCS_VECT(HQE, 0x0540),
-	INTCS_VECT(JPU, 0x0560),
-	INTCS_VECT(LCDC0, 0x0580),
-	__IGNORE(INTCS_VECT(LCRC, 0x05A0))
-	INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320),
-	INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360),
-	INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13A0),
-	INTCS_VECT(RTDMAC2_2_DADERR, 0x13C0),
-	INTCS_VECT(FRC, 0x1700),
-	INTCS_VECT(LCDC1, 0x1780),
-	INTCS_VECT(CSIRX, 0x17A0),
-	INTCS_VECT(DSITX_DSITX0, 0x17C0), INTCS_VECT(DSITX_DSITX1, 0x17E0),
-	__IGNORE(INTCS_VECT(SPU2_SPU0, 0x1800))
-	__IGNORE(INTCS_VECT(SPU2_SPU1, 0x1820))
-	__IGNORE(INTCS_VECT(FSI, 0x1840))
-	__IGNORE(INTCS_VECT(FMSI, 0x1860))
-	__IGNORE(INTCS_VECT(SCUV, 0x1880))
-	INTCS_VECT(TMU1_TUNI10, 0x1900), INTCS_VECT(TMU1_TUNI11, 0x1920),
-	INTCS_VECT(TMU1_TUNI12, 0x1940),
-	INTCS_VECT(TSIF2, 0x1960),
-	INTCS_VECT(CMT4, 0x1980),
-	__IGNORE(INTCS_VECT(MFIS2, 0x1A00))
-	INTCS_VECT(CPORTS2R, 0x1A20),
-
-	INTC_VECT(INTCS, INTCS_INTVECT),
-};
-
-static struct intc_group intcs_groups[] __initdata = {
-	INTC_GROUP(RTDMAC1_1,
-		   RTDMAC1_1_DEI0, RTDMAC1_1_DEI1,
-		   RTDMAC1_1_DEI2, RTDMAC1_1_DEI3),
-	INTC_GROUP(RTDMAC1_2,
-		   RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR),
-	INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3),
-	INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2),
-	INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0),
-	__IGNORE(INTC_GROUP(MSU, MSU_MSU, MSU_MSU2))
-	INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2),
-	INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2),
-	INTC_GROUP(RTDMAC2_1,
-		   RTDMAC2_1_DEI0, RTDMAC2_1_DEI1,
-		   RTDMAC2_1_DEI2, RTDMAC2_1_DEI3),
-	INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR),
-	INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1),
-	__IGNORE(INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1))
-	INTC_GROUP(TMU1, TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12),
-};
-
-static struct intc_mask_reg intcs_mask_registers[] __initdata = {
-	{ 0xE6940184, 0xE69401C4, 8, /* IMR1AS / IMCR1AS  */
-	  { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU,
-	    VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } },
-	{ 0xE6940188, 0xE69401C8, 8, /* IMR2AS / IMCR2AS */
-	  { 0, 0, 0, VPU,
-	    __IGNORE0(BBIF2), 0, 0, __IGNORE0(MFI) } },
-	{ 0xE694018C, 0xE69401CC, 8, /* IMR3AS / IMCR3AS */
-	  { 0, 0, 0, _2DDMAC,
-	    __IGNORE0(_2DG), ASA, PEP, ICB } },
-	{ 0xE6940190, 0xE69401D0, 8, /* IMR4AS / IMCR4AS */
-	  { 0, 0, MVI3, __IGNORE0(CTI),
-	    JPU, HQE, __IGNORE0(LCRC), LCDC0 } },
-	{ 0xE6940194, 0xE69401D4, 8, /* IMR5AS / IMCR5AS */
-	  { __IGNORE0(KEYSC), RTDMAC1_2_DADERR, RTDMAC1_2_DEI5, RTDMAC1_2_DEI4,
-	    RTDMAC1_1_DEI3, RTDMAC1_1_DEI2, RTDMAC1_1_DEI1, RTDMAC1_1_DEI0 } },
-	__IGNORE({ 0xE6940198, 0xE69401D8, 8, /* IMR6AS / IMCR6AS */
-	  { 0, 0, MSIOF, 0,
-	    SGX540, 0, TTI20, 0 } })
-	{ 0xE694019C, 0xE69401DC, 8, /* IMR7AS / IMCR7AS */
-	  { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
-	    0, 0, 0, 0 } },
-	__IGNORE({ 0xE69401A0, 0xE69401E0, 8, /* IMR8AS / IMCR8AS */
-	  { 0, 0, 0, 0,
-	    0, MSU_MSU, MSU_MSU2, MSUG } })
-	{ 0xE69401A4, 0xE69401E4, 8, /* IMR9AS / IMCR9AS */
-	  { __IGNORE0(RWDT1), __IGNORE0(RWDT0), __IGNORE0(CMT2), CMT0,
-	    IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } },
-	{ 0xE69401A8, 0xE69401E8, 8, /* IMR10AS / IMCR10AS */
-	  { 0, 0, IPMMU_IPMMUR, IPMMU_IPMMUR2,
-	    0, 0, 0, 0 } },
-	{ 0xE69401AC, 0xE69401EC, 8, /* IMR11AS / IMCR11AS */
-	  { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0,
-	    0, TSIF1, LMB, TSIF0 } },
-	{ 0xE6950180, 0xE69501C0, 8, /* IMR0AS3 / IMCR0AS3 */
-	  { RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3,
-	    RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, 0 } },
-	{ 0xE6950190, 0xE69501D0, 8, /* IMR4AS3 / IMCR4AS3 */
-	  { FRC, 0, 0, 0,
-	    LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } },
-	__IGNORE({ 0xE6950194, 0xE69501D4, 8, /* IMR5AS3 / IMCR5AS3 */
-	  {SPU2_SPU0, SPU2_SPU1, FSI, FMSI,
-	   SCUV, 0, 0, 0 } })
-	{ 0xE6950198, 0xE69501D8, 8, /* IMR6AS3 / IMCR6AS3 */
-	  { TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, TSIF2,
-	    CMT4, 0, 0, 0 } },
-	{ 0xE695019C, 0xE69501DC, 8, /* IMR7AS3 / IMCR7AS3 */
-	  { __IGNORE0(MFIS2), CPORTS2R, 0, 0,
-	    0, 0, 0, 0 } },
-	{ 0xFFD20104, 0, 16, /* INTAMASK */
-	  { 0, 0, 0, 0, 0, 0, 0, 0,
-	    0, 0, 0, 0, 0, 0, 0, INTCS } }
-};
-
-static struct intc_prio_reg intcs_prio_registers[] __initdata = {
-	/* IPRAS */
-	{ 0xFFD20000, 0, 16, 4, { __IGNORE0(CTI), MVI3, _2DDMAC, ICB } },
-	/* IPRBS */
-	{ 0xFFD20004, 0, 16, 4, { JPU, LCDC0, 0, __IGNORE0(LCRC) } },
-	/* IPRCS */
-	__IGNORE({ 0xFFD20008, 0, 16, 4, { BBIF2, 0, 0, 0 } })
-	/* IPRES */
-	{ 0xFFD20010, 0, 16, 4, { RTDMAC1_1, CEU, __IGNORE0(MFI), VPU } },
-	/* IPRFS */
-	{ 0xFFD20014, 0, 16, 4,
-	  { __IGNORE0(KEYSC), RTDMAC1_2, __IGNORE0(CMT2), CMT0 } },
-	/* IPRGS */
-	{ 0xFFD20018, 0, 16, 4, { TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, TSIF1 } },
-	/* IPRHS */
-	{ 0xFFD2001C, 0, 16, 4, { __IGNORE0(TTI20), 0, VEU, BEU } },
-	/* IPRIS */
-	{ 0xFFD20020, 0, 16, 4, { 0, __IGNORE0(MSIOF), TSIF0, IIC0 } },
-	/* IPRJS */
-	__IGNORE({ 0xFFD20024, 0, 16, 4, { 0, SGX540, MSUG, MSU } })
-	/* IPRKS */
-	{ 0xFFD20028, 0, 16, 4, { __IGNORE0(_2DG), ASA, LMB, PEP } },
-	/* IPRLS */
-	{ 0xFFD2002C, 0, 16, 4, { IPMMU, 0, 0, HQE } },
-	/* IPRMS */
-	{ 0xFFD20030, 0, 16, 4,
-	  { IIC2, 0, __IGNORE0(RWDT1), __IGNORE0(RWDT0) } },
-	/* IPRAS3 */
-	{ 0xFFD50000, 0, 16, 4, { RTDMAC2_1, 0, 0, 0 } },
-	/* IPRBS3 */
-	{ 0xFFD50004, 0, 16, 4, { RTDMAC2_2, 0, 0, 0 } },
-	/* IPRIS3 */
-	{ 0xFFD50020, 0, 16, 4, { FRC, 0, 0, 0 } },
-	/* IPRJS3 */
-	{ 0xFFD50024, 0, 16, 4, { LCDC1, CSIRX, DSITX, 0 } },
-	/* IPRKS3 */
-	__IGNORE({ 0xFFD50028, 0, 16, 4, { SPU2, 0, FSI, FMSI } })
-	/* IPRLS3 */
-	__IGNORE({ 0xFFD5002C, 0, 16, 4, { SCUV, 0, 0, 0 } })
-	/* IPRMS3 */
-	{ 0xFFD50030, 0, 16, 4, { TMU1, 0, 0, TSIF2 } },
-	/* IPRNS3 */
-	{ 0xFFD50034, 0, 16, 4, { CMT4, 0, 0, 0 } },
-	/* IPROS3 */
-	{ 0xFFD50038, 0, 16, 4, { __IGNORE0(MFIS2), CPORTS2R, 0, 0 } },
-};
-
-static struct resource intcs_resources[] __initdata = {
-	[0] = {
-		.start	= 0xffd20000,
-		.end	= 0xffd500ff,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct intc_desc intcs_desc __initdata = {
-	.name = "sh7377-intcs",
-	.resource = intcs_resources,
-	.num_resources = ARRAY_SIZE(intcs_resources),
-	.hw = INTC_HW_DESC(intcs_vectors, intcs_groups,
-			   intcs_mask_registers, intcs_prio_registers,
-			   NULL, NULL),
-};
-
-static void intcs_demux(unsigned int irq, struct irq_desc *desc)
-{
-	void __iomem *reg = (void *)irq_get_handler_data(irq);
-	unsigned int evtcodeas = ioread32(reg);
-
-	generic_handle_irq(intcs_evt2irq(evtcodeas));
-}
-
-#define INTEVTSA 0xFFD20100
-void __init sh7377_init_irq(void)
-{
-	void __iomem *intevtsa = ioremap_nocache(INTEVTSA, PAGE_SIZE);
-
-	register_intc_controller(&intca_desc);
-	register_intc_controller(&intca_irq_pins_desc);
-	register_intc_controller(&intcs_desc);
-
-	/* demux using INTEVTSA */
-	irq_set_handler_data(evt2irq(INTCS_INTVECT), (void *)intevtsa);
-	irq_set_chained_handler(evt2irq(INTCS_INTVECT), intcs_demux);
-}
diff --git a/arch/arm/mach-shmobile/pfc-r8a7779.c b/arch/arm/mach-shmobile/pfc-r8a7779.c
index cbc26ba..9513234 100644
--- a/arch/arm/mach-shmobile/pfc-r8a7779.c
+++ b/arch/arm/mach-shmobile/pfc-r8a7779.c
@@ -140,7 +140,7 @@
 	FN_IP7_3_2, FN_IP7_6_4, FN_IP7_9_7, FN_IP7_12_10,
 	FN_IP7_14_13, FN_IP2_7_4, FN_IP2_11_8, FN_IP2_15_12,
 	FN_IP1_28_25, FN_IP2_3_0, FN_IP8_3_0, FN_IP8_7_4,
-	FN_IP8_11_8, FN_IP8_15_12, FN_PENC0, FN_PENC1,
+	FN_IP8_11_8, FN_IP8_15_12, FN_USB_PENC0, FN_USB_PENC1,
 	FN_IP0_2_0, FN_IP8_17_16, FN_IP8_18, FN_IP8_19,
 
 	/* GPSR5 */
@@ -176,7 +176,7 @@
 	FN_A0, FN_SD1_DAT3, FN_MMC0_D3, FN_FD3,
 	FN_BS, FN_SD1_DAT2, FN_MMC0_D2, FN_FD2,
 	FN_ATADIR0, FN_SDSELF, FN_HCTS1, FN_TX4_C,
-	FN_PENC2, FN_SCK0, FN_PWM1, FN_PWMFSW0,
+	FN_USB_PENC2, FN_SCK0, FN_PWM1, FN_PWMFSW0,
 	FN_SCIF_CLK, FN_TCLK0_C,
 
 	/* IPSR1 */
@@ -447,7 +447,7 @@
 	A0_MARK, SD1_DAT3_MARK, MMC0_D3_MARK, FD3_MARK,
 	BS_MARK, SD1_DAT2_MARK, MMC0_D2_MARK, FD2_MARK,
 	ATADIR0_MARK, SDSELF_MARK, HCTS1_MARK, TX4_C_MARK,
-	PENC2_MARK, SCK0_MARK, PWM1_MARK, PWMFSW0_MARK,
+	USB_PENC2_MARK, SCK0_MARK, PWM1_MARK, PWMFSW0_MARK,
 	SCIF_CLK_MARK, TCLK0_C_MARK,
 
 	EX_CS0_MARK, RX3_C_IRDA_RX_C_MARK, MMC0_D6_MARK,
@@ -658,7 +658,7 @@
 	PINMUX_DATA(A18_MARK, FN_A18),
 	PINMUX_DATA(A19_MARK, FN_A19),
 
-	PINMUX_IPSR_DATA(IP0_2_0, PENC2),
+	PINMUX_IPSR_DATA(IP0_2_0, USB_PENC2),
 	PINMUX_IPSR_MODSEL_DATA(IP0_2_0, SCK0, SEL_SCIF0_0),
 	PINMUX_IPSR_DATA(IP0_2_0, PWM1),
 	PINMUX_IPSR_MODSEL_DATA(IP0_2_0, PWMFSW0, SEL_PWMFSW_0),
@@ -1456,7 +1456,7 @@
 	GPIO_FN(A19),
 
 	/* IPSR0 */
-	GPIO_FN(PENC2), GPIO_FN(SCK0), GPIO_FN(PWM1), GPIO_FN(PWMFSW0),
+	GPIO_FN(USB_PENC2), GPIO_FN(SCK0), GPIO_FN(PWM1), GPIO_FN(PWMFSW0),
 	GPIO_FN(SCIF_CLK), GPIO_FN(TCLK0_C), GPIO_FN(BS), GPIO_FN(SD1_DAT2),
 	GPIO_FN(MMC0_D2), GPIO_FN(FD2), GPIO_FN(ATADIR0), GPIO_FN(SDSELF),
 	GPIO_FN(HCTS1), GPIO_FN(TX4_C), GPIO_FN(A0), GPIO_FN(SD1_DAT3),
@@ -1865,8 +1865,8 @@
 		GP_4_30_FN, FN_IP8_18,
 		GP_4_29_FN, FN_IP8_17_16,
 		GP_4_28_FN, FN_IP0_2_0,
-		GP_4_27_FN, FN_PENC1,
-		GP_4_26_FN, FN_PENC0,
+		GP_4_27_FN, FN_USB_PENC1,
+		GP_4_26_FN, FN_USB_PENC0,
 		GP_4_25_FN, FN_IP8_15_12,
 		GP_4_24_FN, FN_IP8_11_8,
 		GP_4_23_FN, FN_IP8_7_4,
@@ -1981,7 +1981,7 @@
 		FN_BS, FN_SD1_DAT2, FN_MMC0_D2, FN_FD2,
 		FN_ATADIR0, FN_SDSELF, FN_HCTS1, FN_TX4_C,
 		/* IP0_2_0 [3] */
-		FN_PENC2, FN_SCK0, FN_PWM1, FN_PWMFSW0,
+		FN_USB_PENC2, FN_SCK0, FN_PWM1, FN_PWMFSW0,
 		FN_SCIF_CLK, FN_TCLK0_C, 0, 0 }
 	},
 	{ PINMUX_CFG_REG_VAR("IPSR1", 0xfffc0024, 32,
diff --git a/arch/arm/mach-shmobile/pfc-sh7367.c b/arch/arm/mach-shmobile/pfc-sh7367.c
deleted file mode 100644
index c0c137f..0000000
--- a/arch/arm/mach-shmobile/pfc-sh7367.c
+++ /dev/null
@@ -1,1727 +0,0 @@
-/*
- * sh7367 processor support - PFC hardware block
- *
- * Copyright (C) 2010  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sh_pfc.h>
-#include <mach/sh7367.h>
-
-#define CPU_ALL_PORT(fn, pfx, sfx)				\
-	PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx),		\
-	PORT_10(fn, pfx##10, sfx), PORT_90(fn, pfx##1, sfx),	\
-	PORT_10(fn, pfx##20, sfx), PORT_10(fn, pfx##21, sfx),	\
-	PORT_10(fn, pfx##22, sfx), PORT_10(fn, pfx##23, sfx),	\
-	PORT_10(fn, pfx##24, sfx), PORT_10(fn, pfx##25, sfx),	\
-	PORT_10(fn, pfx##26, sfx), PORT_1(fn, pfx##270, sfx),	\
-	PORT_1(fn, pfx##271, sfx), PORT_1(fn, pfx##272, sfx)
-
-enum {
-	PINMUX_RESERVED = 0,
-
-	PINMUX_DATA_BEGIN,
-	PORT_ALL(DATA), /* PORT0_DATA -> PORT272_DATA */
-	PINMUX_DATA_END,
-
-	PINMUX_INPUT_BEGIN,
-	PORT_ALL(IN), /* PORT0_IN -> PORT272_IN */
-	PINMUX_INPUT_END,
-
-	PINMUX_INPUT_PULLUP_BEGIN,
-	PORT_ALL(IN_PU), /* PORT0_IN_PU -> PORT272_IN_PU */
-	PINMUX_INPUT_PULLUP_END,
-
-	PINMUX_INPUT_PULLDOWN_BEGIN,
-	PORT_ALL(IN_PD), /* PORT0_IN_PD -> PORT272_IN_PD */
-	PINMUX_INPUT_PULLDOWN_END,
-
-	PINMUX_OUTPUT_BEGIN,
-	PORT_ALL(OUT), /* PORT0_OUT -> PORT272_OUT */
-	PINMUX_OUTPUT_END,
-
-	PINMUX_FUNCTION_BEGIN,
-	PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT272_FN_IN */
-	PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT272_FN_OUT */
-	PORT_ALL(FN0), /* PORT0_FN0 -> PORT272_FN0 */
-	PORT_ALL(FN1), /* PORT0_FN1 -> PORT272_FN1 */
-	PORT_ALL(FN2), /* PORT0_FN2 -> PORT272_FN2 */
-	PORT_ALL(FN3), /* PORT0_FN3 -> PORT272_FN3 */
-	PORT_ALL(FN4), /* PORT0_FN4 -> PORT272_FN4 */
-	PORT_ALL(FN5), /* PORT0_FN5 -> PORT272_FN5 */
-	PORT_ALL(FN6), /* PORT0_FN6 -> PORT272_FN6 */
-	PORT_ALL(FN7), /* PORT0_FN7 -> PORT272_FN7 */
-
-	MSELBCR_MSEL2_1, MSELBCR_MSEL2_0,
-	PINMUX_FUNCTION_END,
-
-	PINMUX_MARK_BEGIN,
-	/* Special Pull-up / Pull-down Functions */
-	PORT48_KEYIN0_PU_MARK, PORT49_KEYIN1_PU_MARK,
-	PORT50_KEYIN2_PU_MARK, PORT55_KEYIN3_PU_MARK,
-	PORT56_KEYIN4_PU_MARK, PORT57_KEYIN5_PU_MARK,
-	PORT58_KEYIN6_PU_MARK,
-
-	/* 49-1 */
-	VBUS0_MARK, CPORT0_MARK, CPORT1_MARK, CPORT2_MARK,
-	CPORT3_MARK, CPORT4_MARK, CPORT5_MARK, CPORT6_MARK,
-	CPORT7_MARK, CPORT8_MARK, CPORT9_MARK, CPORT10_MARK,
-	CPORT11_MARK, SIN2_MARK, CPORT12_MARK, XCTS2_MARK,
-	CPORT13_MARK, RFSPO4_MARK, CPORT14_MARK, RFSPO5_MARK,
-	CPORT15_MARK, CPORT16_MARK, CPORT17_MARK, SOUT2_MARK,
-	CPORT18_MARK, XRTS2_MARK, CPORT19_MARK, CPORT20_MARK,
-	RFSPO6_MARK, CPORT21_MARK, STATUS0_MARK, CPORT22_MARK,
-	STATUS1_MARK, CPORT23_MARK, STATUS2_MARK, RFSPO7_MARK,
-	MPORT0_MARK, MPORT1_MARK, B_SYNLD1_MARK, B_SYNLD2_MARK,
-	XMAINPS_MARK, XDIVPS_MARK, XIDRST_MARK, IDCLK_MARK,
-	IDIO_MARK, SOUT1_MARK, SCIFA4_TXD_MARK,
-	M02_BERDAT_MARK, SIN1_MARK, SCIFA4_RXD_MARK, XWUP_MARK,
-	XRTS1_MARK, SCIFA4_RTS_MARK, M03_BERCLK_MARK,
-	XCTS1_MARK, SCIFA4_CTS_MARK,
-
-	/* 49-2 */
-	HSU_IQ_AGC6_MARK, MFG2_IN2_MARK, MSIOF2_MCK0_MARK,
-	HSU_IQ_AGC5_MARK, MFG2_IN1_MARK, MSIOF2_MCK1_MARK,
-	HSU_IQ_AGC4_MARK, MSIOF2_RSYNC_MARK,
-	HSU_IQ_AGC3_MARK, MFG2_OUT1_MARK, MSIOF2_RSCK_MARK,
-	HSU_IQ_AGC2_MARK, PORT42_KEYOUT0_MARK,
-	HSU_IQ_AGC1_MARK, PORT43_KEYOUT1_MARK,
-	HSU_IQ_AGC0_MARK, PORT44_KEYOUT2_MARK,
-	HSU_IQ_AGC_ST_MARK, PORT45_KEYOUT3_MARK,
-	HSU_IQ_PDO_MARK, PORT46_KEYOUT4_MARK,
-	HSU_IQ_PYO_MARK, PORT47_KEYOUT5_MARK,
-	HSU_EN_TXMUX_G3MO_MARK, PORT48_KEYIN0_MARK,
-	HSU_I_TXMUX_G3MO_MARK, PORT49_KEYIN1_MARK,
-	HSU_Q_TXMUX_G3MO_MARK, PORT50_KEYIN2_MARK,
-	HSU_SYO_MARK, PORT51_MSIOF2_TSYNC_MARK,
-	HSU_SDO_MARK, PORT52_MSIOF2_TSCK_MARK,
-	HSU_TGTTI_G3MO_MARK, PORT53_MSIOF2_TXD_MARK,
-	B_TIME_STAMP_MARK, PORT54_MSIOF2_RXD_MARK,
-	HSU_SDI_MARK, PORT55_KEYIN3_MARK,
-	HSU_SCO_MARK, PORT56_KEYIN4_MARK,
-	HSU_DREQ_MARK, PORT57_KEYIN5_MARK,
-	HSU_DACK_MARK, PORT58_KEYIN6_MARK,
-	HSU_CLK61M_MARK, PORT59_MSIOF2_SS1_MARK,
-	HSU_XRST_MARK, PORT60_MSIOF2_SS2_MARK,
-	PCMCLKO_MARK, SYNC8KO_MARK, DNPCM_A_MARK, UPPCM_A_MARK,
-	XTALB1L_MARK,
-	GPS_AGC1_MARK, SCIFA0_RTS_MARK,
-	GPS_AGC2_MARK, SCIFA0_SCK_MARK,
-	GPS_AGC3_MARK, SCIFA0_TXD_MARK,
-	GPS_AGC4_MARK, SCIFA0_RXD_MARK,
-	GPS_PWRD_MARK, SCIFA0_CTS_MARK,
-	GPS_IM_MARK, GPS_IS_MARK, GPS_QM_MARK, GPS_QS_MARK,
-	SIUBOMC_MARK, TPU2TO0_MARK,
-	SIUCKB_MARK, TPU2TO1_MARK,
-	SIUBOLR_MARK, BBIF2_TSYNC_MARK, TPU2TO2_MARK,
-	SIUBOBT_MARK, BBIF2_TSCK_MARK, TPU2TO3_MARK,
-	SIUBOSLD_MARK, BBIF2_TXD_MARK, TPU3TO0_MARK,
-	SIUBILR_MARK, TPU3TO1_MARK,
-	SIUBIBT_MARK, TPU3TO2_MARK,
-	SIUBISLD_MARK, TPU3TO3_MARK,
-	NMI_MARK, TPU4TO0_MARK,
-	DNPCM_M_MARK, TPU4TO1_MARK, TPU4TO2_MARK, TPU4TO3_MARK,
-	IRQ_TMPB_MARK,
-	PWEN_MARK, MFG1_OUT1_MARK,
-	OVCN_MARK, MFG1_IN1_MARK,
-	OVCN2_MARK, MFG1_IN2_MARK,
-
-	/* 49-3 */
-	RFSPO1_MARK, RFSPO2_MARK, RFSPO3_MARK, PORT93_VIO_CKO2_MARK,
-	USBTERM_MARK, EXTLP_MARK, IDIN_MARK,
-	SCIFA5_CTS_MARK, MFG0_IN1_MARK,
-	SCIFA5_RTS_MARK, MFG0_IN2_MARK,
-	SCIFA5_RXD_MARK,
-	SCIFA5_TXD_MARK,
-	SCIFA5_SCK_MARK, MFG0_OUT1_MARK,
-	A0_EA0_MARK, BS_MARK,
-	A14_EA14_MARK, PORT102_KEYOUT0_MARK,
-	A15_EA15_MARK, PORT103_KEYOUT1_MARK, DV_CLKOL_MARK,
-	A16_EA16_MARK, PORT104_KEYOUT2_MARK,
-	DV_VSYNCL_MARK, MSIOF0_SS1_MARK,
-	A17_EA17_MARK, PORT105_KEYOUT3_MARK,
-	DV_HSYNCL_MARK, MSIOF0_TSYNC_MARK,
-	A18_EA18_MARK, PORT106_KEYOUT4_MARK,
-	DV_DL0_MARK, MSIOF0_TSCK_MARK,
-	A19_EA19_MARK, PORT107_KEYOUT5_MARK,
-	DV_DL1_MARK, MSIOF0_TXD_MARK,
-	A20_EA20_MARK, PORT108_KEYIN0_MARK,
-	DV_DL2_MARK, MSIOF0_RSCK_MARK,
-	A21_EA21_MARK, PORT109_KEYIN1_MARK,
-	DV_DL3_MARK, MSIOF0_RSYNC_MARK,
-	A22_EA22_MARK, PORT110_KEYIN2_MARK,
-	DV_DL4_MARK, MSIOF0_MCK0_MARK,
-	A23_EA23_MARK, PORT111_KEYIN3_MARK,
-	DV_DL5_MARK, MSIOF0_MCK1_MARK,
-	A24_EA24_MARK, PORT112_KEYIN4_MARK,
-	DV_DL6_MARK, MSIOF0_RXD_MARK,
-	A25_EA25_MARK, PORT113_KEYIN5_MARK,
-	DV_DL7_MARK, MSIOF0_SS2_MARK,
-	A26_MARK, PORT113_KEYIN6_MARK, DV_CLKIL_MARK,
-	D0_ED0_NAF0_MARK, D1_ED1_NAF1_MARK, D2_ED2_NAF2_MARK,
-	D3_ED3_NAF3_MARK, D4_ED4_NAF4_MARK, D5_ED5_NAF5_MARK,
-	D6_ED6_NAF6_MARK, D7_ED7_NAF7_MARK, D8_ED8_NAF8_MARK,
-	D9_ED9_NAF9_MARK, D10_ED10_NAF10_MARK, D11_ED11_NAF11_MARK,
-	D12_ED12_NAF12_MARK, D13_ED13_NAF13_MARK,
-	D14_ED14_NAF14_MARK, D15_ED15_NAF15_MARK,
-	CS4_MARK, CS5A_MARK, CS5B_MARK, FCE1_MARK,
-	CS6B_MARK, XCS2_MARK, FCE0_MARK, CS6A_MARK,
-	DACK0_MARK, WAIT_MARK, DREQ0_MARK, RD_XRD_MARK,
-	A27_MARK, RDWR_XWE_MARK, WE0_XWR0_FWE_MARK,
-	WE1_XWR1_MARK, FRB_MARK, CKO_MARK,
-	NBRSTOUT_MARK, NBRST_MARK,
-
-	/* 49-4 */
-	RFSPO0_MARK, PORT146_VIO_CKO2_MARK, TSTMD_MARK,
-	VIO_VD_MARK, VIO_HD_MARK,
-	VIO_D0_MARK, VIO_D1_MARK, VIO_D2_MARK,
-	VIO_D3_MARK, VIO_D4_MARK, VIO_D5_MARK,
-	VIO_D6_MARK, VIO_D7_MARK, VIO_D8_MARK,
-	VIO_D9_MARK, VIO_D10_MARK, VIO_D11_MARK,
-	VIO_D12_MARK, VIO_D13_MARK, VIO_D14_MARK,
-	VIO_D15_MARK, VIO_CLK_MARK, VIO_FIELD_MARK,
-	VIO_CKO_MARK,
-	MFG3_IN1_MARK, MFG3_IN2_MARK,
-	M9_SLCD_A01_MARK, MFG3_OUT1_MARK, TPU0TO0_MARK,
-	M10_SLCD_CK1_MARK, MFG4_IN1_MARK, TPU0TO1_MARK,
-	M11_SLCD_SO1_MARK, MFG4_IN2_MARK, TPU0TO2_MARK,
-	M12_SLCD_CE1_MARK, MFG4_OUT1_MARK, TPU0TO3_MARK,
-	LCDD0_MARK, PORT175_KEYOUT0_MARK, DV_D0_MARK,
-	SIUCKA_MARK, MFG0_OUT2_MARK,
-	LCDD1_MARK, PORT176_KEYOUT1_MARK, DV_D1_MARK,
-	SIUAOLR_MARK, BBIF2_TSYNC1_MARK,
-	LCDD2_MARK, PORT177_KEYOUT2_MARK, DV_D2_MARK,
-	SIUAOBT_MARK, BBIF2_TSCK1_MARK,
-	LCDD3_MARK, PORT178_KEYOUT3_MARK, DV_D3_MARK,
-	SIUAOSLD_MARK, BBIF2_TXD1_MARK,
-	LCDD4_MARK, PORT179_KEYOUT4_MARK, DV_D4_MARK,
-	SIUAISPD_MARK, MFG1_OUT2_MARK,
-	LCDD5_MARK, PORT180_KEYOUT5_MARK, DV_D5_MARK,
-	SIUAILR_MARK, MFG2_OUT2_MARK,
-	LCDD6_MARK, DV_D6_MARK,
-	SIUAIBT_MARK, MFG3_OUT2_MARK, XWR2_MARK,
-	LCDD7_MARK, DV_D7_MARK,
-	SIUAISLD_MARK, MFG4_OUT2_MARK, XWR3_MARK,
-	LCDD8_MARK, DV_D8_MARK, D16_MARK, ED16_MARK,
-	LCDD9_MARK, DV_D9_MARK, D17_MARK, ED17_MARK,
-	LCDD10_MARK, DV_D10_MARK, D18_MARK, ED18_MARK,
-	LCDD11_MARK, DV_D11_MARK, D19_MARK, ED19_MARK,
-	LCDD12_MARK, DV_D12_MARK, D20_MARK, ED20_MARK,
-	LCDD13_MARK, DV_D13_MARK, D21_MARK, ED21_MARK,
-	LCDD14_MARK, DV_D14_MARK, D22_MARK, ED22_MARK,
-	LCDD15_MARK, DV_D15_MARK, D23_MARK, ED23_MARK,
-	LCDD16_MARK, DV_HSYNC_MARK, D24_MARK, ED24_MARK,
-	LCDD17_MARK, DV_VSYNC_MARK, D25_MARK, ED25_MARK,
-	LCDD18_MARK, DREQ2_MARK, MSIOF0L_TSCK_MARK,
-	D26_MARK, ED26_MARK,
-	LCDD19_MARK, MSIOF0L_TSYNC_MARK,
-	D27_MARK, ED27_MARK,
-	LCDD20_MARK, TS_SPSYNC1_MARK, MSIOF0L_MCK0_MARK,
-	D28_MARK, ED28_MARK,
-	LCDD21_MARK, TS_SDAT1_MARK, MSIOF0L_MCK1_MARK,
-	D29_MARK, ED29_MARK,
-	LCDD22_MARK, TS_SDEN1_MARK, MSIOF0L_SS1_MARK,
-	D30_MARK, ED30_MARK,
-	LCDD23_MARK, TS_SCK1_MARK, MSIOF0L_SS2_MARK,
-	D31_MARK, ED31_MARK,
-	LCDDCK_MARK, LCDWR_MARK, DV_CKO_MARK, SIUAOSPD_MARK,
-	LCDRD_MARK, DACK2_MARK, MSIOF0L_RSYNC_MARK,
-
-	/* 49-5 */
-	LCDHSYN_MARK, LCDCS_MARK, LCDCS2_MARK, DACK3_MARK,
-	LCDDISP_MARK, LCDRS_MARK, DREQ3_MARK, MSIOF0L_RSCK_MARK,
-	LCDCSYN_MARK, LCDCSYN2_MARK, DV_CKI_MARK,
-	LCDLCLK_MARK, DREQ1_MARK, MSIOF0L_RXD_MARK,
-	LCDDON_MARK, LCDDON2_MARK, DACK1_MARK, MSIOF0L_TXD_MARK,
-	VIO_DR0_MARK, VIO_DR1_MARK, VIO_DR2_MARK, VIO_DR3_MARK,
-	VIO_DR4_MARK, VIO_DR5_MARK, VIO_DR6_MARK, VIO_DR7_MARK,
-	VIO_VDR_MARK, VIO_HDR_MARK,
-	VIO_CLKR_MARK, VIO_CKOR_MARK,
-	SCIFA1_TXD_MARK, GPS_PGFA0_MARK,
-	SCIFA1_SCK_MARK, GPS_PGFA1_MARK,
-	SCIFA1_RTS_MARK, GPS_EPPSINMON_MARK,
-	SCIFA1_RXD_MARK, SCIFA1_CTS_MARK,
-	MSIOF1_TXD_MARK, SCIFA1_TXD2_MARK, GPS_TXD_MARK,
-	MSIOF1_TSYNC_MARK, SCIFA1_CTS2_MARK, I2C_SDA2_MARK,
-	MSIOF1_TSCK_MARK, SCIFA1_SCK2_MARK,
-	MSIOF1_RXD_MARK, SCIFA1_RXD2_MARK, GPS_RXD_MARK,
-	MSIOF1_RSCK_MARK, SCIFA1_RTS2_MARK,
-	MSIOF1_RSYNC_MARK, I2C_SCL2_MARK,
-	MSIOF1_MCK0_MARK, MSIOF1_MCK1_MARK,
-	MSIOF1_SS1_MARK, EDBGREQ3_MARK,
-	MSIOF1_SS2_MARK,
-	PORT236_IROUT_MARK, IRDA_OUT_MARK,
-	IRDA_IN_MARK, IRDA_FIRSEL_MARK,
-	TPU1TO0_MARK, TS_SPSYNC3_MARK,
-	TPU1TO1_MARK, TS_SDAT3_MARK,
-	TPU1TO2_MARK, TS_SDEN3_MARK, PORT241_MSIOF2_SS1_MARK,
-	TPU1TO3_MARK, PORT242_MSIOF2_TSCK_MARK,
-	M13_BSW_MARK, PORT243_MSIOF2_TSYNC_MARK,
-	M14_GSW_MARK, PORT244_MSIOF2_TXD_MARK,
-	PORT245_IROUT_MARK, M15_RSW_MARK,
-	SOUT3_MARK, SCIFA2_TXD1_MARK,
-	SIN3_MARK, SCIFA2_RXD1_MARK,
-	XRTS3_MARK, SCIFA2_RTS1_MARK, PORT248_MSIOF2_SS2_MARK,
-	XCTS3_MARK, SCIFA2_CTS1_MARK, PORT249_MSIOF2_RXD_MARK,
-	DINT_MARK, SCIFA2_SCK1_MARK, TS_SCK3_MARK,
-	SDHICLK0_MARK, TCK2_MARK,
-	SDHICD0_MARK,
-	SDHID0_0_MARK, TMS2_MARK,
-	SDHID0_1_MARK, TDO2_MARK,
-	SDHID0_2_MARK, TDI2_MARK,
-	SDHID0_3_MARK, RTCK2_MARK,
-
-	/* 49-6 */
-	SDHICMD0_MARK, TRST2_MARK,
-	SDHIWP0_MARK, EDBGREQ2_MARK,
-	SDHICLK1_MARK, TCK3_MARK,
-	SDHID1_0_MARK, M11_SLCD_SO2_MARK,
-	TS_SPSYNC2_MARK, TMS3_MARK,
-	SDHID1_1_MARK, M9_SLCD_AO2_MARK,
-	TS_SDAT2_MARK, TDO3_MARK,
-	SDHID1_2_MARK, M10_SLCD_CK2_MARK,
-	TS_SDEN2_MARK, TDI3_MARK,
-	SDHID1_3_MARK, M12_SLCD_CE2_MARK,
-	TS_SCK2_MARK, RTCK3_MARK,
-	SDHICMD1_MARK, TRST3_MARK,
-	SDHICLK2_MARK, SCIFB_SCK_MARK,
-	SDHID2_0_MARK, SCIFB_TXD_MARK,
-	SDHID2_1_MARK, SCIFB_CTS_MARK,
-	SDHID2_2_MARK, SCIFB_RXD_MARK,
-	SDHID2_3_MARK, SCIFB_RTS_MARK,
-	SDHICMD2_MARK,
-	RESETOUTS_MARK,
-	DIVLOCK_MARK,
-	PINMUX_MARK_END,
-};
-
-static pinmux_enum_t pinmux_data[] = {
-
-	/* specify valid pin states for each pin in GPIO mode */
-
-	/* 49-1 (GPIO) */
-	PORT_DATA_I_PD(0),
-	PORT_DATA_I_PU(1), PORT_DATA_I_PU(2), PORT_DATA_I_PU(3),
-	PORT_DATA_I_PU(4), PORT_DATA_I_PU(5), PORT_DATA_I_PU(6),
-	PORT_DATA_I_PU(7), PORT_DATA_I_PU(8), PORT_DATA_I_PU(9),
-	PORT_DATA_I_PU(10), PORT_DATA_I_PU(11), PORT_DATA_I_PU(12),
-	PORT_DATA_I_PU(13),
-	PORT_DATA_IO_PU_PD(14), PORT_DATA_IO_PU_PD(15),
-	PORT_DATA_O(16), PORT_DATA_O(17), PORT_DATA_O(18), PORT_DATA_O(19),
-	PORT_DATA_O(20), PORT_DATA_O(21), PORT_DATA_O(22), PORT_DATA_O(23),
-	PORT_DATA_O(24), PORT_DATA_O(25), PORT_DATA_O(26),
-	PORT_DATA_I_PD(27), PORT_DATA_I_PD(28),
-	PORT_DATA_O(29), PORT_DATA_O(30), PORT_DATA_O(31), PORT_DATA_O(32),
-	PORT_DATA_IO_PU(33),
-	PORT_DATA_O(34),
-	PORT_DATA_I_PU(35),
-	PORT_DATA_O(36),
-	PORT_DATA_I_PU_PD(37),
-
-	/* 49-2 (GPIO) */
-	PORT_DATA_IO_PU_PD(38),
-	PORT_DATA_IO_PD(39), PORT_DATA_IO_PD(40), PORT_DATA_IO_PD(41),
-	PORT_DATA_O(42), PORT_DATA_O(43), PORT_DATA_O(44), PORT_DATA_O(45),
-	PORT_DATA_O(46), PORT_DATA_O(47),
-	PORT_DATA_I_PU_PD(48), PORT_DATA_I_PU_PD(49), PORT_DATA_I_PU_PD(50),
-	PORT_DATA_IO_PD(51), PORT_DATA_IO_PD(52),
-	PORT_DATA_O(53),
-	PORT_DATA_IO_PD(54),
-	PORT_DATA_I_PU_PD(55),
-	PORT_DATA_IO_PU_PD(56),
-	PORT_DATA_I_PU_PD(57),
-	PORT_DATA_IO_PU_PD(58),
-	PORT_DATA_O(59), PORT_DATA_O(60), PORT_DATA_O(61), PORT_DATA_O(62),
-	PORT_DATA_O(63),
-	PORT_DATA_I_PU(64),
-	PORT_DATA_O(65), PORT_DATA_O(66), PORT_DATA_O(67), PORT_DATA_O(68),
-	PORT_DATA_IO_PD(69), PORT_DATA_IO_PD(70),
-	PORT_DATA_I_PD(71), PORT_DATA_I_PD(72), PORT_DATA_I_PD(73),
-	PORT_DATA_I_PD(74),
-	PORT_DATA_IO_PU_PD(75), PORT_DATA_IO_PU_PD(76),
-	PORT_DATA_IO_PD(77), PORT_DATA_IO_PD(78),
-	PORT_DATA_O(79),
-	PORT_DATA_IO_PD(80), PORT_DATA_IO_PD(81), PORT_DATA_IO_PD(82),
-	PORT_DATA_IO_PU_PD(83), PORT_DATA_IO_PU_PD(84),
-	PORT_DATA_IO_PU_PD(85), PORT_DATA_IO_PU_PD(86),
-	PORT_DATA_I_PD(87),
-	PORT_DATA_IO_PU_PD(88),
-	PORT_DATA_I_PU_PD(89), PORT_DATA_I_PU_PD(90),
-
-	/* 49-3 (GPIO) */
-	PORT_DATA_O(91), PORT_DATA_O(92), PORT_DATA_O(93), PORT_DATA_O(94),
-	PORT_DATA_I_PU_PD(95),
-	PORT_DATA_IO_PU_PD(96), PORT_DATA_IO_PU_PD(97), PORT_DATA_IO_PU_PD(98),
-	PORT_DATA_IO_PU_PD(99),	PORT_DATA_IO_PU_PD(100),
-	PORT_DATA_IO(101), PORT_DATA_IO(102), PORT_DATA_IO(103),
-	PORT_DATA_IO_PD(104), PORT_DATA_IO_PD(105), PORT_DATA_IO_PD(106),
-	PORT_DATA_IO_PD(107),
-	PORT_DATA_IO_PU_PD(108), PORT_DATA_IO_PU_PD(109),
-	PORT_DATA_IO_PU_PD(110), PORT_DATA_IO_PU_PD(111),
-	PORT_DATA_IO_PU_PD(112), PORT_DATA_IO_PU_PD(113),
-	PORT_DATA_IO_PU_PD(114),
-	PORT_DATA_IO_PU(115), PORT_DATA_IO_PU(116), PORT_DATA_IO_PU(117),
-	PORT_DATA_IO_PU(118), PORT_DATA_IO_PU(119), PORT_DATA_IO_PU(120),
-	PORT_DATA_IO_PU(121), PORT_DATA_IO_PU(122), PORT_DATA_IO_PU(123),
-	PORT_DATA_IO_PU(124), PORT_DATA_IO_PU(125), PORT_DATA_IO_PU(126),
-	PORT_DATA_IO_PU(127), PORT_DATA_IO_PU(128), PORT_DATA_IO_PU(129),
-	PORT_DATA_IO_PU(130),
-	PORT_DATA_O(131), PORT_DATA_O(132), PORT_DATA_O(133),
-	PORT_DATA_IO_PU(134),
-	PORT_DATA_O(135), PORT_DATA_O(136),
-	PORT_DATA_I_PU_PD(137),
-	PORT_DATA_IO(138),
-	PORT_DATA_IO_PU_PD(139),
-	PORT_DATA_IO(140), PORT_DATA_IO(141),
-	PORT_DATA_I_PU(142),
-	PORT_DATA_O(143), PORT_DATA_O(144),
-	PORT_DATA_I_PU(145),
-
-	/* 49-4 (GPIO) */
-	PORT_DATA_O(146),
-	PORT_DATA_I_PU_PD(147),
-	PORT_DATA_I_PD(148), PORT_DATA_I_PD(149),
-	PORT_DATA_IO_PD(150), PORT_DATA_IO_PD(151), PORT_DATA_IO_PD(152),
-	PORT_DATA_IO_PD(153), PORT_DATA_IO_PD(154), PORT_DATA_IO_PD(155),
-	PORT_DATA_IO_PD(156), PORT_DATA_IO_PD(157), PORT_DATA_IO_PD(158),
-	PORT_DATA_IO_PD(159), PORT_DATA_IO_PD(160), PORT_DATA_IO_PD(161),
-	PORT_DATA_IO_PD(162), PORT_DATA_IO_PD(163), PORT_DATA_IO_PD(164),
-	PORT_DATA_IO_PD(165), PORT_DATA_IO_PD(166),
-	PORT_DATA_IO_PU_PD(167),
-	PORT_DATA_O(168),
-	PORT_DATA_I_PD(169), PORT_DATA_I_PD(170),
-	PORT_DATA_O(171),
-	PORT_DATA_IO_PD(172), PORT_DATA_IO_PD(173),
-	PORT_DATA_O(174),
-	PORT_DATA_IO_PD(175), PORT_DATA_IO_PD(176), PORT_DATA_IO_PD(177),
-	PORT_DATA_IO_PD(178), PORT_DATA_IO_PD(179), PORT_DATA_IO_PD(180),
-	PORT_DATA_IO_PD(181), PORT_DATA_IO_PD(182), PORT_DATA_IO_PD(183),
-	PORT_DATA_IO_PD(184), PORT_DATA_IO_PD(185), PORT_DATA_IO_PD(186),
-	PORT_DATA_IO_PD(187), PORT_DATA_IO_PD(188), PORT_DATA_IO_PD(189),
-	PORT_DATA_IO_PD(190), PORT_DATA_IO_PD(191), PORT_DATA_IO_PD(192),
-	PORT_DATA_IO_PD(193), PORT_DATA_IO_PD(194), PORT_DATA_IO_PD(195),
-	PORT_DATA_IO_PD(196), PORT_DATA_IO_PD(197), PORT_DATA_IO_PD(198),
-	PORT_DATA_O(199),
-	PORT_DATA_IO_PD(200),
-
-	/* 49-5 (GPIO) */
-	PORT_DATA_O(201),
-	PORT_DATA_IO_PD(202), PORT_DATA_IO_PD(203),
-	PORT_DATA_I(204),
-	PORT_DATA_O(205),
-	PORT_DATA_IO_PD(206), PORT_DATA_IO_PD(207), PORT_DATA_IO_PD(208),
-	PORT_DATA_IO_PD(209), PORT_DATA_IO_PD(210), PORT_DATA_IO_PD(211),
-	PORT_DATA_IO_PD(212), PORT_DATA_IO_PD(213), PORT_DATA_IO_PD(214),
-	PORT_DATA_IO_PD(215), PORT_DATA_IO_PD(216),
-	PORT_DATA_O(217),
-	PORT_DATA_I_PU_PD(218), PORT_DATA_I_PU_PD(219),
-	PORT_DATA_O(220), PORT_DATA_O(221), PORT_DATA_O(222),
-	PORT_DATA_I_PD(223),
-	PORT_DATA_I_PU_PD(224),
-	PORT_DATA_O(225),
-	PORT_DATA_IO_PD(226),
-	PORT_DATA_IO_PU_PD(227),
-	PORT_DATA_I_PD(228),
-	PORT_DATA_IO_PD(229), PORT_DATA_IO_PD(230),
-	PORT_DATA_I_PU_PD(231), PORT_DATA_I_PU_PD(232),
-	PORT_DATA_IO_PU_PD(233), PORT_DATA_IO_PU_PD(234),
-	PORT_DATA_I_PU_PD(235),
-	PORT_DATA_O(236),
-	PORT_DATA_I_PD(237),
-	PORT_DATA_IO_PU_PD(238), PORT_DATA_IO_PU_PD(239),
-	PORT_DATA_IO_PD(240), PORT_DATA_IO_PD(241),
-	PORT_DATA_IO_PD(242), PORT_DATA_IO_PD(243),
-	PORT_DATA_O(244),
-	PORT_DATA_IO_PU_PD(245),
-	PORT_DATA_O(246),
-	PORT_DATA_I_PD(247),
-	PORT_DATA_IO_PU_PD(248),
-	PORT_DATA_I_PU_PD(249),
-	PORT_DATA_IO_PD(250), PORT_DATA_IO_PD(251),
-	PORT_DATA_IO_PU_PD(252), PORT_DATA_IO_PU_PD(253),
-	PORT_DATA_IO_PU_PD(254), PORT_DATA_IO_PU_PD(255),
-	PORT_DATA_IO_PU_PD(256),
-
-	/* 49-6 (GPIO) */
-	PORT_DATA_IO_PU_PD(257), PORT_DATA_IO_PU_PD(258),
-	PORT_DATA_IO_PD(259),
-	PORT_DATA_IO_PU(260), PORT_DATA_IO_PU(261), PORT_DATA_IO_PU(262),
-	PORT_DATA_IO_PU(263), PORT_DATA_IO_PU(264),
-	PORT_DATA_O(265),
-	PORT_DATA_IO_PU(266), PORT_DATA_IO_PU(267), PORT_DATA_IO_PU(268),
-	PORT_DATA_IO_PU(269), PORT_DATA_IO_PU(270),
-	PORT_DATA_O(271),
-	PORT_DATA_I_PD(272),
-
-	/* Special Pull-up / Pull-down Functions */
-	PINMUX_DATA(PORT48_KEYIN0_PU_MARK, MSELBCR_MSEL2_1,
-		    PORT48_FN2, PORT48_IN_PU),
-	PINMUX_DATA(PORT49_KEYIN1_PU_MARK, MSELBCR_MSEL2_1,
-		    PORT49_FN2, PORT49_IN_PU),
-	PINMUX_DATA(PORT50_KEYIN2_PU_MARK, MSELBCR_MSEL2_1,
-		    PORT50_FN2, PORT50_IN_PU),
-	PINMUX_DATA(PORT55_KEYIN3_PU_MARK, MSELBCR_MSEL2_1,
-		    PORT55_FN2, PORT55_IN_PU),
-	PINMUX_DATA(PORT56_KEYIN4_PU_MARK, MSELBCR_MSEL2_1,
-		    PORT56_FN2, PORT56_IN_PU),
-	PINMUX_DATA(PORT57_KEYIN5_PU_MARK, MSELBCR_MSEL2_1,
-		    PORT57_FN2, PORT57_IN_PU),
-	PINMUX_DATA(PORT58_KEYIN6_PU_MARK, MSELBCR_MSEL2_1,
-		    PORT58_FN2, PORT58_IN_PU),
-
-	/* 49-1 (FN) */
-	PINMUX_DATA(VBUS0_MARK, PORT0_FN1),
-	PINMUX_DATA(CPORT0_MARK, PORT1_FN1),
-	PINMUX_DATA(CPORT1_MARK, PORT2_FN1),
-	PINMUX_DATA(CPORT2_MARK, PORT3_FN1),
-	PINMUX_DATA(CPORT3_MARK, PORT4_FN1),
-	PINMUX_DATA(CPORT4_MARK, PORT5_FN1),
-	PINMUX_DATA(CPORT5_MARK, PORT6_FN1),
-	PINMUX_DATA(CPORT6_MARK, PORT7_FN1),
-	PINMUX_DATA(CPORT7_MARK, PORT8_FN1),
-	PINMUX_DATA(CPORT8_MARK, PORT9_FN1),
-	PINMUX_DATA(CPORT9_MARK, PORT10_FN1),
-	PINMUX_DATA(CPORT10_MARK, PORT11_FN1),
-	PINMUX_DATA(CPORT11_MARK, PORT12_FN1),
-	PINMUX_DATA(SIN2_MARK, PORT12_FN2),
-	PINMUX_DATA(CPORT12_MARK, PORT13_FN1),
-	PINMUX_DATA(XCTS2_MARK, PORT13_FN2),
-	PINMUX_DATA(CPORT13_MARK, PORT14_FN1),
-	PINMUX_DATA(RFSPO4_MARK, PORT14_FN2),
-	PINMUX_DATA(CPORT14_MARK, PORT15_FN1),
-	PINMUX_DATA(RFSPO5_MARK, PORT15_FN2),
-	PINMUX_DATA(CPORT15_MARK, PORT16_FN1),
-	PINMUX_DATA(CPORT16_MARK, PORT17_FN1),
-	PINMUX_DATA(CPORT17_MARK, PORT18_FN1),
-	PINMUX_DATA(SOUT2_MARK, PORT18_FN2),
-	PINMUX_DATA(CPORT18_MARK, PORT19_FN1),
-	PINMUX_DATA(XRTS2_MARK, PORT19_FN1),
-	PINMUX_DATA(CPORT19_MARK, PORT20_FN1),
-	PINMUX_DATA(CPORT20_MARK, PORT21_FN1),
-	PINMUX_DATA(RFSPO6_MARK, PORT21_FN2),
-	PINMUX_DATA(CPORT21_MARK, PORT22_FN1),
-	PINMUX_DATA(STATUS0_MARK, PORT22_FN2),
-	PINMUX_DATA(CPORT22_MARK, PORT23_FN1),
-	PINMUX_DATA(STATUS1_MARK, PORT23_FN2),
-	PINMUX_DATA(CPORT23_MARK, PORT24_FN1),
-	PINMUX_DATA(STATUS2_MARK, PORT24_FN2),
-	PINMUX_DATA(RFSPO7_MARK, PORT24_FN3),
-	PINMUX_DATA(MPORT0_MARK, PORT25_FN1),
-	PINMUX_DATA(MPORT1_MARK, PORT26_FN1),
-	PINMUX_DATA(B_SYNLD1_MARK, PORT27_FN1),
-	PINMUX_DATA(B_SYNLD2_MARK, PORT28_FN1),
-	PINMUX_DATA(XMAINPS_MARK, PORT29_FN1),
-	PINMUX_DATA(XDIVPS_MARK, PORT30_FN1),
-	PINMUX_DATA(XIDRST_MARK, PORT31_FN1),
-	PINMUX_DATA(IDCLK_MARK, PORT32_FN1),
-	PINMUX_DATA(IDIO_MARK, PORT33_FN1),
-	PINMUX_DATA(SOUT1_MARK, PORT34_FN1),
-	PINMUX_DATA(SCIFA4_TXD_MARK, PORT34_FN2),
-	PINMUX_DATA(M02_BERDAT_MARK, PORT34_FN3),
-	PINMUX_DATA(SIN1_MARK, PORT35_FN1),
-	PINMUX_DATA(SCIFA4_RXD_MARK, PORT35_FN2),
-	PINMUX_DATA(XWUP_MARK, PORT35_FN3),
-	PINMUX_DATA(XRTS1_MARK, PORT36_FN1),
-	PINMUX_DATA(SCIFA4_RTS_MARK, PORT36_FN2),
-	PINMUX_DATA(M03_BERCLK_MARK, PORT36_FN3),
-	PINMUX_DATA(XCTS1_MARK, PORT37_FN1),
-	PINMUX_DATA(SCIFA4_CTS_MARK, PORT37_FN2),
-
-	/* 49-2 (FN) */
-	PINMUX_DATA(HSU_IQ_AGC6_MARK, PORT38_FN1),
-	PINMUX_DATA(MFG2_IN2_MARK, PORT38_FN2),
-	PINMUX_DATA(MSIOF2_MCK0_MARK, PORT38_FN3),
-	PINMUX_DATA(HSU_IQ_AGC5_MARK, PORT39_FN1),
-	PINMUX_DATA(MFG2_IN1_MARK, PORT39_FN2),
-	PINMUX_DATA(MSIOF2_MCK1_MARK, PORT39_FN3),
-	PINMUX_DATA(HSU_IQ_AGC4_MARK, PORT40_FN1),
-	PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT40_FN3),
-	PINMUX_DATA(HSU_IQ_AGC3_MARK, PORT41_FN1),
-	PINMUX_DATA(MFG2_OUT1_MARK, PORT41_FN2),
-	PINMUX_DATA(MSIOF2_RSCK_MARK, PORT41_FN3),
-	PINMUX_DATA(HSU_IQ_AGC2_MARK, PORT42_FN1),
-	PINMUX_DATA(PORT42_KEYOUT0_MARK, MSELBCR_MSEL2_1, PORT42_FN2),
-	PINMUX_DATA(HSU_IQ_AGC1_MARK, PORT43_FN1),
-	PINMUX_DATA(PORT43_KEYOUT1_MARK, MSELBCR_MSEL2_1, PORT43_FN2),
-	PINMUX_DATA(HSU_IQ_AGC0_MARK, PORT44_FN1),
-	PINMUX_DATA(PORT44_KEYOUT2_MARK, MSELBCR_MSEL2_1, PORT44_FN2),
-	PINMUX_DATA(HSU_IQ_AGC_ST_MARK, PORT45_FN1),
-	PINMUX_DATA(PORT45_KEYOUT3_MARK, MSELBCR_MSEL2_1, PORT45_FN2),
-	PINMUX_DATA(HSU_IQ_PDO_MARK, PORT46_FN1),
-	PINMUX_DATA(PORT46_KEYOUT4_MARK, MSELBCR_MSEL2_1, PORT46_FN2),
-	PINMUX_DATA(HSU_IQ_PYO_MARK, PORT47_FN1),
-	PINMUX_DATA(PORT47_KEYOUT5_MARK, MSELBCR_MSEL2_1, PORT47_FN2),
-	PINMUX_DATA(HSU_EN_TXMUX_G3MO_MARK, PORT48_FN1),
-	PINMUX_DATA(PORT48_KEYIN0_MARK, MSELBCR_MSEL2_1, PORT48_FN2),
-	PINMUX_DATA(HSU_I_TXMUX_G3MO_MARK, PORT49_FN1),
-	PINMUX_DATA(PORT49_KEYIN1_MARK, MSELBCR_MSEL2_1, PORT49_FN2),
-	PINMUX_DATA(HSU_Q_TXMUX_G3MO_MARK, PORT50_FN1),
-	PINMUX_DATA(PORT50_KEYIN2_MARK, MSELBCR_MSEL2_1, PORT50_FN2),
-	PINMUX_DATA(HSU_SYO_MARK, PORT51_FN1),
-	PINMUX_DATA(PORT51_MSIOF2_TSYNC_MARK, PORT51_FN2),
-	PINMUX_DATA(HSU_SDO_MARK, PORT52_FN1),
-	PINMUX_DATA(PORT52_MSIOF2_TSCK_MARK, PORT52_FN2),
-	PINMUX_DATA(HSU_TGTTI_G3MO_MARK, PORT53_FN1),
-	PINMUX_DATA(PORT53_MSIOF2_TXD_MARK, PORT53_FN2),
-	PINMUX_DATA(B_TIME_STAMP_MARK, PORT54_FN1),
-	PINMUX_DATA(PORT54_MSIOF2_RXD_MARK, PORT54_FN2),
-	PINMUX_DATA(HSU_SDI_MARK, PORT55_FN1),
-	PINMUX_DATA(PORT55_KEYIN3_MARK, MSELBCR_MSEL2_1, PORT55_FN2),
-	PINMUX_DATA(HSU_SCO_MARK, PORT56_FN1),
-	PINMUX_DATA(PORT56_KEYIN4_MARK, MSELBCR_MSEL2_1, PORT56_FN2),
-	PINMUX_DATA(HSU_DREQ_MARK, PORT57_FN1),
-	PINMUX_DATA(PORT57_KEYIN5_MARK, MSELBCR_MSEL2_1, PORT57_FN2),
-	PINMUX_DATA(HSU_DACK_MARK, PORT58_FN1),
-	PINMUX_DATA(PORT58_KEYIN6_MARK, MSELBCR_MSEL2_1, PORT58_FN2),
-	PINMUX_DATA(HSU_CLK61M_MARK, PORT59_FN1),
-	PINMUX_DATA(PORT59_MSIOF2_SS1_MARK, PORT59_FN2),
-	PINMUX_DATA(HSU_XRST_MARK, PORT60_FN1),
-	PINMUX_DATA(PORT60_MSIOF2_SS2_MARK, PORT60_FN2),
-	PINMUX_DATA(PCMCLKO_MARK, PORT61_FN1),
-	PINMUX_DATA(SYNC8KO_MARK, PORT62_FN1),
-	PINMUX_DATA(DNPCM_A_MARK, PORT63_FN1),
-	PINMUX_DATA(UPPCM_A_MARK, PORT64_FN1),
-	PINMUX_DATA(XTALB1L_MARK, PORT65_FN1),
-	PINMUX_DATA(GPS_AGC1_MARK, PORT66_FN1),
-	PINMUX_DATA(SCIFA0_RTS_MARK, PORT66_FN2),
-	PINMUX_DATA(GPS_AGC2_MARK, PORT67_FN1),
-	PINMUX_DATA(SCIFA0_SCK_MARK, PORT67_FN2),
-	PINMUX_DATA(GPS_AGC3_MARK, PORT68_FN1),
-	PINMUX_DATA(SCIFA0_TXD_MARK, PORT68_FN2),
-	PINMUX_DATA(GPS_AGC4_MARK, PORT69_FN1),
-	PINMUX_DATA(SCIFA0_RXD_MARK, PORT69_FN2),
-	PINMUX_DATA(GPS_PWRD_MARK, PORT70_FN1),
-	PINMUX_DATA(SCIFA0_CTS_MARK, PORT70_FN2),
-	PINMUX_DATA(GPS_IM_MARK, PORT71_FN1),
-	PINMUX_DATA(GPS_IS_MARK, PORT72_FN1),
-	PINMUX_DATA(GPS_QM_MARK, PORT73_FN1),
-	PINMUX_DATA(GPS_QS_MARK, PORT74_FN1),
-	PINMUX_DATA(SIUBOMC_MARK, PORT75_FN1),
-	PINMUX_DATA(TPU2TO0_MARK, PORT75_FN3),
-	PINMUX_DATA(SIUCKB_MARK, PORT76_FN1),
-	PINMUX_DATA(TPU2TO1_MARK, PORT76_FN3),
-	PINMUX_DATA(SIUBOLR_MARK, PORT77_FN1),
-	PINMUX_DATA(BBIF2_TSYNC_MARK, PORT77_FN2),
-	PINMUX_DATA(TPU2TO2_MARK, PORT77_FN3),
-	PINMUX_DATA(SIUBOBT_MARK, PORT78_FN1),
-	PINMUX_DATA(BBIF2_TSCK_MARK, PORT78_FN2),
-	PINMUX_DATA(TPU2TO3_MARK, PORT78_FN3),
-	PINMUX_DATA(SIUBOSLD_MARK, PORT79_FN1),
-	PINMUX_DATA(BBIF2_TXD_MARK, PORT79_FN2),
-	PINMUX_DATA(TPU3TO0_MARK, PORT79_FN3),
-	PINMUX_DATA(SIUBILR_MARK, PORT80_FN1),
-	PINMUX_DATA(TPU3TO1_MARK, PORT80_FN3),
-	PINMUX_DATA(SIUBIBT_MARK, PORT81_FN1),
-	PINMUX_DATA(TPU3TO2_MARK, PORT81_FN3),
-	PINMUX_DATA(SIUBISLD_MARK, PORT82_FN1),
-	PINMUX_DATA(TPU3TO3_MARK, PORT82_FN3),
-	PINMUX_DATA(NMI_MARK, PORT83_FN1),
-	PINMUX_DATA(TPU4TO0_MARK, PORT83_FN3),
-	PINMUX_DATA(DNPCM_M_MARK, PORT84_FN1),
-	PINMUX_DATA(TPU4TO1_MARK, PORT84_FN3),
-	PINMUX_DATA(TPU4TO2_MARK, PORT85_FN3),
-	PINMUX_DATA(TPU4TO3_MARK, PORT86_FN3),
-	PINMUX_DATA(IRQ_TMPB_MARK, PORT87_FN1),
-	PINMUX_DATA(PWEN_MARK, PORT88_FN1),
-	PINMUX_DATA(MFG1_OUT1_MARK, PORT88_FN2),
-	PINMUX_DATA(OVCN_MARK, PORT89_FN1),
-	PINMUX_DATA(MFG1_IN1_MARK, PORT89_FN2),
-	PINMUX_DATA(OVCN2_MARK, PORT90_FN1),
-	PINMUX_DATA(MFG1_IN2_MARK, PORT90_FN2),
-
-	/* 49-3 (FN) */
-	PINMUX_DATA(RFSPO1_MARK, PORT91_FN1),
-	PINMUX_DATA(RFSPO2_MARK, PORT92_FN1),
-	PINMUX_DATA(RFSPO3_MARK, PORT93_FN1),
-	PINMUX_DATA(PORT93_VIO_CKO2_MARK, PORT93_FN2),
-	PINMUX_DATA(USBTERM_MARK, PORT94_FN1),
-	PINMUX_DATA(EXTLP_MARK, PORT94_FN2),
-	PINMUX_DATA(IDIN_MARK, PORT95_FN1),
-	PINMUX_DATA(SCIFA5_CTS_MARK, PORT96_FN1),
-	PINMUX_DATA(MFG0_IN1_MARK, PORT96_FN2),
-	PINMUX_DATA(SCIFA5_RTS_MARK, PORT97_FN1),
-	PINMUX_DATA(MFG0_IN2_MARK, PORT97_FN2),
-	PINMUX_DATA(SCIFA5_RXD_MARK, PORT98_FN1),
-	PINMUX_DATA(SCIFA5_TXD_MARK, PORT99_FN1),
-	PINMUX_DATA(SCIFA5_SCK_MARK, PORT100_FN1),
-	PINMUX_DATA(MFG0_OUT1_MARK, PORT100_FN2),
-	PINMUX_DATA(A0_EA0_MARK, PORT101_FN1),
-	PINMUX_DATA(BS_MARK, PORT101_FN2),
-	PINMUX_DATA(A14_EA14_MARK, PORT102_FN1),
-	PINMUX_DATA(PORT102_KEYOUT0_MARK, MSELBCR_MSEL2_0, PORT102_FN2),
-	PINMUX_DATA(A15_EA15_MARK, PORT103_FN1),
-	PINMUX_DATA(PORT103_KEYOUT1_MARK, MSELBCR_MSEL2_0, PORT103_FN2),
-	PINMUX_DATA(DV_CLKOL_MARK, PORT103_FN3),
-	PINMUX_DATA(A16_EA16_MARK, PORT104_FN1),
-	PINMUX_DATA(PORT104_KEYOUT2_MARK, MSELBCR_MSEL2_0, PORT104_FN2),
-	PINMUX_DATA(DV_VSYNCL_MARK, PORT104_FN3),
-	PINMUX_DATA(MSIOF0_SS1_MARK, PORT104_FN4),
-	PINMUX_DATA(A17_EA17_MARK, PORT105_FN1),
-	PINMUX_DATA(PORT105_KEYOUT3_MARK, MSELBCR_MSEL2_0, PORT105_FN2),
-	PINMUX_DATA(DV_HSYNCL_MARK, PORT105_FN3),
-	PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT105_FN4),
-	PINMUX_DATA(A18_EA18_MARK, PORT106_FN1),
-	PINMUX_DATA(PORT106_KEYOUT4_MARK, MSELBCR_MSEL2_0, PORT106_FN2),
-	PINMUX_DATA(DV_DL0_MARK, PORT106_FN3),
-	PINMUX_DATA(MSIOF0_TSCK_MARK, PORT106_FN4),
-	PINMUX_DATA(A19_EA19_MARK, PORT107_FN1),
-	PINMUX_DATA(PORT107_KEYOUT5_MARK, MSELBCR_MSEL2_0, PORT107_FN2),
-	PINMUX_DATA(DV_DL1_MARK, PORT107_FN3),
-	PINMUX_DATA(MSIOF0_TXD_MARK, PORT107_FN4),
-	PINMUX_DATA(A20_EA20_MARK, PORT108_FN1),
-	PINMUX_DATA(PORT108_KEYIN0_MARK, MSELBCR_MSEL2_0, PORT108_FN2),
-	PINMUX_DATA(DV_DL2_MARK, PORT108_FN3),
-	PINMUX_DATA(MSIOF0_RSCK_MARK, PORT108_FN4),
-	PINMUX_DATA(A21_EA21_MARK, PORT109_FN1),
-	PINMUX_DATA(PORT109_KEYIN1_MARK, MSELBCR_MSEL2_0, PORT109_FN2),
-	PINMUX_DATA(DV_DL3_MARK, PORT109_FN3),
-	PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT109_FN4),
-	PINMUX_DATA(A22_EA22_MARK, PORT110_FN1),
-	PINMUX_DATA(PORT110_KEYIN2_MARK, MSELBCR_MSEL2_0, PORT110_FN2),
-	PINMUX_DATA(DV_DL4_MARK, PORT110_FN3),
-	PINMUX_DATA(MSIOF0_MCK0_MARK, PORT110_FN4),
-	PINMUX_DATA(A23_EA23_MARK, PORT111_FN1),
-	PINMUX_DATA(PORT111_KEYIN3_MARK, MSELBCR_MSEL2_0, PORT111_FN2),
-	PINMUX_DATA(DV_DL5_MARK, PORT111_FN3),
-	PINMUX_DATA(MSIOF0_MCK1_MARK, PORT111_FN4),
-	PINMUX_DATA(A24_EA24_MARK, PORT112_FN1),
-	PINMUX_DATA(PORT112_KEYIN4_MARK, MSELBCR_MSEL2_0, PORT112_FN2),
-	PINMUX_DATA(DV_DL6_MARK, PORT112_FN3),
-	PINMUX_DATA(MSIOF0_RXD_MARK, PORT112_FN4),
-	PINMUX_DATA(A25_EA25_MARK, PORT113_FN1),
-	PINMUX_DATA(PORT113_KEYIN5_MARK, MSELBCR_MSEL2_0, PORT113_FN2),
-	PINMUX_DATA(DV_DL7_MARK, PORT113_FN3),
-	PINMUX_DATA(MSIOF0_SS2_MARK, PORT113_FN4),
-	PINMUX_DATA(A26_MARK, PORT114_FN1),
-	PINMUX_DATA(PORT113_KEYIN6_MARK, MSELBCR_MSEL2_0, PORT114_FN2),
-	PINMUX_DATA(DV_CLKIL_MARK, PORT114_FN3),
-	PINMUX_DATA(D0_ED0_NAF0_MARK, PORT115_FN1),
-	PINMUX_DATA(D1_ED1_NAF1_MARK, PORT116_FN1),
-	PINMUX_DATA(D2_ED2_NAF2_MARK, PORT117_FN1),
-	PINMUX_DATA(D3_ED3_NAF3_MARK, PORT118_FN1),
-	PINMUX_DATA(D4_ED4_NAF4_MARK, PORT119_FN1),
-	PINMUX_DATA(D5_ED5_NAF5_MARK, PORT120_FN1),
-	PINMUX_DATA(D6_ED6_NAF6_MARK, PORT121_FN1),
-	PINMUX_DATA(D7_ED7_NAF7_MARK, PORT122_FN1),
-	PINMUX_DATA(D8_ED8_NAF8_MARK, PORT123_FN1),
-	PINMUX_DATA(D9_ED9_NAF9_MARK, PORT124_FN1),
-	PINMUX_DATA(D10_ED10_NAF10_MARK, PORT125_FN1),
-	PINMUX_DATA(D11_ED11_NAF11_MARK, PORT126_FN1),
-	PINMUX_DATA(D12_ED12_NAF12_MARK, PORT127_FN1),
-	PINMUX_DATA(D13_ED13_NAF13_MARK, PORT128_FN1),
-	PINMUX_DATA(D14_ED14_NAF14_MARK, PORT129_FN1),
-	PINMUX_DATA(D15_ED15_NAF15_MARK, PORT130_FN1),
-	PINMUX_DATA(CS4_MARK, PORT131_FN1),
-	PINMUX_DATA(CS5A_MARK, PORT132_FN1),
-	PINMUX_DATA(CS5B_MARK, PORT133_FN1),
-	PINMUX_DATA(FCE1_MARK, PORT133_FN2),
-	PINMUX_DATA(CS6B_MARK, PORT134_FN1),
-	PINMUX_DATA(XCS2_MARK, PORT134_FN2),
-	PINMUX_DATA(FCE0_MARK, PORT135_FN1),
-	PINMUX_DATA(CS6A_MARK, PORT136_FN1),
-	PINMUX_DATA(DACK0_MARK, PORT136_FN2),
-	PINMUX_DATA(WAIT_MARK, PORT137_FN1),
-	PINMUX_DATA(DREQ0_MARK, PORT137_FN2),
-	PINMUX_DATA(RD_XRD_MARK, PORT138_FN1),
-	PINMUX_DATA(A27_MARK, PORT139_FN1),
-	PINMUX_DATA(RDWR_XWE_MARK, PORT139_FN2),
-	PINMUX_DATA(WE0_XWR0_FWE_MARK, PORT140_FN1),
-	PINMUX_DATA(WE1_XWR1_MARK, PORT141_FN1),
-	PINMUX_DATA(FRB_MARK, PORT142_FN1),
-	PINMUX_DATA(CKO_MARK, PORT143_FN1),
-	PINMUX_DATA(NBRSTOUT_MARK, PORT144_FN1),
-	PINMUX_DATA(NBRST_MARK, PORT145_FN1),
-
-	/* 49-4 (FN) */
-	PINMUX_DATA(RFSPO0_MARK, PORT146_FN1),
-	PINMUX_DATA(PORT146_VIO_CKO2_MARK, PORT146_FN2),
-	PINMUX_DATA(TSTMD_MARK, PORT147_FN1),
-	PINMUX_DATA(VIO_VD_MARK, PORT148_FN1),
-	PINMUX_DATA(VIO_HD_MARK, PORT149_FN1),
-	PINMUX_DATA(VIO_D0_MARK, PORT150_FN1),
-	PINMUX_DATA(VIO_D1_MARK, PORT151_FN1),
-	PINMUX_DATA(VIO_D2_MARK, PORT152_FN1),
-	PINMUX_DATA(VIO_D3_MARK, PORT153_FN1),
-	PINMUX_DATA(VIO_D4_MARK, PORT154_FN1),
-	PINMUX_DATA(VIO_D5_MARK, PORT155_FN1),
-	PINMUX_DATA(VIO_D6_MARK, PORT156_FN1),
-	PINMUX_DATA(VIO_D7_MARK, PORT157_FN1),
-	PINMUX_DATA(VIO_D8_MARK, PORT158_FN1),
-	PINMUX_DATA(VIO_D9_MARK, PORT159_FN1),
-	PINMUX_DATA(VIO_D10_MARK, PORT160_FN1),
-	PINMUX_DATA(VIO_D11_MARK, PORT161_FN1),
-	PINMUX_DATA(VIO_D12_MARK, PORT162_FN1),
-	PINMUX_DATA(VIO_D13_MARK, PORT163_FN1),
-	PINMUX_DATA(VIO_D14_MARK, PORT164_FN1),
-	PINMUX_DATA(VIO_D15_MARK, PORT165_FN1),
-	PINMUX_DATA(VIO_CLK_MARK, PORT166_FN1),
-	PINMUX_DATA(VIO_FIELD_MARK, PORT167_FN1),
-	PINMUX_DATA(VIO_CKO_MARK, PORT168_FN1),
-	PINMUX_DATA(MFG3_IN1_MARK, PORT169_FN2),
-	PINMUX_DATA(MFG3_IN2_MARK, PORT170_FN2),
-	PINMUX_DATA(M9_SLCD_A01_MARK, PORT171_FN1),
-	PINMUX_DATA(MFG3_OUT1_MARK, PORT171_FN2),
-	PINMUX_DATA(TPU0TO0_MARK, PORT171_FN3),
-	PINMUX_DATA(M10_SLCD_CK1_MARK, PORT172_FN1),
-	PINMUX_DATA(MFG4_IN1_MARK, PORT172_FN2),
-	PINMUX_DATA(TPU0TO1_MARK, PORT172_FN3),
-	PINMUX_DATA(M11_SLCD_SO1_MARK, PORT173_FN1),
-	PINMUX_DATA(MFG4_IN2_MARK, PORT173_FN2),
-	PINMUX_DATA(TPU0TO2_MARK, PORT173_FN3),
-	PINMUX_DATA(M12_SLCD_CE1_MARK, PORT174_FN1),
-	PINMUX_DATA(MFG4_OUT1_MARK, PORT174_FN2),
-	PINMUX_DATA(TPU0TO3_MARK, PORT174_FN3),
-	PINMUX_DATA(LCDD0_MARK, PORT175_FN1),
-	PINMUX_DATA(PORT175_KEYOUT0_MARK, PORT175_FN2),
-	PINMUX_DATA(DV_D0_MARK, PORT175_FN3),
-	PINMUX_DATA(SIUCKA_MARK, PORT175_FN4),
-	PINMUX_DATA(MFG0_OUT2_MARK, PORT175_FN5),
-	PINMUX_DATA(LCDD1_MARK, PORT176_FN1),
-	PINMUX_DATA(PORT176_KEYOUT1_MARK, PORT176_FN2),
-	PINMUX_DATA(DV_D1_MARK, PORT176_FN3),
-	PINMUX_DATA(SIUAOLR_MARK, PORT176_FN4),
-	PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT176_FN5),
-	PINMUX_DATA(LCDD2_MARK, PORT177_FN1),
-	PINMUX_DATA(PORT177_KEYOUT2_MARK, PORT177_FN2),
-	PINMUX_DATA(DV_D2_MARK, PORT177_FN3),
-	PINMUX_DATA(SIUAOBT_MARK, PORT177_FN4),
-	PINMUX_DATA(BBIF2_TSCK1_MARK, PORT177_FN5),
-	PINMUX_DATA(LCDD3_MARK, PORT178_FN1),
-	PINMUX_DATA(PORT178_KEYOUT3_MARK, PORT178_FN2),
-	PINMUX_DATA(DV_D3_MARK, PORT178_FN3),
-	PINMUX_DATA(SIUAOSLD_MARK, PORT178_FN4),
-	PINMUX_DATA(BBIF2_TXD1_MARK, PORT178_FN5),
-	PINMUX_DATA(LCDD4_MARK, PORT179_FN1),
-	PINMUX_DATA(PORT179_KEYOUT4_MARK, PORT179_FN2),
-	PINMUX_DATA(DV_D4_MARK, PORT179_FN3),
-	PINMUX_DATA(SIUAISPD_MARK, PORT179_FN4),
-	PINMUX_DATA(MFG1_OUT2_MARK, PORT179_FN5),
-	PINMUX_DATA(LCDD5_MARK, PORT180_FN1),
-	PINMUX_DATA(PORT180_KEYOUT5_MARK, PORT180_FN2),
-	PINMUX_DATA(DV_D5_MARK, PORT180_FN3),
-	PINMUX_DATA(SIUAILR_MARK, PORT180_FN4),
-	PINMUX_DATA(MFG2_OUT2_MARK, PORT180_FN5),
-	PINMUX_DATA(LCDD6_MARK, PORT181_FN1),
-	PINMUX_DATA(DV_D6_MARK, PORT181_FN3),
-	PINMUX_DATA(SIUAIBT_MARK, PORT181_FN4),
-	PINMUX_DATA(MFG3_OUT2_MARK, PORT181_FN5),
-	PINMUX_DATA(XWR2_MARK, PORT181_FN7),
-	PINMUX_DATA(LCDD7_MARK, PORT182_FN1),
-	PINMUX_DATA(DV_D7_MARK, PORT182_FN3),
-	PINMUX_DATA(SIUAISLD_MARK, PORT182_FN4),
-	PINMUX_DATA(MFG4_OUT2_MARK, PORT182_FN5),
-	PINMUX_DATA(XWR3_MARK, PORT182_FN7),
-	PINMUX_DATA(LCDD8_MARK, PORT183_FN1),
-	PINMUX_DATA(DV_D8_MARK, PORT183_FN3),
-	PINMUX_DATA(D16_MARK, PORT183_FN6),
-	PINMUX_DATA(ED16_MARK, PORT183_FN7),
-	PINMUX_DATA(LCDD9_MARK, PORT184_FN1),
-	PINMUX_DATA(DV_D9_MARK, PORT184_FN3),
-	PINMUX_DATA(D17_MARK, PORT184_FN6),
-	PINMUX_DATA(ED17_MARK, PORT184_FN7),
-	PINMUX_DATA(LCDD10_MARK, PORT185_FN1),
-	PINMUX_DATA(DV_D10_MARK, PORT185_FN3),
-	PINMUX_DATA(D18_MARK, PORT185_FN6),
-	PINMUX_DATA(ED18_MARK, PORT185_FN7),
-	PINMUX_DATA(LCDD11_MARK, PORT186_FN1),
-	PINMUX_DATA(DV_D11_MARK, PORT186_FN3),
-	PINMUX_DATA(D19_MARK, PORT186_FN6),
-	PINMUX_DATA(ED19_MARK, PORT186_FN7),
-	PINMUX_DATA(LCDD12_MARK, PORT187_FN1),
-	PINMUX_DATA(DV_D12_MARK, PORT187_FN3),
-	PINMUX_DATA(D20_MARK, PORT187_FN6),
-	PINMUX_DATA(ED20_MARK, PORT187_FN7),
-	PINMUX_DATA(LCDD13_MARK, PORT188_FN1),
-	PINMUX_DATA(DV_D13_MARK, PORT188_FN3),
-	PINMUX_DATA(D21_MARK, PORT188_FN6),
-	PINMUX_DATA(ED21_MARK, PORT188_FN7),
-	PINMUX_DATA(LCDD14_MARK, PORT189_FN1),
-	PINMUX_DATA(DV_D14_MARK, PORT189_FN3),
-	PINMUX_DATA(D22_MARK, PORT189_FN6),
-	PINMUX_DATA(ED22_MARK, PORT189_FN7),
-	PINMUX_DATA(LCDD15_MARK, PORT190_FN1),
-	PINMUX_DATA(DV_D15_MARK, PORT190_FN3),
-	PINMUX_DATA(D23_MARK, PORT190_FN6),
-	PINMUX_DATA(ED23_MARK, PORT190_FN7),
-	PINMUX_DATA(LCDD16_MARK, PORT191_FN1),
-	PINMUX_DATA(DV_HSYNC_MARK, PORT191_FN3),
-	PINMUX_DATA(D24_MARK, PORT191_FN6),
-	PINMUX_DATA(ED24_MARK, PORT191_FN7),
-	PINMUX_DATA(LCDD17_MARK, PORT192_FN1),
-	PINMUX_DATA(DV_VSYNC_MARK, PORT192_FN3),
-	PINMUX_DATA(D25_MARK, PORT192_FN6),
-	PINMUX_DATA(ED25_MARK, PORT192_FN7),
-	PINMUX_DATA(LCDD18_MARK, PORT193_FN1),
-	PINMUX_DATA(DREQ2_MARK, PORT193_FN2),
-	PINMUX_DATA(MSIOF0L_TSCK_MARK, PORT193_FN5),
-	PINMUX_DATA(D26_MARK, PORT193_FN6),
-	PINMUX_DATA(ED26_MARK, PORT193_FN7),
-	PINMUX_DATA(LCDD19_MARK, PORT194_FN1),
-	PINMUX_DATA(MSIOF0L_TSYNC_MARK, PORT194_FN5),
-	PINMUX_DATA(D27_MARK, PORT194_FN6),
-	PINMUX_DATA(ED27_MARK, PORT194_FN7),
-	PINMUX_DATA(LCDD20_MARK, PORT195_FN1),
-	PINMUX_DATA(TS_SPSYNC1_MARK, PORT195_FN2),
-	PINMUX_DATA(MSIOF0L_MCK0_MARK, PORT195_FN5),
-	PINMUX_DATA(D28_MARK, PORT195_FN6),
-	PINMUX_DATA(ED28_MARK, PORT195_FN7),
-	PINMUX_DATA(LCDD21_MARK, PORT196_FN1),
-	PINMUX_DATA(TS_SDAT1_MARK, PORT196_FN2),
-	PINMUX_DATA(MSIOF0L_MCK1_MARK, PORT196_FN5),
-	PINMUX_DATA(D29_MARK, PORT196_FN6),
-	PINMUX_DATA(ED29_MARK, PORT196_FN7),
-	PINMUX_DATA(LCDD22_MARK, PORT197_FN1),
-	PINMUX_DATA(TS_SDEN1_MARK, PORT197_FN2),
-	PINMUX_DATA(MSIOF0L_SS1_MARK, PORT197_FN5),
-	PINMUX_DATA(D30_MARK, PORT197_FN6),
-	PINMUX_DATA(ED30_MARK, PORT197_FN7),
-	PINMUX_DATA(LCDD23_MARK, PORT198_FN1),
-	PINMUX_DATA(TS_SCK1_MARK, PORT198_FN2),
-	PINMUX_DATA(MSIOF0L_SS2_MARK, PORT198_FN5),
-	PINMUX_DATA(D31_MARK, PORT198_FN6),
-	PINMUX_DATA(ED31_MARK, PORT198_FN7),
-	PINMUX_DATA(LCDDCK_MARK, PORT199_FN1),
-	PINMUX_DATA(LCDWR_MARK, PORT199_FN2),
-	PINMUX_DATA(DV_CKO_MARK, PORT199_FN3),
-	PINMUX_DATA(SIUAOSPD_MARK, PORT199_FN4),
-	PINMUX_DATA(LCDRD_MARK, PORT200_FN1),
-	PINMUX_DATA(DACK2_MARK, PORT200_FN2),
-	PINMUX_DATA(MSIOF0L_RSYNC_MARK, PORT200_FN5),
-
-	/* 49-5 (FN) */
-	PINMUX_DATA(LCDHSYN_MARK, PORT201_FN1),
-	PINMUX_DATA(LCDCS_MARK, PORT201_FN2),
-	PINMUX_DATA(LCDCS2_MARK, PORT201_FN3),
-	PINMUX_DATA(DACK3_MARK, PORT201_FN4),
-	PINMUX_DATA(LCDDISP_MARK, PORT202_FN1),
-	PINMUX_DATA(LCDRS_MARK, PORT202_FN2),
-	PINMUX_DATA(DREQ3_MARK, PORT202_FN4),
-	PINMUX_DATA(MSIOF0L_RSCK_MARK, PORT202_FN5),
-	PINMUX_DATA(LCDCSYN_MARK, PORT203_FN1),
-	PINMUX_DATA(LCDCSYN2_MARK, PORT203_FN2),
-	PINMUX_DATA(DV_CKI_MARK, PORT203_FN3),
-	PINMUX_DATA(LCDLCLK_MARK, PORT204_FN1),
-	PINMUX_DATA(DREQ1_MARK, PORT204_FN3),
-	PINMUX_DATA(MSIOF0L_RXD_MARK, PORT204_FN5),
-	PINMUX_DATA(LCDDON_MARK, PORT205_FN1),
-	PINMUX_DATA(LCDDON2_MARK, PORT205_FN2),
-	PINMUX_DATA(DACK1_MARK, PORT205_FN3),
-	PINMUX_DATA(MSIOF0L_TXD_MARK, PORT205_FN5),
-	PINMUX_DATA(VIO_DR0_MARK, PORT206_FN1),
-	PINMUX_DATA(VIO_DR1_MARK, PORT207_FN1),
-	PINMUX_DATA(VIO_DR2_MARK, PORT208_FN1),
-	PINMUX_DATA(VIO_DR3_MARK, PORT209_FN1),
-	PINMUX_DATA(VIO_DR4_MARK, PORT210_FN1),
-	PINMUX_DATA(VIO_DR5_MARK, PORT211_FN1),
-	PINMUX_DATA(VIO_DR6_MARK, PORT212_FN1),
-	PINMUX_DATA(VIO_DR7_MARK, PORT213_FN1),
-	PINMUX_DATA(VIO_VDR_MARK, PORT214_FN1),
-	PINMUX_DATA(VIO_HDR_MARK, PORT215_FN1),
-	PINMUX_DATA(VIO_CLKR_MARK, PORT216_FN1),
-	PINMUX_DATA(VIO_CKOR_MARK, PORT217_FN1),
-	PINMUX_DATA(SCIFA1_TXD_MARK, PORT220_FN2),
-	PINMUX_DATA(GPS_PGFA0_MARK, PORT220_FN3),
-	PINMUX_DATA(SCIFA1_SCK_MARK, PORT221_FN2),
-	PINMUX_DATA(GPS_PGFA1_MARK, PORT221_FN3),
-	PINMUX_DATA(SCIFA1_RTS_MARK, PORT222_FN2),
-	PINMUX_DATA(GPS_EPPSINMON_MARK, PORT222_FN3),
-	PINMUX_DATA(SCIFA1_RXD_MARK, PORT223_FN2),
-	PINMUX_DATA(SCIFA1_CTS_MARK, PORT224_FN2),
-	PINMUX_DATA(MSIOF1_TXD_MARK, PORT225_FN1),
-	PINMUX_DATA(SCIFA1_TXD2_MARK, PORT225_FN2),
-	PINMUX_DATA(GPS_TXD_MARK, PORT225_FN3),
-	PINMUX_DATA(MSIOF1_TSYNC_MARK, PORT226_FN1),
-	PINMUX_DATA(SCIFA1_CTS2_MARK, PORT226_FN2),
-	PINMUX_DATA(I2C_SDA2_MARK, PORT226_FN3),
-	PINMUX_DATA(MSIOF1_TSCK_MARK, PORT227_FN1),
-	PINMUX_DATA(SCIFA1_SCK2_MARK, PORT227_FN2),
-	PINMUX_DATA(MSIOF1_RXD_MARK, PORT228_FN1),
-	PINMUX_DATA(SCIFA1_RXD2_MARK, PORT228_FN2),
-	PINMUX_DATA(GPS_RXD_MARK, PORT228_FN3),
-	PINMUX_DATA(MSIOF1_RSCK_MARK, PORT229_FN1),
-	PINMUX_DATA(SCIFA1_RTS2_MARK, PORT229_FN2),
-	PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT230_FN1),
-	PINMUX_DATA(I2C_SCL2_MARK, PORT230_FN3),
-	PINMUX_DATA(MSIOF1_MCK0_MARK, PORT231_FN1),
-	PINMUX_DATA(MSIOF1_MCK1_MARK, PORT232_FN1),
-	PINMUX_DATA(MSIOF1_SS1_MARK, PORT233_FN1),
-	PINMUX_DATA(EDBGREQ3_MARK, PORT233_FN2),
-	PINMUX_DATA(MSIOF1_SS2_MARK, PORT234_FN1),
-	PINMUX_DATA(PORT236_IROUT_MARK, PORT236_FN1),
-	PINMUX_DATA(IRDA_OUT_MARK, PORT236_FN2),
-	PINMUX_DATA(IRDA_IN_MARK, PORT237_FN2),
-	PINMUX_DATA(IRDA_FIRSEL_MARK, PORT238_FN1),
-	PINMUX_DATA(TPU1TO0_MARK, PORT239_FN3),
-	PINMUX_DATA(TS_SPSYNC3_MARK, PORT239_FN4),
-	PINMUX_DATA(TPU1TO1_MARK, PORT240_FN3),
-	PINMUX_DATA(TS_SDAT3_MARK, PORT240_FN4),
-	PINMUX_DATA(TPU1TO2_MARK, PORT241_FN3),
-	PINMUX_DATA(TS_SDEN3_MARK, PORT241_FN4),
-	PINMUX_DATA(PORT241_MSIOF2_SS1_MARK, PORT241_FN5),
-	PINMUX_DATA(TPU1TO3_MARK, PORT242_FN3),
-	PINMUX_DATA(PORT242_MSIOF2_TSCK_MARK, PORT242_FN5),
-	PINMUX_DATA(M13_BSW_MARK, PORT243_FN2),
-	PINMUX_DATA(PORT243_MSIOF2_TSYNC_MARK, PORT243_FN5),
-	PINMUX_DATA(M14_GSW_MARK, PORT244_FN2),
-	PINMUX_DATA(PORT244_MSIOF2_TXD_MARK, PORT244_FN5),
-	PINMUX_DATA(PORT245_IROUT_MARK, PORT245_FN1),
-	PINMUX_DATA(M15_RSW_MARK, PORT245_FN2),
-	PINMUX_DATA(SOUT3_MARK, PORT246_FN1),
-	PINMUX_DATA(SCIFA2_TXD1_MARK, PORT246_FN2),
-	PINMUX_DATA(SIN3_MARK, PORT247_FN1),
-	PINMUX_DATA(SCIFA2_RXD1_MARK, PORT247_FN2),
-	PINMUX_DATA(XRTS3_MARK, PORT248_FN1),
-	PINMUX_DATA(SCIFA2_RTS1_MARK, PORT248_FN2),
-	PINMUX_DATA(PORT248_MSIOF2_SS2_MARK, PORT248_FN5),
-	PINMUX_DATA(XCTS3_MARK, PORT249_FN1),
-	PINMUX_DATA(SCIFA2_CTS1_MARK, PORT249_FN2),
-	PINMUX_DATA(PORT249_MSIOF2_RXD_MARK, PORT249_FN5),
-	PINMUX_DATA(DINT_MARK, PORT250_FN1),
-	PINMUX_DATA(SCIFA2_SCK1_MARK, PORT250_FN2),
-	PINMUX_DATA(TS_SCK3_MARK, PORT250_FN4),
-	PINMUX_DATA(SDHICLK0_MARK, PORT251_FN1),
-	PINMUX_DATA(TCK2_MARK, PORT251_FN2),
-	PINMUX_DATA(SDHICD0_MARK, PORT252_FN1),
-	PINMUX_DATA(SDHID0_0_MARK, PORT253_FN1),
-	PINMUX_DATA(TMS2_MARK, PORT253_FN2),
-	PINMUX_DATA(SDHID0_1_MARK, PORT254_FN1),
-	PINMUX_DATA(TDO2_MARK, PORT254_FN2),
-	PINMUX_DATA(SDHID0_2_MARK, PORT255_FN1),
-	PINMUX_DATA(TDI2_MARK, PORT255_FN2),
-	PINMUX_DATA(SDHID0_3_MARK, PORT256_FN1),
-	PINMUX_DATA(RTCK2_MARK, PORT256_FN2),
-
-	/* 49-6 (FN) */
-	PINMUX_DATA(SDHICMD0_MARK, PORT257_FN1),
-	PINMUX_DATA(TRST2_MARK, PORT257_FN2),
-	PINMUX_DATA(SDHIWP0_MARK, PORT258_FN1),
-	PINMUX_DATA(EDBGREQ2_MARK, PORT258_FN2),
-	PINMUX_DATA(SDHICLK1_MARK, PORT259_FN1),
-	PINMUX_DATA(TCK3_MARK, PORT259_FN4),
-	PINMUX_DATA(SDHID1_0_MARK, PORT260_FN1),
-	PINMUX_DATA(M11_SLCD_SO2_MARK, PORT260_FN2),
-	PINMUX_DATA(TS_SPSYNC2_MARK, PORT260_FN3),
-	PINMUX_DATA(TMS3_MARK, PORT260_FN4),
-	PINMUX_DATA(SDHID1_1_MARK, PORT261_FN1),
-	PINMUX_DATA(M9_SLCD_AO2_MARK, PORT261_FN2),
-	PINMUX_DATA(TS_SDAT2_MARK, PORT261_FN3),
-	PINMUX_DATA(TDO3_MARK, PORT261_FN4),
-	PINMUX_DATA(SDHID1_2_MARK, PORT262_FN1),
-	PINMUX_DATA(M10_SLCD_CK2_MARK, PORT262_FN2),
-	PINMUX_DATA(TS_SDEN2_MARK, PORT262_FN3),
-	PINMUX_DATA(TDI3_MARK, PORT262_FN4),
-	PINMUX_DATA(SDHID1_3_MARK, PORT263_FN1),
-	PINMUX_DATA(M12_SLCD_CE2_MARK, PORT263_FN2),
-	PINMUX_DATA(TS_SCK2_MARK, PORT263_FN3),
-	PINMUX_DATA(RTCK3_MARK, PORT263_FN4),
-	PINMUX_DATA(SDHICMD1_MARK, PORT264_FN1),
-	PINMUX_DATA(TRST3_MARK, PORT264_FN4),
-	PINMUX_DATA(SDHICLK2_MARK, PORT265_FN1),
-	PINMUX_DATA(SCIFB_SCK_MARK, PORT265_FN2),
-	PINMUX_DATA(SDHID2_0_MARK, PORT266_FN1),
-	PINMUX_DATA(SCIFB_TXD_MARK, PORT266_FN2),
-	PINMUX_DATA(SDHID2_1_MARK, PORT267_FN1),
-	PINMUX_DATA(SCIFB_CTS_MARK, PORT267_FN2),
-	PINMUX_DATA(SDHID2_2_MARK, PORT268_FN1),
-	PINMUX_DATA(SCIFB_RXD_MARK, PORT268_FN2),
-	PINMUX_DATA(SDHID2_3_MARK, PORT269_FN1),
-	PINMUX_DATA(SCIFB_RTS_MARK, PORT269_FN2),
-	PINMUX_DATA(SDHICMD2_MARK, PORT270_FN1),
-	PINMUX_DATA(RESETOUTS_MARK, PORT271_FN1),
-	PINMUX_DATA(DIVLOCK_MARK, PORT272_FN1),
-};
-
-static struct pinmux_gpio pinmux_gpios[] = {
-	/* 49-1 -> 49-6 (GPIO) */
-	GPIO_PORT_ALL(),
-
-	/* Special Pull-up / Pull-down Functions */
-	GPIO_FN(PORT48_KEYIN0_PU), GPIO_FN(PORT49_KEYIN1_PU),
-	GPIO_FN(PORT50_KEYIN2_PU), GPIO_FN(PORT55_KEYIN3_PU),
-	GPIO_FN(PORT56_KEYIN4_PU), GPIO_FN(PORT57_KEYIN5_PU),
-	GPIO_FN(PORT58_KEYIN6_PU),
-
-	/* 49-1 (FN) */
-	GPIO_FN(VBUS0), GPIO_FN(CPORT0), GPIO_FN(CPORT1), GPIO_FN(CPORT2),
-	GPIO_FN(CPORT3), GPIO_FN(CPORT4), GPIO_FN(CPORT5), GPIO_FN(CPORT6),
-	GPIO_FN(CPORT7), GPIO_FN(CPORT8), GPIO_FN(CPORT9), GPIO_FN(CPORT10),
-	GPIO_FN(CPORT11), GPIO_FN(SIN2), GPIO_FN(CPORT12), GPIO_FN(XCTS2),
-	GPIO_FN(CPORT13), GPIO_FN(RFSPO4), GPIO_FN(CPORT14), GPIO_FN(RFSPO5),
-	GPIO_FN(CPORT15), GPIO_FN(CPORT16), GPIO_FN(CPORT17), GPIO_FN(SOUT2),
-	GPIO_FN(CPORT18), GPIO_FN(XRTS2), GPIO_FN(CPORT19), GPIO_FN(CPORT20),
-	GPIO_FN(RFSPO6), GPIO_FN(CPORT21), GPIO_FN(STATUS0), GPIO_FN(CPORT22),
-	GPIO_FN(STATUS1), GPIO_FN(CPORT23), GPIO_FN(STATUS2), GPIO_FN(RFSPO7),
-	GPIO_FN(MPORT0), GPIO_FN(MPORT1), GPIO_FN(B_SYNLD1), GPIO_FN(B_SYNLD2),
-	GPIO_FN(XMAINPS), GPIO_FN(XDIVPS), GPIO_FN(XIDRST), GPIO_FN(IDCLK),
-	GPIO_FN(IDIO), GPIO_FN(SOUT1), GPIO_FN(SCIFA4_TXD),
-	GPIO_FN(M02_BERDAT), GPIO_FN(SIN1), GPIO_FN(SCIFA4_RXD), GPIO_FN(XWUP),
-	GPIO_FN(XRTS1), GPIO_FN(SCIFA4_RTS), GPIO_FN(M03_BERCLK),
-	GPIO_FN(XCTS1), GPIO_FN(SCIFA4_CTS),
-
-	/* 49-2 (FN) */
-	GPIO_FN(HSU_IQ_AGC6), GPIO_FN(MFG2_IN2), GPIO_FN(MSIOF2_MCK0),
-	GPIO_FN(HSU_IQ_AGC5), GPIO_FN(MFG2_IN1), GPIO_FN(MSIOF2_MCK1),
-	GPIO_FN(HSU_IQ_AGC4), GPIO_FN(MSIOF2_RSYNC),
-	GPIO_FN(HSU_IQ_AGC3), GPIO_FN(MFG2_OUT1), GPIO_FN(MSIOF2_RSCK),
-	GPIO_FN(HSU_IQ_AGC2), GPIO_FN(PORT42_KEYOUT0),
-	GPIO_FN(HSU_IQ_AGC1), GPIO_FN(PORT43_KEYOUT1),
-	GPIO_FN(HSU_IQ_AGC0), GPIO_FN(PORT44_KEYOUT2),
-	GPIO_FN(HSU_IQ_AGC_ST), GPIO_FN(PORT45_KEYOUT3),
-	GPIO_FN(HSU_IQ_PDO), GPIO_FN(PORT46_KEYOUT4),
-	GPIO_FN(HSU_IQ_PYO), GPIO_FN(PORT47_KEYOUT5),
-	GPIO_FN(HSU_EN_TXMUX_G3MO), GPIO_FN(PORT48_KEYIN0),
-	GPIO_FN(HSU_I_TXMUX_G3MO), GPIO_FN(PORT49_KEYIN1),
-	GPIO_FN(HSU_Q_TXMUX_G3MO), GPIO_FN(PORT50_KEYIN2),
-	GPIO_FN(HSU_SYO), GPIO_FN(PORT51_MSIOF2_TSYNC),
-	GPIO_FN(HSU_SDO), GPIO_FN(PORT52_MSIOF2_TSCK),
-	GPIO_FN(HSU_TGTTI_G3MO), GPIO_FN(PORT53_MSIOF2_TXD),
-	GPIO_FN(B_TIME_STAMP), GPIO_FN(PORT54_MSIOF2_RXD),
-	GPIO_FN(HSU_SDI), GPIO_FN(PORT55_KEYIN3),
-	GPIO_FN(HSU_SCO), GPIO_FN(PORT56_KEYIN4),
-	GPIO_FN(HSU_DREQ), GPIO_FN(PORT57_KEYIN5),
-	GPIO_FN(HSU_DACK), GPIO_FN(PORT58_KEYIN6),
-	GPIO_FN(HSU_CLK61M), GPIO_FN(PORT59_MSIOF2_SS1),
-	GPIO_FN(HSU_XRST), GPIO_FN(PORT60_MSIOF2_SS2),
-	GPIO_FN(PCMCLKO), GPIO_FN(SYNC8KO), GPIO_FN(DNPCM_A), GPIO_FN(UPPCM_A),
-	GPIO_FN(XTALB1L),
-	GPIO_FN(GPS_AGC1), GPIO_FN(SCIFA0_RTS),
-	GPIO_FN(GPS_AGC2), GPIO_FN(SCIFA0_SCK),
-	GPIO_FN(GPS_AGC3), GPIO_FN(SCIFA0_TXD),
-	GPIO_FN(GPS_AGC4), GPIO_FN(SCIFA0_RXD),
-	GPIO_FN(GPS_PWRD), GPIO_FN(SCIFA0_CTS),
-	GPIO_FN(GPS_IM), GPIO_FN(GPS_IS), GPIO_FN(GPS_QM), GPIO_FN(GPS_QS),
-	GPIO_FN(SIUBOMC), GPIO_FN(TPU2TO0),
-	GPIO_FN(SIUCKB), GPIO_FN(TPU2TO1),
-	GPIO_FN(SIUBOLR), GPIO_FN(BBIF2_TSYNC), GPIO_FN(TPU2TO2),
-	GPIO_FN(SIUBOBT), GPIO_FN(BBIF2_TSCK), GPIO_FN(TPU2TO3),
-	GPIO_FN(SIUBOSLD), GPIO_FN(BBIF2_TXD), GPIO_FN(TPU3TO0),
-	GPIO_FN(SIUBILR), GPIO_FN(TPU3TO1),
-	GPIO_FN(SIUBIBT), GPIO_FN(TPU3TO2),
-	GPIO_FN(SIUBISLD), GPIO_FN(TPU3TO3),
-	GPIO_FN(NMI), GPIO_FN(TPU4TO0),
-	GPIO_FN(DNPCM_M), GPIO_FN(TPU4TO1), GPIO_FN(TPU4TO2), GPIO_FN(TPU4TO3),
-	GPIO_FN(IRQ_TMPB),
-	GPIO_FN(PWEN), GPIO_FN(MFG1_OUT1),
-	GPIO_FN(OVCN), GPIO_FN(MFG1_IN1),
-	GPIO_FN(OVCN2), GPIO_FN(MFG1_IN2),
-
-	/* 49-3 (FN) */
-	GPIO_FN(RFSPO1), GPIO_FN(RFSPO2), GPIO_FN(RFSPO3),
-	GPIO_FN(PORT93_VIO_CKO2),
-	GPIO_FN(USBTERM), GPIO_FN(EXTLP), GPIO_FN(IDIN),
-	GPIO_FN(SCIFA5_CTS), GPIO_FN(MFG0_IN1),
-	GPIO_FN(SCIFA5_RTS), GPIO_FN(MFG0_IN2),
-	GPIO_FN(SCIFA5_RXD),
-	GPIO_FN(SCIFA5_TXD),
-	GPIO_FN(SCIFA5_SCK), GPIO_FN(MFG0_OUT1),
-	GPIO_FN(A0_EA0), GPIO_FN(BS),
-	GPIO_FN(A14_EA14), GPIO_FN(PORT102_KEYOUT0),
-	GPIO_FN(A15_EA15), GPIO_FN(PORT103_KEYOUT1), GPIO_FN(DV_CLKOL),
-	GPIO_FN(A16_EA16), GPIO_FN(PORT104_KEYOUT2),
-	GPIO_FN(DV_VSYNCL), GPIO_FN(MSIOF0_SS1),
-	GPIO_FN(A17_EA17), GPIO_FN(PORT105_KEYOUT3),
-	GPIO_FN(DV_HSYNCL), GPIO_FN(MSIOF0_TSYNC),
-	GPIO_FN(A18_EA18), GPIO_FN(PORT106_KEYOUT4),
-	GPIO_FN(DV_DL0), GPIO_FN(MSIOF0_TSCK),
-	GPIO_FN(A19_EA19), GPIO_FN(PORT107_KEYOUT5),
-	GPIO_FN(DV_DL1), GPIO_FN(MSIOF0_TXD),
-	GPIO_FN(A20_EA20), GPIO_FN(PORT108_KEYIN0),
-	GPIO_FN(DV_DL2), GPIO_FN(MSIOF0_RSCK),
-	GPIO_FN(A21_EA21), GPIO_FN(PORT109_KEYIN1),
-	GPIO_FN(DV_DL3), GPIO_FN(MSIOF0_RSYNC),
-	GPIO_FN(A22_EA22), GPIO_FN(PORT110_KEYIN2),
-	GPIO_FN(DV_DL4), GPIO_FN(MSIOF0_MCK0),
-	GPIO_FN(A23_EA23), GPIO_FN(PORT111_KEYIN3),
-	GPIO_FN(DV_DL5), GPIO_FN(MSIOF0_MCK1),
-	GPIO_FN(A24_EA24), GPIO_FN(PORT112_KEYIN4),
-	GPIO_FN(DV_DL6), GPIO_FN(MSIOF0_RXD),
-	GPIO_FN(A25_EA25), GPIO_FN(PORT113_KEYIN5),
-	GPIO_FN(DV_DL7), GPIO_FN(MSIOF0_SS2),
-	GPIO_FN(A26), GPIO_FN(PORT113_KEYIN6), GPIO_FN(DV_CLKIL),
-	GPIO_FN(D0_ED0_NAF0), GPIO_FN(D1_ED1_NAF1), GPIO_FN(D2_ED2_NAF2),
-	GPIO_FN(D3_ED3_NAF3), GPIO_FN(D4_ED4_NAF4), GPIO_FN(D5_ED5_NAF5),
-	GPIO_FN(D6_ED6_NAF6), GPIO_FN(D7_ED7_NAF7), GPIO_FN(D8_ED8_NAF8),
-	GPIO_FN(D9_ED9_NAF9), GPIO_FN(D10_ED10_NAF10), GPIO_FN(D11_ED11_NAF11),
-	GPIO_FN(D12_ED12_NAF12), GPIO_FN(D13_ED13_NAF13),
-	GPIO_FN(D14_ED14_NAF14), GPIO_FN(D15_ED15_NAF15),
-	GPIO_FN(CS4), GPIO_FN(CS5A), GPIO_FN(CS5B), GPIO_FN(FCE1),
-	GPIO_FN(CS6B), GPIO_FN(XCS2), GPIO_FN(FCE0), GPIO_FN(CS6A),
-	GPIO_FN(DACK0), GPIO_FN(WAIT), GPIO_FN(DREQ0), GPIO_FN(RD_XRD),
-	GPIO_FN(A27), GPIO_FN(RDWR_XWE), GPIO_FN(WE0_XWR0_FWE),
-	GPIO_FN(WE1_XWR1), GPIO_FN(FRB), GPIO_FN(CKO),
-	GPIO_FN(NBRSTOUT), GPIO_FN(NBRST),
-
-	/* 49-4 (FN) */
-	GPIO_FN(RFSPO0), GPIO_FN(PORT146_VIO_CKO2), GPIO_FN(TSTMD),
-	GPIO_FN(VIO_VD), GPIO_FN(VIO_HD),
-	GPIO_FN(VIO_D0), GPIO_FN(VIO_D1), GPIO_FN(VIO_D2),
-	GPIO_FN(VIO_D3), GPIO_FN(VIO_D4), GPIO_FN(VIO_D5),
-	GPIO_FN(VIO_D6), GPIO_FN(VIO_D7), GPIO_FN(VIO_D8),
-	GPIO_FN(VIO_D9), GPIO_FN(VIO_D10), GPIO_FN(VIO_D11),
-	GPIO_FN(VIO_D12), GPIO_FN(VIO_D13), GPIO_FN(VIO_D14),
-	GPIO_FN(VIO_D15), GPIO_FN(VIO_CLK), GPIO_FN(VIO_FIELD),
-	GPIO_FN(VIO_CKO),
-	GPIO_FN(MFG3_IN1), GPIO_FN(MFG3_IN2),
-	GPIO_FN(M9_SLCD_A01), GPIO_FN(MFG3_OUT1), GPIO_FN(TPU0TO0),
-	GPIO_FN(M10_SLCD_CK1), GPIO_FN(MFG4_IN1), GPIO_FN(TPU0TO1),
-	GPIO_FN(M11_SLCD_SO1), GPIO_FN(MFG4_IN2), GPIO_FN(TPU0TO2),
-	GPIO_FN(M12_SLCD_CE1), GPIO_FN(MFG4_OUT1), GPIO_FN(TPU0TO3),
-	GPIO_FN(LCDD0), GPIO_FN(PORT175_KEYOUT0), GPIO_FN(DV_D0),
-	GPIO_FN(SIUCKA), GPIO_FN(MFG0_OUT2),
-	GPIO_FN(LCDD1), GPIO_FN(PORT176_KEYOUT1), GPIO_FN(DV_D1),
-	GPIO_FN(SIUAOLR), GPIO_FN(BBIF2_TSYNC1),
-	GPIO_FN(LCDD2), GPIO_FN(PORT177_KEYOUT2), GPIO_FN(DV_D2),
-	GPIO_FN(SIUAOBT), GPIO_FN(BBIF2_TSCK1),
-	GPIO_FN(LCDD3), GPIO_FN(PORT178_KEYOUT3), GPIO_FN(DV_D3),
-	GPIO_FN(SIUAOSLD), GPIO_FN(BBIF2_TXD1),
-	GPIO_FN(LCDD4), GPIO_FN(PORT179_KEYOUT4), GPIO_FN(DV_D4),
-	GPIO_FN(SIUAISPD), GPIO_FN(MFG1_OUT2),
-	GPIO_FN(LCDD5), GPIO_FN(PORT180_KEYOUT5), GPIO_FN(DV_D5),
-	GPIO_FN(SIUAILR), GPIO_FN(MFG2_OUT2),
-	GPIO_FN(LCDD6), GPIO_FN(DV_D6),
-	GPIO_FN(SIUAIBT), GPIO_FN(MFG3_OUT2), GPIO_FN(XWR2),
-	GPIO_FN(LCDD7), GPIO_FN(DV_D7),
-	GPIO_FN(SIUAISLD), GPIO_FN(MFG4_OUT2), GPIO_FN(XWR3),
-	GPIO_FN(LCDD8), GPIO_FN(DV_D8), GPIO_FN(D16), GPIO_FN(ED16),
-	GPIO_FN(LCDD9), GPIO_FN(DV_D9), GPIO_FN(D17), GPIO_FN(ED17),
-	GPIO_FN(LCDD10), GPIO_FN(DV_D10), GPIO_FN(D18), GPIO_FN(ED18),
-	GPIO_FN(LCDD11), GPIO_FN(DV_D11), GPIO_FN(D19), GPIO_FN(ED19),
-	GPIO_FN(LCDD12), GPIO_FN(DV_D12), GPIO_FN(D20), GPIO_FN(ED20),
-	GPIO_FN(LCDD13), GPIO_FN(DV_D13), GPIO_FN(D21), GPIO_FN(ED21),
-	GPIO_FN(LCDD14), GPIO_FN(DV_D14), GPIO_FN(D22), GPIO_FN(ED22),
-	GPIO_FN(LCDD15), GPIO_FN(DV_D15), GPIO_FN(D23), GPIO_FN(ED23),
-	GPIO_FN(LCDD16), GPIO_FN(DV_HSYNC), GPIO_FN(D24), GPIO_FN(ED24),
-	GPIO_FN(LCDD17), GPIO_FN(DV_VSYNC), GPIO_FN(D25), GPIO_FN(ED25),
-	GPIO_FN(LCDD18), GPIO_FN(DREQ2), GPIO_FN(MSIOF0L_TSCK),
-	GPIO_FN(D26), GPIO_FN(ED26),
-	GPIO_FN(LCDD19), GPIO_FN(MSIOF0L_TSYNC),
-	GPIO_FN(D27), GPIO_FN(ED27),
-	GPIO_FN(LCDD20), GPIO_FN(TS_SPSYNC1), GPIO_FN(MSIOF0L_MCK0),
-	GPIO_FN(D28), GPIO_FN(ED28),
-	GPIO_FN(LCDD21), GPIO_FN(TS_SDAT1), GPIO_FN(MSIOF0L_MCK1),
-	GPIO_FN(D29), GPIO_FN(ED29),
-	GPIO_FN(LCDD22), GPIO_FN(TS_SDEN1), GPIO_FN(MSIOF0L_SS1),
-	GPIO_FN(D30), GPIO_FN(ED30),
-	GPIO_FN(LCDD23), GPIO_FN(TS_SCK1), GPIO_FN(MSIOF0L_SS2),
-	GPIO_FN(D31), GPIO_FN(ED31),
-	GPIO_FN(LCDDCK), GPIO_FN(LCDWR), GPIO_FN(DV_CKO), GPIO_FN(SIUAOSPD),
-	GPIO_FN(LCDRD), GPIO_FN(DACK2), GPIO_FN(MSIOF0L_RSYNC),
-
-	/* 49-5 (FN) */
-	GPIO_FN(LCDHSYN), GPIO_FN(LCDCS), GPIO_FN(LCDCS2), GPIO_FN(DACK3),
-	GPIO_FN(LCDDISP), GPIO_FN(LCDRS), GPIO_FN(DREQ3), GPIO_FN(MSIOF0L_RSCK),
-	GPIO_FN(LCDCSYN), GPIO_FN(LCDCSYN2), GPIO_FN(DV_CKI),
-	GPIO_FN(LCDLCLK), GPIO_FN(DREQ1), GPIO_FN(MSIOF0L_RXD),
-	GPIO_FN(LCDDON), GPIO_FN(LCDDON2), GPIO_FN(DACK1), GPIO_FN(MSIOF0L_TXD),
-	GPIO_FN(VIO_DR0), GPIO_FN(VIO_DR1), GPIO_FN(VIO_DR2), GPIO_FN(VIO_DR3),
-	GPIO_FN(VIO_DR4), GPIO_FN(VIO_DR5), GPIO_FN(VIO_DR6), GPIO_FN(VIO_DR7),
-	GPIO_FN(VIO_VDR), GPIO_FN(VIO_HDR),
-	GPIO_FN(VIO_CLKR), GPIO_FN(VIO_CKOR),
-	GPIO_FN(SCIFA1_TXD), GPIO_FN(GPS_PGFA0),
-	GPIO_FN(SCIFA1_SCK), GPIO_FN(GPS_PGFA1),
-	GPIO_FN(SCIFA1_RTS), GPIO_FN(GPS_EPPSINMON),
-	GPIO_FN(SCIFA1_RXD), GPIO_FN(SCIFA1_CTS),
-	GPIO_FN(MSIOF1_TXD), GPIO_FN(SCIFA1_TXD2), GPIO_FN(GPS_TXD),
-	GPIO_FN(MSIOF1_TSYNC), GPIO_FN(SCIFA1_CTS2), GPIO_FN(I2C_SDA2),
-	GPIO_FN(MSIOF1_TSCK), GPIO_FN(SCIFA1_SCK2),
-	GPIO_FN(MSIOF1_RXD), GPIO_FN(SCIFA1_RXD2), GPIO_FN(GPS_RXD),
-	GPIO_FN(MSIOF1_RSCK), GPIO_FN(SCIFA1_RTS2),
-	GPIO_FN(MSIOF1_RSYNC), GPIO_FN(I2C_SCL2),
-	GPIO_FN(MSIOF1_MCK0), GPIO_FN(MSIOF1_MCK1),
-	GPIO_FN(MSIOF1_SS1), GPIO_FN(EDBGREQ3),
-	GPIO_FN(MSIOF1_SS2),
-	GPIO_FN(PORT236_IROUT), GPIO_FN(IRDA_OUT),
-	GPIO_FN(IRDA_IN), GPIO_FN(IRDA_FIRSEL),
-	GPIO_FN(TPU1TO0), GPIO_FN(TS_SPSYNC3),
-	GPIO_FN(TPU1TO1), GPIO_FN(TS_SDAT3),
-	GPIO_FN(TPU1TO2), GPIO_FN(TS_SDEN3), GPIO_FN(PORT241_MSIOF2_SS1),
-	GPIO_FN(TPU1TO3), GPIO_FN(PORT242_MSIOF2_TSCK),
-	GPIO_FN(M13_BSW), GPIO_FN(PORT243_MSIOF2_TSYNC),
-	GPIO_FN(M14_GSW), GPIO_FN(PORT244_MSIOF2_TXD),
-	GPIO_FN(PORT245_IROUT), GPIO_FN(M15_RSW),
-	GPIO_FN(SOUT3), GPIO_FN(SCIFA2_TXD1),
-	GPIO_FN(SIN3), GPIO_FN(SCIFA2_RXD1),
-	GPIO_FN(XRTS3), GPIO_FN(SCIFA2_RTS1), GPIO_FN(PORT248_MSIOF2_SS2),
-	GPIO_FN(XCTS3), GPIO_FN(SCIFA2_CTS1), GPIO_FN(PORT249_MSIOF2_RXD),
-	GPIO_FN(DINT), GPIO_FN(SCIFA2_SCK1), GPIO_FN(TS_SCK3),
-	GPIO_FN(SDHICLK0), GPIO_FN(TCK2),
-	GPIO_FN(SDHICD0),
-	GPIO_FN(SDHID0_0), GPIO_FN(TMS2),
-	GPIO_FN(SDHID0_1), GPIO_FN(TDO2),
-	GPIO_FN(SDHID0_2), GPIO_FN(TDI2),
-	GPIO_FN(SDHID0_3), GPIO_FN(RTCK2),
-
-	/* 49-6 (FN) */
-	GPIO_FN(SDHICMD0), GPIO_FN(TRST2),
-	GPIO_FN(SDHIWP0), GPIO_FN(EDBGREQ2),
-	GPIO_FN(SDHICLK1), GPIO_FN(TCK3),
-	GPIO_FN(SDHID1_0), GPIO_FN(M11_SLCD_SO2),
-	GPIO_FN(TS_SPSYNC2), GPIO_FN(TMS3),
-	GPIO_FN(SDHID1_1), GPIO_FN(M9_SLCD_AO2),
-	GPIO_FN(TS_SDAT2), GPIO_FN(TDO3),
-	GPIO_FN(SDHID1_2), GPIO_FN(M10_SLCD_CK2),
-	GPIO_FN(TS_SDEN2), GPIO_FN(TDI3),
-	GPIO_FN(SDHID1_3), GPIO_FN(M12_SLCD_CE2),
-	GPIO_FN(TS_SCK2), GPIO_FN(RTCK3),
-	GPIO_FN(SDHICMD1), GPIO_FN(TRST3),
-	GPIO_FN(SDHICLK2), GPIO_FN(SCIFB_SCK),
-	GPIO_FN(SDHID2_0), GPIO_FN(SCIFB_TXD),
-	GPIO_FN(SDHID2_1), GPIO_FN(SCIFB_CTS),
-	GPIO_FN(SDHID2_2), GPIO_FN(SCIFB_RXD),
-	GPIO_FN(SDHID2_3), GPIO_FN(SCIFB_RTS),
-	GPIO_FN(SDHICMD2),
-	GPIO_FN(RESETOUTS),
-	GPIO_FN(DIVLOCK),
-};
-
-static struct pinmux_cfg_reg pinmux_config_regs[] = {
-	PORTCR(0, 0xe6050000), /* PORT0CR */
-	PORTCR(1, 0xe6050001), /* PORT1CR */
-	PORTCR(2, 0xe6050002), /* PORT2CR */
-	PORTCR(3, 0xe6050003), /* PORT3CR */
-	PORTCR(4, 0xe6050004), /* PORT4CR */
-	PORTCR(5, 0xe6050005), /* PORT5CR */
-	PORTCR(6, 0xe6050006), /* PORT6CR */
-	PORTCR(7, 0xe6050007), /* PORT7CR */
-	PORTCR(8, 0xe6050008), /* PORT8CR */
-	PORTCR(9, 0xe6050009), /* PORT9CR */
-
-	PORTCR(10, 0xe605000a), /* PORT10CR */
-	PORTCR(11, 0xe605000b), /* PORT11CR */
-	PORTCR(12, 0xe605000c), /* PORT12CR */
-	PORTCR(13, 0xe605000d), /* PORT13CR */
-	PORTCR(14, 0xe605000e), /* PORT14CR */
-	PORTCR(15, 0xe605000f), /* PORT15CR */
-	PORTCR(16, 0xe6050010), /* PORT16CR */
-	PORTCR(17, 0xe6050011), /* PORT17CR */
-	PORTCR(18, 0xe6050012), /* PORT18CR */
-	PORTCR(19, 0xe6050013), /* PORT19CR */
-
-	PORTCR(20, 0xe6050014), /* PORT20CR */
-	PORTCR(21, 0xe6050015), /* PORT21CR */
-	PORTCR(22, 0xe6050016), /* PORT22CR */
-	PORTCR(23, 0xe6050017), /* PORT23CR */
-	PORTCR(24, 0xe6050018), /* PORT24CR */
-	PORTCR(25, 0xe6050019), /* PORT25CR */
-	PORTCR(26, 0xe605001a), /* PORT26CR */
-	PORTCR(27, 0xe605001b), /* PORT27CR */
-	PORTCR(28, 0xe605001c), /* PORT28CR */
-	PORTCR(29, 0xe605001d), /* PORT29CR */
-
-	PORTCR(30, 0xe605001e), /* PORT30CR */
-	PORTCR(31, 0xe605001f), /* PORT31CR */
-	PORTCR(32, 0xe6050020), /* PORT32CR */
-	PORTCR(33, 0xe6050021), /* PORT33CR */
-	PORTCR(34, 0xe6050022), /* PORT34CR */
-	PORTCR(35, 0xe6050023), /* PORT35CR */
-	PORTCR(36, 0xe6050024), /* PORT36CR */
-	PORTCR(37, 0xe6050025), /* PORT37CR */
-	PORTCR(38, 0xe6050026), /* PORT38CR */
-	PORTCR(39, 0xe6050027), /* PORT39CR */
-
-	PORTCR(40, 0xe6050028), /* PORT40CR */
-	PORTCR(41, 0xe6050029), /* PORT41CR */
-	PORTCR(42, 0xe605002a), /* PORT42CR */
-	PORTCR(43, 0xe605002b), /* PORT43CR */
-	PORTCR(44, 0xe605002c), /* PORT44CR */
-	PORTCR(45, 0xe605002d), /* PORT45CR */
-	PORTCR(46, 0xe605002e), /* PORT46CR */
-	PORTCR(47, 0xe605002f), /* PORT47CR */
-	PORTCR(48, 0xe6050030), /* PORT48CR */
-	PORTCR(49, 0xe6050031), /* PORT49CR */
-
-	PORTCR(50, 0xe6050032), /* PORT50CR */
-	PORTCR(51, 0xe6050033), /* PORT51CR */
-	PORTCR(52, 0xe6050034), /* PORT52CR */
-	PORTCR(53, 0xe6050035), /* PORT53CR */
-	PORTCR(54, 0xe6050036), /* PORT54CR */
-	PORTCR(55, 0xe6050037), /* PORT55CR */
-	PORTCR(56, 0xe6050038), /* PORT56CR */
-	PORTCR(57, 0xe6050039), /* PORT57CR */
-	PORTCR(58, 0xe605003a), /* PORT58CR */
-	PORTCR(59, 0xe605003b), /* PORT59CR */
-
-	PORTCR(60, 0xe605003c), /* PORT60CR */
-	PORTCR(61, 0xe605003d), /* PORT61CR */
-	PORTCR(62, 0xe605003e), /* PORT62CR */
-	PORTCR(63, 0xe605003f), /* PORT63CR */
-	PORTCR(64, 0xe6050040), /* PORT64CR */
-	PORTCR(65, 0xe6050041), /* PORT65CR */
-	PORTCR(66, 0xe6050042), /* PORT66CR */
-	PORTCR(67, 0xe6050043), /* PORT67CR */
-	PORTCR(68, 0xe6050044), /* PORT68CR */
-	PORTCR(69, 0xe6050045), /* PORT69CR */
-
-	PORTCR(70, 0xe6050046), /* PORT70CR */
-	PORTCR(71, 0xe6050047), /* PORT71CR */
-	PORTCR(72, 0xe6050048), /* PORT72CR */
-	PORTCR(73, 0xe6050049), /* PORT73CR */
-	PORTCR(74, 0xe605004a), /* PORT74CR */
-	PORTCR(75, 0xe605004b), /* PORT75CR */
-	PORTCR(76, 0xe605004c), /* PORT76CR */
-	PORTCR(77, 0xe605004d), /* PORT77CR */
-	PORTCR(78, 0xe605004e), /* PORT78CR */
-	PORTCR(79, 0xe605004f), /* PORT79CR */
-
-	PORTCR(80, 0xe6050050), /* PORT80CR */
-	PORTCR(81, 0xe6050051), /* PORT81CR */
-	PORTCR(82, 0xe6050052), /* PORT82CR */
-	PORTCR(83, 0xe6050053), /* PORT83CR */
-	PORTCR(84, 0xe6050054), /* PORT84CR */
-	PORTCR(85, 0xe6050055), /* PORT85CR */
-	PORTCR(86, 0xe6050056), /* PORT86CR */
-	PORTCR(87, 0xe6050057), /* PORT87CR */
-	PORTCR(88, 0xe6051058), /* PORT88CR */
-	PORTCR(89, 0xe6051059), /* PORT89CR */
-
-	PORTCR(90, 0xe605105a), /* PORT90CR */
-	PORTCR(91, 0xe605105b), /* PORT91CR */
-	PORTCR(92, 0xe605105c), /* PORT92CR */
-	PORTCR(93, 0xe605105d), /* PORT93CR */
-	PORTCR(94, 0xe605105e), /* PORT94CR */
-	PORTCR(95, 0xe605105f), /* PORT95CR */
-	PORTCR(96, 0xe6051060), /* PORT96CR */
-	PORTCR(97, 0xe6051061), /* PORT97CR */
-	PORTCR(98, 0xe6051062), /* PORT98CR */
-	PORTCR(99, 0xe6051063), /* PORT99CR */
-
-	PORTCR(100, 0xe6051064), /* PORT100CR */
-	PORTCR(101, 0xe6051065), /* PORT101CR */
-	PORTCR(102, 0xe6051066), /* PORT102CR */
-	PORTCR(103, 0xe6051067), /* PORT103CR */
-	PORTCR(104, 0xe6051068), /* PORT104CR */
-	PORTCR(105, 0xe6051069), /* PORT105CR */
-	PORTCR(106, 0xe605106a), /* PORT106CR */
-	PORTCR(107, 0xe605106b), /* PORT107CR */
-	PORTCR(108, 0xe605106c), /* PORT108CR */
-	PORTCR(109, 0xe605106d), /* PORT109CR */
-
-	PORTCR(110, 0xe605106e), /* PORT110CR */
-	PORTCR(111, 0xe605106f), /* PORT111CR */
-	PORTCR(112, 0xe6051070), /* PORT112CR */
-	PORTCR(113, 0xe6051071), /* PORT113CR */
-	PORTCR(114, 0xe6051072), /* PORT114CR */
-	PORTCR(115, 0xe6051073), /* PORT115CR */
-	PORTCR(116, 0xe6051074), /* PORT116CR */
-	PORTCR(117, 0xe6051075), /* PORT117CR */
-	PORTCR(118, 0xe6051076), /* PORT118CR */
-	PORTCR(119, 0xe6051077), /* PORT119CR */
-
-	PORTCR(120, 0xe6051078), /* PORT120CR */
-	PORTCR(121, 0xe6051079), /* PORT121CR */
-	PORTCR(122, 0xe605107a), /* PORT122CR */
-	PORTCR(123, 0xe605107b), /* PORT123CR */
-	PORTCR(124, 0xe605107c), /* PORT124CR */
-	PORTCR(125, 0xe605107d), /* PORT125CR */
-	PORTCR(126, 0xe605107e), /* PORT126CR */
-	PORTCR(127, 0xe605107f), /* PORT127CR */
-	PORTCR(128, 0xe6051080), /* PORT128CR */
-	PORTCR(129, 0xe6051081), /* PORT129CR */
-
-	PORTCR(130, 0xe6051082), /* PORT130CR */
-	PORTCR(131, 0xe6051083), /* PORT131CR */
-	PORTCR(132, 0xe6051084), /* PORT132CR */
-	PORTCR(133, 0xe6051085), /* PORT133CR */
-	PORTCR(134, 0xe6051086), /* PORT134CR */
-	PORTCR(135, 0xe6051087), /* PORT135CR */
-	PORTCR(136, 0xe6051088), /* PORT136CR */
-	PORTCR(137, 0xe6051089), /* PORT137CR */
-	PORTCR(138, 0xe605108a), /* PORT138CR */
-	PORTCR(139, 0xe605108b), /* PORT139CR */
-
-	PORTCR(140, 0xe605108c), /* PORT140CR */
-	PORTCR(141, 0xe605108d), /* PORT141CR */
-	PORTCR(142, 0xe605108e), /* PORT142CR */
-	PORTCR(143, 0xe605108f), /* PORT143CR */
-	PORTCR(144, 0xe6051090), /* PORT144CR */
-	PORTCR(145, 0xe6051091), /* PORT145CR */
-	PORTCR(146, 0xe6051092), /* PORT146CR */
-	PORTCR(147, 0xe6051093), /* PORT147CR */
-	PORTCR(148, 0xe6051094), /* PORT148CR */
-	PORTCR(149, 0xe6051095), /* PORT149CR */
-
-	PORTCR(150, 0xe6051096), /* PORT150CR */
-	PORTCR(151, 0xe6051097), /* PORT151CR */
-	PORTCR(152, 0xe6051098), /* PORT152CR */
-	PORTCR(153, 0xe6051099), /* PORT153CR */
-	PORTCR(154, 0xe605109a), /* PORT154CR */
-	PORTCR(155, 0xe605109b), /* PORT155CR */
-	PORTCR(156, 0xe605109c), /* PORT156CR */
-	PORTCR(157, 0xe605109d), /* PORT157CR */
-	PORTCR(158, 0xe605109e), /* PORT158CR */
-	PORTCR(159, 0xe605109f), /* PORT159CR */
-
-	PORTCR(160, 0xe60510a0), /* PORT160CR */
-	PORTCR(161, 0xe60510a1), /* PORT161CR */
-	PORTCR(162, 0xe60510a2), /* PORT162CR */
-	PORTCR(163, 0xe60510a3), /* PORT163CR */
-	PORTCR(164, 0xe60510a4), /* PORT164CR */
-	PORTCR(165, 0xe60510a5), /* PORT165CR */
-	PORTCR(166, 0xe60510a6), /* PORT166CR */
-	PORTCR(167, 0xe60510a7), /* PORT167CR */
-	PORTCR(168, 0xe60510a8), /* PORT168CR */
-	PORTCR(169, 0xe60510a9), /* PORT169CR */
-
-	PORTCR(170, 0xe60510aa), /* PORT170CR */
-	PORTCR(171, 0xe60510ab), /* PORT171CR */
-	PORTCR(172, 0xe60510ac), /* PORT172CR */
-	PORTCR(173, 0xe60510ad), /* PORT173CR */
-	PORTCR(174, 0xe60510ae), /* PORT174CR */
-	PORTCR(175, 0xe60520af), /* PORT175CR */
-	PORTCR(176, 0xe60520b0), /* PORT176CR */
-	PORTCR(177, 0xe60520b1), /* PORT177CR */
-	PORTCR(178, 0xe60520b2), /* PORT178CR */
-	PORTCR(179, 0xe60520b3), /* PORT179CR */
-
-	PORTCR(180, 0xe60520b4), /* PORT180CR */
-	PORTCR(181, 0xe60520b5), /* PORT181CR */
-	PORTCR(182, 0xe60520b6), /* PORT182CR */
-	PORTCR(183, 0xe60520b7), /* PORT183CR */
-	PORTCR(184, 0xe60520b8), /* PORT184CR */
-	PORTCR(185, 0xe60520b9), /* PORT185CR */
-	PORTCR(186, 0xe60520ba), /* PORT186CR */
-	PORTCR(187, 0xe60520bb), /* PORT187CR */
-	PORTCR(188, 0xe60520bc), /* PORT188CR */
-	PORTCR(189, 0xe60520bd), /* PORT189CR */
-
-	PORTCR(190, 0xe60520be), /* PORT190CR */
-	PORTCR(191, 0xe60520bf), /* PORT191CR */
-	PORTCR(192, 0xe60520c0), /* PORT192CR */
-	PORTCR(193, 0xe60520c1), /* PORT193CR */
-	PORTCR(194, 0xe60520c2), /* PORT194CR */
-	PORTCR(195, 0xe60520c3), /* PORT195CR */
-	PORTCR(196, 0xe60520c4), /* PORT196CR */
-	PORTCR(197, 0xe60520c5), /* PORT197CR */
-	PORTCR(198, 0xe60520c6), /* PORT198CR */
-	PORTCR(199, 0xe60520c7), /* PORT199CR */
-
-	PORTCR(200, 0xe60520c8), /* PORT200CR */
-	PORTCR(201, 0xe60520c9), /* PORT201CR */
-	PORTCR(202, 0xe60520ca), /* PORT202CR */
-	PORTCR(203, 0xe60520cb), /* PORT203CR */
-	PORTCR(204, 0xe60520cc), /* PORT204CR */
-	PORTCR(205, 0xe60520cd), /* PORT205CR */
-	PORTCR(206, 0xe60520ce), /* PORT206CR */
-	PORTCR(207, 0xe60520cf), /* PORT207CR */
-	PORTCR(208, 0xe60520d0), /* PORT208CR */
-	PORTCR(209, 0xe60520d1), /* PORT209CR */
-
-	PORTCR(210, 0xe60520d2), /* PORT210CR */
-	PORTCR(211, 0xe60520d3), /* PORT211CR */
-	PORTCR(212, 0xe60520d4), /* PORT212CR */
-	PORTCR(213, 0xe60520d5), /* PORT213CR */
-	PORTCR(214, 0xe60520d6), /* PORT214CR */
-	PORTCR(215, 0xe60520d7), /* PORT215CR */
-	PORTCR(216, 0xe60520d8), /* PORT216CR */
-	PORTCR(217, 0xe60520d9), /* PORT217CR */
-	PORTCR(218, 0xe60520da), /* PORT218CR */
-	PORTCR(219, 0xe60520db), /* PORT219CR */
-
-	PORTCR(220, 0xe60520dc), /* PORT220CR */
-	PORTCR(221, 0xe60520dd), /* PORT221CR */
-	PORTCR(222, 0xe60520de), /* PORT222CR */
-	PORTCR(223, 0xe60520df), /* PORT223CR */
-	PORTCR(224, 0xe60520e0), /* PORT224CR */
-	PORTCR(225, 0xe60520e1), /* PORT225CR */
-	PORTCR(226, 0xe60520e2), /* PORT226CR */
-	PORTCR(227, 0xe60520e3), /* PORT227CR */
-	PORTCR(228, 0xe60520e4), /* PORT228CR */
-	PORTCR(229, 0xe60520e5), /* PORT229CR */
-
-	PORTCR(230, 0xe60520e6), /* PORT230CR */
-	PORTCR(231, 0xe60520e7), /* PORT231CR */
-	PORTCR(232, 0xe60520e8), /* PORT232CR */
-	PORTCR(233, 0xe60520e9), /* PORT233CR */
-	PORTCR(234, 0xe60520ea), /* PORT234CR */
-	PORTCR(235, 0xe60520eb), /* PORT235CR */
-	PORTCR(236, 0xe60530ec), /* PORT236CR */
-	PORTCR(237, 0xe60530ed), /* PORT237CR */
-	PORTCR(238, 0xe60530ee), /* PORT238CR */
-	PORTCR(239, 0xe60530ef), /* PORT239CR */
-
-	PORTCR(240, 0xe60530f0), /* PORT240CR */
-	PORTCR(241, 0xe60530f1), /* PORT241CR */
-	PORTCR(242, 0xe60530f2), /* PORT242CR */
-	PORTCR(243, 0xe60530f3), /* PORT243CR */
-	PORTCR(244, 0xe60530f4), /* PORT244CR */
-	PORTCR(245, 0xe60530f5), /* PORT245CR */
-	PORTCR(246, 0xe60530f6), /* PORT246CR */
-	PORTCR(247, 0xe60530f7), /* PORT247CR */
-	PORTCR(248, 0xe60530f8), /* PORT248CR */
-	PORTCR(249, 0xe60530f9), /* PORT249CR */
-
-	PORTCR(250, 0xe60530fa), /* PORT250CR */
-	PORTCR(251, 0xe60530fb), /* PORT251CR */
-	PORTCR(252, 0xe60530fc), /* PORT252CR */
-	PORTCR(253, 0xe60530fd), /* PORT253CR */
-	PORTCR(254, 0xe60530fe), /* PORT254CR */
-	PORTCR(255, 0xe60530ff), /* PORT255CR */
-	PORTCR(256, 0xe6053100), /* PORT256CR */
-	PORTCR(257, 0xe6053101), /* PORT257CR */
-	PORTCR(258, 0xe6053102), /* PORT258CR */
-	PORTCR(259, 0xe6053103), /* PORT259CR */
-
-	PORTCR(260, 0xe6053104), /* PORT260CR */
-	PORTCR(261, 0xe6053105), /* PORT261CR */
-	PORTCR(262, 0xe6053106), /* PORT262CR */
-	PORTCR(263, 0xe6053107), /* PORT263CR */
-	PORTCR(264, 0xe6053108), /* PORT264CR */
-	PORTCR(265, 0xe6053109), /* PORT265CR */
-	PORTCR(266, 0xe605310a), /* PORT266CR */
-	PORTCR(267, 0xe605310b), /* PORT267CR */
-	PORTCR(268, 0xe605310c), /* PORT268CR */
-	PORTCR(269, 0xe605310d), /* PORT269CR */
-
-	PORTCR(270, 0xe605310e), /* PORT270CR */
-	PORTCR(271, 0xe605310f), /* PORT271CR */
-	PORTCR(272, 0xe6053110), /* PORT272CR */
-
-	{ PINMUX_CFG_REG("MSELBCR", 0xe6058024, 32, 1) {
-		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-		0, 0,
-		0, 0,
-		0, 0,
-		0, 0,
-		0, 0,
-		MSELBCR_MSEL2_0, MSELBCR_MSEL2_1,
-		0, 0,
-		0, 0 }
-	},
-	{ },
-};
-
-static struct pinmux_data_reg pinmux_data_regs[] = {
-	{ PINMUX_DATA_REG("PORTL031_000DR", 0xe6054000, 32) {
-		PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
-		PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
-		PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
-		PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
-		PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
-		PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
-		PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
-		PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTL063_032DR", 0xe6054004, 32) {
-		PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
-		PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
-		PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
-		PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
-		PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA,
-		PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
-		PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
-		PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTL095_064DR", 0xe6054008, 32) {
-		PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
-		PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
-		PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
-		PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
-		PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
-		PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
-		PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
-		PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTD127_096DR", 0xe6055004, 32) {
-		PORT127_DATA, PORT126_DATA, PORT125_DATA, PORT124_DATA,
-		PORT123_DATA, PORT122_DATA, PORT121_DATA, PORT120_DATA,
-		PORT119_DATA, PORT118_DATA, PORT117_DATA, PORT116_DATA,
-		PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
-		PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
-		PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
-		PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
-		PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTD159_128DR", 0xe6055008, 32) {
-		PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
-		PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
-		PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
-		PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
-		PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
-		PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
-		PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
-		PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTR191_160DR", 0xe6056000, 32) {
-		PORT191_DATA, PORT190_DATA, PORT189_DATA, PORT188_DATA,
-		PORT187_DATA, PORT186_DATA, PORT185_DATA, PORT184_DATA,
-		PORT183_DATA, PORT182_DATA, PORT181_DATA, PORT180_DATA,
-		PORT179_DATA, PORT178_DATA, PORT177_DATA, PORT176_DATA,
-		PORT175_DATA, PORT174_DATA, PORT173_DATA, PORT172_DATA,
-		PORT171_DATA, PORT170_DATA, PORT169_DATA, PORT168_DATA,
-		PORT167_DATA, PORT166_DATA, PORT165_DATA, PORT164_DATA,
-		PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTR223_192DR", 0xe6056004, 32) {
-		PORT223_DATA, PORT222_DATA, PORT221_DATA, PORT220_DATA,
-		PORT219_DATA, PORT218_DATA, PORT217_DATA, PORT216_DATA,
-		PORT215_DATA, PORT214_DATA, PORT213_DATA, PORT212_DATA,
-		PORT211_DATA, PORT210_DATA, PORT209_DATA, PORT208_DATA,
-		PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA,
-		PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA,
-		PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA,
-		PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTU255_224DR", 0xe6057000, 32) {
-		PORT255_DATA, PORT254_DATA, PORT253_DATA, PORT252_DATA,
-		PORT251_DATA, PORT250_DATA, PORT249_DATA, PORT248_DATA,
-		PORT247_DATA, PORT246_DATA, PORT245_DATA, PORT244_DATA,
-		PORT243_DATA, PORT242_DATA, PORT241_DATA, PORT240_DATA,
-		PORT239_DATA, PORT238_DATA, PORT237_DATA, PORT236_DATA,
-		PORT235_DATA, PORT234_DATA, PORT233_DATA, PORT232_DATA,
-		PORT231_DATA, PORT230_DATA, PORT229_DATA, PORT228_DATA,
-		PORT227_DATA, PORT226_DATA, PORT225_DATA, PORT224_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTU287_256DR", 0xe6057004, 32) {
-		0, 0, 0, 0,
-		0, 0, 0, 0,
-		0, 0, 0, 0,
-		0, 0, 0, PORT272_DATA,
-		PORT271_DATA, PORT270_DATA, PORT269_DATA, PORT268_DATA,
-		PORT267_DATA, PORT266_DATA, PORT265_DATA, PORT264_DATA,
-		PORT263_DATA, PORT262_DATA, PORT261_DATA, PORT260_DATA,
-		PORT259_DATA, PORT258_DATA, PORT257_DATA, PORT256_DATA }
-	},
-	{ },
-};
-
-static struct pinmux_info sh7367_pinmux_info = {
-	.name = "sh7367_pfc",
-	.reserved_id = PINMUX_RESERVED,
-	.data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
-	.input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
-	.input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
-	.input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END },
-	.output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
-	.mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
-	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
-
-	.first_gpio = GPIO_PORT0,
-	.last_gpio = GPIO_FN_DIVLOCK,
-
-	.gpios = pinmux_gpios,
-	.cfg_regs = pinmux_config_regs,
-	.data_regs = pinmux_data_regs,
-
-	.gpio_data = pinmux_data,
-	.gpio_data_size = ARRAY_SIZE(pinmux_data),
-};
-
-void sh7367_pinmux_init(void)
-{
-	register_pinmux(&sh7367_pinmux_info);
-}
diff --git a/arch/arm/mach-shmobile/pfc-sh7377.c b/arch/arm/mach-shmobile/pfc-sh7377.c
deleted file mode 100644
index f3117f6..0000000
--- a/arch/arm/mach-shmobile/pfc-sh7377.c
+++ /dev/null
@@ -1,1688 +0,0 @@
-/*
- * sh7377 processor support - PFC hardware block
- *
- * Copyright (C) 2010  NISHIMOTO Hiroki
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of the
- * License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sh_pfc.h>
-#include <mach/sh7377.h>
-
-#define CPU_ALL_PORT(fn, pfx, sfx)				\
-	PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx),		\
-	PORT_10(fn, pfx##10, sfx),				\
-	PORT_1(fn, pfx##110, sfx), PORT_1(fn, pfx##111, sfx),	\
-	PORT_1(fn, pfx##112, sfx), PORT_1(fn, pfx##113, sfx),	\
-	PORT_1(fn, pfx##114, sfx), PORT_1(fn, pfx##115, sfx),	\
-	PORT_1(fn, pfx##116, sfx), PORT_1(fn, pfx##117, sfx),	\
-	PORT_1(fn, pfx##118, sfx),				\
-	PORT_1(fn, pfx##128, sfx), PORT_1(fn, pfx##129, sfx),	\
-	PORT_10(fn, pfx##13, sfx), PORT_10(fn, pfx##14, sfx),	\
-	PORT_10(fn, pfx##15, sfx),				\
-	PORT_1(fn, pfx##160, sfx), PORT_1(fn, pfx##161, sfx),	\
-	PORT_1(fn, pfx##162, sfx), PORT_1(fn, pfx##163, sfx),	\
-	PORT_1(fn, pfx##164, sfx),				\
-	PORT_1(fn, pfx##192, sfx), PORT_1(fn, pfx##193, sfx),	\
-	PORT_1(fn, pfx##194, sfx), PORT_1(fn, pfx##195, sfx),	\
-	PORT_1(fn, pfx##196, sfx), PORT_1(fn, pfx##197, sfx),	\
-	PORT_1(fn, pfx##198, sfx), PORT_1(fn, pfx##199, sfx),	\
-	PORT_10(fn, pfx##20, sfx), PORT_10(fn, pfx##21, sfx),	\
-	PORT_10(fn, pfx##22, sfx), PORT_10(fn, pfx##23, sfx),	\
-	PORT_10(fn, pfx##24, sfx), PORT_10(fn, pfx##25, sfx),	\
-	PORT_1(fn, pfx##260, sfx), PORT_1(fn, pfx##261, sfx),	\
-	PORT_1(fn, pfx##262, sfx), PORT_1(fn, pfx##263, sfx),	\
-	PORT_1(fn, pfx##264, sfx)
-
-enum {
-	PINMUX_RESERVED = 0,
-
-	PINMUX_DATA_BEGIN,
-	PORT_ALL(DATA), /* PORT0_DATA -> PORT264_DATA */
-	PINMUX_DATA_END,
-
-	PINMUX_INPUT_BEGIN,
-	PORT_ALL(IN), /* PORT0_IN -> PORT264_IN */
-	PINMUX_INPUT_END,
-
-	PINMUX_INPUT_PULLUP_BEGIN,
-	PORT_ALL(IN_PU), /* PORT0_IN_PU -> PORT264_IN_PU */
-	PINMUX_INPUT_PULLUP_END,
-
-	PINMUX_INPUT_PULLDOWN_BEGIN,
-	PORT_ALL(IN_PD), /* PORT0_IN_PD -> PORT264_IN_PD */
-	PINMUX_INPUT_PULLDOWN_END,
-
-	PINMUX_OUTPUT_BEGIN,
-	PORT_ALL(OUT), /* PORT0_OUT -> PORT264_OUT */
-	PINMUX_OUTPUT_END,
-
-	PINMUX_FUNCTION_BEGIN,
-	PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT264_FN_IN */
-	PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT264_FN_OUT */
-	PORT_ALL(FN0), /* PORT0_FN0 -> PORT264_FN0 */
-	PORT_ALL(FN1), /* PORT0_FN1 -> PORT264_FN1 */
-	PORT_ALL(FN2), /* PORT0_FN2 -> PORT264_FN2 */
-	PORT_ALL(FN3), /* PORT0_FN3 -> PORT264_FN3 */
-	PORT_ALL(FN4), /* PORT0_FN4 -> PORT264_FN4 */
-	PORT_ALL(FN5), /* PORT0_FN5 -> PORT264_FN5 */
-	PORT_ALL(FN6), /* PORT0_FN6 -> PORT264_FN6 */
-	PORT_ALL(FN7), /* PORT0_FN7 -> PORT264_FN7 */
-
-	MSELBCR_MSEL17_1, MSELBCR_MSEL17_0,
-	MSELBCR_MSEL16_1, MSELBCR_MSEL16_0,
-	PINMUX_FUNCTION_END,
-
-	PINMUX_MARK_BEGIN,
-	/* Special Pull-up / Pull-down Functions */
-	PORT66_KEYIN0_PU_MARK, PORT67_KEYIN1_PU_MARK,
-	PORT68_KEYIN2_PU_MARK, PORT69_KEYIN3_PU_MARK,
-	PORT70_KEYIN4_PU_MARK, PORT71_KEYIN5_PU_MARK,
-	PORT72_KEYIN6_PU_MARK,
-
-	/* 55-1 */
-	VBUS_0_MARK,
-	CPORT0_MARK,
-	CPORT1_MARK,
-	CPORT2_MARK,
-	CPORT3_MARK,
-	CPORT4_MARK,
-	CPORT5_MARK,
-	CPORT6_MARK,
-	CPORT7_MARK,
-	CPORT8_MARK,
-	CPORT9_MARK,
-	CPORT10_MARK,
-	CPORT11_MARK, SIN2_MARK,
-	CPORT12_MARK, XCTS2_MARK,
-	CPORT13_MARK, RFSPO4_MARK,
-	CPORT14_MARK, RFSPO5_MARK,
-	CPORT15_MARK, SCIFA0_SCK_MARK, GPS_AGC2_MARK,
-	CPORT16_MARK, SCIFA0_TXD_MARK, GPS_AGC3_MARK,
-	CPORT17_IC_OE_MARK, SOUT2_MARK,
-	CPORT18_MARK, XRTS2_MARK, PORT19_VIO_CKO2_MARK,
-	CPORT19_MPORT1_MARK,
-	CPORT20_MARK, RFSPO6_MARK,
-	CPORT21_MARK, STATUS0_MARK,
-	CPORT22_MARK, STATUS1_MARK,
-	CPORT23_MARK, STATUS2_MARK, RFSPO7_MARK,
-	B_SYNLD1_MARK,
-	B_SYNLD2_MARK, SYSENMSK_MARK,
-	XMAINPS_MARK,
-	XDIVPS_MARK,
-	XIDRST_MARK,
-	IDCLK_MARK, IC_DP_MARK,
-	IDIO_MARK, IC_DM_MARK,
-	SOUT1_MARK, SCIFA4_TXD_MARK, M02_BERDAT_MARK,
-	SIN1_MARK, SCIFA4_RXD_MARK, XWUP_MARK,
-	XRTS1_MARK, SCIFA4_RTS_MARK, M03_BERCLK_MARK,
-	XCTS1_MARK, SCIFA4_CTS_MARK,
-	PCMCLKO_MARK,
-	SYNC8KO_MARK,
-
-	/* 55-2 */
-	DNPCM_A_MARK,
-	UPPCM_A_MARK,
-	VACK_MARK,
-	XTALB1L_MARK,
-	GPS_AGC1_MARK, SCIFA0_RTS_MARK,
-	GPS_AGC4_MARK, SCIFA0_RXD_MARK,
-	GPS_PWRDOWN_MARK, SCIFA0_CTS_MARK,
-	GPS_IM_MARK,
-	GPS_IS_MARK,
-	GPS_QM_MARK,
-	GPS_QS_MARK,
-	FMSOCK_MARK, PORT49_IRDA_OUT_MARK, PORT49_IROUT_MARK,
-	FMSOOLR_MARK, BBIF2_TSYNC2_MARK, TPU2TO2_MARK, IPORT3_MARK,
-	FMSIOLR_MARK,
-	FMSOOBT_MARK, BBIF2_TSCK2_MARK, TPU2TO3_MARK, OPORT1_MARK,
-	FMSIOBT_MARK,
-	FMSOSLD_MARK, BBIF2_TXD2_MARK, OPORT2_MARK,
-	FMSOILR_MARK, PORT53_IRDA_IN_MARK, TPU3TO3_MARK, OPORT3_MARK,
-	FMSIILR_MARK,
-	FMSOIBT_MARK, PORT54_IRDA_FIRSEL_MARK, TPU3TO2_MARK, FMSIIBT_MARK,
-	FMSISLD_MARK, MFG0_OUT1_MARK, TPU0TO0_MARK,
-	A0_EA0_MARK, BS_MARK,
-	A12_EA12_MARK, PORT58_VIO_CKOR_MARK, TPU4TO2_MARK,
-	A13_EA13_MARK, PORT59_IROUT_MARK, MFG0_OUT2_MARK, TPU0TO1_MARK,
-	A14_EA14_MARK, PORT60_KEYOUT5_MARK,
-	A15_EA15_MARK, PORT61_KEYOUT4_MARK,
-	A16_EA16_MARK, PORT62_KEYOUT3_MARK, MSIOF0_SS1_MARK,
-	A17_EA17_MARK, PORT63_KEYOUT2_MARK, MSIOF0_TSYNC_MARK,
-	A18_EA18_MARK, PORT64_KEYOUT1_MARK, MSIOF0_TSCK_MARK,
-	A19_EA19_MARK, PORT65_KEYOUT0_MARK, MSIOF0_TXD_MARK,
-	A20_EA20_MARK, PORT66_KEYIN0_MARK, MSIOF0_RSCK_MARK,
-	A21_EA21_MARK, PORT67_KEYIN1_MARK, MSIOF0_RSYNC_MARK,
-	A22_EA22_MARK, PORT68_KEYIN2_MARK, MSIOF0_MCK0_MARK,
-	A23_EA23_MARK, PORT69_KEYIN3_MARK, MSIOF0_MCK1_MARK,
-	A24_EA24_MARK, PORT70_KEYIN4_MARK, MSIOF0_RXD_MARK,
-	A25_EA25_MARK, PORT71_KEYIN5_MARK, MSIOF0_SS2_MARK,
-	A26_MARK, PORT72_KEYIN6_MARK,
-	D0_ED0_NAF0_MARK,
-	D1_ED1_NAF1_MARK,
-	D2_ED2_NAF2_MARK,
-	D3_ED3_NAF3_MARK,
-	D4_ED4_NAF4_MARK,
-	D5_ED5_NAF5_MARK,
-	D6_ED6_NAF6_MARK,
-	D7_ED7_NAF7_MARK,
-	D8_ED8_NAF8_MARK,
-	D9_ED9_NAF9_MARK,
-	D10_ED10_NAF10_MARK,
-	D11_ED11_NAF11_MARK,
-	D12_ED12_NAF12_MARK,
-	D13_ED13_NAF13_MARK,
-	D14_ED14_NAF14_MARK,
-	D15_ED15_NAF15_MARK,
-	CS4_MARK,
-	CS5A_MARK, FMSICK_MARK,
-	CS5B_MARK, FCE1_MARK,
-
-	/* 55-3 */
-	CS6B_MARK, XCS2_MARK, CS6A_MARK, DACK0_MARK,
-	FCE0_MARK,
-	WAIT_MARK, DREQ0_MARK,
-	RD_XRD_MARK,
-	WE0_XWR0_FWE_MARK,
-	WE1_XWR1_MARK,
-	FRB_MARK,
-	CKO_MARK,
-	NBRSTOUT_MARK,
-	NBRST_MARK,
-	GPS_EPPSIN_MARK,
-	LATCHPULSE_MARK,
-	LTESIGNAL_MARK,
-	LEGACYSTATE_MARK,
-	TCKON_MARK,
-	VIO_VD_MARK, PORT128_KEYOUT0_MARK, IPORT0_MARK,
-	VIO_HD_MARK, PORT129_KEYOUT1_MARK, IPORT1_MARK,
-	VIO_D0_MARK, PORT130_KEYOUT2_MARK, PORT130_MSIOF2_RXD_MARK,
-	VIO_D1_MARK, PORT131_KEYOUT3_MARK, PORT131_MSIOF2_SS1_MARK,
-	VIO_D2_MARK, PORT132_KEYOUT4_MARK, PORT132_MSIOF2_SS2_MARK,
-	VIO_D3_MARK, PORT133_KEYOUT5_MARK, PORT133_MSIOF2_TSYNC_MARK,
-	VIO_D4_MARK, PORT134_KEYIN0_MARK, PORT134_MSIOF2_TXD_MARK,
-	VIO_D5_MARK, PORT135_KEYIN1_MARK, PORT135_MSIOF2_TSCK_MARK,
-	VIO_D6_MARK, PORT136_KEYIN2_MARK,
-	VIO_D7_MARK, PORT137_KEYIN3_MARK,
-	VIO_D8_MARK, M9_SLCD_A01_MARK, PORT138_FSIAOMC_MARK,
-	VIO_D9_MARK, M10_SLCD_CK1_MARK, PORT139_FSIAOLR_MARK,
-	VIO_D10_MARK, M11_SLCD_SO1_MARK, TPU0TO2_MARK, PORT140_FSIAOBT_MARK,
-	VIO_D11_MARK, M12_SLCD_CE1_MARK, TPU0TO3_MARK, PORT141_FSIAOSLD_MARK,
-	VIO_D12_MARK, M13_BSW_MARK, PORT142_FSIACK_MARK,
-	VIO_D13_MARK, M14_GSW_MARK, PORT143_FSIAILR_MARK,
-	VIO_D14_MARK, M15_RSW_MARK, PORT144_FSIAIBT_MARK,
-	VIO_D15_MARK, TPU1TO3_MARK, PORT145_FSIAISLD_MARK,
-	VIO_CLK_MARK, PORT146_KEYIN4_MARK, IPORT2_MARK,
-	VIO_FIELD_MARK, PORT147_KEYIN5_MARK,
-	VIO_CKO_MARK, PORT148_KEYIN6_MARK,
-	A27_MARK, RDWR_XWE_MARK, MFG0_IN1_MARK,
-	MFG0_IN2_MARK,
-	TS_SPSYNC3_MARK, MSIOF2_RSCK_MARK,
-	TS_SDAT3_MARK, MSIOF2_RSYNC_MARK,
-	TPU1TO2_MARK, TS_SDEN3_MARK, PORT153_MSIOF2_SS1_MARK,
-	SOUT3_MARK, SCIFA2_TXD1_MARK, MSIOF2_MCK0_MARK,
-	SIN3_MARK, SCIFA2_RXD1_MARK, MSIOF2_MCK1_MARK,
-	XRTS3_MARK, SCIFA2_RTS1_MARK, PORT156_MSIOF2_SS2_MARK,
-	XCTS3_MARK, SCIFA2_CTS1_MARK, PORT157_MSIOF2_RXD_MARK,
-
-	/* 55-4 */
-	DINT_MARK, SCIFA2_SCK1_MARK, TS_SCK3_MARK,
-	PORT159_SCIFB_SCK_MARK, PORT159_SCIFA5_SCK_MARK, NMI_MARK,
-	PORT160_SCIFB_TXD_MARK, PORT160_SCIFA5_TXD_MARK, SOUT0_MARK,
-	PORT161_SCIFB_CTS_MARK, PORT161_SCIFA5_CTS_MARK, XCTS0_MARK,
-	MFG3_IN2_MARK,
-	PORT162_SCIFB_RXD_MARK, PORT162_SCIFA5_RXD_MARK, SIN0_MARK,
-	MFG3_IN1_MARK,
-	PORT163_SCIFB_RTS_MARK, PORT163_SCIFA5_RTS_MARK, XRTS0_MARK,
-	MFG3_OUT1_MARK, TPU3TO0_MARK,
-	LCDD0_MARK, PORT192_KEYOUT0_MARK, EXT_CKI_MARK,
-	LCDD1_MARK, PORT193_KEYOUT1_MARK, PORT193_SCIFA5_CTS_MARK,
-	BBIF2_TSYNC1_MARK,
-	LCDD2_MARK, PORT194_KEYOUT2_MARK, PORT194_SCIFA5_RTS_MARK,
-	BBIF2_TSCK1_MARK,
-	LCDD3_MARK, PORT195_KEYOUT3_MARK, PORT195_SCIFA5_RXD_MARK,
-	BBIF2_TXD1_MARK,
-	LCDD4_MARK, PORT196_KEYOUT4_MARK, PORT196_SCIFA5_TXD_MARK,
-	LCDD5_MARK, PORT197_KEYOUT5_MARK, PORT197_SCIFA5_SCK_MARK,
-	MFG2_OUT2_MARK,
-	TPU2TO1_MARK,
-	LCDD6_MARK, XWR2_MARK,
-	LCDD7_MARK, TPU4TO1_MARK, MFG4_OUT2_MARK, XWR3_MARK,
-	LCDD8_MARK, PORT200_KEYIN0_MARK, VIO_DR0_MARK, D16_MARK, ED16_MARK,
-	LCDD9_MARK, PORT201_KEYIN1_MARK, VIO_DR1_MARK, D17_MARK, ED17_MARK,
-	LCDD10_MARK, PORT202_KEYIN2_MARK, VIO_DR2_MARK, D18_MARK, ED18_MARK,
-	LCDD11_MARK, PORT203_KEYIN3_MARK, VIO_DR3_MARK, D19_MARK, ED19_MARK,
-	LCDD12_MARK, PORT204_KEYIN4_MARK, VIO_DR4_MARK, D20_MARK, ED20_MARK,
-	LCDD13_MARK, PORT205_KEYIN5_MARK, VIO_DR5_MARK, D21_MARK, ED21_MARK,
-	LCDD14_MARK, PORT206_KEYIN6_MARK, VIO_DR6_MARK, D22_MARK, ED22_MARK,
-	LCDD15_MARK, PORT207_MSIOF0L_SS1_MARK, PORT207_KEYOUT0_MARK,
-	VIO_DR7_MARK, D23_MARK, ED23_MARK,
-	LCDD16_MARK, PORT208_MSIOF0L_SS2_MARK, PORT208_KEYOUT1_MARK,
-	VIO_VDR_MARK, D24_MARK, ED24_MARK,
-	LCDD17_MARK, PORT209_KEYOUT2_MARK, VIO_HDR_MARK, D25_MARK, ED25_MARK,
-	LCDD18_MARK, DREQ2_MARK, PORT210_MSIOF0L_SS1_MARK, D26_MARK, ED26_MARK,
-	LCDD19_MARK, PORT211_MSIOF0L_SS2_MARK, D27_MARK, ED27_MARK,
-	LCDD20_MARK, TS_SPSYNC1_MARK, MSIOF0L_MCK0_MARK, D28_MARK, ED28_MARK,
-	LCDD21_MARK, TS_SDAT1_MARK, MSIOF0L_MCK1_MARK, D29_MARK, ED29_MARK,
-	LCDD22_MARK, TS_SDEN1_MARK, MSIOF0L_RSCK_MARK, D30_MARK, ED30_MARK,
-	LCDD23_MARK, TS_SCK1_MARK, MSIOF0L_RSYNC_MARK, D31_MARK, ED31_MARK,
-	LCDDCK_MARK, LCDWR_MARK, PORT216_KEYOUT3_MARK, VIO_CLKR_MARK,
-	LCDRD_MARK, DACK2_MARK, MSIOF0L_TSYNC_MARK,
-	LCDHSYN_MARK, LCDCS_MARK, LCDCS2_MARK, DACK3_MARK,
-	PORT218_VIO_CKOR_MARK, PORT218_KEYOUT4_MARK,
-	LCDDISP_MARK, LCDRS_MARK, DREQ3_MARK, MSIOF0L_TSCK_MARK,
-	LCDVSYN_MARK, LCDVSYN2_MARK, PORT220_KEYOUT5_MARK,
-	LCDLCLK_MARK, DREQ1_MARK, PWEN_MARK, MSIOF0L_RXD_MARK,
-	LCDDON_MARK, LCDDON2_MARK, DACK1_MARK, OVCN_MARK, MSIOF0L_TXD_MARK,
-	SCIFA1_TXD_MARK, OVCN2_MARK,
-	EXTLP_MARK, SCIFA1_SCK_MARK, USBTERM_MARK, PORT226_VIO_CKO2_MARK,
-	SCIFA1_RTS_MARK, IDIN_MARK,
-	SCIFA1_RXD_MARK,
-	SCIFA1_CTS_MARK, MFG1_IN1_MARK,
-	MSIOF1_TXD_MARK, SCIFA2_TXD2_MARK, PORT230_FSIAOMC_MARK,
-	MSIOF1_TSYNC_MARK, SCIFA2_CTS2_MARK, PORT231_FSIAOLR_MARK,
-	MSIOF1_TSCK_MARK, SCIFA2_SCK2_MARK, PORT232_FSIAOBT_MARK,
-	MSIOF1_RXD_MARK, SCIFA2_RXD2_MARK, GPS_VCOTRIG_MARK,
-	PORT233_FSIACK_MARK,
-	MSIOF1_RSCK_MARK, SCIFA2_RTS2_MARK, PORT234_FSIAOSLD_MARK,
-	MSIOF1_RSYNC_MARK, OPORT0_MARK, MFG1_IN2_MARK, PORT235_FSIAILR_MARK,
-	MSIOF1_MCK0_MARK, I2C_SDA2_MARK, PORT236_FSIAIBT_MARK,
-	MSIOF1_MCK1_MARK, I2C_SCL2_MARK, PORT237_FSIAISLD_MARK,
-	MSIOF1_SS1_MARK, EDBGREQ3_MARK,
-
-	/* 55-5 */
-	MSIOF1_SS2_MARK,
-	SCIFA6_TXD_MARK,
-	PORT241_IRDA_OUT_MARK, PORT241_IROUT_MARK, MFG4_OUT1_MARK,
-	TPU4TO0_MARK,
-	PORT242_IRDA_IN_MARK, MFG4_IN2_MARK,
-	PORT243_IRDA_FIRSEL_MARK, PORT243_VIO_CKO2_MARK,
-	PORT244_SCIFA5_CTS_MARK, MFG2_IN1_MARK, PORT244_SCIFB_CTS_MARK,
-	PORT244_MSIOF2_RXD_MARK,
-	PORT245_SCIFA5_RTS_MARK, MFG2_IN2_MARK, PORT245_SCIFB_RTS_MARK,
-	PORT245_MSIOF2_TXD_MARK,
-	PORT246_SCIFA5_RXD_MARK, MFG1_OUT1_MARK, PORT246_SCIFB_RXD_MARK,
-	TPU1TO0_MARK,
-	PORT247_SCIFA5_TXD_MARK, MFG3_OUT2_MARK, PORT247_SCIFB_TXD_MARK,
-	TPU3TO1_MARK,
-	PORT248_SCIFA5_SCK_MARK, MFG2_OUT1_MARK, PORT248_SCIFB_SCK_MARK,
-	TPU2TO0_MARK,
-	PORT248_MSIOF2_TSCK_MARK,
-	PORT249_IROUT_MARK, MFG4_IN1_MARK, PORT249_MSIOF2_TSYNC_MARK,
-	SDHICLK0_MARK, TCK2_SWCLK_MC0_MARK,
-	SDHICD0_MARK,
-	SDHID0_0_MARK, TMS2_SWDIO_MC0_MARK,
-	SDHID0_1_MARK, TDO2_SWO0_MC0_MARK,
-	SDHID0_2_MARK, TDI2_MARK,
-	SDHID0_3_MARK, RTCK2_SWO1_MC0_MARK,
-	SDHICMD0_MARK, TRST2_MARK,
-	SDHIWP0_MARK, EDBGREQ2_MARK,
-	SDHICLK1_MARK, TCK3_SWCLK_MC1_MARK,
-	SDHID1_0_MARK, M11_SLCD_SO2_MARK, TS_SPSYNC2_MARK,
-	TMS3_SWDIO_MC1_MARK,
-	SDHID1_1_MARK, M9_SLCD_A02_MARK, TS_SDAT2_MARK, TDO3_SWO0_MC1_MARK,
-	SDHID1_2_MARK, M10_SLCD_CK2_MARK, TS_SDEN2_MARK, TDI3_MARK,
-	SDHID1_3_MARK, M12_SLCD_CE2_MARK, TS_SCK2_MARK, RTCK3_SWO1_MC1_MARK,
-	SDHICMD1_MARK, TRST3_MARK,
-	RESETOUTS_MARK,
-	PINMUX_MARK_END,
-};
-
-static pinmux_enum_t pinmux_data[] = {
-	/* specify valid pin states for each pin in GPIO mode */
-	/* 55-1 (GPIO) */
-	PORT_DATA_I_PD(0), PORT_DATA_I_PU(1),
-	PORT_DATA_I_PU(2), PORT_DATA_I_PU(3),
-	PORT_DATA_I_PU(4), PORT_DATA_I_PU(5),
-	PORT_DATA_I_PU(6), PORT_DATA_I_PU(7),
-	PORT_DATA_I_PU(8), PORT_DATA_I_PU(9),
-	PORT_DATA_I_PU(10), PORT_DATA_I_PU(11),
-	PORT_DATA_IO_PU(12), PORT_DATA_IO_PU(13),
-	PORT_DATA_IO_PU_PD(14), PORT_DATA_IO_PU_PD(15),
-	PORT_DATA_O(16), PORT_DATA_IO(17),
-	PORT_DATA_O(18), PORT_DATA_O(19),
-	PORT_DATA_O(20), PORT_DATA_O(21),
-	PORT_DATA_O(22), PORT_DATA_O(23),
-	PORT_DATA_O(24), PORT_DATA_I_PD(25),
-	PORT_DATA_I_PD(26), PORT_DATA_O(27),
-	PORT_DATA_O(28), PORT_DATA_O(29),
-	PORT_DATA_IO(30), PORT_DATA_IO_PU(31),
-	PORT_DATA_IO_PD(32), PORT_DATA_I_PU(33),
-	PORT_DATA_IO_PD(34), PORT_DATA_I_PU_PD(35),
-	PORT_DATA_O(36), PORT_DATA_IO(37),
-
-	/* 55-2 (GPIO) */
-	PORT_DATA_O(38), PORT_DATA_I_PU(39),
-	PORT_DATA_I_PU_PD(40), PORT_DATA_O(41),
-	PORT_DATA_IO_PD(42), PORT_DATA_IO_PD(43),
-	PORT_DATA_IO_PD(44), PORT_DATA_I_PD(45),
-	PORT_DATA_I_PD(46), PORT_DATA_I_PD(47),
-	PORT_DATA_I_PD(48), PORT_DATA_IO_PU_PD(49),
-	PORT_DATA_IO_PD(50), PORT_DATA_IO_PD(51),
-	PORT_DATA_O(52), PORT_DATA_IO_PU_PD(53),
-	PORT_DATA_IO_PU_PD(54), PORT_DATA_IO_PD(55),
-	PORT_DATA_I_PU_PD(56), PORT_DATA_IO(57),
-	PORT_DATA_IO(58), PORT_DATA_IO(59),
-	PORT_DATA_IO(60), PORT_DATA_IO(61),
-	PORT_DATA_IO_PD(62), PORT_DATA_IO_PD(63),
-	PORT_DATA_IO_PD(64), PORT_DATA_IO_PD(65),
-	PORT_DATA_IO_PU_PD(66), PORT_DATA_IO_PU_PD(67),
-	PORT_DATA_IO_PU_PD(68), PORT_DATA_IO_PU_PD(69),
-	PORT_DATA_IO_PU_PD(70), PORT_DATA_IO_PU_PD(71),
-	PORT_DATA_IO_PU_PD(72), PORT_DATA_I_PU_PD(73),
-	PORT_DATA_IO_PU(74), PORT_DATA_IO_PU(75),
-	PORT_DATA_IO_PU(76), PORT_DATA_IO_PU(77),
-	PORT_DATA_IO_PU(78), PORT_DATA_IO_PU(79),
-	PORT_DATA_IO_PU(80), PORT_DATA_IO_PU(81),
-	PORT_DATA_IO_PU(82), PORT_DATA_IO_PU(83),
-	PORT_DATA_IO_PU(84), PORT_DATA_IO_PU(85),
-	PORT_DATA_IO_PU(86), PORT_DATA_IO_PU(87),
-	PORT_DATA_IO_PU(88), PORT_DATA_IO_PU(89),
-	PORT_DATA_O(90), PORT_DATA_IO_PU(91),
-	PORT_DATA_O(92),
-
-	/* 55-3 (GPIO) */
-	PORT_DATA_IO_PU(93),
-	PORT_DATA_O(94),
-	PORT_DATA_I_PU_PD(95),
-	PORT_DATA_IO(96), PORT_DATA_IO(97),
-	PORT_DATA_IO(98), PORT_DATA_I_PU(99),
-	PORT_DATA_O(100), PORT_DATA_O(101),
-	PORT_DATA_I_PU(102), PORT_DATA_IO_PD(103),
-	PORT_DATA_I_PD(104), PORT_DATA_I_PD(105),
-	PORT_DATA_I_PD(106), PORT_DATA_I_PD(107),
-	PORT_DATA_I_PD(108), PORT_DATA_IO_PD(109),
-	PORT_DATA_IO_PD(110), PORT_DATA_I_PD(111),
-	PORT_DATA_IO_PD(112), PORT_DATA_IO_PD(113),
-	PORT_DATA_IO_PD(114), PORT_DATA_I_PD(115),
-	PORT_DATA_I_PD(116), PORT_DATA_IO_PD(117),
-	PORT_DATA_I_PD(118), PORT_DATA_IO_PD(128),
-	PORT_DATA_IO_PD(129), PORT_DATA_IO_PD(130),
-	PORT_DATA_IO_PD(131), PORT_DATA_IO_PD(132),
-	PORT_DATA_IO_PD(133), PORT_DATA_IO_PU_PD(134),
-	PORT_DATA_IO_PU_PD(135), PORT_DATA_IO_PU_PD(136),
-	PORT_DATA_IO_PU_PD(137), PORT_DATA_IO_PD(138),
-	PORT_DATA_IO_PD(139), PORT_DATA_IO_PD(140),
-	PORT_DATA_IO_PD(141), PORT_DATA_IO_PD(142),
-	PORT_DATA_IO_PD(143), PORT_DATA_IO_PU_PD(144),
-	PORT_DATA_IO_PD(145), PORT_DATA_IO_PU_PD(146),
-	PORT_DATA_IO_PU_PD(147), PORT_DATA_IO_PU_PD(148),
-	PORT_DATA_IO_PU_PD(149), PORT_DATA_I_PD(150),
-	PORT_DATA_IO_PU_PD(151), PORT_DATA_IO_PD(152),
-	PORT_DATA_IO_PD(153), PORT_DATA_IO_PD(154),
-	PORT_DATA_I_PD(155), PORT_DATA_IO_PU_PD(156),
-	PORT_DATA_I_PD(157), PORT_DATA_IO_PD(158),
-
-	/* 55-4 (GPIO) */
-	PORT_DATA_IO_PU_PD(159), PORT_DATA_IO_PU_PD(160),
-	PORT_DATA_I_PU_PD(161), PORT_DATA_I_PU_PD(162),
-	PORT_DATA_IO_PU_PD(163), PORT_DATA_I_PU_PD(164),
-	PORT_DATA_IO_PD(192), PORT_DATA_IO_PD(193),
-	PORT_DATA_IO_PD(194), PORT_DATA_IO_PD(195),
-	PORT_DATA_IO_PD(196), PORT_DATA_IO_PD(197),
-	PORT_DATA_IO_PD(198), PORT_DATA_IO_PD(199),
-	PORT_DATA_IO_PU_PD(200), PORT_DATA_IO_PU_PD(201),
-	PORT_DATA_IO_PU_PD(202), PORT_DATA_IO_PU_PD(203),
-	PORT_DATA_IO_PU_PD(204), PORT_DATA_IO_PU_PD(205),
-	PORT_DATA_IO_PU_PD(206), PORT_DATA_IO_PD(207),
-	PORT_DATA_IO_PD(208), PORT_DATA_IO_PD(209),
-	PORT_DATA_IO_PD(210), PORT_DATA_IO_PD(211),
-	PORT_DATA_IO_PD(212), PORT_DATA_IO_PD(213),
-	PORT_DATA_IO_PD(214), PORT_DATA_IO_PD(215),
-	PORT_DATA_IO_PD(216), PORT_DATA_IO_PD(217),
-	PORT_DATA_O(218), PORT_DATA_IO_PD(219),
-	PORT_DATA_IO_PD(220), PORT_DATA_IO_PD(221),
-	PORT_DATA_IO_PU_PD(222),
-	PORT_DATA_I_PU_PD(223), PORT_DATA_I_PU_PD(224),
-	PORT_DATA_IO_PU_PD(225), PORT_DATA_O(226),
-	PORT_DATA_IO_PU_PD(227), PORT_DATA_I_PD(228),
-	PORT_DATA_I_PD(229), PORT_DATA_IO(230),
-	PORT_DATA_IO_PD(231), PORT_DATA_IO_PU_PD(232),
-	PORT_DATA_I_PD(233), PORT_DATA_IO_PU_PD(234),
-	PORT_DATA_IO_PU_PD(235), PORT_DATA_IO_PU_PD(236),
-	PORT_DATA_IO_PD(237), PORT_DATA_IO_PU_PD(238),
-
-	/* 55-5 (GPIO) */
-	PORT_DATA_IO_PU_PD(239), PORT_DATA_IO_PU_PD(240),
-	PORT_DATA_O(241), PORT_DATA_I_PD(242),
-	PORT_DATA_IO_PU_PD(243), PORT_DATA_IO_PU_PD(244),
-	PORT_DATA_IO_PU_PD(245), PORT_DATA_IO_PU_PD(246),
-	PORT_DATA_IO_PU_PD(247), PORT_DATA_IO_PU_PD(248),
-	PORT_DATA_IO_PU_PD(249), PORT_DATA_IO_PD(250),
-	PORT_DATA_IO_PU_PD(251), PORT_DATA_IO_PU_PD(252),
-	PORT_DATA_IO_PU_PD(253), PORT_DATA_IO_PU_PD(254),
-	PORT_DATA_IO_PU_PD(255), PORT_DATA_IO_PU_PD(256),
-	PORT_DATA_IO_PU_PD(257), PORT_DATA_IO_PD(258),
-	PORT_DATA_IO_PU_PD(259), PORT_DATA_IO_PU_PD(260),
-	PORT_DATA_IO_PU_PD(261), PORT_DATA_IO_PU_PD(262),
-	PORT_DATA_IO_PU_PD(263),
-
-	/* Special Pull-up / Pull-down Functions */
-	PINMUX_DATA(PORT66_KEYIN0_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
-				PORT66_FN2, PORT66_IN_PU),
-	PINMUX_DATA(PORT67_KEYIN1_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
-				PORT67_FN2, PORT67_IN_PU),
-	PINMUX_DATA(PORT68_KEYIN2_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
-				PORT68_FN2, PORT68_IN_PU),
-	PINMUX_DATA(PORT69_KEYIN3_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
-				PORT69_FN2, PORT69_IN_PU),
-	PINMUX_DATA(PORT70_KEYIN4_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
-				PORT70_FN2, PORT70_IN_PU),
-	PINMUX_DATA(PORT71_KEYIN5_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
-				PORT71_FN2, PORT71_IN_PU),
-	PINMUX_DATA(PORT72_KEYIN6_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
-				PORT72_FN2, PORT72_IN_PU),
-
-
-	/* 55-1 (FN) */
-	PINMUX_DATA(VBUS_0_MARK, PORT0_FN1),
-	PINMUX_DATA(CPORT0_MARK, PORT1_FN1),
-	PINMUX_DATA(CPORT1_MARK, PORT2_FN1),
-	PINMUX_DATA(CPORT2_MARK, PORT3_FN1),
-	PINMUX_DATA(CPORT3_MARK, PORT4_FN1),
-	PINMUX_DATA(CPORT4_MARK, PORT5_FN1),
-	PINMUX_DATA(CPORT5_MARK, PORT6_FN1),
-	PINMUX_DATA(CPORT6_MARK, PORT7_FN1),
-	PINMUX_DATA(CPORT7_MARK, PORT8_FN1),
-	PINMUX_DATA(CPORT8_MARK, PORT9_FN1),
-	PINMUX_DATA(CPORT9_MARK, PORT10_FN1),
-	PINMUX_DATA(CPORT10_MARK, PORT11_FN1),
-	PINMUX_DATA(CPORT11_MARK, PORT12_FN1),
-	PINMUX_DATA(SIN2_MARK, PORT12_FN2),
-	PINMUX_DATA(CPORT12_MARK, PORT13_FN1),
-	PINMUX_DATA(XCTS2_MARK, PORT13_FN2),
-	PINMUX_DATA(CPORT13_MARK, PORT14_FN1),
-	PINMUX_DATA(RFSPO4_MARK, PORT14_FN2),
-	PINMUX_DATA(CPORT14_MARK, PORT15_FN1),
-	PINMUX_DATA(RFSPO5_MARK, PORT15_FN2),
-	PINMUX_DATA(CPORT15_MARK, PORT16_FN1),
-	PINMUX_DATA(SCIFA0_SCK_MARK, PORT16_FN2),
-	PINMUX_DATA(GPS_AGC2_MARK, PORT16_FN3),
-	PINMUX_DATA(CPORT16_MARK, PORT17_FN1),
-	PINMUX_DATA(SCIFA0_TXD_MARK, PORT17_FN2),
-	PINMUX_DATA(GPS_AGC3_MARK, PORT17_FN3),
-	PINMUX_DATA(CPORT17_IC_OE_MARK, PORT18_FN1),
-	PINMUX_DATA(SOUT2_MARK, PORT18_FN2),
-	PINMUX_DATA(CPORT18_MARK, PORT19_FN1),
-	PINMUX_DATA(XRTS2_MARK, PORT19_FN2),
-	PINMUX_DATA(PORT19_VIO_CKO2_MARK, PORT19_FN3),
-	PINMUX_DATA(CPORT19_MPORT1_MARK, PORT20_FN1),
-	PINMUX_DATA(CPORT20_MARK, PORT21_FN1),
-	PINMUX_DATA(RFSPO6_MARK, PORT21_FN2),
-	PINMUX_DATA(CPORT21_MARK, PORT22_FN1),
-	PINMUX_DATA(STATUS0_MARK, PORT22_FN2),
-	PINMUX_DATA(CPORT22_MARK, PORT23_FN1),
-	PINMUX_DATA(STATUS1_MARK, PORT23_FN2),
-	PINMUX_DATA(CPORT23_MARK, PORT24_FN1),
-	PINMUX_DATA(STATUS2_MARK, PORT24_FN2),
-	PINMUX_DATA(RFSPO7_MARK, PORT24_FN3),
-	PINMUX_DATA(B_SYNLD1_MARK, PORT25_FN1),
-	PINMUX_DATA(B_SYNLD2_MARK, PORT26_FN1),
-	PINMUX_DATA(SYSENMSK_MARK, PORT26_FN2),
-	PINMUX_DATA(XMAINPS_MARK, PORT27_FN1),
-	PINMUX_DATA(XDIVPS_MARK, PORT28_FN1),
-	PINMUX_DATA(XIDRST_MARK, PORT29_FN1),
-	PINMUX_DATA(IDCLK_MARK, PORT30_FN1),
-	PINMUX_DATA(IC_DP_MARK, PORT30_FN2),
-	PINMUX_DATA(IDIO_MARK, PORT31_FN1),
-	PINMUX_DATA(IC_DM_MARK, PORT31_FN2),
-	PINMUX_DATA(SOUT1_MARK, PORT32_FN1),
-	PINMUX_DATA(SCIFA4_TXD_MARK, PORT32_FN2),
-	PINMUX_DATA(M02_BERDAT_MARK, PORT32_FN3),
-	PINMUX_DATA(SIN1_MARK, PORT33_FN1),
-	PINMUX_DATA(SCIFA4_RXD_MARK, PORT33_FN2),
-	PINMUX_DATA(XWUP_MARK, PORT33_FN3),
-	PINMUX_DATA(XRTS1_MARK, PORT34_FN1),
-	PINMUX_DATA(SCIFA4_RTS_MARK, PORT34_FN2),
-	PINMUX_DATA(M03_BERCLK_MARK, PORT34_FN3),
-	PINMUX_DATA(XCTS1_MARK, PORT35_FN1),
-	PINMUX_DATA(SCIFA4_CTS_MARK, PORT35_FN2),
-	PINMUX_DATA(PCMCLKO_MARK, PORT36_FN1),
-	PINMUX_DATA(SYNC8KO_MARK, PORT37_FN1),
-
-	/* 55-2 (FN) */
-	PINMUX_DATA(DNPCM_A_MARK, PORT38_FN1),
-	PINMUX_DATA(UPPCM_A_MARK, PORT39_FN1),
-	PINMUX_DATA(VACK_MARK, PORT40_FN1),
-	PINMUX_DATA(XTALB1L_MARK, PORT41_FN1),
-	PINMUX_DATA(GPS_AGC1_MARK, PORT42_FN1),
-	PINMUX_DATA(SCIFA0_RTS_MARK, PORT42_FN2),
-	PINMUX_DATA(GPS_AGC4_MARK, PORT43_FN1),
-	PINMUX_DATA(SCIFA0_RXD_MARK, PORT43_FN2),
-	PINMUX_DATA(GPS_PWRDOWN_MARK, PORT44_FN1),
-	PINMUX_DATA(SCIFA0_CTS_MARK, PORT44_FN2),
-	PINMUX_DATA(GPS_IM_MARK, PORT45_FN1),
-	PINMUX_DATA(GPS_IS_MARK, PORT46_FN1),
-	PINMUX_DATA(GPS_QM_MARK, PORT47_FN1),
-	PINMUX_DATA(GPS_QS_MARK, PORT48_FN1),
-	PINMUX_DATA(FMSOCK_MARK, PORT49_FN1),
-	PINMUX_DATA(PORT49_IRDA_OUT_MARK, PORT49_FN2),
-	PINMUX_DATA(PORT49_IROUT_MARK, PORT49_FN3),
-	PINMUX_DATA(FMSOOLR_MARK, PORT50_FN1),
-	PINMUX_DATA(BBIF2_TSYNC2_MARK, PORT50_FN2),
-	PINMUX_DATA(TPU2TO2_MARK, PORT50_FN3),
-	PINMUX_DATA(IPORT3_MARK, PORT50_FN4),
-	PINMUX_DATA(FMSIOLR_MARK, PORT50_FN5),
-	PINMUX_DATA(FMSOOBT_MARK, PORT51_FN1),
-	PINMUX_DATA(BBIF2_TSCK2_MARK, PORT51_FN2),
-	PINMUX_DATA(TPU2TO3_MARK, PORT51_FN3),
-	PINMUX_DATA(OPORT1_MARK, PORT51_FN4),
-	PINMUX_DATA(FMSIOBT_MARK, PORT51_FN5),
-	PINMUX_DATA(FMSOSLD_MARK, PORT52_FN1),
-	PINMUX_DATA(BBIF2_TXD2_MARK, PORT52_FN2),
-	PINMUX_DATA(OPORT2_MARK, PORT52_FN3),
-	PINMUX_DATA(FMSOILR_MARK, PORT53_FN1),
-	PINMUX_DATA(PORT53_IRDA_IN_MARK, PORT53_FN2),
-	PINMUX_DATA(TPU3TO3_MARK, PORT53_FN3),
-	PINMUX_DATA(OPORT3_MARK, PORT53_FN4),
-	PINMUX_DATA(FMSIILR_MARK, PORT53_FN5),
-	PINMUX_DATA(FMSOIBT_MARK, PORT54_FN1),
-	PINMUX_DATA(PORT54_IRDA_FIRSEL_MARK, PORT54_FN2),
-	PINMUX_DATA(TPU3TO2_MARK, PORT54_FN3),
-	PINMUX_DATA(FMSIIBT_MARK, PORT54_FN4),
-	PINMUX_DATA(FMSISLD_MARK, PORT55_FN1),
-	PINMUX_DATA(MFG0_OUT1_MARK, PORT55_FN2),
-	PINMUX_DATA(TPU0TO0_MARK, PORT55_FN3),
-	PINMUX_DATA(A0_EA0_MARK, PORT57_FN1),
-	PINMUX_DATA(BS_MARK, PORT57_FN2),
-	PINMUX_DATA(A12_EA12_MARK, PORT58_FN1),
-	PINMUX_DATA(PORT58_VIO_CKOR_MARK, PORT58_FN2),
-	PINMUX_DATA(TPU4TO2_MARK, PORT58_FN3),
-	PINMUX_DATA(A13_EA13_MARK, PORT59_FN1),
-	PINMUX_DATA(PORT59_IROUT_MARK, PORT59_FN2),
-	PINMUX_DATA(MFG0_OUT2_MARK, PORT59_FN3),
-	PINMUX_DATA(TPU0TO1_MARK, PORT59_FN4),
-	PINMUX_DATA(A14_EA14_MARK, PORT60_FN1),
-	PINMUX_DATA(PORT60_KEYOUT5_MARK, PORT60_FN2),
-	PINMUX_DATA(A15_EA15_MARK, PORT61_FN1),
-	PINMUX_DATA(PORT61_KEYOUT4_MARK, PORT61_FN2),
-	PINMUX_DATA(A16_EA16_MARK, PORT62_FN1),
-	PINMUX_DATA(PORT62_KEYOUT3_MARK, PORT62_FN2),
-	PINMUX_DATA(MSIOF0_SS1_MARK, PORT62_FN3),
-	PINMUX_DATA(A17_EA17_MARK, PORT63_FN1),
-	PINMUX_DATA(PORT63_KEYOUT2_MARK, PORT63_FN2),
-	PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT63_FN3),
-	PINMUX_DATA(A18_EA18_MARK, PORT64_FN1),
-	PINMUX_DATA(PORT64_KEYOUT1_MARK, PORT64_FN2),
-	PINMUX_DATA(MSIOF0_TSCK_MARK, PORT64_FN3),
-	PINMUX_DATA(A19_EA19_MARK, PORT65_FN1),
-	PINMUX_DATA(PORT65_KEYOUT0_MARK, PORT65_FN2),
-	PINMUX_DATA(MSIOF0_TXD_MARK, PORT65_FN3),
-	PINMUX_DATA(A20_EA20_MARK, PORT66_FN1),
-	PINMUX_DATA(PORT66_KEYIN0_MARK, PORT66_FN2),
-	PINMUX_DATA(MSIOF0_RSCK_MARK, PORT66_FN3),
-	PINMUX_DATA(A21_EA21_MARK, PORT67_FN1),
-	PINMUX_DATA(PORT67_KEYIN1_MARK, PORT67_FN2),
-	PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT67_FN3),
-	PINMUX_DATA(A22_EA22_MARK, PORT68_FN1),
-	PINMUX_DATA(PORT68_KEYIN2_MARK, PORT68_FN2),
-	PINMUX_DATA(MSIOF0_MCK0_MARK, PORT68_FN3),
-	PINMUX_DATA(A23_EA23_MARK, PORT69_FN1),
-	PINMUX_DATA(PORT69_KEYIN3_MARK, PORT69_FN2),
-	PINMUX_DATA(MSIOF0_MCK1_MARK, PORT69_FN3),
-	PINMUX_DATA(A24_EA24_MARK, PORT70_FN1),
-	PINMUX_DATA(PORT70_KEYIN4_MARK, PORT70_FN2),
-	PINMUX_DATA(MSIOF0_RXD_MARK, PORT70_FN3),
-	PINMUX_DATA(A25_EA25_MARK, PORT71_FN1),
-	PINMUX_DATA(PORT71_KEYIN5_MARK, PORT71_FN2),
-	PINMUX_DATA(MSIOF0_SS2_MARK, PORT71_FN3),
-	PINMUX_DATA(A26_MARK, PORT72_FN1),
-	PINMUX_DATA(PORT72_KEYIN6_MARK, PORT72_FN2),
-	PINMUX_DATA(D0_ED0_NAF0_MARK, PORT74_FN1),
-	PINMUX_DATA(D1_ED1_NAF1_MARK, PORT75_FN1),
-	PINMUX_DATA(D2_ED2_NAF2_MARK, PORT76_FN1),
-	PINMUX_DATA(D3_ED3_NAF3_MARK, PORT77_FN1),
-	PINMUX_DATA(D4_ED4_NAF4_MARK, PORT78_FN1),
-	PINMUX_DATA(D5_ED5_NAF5_MARK, PORT79_FN1),
-	PINMUX_DATA(D6_ED6_NAF6_MARK, PORT80_FN1),
-	PINMUX_DATA(D7_ED7_NAF7_MARK, PORT81_FN1),
-	PINMUX_DATA(D8_ED8_NAF8_MARK, PORT82_FN1),
-	PINMUX_DATA(D9_ED9_NAF9_MARK, PORT83_FN1),
-	PINMUX_DATA(D10_ED10_NAF10_MARK, PORT84_FN1),
-	PINMUX_DATA(D11_ED11_NAF11_MARK, PORT85_FN1),
-	PINMUX_DATA(D12_ED12_NAF12_MARK, PORT86_FN1),
-	PINMUX_DATA(D13_ED13_NAF13_MARK, PORT87_FN1),
-	PINMUX_DATA(D14_ED14_NAF14_MARK, PORT88_FN1),
-	PINMUX_DATA(D15_ED15_NAF15_MARK, PORT89_FN1),
-	PINMUX_DATA(CS4_MARK, PORT90_FN1),
-	PINMUX_DATA(CS5A_MARK, PORT91_FN1),
-	PINMUX_DATA(FMSICK_MARK, PORT91_FN2),
-	PINMUX_DATA(CS5B_MARK, PORT92_FN1),
-	PINMUX_DATA(FCE1_MARK, PORT92_FN2),
-
-	/* 55-3 (FN) */
-	PINMUX_DATA(CS6B_MARK, PORT93_FN1),
-	PINMUX_DATA(XCS2_MARK, PORT93_FN2),
-	PINMUX_DATA(CS6A_MARK, PORT93_FN3),
-	PINMUX_DATA(DACK0_MARK, PORT93_FN4),
-	PINMUX_DATA(FCE0_MARK, PORT94_FN1),
-	PINMUX_DATA(WAIT_MARK, PORT95_FN1),
-	PINMUX_DATA(DREQ0_MARK, PORT95_FN2),
-	PINMUX_DATA(RD_XRD_MARK, PORT96_FN1),
-	PINMUX_DATA(WE0_XWR0_FWE_MARK, PORT97_FN1),
-	PINMUX_DATA(WE1_XWR1_MARK, PORT98_FN1),
-	PINMUX_DATA(FRB_MARK, PORT99_FN1),
-	PINMUX_DATA(CKO_MARK, PORT100_FN1),
-	PINMUX_DATA(NBRSTOUT_MARK, PORT101_FN1),
-	PINMUX_DATA(NBRST_MARK, PORT102_FN1),
-	PINMUX_DATA(GPS_EPPSIN_MARK, PORT106_FN1),
-	PINMUX_DATA(LATCHPULSE_MARK, PORT110_FN1),
-	PINMUX_DATA(LTESIGNAL_MARK, PORT111_FN1),
-	PINMUX_DATA(LEGACYSTATE_MARK, PORT112_FN1),
-	PINMUX_DATA(TCKON_MARK, PORT118_FN1),
-	PINMUX_DATA(VIO_VD_MARK, PORT128_FN1),
-	PINMUX_DATA(PORT128_KEYOUT0_MARK, PORT128_FN2),
-	PINMUX_DATA(IPORT0_MARK, PORT128_FN3),
-	PINMUX_DATA(VIO_HD_MARK, PORT129_FN1),
-	PINMUX_DATA(PORT129_KEYOUT1_MARK, PORT129_FN2),
-	PINMUX_DATA(IPORT1_MARK, PORT129_FN3),
-	PINMUX_DATA(VIO_D0_MARK, PORT130_FN1),
-	PINMUX_DATA(PORT130_KEYOUT2_MARK, PORT130_FN2),
-	PINMUX_DATA(PORT130_MSIOF2_RXD_MARK, PORT130_FN3),
-	PINMUX_DATA(VIO_D1_MARK, PORT131_FN1),
-	PINMUX_DATA(PORT131_KEYOUT3_MARK, PORT131_FN2),
-	PINMUX_DATA(PORT131_MSIOF2_SS1_MARK, PORT131_FN3),
-	PINMUX_DATA(VIO_D2_MARK, PORT132_FN1),
-	PINMUX_DATA(PORT132_KEYOUT4_MARK, PORT132_FN2),
-	PINMUX_DATA(PORT132_MSIOF2_SS2_MARK, PORT132_FN3),
-	PINMUX_DATA(VIO_D3_MARK, PORT133_FN1),
-	PINMUX_DATA(PORT133_KEYOUT5_MARK, PORT133_FN2),
-	PINMUX_DATA(PORT133_MSIOF2_TSYNC_MARK, PORT133_FN3),
-	PINMUX_DATA(VIO_D4_MARK, PORT134_FN1),
-	PINMUX_DATA(PORT134_KEYIN0_MARK, PORT134_FN2),
-	PINMUX_DATA(PORT134_MSIOF2_TXD_MARK, PORT134_FN3),
-	PINMUX_DATA(VIO_D5_MARK, PORT135_FN1),
-	PINMUX_DATA(PORT135_KEYIN1_MARK, PORT135_FN2),
-	PINMUX_DATA(PORT135_MSIOF2_TSCK_MARK, PORT135_FN3),
-	PINMUX_DATA(VIO_D6_MARK, PORT136_FN1),
-	PINMUX_DATA(PORT136_KEYIN2_MARK, PORT136_FN2),
-	PINMUX_DATA(VIO_D7_MARK, PORT137_FN1),
-	PINMUX_DATA(PORT137_KEYIN3_MARK, PORT137_FN2),
-	PINMUX_DATA(VIO_D8_MARK, PORT138_FN1),
-	PINMUX_DATA(M9_SLCD_A01_MARK, PORT138_FN2),
-	PINMUX_DATA(PORT138_FSIAOMC_MARK, PORT138_FN3),
-	PINMUX_DATA(VIO_D9_MARK, PORT139_FN1),
-	PINMUX_DATA(M10_SLCD_CK1_MARK, PORT139_FN2),
-	PINMUX_DATA(PORT139_FSIAOLR_MARK, PORT139_FN3),
-	PINMUX_DATA(VIO_D10_MARK, PORT140_FN1),
-	PINMUX_DATA(M11_SLCD_SO1_MARK, PORT140_FN2),
-	PINMUX_DATA(TPU0TO2_MARK, PORT140_FN3),
-	PINMUX_DATA(PORT140_FSIAOBT_MARK, PORT140_FN4),
-	PINMUX_DATA(VIO_D11_MARK, PORT141_FN1),
-	PINMUX_DATA(M12_SLCD_CE1_MARK, PORT141_FN2),
-	PINMUX_DATA(TPU0TO3_MARK, PORT141_FN3),
-	PINMUX_DATA(PORT141_FSIAOSLD_MARK, PORT141_FN4),
-	PINMUX_DATA(VIO_D12_MARK, PORT142_FN1),
-	PINMUX_DATA(M13_BSW_MARK, PORT142_FN2),
-	PINMUX_DATA(PORT142_FSIACK_MARK, PORT142_FN3),
-	PINMUX_DATA(VIO_D13_MARK, PORT143_FN1),
-	PINMUX_DATA(M14_GSW_MARK, PORT143_FN2),
-	PINMUX_DATA(PORT143_FSIAILR_MARK, PORT143_FN3),
-	PINMUX_DATA(VIO_D14_MARK, PORT144_FN1),
-	PINMUX_DATA(M15_RSW_MARK, PORT144_FN2),
-	PINMUX_DATA(PORT144_FSIAIBT_MARK, PORT144_FN3),
-	PINMUX_DATA(VIO_D15_MARK, PORT145_FN1),
-	PINMUX_DATA(TPU1TO3_MARK, PORT145_FN2),
-	PINMUX_DATA(PORT145_FSIAISLD_MARK, PORT145_FN3),
-	PINMUX_DATA(VIO_CLK_MARK, PORT146_FN1),
-	PINMUX_DATA(PORT146_KEYIN4_MARK, PORT146_FN2),
-	PINMUX_DATA(IPORT2_MARK, PORT146_FN3),
-	PINMUX_DATA(VIO_FIELD_MARK, PORT147_FN1),
-	PINMUX_DATA(PORT147_KEYIN5_MARK, PORT147_FN2),
-	PINMUX_DATA(VIO_CKO_MARK, PORT148_FN1),
-	PINMUX_DATA(PORT148_KEYIN6_MARK, PORT148_FN2),
-	PINMUX_DATA(A27_MARK, PORT149_FN1),
-	PINMUX_DATA(RDWR_XWE_MARK, PORT149_FN2),
-	PINMUX_DATA(MFG0_IN1_MARK, PORT149_FN3),
-	PINMUX_DATA(MFG0_IN2_MARK, PORT150_FN1),
-	PINMUX_DATA(TS_SPSYNC3_MARK, PORT151_FN1),
-	PINMUX_DATA(MSIOF2_RSCK_MARK, PORT151_FN2),
-	PINMUX_DATA(TS_SDAT3_MARK, PORT152_FN1),
-	PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT152_FN2),
-	PINMUX_DATA(TPU1TO2_MARK, PORT153_FN1),
-	PINMUX_DATA(TS_SDEN3_MARK, PORT153_FN2),
-	PINMUX_DATA(PORT153_MSIOF2_SS1_MARK, PORT153_FN3),
-	PINMUX_DATA(SOUT3_MARK, PORT154_FN1),
-	PINMUX_DATA(SCIFA2_TXD1_MARK, PORT154_FN2),
-	PINMUX_DATA(MSIOF2_MCK0_MARK, PORT154_FN3),
-	PINMUX_DATA(SIN3_MARK, PORT155_FN1),
-	PINMUX_DATA(SCIFA2_RXD1_MARK, PORT155_FN2),
-	PINMUX_DATA(MSIOF2_MCK1_MARK, PORT155_FN3),
-	PINMUX_DATA(XRTS3_MARK, PORT156_FN1),
-	PINMUX_DATA(SCIFA2_RTS1_MARK, PORT156_FN2),
-	PINMUX_DATA(PORT156_MSIOF2_SS2_MARK, PORT156_FN3),
-	PINMUX_DATA(XCTS3_MARK, PORT157_FN1),
-	PINMUX_DATA(SCIFA2_CTS1_MARK, PORT157_FN2),
-	PINMUX_DATA(PORT157_MSIOF2_RXD_MARK, PORT157_FN3),
-
-	/* 55-4 (FN) */
-	PINMUX_DATA(DINT_MARK, PORT158_FN1),
-	PINMUX_DATA(SCIFA2_SCK1_MARK, PORT158_FN2),
-	PINMUX_DATA(TS_SCK3_MARK, PORT158_FN3),
-	PINMUX_DATA(PORT159_SCIFB_SCK_MARK, PORT159_FN1),
-	PINMUX_DATA(PORT159_SCIFA5_SCK_MARK, PORT159_FN2),
-	PINMUX_DATA(NMI_MARK, PORT159_FN3),
-	PINMUX_DATA(PORT160_SCIFB_TXD_MARK, PORT160_FN1),
-	PINMUX_DATA(PORT160_SCIFA5_TXD_MARK, PORT160_FN2),
-	PINMUX_DATA(SOUT0_MARK, PORT160_FN3),
-	PINMUX_DATA(PORT161_SCIFB_CTS_MARK, PORT161_FN1),
-	PINMUX_DATA(PORT161_SCIFA5_CTS_MARK, PORT161_FN2),
-	PINMUX_DATA(XCTS0_MARK, PORT161_FN3),
-	PINMUX_DATA(MFG3_IN2_MARK, PORT161_FN4),
-	PINMUX_DATA(PORT162_SCIFB_RXD_MARK, PORT162_FN1),
-	PINMUX_DATA(PORT162_SCIFA5_RXD_MARK, PORT162_FN2),
-	PINMUX_DATA(SIN0_MARK, PORT162_FN3),
-	PINMUX_DATA(MFG3_IN1_MARK, PORT162_FN4),
-	PINMUX_DATA(PORT163_SCIFB_RTS_MARK, PORT163_FN1),
-	PINMUX_DATA(PORT163_SCIFA5_RTS_MARK, PORT163_FN2),
-	PINMUX_DATA(XRTS0_MARK, PORT163_FN3),
-	PINMUX_DATA(MFG3_OUT1_MARK, PORT163_FN4),
-	PINMUX_DATA(TPU3TO0_MARK, PORT163_FN5),
-	PINMUX_DATA(LCDD0_MARK, PORT192_FN1),
-	PINMUX_DATA(PORT192_KEYOUT0_MARK, PORT192_FN2),
-	PINMUX_DATA(EXT_CKI_MARK, PORT192_FN3),
-	PINMUX_DATA(LCDD1_MARK, PORT193_FN1),
-	PINMUX_DATA(PORT193_KEYOUT1_MARK, PORT193_FN2),
-	PINMUX_DATA(PORT193_SCIFA5_CTS_MARK, PORT193_FN3),
-	PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT193_FN4),
-	PINMUX_DATA(LCDD2_MARK, PORT194_FN1),
-	PINMUX_DATA(PORT194_KEYOUT2_MARK, PORT194_FN2),
-	PINMUX_DATA(PORT194_SCIFA5_RTS_MARK, PORT194_FN3),
-	PINMUX_DATA(BBIF2_TSCK1_MARK, PORT194_FN4),
-	PINMUX_DATA(LCDD3_MARK, PORT195_FN1),
-	PINMUX_DATA(PORT195_KEYOUT3_MARK, PORT195_FN2),
-	PINMUX_DATA(PORT195_SCIFA5_RXD_MARK, PORT195_FN3),
-	PINMUX_DATA(BBIF2_TXD1_MARK, PORT195_FN4),
-	PINMUX_DATA(LCDD4_MARK, PORT196_FN1),
-	PINMUX_DATA(PORT196_KEYOUT4_MARK, PORT196_FN2),
-	PINMUX_DATA(PORT196_SCIFA5_TXD_MARK, PORT196_FN3),
-	PINMUX_DATA(LCDD5_MARK, PORT197_FN1),
-	PINMUX_DATA(PORT197_KEYOUT5_MARK, PORT197_FN2),
-	PINMUX_DATA(PORT197_SCIFA5_SCK_MARK, PORT197_FN3),
-	PINMUX_DATA(MFG2_OUT2_MARK, PORT197_FN4),
-	PINMUX_DATA(LCDD6_MARK, PORT198_FN1),
-	PINMUX_DATA(LCDD7_MARK, PORT199_FN1),
-	PINMUX_DATA(TPU4TO1_MARK, PORT199_FN2),
-	PINMUX_DATA(MFG4_OUT2_MARK, PORT199_FN3),
-	PINMUX_DATA(LCDD8_MARK, PORT200_FN1),
-	PINMUX_DATA(PORT200_KEYIN0_MARK, PORT200_FN2),
-	PINMUX_DATA(VIO_DR0_MARK, PORT200_FN3),
-	PINMUX_DATA(D16_MARK, PORT200_FN4),
-	PINMUX_DATA(LCDD9_MARK, PORT201_FN1),
-	PINMUX_DATA(PORT201_KEYIN1_MARK, PORT201_FN2),
-	PINMUX_DATA(VIO_DR1_MARK, PORT201_FN3),
-	PINMUX_DATA(D17_MARK, PORT201_FN4),
-	PINMUX_DATA(LCDD10_MARK, PORT202_FN1),
-	PINMUX_DATA(PORT202_KEYIN2_MARK, PORT202_FN2),
-	PINMUX_DATA(VIO_DR2_MARK, PORT202_FN3),
-	PINMUX_DATA(D18_MARK, PORT202_FN4),
-	PINMUX_DATA(LCDD11_MARK, PORT203_FN1),
-	PINMUX_DATA(PORT203_KEYIN3_MARK, PORT203_FN2),
-	PINMUX_DATA(VIO_DR3_MARK, PORT203_FN3),
-	PINMUX_DATA(D19_MARK, PORT203_FN4),
-	PINMUX_DATA(LCDD12_MARK, PORT204_FN1),
-	PINMUX_DATA(PORT204_KEYIN4_MARK, PORT204_FN2),
-	PINMUX_DATA(VIO_DR4_MARK, PORT204_FN3),
-	PINMUX_DATA(D20_MARK, PORT204_FN4),
-	PINMUX_DATA(LCDD13_MARK, PORT205_FN1),
-	PINMUX_DATA(PORT205_KEYIN5_MARK, PORT205_FN2),
-	PINMUX_DATA(VIO_DR5_MARK, PORT205_FN3),
-	PINMUX_DATA(D21_MARK, PORT205_FN4),
-	PINMUX_DATA(LCDD14_MARK, PORT206_FN1),
-	PINMUX_DATA(PORT206_KEYIN6_MARK, PORT206_FN2),
-	PINMUX_DATA(VIO_DR6_MARK, PORT206_FN3),
-	PINMUX_DATA(D22_MARK, PORT206_FN4),
-	PINMUX_DATA(LCDD15_MARK, PORT207_FN1),
-	PINMUX_DATA(PORT207_MSIOF0L_SS1_MARK, PORT207_FN2),
-	PINMUX_DATA(PORT207_KEYOUT0_MARK, PORT207_FN3),
-	PINMUX_DATA(VIO_DR7_MARK, PORT207_FN4),
-	PINMUX_DATA(D23_MARK, PORT207_FN5),
-	PINMUX_DATA(LCDD16_MARK, PORT208_FN1),
-	PINMUX_DATA(PORT208_MSIOF0L_SS2_MARK, PORT208_FN2),
-	PINMUX_DATA(PORT208_KEYOUT1_MARK, PORT208_FN3),
-	PINMUX_DATA(VIO_VDR_MARK, PORT208_FN4),
-	PINMUX_DATA(D24_MARK, PORT208_FN5),
-	PINMUX_DATA(LCDD17_MARK, PORT209_FN1),
-	PINMUX_DATA(PORT209_KEYOUT2_MARK, PORT209_FN2),
-	PINMUX_DATA(VIO_HDR_MARK, PORT209_FN3),
-	PINMUX_DATA(D25_MARK, PORT209_FN4),
-	PINMUX_DATA(LCDD18_MARK, PORT210_FN1),
-	PINMUX_DATA(DREQ2_MARK, PORT210_FN2),
-	PINMUX_DATA(PORT210_MSIOF0L_SS1_MARK, PORT210_FN3),
-	PINMUX_DATA(D26_MARK, PORT210_FN4),
-	PINMUX_DATA(LCDD19_MARK, PORT211_FN1),
-	PINMUX_DATA(PORT211_MSIOF0L_SS2_MARK, PORT211_FN2),
-	PINMUX_DATA(D27_MARK, PORT211_FN3),
-	PINMUX_DATA(LCDD20_MARK, PORT212_FN1),
-	PINMUX_DATA(TS_SPSYNC1_MARK, PORT212_FN2),
-	PINMUX_DATA(MSIOF0L_MCK0_MARK, PORT212_FN3),
-	PINMUX_DATA(D28_MARK, PORT212_FN4),
-	PINMUX_DATA(LCDD21_MARK, PORT213_FN1),
-	PINMUX_DATA(TS_SDAT1_MARK, PORT213_FN2),
-	PINMUX_DATA(MSIOF0L_MCK1_MARK, PORT213_FN3),
-	PINMUX_DATA(D29_MARK, PORT213_FN4),
-	PINMUX_DATA(LCDD22_MARK, PORT214_FN1),
-	PINMUX_DATA(TS_SDEN1_MARK, PORT214_FN2),
-	PINMUX_DATA(MSIOF0L_RSCK_MARK, PORT214_FN3),
-	PINMUX_DATA(D30_MARK, PORT214_FN4),
-	PINMUX_DATA(LCDD23_MARK, PORT215_FN1),
-	PINMUX_DATA(TS_SCK1_MARK, PORT215_FN2),
-	PINMUX_DATA(MSIOF0L_RSYNC_MARK, PORT215_FN3),
-	PINMUX_DATA(D31_MARK, PORT215_FN4),
-	PINMUX_DATA(LCDDCK_MARK, PORT216_FN1),
-	PINMUX_DATA(LCDWR_MARK, PORT216_FN2),
-	PINMUX_DATA(PORT216_KEYOUT3_MARK, PORT216_FN3),
-	PINMUX_DATA(VIO_CLKR_MARK, PORT216_FN4),
-	PINMUX_DATA(LCDRD_MARK, PORT217_FN1),
-	PINMUX_DATA(DACK2_MARK, PORT217_FN2),
-	PINMUX_DATA(MSIOF0L_TSYNC_MARK, PORT217_FN3),
-	PINMUX_DATA(LCDHSYN_MARK, PORT218_FN1),
-	PINMUX_DATA(LCDCS_MARK, PORT218_FN2),
-	PINMUX_DATA(LCDCS2_MARK, PORT218_FN3),
-	PINMUX_DATA(DACK3_MARK, PORT218_FN4),
-	PINMUX_DATA(PORT218_VIO_CKOR_MARK, PORT218_FN5),
-	PINMUX_DATA(PORT218_KEYOUT4_MARK, PORT218_FN6),
-	PINMUX_DATA(LCDDISP_MARK, PORT219_FN1),
-	PINMUX_DATA(LCDRS_MARK, PORT219_FN2),
-	PINMUX_DATA(DREQ3_MARK, PORT219_FN3),
-	PINMUX_DATA(MSIOF0L_TSCK_MARK, PORT219_FN4),
-	PINMUX_DATA(LCDVSYN_MARK, PORT220_FN1),
-	PINMUX_DATA(LCDVSYN2_MARK, PORT220_FN2),
-	PINMUX_DATA(PORT220_KEYOUT5_MARK, PORT220_FN3),
-	PINMUX_DATA(LCDLCLK_MARK, PORT221_FN1),
-	PINMUX_DATA(DREQ1_MARK, PORT221_FN2),
-	PINMUX_DATA(PWEN_MARK, PORT221_FN3),
-	PINMUX_DATA(MSIOF0L_RXD_MARK, PORT221_FN4),
-	PINMUX_DATA(LCDDON_MARK, PORT222_FN1),
-	PINMUX_DATA(LCDDON2_MARK, PORT222_FN2),
-	PINMUX_DATA(DACK1_MARK, PORT222_FN3),
-	PINMUX_DATA(OVCN_MARK, PORT222_FN4),
-	PINMUX_DATA(MSIOF0L_TXD_MARK, PORT222_FN5),
-	PINMUX_DATA(SCIFA1_TXD_MARK, PORT225_FN1),
-	PINMUX_DATA(OVCN2_MARK, PORT225_FN2),
-	PINMUX_DATA(EXTLP_MARK, PORT226_FN1),
-	PINMUX_DATA(SCIFA1_SCK_MARK, PORT226_FN2),
-	PINMUX_DATA(USBTERM_MARK, PORT226_FN3),
-	PINMUX_DATA(PORT226_VIO_CKO2_MARK, PORT226_FN4),
-	PINMUX_DATA(SCIFA1_RTS_MARK, PORT227_FN1),
-	PINMUX_DATA(IDIN_MARK, PORT227_FN2),
-	PINMUX_DATA(SCIFA1_RXD_MARK, PORT228_FN1),
-	PINMUX_DATA(SCIFA1_CTS_MARK, PORT229_FN1),
-	PINMUX_DATA(MFG1_IN1_MARK, PORT229_FN2),
-	PINMUX_DATA(MSIOF1_TXD_MARK, PORT230_FN1),
-	PINMUX_DATA(SCIFA2_TXD2_MARK, PORT230_FN2),
-	PINMUX_DATA(PORT230_FSIAOMC_MARK, PORT230_FN3),
-	PINMUX_DATA(MSIOF1_TSYNC_MARK, PORT231_FN1),
-	PINMUX_DATA(SCIFA2_CTS2_MARK, PORT231_FN2),
-	PINMUX_DATA(PORT231_FSIAOLR_MARK, PORT231_FN3),
-	PINMUX_DATA(MSIOF1_TSCK_MARK, PORT232_FN1),
-	PINMUX_DATA(SCIFA2_SCK2_MARK, PORT232_FN2),
-	PINMUX_DATA(PORT232_FSIAOBT_MARK, PORT232_FN3),
-	PINMUX_DATA(MSIOF1_RXD_MARK, PORT233_FN1),
-	PINMUX_DATA(SCIFA2_RXD2_MARK, PORT233_FN2),
-	PINMUX_DATA(GPS_VCOTRIG_MARK, PORT233_FN3),
-	PINMUX_DATA(PORT233_FSIACK_MARK, PORT233_FN4),
-	PINMUX_DATA(MSIOF1_RSCK_MARK, PORT234_FN1),
-	PINMUX_DATA(SCIFA2_RTS2_MARK, PORT234_FN2),
-	PINMUX_DATA(PORT234_FSIAOSLD_MARK, PORT234_FN3),
-	PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT235_FN1),
-	PINMUX_DATA(OPORT0_MARK, PORT235_FN2),
-	PINMUX_DATA(MFG1_IN2_MARK, PORT235_FN3),
-	PINMUX_DATA(PORT235_FSIAILR_MARK, PORT235_FN4),
-	PINMUX_DATA(MSIOF1_MCK0_MARK, PORT236_FN1),
-	PINMUX_DATA(I2C_SDA2_MARK, PORT236_FN2),
-	PINMUX_DATA(PORT236_FSIAIBT_MARK, PORT236_FN3),
-	PINMUX_DATA(MSIOF1_MCK1_MARK, PORT237_FN1),
-	PINMUX_DATA(I2C_SCL2_MARK, PORT237_FN2),
-	PINMUX_DATA(PORT237_FSIAISLD_MARK, PORT237_FN3),
-	PINMUX_DATA(MSIOF1_SS1_MARK, PORT238_FN1),
-	PINMUX_DATA(EDBGREQ3_MARK, PORT238_FN2),
-
-	/* 55-5 (FN) */
-	PINMUX_DATA(MSIOF1_SS2_MARK, PORT239_FN1),
-	PINMUX_DATA(SCIFA6_TXD_MARK, PORT240_FN1),
-	PINMUX_DATA(PORT241_IRDA_OUT_MARK, PORT241_FN1),
-	PINMUX_DATA(PORT241_IROUT_MARK, PORT241_FN2),
-	PINMUX_DATA(MFG4_OUT1_MARK, PORT241_FN3),
-	PINMUX_DATA(TPU4TO0_MARK, PORT241_FN4),
-	PINMUX_DATA(PORT242_IRDA_IN_MARK, PORT242_FN1),
-	PINMUX_DATA(MFG4_IN2_MARK, PORT242_FN2),
-	PINMUX_DATA(PORT243_IRDA_FIRSEL_MARK, PORT243_FN1),
-	PINMUX_DATA(PORT243_VIO_CKO2_MARK, PORT243_FN2),
-	PINMUX_DATA(PORT244_SCIFA5_CTS_MARK, PORT244_FN1),
-	PINMUX_DATA(MFG2_IN1_MARK, PORT244_FN2),
-	PINMUX_DATA(PORT244_SCIFB_CTS_MARK, PORT244_FN3),
-	PINMUX_DATA(PORT245_SCIFA5_RTS_MARK, PORT245_FN1),
-	PINMUX_DATA(MFG2_IN2_MARK, PORT245_FN2),
-	PINMUX_DATA(PORT245_SCIFB_RTS_MARK, PORT245_FN3),
-	PINMUX_DATA(PORT246_SCIFA5_RXD_MARK, PORT246_FN1),
-	PINMUX_DATA(MFG1_OUT1_MARK, PORT246_FN2),
-	PINMUX_DATA(PORT246_SCIFB_RXD_MARK, PORT246_FN3),
-	PINMUX_DATA(TPU1TO0_MARK, PORT246_FN4),
-	PINMUX_DATA(PORT247_SCIFA5_TXD_MARK, PORT247_FN1),
-	PINMUX_DATA(MFG3_OUT2_MARK, PORT247_FN2),
-	PINMUX_DATA(PORT247_SCIFB_TXD_MARK, PORT247_FN3),
-	PINMUX_DATA(TPU3TO1_MARK, PORT247_FN4),
-	PINMUX_DATA(PORT248_SCIFA5_SCK_MARK, PORT248_FN1),
-	PINMUX_DATA(MFG2_OUT1_MARK, PORT248_FN2),
-	PINMUX_DATA(PORT248_SCIFB_SCK_MARK, PORT248_FN3),
-	PINMUX_DATA(TPU2TO0_MARK, PORT248_FN4),
-	PINMUX_DATA(PORT249_IROUT_MARK, PORT249_FN1),
-	PINMUX_DATA(MFG4_IN1_MARK, PORT249_FN2),
-	PINMUX_DATA(SDHICLK0_MARK, PORT250_FN1),
-	PINMUX_DATA(TCK2_SWCLK_MC0_MARK, PORT250_FN2),
-	PINMUX_DATA(SDHICD0_MARK, PORT251_FN1),
-	PINMUX_DATA(SDHID0_0_MARK, PORT252_FN1),
-	PINMUX_DATA(TMS2_SWDIO_MC0_MARK, PORT252_FN2),
-	PINMUX_DATA(SDHID0_1_MARK, PORT253_FN1),
-	PINMUX_DATA(TDO2_SWO0_MC0_MARK, PORT253_FN2),
-	PINMUX_DATA(SDHID0_2_MARK, PORT254_FN1),
-	PINMUX_DATA(TDI2_MARK, PORT254_FN2),
-	PINMUX_DATA(SDHID0_3_MARK, PORT255_FN1),
-	PINMUX_DATA(RTCK2_SWO1_MC0_MARK, PORT255_FN2),
-	PINMUX_DATA(SDHICMD0_MARK, PORT256_FN1),
-	PINMUX_DATA(TRST2_MARK, PORT256_FN2),
-	PINMUX_DATA(SDHIWP0_MARK, PORT257_FN1),
-	PINMUX_DATA(EDBGREQ2_MARK, PORT257_FN2),
-	PINMUX_DATA(SDHICLK1_MARK, PORT258_FN1),
-	PINMUX_DATA(TCK3_SWCLK_MC1_MARK, PORT258_FN2),
-	PINMUX_DATA(SDHID1_0_MARK, PORT259_FN1),
-	PINMUX_DATA(M11_SLCD_SO2_MARK, PORT259_FN2),
-	PINMUX_DATA(TS_SPSYNC2_MARK, PORT259_FN3),
-	PINMUX_DATA(TMS3_SWDIO_MC1_MARK, PORT259_FN4),
-	PINMUX_DATA(SDHID1_1_MARK, PORT260_FN1),
-	PINMUX_DATA(M9_SLCD_A02_MARK, PORT260_FN2),
-	PINMUX_DATA(TS_SDAT2_MARK, PORT260_FN3),
-	PINMUX_DATA(TDO3_SWO0_MC1_MARK, PORT260_FN4),
-	PINMUX_DATA(SDHID1_2_MARK, PORT261_FN1),
-	PINMUX_DATA(M10_SLCD_CK2_MARK, PORT261_FN2),
-	PINMUX_DATA(TS_SDEN2_MARK, PORT261_FN3),
-	PINMUX_DATA(TDI3_MARK, PORT261_FN4),
-	PINMUX_DATA(SDHID1_3_MARK, PORT262_FN1),
-	PINMUX_DATA(M12_SLCD_CE2_MARK, PORT262_FN2),
-	PINMUX_DATA(TS_SCK2_MARK, PORT262_FN3),
-	PINMUX_DATA(RTCK3_SWO1_MC1_MARK, PORT262_FN4),
-	PINMUX_DATA(SDHICMD1_MARK, PORT263_FN1),
-	PINMUX_DATA(TRST3_MARK, PORT263_FN2),
-	PINMUX_DATA(RESETOUTS_MARK, PORT264_FN1),
-};
-
-static struct pinmux_gpio pinmux_gpios[] = {
-	/* 55-1 -> 55-5 (GPIO) */
-	GPIO_PORT_ALL(),
-
-	/* Special Pull-up / Pull-down Functions */
-	GPIO_FN(PORT66_KEYIN0_PU), GPIO_FN(PORT67_KEYIN1_PU),
-	GPIO_FN(PORT68_KEYIN2_PU), GPIO_FN(PORT69_KEYIN3_PU),
-	GPIO_FN(PORT70_KEYIN4_PU), GPIO_FN(PORT71_KEYIN5_PU),
-	GPIO_FN(PORT72_KEYIN6_PU),
-
-	/* 55-1 (FN) */
-	GPIO_FN(VBUS_0),
-	GPIO_FN(CPORT0),
-	GPIO_FN(CPORT1),
-	GPIO_FN(CPORT2),
-	GPIO_FN(CPORT3),
-	GPIO_FN(CPORT4),
-	GPIO_FN(CPORT5),
-	GPIO_FN(CPORT6),
-	GPIO_FN(CPORT7),
-	GPIO_FN(CPORT8),
-	GPIO_FN(CPORT9),
-	GPIO_FN(CPORT10),
-	GPIO_FN(CPORT11), GPIO_FN(SIN2),
-	GPIO_FN(CPORT12), GPIO_FN(XCTS2),
-	GPIO_FN(CPORT13), GPIO_FN(RFSPO4),
-	GPIO_FN(CPORT14), GPIO_FN(RFSPO5),
-	GPIO_FN(CPORT15), GPIO_FN(SCIFA0_SCK), GPIO_FN(GPS_AGC2),
-	GPIO_FN(CPORT16), GPIO_FN(SCIFA0_TXD), GPIO_FN(GPS_AGC3),
-	GPIO_FN(CPORT17_IC_OE), GPIO_FN(SOUT2),
-	GPIO_FN(CPORT18), GPIO_FN(XRTS2), GPIO_FN(PORT19_VIO_CKO2),
-	GPIO_FN(CPORT19_MPORT1),
-	GPIO_FN(CPORT20), GPIO_FN(RFSPO6),
-	GPIO_FN(CPORT21), GPIO_FN(STATUS0),
-	GPIO_FN(CPORT22), GPIO_FN(STATUS1),
-	GPIO_FN(CPORT23), GPIO_FN(STATUS2), GPIO_FN(RFSPO7),
-	GPIO_FN(B_SYNLD1),
-	GPIO_FN(B_SYNLD2), GPIO_FN(SYSENMSK),
-	GPIO_FN(XMAINPS),
-	GPIO_FN(XDIVPS),
-	GPIO_FN(XIDRST),
-	GPIO_FN(IDCLK), GPIO_FN(IC_DP),
-	GPIO_FN(IDIO), GPIO_FN(IC_DM),
-	GPIO_FN(SOUT1), GPIO_FN(SCIFA4_TXD), GPIO_FN(M02_BERDAT),
-	GPIO_FN(SIN1), GPIO_FN(SCIFA4_RXD), GPIO_FN(XWUP),
-	GPIO_FN(XRTS1), GPIO_FN(SCIFA4_RTS), GPIO_FN(M03_BERCLK),
-	GPIO_FN(XCTS1), GPIO_FN(SCIFA4_CTS),
-	GPIO_FN(PCMCLKO),
-	GPIO_FN(SYNC8KO),
-
-	/* 55-2 (FN) */
-	GPIO_FN(DNPCM_A),
-	GPIO_FN(UPPCM_A),
-	GPIO_FN(VACK),
-	GPIO_FN(XTALB1L),
-	GPIO_FN(GPS_AGC1), GPIO_FN(SCIFA0_RTS),
-	GPIO_FN(GPS_AGC4), GPIO_FN(SCIFA0_RXD),
-	GPIO_FN(GPS_PWRDOWN), GPIO_FN(SCIFA0_CTS),
-	GPIO_FN(GPS_IM),
-	GPIO_FN(GPS_IS),
-	GPIO_FN(GPS_QM),
-	GPIO_FN(GPS_QS),
-	GPIO_FN(FMSOCK), GPIO_FN(PORT49_IRDA_OUT), GPIO_FN(PORT49_IROUT),
-	GPIO_FN(FMSOOLR), GPIO_FN(BBIF2_TSYNC2), GPIO_FN(TPU2TO2),
-	GPIO_FN(IPORT3), GPIO_FN(FMSIOLR),
-	GPIO_FN(FMSOOBT), GPIO_FN(BBIF2_TSCK2), GPIO_FN(TPU2TO3),
-	GPIO_FN(OPORT1), GPIO_FN(FMSIOBT),
-	GPIO_FN(FMSOSLD), GPIO_FN(BBIF2_TXD2), GPIO_FN(OPORT2),
-	GPIO_FN(FMSOILR), GPIO_FN(PORT53_IRDA_IN), GPIO_FN(TPU3TO3),
-	GPIO_FN(OPORT3), GPIO_FN(FMSIILR),
-	GPIO_FN(FMSOIBT), GPIO_FN(PORT54_IRDA_FIRSEL), GPIO_FN(TPU3TO2),
-	GPIO_FN(FMSIIBT),
-	GPIO_FN(FMSISLD), GPIO_FN(MFG0_OUT1), GPIO_FN(TPU0TO0),
-	GPIO_FN(A0_EA0), GPIO_FN(BS),
-	GPIO_FN(A12_EA12), GPIO_FN(PORT58_VIO_CKOR), GPIO_FN(TPU4TO2),
-	GPIO_FN(A13_EA13), GPIO_FN(PORT59_IROUT), GPIO_FN(MFG0_OUT2),
-	GPIO_FN(TPU0TO1),
-	GPIO_FN(A14_EA14), GPIO_FN(PORT60_KEYOUT5),
-	GPIO_FN(A15_EA15), GPIO_FN(PORT61_KEYOUT4),
-	GPIO_FN(A16_EA16), GPIO_FN(PORT62_KEYOUT3), GPIO_FN(MSIOF0_SS1),
-	GPIO_FN(A17_EA17), GPIO_FN(PORT63_KEYOUT2), GPIO_FN(MSIOF0_TSYNC),
-	GPIO_FN(A18_EA18), GPIO_FN(PORT64_KEYOUT1), GPIO_FN(MSIOF0_TSCK),
-	GPIO_FN(A19_EA19), GPIO_FN(PORT65_KEYOUT0), GPIO_FN(MSIOF0_TXD),
-	GPIO_FN(A20_EA20), GPIO_FN(PORT66_KEYIN0), GPIO_FN(MSIOF0_RSCK),
-	GPIO_FN(A21_EA21), GPIO_FN(PORT67_KEYIN1), GPIO_FN(MSIOF0_RSYNC),
-	GPIO_FN(A22_EA22), GPIO_FN(PORT68_KEYIN2), GPIO_FN(MSIOF0_MCK0),
-	GPIO_FN(A23_EA23), GPIO_FN(PORT69_KEYIN3), GPIO_FN(MSIOF0_MCK1),
-	GPIO_FN(A24_EA24), GPIO_FN(PORT70_KEYIN4), GPIO_FN(MSIOF0_RXD),
-	GPIO_FN(A25_EA25), GPIO_FN(PORT71_KEYIN5), GPIO_FN(MSIOF0_SS2),
-	GPIO_FN(A26), GPIO_FN(PORT72_KEYIN6),
-	GPIO_FN(D0_ED0_NAF0),
-	GPIO_FN(D1_ED1_NAF1),
-	GPIO_FN(D2_ED2_NAF2),
-	GPIO_FN(D3_ED3_NAF3),
-	GPIO_FN(D4_ED4_NAF4),
-	GPIO_FN(D5_ED5_NAF5),
-	GPIO_FN(D6_ED6_NAF6),
-	GPIO_FN(D7_ED7_NAF7),
-	GPIO_FN(D8_ED8_NAF8),
-	GPIO_FN(D9_ED9_NAF9),
-	GPIO_FN(D10_ED10_NAF10),
-	GPIO_FN(D11_ED11_NAF11),
-	GPIO_FN(D12_ED12_NAF12),
-	GPIO_FN(D13_ED13_NAF13),
-	GPIO_FN(D14_ED14_NAF14),
-	GPIO_FN(D15_ED15_NAF15),
-	GPIO_FN(CS4),
-	GPIO_FN(CS5A), GPIO_FN(FMSICK),
-
-	/* 55-3 (FN) */
-	GPIO_FN(CS5B), GPIO_FN(FCE1),
-	GPIO_FN(CS6B), GPIO_FN(XCS2), GPIO_FN(CS6A), GPIO_FN(DACK0),
-	GPIO_FN(FCE0),
-	GPIO_FN(WAIT), GPIO_FN(DREQ0),
-	GPIO_FN(RD_XRD),
-	GPIO_FN(WE0_XWR0_FWE),
-	GPIO_FN(WE1_XWR1),
-	GPIO_FN(FRB),
-	GPIO_FN(CKO),
-	GPIO_FN(NBRSTOUT),
-	GPIO_FN(NBRST),
-	GPIO_FN(GPS_EPPSIN),
-	GPIO_FN(LATCHPULSE),
-	GPIO_FN(LTESIGNAL),
-	GPIO_FN(LEGACYSTATE),
-	GPIO_FN(TCKON),
-	GPIO_FN(VIO_VD), GPIO_FN(PORT128_KEYOUT0), GPIO_FN(IPORT0),
-	GPIO_FN(VIO_HD), GPIO_FN(PORT129_KEYOUT1), GPIO_FN(IPORT1),
-	GPIO_FN(VIO_D0), GPIO_FN(PORT130_KEYOUT2), GPIO_FN(PORT130_MSIOF2_RXD),
-	GPIO_FN(VIO_D1), GPIO_FN(PORT131_KEYOUT3), GPIO_FN(PORT131_MSIOF2_SS1),
-	GPIO_FN(VIO_D2), GPIO_FN(PORT132_KEYOUT4), GPIO_FN(PORT132_MSIOF2_SS2),
-	GPIO_FN(VIO_D3), GPIO_FN(PORT133_KEYOUT5),
-	GPIO_FN(PORT133_MSIOF2_TSYNC),
-	GPIO_FN(VIO_D4), GPIO_FN(PORT134_KEYIN0), GPIO_FN(PORT134_MSIOF2_TXD),
-	GPIO_FN(VIO_D5), GPIO_FN(PORT135_KEYIN1), GPIO_FN(PORT135_MSIOF2_TSCK),
-	GPIO_FN(VIO_D6), GPIO_FN(PORT136_KEYIN2),
-	GPIO_FN(VIO_D7), GPIO_FN(PORT137_KEYIN3),
-	GPIO_FN(VIO_D8), GPIO_FN(M9_SLCD_A01), GPIO_FN(PORT138_FSIAOMC),
-	GPIO_FN(VIO_D9), GPIO_FN(M10_SLCD_CK1), GPIO_FN(PORT139_FSIAOLR),
-	GPIO_FN(VIO_D10), GPIO_FN(M11_SLCD_SO1), GPIO_FN(TPU0TO2),
-	GPIO_FN(PORT140_FSIAOBT),
-	GPIO_FN(VIO_D11), GPIO_FN(M12_SLCD_CE1), GPIO_FN(TPU0TO3),
-	GPIO_FN(PORT141_FSIAOSLD),
-	GPIO_FN(VIO_D12), GPIO_FN(M13_BSW), GPIO_FN(PORT142_FSIACK),
-	GPIO_FN(VIO_D13), GPIO_FN(M14_GSW), GPIO_FN(PORT143_FSIAILR),
-	GPIO_FN(VIO_D14), GPIO_FN(M15_RSW), GPIO_FN(PORT144_FSIAIBT),
-	GPIO_FN(VIO_D15), GPIO_FN(TPU1TO3), GPIO_FN(PORT145_FSIAISLD),
-	GPIO_FN(VIO_CLK), GPIO_FN(PORT146_KEYIN4), GPIO_FN(IPORT2),
-	GPIO_FN(VIO_FIELD), GPIO_FN(PORT147_KEYIN5),
-	GPIO_FN(VIO_CKO), GPIO_FN(PORT148_KEYIN6),
-	GPIO_FN(A27), GPIO_FN(RDWR_XWE), GPIO_FN(MFG0_IN1),
-	GPIO_FN(MFG0_IN2),
-	GPIO_FN(TS_SPSYNC3), GPIO_FN(MSIOF2_RSCK),
-	GPIO_FN(TS_SDAT3), GPIO_FN(MSIOF2_RSYNC),
-	GPIO_FN(TPU1TO2), GPIO_FN(TS_SDEN3), GPIO_FN(PORT153_MSIOF2_SS1),
-	GPIO_FN(SOUT3), GPIO_FN(SCIFA2_TXD1), GPIO_FN(MSIOF2_MCK0),
-	GPIO_FN(SIN3), GPIO_FN(SCIFA2_RXD1), GPIO_FN(MSIOF2_MCK1),
-	GPIO_FN(XRTS3), GPIO_FN(SCIFA2_RTS1), GPIO_FN(PORT156_MSIOF2_SS2),
-	GPIO_FN(XCTS3), GPIO_FN(SCIFA2_CTS1), GPIO_FN(PORT157_MSIOF2_RXD),
-
-	/* 55-4 (FN) */
-	GPIO_FN(DINT), GPIO_FN(SCIFA2_SCK1), GPIO_FN(TS_SCK3),
-	GPIO_FN(PORT159_SCIFB_SCK), GPIO_FN(PORT159_SCIFA5_SCK), GPIO_FN(NMI),
-	GPIO_FN(PORT160_SCIFB_TXD), GPIO_FN(PORT160_SCIFA5_TXD), GPIO_FN(SOUT0),
-	GPIO_FN(PORT161_SCIFB_CTS), GPIO_FN(PORT161_SCIFA5_CTS), GPIO_FN(XCTS0),
-	GPIO_FN(MFG3_IN2),
-	GPIO_FN(PORT162_SCIFB_RXD), GPIO_FN(PORT162_SCIFA5_RXD), GPIO_FN(SIN0),
-	GPIO_FN(MFG3_IN1),
-	GPIO_FN(PORT163_SCIFB_RTS), GPIO_FN(PORT163_SCIFA5_RTS), GPIO_FN(XRTS0),
-	GPIO_FN(MFG3_OUT1), GPIO_FN(TPU3TO0),
-	GPIO_FN(LCDD0), GPIO_FN(PORT192_KEYOUT0), GPIO_FN(EXT_CKI),
-	GPIO_FN(LCDD1), GPIO_FN(PORT193_KEYOUT1), GPIO_FN(PORT193_SCIFA5_CTS),
-	GPIO_FN(BBIF2_TSYNC1),
-	GPIO_FN(LCDD2), GPIO_FN(PORT194_KEYOUT2), GPIO_FN(PORT194_SCIFA5_RTS),
-	GPIO_FN(BBIF2_TSCK1),
-	GPIO_FN(LCDD3), GPIO_FN(PORT195_KEYOUT3), GPIO_FN(PORT195_SCIFA5_RXD),
-	GPIO_FN(BBIF2_TXD1),
-	GPIO_FN(LCDD4), GPIO_FN(PORT196_KEYOUT4), GPIO_FN(PORT196_SCIFA5_TXD),
-	GPIO_FN(LCDD5), GPIO_FN(PORT197_KEYOUT5), GPIO_FN(PORT197_SCIFA5_SCK),
-	GPIO_FN(MFG2_OUT2),
-	GPIO_FN(LCDD6),
-	GPIO_FN(LCDD7), GPIO_FN(TPU4TO1), GPIO_FN(MFG4_OUT2),
-	GPIO_FN(LCDD8), GPIO_FN(PORT200_KEYIN0), GPIO_FN(VIO_DR0),
-	GPIO_FN(D16),
-	GPIO_FN(LCDD9), GPIO_FN(PORT201_KEYIN1), GPIO_FN(VIO_DR1),
-	GPIO_FN(D17),
-	GPIO_FN(LCDD10), GPIO_FN(PORT202_KEYIN2), GPIO_FN(VIO_DR2),
-	GPIO_FN(D18),
-	GPIO_FN(LCDD11), GPIO_FN(PORT203_KEYIN3), GPIO_FN(VIO_DR3),
-	GPIO_FN(D19),
-	GPIO_FN(LCDD12), GPIO_FN(PORT204_KEYIN4), GPIO_FN(VIO_DR4),
-	GPIO_FN(D20),
-	GPIO_FN(LCDD13), GPIO_FN(PORT205_KEYIN5), GPIO_FN(VIO_DR5),
-	GPIO_FN(D21),
-	GPIO_FN(LCDD14), GPIO_FN(PORT206_KEYIN6), GPIO_FN(VIO_DR6),
-	GPIO_FN(D22),
-	GPIO_FN(LCDD15), GPIO_FN(PORT207_MSIOF0L_SS1), GPIO_FN(PORT207_KEYOUT0),
-	GPIO_FN(VIO_DR7), GPIO_FN(D23),
-	GPIO_FN(LCDD16), GPIO_FN(PORT208_MSIOF0L_SS2), GPIO_FN(PORT208_KEYOUT1),
-	GPIO_FN(VIO_VDR), GPIO_FN(D24),
-	GPIO_FN(LCDD17), GPIO_FN(PORT209_KEYOUT2), GPIO_FN(VIO_HDR),
-	GPIO_FN(D25),
-	GPIO_FN(LCDD18), GPIO_FN(DREQ2), GPIO_FN(PORT210_MSIOF0L_SS1),
-	GPIO_FN(D26),
-	GPIO_FN(LCDD19), GPIO_FN(PORT211_MSIOF0L_SS2), GPIO_FN(D27),
-	GPIO_FN(LCDD20), GPIO_FN(TS_SPSYNC1), GPIO_FN(MSIOF0L_MCK0),
-	GPIO_FN(D28),
-	GPIO_FN(LCDD21), GPIO_FN(TS_SDAT1), GPIO_FN(MSIOF0L_MCK1),
-	GPIO_FN(D29),
-	GPIO_FN(LCDD22), GPIO_FN(TS_SDEN1), GPIO_FN(MSIOF0L_RSCK),
-	GPIO_FN(D30),
-	GPIO_FN(LCDD23), GPIO_FN(TS_SCK1), GPIO_FN(MSIOF0L_RSYNC),
-	GPIO_FN(D31),
-	GPIO_FN(LCDDCK), GPIO_FN(LCDWR), GPIO_FN(PORT216_KEYOUT3),
-	GPIO_FN(VIO_CLKR),
-	GPIO_FN(LCDRD), GPIO_FN(DACK2), GPIO_FN(MSIOF0L_TSYNC),
-	GPIO_FN(LCDHSYN), GPIO_FN(LCDCS), GPIO_FN(LCDCS2), GPIO_FN(DACK3),
-	GPIO_FN(PORT218_VIO_CKOR), GPIO_FN(PORT218_KEYOUT4),
-	GPIO_FN(LCDDISP), GPIO_FN(LCDRS), GPIO_FN(DREQ3), GPIO_FN(MSIOF0L_TSCK),
-	GPIO_FN(LCDVSYN), GPIO_FN(LCDVSYN2), GPIO_FN(PORT220_KEYOUT5),
-	GPIO_FN(LCDLCLK), GPIO_FN(DREQ1), GPIO_FN(PWEN), GPIO_FN(MSIOF0L_RXD),
-	GPIO_FN(LCDDON), GPIO_FN(LCDDON2), GPIO_FN(DACK1), GPIO_FN(OVCN),
-	GPIO_FN(MSIOF0L_TXD),
-	GPIO_FN(SCIFA1_TXD), GPIO_FN(OVCN2),
-	GPIO_FN(EXTLP), GPIO_FN(SCIFA1_SCK), GPIO_FN(USBTERM),
-	GPIO_FN(PORT226_VIO_CKO2),
-	GPIO_FN(SCIFA1_RTS), GPIO_FN(IDIN),
-	GPIO_FN(SCIFA1_RXD),
-	GPIO_FN(SCIFA1_CTS), GPIO_FN(MFG1_IN1),
-	GPIO_FN(MSIOF1_TXD), GPIO_FN(SCIFA2_TXD2), GPIO_FN(PORT230_FSIAOMC),
-	GPIO_FN(MSIOF1_TSYNC), GPIO_FN(SCIFA2_CTS2), GPIO_FN(PORT231_FSIAOLR),
-	GPIO_FN(MSIOF1_TSCK), GPIO_FN(SCIFA2_SCK2), GPIO_FN(PORT232_FSIAOBT),
-	GPIO_FN(MSIOF1_RXD), GPIO_FN(SCIFA2_RXD2), GPIO_FN(GPS_VCOTRIG),
-	GPIO_FN(PORT233_FSIACK),
-	GPIO_FN(MSIOF1_RSCK), GPIO_FN(SCIFA2_RTS2), GPIO_FN(PORT234_FSIAOSLD),
-	GPIO_FN(MSIOF1_RSYNC), GPIO_FN(OPORT0), GPIO_FN(MFG1_IN2),
-	GPIO_FN(PORT235_FSIAILR),
-	GPIO_FN(MSIOF1_MCK0), GPIO_FN(I2C_SDA2), GPIO_FN(PORT236_FSIAIBT),
-	GPIO_FN(MSIOF1_MCK1), GPIO_FN(I2C_SCL2), GPIO_FN(PORT237_FSIAISLD),
-	GPIO_FN(MSIOF1_SS1), GPIO_FN(EDBGREQ3),
-
-	/* 55-5 (FN) */
-	GPIO_FN(MSIOF1_SS2),
-	GPIO_FN(SCIFA6_TXD),
-	GPIO_FN(PORT241_IRDA_OUT), GPIO_FN(PORT241_IROUT), GPIO_FN(MFG4_OUT1),
-	GPIO_FN(TPU4TO0),
-	GPIO_FN(PORT242_IRDA_IN), GPIO_FN(MFG4_IN2),
-	GPIO_FN(PORT243_IRDA_FIRSEL), GPIO_FN(PORT243_VIO_CKO2),
-	GPIO_FN(PORT244_SCIFA5_CTS), GPIO_FN(MFG2_IN1),
-	GPIO_FN(PORT244_SCIFB_CTS),
-	GPIO_FN(PORT245_SCIFA5_RTS), GPIO_FN(MFG2_IN2),
-	GPIO_FN(PORT245_SCIFB_RTS),
-	GPIO_FN(PORT246_SCIFA5_RXD), GPIO_FN(MFG1_OUT1),
-	GPIO_FN(PORT246_SCIFB_RXD), GPIO_FN(TPU1TO0),
-	GPIO_FN(PORT247_SCIFA5_TXD), GPIO_FN(MFG3_OUT2),
-	GPIO_FN(PORT247_SCIFB_TXD), GPIO_FN(TPU3TO1),
-	GPIO_FN(PORT248_SCIFA5_SCK), GPIO_FN(MFG2_OUT1),
-	GPIO_FN(PORT248_SCIFB_SCK), GPIO_FN(TPU2TO0),
-	GPIO_FN(PORT249_IROUT), GPIO_FN(MFG4_IN1),
-	GPIO_FN(SDHICLK0), GPIO_FN(TCK2_SWCLK_MC0),
-	GPIO_FN(SDHICD0),
-	GPIO_FN(SDHID0_0), GPIO_FN(TMS2_SWDIO_MC0),
-	GPIO_FN(SDHID0_1), GPIO_FN(TDO2_SWO0_MC0),
-	GPIO_FN(SDHID0_2), GPIO_FN(TDI2),
-	GPIO_FN(SDHID0_3), GPIO_FN(RTCK2_SWO1_MC0),
-	GPIO_FN(SDHICMD0), GPIO_FN(TRST2),
-	GPIO_FN(SDHIWP0), GPIO_FN(EDBGREQ2),
-	GPIO_FN(SDHICLK1), GPIO_FN(TCK3_SWCLK_MC1),
-	GPIO_FN(SDHID1_0), GPIO_FN(M11_SLCD_SO2), GPIO_FN(TS_SPSYNC2),
-	GPIO_FN(TMS3_SWDIO_MC1),
-	GPIO_FN(SDHID1_1), GPIO_FN(M9_SLCD_A02), GPIO_FN(TS_SDAT2),
-	GPIO_FN(TDO3_SWO0_MC1),
-	GPIO_FN(SDHID1_2), GPIO_FN(M10_SLCD_CK2), GPIO_FN(TS_SDEN2),
-	GPIO_FN(TDI3),
-	GPIO_FN(SDHID1_3), GPIO_FN(M12_SLCD_CE2), GPIO_FN(TS_SCK2),
-	GPIO_FN(RTCK3_SWO1_MC1),
-	GPIO_FN(SDHICMD1), GPIO_FN(TRST3),
-	GPIO_FN(RESETOUTS),
-};
-
-static struct pinmux_cfg_reg pinmux_config_regs[] = {
-	PORTCR(0, 0xe6050000), /* PORT0CR */
-	PORTCR(1, 0xe6050001), /* PORT1CR */
-	PORTCR(2, 0xe6050002), /* PORT2CR */
-	PORTCR(3, 0xe6050003), /* PORT3CR */
-	PORTCR(4, 0xe6050004), /* PORT4CR */
-	PORTCR(5, 0xe6050005), /* PORT5CR */
-	PORTCR(6, 0xe6050006), /* PORT6CR */
-	PORTCR(7, 0xe6050007), /* PORT7CR */
-	PORTCR(8, 0xe6050008), /* PORT8CR */
-	PORTCR(9, 0xe6050009), /* PORT9CR */
-
-	PORTCR(10, 0xe605000a), /* PORT10CR */
-	PORTCR(11, 0xe605000b), /* PORT11CR */
-	PORTCR(12, 0xe605000c), /* PORT12CR */
-	PORTCR(13, 0xe605000d), /* PORT13CR */
-	PORTCR(14, 0xe605000e), /* PORT14CR */
-	PORTCR(15, 0xe605000f), /* PORT15CR */
-	PORTCR(16, 0xe6050010), /* PORT16CR */
-	PORTCR(17, 0xe6050011), /* PORT17CR */
-	PORTCR(18, 0xe6050012), /* PORT18CR */
-	PORTCR(19, 0xe6050013), /* PORT19CR */
-
-	PORTCR(20, 0xe6050014), /* PORT20CR */
-	PORTCR(21, 0xe6050015), /* PORT21CR */
-	PORTCR(22, 0xe6050016), /* PORT22CR */
-	PORTCR(23, 0xe6050017), /* PORT23CR */
-	PORTCR(24, 0xe6050018), /* PORT24CR */
-	PORTCR(25, 0xe6050019), /* PORT25CR */
-	PORTCR(26, 0xe605001a), /* PORT26CR */
-	PORTCR(27, 0xe605001b), /* PORT27CR */
-	PORTCR(28, 0xe605001c), /* PORT28CR */
-	PORTCR(29, 0xe605001d), /* PORT29CR */
-
-	PORTCR(30, 0xe605001e), /* PORT30CR */
-	PORTCR(31, 0xe605001f), /* PORT31CR */
-	PORTCR(32, 0xe6050020), /* PORT32CR */
-	PORTCR(33, 0xe6050021), /* PORT33CR */
-	PORTCR(34, 0xe6050022), /* PORT34CR */
-	PORTCR(35, 0xe6050023), /* PORT35CR */
-	PORTCR(36, 0xe6050024), /* PORT36CR */
-	PORTCR(37, 0xe6050025), /* PORT37CR */
-	PORTCR(38, 0xe6050026), /* PORT38CR */
-	PORTCR(39, 0xe6050027), /* PORT39CR */
-
-	PORTCR(40, 0xe6050028), /* PORT40CR */
-	PORTCR(41, 0xe6050029), /* PORT41CR */
-	PORTCR(42, 0xe605002a), /* PORT42CR */
-	PORTCR(43, 0xe605002b), /* PORT43CR */
-	PORTCR(44, 0xe605002c), /* PORT44CR */
-	PORTCR(45, 0xe605002d), /* PORT45CR */
-	PORTCR(46, 0xe605002e), /* PORT46CR */
-	PORTCR(47, 0xe605002f), /* PORT47CR */
-	PORTCR(48, 0xe6050030), /* PORT48CR */
-	PORTCR(49, 0xe6050031), /* PORT49CR */
-
-	PORTCR(50, 0xe6050032), /* PORT50CR */
-	PORTCR(51, 0xe6050033), /* PORT51CR */
-	PORTCR(52, 0xe6050034), /* PORT52CR */
-	PORTCR(53, 0xe6050035), /* PORT53CR */
-	PORTCR(54, 0xe6050036), /* PORT54CR */
-	PORTCR(55, 0xe6050037), /* PORT55CR */
-	PORTCR(56, 0xe6050038), /* PORT56CR */
-	PORTCR(57, 0xe6050039), /* PORT57CR */
-	PORTCR(58, 0xe605003a), /* PORT58CR */
-	PORTCR(59, 0xe605003b), /* PORT59CR */
-
-	PORTCR(60, 0xe605003c), /* PORT60CR */
-	PORTCR(61, 0xe605003d), /* PORT61CR */
-	PORTCR(62, 0xe605003e), /* PORT62CR */
-	PORTCR(63, 0xe605003f), /* PORT63CR */
-	PORTCR(64, 0xe6050040), /* PORT64CR */
-	PORTCR(65, 0xe6050041), /* PORT65CR */
-	PORTCR(66, 0xe6050042), /* PORT66CR */
-	PORTCR(67, 0xe6050043), /* PORT67CR */
-	PORTCR(68, 0xe6050044), /* PORT68CR */
-	PORTCR(69, 0xe6050045), /* PORT69CR */
-
-	PORTCR(70, 0xe6050046), /* PORT70CR */
-	PORTCR(71, 0xe6050047), /* PORT71CR */
-	PORTCR(72, 0xe6050048), /* PORT72CR */
-	PORTCR(73, 0xe6050049), /* PORT73CR */
-	PORTCR(74, 0xe605004a), /* PORT74CR */
-	PORTCR(75, 0xe605004b), /* PORT75CR */
-	PORTCR(76, 0xe605004c), /* PORT76CR */
-	PORTCR(77, 0xe605004d), /* PORT77CR */
-	PORTCR(78, 0xe605004e), /* PORT78CR */
-	PORTCR(79, 0xe605004f), /* PORT79CR */
-
-	PORTCR(80, 0xe6050050), /* PORT80CR */
-	PORTCR(81, 0xe6050051), /* PORT81CR */
-	PORTCR(82, 0xe6050052), /* PORT82CR */
-	PORTCR(83, 0xe6050053), /* PORT83CR */
-	PORTCR(84, 0xe6050054), /* PORT84CR */
-	PORTCR(85, 0xe6050055), /* PORT85CR */
-	PORTCR(86, 0xe6050056), /* PORT86CR */
-	PORTCR(87, 0xe6050057), /* PORT87CR */
-	PORTCR(88, 0xe6050058), /* PORT88CR */
-	PORTCR(89, 0xe6050059), /* PORT89CR */
-
-	PORTCR(90, 0xe605005a), /* PORT90CR */
-	PORTCR(91, 0xe605005b), /* PORT91CR */
-	PORTCR(92, 0xe605005c), /* PORT92CR */
-	PORTCR(93, 0xe605005d), /* PORT93CR */
-	PORTCR(94, 0xe605005e), /* PORT94CR */
-	PORTCR(95, 0xe605005f), /* PORT95CR */
-	PORTCR(96, 0xe6050060), /* PORT96CR */
-	PORTCR(97, 0xe6050061), /* PORT97CR */
-	PORTCR(98, 0xe6050062), /* PORT98CR */
-	PORTCR(99, 0xe6050063), /* PORT99CR */
-
-	PORTCR(100, 0xe6050064), /* PORT100CR */
-	PORTCR(101, 0xe6050065), /* PORT101CR */
-	PORTCR(102, 0xe6050066), /* PORT102CR */
-	PORTCR(103, 0xe6050067), /* PORT103CR */
-	PORTCR(104, 0xe6050068), /* PORT104CR */
-	PORTCR(105, 0xe6050069), /* PORT105CR */
-	PORTCR(106, 0xe605006a), /* PORT106CR */
-	PORTCR(107, 0xe605006b), /* PORT107CR */
-	PORTCR(108, 0xe605006c), /* PORT108CR */
-	PORTCR(109, 0xe605006d), /* PORT109CR */
-
-	PORTCR(110, 0xe605006e), /* PORT110CR */
-	PORTCR(111, 0xe605006f), /* PORT111CR */
-	PORTCR(112, 0xe6050070), /* PORT112CR */
-	PORTCR(113, 0xe6050071), /* PORT113CR */
-	PORTCR(114, 0xe6050072), /* PORT114CR */
-	PORTCR(115, 0xe6050073), /* PORT115CR */
-	PORTCR(116, 0xe6050074), /* PORT116CR */
-	PORTCR(117, 0xe6050075), /* PORT117CR */
-	PORTCR(118, 0xe6050076), /* PORT118CR */
-
-	PORTCR(128, 0xe6051080), /* PORT128CR */
-	PORTCR(129, 0xe6051081), /* PORT129CR */
-
-	PORTCR(130, 0xe6051082), /* PORT130CR */
-	PORTCR(131, 0xe6051083), /* PORT131CR */
-	PORTCR(132, 0xe6051084), /* PORT132CR */
-	PORTCR(133, 0xe6051085), /* PORT133CR */
-	PORTCR(134, 0xe6051086), /* PORT134CR */
-	PORTCR(135, 0xe6051087), /* PORT135CR */
-	PORTCR(136, 0xe6051088), /* PORT136CR */
-	PORTCR(137, 0xe6051089), /* PORT137CR */
-	PORTCR(138, 0xe605108a), /* PORT138CR */
-	PORTCR(139, 0xe605108b), /* PORT139CR */
-
-	PORTCR(140, 0xe605108c), /* PORT140CR */
-	PORTCR(141, 0xe605108d), /* PORT141CR */
-	PORTCR(142, 0xe605108e), /* PORT142CR */
-	PORTCR(143, 0xe605108f), /* PORT143CR */
-	PORTCR(144, 0xe6051090), /* PORT144CR */
-	PORTCR(145, 0xe6051091), /* PORT145CR */
-	PORTCR(146, 0xe6051092), /* PORT146CR */
-	PORTCR(147, 0xe6051093), /* PORT147CR */
-	PORTCR(148, 0xe6051094), /* PORT148CR */
-	PORTCR(149, 0xe6051095), /* PORT149CR */
-
-	PORTCR(150, 0xe6051096), /* PORT150CR */
-	PORTCR(151, 0xe6051097), /* PORT151CR */
-	PORTCR(152, 0xe6051098), /* PORT152CR */
-	PORTCR(153, 0xe6051099), /* PORT153CR */
-	PORTCR(154, 0xe605109a), /* PORT154CR */
-	PORTCR(155, 0xe605109b), /* PORT155CR */
-	PORTCR(156, 0xe605109c), /* PORT156CR */
-	PORTCR(157, 0xe605109d), /* PORT157CR */
-	PORTCR(158, 0xe605109e), /* PORT158CR */
-	PORTCR(159, 0xe605109f), /* PORT159CR */
-
-	PORTCR(160, 0xe60510a0), /* PORT160CR */
-	PORTCR(161, 0xe60510a1), /* PORT161CR */
-	PORTCR(162, 0xe60510a2), /* PORT162CR */
-	PORTCR(163, 0xe60510a3), /* PORT163CR */
-	PORTCR(164, 0xe60510a4), /* PORT164CR */
-
-	PORTCR(192, 0xe60520c0), /* PORT192CR */
-	PORTCR(193, 0xe60520c1), /* PORT193CR */
-	PORTCR(194, 0xe60520c2), /* PORT194CR */
-	PORTCR(195, 0xe60520c3), /* PORT195CR */
-	PORTCR(196, 0xe60520c4), /* PORT196CR */
-	PORTCR(197, 0xe60520c5), /* PORT197CR */
-	PORTCR(198, 0xe60520c6), /* PORT198CR */
-	PORTCR(199, 0xe60520c7), /* PORT199CR */
-
-	PORTCR(200, 0xe60520c8), /* PORT200CR */
-	PORTCR(201, 0xe60520c9), /* PORT201CR */
-	PORTCR(202, 0xe60520ca), /* PORT202CR */
-	PORTCR(203, 0xe60520cb), /* PORT203CR */
-	PORTCR(204, 0xe60520cc), /* PORT204CR */
-	PORTCR(205, 0xe60520cd), /* PORT205CR */
-	PORTCR(206, 0xe60520ce), /* PORT206CR */
-	PORTCR(207, 0xe60520cf), /* PORT207CR */
-	PORTCR(208, 0xe60520d0), /* PORT208CR */
-	PORTCR(209, 0xe60520d1), /* PORT209CR */
-
-	PORTCR(210, 0xe60520d2), /* PORT210CR */
-	PORTCR(211, 0xe60520d3), /* PORT211CR */
-	PORTCR(212, 0xe60520d4), /* PORT212CR */
-	PORTCR(213, 0xe60520d5), /* PORT213CR */
-	PORTCR(214, 0xe60520d6), /* PORT214CR */
-	PORTCR(215, 0xe60520d7), /* PORT215CR */
-	PORTCR(216, 0xe60520d8), /* PORT216CR */
-	PORTCR(217, 0xe60520d9), /* PORT217CR */
-	PORTCR(218, 0xe60520da), /* PORT218CR */
-	PORTCR(219, 0xe60520db), /* PORT219CR */
-
-	PORTCR(220, 0xe60520dc), /* PORT220CR */
-	PORTCR(221, 0xe60520dd), /* PORT221CR */
-	PORTCR(222, 0xe60520de), /* PORT222CR */
-	PORTCR(223, 0xe60520df), /* PORT223CR */
-	PORTCR(224, 0xe60520e0), /* PORT224CR */
-	PORTCR(225, 0xe60520e1), /* PORT225CR */
-	PORTCR(226, 0xe60520e2), /* PORT226CR */
-	PORTCR(227, 0xe60520e3), /* PORT227CR */
-	PORTCR(228, 0xe60520e4), /* PORT228CR */
-	PORTCR(229, 0xe60520e5), /* PORT229CR */
-
-	PORTCR(230, 0xe60520e6), /* PORT230CR */
-	PORTCR(231, 0xe60520e7), /* PORT231CR */
-	PORTCR(232, 0xe60520e8), /* PORT232CR */
-	PORTCR(233, 0xe60520e9), /* PORT233CR */
-	PORTCR(234, 0xe60520ea), /* PORT234CR */
-	PORTCR(235, 0xe60520eb), /* PORT235CR */
-	PORTCR(236, 0xe60520ec), /* PORT236CR */
-	PORTCR(237, 0xe60520ed), /* PORT237CR */
-	PORTCR(238, 0xe60520ee), /* PORT238CR */
-	PORTCR(239, 0xe60520ef), /* PORT239CR */
-
-	PORTCR(240, 0xe60520f0), /* PORT240CR */
-	PORTCR(241, 0xe60520f1), /* PORT241CR */
-	PORTCR(242, 0xe60520f2), /* PORT242CR */
-	PORTCR(243, 0xe60520f3), /* PORT243CR */
-	PORTCR(244, 0xe60520f4), /* PORT244CR */
-	PORTCR(245, 0xe60520f5), /* PORT245CR */
-	PORTCR(246, 0xe60520f6), /* PORT246CR */
-	PORTCR(247, 0xe60520f7), /* PORT247CR */
-	PORTCR(248, 0xe60520f8), /* PORT248CR */
-	PORTCR(249, 0xe60520f9), /* PORT249CR */
-
-	PORTCR(250, 0xe60520fa), /* PORT250CR */
-	PORTCR(251, 0xe60520fb), /* PORT251CR */
-	PORTCR(252, 0xe60520fc), /* PORT252CR */
-	PORTCR(253, 0xe60520fd), /* PORT253CR */
-	PORTCR(254, 0xe60520fe), /* PORT254CR */
-	PORTCR(255, 0xe60520ff), /* PORT255CR */
-	PORTCR(256, 0xe6052100), /* PORT256CR */
-	PORTCR(257, 0xe6052101), /* PORT257CR */
-	PORTCR(258, 0xe6052102), /* PORT258CR */
-	PORTCR(259, 0xe6052103), /* PORT259CR */
-
-	PORTCR(260, 0xe6052104), /* PORT260CR */
-	PORTCR(261, 0xe6052105), /* PORT261CR */
-	PORTCR(262, 0xe6052106), /* PORT262CR */
-	PORTCR(263, 0xe6052107), /* PORT263CR */
-	PORTCR(264, 0xe6052108), /* PORT264CR */
-
-	{ PINMUX_CFG_REG("MSELBCR", 0xe6058024, 32, 1) {
-			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-			MSELBCR_MSEL17_0, MSELBCR_MSEL17_1,
-			MSELBCR_MSEL16_0, MSELBCR_MSEL16_1,
-			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-	},
-	{ },
-};
-
-static struct pinmux_data_reg pinmux_data_regs[] = {
-	{ PINMUX_DATA_REG("PORTL031_000DR", 0xe6054000, 32) {
-			PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
-			PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
-			PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
-			PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
-			PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
-			PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
-			PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
-			PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTL063_032DR", 0xe6054004, 32) {
-			PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
-			PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
-			PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
-			PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
-			PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA,
-			PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
-			PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
-			PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTL095_064DR", 0xe6054008, 32) {
-			PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
-			PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
-			PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
-			PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
-			PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
-			PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
-			PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
-			PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTD127_096DR", 0xe605400C, 32) {
-			0, 0, 0, 0,
-			0, 0, 0, 0,
-			0, PORT118_DATA, PORT117_DATA, PORT116_DATA,
-			PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
-			PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
-			PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
-			PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
-			PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTD159_128DR", 0xe6055000, 32) {
-			PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
-			PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
-			PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
-			PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
-			PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
-			PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
-			PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
-			PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTR191_160DR", 0xe6055004, 32) {
-			0, 0, 0, 0,
-			0, 0, 0, 0,
-			0, 0, 0, 0,
-			0, 0, 0, 0,
-			0, 0, 0, 0,
-			0, 0, 0, 0,
-			0, 0, 0, PORT164_DATA,
-			PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTR223_192DR", 0xe6056000, 32) {
-			PORT223_DATA, PORT222_DATA, PORT221_DATA, PORT220_DATA,
-			PORT219_DATA, PORT218_DATA, PORT217_DATA, PORT216_DATA,
-			PORT215_DATA, PORT214_DATA, PORT213_DATA, PORT212_DATA,
-			PORT211_DATA, PORT210_DATA, PORT209_DATA, PORT208_DATA,
-			PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA,
-			PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA,
-			PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA,
-			PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTU255_224DR", 0xe6056004, 32) {
-			PORT255_DATA, PORT254_DATA, PORT253_DATA, PORT252_DATA,
-			PORT251_DATA, PORT250_DATA, PORT249_DATA, PORT248_DATA,
-			PORT247_DATA, PORT246_DATA, PORT245_DATA, PORT244_DATA,
-			PORT243_DATA, PORT242_DATA, PORT241_DATA, PORT240_DATA,
-			PORT239_DATA, PORT238_DATA, PORT237_DATA, PORT236_DATA,
-			PORT235_DATA, PORT234_DATA, PORT233_DATA, PORT232_DATA,
-			PORT231_DATA, PORT230_DATA, PORT229_DATA, PORT228_DATA,
-			PORT227_DATA, PORT226_DATA, PORT225_DATA, PORT224_DATA }
-	},
-	{ PINMUX_DATA_REG("PORTU287_256DR", 0xe6056008, 32) {
-			0, 0, 0, 0,
-			0, 0, 0, 0,
-			0, 0, 0, 0,
-			0, 0, 0, 0,
-			0, 0, 0, 0,
-			0, 0, 0, PORT264_DATA,
-			PORT263_DATA, PORT262_DATA, PORT261_DATA, PORT260_DATA,
-			PORT259_DATA, PORT258_DATA, PORT257_DATA, PORT256_DATA }
-	},
-	{ },
-};
-
-static struct pinmux_info sh7377_pinmux_info = {
-	.name = "sh7377_pfc",
-	.reserved_id = PINMUX_RESERVED,
-	.data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
-	.input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
-	.input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
-	.input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END },
-	.output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
-	.mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
-	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
-
-	.first_gpio = GPIO_PORT0,
-	.last_gpio = GPIO_FN_RESETOUTS,
-
-	.gpios = pinmux_gpios,
-	.cfg_regs = pinmux_config_regs,
-	.data_regs = pinmux_data_regs,
-
-	.gpio_data = pinmux_data,
-	.gpio_data_size = ARRAY_SIZE(pinmux_data),
-};
-
-void sh7377_pinmux_init(void)
-{
-	register_pinmux(&sh7377_pinmux_info);
-}
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 11bb1d9..6ac242c 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -590,6 +590,21 @@
 	.num_resources	= ARRAY_SIZE(i2c1_resources),
 };
 
+static struct resource pmu_resources[] = {
+	[0] = {
+		.start	= evt2irq(0x19a0),
+		.end	= evt2irq(0x19a0),
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device pmu_device = {
+	.name	= "arm-pmu",
+	.id	= -1,
+	.num_resources = ARRAY_SIZE(pmu_resources),
+	.resource = pmu_resources,
+};
+
 static struct platform_device *r8a7740_late_devices[] __initdata = {
 	&i2c0_device,
 	&i2c1_device,
@@ -597,6 +612,7 @@
 	&dma1_device,
 	&dma2_device,
 	&usb_dma_device,
+	&pmu_device,
 };
 
 /*
@@ -747,7 +763,7 @@
 	NULL,
 };
 
-DT_MACHINE_START(SH7372_DT, "Generic R8A7740 (Flattened Device Tree)")
+DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)")
 	.map_io		= r8a7740_map_io,
 	.init_early	= r8a7740_add_early_devices_dt,
 	.init_irq	= r8a7740_init_irq,
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 2917668..7a1ad4f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -229,6 +229,79 @@
 	.num_resources	= ARRAY_SIZE(tmu01_resources),
 };
 
+/* I2C */
+static struct resource rcar_i2c0_res[] = {
+	{
+		.start  = 0xffc70000,
+		.end    = 0xffc70fff,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.start  = gic_spi(79),
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device i2c0_device = {
+	.name		= "i2c-rcar",
+	.id		= 0,
+	.resource	= rcar_i2c0_res,
+	.num_resources	= ARRAY_SIZE(rcar_i2c0_res),
+};
+
+static struct resource rcar_i2c1_res[] = {
+	{
+		.start  = 0xffc71000,
+		.end    = 0xffc71fff,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.start  = gic_spi(82),
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device i2c1_device = {
+	.name		= "i2c-rcar",
+	.id		= 1,
+	.resource	= rcar_i2c1_res,
+	.num_resources	= ARRAY_SIZE(rcar_i2c1_res),
+};
+
+static struct resource rcar_i2c2_res[] = {
+	{
+		.start  = 0xffc72000,
+		.end    = 0xffc72fff,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.start  = gic_spi(80),
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device i2c2_device = {
+	.name		= "i2c-rcar",
+	.id		= 2,
+	.resource	= rcar_i2c2_res,
+	.num_resources	= ARRAY_SIZE(rcar_i2c2_res),
+};
+
+static struct resource rcar_i2c3_res[] = {
+	{
+		.start  = 0xffc73000,
+		.end    = 0xffc73fff,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.start  = gic_spi(81),
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device i2c3_device = {
+	.name		= "i2c-rcar",
+	.id		= 3,
+	.resource	= rcar_i2c3_res,
+	.num_resources	= ARRAY_SIZE(rcar_i2c3_res),
+};
+
 static struct platform_device *r8a7779_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
@@ -238,6 +311,10 @@
 	&scif5_device,
 	&tmu00_device,
 	&tmu01_device,
+	&i2c0_device,
+	&i2c1_device,
+	&i2c2_device,
+	&i2c3_device,
 };
 
 static struct platform_device *r8a7779_late_devices[] __initdata = {
@@ -247,7 +324,7 @@
 {
 #ifdef CONFIG_CACHE_L2X0
 	/* Early BRESP enable, Shared attribute override enable, 64K*16way */
-	l2x0_init((void __iomem __force *)(0xf0100000), 0x40470000, 0x82000fff);
+	l2x0_init(IOMEM(0xf0100000), 0x40470000, 0x82000fff);
 #endif
 	r8a7779_pm_init();
 
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
deleted file mode 100644
index e647f54..0000000
--- a/arch/arm/mach-shmobile/setup-sh7367.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * sh7367 processor support
- *
- * Copyright (C) 2010  Magnus Damm
- * Copyright (C) 2008  Yoshihiro Shimoda
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-#include <linux/uio_driver.h>
-#include <linux/delay.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/serial_sci.h>
-#include <linux/sh_timer.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/irqs.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/time.h>
-
-static struct map_desc sh7367_io_desc[] __initdata = {
-	/* create a 1:1 entity map for 0xe6xxxxxx
-	 * used by CPGA, INTC and PFC.
-	 */
-	{
-		.virtual	= 0xe6000000,
-		.pfn		= __phys_to_pfn(0xe6000000),
-		.length		= 256 << 20,
-		.type		= MT_DEVICE_NONSHARED
-	},
-};
-
-void __init sh7367_map_io(void)
-{
-	iotable_init(sh7367_io_desc, ARRAY_SIZE(sh7367_io_desc));
-}
-
-/* SCIFA0 */
-static struct plat_sci_port scif0_platform_data = {
-	.mapbase	= 0xe6c40000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xc00), evt2irq(0xc00),
-			    evt2irq(0xc00), evt2irq(0xc00) },
-};
-
-static struct platform_device scif0_device = {
-	.name		= "sh-sci",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &scif0_platform_data,
-	},
-};
-
-/* SCIFA1 */
-static struct plat_sci_port scif1_platform_data = {
-	.mapbase	= 0xe6c50000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xc20), evt2irq(0xc20),
-			    evt2irq(0xc20), evt2irq(0xc20) },
-};
-
-static struct platform_device scif1_device = {
-	.name		= "sh-sci",
-	.id		= 1,
-	.dev		= {
-		.platform_data	= &scif1_platform_data,
-	},
-};
-
-/* SCIFA2 */
-static struct plat_sci_port scif2_platform_data = {
-	.mapbase	= 0xe6c60000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xc40), evt2irq(0xc40),
-			    evt2irq(0xc40), evt2irq(0xc40) },
-};
-
-static struct platform_device scif2_device = {
-	.name		= "sh-sci",
-	.id		= 2,
-	.dev		= {
-		.platform_data	= &scif2_platform_data,
-	},
-};
-
-/* SCIFA3 */
-static struct plat_sci_port scif3_platform_data = {
-	.mapbase	= 0xe6c70000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xc60), evt2irq(0xc60),
-			    evt2irq(0xc60), evt2irq(0xc60) },
-};
-
-static struct platform_device scif3_device = {
-	.name		= "sh-sci",
-	.id		= 3,
-	.dev		= {
-		.platform_data	= &scif3_platform_data,
-	},
-};
-
-/* SCIFA4 */
-static struct plat_sci_port scif4_platform_data = {
-	.mapbase	= 0xe6c80000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xd20), evt2irq(0xd20),
-			    evt2irq(0xd20), evt2irq(0xd20) },
-};
-
-static struct platform_device scif4_device = {
-	.name		= "sh-sci",
-	.id		= 4,
-	.dev		= {
-		.platform_data	= &scif4_platform_data,
-	},
-};
-
-/* SCIFA5 */
-static struct plat_sci_port scif5_platform_data = {
-	.mapbase	= 0xe6cb0000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xd40), evt2irq(0xd40),
-			    evt2irq(0xd40), evt2irq(0xd40) },
-};
-
-static struct platform_device scif5_device = {
-	.name		= "sh-sci",
-	.id		= 5,
-	.dev		= {
-		.platform_data	= &scif5_platform_data,
-	},
-};
-
-/* SCIFB */
-static struct plat_sci_port scif6_platform_data = {
-	.mapbase	= 0xe6c30000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFB,
-	.irqs		= { evt2irq(0xd60), evt2irq(0xd60),
-			    evt2irq(0xd60), evt2irq(0xd60) },
-};
-
-static struct platform_device scif6_device = {
-	.name		= "sh-sci",
-	.id		= 6,
-	.dev		= {
-		.platform_data	= &scif6_platform_data,
-	},
-};
-
-static struct sh_timer_config cmt10_platform_data = {
-	.name = "CMT10",
-	.channel_offset = 0x10,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
-};
-
-static struct resource cmt10_resources[] = {
-	[0] = {
-		.name	= "CMT10",
-		.start	= 0xe6138010,
-		.end	= 0xe613801b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xb00), /* CMT1_CMT10 */
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt10_device = {
-	.name		= "sh_cmt",
-	.id		= 10,
-	.dev = {
-		.platform_data	= &cmt10_platform_data,
-	},
-	.resource	= cmt10_resources,
-	.num_resources	= ARRAY_SIZE(cmt10_resources),
-};
-
-/* VPU */
-static struct uio_info vpu_platform_data = {
-	.name = "VPU5",
-	.version = "0",
-	.irq = intcs_evt2irq(0x980),
-};
-
-static struct resource vpu_resources[] = {
-	[0] = {
-		.name	= "VPU",
-		.start	= 0xfe900000,
-		.end	= 0xfe902807,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device vpu_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &vpu_platform_data,
-	},
-	.resource	= vpu_resources,
-	.num_resources	= ARRAY_SIZE(vpu_resources),
-};
-
-/* VEU0 */
-static struct uio_info veu0_platform_data = {
-	.name = "VEU0",
-	.version = "0",
-	.irq = intcs_evt2irq(0x700),
-};
-
-static struct resource veu0_resources[] = {
-	[0] = {
-		.name	= "VEU0",
-		.start	= 0xfe920000,
-		.end	= 0xfe9200b7,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device veu0_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 1,
-	.dev = {
-		.platform_data	= &veu0_platform_data,
-	},
-	.resource	= veu0_resources,
-	.num_resources	= ARRAY_SIZE(veu0_resources),
-};
-
-/* VEU1 */
-static struct uio_info veu1_platform_data = {
-	.name = "VEU1",
-	.version = "0",
-	.irq = intcs_evt2irq(0x720),
-};
-
-static struct resource veu1_resources[] = {
-	[0] = {
-		.name	= "VEU1",
-		.start	= 0xfe924000,
-		.end	= 0xfe9240b7,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device veu1_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 2,
-	.dev = {
-		.platform_data	= &veu1_platform_data,
-	},
-	.resource	= veu1_resources,
-	.num_resources	= ARRAY_SIZE(veu1_resources),
-};
-
-/* VEU2 */
-static struct uio_info veu2_platform_data = {
-	.name = "VEU2",
-	.version = "0",
-	.irq = intcs_evt2irq(0x740),
-};
-
-static struct resource veu2_resources[] = {
-	[0] = {
-		.name	= "VEU2",
-		.start	= 0xfe928000,
-		.end	= 0xfe9280b7,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device veu2_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 3,
-	.dev = {
-		.platform_data	= &veu2_platform_data,
-	},
-	.resource	= veu2_resources,
-	.num_resources	= ARRAY_SIZE(veu2_resources),
-};
-
-/* VEU3 */
-static struct uio_info veu3_platform_data = {
-	.name = "VEU3",
-	.version = "0",
-	.irq = intcs_evt2irq(0x760),
-};
-
-static struct resource veu3_resources[] = {
-	[0] = {
-		.name	= "VEU3",
-		.start	= 0xfe92c000,
-		.end	= 0xfe92c0b7,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device veu3_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 4,
-	.dev = {
-		.platform_data	= &veu3_platform_data,
-	},
-	.resource	= veu3_resources,
-	.num_resources	= ARRAY_SIZE(veu3_resources),
-};
-
-/* VEU2H */
-static struct uio_info veu2h_platform_data = {
-	.name = "VEU2H",
-	.version = "0",
-	.irq = intcs_evt2irq(0x520),
-};
-
-static struct resource veu2h_resources[] = {
-	[0] = {
-		.name	= "VEU2H",
-		.start	= 0xfe93c000,
-		.end	= 0xfe93c27b,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device veu2h_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 5,
-	.dev = {
-		.platform_data	= &veu2h_platform_data,
-	},
-	.resource	= veu2h_resources,
-	.num_resources	= ARRAY_SIZE(veu2h_resources),
-};
-
-/* JPU */
-static struct uio_info jpu_platform_data = {
-	.name = "JPU",
-	.version = "0",
-	.irq = intcs_evt2irq(0x560),
-};
-
-static struct resource jpu_resources[] = {
-	[0] = {
-		.name	= "JPU",
-		.start	= 0xfe980000,
-		.end	= 0xfe9902d3,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device jpu_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 6,
-	.dev = {
-		.platform_data	= &jpu_platform_data,
-	},
-	.resource	= jpu_resources,
-	.num_resources	= ARRAY_SIZE(jpu_resources),
-};
-
-/* SPU1 */
-static struct uio_info spu1_platform_data = {
-	.name = "SPU1",
-	.version = "0",
-	.irq = evt2irq(0xfc0),
-};
-
-static struct resource spu1_resources[] = {
-	[0] = {
-		.name	= "SPU1",
-		.start	= 0xfe300000,
-		.end	= 0xfe3fffff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device spu1_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 7,
-	.dev = {
-		.platform_data	= &spu1_platform_data,
-	},
-	.resource	= spu1_resources,
-	.num_resources	= ARRAY_SIZE(spu1_resources),
-};
-
-static struct platform_device *sh7367_early_devices[] __initdata = {
-	&scif0_device,
-	&scif1_device,
-	&scif2_device,
-	&scif3_device,
-	&scif4_device,
-	&scif5_device,
-	&scif6_device,
-	&cmt10_device,
-};
-
-static struct platform_device *sh7367_devices[] __initdata = {
-	&vpu_device,
-	&veu0_device,
-	&veu1_device,
-	&veu2_device,
-	&veu3_device,
-	&veu2h_device,
-	&jpu_device,
-	&spu1_device,
-};
-
-void __init sh7367_add_standard_devices(void)
-{
-	platform_add_devices(sh7367_early_devices,
-			     ARRAY_SIZE(sh7367_early_devices));
-
-	platform_add_devices(sh7367_devices,
-			    ARRAY_SIZE(sh7367_devices));
-}
-
-static void __init sh7367_earlytimer_init(void)
-{
-	sh7367_clock_init();
-	shmobile_earlytimer_init();
-}
-
-#define SYMSTPCR2 IOMEM(0xe6158048)
-#define SYMSTPCR2_CMT1 (1 << 29)
-
-void __init sh7367_add_early_devices(void)
-{
-	/* enable clock to CMT1 */
-	__raw_writel(__raw_readl(SYMSTPCR2) & ~SYMSTPCR2_CMT1, SYMSTPCR2);
-
-	early_platform_add_devices(sh7367_early_devices,
-				   ARRAY_SIZE(sh7367_early_devices));
-
-	/* setup early console here as well */
-	shmobile_setup_console();
-
-	/* override timer setup with soc-specific code */
-	shmobile_timer.init = sh7367_earlytimer_init;
-}
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index a07954f..a360111 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -408,6 +408,26 @@
 		.chcr		= CHCR_RX(XMIT_SZ_8BIT),
 		.mid_rid	= 0x3e,
 	}, {
+		.slave_id	= SHDMA_SLAVE_FLCTL0_TX,
+		.addr		= 0xe6a30050,
+		.chcr		= CHCR_TX(XMIT_SZ_32BIT),
+		.mid_rid	= 0x83,
+	}, {
+		.slave_id	= SHDMA_SLAVE_FLCTL0_RX,
+		.addr		= 0xe6a30050,
+		.chcr		= CHCR_RX(XMIT_SZ_32BIT),
+		.mid_rid	= 0x83,
+	}, {
+		.slave_id	= SHDMA_SLAVE_FLCTL1_TX,
+		.addr		= 0xe6a30060,
+		.chcr		= CHCR_TX(XMIT_SZ_32BIT),
+		.mid_rid	= 0x87,
+	}, {
+		.slave_id	= SHDMA_SLAVE_FLCTL1_RX,
+		.addr		= 0xe6a30060,
+		.chcr		= CHCR_RX(XMIT_SZ_32BIT),
+		.mid_rid	= 0x87,
+	}, {
 		.slave_id	= SHDMA_SLAVE_SDHI0_TX,
 		.addr		= 0xe6850030,
 		.chcr		= CHCR_TX(XMIT_SZ_16BIT),
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
deleted file mode 100644
index edcf98b..0000000
--- a/arch/arm/mach-shmobile/setup-sh7377.c
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * sh7377 processor support
- *
- * Copyright (C) 2010  Magnus Damm
- * Copyright (C) 2008  Yoshihiro Shimoda
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-#include <linux/of_platform.h>
-#include <linux/uio_driver.h>
-#include <linux/delay.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/serial_sci.h>
-#include <linux/sh_intc.h>
-#include <linux/sh_timer.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <asm/mach/map.h>
-#include <mach/irqs.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-
-static struct map_desc sh7377_io_desc[] __initdata = {
-	/* create a 1:1 entity map for 0xe6xxxxxx
-	 * used by CPGA, INTC and PFC.
-	 */
-	{
-		.virtual	= 0xe6000000,
-		.pfn		= __phys_to_pfn(0xe6000000),
-		.length		= 256 << 20,
-		.type		= MT_DEVICE_NONSHARED
-	},
-};
-
-void __init sh7377_map_io(void)
-{
-	iotable_init(sh7377_io_desc, ARRAY_SIZE(sh7377_io_desc));
-}
-
-/* SCIFA0 */
-static struct plat_sci_port scif0_platform_data = {
-	.mapbase	= 0xe6c40000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xc00), evt2irq(0xc00),
-			    evt2irq(0xc00), evt2irq(0xc00) },
-};
-
-static struct platform_device scif0_device = {
-	.name		= "sh-sci",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &scif0_platform_data,
-	},
-};
-
-/* SCIFA1 */
-static struct plat_sci_port scif1_platform_data = {
-	.mapbase	= 0xe6c50000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xc20), evt2irq(0xc20),
-			    evt2irq(0xc20), evt2irq(0xc20) },
-};
-
-static struct platform_device scif1_device = {
-	.name		= "sh-sci",
-	.id		= 1,
-	.dev		= {
-		.platform_data	= &scif1_platform_data,
-	},
-};
-
-/* SCIFA2 */
-static struct plat_sci_port scif2_platform_data = {
-	.mapbase	= 0xe6c60000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xc40), evt2irq(0xc40),
-			    evt2irq(0xc40), evt2irq(0xc40) },
-};
-
-static struct platform_device scif2_device = {
-	.name		= "sh-sci",
-	.id		= 2,
-	.dev		= {
-		.platform_data	= &scif2_platform_data,
-	},
-};
-
-/* SCIFA3 */
-static struct plat_sci_port scif3_platform_data = {
-	.mapbase	= 0xe6c70000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xc60), evt2irq(0xc60),
-			    evt2irq(0xc60), evt2irq(0xc60) },
-};
-
-static struct platform_device scif3_device = {
-	.name		= "sh-sci",
-	.id		= 3,
-	.dev		= {
-		.platform_data	= &scif3_platform_data,
-	},
-};
-
-/* SCIFA4 */
-static struct plat_sci_port scif4_platform_data = {
-	.mapbase	= 0xe6c80000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xd20), evt2irq(0xd20),
-			    evt2irq(0xd20), evt2irq(0xd20) },
-};
-
-static struct platform_device scif4_device = {
-	.name		= "sh-sci",
-	.id		= 4,
-	.dev		= {
-		.platform_data	= &scif4_platform_data,
-	},
-};
-
-/* SCIFA5 */
-static struct plat_sci_port scif5_platform_data = {
-	.mapbase	= 0xe6cb0000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { evt2irq(0xd40), evt2irq(0xd40),
-			    evt2irq(0xd40), evt2irq(0xd40) },
-};
-
-static struct platform_device scif5_device = {
-	.name		= "sh-sci",
-	.id		= 5,
-	.dev		= {
-		.platform_data	= &scif5_platform_data,
-	},
-};
-
-/* SCIFA6 */
-static struct plat_sci_port scif6_platform_data = {
-	.mapbase	= 0xe6cc0000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFA,
-	.irqs		= { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80),
-			    intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) },
-};
-
-static struct platform_device scif6_device = {
-	.name		= "sh-sci",
-	.id		= 6,
-	.dev		= {
-		.platform_data	= &scif6_platform_data,
-	},
-};
-
-/* SCIFB */
-static struct plat_sci_port scif7_platform_data = {
-	.mapbase	= 0xe6c30000,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.scscr		= SCSCR_RE | SCSCR_TE,
-	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIFB,
-	.irqs		= { evt2irq(0xd60), evt2irq(0xd60),
-			    evt2irq(0xd60), evt2irq(0xd60) },
-};
-
-static struct platform_device scif7_device = {
-	.name		= "sh-sci",
-	.id		= 7,
-	.dev		= {
-		.platform_data	= &scif7_platform_data,
-	},
-};
-
-static struct sh_timer_config cmt10_platform_data = {
-	.name = "CMT10",
-	.channel_offset = 0x10,
-	.timer_bit = 0,
-	.clockevent_rating = 125,
-	.clocksource_rating = 125,
-};
-
-static struct resource cmt10_resources[] = {
-	[0] = {
-		.name	= "CMT10",
-		.start	= 0xe6138010,
-		.end	= 0xe613801b,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0xb00), /* CMT1_CMT10 */
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device cmt10_device = {
-	.name		= "sh_cmt",
-	.id		= 10,
-	.dev = {
-		.platform_data	= &cmt10_platform_data,
-	},
-	.resource	= cmt10_resources,
-	.num_resources	= ARRAY_SIZE(cmt10_resources),
-};
-
-/* VPU */
-static struct uio_info vpu_platform_data = {
-	.name = "VPU5HG",
-	.version = "0",
-	.irq = intcs_evt2irq(0x980),
-};
-
-static struct resource vpu_resources[] = {
-	[0] = {
-		.name	= "VPU",
-		.start	= 0xfe900000,
-		.end	= 0xfe900157,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device vpu_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &vpu_platform_data,
-	},
-	.resource	= vpu_resources,
-	.num_resources	= ARRAY_SIZE(vpu_resources),
-};
-
-/* VEU0 */
-static struct uio_info veu0_platform_data = {
-	.name = "VEU0",
-	.version = "0",
-	.irq = intcs_evt2irq(0x700),
-};
-
-static struct resource veu0_resources[] = {
-	[0] = {
-		.name	= "VEU0",
-		.start	= 0xfe920000,
-		.end	= 0xfe9200cb,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device veu0_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 1,
-	.dev = {
-		.platform_data	= &veu0_platform_data,
-	},
-	.resource	= veu0_resources,
-	.num_resources	= ARRAY_SIZE(veu0_resources),
-};
-
-/* VEU1 */
-static struct uio_info veu1_platform_data = {
-	.name = "VEU1",
-	.version = "0",
-	.irq = intcs_evt2irq(0x720),
-};
-
-static struct resource veu1_resources[] = {
-	[0] = {
-		.name	= "VEU1",
-		.start	= 0xfe924000,
-		.end	= 0xfe9240cb,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device veu1_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 2,
-	.dev = {
-		.platform_data	= &veu1_platform_data,
-	},
-	.resource	= veu1_resources,
-	.num_resources	= ARRAY_SIZE(veu1_resources),
-};
-
-/* VEU2 */
-static struct uio_info veu2_platform_data = {
-	.name = "VEU2",
-	.version = "0",
-	.irq = intcs_evt2irq(0x740),
-};
-
-static struct resource veu2_resources[] = {
-	[0] = {
-		.name	= "VEU2",
-		.start	= 0xfe928000,
-		.end	= 0xfe928307,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device veu2_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 3,
-	.dev = {
-		.platform_data	= &veu2_platform_data,
-	},
-	.resource	= veu2_resources,
-	.num_resources	= ARRAY_SIZE(veu2_resources),
-};
-
-/* VEU3 */
-static struct uio_info veu3_platform_data = {
-	.name = "VEU3",
-	.version = "0",
-	.irq = intcs_evt2irq(0x760),
-};
-
-static struct resource veu3_resources[] = {
-	[0] = {
-		.name	= "VEU3",
-		.start	= 0xfe92c000,
-		.end	= 0xfe92c307,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device veu3_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 4,
-	.dev = {
-		.platform_data	= &veu3_platform_data,
-	},
-	.resource	= veu3_resources,
-	.num_resources	= ARRAY_SIZE(veu3_resources),
-};
-
-/* JPU */
-static struct uio_info jpu_platform_data = {
-	.name = "JPU",
-	.version = "0",
-	.irq = intcs_evt2irq(0x560),
-};
-
-static struct resource jpu_resources[] = {
-	[0] = {
-		.name	= "JPU",
-		.start	= 0xfe980000,
-		.end	= 0xfe9902d3,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device jpu_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 5,
-	.dev = {
-		.platform_data	= &jpu_platform_data,
-	},
-	.resource	= jpu_resources,
-	.num_resources	= ARRAY_SIZE(jpu_resources),
-};
-
-/* SPU2DSP0 */
-static struct uio_info spu0_platform_data = {
-	.name = "SPU2DSP0",
-	.version = "0",
-	.irq = evt2irq(0x1800),
-};
-
-static struct resource spu0_resources[] = {
-	[0] = {
-		.name	= "SPU2DSP0",
-		.start	= 0xfe200000,
-		.end	= 0xfe2fffff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device spu0_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 6,
-	.dev = {
-		.platform_data	= &spu0_platform_data,
-	},
-	.resource	= spu0_resources,
-	.num_resources	= ARRAY_SIZE(spu0_resources),
-};
-
-/* SPU2DSP1 */
-static struct uio_info spu1_platform_data = {
-	.name = "SPU2DSP1",
-	.version = "0",
-	.irq = evt2irq(0x1820),
-};
-
-static struct resource spu1_resources[] = {
-	[0] = {
-		.name	= "SPU2DSP1",
-		.start	= 0xfe300000,
-		.end	= 0xfe3fffff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device spu1_device = {
-	.name		= "uio_pdrv_genirq",
-	.id		= 7,
-	.dev = {
-		.platform_data	= &spu1_platform_data,
-	},
-	.resource	= spu1_resources,
-	.num_resources	= ARRAY_SIZE(spu1_resources),
-};
-
-static struct platform_device *sh7377_early_devices[] __initdata = {
-	&scif0_device,
-	&scif1_device,
-	&scif2_device,
-	&scif3_device,
-	&scif4_device,
-	&scif5_device,
-	&scif6_device,
-	&scif7_device,
-	&cmt10_device,
-};
-
-static struct platform_device *sh7377_devices[] __initdata = {
-	&vpu_device,
-	&veu0_device,
-	&veu1_device,
-	&veu2_device,
-	&veu3_device,
-	&jpu_device,
-	&spu0_device,
-	&spu1_device,
-};
-
-void __init sh7377_add_standard_devices(void)
-{
-	platform_add_devices(sh7377_early_devices,
-			    ARRAY_SIZE(sh7377_early_devices));
-
-	platform_add_devices(sh7377_devices,
-			    ARRAY_SIZE(sh7377_devices));
-}
-
-static void __init sh7377_earlytimer_init(void)
-{
-	sh7377_clock_init();
-	shmobile_earlytimer_init();
-}
-
-#define SMSTPCR3 IOMEM(0xe615013c)
-#define SMSTPCR3_CMT1 (1 << 29)
-
-void __init sh7377_add_early_devices(void)
-{
-	/* enable clock to CMT1 */
-	__raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3);
-
-	early_platform_add_devices(sh7377_early_devices,
-				   ARRAY_SIZE(sh7377_early_devices));
-
-	/* setup early console here as well */
-	shmobile_setup_console();
-
-	/* override timer setup with soc-specific code */
-	shmobile_timer.init = sh7377_earlytimer_init;
-}
-
-#ifdef CONFIG_USE_OF
-
-void __init sh7377_add_early_devices_dt(void)
-{
-	shmobile_setup_delay(600, 1, 3); /* Cortex-A8 @ 600MHz */
-
-	early_platform_add_devices(sh7377_early_devices,
-				   ARRAY_SIZE(sh7377_early_devices));
-
-	/* setup early console here as well */
-	shmobile_setup_console();
-}
-
-static const struct of_dev_auxdata sh7377_auxdata_lookup[] __initconst = {
-	{ }
-};
-
-void __init sh7377_add_standard_devices_dt(void)
-{
-	/* clocks are setup late during boot in the case of DT */
-	sh7377_clock_init();
-
-	platform_add_devices(sh7377_early_devices,
-			    ARRAY_SIZE(sh7377_early_devices));
-
-	of_platform_populate(NULL, of_default_bus_match_table,
-			     sh7377_auxdata_lookup, NULL);
-}
-
-static const char *sh7377_boards_compat_dt[] __initdata = {
-	"renesas,sh7377",
-	NULL,
-};
-
-DT_MACHINE_START(SH7377_DT, "Generic SH7377 (Flattened Device Tree)")
-	.map_io		= sh7377_map_io,
-	.init_early	= sh7377_add_early_devices_dt,
-	.init_irq	= sh7377_init_irq,
-	.handle_irq	= shmobile_handle_irq_intc,
-	.init_machine	= sh7377_add_standard_devices_dt,
-	.timer		= &shmobile_timer,
-	.dt_compat	= sh7377_boards_compat_dt,
-MACHINE_END
-
-#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c
index f674562..535426c 100644
--- a/arch/arm/mach-shmobile/smp-emev2.c
+++ b/arch/arm/mach-shmobile/smp-emev2.c
@@ -32,24 +32,8 @@
 
 #define EMEV2_SCU_BASE 0x1e000000
 
-static DEFINE_SPINLOCK(scu_lock);
 static void __iomem *scu_base;
 
-static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
-{
-	unsigned long tmp;
-
-	/* we assume this code is running on a different cpu
-	 * than the one that is changing coherency setting */
-	spin_lock(&scu_lock);
-	tmp = readl(scu_base + 8);
-	tmp &= ~clr;
-	tmp |= set;
-	writel(tmp, scu_base + 8);
-	spin_unlock(&scu_lock);
-
-}
-
 static unsigned int __init emev2_get_core_count(void)
 {
 	if (!scu_base) {
@@ -95,7 +79,7 @@
 	cpu = cpu_logical_map(cpu);
 
 	/* enable cache coherency */
-	modify_scu_cpu_psr(0, 3 << (cpu * 8));
+	scu_power_mode(scu_base, 0);
 
 	/* Tell ROM loader about our vector (in headsmp.S) */
 	emev2_set_boot_vector(__pa(shmobile_secondary_vector));
@@ -106,12 +90,10 @@
 
 static void __init emev2_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int cpu = cpu_logical_map(0);
-
 	scu_enable(scu_base);
 
 	/* enable cache coherency on CPU0 */
-	modify_scu_cpu_psr(0, 3 << (cpu * 8));
+	scu_power_mode(scu_base, 0);
 }
 
 static void __init emev2_smp_init_cpus(void)
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
index 2ce6af9..9def0f2 100644
--- a/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -61,9 +61,6 @@
 	return (void __iomem *)0xf0000000;
 }
 
-static DEFINE_SPINLOCK(scu_lock);
-static unsigned long tmp;
-
 #ifdef CONFIG_HAVE_ARM_TWD
 static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
 
@@ -73,20 +70,6 @@
 }
 #endif
 
-static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
-{
-	void __iomem *scu_base = scu_base_addr();
-
-	spin_lock(&scu_lock);
-	tmp = __raw_readl(scu_base + 8);
-	tmp &= ~clr;
-	tmp |= set;
-	spin_unlock(&scu_lock);
-
-	/* disable cache coherency after releasing the lock */
-	__raw_writel(tmp, scu_base + 8);
-}
-
 static unsigned int __init r8a7779_get_core_count(void)
 {
 	void __iomem *scu_base = scu_base_addr();
@@ -102,7 +85,7 @@
 	cpu = cpu_logical_map(cpu);
 
 	/* disable cache coherency */
-	modify_scu_cpu_psr(3 << (cpu * 8), 0);
+	scu_power_mode(scu_base_addr(), 3);
 
 	if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
 		ch = r8a7779_ch_cpu[cpu];
@@ -145,7 +128,7 @@
 	cpu = cpu_logical_map(cpu);
 
 	/* enable cache coherency */
-	modify_scu_cpu_psr(0, 3 << (cpu * 8));
+	scu_power_mode(scu_base_addr(), 0);
 
 	if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
 		ch = r8a7779_ch_cpu[cpu];
@@ -158,15 +141,13 @@
 
 static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int cpu = cpu_logical_map(0);
-
 	scu_enable(scu_base_addr());
 
 	/* Map the reset vector (in headsmp.S) */
 	__raw_writel(__pa(shmobile_secondary_vector), AVECR);
 
 	/* enable cache coherency on CPU0 */
-	modify_scu_cpu_psr(0, 3 << (cpu * 8));
+	scu_power_mode(scu_base_addr(), 0);
 
 	r8a7779_pm_init();
 
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index 624f00f..96ddb97 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -41,9 +41,6 @@
 	return (void __iomem *)0xf0000000;
 }
 
-static DEFINE_SPINLOCK(scu_lock);
-static unsigned long tmp;
-
 #ifdef CONFIG_HAVE_ARM_TWD
 static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
 void __init sh73a0_register_twd(void)
@@ -52,20 +49,6 @@
 }
 #endif
 
-static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
-{
-	void __iomem *scu_base = scu_base_addr();
-
-	spin_lock(&scu_lock);
-	tmp = __raw_readl(scu_base + 8);
-	tmp &= ~clr;
-	tmp |= set;
-	spin_unlock(&scu_lock);
-
-	/* disable cache coherency after releasing the lock */
-	__raw_writel(tmp, scu_base + 8);
-}
-
 static unsigned int __init sh73a0_get_core_count(void)
 {
 	void __iomem *scu_base = scu_base_addr();
@@ -83,7 +66,7 @@
 	cpu = cpu_logical_map(cpu);
 
 	/* enable cache coherency */
-	modify_scu_cpu_psr(0, 3 << (cpu * 8));
+	scu_power_mode(scu_base_addr(), 0);
 
 	if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3)
 		__raw_writel(1 << cpu, WUPCR);	/* wake up */
@@ -95,8 +78,6 @@
 
 static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int cpu = cpu_logical_map(0);
-
 	scu_enable(scu_base_addr());
 
 	/* Map the reset vector (in headsmp.S) */
@@ -104,7 +85,7 @@
 	__raw_writel(__pa(shmobile_secondary_vector), SBAR);
 
 	/* enable cache coherency on CPU0 */
-	modify_scu_cpu_psr(0, 3 << (cpu * 8));
+	scu_power_mode(scu_base_addr(), 0);
 }
 
 static void __init sh73a0_smp_init_cpus(void)
diff --git a/arch/arm/mach-spear13xx/include/mach/spear1310_misc_regs.h b/arch/arm/mach-spear13xx/include/mach/spear1310_misc_regs.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/arm/mach-spear13xx/include/mach/spear1310_misc_regs.h
+++ /dev/null
diff --git a/arch/arm/mach-spear13xx/include/mach/spear1340_misc_regs.h b/arch/arm/mach-spear13xx/include/mach/spear1340_misc_regs.h
deleted file mode 100644
index e69de29..0000000
--- a/arch/arm/mach-spear13xx/include/mach/spear1340_misc_regs.h
+++ /dev/null
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
new file mode 100644
index 0000000..3fdd008
--- /dev/null
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -0,0 +1,9 @@
+config ARCH_SUNXI
+	bool "Allwinner A1X SOCs" if ARCH_MULTI_V7
+	select CLKSRC_MMIO
+	select COMMON_CLK
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_IRQ_CHIP
+	select PINCTRL
+	select SPARSE_IRQ
+	select SUNXI_TIMER
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
new file mode 100644
index 0000000..93bebfc
--- /dev/null
+++ b/arch/arm/mach-sunxi/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
diff --git a/arch/arm/mach-sunxi/Makefile.boot b/arch/arm/mach-sunxi/Makefile.boot
new file mode 100644
index 0000000..46d4cf0
--- /dev/null
+++ b/arch/arm/mach-sunxi/Makefile.boot
@@ -0,0 +1 @@
+zreladdr-$(CONFIG_ARCH_SUNXI)	+= 0x40008000
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
new file mode 100644
index 0000000..9be910f
--- /dev/null
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -0,0 +1,96 @@
+/*
+ * Device Tree support for Allwinner A1X SoCs
+ *
+ * Copyright (C) 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.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/delay.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/sunxi_timer.h>
+
+#include <linux/irqchip/sunxi.h>
+
+#include <asm/hardware/vic.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "sunxi.h"
+
+#define WATCHDOG_CTRL_REG	0x00
+#define WATCHDOG_MODE_REG	0x04
+
+static void __iomem *wdt_base;
+
+static void sunxi_setup_restart(void)
+{
+	struct device_node *np = of_find_compatible_node(NULL, NULL,
+						"allwinner,sunxi-wdt");
+	if (WARN(!np, "unable to setup watchdog restart"))
+		return;
+
+	wdt_base = of_iomap(np, 0);
+	WARN(!wdt_base, "failed to map watchdog base address");
+}
+
+static void sunxi_restart(char mode, const char *cmd)
+{
+	if (!wdt_base)
+		return;
+
+	/* Enable timer and set reset bit in the watchdog */
+	writel(3, wdt_base + WATCHDOG_MODE_REG);
+	writel(0xa57 << 1 | 1, wdt_base + WATCHDOG_CTRL_REG);
+	while(1) {
+		mdelay(5);
+		writel(3, wdt_base + WATCHDOG_MODE_REG);
+	}
+}
+
+static struct map_desc sunxi_io_desc[] __initdata = {
+	{
+		.virtual	= (unsigned long) SUNXI_REGS_VIRT_BASE,
+		.pfn		= __phys_to_pfn(SUNXI_REGS_PHYS_BASE),
+		.length		= SUNXI_REGS_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
+void __init sunxi_map_io(void)
+{
+	iotable_init(sunxi_io_desc, ARRAY_SIZE(sunxi_io_desc));
+}
+
+static void __init sunxi_dt_init(void)
+{
+	sunxi_setup_restart();
+
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char * const sunxi_board_dt_compat[] = {
+	"allwinner,sun4i",
+	"allwinner,sun5i",
+	NULL,
+};
+
+DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
+	.init_machine	= sunxi_dt_init,
+	.map_io		= sunxi_map_io,
+	.init_irq	= sunxi_init_irq,
+	.handle_irq	= sunxi_handle_irq,
+	.restart	= sunxi_restart,
+	.timer		= &sunxi_timer,
+	.dt_compat	= sunxi_board_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-sunxi/sunxi.h b/arch/arm/mach-sunxi/sunxi.h
new file mode 100644
index 0000000..33b5871
--- /dev/null
+++ b/arch/arm/mach-sunxi/sunxi.h
@@ -0,0 +1,20 @@
+/*
+ * Generic definitions for Allwinner SunXi SoCs
+ *
+ * Copyright (C) 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SUNXI_H
+#define __MACH_SUNXI_H
+
+#define SUNXI_REGS_PHYS_BASE	0x01c00000
+#define SUNXI_REGS_VIRT_BASE	IOMEM(0xf1c00000)
+#define SUNXI_REGS_SIZE		(SZ_2M + SZ_1M)
+
+#endif /* __MACH_SUNXI_H */
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 9aa653b..0979e8b 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -8,15 +8,24 @@
 obj-y					+= flowctrl.o
 obj-y					+= powergate.o
 obj-y					+= apbio.o
+obj-y					+= pm.o
 obj-$(CONFIG_CPU_IDLE)			+= cpuidle.o
 obj-$(CONFIG_CPU_IDLE)			+= sleep.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra20_clocks.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra20_clocks_data.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= tegra20_speedo.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= tegra2_emc.o
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= sleep-t20.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= sleep-tegra20.o
+ifeq ($(CONFIG_CPU_IDLE),y)
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= cpuidle-tegra20.o
+endif
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= tegra30_clocks.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= tegra30_clocks_data.o
-obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-t30.o
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= tegra30_speedo.o
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-tegra30.o
+ifeq ($(CONFIG_CPU_IDLE),y)
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= cpuidle-tegra30.o
+endif
 obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
 obj-$(CONFIG_SMP)                       += reset.o
 obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
index b5015d0..d091675 100644
--- a/arch/arm/mach-tegra/apbio.c
+++ b/arch/arm/mach-tegra/apbio.c
@@ -15,7 +15,6 @@
 
 #include <linux/kernel.h>
 #include <linux/io.h>
-#include <mach/iomap.h>
 #include <linux/of.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
@@ -24,9 +23,8 @@
 #include <linux/sched.h>
 #include <linux/mutex.h>
 
-#include <mach/dma.h>
-
 #include "apbio.h"
+#include "iomap.h"
 
 #if defined(CONFIG_TEGRA20_APB_DMA)
 static DEFINE_MUTEX(tegra_apb_dma_lock);
@@ -71,7 +69,6 @@
 
 	dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 	dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	dma_sconfig.slave_id = TEGRA_DMA_REQ_SEL_CNTR;
 	dma_sconfig.src_maxburst = 1;
 	dma_sconfig.dst_maxburst = 1;
 
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index aa5325c..734d9cc 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -40,12 +40,10 @@
 #include <asm/mach/time.h>
 #include <asm/setup.h>
 
-#include <mach/iomap.h>
-#include <mach/irqs.h>
-
 #include "board.h"
 #include "clock.h"
 #include "common.h"
+#include "iomap.h"
 
 struct tegra_ehci_platform_data tegra_ehci1_pdata = {
 	.operating_mode = TEGRA_USB_OTG,
@@ -91,6 +89,17 @@
 		       &tegra_ehci3_pdata),
 	OF_DEV_AUXDATA("nvidia,tegra20-apbdma", TEGRA_APB_DMA_BASE, "tegra-apbdma", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra20-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-sflash", 0x7000c380, "spi", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D400, "spi_tegra.0", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D600, "spi_tegra.1", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D800, "spi_tegra.2", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000DA00, "spi_tegra.3", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-host1x", 0x50000000, "host1x", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x54200000, "tegradc.0", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x54240000, "tegradc.1", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-hdmi", 0x54280000, "hdmi", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-dsi", 0x54300000, "dsi", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-tvo", 0x542c0000, "tvo", NULL),
 	{}
 };
 
@@ -104,8 +113,20 @@
 	{ "pll_a",      "pll_p_out1",   56448000,       true },
 	{ "pll_a_out0", "pll_a",        11289600,       true },
 	{ "cdev1",      NULL,           0,              true },
+	{ "blink",      "clk_32k",      32768,          true },
 	{ "i2s1",       "pll_a_out0",   11289600,       false},
 	{ "i2s2",       "pll_a_out0",   11289600,       false},
+	{ "sdmmc1",	"pll_p",	48000000,	false},
+	{ "sdmmc3",	"pll_p",	48000000,	false},
+	{ "sdmmc4",	"pll_p",	48000000,	false},
+	{ "spi",	"pll_p",	20000000,	false },
+	{ "sbc1",	"pll_p",	100000000,	false },
+	{ "sbc2",	"pll_p",	100000000,	false },
+	{ "sbc3",	"pll_p",	100000000,	false },
+	{ "sbc4",	"pll_p",	100000000,	false },
+	{ "host1x",	"pll_c",	150000000,	false },
+	{ "disp1",	"pll_p",	600000000,	false },
+	{ "disp2",	"pll_p",	600000000,	false },
 	{ NULL,		NULL,		0,		0},
 };
 
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
index 5e92a81..6497d12 100644
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -33,11 +33,10 @@
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
 
-#include <mach/iomap.h>
-
 #include "board.h"
 #include "clock.h"
 #include "common.h"
+#include "iomap.h"
 
 struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL),
@@ -52,6 +51,18 @@
 	OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra30-apbdma", 0x6000a000, "tegra-apbdma", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra30-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D400, "spi_tegra.0", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D600, "spi_tegra.1", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000D800, "spi_tegra.2", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DA00, "spi_tegra.3", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DC00, "spi_tegra.4", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DE00, "spi_tegra.5", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-host1x", 0x50000000, "host1x", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x54200000, "tegradc.0", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x54240000, "tegradc.1", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-hdmi", 0x54280000, "hdmi", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-dsi", 0x54300000, "dsi", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-tvo", 0x542c0000, "tvo", NULL),
 	{}
 };
 
@@ -62,11 +73,24 @@
 	{ "pll_a_out0",	"pll_a",	11289600,	true },
 	{ "extern1",	"pll_a_out0",	0,		true },
 	{ "clk_out_1",	"extern1",	0,		true },
+	{ "blink",	"clk_32k",	32768,		true },
 	{ "i2s0",	"pll_a_out0",	11289600,	false},
 	{ "i2s1",	"pll_a_out0",	11289600,	false},
 	{ "i2s2",	"pll_a_out0",	11289600,	false},
 	{ "i2s3",	"pll_a_out0",	11289600,	false},
 	{ "i2s4",	"pll_a_out0",	11289600,	false},
+	{ "sdmmc1",	"pll_p",	48000000,	false},
+	{ "sdmmc3",	"pll_p",	48000000,	false},
+	{ "sdmmc4",	"pll_p",	48000000,	false},
+	{ "sbc1",	"pll_p",	100000000,	false},
+	{ "sbc2",	"pll_p",	100000000,	false},
+	{ "sbc3",	"pll_p",	100000000,	false},
+	{ "sbc4",	"pll_p",	100000000,	false},
+	{ "sbc5",	"pll_p",	100000000,	false},
+	{ "sbc6",	"pll_p",	100000000,	false},
+	{ "host1x",	"pll_c",	150000000,	false},
+	{ "disp1",	"pll_p",	600000000,	false},
+	{ "disp2",	"pll_p",	600000000,	false},
 	{ NULL,		NULL,		0,		0},
 };
 
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index fd82085..867bf8b 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -27,8 +27,6 @@
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 
-#include <mach/clk.h>
-
 #include "board.h"
 #include "clock.h"
 #include "tegra_cpu_car.h"
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 0b0a5f5..11a74db 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -26,16 +26,17 @@
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
 
-#include <mach/iomap.h>
 #include <mach/powergate.h>
 
 #include "board.h"
 #include "clock.h"
 #include "common.h"
 #include "fuse.h"
+#include "iomap.h"
 #include "pmc.h"
 #include "apbio.h"
 #include "sleep.h"
+#include "pm.h"
 
 /*
  * Storage for debug-macro.S's state.
@@ -104,25 +105,30 @@
 	{ "clk_m",	NULL,		0,		true },
 	{ "pll_p",	"clk_m",	408000000,	true },
 	{ "pll_p_out1",	"pll_p",	9600000,	true },
+	{ "pll_p_out4",	"pll_p",	102000000,	true },
+	{ "sclk",	"pll_p_out4",	102000000,	true },
+	{ "hclk",	"sclk",		102000000,	true },
+	{ "pclk",	"hclk",		51000000,	true },
+	{ "csite",	NULL,		0,		true },
 	{ NULL,		NULL,		0,		0},
 };
 #endif
 
 
-static void __init tegra_init_cache(u32 tag_latency, u32 data_latency)
+static void __init tegra_init_cache(void)
 {
 #ifdef CONFIG_CACHE_L2X0
+	int ret;
 	void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
 	u32 aux_ctrl, cache_type;
 
-	writel_relaxed(tag_latency, p + L2X0_TAG_LATENCY_CTRL);
-	writel_relaxed(data_latency, p + L2X0_DATA_LATENCY_CTRL);
-
 	cache_type = readl(p + L2X0_CACHE_TYPE);
 	aux_ctrl = (cache_type & 0x700) << (17-8);
-	aux_ctrl |= 0x6C000001;
+	aux_ctrl |= 0x7C400001;
 
-	l2x0_init(p, aux_ctrl, 0x8200c3fe);
+	ret = l2x0_of_init(aux_ctrl, 0x8200c3fe);
+	if (!ret)
+		l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs);
 #endif
 
 }
@@ -134,7 +140,7 @@
 	tegra_init_fuse();
 	tegra2_init_clocks();
 	tegra_clk_init_from_table(tegra20_clk_init_table);
-	tegra_init_cache(0x331, 0x441);
+	tegra_init_cache();
 	tegra_pmc_init();
 	tegra_powergate_init();
 	tegra20_hotplug_init();
@@ -147,7 +153,7 @@
 	tegra_init_fuse();
 	tegra30_init_clocks();
 	tegra_clk_init_from_table(tegra30_clk_init_table);
-	tegra_init_cache(0x441, 0x551);
+	tegra_init_cache();
 	tegra_pmc_init();
 	tegra_powergate_init();
 	tegra30_hotplug_init();
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c
index 627bf0f..a74d3c7 100644
--- a/arch/arm/mach-tegra/cpu-tegra.c
+++ b/arch/arm/mach-tegra/cpu-tegra.c
@@ -30,9 +30,6 @@
 #include <linux/io.h>
 #include <linux/suspend.h>
 
-
-#include <mach/clk.h>
-
 /* Frequency table index must be sequential starting at 0 */
 static struct cpufreq_frequency_table freq_table[] = {
 	{ 0, 216000 },
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
new file mode 100644
index 0000000..d32e8b0
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -0,0 +1,66 @@
+/*
+ * CPU idle driver for Tegra CPUs
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2011 Google, Inc.
+ * Author: Colin Cross <ccross@android.com>
+ *         Gary King <gking@nvidia.com>
+ *
+ * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cpuidle.h>
+
+#include <asm/cpuidle.h>
+
+static struct cpuidle_driver tegra_idle_driver = {
+	.name = "tegra_idle",
+	.owner = THIS_MODULE,
+	.en_core_tk_irqen = 1,
+	.state_count = 1,
+	.states = {
+		[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
+	},
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
+
+int __init tegra20_cpuidle_init(void)
+{
+	int ret;
+	unsigned int cpu;
+	struct cpuidle_device *dev;
+	struct cpuidle_driver *drv = &tegra_idle_driver;
+
+	ret = cpuidle_register_driver(&tegra_idle_driver);
+	if (ret) {
+		pr_err("CPUidle driver registration failed\n");
+		return ret;
+	}
+
+	for_each_possible_cpu(cpu) {
+		dev = &per_cpu(tegra_idle_device, cpu);
+		dev->cpu = cpu;
+
+		dev->state_count = drv->state_count;
+		ret = cpuidle_register_device(dev);
+		if (ret) {
+			pr_err("CPU%u: CPUidle device registration failed\n",
+				cpu);
+			return ret;
+		}
+	}
+	return 0;
+}
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c
new file mode 100644
index 0000000..5e8cbf5
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle-tegra30.c
@@ -0,0 +1,188 @@
+/*
+ * CPU idle driver for Tegra CPUs
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2011 Google, Inc.
+ * Author: Colin Cross <ccross@android.com>
+ *         Gary King <gking@nvidia.com>
+ *
+ * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/clockchips.h>
+
+#include <asm/cpuidle.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/smp_plat.h>
+
+#include "pm.h"
+#include "sleep.h"
+#include "tegra_cpu_car.h"
+
+#ifdef CONFIG_PM_SLEEP
+static int tegra30_idle_lp2(struct cpuidle_device *dev,
+			    struct cpuidle_driver *drv,
+			    int index);
+#endif
+
+static struct cpuidle_driver tegra_idle_driver = {
+	.name = "tegra_idle",
+	.owner = THIS_MODULE,
+	.en_core_tk_irqen = 1,
+#ifdef CONFIG_PM_SLEEP
+	.state_count = 2,
+#else
+	.state_count = 1,
+#endif
+	.states = {
+		[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
+#ifdef CONFIG_PM_SLEEP
+		[1] = {
+			.enter			= tegra30_idle_lp2,
+			.exit_latency		= 2000,
+			.target_residency	= 2200,
+			.power_usage		= 0,
+			.flags			= CPUIDLE_FLAG_TIME_VALID,
+			.name			= "powered-down",
+			.desc			= "CPU power gated",
+		},
+#endif
+	},
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
+
+#ifdef CONFIG_PM_SLEEP
+static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
+					   struct cpuidle_driver *drv,
+					   int index)
+{
+	struct cpuidle_state *state = &drv->states[index];
+	u32 cpu_on_time = state->exit_latency;
+	u32 cpu_off_time = state->target_residency - state->exit_latency;
+
+	/* All CPUs entering LP2 is not working.
+	 * Don't let CPU0 enter LP2 when any secondary CPU is online.
+	 */
+	if (num_online_cpus() > 1 || !tegra_cpu_rail_off_ready()) {
+		cpu_do_idle();
+		return false;
+	}
+
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+
+	tegra_idle_lp2_last(cpu_on_time, cpu_off_time);
+
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+
+	return true;
+}
+
+#ifdef CONFIG_SMP
+static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
+					struct cpuidle_driver *drv,
+					int index)
+{
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+
+	smp_wmb();
+
+	save_cpu_arch_register();
+
+	cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
+
+	restore_cpu_arch_register();
+
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+
+	return true;
+}
+#else
+static inline bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
+					       struct cpuidle_driver *drv,
+					       int index)
+{
+	return true;
+}
+#endif
+
+static int __cpuinit tegra30_idle_lp2(struct cpuidle_device *dev,
+				      struct cpuidle_driver *drv,
+				      int index)
+{
+	u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu;
+	bool entered_lp2 = false;
+	bool last_cpu;
+
+	local_fiq_disable();
+
+	last_cpu = tegra_set_cpu_in_lp2(cpu);
+	cpu_pm_enter();
+
+	if (cpu == 0) {
+		if (last_cpu)
+			entered_lp2 = tegra30_cpu_cluster_power_down(dev, drv,
+								     index);
+		else
+			cpu_do_idle();
+	} else {
+		entered_lp2 = tegra30_cpu_core_power_down(dev, drv, index);
+	}
+
+	cpu_pm_exit();
+	tegra_clear_cpu_in_lp2(cpu);
+
+	local_fiq_enable();
+
+	smp_rmb();
+
+	return (entered_lp2) ? index : 0;
+}
+#endif
+
+int __init tegra30_cpuidle_init(void)
+{
+	int ret;
+	unsigned int cpu;
+	struct cpuidle_device *dev;
+	struct cpuidle_driver *drv = &tegra_idle_driver;
+
+#ifdef CONFIG_PM_SLEEP
+	tegra_tear_down_cpu = tegra30_tear_down_cpu;
+#endif
+
+	ret = cpuidle_register_driver(&tegra_idle_driver);
+	if (ret) {
+		pr_err("CPUidle driver registration failed\n");
+		return ret;
+	}
+
+	for_each_possible_cpu(cpu) {
+		dev = &per_cpu(tegra_idle_device, cpu);
+		dev->cpu = cpu;
+
+		dev->state_count = drv->state_count;
+		ret = cpuidle_register_device(dev);
+		if (ret) {
+			pr_err("CPU%u: CPUidle device registration failed\n",
+				cpu);
+			return ret;
+		}
+	}
+	return 0;
+}
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
index 566e2f8..d065139 100644
--- a/arch/arm/mach-tegra/cpuidle.c
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -23,85 +23,26 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/cpu.h>
-#include <linux/cpuidle.h>
-#include <linux/hrtimer.h>
 
-#include <asm/proc-fns.h>
-
-#include <mach/iomap.h>
-
-static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
-				struct cpuidle_driver *drv, int index);
-
-struct cpuidle_driver tegra_idle_driver = {
-	.name = "tegra_idle",
-	.owner = THIS_MODULE,
-	.state_count = 1,
-	.states = {
-		[0] = {
-			.enter			= tegra_idle_enter_lp3,
-			.exit_latency		= 10,
-			.target_residency	= 10,
-			.power_usage		= 600,
-			.flags			= CPUIDLE_FLAG_TIME_VALID,
-			.name			= "LP3",
-			.desc			= "CPU flow-controlled",
-		},
-	},
-};
-
-static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
-
-static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
-	struct cpuidle_driver *drv, int index)
-{
-	ktime_t enter, exit;
-	s64 us;
-
-	local_irq_disable();
-	local_fiq_disable();
-
-	enter = ktime_get();
-
-	cpu_do_idle();
-
-	exit = ktime_sub(ktime_get(), enter);
-	us = ktime_to_us(exit);
-
-	local_fiq_enable();
-	local_irq_enable();
-
-	dev->last_residency = us;
-
-	return index;
-}
+#include "fuse.h"
+#include "cpuidle.h"
 
 static int __init tegra_cpuidle_init(void)
 {
 	int ret;
-	unsigned int cpu;
-	struct cpuidle_device *dev;
-	struct cpuidle_driver *drv = &tegra_idle_driver;
 
-	ret = cpuidle_register_driver(&tegra_idle_driver);
-	if (ret) {
-		pr_err("CPUidle driver registration failed\n");
-		return ret;
+	switch (tegra_chip_id) {
+	case TEGRA20:
+		ret = tegra20_cpuidle_init();
+		break;
+	case TEGRA30:
+		ret = tegra30_cpuidle_init();
+		break;
+	default:
+		ret = -ENODEV;
+		break;
 	}
 
-	for_each_possible_cpu(cpu) {
-		dev = &per_cpu(tegra_idle_device, cpu);
-		dev->cpu = cpu;
-
-		dev->state_count = drv->state_count;
-		ret = cpuidle_register_device(dev);
-		if (ret) {
-			pr_err("CPU%u: CPUidle device registration failed\n",
-				cpu);
-			return ret;
-		}
-	}
-	return 0;
+	return ret;
 }
 device_initcall(tegra_cpuidle_init);
diff --git a/arch/arm/mach-tegra/cpuidle.h b/arch/arm/mach-tegra/cpuidle.h
new file mode 100644
index 0000000..496204d
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA_CPUIDLE_H
+#define __MACH_TEGRA_CPUIDLE_H
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+int tegra20_cpuidle_init(void);
+#else
+static inline int tegra20_cpuidle_init(void) { return -ENODEV; }
+#endif
+
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+int tegra30_cpuidle_init(void);
+#else
+static inline int tegra30_cpuidle_init(void) { return -ENODEV; }
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
index f07488e..a2250dd 100644
--- a/arch/arm/mach-tegra/flowctrl.c
+++ b/arch/arm/mach-tegra/flowctrl.c
@@ -21,10 +21,10 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
-
-#include <mach/iomap.h>
+#include <linux/cpumask.h>
 
 #include "flowctrl.h"
+#include "iomap.h"
 
 u8 flowctrl_offset_halt_cpu[] = {
 	FLOW_CTRL_HALT_CPU0_EVENTS,
@@ -51,6 +51,14 @@
 	readl_relaxed(addr);
 }
 
+u32 flowctrl_read_cpu_csr(unsigned int cpuid)
+{
+	u8 offset = flowctrl_offset_cpu_csr[cpuid];
+	void __iomem *addr = IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + offset;
+
+	return readl(addr);
+}
+
 void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value)
 {
 	return flowctrl_update(flowctrl_offset_cpu_csr[cpuid], value);
@@ -60,3 +68,41 @@
 {
 	return flowctrl_update(flowctrl_offset_halt_cpu[cpuid], value);
 }
+
+void flowctrl_cpu_suspend_enter(unsigned int cpuid)
+{
+	unsigned int reg;
+	int i;
+
+	reg = flowctrl_read_cpu_csr(cpuid);
+	reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;	/* clear wfe bitmap */
+	reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;	/* clear wfi bitmap */
+	reg |= FLOW_CTRL_CSR_INTR_FLAG;			/* clear intr flag */
+	reg |= FLOW_CTRL_CSR_EVENT_FLAG;		/* clear event flag */
+	reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid;	/* pwr gating on wfi */
+	reg |= FLOW_CTRL_CSR_ENABLE;			/* pwr gating */
+	flowctrl_write_cpu_csr(cpuid, reg);
+
+	for (i = 0; i < num_possible_cpus(); i++) {
+		if (i == cpuid)
+			continue;
+		reg = flowctrl_read_cpu_csr(i);
+		reg |= FLOW_CTRL_CSR_EVENT_FLAG;
+		reg |= FLOW_CTRL_CSR_INTR_FLAG;
+		flowctrl_write_cpu_csr(i, reg);
+	}
+}
+
+void flowctrl_cpu_suspend_exit(unsigned int cpuid)
+{
+	unsigned int reg;
+
+	/* Disable powergating via flow controller for CPU0 */
+	reg = flowctrl_read_cpu_csr(cpuid);
+	reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;	/* clear wfe bitmap */
+	reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;	/* clear wfi bitmap */
+	reg &= ~FLOW_CTRL_CSR_ENABLE;			/* clear enable */
+	reg |= FLOW_CTRL_CSR_INTR_FLAG;			/* clear intr */
+	reg |= FLOW_CTRL_CSR_EVENT_FLAG;		/* clear event */
+	flowctrl_write_cpu_csr(cpuid, reg);
+}
diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h
index 1942817..0798dec 100644
--- a/arch/arm/mach-tegra/flowctrl.h
+++ b/arch/arm/mach-tegra/flowctrl.h
@@ -34,9 +34,17 @@
 #define FLOW_CTRL_HALT_CPU1_EVENTS	0x14
 #define FLOW_CTRL_CPU1_CSR		0x18
 
+#define TEGRA30_FLOW_CTRL_CSR_WFI_CPU0		(1 << 8)
+#define TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP	(0xF << 4)
+#define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP	(0xF << 8)
+
 #ifndef __ASSEMBLY__
+u32 flowctrl_read_cpu_csr(unsigned int cpuid);
 void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value);
 void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value);
+
+void flowctrl_cpu_suspend_enter(unsigned int cpuid);
+void flowctrl_cpu_suspend_exit(unsigned int cpuid);
 #endif
 
 #endif
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index 0b7db17..8121742 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -21,22 +21,28 @@
 #include <linux/io.h>
 #include <linux/export.h>
 
-#include <mach/iomap.h>
-
 #include "fuse.h"
+#include "iomap.h"
 #include "apbio.h"
 
 #define FUSE_UID_LOW		0x108
 #define FUSE_UID_HIGH		0x10c
 #define FUSE_SKU_INFO		0x110
-#define FUSE_SPARE_BIT		0x200
+
+#define TEGRA20_FUSE_SPARE_BIT		0x200
+#define TEGRA30_FUSE_SPARE_BIT		0x244
 
 int tegra_sku_id;
 int tegra_cpu_process_id;
 int tegra_core_process_id;
 int tegra_chip_id;
+int tegra_cpu_speedo_id;		/* only exist in Tegra30 and later */
+int tegra_soc_speedo_id;
 enum tegra_revision tegra_revision;
 
+static int tegra_fuse_spare_bit;
+static void (*tegra_init_speedo_data)(void);
+
 /* The BCT to use at boot is specified by board straps that can be read
  * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.
  */
@@ -57,14 +63,14 @@
 	[TEGRA_REVISION_A04]     = "A04",
 };
 
-static inline u32 tegra_fuse_readl(unsigned long offset)
+u32 tegra_fuse_readl(unsigned long offset)
 {
 	return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
 }
 
-static inline bool get_spare_fuse(int bit)
+bool tegra_spare_fuse(int bit)
 {
-	return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4);
+	return tegra_fuse_readl(tegra_fuse_spare_bit + bit * 4);
 }
 
 static enum tegra_revision tegra_get_revision(u32 id)
@@ -78,7 +84,7 @@
 		return TEGRA_REVISION_A02;
 	case 3:
 		if (tegra_chip_id == TEGRA20 &&
-			(get_spare_fuse(18) || get_spare_fuse(19)))
+			(tegra_spare_fuse(18) || tegra_spare_fuse(19)))
 			return TEGRA_REVISION_A03p;
 		else
 			return TEGRA_REVISION_A03;
@@ -89,6 +95,16 @@
 	}
 }
 
+static void tegra_get_process_id(void)
+{
+	u32 reg;
+
+	reg = tegra_fuse_readl(tegra_fuse_spare_bit);
+	tegra_cpu_process_id = (reg >> 6) & 3;
+	reg = tegra_fuse_readl(tegra_fuse_spare_bit);
+	tegra_core_process_id = (reg >> 12) & 3;
+}
+
 void tegra_init_fuse(void)
 {
 	u32 id;
@@ -100,19 +116,29 @@
 	reg = tegra_fuse_readl(FUSE_SKU_INFO);
 	tegra_sku_id = reg & 0xFF;
 
-	reg = tegra_fuse_readl(FUSE_SPARE_BIT);
-	tegra_cpu_process_id = (reg >> 6) & 3;
-
-	reg = tegra_fuse_readl(FUSE_SPARE_BIT);
-	tegra_core_process_id = (reg >> 12) & 3;
-
 	reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
 	tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
 
 	id = readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
 	tegra_chip_id = (id >> 8) & 0xff;
 
+	switch (tegra_chip_id) {
+	case TEGRA20:
+		tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
+		tegra_init_speedo_data = &tegra20_init_speedo_data;
+		break;
+	case TEGRA30:
+		tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT;
+		tegra_init_speedo_data = &tegra30_init_speedo_data;
+		break;
+	default:
+		pr_warn("Tegra: unknown chip id %d\n", tegra_chip_id);
+		tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
+		tegra_init_speedo_data = &tegra_get_process_id;
+	}
+
 	tegra_revision = tegra_get_revision(id);
+	tegra_init_speedo_data();
 
 	pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
 		tegra_revision_name[tegra_revision],
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index d2107b2..ff1383d 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -42,11 +42,27 @@
 extern int tegra_cpu_process_id;
 extern int tegra_core_process_id;
 extern int tegra_chip_id;
+extern int tegra_cpu_speedo_id;		/* only exist in Tegra30 and later */
+extern int tegra_soc_speedo_id;
 extern enum tegra_revision tegra_revision;
 
 extern int tegra_bct_strapping;
 
 unsigned long long tegra_chip_uid(void);
 void tegra_init_fuse(void);
+bool tegra_spare_fuse(int bit);
+u32 tegra_fuse_readl(unsigned long offset);
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+void tegra20_init_speedo_data(void);
+#else
+static inline void tegra20_init_speedo_data(void) {}
+#endif
+
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+void tegra30_init_speedo_data(void);
+#else
+static inline void tegra30_init_speedo_data(void) {}
+#endif
 
 #endif
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
index 6addc78..4a317fa 100644
--- a/arch/arm/mach-tegra/headsmp.S
+++ b/arch/arm/mach-tegra/headsmp.S
@@ -2,10 +2,11 @@
 #include <linux/init.h>
 
 #include <asm/cache.h>
-
-#include <mach/iomap.h>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
 
 #include "flowctrl.h"
+#include "iomap.h"
 #include "reset.h"
 #include "sleep.h"
 
@@ -69,6 +70,64 @@
         b       secondary_startup
 ENDPROC(tegra_secondary_startup)
 
+#ifdef CONFIG_PM_SLEEP
+/*
+ *	tegra_resume
+ *
+ *	  CPU boot vector when restarting the a CPU following
+ *	  an LP2 transition. Also branched to by LP0 and LP1 resume after
+ *	  re-enabling sdram.
+ */
+ENTRY(tegra_resume)
+	bl	v7_invalidate_l1
+	/* Enable coresight */
+	mov32	r0, 0xC5ACCE55
+	mcr	p14, 0, r0, c7, c12, 6
+
+	cpu_id	r0
+	cmp	r0, #0				@ CPU0?
+	bne	cpu_resume			@ no
+
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+	/* Are we on Tegra20? */
+	mov32	r6, TEGRA_APB_MISC_BASE
+	ldr	r0, [r6, #APB_MISC_GP_HIDREV]
+	and	r0, r0, #0xff00
+	cmp	r0, #(0x20 << 8)
+	beq	1f				@ Yes
+	/* Clear the flow controller flags for this CPU. */
+	mov32	r2, TEGRA_FLOW_CTRL_BASE + FLOW_CTRL_CPU0_CSR	@ CPU0 CSR
+	ldr	r1, [r2]
+	/* Clear event & intr flag */
+	orr	r1, r1, \
+		#FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
+	movw	r0, #0x0FFD	@ enable, cluster_switch, immed, & bitmaps
+	bic	r1, r1, r0
+	str	r1, [r2]
+1:
+#endif
+
+#ifdef CONFIG_HAVE_ARM_SCU
+	/* enable SCU */
+	mov32	r0, TEGRA_ARM_PERIF_BASE
+	ldr	r1, [r0]
+	orr	r1, r1, #1
+	str	r1, [r0]
+#endif
+
+	/* L2 cache resume & re-enable */
+	l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr
+
+	b	cpu_resume
+ENDPROC(tegra_resume)
+#endif
+
+#ifdef CONFIG_CACHE_L2X0
+	.globl	l2x0_saved_regs_addr
+l2x0_saved_regs_addr:
+	.long	0
+#endif
+
 	.align L1_CACHE_SHIFT
 ENTRY(__tegra_cpu_reset_handler_start)
 
@@ -122,6 +181,17 @@
 1:
 #endif
 
+	/* Waking up from LP2? */
+	ldr	r9, [r12, #RESET_DATA(MASK_LP2)]
+	tst	r9, r11				@ if in_lp2
+	beq	__is_not_lp2
+	ldr	lr, [r12, #RESET_DATA(STARTUP_LP2)]
+	cmp	lr, #0
+	bleq	__die				@ no LP2 startup handler
+	bx	lr
+
+__is_not_lp2:
+
 #ifdef CONFIG_SMP
 	/*
 	 * Can only be secondary boot (initial or hotplug) but CPU 0
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
index 8ce0661..44ca7b1 100644
--- a/arch/arm/mach-tegra/include/mach/debug-macro.S
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -26,8 +26,8 @@
 
 #include <linux/serial_reg.h>
 
-#include <mach/iomap.h>
-#include <mach/irammap.h>
+#include "../../iomap.h"
+#include "../../irammap.h"
 
 		.macro  addruart, rp, rv, tmp
 		adr	\rp, 99f		@ actual addr of 99f
diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h
deleted file mode 100644
index 3081cc6..0000000
--- a/arch/arm/mach-tegra/include/mach/dma.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * arch/arm/mach-tegra/include/mach/dma.h
- *
- * Copyright (c) 2008-2009, NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-#ifndef __MACH_TEGRA_DMA_H
-#define __MACH_TEGRA_DMA_H
-
-#include <linux/list.h>
-
-#define TEGRA_DMA_REQ_SEL_CNTR			0
-#define TEGRA_DMA_REQ_SEL_I2S_2			1
-#define TEGRA_DMA_REQ_SEL_I2S_1			2
-#define TEGRA_DMA_REQ_SEL_SPD_I			3
-#define TEGRA_DMA_REQ_SEL_UI_I			4
-#define TEGRA_DMA_REQ_SEL_MIPI			5
-#define TEGRA_DMA_REQ_SEL_I2S2_2		6
-#define TEGRA_DMA_REQ_SEL_I2S2_1		7
-#define TEGRA_DMA_REQ_SEL_UARTA			8
-#define TEGRA_DMA_REQ_SEL_UARTB			9
-#define TEGRA_DMA_REQ_SEL_UARTC			10
-#define TEGRA_DMA_REQ_SEL_SPI			11
-#define TEGRA_DMA_REQ_SEL_AC97			12
-#define TEGRA_DMA_REQ_SEL_ACMODEM		13
-#define TEGRA_DMA_REQ_SEL_SL4B			14
-#define TEGRA_DMA_REQ_SEL_SL2B1			15
-#define TEGRA_DMA_REQ_SEL_SL2B2			16
-#define TEGRA_DMA_REQ_SEL_SL2B3			17
-#define TEGRA_DMA_REQ_SEL_SL2B4			18
-#define TEGRA_DMA_REQ_SEL_UARTD			19
-#define TEGRA_DMA_REQ_SEL_UARTE			20
-#define TEGRA_DMA_REQ_SEL_I2C			21
-#define TEGRA_DMA_REQ_SEL_I2C2			22
-#define TEGRA_DMA_REQ_SEL_I2C3			23
-#define TEGRA_DMA_REQ_SEL_DVC_I2C		24
-#define TEGRA_DMA_REQ_SEL_OWR			25
-#define TEGRA_DMA_REQ_SEL_INVALID		31
-
-#endif
diff --git a/arch/arm/mach-tegra/include/mach/powergate.h b/arch/arm/mach-tegra/include/mach/powergate.h
index 4752b1a68..06763fe 100644
--- a/arch/arm/mach-tegra/include/mach/powergate.h
+++ b/arch/arm/mach-tegra/include/mach/powergate.h
@@ -20,6 +20,8 @@
 #ifndef _MACH_TEGRA_POWERGATE_H_
 #define _MACH_TEGRA_POWERGATE_H_
 
+struct clk;
+
 #define TEGRA_POWERGATE_CPU	0
 #define TEGRA_POWERGATE_3D	1
 #define TEGRA_POWERGATE_VENC	2
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
index 937c4c5..2772575 100644
--- a/arch/arm/mach-tegra/include/mach/uncompress.h
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -28,8 +28,8 @@
 #include <linux/types.h>
 #include <linux/serial_reg.h>
 
-#include <mach/iomap.h>
-#include <mach/irammap.h>
+#include "../../iomap.h"
+#include "../../irammap.h"
 
 #define BIT(x) (1 << (x))
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c
index 58b4baf..7d09f30 100644
--- a/arch/arm/mach-tegra/io.c
+++ b/arch/arm/mach-tegra/io.c
@@ -26,9 +26,9 @@
 
 #include <asm/page.h>
 #include <asm/mach/map.h>
-#include <mach/iomap.h>
 
 #include "board.h"
+#include "iomap.h"
 
 static struct map_desc tegra_io_desc[] __initdata = {
 	{
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/iomap.h
similarity index 99%
rename from arch/arm/mach-tegra/include/mach/iomap.h
rename to arch/arm/mach-tegra/iomap.h
index fee3a94..5315103 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/iomap.h
@@ -1,6 +1,4 @@
 /*
- * arch/arm/mach-tegra/include/mach/iomap.h
- *
  * Copyright (C) 2010 Google, Inc.
  *
  * Author:
diff --git a/arch/arm/mach-tegra/include/mach/irammap.h b/arch/arm/mach-tegra/irammap.h
similarity index 100%
rename from arch/arm/mach-tegra/include/mach/irammap.h
rename to arch/arm/mach-tegra/irammap.h
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 2f5bd2d..b7886f1 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -25,9 +25,8 @@
 
 #include <asm/hardware/gic.h>
 
-#include <mach/iomap.h>
-
 #include "board.h"
+#include "iomap.h"
 
 #define ICTLR_CPU_IEP_VFIQ	0x08
 #define ICTLR_CPU_IEP_FIR	0x14
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index a8dba64..f18fc3a 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -37,11 +37,11 @@
 #include <asm/sizes.h>
 #include <asm/mach/pci.h>
 
-#include <mach/iomap.h>
 #include <mach/clk.h>
 #include <mach/powergate.h>
 
 #include "board.h"
+#include "iomap.h"
 
 /* register definitions */
 #define AFI_OFFSET	0x3800
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 81cb265..1b926df 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -24,8 +24,6 @@
 #include <asm/mach-types.h>
 #include <asm/smp_scu.h>
 
-#include <mach/clk.h>
-#include <mach/iomap.h>
 #include <mach/powergate.h>
 
 #include "fuse.h"
@@ -34,6 +32,7 @@
 #include "tegra_cpu_car.h"
 
 #include "common.h"
+#include "iomap.h"
 
 extern void tegra_secondary_startup(void);
 
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
new file mode 100644
index 0000000..1b11707
--- /dev/null
+++ b/arch/arm/mach-tegra/pm.c
@@ -0,0 +1,216 @@
+/*
+ * CPU complex suspend & resume functions for Tegra SoCs
+ *
+ * Copyright (c) 2009-2012, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+#include <linux/cpu_pm.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/smp_plat.h>
+#include <asm/cacheflush.h>
+#include <asm/suspend.h>
+#include <asm/idmap.h>
+#include <asm/proc-fns.h>
+#include <asm/tlbflush.h>
+
+#include "iomap.h"
+#include "reset.h"
+#include "flowctrl.h"
+#include "sleep.h"
+#include "tegra_cpu_car.h"
+
+#define TEGRA_POWER_CPU_PWRREQ_OE	(1 << 16)  /* CPU pwr req enable */
+
+#define PMC_CTRL		0x0
+#define PMC_CPUPWRGOOD_TIMER	0xc8
+#define PMC_CPUPWROFF_TIMER	0xcc
+
+#ifdef CONFIG_PM_SLEEP
+static unsigned int g_diag_reg;
+static DEFINE_SPINLOCK(tegra_lp2_lock);
+static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
+static struct clk *tegra_pclk;
+void (*tegra_tear_down_cpu)(void);
+
+void save_cpu_arch_register(void)
+{
+	/* read diagnostic register */
+	asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc");
+	return;
+}
+
+void restore_cpu_arch_register(void)
+{
+	/* write diagnostic register */
+	asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc");
+	return;
+}
+
+static void set_power_timers(unsigned long us_on, unsigned long us_off)
+{
+	unsigned long long ticks;
+	unsigned long long pclk;
+	unsigned long rate;
+	static unsigned long tegra_last_pclk;
+
+	if (tegra_pclk == NULL) {
+		tegra_pclk = clk_get_sys(NULL, "pclk");
+		WARN_ON(IS_ERR(tegra_pclk));
+	}
+
+	rate = clk_get_rate(tegra_pclk);
+
+	if (WARN_ON_ONCE(rate <= 0))
+		pclk = 100000000;
+	else
+		pclk = rate;
+
+	if ((rate != tegra_last_pclk)) {
+		ticks = (us_on * pclk) + 999999ull;
+		do_div(ticks, 1000000);
+		writel((unsigned long)ticks, pmc + PMC_CPUPWRGOOD_TIMER);
+
+		ticks = (us_off * pclk) + 999999ull;
+		do_div(ticks, 1000000);
+		writel((unsigned long)ticks, pmc + PMC_CPUPWROFF_TIMER);
+		wmb();
+	}
+	tegra_last_pclk = pclk;
+}
+
+/*
+ * restore_cpu_complex
+ *
+ * restores cpu clock setting, clears flow controller
+ *
+ * Always called on CPU 0.
+ */
+static void restore_cpu_complex(void)
+{
+	int cpu = smp_processor_id();
+
+	BUG_ON(cpu != 0);
+
+#ifdef CONFIG_SMP
+	cpu = cpu_logical_map(cpu);
+#endif
+
+	/* Restore the CPU clock settings */
+	tegra_cpu_clock_resume();
+
+	flowctrl_cpu_suspend_exit(cpu);
+
+	restore_cpu_arch_register();
+}
+
+/*
+ * suspend_cpu_complex
+ *
+ * saves pll state for use by restart_plls, prepares flow controller for
+ * transition to suspend state
+ *
+ * Must always be called on cpu 0.
+ */
+static void suspend_cpu_complex(void)
+{
+	int cpu = smp_processor_id();
+
+	BUG_ON(cpu != 0);
+
+#ifdef CONFIG_SMP
+	cpu = cpu_logical_map(cpu);
+#endif
+
+	/* Save the CPU clock settings */
+	tegra_cpu_clock_suspend();
+
+	flowctrl_cpu_suspend_enter(cpu);
+
+	save_cpu_arch_register();
+}
+
+void __cpuinit tegra_clear_cpu_in_lp2(int phy_cpu_id)
+{
+	u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
+
+	spin_lock(&tegra_lp2_lock);
+
+	BUG_ON(!(*cpu_in_lp2 & BIT(phy_cpu_id)));
+	*cpu_in_lp2 &= ~BIT(phy_cpu_id);
+
+	spin_unlock(&tegra_lp2_lock);
+}
+
+bool __cpuinit tegra_set_cpu_in_lp2(int phy_cpu_id)
+{
+	bool last_cpu = false;
+	cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
+	u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
+
+	spin_lock(&tegra_lp2_lock);
+
+	BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
+	*cpu_in_lp2 |= BIT(phy_cpu_id);
+
+	if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
+		last_cpu = true;
+
+	spin_unlock(&tegra_lp2_lock);
+	return last_cpu;
+}
+
+static int tegra_sleep_cpu(unsigned long v2p)
+{
+	/* Switch to the identity mapping. */
+	cpu_switch_mm(idmap_pgd, &init_mm);
+
+	/* Flush the TLB. */
+	local_flush_tlb_all();
+
+	tegra_sleep_cpu_finish(v2p);
+
+	/* should never here */
+	BUG();
+
+	return 0;
+}
+
+void tegra_idle_lp2_last(u32 cpu_on_time, u32 cpu_off_time)
+{
+	u32 mode;
+
+	/* Only the last cpu down does the final suspend steps */
+	mode = readl(pmc + PMC_CTRL);
+	mode |= TEGRA_POWER_CPU_PWRREQ_OE;
+	writel(mode, pmc + PMC_CTRL);
+
+	set_power_timers(cpu_on_time, cpu_off_time);
+
+	cpu_cluster_pm_enter();
+	suspend_cpu_complex();
+
+	cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
+
+	restore_cpu_complex();
+	cpu_cluster_pm_exit();
+}
+#endif
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
new file mode 100644
index 0000000..787335c
--- /dev/null
+++ b/arch/arm/mach-tegra/pm.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2010-2012 NVIDIA Corporation. All rights reserved.
+ *
+ * Author:
+ *	Colin Cross <ccross@google.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MACH_TEGRA_PM_H_
+#define _MACH_TEGRA_PM_H_
+
+extern unsigned long l2x0_saved_regs_addr;
+
+void save_cpu_arch_register(void);
+void restore_cpu_arch_register(void);
+
+void tegra_clear_cpu_in_lp2(int phy_cpu_id);
+bool tegra_set_cpu_in_lp2(int phy_cpu_id);
+
+void tegra_idle_lp2_last(u32 cpu_on_time, u32 cpu_off_time);
+extern void (*tegra_tear_down_cpu)(void);
+
+#endif /* _MACH_TEGRA_PM_H_ */
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index 7af6a54..d4fdb5f 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -19,7 +19,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 
-#include <mach/iomap.h>
+#include "iomap.h"
 
 #define PMC_CTRL		0x0
 #define PMC_CTRL_INTR_LOW	(1 << 17)
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
index de0662d..2cc1185 100644
--- a/arch/arm/mach-tegra/powergate.c
+++ b/arch/arm/mach-tegra/powergate.c
@@ -28,10 +28,10 @@
 #include <linux/spinlock.h>
 
 #include <mach/clk.h>
-#include <mach/iomap.h>
 #include <mach/powergate.h>
 
 #include "fuse.h"
+#include "iomap.h"
 
 #define PWRGATE_TOGGLE		0x30
 #define  PWRGATE_TOGGLE_START	(1 << 8)
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index 5beb7eb..3fd89ec 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -22,10 +22,10 @@
 #include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
 
-#include <mach/iomap.h>
-#include <mach/irammap.h>
-
+#include "iomap.h"
+#include "irammap.h"
 #include "reset.h"
+#include "sleep.h"
 #include "fuse.h"
 
 #define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \
@@ -80,5 +80,10 @@
 		virt_to_phys((void *)tegra_secondary_startup);
 #endif
 
+#ifdef CONFIG_PM_SLEEP
+	__tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_LP2] =
+		virt_to_phys((void *)tegra_resume);
+#endif
+
 	tegra_cpu_reset_handler_enable();
 }
diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h
index de88bf8..c90d8e9 100644
--- a/arch/arm/mach-tegra/reset.h
+++ b/arch/arm/mach-tegra/reset.h
@@ -29,6 +29,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include "irammap.h"
+
 extern unsigned long __tegra_cpu_reset_handler_data[TEGRA_RESET_DATA_SIZE];
 
 void __tegra_cpu_reset_handler_start(void);
@@ -36,6 +38,13 @@
 void __tegra_cpu_reset_handler_end(void);
 void tegra_secondary_startup(void);
 
+#ifdef CONFIG_PM_SLEEP
+#define tegra_cpu_lp2_mask \
+	(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
+	((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \
+	 (u32)__tegra_cpu_reset_handler_start)))
+#endif
+
 #define tegra_cpu_reset_handler_offset \
 		((u32)__tegra_cpu_reset_handler - \
 		 (u32)__tegra_cpu_reset_handler_start)
diff --git a/arch/arm/mach-tegra/sleep-t20.S b/arch/arm/mach-tegra/sleep-tegra20.S
similarity index 98%
rename from arch/arm/mach-tegra/sleep-t20.S
rename to arch/arm/mach-tegra/sleep-tegra20.S
index a36ae41..72ce709 100644
--- a/arch/arm/mach-tegra/sleep-t20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -22,8 +22,6 @@
 
 #include <asm/assembler.h>
 
-#include <mach/iomap.h>
-
 #include "sleep.h"
 #include "flowctrl.h"
 
diff --git a/arch/arm/mach-tegra/sleep-t30.S b/arch/arm/mach-tegra/sleep-tegra30.S
similarity index 63%
rename from arch/arm/mach-tegra/sleep-t30.S
rename to arch/arm/mach-tegra/sleep-tegra30.S
index 777d9ce..562a8e7 100644
--- a/arch/arm/mach-tegra/sleep-t30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -17,8 +17,7 @@
 #include <linux/linkage.h>
 
 #include <asm/assembler.h>
-
-#include <mach/iomap.h>
+#include <asm/asm-offsets.h>
 
 #include "sleep.h"
 #include "flowctrl.h"
@@ -82,6 +81,7 @@
 	ldr	r3, [r1]			@ read CSR
 	str	r3, [r1]			@ clear CSR
 	tst	r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
+	moveq   r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT	@ For LP2
 	movne	r3, #FLOW_CTRL_WAITEVENT		@ For hotplug
 	str	r3, [r2]
 	ldr	r0, [r2]
@@ -105,3 +105,67 @@
 
 ENDPROC(tegra30_cpu_shutdown)
 #endif
+
+#ifdef CONFIG_PM_SLEEP
+/*
+ * tegra30_sleep_cpu_secondary_finish(unsigned long v2p)
+ *
+ * Enters LP2 on secondary CPU by exiting coherency and powergating the CPU.
+ */
+ENTRY(tegra30_sleep_cpu_secondary_finish)
+	mov	r7, lr
+
+	/* Flush and disable the L1 data cache */
+	bl	tegra_disable_clean_inv_dcache
+
+	/* Powergate this CPU. */
+	mov	r0, #0                          @ power mode flags (!hotplug)
+	bl	tegra30_cpu_shutdown
+	mov	r0, #1                          @ never return here
+	mov	pc, r7
+ENDPROC(tegra30_sleep_cpu_secondary_finish)
+
+/*
+ * tegra30_tear_down_cpu
+ *
+ * Switches the CPU to enter sleep.
+ */
+ENTRY(tegra30_tear_down_cpu)
+	mov32	r6, TEGRA_FLOW_CTRL_BASE
+
+	b	tegra30_enter_sleep
+ENDPROC(tegra30_tear_down_cpu)
+
+/*
+ * tegra30_enter_sleep
+ *
+ * uses flow controller to enter sleep state
+ * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
+ * executes from SDRAM with target state is LP2
+ * r6 = TEGRA_FLOW_CTRL_BASE
+ */
+tegra30_enter_sleep:
+	cpu_id	r1
+
+	cpu_to_csr_reg	r2, r1
+	ldr	r0, [r6, r2]
+	orr	r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
+	orr	r0, r0, #FLOW_CTRL_CSR_ENABLE
+	str	r0, [r6, r2]
+
+	mov	r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
+	orr	r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
+	cpu_to_halt_reg r2, r1
+	str	r0, [r6, r2]
+	dsb
+	ldr	r0, [r6, r2] /* memory barrier */
+
+halted:
+	isb
+	dsb
+	wfi	/* CPU should be power gated here */
+
+	/* !!!FIXME!!! Implement halt failure handler */
+	b	halted
+
+#endif
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
index ea81554..26afa7c 100644
--- a/arch/arm/mach-tegra/sleep.S
+++ b/arch/arm/mach-tegra/sleep.S
@@ -25,9 +25,87 @@
 #include <linux/linkage.h>
 
 #include <asm/assembler.h>
+#include <asm/cache.h>
+#include <asm/cp15.h>
+#include <asm/hardware/cache-l2x0.h>
 
-#include <mach/iomap.h>
+#include "iomap.h"
 
 #include "flowctrl.h"
 #include "sleep.h"
 
+#ifdef CONFIG_PM_SLEEP
+/*
+ * tegra_disable_clean_inv_dcache
+ *
+ * disable, clean & invalidate the D-cache
+ *
+ * Corrupted registers: r1-r3, r6, r8, r9-r11
+ */
+ENTRY(tegra_disable_clean_inv_dcache)
+	stmfd	sp!, {r0, r4-r5, r7, r9-r11, lr}
+	dmb					@ ensure ordering
+
+	/* Disable the D-cache */
+	mrc	p15, 0, r2, c1, c0, 0
+	bic	r2, r2, #CR_C
+	mcr	p15, 0, r2, c1, c0, 0
+	isb
+
+	/* Flush the D-cache */
+	bl	v7_flush_dcache_louis
+
+	/* Trun off coherency */
+	exit_smp r4, r5
+
+	ldmfd	sp!, {r0, r4-r5, r7, r9-r11, pc}
+ENDPROC(tegra_disable_clean_inv_dcache)
+
+/*
+ * tegra_sleep_cpu_finish(unsigned long v2p)
+ *
+ * enters suspend in LP2 by turning off the mmu and jumping to
+ * tegra?_tear_down_cpu
+ */
+ENTRY(tegra_sleep_cpu_finish)
+	/* Flush and disable the L1 data cache */
+	bl	tegra_disable_clean_inv_dcache
+
+	mov32	r6, tegra_tear_down_cpu
+	ldr	r1, [r6]
+	add	r1, r1, r0
+
+	mov32	r3, tegra_shut_off_mmu
+	add	r3, r3, r0
+	mov	r0, r1
+
+	mov	pc, r3
+ENDPROC(tegra_sleep_cpu_finish)
+
+/*
+ * tegra_shut_off_mmu
+ *
+ * r0 = physical address to jump to with mmu off
+ *
+ * called with VA=PA mapping
+ * turns off MMU, icache, dcache and branch prediction
+ */
+	.align	L1_CACHE_SHIFT
+	.pushsection	.idmap.text, "ax"
+ENTRY(tegra_shut_off_mmu)
+	mrc	p15, 0, r3, c1, c0, 0
+	movw	r2, #CR_I | CR_Z | CR_C | CR_M
+	bic	r3, r3, r2
+	dsb
+	mcr	p15, 0, r3, c1, c0, 0
+	isb
+#ifdef CONFIG_CACHE_L2X0
+	/* Disable L2 cache */
+	mov32	r4, TEGRA_ARM_PERIF_BASE + 0x3000
+	mov	r5, #0
+	str	r5, [r4, #L2X0_CTRL]
+#endif
+	mov	pc, r0
+ENDPROC(tegra_shut_off_mmu)
+	.popsection
+#endif
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index e25a7cd..9821ee7 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -17,7 +17,7 @@
 #ifndef __MACH_TEGRA_SLEEP_H
 #define __MACH_TEGRA_SLEEP_H
 
-#include <mach/iomap.h>
+#include "iomap.h"
 
 #define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS \
 					+ IO_CPU_VIRT)
@@ -71,7 +71,41 @@
 	str	\tmp2, [\tmp1]			@ invalidate SCU tags for CPU
 	dsb
 .endm
+
+/* Macro to resume & re-enable L2 cache */
+#ifndef L2X0_CTRL_EN
+#define L2X0_CTRL_EN	1
+#endif
+
+#ifdef CONFIG_CACHE_L2X0
+.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
+	adr	\tmp1, \phys_l2x0_saved_regs
+	ldr	\tmp1, [\tmp1]
+	ldr	\tmp2, [\tmp1, #L2X0_R_PHY_BASE]
+	ldr	\tmp3, [\tmp2, #L2X0_CTRL]
+	tst	\tmp3, #L2X0_CTRL_EN
+	bne	exit_l2_resume
+	ldr	\tmp3, [\tmp1, #L2X0_R_TAG_LATENCY]
+	str	\tmp3, [\tmp2, #L2X0_TAG_LATENCY_CTRL]
+	ldr	\tmp3, [\tmp1, #L2X0_R_DATA_LATENCY]
+	str	\tmp3, [\tmp2, #L2X0_DATA_LATENCY_CTRL]
+	ldr	\tmp3, [\tmp1, #L2X0_R_PREFETCH_CTRL]
+	str	\tmp3, [\tmp2, #L2X0_PREFETCH_CTRL]
+	ldr	\tmp3, [\tmp1, #L2X0_R_PWR_CTRL]
+	str	\tmp3, [\tmp2, #L2X0_POWER_CTRL]
+	ldr	\tmp3, [\tmp1, #L2X0_R_AUX_CTRL]
+	str	\tmp3, [\tmp2, #L2X0_AUX_CTRL]
+	mov	\tmp3, #L2X0_CTRL_EN
+	str	\tmp3, [\tmp2, #L2X0_CTRL]
+exit_l2_resume:
+.endm
+#else /* CONFIG_CACHE_L2X0 */
+.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
+.endm
+#endif /* CONFIG_CACHE_L2X0 */
 #else
+void tegra_resume(void);
+int tegra_sleep_cpu_finish(unsigned long);
 
 #ifdef CONFIG_HOTPLUG_CPU
 void tegra20_hotplug_init(void);
@@ -81,5 +115,8 @@
 static inline void tegra30_hotplug_init(void) {}
 #endif
 
+int tegra30_sleep_cpu_secondary_finish(unsigned long);
+void tegra30_tear_down_cpu(void);
+
 #endif
 #endif
diff --git a/arch/arm/mach-tegra/tegra20_clocks.c b/arch/arm/mach-tegra/tegra20_clocks.c
index deb873f..4eb6bc8 100644
--- a/arch/arm/mach-tegra/tegra20_clocks.c
+++ b/arch/arm/mach-tegra/tegra20_clocks.c
@@ -27,10 +27,9 @@
 #include <linux/clkdev.h>
 #include <linux/clk.h>
 
-#include <mach/iomap.h>
-
 #include "clock.h"
 #include "fuse.h"
+#include "iomap.h"
 #include "tegra2_emc.h"
 #include "tegra_cpu_car.h"
 
diff --git a/arch/arm/mach-tegra/tegra20_clocks_data.c b/arch/arm/mach-tegra/tegra20_clocks_data.c
index 8d398a3..a23a073 100644
--- a/arch/arm/mach-tegra/tegra20_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra20_clocks_data.c
@@ -27,8 +27,6 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 
-#include <mach/iomap.h>
-
 #include "clock.h"
 #include "fuse.h"
 #include "tegra2_emc.h"
@@ -248,11 +246,16 @@
 	{ 19200000, 216000000, 135, 12, 1, 3},
 	{ 26000000, 216000000, 216, 26, 1, 4},
 
+	{ 12000000, 297000000,  99,  4, 1, 4 },
+	{ 12000000, 339000000, 113,  4, 1, 4 },
+
 	{ 12000000, 594000000, 594, 12, 1, 8},
 	{ 13000000, 594000000, 594, 13, 1, 8},
 	{ 19200000, 594000000, 495, 16, 1, 8},
 	{ 26000000, 594000000, 594, 26, 1, 8},
 
+	{ 12000000, 616000000, 616, 12, 1, 8},
+
 	{ 12000000, 1000000000, 1000, 12, 1, 12},
 	{ 13000000, 1000000000, 1000, 13, 1, 12},
 	{ 19200000, 1000000000, 625,  12, 1, 8},
@@ -1038,9 +1041,6 @@
 	CLK_DUPLICATE("usbd",	"utmip-pad",	NULL),
 	CLK_DUPLICATE("usbd",	"tegra-ehci.0",	NULL),
 	CLK_DUPLICATE("usbd",	"tegra-otg",	NULL),
-	CLK_DUPLICATE("hdmi",	"tegradc.0",	"hdmi"),
-	CLK_DUPLICATE("hdmi",	"tegradc.1",	"hdmi"),
-	CLK_DUPLICATE("host1x",	"tegra_grhost",	"host1x"),
 	CLK_DUPLICATE("2d",	"tegra_grhost",	"gr2d"),
 	CLK_DUPLICATE("3d",	"tegra_grhost",	"gr3d"),
 	CLK_DUPLICATE("epp",	"tegra_grhost",	"epp"),
@@ -1053,6 +1053,9 @@
 	CLK_DUPLICATE("pll_p_out3", "tegra-i2c.1", "fast-clk"),
 	CLK_DUPLICATE("pll_p_out3", "tegra-i2c.2", "fast-clk"),
 	CLK_DUPLICATE("pll_p_out3", "tegra-i2c.3", "fast-clk"),
+	CLK_DUPLICATE("pll_p", "tegradc.0", "parent"),
+	CLK_DUPLICATE("pll_p", "tegradc.1", "parent"),
+	CLK_DUPLICATE("pll_d_out0", "hdmi", "parent"),
 };
 
 #define CLK(dev, con, ck)	\
diff --git a/arch/arm/mach-tegra/tegra20_speedo.c b/arch/arm/mach-tegra/tegra20_speedo.c
new file mode 100644
index 0000000..fa6eb57
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra20_speedo.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bug.h>
+
+#include "fuse.h"
+
+#define CPU_SPEEDO_LSBIT		20
+#define CPU_SPEEDO_MSBIT		29
+#define CPU_SPEEDO_REDUND_LSBIT		30
+#define CPU_SPEEDO_REDUND_MSBIT		39
+#define CPU_SPEEDO_REDUND_OFFS	(CPU_SPEEDO_REDUND_MSBIT - CPU_SPEEDO_MSBIT)
+
+#define CORE_SPEEDO_LSBIT		40
+#define CORE_SPEEDO_MSBIT		47
+#define CORE_SPEEDO_REDUND_LSBIT	48
+#define CORE_SPEEDO_REDUND_MSBIT	55
+#define CORE_SPEEDO_REDUND_OFFS	(CORE_SPEEDO_REDUND_MSBIT - CORE_SPEEDO_MSBIT)
+
+#define SPEEDO_MULT			4
+
+#define PROCESS_CORNERS_NUM		4
+
+#define SPEEDO_ID_SELECT_0(rev)		((rev) <= 2)
+#define SPEEDO_ID_SELECT_1(sku)		\
+	(((sku) != 20) && ((sku) != 23) && ((sku) != 24) && \
+	 ((sku) != 27) && ((sku) != 28))
+
+enum {
+	SPEEDO_ID_0,
+	SPEEDO_ID_1,
+	SPEEDO_ID_2,
+	SPEEDO_ID_COUNT,
+};
+
+static const u32 cpu_process_speedos[][PROCESS_CORNERS_NUM] = {
+	{315, 366, 420, UINT_MAX},
+	{303, 368, 419, UINT_MAX},
+	{316, 331, 383, UINT_MAX},
+};
+
+static const u32 core_process_speedos[][PROCESS_CORNERS_NUM] = {
+	{165, 195, 224, UINT_MAX},
+	{165, 195, 224, UINT_MAX},
+	{165, 195, 224, UINT_MAX},
+};
+
+void tegra20_init_speedo_data(void)
+{
+	u32 reg;
+	u32 val;
+	int i;
+
+	BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != SPEEDO_ID_COUNT);
+	BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != SPEEDO_ID_COUNT);
+
+	if (SPEEDO_ID_SELECT_0(tegra_revision))
+		tegra_soc_speedo_id = SPEEDO_ID_0;
+	else if (SPEEDO_ID_SELECT_1(tegra_sku_id))
+		tegra_soc_speedo_id = SPEEDO_ID_1;
+	else
+		tegra_soc_speedo_id = SPEEDO_ID_2;
+
+	val = 0;
+	for (i = CPU_SPEEDO_MSBIT; i >= CPU_SPEEDO_LSBIT; i--) {
+		reg = tegra_spare_fuse(i) |
+			tegra_spare_fuse(i + CPU_SPEEDO_REDUND_OFFS);
+		val = (val << 1) | (reg & 0x1);
+	}
+	val = val * SPEEDO_MULT;
+	pr_debug("%s CPU speedo value %u\n", __func__, val);
+
+	for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
+		if (val <= cpu_process_speedos[tegra_soc_speedo_id][i])
+			break;
+	}
+	tegra_cpu_process_id = i;
+
+	val = 0;
+	for (i = CORE_SPEEDO_MSBIT; i >= CORE_SPEEDO_LSBIT; i--) {
+		reg = tegra_spare_fuse(i) |
+			tegra_spare_fuse(i + CORE_SPEEDO_REDUND_OFFS);
+		val = (val << 1) | (reg & 0x1);
+	}
+	val = val * SPEEDO_MULT;
+	pr_debug("%s Core speedo value %u\n", __func__, val);
+
+	for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
+		if (val <= core_process_speedos[tegra_soc_speedo_id][i])
+			break;
+	}
+	tegra_core_process_id = i;
+
+	pr_info("Tegra20 Soc Speedo ID %d", tegra_soc_speedo_id);
+}
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
index 5070d83..837c7b9 100644
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -25,8 +25,6 @@
 #include <linux/platform_device.h>
 #include <linux/platform_data/tegra_emc.h>
 
-#include <mach/iomap.h>
-
 #include "tegra2_emc.h"
 #include "fuse.h"
 
diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c
index e9de5df..efc000e 100644
--- a/arch/arm/mach-tegra/tegra30_clocks.c
+++ b/arch/arm/mach-tegra/tegra30_clocks.c
@@ -31,10 +31,11 @@
 
 #include <asm/clkdev.h>
 
-#include <mach/iomap.h>
+#include <mach/powergate.h>
 
 #include "clock.h"
 #include "fuse.h"
+#include "iomap.h"
 #include "tegra_cpu_car.h"
 
 #define USE_PLL_LOCK_BITS 0
@@ -310,6 +311,31 @@
 #define CPU_CLOCK(cpu)	(0x1 << (8 + cpu))
 #define CPU_RESET(cpu)	(0x1111ul << (cpu))
 
+#define CLK_RESET_CCLK_BURST	0x20
+#define CLK_RESET_CCLK_DIVIDER  0x24
+#define CLK_RESET_PLLX_BASE	0xe0
+#define CLK_RESET_PLLX_MISC	0xe4
+
+#define CLK_RESET_SOURCE_CSITE	0x1d4
+
+#define CLK_RESET_CCLK_BURST_POLICY_SHIFT	28
+#define CLK_RESET_CCLK_RUN_POLICY_SHIFT		4
+#define CLK_RESET_CCLK_IDLE_POLICY_SHIFT	0
+#define CLK_RESET_CCLK_IDLE_POLICY		1
+#define CLK_RESET_CCLK_RUN_POLICY		2
+#define CLK_RESET_CCLK_BURST_POLICY_PLLX	8
+
+#ifdef CONFIG_PM_SLEEP
+static struct cpu_clk_suspend_context {
+	u32 pllx_misc;
+	u32 pllx_base;
+
+	u32 cpu_burst;
+	u32 clk_csite_src;
+	u32 cclk_divider;
+} tegra30_cpu_clk_sctx;
+#endif
+
 /**
 * Structure defining the fields for USB UTMI clocks Parameters.
 */
@@ -792,6 +818,112 @@
 	.recalc_rate = tegra30_twd_clk_recalc_rate,
 };
 
+/* bus clock functions */
+static int tegra30_bus_clk_is_enabled(struct clk_hw *hw)
+{
+	struct clk_tegra *c = to_clk_tegra(hw);
+	u32 val = clk_readl(c->reg);
+
+	c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
+	return c->state;
+}
+
+static int tegra30_bus_clk_enable(struct clk_hw *hw)
+{
+	struct clk_tegra *c = to_clk_tegra(hw);
+	u32 val;
+
+	val = clk_readl(c->reg);
+	val &= ~(BUS_CLK_DISABLE << c->reg_shift);
+	clk_writel(val, c->reg);
+
+	return 0;
+}
+
+static void tegra30_bus_clk_disable(struct clk_hw *hw)
+{
+	struct clk_tegra *c = to_clk_tegra(hw);
+	u32 val;
+
+	val = clk_readl(c->reg);
+	val |= BUS_CLK_DISABLE << c->reg_shift;
+	clk_writel(val, c->reg);
+}
+
+static unsigned long tegra30_bus_clk_recalc_rate(struct clk_hw *hw,
+			unsigned long prate)
+{
+	struct clk_tegra *c = to_clk_tegra(hw);
+	u32 val = clk_readl(c->reg);
+	u64 rate = prate;
+
+	c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
+	c->mul = 1;
+
+	if (c->mul != 0 && c->div != 0) {
+		rate *= c->mul;
+		rate += c->div - 1; /* round up */
+		do_div(rate, c->div);
+	}
+	return rate;
+}
+
+static int tegra30_bus_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct clk_tegra *c = to_clk_tegra(hw);
+	int ret = -EINVAL;
+	u32 val;
+	int i;
+
+	val = clk_readl(c->reg);
+	for (i = 1; i <= 4; i++) {
+		if (rate == parent_rate / i) {
+			val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
+			val |= (i - 1) << c->reg_shift;
+			clk_writel(val, c->reg);
+			c->div = i;
+			c->mul = 1;
+			ret = 0;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static long tegra30_bus_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	unsigned long parent_rate = *prate;
+	s64 divider;
+
+	if (rate >= parent_rate)
+		return parent_rate;
+
+	divider = parent_rate;
+	divider += rate - 1;
+	do_div(divider, rate);
+
+	if (divider < 0)
+		return divider;
+
+	if (divider > 4)
+		divider = 4;
+	do_div(parent_rate, divider);
+
+	return parent_rate;
+}
+
+struct clk_ops tegra30_bus_ops = {
+	.is_enabled = tegra30_bus_clk_is_enabled,
+	.enable = tegra30_bus_clk_enable,
+	.disable = tegra30_bus_clk_disable,
+	.set_rate = tegra30_bus_clk_set_rate,
+	.round_rate = tegra30_bus_clk_round_rate,
+	.recalc_rate = tegra30_bus_clk_recalc_rate,
+};
+
 /* Blink output functions */
 static int tegra30_blink_clk_is_enabled(struct clk_hw *hw)
 {
@@ -2281,12 +2413,93 @@
 	       reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
 }
 
+#ifdef CONFIG_PM_SLEEP
+static bool tegra30_cpu_rail_off_ready(void)
+{
+	unsigned int cpu_rst_status;
+	int cpu_pwr_status;
+
+	cpu_rst_status = readl(reg_clk_base +
+			       TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS);
+	cpu_pwr_status = tegra_powergate_is_powered(TEGRA_POWERGATE_CPU1) ||
+			 tegra_powergate_is_powered(TEGRA_POWERGATE_CPU2) ||
+			 tegra_powergate_is_powered(TEGRA_POWERGATE_CPU3);
+
+	if (((cpu_rst_status & 0xE) != 0xE) || cpu_pwr_status)
+		return false;
+
+	return true;
+}
+
+static void tegra30_cpu_clock_suspend(void)
+{
+	/* switch coresite to clk_m, save off original source */
+	tegra30_cpu_clk_sctx.clk_csite_src =
+				readl(reg_clk_base + CLK_RESET_SOURCE_CSITE);
+	writel(3<<30, reg_clk_base + CLK_RESET_SOURCE_CSITE);
+
+	tegra30_cpu_clk_sctx.cpu_burst =
+				readl(reg_clk_base + CLK_RESET_CCLK_BURST);
+	tegra30_cpu_clk_sctx.pllx_base =
+				readl(reg_clk_base + CLK_RESET_PLLX_BASE);
+	tegra30_cpu_clk_sctx.pllx_misc =
+				readl(reg_clk_base + CLK_RESET_PLLX_MISC);
+	tegra30_cpu_clk_sctx.cclk_divider =
+				readl(reg_clk_base + CLK_RESET_CCLK_DIVIDER);
+}
+
+static void tegra30_cpu_clock_resume(void)
+{
+	unsigned int reg, policy;
+
+	/* Is CPU complex already running on PLLX? */
+	reg = readl(reg_clk_base + CLK_RESET_CCLK_BURST);
+	policy = (reg >> CLK_RESET_CCLK_BURST_POLICY_SHIFT) & 0xF;
+
+	if (policy == CLK_RESET_CCLK_IDLE_POLICY)
+		reg = (reg >> CLK_RESET_CCLK_IDLE_POLICY_SHIFT) & 0xF;
+	else if (policy == CLK_RESET_CCLK_RUN_POLICY)
+		reg = (reg >> CLK_RESET_CCLK_RUN_POLICY_SHIFT) & 0xF;
+	else
+		BUG();
+
+	if (reg != CLK_RESET_CCLK_BURST_POLICY_PLLX) {
+		/* restore PLLX settings if CPU is on different PLL */
+		writel(tegra30_cpu_clk_sctx.pllx_misc,
+					reg_clk_base + CLK_RESET_PLLX_MISC);
+		writel(tegra30_cpu_clk_sctx.pllx_base,
+					reg_clk_base + CLK_RESET_PLLX_BASE);
+
+		/* wait for PLL stabilization if PLLX was enabled */
+		if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30))
+			udelay(300);
+	}
+
+	/*
+	 * Restore original burst policy setting for calls resulting from CPU
+	 * LP2 in idle or system suspend.
+	 */
+	writel(tegra30_cpu_clk_sctx.cclk_divider,
+					reg_clk_base + CLK_RESET_CCLK_DIVIDER);
+	writel(tegra30_cpu_clk_sctx.cpu_burst,
+					reg_clk_base + CLK_RESET_CCLK_BURST);
+
+	writel(tegra30_cpu_clk_sctx.clk_csite_src,
+					reg_clk_base + CLK_RESET_SOURCE_CSITE);
+}
+#endif
+
 static struct tegra_cpu_car_ops tegra30_cpu_car_ops = {
 	.wait_for_reset	= tegra30_wait_cpu_in_reset,
 	.put_in_reset	= tegra30_put_cpu_in_reset,
 	.out_of_reset	= tegra30_cpu_out_of_reset,
 	.enable_clock	= tegra30_enable_cpu_clock,
 	.disable_clock	= tegra30_disable_cpu_clock,
+#ifdef CONFIG_PM_SLEEP
+	.rail_off_ready	= tegra30_cpu_rail_off_ready,
+	.suspend	= tegra30_cpu_clock_suspend,
+	.resume		= tegra30_cpu_clock_resume,
+#endif
 };
 
 void __init tegra30_cpu_car_ops_init(void)
diff --git a/arch/arm/mach-tegra/tegra30_clocks.h b/arch/arm/mach-tegra/tegra30_clocks.h
index f2f88fe..7a34adb 100644
--- a/arch/arm/mach-tegra/tegra30_clocks.h
+++ b/arch/arm/mach-tegra/tegra30_clocks.h
@@ -34,6 +34,7 @@
 extern struct clk_ops tegra30_super_ops;
 extern struct clk_ops tegra30_blink_clk_ops;
 extern struct clk_ops tegra30_twd_ops;
+extern struct clk_ops tegra30_bus_ops;
 extern struct clk_ops tegra30_periph_clk_ops;
 extern struct clk_ops tegra30_dsib_clk_ops;
 extern struct clk_ops tegra_nand_clk_ops;
diff --git a/arch/arm/mach-tegra/tegra30_clocks_data.c b/arch/arm/mach-tegra/tegra30_clocks_data.c
index 3d2e553..6942c7a 100644
--- a/arch/arm/mach-tegra/tegra30_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra30_clocks_data.c
@@ -711,6 +711,50 @@
 	.num_parents = ARRAY_SIZE(mux_sclk),
 };
 
+static const char *tegra_hclk_parent_names[] = {
+	"tegra_sclk",
+};
+
+static struct clk *tegra_hclk_parents[] = {
+	&tegra_clk_sclk,
+};
+
+static struct clk tegra_hclk;
+static struct clk_tegra tegra_hclk_hw = {
+	.hw = {
+		.clk = &tegra_hclk,
+	},
+	.flags = DIV_BUS,
+	.reg = 0x30,
+	.reg_shift = 4,
+	.max_rate = 378000000,
+	.min_rate = 12000000,
+};
+DEFINE_CLK_TEGRA(hclk, 0, &tegra30_bus_ops, 0, tegra_hclk_parent_names,
+		tegra_hclk_parents, &tegra_clk_sclk);
+
+static const char *tegra_pclk_parent_names[] = {
+	"tegra_hclk",
+};
+
+static struct clk *tegra_pclk_parents[] = {
+	&tegra_hclk,
+};
+
+static struct clk tegra_pclk;
+static struct clk_tegra tegra_pclk_hw = {
+	.hw = {
+		.clk = &tegra_pclk,
+	},
+	.flags = DIV_BUS,
+	.reg = 0x30,
+	.reg_shift = 0,
+	.max_rate = 167000000,
+	.min_rate = 12000000,
+};
+DEFINE_CLK_TEGRA(pclk, 0, &tegra30_bus_ops, 0, tegra_pclk_parent_names,
+		tegra_pclk_parents, &tegra_hclk);
+
 static const char *mux_blink[] = {
 	"clk_32k",
 };
@@ -1254,8 +1298,6 @@
 	CLK_DUPLICATE("usbd", "utmip-pad", NULL),
 	CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
 	CLK_DUPLICATE("usbd", "tegra-otg", NULL),
-	CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
-	CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
 	CLK_DUPLICATE("dsib", "tegradc.0", "dsib"),
 	CLK_DUPLICATE("dsia", "tegradc.1", "dsia"),
 	CLK_DUPLICATE("bsev", "tegra-avp", "bsev"),
@@ -1293,6 +1335,9 @@
 	CLK_DUPLICATE("pll_p_out3", "tegra-i2c.2", "fast-clk"),
 	CLK_DUPLICATE("pll_p_out3", "tegra-i2c.3", "fast-clk"),
 	CLK_DUPLICATE("pll_p_out3", "tegra-i2c.4", "fast-clk"),
+	CLK_DUPLICATE("pll_p", "tegradc.0", "parent"),
+	CLK_DUPLICATE("pll_p", "tegradc.1", "parent"),
+	CLK_DUPLICATE("pll_d2_out0", "hdmi", "parent"),
 };
 
 struct clk *tegra_ptr_clks[] = {
@@ -1325,6 +1370,8 @@
 	&tegra_cml1,
 	&tegra_pciex,
 	&tegra_clk_sclk,
+	&tegra_hclk,
+	&tegra_pclk,
 	&tegra_clk_blink,
 	&tegra30_clk_twd,
 };
diff --git a/arch/arm/mach-tegra/tegra30_speedo.c b/arch/arm/mach-tegra/tegra30_speedo.c
new file mode 100644
index 0000000..125cb16
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra30_speedo.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bug.h>
+
+#include "fuse.h"
+
+#define CORE_PROCESS_CORNERS_NUM	1
+#define CPU_PROCESS_CORNERS_NUM		6
+
+#define FUSE_SPEEDO_CALIB_0	0x114
+#define FUSE_PACKAGE_INFO	0X1FC
+#define FUSE_TEST_PROG_VER	0X128
+
+#define G_SPEEDO_BIT_MINUS1	58
+#define G_SPEEDO_BIT_MINUS1_R	59
+#define G_SPEEDO_BIT_MINUS2	60
+#define G_SPEEDO_BIT_MINUS2_R	61
+#define LP_SPEEDO_BIT_MINUS1	62
+#define LP_SPEEDO_BIT_MINUS1_R	63
+#define LP_SPEEDO_BIT_MINUS2	64
+#define LP_SPEEDO_BIT_MINUS2_R	65
+
+enum {
+	THRESHOLD_INDEX_0,
+	THRESHOLD_INDEX_1,
+	THRESHOLD_INDEX_2,
+	THRESHOLD_INDEX_3,
+	THRESHOLD_INDEX_4,
+	THRESHOLD_INDEX_5,
+	THRESHOLD_INDEX_6,
+	THRESHOLD_INDEX_7,
+	THRESHOLD_INDEX_8,
+	THRESHOLD_INDEX_9,
+	THRESHOLD_INDEX_10,
+	THRESHOLD_INDEX_11,
+	THRESHOLD_INDEX_COUNT,
+};
+
+static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
+	{180},
+	{170},
+	{195},
+	{180},
+	{168},
+	{192},
+	{180},
+	{170},
+	{195},
+	{180},
+	{180},
+	{180},
+};
+
+static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
+	{306, 338, 360, 376, UINT_MAX},
+	{295, 336, 358, 375, UINT_MAX},
+	{325, 325, 358, 375, UINT_MAX},
+	{325, 325, 358, 375, UINT_MAX},
+	{292, 324, 348, 364, UINT_MAX},
+	{324, 324, 348, 364, UINT_MAX},
+	{324, 324, 348, 364, UINT_MAX},
+	{295, 336, 358, 375, UINT_MAX},
+	{358, 358, 358, 358, 397, UINT_MAX},
+	{364, 364, 364, 364, 397, UINT_MAX},
+	{295, 336, 358, 375, 391, UINT_MAX},
+	{295, 336, 358, 375, 391, UINT_MAX},
+};
+
+static int threshold_index;
+static int package_id;
+
+static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
+{
+	u32 reg;
+	int ate_ver;
+	int bit_minus1;
+	int bit_minus2;
+
+	reg = tegra_fuse_readl(FUSE_SPEEDO_CALIB_0);
+
+	*speedo_lp = (reg & 0xFFFF) * 4;
+	*speedo_g = ((reg >> 16) & 0xFFFF) * 4;
+
+	ate_ver = tegra_fuse_readl(FUSE_TEST_PROG_VER);
+	pr_info("%s: ATE prog ver %d.%d\n", __func__, ate_ver/10, ate_ver%10);
+
+	if (ate_ver >= 26) {
+		bit_minus1 = tegra_spare_fuse(LP_SPEEDO_BIT_MINUS1);
+		bit_minus1 |= tegra_spare_fuse(LP_SPEEDO_BIT_MINUS1_R);
+		bit_minus2 = tegra_spare_fuse(LP_SPEEDO_BIT_MINUS2);
+		bit_minus2 |= tegra_spare_fuse(LP_SPEEDO_BIT_MINUS2_R);
+		*speedo_lp |= (bit_minus1 << 1) | bit_minus2;
+
+		bit_minus1 = tegra_spare_fuse(G_SPEEDO_BIT_MINUS1);
+		bit_minus1 |= tegra_spare_fuse(G_SPEEDO_BIT_MINUS1_R);
+		bit_minus2 = tegra_spare_fuse(G_SPEEDO_BIT_MINUS2);
+		bit_minus2 |= tegra_spare_fuse(G_SPEEDO_BIT_MINUS2_R);
+		*speedo_g |= (bit_minus1 << 1) | bit_minus2;
+	} else {
+		*speedo_lp |= 0x3;
+		*speedo_g |= 0x3;
+	}
+}
+
+static void rev_sku_to_speedo_ids(int rev, int sku)
+{
+	switch (rev) {
+	case TEGRA_REVISION_A01:
+		tegra_cpu_speedo_id = 0;
+		tegra_soc_speedo_id = 0;
+		threshold_index = THRESHOLD_INDEX_0;
+		break;
+	case TEGRA_REVISION_A02:
+	case TEGRA_REVISION_A03:
+		switch (sku) {
+		case 0x87:
+		case 0x82:
+			tegra_cpu_speedo_id = 1;
+			tegra_soc_speedo_id = 1;
+			threshold_index = THRESHOLD_INDEX_1;
+			break;
+		case 0x81:
+			switch (package_id) {
+			case 1:
+				tegra_cpu_speedo_id = 2;
+				tegra_soc_speedo_id = 2;
+				threshold_index = THRESHOLD_INDEX_2;
+				break;
+			case 2:
+				tegra_cpu_speedo_id = 4;
+				tegra_soc_speedo_id = 1;
+				threshold_index = THRESHOLD_INDEX_7;
+				break;
+			default:
+				pr_err("Tegra30: Unknown pkg %d\n", package_id);
+				BUG();
+				break;
+			}
+			break;
+		case 0x80:
+			switch (package_id) {
+			case 1:
+				tegra_cpu_speedo_id = 5;
+				tegra_soc_speedo_id = 2;
+				threshold_index = THRESHOLD_INDEX_8;
+				break;
+			case 2:
+				tegra_cpu_speedo_id = 6;
+				tegra_soc_speedo_id = 2;
+				threshold_index = THRESHOLD_INDEX_9;
+				break;
+			default:
+				pr_err("Tegra30: Unknown pkg %d\n", package_id);
+				BUG();
+				break;
+			}
+			break;
+		case 0x83:
+			switch (package_id) {
+			case 1:
+				tegra_cpu_speedo_id = 7;
+				tegra_soc_speedo_id = 1;
+				threshold_index = THRESHOLD_INDEX_10;
+				break;
+			case 2:
+				tegra_cpu_speedo_id = 3;
+				tegra_soc_speedo_id = 2;
+				threshold_index = THRESHOLD_INDEX_3;
+				break;
+			default:
+				pr_err("Tegra30: Unknown pkg %d\n", package_id);
+				BUG();
+				break;
+			}
+			break;
+		case 0x8F:
+			tegra_cpu_speedo_id = 8;
+			tegra_soc_speedo_id = 1;
+			threshold_index = THRESHOLD_INDEX_11;
+			break;
+		case 0x08:
+			tegra_cpu_speedo_id = 1;
+			tegra_soc_speedo_id = 1;
+			threshold_index = THRESHOLD_INDEX_4;
+			break;
+		case 0x02:
+			tegra_cpu_speedo_id = 2;
+			tegra_soc_speedo_id = 2;
+			threshold_index = THRESHOLD_INDEX_5;
+			break;
+		case 0x04:
+			tegra_cpu_speedo_id = 3;
+			tegra_soc_speedo_id = 2;
+			threshold_index = THRESHOLD_INDEX_6;
+			break;
+		case 0:
+			switch (package_id) {
+			case 1:
+				tegra_cpu_speedo_id = 2;
+				tegra_soc_speedo_id = 2;
+				threshold_index = THRESHOLD_INDEX_2;
+				break;
+			case 2:
+				tegra_cpu_speedo_id = 3;
+				tegra_soc_speedo_id = 2;
+				threshold_index = THRESHOLD_INDEX_3;
+				break;
+			default:
+				pr_err("Tegra30: Unknown pkg %d\n", package_id);
+				BUG();
+				break;
+			}
+			break;
+		default:
+			pr_warn("Tegra30: Unknown SKU %d\n", sku);
+			tegra_cpu_speedo_id = 0;
+			tegra_soc_speedo_id = 0;
+			threshold_index = THRESHOLD_INDEX_0;
+			break;
+		}
+		break;
+	default:
+		pr_warn("Tegra30: Unknown chip rev %d\n", rev);
+		tegra_cpu_speedo_id = 0;
+		tegra_soc_speedo_id = 0;
+		threshold_index = THRESHOLD_INDEX_0;
+		break;
+	}
+}
+
+void tegra30_init_speedo_data(void)
+{
+	u32 cpu_speedo_val;
+	u32 core_speedo_val;
+	int i;
+
+	BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
+			THRESHOLD_INDEX_COUNT);
+	BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
+			THRESHOLD_INDEX_COUNT);
+
+	package_id = tegra_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
+
+	rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id);
+	fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val);
+	pr_debug("%s CPU speedo value %u\n", __func__, cpu_speedo_val);
+	pr_debug("%s Core speedo value %u\n", __func__, core_speedo_val);
+
+	for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++) {
+		if (cpu_speedo_val < cpu_process_speedos[threshold_index][i])
+			break;
+	}
+	tegra_cpu_process_id = i - 1;
+
+	if (tegra_cpu_process_id == -1) {
+		pr_warn("Tegra30: CPU speedo value %3d out of range",
+		       cpu_speedo_val);
+		tegra_cpu_process_id = 0;
+		tegra_cpu_speedo_id = 1;
+	}
+
+	for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++) {
+		if (core_speedo_val < core_process_speedos[threshold_index][i])
+			break;
+	}
+	tegra_core_process_id = i - 1;
+
+	if (tegra_core_process_id == -1) {
+		pr_warn("Tegra30: CORE speedo value %3d out of range",
+		       core_speedo_val);
+		tegra_core_process_id = 0;
+		tegra_soc_speedo_id = 1;
+	}
+
+	pr_info("Tegra30: CPU Speedo ID %d, Soc Speedo ID %d",
+		tegra_cpu_speedo_id, tegra_soc_speedo_id);
+}
diff --git a/arch/arm/mach-tegra/tegra_cpu_car.h b/arch/arm/mach-tegra/tegra_cpu_car.h
index 30d063a..9764d31 100644
--- a/arch/arm/mach-tegra/tegra_cpu_car.h
+++ b/arch/arm/mach-tegra/tegra_cpu_car.h
@@ -30,6 +30,12 @@
  *	CPU clock un-gate
  * disable_clock:
  *	CPU clock gate
+ * rail_off_ready:
+ *	CPU is ready for rail off
+ * suspend:
+ *	save the clock settings when CPU go into low-power state
+ * resume:
+ *	restore the clock settings when CPU exit low-power state
  */
 struct tegra_cpu_car_ops {
 	void (*wait_for_reset)(u32 cpu);
@@ -37,6 +43,11 @@
 	void (*out_of_reset)(u32 cpu);
 	void (*enable_clock)(u32 cpu);
 	void (*disable_clock)(u32 cpu);
+#ifdef CONFIG_PM_SLEEP
+	bool (*rail_off_ready)(void);
+	void (*suspend)(void);
+	void (*resume)(void);
+#endif
 };
 
 extern struct tegra_cpu_car_ops *tegra_cpu_car_ops;
@@ -81,6 +92,32 @@
 	tegra_cpu_car_ops->disable_clock(cpu);
 }
 
+#ifdef CONFIG_PM_SLEEP
+static inline bool tegra_cpu_rail_off_ready(void)
+{
+	if (WARN_ON(!tegra_cpu_car_ops->rail_off_ready))
+		return false;
+
+	return tegra_cpu_car_ops->rail_off_ready();
+}
+
+static inline void tegra_cpu_clock_suspend(void)
+{
+	if (WARN_ON(!tegra_cpu_car_ops->suspend))
+		return;
+
+	tegra_cpu_car_ops->suspend();
+}
+
+static inline void tegra_cpu_clock_resume(void)
+{
+	if (WARN_ON(!tegra_cpu_car_ops->resume))
+		return;
+
+	tegra_cpu_car_ops->resume();
+}
+#endif
+
 void tegra20_cpu_car_ops_init(void);
 void tegra30_cpu_car_ops_init(void);
 
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
index d3b8c8e..6ff5035 100644
--- a/arch/arm/mach-tegra/timer.c
+++ b/arch/arm/mach-tegra/timer.c
@@ -31,11 +31,11 @@
 #include <asm/smp_twd.h>
 #include <asm/sched_clock.h>
 
-#include <mach/iomap.h>
 #include <mach/irqs.h>
 
 #include "board.h"
 #include "clock.h"
+#include "iomap.h"
 
 #define RTC_SECONDS            0x08
 #define RTC_SHADOW_SECONDS     0x0c
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 416d436..e4dad22 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (C) 2008-2009 ST-Ericsson
+ * Copyright (C) 2008-2012 ST-Ericsson
  *
  * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
  *
@@ -701,6 +700,16 @@
 	.init_late	= ux500_init_late,
 MACHINE_END
 
+MACHINE_START(U8520, "ST-Ericsson U8520 Platform HREFP520")
+	.atag_offset	= 0x100,
+	.map_io		= u8500_map_io,
+	.init_irq	= ux500_init_irq,
+	.timer		= &ux500_timer,
+	.handle_irq	= gic_handle_irq,
+	.init_machine	= mop500_init_machine,
+	.init_late	= ux500_init_late,
+MACHINE_END
+
 MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")
 	.atag_offset	= 0x100,
 	.smp		= smp_ops(ux500_smp_ops),
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index bcdfe6b..50202a1 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -17,6 +17,8 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/mfd/abx500/ab8500.h>
+#include <linux/platform_data/usb-musb-ux500.h>
+#include <linux/random.h>
 
 #include <asm/pmu.h>
 #include <asm/mach/map.h>
@@ -24,7 +26,6 @@
 #include <mach/hardware.h>
 #include <mach/setup.h>
 #include <mach/devices.h>
-#include <linux/platform_data/usb-musb-ux500.h>
 #include <mach/db8500-regs.h>
 
 #include "devices-db8500.h"
@@ -187,6 +188,8 @@
 {
 	void __iomem *uid = __io_address(U8500_BB_UID_BASE);
 
+	/* Throw these device-specific numbers into the entropy pool */
+	add_device_randomness(uid, 0x14);
 	return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x",
 			 readl((u32 *)uid+1),
 			 readl((u32 *)uid+1), readl((u32 *)uid+2),
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index 2236cbd..1f3fbc2 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -16,6 +16,7 @@
 #include <linux/stat.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
+#include <linux/irq.h>
 #include <linux/platform_data/clk-ux500.h>
 
 #include <asm/hardware/gic.h>
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index c952960..99e63f5 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -1,11 +1,12 @@
 config ARCH_VEXPRESS
 	bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7
-	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select ARCH_REQUIRE_GPIOLIB
 	select ARM_AMBA
 	select ARM_GIC
 	select ARM_TIMER_SP804
 	select CLKDEV_LOOKUP
 	select COMMON_CLK
+	select COMMON_CLK_VERSATILE
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
@@ -17,6 +18,7 @@
 	select PLAT_VERSATILE
 	select PLAT_VERSATILE_CLCD
 	select REGULATOR_FIXED_VOLTAGE if REGULATOR
+	select VEXPRESS_CONFIG
 	help
 	  This option enables support for systems using Cortex processor based
 	  ARM core and logic (FPGA) tiles on the Versatile Express motherboard,
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 42703e8..80b6497 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -4,7 +4,7 @@
 ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
 	-I$(srctree)/arch/arm/plat-versatile/include
 
-obj-y					:= v2m.o
+obj-y					:= v2m.o reset.o
 obj-$(CONFIG_ARCH_VEXPRESS_CA9X4)	+= ct-ca9x4.o
 obj-$(CONFIG_SMP)			+= platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 4f471fa..60838dd 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -9,6 +9,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
 #include <linux/clkdev.h>
+#include <linux/vexpress.h>
 
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -64,19 +65,6 @@
 	ca9x4_twd_init();
 }
 
-static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
-{
-	u32 site = v2m_get_master_site();
-
-	/*
-	 * Old firmware was using the "site" component of the command
-	 * to control the DVI muxer (while it should be always 0 ie. MB).
-	 * Newer firmware uses the data register. Keep both for compatibility.
-	 */
-	v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE(site), site);
-	v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE(SYS_CFG_SITE_MB), 2);
-}
-
 static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
 {
 	unsigned long framesize = 1024 * 768 * 2;
@@ -93,7 +81,6 @@
 	.caps		= CLCD_CAP_5551 | CLCD_CAP_565,
 	.check		= clcdfb_check,
 	.decode		= clcdfb_decode,
-	.enable		= ct_ca9x4_clcd_enable,
 	.setup		= ct_ca9x4_clcd_setup,
 	.mmap		= versatile_clcd_mmap_dma,
 	.remove		= versatile_clcd_remove_dma,
@@ -111,14 +98,6 @@
 	&gpio_device,
 };
 
-
-static struct v2m_osc ct_osc1 = {
-	.osc = 1,
-	.rate_min = 10000000,
-	.rate_max = 80000000,
-	.rate_default = 23750000,
-};
-
 static struct resource pmu_resources[] = {
 	[0] = {
 		.start	= IRQ_CT_CA9X4_PMU_CPU0,
@@ -149,10 +128,18 @@
 	.resource	= pmu_resources,
 };
 
+static struct platform_device osc1_device = {
+	.name		= "vexpress-osc",
+	.id		= 1,
+	.num_resources	= 1,
+	.resource	= (struct resource []) {
+		VEXPRESS_RES_FUNC(0xf, 1),
+	},
+};
+
 static void __init ct_ca9x4_init(void)
 {
 	int i;
-	struct clk *clk;
 
 #ifdef CONFIG_CACHE_L2X0
 	void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
@@ -164,14 +151,14 @@
 	l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
 #endif
 
-	ct_osc1.site = v2m_get_master_site();
-	clk = v2m_osc_register("ct:osc1", &ct_osc1);
-	clk_register_clkdev(clk, NULL, "ct:clcd");
-
 	for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
 		amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
 
 	platform_device_register(&pmu_device);
+	platform_device_register(&osc1_device);
+
+	WARN_ON(clk_register_clkdev(vexpress_osc_setup(&osc1_device.dev),
+			NULL, "ct:clcd"));
 }
 
 #ifdef CONFIG_SMP
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
index 1e388c7..68abc8b 100644
--- a/arch/arm/mach-vexpress/include/mach/motherboard.h
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -1,8 +1,6 @@
 #ifndef __MACH_MOTHERBOARD_H
 #define __MACH_MOTHERBOARD_H
 
-#include <linux/clk-provider.h>
-
 /*
  * Physical addresses, offset from V2M_PA_CS0-3
  */
@@ -41,31 +39,6 @@
 #define V2M_CF			(V2M_PA_CS7 + 0x0001a000)
 #define V2M_CLCD		(V2M_PA_CS7 + 0x0001f000)
 
-/*
- * Offsets from SYSREGS base
- */
-#define V2M_SYS_ID		0x000
-#define V2M_SYS_SW		0x004
-#define V2M_SYS_LED		0x008
-#define V2M_SYS_100HZ		0x024
-#define V2M_SYS_FLAGS		0x030
-#define V2M_SYS_FLAGSSET	0x030
-#define V2M_SYS_FLAGSCLR	0x034
-#define V2M_SYS_NVFLAGS		0x038
-#define V2M_SYS_NVFLAGSSET	0x038
-#define V2M_SYS_NVFLAGSCLR	0x03c
-#define V2M_SYS_MCI		0x048
-#define V2M_SYS_FLASH		0x03c
-#define V2M_SYS_CFGSW		0x058
-#define V2M_SYS_24MHZ		0x05c
-#define V2M_SYS_MISC		0x060
-#define V2M_SYS_DMA		0x064
-#define V2M_SYS_PROCID0		0x084
-#define V2M_SYS_PROCID1		0x088
-#define V2M_SYS_CFGDATA		0x0a0
-#define V2M_SYS_CFGCTRL		0x0a4
-#define V2M_SYS_CFGSTAT		0x0a8
-
 
 /*
  * Interrupts.  Those in {} are for AMBA devices
@@ -91,43 +64,6 @@
 
 
 /*
- * Configuration
- */
-#define SYS_CFG_START		(1 << 31)
-#define SYS_CFG_WRITE		(1 << 30)
-#define SYS_CFG_OSC		(1 << 20)
-#define SYS_CFG_VOLT		(2 << 20)
-#define SYS_CFG_AMP		(3 << 20)
-#define SYS_CFG_TEMP		(4 << 20)
-#define SYS_CFG_RESET		(5 << 20)
-#define SYS_CFG_SCC		(6 << 20)
-#define SYS_CFG_MUXFPGA		(7 << 20)
-#define SYS_CFG_SHUTDOWN	(8 << 20)
-#define SYS_CFG_REBOOT		(9 << 20)
-#define SYS_CFG_DVIMODE		(11 << 20)
-#define SYS_CFG_POWER		(12 << 20)
-#define SYS_CFG_SITE(n)		((n) << 16)
-#define SYS_CFG_SITE_MB		0
-#define SYS_CFG_SITE_DB1	1
-#define SYS_CFG_SITE_DB2	2
-#define SYS_CFG_STACK(n)	((n) << 12)
-
-#define SYS_CFG_ERR		(1 << 1)
-#define SYS_CFG_COMPLETE	(1 << 0)
-
-int v2m_cfg_write(u32 devfn, u32 data);
-int v2m_cfg_read(u32 devfn, u32 *data);
-void v2m_flags_set(u32 data);
-
-/*
- * Miscellaneous
- */
-#define SYS_MISC_MASTERSITE	(1 << 14)
-#define SYS_PROCIDx_HBI_MASK	0xfff
-
-int v2m_get_master_site(void);
-
-/*
  * Core tile IDs
  */
 #define V2M_CT_ID_CA9		0x0c000191
@@ -149,21 +85,4 @@
 
 extern struct ct_desc *ct_desc;
 
-/*
- * OSC clock provider
- */
-struct v2m_osc {
-	struct clk_hw hw;
-	u8 site; /* 0 = motherboard, 1 = site 1, 2 = site 2 */
-	u8 stack; /* board stack position */
-	u16 osc;
-	unsigned long rate_min;
-	unsigned long rate_max;
-	unsigned long rate_default;
-};
-
-#define to_v2m_osc(osc) container_of(osc, struct v2m_osc, hw)
-
-struct clk *v2m_osc_register(const char *name, struct v2m_osc *osc);
-
 #endif
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 7db27c8..c5d70de 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -13,6 +13,7 @@
 #include <linux/smp.h>
 #include <linux/io.h>
 #include <linux/of_fdt.h>
+#include <linux/vexpress.h>
 
 #include <asm/smp_scu.h>
 #include <asm/hardware/gic.h>
@@ -193,7 +194,7 @@
 	 * until it receives a soft interrupt, and then the
 	 * secondary CPU branches to this address.
 	 */
-	v2m_flags_set(virt_to_phys(versatile_secondary_startup));
+	vexpress_flags_set(virt_to_phys(versatile_secondary_startup));
 }
 
 struct smp_operations __initdata vexpress_smp_ops = {
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 560e0df..4e168e8 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -16,11 +16,10 @@
 #include <linux/smsc911x.h>
 #include <linux/spinlock.h>
 #include <linux/usb/isp1760.h>
-#include <linux/clkdev.h>
-#include <linux/clk-provider.h>
 #include <linux/mtd/physmap.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
+#include <linux/vexpress.h>
 
 #include <asm/arch_timer.h>
 #include <asm/mach-types.h>
@@ -33,7 +32,6 @@
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/timer-sp.h>
-#include <asm/hardware/sp810.h>
 
 #include <mach/ct-ca9x4.h>
 #include <mach/motherboard.h>
@@ -58,22 +56,6 @@
 	},
 };
 
-static void __iomem *v2m_sysreg_base;
-
-static void __init v2m_sysctl_init(void __iomem *base)
-{
-	u32 scctrl;
-
-	if (WARN_ON(!base))
-		return;
-
-	/* Select 1MHz TIMCLK as the reference clock for SP804 timers */
-	scctrl = readl(base + SCCTRL);
-	scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
-	scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK;
-	writel(scctrl, base + SCCTRL);
-}
-
 static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
 {
 	if (WARN_ON(!base || irq == NO_IRQ))
@@ -87,69 +69,6 @@
 }
 
 
-static DEFINE_SPINLOCK(v2m_cfg_lock);
-
-int v2m_cfg_write(u32 devfn, u32 data)
-{
-	/* Configuration interface broken? */
-	u32 val;
-
-	printk("%s: writing %08x to %08x\n", __func__, data, devfn);
-
-	devfn |= SYS_CFG_START | SYS_CFG_WRITE;
-
-	spin_lock(&v2m_cfg_lock);
-	val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
-	writel(val & ~SYS_CFG_COMPLETE, v2m_sysreg_base + V2M_SYS_CFGSTAT);
-
-	writel(data, v2m_sysreg_base +  V2M_SYS_CFGDATA);
-	writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL);
-
-	do {
-		val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
-	} while (val == 0);
-	spin_unlock(&v2m_cfg_lock);
-
-	return !!(val & SYS_CFG_ERR);
-}
-
-int v2m_cfg_read(u32 devfn, u32 *data)
-{
-	u32 val;
-
-	devfn |= SYS_CFG_START;
-
-	spin_lock(&v2m_cfg_lock);
-	writel(0, v2m_sysreg_base + V2M_SYS_CFGSTAT);
-	writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL);
-
-	mb();
-
-	do {
-		cpu_relax();
-		val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
-	} while (val == 0);
-
-	*data = readl(v2m_sysreg_base + V2M_SYS_CFGDATA);
-	spin_unlock(&v2m_cfg_lock);
-
-	return !!(val & SYS_CFG_ERR);
-}
-
-void __init v2m_flags_set(u32 data)
-{
-	writel(~0, v2m_sysreg_base + V2M_SYS_FLAGSCLR);
-	writel(data, v2m_sysreg_base + V2M_SYS_FLAGSSET);
-}
-
-int v2m_get_master_site(void)
-{
-	u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC);
-
-	return misc & SYS_MISC_MASTERSITE ? SYS_CFG_SITE_DB2 : SYS_CFG_SITE_DB1;
-}
-
-
 static struct resource v2m_pcie_i2c_resource = {
 	.start	= V2M_SERIAL_BUS_PCI,
 	.end	= V2M_SERIAL_BUS_PCI + SZ_4K - 1,
@@ -237,14 +156,8 @@
 	.dev.platform_data = &v2m_usb_config,
 };
 
-static void v2m_flash_set_vpp(struct platform_device *pdev, int on)
-{
-	writel(on != 0, v2m_sysreg_base + V2M_SYS_FLASH);
-}
-
 static struct physmap_flash_data v2m_flash_data = {
 	.width		= 4,
-	.set_vpp	= v2m_flash_set_vpp,
 };
 
 static struct resource v2m_flash_resources[] = {
@@ -291,14 +204,61 @@
 	.dev.platform_data = &v2m_pata_data,
 };
 
-static unsigned int v2m_mmci_status(struct device *dev)
-{
-	return readl(v2m_sysreg_base + V2M_SYS_MCI) & (1 << 0);
-}
-
 static struct mmci_platform_data v2m_mmci_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.status		= v2m_mmci_status,
+	.gpio_wp	= VEXPRESS_GPIO_MMC_WPROT,
+	.gpio_cd	= VEXPRESS_GPIO_MMC_CARDIN,
+};
+
+static struct resource v2m_sysreg_resources[] = {
+	{
+		.start	= V2M_SYSREGS,
+		.end	= V2M_SYSREGS + 0xfff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device v2m_sysreg_device = {
+	.name		= "vexpress-sysreg",
+	.id		= -1,
+	.resource	= v2m_sysreg_resources,
+	.num_resources	= ARRAY_SIZE(v2m_sysreg_resources),
+};
+
+static struct platform_device v2m_muxfpga_device = {
+	.name		= "vexpress-muxfpga",
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= (struct resource []) {
+		VEXPRESS_RES_FUNC(0, 7),
+	}
+};
+
+static struct platform_device v2m_shutdown_device = {
+	.name		= "vexpress-shutdown",
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= (struct resource []) {
+		VEXPRESS_RES_FUNC(0, 8),
+	}
+};
+
+static struct platform_device v2m_reboot_device = {
+	.name		= "vexpress-reboot",
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= (struct resource []) {
+		VEXPRESS_RES_FUNC(0, 9),
+	}
+};
+
+static struct platform_device v2m_dvimode_device = {
+	.name		= "vexpress-dvimode",
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= (struct resource []) {
+		VEXPRESS_RES_FUNC(0, 11),
+	}
 };
 
 static AMBA_APB_DEVICE(aaci,  "mb:aaci",  0, V2M_AACI, IRQ_V2M_AACI, NULL);
@@ -325,123 +285,9 @@
 	&rtc_device,
 };
 
-
-static unsigned long v2m_osc_recalc_rate(struct clk_hw *hw,
-		unsigned long parent_rate)
-{
-	struct v2m_osc *osc = to_v2m_osc(hw);
-
-	return !parent_rate ? osc->rate_default : parent_rate;
-}
-
-static long v2m_osc_round_rate(struct clk_hw *hw, unsigned long rate,
-		unsigned long *parent_rate)
-{
-	struct v2m_osc *osc = to_v2m_osc(hw);
-
-	if (WARN_ON(rate < osc->rate_min))
-		rate = osc->rate_min;
-
-	if (WARN_ON(rate > osc->rate_max))
-		rate = osc->rate_max;
-
-	return rate;
-}
-
-static int v2m_osc_set_rate(struct clk_hw *hw, unsigned long rate,
-		unsigned long parent_rate)
-{
-	struct v2m_osc *osc = to_v2m_osc(hw);
-
-	v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE(osc->site) |
-			SYS_CFG_STACK(osc->stack) | osc->osc, rate);
-
-	return 0;
-}
-
-static struct clk_ops v2m_osc_ops = {
-	.recalc_rate = v2m_osc_recalc_rate,
-	.round_rate = v2m_osc_round_rate,
-	.set_rate = v2m_osc_set_rate,
-};
-
-struct clk * __init v2m_osc_register(const char *name, struct v2m_osc *osc)
-{
-	struct clk_init_data init;
-
-	WARN_ON(osc->site > 2);
-	WARN_ON(osc->stack > 15);
-	WARN_ON(osc->osc > 4095);
-
-	init.name = name;
-	init.ops = &v2m_osc_ops;
-	init.flags = CLK_IS_ROOT;
-	init.num_parents = 0;
-
-	osc->hw.init = &init;
-
-	return clk_register(NULL, &osc->hw);
-}
-
-static struct v2m_osc v2m_mb_osc1 = {
-	.site = SYS_CFG_SITE_MB,
-	.osc = 1,
-	.rate_min = 23750000,
-	.rate_max = 63500000,
-	.rate_default = 23750000,
-};
-
-static const char *v2m_ref_clk_periphs[] __initconst = {
-	"mb:wdt",   "1000f000.wdt",  "1c0f0000.wdt",	/* SP805 WDT */
-};
-
-static const char *v2m_osc1_periphs[] __initconst = {
-	"mb:clcd",  "1001f000.clcd", "1c1f0000.clcd",	/* PL111 CLCD */
-};
-
-static const char *v2m_osc2_periphs[] __initconst = {
-	"mb:mmci",  "10005000.mmci", "1c050000.mmci",	/* PL180 MMCI */
-	"mb:kmi0",  "10006000.kmi",  "1c060000.kmi",	/* PL050 KMI0 */
-	"mb:kmi1",  "10007000.kmi",  "1c070000.kmi",	/* PL050 KMI1 */
-	"mb:uart0", "10009000.uart", "1c090000.uart",	/* PL011 UART0 */
-	"mb:uart1", "1000a000.uart", "1c0a0000.uart",	/* PL011 UART1 */
-	"mb:uart2", "1000b000.uart", "1c0b0000.uart",	/* PL011 UART2 */
-	"mb:uart3", "1000c000.uart", "1c0c0000.uart",	/* PL011 UART3 */
-};
-
-static void __init v2m_clk_init(void)
-{
-	struct clk *clk;
-	int i;
-
-	clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL,
-			CLK_IS_ROOT, 0);
-	WARN_ON(clk_register_clkdev(clk, "apb_pclk", NULL));
-
-	clk = clk_register_fixed_rate(NULL, "mb:ref_clk", NULL,
-			CLK_IS_ROOT, 32768);
-	for (i = 0; i < ARRAY_SIZE(v2m_ref_clk_periphs); i++)
-		WARN_ON(clk_register_clkdev(clk, NULL, v2m_ref_clk_periphs[i]));
-
-	clk = clk_register_fixed_rate(NULL, "mb:sp804_clk", NULL,
-			CLK_IS_ROOT, 1000000);
-	WARN_ON(clk_register_clkdev(clk, "v2m-timer0", "sp804"));
-	WARN_ON(clk_register_clkdev(clk, "v2m-timer1", "sp804"));
-
-	clk = v2m_osc_register("mb:osc1", &v2m_mb_osc1);
-	for (i = 0; i < ARRAY_SIZE(v2m_osc1_periphs); i++)
-		WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc1_periphs[i]));
-
-	clk = clk_register_fixed_rate(NULL, "mb:osc2", NULL,
-			CLK_IS_ROOT, 24000000);
-	for (i = 0; i < ARRAY_SIZE(v2m_osc2_periphs); i++)
-		WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc2_periphs[i]));
-}
-
 static void __init v2m_timer_init(void)
 {
-	v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K));
-	v2m_clk_init();
+	vexpress_clk_init(ioremap(V2M_SYSCTL, SZ_4K));
 	v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
 }
 
@@ -453,19 +299,7 @@
 {
 	if (ct_desc->init_early)
 		ct_desc->init_early();
-	versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000);
-}
-
-static void v2m_power_off(void)
-{
-	if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE(SYS_CFG_SITE_MB), 0))
-		printk(KERN_EMERG "Unable to shutdown\n");
-}
-
-static void v2m_restart(char str, const char *cmd)
-{
-	if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE(SYS_CFG_SITE_MB), 0))
-		printk(KERN_EMERG "Unable to reboot\n");
+	versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000);
 }
 
 struct ct_desc *ct_desc;
@@ -482,7 +316,7 @@
 	u32 current_tile_id;
 
 	ct_desc = NULL;
-	current_tile_id = readl(v2m_sysreg_base + V2M_SYS_PROCID0)
+	current_tile_id = vexpress_get_procid(VEXPRESS_SITE_MASTER)
 				& V2M_CT_ID_MASK;
 
 	for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
@@ -498,7 +332,7 @@
 static void __init v2m_map_io(void)
 {
 	iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
-	v2m_sysreg_base = ioremap(V2M_SYSREGS, SZ_4K);
+	vexpress_sysreg_early_init(ioremap(V2M_SYSREGS, SZ_4K));
 	v2m_populate_ct_desc();
 	ct_desc->map_io();
 }
@@ -515,6 +349,12 @@
 	regulator_register_fixed(0, v2m_eth_supplies,
 			ARRAY_SIZE(v2m_eth_supplies));
 
+	platform_device_register(&v2m_muxfpga_device);
+	platform_device_register(&v2m_shutdown_device);
+	platform_device_register(&v2m_reboot_device);
+	platform_device_register(&v2m_dvimode_device);
+
+	platform_device_register(&v2m_sysreg_device);
 	platform_device_register(&v2m_pcie_i2c_device);
 	platform_device_register(&v2m_ddc_i2c_device);
 	platform_device_register(&v2m_flash_device);
@@ -525,7 +365,7 @@
 	for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++)
 		amba_device_register(v2m_amba_devs[i], &iomem_resource);
 
-	pm_power_off = v2m_power_off;
+	pm_power_off = vexpress_power_off;
 
 	ct_desc->init_tile();
 }
@@ -539,7 +379,7 @@
 	.timer		= &v2m_timer,
 	.handle_irq	= gic_handle_irq,
 	.init_machine	= v2m_init,
-	.restart	= v2m_restart,
+	.restart	= vexpress_restart,
 MACHINE_END
 
 static struct map_desc v2m_rs1_io_desc __initdata = {
@@ -580,20 +420,13 @@
 
 void __init v2m_dt_init_early(void)
 {
-	struct device_node *node;
 	u32 dt_hbi;
 
-	node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg");
-	v2m_sysreg_base = of_iomap(node, 0);
-	if (WARN_ON(!v2m_sysreg_base))
-		return;
+	vexpress_sysreg_of_early_init();
 
 	/* Confirm board type against DT property, if available */
 	if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) {
-		int site = v2m_get_master_site();
-		u32 id = readl(v2m_sysreg_base + (site == SYS_CFG_SITE_DB2 ?
-				V2M_SYS_PROCID1 : V2M_SYS_PROCID0));
-		u32 hbi = id & SYS_PROCIDx_HBI_MASK;
+		u32 hbi = vexpress_get_hbi(VEXPRESS_SITE_MASTER);
 
 		if (WARN_ON(dt_hbi != hbi))
 			pr_warning("vexpress: DT HBI (%x) is not matching "
@@ -613,51 +446,47 @@
 
 static void __init v2m_dt_timer_init(void)
 {
-	struct device_node *node;
-	const char *path;
-	int err;
+	struct device_node *node = NULL;
 
-	node = of_find_compatible_node(NULL, NULL, "arm,sp810");
-	v2m_sysctl_init(of_iomap(node, 0));
+	vexpress_clk_of_init();
 
-	v2m_clk_init();
+	do {
+		node = of_find_compatible_node(node, NULL, "arm,sp804");
+	} while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB);
+	if (node) {
+		pr_info("Using SP804 '%s' as a clock & events source\n",
+				node->full_name);
+		v2m_sp804_init(of_iomap(node, 0),
+				irq_of_parse_and_map(node, 0));
+	}
 
-	err = of_property_read_string(of_aliases, "arm,v2m_timer", &path);
-	if (WARN_ON(err))
-		return;
-	node = of_find_node_by_path(path);
-	v2m_sp804_init(of_iomap(node, 0), irq_of_parse_and_map(node, 0));
 	if (arch_timer_of_register() != 0)
 		twd_local_timer_of_register();
 
 	if (arch_timer_sched_clock_init() != 0)
-		versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000);
+		versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
+				24000000);
 }
 
 static struct sys_timer v2m_dt_timer = {
 	.init = v2m_dt_timer_init,
 };
 
-static struct of_dev_auxdata v2m_dt_auxdata_lookup[] __initdata = {
-	OF_DEV_AUXDATA("arm,vexpress-flash", V2M_NOR0, "physmap-flash",
-			&v2m_flash_data),
-	OF_DEV_AUXDATA("arm,primecell", V2M_MMCI, "mb:mmci", &v2m_mmci_data),
-	/* RS1 memory map */
-	OF_DEV_AUXDATA("arm,vexpress-flash", 0x08000000, "physmap-flash",
-			&v2m_flash_data),
-	OF_DEV_AUXDATA("arm,primecell", 0x1c050000, "mb:mmci", &v2m_mmci_data),
+static const struct of_device_id v2m_dt_bus_match[] __initconst = {
+	{ .compatible = "simple-bus", },
+	{ .compatible = "arm,amba-bus", },
+	{ .compatible = "arm,vexpress,config-bus", },
 	{}
 };
 
 static void __init v2m_dt_init(void)
 {
 	l2x0_of_init(0x00400000, 0xfe0fffff);
-	of_platform_populate(NULL, of_default_bus_match_table,
-			v2m_dt_auxdata_lookup, NULL);
-	pm_power_off = v2m_power_off;
+	of_platform_populate(NULL, v2m_dt_bus_match, NULL, NULL);
+	pm_power_off = vexpress_power_off;
 }
 
-const static char *v2m_dt_match[] __initconst = {
+static const char * const v2m_dt_match[] __initconst = {
 	"arm,vexpress",
 	"xen,xenvm",
 	NULL,
@@ -672,5 +501,5 @@
 	.timer		= &v2m_dt_timer,
 	.init_machine	= v2m_dt_init,
 	.handle_irq	= gic_handle_irq,
-	.restart	= v2m_restart,
+	.restart	= vexpress_restart,
 MACHINE_END
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index b9f60eb..b820eda 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -745,7 +745,7 @@
 static int
 do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
-	union offset_union offset;
+	union offset_union uninitialized_var(offset);
 	unsigned long instr = 0, instrptr;
 	int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
 	unsigned int type;
@@ -856,8 +856,10 @@
 		if (thumb2_32b) {
 			offset.un = 0;
 			handler = do_alignment_t32_to_handler(&instr, regs, &offset);
-		} else
+		} else {
+			offset.un = 0;
 			handler = do_alignment_ldmstm;
+		}
 		break;
 
 	default:
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 477a2d2..58bc3e4 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -610,7 +610,7 @@
 			 gfp_t gfp, pgprot_t prot, bool is_coherent, const void *caller)
 {
 	u64 mask = get_coherent_dma_mask(dev);
-	struct page *page;
+	struct page *page = NULL;
 	void *addr;
 
 #ifdef CONFIG_DMA_API_DEBUG
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 941dfb9..39719bb 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -876,6 +876,22 @@
 #define pci_reserve_io() do { } while (0)
 #endif
 
+#ifdef CONFIG_DEBUG_LL
+void __init debug_ll_io_init(void)
+{
+	struct map_desc map;
+
+	debug_ll_addr(&map.pfn, &map.virtual);
+	if (!map.pfn || !map.virtual)
+		return;
+	map.pfn = __phys_to_pfn(map.pfn);
+	map.virtual &= PAGE_MASK;
+	map.length = PAGE_SIZE;
+	map.type = MT_DEVICE;
+	create_mapping(&map);
+}
+#endif
+
 static void * __initdata vmalloc_min =
 	(void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET);
 
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h
index bf312c3..0f5a5f2 100644
--- a/arch/arm/mm/vmregion.h
+++ b/arch/arm/mm/vmregion.h
@@ -17,7 +17,6 @@
 	struct list_head	vm_list;
 	unsigned long		vm_start;
 	unsigned long		vm_end;
-	void			*priv;
 	int			vm_active;
 	const void		*caller;
 };
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
deleted file mode 100644
index 88e1e2e..0000000
--- a/arch/arm/plat-mxc/Kconfig
+++ /dev/null
@@ -1,89 +0,0 @@
-if ARCH_MXC
-
-source "arch/arm/plat-mxc/devices/Kconfig"
-
-menu "Freescale MXC Implementations"
-
-choice
-	prompt "Freescale CPU family:"
-	default ARCH_IMX_V6_V7
-
-config ARCH_IMX_V4_V5
-	bool "i.MX1, i.MX21, i.MX25, i.MX27"
-	select ARM_PATCH_PHYS_VIRT
-	select AUTO_ZRELADDR if !ZBOOT_ROM
-	help
-	  This enables support for systems based on the Freescale i.MX ARMv4
-	  and ARMv5 SoCs
-
-config ARCH_IMX_V6_V7
-	bool "i.MX3, i.MX5, i.MX6"
-	select ARM_PATCH_PHYS_VIRT
-	select AUTO_ZRELADDR if !ZBOOT_ROM
-	select MIGHT_HAVE_CACHE_L2X0
-	help
-	  This enables support for systems based on the Freescale i.MX3, i.MX5
-	  and i.MX6 family.
-
-endchoice
-
-source "arch/arm/mach-imx/Kconfig"
-
-endmenu
-
-config MXC_IRQ_PRIOR
-	bool "Use IRQ priority"
-	help
-	  Select this if you want to use prioritized IRQ handling.
-	  This feature prevents higher priority ISR to be interrupted
-	  by lower priority IRQ even IRQF_DISABLED flag is not set.
-	  This may be useful in embedded applications, where are strong
-	  requirements for timing.
-	  Say N here, unless you have a specialized requirement.
-
-config MXC_TZIC
-	bool
-
-config MXC_AVIC
-	bool
-
-config MXC_DEBUG_BOARD
-	bool "Enable MXC debug board(for 3-stack)"
-	help
-	  The debug board is an integral part of the MXC 3-stack(PDK)
-	  platforms, it can be attached or removed from the peripheral
-	  board. On debug board, several debug devices(ethernet, UART,
-	  buttons, LEDs and JTAG) are implemented. Between the MCU and
-	  these devices, a CPLD is added as a bridge which performs
-	  data/address de-multiplexing and decode, signal level shift,
-	  interrupt control and various board functions.
-
-config HAVE_EPIT
-	bool
-
-config MXC_USE_EPIT
-	bool "Use EPIT instead of GPT"
-	depends on HAVE_EPIT
-	help
-	  Use EPIT as the system timer on systems that have it. Normally you
-	  don't have a reason to do so as the EPIT has the same features and
-	  uses the same clocks as the GPT. Anyway, on some systems the GPT
-	  may be in use for other purposes.
-
-config MXC_ULPI
-	bool
-
-config ARCH_HAS_RNGA
-	bool
-
-config IMX_HAVE_IOMUX_V1
-	bool
-
-config ARCH_MXC_IOMUX_V3
-	bool
-
-config IRAM_ALLOC
-	bool
-	select GENERIC_ALLOCATOR
-
-endif
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
deleted file mode 100644
index 149237e2..0000000
--- a/arch/arm/plat-mxc/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Common support
-obj-y := time.o devices.o cpu.o system.o irq-common.o
-
-obj-$(CONFIG_MXC_TZIC) += tzic.o
-obj-$(CONFIG_MXC_AVIC) += avic.o
-
-obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
-obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
-obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
-obj-$(CONFIG_MXC_ULPI) += ulpi.o
-obj-$(CONFIG_MXC_USE_EPIT) += epit.o
-obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
-obj-$(CONFIG_CPU_FREQ_IMX)    += cpufreq.o
-obj-$(CONFIG_CPU_IDLE) += cpuidle.o
-ifdef CONFIG_SND_IMX_SOC
-obj-y += ssi-fiq.o
-obj-y += ssi-fiq-ksym.o
-endif
-
-obj-y += devices/
diff --git a/arch/arm/plat-mxc/devices/platform-mx2-emma.c b/arch/arm/plat-mxc/devices/platform-mx2-emma.c
new file mode 100644
index 0000000..508404d
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mx2-emma.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mx2_emmaprp_data_entry_single(soc)				\
+	{								\
+		.iobase = soc ## _EMMAPRP_BASE_ADDR,			\
+		.iosize = SZ_32,					\
+		.irq = soc ## _INT_EMMAPRP,				\
+	}
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mx2_emma_data imx27_mx2_emmaprp_data __initconst =
+	imx_mx2_emmaprp_data_entry_single(MX27);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+struct platform_device *__init imx_add_mx2_emmaprp(
+		const struct imx_mx2_emma_data *data)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase,
+			.end = data->iobase + data->iosize - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->irq,
+			.end = data->irq,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+	return imx_add_platform_device_dmamask("m2m-emmaprp", 0,
+			res, 2, NULL, 0, DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
deleted file mode 100644
index 761e45f..0000000
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ /dev/null
@@ -1,51 +0,0 @@
-/* arch/arm/mach-imx/include/mach/debug-macro.S
- *
- * Debugging macro include header
- *
- *  Copyright (C) 1994-1999 Russell King
- *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <mach/hardware.h>
-
-#ifdef CONFIG_DEBUG_IMX1_UART
-#define UART_PADDR	MX1_UART1_BASE_ADDR
-#elif defined (CONFIG_DEBUG_IMX25_UART)
-#define UART_PADDR	MX25_UART1_BASE_ADDR
-#elif defined (CONFIG_DEBUG_IMX21_IMX27_UART)
-#define UART_PADDR	MX2x_UART1_BASE_ADDR
-#elif defined (CONFIG_DEBUG_IMX31_IMX35_UART)
-#define UART_PADDR	MX3x_UART1_BASE_ADDR
-#elif defined (CONFIG_DEBUG_IMX51_UART)
-#define UART_PADDR	MX51_UART1_BASE_ADDR
-#elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
-#define UART_PADDR	MX53_UART1_BASE_ADDR
-#elif defined (CONFIG_DEBUG_IMX6Q_UART2)
-#define UART_PADDR	MX6Q_UART2_BASE_ADDR
-#elif defined (CONFIG_DEBUG_IMX6Q_UART4)
-#define UART_PADDR	MX6Q_UART4_BASE_ADDR
-#endif
-
-#define UART_VADDR	IMX_IO_ADDRESS(UART_PADDR)
-
-		.macro	addruart, rp, rv, tmp
-		ldr	\rp, =UART_PADDR	@ physical
-		ldr	\rv, =UART_VADDR	@ virtual
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #0x40]	@ TXDATA
-		.endm
-
-		.macro	waituart,rd,rx
-		.endm
-
-		.macro	busyuart,rd,rx
-1002:		ldr	\rd, [\rx, #0x98]	@ SR2
-		tst	\rd, #1 << 3		@ TXDC
-		beq	1002b			@ wait until transmit done
-		.endm
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
deleted file mode 100644
index d73f5e8..0000000
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_MXC_IRQS_H__
-#define __ASM_ARCH_MXC_IRQS_H__
-
-extern int imx_irq_set_priority(unsigned char irq, unsigned char prio);
-
-/* all normal IRQs can be FIQs */
-#define FIQ_START	0
-/* switch between IRQ and FIQ */
-extern int mxc_set_irq_fiq(unsigned int irq, unsigned int type);
-
-#endif /* __ASM_ARCH_MXC_IRQS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
deleted file mode 100644
index 477971b..0000000
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- *  arch/arm/plat-mxc/include/mach/uncompress.h
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) Shane Nay (shane@minirl.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#ifndef __ASM_ARCH_MXC_UNCOMPRESS_H__
-#define __ASM_ARCH_MXC_UNCOMPRESS_H__
-
-#define __MXC_BOOT_UNCOMPRESS
-
-#include <asm/mach-types.h>
-
-unsigned long uart_base;
-
-#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
-
-#define USR2 0x98
-#define USR2_TXFE (1<<14)
-#define TXR  0x40
-#define UCR1 0x80
-#define UCR1_UARTEN 1
-
-/*
- * The following code assumes the serial port has already been
- * initialized by the bootloader.  We search for the first enabled
- * port in the most probable order.  If you didn't setup a port in
- * your bootloader then nothing will appear (which might be desired).
- *
- * This does not append a newline
- */
-
-static void putc(int ch)
-{
-	if (!uart_base)
-		return;
-	if (!(UART(UCR1) & UCR1_UARTEN))
-		return;
-
-	while (!(UART(USR2) & USR2_TXFE))
-		barrier();
-
-	UART(TXR) = ch;
-}
-
-static inline void flush(void)
-{
-}
-
-#define MX1_UART1_BASE_ADDR	0x00206000
-#define MX25_UART1_BASE_ADDR	0x43f90000
-#define MX2X_UART1_BASE_ADDR	0x1000a000
-#define MX3X_UART1_BASE_ADDR	0x43F90000
-#define MX3X_UART2_BASE_ADDR	0x43F94000
-#define MX3X_UART5_BASE_ADDR	0x43FB4000
-#define MX51_UART1_BASE_ADDR	0x73fbc000
-#define MX50_UART1_BASE_ADDR	0x53fbc000
-#define MX53_UART1_BASE_ADDR	0x53fbc000
-
-static __inline__ void __arch_decomp_setup(unsigned long arch_id)
-{
-	switch (arch_id) {
-	case MACH_TYPE_MX1ADS:
-	case MACH_TYPE_SCB9328:
-		uart_base = MX1_UART1_BASE_ADDR;
-		break;
-	case MACH_TYPE_MX25_3DS:
-		uart_base = MX25_UART1_BASE_ADDR;
-		break;
-	case MACH_TYPE_IMX27LITE:
-	case MACH_TYPE_MX27_3DS:
-	case MACH_TYPE_MX27ADS:
-	case MACH_TYPE_PCM038:
-	case MACH_TYPE_MX21ADS:
-	case MACH_TYPE_PCA100:
-	case MACH_TYPE_MXT_TD60:
-	case MACH_TYPE_IMX27IPCAM:
-		uart_base = MX2X_UART1_BASE_ADDR;
-		break;
-	case MACH_TYPE_MX31LITE:
-	case MACH_TYPE_ARMADILLO5X0:
-	case MACH_TYPE_MX31MOBOARD:
-	case MACH_TYPE_QONG:
-	case MACH_TYPE_MX31_3DS:
-	case MACH_TYPE_PCM037:
-	case MACH_TYPE_MX31ADS:
-	case MACH_TYPE_MX35_3DS:
-	case MACH_TYPE_PCM043:
-	case MACH_TYPE_LILLY1131:
-	case MACH_TYPE_VPR200:
-	case MACH_TYPE_EUKREA_CPUIMX35SD:
-		uart_base = MX3X_UART1_BASE_ADDR;
-		break;
-	case MACH_TYPE_MAGX_ZN5:
-		uart_base = MX3X_UART2_BASE_ADDR;
-		break;
-	case MACH_TYPE_BUG:
-		uart_base = MX3X_UART5_BASE_ADDR;
-		break;
-	case MACH_TYPE_MX51_BABBAGE:
-	case MACH_TYPE_EUKREA_CPUIMX51SD:
-	case MACH_TYPE_MX51_3DS:
-		uart_base = MX51_UART1_BASE_ADDR;
-		break;
-	case MACH_TYPE_MX50_RDP:
-		uart_base = MX50_UART1_BASE_ADDR;
-		break;
-	case MACH_TYPE_MX53_EVK:
-	case MACH_TYPE_MX53_LOCO:
-	case MACH_TYPE_MX53_SMD:
-	case MACH_TYPE_MX53_ARD:
-		uart_base = MX53_UART1_BASE_ADDR;
-		break;
-	default:
-		break;
-	}
-}
-
-#define arch_decomp_setup()	__arch_decomp_setup(arch_id)
-#define arch_decomp_wdog()
-
-#endif				/* __ASM_ARCH_MXC_UNCOMPRESS_H__ */
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 7cd56ed..82fcb20 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -26,6 +26,7 @@
 	select CLKDEV_LOOKUP
 	select GENERIC_IRQ_CHIP
 	select OMAP_DM_TIMER
+	select PINCTRL
 	select PROC_DEVICETREE if PROC_FS
 	select SPARSE_IRQ
 	select USE_OF
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index f4a4cd0..1957a85 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -40,10 +40,10 @@
 #define OMAP_UART_WER_MOD_WKUP	0X7F
 
 /* Enable XON/XOFF flow control on output */
-#define OMAP_UART_SW_TX		0x8
+#define OMAP_UART_SW_TX		0x04
 
 /* Enable XON/XOFF flow control on input */
-#define OMAP_UART_SW_RX		0x2
+#define OMAP_UART_SW_RX		0x04
 
 #define OMAP_UART_SYSC_RESET	0X07
 #define OMAP_UART_TCR_TRIG	0X0F
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index b3349f7..1db0294 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -443,6 +443,11 @@
  *     in order to complete the reset. Optional clocks will be disabled
  *     again after the reset.
  * HWMOD_16BIT_REG: Module has 16bit registers
+ * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for
+ *     this IP block comes from an off-chip source and is not always
+ *     enabled.  This prevents the hwmod code from being able to
+ *     enable and reset the IP block early.  XXX Eventually it should
+ *     be possible to query the clock framework for this information.
  */
 #define HWMOD_SWSUP_SIDLE			(1 << 0)
 #define HWMOD_SWSUP_MSTANDBY			(1 << 1)
@@ -453,6 +458,7 @@
 #define HWMOD_NO_IDLEST				(1 << 6)
 #define HWMOD_CONTROL_OPT_CLKS_IN_RESET		(1 << 7)
 #define HWMOD_16BIT_REG				(1 << 8)
+#define HWMOD_EXT_OPT_MAIN_CLK			(1 << 9)
 
 /*
  * omap_hwmod._int_flags definitions
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 59401e1..a9d52167 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -414,6 +414,11 @@
 	help
 	  Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
 
+config S3C_SETUP_CAMIF
+	bool
+	help
+	  Compile in common setup code for S3C CAMIF devices
+
 # DMA
 
 config S3C_DMA
@@ -502,5 +507,6 @@
 	default "0" if DEBUG_S3C_UART0
 	default "1" if DEBUG_S3C_UART1
 	default "2" if DEBUG_S3C_UART2
+	default "3" if DEBUG_S3C_UART3
 
 endif
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 9e40e8d..3a7c64d 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -41,6 +41,7 @@
 
 obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT)	+= dev-backlight.o
 
+obj-$(CONFIG_S3C_SETUP_CAMIF)	+= setup-camif.o
 obj-$(CONFIG_S5P_SETUP_MIPIPHY)	+= setup-mipiphy.o
 
 # DMA support
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index ace4451..e0072ce 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -43,6 +43,7 @@
 #define EXYNOS4_CPU_MASK	0xFFFE0000
 
 #define EXYNOS5250_SOC_ID	0x43520000
+#define EXYNOS5440_SOC_ID	0x54400000
 #define EXYNOS5_SOC_MASK	0xFFFFF000
 
 #define IS_SAMSUNG_CPU(name, id, mask)		\
@@ -62,6 +63,7 @@
 IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK)
 IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
 IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK)
+IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
 
 #if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
     defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \
@@ -130,6 +132,12 @@
 # define soc_is_exynos5250()	0
 #endif
 
+#if defined(CONFIG_SOC_EXYNOS5440)
+# define soc_is_exynos5440()	is_samsung_exynos5440()
+#else
+# define soc_is_exynos5440()	0
+#endif
+
 #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
 
 #ifndef KHZ
diff --git a/arch/arm/plat-samsung/include/plat/spi-core.h b/arch/arm/plat-samsung/include/plat/spi-core.h
new file mode 100644
index 0000000..0b9428a
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/spi-core.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PLAT_S3C_SPI_CORE_H
+#define __PLAT_S3C_SPI_CORE_H
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c64xx_spi_setname(char *name)
+{
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+	s3c64xx_device_spi0.name = name;
+#endif
+#ifdef CONFIG_S3C64XX_DEV_SPI1
+	s3c64xx_device_spi1.name = name;
+#endif
+#ifdef CONFIG_S3C64XX_DEV_SPI2
+	s3c64xx_device_spi2.name = name;
+#endif
+}
+
+#endif /* __PLAT_S3C_SPI_CORE_H */
diff --git a/arch/arm/plat-samsung/setup-camif.c b/arch/arm/plat-samsung/setup-camif.c
new file mode 100644
index 0000000..e01bf76
--- /dev/null
+++ b/arch/arm/plat-samsung/setup-camif.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+ *
+ * Helper functions for S3C24XX/S3C64XX SoC series CAMIF driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+
+/* Number of camera port pins, without FIELD */
+#define S3C_CAMIF_NUM_GPIOS	13
+
+/* Default camera port configuration helpers. */
+
+static void camif_get_gpios(int *gpio_start, int *gpio_reset)
+{
+#ifdef CONFIG_ARCH_S3C24XX
+	*gpio_start = S3C2410_GPJ(0);
+	*gpio_reset = S3C2410_GPJ(12);
+#else
+	/* s3c64xx */
+	*gpio_start = S3C64XX_GPF(0);
+	*gpio_reset = S3C64XX_GPF(3);
+#endif
+}
+
+int s3c_camif_gpio_get(void)
+{
+	int gpio_start, gpio_reset;
+	int ret, i;
+
+	camif_get_gpios(&gpio_start, &gpio_reset);
+
+	for (i = 0; i < S3C_CAMIF_NUM_GPIOS; i++) {
+		int gpio = gpio_start + i;
+
+		if (gpio == gpio_reset)
+			continue;
+
+		ret = gpio_request(gpio, "camif");
+		if (!ret)
+			ret = s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		if (ret) {
+			pr_err("failed to configure GPIO %d\n", gpio);
+			for (--i; i >= 0; i--)
+				gpio_free(gpio--);
+			return ret;
+		}
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	return 0;
+}
+
+void s3c_camif_gpio_put(void)
+{
+	int i, gpio_start, gpio_reset;
+
+	camif_get_gpios(&gpio_start, &gpio_reset);
+
+	for (i = 0; i < S3C_CAMIF_NUM_GPIOS; i++) {
+		int gpio = gpio_start + i;
+		if (gpio != gpio_reset)
+			gpio_free(gpio);
+	}
+}
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index f8db7b2..87dbd81 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -12,6 +12,7 @@
 	bool "ST SPEAr13xx with Device Tree"
 	select ARM_GIC
 	select CPU_V7
+	select GPIO_SPEAR_SPICS
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
 	select PINCTRL
diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile
index 635cb18..32d05c8 100644
--- a/arch/arm/tools/Makefile
+++ b/arch/arm/tools/Makefile
@@ -5,6 +5,6 @@
 #
 
 include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types
-	@echo '  Generating $@'
+	@$(kecho) '  Generating $@'
 	@mkdir -p $(dir $@)
 	$(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; }
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index c834b32..3b44e0d 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -701,11 +701,14 @@
 			elf_hwcap |= HWCAP_VFPv3;
 
 			/*
-			 * Check for VFPv3 D16. CPUs in this configuration
-			 * only have 16 x 64bit registers.
+			 * Check for VFPv3 D16 and VFPv4 D16.  CPUs in
+			 * this configuration only have 16 x 64bit
+			 * registers.
 			 */
 			if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1)
-				elf_hwcap |= HWCAP_VFPv3D16;
+				elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */
+			else
+				elf_hwcap |= HWCAP_VFPD32;
 		}
 #endif
 		/*
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 59bcb96..f576092 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -166,3 +166,14 @@
 	*pages = NULL;
 }
 EXPORT_SYMBOL_GPL(free_xenballooned_pages);
+
+/* In the hypervisor.S file. */
+EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version);
+EXPORT_SYMBOL_GPL(HYPERVISOR_console_io);
+EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
+EXPORT_SYMBOL_GPL(privcmd_call);
diff --git a/arch/arm/xen/grant-table.c b/arch/arm/xen/grant-table.c
index dbd1330..859a9bb 100644
--- a/arch/arm/xen/grant-table.c
+++ b/arch/arm/xen/grant-table.c
@@ -33,7 +33,7 @@
 #include <xen/page.h>
 #include <xen/grant_table.h>
 
-int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
+int arch_gnttab_map_shared(xen_pfn_t *frames, unsigned long nr_gframes,
 			   unsigned long max_nr_gframes,
 			   void **__shared)
 {
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
index 074f5ed..71f7239 100644
--- a/arch/arm/xen/hypercall.S
+++ b/arch/arm/xen/hypercall.S
@@ -48,20 +48,16 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include <asm/opcodes-virt.h>
 #include <xen/interface/xen.h>
 
 
-/* HVC 0xEA1 */
-#ifdef CONFIG_THUMB2_KERNEL
-#define xen_hvc .word 0xf7e08ea1
-#else
-#define xen_hvc .word 0xe140ea71
-#endif
+#define XEN_IMM 0xEA1
 
 #define HYPERCALL_SIMPLE(hypercall)		\
 ENTRY(HYPERVISOR_##hypercall)			\
 	mov r12, #__HYPERVISOR_##hypercall;	\
-	xen_hvc;							\
+	__HVC(XEN_IMM);						\
 	mov pc, lr;							\
 ENDPROC(HYPERVISOR_##hypercall)
 
@@ -76,7 +72,7 @@
 	stmdb sp!, {r4}						\
 	ldr r4, [sp, #4]					\
 	mov r12, #__HYPERVISOR_##hypercall;	\
-	xen_hvc								\
+	__HVC(XEN_IMM);						\
 	ldm sp!, {r4}						\
 	mov pc, lr							\
 ENDPROC(HYPERVISOR_##hypercall)
@@ -100,7 +96,7 @@
 	mov r2, r3
 	ldr r3, [sp, #8]
 	ldr r4, [sp, #4]
-	xen_hvc
+	__HVC(XEN_IMM)
 	ldm sp!, {r4}
 	mov pc, lr
 ENDPROC(privcmd_call);
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index ef54a59..15ac18a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,6 +1,7 @@
 config ARM64
 	def_bool y
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+	select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_HARDIRQS_NO_DEPRECATED
 	select GENERIC_IOMAP
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index cf28464..07fea29 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -25,12 +25,10 @@
 #include <asm/user.h>
 
 typedef unsigned long elf_greg_t;
-typedef unsigned long elf_freg_t[3];
 
 #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct user_fp elf_fpregset_t;
+typedef struct user_fpsimd_state elf_fpregset_t;
 
 #define EM_AARCH64		183
 
@@ -87,7 +85,6 @@
 #define R_AARCH64_MOVW_PREL_G2_NC	292
 #define R_AARCH64_MOVW_PREL_G3		293
 
-
 /*
  * These are used to set parameters in the core dumps.
  */
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index b42fab9..c43b4ac 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -25,9 +25,8 @@
  *  - FPSR and FPCR
  *  - 32 128-bit data registers
  *
- * Note that user_fp forms a prefix of this structure, which is relied
- * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must
- * form a prefix of struct fpsimd_state.
+ * Note that user_fpsimd forms a prefix of this structure, which is
+ * relied upon in the ptrace FP/SIMD accessors.
  */
 struct fpsimd_state {
 	union {
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 74a2a7d..d2f05a6 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -114,7 +114,7 @@
  *  I/O port access primitives.
  */
 #define IO_SPACE_LIMIT		0xffff
-#define PCI_IOBASE		((void __iomem *)0xffffffbbfffe0000UL)
+#define PCI_IOBASE		((void __iomem *)(MODULES_VADDR - SZ_2M))
 
 static inline u8 inb(unsigned long addr)
 {
@@ -222,12 +222,12 @@
 extern void __iounmap(volatile void __iomem *addr);
 
 #define PROT_DEFAULT		(PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY)
-#define PROT_DEVICE_nGnRE	(PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
+#define PROT_DEVICE_nGnRE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
 #define PROT_NORMAL_NC		(PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC))
 
-#define ioremap(addr, size)		__ioremap((addr), (size), PROT_DEVICE_nGnRE)
-#define ioremap_nocache(addr, size)	__ioremap((addr), (size), PROT_DEVICE_nGnRE)
-#define ioremap_wc(addr, size)		__ioremap((addr), (size), PROT_NORMAL_NC)
+#define ioremap(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
+#define ioremap_nocache(addr, size)	__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
+#define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
 #define iounmap				__iounmap
 
 #define ARCH_HAS_IOREMAP_WC
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 0f3b458..75fd13d 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -38,7 +38,8 @@
 #define PMD_SECT_S		(_AT(pmdval_t, 3) << 8)
 #define PMD_SECT_AF		(_AT(pmdval_t, 1) << 10)
 #define PMD_SECT_NG		(_AT(pmdval_t, 1) << 11)
-#define PMD_SECT_XN		(_AT(pmdval_t, 1) << 54)
+#define PMD_SECT_PXN		(_AT(pmdval_t, 1) << 53)
+#define PMD_SECT_UXN		(_AT(pmdval_t, 1) << 54)
 
 /*
  * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
@@ -57,7 +58,8 @@
 #define PTE_SHARED		(_AT(pteval_t, 3) << 8)		/* SH[1:0], inner shareable */
 #define PTE_AF			(_AT(pteval_t, 1) << 10)	/* Access Flag */
 #define PTE_NG			(_AT(pteval_t, 1) << 11)	/* nG */
-#define PTE_XN			(_AT(pteval_t, 1) << 54)	/* XN */
+#define PTE_PXN			(_AT(pteval_t, 1) << 53)	/* Privileged XN */
+#define PTE_UXN			(_AT(pteval_t, 1) << 54)	/* User XN */
 
 /*
  * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 8960239..14aba2d 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -62,23 +62,23 @@
 
 #define _MOD_PROT(p, b)	__pgprot(pgprot_val(p) | (b))
 
-#define PAGE_NONE		_MOD_PROT(pgprot_default, PTE_NG | PTE_XN | PTE_RDONLY)
-#define PAGE_SHARED		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN)
-#define PAGE_SHARED_EXEC	_MOD_PROT(pgprot_default, PTE_USER | PTE_NG)
-#define PAGE_COPY		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define PAGE_COPY_EXEC		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY)
-#define PAGE_READONLY		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define PAGE_READONLY_EXEC	_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY)
-#define PAGE_KERNEL		_MOD_PROT(pgprot_default, PTE_XN | PTE_DIRTY)
-#define PAGE_KERNEL_EXEC	_MOD_PROT(pgprot_default, PTE_DIRTY)
+#define PAGE_NONE		_MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define PAGE_SHARED		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
+#define PAGE_SHARED_EXEC	_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
+#define PAGE_COPY		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define PAGE_COPY_EXEC		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
+#define PAGE_READONLY		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define PAGE_READONLY_EXEC	_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
+#define PAGE_KERNEL		_MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY)
+#define PAGE_KERNEL_EXEC	_MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY)
 
-#define __PAGE_NONE		__pgprot(_PAGE_DEFAULT | PTE_NG | PTE_XN | PTE_RDONLY)
-#define __PAGE_SHARED		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN)
-#define __PAGE_SHARED_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG)
-#define __PAGE_COPY		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define __PAGE_COPY_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY)
-#define __PAGE_READONLY		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define __PAGE_READONLY_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY)
+#define __PAGE_NONE		__pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define __PAGE_SHARED		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
+#define __PAGE_SHARED_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
+#define __PAGE_COPY		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define __PAGE_COPY_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
+#define __PAGE_READONLY		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define __PAGE_READONLY_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
 
 #endif /* __ASSEMBLY__ */
 
@@ -130,10 +130,10 @@
 #define pte_young(pte)		(pte_val(pte) & PTE_AF)
 #define pte_special(pte)	(pte_val(pte) & PTE_SPECIAL)
 #define pte_write(pte)		(!(pte_val(pte) & PTE_RDONLY))
-#define pte_exec(pte)		(!(pte_val(pte) & PTE_XN))
+#define pte_exec(pte)		(!(pte_val(pte) & PTE_UXN))
 
 #define pte_present_exec_user(pte) \
-	((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_XN)) == \
+	((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \
 	 (PTE_VALID | PTE_USER))
 
 #define PTE_BIT_FUNC(fn,op) \
@@ -262,7 +262,7 @@
 
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
-	const pteval_t mask = PTE_USER | PTE_XN | PTE_RDONLY;
+	const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY;
 	pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
 	return pte;
 }
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 5d81004..77f696c 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -43,6 +43,8 @@
 #else
 #define STACK_TOP		STACK_TOP_MAX
 #endif /* CONFIG_COMPAT */
+
+#define ARCH_LOW_ADDRESS_LIMIT	PHYS_MASK
 #endif /* __KERNEL__ */
 
 struct debug_info {
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 63f853f..68aff28 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -14,7 +14,6 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #ifdef CONFIG_COMPAT
-#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION
 #define __ARCH_WANT_COMPAT_STAT64
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index ecbf2d8..c76c724 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -613,17 +613,11 @@
 	ARMV8_PMUV3_PERFCTR_BUS_ACCESS				= 0x19,
 	ARMV8_PMUV3_PERFCTR_MEM_ERROR				= 0x1A,
 	ARMV8_PMUV3_PERFCTR_BUS_CYCLES				= 0x1D,
-
-	/*
-	 * This isn't an architected event.
-	 * We detect this event number and use the cycle counter instead.
-	 */
-	ARMV8_PMUV3_PERFCTR_CPU_CYCLES				= 0xFF,
 };
 
 /* PMUv3 HW events mapping. */
 static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
-	[PERF_COUNT_HW_CPU_CYCLES]		= ARMV8_PMUV3_PERFCTR_CPU_CYCLES,
+	[PERF_COUNT_HW_CPU_CYCLES]		= ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES,
 	[PERF_COUNT_HW_INSTRUCTIONS]		= ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED,
 	[PERF_COUNT_HW_CACHE_REFERENCES]	= ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
 	[PERF_COUNT_HW_CACHE_MISSES]		= ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
@@ -1106,7 +1100,7 @@
 	unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT;
 
 	/* Always place a cycle counter into the cycle counter. */
-	if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) {
+	if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) {
 		if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask))
 			return -EAGAIN;
 
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index f22965e..e04cebd 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -310,24 +310,6 @@
 }
 
 /*
- * Fill in the task's elfregs structure for a core dump.
- */
-int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
-{
-	elf_core_copy_regs(elfregs, task_pt_regs(t));
-	return 1;
-}
-
-/*
- * fill in the fpe structure for a core dump...
- */
-int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
-{
-	return 0;
-}
-EXPORT_SYMBOL(dump_fpu);
-
-/*
  * Shuffle the argument into the correct register before calling the
  * thread function.  x1 is the thread argument, x2 is the pointer to
  * the thread function, and x3 points to the exit function.
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 226b6bf..538300f 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -211,8 +211,7 @@
 	 * before we continue.
 	 */
 	set_cpu_online(cpu, true);
-	while (!cpu_active(cpu))
-		cpu_relax();
+	complete(&cpu_running);
 
 	/*
 	 * OK, it's off to the idle thread for us
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index efbf7df..4cd2893 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -80,7 +80,7 @@
 #ifdef CONFIG_ZONE_DMA32
 	/* 4GB maximum for 32-bit only capable devices */
 	max_dma32 = min(max, MAX_DMA32_PFN);
-	zone_size[ZONE_DMA32] = max_dma32 - min;
+	zone_size[ZONE_DMA32] = max(min, max_dma32) - min;
 #endif
 	zone_size[ZONE_NORMAL] = max - max_dma32;
 
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index b741250..df2eb4b 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -13,6 +13,7 @@
 	select GENERIC_CPU_DEVICES
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select GENERIC_KERNEL_THREAD
+	select GENERIC_KERNEL_EXECVE
 
 config ZONE_DMA
 	bool
diff --git a/arch/frv/boot/Makefile b/arch/frv/boot/Makefile
index 6ae3254..636d5bb 100644
--- a/arch/frv/boot/Makefile
+++ b/arch/frv/boot/Makefile
@@ -17,6 +17,8 @@
 INITRD_PHYS	 = 0x02180000
 INITRD_VIRT	 = 0x02180000
 
+OBJCOPYFLAGS	:=-O binary -R .note -R .note.gnu.build-id -R .comment
+
 #
 # If you don't define ZRELADDR above,
 # then it defaults to ZTEXTADDR
@@ -32,18 +34,18 @@
 targets: $(obj)/Image
 
 $(obj)/Image: vmlinux FORCE
-	$(OBJCOPY) -O binary -R .note -R .comment -S vmlinux $@
+	$(OBJCOPY) $(OBJCOPYFLAGS) -S vmlinux $@
 
 #$(obj)/Image:	$(CONFIGURE) $(SYSTEM)
-#	$(OBJCOPY) -O binary -R .note -R .comment -g -S $(SYSTEM) $@
+#	$(OBJCOPY) $(OBJCOPYFLAGS) -g -S $(SYSTEM) $@
 
 bzImage: zImage
 
 zImage:	$(CONFIGURE) compressed/$(LINUX)
-	$(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@
+	$(OBJCOPY) $(OBJCOPYFLAGS) -S compressed/$(LINUX) $@
 
 bootpImage: bootp/bootp
-	$(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
+	$(OBJCOPY) $(OBJCOPYFLAGS) -S bootp/bootp $@
 
 compressed/$(LINUX): $(LINUX) dep
 	@$(MAKE) -C compressed $(LINUX)
diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h
index 266a5b2..2358634 100644
--- a/arch/frv/include/asm/unistd.h
+++ b/arch/frv/include/asm/unistd.h
@@ -30,7 +30,6 @@
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #define __ARCH_WANT_SYS_EXECVE
-#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index ee0beb3..dfcd263 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -869,11 +869,6 @@
 	call		schedule_tail
 	calll.p		@(gr21,gr0)
 	or		gr20,gr20,gr8
-	bra		sys_exit
-
-	.globl		ret_from_kernel_execve
-ret_from_kernel_execve:
-	ori		gr28,0,sp
 	bra		__syscall_exit
 
 ###################################################################################################
@@ -1080,27 +1075,10 @@
 	subicc		gr5,#0,gr0,icc0
 	beq		icc0,#0,__entry_return_direct
 
-__entry_preempt_need_resched:
-	ldi		@(gr15,#TI_FLAGS),gr4
-	andicc		gr4,#_TIF_NEED_RESCHED,gr0,icc0
-	beq		icc0,#1,__entry_return_direct
-
-	setlos		#PREEMPT_ACTIVE,gr5
-	sti		gr5,@(gr15,#TI_FLAGS)
-
-	andi		gr23,#~PSR_PIL,gr23
-	movgs		gr23,psr
-
-	call		schedule
-	sti		gr0,@(gr15,#TI_PRE_COUNT)
-
-	movsg		psr,gr23
-	ori		gr23,#PSR_PIL_14,gr23
-	movgs		gr23,psr
-	bra		__entry_preempt_need_resched
-#else
-	bra		__entry_return_direct
+	subcc		gr0,gr0,gr0,icc2		/* set Z and clear C */
+	call		preempt_schedule_irq
 #endif
+	bra		__entry_return_direct
 
 
 ###############################################################################
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index e1e3aa1..7e33215 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -181,6 +181,9 @@
 	childregs = (struct pt_regs *)
 		(task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
 
+	/* set up the userspace frame (the only place that the USP is stored) */
+	*childregs = *__kernel_frame0_ptr;
+
 	p->set_child_tid = p->clear_child_tid = NULL;
 
 	p->thread.frame	 = childregs;
@@ -191,10 +194,8 @@
 	p->thread.frame0 = childregs;
 
 	if (unlikely(!regs)) {
-		memset(childregs, 0, sizeof(struct pt_regs));
 		childregs->gr9 = usp; /* function */
 		childregs->gr8 = arg;
-		childregs->psr = PSR_S;
 		p->thread.pc = (unsigned long) ret_from_kernel_thread;
 		save_user_regs(p->thread.user);
 		return 0;
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index e47857f..b99c2a7 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -11,6 +11,7 @@
 
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
 #include <linux/pci.h>
diff --git a/arch/h8300/include/asm/cache.h b/arch/h8300/include/asm/cache.h
index c635028..05887a1 100644
--- a/arch/h8300/include/asm/cache.h
+++ b/arch/h8300/include/asm/cache.h
@@ -2,7 +2,8 @@
 #define __ARCH_H8300_CACHE_H
 
 /* bytes per L1 cache line */
-#define        L1_CACHE_BYTES  4
+#define        L1_CACHE_SHIFT  2
+#define        L1_CACHE_BYTES  (1 << L1_CACHE_SHIFT)
 
 /* m68k-elf-gcc  2.95.2 doesn't like these */
 
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
index 4a159da..dd02f09 100644
--- a/arch/ia64/include/asm/Kbuild
+++ b/arch/ia64/include/asm/Kbuild
@@ -1,3 +1,4 @@
 
 generic-y += clkdev.h
 generic-y += exec.h
+generic-y += kvm_para.h
diff --git a/arch/ia64/include/asm/kvm_para.h b/arch/ia64/include/asm/kvm_para.h
deleted file mode 100644
index 47c00f9..0000000
--- a/arch/ia64/include/asm/kvm_para.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2007 Xiantao Zhang <xiantao.zhang@intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- */
-#ifndef __IA64_KVM_PARA_H
-#define __IA64_KVM_PARA_H
-
-#include <uapi/asm/kvm_para.h>
-
-
-static inline unsigned int kvm_arch_para_features(void)
-{
-	return 0;
-}
-
-static inline bool kvm_check_and_clear_guest_paused(void)
-{
-	return false;
-}
-
-#endif
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index acd5b68..082e383 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -637,7 +637,6 @@
 
 	high_memory = __va(max_low_pfn * PAGE_SIZE);
 
-	reset_zone_present_pages();
 	for_each_online_pgdat(pgdat)
 		if (pgdat->bdata->node_bootmem_map)
 			totalram_pages += free_all_bootmem_node(pgdat);
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
index ecb5408..88fa3ac 100644
--- a/arch/m68k/include/asm/Kbuild
+++ b/arch/m68k/include/asm/Kbuild
@@ -1,5 +1,3 @@
-include include/asm-generic/Kbuild.asm
-header-y += cachectl.h
 
 generic-y += bitsperlong.h
 generic-y += clkdev.h
diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h
index 5e08b59..0f71704 100644
--- a/arch/m68k/include/asm/ptrace.h
+++ b/arch/m68k/include/asm/ptrace.h
@@ -1,82 +1,10 @@
 #ifndef _M68K_PTRACE_H
 #define _M68K_PTRACE_H
 
-#define PT_D1	   0
-#define PT_D2	   1
-#define PT_D3	   2
-#define PT_D4	   3
-#define PT_D5	   4
-#define PT_D6	   5
-#define PT_D7	   6
-#define PT_A0	   7
-#define PT_A1	   8
-#define PT_A2	   9
-#define PT_A3	   10
-#define PT_A4	   11
-#define PT_A5	   12
-#define PT_A6	   13
-#define PT_D0	   14
-#define PT_USP	   15
-#define PT_ORIG_D0 16
-#define PT_SR	   17
-#define PT_PC	   18
+#include <uapi/asm/ptrace.h>
 
 #ifndef __ASSEMBLY__
 
-/* this struct defines the way the registers are stored on the
-   stack during a system call. */
-
-struct pt_regs {
-  long     d1;
-  long     d2;
-  long     d3;
-  long     d4;
-  long     d5;
-  long     a0;
-  long     a1;
-  long     a2;
-  long     d0;
-  long     orig_d0;
-  long     stkadj;
-#ifdef CONFIG_COLDFIRE
-  unsigned format :  4; /* frame format specifier */
-  unsigned vector : 12; /* vector offset */
-  unsigned short sr;
-  unsigned long  pc;
-#else
-  unsigned short sr;
-  unsigned long  pc;
-  unsigned format :  4; /* frame format specifier */
-  unsigned vector : 12; /* vector offset */
-#endif
-};
-
-/*
- * This is the extended stack used by signal handlers and the context
- * switcher: it's pushed after the normal "struct pt_regs".
- */
-struct switch_stack {
-	unsigned long  d6;
-	unsigned long  d7;
-	unsigned long  a3;
-	unsigned long  a4;
-	unsigned long  a5;
-	unsigned long  a6;
-	unsigned long  retpc;
-};
-
-/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-#define PTRACE_GETREGS            12
-#define PTRACE_SETREGS            13
-#define PTRACE_GETFPREGS          14
-#define PTRACE_SETFPREGS          15
-
-#define PTRACE_GET_THREAD_AREA    25
-
-#define PTRACE_SINGLEBLOCK	33	/* resume execution until next branch */
-
-#ifdef __KERNEL__
-
 #ifndef PS_S
 #define PS_S  (0x2000)
 #define PS_M  (0x1000)
@@ -94,6 +22,5 @@
 #define arch_has_block_step()	(1)
 #endif
 
-#endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 #endif /* _M68K_PTRACE_H */
diff --git a/arch/m68k/include/asm/setup.h b/arch/m68k/include/asm/setup.h
index 00c2c53..65e78a2d 100644
--- a/arch/m68k/include/asm/setup.h
+++ b/arch/m68k/include/asm/setup.h
@@ -19,33 +19,12 @@
 **   Redesign of the boot information structure; moved boot information
 **   structure to bootinfo.h
 */
-
 #ifndef _M68K_SETUP_H
 #define _M68K_SETUP_H
 
+#include <uapi/asm/setup.h>
 
 
-    /*
-     *  Linux/m68k Architectures
-     */
-
-#define MACH_AMIGA    1
-#define MACH_ATARI    2
-#define MACH_MAC      3
-#define MACH_APOLLO   4
-#define MACH_SUN3     5
-#define MACH_MVME147  6
-#define MACH_MVME16x  7
-#define MACH_BVME6000 8
-#define MACH_HP300    9
-#define MACH_Q40     10
-#define MACH_SUN3X   11
-#define MACH_M54XX   12
-
-#define COMMAND_LINE_SIZE 256
-
-#ifdef __KERNEL__
-
 #define CL_SIZE COMMAND_LINE_SIZE
 
 #ifndef __ASSEMBLY__
@@ -194,63 +173,6 @@
 #  define MACH_TYPE (m68k_machtype)
 #endif
 
-#endif /* __KERNEL__ */
-
-
-    /*
-     *  CPU, FPU and MMU types
-     *
-     *  Note: we may rely on the following equalities:
-     *
-     *      CPU_68020 == MMU_68851
-     *      CPU_68030 == MMU_68030
-     *      CPU_68040 == FPU_68040 == MMU_68040
-     *      CPU_68060 == FPU_68060 == MMU_68060
-     */
-
-#define CPUB_68020     0
-#define CPUB_68030     1
-#define CPUB_68040     2
-#define CPUB_68060     3
-#define CPUB_COLDFIRE  4
-
-#define CPU_68020      (1<<CPUB_68020)
-#define CPU_68030      (1<<CPUB_68030)
-#define CPU_68040      (1<<CPUB_68040)
-#define CPU_68060      (1<<CPUB_68060)
-#define CPU_COLDFIRE   (1<<CPUB_COLDFIRE)
-
-#define FPUB_68881     0
-#define FPUB_68882     1
-#define FPUB_68040     2                       /* Internal FPU */
-#define FPUB_68060     3                       /* Internal FPU */
-#define FPUB_SUNFPA    4                       /* Sun-3 FPA */
-#define FPUB_COLDFIRE  5                       /* ColdFire FPU */
-
-#define FPU_68881      (1<<FPUB_68881)
-#define FPU_68882      (1<<FPUB_68882)
-#define FPU_68040      (1<<FPUB_68040)
-#define FPU_68060      (1<<FPUB_68060)
-#define FPU_SUNFPA     (1<<FPUB_SUNFPA)
-#define FPU_COLDFIRE   (1<<FPUB_COLDFIRE)
-
-#define MMUB_68851     0
-#define MMUB_68030     1                       /* Internal MMU */
-#define MMUB_68040     2                       /* Internal MMU */
-#define MMUB_68060     3                       /* Internal MMU */
-#define MMUB_APOLLO    4                       /* Custom Apollo */
-#define MMUB_SUN3      5                       /* Custom Sun-3 */
-#define MMUB_COLDFIRE  6                       /* Internal MMU */
-
-#define MMU_68851      (1<<MMUB_68851)
-#define MMU_68030      (1<<MMUB_68030)
-#define MMU_68040      (1<<MMUB_68040)
-#define MMU_68060      (1<<MMUB_68060)
-#define MMU_SUN3       (1<<MMUB_SUN3)
-#define MMU_APOLLO     (1<<MMUB_APOLLO)
-#define MMU_COLDFIRE   (1<<MMUB_COLDFIRE)
-
-#ifdef __KERNEL__
 
 #ifndef __ASSEMBLY__
 extern unsigned long m68k_cputype;
@@ -385,6 +307,4 @@
 extern struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */
 #endif
 
-#endif /* __KERNEL__ */
-
 #endif /* _M68K_SETUP_H */
diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h
index 60e8866..67e489d 100644
--- a/arch/m68k/include/asm/signal.h
+++ b/arch/m68k/include/asm/signal.h
@@ -1,12 +1,8 @@
 #ifndef _M68K_SIGNAL_H
 #define _M68K_SIGNAL_H
 
-#include <linux/types.h>
+#include <uapi/asm/signal.h>
 
-/* Avoid too many header ordering problems.  */
-struct siginfo;
-
-#ifdef __KERNEL__
 /* Most things should be clean enough to redefine this at will, if care
    is taken to make libc match.  */
 
@@ -20,92 +16,6 @@
 	unsigned long sig[_NSIG_WORDS];
 } sigset_t;
 
-#else
-/* Here we must cater to libcs that poke about in kernel headers.  */
-
-#define NSIG		32
-typedef unsigned long sigset_t;
-
-#endif /* __KERNEL__ */
-
-#define SIGHUP		 1
-#define SIGINT		 2
-#define SIGQUIT		 3
-#define SIGILL		 4
-#define SIGTRAP		 5
-#define SIGABRT		 6
-#define SIGIOT		 6
-#define SIGBUS		 7
-#define SIGFPE		 8
-#define SIGKILL		 9
-#define SIGUSR1		10
-#define SIGSEGV		11
-#define SIGUSR2		12
-#define SIGPIPE		13
-#define SIGALRM		14
-#define SIGTERM		15
-#define SIGSTKFLT	16
-#define SIGCHLD		17
-#define SIGCONT		18
-#define SIGSTOP		19
-#define SIGTSTP		20
-#define SIGTTIN		21
-#define SIGTTOU		22
-#define SIGURG		23
-#define SIGXCPU		24
-#define SIGXFSZ		25
-#define SIGVTALRM	26
-#define SIGPROF		27
-#define SIGWINCH	28
-#define SIGIO		29
-#define SIGPOLL		SIGIO
-/*
-#define SIGLOST		29
-*/
-#define SIGPWR		30
-#define SIGSYS		31
-#define	SIGUNUSED	31
-
-/* These should not be considered constants from userland.  */
-#define SIGRTMIN	32
-#define SIGRTMAX	_NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002
-#define SA_SIGINFO	0x00000004
-#define SA_ONSTACK	0x08000000
-#define SA_RESTART	0x10000000
-#define SA_NODEFER	0x40000000
-#define SA_RESETHAND	0x80000000
-
-#define SA_NOMASK	SA_NODEFER
-#define SA_ONESHOT	SA_RESETHAND
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK	1
-#define SS_DISABLE	2
-
-#define MINSIGSTKSZ	2048
-#define SIGSTKSZ	8192
-
-#include <asm-generic/signal-defs.h>
-
-#ifdef __KERNEL__
 struct old_sigaction {
 	__sighandler_t sa_handler;
 	old_sigset_t sa_mask;
@@ -123,31 +33,6 @@
 struct k_sigaction {
 	struct sigaction sa;
 };
-#else
-/* Here we must cater to libcs that poke about in kernel headers.  */
-
-struct sigaction {
-	union {
-	  __sighandler_t _sa_handler;
-	  void (*_sa_sigaction)(int, struct siginfo *, void *);
-	} _u;
-	sigset_t sa_mask;
-	unsigned long sa_flags;
-	void (*sa_restorer)(void);
-};
-
-#define sa_handler	_u._sa_handler
-#define sa_sigaction	_u._sa_sigaction
-
-#endif /* __KERNEL__ */
-
-typedef struct sigaltstack {
-	void __user *ss_sp;
-	int ss_flags;
-	size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
 #include <asm/sigcontext.h>
 
 #ifndef CONFIG_CPU_HAS_NO_BITFIELDS
@@ -208,5 +93,4 @@
 extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
 #endif /* __uClinux__ */
 
-#endif /* __KERNEL__ */
 #endif /* _M68K_SIGNAL_H */
diff --git a/arch/m68k/include/asm/termios.h b/arch/m68k/include/asm/termios.h
index 0823032..ad8efb0 100644
--- a/arch/m68k/include/asm/termios.h
+++ b/arch/m68k/include/asm/termios.h
@@ -1,27 +1,8 @@
 #ifndef _M68K_TERMIOS_H
 #define _M68K_TERMIOS_H
 
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
+#include <uapi/asm/termios.h>
 
-struct winsize {
-	unsigned short ws_row;
-	unsigned short ws_col;
-	unsigned short ws_xpixel;
-	unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
-	unsigned short c_iflag;		/* input mode flags */
-	unsigned short c_oflag;		/* output mode flags */
-	unsigned short c_cflag;		/* control mode flags */
-	unsigned short c_lflag;		/* local mode flags */
-	unsigned char c_line;		/* line discipline */
-	unsigned char c_cc[NCC];	/* control characters */
-};
-
-#ifdef __KERNEL__
 /*	intr=^C		quit=^|		erase=del	kill=^U
 	eof=^D		vtime=\0	vmin=\1		sxtc=\0
 	start=^Q	stop=^S		susp=^Z		eol=\0
@@ -29,27 +10,6 @@
 	eol2=\0
 */
 #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-#endif
-
-/* modem lines */
-#define TIOCM_LE	0x001
-#define TIOCM_DTR	0x002
-#define TIOCM_RTS	0x004
-#define TIOCM_ST	0x008
-#define TIOCM_SR	0x010
-#define TIOCM_CTS	0x020
-#define TIOCM_CAR	0x040
-#define TIOCM_RNG	0x080
-#define TIOCM_DSR	0x100
-#define TIOCM_CD	TIOCM_CAR
-#define TIOCM_RI	TIOCM_RNG
-#define TIOCM_OUT1	0x2000
-#define TIOCM_OUT2	0x4000
-#define TIOCM_LOOP	0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
 
 /*
  * Translate a "termio" structure into a "termios". Ugh.
@@ -87,6 +47,4 @@
 #define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
 #define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
 
-#endif	/* __KERNEL__ */
-
 #endif /* _M68K_TERMIOS_H */
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index c702ad7..5fc7f7b 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -1,361 +1,10 @@
 #ifndef _ASM_M68K_UNISTD_H_
 #define _ASM_M68K_UNISTD_H_
 
-/*
- * This file contains the system call numbers.
- */
+#include <uapi/asm/unistd.h>
 
-#define __NR_restart_syscall	  0
-#define __NR_exit		  1
-#define __NR_fork		  2
-#define __NR_read		  3
-#define __NR_write		  4
-#define __NR_open		  5
-#define __NR_close		  6
-#define __NR_waitpid		  7
-#define __NR_creat		  8
-#define __NR_link		  9
-#define __NR_unlink		 10
-#define __NR_execve		 11
-#define __NR_chdir		 12
-#define __NR_time		 13
-#define __NR_mknod		 14
-#define __NR_chmod		 15
-#define __NR_chown		 16
-/*#define __NR_break		 17*/
-#define __NR_oldstat		 18
-#define __NR_lseek		 19
-#define __NR_getpid		 20
-#define __NR_mount		 21
-#define __NR_umount		 22
-#define __NR_setuid		 23
-#define __NR_getuid		 24
-#define __NR_stime		 25
-#define __NR_ptrace		 26
-#define __NR_alarm		 27
-#define __NR_oldfstat		 28
-#define __NR_pause		 29
-#define __NR_utime		 30
-/*#define __NR_stty		 31*/
-/*#define __NR_gtty		 32*/
-#define __NR_access		 33
-#define __NR_nice		 34
-/*#define __NR_ftime		 35*/
-#define __NR_sync		 36
-#define __NR_kill		 37
-#define __NR_rename		 38
-#define __NR_mkdir		 39
-#define __NR_rmdir		 40
-#define __NR_dup		 41
-#define __NR_pipe		 42
-#define __NR_times		 43
-/*#define __NR_prof		 44*/
-#define __NR_brk		 45
-#define __NR_setgid		 46
-#define __NR_getgid		 47
-#define __NR_signal		 48
-#define __NR_geteuid		 49
-#define __NR_getegid		 50
-#define __NR_acct		 51
-#define __NR_umount2		 52
-/*#define __NR_lock		 53*/
-#define __NR_ioctl		 54
-#define __NR_fcntl		 55
-/*#define __NR_mpx		 56*/
-#define __NR_setpgid		 57
-/*#define __NR_ulimit		 58*/
-/*#define __NR_oldolduname	 59*/
-#define __NR_umask		 60
-#define __NR_chroot		 61
-#define __NR_ustat		 62
-#define __NR_dup2		 63
-#define __NR_getppid		 64
-#define __NR_getpgrp		 65
-#define __NR_setsid		 66
-#define __NR_sigaction		 67
-#define __NR_sgetmask		 68
-#define __NR_ssetmask		 69
-#define __NR_setreuid		 70
-#define __NR_setregid		 71
-#define __NR_sigsuspend		 72
-#define __NR_sigpending		 73
-#define __NR_sethostname	 74
-#define __NR_setrlimit		 75
-#define __NR_getrlimit		 76
-#define __NR_getrusage		 77
-#define __NR_gettimeofday	 78
-#define __NR_settimeofday	 79
-#define __NR_getgroups		 80
-#define __NR_setgroups		 81
-#define __NR_select		 82
-#define __NR_symlink		 83
-#define __NR_oldlstat		 84
-#define __NR_readlink		 85
-#define __NR_uselib		 86
-#define __NR_swapon		 87
-#define __NR_reboot		 88
-#define __NR_readdir		 89
-#define __NR_mmap		 90
-#define __NR_munmap		 91
-#define __NR_truncate		 92
-#define __NR_ftruncate		 93
-#define __NR_fchmod		 94
-#define __NR_fchown		 95
-#define __NR_getpriority	 96
-#define __NR_setpriority	 97
-/*#define __NR_profil		 98*/
-#define __NR_statfs		 99
-#define __NR_fstatfs		100
-/*#define __NR_ioperm		101*/
-#define __NR_socketcall		102
-#define __NR_syslog		103
-#define __NR_setitimer		104
-#define __NR_getitimer		105
-#define __NR_stat		106
-#define __NR_lstat		107
-#define __NR_fstat		108
-/*#define __NR_olduname		109*/
-/*#define __NR_iopl		110*/ /* not supported */
-#define __NR_vhangup		111
-/*#define __NR_idle		112*/ /* Obsolete */
-/*#define __NR_vm86		113*/ /* not supported */
-#define __NR_wait4		114
-#define __NR_swapoff		115
-#define __NR_sysinfo		116
-#define __NR_ipc		117
-#define __NR_fsync		118
-#define __NR_sigreturn		119
-#define __NR_clone		120
-#define __NR_setdomainname	121
-#define __NR_uname		122
-#define __NR_cacheflush		123
-#define __NR_adjtimex		124
-#define __NR_mprotect		125
-#define __NR_sigprocmask	126
-#define __NR_create_module	127
-#define __NR_init_module	128
-#define __NR_delete_module	129
-#define __NR_get_kernel_syms	130
-#define __NR_quotactl		131
-#define __NR_getpgid		132
-#define __NR_fchdir		133
-#define __NR_bdflush		134
-#define __NR_sysfs		135
-#define __NR_personality	136
-/*#define __NR_afs_syscall	137*/ /* Syscall for Andrew File System */
-#define __NR_setfsuid		138
-#define __NR_setfsgid		139
-#define __NR__llseek		140
-#define __NR_getdents		141
-#define __NR__newselect		142
-#define __NR_flock		143
-#define __NR_msync		144
-#define __NR_readv		145
-#define __NR_writev		146
-#define __NR_getsid		147
-#define __NR_fdatasync		148
-#define __NR__sysctl		149
-#define __NR_mlock		150
-#define __NR_munlock		151
-#define __NR_mlockall		152
-#define __NR_munlockall		153
-#define __NR_sched_setparam		154
-#define __NR_sched_getparam		155
-#define __NR_sched_setscheduler		156
-#define __NR_sched_getscheduler		157
-#define __NR_sched_yield		158
-#define __NR_sched_get_priority_max	159
-#define __NR_sched_get_priority_min	160
-#define __NR_sched_rr_get_interval	161
-#define __NR_nanosleep		162
-#define __NR_mremap		163
-#define __NR_setresuid		164
-#define __NR_getresuid		165
-#define __NR_getpagesize	166
-#define __NR_query_module	167
-#define __NR_poll		168
-#define __NR_nfsservctl		169
-#define __NR_setresgid		170
-#define __NR_getresgid		171
-#define __NR_prctl		172
-#define __NR_rt_sigreturn	173
-#define __NR_rt_sigaction	174
-#define __NR_rt_sigprocmask	175
-#define __NR_rt_sigpending	176
-#define __NR_rt_sigtimedwait	177
-#define __NR_rt_sigqueueinfo	178
-#define __NR_rt_sigsuspend	179
-#define __NR_pread64		180
-#define __NR_pwrite64		181
-#define __NR_lchown		182
-#define __NR_getcwd		183
-#define __NR_capget		184
-#define __NR_capset		185
-#define __NR_sigaltstack	186
-#define __NR_sendfile		187
-#define __NR_getpmsg		188	/* some people actually want streams */
-#define __NR_putpmsg		189	/* some people actually want streams */
-#define __NR_vfork		190
-#define __NR_ugetrlimit		191
-#define __NR_mmap2		192
-#define __NR_truncate64		193
-#define __NR_ftruncate64	194
-#define __NR_stat64		195
-#define __NR_lstat64		196
-#define __NR_fstat64		197
-#define __NR_chown32		198
-#define __NR_getuid32		199
-#define __NR_getgid32		200
-#define __NR_geteuid32		201
-#define __NR_getegid32		202
-#define __NR_setreuid32		203
-#define __NR_setregid32		204
-#define __NR_getgroups32	205
-#define __NR_setgroups32	206
-#define __NR_fchown32		207
-#define __NR_setresuid32	208
-#define __NR_getresuid32	209
-#define __NR_setresgid32	210
-#define __NR_getresgid32	211
-#define __NR_lchown32		212
-#define __NR_setuid32		213
-#define __NR_setgid32		214
-#define __NR_setfsuid32		215
-#define __NR_setfsgid32		216
-#define __NR_pivot_root		217
-/* 218*/
-/* 219*/
-#define __NR_getdents64		220
-#define __NR_gettid		221
-#define __NR_tkill		222
-#define __NR_setxattr		223
-#define __NR_lsetxattr		224
-#define __NR_fsetxattr		225
-#define __NR_getxattr		226
-#define __NR_lgetxattr		227
-#define __NR_fgetxattr		228
-#define __NR_listxattr		229
-#define __NR_llistxattr		230
-#define __NR_flistxattr		231
-#define __NR_removexattr	232
-#define __NR_lremovexattr	233
-#define __NR_fremovexattr	234
-#define __NR_futex		235
-#define __NR_sendfile64		236
-#define __NR_mincore		237
-#define __NR_madvise		238
-#define __NR_fcntl64		239
-#define __NR_readahead		240
-#define __NR_io_setup		241
-#define __NR_io_destroy		242
-#define __NR_io_getevents	243
-#define __NR_io_submit		244
-#define __NR_io_cancel		245
-#define __NR_fadvise64		246
-#define __NR_exit_group		247
-#define __NR_lookup_dcookie	248
-#define __NR_epoll_create	249
-#define __NR_epoll_ctl		250
-#define __NR_epoll_wait		251
-#define __NR_remap_file_pages	252
-#define __NR_set_tid_address	253
-#define __NR_timer_create	254
-#define __NR_timer_settime	255
-#define __NR_timer_gettime	256
-#define __NR_timer_getoverrun	257
-#define __NR_timer_delete	258
-#define __NR_clock_settime	259
-#define __NR_clock_gettime	260
-#define __NR_clock_getres	261
-#define __NR_clock_nanosleep	262
-#define __NR_statfs64		263
-#define __NR_fstatfs64		264
-#define __NR_tgkill		265
-#define __NR_utimes		266
-#define __NR_fadvise64_64	267
-#define __NR_mbind		268
-#define __NR_get_mempolicy	269
-#define __NR_set_mempolicy	270
-#define __NR_mq_open		271
-#define __NR_mq_unlink		272
-#define __NR_mq_timedsend	273
-#define __NR_mq_timedreceive	274
-#define __NR_mq_notify		275
-#define __NR_mq_getsetattr	276
-#define __NR_waitid		277
-/*#define __NR_vserver		278*/
-#define __NR_add_key		279
-#define __NR_request_key	280
-#define __NR_keyctl		281
-#define __NR_ioprio_set		282
-#define __NR_ioprio_get		283
-#define __NR_inotify_init	284
-#define __NR_inotify_add_watch	285
-#define __NR_inotify_rm_watch	286
-#define __NR_migrate_pages	287
-#define __NR_openat		288
-#define __NR_mkdirat		289
-#define __NR_mknodat		290
-#define __NR_fchownat		291
-#define __NR_futimesat		292
-#define __NR_fstatat64		293
-#define __NR_unlinkat		294
-#define __NR_renameat		295
-#define __NR_linkat		296
-#define __NR_symlinkat		297
-#define __NR_readlinkat		298
-#define __NR_fchmodat		299
-#define __NR_faccessat		300
-#define __NR_pselect6		301
-#define __NR_ppoll		302
-#define __NR_unshare		303
-#define __NR_set_robust_list	304
-#define __NR_get_robust_list	305
-#define __NR_splice		306
-#define __NR_sync_file_range	307
-#define __NR_tee		308
-#define __NR_vmsplice		309
-#define __NR_move_pages		310
-#define __NR_sched_setaffinity	311
-#define __NR_sched_getaffinity	312
-#define __NR_kexec_load		313
-#define __NR_getcpu		314
-#define __NR_epoll_pwait	315
-#define __NR_utimensat		316
-#define __NR_signalfd		317
-#define __NR_timerfd_create	318
-#define __NR_eventfd		319
-#define __NR_fallocate		320
-#define __NR_timerfd_settime	321
-#define __NR_timerfd_gettime	322
-#define __NR_signalfd4		323
-#define __NR_eventfd2		324
-#define __NR_epoll_create1	325
-#define __NR_dup3		326
-#define __NR_pipe2		327
-#define __NR_inotify_init1	328
-#define __NR_preadv		329
-#define __NR_pwritev		330
-#define __NR_rt_tgsigqueueinfo	331
-#define __NR_perf_event_open	332
-#define __NR_get_thread_area	333
-#define __NR_set_thread_area	334
-#define __NR_atomic_cmpxchg_32	335
-#define __NR_atomic_barrier	336
-#define __NR_fanotify_init	337
-#define __NR_fanotify_mark	338
-#define __NR_prlimit64		339
-#define __NR_name_to_handle_at	340
-#define __NR_open_by_handle_at	341
-#define __NR_clock_adjtime	342
-#define __NR_syncfs		343
-#define __NR_setns		344
-#define __NR_process_vm_readv	345
-#define __NR_process_vm_writev	346
 
-#ifdef __KERNEL__
-
-#define NR_syscalls		347
+#define NR_syscalls		348
 
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_OLD_STAT
@@ -393,5 +42,4 @@
  */
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
 
-#endif /* __KERNEL__ */
 #endif /* _ASM_M68K_UNISTD_H_ */
diff --git a/arch/m68k/include/uapi/asm/Kbuild b/arch/m68k/include/uapi/asm/Kbuild
index baebb3d..972bce1 100644
--- a/arch/m68k/include/uapi/asm/Kbuild
+++ b/arch/m68k/include/uapi/asm/Kbuild
@@ -1,3 +1,26 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
+header-y += a.out.h
+header-y += auxvec.h
+header-y += byteorder.h
+header-y += cachectl.h
+header-y += fcntl.h
+header-y += ioctls.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += unistd.h
diff --git a/arch/m68k/include/asm/a.out.h b/arch/m68k/include/uapi/asm/a.out.h
similarity index 100%
rename from arch/m68k/include/asm/a.out.h
rename to arch/m68k/include/uapi/asm/a.out.h
diff --git a/arch/m68k/include/asm/auxvec.h b/arch/m68k/include/uapi/asm/auxvec.h
similarity index 100%
rename from arch/m68k/include/asm/auxvec.h
rename to arch/m68k/include/uapi/asm/auxvec.h
diff --git a/arch/m68k/include/asm/byteorder.h b/arch/m68k/include/uapi/asm/byteorder.h
similarity index 100%
rename from arch/m68k/include/asm/byteorder.h
rename to arch/m68k/include/uapi/asm/byteorder.h
diff --git a/arch/m68k/include/asm/cachectl.h b/arch/m68k/include/uapi/asm/cachectl.h
similarity index 100%
rename from arch/m68k/include/asm/cachectl.h
rename to arch/m68k/include/uapi/asm/cachectl.h
diff --git a/arch/m68k/include/asm/fcntl.h b/arch/m68k/include/uapi/asm/fcntl.h
similarity index 100%
rename from arch/m68k/include/asm/fcntl.h
rename to arch/m68k/include/uapi/asm/fcntl.h
diff --git a/arch/m68k/include/asm/ioctls.h b/arch/m68k/include/uapi/asm/ioctls.h
similarity index 100%
rename from arch/m68k/include/asm/ioctls.h
rename to arch/m68k/include/uapi/asm/ioctls.h
diff --git a/arch/m68k/include/asm/msgbuf.h b/arch/m68k/include/uapi/asm/msgbuf.h
similarity index 100%
rename from arch/m68k/include/asm/msgbuf.h
rename to arch/m68k/include/uapi/asm/msgbuf.h
diff --git a/arch/m68k/include/asm/param.h b/arch/m68k/include/uapi/asm/param.h
similarity index 100%
rename from arch/m68k/include/asm/param.h
rename to arch/m68k/include/uapi/asm/param.h
diff --git a/arch/m68k/include/asm/poll.h b/arch/m68k/include/uapi/asm/poll.h
similarity index 100%
rename from arch/m68k/include/asm/poll.h
rename to arch/m68k/include/uapi/asm/poll.h
diff --git a/arch/m68k/include/asm/posix_types.h b/arch/m68k/include/uapi/asm/posix_types.h
similarity index 100%
rename from arch/m68k/include/asm/posix_types.h
rename to arch/m68k/include/uapi/asm/posix_types.h
diff --git a/arch/m68k/include/uapi/asm/ptrace.h b/arch/m68k/include/uapi/asm/ptrace.h
new file mode 100644
index 0000000..caf92fd
--- /dev/null
+++ b/arch/m68k/include/uapi/asm/ptrace.h
@@ -0,0 +1,79 @@
+#ifndef _UAPI_M68K_PTRACE_H
+#define _UAPI_M68K_PTRACE_H
+
+#define PT_D1	   0
+#define PT_D2	   1
+#define PT_D3	   2
+#define PT_D4	   3
+#define PT_D5	   4
+#define PT_D6	   5
+#define PT_D7	   6
+#define PT_A0	   7
+#define PT_A1	   8
+#define PT_A2	   9
+#define PT_A3	   10
+#define PT_A4	   11
+#define PT_A5	   12
+#define PT_A6	   13
+#define PT_D0	   14
+#define PT_USP	   15
+#define PT_ORIG_D0 16
+#define PT_SR	   17
+#define PT_PC	   18
+
+#ifndef __ASSEMBLY__
+
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+
+struct pt_regs {
+  long     d1;
+  long     d2;
+  long     d3;
+  long     d4;
+  long     d5;
+  long     a0;
+  long     a1;
+  long     a2;
+  long     d0;
+  long     orig_d0;
+  long     stkadj;
+#ifdef CONFIG_COLDFIRE
+  unsigned format :  4; /* frame format specifier */
+  unsigned vector : 12; /* vector offset */
+  unsigned short sr;
+  unsigned long  pc;
+#else
+  unsigned short sr;
+  unsigned long  pc;
+  unsigned format :  4; /* frame format specifier */
+  unsigned vector : 12; /* vector offset */
+#endif
+};
+
+/*
+ * This is the extended stack used by signal handlers and the context
+ * switcher: it's pushed after the normal "struct pt_regs".
+ */
+struct switch_stack {
+	unsigned long  d6;
+	unsigned long  d7;
+	unsigned long  a3;
+	unsigned long  a4;
+	unsigned long  a5;
+	unsigned long  a6;
+	unsigned long  retpc;
+};
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+#define PTRACE_GETFPREGS          14
+#define PTRACE_SETFPREGS          15
+
+#define PTRACE_GET_THREAD_AREA    25
+
+#define PTRACE_SINGLEBLOCK	33	/* resume execution until next branch */
+
+#endif /* __ASSEMBLY__ */
+#endif /* _UAPI_M68K_PTRACE_H */
diff --git a/arch/m68k/include/asm/sembuf.h b/arch/m68k/include/uapi/asm/sembuf.h
similarity index 100%
rename from arch/m68k/include/asm/sembuf.h
rename to arch/m68k/include/uapi/asm/sembuf.h
diff --git a/arch/m68k/include/uapi/asm/setup.h b/arch/m68k/include/uapi/asm/setup.h
new file mode 100644
index 0000000..85579bf
--- /dev/null
+++ b/arch/m68k/include/uapi/asm/setup.h
@@ -0,0 +1,103 @@
+/*
+** asm/setup.h -- Definition of the Linux/m68k setup information
+**
+** Copyright 1992 by Greg Harp
+**
+** This file is subject to the terms and conditions of the GNU General Public
+** License.  See the file COPYING in the main directory of this archive
+** for more details.
+**
+** Created 09/29/92 by Greg Harp
+**
+** 5/2/94 Roman Hodek:
+**   Added bi_atari part of the machine dependent union bi_un; for now it
+**   contains just a model field to distinguish between TT and Falcon.
+** 26/7/96 Roman Zippel:
+**   Renamed to setup.h; added some useful macros to allow gcc some
+**   optimizations if possible.
+** 5/10/96 Geert Uytterhoeven:
+**   Redesign of the boot information structure; moved boot information
+**   structure to bootinfo.h
+*/
+
+#ifndef _UAPI_M68K_SETUP_H
+#define _UAPI_M68K_SETUP_H
+
+
+
+    /*
+     *  Linux/m68k Architectures
+     */
+
+#define MACH_AMIGA    1
+#define MACH_ATARI    2
+#define MACH_MAC      3
+#define MACH_APOLLO   4
+#define MACH_SUN3     5
+#define MACH_MVME147  6
+#define MACH_MVME16x  7
+#define MACH_BVME6000 8
+#define MACH_HP300    9
+#define MACH_Q40     10
+#define MACH_SUN3X   11
+#define MACH_M54XX   12
+
+#define COMMAND_LINE_SIZE 256
+
+
+
+    /*
+     *  CPU, FPU and MMU types
+     *
+     *  Note: we may rely on the following equalities:
+     *
+     *      CPU_68020 == MMU_68851
+     *      CPU_68030 == MMU_68030
+     *      CPU_68040 == FPU_68040 == MMU_68040
+     *      CPU_68060 == FPU_68060 == MMU_68060
+     */
+
+#define CPUB_68020     0
+#define CPUB_68030     1
+#define CPUB_68040     2
+#define CPUB_68060     3
+#define CPUB_COLDFIRE  4
+
+#define CPU_68020      (1<<CPUB_68020)
+#define CPU_68030      (1<<CPUB_68030)
+#define CPU_68040      (1<<CPUB_68040)
+#define CPU_68060      (1<<CPUB_68060)
+#define CPU_COLDFIRE   (1<<CPUB_COLDFIRE)
+
+#define FPUB_68881     0
+#define FPUB_68882     1
+#define FPUB_68040     2                       /* Internal FPU */
+#define FPUB_68060     3                       /* Internal FPU */
+#define FPUB_SUNFPA    4                       /* Sun-3 FPA */
+#define FPUB_COLDFIRE  5                       /* ColdFire FPU */
+
+#define FPU_68881      (1<<FPUB_68881)
+#define FPU_68882      (1<<FPUB_68882)
+#define FPU_68040      (1<<FPUB_68040)
+#define FPU_68060      (1<<FPUB_68060)
+#define FPU_SUNFPA     (1<<FPUB_SUNFPA)
+#define FPU_COLDFIRE   (1<<FPUB_COLDFIRE)
+
+#define MMUB_68851     0
+#define MMUB_68030     1                       /* Internal MMU */
+#define MMUB_68040     2                       /* Internal MMU */
+#define MMUB_68060     3                       /* Internal MMU */
+#define MMUB_APOLLO    4                       /* Custom Apollo */
+#define MMUB_SUN3      5                       /* Custom Sun-3 */
+#define MMUB_COLDFIRE  6                       /* Internal MMU */
+
+#define MMU_68851      (1<<MMUB_68851)
+#define MMU_68030      (1<<MMUB_68030)
+#define MMU_68040      (1<<MMUB_68040)
+#define MMU_68060      (1<<MMUB_68060)
+#define MMU_SUN3       (1<<MMUB_SUN3)
+#define MMU_APOLLO     (1<<MMUB_APOLLO)
+#define MMU_COLDFIRE   (1<<MMUB_COLDFIRE)
+
+
+#endif /* _UAPI_M68K_SETUP_H */
diff --git a/arch/m68k/include/asm/shmbuf.h b/arch/m68k/include/uapi/asm/shmbuf.h
similarity index 100%
rename from arch/m68k/include/asm/shmbuf.h
rename to arch/m68k/include/uapi/asm/shmbuf.h
diff --git a/arch/m68k/include/asm/sigcontext.h b/arch/m68k/include/uapi/asm/sigcontext.h
similarity index 100%
rename from arch/m68k/include/asm/sigcontext.h
rename to arch/m68k/include/uapi/asm/sigcontext.h
diff --git a/arch/m68k/include/uapi/asm/signal.h b/arch/m68k/include/uapi/asm/signal.h
new file mode 100644
index 0000000..2b450f3
--- /dev/null
+++ b/arch/m68k/include/uapi/asm/signal.h
@@ -0,0 +1,118 @@
+#ifndef _UAPI_M68K_SIGNAL_H
+#define _UAPI_M68K_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	_NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void __user *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#endif /* _UAPI_M68K_SIGNAL_H */
diff --git a/arch/m68k/include/asm/socket.h b/arch/m68k/include/uapi/asm/socket.h
similarity index 100%
rename from arch/m68k/include/asm/socket.h
rename to arch/m68k/include/uapi/asm/socket.h
diff --git a/arch/m68k/include/asm/sockios.h b/arch/m68k/include/uapi/asm/sockios.h
similarity index 100%
rename from arch/m68k/include/asm/sockios.h
rename to arch/m68k/include/uapi/asm/sockios.h
diff --git a/arch/m68k/include/asm/stat.h b/arch/m68k/include/uapi/asm/stat.h
similarity index 100%
rename from arch/m68k/include/asm/stat.h
rename to arch/m68k/include/uapi/asm/stat.h
diff --git a/arch/m68k/include/asm/swab.h b/arch/m68k/include/uapi/asm/swab.h
similarity index 100%
rename from arch/m68k/include/asm/swab.h
rename to arch/m68k/include/uapi/asm/swab.h
diff --git a/arch/m68k/include/asm/termbits.h b/arch/m68k/include/uapi/asm/termbits.h
similarity index 100%
rename from arch/m68k/include/asm/termbits.h
rename to arch/m68k/include/uapi/asm/termbits.h
diff --git a/arch/m68k/include/uapi/asm/termios.h b/arch/m68k/include/uapi/asm/termios.h
new file mode 100644
index 0000000..ce2142c
--- /dev/null
+++ b/arch/m68k/include/uapi/asm/termios.h
@@ -0,0 +1,44 @@
+#ifndef _UAPI_M68K_TERMIOS_H
+#define _UAPI_M68K_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+
+#endif /* _UAPI_M68K_TERMIOS_H */
diff --git a/arch/m68k/include/uapi/asm/unistd.h b/arch/m68k/include/uapi/asm/unistd.h
new file mode 100644
index 0000000..b94bfbf
--- /dev/null
+++ b/arch/m68k/include/uapi/asm/unistd.h
@@ -0,0 +1,357 @@
+#ifndef _UAPI_ASM_M68K_UNISTD_H_
+#define _UAPI_ASM_M68K_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall	  0
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+/*#define __NR_break		 17*/
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+/*#define __NR_stty		 31*/
+/*#define __NR_gtty		 32*/
+#define __NR_access		 33
+#define __NR_nice		 34
+/*#define __NR_ftime		 35*/
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+/*#define __NR_prof		 44*/
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+/*#define __NR_lock		 53*/
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+/*#define __NR_mpx		 56*/
+#define __NR_setpgid		 57
+/*#define __NR_ulimit		 58*/
+/*#define __NR_oldolduname	 59*/
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit		 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+/*#define __NR_profil		 98*/
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+/*#define __NR_ioperm		101*/
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+/*#define __NR_olduname		109*/
+/*#define __NR_iopl		110*/ /* not supported */
+#define __NR_vhangup		111
+/*#define __NR_idle		112*/ /* Obsolete */
+/*#define __NR_vm86		113*/ /* not supported */
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+/*#define __NR_afs_syscall	137*/ /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_getpagesize	166
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread64		180
+#define __NR_pwrite64		181
+#define __NR_lchown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_ugetrlimit		191
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_chown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_lchown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+/* 218*/
+/* 219*/
+#define __NR_getdents64		220
+#define __NR_gettid		221
+#define __NR_tkill		222
+#define __NR_setxattr		223
+#define __NR_lsetxattr		224
+#define __NR_fsetxattr		225
+#define __NR_getxattr		226
+#define __NR_lgetxattr		227
+#define __NR_fgetxattr		228
+#define __NR_listxattr		229
+#define __NR_llistxattr		230
+#define __NR_flistxattr		231
+#define __NR_removexattr	232
+#define __NR_lremovexattr	233
+#define __NR_fremovexattr	234
+#define __NR_futex		235
+#define __NR_sendfile64		236
+#define __NR_mincore		237
+#define __NR_madvise		238
+#define __NR_fcntl64		239
+#define __NR_readahead		240
+#define __NR_io_setup		241
+#define __NR_io_destroy		242
+#define __NR_io_getevents	243
+#define __NR_io_submit		244
+#define __NR_io_cancel		245
+#define __NR_fadvise64		246
+#define __NR_exit_group		247
+#define __NR_lookup_dcookie	248
+#define __NR_epoll_create	249
+#define __NR_epoll_ctl		250
+#define __NR_epoll_wait		251
+#define __NR_remap_file_pages	252
+#define __NR_set_tid_address	253
+#define __NR_timer_create	254
+#define __NR_timer_settime	255
+#define __NR_timer_gettime	256
+#define __NR_timer_getoverrun	257
+#define __NR_timer_delete	258
+#define __NR_clock_settime	259
+#define __NR_clock_gettime	260
+#define __NR_clock_getres	261
+#define __NR_clock_nanosleep	262
+#define __NR_statfs64		263
+#define __NR_fstatfs64		264
+#define __NR_tgkill		265
+#define __NR_utimes		266
+#define __NR_fadvise64_64	267
+#define __NR_mbind		268
+#define __NR_get_mempolicy	269
+#define __NR_set_mempolicy	270
+#define __NR_mq_open		271
+#define __NR_mq_unlink		272
+#define __NR_mq_timedsend	273
+#define __NR_mq_timedreceive	274
+#define __NR_mq_notify		275
+#define __NR_mq_getsetattr	276
+#define __NR_waitid		277
+/*#define __NR_vserver		278*/
+#define __NR_add_key		279
+#define __NR_request_key	280
+#define __NR_keyctl		281
+#define __NR_ioprio_set		282
+#define __NR_ioprio_get		283
+#define __NR_inotify_init	284
+#define __NR_inotify_add_watch	285
+#define __NR_inotify_rm_watch	286
+#define __NR_migrate_pages	287
+#define __NR_openat		288
+#define __NR_mkdirat		289
+#define __NR_mknodat		290
+#define __NR_fchownat		291
+#define __NR_futimesat		292
+#define __NR_fstatat64		293
+#define __NR_unlinkat		294
+#define __NR_renameat		295
+#define __NR_linkat		296
+#define __NR_symlinkat		297
+#define __NR_readlinkat		298
+#define __NR_fchmodat		299
+#define __NR_faccessat		300
+#define __NR_pselect6		301
+#define __NR_ppoll		302
+#define __NR_unshare		303
+#define __NR_set_robust_list	304
+#define __NR_get_robust_list	305
+#define __NR_splice		306
+#define __NR_sync_file_range	307
+#define __NR_tee		308
+#define __NR_vmsplice		309
+#define __NR_move_pages		310
+#define __NR_sched_setaffinity	311
+#define __NR_sched_getaffinity	312
+#define __NR_kexec_load		313
+#define __NR_getcpu		314
+#define __NR_epoll_pwait	315
+#define __NR_utimensat		316
+#define __NR_signalfd		317
+#define __NR_timerfd_create	318
+#define __NR_eventfd		319
+#define __NR_fallocate		320
+#define __NR_timerfd_settime	321
+#define __NR_timerfd_gettime	322
+#define __NR_signalfd4		323
+#define __NR_eventfd2		324
+#define __NR_epoll_create1	325
+#define __NR_dup3		326
+#define __NR_pipe2		327
+#define __NR_inotify_init1	328
+#define __NR_preadv		329
+#define __NR_pwritev		330
+#define __NR_rt_tgsigqueueinfo	331
+#define __NR_perf_event_open	332
+#define __NR_get_thread_area	333
+#define __NR_set_thread_area	334
+#define __NR_atomic_cmpxchg_32	335
+#define __NR_atomic_barrier	336
+#define __NR_fanotify_init	337
+#define __NR_fanotify_mark	338
+#define __NR_prlimit64		339
+#define __NR_name_to_handle_at	340
+#define __NR_open_by_handle_at	341
+#define __NR_clock_adjtime	342
+#define __NR_syncfs		343
+#define __NR_setns		344
+#define __NR_process_vm_readv	345
+#define __NR_process_vm_writev	346
+#define __NR_kcmp		347
+
+#endif /* _UAPI_ASM_M68K_UNISTD_H_ */
diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S
index ce827b3..4fc2e29 100644
--- a/arch/m68k/kernel/syscalltable.S
+++ b/arch/m68k/kernel/syscalltable.S
@@ -367,4 +367,5 @@
 	.long sys_setns
 	.long sys_process_vm_readv	/* 345 */
 	.long sys_process_vm_writev
+	.long sys_kcmp
 
diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
index d38246e..9f883bf 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
@@ -30,6 +30,7 @@
  * measurement, and debugging facilities.
  */
 
+#include <linux/irqflags.h>
 #include <asm/octeon/cvmx.h>
 #include <asm/octeon/cvmx-l2c.h>
 #include <asm/octeon/cvmx-spinlock.h>
diff --git a/arch/mips/fw/arc/misc.c b/arch/mips/fw/arc/misc.c
index 7cf80ca..f9f5307 100644
--- a/arch/mips/fw/arc/misc.c
+++ b/arch/mips/fw/arc/misc.c
@@ -11,6 +11,7 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/irqflags.h>
 
 #include <asm/bcache.h>
 
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index 82ad35c..46ac73a 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -14,7 +14,6 @@
 #endif
 
 #include <linux/compiler.h>
-#include <linux/irqflags.h>
 #include <linux/types.h>
 #include <asm/barrier.h>
 #include <asm/byteorder.h>		/* sigh ... */
@@ -44,6 +43,24 @@
 #define smp_mb__before_clear_bit()	smp_mb__before_llsc()
 #define smp_mb__after_clear_bit()	smp_llsc_mb()
 
+
+/*
+ * These are the "slower" versions of the functions and are in bitops.c.
+ * These functions call raw_local_irq_{save,restore}().
+ */
+void __mips_set_bit(unsigned long nr, volatile unsigned long *addr);
+void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr);
+void __mips_change_bit(unsigned long nr, volatile unsigned long *addr);
+int __mips_test_and_set_bit(unsigned long nr,
+			    volatile unsigned long *addr);
+int __mips_test_and_set_bit_lock(unsigned long nr,
+				 volatile unsigned long *addr);
+int __mips_test_and_clear_bit(unsigned long nr,
+			      volatile unsigned long *addr);
+int __mips_test_and_change_bit(unsigned long nr,
+			       volatile unsigned long *addr);
+
+
 /*
  * set_bit - Atomically set a bit in memory
  * @nr: the bit to set
@@ -57,7 +74,7 @@
 static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-	unsigned short bit = nr & SZLONG_MASK;
+	int bit = nr & SZLONG_MASK;
 	unsigned long temp;
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
@@ -92,17 +109,8 @@
 			: "=&r" (temp), "+m" (*m)
 			: "ir" (1UL << bit));
 		} while (unlikely(!temp));
-	} else {
-		volatile unsigned long *a = addr;
-		unsigned long mask;
-		unsigned long flags;
-
-		a += nr >> SZLONG_LOG;
-		mask = 1UL << bit;
-		raw_local_irq_save(flags);
-		*a |= mask;
-		raw_local_irq_restore(flags);
-	}
+	} else
+		__mips_set_bit(nr, addr);
 }
 
 /*
@@ -118,7 +126,7 @@
 static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-	unsigned short bit = nr & SZLONG_MASK;
+	int bit = nr & SZLONG_MASK;
 	unsigned long temp;
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
@@ -153,17 +161,8 @@
 			: "=&r" (temp), "+m" (*m)
 			: "ir" (~(1UL << bit)));
 		} while (unlikely(!temp));
-	} else {
-		volatile unsigned long *a = addr;
-		unsigned long mask;
-		unsigned long flags;
-
-		a += nr >> SZLONG_LOG;
-		mask = 1UL << bit;
-		raw_local_irq_save(flags);
-		*a &= ~mask;
-		raw_local_irq_restore(flags);
-	}
+	} else
+		__mips_clear_bit(nr, addr);
 }
 
 /*
@@ -191,7 +190,7 @@
  */
 static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
 {
-	unsigned short bit = nr & SZLONG_MASK;
+	int bit = nr & SZLONG_MASK;
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
@@ -220,17 +219,8 @@
 			: "=&r" (temp), "+m" (*m)
 			: "ir" (1UL << bit));
 		} while (unlikely(!temp));
-	} else {
-		volatile unsigned long *a = addr;
-		unsigned long mask;
-		unsigned long flags;
-
-		a += nr >> SZLONG_LOG;
-		mask = 1UL << bit;
-		raw_local_irq_save(flags);
-		*a ^= mask;
-		raw_local_irq_restore(flags);
-	}
+	} else
+		__mips_change_bit(nr, addr);
 }
 
 /*
@@ -244,7 +234,7 @@
 static inline int test_and_set_bit(unsigned long nr,
 	volatile unsigned long *addr)
 {
-	unsigned short bit = nr & SZLONG_MASK;
+	int bit = nr & SZLONG_MASK;
 	unsigned long res;
 
 	smp_mb__before_llsc();
@@ -281,18 +271,8 @@
 		} while (unlikely(!res));
 
 		res = temp & (1UL << bit);
-	} else {
-		volatile unsigned long *a = addr;
-		unsigned long mask;
-		unsigned long flags;
-
-		a += nr >> SZLONG_LOG;
-		mask = 1UL << bit;
-		raw_local_irq_save(flags);
-		res = (mask & *a);
-		*a |= mask;
-		raw_local_irq_restore(flags);
-	}
+	} else
+		res = __mips_test_and_set_bit(nr, addr);
 
 	smp_llsc_mb();
 
@@ -310,7 +290,7 @@
 static inline int test_and_set_bit_lock(unsigned long nr,
 	volatile unsigned long *addr)
 {
-	unsigned short bit = nr & SZLONG_MASK;
+	int bit = nr & SZLONG_MASK;
 	unsigned long res;
 
 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
@@ -345,18 +325,8 @@
 		} while (unlikely(!res));
 
 		res = temp & (1UL << bit);
-	} else {
-		volatile unsigned long *a = addr;
-		unsigned long mask;
-		unsigned long flags;
-
-		a += nr >> SZLONG_LOG;
-		mask = 1UL << bit;
-		raw_local_irq_save(flags);
-		res = (mask & *a);
-		*a |= mask;
-		raw_local_irq_restore(flags);
-	}
+	} else
+		res = __mips_test_and_set_bit_lock(nr, addr);
 
 	smp_llsc_mb();
 
@@ -373,7 +343,7 @@
 static inline int test_and_clear_bit(unsigned long nr,
 	volatile unsigned long *addr)
 {
-	unsigned short bit = nr & SZLONG_MASK;
+	int bit = nr & SZLONG_MASK;
 	unsigned long res;
 
 	smp_mb__before_llsc();
@@ -428,18 +398,8 @@
 		} while (unlikely(!res));
 
 		res = temp & (1UL << bit);
-	} else {
-		volatile unsigned long *a = addr;
-		unsigned long mask;
-		unsigned long flags;
-
-		a += nr >> SZLONG_LOG;
-		mask = 1UL << bit;
-		raw_local_irq_save(flags);
-		res = (mask & *a);
-		*a &= ~mask;
-		raw_local_irq_restore(flags);
-	}
+	} else
+		res = __mips_test_and_clear_bit(nr, addr);
 
 	smp_llsc_mb();
 
@@ -457,7 +417,7 @@
 static inline int test_and_change_bit(unsigned long nr,
 	volatile unsigned long *addr)
 {
-	unsigned short bit = nr & SZLONG_MASK;
+	int bit = nr & SZLONG_MASK;
 	unsigned long res;
 
 	smp_mb__before_llsc();
@@ -494,18 +454,8 @@
 		} while (unlikely(!res));
 
 		res = temp & (1UL << bit);
-	} else {
-		volatile unsigned long *a = addr;
-		unsigned long mask;
-		unsigned long flags;
-
-		a += nr >> SZLONG_LOG;
-		mask = 1UL << bit;
-		raw_local_irq_save(flags);
-		res = (mask & *a);
-		*a ^= mask;
-		raw_local_irq_restore(flags);
-	}
+	} else
+		res = __mips_test_and_change_bit(nr, addr);
 
 	smp_llsc_mb();
 
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index 58277e0..3c5d146 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -290,7 +290,7 @@
 
 static inline int is_compat_task(void)
 {
-	return test_thread_flag(TIF_32BIT);
+	return test_thread_flag(TIF_32BIT_ADDR);
 }
 
 #endif /* _ASM_COMPAT_H */
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 29d9c23..ff2e034 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -15,6 +15,7 @@
 #include <linux/compiler.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/irqflags.h>
 
 #include <asm/addrspace.h>
 #include <asm/bug.h>
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h
index 309cbcd..9f3384c 100644
--- a/arch/mips/include/asm/irqflags.h
+++ b/arch/mips/include/asm/irqflags.h
@@ -16,6 +16,105 @@
 #include <linux/compiler.h>
 #include <asm/hazards.h>
 
+#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC)
+
+__asm__(
+	"	.macro	arch_local_irq_disable\n"
+	"	.set	push						\n"
+	"	.set	noat						\n"
+	"	di							\n"
+	"	irq_disable_hazard					\n"
+	"	.set	pop						\n"
+	"	.endm							\n");
+
+static inline void arch_local_irq_disable(void)
+{
+	__asm__ __volatile__(
+		"arch_local_irq_disable"
+		: /* no outputs */
+		: /* no inputs */
+		: "memory");
+}
+
+
+__asm__(
+	"	.macro	arch_local_irq_save result			\n"
+	"	.set	push						\n"
+	"	.set	reorder						\n"
+	"	.set	noat						\n"
+	"	di	\\result					\n"
+	"	andi	\\result, 1					\n"
+	"	irq_disable_hazard					\n"
+	"	.set	pop						\n"
+	"	.endm							\n");
+
+static inline unsigned long arch_local_irq_save(void)
+{
+	unsigned long flags;
+	asm volatile("arch_local_irq_save\t%0"
+		     : "=r" (flags)
+		     : /* no inputs */
+		     : "memory");
+	return flags;
+}
+
+
+__asm__(
+	"	.macro	arch_local_irq_restore flags			\n"
+	"	.set	push						\n"
+	"	.set	noreorder					\n"
+	"	.set	noat						\n"
+#if defined(CONFIG_IRQ_CPU)
+	/*
+	 * Slow, but doesn't suffer from a relatively unlikely race
+	 * condition we're having since days 1.
+	 */
+	"	beqz	\\flags, 1f					\n"
+	"	di							\n"
+	"	ei							\n"
+	"1:								\n"
+#else
+	/*
+	 * Fast, dangerous.  Life is fun, life is good.
+	 */
+	"	mfc0	$1, $12						\n"
+	"	ins	$1, \\flags, 0, 1				\n"
+	"	mtc0	$1, $12						\n"
+#endif
+	"	irq_disable_hazard					\n"
+	"	.set	pop						\n"
+	"	.endm							\n");
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+	unsigned long __tmp1;
+
+	__asm__ __volatile__(
+		"arch_local_irq_restore\t%0"
+		: "=r" (__tmp1)
+		: "0" (flags)
+		: "memory");
+}
+
+static inline void __arch_local_irq_restore(unsigned long flags)
+{
+	unsigned long __tmp1;
+
+	__asm__ __volatile__(
+		"arch_local_irq_restore\t%0"
+		: "=r" (__tmp1)
+		: "0" (flags)
+		: "memory");
+}
+#else
+/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */
+void arch_local_irq_disable(void);
+unsigned long arch_local_irq_save(void);
+void arch_local_irq_restore(unsigned long flags);
+void __arch_local_irq_restore(unsigned long flags);
+#endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */
+
+
 __asm__(
 	"	.macro	arch_local_irq_enable				\n"
 	"	.set	push						\n"
@@ -57,55 +156,6 @@
 }
 
 
-/*
- * For cli() we have to insert nops to make sure that the new value
- * has actually arrived in the status register before the end of this
- * macro.
- * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
- * no nops at all.
- */
-/*
- * For TX49, operating only IE bit is not enough.
- *
- * If mfc0 $12 follows store and the mfc0 is last instruction of a
- * page and fetching the next instruction causes TLB miss, the result
- * of the mfc0 might wrongly contain EXL bit.
- *
- * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
- *
- * Workaround: mask EXL bit of the result or place a nop before mfc0.
- */
-__asm__(
-	"	.macro	arch_local_irq_disable\n"
-	"	.set	push						\n"
-	"	.set	noat						\n"
-#ifdef CONFIG_MIPS_MT_SMTC
-	"	mfc0	$1, $2, 1					\n"
-	"	ori	$1, 0x400					\n"
-	"	.set	noreorder					\n"
-	"	mtc0	$1, $2, 1					\n"
-#elif defined(CONFIG_CPU_MIPSR2)
-	"	di							\n"
-#else
-	"	mfc0	$1,$12						\n"
-	"	ori	$1,0x1f						\n"
-	"	xori	$1,0x1f						\n"
-	"	.set	noreorder					\n"
-	"	mtc0	$1,$12						\n"
-#endif
-	"	irq_disable_hazard					\n"
-	"	.set	pop						\n"
-	"	.endm							\n");
-
-static inline void arch_local_irq_disable(void)
-{
-	__asm__ __volatile__(
-		"arch_local_irq_disable"
-		: /* no outputs */
-		: /* no inputs */
-		: "memory");
-}
-
 __asm__(
 	"	.macro	arch_local_save_flags flags			\n"
 	"	.set	push						\n"
@@ -125,113 +175,6 @@
 	return flags;
 }
 
-__asm__(
-	"	.macro	arch_local_irq_save result			\n"
-	"	.set	push						\n"
-	"	.set	reorder						\n"
-	"	.set	noat						\n"
-#ifdef CONFIG_MIPS_MT_SMTC
-	"	mfc0	\\result, $2, 1					\n"
-	"	ori	$1, \\result, 0x400				\n"
-	"	.set	noreorder					\n"
-	"	mtc0	$1, $2, 1					\n"
-	"	andi	\\result, \\result, 0x400			\n"
-#elif defined(CONFIG_CPU_MIPSR2)
-	"	di	\\result					\n"
-	"	andi	\\result, 1					\n"
-#else
-	"	mfc0	\\result, $12					\n"
-	"	ori	$1, \\result, 0x1f				\n"
-	"	xori	$1, 0x1f					\n"
-	"	.set	noreorder					\n"
-	"	mtc0	$1, $12						\n"
-#endif
-	"	irq_disable_hazard					\n"
-	"	.set	pop						\n"
-	"	.endm							\n");
-
-static inline unsigned long arch_local_irq_save(void)
-{
-	unsigned long flags;
-	asm volatile("arch_local_irq_save\t%0"
-		     : "=r" (flags)
-		     : /* no inputs */
-		     : "memory");
-	return flags;
-}
-
-__asm__(
-	"	.macro	arch_local_irq_restore flags			\n"
-	"	.set	push						\n"
-	"	.set	noreorder					\n"
-	"	.set	noat						\n"
-#ifdef CONFIG_MIPS_MT_SMTC
-	"mfc0	$1, $2, 1						\n"
-	"andi	\\flags, 0x400						\n"
-	"ori	$1, 0x400						\n"
-	"xori	$1, 0x400						\n"
-	"or	\\flags, $1						\n"
-	"mtc0	\\flags, $2, 1						\n"
-#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
-	/*
-	 * Slow, but doesn't suffer from a relatively unlikely race
-	 * condition we're having since days 1.
-	 */
-	"	beqz	\\flags, 1f					\n"
-	"	 di							\n"
-	"	ei							\n"
-	"1:								\n"
-#elif defined(CONFIG_CPU_MIPSR2)
-	/*
-	 * Fast, dangerous.  Life is fun, life is good.
-	 */
-	"	mfc0	$1, $12						\n"
-	"	ins	$1, \\flags, 0, 1				\n"
-	"	mtc0	$1, $12						\n"
-#else
-	"	mfc0	$1, $12						\n"
-	"	andi	\\flags, 1					\n"
-	"	ori	$1, 0x1f					\n"
-	"	xori	$1, 0x1f					\n"
-	"	or	\\flags, $1					\n"
-	"	mtc0	\\flags, $12					\n"
-#endif
-	"	irq_disable_hazard					\n"
-	"	.set	pop						\n"
-	"	.endm							\n");
-
-
-static inline void arch_local_irq_restore(unsigned long flags)
-{
-	unsigned long __tmp1;
-
-#ifdef CONFIG_MIPS_MT_SMTC
-	/*
-	 * SMTC kernel needs to do a software replay of queued
-	 * IPIs, at the cost of branch and call overhead on each
-	 * local_irq_restore()
-	 */
-	if (unlikely(!(flags & 0x0400)))
-		smtc_ipi_replay();
-#endif
-
-	__asm__ __volatile__(
-		"arch_local_irq_restore\t%0"
-		: "=r" (__tmp1)
-		: "0" (flags)
-		: "memory");
-}
-
-static inline void __arch_local_irq_restore(unsigned long flags)
-{
-	unsigned long __tmp1;
-
-	__asm__ __volatile__(
-		"arch_local_irq_restore\t%0"
-		: "=r" (__tmp1)
-		: "0" (flags)
-		: "memory");
-}
 
 static inline int arch_irqs_disabled_flags(unsigned long flags)
 {
@@ -245,7 +188,7 @@
 #endif
 }
 
-#endif
+#endif /* #ifndef __ASSEMBLY__ */
 
 /*
  * Do the CPU's IRQ-state tracing from assembly code.
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index 8debe9e..18806a5 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -112,12 +112,6 @@
 #define TIF_LOAD_WATCH		25	/* If set, load watch registers */
 #define TIF_SYSCALL_TRACE	31	/* syscall trace active */
 
-#ifdef CONFIG_MIPS32_O32
-#define TIF_32BIT TIF_32BIT_REGS
-#elif defined(CONFIG_MIPS32_N32)
-#define TIF_32BIT _TIF_32BIT_ADDR
-#endif /* CONFIG_MIPS32_O32 */
-
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index c4a82e8..eeddc58 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -2,8 +2,9 @@
 # Makefile for MIPS-specific library files..
 #
 
-lib-y	+= csum_partial.o delay.o memcpy.o memset.o \
-	   strlen_user.o strncpy_user.o strnlen_user.o uncached.o
+lib-y	+= bitops.o csum_partial.o delay.o memcpy.o memset.o \
+	   mips-atomic.o strlen_user.o strncpy_user.o \
+	   strnlen_user.o uncached.o
 
 obj-y			+= iomap.o
 obj-$(CONFIG_PCI)	+= iomap-pci.o
diff --git a/arch/mips/lib/bitops.c b/arch/mips/lib/bitops.c
new file mode 100644
index 0000000..239a9c9
--- /dev/null
+++ b/arch/mips/lib/bitops.c
@@ -0,0 +1,179 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (c) 1999, 2000  Silicon Graphics, Inc.
+ */
+#include <linux/bitops.h>
+#include <linux/irqflags.h>
+#include <linux/export.h>
+
+
+/**
+ * __mips_set_bit - Atomically set a bit in memory.  This is called by
+ * set_bit() if it cannot find a faster solution.
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ */
+void __mips_set_bit(unsigned long nr, volatile unsigned long *addr)
+{
+	volatile unsigned long *a = addr;
+	unsigned bit = nr & SZLONG_MASK;
+	unsigned long mask;
+	unsigned long flags;
+
+	a += nr >> SZLONG_LOG;
+	mask = 1UL << bit;
+	raw_local_irq_save(flags);
+	*a |= mask;
+	raw_local_irq_restore(flags);
+}
+EXPORT_SYMBOL(__mips_set_bit);
+
+
+/**
+ * __mips_clear_bit - Clears a bit in memory.  This is called by clear_bit() if
+ * it cannot find a faster solution.
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ */
+void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr)
+{
+	volatile unsigned long *a = addr;
+	unsigned bit = nr & SZLONG_MASK;
+	unsigned long mask;
+	unsigned long flags;
+
+	a += nr >> SZLONG_LOG;
+	mask = 1UL << bit;
+	raw_local_irq_save(flags);
+	*a &= ~mask;
+	raw_local_irq_restore(flags);
+}
+EXPORT_SYMBOL(__mips_clear_bit);
+
+
+/**
+ * __mips_change_bit - Toggle a bit in memory.  This is called by change_bit()
+ * if it cannot find a faster solution.
+ * @nr: Bit to change
+ * @addr: Address to start counting from
+ */
+void __mips_change_bit(unsigned long nr, volatile unsigned long *addr)
+{
+	volatile unsigned long *a = addr;
+	unsigned bit = nr & SZLONG_MASK;
+	unsigned long mask;
+	unsigned long flags;
+
+	a += nr >> SZLONG_LOG;
+	mask = 1UL << bit;
+	raw_local_irq_save(flags);
+	*a ^= mask;
+	raw_local_irq_restore(flags);
+}
+EXPORT_SYMBOL(__mips_change_bit);
+
+
+/**
+ * __mips_test_and_set_bit - Set a bit and return its old value.  This is
+ * called by test_and_set_bit() if it cannot find a faster solution.
+ * @nr: Bit to set
+ * @addr: Address to count from
+ */
+int __mips_test_and_set_bit(unsigned long nr,
+			    volatile unsigned long *addr)
+{
+	volatile unsigned long *a = addr;
+	unsigned bit = nr & SZLONG_MASK;
+	unsigned long mask;
+	unsigned long flags;
+	unsigned long res;
+
+	a += nr >> SZLONG_LOG;
+	mask = 1UL << bit;
+	raw_local_irq_save(flags);
+	res = (mask & *a);
+	*a |= mask;
+	raw_local_irq_restore(flags);
+	return res;
+}
+EXPORT_SYMBOL(__mips_test_and_set_bit);
+
+
+/**
+ * __mips_test_and_set_bit_lock - Set a bit and return its old value.  This is
+ * called by test_and_set_bit_lock() if it cannot find a faster solution.
+ * @nr: Bit to set
+ * @addr: Address to count from
+ */
+int __mips_test_and_set_bit_lock(unsigned long nr,
+				 volatile unsigned long *addr)
+{
+	volatile unsigned long *a = addr;
+	unsigned bit = nr & SZLONG_MASK;
+	unsigned long mask;
+	unsigned long flags;
+	unsigned long res;
+
+	a += nr >> SZLONG_LOG;
+	mask = 1UL << bit;
+	raw_local_irq_save(flags);
+	res = (mask & *a);
+	*a |= mask;
+	raw_local_irq_restore(flags);
+	return res;
+}
+EXPORT_SYMBOL(__mips_test_and_set_bit_lock);
+
+
+/**
+ * __mips_test_and_clear_bit - Clear a bit and return its old value.  This is
+ * called by test_and_clear_bit() if it cannot find a faster solution.
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ */
+int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
+{
+	volatile unsigned long *a = addr;
+	unsigned bit = nr & SZLONG_MASK;
+	unsigned long mask;
+	unsigned long flags;
+	unsigned long res;
+
+	a += nr >> SZLONG_LOG;
+	mask = 1UL << bit;
+	raw_local_irq_save(flags);
+	res = (mask & *a);
+	*a &= ~mask;
+	raw_local_irq_restore(flags);
+	return res;
+}
+EXPORT_SYMBOL(__mips_test_and_clear_bit);
+
+
+/**
+ * __mips_test_and_change_bit - Change a bit and return its old value.  This is
+ * called by test_and_change_bit() if it cannot find a faster solution.
+ * @nr: Bit to change
+ * @addr: Address to count from
+ */
+int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
+{
+	volatile unsigned long *a = addr;
+	unsigned bit = nr & SZLONG_MASK;
+	unsigned long mask;
+	unsigned long flags;
+	unsigned long res;
+
+	a += nr >> SZLONG_LOG;
+	mask = 1UL << bit;
+	raw_local_irq_save(flags);
+	res = (mask & *a);
+	*a ^= mask;
+	raw_local_irq_restore(flags);
+	return res;
+}
+EXPORT_SYMBOL(__mips_test_and_change_bit);
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c
new file mode 100644
index 0000000..e091430
--- /dev/null
+++ b/arch/mips/lib/mips-atomic.c
@@ -0,0 +1,176 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
+ * Copyright (C) 1996 by Paul M. Antoine
+ * Copyright (C) 1999 Silicon Graphics
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ */
+#include <asm/irqflags.h>
+#include <asm/hazards.h>
+#include <linux/compiler.h>
+#include <linux/preempt.h>
+#include <linux/export.h>
+
+#if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC)
+
+/*
+ * For cli() we have to insert nops to make sure that the new value
+ * has actually arrived in the status register before the end of this
+ * macro.
+ * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
+ * no nops at all.
+ */
+/*
+ * For TX49, operating only IE bit is not enough.
+ *
+ * If mfc0 $12 follows store and the mfc0 is last instruction of a
+ * page and fetching the next instruction causes TLB miss, the result
+ * of the mfc0 might wrongly contain EXL bit.
+ *
+ * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
+ *
+ * Workaround: mask EXL bit of the result or place a nop before mfc0.
+ */
+__asm__(
+	"	.macro	arch_local_irq_disable\n"
+	"	.set	push						\n"
+	"	.set	noat						\n"
+#ifdef CONFIG_MIPS_MT_SMTC
+	"	mfc0	$1, $2, 1					\n"
+	"	ori	$1, 0x400					\n"
+	"	.set	noreorder					\n"
+	"	mtc0	$1, $2, 1					\n"
+#elif defined(CONFIG_CPU_MIPSR2)
+	/* see irqflags.h for inline function */
+#else
+	"	mfc0	$1,$12						\n"
+	"	ori	$1,0x1f						\n"
+	"	xori	$1,0x1f						\n"
+	"	.set	noreorder					\n"
+	"	mtc0	$1,$12						\n"
+#endif
+	"	irq_disable_hazard					\n"
+	"	.set	pop						\n"
+	"	.endm							\n");
+
+void arch_local_irq_disable(void)
+{
+	preempt_disable();
+	__asm__ __volatile__(
+		"arch_local_irq_disable"
+		: /* no outputs */
+		: /* no inputs */
+		: "memory");
+	preempt_enable();
+}
+EXPORT_SYMBOL(arch_local_irq_disable);
+
+
+__asm__(
+	"	.macro	arch_local_irq_save result			\n"
+	"	.set	push						\n"
+	"	.set	reorder						\n"
+	"	.set	noat						\n"
+#ifdef CONFIG_MIPS_MT_SMTC
+	"	mfc0	\\result, $2, 1					\n"
+	"	ori	$1, \\result, 0x400				\n"
+	"	.set	noreorder					\n"
+	"	mtc0	$1, $2, 1					\n"
+	"	andi	\\result, \\result, 0x400			\n"
+#elif defined(CONFIG_CPU_MIPSR2)
+	/* see irqflags.h for inline function */
+#else
+	"	mfc0	\\result, $12					\n"
+	"	ori	$1, \\result, 0x1f				\n"
+	"	xori	$1, 0x1f					\n"
+	"	.set	noreorder					\n"
+	"	mtc0	$1, $12						\n"
+#endif
+	"	irq_disable_hazard					\n"
+	"	.set	pop						\n"
+	"	.endm							\n");
+
+unsigned long arch_local_irq_save(void)
+{
+	unsigned long flags;
+	preempt_disable();
+	asm volatile("arch_local_irq_save\t%0"
+		     : "=r" (flags)
+		     : /* no inputs */
+		     : "memory");
+	preempt_enable();
+	return flags;
+}
+EXPORT_SYMBOL(arch_local_irq_save);
+
+
+__asm__(
+	"	.macro	arch_local_irq_restore flags			\n"
+	"	.set	push						\n"
+	"	.set	noreorder					\n"
+	"	.set	noat						\n"
+#ifdef CONFIG_MIPS_MT_SMTC
+	"mfc0	$1, $2, 1						\n"
+	"andi	\\flags, 0x400						\n"
+	"ori	$1, 0x400						\n"
+	"xori	$1, 0x400						\n"
+	"or	\\flags, $1						\n"
+	"mtc0	\\flags, $2, 1						\n"
+#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
+	/* see irqflags.h for inline function */
+#elif defined(CONFIG_CPU_MIPSR2)
+	/* see irqflags.h for inline function */
+#else
+	"	mfc0	$1, $12						\n"
+	"	andi	\\flags, 1					\n"
+	"	ori	$1, 0x1f					\n"
+	"	xori	$1, 0x1f					\n"
+	"	or	\\flags, $1					\n"
+	"	mtc0	\\flags, $12					\n"
+#endif
+	"	irq_disable_hazard					\n"
+	"	.set	pop						\n"
+	"	.endm							\n");
+
+void arch_local_irq_restore(unsigned long flags)
+{
+	unsigned long __tmp1;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+	/*
+	 * SMTC kernel needs to do a software replay of queued
+	 * IPIs, at the cost of branch and call overhead on each
+	 * local_irq_restore()
+	 */
+	if (unlikely(!(flags & 0x0400)))
+		smtc_ipi_replay();
+#endif
+	preempt_disable();
+	__asm__ __volatile__(
+		"arch_local_irq_restore\t%0"
+		: "=r" (__tmp1)
+		: "0" (flags)
+		: "memory");
+	preempt_enable();
+}
+EXPORT_SYMBOL(arch_local_irq_restore);
+
+
+void __arch_local_irq_restore(unsigned long flags)
+{
+	unsigned long __tmp1;
+
+	preempt_disable();
+	__asm__ __volatile__(
+		"arch_local_irq_restore\t%0"
+		: "=r" (__tmp1)
+		: "0" (flags)
+		: "memory");
+	preempt_enable();
+}
+EXPORT_SYMBOL(__arch_local_irq_restore);
+
+#endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */
diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c
index 80562b8..7473217 100644
--- a/arch/mips/mti-malta/malta-platform.c
+++ b/arch/mips/mti-malta/malta-platform.c
@@ -29,6 +29,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
+#include <asm/mips-boards/maltaint.h>
 #include <mtd/mtd-abi.h>
 
 #define SMC_PORT(base, int)						\
@@ -48,7 +49,7 @@
 	SMC_PORT(0x2F8, 3),
 	{
 		.mapbase	= 0x1f000900,	/* The CBUS UART */
-		.irq		= MIPS_CPU_IRQ_BASE + 2,
+		.irq		= MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2,
 		.uartclk	= 3686400,	/* Twice the usual clk! */
 		.iotype		= UPIO_MEM32,
 		.flags		= CBUS_UART_FLAGS,
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 3f3d9ca..d385f39 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -96,6 +96,7 @@
 	select HAVE_MEMBLOCK_NODE_MAP
 	select HAVE_CMPXCHG_LOCAL
 	select HAVE_CMPXCHG_DOUBLE
+	select HAVE_ALIGNED_STRUCT_PAGE if SLUB
 	select HAVE_VIRT_CPU_ACCOUNTING
 	select VIRT_CPU_ACCOUNTING
 	select ARCH_DISCARD_MEMBLOCK
@@ -130,6 +131,7 @@
 	select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
 	select HAVE_UID16 if 32BIT
 	select ARCH_WANT_IPC_PARSE_VERSION
+	select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL_OLD
 	select GENERIC_CLOCKEVENTS
diff --git a/arch/s390/boot/compressed/vmlinux.lds.S b/arch/s390/boot/compressed/vmlinux.lds.S
index d80f79d..8e1fb82 100644
--- a/arch/s390/boot/compressed/vmlinux.lds.S
+++ b/arch/s390/boot/compressed/vmlinux.lds.S
@@ -5,7 +5,7 @@
 OUTPUT_ARCH(s390:64-bit)
 #else
 OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
-OUTPUT_ARCH(s390)
+OUTPUT_ARCH(s390:31-bit)
 #endif
 
 ENTRY(startup)
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index 55bde60..ad2b924 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -9,6 +9,8 @@
 
 #define LPM_ANYPATH 0xff
 #define __MAX_CSSID 0
+#define __MAX_SUBCHANNEL 65535
+#define __MAX_SSID 3
 
 #include <asm/scsw.h>
 
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index a34a9d6..18cd6b5 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -20,7 +20,7 @@
 #define PSW32_MASK_CC		0x00003000UL
 #define PSW32_MASK_PM		0x00000f00UL
 
-#define PSW32_MASK_USER		0x00003F00UL
+#define PSW32_MASK_USER		0x0000FF00UL
 
 #define PSW32_ADDR_AMODE	0x80000000UL
 #define PSW32_ADDR_INSN		0x7FFFFFFFUL
diff --git a/arch/s390/include/asm/perf_event.h b/arch/s390/include/asm/perf_event.h
index 7941968..5f0173a 100644
--- a/arch/s390/include/asm/perf_event.h
+++ b/arch/s390/include/asm/perf_event.h
@@ -9,7 +9,7 @@
 #include <asm/cpu_mf.h>
 
 /* CPU-measurement counter facility */
-#define PERF_CPUM_CF_MAX_CTR		160
+#define PERF_CPUM_CF_MAX_CTR		256
 
 /* Per-CPU flags for PMU states */
 #define PMU_F_RESERVED			0x1000
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index dd647c9..2d3b7cb 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -506,12 +506,15 @@
 
 static inline int pmd_present(pmd_t pmd)
 {
-	return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL;
+	unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO;
+	return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE ||
+	       !(pmd_val(pmd) & _SEGMENT_ENTRY_INV);
 }
 
 static inline int pmd_none(pmd_t pmd)
 {
-	return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL;
+	return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) &&
+	       !(pmd_val(pmd) & _SEGMENT_ENTRY_RO);
 }
 
 static inline int pmd_large(pmd_t pmd)
@@ -1223,6 +1226,11 @@
 }
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+
+#define SEGMENT_NONE	__pgprot(_HPAGE_TYPE_NONE)
+#define SEGMENT_RO	__pgprot(_HPAGE_TYPE_RO)
+#define SEGMENT_RW	__pgprot(_HPAGE_TYPE_RW)
+
 #define __HAVE_ARCH_PGTABLE_DEPOSIT
 extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);
 
@@ -1242,16 +1250,15 @@
 
 static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot)
 {
-	unsigned long pgprot_pmd = 0;
-
-	if (pgprot_val(pgprot) & _PAGE_INVALID) {
-		if (pgprot_val(pgprot) & _PAGE_SWT)
-			pgprot_pmd |= _HPAGE_TYPE_NONE;
-		pgprot_pmd |= _SEGMENT_ENTRY_INV;
-	}
-	if (pgprot_val(pgprot) & _PAGE_RO)
-		pgprot_pmd |= _SEGMENT_ENTRY_RO;
-	return pgprot_pmd;
+	/*
+	 * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx)
+	 * Convert to segment table entry format.
+	 */
+	if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE))
+		return pgprot_val(SEGMENT_NONE);
+	if (pgprot_val(pgprot) == pgprot_val(PAGE_RO))
+		return pgprot_val(SEGMENT_RO);
+	return pgprot_val(SEGMENT_RW);
 }
 
 static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
@@ -1269,7 +1276,9 @@
 
 static inline pmd_t pmd_mkwrite(pmd_t pmd)
 {
-	pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
+	/* Do not clobber _HPAGE_TYPE_NONE pages! */
+	if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV))
+		pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
 	return pmd;
 }
 
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index 9ca3053..9935cbd 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -8,6 +8,9 @@
 
 #ifdef CONFIG_SCHED_BOOK
 
+extern unsigned char cpu_socket_id[NR_CPUS];
+#define topology_physical_package_id(cpu) (cpu_socket_id[cpu])
+
 extern unsigned char cpu_core_id[NR_CPUS];
 extern cpumask_t cpu_core_map[NR_CPUS];
 
diff --git a/arch/s390/include/uapi/asm/Kbuild b/arch/s390/include/uapi/asm/Kbuild
index 59b67ed..7bf68ff 100644
--- a/arch/s390/include/uapi/asm/Kbuild
+++ b/arch/s390/include/uapi/asm/Kbuild
@@ -1,8 +1,6 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
-generic-y += kvm_para.h
-
 header-y += auxvec.h
 header-y += bitsperlong.h
 header-y += byteorder.h
diff --git a/arch/s390/include/uapi/asm/chpid.h b/arch/s390/include/uapi/asm/chpid.h
index 581992d..6b4fb29 100644
--- a/arch/s390/include/uapi/asm/chpid.h
+++ b/arch/s390/include/uapi/asm/chpid.h
@@ -1,5 +1,5 @@
 /*
- *    Copyright IBM Corp. 2007
+ *    Copyright IBM Corp. 2007, 2012
  *    Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  */
 
@@ -12,10 +12,10 @@
 #define __MAX_CHPID 255
 
 struct chp_id {
-	u8 reserved1;
-	u8 cssid;
-	u8 reserved2;
-	u8 id;
+	__u8 reserved1;
+	__u8 cssid;
+	__u8 reserved2;
+	__u8 id;
 } __attribute__((packed));
 
 
diff --git a/arch/s390/include/uapi/asm/kvm_para.h b/arch/s390/include/uapi/asm/kvm_para.h
new file mode 100644
index 0000000..ff1f4e7
--- /dev/null
+++ b/arch/s390/include/uapi/asm/kvm_para.h
@@ -0,0 +1,11 @@
+/*
+ * User API definitions for paravirtual devices on s390
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (version 2 only)
+ * as published by the Free Software Foundation.
+ *
+ *    Author(s): Christian Borntraeger <borntraeger@de.ibm.com>
+ */
diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h
index 705588a..a5ca214 100644
--- a/arch/s390/include/uapi/asm/ptrace.h
+++ b/arch/s390/include/uapi/asm/ptrace.h
@@ -239,7 +239,7 @@
 #define PSW_MASK_EA		0x00000000UL
 #define PSW_MASK_BA		0x00000000UL
 
-#define PSW_MASK_USER		0x00003F00UL
+#define PSW_MASK_USER		0x0000FF00UL
 
 #define PSW_ADDR_AMODE		0x80000000UL
 #define PSW_ADDR_INSN		0x7FFFFFFFUL
@@ -269,7 +269,7 @@
 #define PSW_MASK_EA		0x0000000100000000UL
 #define PSW_MASK_BA		0x0000000080000000UL
 
-#define PSW_MASK_USER		0x00003F8180000000UL
+#define PSW_MASK_USER		0x0000FF8180000000UL
 
 #define PSW_ADDR_AMODE		0x0000000000000000UL
 #define PSW_ADDR_INSN		0xFFFFFFFFFFFFFFFFUL
diff --git a/arch/s390/kernel/cache.c b/arch/s390/kernel/cache.c
index 8df8d8a1..64b2465 100644
--- a/arch/s390/kernel/cache.c
+++ b/arch/s390/kernel/cache.c
@@ -59,8 +59,8 @@
 
 enum {
 	CACHE_TI_UNIFIED = 0,
-	CACHE_TI_INSTRUCTION = 0,
-	CACHE_TI_DATA,
+	CACHE_TI_DATA = 0,
+	CACHE_TI_INSTRUCTION,
 };
 
 struct cache_info {
@@ -121,7 +121,10 @@
 	cache = kzalloc(sizeof(*cache), GFP_KERNEL);
 	if (!cache)
 		return -ENOMEM;
-	ti = type == CACHE_TYPE_DATA ? CACHE_TI_DATA : CACHE_TI_UNIFIED;
+	if (type == CACHE_TYPE_INSTRUCTION)
+		ti = CACHE_TI_INSTRUCTION;
+	else
+		ti = CACHE_TI_UNIFIED;
 	cache->size = ecag(EXTRACT_SIZE, level, ti);
 	cache->line_size = ecag(EXTRACT_LINE_SIZE, level, ti);
 	cache->associativity = ecag(EXTRACT_ASSOCIATIVITY, level, ti);
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index a1e8a86..593fcc9 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -309,6 +309,10 @@
 	regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
 		(__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 |
 		(__u64)(regs32.psw.addr & PSW32_ADDR_AMODE);
+	/* Check for invalid user address space control. */
+	if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC))
+		regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
+			(regs->psw.mask & ~PSW_MASK_ASC);
 	regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
 	for (i = 0; i < NUM_GPRS; i++)
 		regs->gprs[i] = (__u64) regs32.gprs[i];
@@ -481,7 +485,10 @@
 
 	/* Set up registers for signal handler */
 	regs->gprs[15] = (__force __u64) frame;
-	regs->psw.mask |= PSW_MASK_BA;		/* force amode 31 */
+	/* Force 31 bit amode and default user address space control. */
+	regs->psw.mask = PSW_MASK_BA |
+		(psw_user_bits & PSW_MASK_ASC) |
+		(regs->psw.mask & ~PSW_MASK_ASC);
 	regs->psw.addr = (__force __u64) ka->sa.sa_handler;
 
 	regs->gprs[2] = map_signal(sig);
@@ -549,7 +556,10 @@
 
 	/* Set up registers for signal handler */
 	regs->gprs[15] = (__force __u64) frame;
-	regs->psw.mask |= PSW_MASK_BA;		/* force amode 31 */
+	/* Force 31 bit amode and default user address space control. */
+	regs->psw.mask = PSW_MASK_BA |
+		(psw_user_bits & PSW_MASK_ASC) |
+		(regs->psw.mask & ~PSW_MASK_ASC);
 	regs->psw.addr = (__u64) ka->sa.sa_handler;
 
 	regs->gprs[2] = map_signal(sig);
diff --git a/arch/s390/kernel/head_kdump.S b/arch/s390/kernel/head_kdump.S
index acaaaf4..085a95e 100644
--- a/arch/s390/kernel/head_kdump.S
+++ b/arch/s390/kernel/head_kdump.S
@@ -85,16 +85,10 @@
 .align 2
 startup_kdump_relocated:
 	basr	%r13,0
-0:
-	mvc	0(8,%r0),.Lrestart_psw-0b(%r13)	# Setup restart PSW
-	sam31					# Switch to 31 bit addr mode
-	sr	%r1,%r1				# Erase register r1
-	sr	%r2,%r2				# Erase register r2
-	sigp	%r1,%r2,SIGP_SET_ARCHITECTURE	# Switch to 31 bit arch mode
-	lpsw	0				# Start new kernel...
+0:	lpswe	.Lrestart_psw-0b(%r13)		# Start new kernel...
 .align	8
 .Lrestart_psw:
-	.long	0x00080000,0x80000000 + startup
+	.quad	0x0000000080000000,0x0000000000000000 + startup
 #else
 .align 2
 .Lep_startup_kdump:
diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c
index 9871b19..c4e7269 100644
--- a/arch/s390/kernel/perf_cpum_cf.c
+++ b/arch/s390/kernel/perf_cpum_cf.c
@@ -94,7 +94,7 @@
 		set = CPUMF_CTR_SET_USER;
 	else if (event < 128)
 		set = CPUMF_CTR_SET_CRYPTO;
-	else if (event < 160)
+	else if (event < 256)
 		set = CPUMF_CTR_SET_EXT;
 
 	return set;
@@ -138,6 +138,10 @@
 	case CPUMF_CTR_SET_EXT:
 		if (cpuhw->info.csvn < 1)
 			err = -EOPNOTSUPP;
+		if ((cpuhw->info.csvn == 1 && hwc->config > 159) ||
+		    (cpuhw->info.csvn == 2 && hwc->config > 175) ||
+		    (cpuhw->info.csvn  > 2 && hwc->config > 255))
+			err = -EOPNOTSUPP;
 		break;
 	}
 
diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S
index bf05389..b6506ee 100644
--- a/arch/s390/kernel/sclp.S
+++ b/arch/s390/kernel/sclp.S
@@ -44,6 +44,12 @@
 #endif
 	mvc	.LoldpswS1-.LbaseS1(16,%r13),0(%r8)
 	mvc	0(16,%r8),0(%r9)
+#ifdef CONFIG_64BIT
+	epsw	%r6,%r7				# set current addressing mode
+	nill	%r6,0x1				# in new psw (31 or 64 bit mode)
+	nilh	%r7,0x8000
+	stm	%r6,%r7,0(%r8)
+#endif
 	lhi	%r6,0x0200			# cr mask for ext int (cr0.54)
 	ltr	%r2,%r2
 	jz	.LsetctS1
@@ -87,7 +93,7 @@
 	.long	0x00080000, 0x80000000+.LwaitS1	# PSW to handle ext int
 #ifdef CONFIG_64BIT
 .LextpswS1_64:
-	.quad	0x0000000180000000, .LwaitS1	# PSW to handle ext int, 64 bit
+	.quad	0, .LwaitS1			# PSW to handle ext int, 64 bit
 #endif
 .LwaitpswS1:
 	.long	0x010a0000, 0x00000000+.LloopS1	# PSW to wait for ext int
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index c13a2a3..d1259d8 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -136,6 +136,10 @@
 	/* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */
 	regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
 		(user_sregs.regs.psw.mask & PSW_MASK_USER);
+	/* Check for invalid user address space control. */
+	if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC))
+		regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
+			(regs->psw.mask & ~PSW_MASK_ASC);
 	/* Check for invalid amode */
 	if (regs->psw.mask & PSW_MASK_EA)
 		regs->psw.mask |= PSW_MASK_BA;
@@ -273,7 +277,10 @@
 
 	/* Set up registers for signal handler */
 	regs->gprs[15] = (unsigned long) frame;
-	regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA;	/* 64 bit amode */
+	/* Force default amode and default user address space control. */
+	regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
+		(psw_user_bits & PSW_MASK_ASC) |
+		(regs->psw.mask & ~PSW_MASK_ASC);
 	regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
 
 	regs->gprs[2] = map_signal(sig);
@@ -346,7 +353,10 @@
 
 	/* Set up registers for signal handler */
 	regs->gprs[15] = (unsigned long) frame;
-	regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA;	/* 64 bit amode */
+	/* Force default amode and default user address space control. */
+	regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
+		(psw_user_bits & PSW_MASK_ASC) |
+		(regs->psw.mask & ~PSW_MASK_ASC);
 	regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
 
 	regs->gprs[2] = map_signal(sig);
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 54d93f4..dd55f7c 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -40,6 +40,7 @@
 static struct mask_info core_info;
 cpumask_t cpu_core_map[NR_CPUS];
 unsigned char cpu_core_id[NR_CPUS];
+unsigned char cpu_socket_id[NR_CPUS];
 
 static struct mask_info book_info;
 cpumask_t cpu_book_map[NR_CPUS];
@@ -83,11 +84,12 @@
 			cpumask_set_cpu(lcpu, &book->mask);
 			cpu_book_id[lcpu] = book->id;
 			cpumask_set_cpu(lcpu, &core->mask);
+			cpu_core_id[lcpu] = rcpu;
 			if (one_core_per_cpu) {
-				cpu_core_id[lcpu] = rcpu;
+				cpu_socket_id[lcpu] = rcpu;
 				core = core->next;
 			} else {
-				cpu_core_id[lcpu] = core->id;
+				cpu_socket_id[lcpu] = core->id;
 			}
 			smp_cpu_set_polarization(lcpu, tl_cpu->pp);
 		}
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index de8fa9b..79cb51a 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -8,7 +8,7 @@
 
 #ifndef CONFIG_64BIT
 OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
-OUTPUT_ARCH(s390)
+OUTPUT_ARCH(s390:31-bit)
 ENTRY(startup)
 jiffies = jiffies_64 + 4;
 #else
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c
index 2d37bb8..9017a63 100644
--- a/arch/s390/lib/uaccess_pt.c
+++ b/arch/s390/lib/uaccess_pt.c
@@ -39,7 +39,7 @@
 	pmd = pmd_offset(pud, addr);
 	if (pmd_none(*pmd))
 		return -0x10UL;
-	if (pmd_huge(*pmd)) {
+	if (pmd_large(*pmd)) {
 		if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
 			return -0x04UL;
 		return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c
index 60acb93..1f5315d1 100644
--- a/arch/s390/mm/gup.c
+++ b/arch/s390/mm/gup.c
@@ -126,7 +126,7 @@
 		 */
 		if (pmd_none(pmd) || pmd_trans_splitting(pmd))
 			return 0;
-		if (unlikely(pmd_huge(pmd))) {
+		if (unlikely(pmd_large(pmd))) {
 			if (!gup_huge_pmd(pmdp, pmd, addr, next,
 					  write, pages, nr))
 				return 0;
@@ -180,8 +180,7 @@
 	addr = start;
 	len = (unsigned long) nr_pages << PAGE_SHIFT;
 	end = start + len;
-	if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
-					(void __user *)start, len)))
+	if ((end < start) || (end > TASK_SIZE))
 		return 0;
 
 	local_irq_save(flags);
@@ -229,7 +228,7 @@
 	addr = start;
 	len = (unsigned long) nr_pages << PAGE_SHIFT;
 	end = start + len;
-	if (end < start)
+	if ((end < start) || (end > TASK_SIZE))
 		goto slow_irqon;
 
 	/*
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index b6b442b..9f2edb5 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -20,6 +20,7 @@
 	select HAVE_ARCH_TRACEHOOK
 	select SYSCTL_EXCEPTION_TRACE
 	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select RTC_CLASS
 	select RTC_DRV_M48T59
 	select HAVE_IRQ_WORK
diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile
index 6ae1ad5..5d469d8 100644
--- a/arch/sparc/crypto/Makefile
+++ b/arch/sparc/crypto/Makefile
@@ -13,13 +13,13 @@
 
 obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o
 
-sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o
-sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o
-sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o
-md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o
+sha1-sparc64-y := sha1_asm.o sha1_glue.o
+sha256-sparc64-y := sha256_asm.o sha256_glue.o
+sha512-sparc64-y := sha512_asm.o sha512_glue.o
+md5-sparc64-y := md5_asm.o md5_glue.o
 
-aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o
-des-sparc64-y := des_asm.o des_glue.o crop_devid.o
-camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o
+aes-sparc64-y := aes_asm.o aes_glue.o
+des-sparc64-y := des_asm.o des_glue.o
+camellia-sparc64-y := camellia_asm.o camellia_glue.o
 
-crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o crop_devid.o
+crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o
diff --git a/arch/sparc/crypto/aes_glue.c b/arch/sparc/crypto/aes_glue.c
index 8f1c998..3965d1d 100644
--- a/arch/sparc/crypto/aes_glue.c
+++ b/arch/sparc/crypto/aes_glue.c
@@ -475,3 +475,5 @@
 MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated");
 
 MODULE_ALIAS("aes");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/camellia_glue.c b/arch/sparc/crypto/camellia_glue.c
index 42905c0..62c89af 100644
--- a/arch/sparc/crypto/camellia_glue.c
+++ b/arch/sparc/crypto/camellia_glue.c
@@ -320,3 +320,5 @@
 MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated");
 
 MODULE_ALIAS("aes");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/crc32c_glue.c b/arch/sparc/crypto/crc32c_glue.c
index 0bd89ce..5162fad 100644
--- a/arch/sparc/crypto/crc32c_glue.c
+++ b/arch/sparc/crypto/crc32c_glue.c
@@ -177,3 +177,5 @@
 MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated");
 
 MODULE_ALIAS("crc32c");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/des_glue.c b/arch/sparc/crypto/des_glue.c
index c4940c2..41524ce 100644
--- a/arch/sparc/crypto/des_glue.c
+++ b/arch/sparc/crypto/des_glue.c
@@ -527,3 +527,5 @@
 MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated");
 
 MODULE_ALIAS("des");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/md5_glue.c b/arch/sparc/crypto/md5_glue.c
index 603d723..09a9ea1 100644
--- a/arch/sparc/crypto/md5_glue.c
+++ b/arch/sparc/crypto/md5_glue.c
@@ -186,3 +186,5 @@
 MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated");
 
 MODULE_ALIAS("md5");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/sha1_glue.c b/arch/sparc/crypto/sha1_glue.c
index 2bbb20b..6cd5f29 100644
--- a/arch/sparc/crypto/sha1_glue.c
+++ b/arch/sparc/crypto/sha1_glue.c
@@ -181,3 +181,5 @@
 MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated");
 
 MODULE_ALIAS("sha1");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/sha256_glue.c b/arch/sparc/crypto/sha256_glue.c
index 591e656..04f555a 100644
--- a/arch/sparc/crypto/sha256_glue.c
+++ b/arch/sparc/crypto/sha256_glue.c
@@ -239,3 +239,5 @@
 
 MODULE_ALIAS("sha224");
 MODULE_ALIAS("sha256");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/sha512_glue.c b/arch/sparc/crypto/sha512_glue.c
index 486f0a2..f04d199 100644
--- a/arch/sparc/crypto/sha512_glue.c
+++ b/arch/sparc/crypto/sha512_glue.c
@@ -224,3 +224,5 @@
 
 MODULE_ALIAS("sha384");
 MODULE_ALIAS("sha512");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
index ce35a1c..be56a24 100644
--- a/arch/sparc/include/asm/atomic_64.h
+++ b/arch/sparc/include/asm/atomic_64.h
@@ -1,7 +1,7 @@
 /* atomic.h: Thankfully the V9 is at least reasonable for this
  *           stuff.
  *
- * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com)
  */
 
 #ifndef __ARCH_SPARC64_ATOMIC__
@@ -106,6 +106,8 @@
 
 #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
 
+extern long atomic64_dec_if_positive(atomic64_t *v);
+
 /* Atomic operations are already serializing */
 #define smp_mb__before_atomic_dec()	barrier()
 #define smp_mb__after_atomic_dec()	barrier()
diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h
index db3af0d..4e02086 100644
--- a/arch/sparc/include/asm/backoff.h
+++ b/arch/sparc/include/asm/backoff.h
@@ -1,6 +1,46 @@
 #ifndef _SPARC64_BACKOFF_H
 #define _SPARC64_BACKOFF_H
 
+/* The macros in this file implement an exponential backoff facility
+ * for atomic operations.
+ *
+ * When multiple threads compete on an atomic operation, it is
+ * possible for one thread to be continually denied a successful
+ * completion of the compare-and-swap instruction.  Heavily
+ * threaded cpu implementations like Niagara can compound this
+ * problem even further.
+ *
+ * When an atomic operation fails and needs to be retried, we spin a
+ * certain number of times.  At each subsequent failure of the same
+ * operation we double the spin count, realizing an exponential
+ * backoff.
+ *
+ * When we spin, we try to use an operation that will cause the
+ * current cpu strand to block, and therefore make the core fully
+ * available to any other other runnable strands.  There are two
+ * options, based upon cpu capabilities.
+ *
+ * On all cpus prior to SPARC-T4 we do three dummy reads of the
+ * condition code register.  Each read blocks the strand for something
+ * between 40 and 50 cpu cycles.
+ *
+ * For SPARC-T4 and later we have a special "pause" instruction
+ * available.  This is implemented using writes to register %asr27.
+ * The cpu will block the number of cycles written into the register,
+ * unless a disrupting trap happens first.  SPARC-T4 specifically
+ * implements pause with a granularity of 8 cycles.  Each strand has
+ * an internal pause counter which decrements every 8 cycles.  So the
+ * chip shifts the %asr27 value down by 3 bits, and writes the result
+ * into the pause counter.  If a value smaller than 8 is written, the
+ * chip blocks for 1 cycle.
+ *
+ * To achieve the same amount of backoff as the three %ccr reads give
+ * on earlier chips, we shift the backoff value up by 7 bits.  (Three
+ * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the
+ * whole amount we want to block into the pause register, rather than
+ * loop writing 128 each time.
+ */
+
 #define BACKOFF_LIMIT	(4 * 1024)
 
 #ifdef CONFIG_SMP
@@ -11,16 +51,25 @@
 #define BACKOFF_LABEL(spin_label, continue_label) \
 	spin_label
 
-#define BACKOFF_SPIN(reg, tmp, label)	\
-	mov	reg, tmp; \
-88:	brnz,pt	tmp, 88b; \
-	 sub	tmp, 1, tmp; \
-	set	BACKOFF_LIMIT, tmp; \
-	cmp	reg, tmp; \
-	bg,pn	%xcc, label; \
-	 nop; \
-	ba,pt	%xcc, label; \
-	 sllx	reg, 1, reg;
+#define BACKOFF_SPIN(reg, tmp, label)		\
+	mov		reg, tmp;		\
+88:	rd		%ccr, %g0;		\
+	rd		%ccr, %g0;		\
+	rd		%ccr, %g0;		\
+	.section	.pause_3insn_patch,"ax";\
+	.word		88b;			\
+	sllx		tmp, 7, tmp;		\
+	wr		tmp, 0, %asr27;		\
+	clr		tmp;			\
+	.previous;				\
+	brnz,pt		tmp, 88b;		\
+	 sub		tmp, 1, tmp;		\
+	set		BACKOFF_LIMIT, tmp;	\
+	cmp		reg, tmp;		\
+	bg,pn		%xcc, label;		\
+	 nop;					\
+	ba,pt		%xcc, label;		\
+	 sllx		reg, 1, reg;
 
 #else
 
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index cef99fb..830502fe 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -232,9 +232,10 @@
 	struct pt_regs *regs = current_thread_info()->kregs;
 	unsigned long usp = regs->u_regs[UREG_I6];
 
-	if (!(test_thread_flag(TIF_32BIT)))
+	if (test_thread_64bit_stack(usp))
 		usp += STACK_BIAS;
-	else
+
+	if (test_thread_flag(TIF_32BIT))
 		usp &= 0xffffffffUL;
 
 	usp -= len;
diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h
index 4e5a483..721e25f 100644
--- a/arch/sparc/include/asm/processor_64.h
+++ b/arch/sparc/include/asm/processor_64.h
@@ -196,7 +196,22 @@
 #define KSTK_EIP(tsk)  (task_pt_regs(tsk)->tpc)
 #define KSTK_ESP(tsk)  (task_pt_regs(tsk)->u_regs[UREG_FP])
 
-#define cpu_relax()	barrier()
+/* Please see the commentary in asm/backoff.h for a description of
+ * what these instructions are doing and how they have been choosen.
+ * To make a long story short, we are trying to yield the current cpu
+ * strand during busy loops.
+ */
+#define cpu_relax()	asm volatile("\n99:\n\t"			\
+				     "rd	%%ccr, %%g0\n\t"	\
+				     "rd	%%ccr, %%g0\n\t"	\
+				     "rd	%%ccr, %%g0\n\t"	\
+				     ".section	.pause_3insn_patch,\"ax\"\n\t"\
+				     ".word	99b\n\t"		\
+				     "wr	%%g0, 128, %%asr27\n\t"	\
+				     "nop\n\t"				\
+				     "nop\n\t"				\
+				     ".previous"			\
+				     ::: "memory")
 
 /* Prefetch support.  This is tuned for UltraSPARC-III and later.
  * UltraSPARC-I will treat these as nops, and UltraSPARC-II has
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
index c287651..f930031 100644
--- a/arch/sparc/include/asm/prom.h
+++ b/arch/sparc/include/asm/prom.h
@@ -63,5 +63,10 @@
 extern void irq_trans_init(struct device_node *dp);
 extern char *build_path_component(struct device_node *dp);
 
+/* SPARC has a local implementation */
+extern int of_address_to_resource(struct device_node *dev, int index,
+				  struct resource *r);
+#define of_address_to_resource of_address_to_resource
+
 #endif /* __KERNEL__ */
 #endif /* _SPARC_PROM_H */
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 4e227663..a3fe4dc 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -259,6 +259,11 @@
 
 #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
 
+#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0)
+#define test_thread_64bit_stack(__SP) \
+	((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \
+	 false : true)
+
 #endif	/* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h
index 48f2807..71b5a67 100644
--- a/arch/sparc/include/asm/ttable.h
+++ b/arch/sparc/include/asm/ttable.h
@@ -372,7 +372,9 @@
 
 /* Normal 32bit spill */
 #define SPILL_2_GENERIC(ASI)				\
-	srl	%sp, 0, %sp;				\
+	and	%sp, 1, %g3;				\
+	brnz,pn	%g3, (. - (128 + 4));			\
+	 srl	%sp, 0, %sp;				\
 	stwa	%l0, [%sp + %g0] ASI;			\
 	mov	0x04, %g3;				\
 	stwa	%l1, [%sp + %g3] ASI;			\
@@ -398,14 +400,16 @@
 	stwa	%i6, [%g1 + %g0] ASI;			\
 	stwa	%i7, [%g1 + %g3] ASI;			\
 	saved;						\
-        retry; nop; nop;				\
+        retry;						\
 	b,a,pt	%xcc, spill_fixup_dax;			\
 	b,a,pt	%xcc, spill_fixup_mna;			\
 	b,a,pt	%xcc, spill_fixup;
 
 #define SPILL_2_GENERIC_ETRAP		\
 etrap_user_spill_32bit:			\
-	srl	%sp, 0, %sp;		\
+	and	%sp, 1, %g3;		\
+	brnz,pn	%g3, etrap_user_spill_64bit;	\
+	 srl	%sp, 0, %sp;		\
 	stwa	%l0, [%sp + 0x00] %asi;	\
 	stwa	%l1, [%sp + 0x04] %asi;	\
 	stwa	%l2, [%sp + 0x08] %asi;	\
@@ -427,7 +431,7 @@
 	ba,pt	%xcc, etrap_save;	\
 	 wrpr	%g1, %cwp;		\
 	nop; nop; nop; nop;		\
-	nop; nop; nop; nop;		\
+	nop; nop;			\
 	ba,a,pt	%xcc, etrap_spill_fixup_32bit; \
 	ba,a,pt	%xcc, etrap_spill_fixup_32bit; \
 	ba,a,pt	%xcc, etrap_spill_fixup_32bit;
@@ -592,7 +596,9 @@
 
 /* Normal 32bit fill */
 #define FILL_2_GENERIC(ASI)				\
-	srl	%sp, 0, %sp;				\
+	and	%sp, 1, %g3;				\
+	brnz,pn	%g3, (. - (128 + 4));			\
+	 srl	%sp, 0, %sp;				\
 	lduwa	[%sp + %g0] ASI, %l0;			\
 	mov	0x04, %g2;				\
 	mov	0x08, %g3;				\
@@ -616,14 +622,16 @@
 	lduwa	[%g1 + %g3] ASI, %i6;			\
 	lduwa	[%g1 + %g5] ASI, %i7;			\
 	restored;					\
-	retry; nop; nop; nop; nop;			\
+	retry; nop; nop;				\
 	b,a,pt	%xcc, fill_fixup_dax;			\
 	b,a,pt	%xcc, fill_fixup_mna;			\
 	b,a,pt	%xcc, fill_fixup;
 
 #define FILL_2_GENERIC_RTRAP				\
 user_rtt_fill_32bit:					\
-	srl	%sp, 0, %sp;				\
+	and	%sp, 1, %g3;				\
+	brnz,pn	%g3, user_rtt_fill_64bit;		\
+	 srl	%sp, 0, %sp;				\
 	lduwa	[%sp + 0x00] %asi, %l0;			\
 	lduwa	[%sp + 0x04] %asi, %l1;			\
 	lduwa	[%sp + 0x08] %asi, %l2;			\
@@ -643,7 +651,7 @@
 	ba,pt	%xcc, user_rtt_pre_restore;		\
 	 restored;					\
 	nop; nop; nop; nop; nop;			\
-	nop; nop; nop; nop; nop;			\
+	nop; nop; nop;					\
 	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
 	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
 	ba,a,pt	%xcc, user_rtt_fill_fixup;
diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h
index 8974ef7..cac719d 100644
--- a/arch/sparc/include/uapi/asm/unistd.h
+++ b/arch/sparc/include/uapi/asm/unistd.h
@@ -405,8 +405,13 @@
 #define __NR_setns		337
 #define __NR_process_vm_readv	338
 #define __NR_process_vm_writev	339
+#define __NR_kern_features	340
+#define __NR_kcmp		341
 
-#define NR_syscalls		340
+#define NR_syscalls		342
+
+/* Bitmask values returned from kern_features system call.  */
+#define KERN_FEATURE_MIXED_MODE_STACK	0x00000001
 
 #ifdef __32bit_syscall_numbers__
 /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h
index 0c218e4..cc3c5cb 100644
--- a/arch/sparc/kernel/entry.h
+++ b/arch/sparc/kernel/entry.h
@@ -59,6 +59,13 @@
 extern struct popc_6insn_patch_entry __popc_6insn_patch,
 	__popc_6insn_patch_end;
 
+struct pause_patch_entry {
+	unsigned int	addr;
+	unsigned int	insns[3];
+};
+extern struct pause_patch_entry __pause_3insn_patch,
+	__pause_3insn_patch_end;
+
 extern void __init per_cpu_patch(void);
 extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
 				    struct sun4v_1insn_patch_entry *);
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index f8b6eee..87f60ee 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -56,11 +56,13 @@
 static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int eirq;
+	struct irq_bucket *p;
 	int cpu = sparc_leon3_cpuid();
 
 	eirq = leon_eirq_get(cpu);
-	if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */
-		generic_handle_irq(irq_map[eirq]->irq);
+	p = irq_map[eirq];
+	if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */
+		generic_handle_irq(p->irq);
 }
 
 /* The extended IRQ controller has been found, this function registers it */
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 885a8af..b5c38fa 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -1762,15 +1762,25 @@
 
 	ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
 	do {
-		struct sparc_stackf32 *usf, sf;
 		unsigned long pc;
 
-		usf = (struct sparc_stackf32 *) ufp;
-		if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
-			break;
+		if (thread32_stack_is_64bit(ufp)) {
+			struct sparc_stackf *usf, sf;
 
-		pc = sf.callers_pc;
-		ufp = (unsigned long)sf.fp;
+			ufp += STACK_BIAS;
+			usf = (struct sparc_stackf *) ufp;
+			if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
+				break;
+			pc = sf.callers_pc & 0xffffffff;
+			ufp = ((unsigned long) sf.fp) & 0xffffffff;
+		} else {
+			struct sparc_stackf32 *usf, sf;
+			usf = (struct sparc_stackf32 *) ufp;
+			if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
+				break;
+			pc = sf.callers_pc;
+			ufp = (unsigned long)sf.fp;
+		}
 		perf_callchain_store(entry, pc);
 	} while (entry->nr < PERF_MAX_STACK_DEPTH);
 }
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index d778248..c6e0c29 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -452,13 +452,16 @@
 /* It's a bit more tricky when 64-bit tasks are involved... */
 static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
 {
+	bool stack_64bit = test_thread_64bit_stack(psp);
 	unsigned long fp, distance, rval;
 
-	if (!(test_thread_flag(TIF_32BIT))) {
+	if (stack_64bit) {
 		csp += STACK_BIAS;
 		psp += STACK_BIAS;
 		__get_user(fp, &(((struct reg_window __user *)psp)->ins[6]));
 		fp += STACK_BIAS;
+		if (test_thread_flag(TIF_32BIT))
+			fp &= 0xffffffff;
 	} else
 		__get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6]));
 
@@ -472,7 +475,7 @@
 	rval = (csp - distance);
 	if (copy_in_user((void __user *) rval, (void __user *) psp, distance))
 		rval = 0;
-	else if (test_thread_flag(TIF_32BIT)) {
+	else if (!stack_64bit) {
 		if (put_user(((u32)csp),
 			     &(((struct reg_window32 __user *)rval)->ins[6])))
 			rval = 0;
@@ -507,18 +510,18 @@
 
 	flush_user_windows();
 	if ((window = get_thread_wsaved()) != 0) {
-		int winsize = sizeof(struct reg_window);
-		int bias = 0;
-
-		if (test_thread_flag(TIF_32BIT))
-			winsize = sizeof(struct reg_window32);
-		else
-			bias = STACK_BIAS;
-
 		window -= 1;
 		do {
-			unsigned long sp = (t->rwbuf_stkptrs[window] + bias);
 			struct reg_window *rwin = &t->reg_window[window];
+			int winsize = sizeof(struct reg_window);
+			unsigned long sp;
+
+			sp = t->rwbuf_stkptrs[window];
+
+			if (test_thread_64bit_stack(sp))
+				sp += STACK_BIAS;
+			else
+				winsize = sizeof(struct reg_window32);
 
 			if (!copy_to_user((char __user *)sp, rwin, winsize)) {
 				shift_window_buffer(window, get_thread_wsaved() - 1, t);
@@ -544,13 +547,6 @@
 {
 	struct thread_info *t = current_thread_info();
 	unsigned long window;
-	int winsize = sizeof(struct reg_window);
-	int bias = 0;
-
-	if (test_thread_flag(TIF_32BIT))
-		winsize = sizeof(struct reg_window32);
-	else
-		bias = STACK_BIAS;
 
 	flush_user_windows();
 	window = get_thread_wsaved();
@@ -558,8 +554,16 @@
 	if (likely(window != 0)) {
 		window -= 1;
 		do {
-			unsigned long sp = (t->rwbuf_stkptrs[window] + bias);
 			struct reg_window *rwin = &t->reg_window[window];
+			int winsize = sizeof(struct reg_window);
+			unsigned long sp;
+
+			sp = t->rwbuf_stkptrs[window];
+
+			if (test_thread_64bit_stack(sp))
+				sp += STACK_BIAS;
+			else
+				winsize = sizeof(struct reg_window32);
 
 			if (unlikely(sp & 0x7UL))
 				stack_unaligned(sp);
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
index 484daba..7ff45e4 100644
--- a/arch/sparc/kernel/ptrace_64.c
+++ b/arch/sparc/kernel/ptrace_64.c
@@ -151,7 +151,7 @@
 {
 	unsigned long rw_addr = regs->u_regs[UREG_I6];
 
-	if (test_tsk_thread_flag(current, TIF_32BIT)) {
+	if (!test_thread_64bit_stack(rw_addr)) {
 		struct reg_window32 win32;
 		int i;
 
@@ -176,7 +176,7 @@
 {
 	unsigned long rw_addr = regs->u_regs[UREG_I6];
 
-	if (test_tsk_thread_flag(current, TIF_32BIT)) {
+	if (!test_thread_64bit_stack(rw_addr)) {
 		struct reg_window32 win32;
 		int i;
 
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 0800e71..0eaf005 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -316,6 +316,25 @@
 	}
 }
 
+static void __init pause_patch(void)
+{
+	struct pause_patch_entry *p;
+
+	p = &__pause_3insn_patch;
+	while (p < &__pause_3insn_patch_end) {
+		unsigned long i, addr = p->addr;
+
+		for (i = 0; i < 3; i++) {
+			*(unsigned int *) (addr +  (i * 4)) = p->insns[i];
+			wmb();
+			__asm__ __volatile__("flush	%0"
+					     : : "r" (addr +  (i * 4)));
+		}
+
+		p++;
+	}
+}
+
 #ifdef CONFIG_SMP
 void __init boot_cpu_id_too_large(int cpu)
 {
@@ -528,6 +547,8 @@
 
 	if (sparc64_elf_hwcap & AV_SPARC_POPC)
 		popc_patch();
+	if (sparc64_elf_hwcap & AV_SPARC_PAUSE)
+		pause_patch();
 }
 
 void __init setup_arch(char **cmdline_p)
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 11c6c96..878ef3d 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -751,3 +751,8 @@
 		      : "cc");
 	return __res;
 }
+
+asmlinkage long sys_kern_features(void)
+{
+	return KERN_FEATURE_MIXED_MODE_STACK;
+}
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
index 63402f9..5147f57 100644
--- a/arch/sparc/kernel/systbls_32.S
+++ b/arch/sparc/kernel/systbls_32.S
@@ -85,3 +85,4 @@
 /*325*/	.long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
 /*330*/	.long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
 /*335*/	.long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
+/*340*/	.long sys_ni_syscall, sys_kcmp
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 3a58e0d..1c9af9f 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -86,6 +86,7 @@
 	.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
 /*330*/	.word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
 	.word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev
+/*340*/	.word sys_kern_features, sys_kcmp
 
 #endif /* CONFIG_COMPAT */
 
@@ -163,3 +164,4 @@
 	.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
 /*330*/	.word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
 	.word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
+/*340*/	.word sys_kern_features, sys_kcmp
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
index f81d038..8201c25e 100644
--- a/arch/sparc/kernel/unaligned_64.c
+++ b/arch/sparc/kernel/unaligned_64.c
@@ -113,21 +113,24 @@
 
 static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
 {
-	unsigned long value;
+	unsigned long value, fp;
 	
 	if (reg < 16)
 		return (!reg ? 0 : regs->u_regs[reg]);
+
+	fp = regs->u_regs[UREG_FP];
+
 	if (regs->tstate & TSTATE_PRIV) {
 		struct reg_window *win;
-		win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+		win = (struct reg_window *)(fp + STACK_BIAS);
 		value = win->locals[reg - 16];
-	} else if (test_thread_flag(TIF_32BIT)) {
+	} else if (!test_thread_64bit_stack(fp)) {
 		struct reg_window32 __user *win32;
-		win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+		win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
 		get_user(value, &win32->locals[reg - 16]);
 	} else {
 		struct reg_window __user *win;
-		win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+		win = (struct reg_window __user *)(fp + STACK_BIAS);
 		get_user(value, &win->locals[reg - 16]);
 	}
 	return value;
@@ -135,19 +138,24 @@
 
 static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs)
 {
+	unsigned long fp;
+
 	if (reg < 16)
 		return &regs->u_regs[reg];
+
+	fp = regs->u_regs[UREG_FP];
+
 	if (regs->tstate & TSTATE_PRIV) {
 		struct reg_window *win;
-		win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+		win = (struct reg_window *)(fp + STACK_BIAS);
 		return &win->locals[reg - 16];
-	} else if (test_thread_flag(TIF_32BIT)) {
+	} else if (!test_thread_64bit_stack(fp)) {
 		struct reg_window32 *win32;
-		win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+		win32 = (struct reg_window32 *)((unsigned long)((u32)fp));
 		return (unsigned long *)&win32->locals[reg - 16];
 	} else {
 		struct reg_window *win;
-		win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+		win = (struct reg_window *)(fp + STACK_BIAS);
 		return &win->locals[reg - 16];
 	}
 }
@@ -392,13 +400,15 @@
 		if (rd)
 			regs->u_regs[rd] = ret;
 	} else {
-		if (test_thread_flag(TIF_32BIT)) {
+		unsigned long fp = regs->u_regs[UREG_FP];
+
+		if (!test_thread_64bit_stack(fp)) {
 			struct reg_window32 __user *win32;
-			win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+			win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
 			put_user(ret, &win32->locals[rd - 16]);
 		} else {
 			struct reg_window __user *win;
-			win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+			win = (struct reg_window __user *)(fp + STACK_BIAS);
 			put_user(ret, &win->locals[rd - 16]);
 		}
 	}
@@ -554,7 +564,7 @@
 		reg[0] = 0;
 		if ((insn & 0x780000) == 0x180000)
 			reg[1] = 0;
-	} else if (test_thread_flag(TIF_32BIT)) {
+	} else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) {
 		put_user(0, (int __user *) reg);
 		if ((insn & 0x780000) == 0x180000)
 			put_user(0, ((int __user *) reg) + 1);
diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c
index 08e074b7..c096c62 100644
--- a/arch/sparc/kernel/visemul.c
+++ b/arch/sparc/kernel/visemul.c
@@ -149,21 +149,24 @@
 
 static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
 {
-	unsigned long value;
+	unsigned long value, fp;
 	
 	if (reg < 16)
 		return (!reg ? 0 : regs->u_regs[reg]);
+
+	fp = regs->u_regs[UREG_FP];
+
 	if (regs->tstate & TSTATE_PRIV) {
 		struct reg_window *win;
-		win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+		win = (struct reg_window *)(fp + STACK_BIAS);
 		value = win->locals[reg - 16];
-	} else if (test_thread_flag(TIF_32BIT)) {
+	} else if (!test_thread_64bit_stack(fp)) {
 		struct reg_window32 __user *win32;
-		win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+		win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
 		get_user(value, &win32->locals[reg - 16]);
 	} else {
 		struct reg_window __user *win;
-		win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+		win = (struct reg_window __user *)(fp + STACK_BIAS);
 		get_user(value, &win->locals[reg - 16]);
 	}
 	return value;
@@ -172,16 +175,18 @@
 static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg,
 							  struct pt_regs *regs)
 {
+	unsigned long fp = regs->u_regs[UREG_FP];
+
 	BUG_ON(reg < 16);
 	BUG_ON(regs->tstate & TSTATE_PRIV);
 
-	if (test_thread_flag(TIF_32BIT)) {
+	if (!test_thread_64bit_stack(fp)) {
 		struct reg_window32 __user *win32;
-		win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+		win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
 		return (unsigned long __user *)&win32->locals[reg - 16];
 	} else {
 		struct reg_window __user *win;
-		win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+		win = (struct reg_window __user *)(fp + STACK_BIAS);
 		return &win->locals[reg - 16];
 	}
 }
@@ -204,7 +209,7 @@
 	} else {
 		unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs);
 
-		if (test_thread_flag(TIF_32BIT))
+		if (!test_thread_64bit_stack(regs->u_regs[UREG_FP]))
 			__put_user((u32)val, (u32 __user *)rd_user);
 		else
 			__put_user(val, rd_user);
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 89c2c29..0bacceb 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -132,6 +132,11 @@
 		*(.popc_6insn_patch)
 		__popc_6insn_patch_end = .;
 	}
+	.pause_3insn_patch : {
+		__pause_3insn_patch = .;
+		*(.pause_3insn_patch)
+		__pause_3insn_patch_end = .;
+	}
 	PERCPU_SECTION(SMP_CACHE_BYTES)
 
 	. = ALIGN(PAGE_SIZE);
diff --git a/arch/sparc/kernel/winfixup.S b/arch/sparc/kernel/winfixup.S
index a6b0863..1e67ce9 100644
--- a/arch/sparc/kernel/winfixup.S
+++ b/arch/sparc/kernel/winfixup.S
@@ -43,6 +43,8 @@
 spill_fixup_dax:
 	TRAP_LOAD_THREAD_REG(%g6, %g1)
 	ldx	[%g6 + TI_FLAGS], %g1
+	andcc	%sp, 0x1, %g0
+	movne	%icc, 0, %g1
 	andcc	%g1, _TIF_32BIT, %g0
 	ldub	[%g6 + TI_WSAVED], %g1
 	sll	%g1, 3, %g3
diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S
index 4d502da..85c233d 100644
--- a/arch/sparc/lib/atomic_64.S
+++ b/arch/sparc/lib/atomic_64.S
@@ -1,6 +1,6 @@
 /* atomic.S: These things are too big to do inline.
  *
- * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/linkage.h>
@@ -117,3 +117,17 @@
 	 sub	%g1, %o0, %o0
 2:	BACKOFF_SPIN(%o2, %o3, 1b)
 ENDPROC(atomic64_sub_ret)
+
+ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */
+	BACKOFF_SETUP(%o2)
+1:	ldx	[%o0], %g1
+	brlez,pn %g1, 3f
+	 sub	%g1, 1, %g7
+	casx	[%o0], %g1, %g7
+	cmp	%g1, %g7
+	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
+	 nop
+3:	retl
+	 sub	%g1, 1, %o0
+2:	BACKOFF_SPIN(%o2, %o3, 1b)
+ENDPROC(atomic64_dec_if_positive)
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
index ee31b88..0c4e35e 100644
--- a/arch/sparc/lib/ksyms.c
+++ b/arch/sparc/lib/ksyms.c
@@ -116,6 +116,7 @@
 EXPORT_SYMBOL(atomic64_add_ret);
 EXPORT_SYMBOL(atomic64_sub);
 EXPORT_SYMBOL(atomic64_sub_ret);
+EXPORT_SYMBOL(atomic64_dec_if_positive);
 
 /* Atomic bit operations. */
 EXPORT_SYMBOL(test_and_set_bit);
diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c
index 1704068..034aadb 100644
--- a/arch/sparc/math-emu/math_64.c
+++ b/arch/sparc/math-emu/math_64.c
@@ -320,7 +320,7 @@
 					XR = 0;
 				else if (freg < 16)
 					XR = regs->u_regs[freg];
-				else if (test_thread_flag(TIF_32BIT)) {
+				else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) {
 					struct reg_window32 __user *win32;
 					flushw_user ();
 					win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
diff --git a/arch/tile/Makefile b/arch/tile/Makefile
index 55640cf..3d15364 100644
--- a/arch/tile/Makefile
+++ b/arch/tile/Makefile
@@ -26,6 +26,10 @@
   endif
 endif
 
+# The tile compiler may emit .eh_frame information for backtracing.
+# In kernel modules, this causes load failures due to unsupported relocations.
+KBUILD_CFLAGS   += -fno-asynchronous-unwind-tables
+
 ifneq ($(CONFIG_DEBUG_EXTRA_FLAGS),"")
 KBUILD_CFLAGS   += $(CONFIG_DEBUG_EXTRA_FLAGS)
 endif
diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c
index 001cbfa..243ffeb 100644
--- a/arch/tile/kernel/module.c
+++ b/arch/tile/kernel/module.c
@@ -24,16 +24,6 @@
 #include <asm/homecache.h>
 #include <arch/opcode.h>
 
-#ifdef __tilegx__
-# define Elf_Rela Elf64_Rela
-# define ELF_R_SYM ELF64_R_SYM
-# define ELF_R_TYPE ELF64_R_TYPE
-#else
-# define Elf_Rela Elf32_Rela
-# define ELF_R_SYM ELF32_R_SYM
-# define ELF_R_TYPE ELF32_R_TYPE
-#endif
-
 #ifdef MODULE_DEBUG
 #define DEBUGP printk
 #else
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index e5c5473..c4fbb21 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -16,6 +16,8 @@
 	select ARCH_WANT_FRAME_POINTERS
 	select GENERIC_IOMAP
 	select MODULES_USE_ELF_REL
+	select GENERIC_KERNEL_THREAD
+	select GENERIC_KERNEL_EXECVE
 	help
 	  UniCore-32 is 32-bit Instruction Set Architecture,
 	  including a series of low-power-consumption RISC chip
@@ -64,6 +66,9 @@
 config ARCH_MAY_HAVE_PC_FDC
 	bool
 
+config ZONE_DMA
+	def_bool y
+
 config NEED_DMA_MAP_STATE
        def_bool y
 
@@ -216,7 +221,7 @@
 	bool
 	depends on !ARCH_FPGA
 	select GENERIC_GPIO
-	select GPIO_SYSFS if EXPERIMENTAL
+	select GPIO_SYSFS
 	default y
 
 if PUV3_NB0916
diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild
index c910c98..601e92f 100644
--- a/arch/unicore32/include/asm/Kbuild
+++ b/arch/unicore32/include/asm/Kbuild
@@ -1,4 +1,3 @@
-include include/asm-generic/Kbuild.asm
 
 generic-y += atomic.h
 generic-y += auxvec.h
diff --git a/arch/unicore32/include/asm/bug.h b/arch/unicore32/include/asm/bug.h
index b1ff8ca..93a56f3 100644
--- a/arch/unicore32/include/asm/bug.h
+++ b/arch/unicore32/include/asm/bug.h
@@ -19,9 +19,4 @@
 extern void uc32_notify_die(const char *str, struct pt_regs *regs,
 		struct siginfo *info, unsigned long err, unsigned long trap);
 
-extern asmlinkage void __backtrace(void);
-extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
-
-extern void __show_regs(struct pt_regs *);
-
 #endif /* __UNICORE_BUG_H__ */
diff --git a/arch/unicore32/include/asm/cmpxchg.h b/arch/unicore32/include/asm/cmpxchg.h
index df4d5ac..8e797ad 100644
--- a/arch/unicore32/include/asm/cmpxchg.h
+++ b/arch/unicore32/include/asm/cmpxchg.h
@@ -35,7 +35,7 @@
 			: "memory", "cc");
 		break;
 	default:
-		ret = __xchg_bad_pointer();
+		__xchg_bad_pointer();
 	}
 
 	return ret;
diff --git a/arch/unicore32/include/asm/kvm_para.h b/arch/unicore32/include/asm/kvm_para.h
deleted file mode 100644
index 14fab8f..0000000
--- a/arch/unicore32/include/asm/kvm_para.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/kvm_para.h>
diff --git a/arch/unicore32/include/asm/processor.h b/arch/unicore32/include/asm/processor.h
index 14382cb..4eaa421 100644
--- a/arch/unicore32/include/asm/processor.h
+++ b/arch/unicore32/include/asm/processor.h
@@ -72,11 +72,6 @@
 
 #define cpu_relax()			barrier()
 
-/*
- * Create a new kernel thread
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
 #define task_pt_regs(p) \
 	((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
 
diff --git a/arch/unicore32/include/asm/ptrace.h b/arch/unicore32/include/asm/ptrace.h
index b9caf9b..726749d 100644
--- a/arch/unicore32/include/asm/ptrace.h
+++ b/arch/unicore32/include/asm/ptrace.h
@@ -12,80 +12,10 @@
 #ifndef __UNICORE_PTRACE_H__
 #define __UNICORE_PTRACE_H__
 
-#define PTRACE_GET_THREAD_AREA	22
-
-/*
- * PSR bits
- */
-#define USER_MODE	0x00000010
-#define REAL_MODE	0x00000011
-#define INTR_MODE	0x00000012
-#define PRIV_MODE	0x00000013
-#define ABRT_MODE	0x00000017
-#define EXTN_MODE	0x0000001b
-#define SUSR_MODE	0x0000001f
-#define MODE_MASK	0x0000001f
-#define PSR_R_BIT	0x00000040
-#define PSR_I_BIT	0x00000080
-#define PSR_V_BIT	0x10000000
-#define PSR_C_BIT	0x20000000
-#define PSR_Z_BIT	0x40000000
-#define PSR_S_BIT	0x80000000
-
-/*
- * Groups of PSR bits
- */
-#define PSR_f		0xff000000	/* Flags		*/
-#define PSR_c		0x000000ff	/* Control		*/
+#include <uapi/asm/ptrace.h>
 
 #ifndef __ASSEMBLY__
 
-/*
- * This struct defines the way the registers are stored on the
- * stack during a system call.  Note that sizeof(struct pt_regs)
- * has to be a multiple of 8.
- */
-struct pt_regs {
-	unsigned long uregs[34];
-};
-
-#define UCreg_asr		uregs[32]
-#define UCreg_pc		uregs[31]
-#define UCreg_lr		uregs[30]
-#define UCreg_sp		uregs[29]
-#define UCreg_ip		uregs[28]
-#define UCreg_fp		uregs[27]
-#define UCreg_26		uregs[26]
-#define UCreg_25		uregs[25]
-#define UCreg_24		uregs[24]
-#define UCreg_23		uregs[23]
-#define UCreg_22		uregs[22]
-#define UCreg_21		uregs[21]
-#define UCreg_20		uregs[20]
-#define UCreg_19		uregs[19]
-#define UCreg_18		uregs[18]
-#define UCreg_17		uregs[17]
-#define UCreg_16		uregs[16]
-#define UCreg_15		uregs[15]
-#define UCreg_14		uregs[14]
-#define UCreg_13		uregs[13]
-#define UCreg_12		uregs[12]
-#define UCreg_11		uregs[11]
-#define UCreg_10		uregs[10]
-#define UCreg_09		uregs[9]
-#define UCreg_08		uregs[8]
-#define UCreg_07		uregs[7]
-#define UCreg_06		uregs[6]
-#define UCreg_05		uregs[5]
-#define UCreg_04		uregs[4]
-#define UCreg_03		uregs[3]
-#define UCreg_02		uregs[2]
-#define UCreg_01		uregs[1]
-#define UCreg_00		uregs[0]
-#define UCreg_ORIG_00		uregs[33]
-
-#ifdef __KERNEL__
-
 #define user_mode(regs)	\
 	(processor_mode(regs) == USER_MODE)
 
@@ -125,9 +55,5 @@
 
 #define instruction_pointer(regs)	((regs)->UCreg_pc)
 
-#endif /* __KERNEL__ */
-
 #endif /* __ASSEMBLY__ */
-
 #endif
-
diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild
index baebb3d..0514d7a 100644
--- a/arch/unicore32/include/uapi/asm/Kbuild
+++ b/arch/unicore32/include/uapi/asm/Kbuild
@@ -1,3 +1,10 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
+header-y += byteorder.h
+header-y += kvm_para.h
+header-y += ptrace.h
+header-y += sigcontext.h
+header-y += unistd.h
+
+generic-y += kvm_para.h
diff --git a/arch/unicore32/include/asm/byteorder.h b/arch/unicore32/include/uapi/asm/byteorder.h
similarity index 100%
rename from arch/unicore32/include/asm/byteorder.h
rename to arch/unicore32/include/uapi/asm/byteorder.h
diff --git a/arch/unicore32/include/uapi/asm/ptrace.h b/arch/unicore32/include/uapi/asm/ptrace.h
new file mode 100644
index 0000000..187aa2e
--- /dev/null
+++ b/arch/unicore32/include/uapi/asm/ptrace.h
@@ -0,0 +1,90 @@
+/*
+ * linux/arch/unicore32/include/asm/ptrace.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _UAPI__UNICORE_PTRACE_H__
+#define _UAPI__UNICORE_PTRACE_H__
+
+#define PTRACE_GET_THREAD_AREA	22
+
+/*
+ * PSR bits
+ */
+#define USER_MODE	0x00000010
+#define REAL_MODE	0x00000011
+#define INTR_MODE	0x00000012
+#define PRIV_MODE	0x00000013
+#define ABRT_MODE	0x00000017
+#define EXTN_MODE	0x0000001b
+#define SUSR_MODE	0x0000001f
+#define MODE_MASK	0x0000001f
+#define PSR_R_BIT	0x00000040
+#define PSR_I_BIT	0x00000080
+#define PSR_V_BIT	0x10000000
+#define PSR_C_BIT	0x20000000
+#define PSR_Z_BIT	0x40000000
+#define PSR_S_BIT	0x80000000
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f		0xff000000	/* Flags		*/
+#define PSR_c		0x000000ff	/* Control		*/
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This struct defines the way the registers are stored on the
+ * stack during a system call.  Note that sizeof(struct pt_regs)
+ * has to be a multiple of 8.
+ */
+struct pt_regs {
+	unsigned long uregs[34];
+};
+
+#define UCreg_asr		uregs[32]
+#define UCreg_pc		uregs[31]
+#define UCreg_lr		uregs[30]
+#define UCreg_sp		uregs[29]
+#define UCreg_ip		uregs[28]
+#define UCreg_fp		uregs[27]
+#define UCreg_26		uregs[26]
+#define UCreg_25		uregs[25]
+#define UCreg_24		uregs[24]
+#define UCreg_23		uregs[23]
+#define UCreg_22		uregs[22]
+#define UCreg_21		uregs[21]
+#define UCreg_20		uregs[20]
+#define UCreg_19		uregs[19]
+#define UCreg_18		uregs[18]
+#define UCreg_17		uregs[17]
+#define UCreg_16		uregs[16]
+#define UCreg_15		uregs[15]
+#define UCreg_14		uregs[14]
+#define UCreg_13		uregs[13]
+#define UCreg_12		uregs[12]
+#define UCreg_11		uregs[11]
+#define UCreg_10		uregs[10]
+#define UCreg_09		uregs[9]
+#define UCreg_08		uregs[8]
+#define UCreg_07		uregs[7]
+#define UCreg_06		uregs[6]
+#define UCreg_05		uregs[5]
+#define UCreg_04		uregs[4]
+#define UCreg_03		uregs[3]
+#define UCreg_02		uregs[2]
+#define UCreg_01		uregs[1]
+#define UCreg_00		uregs[0]
+#define UCreg_ORIG_00		uregs[33]
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI__UNICORE_PTRACE_H__ */
diff --git a/arch/unicore32/include/asm/sigcontext.h b/arch/unicore32/include/uapi/asm/sigcontext.h
similarity index 100%
rename from arch/unicore32/include/asm/sigcontext.h
rename to arch/unicore32/include/uapi/asm/sigcontext.h
diff --git a/arch/unicore32/include/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h
similarity index 92%
rename from arch/unicore32/include/asm/unistd.h
rename to arch/unicore32/include/uapi/asm/unistd.h
index 2abcf61..d18a3be8 100644
--- a/arch/unicore32/include/asm/unistd.h
+++ b/arch/unicore32/include/uapi/asm/unistd.h
@@ -12,3 +12,4 @@
 
 /* Use the standard ABI for syscalls. */
 #include <asm-generic/unistd.h>
+#define __ARCH_WANT_SYS_EXECVE
diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S
index dcb87ab..7049350 100644
--- a/arch/unicore32/kernel/entry.S
+++ b/arch/unicore32/kernel/entry.S
@@ -573,17 +573,16 @@
  */
 ENTRY(ret_from_fork)
 	b.l	schedule_tail
-	get_thread_info tsk
-	ldw	r1, [tsk+], #TI_FLAGS		@ check for syscall tracing
-	mov	why, #1
-	cand.a	r1, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls?
-	beq	ret_slow_syscall
-	mov	r1, sp
-	mov	r0, #1				@ trace exit [IP = 1]
-	b.l	syscall_trace
 	b	ret_slow_syscall
 ENDPROC(ret_from_fork)
 
+ENTRY(ret_from_kernel_thread)
+	b.l	schedule_tail
+	mov	r0, r5
+	adr	lr, ret_slow_syscall
+	mov	pc, r4
+ENDPROC(ret_from_kernel_thread)
+
 /*=============================================================================
  * SWI handler
  *-----------------------------------------------------------------------------
@@ -669,11 +668,6 @@
 #endif
 	.ltorg
 
-ENTRY(sys_execve)
-		add	r3, sp, #S_OFF
-		b	__sys_execve
-ENDPROC(sys_execve)
-
 ENTRY(sys_clone)
 		add	ip, sp, #S_OFF
 		stw	ip, [sp+], #4
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c
index b008586..a8fe265 100644
--- a/arch/unicore32/kernel/process.c
+++ b/arch/unicore32/kernel/process.c
@@ -258,6 +258,7 @@
 }
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
 
 int
 copy_thread(unsigned long clone_flags, unsigned long stack_start,
@@ -266,17 +267,22 @@
 	struct thread_info *thread = task_thread_info(p);
 	struct pt_regs *childregs = task_pt_regs(p);
 
-	*childregs = *regs;
-	childregs->UCreg_00 = 0;
-	childregs->UCreg_sp = stack_start;
-
 	memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
 	thread->cpu_context.sp = (unsigned long)childregs;
-	thread->cpu_context.pc = (unsigned long)ret_from_fork;
+	if (unlikely(!regs)) {
+		thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread;
+		thread->cpu_context.r4 = stack_start;
+		thread->cpu_context.r5 = stk_sz;
+		memset(childregs, 0, sizeof(struct pt_regs));
+	} else {
+		thread->cpu_context.pc = (unsigned long)ret_from_fork;
+		*childregs = *regs;
+		childregs->UCreg_00 = 0;
+		childregs->UCreg_sp = stack_start;
 
-	if (clone_flags & CLONE_SETTLS)
-		childregs->UCreg_16 = regs->UCreg_03;
-
+		if (clone_flags & CLONE_SETTLS)
+			childregs->UCreg_16 = regs->UCreg_03;
+	}
 	return 0;
 }
 
@@ -305,42 +311,6 @@
 }
 EXPORT_SYMBOL(dump_fpu);
 
-/*
- * Shuffle the argument into the correct register before calling the
- * thread function.  r1 is the thread argument, r2 is the pointer to
- * the thread function, and r3 points to the exit function.
- */
-asm(".pushsection .text\n"
-"	.align\n"
-"	.type	kernel_thread_helper, #function\n"
-"kernel_thread_helper:\n"
-"	mov.a	asr, r7\n"
-"	mov	r0, r4\n"
-"	mov	lr, r6\n"
-"	mov	pc, r5\n"
-"	.size	kernel_thread_helper, . - kernel_thread_helper\n"
-"	.popsection");
-
-/*
- * Create a kernel thread.
- */
-pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
-	struct pt_regs regs;
-
-	memset(&regs, 0, sizeof(regs));
-
-	regs.UCreg_04 = (unsigned long)arg;
-	regs.UCreg_05 = (unsigned long)fn;
-	regs.UCreg_06 = (unsigned long)do_exit;
-	regs.UCreg_07 = PRIV_MODE;
-	regs.UCreg_pc = (unsigned long)kernel_thread_helper;
-	regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT;
-
-	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
 unsigned long get_wchan(struct task_struct *p)
 {
 	struct stackframe frame;
diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h
index f239550..30f749d 100644
--- a/arch/unicore32/kernel/setup.h
+++ b/arch/unicore32/kernel/setup.h
@@ -30,4 +30,10 @@
 extern void kernel_thread_helper(void);
 
 extern void __init early_signal_init(void);
+
+extern asmlinkage void __backtrace(void);
+extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
+
+extern void __show_regs(struct pt_regs *);
+
 #endif
diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c
index fabdee9..9680134 100644
--- a/arch/unicore32/kernel/sys.c
+++ b/arch/unicore32/kernel/sys.c
@@ -42,69 +42,6 @@
 			parent_tid, child_tid);
 }
 
-/* sys_execve() executes a new program.
- * This is called indirectly via a small wrapper
- */
-asmlinkage long __sys_execve(const char __user *filename,
-			  const char __user *const __user *argv,
-			  const char __user *const __user *envp,
-			  struct pt_regs *regs)
-{
-	int error;
-	struct filename *fn;
-
-	fn = getname(filename);
-	error = PTR_ERR(fn);
-	if (IS_ERR(fn))
-		goto out;
-	error = do_execve(fn->name, argv, envp, regs);
-	putname(fn);
-out:
-	return error;
-}
-
-int kernel_execve(const char *filename,
-		  const char *const argv[],
-		  const char *const envp[])
-{
-	struct pt_regs regs;
-	int ret;
-
-	memset(&regs, 0, sizeof(struct pt_regs));
-	ret = do_execve(filename,
-			(const char __user *const __user *)argv,
-			(const char __user *const __user *)envp, &regs);
-	if (ret < 0)
-		goto out;
-
-	/*
-	 * Save argc to the register structure for userspace.
-	 */
-	regs.UCreg_00 = ret;
-
-	/*
-	 * We were successful.  We won't be returning to our caller, but
-	 * instead to user space by manipulating the kernel stack.
-	 */
-	asm("add	r0, %0, %1\n\t"
-		"mov	r1, %2\n\t"
-		"mov	r2, %3\n\t"
-		"mov	r22, #0\n\t"	/* not a syscall */
-		"mov	r23, %0\n\t"	/* thread structure */
-		"b.l	memmove\n\t"	/* copy regs to top of stack */
-		"mov	sp, r0\n\t"	/* reposition stack pointer */
-		"b	ret_to_user"
-		:
-		: "r" (current_thread_info()),
-		  "Ir" (THREAD_START_SP - sizeof(regs)),
-		  "r" (&regs),
-		  "Ir" (sizeof(regs))
-		: "r0", "r1", "r2", "r3", "ip", "lr", "memory");
-
- out:
-	return ret;
-}
-
 /* Note: used by the compat code even in 64-bit Linux. */
 SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
 		unsigned long, prot, unsigned long, flags,
diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c
index 2eeb9c0..f9b5c10 100644
--- a/arch/unicore32/mm/fault.c
+++ b/arch/unicore32/mm/fault.c
@@ -168,7 +168,7 @@
 }
 
 static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
-		struct task_struct *tsk)
+		unsigned int flags, struct task_struct *tsk)
 {
 	struct vm_area_struct *vma;
 	int fault;
@@ -194,14 +194,7 @@
 	 * If for any reason at all we couldn't handle the fault, make
 	 * sure we exit gracefully rather than endlessly redo the fault.
 	 */
-	fault = handle_mm_fault(mm, vma, addr & PAGE_MASK,
-			    (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0);
-	if (unlikely(fault & VM_FAULT_ERROR))
-		return fault;
-	if (fault & VM_FAULT_MAJOR)
-		tsk->maj_flt++;
-	else
-		tsk->min_flt++;
+	fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags);
 	return fault;
 
 check_stack:
@@ -216,6 +209,8 @@
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	int fault, sig, code;
+	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+				 ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0);
 
 	tsk = current;
 	mm = tsk->mm;
@@ -236,6 +231,7 @@
 		if (!user_mode(regs)
 		    && !search_exception_tables(regs->UCreg_pc))
 			goto no_context;
+retry:
 		down_read(&mm->mmap_sem);
 	} else {
 		/*
@@ -251,7 +247,28 @@
 #endif
 	}
 
-	fault = __do_pf(mm, addr, fsr, tsk);
+	fault = __do_pf(mm, addr, fsr, flags, tsk);
+
+	/* If we need to retry but a fatal signal is pending, handle the
+	 * signal first. We do not need to release the mmap_sem because
+	 * it would already be released in __lock_page_or_retry in
+	 * mm/filemap.c. */
+	if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+		return 0;
+
+	if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) {
+		if (fault & VM_FAULT_MAJOR)
+			tsk->maj_flt++;
+		else
+			tsk->min_flt++;
+		if (fault & VM_FAULT_RETRY) {
+			/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
+			* of starvation. */
+			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			goto retry;
+		}
+	}
+
 	up_read(&mm->mmap_sem);
 
 	/*
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index c9dcc18..6e8fdf5 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -35,7 +35,7 @@
 #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6)	\
 	efi_call_virt(f, a1, a2, a3, a4, a5, a6)
 
-#define efi_ioremap(addr, size, type)		ioremap_cache(addr, size)
+#define efi_ioremap(addr, size, type, attr)	ioremap_cache(addr, size)
 
 #else /* !CONFIG_X86_32 */
 
@@ -89,7 +89,7 @@
 		  (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
 
 extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
-				 u32 type);
+				 u32 type, u64 attribute);
 
 #endif /* CONFIG_X86_32 */
 
@@ -98,6 +98,8 @@
 extern int efi_memblock_x86_reserve_range(void);
 extern void efi_call_phys_prelog(void);
 extern void efi_call_phys_epilog(void);
+extern void efi_unmap_memmap(void);
+extern void efi_memory_uc(u64 addr, unsigned long size);
 
 #ifndef CONFIG_EFI
 /*
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 59c226d..c20d1ce 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -359,18 +359,14 @@
 		return _hypercall4(int, update_va_mapping, va,
 				   new_val.pte, new_val.pte >> 32, flags);
 }
+extern int __must_check xen_event_channel_op_compat(int, void *);
 
 static inline int
 HYPERVISOR_event_channel_op(int cmd, void *arg)
 {
 	int rc = _hypercall2(int, event_channel_op, cmd, arg);
-	if (unlikely(rc == -ENOSYS)) {
-		struct evtchn_op op;
-		op.cmd = cmd;
-		memcpy(&op.u, arg, sizeof(op.u));
-		rc = _hypercall1(int, event_channel_op_compat, &op);
-		memcpy(arg, &op.u, sizeof(op.u));
-	}
+	if (unlikely(rc == -ENOSYS))
+		rc = xen_event_channel_op_compat(cmd, arg);
 	return rc;
 }
 
@@ -386,17 +382,14 @@
 	return _hypercall3(int, console_io, cmd, count, str);
 }
 
+extern int __must_check HYPERVISOR_physdev_op_compat(int, void *);
+
 static inline int
 HYPERVISOR_physdev_op(int cmd, void *arg)
 {
 	int rc = _hypercall2(int, physdev_op, cmd, arg);
-	if (unlikely(rc == -ENOSYS)) {
-		struct physdev_op op;
-		op.cmd = cmd;
-		memcpy(&op.u, arg, sizeof(op.u));
-		rc = _hypercall1(int, physdev_op_compat, &op);
-		memcpy(arg, &op.u, sizeof(op.u));
-	}
+	if (unlikely(rc == -ENOSYS))
+		rc = HYPERVISOR_physdev_op_compat(cmd, arg);
 	return rc;
 }
 
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h
index 66d0fff..125f344 100644
--- a/arch/x86/include/asm/xen/hypervisor.h
+++ b/arch/x86/include/asm/xen/hypervisor.h
@@ -33,7 +33,6 @@
 #ifndef _ASM_X86_XEN_HYPERVISOR_H
 #define _ASM_X86_XEN_HYPERVISOR_H
 
-/* arch/i386/kernel/setup.c */
 extern struct shared_info *HYPERVISOR_shared_info;
 extern struct start_info *xen_start_info;
 
diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h
index 6d2f75a..54d52ff 100644
--- a/arch/x86/include/asm/xen/interface.h
+++ b/arch/x86/include/asm/xen/interface.h
@@ -51,14 +51,14 @@
  * with Xen so that on ARM we can have one ABI that works for 32 and 64
  * bit guests. */
 typedef unsigned long xen_pfn_t;
+#define PRI_xen_pfn "lx"
 typedef unsigned long xen_ulong_t;
+#define PRI_xen_ulong "lx"
 /* Guest handles for primitive C types. */
 __DEFINE_GUEST_HANDLE(uchar, unsigned char);
 __DEFINE_GUEST_HANDLE(uint,  unsigned int);
-__DEFINE_GUEST_HANDLE(ulong, unsigned long);
 DEFINE_GUEST_HANDLE(char);
 DEFINE_GUEST_HANDLE(int);
-DEFINE_GUEST_HANDLE(long);
 DEFINE_GUEST_HANDLE(void);
 DEFINE_GUEST_HANDLE(uint64_t);
 DEFINE_GUEST_HANDLE(uint32_t);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index c265593..1817fa9 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2257,6 +2257,9 @@
 			continue;
 
 		cfg = irq_cfg(irq);
+		if (!cfg)
+			continue;
+
 		raw_spin_lock(&desc->lock);
 
 		/*
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 3373f84..4a3374e 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -208,12 +208,14 @@
 	}
 
 	/*
-	 * Now write a value and read it back to see if it matches,
-	 * this is needed to detect certain hardware emulators (qemu/kvm)
-	 * that don't trap on the MSR access and always return 0s.
+	 * Read the current value, change it and read it back to see if it
+	 * matches, this is needed to detect certain hardware emulators
+	 * (qemu/kvm) that don't trap on the MSR access and always return 0s.
 	 */
-	val = 0xabcdUL;
 	reg = x86_pmu_event_addr(0);
+	if (rdmsrl_safe(reg, &val))
+		goto msr_fail;
+	val ^= 0xffffUL;
 	ret = wrmsrl_safe(reg, val);
 	ret |= rdmsrl_safe(reg, &val_new);
 	if (ret || val != val_new)
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
index 99d96a4..3cf3d97 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
@@ -118,22 +118,24 @@
 {
 	struct pci_dev *pdev = box->pci_dev;
 	int box_ctl = uncore_pci_box_ctl(box);
-	u32 config;
+	u32 config = 0;
 
-	pci_read_config_dword(pdev, box_ctl, &config);
-	config |= SNBEP_PMON_BOX_CTL_FRZ;
-	pci_write_config_dword(pdev, box_ctl, config);
+	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
+		config |= SNBEP_PMON_BOX_CTL_FRZ;
+		pci_write_config_dword(pdev, box_ctl, config);
+	}
 }
 
 static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box)
 {
 	struct pci_dev *pdev = box->pci_dev;
 	int box_ctl = uncore_pci_box_ctl(box);
-	u32 config;
+	u32 config = 0;
 
-	pci_read_config_dword(pdev, box_ctl, &config);
-	config &= ~SNBEP_PMON_BOX_CTL_FRZ;
-	pci_write_config_dword(pdev, box_ctl, config);
+	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
+		config &= ~SNBEP_PMON_BOX_CTL_FRZ;
+		pci_write_config_dword(pdev, box_ctl, config);
+	}
 }
 
 static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
@@ -156,7 +158,7 @@
 {
 	struct pci_dev *pdev = box->pci_dev;
 	struct hw_perf_event *hwc = &event->hw;
-	u64 count;
+	u64 count = 0;
 
 	pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count);
 	pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1);
@@ -603,11 +605,12 @@
 /*
  * build pci bus to socket mapping
  */
-static void snbep_pci2phy_map_init(void)
+static int snbep_pci2phy_map_init(void)
 {
 	struct pci_dev *ubox_dev = NULL;
 	int i, bus, nodeid;
-	u32 config;
+	int err = 0;
+	u32 config = 0;
 
 	while (1) {
 		/* find the UBOX device */
@@ -618,10 +621,14 @@
 			break;
 		bus = ubox_dev->bus->number;
 		/* get the Node ID of the local register */
-		pci_read_config_dword(ubox_dev, 0x40, &config);
+		err = pci_read_config_dword(ubox_dev, 0x40, &config);
+		if (err)
+			break;
 		nodeid = config;
 		/* get the Node ID mapping */
-		pci_read_config_dword(ubox_dev, 0x54, &config);
+		err = pci_read_config_dword(ubox_dev, 0x54, &config);
+		if (err)
+			break;
 		/*
 		 * every three bits in the Node ID mapping register maps
 		 * to a particular node.
@@ -633,7 +640,11 @@
 			}
 		}
 	};
-	return;
+
+	if (ubox_dev)
+		pci_dev_put(ubox_dev);
+
+	return err ? pcibios_err_to_errno(err) : 0;
 }
 /* end of Sandy Bridge-EP uncore support */
 
@@ -1547,7 +1558,6 @@
 {
 	struct hw_perf_event *hwc = &event->hw;
 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	int port;
 
 	/* adjust the main event selector and extra register index */
 	if (reg1->idx % 2) {
@@ -1559,7 +1569,6 @@
 	}
 
 	/* adjust extra register config */
-	port = reg1->idx / 6 + box->pmu->pmu_idx * 4;
 	switch (reg1->idx % 6) {
 	case 2:
 		/* shift the 8~15 bits to the 0~7 bits */
@@ -2578,9 +2587,11 @@
 
 	switch (boot_cpu_data.x86_model) {
 	case 45: /* Sandy Bridge-EP */
+		ret = snbep_pci2phy_map_init();
+		if (ret)
+			return ret;
 		pci_uncores = snbep_pci_uncores;
 		uncore_pci_driver = &snbep_uncore_pci_driver;
-		snbep_pci2phy_map_init();
 		break;
 	default:
 		return 0;
@@ -2926,6 +2937,9 @@
 	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
 		return -ENODEV;
 
+	if (cpu_has_hypervisor)
+		return -ENODEV;
+
 	ret = uncore_pci_init();
 	if (ret)
 		goto fail;
diff --git a/arch/x86/kernel/cpu/perf_event_knc.c b/arch/x86/kernel/cpu/perf_event_knc.c
index 7c46bfd..4b7731b 100644
--- a/arch/x86/kernel/cpu/perf_event_knc.c
+++ b/arch/x86/kernel/cpu/perf_event_knc.c
@@ -3,6 +3,8 @@
 #include <linux/perf_event.h>
 #include <linux/types.h>
 
+#include <asm/hardirq.h>
+
 #include "perf_event.h"
 
 static const u64 knc_perfmon_event_map[] =
@@ -173,30 +175,100 @@
 static inline void
 knc_pmu_disable_event(struct perf_event *event)
 {
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct hw_perf_event *hwc = &event->hw;
 	u64 val;
 
 	val = hwc->config;
-	if (cpuc->enabled)
-		val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+	val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
 
 	(void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
 }
 
 static void knc_pmu_enable_event(struct perf_event *event)
 {
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct hw_perf_event *hwc = &event->hw;
 	u64 val;
 
 	val = hwc->config;
-	if (cpuc->enabled)
-		val |= ARCH_PERFMON_EVENTSEL_ENABLE;
+	val |= ARCH_PERFMON_EVENTSEL_ENABLE;
 
 	(void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
 }
 
+static inline u64 knc_pmu_get_status(void)
+{
+	u64 status;
+
+	rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_STATUS, status);
+
+	return status;
+}
+
+static inline void knc_pmu_ack_status(u64 ack)
+{
+	wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL, ack);
+}
+
+static int knc_pmu_handle_irq(struct pt_regs *regs)
+{
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	int handled = 0;
+	int bit, loops;
+	u64 status;
+
+	cpuc = &__get_cpu_var(cpu_hw_events);
+
+	knc_pmu_disable_all();
+
+	status = knc_pmu_get_status();
+	if (!status) {
+		knc_pmu_enable_all(0);
+		return handled;
+	}
+
+	loops = 0;
+again:
+	knc_pmu_ack_status(status);
+	if (++loops > 100) {
+		WARN_ONCE(1, "perf: irq loop stuck!\n");
+		perf_event_print_debug();
+		goto done;
+	}
+
+	inc_irq_stat(apic_perf_irqs);
+
+	for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
+		struct perf_event *event = cpuc->events[bit];
+
+		handled++;
+
+		if (!test_bit(bit, cpuc->active_mask))
+			continue;
+
+		if (!intel_pmu_save_and_restart(event))
+			continue;
+
+		perf_sample_data_init(&data, 0, event->hw.last_period);
+
+		if (perf_event_overflow(event, &data, regs))
+			x86_pmu_stop(event, 0);
+	}
+
+	/*
+	 * Repeat if there is more work to be done:
+	 */
+	status = knc_pmu_get_status();
+	if (status)
+		goto again;
+
+done:
+	knc_pmu_enable_all(0);
+
+	return handled;
+}
+
+
 PMU_FORMAT_ATTR(event,	"config:0-7"	);
 PMU_FORMAT_ATTR(umask,	"config:8-15"	);
 PMU_FORMAT_ATTR(edge,	"config:18"	);
@@ -214,7 +286,7 @@
 
 static __initconst struct x86_pmu knc_pmu = {
 	.name			= "knc",
-	.handle_irq		= x86_pmu_handle_irq,
+	.handle_irq		= knc_pmu_handle_irq,
 	.disable_all		= knc_pmu_disable_all,
 	.enable_all		= knc_pmu_enable_all,
 	.enable			= knc_pmu_enable_event,
@@ -226,12 +298,11 @@
 	.event_map		= knc_pmu_event_map,
 	.max_events             = ARRAY_SIZE(knc_perfmon_event_map),
 	.apic			= 1,
-	.max_period		= (1ULL << 31) - 1,
+	.max_period		= (1ULL << 39) - 1,
 	.version		= 0,
 	.num_counters		= 2,
-	/* in theory 40 bits, early silicon is buggy though */
-	.cntval_bits		= 32,
-	.cntval_mask		= (1ULL << 32) - 1,
+	.cntval_bits		= 40,
+	.cntval_mask		= (1ULL << 40) - 1,
 	.get_event_constraints	= x86_get_event_constraints,
 	.event_constraints	= knc_event_constraints,
 	.format_attrs		= intel_knc_formats_attr,
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c
index e4dd0f7..7d0270b 100644
--- a/arch/x86/kernel/cpu/perf_event_p6.c
+++ b/arch/x86/kernel/cpu/perf_event_p6.c
@@ -8,13 +8,106 @@
  */
 static const u64 p6_perfmon_event_map[] =
 {
-  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0079,
-  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
-  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0f2e,
-  [PERF_COUNT_HW_CACHE_MISSES]		= 0x012e,
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
-  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
-  [PERF_COUNT_HW_BUS_CYCLES]		= 0x0062,
+  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0079,	/* CPU_CLK_UNHALTED */
+  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,	/* INST_RETIRED     */
+  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0f2e,	/* L2_RQSTS:M:E:S:I */
+  [PERF_COUNT_HW_CACHE_MISSES]		= 0x012e,	/* L2_RQSTS:I       */
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,	/* BR_INST_RETIRED  */
+  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,	/* BR_MISS_PRED_RETIRED */
+  [PERF_COUNT_HW_BUS_CYCLES]		= 0x0062,	/* BUS_DRDY_CLOCKS  */
+  [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a2,	/* RESOURCE_STALLS  */
+
+};
+
+static __initconst u64 p6_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0043,	/* DATA_MEM_REFS       */
+                [ C(RESULT_MISS)   ] = 0x0045,	/* DCU_LINES_IN        */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0x0f29,	/* L2_LD:M:E:S:I       */
+	},
+        [ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+        },
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080,	/* IFU_IFETCH         */
+		[ C(RESULT_MISS)   ] = 0x0f28,	/* L2_IFETCH:M:E:S:I  */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0x0025,	/* L2_M_LINES_INM     */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0043,	/* DATA_MEM_REFS      */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080,	/* IFU_IFETCH         */
+		[ C(RESULT_MISS)   ] = 0x0085,	/* ITLB_MISS          */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4,	/* BR_INST_RETIRED      */
+		[ C(RESULT_MISS)   ] = 0x00c5,	/* BR_MISS_PRED_RETIRED */
+        },
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
 };
 
 static u64 p6_pmu_event_map(int hw_event)
@@ -34,7 +127,7 @@
 {
 	INTEL_EVENT_CONSTRAINT(0xc1, 0x1),	/* FLOPS */
 	INTEL_EVENT_CONSTRAINT(0x10, 0x1),	/* FP_COMP_OPS_EXE */
-	INTEL_EVENT_CONSTRAINT(0x11, 0x1),	/* FP_ASSIST */
+	INTEL_EVENT_CONSTRAINT(0x11, 0x2),	/* FP_ASSIST */
 	INTEL_EVENT_CONSTRAINT(0x12, 0x2),	/* MUL */
 	INTEL_EVENT_CONSTRAINT(0x13, 0x2),	/* DIV */
 	INTEL_EVENT_CONSTRAINT(0x14, 0x1),	/* CYCLES_DIV_BUSY */
@@ -64,25 +157,25 @@
 static inline void
 p6_pmu_disable_event(struct perf_event *event)
 {
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct hw_perf_event *hwc = &event->hw;
 	u64 val = P6_NOP_EVENT;
 
-	if (cpuc->enabled)
-		val |= ARCH_PERFMON_EVENTSEL_ENABLE;
-
 	(void)wrmsrl_safe(hwc->config_base, val);
 }
 
 static void p6_pmu_enable_event(struct perf_event *event)
 {
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct hw_perf_event *hwc = &event->hw;
 	u64 val;
 
 	val = hwc->config;
-	if (cpuc->enabled)
-		val |= ARCH_PERFMON_EVENTSEL_ENABLE;
+
+	/*
+	 * p6 only has a global event enable, set on PerfEvtSel0
+	 * We "disable" events by programming P6_NOP_EVENT
+	 * and we rely on p6_pmu_enable_all() being called
+	 * to actually enable the events.
+	 */
 
 	(void)wrmsrl_safe(hwc->config_base, val);
 }
@@ -158,5 +251,9 @@
 
 	x86_pmu = p6_pmu;
 
+	memcpy(hw_cache_event_ids, p6_hw_cache_event_ids,
+		sizeof(hw_cache_event_ids));
+
+
 	return 0;
 }
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index ed858e9..df06ade 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -1077,6 +1077,9 @@
 		memblock_add(ei->addr, ei->size);
 	}
 
+	/* throw away partial pages */
+	memblock_trim_memory(PAGE_SIZE);
+
 	memblock_dump_all();
 }
 
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index a1193ae..88b725a 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -1035,7 +1035,7 @@
 
 ENTRY(xen_hypervisor_callback)
 	CFI_STARTPROC
-	pushl_cfi $0
+	pushl_cfi $-1 /* orig_ax = -1 => not a system call */
 	SAVE_ALL
 	TRACE_IRQS_OFF
 
@@ -1077,14 +1077,16 @@
 2:	mov 8(%esp),%es
 3:	mov 12(%esp),%fs
 4:	mov 16(%esp),%gs
+	/* EAX == 0 => Category 1 (Bad segment)
+	   EAX != 0 => Category 2 (Bad IRET) */
 	testl %eax,%eax
 	popl_cfi %eax
 	lea 16(%esp),%esp
 	CFI_ADJUST_CFA_OFFSET -16
 	jz 5f
 	addl $16,%esp
-	jmp iret_exc		# EAX != 0 => Category 2 (Bad IRET)
-5:	pushl_cfi $0		# EAX == 0 => Category 1 (Bad segment)
+	jmp iret_exc
+5:	pushl_cfi $-1 /* orig_ax = -1 => not a system call */
 	SAVE_ALL
 	jmp ret_from_exception
 	CFI_ENDPROC
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 0c58952..b51b2c7 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1435,7 +1435,7 @@
 	CFI_RESTORE r11
 	addq $0x30,%rsp
 	CFI_ADJUST_CFA_OFFSET -0x30
-	pushq_cfi $0
+	pushq_cfi $-1 /* orig_ax = -1 => not a system call */
 	SAVE_ALL
 	jmp error_exit
 	CFI_ENDPROC
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index b3e5e51..4180a87 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -247,7 +247,10 @@
 		break;
 	case KVM_PV_REASON_PAGE_NOT_PRESENT:
 		/* page is swapped out by the host. */
+		rcu_irq_enter();
+		exit_idle();
 		kvm_async_pf_task_wait((u32)read_cr2());
+		rcu_irq_exit();
 		break;
 	case KVM_PV_REASON_PAGE_READY:
 		rcu_irq_enter();
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 468e98d..ca45696 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -921,18 +921,19 @@
 #ifdef CONFIG_X86_64
 	if (max_pfn > max_low_pfn) {
 		int i;
-		for (i = 0; i < e820.nr_map; i++) {
-			struct e820entry *ei = &e820.map[i];
+		unsigned long start, end;
+		unsigned long start_pfn, end_pfn;
 
-			if (ei->addr + ei->size <= 1UL << 32)
+		for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn,
+							 NULL) {
+
+			end = PFN_PHYS(end_pfn);
+			if (end <= (1UL<<32))
 				continue;
 
-			if (ei->type == E820_RESERVED)
-				continue;
-
+			start = PFN_PHYS(start_pfn);
 			max_pfn_mapped = init_memory_mapping(
-				ei->addr < 1UL << 32 ? 1UL << 32 : ei->addr,
-				ei->addr + ei->size);
+						max((1UL<<32), start), end);
 		}
 
 		/* can we preseve max_low_pfn ?*/
@@ -1048,6 +1049,18 @@
 	arch_init_ideal_nops();
 
 	register_refined_jiffies(CLOCK_TICK_RATE);
+
+#ifdef CONFIG_EFI
+	/* Once setup is done above, disable efi_enabled on mismatched
+	 * firmware/kernel archtectures since there is no support for
+	 * runtime services.
+	 */
+	if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) {
+		pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n");
+		efi_unmap_memmap();
+		efi_enabled = 0;
+	}
+#endif
 }
 
 #ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 29ad351..70b27ee 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -824,10 +824,8 @@
 		mce_notify_process();
 #endif /* CONFIG_X86_64 && CONFIG_X86_MCE */
 
-	if (thread_info_flags & _TIF_UPROBE) {
-		clear_thread_flag(TIF_UPROBE);
+	if (thread_info_flags & _TIF_UPROBE)
 		uprobe_notify_resume(regs);
-	}
 
 	/* deal with pending signal delivery */
 	if (thread_info_flags & _TIF_SIGPENDING)
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 9538f00..aafa555 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -651,31 +651,19 @@
 
 /*
  * Skip these instructions as per the currently known x86 ISA.
- * 0x66* { 0x90 | 0x0f 0x1f | 0x0f 0x19 | 0x87 0xc0 }
+ * rep=0x66*; nop=0x90
  */
 static bool __skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
 {
 	int i;
 
 	for (i = 0; i < MAX_UINSN_BYTES; i++) {
-		if ((auprobe->insn[i] == 0x66))
+		if (auprobe->insn[i] == 0x66)
 			continue;
 
 		if (auprobe->insn[i] == 0x90)
 			return true;
 
-		if (i == (MAX_UINSN_BYTES - 1))
-			break;
-
-		if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x1f))
-			return true;
-
-		if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x19))
-			return true;
-
-		if ((auprobe->insn[i] == 0x87) && (auprobe->insn[i+1] == 0xc0))
-			return true;
-
 		break;
 	}
 	return false;
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index a10e460..58fc514 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -24,6 +24,9 @@
 {
 	struct kvm_cpuid_entry2 *best;
 
+	if (!static_cpu_has(X86_FEATURE_XSAVE))
+		return 0;
+
 	best = kvm_find_cpuid_entry(vcpu, 1, 0);
 	return best && (best->ecx & bit(X86_FEATURE_XSAVE));
 }
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index c6e6b72..43e9fad 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1311,7 +1311,7 @@
 	vcpu->arch.apic_base = value;
 	if (apic_x2apic_mode(apic)) {
 		u32 id = kvm_apic_id(apic);
-		u32 ldr = ((id & ~0xf) << 16) | (1 << (id & 0xf));
+		u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf));
 		kvm_apic_set_ldr(apic, ldr);
 	}
 	apic->base_address = apic->vcpu->arch.apic_base &
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index d289fee..6f85fe0 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -2497,8 +2497,7 @@
 		}
 	}
 
-	if (!is_error_pfn(pfn))
-		kvm_release_pfn_clean(pfn);
+	kvm_release_pfn_clean(pfn);
 }
 
 static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ad6b1dd..f858159 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -6549,19 +6549,22 @@
 		}
 	}
 
-	exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
 	/* Exposing INVPCID only when PCID is exposed */
 	best = kvm_find_cpuid_entry(vcpu, 0x7, 0);
 	if (vmx_invpcid_supported() &&
 	    best && (best->ebx & bit(X86_FEATURE_INVPCID)) &&
 	    guest_cpuid_has_pcid(vcpu)) {
+		exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
 		exec_control |= SECONDARY_EXEC_ENABLE_INVPCID;
 		vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
 			     exec_control);
 	} else {
-		exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
-		vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
-			     exec_control);
+		if (cpu_has_secondary_exec_ctrls()) {
+			exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
+			exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
+			vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
+				     exec_control);
+		}
 		if (best)
 			best->ebx &= ~bit(X86_FEATURE_INVPCID);
 	}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1eefebe..4f76417 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3779,7 +3779,7 @@
 {
 	struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0];
 
-	memcpy(vcpu->run->mmio.data, frag->data, frag->len);
+	memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len));
 	return X86EMUL_CONTINUE;
 }
 
@@ -3832,18 +3832,11 @@
 	bytes -= handled;
 	val += handled;
 
-	while (bytes) {
-		unsigned now = min(bytes, 8U);
-
-		frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++];
-		frag->gpa = gpa;
-		frag->data = val;
-		frag->len = now;
-
-		gpa += now;
-		val += now;
-		bytes -= now;
-	}
+	WARN_ON(vcpu->mmio_nr_fragments >= KVM_MAX_MMIO_FRAGMENTS);
+	frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++];
+	frag->gpa = gpa;
+	frag->data = val;
+	frag->len = bytes;
 	return X86EMUL_CONTINUE;
 }
 
@@ -3890,7 +3883,7 @@
 	vcpu->mmio_needed = 1;
 	vcpu->mmio_cur_fragment = 0;
 
-	vcpu->run->mmio.len = vcpu->mmio_fragments[0].len;
+	vcpu->run->mmio.len = min(8u, vcpu->mmio_fragments[0].len);
 	vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write;
 	vcpu->run->exit_reason = KVM_EXIT_MMIO;
 	vcpu->run->mmio.phys_addr = gpa;
@@ -5522,28 +5515,44 @@
  *
  * read:
  *   for each fragment
- *     write gpa, len
- *     exit
- *     copy data
+ *     for each mmio piece in the fragment
+ *       write gpa, len
+ *       exit
+ *       copy data
  *   execute insn
  *
  * write:
  *   for each fragment
- *      write gpa, len
- *      copy data
- *      exit
+ *     for each mmio piece in the fragment
+ *       write gpa, len
+ *       copy data
+ *       exit
  */
 static int complete_emulated_mmio(struct kvm_vcpu *vcpu)
 {
 	struct kvm_run *run = vcpu->run;
 	struct kvm_mmio_fragment *frag;
+	unsigned len;
 
 	BUG_ON(!vcpu->mmio_needed);
 
 	/* Complete previous fragment */
-	frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++];
+	frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment];
+	len = min(8u, frag->len);
 	if (!vcpu->mmio_is_write)
-		memcpy(frag->data, run->mmio.data, frag->len);
+		memcpy(frag->data, run->mmio.data, len);
+
+	if (frag->len <= 8) {
+		/* Switch to the next fragment. */
+		frag++;
+		vcpu->mmio_cur_fragment++;
+	} else {
+		/* Go forward to the next mmio piece. */
+		frag->data += len;
+		frag->gpa += len;
+		frag->len -= len;
+	}
+
 	if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) {
 		vcpu->mmio_needed = 0;
 		if (vcpu->mmio_is_write)
@@ -5551,13 +5560,12 @@
 		vcpu->mmio_read_completed = 1;
 		return complete_emulated_io(vcpu);
 	}
-	/* Initiate next fragment */
-	++frag;
+
 	run->exit_reason = KVM_EXIT_MMIO;
 	run->mmio.phys_addr = frag->gpa;
 	if (vcpu->mmio_is_write)
-		memcpy(run->mmio.data, frag->data, frag->len);
-	run->mmio.len = frag->len;
+		memcpy(run->mmio.data, frag->data, min(8u, frag->len));
+	run->mmio.len = min(8u, frag->len);
 	run->mmio.is_write = vcpu->mmio_is_write;
 	vcpu->arch.complete_userspace_io = complete_emulated_mmio;
 	return 0;
@@ -5773,6 +5781,9 @@
 	int pending_vec, max_bits, idx;
 	struct desc_ptr dt;
 
+	if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE))
+		return -EINVAL;
+
 	dt.size = sregs->idt.limit;
 	dt.address = sregs->idt.base;
 	kvm_x86_ops->set_idt(vcpu, &dt);
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index ab1f6a9..d7aea41 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -35,40 +35,44 @@
 	unsigned page_size_mask;
 };
 
-static void __init find_early_table_space(struct map_range *mr, unsigned long end,
-					  int use_pse, int use_gbpages)
+/*
+ * First calculate space needed for kernel direct mapping page tables to cover
+ * mr[0].start to mr[nr_range - 1].end, while accounting for possible 2M and 1GB
+ * pages. Then find enough contiguous space for those page tables.
+ */
+static void __init find_early_table_space(struct map_range *mr, int nr_range)
 {
-	unsigned long puds, pmds, ptes, tables, start = 0, good_end = end;
+	int i;
+	unsigned long puds = 0, pmds = 0, ptes = 0, tables;
+	unsigned long start = 0, good_end;
 	phys_addr_t base;
 
-	puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
-	tables = roundup(puds * sizeof(pud_t), PAGE_SIZE);
+	for (i = 0; i < nr_range; i++) {
+		unsigned long range, extra;
 
-	if (use_gbpages) {
-		unsigned long extra;
+		range = mr[i].end - mr[i].start;
+		puds += (range + PUD_SIZE - 1) >> PUD_SHIFT;
 
-		extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT);
-		pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT;
-	} else
-		pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
+		if (mr[i].page_size_mask & (1 << PG_LEVEL_1G)) {
+			extra = range - ((range >> PUD_SHIFT) << PUD_SHIFT);
+			pmds += (extra + PMD_SIZE - 1) >> PMD_SHIFT;
+		} else {
+			pmds += (range + PMD_SIZE - 1) >> PMD_SHIFT;
+		}
 
-	tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE);
-
-	if (use_pse) {
-		unsigned long extra;
-
-		extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT);
+		if (mr[i].page_size_mask & (1 << PG_LEVEL_2M)) {
+			extra = range - ((range >> PMD_SHIFT) << PMD_SHIFT);
 #ifdef CONFIG_X86_32
-		extra += PMD_SIZE;
+			extra += PMD_SIZE;
 #endif
-		/* The first 2/4M doesn't use large pages. */
-		if (mr->start < PMD_SIZE)
-			extra += mr->end - mr->start;
+			ptes += (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
+		} else {
+			ptes += (range + PAGE_SIZE - 1) >> PAGE_SHIFT;
+		}
+	}
 
-		ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	} else
-		ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
+	tables = roundup(puds * sizeof(pud_t), PAGE_SIZE);
+	tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE);
 	tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE);
 
 #ifdef CONFIG_X86_32
@@ -86,7 +90,7 @@
 	pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT);
 
 	printk(KERN_DEBUG "kernel direct mapping tables up to %#lx @ [mem %#010lx-%#010lx]\n",
-		end - 1, pgt_buf_start << PAGE_SHIFT,
+		mr[nr_range - 1].end - 1, pgt_buf_start << PAGE_SHIFT,
 		(pgt_buf_top << PAGE_SHIFT) - 1);
 }
 
@@ -267,7 +271,7 @@
 	 * nodes are discovered.
 	 */
 	if (!after_bootmem)
-		find_early_table_space(&mr[0], end, use_pse, use_gbpages);
+		find_early_table_space(mr, nr_range);
 
 	for (i = 0; i < nr_range; i++)
 		ret = kernel_physical_mapping_init(mr[i].start, mr[i].end,
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 2b6b4a3..3baff25 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -386,7 +386,8 @@
 		 * these mappings are more intelligent.
 		 */
 		if (pte_val(*pte)) {
-			pages++;
+			if (!after_bootmem)
+				pages++;
 			continue;
 		}
 
@@ -451,6 +452,8 @@
 			 * attributes.
 			 */
 			if (page_size_mask & (1 << PG_LEVEL_2M)) {
+				if (!after_bootmem)
+					pages++;
 				last_map_addr = next;
 				continue;
 			}
@@ -526,6 +529,8 @@
 			 * attributes.
 			 */
 			if (page_size_mask & (1 << PG_LEVEL_1G)) {
+				if (!after_bootmem)
+					pages++;
 				last_map_addr = next;
 				continue;
 			}
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 26b8a85..48768df 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -55,7 +55,7 @@
 	val |= counter_config->extra;
 	event &= model->event_mask ? model->event_mask : 0xFF;
 	val |= event & 0xFF;
-	val |= (event & 0x0F00) << 24;
+	val |= (u64)(event & 0x0F00) << 24;
 
 	return val;
 }
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index aded2a9..ad443914 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -70,11 +70,15 @@
 struct efi_memory_map memmap;
 
 bool efi_64bit;
-static bool efi_native;
 
 static struct efi efi_phys __initdata;
 static efi_system_table_t efi_systab __initdata;
 
+static inline bool efi_is_native(void)
+{
+	return IS_ENABLED(CONFIG_X86_64) == efi_64bit;
+}
+
 static int __init setup_noefi(char *arg)
 {
 	efi_enabled = 0;
@@ -420,7 +424,7 @@
 	}
 }
 
-static void __init efi_unmap_memmap(void)
+void __init efi_unmap_memmap(void)
 {
 	if (memmap.map) {
 		early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
@@ -432,7 +436,7 @@
 {
 	void *p;
 
-	if (!efi_native)
+	if (!efi_is_native())
 		return;
 
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
@@ -684,12 +688,10 @@
 		return;
 	}
 	efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab;
-	efi_native = !efi_64bit;
 #else
 	efi_phys.systab = (efi_system_table_t *)
 			  (boot_params.efi_info.efi_systab |
 			  ((__u64)boot_params.efi_info.efi_systab_hi<<32));
-	efi_native = efi_64bit;
 #endif
 
 	if (efi_systab_init(efi_phys.systab)) {
@@ -723,7 +725,7 @@
 	 * that doesn't match the kernel 32/64-bit mode.
 	 */
 
-	if (!efi_native)
+	if (!efi_is_native())
 		pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n");
 	else if (efi_runtime_init()) {
 		efi_enabled = 0;
@@ -735,7 +737,7 @@
 		return;
 	}
 #ifdef CONFIG_X86_32
-	if (efi_native) {
+	if (efi_is_native()) {
 		x86_platform.get_wallclock = efi_get_time;
 		x86_platform.set_wallclock = efi_set_rtc_mmss;
 	}
@@ -810,6 +812,16 @@
 	return NULL;
 }
 
+void efi_memory_uc(u64 addr, unsigned long size)
+{
+	unsigned long page_shift = 1UL << EFI_PAGE_SHIFT;
+	u64 npages;
+
+	npages = round_up(size, page_shift) / page_shift;
+	memrange_efi_to_native(&addr, &npages);
+	set_memory_uc(addr, npages);
+}
+
 /*
  * This function will switch the EFI runtime services to virtual mode.
  * Essentially, look through the EFI memmap and map every region that
@@ -823,7 +835,7 @@
 	efi_memory_desc_t *md, *prev_md = NULL;
 	efi_status_t status;
 	unsigned long size;
-	u64 end, systab, addr, npages, end_pfn;
+	u64 end, systab, end_pfn;
 	void *p, *va, *new_memmap = NULL;
 	int count = 0;
 
@@ -834,7 +846,7 @@
 	 * non-native EFI
 	 */
 
-	if (!efi_native) {
+	if (!efi_is_native()) {
 		efi_unmap_memmap();
 		return;
 	}
@@ -879,10 +891,14 @@
 		end_pfn = PFN_UP(end);
 		if (end_pfn <= max_low_pfn_mapped
 		    || (end_pfn > (1UL << (32 - PAGE_SHIFT))
-			&& end_pfn <= max_pfn_mapped))
+			&& end_pfn <= max_pfn_mapped)) {
 			va = __va(md->phys_addr);
-		else
-			va = efi_ioremap(md->phys_addr, size, md->type);
+
+			if (!(md->attribute & EFI_MEMORY_WB))
+				efi_memory_uc((u64)(unsigned long)va, size);
+		} else
+			va = efi_ioremap(md->phys_addr, size,
+					 md->type, md->attribute);
 
 		md->virt_addr = (u64) (unsigned long) va;
 
@@ -892,13 +908,6 @@
 			continue;
 		}
 
-		if (!(md->attribute & EFI_MEMORY_WB)) {
-			addr = md->virt_addr;
-			npages = md->num_pages;
-			memrange_efi_to_native(&addr, &npages);
-			set_memory_uc(addr, npages);
-		}
-
 		systab = (u64) (unsigned long) efi_phys.systab;
 		if (md->phys_addr <= systab && systab < end) {
 			systab += md->virt_addr - md->phys_addr;
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index ac3aa54..95fd505 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -82,7 +82,7 @@
 }
 
 void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
-				 u32 type)
+				 u32 type, u64 attribute)
 {
 	unsigned long last_map_pfn;
 
@@ -92,8 +92,11 @@
 	last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size);
 	if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) {
 		unsigned long top = last_map_pfn << PAGE_SHIFT;
-		efi_ioremap(top, size - (top - phys_addr), type);
+		efi_ioremap(top, size - (top - phys_addr), type, attribute);
 	}
 
+	if (!(attribute & EFI_MEMORY_WB))
+		efi_memory_uc((u64)(unsigned long)__va(phys_addr), size);
+
 	return (void __iomem *)__va(phys_addr);
 }
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index e3497f2..586d838 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -81,8 +81,6 @@
 #include "smp.h"
 #include "multicalls.h"
 
-#include <xen/events.h>
-
 EXPORT_SYMBOL_GPL(hypercall_page);
 
 DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 6226c99..dcf5f2d 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1288,6 +1288,25 @@
 	return this_cpu_read(xen_vcpu_info.arch.cr2);
 }
 
+void xen_flush_tlb_all(void)
+{
+	struct mmuext_op *op;
+	struct multicall_space mcs;
+
+	trace_xen_mmu_flush_tlb_all(0);
+
+	preempt_disable();
+
+	mcs = xen_mc_entry(sizeof(*op));
+
+	op = mcs.args;
+	op->cmd = MMUEXT_TLB_FLUSH_ALL;
+	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
+
+	xen_mc_issue(PARAVIRT_LAZY_MMU);
+
+	preempt_enable();
+}
 static void xen_flush_tlb(void)
 {
 	struct mmuext_op *op;
@@ -2518,7 +2537,7 @@
 	err = 0;
 out:
 
-	flush_tlb_all();
+	xen_flush_tlb_all();
 
 	return err;
 }
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index cdcb48a..0d1f36a 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -13,6 +13,8 @@
 	select GENERIC_CPU_DEVICES
 	select MODULES_USE_ELF_RELA
 	select GENERIC_PCI_IOMAP
+	select GENERIC_KERNEL_THREAD
+	select GENERIC_KERNEL_EXECVE
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	help
 	  Xtensa processors are 32-bit RISC machines designed by Tensilica
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index e6be5b9..700c2e6 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -62,6 +62,10 @@
 static inline void iounmap(volatile void __iomem *addr)
 {
 }
+
+#define virt_to_bus     virt_to_phys
+#define bus_to_virt     phys_to_virt
+
 #endif /* CONFIG_MMU */
 
 /*
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h
index 5c371d8..2d630e7 100644
--- a/arch/xtensa/include/asm/processor.h
+++ b/arch/xtensa/include/asm/processor.h
@@ -152,6 +152,7 @@
 
 /* Clearing a0 terminates the backtrace. */
 #define start_thread(regs, new_pc, new_sp) \
+	memset(regs, 0, sizeof(*regs)); \
 	regs->pc = new_pc; \
 	regs->ps = USER_PS_VALUE; \
 	regs->areg[1] = new_sp; \
@@ -168,9 +169,6 @@
 /* Free all resources held by a thread. */
 #define release_thread(thread) do { } while(0)
 
-/* Create a kernel thread without removing it from tasklists */
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
 /* Copy and release all segment info associated with a VM */
 #define copy_segments(p, mm)	do { } while(0)
 #define release_segments(mm)	do { } while(0)
diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h
index c1dacca..124aeee 100644
--- a/arch/xtensa/include/asm/syscall.h
+++ b/arch/xtensa/include/asm/syscall.h
@@ -10,7 +10,7 @@
 
 struct pt_regs;
 struct sigaction;
-asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*);
+asmlinkage long sys_execve(char*, char**, char**, struct pt_regs*);
 asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*);
 asmlinkage long xtensa_ptrace(long, long, long, long);
 asmlinkage long xtensa_sigreturn(struct pt_regs*);
diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h
index 9ef1c31..f4e6eaa 100644
--- a/arch/xtensa/include/asm/unistd.h
+++ b/arch/xtensa/include/asm/unistd.h
@@ -1,16 +1,9 @@
-/*
- * include/asm-xtensa/unistd.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
- */
+#ifndef _XTENSA_UNISTD_H
+#define _XTENSA_UNISTD_H
 
+#define __ARCH_WANT_SYS_EXECVE
 #include <uapi/asm/unistd.h>
 
-
 /*
  * "Conditional" syscalls
  *
@@ -37,3 +30,5 @@
 #define __IGNORE_mmap				/* use mmap2 */
 #define __IGNORE_vfork				/* use clone */
 #define __IGNORE_fadvise64			/* use fadvise64_64 */
+
+#endif /* _XTENSA_UNISTD_H */
diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h
index 479abae..9f36d0e 100644
--- a/arch/xtensa/include/uapi/asm/unistd.h
+++ b/arch/xtensa/include/uapi/asm/unistd.h
@@ -1,14 +1,4 @@
-/*
- * include/asm-xtensa/unistd.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 - 2012 Tensilica Inc.
- */
-
-#ifndef _UAPI_XTENSA_UNISTD_H
+#if !defined(_UAPI_XTENSA_UNISTD_H) || defined(__SYSCALL)
 #define _UAPI_XTENSA_UNISTD_H
 
 #ifndef __SYSCALL
@@ -272,7 +262,7 @@
 #define __NR_clone 				116
 __SYSCALL(116, xtensa_clone, 5)
 #define __NR_execve 				117
-__SYSCALL(117, xtensa_execve, 3)
+__SYSCALL(117, sys_execve, 3)
 #define __NR_exit 				118
 __SYSCALL(118, sys_exit, 1)
 #define __NR_exit_group 			119
@@ -759,4 +749,6 @@
 
 #define SYS_XTENSA_COUNT                  5     /* count */
 
+#undef __SYSCALL
+
 #endif /* _UAPI_XTENSA_UNISTD_H */
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 18453067..90bfc1d 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -1833,50 +1833,6 @@
 
 
 /*
- * Create a kernel thread
- *
- * int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
- * a2                    a2                 a3             a4
- */
-
-ENTRY(kernel_thread)
-	entry	a1, 16
-
-	mov	a5, a2			# preserve fn over syscall
-	mov	a7, a3			# preserve args over syscall
-
-	movi	a3, _CLONE_VM | _CLONE_UNTRACED
-	movi	a2, __NR_clone
-	or	a6, a4, a3		# arg0: flags
-	mov	a3, a1			# arg1: sp
-	syscall
-
-	beq	a3, a1, 1f		# branch if parent
-	mov	a6, a7			# args
-	callx4	a5			# fn(args)
-
-	movi	a2, __NR_exit
-	syscall				# return value of fn(args) still in a6
-
-1:	retw
-
-/*
- * Do a system call from kernel instead of calling sys_execve, so we end up
- * with proper pt_regs.
- *
- * int kernel_execve(const char *fname, char *const argv[], charg *const envp[])
- * a2                        a2               a3                  a4
- */
-
-ENTRY(kernel_execve)
-	entry	a1, 16
-	mov	a6, a2			# arg0 is in a6
-	movi	a2, __NR_execve
-	syscall
-
-	retw
-
-/*
  * Task switch.
  *
  * struct task*  _switch_to (struct task* prev, struct task* next)
@@ -1958,3 +1914,16 @@
 
 	j	common_exception_return
 
+/*
+ * Kernel thread creation helper
+ * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg
+ *           left from _switch_to: a6 = prev
+ */
+ENTRY(ret_from_kernel_thread)
+
+	call4	schedule_tail
+	mov	a6, a3
+	callx4	a2
+	j	common_exception_return
+
+ENDPROC(ret_from_kernel_thread)
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 1908f66..09ae7bf 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -45,6 +45,7 @@
 #include <asm/regs.h>
 
 extern void ret_from_fork(void);
+extern void ret_from_kernel_thread(void);
 
 struct task_struct *current_set[NR_CPUS] = {&init_task, };
 
@@ -158,18 +159,30 @@
 /*
  * Copy thread.
  *
+ * There are two modes in which this function is called:
+ * 1) Userspace thread creation,
+ *    regs != NULL, usp_thread_fn is userspace stack pointer.
+ *    It is expected to copy parent regs (in case CLONE_VM is not set
+ *    in the clone_flags) and set up passed usp in the childregs.
+ * 2) Kernel thread creation,
+ *    regs == NULL, usp_thread_fn is the function to run in the new thread
+ *    and thread_fn_arg is its parameter.
+ *    childregs are not used for the kernel threads.
+ *
  * The stack layout for the new thread looks like this:
  *
- *	+------------------------+ <- sp in childregs (= tos)
+ *	+------------------------+
  *	|       childregs        |
  *	+------------------------+ <- thread.sp = sp in dummy-frame
  *	|      dummy-frame       |    (saved in dummy-frame spill-area)
  *	+------------------------+
  *
- * We create a dummy frame to return to ret_from_fork:
- *   a0 points to ret_from_fork (simulating a call4)
+ * We create a dummy frame to return to either ret_from_fork or
+ *   ret_from_kernel_thread:
+ *   a0 points to ret_from_fork/ret_from_kernel_thread (simulating a call4)
  *   sp points to itself (thread.sp)
- *   a2, a3 are unused.
+ *   a2, a3 are unused for userspace threads,
+ *   a2 points to thread_fn, a3 holds thread_fn arg for kernel threads.
  *
  * Note: This is a pristine frame, so we don't need any spill region on top of
  *       childregs.
@@ -185,43 +198,63 @@
  * involved.  Much simpler to just not copy those live frames across.
  */
 
-int copy_thread(unsigned long clone_flags, unsigned long usp,
-		unsigned long unused,
-                struct task_struct * p, struct pt_regs * regs)
+int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
+		unsigned long thread_fn_arg,
+		struct task_struct *p, struct pt_regs *unused)
 {
-	struct pt_regs *childregs;
-	unsigned long tos;
-	int user_mode = user_mode(regs);
+	struct pt_regs *childregs = task_pt_regs(p);
 
 #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
 	struct thread_info *ti;
 #endif
 
-	/* Set up new TSS. */
-	tos = (unsigned long)task_stack_page(p) + THREAD_SIZE;
-	if (user_mode)
-		childregs = (struct pt_regs*)(tos - PT_USER_SIZE);
-	else
-		childregs = (struct pt_regs*)tos - 1;
-
-	/* This does not copy all the regs.  In a bout of brilliance or madness,
-	   ARs beyond a0-a15 exist past the end of the struct. */
-	*childregs = *regs;
-
 	/* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */
 	*((int*)childregs - 3) = (unsigned long)childregs;
 	*((int*)childregs - 4) = 0;
 
-	childregs->areg[2] = 0;
-	p->set_child_tid = p->clear_child_tid = NULL;
-	p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1);
 	p->thread.sp = (unsigned long)childregs;
 
-	if (user_mode(regs)) {
+	if (!(p->flags & PF_KTHREAD)) {
+		struct pt_regs *regs = current_pt_regs();
+		unsigned long usp = usp_thread_fn ?
+			usp_thread_fn : regs->areg[1];
 
+		p->thread.ra = MAKE_RA_FOR_CALL(
+				(unsigned long)ret_from_fork, 0x1);
+
+		/* This does not copy all the regs.
+		 * In a bout of brilliance or madness,
+		 * ARs beyond a0-a15 exist past the end of the struct.
+		 */
+		*childregs = *regs;
 		childregs->areg[1] = usp;
+		childregs->areg[2] = 0;
+
+		/* When sharing memory with the parent thread, the child
+		   usually starts on a pristine stack, so we have to reset
+		   windowbase, windowstart and wmask.
+		   (Note that such a new thread is required to always create
+		   an initial call4 frame)
+		   The exception is vfork, where the new thread continues to
+		   run on the parent's stack until it calls execve. This could
+		   be a call8 or call12, which requires a legal stack frame
+		   of the previous caller for the overflow handlers to work.
+		   (Note that it's always legal to overflow live registers).
+		   In this case, ensure to spill at least the stack pointer
+		   of that frame. */
+
 		if (clone_flags & CLONE_VM) {
-			childregs->wmask = 1;	/* can't share live windows */
+			/* check that caller window is live and same stack */
+			int len = childregs->wmask & ~0xf;
+			if (regs->areg[1] == usp && len != 0) {
+				int callinc = (regs->areg[0] >> 30) & 3;
+				int caller_ars = XCHAL_NUM_AREGS - callinc * 4;
+				put_user(regs->areg[caller_ars+1],
+					 (unsigned __user*)(usp - 12));
+			}
+			childregs->wmask = 1;
+			childregs->windowstart = 1;
+			childregs->windowbase = 0;
 		} else {
 			int len = childregs->wmask & ~0xf;
 			memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4],
@@ -230,11 +263,19 @@
 // FIXME: we need to set THREADPTR in thread_info...
 		if (clone_flags & CLONE_SETTLS)
 			childregs->areg[2] = childregs->areg[6];
-
 	} else {
-		/* In kernel space, we start a new thread with a new stack. */
-		childregs->wmask = 1;
-		childregs->areg[1] = tos;
+		p->thread.ra = MAKE_RA_FOR_CALL(
+				(unsigned long)ret_from_kernel_thread, 1);
+
+		/* pass parameters to ret_from_kernel_thread:
+		 * a2 = thread_fn, a3 = thread_fn arg
+		 */
+		*((int *)childregs - 1) = thread_fn_arg;
+		*((int *)childregs - 2) = usp_thread_fn;
+
+		/* Childregs are only used when we're going to userspace
+		 * in which case start_thread will set them up.
+		 */
 	}
 
 #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
@@ -330,32 +371,5 @@
                   void __user *child_tid, long a5,
                   struct pt_regs *regs)
 {
-        if (!newsp)
-                newsp = regs->areg[1];
         return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
 }
-
-/*
- * xtensa_execve() executes a new program.
- */
-
-asmlinkage
-long xtensa_execve(const char __user *name,
-		   const char __user *const __user *argv,
-                   const char __user *const __user *envp,
-                   long a3, long a4, long a5,
-                   struct pt_regs *regs)
-{
-	long error;
-	struct filename *filename;
-
-	filename = getname(name);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		goto out;
-	error = do_execve(filename->name, argv, envp, regs);
-	putname(filename);
-out:
-	return error;
-}
-
diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c
index a5c01e7..5702065 100644
--- a/arch/xtensa/kernel/syscall.c
+++ b/arch/xtensa/kernel/syscall.c
@@ -32,10 +32,8 @@
 syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= {
 	[0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall,
 
-#undef __SYSCALL
 #define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol,
-#undef  __KERNEL_SYSCALLS__
-#include <asm/unistd.h>
+#include <uapi/asm/unistd.h>
 };
 
 asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg)
@@ -49,7 +47,8 @@
 	return (long)ret;
 }
 
-asmlinkage long xtensa_fadvise64_64(int fd, int advice, unsigned long long offset, unsigned long long len)
+asmlinkage long xtensa_fadvise64_64(int fd, int advice,
+		unsigned long long offset, unsigned long long len)
 {
 	return sys_fadvise64_64(fd, offset, len, advice);
 }
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index a8b9f1f..afe058b 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -43,7 +43,6 @@
 EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(copy_page);
 
-EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(empty_zero_page);
 
 /*
diff --git a/block/Kconfig b/block/Kconfig
index 09acf1b..a7e40a7 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -89,7 +89,7 @@
 
 config BLK_DEV_THROTTLING
 	bool "Block layer bio throttling support"
-	depends on BLK_CGROUP=y && EXPERIMENTAL
+	depends on BLK_CGROUP=y
 	default n
 	---help---
 	Block layer bio throttling support. It can be used to limit
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index cafcd74..d0b7703 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -285,6 +285,13 @@
 		blkg_destroy(blkg);
 		spin_unlock(&blkcg->lock);
 	}
+
+	/*
+	 * root blkg is destroyed.  Just clear the pointer since
+	 * root_rl does not take reference on root blkg.
+	 */
+	q->root_blkg = NULL;
+	q->root_rl.blkg = NULL;
 }
 
 static void blkg_rcu_free(struct rcu_head *rcu_head)
@@ -326,6 +333,9 @@
 	 */
 	if (rl == &q->root_rl) {
 		ent = &q->blkg_list;
+		/* There are no more block groups, hence no request lists */
+		if (list_empty(ent))
+			return NULL;
 	} else {
 		blkg = container_of(rl, struct blkcg_gq, rl);
 		ent = &blkg->q_node;
diff --git a/block/blk-core.c b/block/blk-core.c
index a33870b..3c95c4d 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -2868,7 +2868,8 @@
 	struct request *rqa = container_of(a, struct request, queuelist);
 	struct request *rqb = container_of(b, struct request, queuelist);
 
-	return !(rqa->q <= rqb->q);
+	return !(rqa->q < rqb->q ||
+		(rqa->q == rqb->q && blk_rq_pos(rqa) < blk_rq_pos(rqb)));
 }
 
 /*
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index 671d4d6..7bdd61b 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -137,13 +137,18 @@
 	struct crypto_async_request *req, *backlog;
 
 	cpu_queue = container_of(work, struct cryptd_cpu_queue, work);
-	/* Only handle one request at a time to avoid hogging crypto
-	 * workqueue. preempt_disable/enable is used to prevent
-	 * being preempted by cryptd_enqueue_request() */
+	/*
+	 * Only handle one request at a time to avoid hogging crypto workqueue.
+	 * preempt_disable/enable is used to prevent being preempted by
+	 * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent
+	 * cryptd_enqueue_request() being accessed from software interrupts.
+	 */
+	local_bh_disable();
 	preempt_disable();
 	backlog = crypto_get_backlog(&cpu_queue->queue);
 	req = crypto_dequeue_request(&cpu_queue->queue);
 	preempt_enable();
+	local_bh_enable();
 
 	if (!req)
 		return;
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index d1a2d74..0837308 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -159,6 +159,7 @@
 	if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) {
 		retval = -ENOSPC;
 		mutex_unlock(&acpi_dev->physical_node_lock);
+		kfree(physical_node);
 		goto err;
 	}
 
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index e78c2a5..bd4e5dc 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -409,6 +409,7 @@
 		acpi_bus_generate_proc_event(device, event, 0);
 		acpi_bus_generate_netlink_event(device->pnp.device_class,
 						  dev_name(&device->dev), event, 0);
+		break;
 	default:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Unsupported event [0x%x]\n", event));
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index f94d4c8..0230cb6 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1345,12 +1345,15 @@
 acpi_video_bus_get_devices(struct acpi_video_bus *video,
 			   struct acpi_device *device)
 {
-	int status;
+	int status = 0;
 	struct acpi_device *dev;
 
-	status = acpi_video_device_enumerate(video);
-	if (status)
-		return status;
+	/*
+	 * There are systems where video module known to work fine regardless
+	 * of broken _DOD and ignoring returned value here doesn't cause
+	 * any issues later.
+	 */
+	acpi_video_device_enumerate(video);
 
 	list_for_each_entry(dev, &device->children, node) {
 
diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c
index 0b6f0b2..bd5de08 100644
--- a/drivers/amba/tegra-ahb.c
+++ b/drivers/amba/tegra-ahb.c
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/tegra-ahb.h>
 
 #define DRV_NAME "tegra-ahb"
 
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 08b4c52..b34b5cd 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -236,7 +236,7 @@
 
 choice
 	prompt "Selected region size"
-	default CMA_SIZE_SEL_ABSOLUTE
+	default CMA_SIZE_SEL_MBYTES
 
 config CMA_SIZE_SEL_MBYTES
 	bool "Use mega bytes value only"
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index 560a717..bc256b6 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -191,9 +191,8 @@
  * This checks whether the memory was allocated from the per-device
  * coherent memory pool and if so, maps that memory to the provided vma.
  *
- * Returns 1 if we correctly mapped the memory, or 0 if
- * dma_release_coherent() should proceed with mapping memory from
- * generic pools.
+ * Returns 1 if we correctly mapped the memory, or 0 if the caller should
+ * proceed with mapping memory from generic pools.
  */
 int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma,
 			   void *vaddr, size_t size, int *ret)
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 9a14694..612afcc 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -27,15 +27,12 @@
 #include <linux/mm.h>
 #include <linux/mutex.h>
 #include <linux/page-isolation.h>
+#include <linux/sizes.h>
 #include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/mm_types.h>
 #include <linux/dma-contiguous.h>
 
-#ifndef SZ_1M
-#define SZ_1M (1 << 20)
-#endif
-
 struct cma {
 	unsigned long	base_pfn;
 	unsigned long	count;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 8154145..8945f4e 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -36,68 +36,6 @@
 MODULE_DESCRIPTION("Multi purpose firmware loading support");
 MODULE_LICENSE("GPL");
 
-static const char *fw_path[] = {
-	"/lib/firmware/updates/" UTS_RELEASE,
-	"/lib/firmware/updates",
-	"/lib/firmware/" UTS_RELEASE,
-	"/lib/firmware"
-};
-
-/* Don't inline this: 'struct kstat' is biggish */
-static noinline long fw_file_size(struct file *file)
-{
-	struct kstat st;
-	if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st))
-		return -1;
-	if (!S_ISREG(st.mode))
-		return -1;
-	if (st.size != (long)st.size)
-		return -1;
-	return st.size;
-}
-
-static bool fw_read_file_contents(struct file *file, struct firmware *fw)
-{
-	long size;
-	char *buf;
-
-	size = fw_file_size(file);
-	if (size < 0)
-		return false;
-	buf = vmalloc(size);
-	if (!buf)
-		return false;
-	if (kernel_read(file, 0, buf, size) != size) {
-		vfree(buf);
-		return false;
-	}
-	fw->data = buf;
-	fw->size = size;
-	return true;
-}
-
-static bool fw_get_filesystem_firmware(struct firmware *fw, const char *name)
-{
-	int i;
-	bool success = false;
-	char *path = __getname();
-
-	for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
-		struct file *file;
-		snprintf(path, PATH_MAX, "%s/%s", fw_path[i], name);
-
-		file = filp_open(path, O_RDONLY, 0);
-		if (IS_ERR(file))
-			continue;
-		success = fw_read_file_contents(file, fw);
-		fput(file);
-		if (success)
-			break;
-	}
-	__putname(path);
-	return success;
-}
-
 /* Builtin firmware support */
 
 #ifdef CONFIG_FW_LOADER
@@ -150,6 +88,11 @@
 	FW_STATUS_ABORT,
 };
 
+enum fw_buf_fmt {
+	VMALLOC_BUF,	/* used in direct loading */
+	PAGE_BUF,	/* used in loading via userspace */
+};
+
 static int loading_timeout = 60;	/* In seconds */
 
 static inline long firmware_loading_timeout(void)
@@ -173,8 +116,6 @@
 	spinlock_t name_lock;
 	struct list_head fw_names;
 
-	wait_queue_head_t wait_queue;
-	int cnt;
 	struct delayed_work work;
 
 	struct notifier_block   pm_notify;
@@ -187,6 +128,7 @@
 	struct completion completion;
 	struct firmware_cache *fwc;
 	unsigned long status;
+	enum fw_buf_fmt fmt;
 	void *data;
 	size_t size;
 	struct page **pages;
@@ -240,6 +182,7 @@
 	strcpy(buf->fw_id, fw_name);
 	buf->fwc = fwc;
 	init_completion(&buf->completion);
+	buf->fmt = VMALLOC_BUF;
 
 	pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf);
 
@@ -307,10 +250,14 @@
 	list_del(&buf->list);
 	spin_unlock(&fwc->lock);
 
-	vunmap(buf->data);
-	for (i = 0; i < buf->nr_pages; i++)
-		__free_page(buf->pages[i]);
-	kfree(buf->pages);
+
+	if (buf->fmt == PAGE_BUF) {
+		vunmap(buf->data);
+		for (i = 0; i < buf->nr_pages; i++)
+			__free_page(buf->pages[i]);
+		kfree(buf->pages);
+	} else
+		vfree(buf->data);
 	kfree(buf);
 }
 
@@ -319,6 +266,69 @@
 	kref_put(&buf->ref, __fw_free_buf);
 }
 
+/* direct firmware loading support */
+static const char *fw_path[] = {
+	"/lib/firmware/updates/" UTS_RELEASE,
+	"/lib/firmware/updates",
+	"/lib/firmware/" UTS_RELEASE,
+	"/lib/firmware"
+};
+
+/* Don't inline this: 'struct kstat' is biggish */
+static noinline long fw_file_size(struct file *file)
+{
+	struct kstat st;
+	if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st))
+		return -1;
+	if (!S_ISREG(st.mode))
+		return -1;
+	if (st.size != (long)st.size)
+		return -1;
+	return st.size;
+}
+
+static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
+{
+	long size;
+	char *buf;
+
+	size = fw_file_size(file);
+	if (size < 0)
+		return false;
+	buf = vmalloc(size);
+	if (!buf)
+		return false;
+	if (kernel_read(file, 0, buf, size) != size) {
+		vfree(buf);
+		return false;
+	}
+	fw_buf->data = buf;
+	fw_buf->size = size;
+	return true;
+}
+
+static bool fw_get_filesystem_firmware(struct firmware_buf *buf)
+{
+	int i;
+	bool success = false;
+	char *path = __getname();
+
+	for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
+		struct file *file;
+		snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id);
+
+		file = filp_open(path, O_RDONLY, 0);
+		if (IS_ERR(file))
+			continue;
+		success = fw_read_file_contents(file, buf);
+		fput(file);
+		if (success)
+			break;
+	}
+	__putname(path);
+	return success;
+}
+
 static struct firmware_priv *to_firmware_priv(struct device *dev)
 {
 	return container_of(dev, struct firmware_priv, dev);
@@ -423,6 +433,21 @@
 #ifndef PAGE_KERNEL_RO
 #define PAGE_KERNEL_RO PAGE_KERNEL
 #endif
+
+/* one pages buffer should be mapped/unmapped only once */
+static int fw_map_pages_buf(struct firmware_buf *buf)
+{
+	if (buf->fmt != PAGE_BUF)
+		return 0;
+
+	if (buf->data)
+		vunmap(buf->data);
+	buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO);
+	if (!buf->data)
+		return -ENOMEM;
+	return 0;
+}
+
 /**
  * firmware_loading_store - set value in the 'loading' control file
  * @dev: device pointer
@@ -467,6 +492,14 @@
 		if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) {
 			set_bit(FW_STATUS_DONE, &fw_buf->status);
 			clear_bit(FW_STATUS_LOADING, &fw_buf->status);
+
+			/*
+			 * Several loading requests may be pending on
+			 * one same firmware buf, so let all requests
+			 * see the mapped 'buf->data' once the loading
+			 * is completed.
+			 * */
+			fw_map_pages_buf(fw_buf);
 			complete_all(&fw_buf->completion);
 			break;
 		}
@@ -670,15 +703,6 @@
 	return fw_priv;
 }
 
-/* one pages buffer is mapped/unmapped only once */
-static int fw_map_pages_buf(struct firmware_buf *buf)
-{
-	buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO);
-	if (!buf->data)
-		return -ENOMEM;
-	return 0;
-}
-
 /* store the pages buffer info firmware from buf */
 static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw)
 {
@@ -778,11 +802,6 @@
 		return NULL;
 	}
 
-	if (fw_get_filesystem_firmware(firmware, name)) {
-		dev_dbg(device, "firmware: direct-loading firmware %s\n", name);
-		return NULL;
-	}
-
 	ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf);
 	if (!ret)
 		fw_priv = fw_create_instance(firmware, name, device,
@@ -832,6 +851,21 @@
 	struct device *f_dev = &fw_priv->dev;
 	struct firmware_buf *buf = fw_priv->buf;
 	struct firmware_cache *fwc = &fw_cache;
+	int direct_load = 0;
+
+	/* try direct loading from fs first */
+	if (fw_get_filesystem_firmware(buf)) {
+		dev_dbg(f_dev->parent, "firmware: direct-loading"
+			" firmware %s\n", buf->fw_id);
+
+		set_bit(FW_STATUS_DONE, &buf->status);
+		complete_all(&buf->completion);
+		direct_load = 1;
+		goto handle_fw;
+	}
+
+	/* fall back on userspace loading */
+	buf->fmt = PAGE_BUF;
 
 	dev_set_uevent_suppress(f_dev, true);
 
@@ -870,6 +904,7 @@
 
 	del_timer_sync(&fw_priv->timeout);
 
+handle_fw:
 	mutex_lock(&fw_lock);
 	if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status))
 		retval = -ENOENT;
@@ -884,9 +919,6 @@
 	if (!retval && f_dev->parent)
 		fw_add_devm_name(f_dev->parent, buf->fw_id);
 
-	if (!retval)
-		retval = fw_map_pages_buf(buf);
-
 	/*
 	 * After caching firmware image is started, let it piggyback
 	 * on request firmware.
@@ -902,6 +934,9 @@
 	fw_priv->buf = NULL;
 	mutex_unlock(&fw_lock);
 
+	if (direct_load)
+		goto err_put_dev;
+
 	device_remove_file(f_dev, &dev_attr_loading);
 err_del_bin_attr:
 	device_remove_bin_file(f_dev, &firmware_attr_data);
@@ -1129,6 +1164,8 @@
 }
 
 #ifdef CONFIG_PM_SLEEP
+static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
+
 static struct fw_cache_entry *alloc_fw_cache_entry(const char *name)
 {
 	struct fw_cache_entry *fce;
@@ -1142,6 +1179,18 @@
 	return fce;
 }
 
+static int __fw_entry_found(const char *name)
+{
+	struct firmware_cache *fwc = &fw_cache;
+	struct fw_cache_entry *fce;
+
+	list_for_each_entry(fce, &fwc->fw_names, list) {
+		if (!strcmp(fce->name, name))
+			return 1;
+	}
+	return 0;
+}
+
 static int fw_cache_piggyback_on_request(const char *name)
 {
 	struct firmware_cache *fwc = &fw_cache;
@@ -1149,10 +1198,8 @@
 	int ret = 0;
 
 	spin_lock(&fwc->name_lock);
-	list_for_each_entry(fce, &fwc->fw_names, list) {
-		if (!strcmp(fce->name, name))
-			goto found;
-	}
+	if (__fw_entry_found(name))
+		goto found;
 
 	fce = alloc_fw_cache_entry(name);
 	if (fce) {
@@ -1185,12 +1232,6 @@
 
 		free_fw_cache_entry(fce);
 	}
-
-	spin_lock(&fwc->name_lock);
-	fwc->cnt--;
-	spin_unlock(&fwc->name_lock);
-
-	wake_up(&fwc->wait_queue);
 }
 
 /* called with dev->devres_lock held */
@@ -1229,11 +1270,19 @@
 		list_del(&fce->list);
 
 		spin_lock(&fwc->name_lock);
-		fwc->cnt++;
-		list_add(&fce->list, &fwc->fw_names);
+		/* only one cache entry for one firmware */
+		if (!__fw_entry_found(fce->name)) {
+			list_add(&fce->list, &fwc->fw_names);
+		} else {
+			free_fw_cache_entry(fce);
+			fce = NULL;
+		}
 		spin_unlock(&fwc->name_lock);
 
-		async_schedule(__async_dev_cache_fw_image, (void *)fce);
+		if (fce)
+			async_schedule_domain(__async_dev_cache_fw_image,
+					      (void *)fce,
+					      &fw_cache_domain);
 	}
 }
 
@@ -1275,6 +1324,9 @@
 
 	pr_debug("%s\n", __func__);
 
+	/* cancel uncache work */
+	cancel_delayed_work_sync(&fwc->work);
+
 	/*
 	 * use small loading timeout for caching devices' firmware
 	 * because all these firmware images have been loaded
@@ -1292,21 +1344,7 @@
 	mutex_unlock(&fw_lock);
 
 	/* wait for completion of caching firmware for all devices */
-	spin_lock(&fwc->name_lock);
-	for (;;) {
-		prepare_to_wait(&fwc->wait_queue, &wait,
-				TASK_UNINTERRUPTIBLE);
-		if (!fwc->cnt)
-			break;
-
-		spin_unlock(&fwc->name_lock);
-
-		schedule();
-
-		spin_lock(&fwc->name_lock);
-	}
-	spin_unlock(&fwc->name_lock);
-	finish_wait(&fwc->wait_queue, &wait);
+	async_synchronize_full_domain(&fw_cache_domain);
 
 	loading_timeout = old_timeout;
 }
@@ -1394,9 +1432,7 @@
 #ifdef CONFIG_PM_SLEEP
 	spin_lock_init(&fw_cache.name_lock);
 	INIT_LIST_HEAD(&fw_cache.fw_names);
-	fw_cache.cnt = 0;
 
-	init_waitqueue_head(&fw_cache.wait_queue);
 	INIT_DELAYED_WORK(&fw_cache.work,
 			  device_uncache_fw_images_work);
 
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 8727e9c..72c776f 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -83,9 +83,16 @@
  */
 int platform_get_irq(struct platform_device *dev, unsigned int num)
 {
+#ifdef CONFIG_SPARC
+	/* sparc does not have irqs represented as IORESOURCE_IRQ resources */
+	if (!dev || num >= dev->archdata.num_irqs)
+		return -ENXIO;
+	return dev->archdata.irqs[num];
+#else
 	struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
 
 	return r ? r->start : -ENXIO;
+#endif
 }
 EXPORT_SYMBOL_GPL(platform_get_irq);
 
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index c22b869..96b71b6 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1862,7 +1862,7 @@
 	cpuidle_drv = cpuidle_driver_ref();
 	if (!cpuidle_drv) {
 		ret = -ENODEV;
-		goto out;
+		goto err_drv;
 	}
 	if (cpuidle_drv->state_count <= state) {
 		ret = -EINVAL;
@@ -1884,6 +1884,9 @@
 
  err:
 	cpuidle_driver_unref();
+
+ err_drv:
+	kfree(cpu_data);
 	goto out;
 }
 
diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig
index 6be390b..f0d3054 100644
--- a/drivers/base/regmap/Kconfig
+++ b/drivers/base/regmap/Kconfig
@@ -3,7 +3,7 @@
 # subsystems should select the appropriate symbols.
 
 config REGMAP
-	default y if (REGMAP_I2C || REGMAP_SPI)
+	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_MMIO || REGMAP_IRQ)
 	select LZO_COMPRESS
 	select LZO_DECOMPRESS
 	select IRQ_DOMAIN if REGMAP_IRQ
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 432aeee..d865470 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -158,9 +158,10 @@
 
 static void bcma_unregister_cores(struct bcma_bus *bus)
 {
-	struct bcma_device *core;
+	struct bcma_device *core, *tmp;
 
-	list_for_each_entry(core, &bus->cores, list) {
+	list_for_each_entry_safe(core, tmp, &bus->cores, list) {
+		list_del(&core->list);
 		if (core->dev_registered)
 			device_unregister(&core->dev);
 	}
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index f529407..824e09c 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -131,6 +131,7 @@
 config BLK_CPQ_CISS_DA
 	tristate "Compaq Smart Array 5xxx support"
 	depends on PCI
+	select CHECK_SIGNATURE
 	help
 	  This is the driver for Compaq Smart Array 5xxx controllers.
 	  Everyone using these boards should say Y here.
@@ -166,8 +167,8 @@
 	  module will be called DAC960.
 
 config BLK_DEV_UMEM
-	tristate "Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)"
-	depends on PCI && EXPERIMENTAL
+	tristate "Micro Memory MM5415 Battery Backed RAM support"
+	depends on PCI
 	---help---
 	  Saying Y here will include support for the MM5415 family of
 	  battery backed (Non-volatile) RAM cards.
@@ -430,8 +431,8 @@
 	  a disc is opened for writing.
 
 config CDROM_PKTCDVD_WCACHE
-	bool "Enable write caching (EXPERIMENTAL)"
-	depends on CDROM_PKTCDVD && EXPERIMENTAL
+	bool "Enable write caching"
+	depends on CDROM_PKTCDVD
 	help
 	  If enabled, write caching will be set for the CD-R/W device. For now
 	  this option is dangerous unless the CD-RW media is known good, as we
@@ -508,8 +509,8 @@
 
 
 config VIRTIO_BLK
-	tristate "Virtio block driver (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && VIRTIO
+	tristate "Virtio block driver"
+	depends on VIRTIO
 	---help---
 	  This is the virtual block driver for virtio.  It can be used with
           lguest or QEMU based VMMs (like KVM or Xen).  Say Y or M.
@@ -528,7 +529,7 @@
 
 config BLK_DEV_RBD
 	tristate "Rados block device (RBD)"
-	depends on INET && EXPERIMENTAL && BLOCK
+	depends on INET && BLOCK
 	select CEPH_LIB
 	select LIBCRC32C
 	select CRYPTO_AES
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index b0f553b..ca83f96 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -5205,7 +5205,6 @@
 		return;
 	}
 	/* write all data in the battery backed cache to disk */
-	memset(flush_buf, 0, 4);
 	return_code = sendcmd_withirq(h, CCISS_CACHE_FLUSH, flush_buf,
 		4, 0, CTLR_LUNID, TYPE_CMD);
 	kfree(flush_buf);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 17c675c..1c49d71 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4109,12 +4109,19 @@
 
 static struct platform_device floppy_device[N_DRIVE];
 
+static bool floppy_available(int drive)
+{
+	if (!(allowed_drive_mask & (1 << drive)))
+		return false;
+	if (fdc_state[FDC(drive)].version == FDC_NONE)
+		return false;
+	return true;
+}
+
 static struct kobject *floppy_find(dev_t dev, int *part, void *data)
 {
 	int drive = (*part & 3) | ((*part & 0x80) >> 5);
-	if (drive >= N_DRIVE ||
-	    !(allowed_drive_mask & (1 << drive)) ||
-	    fdc_state[FDC(drive)].version == FDC_NONE)
+	if (drive >= N_DRIVE || !floppy_available(drive))
 		return NULL;
 	if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type))
 		return NULL;
@@ -4124,8 +4131,7 @@
 
 static int __init do_floppy_init(void)
 {
-	int i, unit, drive;
-	int err, dr;
+	int i, unit, drive, err;
 
 	set_debugt();
 	interruptjiffies = resultjiffies = jiffies;
@@ -4137,34 +4143,32 @@
 
 	raw_cmd = NULL;
 
-	for (dr = 0; dr < N_DRIVE; dr++) {
-		disks[dr] = alloc_disk(1);
-		if (!disks[dr]) {
+	floppy_wq = alloc_ordered_workqueue("floppy", 0);
+	if (!floppy_wq)
+		return -ENOMEM;
+
+	for (drive = 0; drive < N_DRIVE; drive++) {
+		disks[drive] = alloc_disk(1);
+		if (!disks[drive]) {
 			err = -ENOMEM;
 			goto out_put_disk;
 		}
 
-		floppy_wq = alloc_ordered_workqueue("floppy", 0);
-		if (!floppy_wq) {
+		disks[drive]->queue = blk_init_queue(do_fd_request, &floppy_lock);
+		if (!disks[drive]->queue) {
 			err = -ENOMEM;
 			goto out_put_disk;
 		}
 
-		disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock);
-		if (!disks[dr]->queue) {
-			err = -ENOMEM;
-			goto out_destroy_workq;
-		}
+		blk_queue_max_hw_sectors(disks[drive]->queue, 64);
+		disks[drive]->major = FLOPPY_MAJOR;
+		disks[drive]->first_minor = TOMINOR(drive);
+		disks[drive]->fops = &floppy_fops;
+		sprintf(disks[drive]->disk_name, "fd%d", drive);
 
-		blk_queue_max_hw_sectors(disks[dr]->queue, 64);
-		disks[dr]->major = FLOPPY_MAJOR;
-		disks[dr]->first_minor = TOMINOR(dr);
-		disks[dr]->fops = &floppy_fops;
-		sprintf(disks[dr]->disk_name, "fd%d", dr);
-
-		init_timer(&motor_off_timer[dr]);
-		motor_off_timer[dr].data = dr;
-		motor_off_timer[dr].function = motor_off_callback;
+		init_timer(&motor_off_timer[drive]);
+		motor_off_timer[drive].data = drive;
+		motor_off_timer[drive].function = motor_off_callback;
 	}
 
 	err = register_blkdev(FLOPPY_MAJOR, "fd");
@@ -4282,9 +4286,7 @@
 	}
 
 	for (drive = 0; drive < N_DRIVE; drive++) {
-		if (!(allowed_drive_mask & (1 << drive)))
-			continue;
-		if (fdc_state[FDC(drive)].version == FDC_NONE)
+		if (!floppy_available(drive))
 			continue;
 
 		floppy_device[drive].name = floppy_device_name;
@@ -4293,7 +4295,7 @@
 
 		err = platform_device_register(&floppy_device[drive]);
 		if (err)
-			goto out_release_dma;
+			goto out_remove_drives;
 
 		err = device_create_file(&floppy_device[drive].dev,
 					 &dev_attr_cmos);
@@ -4311,29 +4313,34 @@
 
 out_unreg_platform_dev:
 	platform_device_unregister(&floppy_device[drive]);
+out_remove_drives:
+	while (drive--) {
+		if (floppy_available(drive)) {
+			del_gendisk(disks[drive]);
+			device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos);
+			platform_device_unregister(&floppy_device[drive]);
+		}
+	}
 out_release_dma:
 	if (atomic_read(&usage_count))
 		floppy_release_irq_and_dma();
 out_unreg_region:
 	blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
 	platform_driver_unregister(&floppy_driver);
-out_destroy_workq:
-	destroy_workqueue(floppy_wq);
 out_unreg_blkdev:
 	unregister_blkdev(FLOPPY_MAJOR, "fd");
 out_put_disk:
-	while (dr--) {
-		del_timer_sync(&motor_off_timer[dr]);
-		if (disks[dr]->queue) {
-			blk_cleanup_queue(disks[dr]->queue);
-			/*
-			 * put_disk() is not paired with add_disk() and
-			 * will put queue reference one extra time. fix it.
-			 */
-			disks[dr]->queue = NULL;
+	for (drive = 0; drive < N_DRIVE; drive++) {
+		if (!disks[drive])
+			break;
+		if (disks[drive]->queue) {
+			del_timer_sync(&motor_off_timer[drive]);
+			blk_cleanup_queue(disks[drive]->queue);
+			disks[drive]->queue = NULL;
 		}
-		put_disk(disks[dr]);
+		put_disk(disks[drive]);
 	}
+	destroy_workqueue(floppy_wq);
 	return err;
 }
 
@@ -4551,8 +4558,7 @@
 	for (drive = 0; drive < N_DRIVE; drive++) {
 		del_timer_sync(&motor_off_timer[drive]);
 
-		if ((allowed_drive_mask & (1 << drive)) &&
-		    fdc_state[FDC(drive)].version != FDC_NONE) {
+		if (floppy_available(drive)) {
 			del_gendisk(disks[drive]);
 			device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos);
 			platform_device_unregister(&floppy_device[drive]);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index e9d594f..54046e5 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -976,8 +976,21 @@
 	if (lo->lo_state != Lo_bound)
 		return -ENXIO;
 
-	if (lo->lo_refcnt > 1)	/* we needed one fd for the ioctl */
-		return -EBUSY;
+	/*
+	 * If we've explicitly asked to tear down the loop device,
+	 * and it has an elevated reference count, set it for auto-teardown when
+	 * the last reference goes away. This stops $!~#$@ udev from
+	 * preventing teardown because it decided that it needs to run blkid on
+	 * the loopback device whenever they appear. xfstests is notorious for
+	 * failing tests because blkid via udev races with a losetup
+	 * <dev>/do something like mkfs/losetup -d <dev> causing the losetup -d
+	 * command to fail with EBUSY.
+	 */
+	if (lo->lo_refcnt > 1) {
+		lo->lo_flags |= LO_FLAGS_AUTOCLEAR;
+		mutex_unlock(&lo->lo_ctl_mutex);
+		return 0;
+	}
 
 	if (filp == NULL)
 		return -EINVAL;
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index f946d31..adc6f36 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -2035,8 +2035,9 @@
 	}
 	return rv;
 }
-
-static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout)
+static void mtip_set_timeout(struct driver_data *dd,
+					struct host_to_dev_fis *fis,
+					unsigned int *timeout, u8 erasemode)
 {
 	switch (fis->command) {
 	case ATA_CMD_DOWNLOAD_MICRO:
@@ -2044,7 +2045,10 @@
 		break;
 	case ATA_CMD_SEC_ERASE_UNIT:
 	case 0xFC:
-		*timeout = 240000; /* 4 minutes */
+		if (erasemode)
+			*timeout = ((*(dd->port->identify + 90) * 2) * 60000);
+		else
+			*timeout = ((*(dd->port->identify + 89) * 2) * 60000);
 		break;
 	case ATA_CMD_STANDBYNOW1:
 		*timeout = 120000;  /* 2 minutes */
@@ -2087,6 +2091,7 @@
 	unsigned int transfer_size;
 	unsigned long task_file_data;
 	int intotal = outtotal + req_task->out_size;
+	int erasemode = 0;
 
 	taskout = req_task->out_size;
 	taskin = req_task->in_size;
@@ -2212,7 +2217,13 @@
 		fis.lba_hi,
 		fis.device);
 
-	mtip_set_timeout(&fis, &timeout);
+	/* check for erase mode support during secure erase.*/
+	if ((fis.command == ATA_CMD_SEC_ERASE_UNIT)
+					&& (outbuf[0] & MTIP_SEC_ERASE_MODE)) {
+		erasemode = 1;
+	}
+
+	mtip_set_timeout(dd, &fis, &timeout, erasemode);
 
 	/* Determine the correct transfer size.*/
 	if (force_single_sector)
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h
index 18627a1..5f4a917 100644
--- a/drivers/block/mtip32xx/mtip32xx.h
+++ b/drivers/block/mtip32xx/mtip32xx.h
@@ -33,6 +33,9 @@
 /* offset of Device Control register in PCIe extended capabilites space */
 #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET	0x48
 
+/* check for erase mode support during secure erase */
+#define MTIP_SEC_ERASE_MODE     0x3
+
 /* # of times to retry timed out/failed IOs */
 #define MTIP_MAX_RETRIES	2
 
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
index 9ad3b5e..9a54623 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -158,8 +158,8 @@
 	struct block_device	*bdev;
 	/* Cached size parameter. */
 	sector_t		size;
-	bool			flush_support;
-	bool			discard_secure;
+	unsigned int		flush_support:1;
+	unsigned int		discard_secure:1;
 };
 
 struct backend_info;
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 4f66171..f58434c 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -105,11 +105,10 @@
 {
 	struct xen_blkif *blkif;
 
-	blkif = kmem_cache_alloc(xen_blkif_cachep, GFP_KERNEL);
+	blkif = kmem_cache_zalloc(xen_blkif_cachep, GFP_KERNEL);
 	if (!blkif)
 		return ERR_PTR(-ENOMEM);
 
-	memset(blkif, 0, sizeof(*blkif));
 	blkif->domid = domid;
 	spin_lock_init(&blkif->blk_ring_lock);
 	atomic_set(&blkif->refcnt, 1);
@@ -196,7 +195,7 @@
 	}
 }
 
-void xen_blkif_free(struct xen_blkif *blkif)
+static void xen_blkif_free(struct xen_blkif *blkif)
 {
 	if (!atomic_dec_and_test(&blkif->refcnt))
 		BUG();
@@ -257,7 +256,7 @@
 VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
 VBD_SHOW(mode, "%s\n", be->mode);
 
-int xenvbd_sysfs_addif(struct xenbus_device *dev)
+static int xenvbd_sysfs_addif(struct xenbus_device *dev)
 {
 	int error;
 
@@ -281,7 +280,7 @@
 	return error;
 }
 
-void xenvbd_sysfs_delif(struct xenbus_device *dev)
+static void xenvbd_sysfs_delif(struct xenbus_device *dev)
 {
 	sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group);
 	device_remove_file(&dev->dev, &dev_attr_mode);
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index fc2de55..b00000e 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -67,6 +67,7 @@
 	{ USB_DEVICE(0x13d3, 0x3304) },
 	{ USB_DEVICE(0x0930, 0x0215) },
 	{ USB_DEVICE(0x0489, 0xE03D) },
+	{ USB_DEVICE(0x0489, 0xE027) },
 
 	/* Atheros AR9285 Malbec with sflash firmware */
 	{ USB_DEVICE(0x03F0, 0x311D) },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index debda27..ee82f2f 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -124,6 +124,7 @@
 	{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
 	{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
 	{ USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
+	{ USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE },
 
 	/* Atheros AR9285 Malbec with sflash firmware */
 	{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
diff --git a/drivers/bus/omap-ocp2scp.c b/drivers/bus/omap-ocp2scp.c
index ff63560..0c48b0e 100644
--- a/drivers/bus/omap-ocp2scp.c
+++ b/drivers/bus/omap-ocp2scp.c
@@ -22,6 +22,26 @@
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/platform_data/omap_ocp2scp.h>
+
+/**
+ * _count_resources - count for the number of resources
+ * @res: struct resource *
+ *
+ * Count and return the number of resources populated for the device that is
+ * connected to ocp2scp.
+ */
+static unsigned _count_resources(struct resource *res)
+{
+	int cnt	= 0;
+
+	while (res->start != res->end) {
+		cnt++;
+		res++;
+	}
+
+	return cnt;
+}
 
 static int ocp2scp_remove_devices(struct device *dev, void *c)
 {
@@ -34,20 +54,62 @@
 
 static int __devinit omap_ocp2scp_probe(struct platform_device *pdev)
 {
-	int			ret;
-	struct device_node	*np = pdev->dev.of_node;
+	int ret;
+	unsigned res_cnt, i;
+	struct device_node *np = pdev->dev.of_node;
+	struct platform_device *pdev_child;
+	struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data;
+	struct omap_ocp2scp_dev *dev;
 
 	if (np) {
 		ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
 		if (ret) {
-			dev_err(&pdev->dev, "failed to add resources for ocp2scp child\n");
+			dev_err(&pdev->dev,
+			    "failed to add resources for ocp2scp child\n");
 			goto err0;
 		}
+	} else if (pdata) {
+		for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++,
+		    dev++) {
+			res_cnt = _count_resources(dev->res);
+
+			pdev_child = platform_device_alloc(dev->drv_name,
+			    PLATFORM_DEVID_AUTO);
+			if (!pdev_child) {
+				dev_err(&pdev->dev,
+				  "failed to allocate mem for ocp2scp child\n");
+				goto err0;
+			}
+
+			ret = platform_device_add_resources(pdev_child,
+			    dev->res, res_cnt);
+			if (ret) {
+				dev_err(&pdev->dev,
+				 "failed to add resources for ocp2scp child\n");
+				goto err1;
+			}
+
+			pdev_child->dev.parent	= &pdev->dev;
+
+			ret = platform_device_add(pdev_child);
+			if (ret) {
+				dev_err(&pdev->dev,
+				   "failed to register ocp2scp child device\n");
+				goto err1;
+			}
+		}
+	} else {
+		dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n");
+		return -EINVAL;
 	}
+
 	pm_runtime_enable(&pdev->dev);
 
 	return 0;
 
+err1:
+	platform_device_put(pdev_child);
+
 err0:
 	device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices);
 
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 320debb..9b4f011 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -1456,7 +1456,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int old_camera_power;
 
 static int sonypi_suspend(struct device *dev)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index bace9e9..823f62d 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -42,10 +42,12 @@
 
 config COMMON_CLK_VERSATILE
 	bool "Clock driver for ARM Reference designs"
-	depends on ARCH_INTEGRATOR || ARCH_REALVIEW
+	depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS
 	---help---
-          Supports clocking on ARM Reference designs Integrator/AP,
-	  Integrator/CP, RealView PB1176, EB, PB11MP and PBX.
+          Supports clocking on ARM Reference designs:
+	  - Integrator/AP and Integrator/CP
+	  - RealView PB1176, EB, PB11MP and PBX
+	  - Versatile Express
 
 config COMMON_CLK_MAX77686
 	tristate "Clock driver for Maxim 77686 MFD"
@@ -53,4 +55,12 @@
 	---help---
 	  This driver supports Maxim 77686 crystal oscillator clock. 
 
+config CLK_TWL6040
+	tristate "External McPDM functional clock from twl6040"
+	depends on TWL6040_CORE
+	---help---
+	  Enable the external functional clock support on OMAP4+ platforms for
+	  McPDM. McPDM module is using the external bit clock on the McPDM bus
+	  as functional clock.
+
 endmenu
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 71a25b9..a96bda3 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -19,7 +19,9 @@
 obj-$(CONFIG_MACH_LOONGSON1)	+= clk-ls1x.o
 obj-$(CONFIG_ARCH_U8500)	+= ux500/
 obj-$(CONFIG_ARCH_VT8500)	+= clk-vt8500.o
+obj-$(CONFIG_ARCH_SUNXI)	+= clk-sunxi.o
 
 # Chip specific
 obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
+obj-$(CONFIG_CLK_TWL6040)	+= clk-twl6040.o
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index f5ec0ee..af78ed6 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -97,7 +97,7 @@
 	of_property_read_string(node, "clock-output-names", &clk_name);
 
 	clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, rate);
-	if (clk)
+	if (!IS_ERR(clk))
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 }
 EXPORT_SYMBOL_GPL(of_fixed_clk_setup);
diff --git a/drivers/clk/clk-prima2.c b/drivers/clk/clk-prima2.c
index 517874f..a203ecc 100644
--- a/drivers/clk/clk-prima2.c
+++ b/drivers/clk/clk-prima2.c
@@ -1054,118 +1054,118 @@
 	/* These are always available (RTC and 26MHz OSC)*/
 	clk = clk_register_fixed_rate(NULL, "rtc", NULL,
 		CLK_IS_ROOT, 32768);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register_fixed_rate(NULL, "osc", NULL,
 		CLK_IS_ROOT, 26000000);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 
 	clk = clk_register(NULL, &clk_pll1.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register(NULL, &clk_pll2.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register(NULL, &clk_pll3.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register(NULL, &clk_mem.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register(NULL, &clk_sys.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register(NULL, &clk_security.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b8030000.security");
 	clk = clk_register(NULL, &clk_dsp.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register(NULL, &clk_gps.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "a8010000.gps");
 	clk = clk_register(NULL, &clk_mf.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register(NULL, &clk_io.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "io");
 	clk = clk_register(NULL, &clk_cpu.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "cpu");
 	clk = clk_register(NULL, &clk_uart0.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0050000.uart");
 	clk = clk_register(NULL, &clk_uart1.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0060000.uart");
 	clk = clk_register(NULL, &clk_uart2.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0070000.uart");
 	clk = clk_register(NULL, &clk_tsc.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0110000.tsc");
 	clk = clk_register(NULL, &clk_i2c0.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b00e0000.i2c");
 	clk = clk_register(NULL, &clk_i2c1.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b00f0000.i2c");
 	clk = clk_register(NULL, &clk_spi0.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b00d0000.spi");
 	clk = clk_register(NULL, &clk_spi1.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0170000.spi");
 	clk = clk_register(NULL, &clk_pwmc.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0130000.pwm");
 	clk = clk_register(NULL, &clk_efuse.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0140000.efusesys");
 	clk = clk_register(NULL, &clk_pulse.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0150000.pulsec");
 	clk = clk_register(NULL, &clk_dmac0.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b00b0000.dma-controller");
 	clk = clk_register(NULL, &clk_dmac1.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0160000.dma-controller");
 	clk = clk_register(NULL, &clk_nand.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0030000.nand");
 	clk = clk_register(NULL, &clk_audio.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0040000.audio");
 	clk = clk_register(NULL, &clk_usp0.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0080000.usp");
 	clk = clk_register(NULL, &clk_usp1.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b0090000.usp");
 	clk = clk_register(NULL, &clk_usp2.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b00a0000.usp");
 	clk = clk_register(NULL, &clk_vip.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b00c0000.vip");
 	clk = clk_register(NULL, &clk_gfx.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "98000000.graphics");
 	clk = clk_register(NULL, &clk_mm.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "a0000000.multimedia");
 	clk = clk_register(NULL, &clk_lcd.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "90010000.display");
 	clk = clk_register(NULL, &clk_vpp.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "90020000.vpp");
 	clk = clk_register(NULL, &clk_mmc01.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register(NULL, &clk_mmc23.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register(NULL, &clk_mmc45.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register(NULL, &usb_pll_clk_hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk = clk_register(NULL, &clk_usb0.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b00e0000.usb");
 	clk = clk_register(NULL, &clk_usb1.hw);
-	BUG_ON(!clk);
+	BUG_ON(IS_ERR(clk));
 	clk_register_clkdev(clk, NULL, "b00f0000.usb");
 }
diff --git a/drivers/clk/clk-sunxi.c b/drivers/clk/clk-sunxi.c
new file mode 100644
index 0000000..0e831b5
--- /dev/null
+++ b/drivers/clk/clk-sunxi.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/sunxi.h>
+#include <linux/of.h>
+
+static const __initconst struct of_device_id clk_match[] = {
+	{ .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
+	{}
+};
+
+void __init sunxi_init_clocks(void)
+{
+	of_clk_init(clk_match);
+}
diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c
new file mode 100644
index 0000000..f4a3389
--- /dev/null
+++ b/drivers/clk/clk-twl6040.c
@@ -0,0 +1,126 @@
+/*
+* TWL6040 clock module driver for OMAP4 McPDM functional clock
+*
+* Copyright (C) 2012 Texas Instruments Inc.
+* Peter Ujfalusi <peter.ujfalusi@ti.com>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA
+*
+*/
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/twl6040.h>
+#include <linux/clk-provider.h>
+
+struct twl6040_clk {
+	struct twl6040 *twl6040;
+	struct device *dev;
+	struct clk_hw mcpdm_fclk;
+	struct clk *clk;
+	int enabled;
+};
+
+static int twl6040_bitclk_is_enabled(struct clk_hw *hw)
+{
+	struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
+						       mcpdm_fclk);
+	return twl6040_clk->enabled;
+}
+
+static int twl6040_bitclk_prepare(struct clk_hw *hw)
+{
+	struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
+						       mcpdm_fclk);
+	int ret;
+
+	ret = twl6040_power(twl6040_clk->twl6040, 1);
+	if (!ret)
+		twl6040_clk->enabled = 1;
+
+	return ret;
+}
+
+static void twl6040_bitclk_unprepare(struct clk_hw *hw)
+{
+	struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
+						       mcpdm_fclk);
+	int ret;
+
+	ret = twl6040_power(twl6040_clk->twl6040, 0);
+	if (!ret)
+		twl6040_clk->enabled = 0;
+}
+
+static const struct clk_ops twl6040_mcpdm_ops = {
+	.is_enabled = twl6040_bitclk_is_enabled,
+	.prepare = twl6040_bitclk_prepare,
+	.unprepare = twl6040_bitclk_unprepare,
+};
+
+static struct clk_init_data wm831x_clkout_init = {
+	.name = "mcpdm_fclk",
+	.ops = &twl6040_mcpdm_ops,
+	.flags = CLK_IS_ROOT,
+};
+
+static int __devinit twl6040_clk_probe(struct platform_device *pdev)
+{
+	struct twl6040 *twl6040 = dev_get_drvdata(pdev->dev.parent);
+	struct twl6040_clk *clkdata;
+
+	clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL);
+	if (!clkdata)
+		return -ENOMEM;
+
+	clkdata->dev = &pdev->dev;
+	clkdata->twl6040 = twl6040;
+
+	clkdata->mcpdm_fclk.init = &wm831x_clkout_init;
+	clkdata->clk = clk_register(&pdev->dev, &clkdata->mcpdm_fclk);
+	if (!clkdata->clk)
+		return -EINVAL;
+
+	dev_set_drvdata(&pdev->dev, clkdata);
+
+	return 0;
+}
+
+static int __devexit twl6040_clk_remove(struct platform_device *pdev)
+{
+	struct twl6040_clk *clkdata = dev_get_drvdata(&pdev->dev);
+
+	clk_unregister(clkdata->clk);
+
+	return 0;
+}
+
+static struct platform_driver twl6040_clk_driver = {
+	.driver = {
+		.name = "twl6040-clk",
+		.owner = THIS_MODULE,
+	},
+	.probe = twl6040_clk_probe,
+	.remove = __devexit_p(twl6040_clk_remove),
+};
+
+module_platform_driver(twl6040_clk_driver);
+
+MODULE_DESCRIPTION("TWL6040 clock driver for McPDM functional clock");
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_ALIAS("platform:twl6040-clk");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 56e4495e..bbe52c4 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -261,7 +261,7 @@
 
 inline u8 __clk_get_num_parents(struct clk *clk)
 {
-	return !clk ? -EINVAL : clk->num_parents;
+	return !clk ? 0 : clk->num_parents;
 }
 
 inline struct clk *__clk_get_parent(struct clk *clk)
@@ -269,14 +269,14 @@
 	return !clk ? NULL : clk->parent;
 }
 
-inline int __clk_get_enable_count(struct clk *clk)
+inline unsigned int __clk_get_enable_count(struct clk *clk)
 {
-	return !clk ? -EINVAL : clk->enable_count;
+	return !clk ? 0 : clk->enable_count;
 }
 
-inline int __clk_get_prepare_count(struct clk *clk)
+inline unsigned int __clk_get_prepare_count(struct clk *clk)
 {
-	return !clk ? -EINVAL : clk->prepare_count;
+	return !clk ? 0 : clk->prepare_count;
 }
 
 unsigned long __clk_get_rate(struct clk *clk)
@@ -302,15 +302,15 @@
 
 inline unsigned long __clk_get_flags(struct clk *clk)
 {
-	return !clk ? -EINVAL : clk->flags;
+	return !clk ? 0 : clk->flags;
 }
 
-int __clk_is_enabled(struct clk *clk)
+bool __clk_is_enabled(struct clk *clk)
 {
 	int ret;
 
 	if (!clk)
-		return -EINVAL;
+		return false;
 
 	/*
 	 * .is_enabled is only mandatory for clocks that gate
@@ -323,7 +323,7 @@
 
 	ret = clk->ops->is_enabled(clk->hw);
 out:
-	return ret;
+	return !!ret;
 }
 
 static struct clk *__clk_lookup_subtree(const char *name, struct clk *clk)
@@ -568,7 +568,7 @@
 	unsigned long parent_rate = 0;
 
 	if (!clk)
-		return -EINVAL;
+		return 0;
 
 	if (!clk->ops->round_rate) {
 		if (clk->flags & CLK_SET_RATE_PARENT)
diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c
index 5f1b6ba..1b9b65b 100644
--- a/drivers/clk/spear/clk-vco-pll.c
+++ b/drivers/clk/spear/clk-vco-pll.c
@@ -147,7 +147,7 @@
 	struct clk_pll *pll = to_clk_pll(hw);
 	struct pll_rate_tbl *rtbl = pll->vco->rtbl;
 	unsigned long flags = 0, val;
-	int i;
+	int uninitialized_var(i);
 
 	clk_pll_round_rate_index(hw, drate, NULL, &i);
 
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c
index 930cdfe..04577ca 100644
--- a/drivers/clk/ux500/clk-prcmu.c
+++ b/drivers/clk/ux500/clk-prcmu.c
@@ -133,6 +133,40 @@
 		hw->init->name);
 }
 
+static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
+{
+	int err;
+	struct clk_prcmu *clk = to_clk_prcmu(hw);
+
+	err = prcmu_request_ape_opp_100_voltage(true);
+	if (err) {
+		pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n",
+			__func__, hw->init->name);
+		return err;
+	}
+
+	err = prcmu_request_clock(clk->cg_sel, true);
+	if (err)
+		prcmu_request_ape_opp_100_voltage(false);
+
+	return err;
+}
+
+static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
+{
+	struct clk_prcmu *clk = to_clk_prcmu(hw);
+
+	if (prcmu_request_clock(clk->cg_sel, false))
+		goto out_error;
+	if (prcmu_request_ape_opp_100_voltage(false))
+		goto out_error;
+	return;
+
+out_error:
+	pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
+		hw->init->name);
+}
+
 static struct clk_ops clk_prcmu_scalable_ops = {
 	.prepare = clk_prcmu_prepare,
 	.unprepare = clk_prcmu_unprepare,
@@ -167,6 +201,17 @@
 	.recalc_rate = clk_prcmu_recalc_rate,
 };
 
+static struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
+	.prepare = clk_prcmu_opp_volt_prepare,
+	.unprepare = clk_prcmu_opp_volt_unprepare,
+	.enable = clk_prcmu_enable,
+	.disable = clk_prcmu_disable,
+	.is_enabled = clk_prcmu_is_enabled,
+	.recalc_rate = clk_prcmu_recalc_rate,
+	.round_rate = clk_prcmu_round_rate,
+	.set_rate = clk_prcmu_set_rate,
+};
+
 static struct clk *clk_reg_prcmu(const char *name,
 				 const char *parent_name,
 				 u8 cg_sel,
@@ -250,3 +295,13 @@
 	return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
 			&clk_prcmu_opp_gate_ops);
 }
+
+struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name,
+					    const char *parent_name,
+					    u8 cg_sel,
+					    unsigned long rate,
+					    unsigned long flags)
+{
+	return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
+			&clk_prcmu_opp_volt_scalable_ops);
+}
diff --git a/drivers/clk/ux500/clk.h b/drivers/clk/ux500/clk.h
index 836d7d1..f36eeed 100644
--- a/drivers/clk/ux500/clk.h
+++ b/drivers/clk/ux500/clk.h
@@ -45,4 +45,10 @@
 				   u8 cg_sel,
 				   unsigned long flags);
 
+struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name,
+					    const char *parent_name,
+					    u8 cg_sel,
+					    unsigned long rate,
+					    unsigned long flags);
+
 #endif /* __UX500_CLK_H */
diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c
index ca4a25e..dd76993 100644
--- a/drivers/clk/ux500/u8500_clk.c
+++ b/drivers/clk/ux500/u8500_clk.c
@@ -40,7 +40,7 @@
 				CLK_IS_ROOT|CLK_IGNORE_UNUSED,
 				32768);
 	clk_register_clkdev(clk, "clk32k", NULL);
-	clk_register_clkdev(clk, NULL, "rtc-pl031");
+	clk_register_clkdev(clk, "apb_pclk", "rtc-pl031");
 
 	/* PRCMU clocks */
 	fw_version = prcmu_get_fw_version();
@@ -170,10 +170,11 @@
 	clk_register_clkdev(clk, NULL, "mtu0");
 	clk_register_clkdev(clk, NULL, "mtu1");
 
-	clk = clk_reg_prcmu_gate("sdmmcclk", NULL, PRCMU_SDMMCCLK, CLK_IS_ROOT);
+	clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, PRCMU_SDMMCCLK,
+					100000000,
+					CLK_IS_ROOT|CLK_SET_RATE_GATE);
 	clk_register_clkdev(clk, NULL, "sdmmc");
 
-
 	clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk",
 				PRCMU_PLLDSI, 0, CLK_SET_RATE_GATE);
 	clk_register_clkdev(clk, "dsihs2", "mcde");
@@ -228,10 +229,17 @@
 
 	clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE,
 				BIT(2), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1");
+
 	clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE,
 				BIT(3), 0);
+	clk_register_clkdev(clk, "apb_pclk", "msp0");
+	clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0");
+
 	clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE,
 				BIT(4), 0);
+	clk_register_clkdev(clk, "apb_pclk", "msp1");
+	clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1");
 
 	clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE,
 				BIT(5), 0);
@@ -239,6 +247,7 @@
 
 	clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE,
 				BIT(6), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2");
 
 	clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE,
 				BIT(7), 0);
@@ -246,6 +255,7 @@
 
 	clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE,
 				BIT(8), 0);
+	clk_register_clkdev(clk, "apb_pclk", "slimbus0");
 
 	clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE,
 				BIT(9), 0);
@@ -255,11 +265,16 @@
 
 	clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE,
 				BIT(10), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4");
+
 	clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE,
 				BIT(11), 0);
+	clk_register_clkdev(clk, "apb_pclk", "msp3");
+	clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3");
 
 	clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE,
 				BIT(0), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3");
 
 	clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE,
 				BIT(1), 0);
@@ -279,12 +294,13 @@
 
 	clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE,
 				BIT(5), 0);
+	clk_register_clkdev(clk, "apb_pclk", "msp2");
+	clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2");
 
 	clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE,
 				BIT(6), 0);
 	clk_register_clkdev(clk, "apb_pclk", "sdi1");
 
-
 	clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE,
 				BIT(7), 0);
 	clk_register_clkdev(clk, "apb_pclk", "sdi3");
@@ -316,10 +332,15 @@
 
 	clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE,
 				BIT(1), 0);
+	clk_register_clkdev(clk, "apb_pclk", "ssp0");
+
 	clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE,
 				BIT(2), 0);
+	clk_register_clkdev(clk, "apb_pclk", "ssp1");
+
 	clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE,
 				BIT(3), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0");
 
 	clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE,
 				BIT(4), 0);
@@ -401,10 +422,17 @@
 
 	clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk",
 			U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.1");
+
 	clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk",
 			U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "msp0");
+	clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0");
+
 	clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk",
 			U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "msp1");
+	clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1");
 
 	clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk",
 			U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE);
@@ -412,17 +440,25 @@
 
 	clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk",
 			U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.2");
+
 	clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk",
-			U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE);
-	/* FIXME: Redefinition of BIT(3). */
+			U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "slimbus0");
+
 	clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk",
 			U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.4");
+
 	clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk",
 			U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "msp3");
+	clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3");
 
 	/* Periph2 */
 	clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk",
 			U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.3");
 
 	clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk",
 			U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE);
@@ -430,6 +466,8 @@
 
 	clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk",
 			U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "msp2");
+	clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2");
 
 	clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk",
 			U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE);
@@ -450,10 +488,15 @@
 	/* Periph3 */
 	clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk",
 			U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "ssp0");
+
 	clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk",
 			U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "ssp1");
+
 	clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk",
 			U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.0");
 
 	clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk",
 			U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE);
diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile
index c0a0f64..c776053 100644
--- a/drivers/clk/versatile/Makefile
+++ b/drivers/clk/versatile/Makefile
@@ -2,3 +2,5 @@
 obj-$(CONFIG_ICST)		+= clk-icst.o
 obj-$(CONFIG_ARCH_INTEGRATOR)	+= clk-integrator.o
 obj-$(CONFIG_ARCH_REALVIEW)	+= clk-realview.o
+obj-$(CONFIG_ARCH_VEXPRESS)	+= clk-vexpress.o
+obj-$(CONFIG_VEXPRESS_CONFIG)	+= clk-vexpress-osc.o
diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c
new file mode 100644
index 0000000..dcb6ae0
--- /dev/null
+++ b/drivers/clk/versatile/clk-vexpress-osc.c
@@ -0,0 +1,146 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#define pr_fmt(fmt) "vexpress-osc: " fmt
+
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/vexpress.h>
+
+struct vexpress_osc {
+	struct vexpress_config_func *func;
+	struct clk_hw hw;
+	unsigned long rate_min;
+	unsigned long rate_max;
+};
+
+#define to_vexpress_osc(osc) container_of(osc, struct vexpress_osc, hw)
+
+static unsigned long vexpress_osc_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct vexpress_osc *osc = to_vexpress_osc(hw);
+	u32 rate;
+
+	vexpress_config_read(osc->func, 0, &rate);
+
+	return rate;
+}
+
+static long vexpress_osc_round_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long *parent_rate)
+{
+	struct vexpress_osc *osc = to_vexpress_osc(hw);
+
+	if (WARN_ON(osc->rate_min && rate < osc->rate_min))
+		rate = osc->rate_min;
+
+	if (WARN_ON(osc->rate_max && rate > osc->rate_max))
+		rate = osc->rate_max;
+
+	return rate;
+}
+
+static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct vexpress_osc *osc = to_vexpress_osc(hw);
+
+	return vexpress_config_write(osc->func, 0, rate);
+}
+
+static struct clk_ops vexpress_osc_ops = {
+	.recalc_rate = vexpress_osc_recalc_rate,
+	.round_rate = vexpress_osc_round_rate,
+	.set_rate = vexpress_osc_set_rate,
+};
+
+
+struct clk * __init vexpress_osc_setup(struct device *dev)
+{
+	struct clk_init_data init;
+	struct vexpress_osc *osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+
+	if (!osc)
+		return NULL;
+
+	osc->func = vexpress_config_func_get_by_dev(dev);
+	if (!osc->func) {
+		kfree(osc);
+		return NULL;
+	}
+
+	init.name = dev_name(dev);
+	init.ops = &vexpress_osc_ops;
+	init.flags = CLK_IS_ROOT;
+	init.num_parents = 0;
+	osc->hw.init = &init;
+
+	return clk_register(NULL, &osc->hw);
+}
+
+void __init vexpress_osc_of_setup(struct device_node *node)
+{
+	struct clk_init_data init;
+	struct vexpress_osc *osc;
+	struct clk *clk;
+	u32 range[2];
+
+	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+	if (!osc)
+		goto error;
+
+	osc->func = vexpress_config_func_get_by_node(node);
+	if (!osc->func) {
+		pr_err("Failed to obtain config func for node '%s'!\n",
+				node->name);
+		goto error;
+	}
+
+	if (of_property_read_u32_array(node, "freq-range", range,
+			ARRAY_SIZE(range)) == 0) {
+		osc->rate_min = range[0];
+		osc->rate_max = range[1];
+	}
+
+	of_property_read_string(node, "clock-output-names", &init.name);
+	if (!init.name)
+		init.name = node->name;
+
+	init.ops = &vexpress_osc_ops;
+	init.flags = CLK_IS_ROOT;
+	init.num_parents = 0;
+
+	osc->hw.init = &init;
+
+	clk = clk_register(NULL, &osc->hw);
+	if (IS_ERR(clk)) {
+		pr_err("Failed to register clock '%s'!\n", init.name);
+		goto error;
+	}
+
+	of_clk_add_provider(node, of_clk_src_simple_get, clk);
+
+	pr_debug("Registered clock '%s'\n", init.name);
+
+	return;
+
+error:
+	if (osc->func)
+		vexpress_config_func_put(osc->func);
+	kfree(osc);
+}
diff --git a/drivers/clk/versatile/clk-vexpress.c b/drivers/clk/versatile/clk-vexpress.c
new file mode 100644
index 0000000..c742ac7
--- /dev/null
+++ b/drivers/clk/versatile/clk-vexpress.c
@@ -0,0 +1,142 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/vexpress.h>
+
+#include <asm/hardware/sp810.h>
+
+static struct clk *vexpress_sp810_timerclken[4];
+static DEFINE_SPINLOCK(vexpress_sp810_lock);
+
+static void __init vexpress_sp810_init(void __iomem *base)
+{
+	int i;
+
+	if (WARN_ON(!base))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) {
+		char name[12];
+		const char *parents[] = {
+			"v2m:refclk32khz", /* REFCLK */
+			"v2m:refclk1mhz" /* TIMCLK */
+		};
+
+		snprintf(name, ARRAY_SIZE(name), "timerclken%d", i);
+
+		vexpress_sp810_timerclken[i] = clk_register_mux(NULL, name,
+				parents, 2, 0, base + SCCTRL,
+				SCCTRL_TIMERENnSEL_SHIFT(i), 1,
+				0, &vexpress_sp810_lock);
+
+		if (WARN_ON(IS_ERR(vexpress_sp810_timerclken[i])))
+			break;
+	}
+}
+
+
+static const char * const vexpress_clk_24mhz_periphs[] __initconst = {
+	"mb:uart0", "mb:uart1", "mb:uart2", "mb:uart3",
+	"mb:mmci", "mb:kmi0", "mb:kmi1"
+};
+
+void __init vexpress_clk_init(void __iomem *sp810_base)
+{
+	struct clk *clk;
+	int i;
+
+	clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL,
+			CLK_IS_ROOT, 0);
+	WARN_ON(clk_register_clkdev(clk, "apb_pclk", NULL));
+
+	clk = clk_register_fixed_rate(NULL, "v2m:clk_24mhz", NULL,
+			CLK_IS_ROOT, 24000000);
+	for (i = 0; i < ARRAY_SIZE(vexpress_clk_24mhz_periphs); i++)
+		WARN_ON(clk_register_clkdev(clk, NULL,
+				vexpress_clk_24mhz_periphs[i]));
+
+	clk = clk_register_fixed_rate(NULL, "v2m:refclk32khz", NULL,
+			CLK_IS_ROOT, 32768);
+	WARN_ON(clk_register_clkdev(clk, NULL, "v2m:wdt"));
+
+	clk = clk_register_fixed_rate(NULL, "v2m:refclk1mhz", NULL,
+			CLK_IS_ROOT, 1000000);
+
+	vexpress_sp810_init(sp810_base);
+
+	for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++)
+		WARN_ON(clk_set_parent(vexpress_sp810_timerclken[i], clk));
+
+	WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[0],
+				"v2m-timer0", "sp804"));
+	WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1],
+				"v2m-timer1", "sp804"));
+}
+
+#if defined(CONFIG_OF)
+
+struct clk *vexpress_sp810_of_get(struct of_phandle_args *clkspec, void *data)
+{
+	if (WARN_ON(clkspec->args_count != 1 || clkspec->args[0] >
+			ARRAY_SIZE(vexpress_sp810_timerclken)))
+		return NULL;
+
+	return vexpress_sp810_timerclken[clkspec->args[0]];
+}
+
+static const __initconst struct of_device_id vexpress_fixed_clk_match[] = {
+	{ .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
+	{ .compatible = "arm,vexpress-osc", .data = vexpress_osc_of_setup, },
+	{}
+};
+
+void __init vexpress_clk_of_init(void)
+{
+	struct device_node *node;
+	struct clk *clk;
+	struct clk *refclk, *timclk;
+
+	of_clk_init(vexpress_fixed_clk_match);
+
+	node = of_find_compatible_node(NULL, NULL, "arm,sp810");
+	vexpress_sp810_init(of_iomap(node, 0));
+	of_clk_add_provider(node, vexpress_sp810_of_get, NULL);
+
+	/* Select "better" (faster) parent for SP804 timers */
+	refclk = of_clk_get_by_name(node, "refclk");
+	timclk = of_clk_get_by_name(node, "timclk");
+	if (!WARN_ON(IS_ERR(refclk) || IS_ERR(timclk))) {
+		int i = 0;
+
+		if (clk_get_rate(refclk) > clk_get_rate(timclk))
+			clk = refclk;
+		else
+			clk = timclk;
+
+		for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++)
+			WARN_ON(clk_set_parent(vexpress_sp810_timerclken[i],
+					clk));
+	}
+
+	WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[0],
+				"v2m-timer0", "sp804"));
+	WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1],
+				"v2m-timer1", "sp804"));
+}
+
+#endif
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 6a78073..a098573 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -22,6 +22,9 @@
 config ARMADA_370_XP_TIMER
 	bool
 
+config SUNXI_TIMER
+	bool
+
 config CLKSRC_DBX500_PRCMU
 	bool "Clocksource PRCMU Timer"
 	depends on UX500_SOC_DB8500
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 603be36..36f06de 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -14,5 +14,6 @@
 obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
 obj-$(CONFIG_ARMADA_370_XP_TIMER)	+= time-armada-370-xp.o
 obj-$(CONFIG_ARCH_BCM2835)	+= bcm2835_timer.o
+obj-$(CONFIG_SUNXI_TIMER)	+= sunxi_timer.o
 
 obj-$(CONFIG_CLKSRC_ARM_GENERIC)	+= arm_generic.o
diff --git a/drivers/clocksource/sunxi_timer.c b/drivers/clocksource/sunxi_timer.c
new file mode 100644
index 0000000..3c46434
--- /dev/null
+++ b/drivers/clocksource/sunxi_timer.c
@@ -0,0 +1,170 @@
+/*
+ * Allwinner A1X SoCs timer handling.
+ *
+ * Copyright (C) 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * Based on code from
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Benn Huang <benn@allwinnertech.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sunxi_timer.h>
+#include <linux/clk/sunxi.h>
+
+#define TIMER_CTL_REG		0x00
+#define TIMER_CTL_ENABLE		(1 << 0)
+#define TIMER_IRQ_ST_REG	0x04
+#define TIMER0_CTL_REG		0x10
+#define TIMER0_CTL_ENABLE		(1 << 0)
+#define TIMER0_CTL_AUTORELOAD		(1 << 1)
+#define TIMER0_CTL_ONESHOT		(1 << 7)
+#define TIMER0_INTVAL_REG	0x14
+#define TIMER0_CNTVAL_REG	0x18
+
+#define TIMER_SCAL		16
+
+static void __iomem *timer_base;
+
+static void sunxi_clkevt_mode(enum clock_event_mode mode,
+			      struct clock_event_device *clk)
+{
+	u32 u = readl(timer_base + TIMER0_CTL_REG);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		u &= ~(TIMER0_CTL_ONESHOT);
+		writel(u | TIMER0_CTL_ENABLE, timer_base + TIMER0_CTL_REG);
+		break;
+
+	case CLOCK_EVT_MODE_ONESHOT:
+		writel(u | TIMER0_CTL_ONESHOT, timer_base + TIMER0_CTL_REG);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	default:
+		writel(u & ~(TIMER0_CTL_ENABLE), timer_base + TIMER0_CTL_REG);
+		break;
+	}
+}
+
+static int sunxi_clkevt_next_event(unsigned long evt,
+				   struct clock_event_device *unused)
+{
+	u32 u = readl(timer_base + TIMER0_CTL_REG);
+	writel(evt, timer_base + TIMER0_CNTVAL_REG);
+	writel(u | TIMER0_CTL_ENABLE | TIMER0_CTL_AUTORELOAD,
+	       timer_base + TIMER0_CTL_REG);
+
+	return 0;
+}
+
+static struct clock_event_device sunxi_clockevent = {
+	.name = "sunxi_tick",
+	.shift = 32,
+	.rating = 300,
+	.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode = sunxi_clkevt_mode,
+	.set_next_event = sunxi_clkevt_next_event,
+};
+
+
+static irqreturn_t sunxi_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+
+	writel(0x1, timer_base + TIMER_IRQ_ST_REG);
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction sunxi_timer_irq = {
+	.name = "sunxi_timer0",
+	.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler = sunxi_timer_interrupt,
+	.dev_id = &sunxi_clockevent,
+};
+
+static struct of_device_id sunxi_timer_dt_ids[] = {
+	{ .compatible = "allwinner,sunxi-timer" },
+};
+
+static void __init sunxi_timer_init(void)
+{
+	struct device_node *node;
+	unsigned long rate = 0;
+	struct clk *clk;
+	int ret, irq;
+	u32 val;
+
+	node = of_find_matching_node(NULL, sunxi_timer_dt_ids);
+	if (!node)
+		panic("No sunxi timer node");
+
+	timer_base = of_iomap(node, 0);
+	if (!timer_base)
+		panic("Can't map registers");
+
+	irq = irq_of_parse_and_map(node, 0);
+	if (irq <= 0)
+		panic("Can't parse IRQ");
+
+	sunxi_init_clocks();
+
+	clk = of_clk_get(node, 0);
+	if (IS_ERR(clk))
+		panic("Can't get timer clock");
+
+	rate = clk_get_rate(clk);
+
+	writel(rate / (TIMER_SCAL * HZ),
+	       timer_base + TIMER0_INTVAL_REG);
+
+	/* set clock source to HOSC, 16 pre-division */
+	val = readl(timer_base + TIMER0_CTL_REG);
+	val &= ~(0x07 << 4);
+	val &= ~(0x03 << 2);
+	val |= (4 << 4) | (1 << 2);
+	writel(val, timer_base + TIMER0_CTL_REG);
+
+	/* set mode to auto reload */
+	val = readl(timer_base + TIMER0_CTL_REG);
+	writel(val | TIMER0_CTL_AUTORELOAD, timer_base + TIMER0_CTL_REG);
+
+	ret = setup_irq(irq, &sunxi_timer_irq);
+	if (ret)
+		pr_warn("failed to setup irq %d\n", irq);
+
+	/* Enable timer0 interrupt */
+	val = readl(timer_base + TIMER_CTL_REG);
+	writel(val | TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG);
+
+	sunxi_clockevent.mult = div_sc(rate / TIMER_SCAL,
+				NSEC_PER_SEC,
+				sunxi_clockevent.shift);
+	sunxi_clockevent.max_delta_ns = clockevent_delta2ns(0xff,
+							    &sunxi_clockevent);
+	sunxi_clockevent.min_delta_ns = clockevent_delta2ns(0x1,
+							    &sunxi_clockevent);
+	sunxi_clockevent.cpumask = cpumask_of(0);
+
+	clockevents_register_device(&sunxi_clockevent);
+}
+
+struct sys_timer sunxi_timer = {
+	.init = sunxi_timer_init,
+};
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index b40ee14..3998316 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -328,6 +328,7 @@
 		cpufreq_update_policy(cpu);
 		break;
 	case CPU_DOWN_PREPARE:
+	case CPU_DOWN_PREPARE_FROZEN:
 		cpufreq_stats_free_sysfs(cpu);
 		break;
 	case CPU_DEAD:
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 129e80b..e3ebb4f 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -5,7 +5,7 @@
  *  http://www.gnu.org/licenses/gpl.html
  *
  *  Maintainer:
- *  Andreas Herrmann <andreas.herrmann3@amd.com>
+ *  Andreas Herrmann <herrmann.der.user@googlemail.com>
  *
  *  Based on the powernow-k7.c module written by Dave Jones.
  *  (C) 2003 Dave Jones on behalf of SuSE Labs
@@ -1052,14 +1052,7 @@
 	struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq,
 					     .relation = relation };
 
-	/*
-	 * Must run on @pol->cpu.  cpufreq core is responsible for ensuring
-	 * that we're bound to the current CPU and pol->cpu stays online.
-	 */
-	if (smp_processor_id() == pol->cpu)
-		return powernowk8_target_fn(&pta);
-	else
-		return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
+	return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
 }
 
 /* Driver entry point to verify the policy and range of frequencies */
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index a76b689..d2d007b 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -21,3 +21,13 @@
 
 config ARCH_NEEDS_CPU_IDLE_COUPLED
 	def_bool n
+
+if CPU_IDLE
+
+config CPU_IDLE_CALXEDA
+	bool "CPU Idle Driver for Calxeda processors"
+	depends on ARCH_HIGHBANK
+	help
+	  Select this to enable cpuidle on Calxeda processors.
+
+endif
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 38c8f69..03ee874 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -4,3 +4,5 @@
 
 obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
 obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
+
+obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
diff --git a/drivers/cpuidle/cpuidle-calxeda.c b/drivers/cpuidle/cpuidle-calxeda.c
new file mode 100644
index 0000000..e1aab38
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-calxeda.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2012 Calxeda, Inc.
+ *
+ * Based on arch/arm/plat-mxc/cpuidle.c:
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/cpuidle.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/suspend.h>
+#include <asm/cpuidle.h>
+#include <asm/proc-fns.h>
+#include <asm/smp_scu.h>
+#include <asm/suspend.h>
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+
+extern void highbank_set_cpu_jump(int cpu, void *jump_addr);
+extern void *scu_base_addr;
+
+static struct cpuidle_device __percpu *calxeda_idle_cpuidle_devices;
+
+static inline unsigned int get_auxcr(void)
+{
+	unsigned int val;
+	asm("mrc p15, 0, %0, c1, c0, 1	@ get AUXCR" : "=r" (val) : : "cc");
+	return val;
+}
+
+static inline void set_auxcr(unsigned int val)
+{
+	asm volatile("mcr p15, 0, %0, c1, c0, 1	@ set AUXCR"
+	  : : "r" (val) : "cc");
+	isb();
+}
+
+static noinline void calxeda_idle_restore(void)
+{
+	set_cr(get_cr() | CR_C);
+	set_auxcr(get_auxcr() | 0x40);
+	scu_power_mode(scu_base_addr, SCU_PM_NORMAL);
+}
+
+static int calxeda_idle_finish(unsigned long val)
+{
+	/* Already flushed cache, but do it again as the outer cache functions
+	 * dirty the cache with spinlocks */
+	flush_cache_all();
+
+	set_auxcr(get_auxcr() & ~0x40);
+	set_cr(get_cr() & ~CR_C);
+
+	scu_power_mode(scu_base_addr, SCU_PM_DORMANT);
+
+	cpu_do_idle();
+
+	/* Restore things if we didn't enter power-gating */
+	calxeda_idle_restore();
+	return 1;
+}
+
+static int calxeda_pwrdown_idle(struct cpuidle_device *dev,
+				struct cpuidle_driver *drv,
+				int index)
+{
+	highbank_set_cpu_jump(smp_processor_id(), cpu_resume);
+	cpu_suspend(0, calxeda_idle_finish);
+	return index;
+}
+
+static void calxeda_idle_cpuidle_devices_uninit(void)
+{
+	int i;
+	struct cpuidle_device *dev;
+
+	for_each_possible_cpu(i) {
+		dev = per_cpu_ptr(calxeda_idle_cpuidle_devices, i);
+		cpuidle_unregister_device(dev);
+	}
+
+	free_percpu(calxeda_idle_cpuidle_devices);
+}
+
+static struct cpuidle_driver calxeda_idle_driver = {
+	.name = "calxeda_idle",
+	.en_core_tk_irqen = 1,
+	.states = {
+		ARM_CPUIDLE_WFI_STATE,
+		{
+			.name = "PG",
+			.desc = "Power Gate",
+			.flags = CPUIDLE_FLAG_TIME_VALID,
+			.exit_latency = 30,
+			.power_usage = 50,
+			.target_residency = 200,
+			.enter = calxeda_pwrdown_idle,
+		},
+	},
+	.state_count = 2,
+};
+
+static int __init calxeda_cpuidle_init(void)
+{
+	int cpu_id;
+	int ret;
+	struct cpuidle_device *dev;
+	struct cpuidle_driver *drv = &calxeda_idle_driver;
+
+	if (!of_machine_is_compatible("calxeda,highbank"))
+		return -ENODEV;
+
+	ret = cpuidle_register_driver(drv);
+	if (ret)
+		return ret;
+
+	calxeda_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device);
+	if (calxeda_idle_cpuidle_devices == NULL) {
+		ret = -ENOMEM;
+		goto unregister_drv;
+	}
+
+	/* initialize state data for each cpuidle_device */
+	for_each_possible_cpu(cpu_id) {
+		dev = per_cpu_ptr(calxeda_idle_cpuidle_devices, cpu_id);
+		dev->cpu = cpu_id;
+		dev->state_count = drv->state_count;
+
+		ret = cpuidle_register_device(dev);
+		if (ret) {
+			pr_err("Failed to register cpu %u, error: %d\n",
+			       cpu_id, ret);
+			goto uninit;
+		}
+	}
+
+	return 0;
+
+uninit:
+	calxeda_idle_cpuidle_devices_uninit();
+unregister_drv:
+	cpuidle_unregister_driver(drv);
+	return ret;
+}
+module_init(calxeda_cpuidle_init);
diff --git a/drivers/crypto/tegra-aes.c b/drivers/crypto/tegra-aes.c
index 37185e6..e69f3bc 100644
--- a/drivers/crypto/tegra-aes.c
+++ b/drivers/crypto/tegra-aes.c
@@ -41,8 +41,6 @@
 #include <linux/completion.h>
 #include <linux/workqueue.h>
 
-#include <mach/clk.h>
-
 #include <crypto/scatterwalk.h>
 #include <crypto/aes.h>
 #include <crypto/internal/rng.h>
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 677cd6e..d4c1218 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -90,6 +90,17 @@
 	  Support the Synopsys DesignWare AHB DMA controller.  This
 	  can be integrated in chips such as the Atmel AT32ap7000.
 
+config DW_DMAC_BIG_ENDIAN_IO
+	bool "Use big endian I/O register access"
+	default y if AVR32
+	depends on DW_DMAC
+	help
+	  Say yes here to use big endian I/O access when reading and writing
+	  to the DMA controller registers. This is needed on some platforms,
+	  like the Atmel AVR32 architecture.
+
+	  If unsure, use the default setting.
+
 config AT_HDMAC
 	tristate "Atmel AHB DMA support"
 	depends on ARCH_AT91
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index ff39fa6..8896559 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -98,9 +98,17 @@
 	u32	DW_PARAMS;
 };
 
+#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
+#define dma_readl_native ioread32be
+#define dma_writel_native iowrite32be
+#else
+#define dma_readl_native readl
+#define dma_writel_native writel
+#endif
+
 /* To access the registers in early stage of probe */
 #define dma_read_byaddr(addr, name) \
-	readl((addr) + offsetof(struct dw_dma_regs, name))
+	dma_readl_native((addr) + offsetof(struct dw_dma_regs, name))
 
 /* Bitfields in DW_PARAMS */
 #define DW_PARAMS_NR_CHAN	8		/* number of channels */
@@ -216,9 +224,9 @@
 }
 
 #define channel_readl(dwc, name) \
-	readl(&(__dwc_regs(dwc)->name))
+	dma_readl_native(&(__dwc_regs(dwc)->name))
 #define channel_writel(dwc, name, val) \
-	writel((val), &(__dwc_regs(dwc)->name))
+	dma_writel_native((val), &(__dwc_regs(dwc)->name))
 
 static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
 {
@@ -246,9 +254,9 @@
 }
 
 #define dma_readl(dw, name) \
-	readl(&(__dw_regs(dw)->name))
+	dma_readl_native(&(__dw_regs(dw)->name))
 #define dma_writel(dw, name, val) \
-	writel((val), &(__dw_regs(dw)->name))
+	dma_writel_native((val), &(__dw_regs(dw)->name))
 
 #define channel_set_bit(dw, reg, mask) \
 	dma_writel(dw, reg, ((mask) << 8) | (mask))
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index f11b5b2..dbf0e6f 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -29,7 +29,6 @@
 
 #include <asm/irq.h>
 #include <linux/platform_data/dma-imx.h>
-#include <mach/hardware.h>
 
 #include "dmaengine.h"
 #define IMXDMA_MAX_CHAN_DESCRIPTORS	16
@@ -167,6 +166,12 @@
 	int				slot_2d;
 };
 
+enum imx_dma_type {
+	IMX1_DMA,
+	IMX21_DMA,
+	IMX27_DMA,
+};
+
 struct imxdma_engine {
 	struct device			*dev;
 	struct device_dma_parameters	dma_parms;
@@ -177,8 +182,40 @@
 	spinlock_t			lock;
 	struct imx_dma_2d_config	slots_2d[IMX_DMA_2D_SLOTS];
 	struct imxdma_channel		channel[IMX_DMA_CHANNELS];
+	enum imx_dma_type		devtype;
 };
 
+static struct platform_device_id imx_dma_devtype[] = {
+	{
+		.name = "imx1-dma",
+		.driver_data = IMX1_DMA,
+	}, {
+		.name = "imx21-dma",
+		.driver_data = IMX21_DMA,
+	}, {
+		.name = "imx27-dma",
+		.driver_data = IMX27_DMA,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, imx_dma_devtype);
+
+static inline int is_imx1_dma(struct imxdma_engine *imxdma)
+{
+	return imxdma->devtype == IMX1_DMA;
+}
+
+static inline int is_imx21_dma(struct imxdma_engine *imxdma)
+{
+	return imxdma->devtype == IMX21_DMA;
+}
+
+static inline int is_imx27_dma(struct imxdma_engine *imxdma)
+{
+	return imxdma->devtype == IMX27_DMA;
+}
+
 static struct imxdma_channel *to_imxdma_chan(struct dma_chan *chan)
 {
 	return container_of(chan, struct imxdma_channel, chan);
@@ -212,7 +249,9 @@
 
 static int imxdma_hw_chain(struct imxdma_channel *imxdmac)
 {
-	if (cpu_is_mx27())
+	struct imxdma_engine *imxdma = imxdmac->imxdma;
+
+	if (is_imx27_dma(imxdma))
 		return imxdmac->hw_chaining;
 	else
 		return 0;
@@ -267,7 +306,7 @@
 	imx_dmav1_writel(imxdma, imx_dmav1_readl(imxdma, DMA_CCR(channel)) |
 			 CCR_CEN | CCR_ACRPT, DMA_CCR(channel));
 
-	if ((cpu_is_mx21() || cpu_is_mx27()) &&
+	if (!is_imx1_dma(imxdma) &&
 			d->sg && imxdma_hw_chain(imxdmac)) {
 		d->sg = sg_next(d->sg);
 		if (d->sg) {
@@ -436,7 +475,7 @@
 	struct imxdma_engine *imxdma = dev_id;
 	int i, disr;
 
-	if (cpu_is_mx21() || cpu_is_mx27())
+	if (!is_imx1_dma(imxdma))
 		imxdma_err_handler(irq, dev_id);
 
 	disr = imx_dmav1_readl(imxdma, DMA_DISR);
@@ -474,8 +513,10 @@
 			slot = i;
 			break;
 		}
-		if (slot < 0)
+		if (slot < 0) {
+			spin_unlock_irqrestore(&imxdma->lock, flags);
 			return -EBUSY;
+		}
 
 		imxdma->slots_2d[slot].xsr = d->x;
 		imxdma->slots_2d[slot].ysr = d->y;
@@ -959,35 +1000,32 @@
 static int __init imxdma_probe(struct platform_device *pdev)
 	{
 	struct imxdma_engine *imxdma;
+	struct resource *res;
 	int ret, i;
+	int irq, irq_err;
 
-
-	imxdma = kzalloc(sizeof(*imxdma), GFP_KERNEL);
+	imxdma = devm_kzalloc(&pdev->dev, sizeof(*imxdma), GFP_KERNEL);
 	if (!imxdma)
 		return -ENOMEM;
 
-	if (cpu_is_mx1()) {
-		imxdma->base = MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR);
-	} else if (cpu_is_mx21()) {
-		imxdma->base = MX21_IO_ADDRESS(MX21_DMA_BASE_ADDR);
-	} else if (cpu_is_mx27()) {
-		imxdma->base = MX27_IO_ADDRESS(MX27_DMA_BASE_ADDR);
-	} else {
-		kfree(imxdma);
-		return 0;
-	}
+	imxdma->devtype = pdev->id_entry->driver_data;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	imxdma->base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!imxdma->base)
+		return -EADDRNOTAVAIL;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
 
 	imxdma->dma_ipg = devm_clk_get(&pdev->dev, "ipg");
-	if (IS_ERR(imxdma->dma_ipg)) {
-		ret = PTR_ERR(imxdma->dma_ipg);
-		goto err_clk;
-	}
+	if (IS_ERR(imxdma->dma_ipg))
+		return PTR_ERR(imxdma->dma_ipg);
 
 	imxdma->dma_ahb = devm_clk_get(&pdev->dev, "ahb");
-	if (IS_ERR(imxdma->dma_ahb)) {
-		ret = PTR_ERR(imxdma->dma_ahb);
-		goto err_clk;
-	}
+	if (IS_ERR(imxdma->dma_ahb))
+		return PTR_ERR(imxdma->dma_ahb);
 
 	clk_prepare_enable(imxdma->dma_ipg);
 	clk_prepare_enable(imxdma->dma_ahb);
@@ -995,18 +1033,25 @@
 	/* reset DMA module */
 	imx_dmav1_writel(imxdma, DCR_DRST, DMA_DCR);
 
-	if (cpu_is_mx1()) {
-		ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", imxdma);
+	if (is_imx1_dma(imxdma)) {
+		ret = devm_request_irq(&pdev->dev, irq,
+				       dma_irq_handler, 0, "DMA", imxdma);
 		if (ret) {
 			dev_warn(imxdma->dev, "Can't register IRQ for DMA\n");
-			goto err_enable;
+			goto err;
 		}
 
-		ret = request_irq(MX1_DMA_ERR, imxdma_err_handler, 0, "DMA", imxdma);
+		irq_err = platform_get_irq(pdev, 1);
+		if (irq_err < 0) {
+			ret = irq_err;
+			goto err;
+		}
+
+		ret = devm_request_irq(&pdev->dev, irq_err,
+				       imxdma_err_handler, 0, "DMA", imxdma);
 		if (ret) {
 			dev_warn(imxdma->dev, "Can't register ERRIRQ for DMA\n");
-			free_irq(MX1_DMA_INT, NULL);
-			goto err_enable;
+			goto err;
 		}
 	}
 
@@ -1036,14 +1081,14 @@
 	for (i = 0; i < IMX_DMA_CHANNELS; i++) {
 		struct imxdma_channel *imxdmac = &imxdma->channel[i];
 
-		if (cpu_is_mx21() || cpu_is_mx27()) {
-			ret = request_irq(MX2x_INT_DMACH0 + i,
+		if (!is_imx1_dma(imxdma)) {
+			ret = devm_request_irq(&pdev->dev, irq + i,
 					dma_irq_handler, 0, "DMA", imxdma);
 			if (ret) {
 				dev_warn(imxdma->dev, "Can't register IRQ %d "
 					 "for DMA channel %d\n",
-					 MX2x_INT_DMACH0 + i, i);
-				goto err_init;
+					 irq + i, i);
+				goto err;
 			}
 			init_timer(&imxdmac->watchdog);
 			imxdmac->watchdog.function = &imxdma_watchdog;
@@ -1089,46 +1134,25 @@
 	ret = dma_async_device_register(&imxdma->dma_device);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to register\n");
-		goto err_init;
+		goto err;
 	}
 
 	return 0;
 
-err_init:
-
-	if (cpu_is_mx21() || cpu_is_mx27()) {
-		while (--i >= 0)
-			free_irq(MX2x_INT_DMACH0 + i, NULL);
-	} else if cpu_is_mx1() {
-		free_irq(MX1_DMA_INT, NULL);
-		free_irq(MX1_DMA_ERR, NULL);
-	}
-err_enable:
+err:
 	clk_disable_unprepare(imxdma->dma_ipg);
 	clk_disable_unprepare(imxdma->dma_ahb);
-err_clk:
-	kfree(imxdma);
 	return ret;
 }
 
 static int __exit imxdma_remove(struct platform_device *pdev)
 {
 	struct imxdma_engine *imxdma = platform_get_drvdata(pdev);
-	int i;
 
         dma_async_device_unregister(&imxdma->dma_device);
 
-	if (cpu_is_mx21() || cpu_is_mx27()) {
-		for (i = 0; i < IMX_DMA_CHANNELS; i++)
-			free_irq(MX2x_INT_DMACH0 + i, NULL);
-	} else if cpu_is_mx1() {
-		free_irq(MX1_DMA_INT, NULL);
-		free_irq(MX1_DMA_ERR, NULL);
-	}
-
 	clk_disable_unprepare(imxdma->dma_ipg);
 	clk_disable_unprepare(imxdma->dma_ahb);
-	kfree(imxdma);
 
         return 0;
 }
@@ -1137,6 +1161,7 @@
 	.driver		= {
 		.name	= "imx-dma",
 	},
+	.id_table	= imx_dma_devtype,
 	.remove		= __exit_p(imxdma_remove),
 };
 
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index c099ca0..f082aa3 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -40,7 +40,6 @@
 #include <asm/irq.h>
 #include <linux/platform_data/dma-imx-sdma.h>
 #include <linux/platform_data/dma-imx.h>
-#include <mach/hardware.h>
 
 #include "dmaengine.h"
 
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index c7573e5..6585537 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -22,8 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
-
-#include <mach/ipu.h>
+#include <linux/dma/ipu-dma.h>
 
 #include "../dmaengine.h"
 #include "ipu_intern.h"
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
index fa95bcc..a5ee37d 100644
--- a/drivers/dma/ipu/ipu_irq.c
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -15,8 +15,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/module.h>
-
-#include <mach/ipu.h>
+#include <linux/dma/ipu-dma.h>
 
 #include "ipu_intern.h"
 
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 64385cd..d451caa 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -109,7 +109,7 @@
 	sdesc = list_first_entry(&schan->queued, struct sirfsoc_dma_desc,
 		node);
 	/* Move the first queued descriptor to active list */
-	list_move_tail(&schan->queued, &schan->active);
+	list_move_tail(&sdesc->node, &schan->active);
 
 	/* Start the DMA transfer */
 	writel_relaxed(sdesc->width, sdma->base + SIRFSOC_DMA_WIDTH_0 +
@@ -428,7 +428,7 @@
 	unsigned long iflags;
 	int ret;
 
-	if ((xt->dir != DMA_MEM_TO_DEV) || (xt->dir != DMA_DEV_TO_MEM)) {
+	if ((xt->dir != DMA_MEM_TO_DEV) && (xt->dir != DMA_DEV_TO_MEM)) {
 		ret = -EINVAL;
 		goto err_dir;
 	}
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 5a297a2..cc8e7c7 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -170,8 +170,11 @@
 	 * memory controller and apply to register. Search for the first
 	 * bandwidth entry that is greater or equal than the setting requested
 	 * and program that. If at last entry, turn off DRAM scrubbing.
+	 *
+	 * If no suitable bandwidth is found, turn off DRAM scrubbing entirely
+	 * by falling back to the last element in scrubrates[].
 	 */
-	for (i = 0; i < ARRAY_SIZE(scrubrates); i++) {
+	for (i = 0; i < ARRAY_SIZE(scrubrates) - 1; i++) {
 		/*
 		 * skip scrub rates which aren't recommended
 		 * (see F10 BKDG, F3x58)
@@ -181,12 +184,6 @@
 
 		if (scrubrates[i].bandwidth <= new_bw)
 			break;
-
-		/*
-		 * if no suitable bandwidth found, turn off DRAM scrubbing
-		 * entirely by falling back to the last element in the
-		 * scrubrates array.
-		 */
 	}
 
 	scrubval = scrubrates[i].scrubval;
diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c
index 725eb5a..e87196f 100644
--- a/drivers/extcon/extcon-adc-jack.c
+++ b/drivers/extcon/extcon-adc-jack.c
@@ -14,6 +14,7 @@
  *
  */
 
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
@@ -161,13 +162,12 @@
 	err = request_any_context_irq(data->irq, adc_jack_irq_thread,
 			pdata->irq_flags, pdata->name, data);
 
-	if (err) {
+	if (err < 0) {
 		dev_err(&pdev->dev, "error: irq %d\n", data->irq);
-		err = -EINVAL;
 		goto err_irq;
 	}
 
-	goto out;
+	return 0;
 
 err_irq:
 	extcon_dev_unregister(&data->edev);
@@ -196,3 +196,7 @@
 };
 
 module_platform_driver(adc_jack_driver);
+
+MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
+MODULE_DESCRIPTION("ADC Jack extcon driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
index 946a318..d398821 100644
--- a/drivers/extcon/extcon-class.c
+++ b/drivers/extcon/extcon-class.c
@@ -41,7 +41,7 @@
  * every single port-type of the following cable names. Please choose cable
  * names that are actually used in your extcon device.
  */
-const char *extcon_cable_name[] = {
+const char extcon_cable_name[][CABLE_NAME_MAX + 1] = {
 	[EXTCON_USB]		= "USB",
 	[EXTCON_USB_HOST]	= "USB-Host",
 	[EXTCON_TA]		= "TA",
@@ -62,8 +62,6 @@
 	[EXTCON_VIDEO_IN]	= "Video-in",
 	[EXTCON_VIDEO_OUT]	= "Video-out",
 	[EXTCON_MECHANICAL]	= "Mechanical",
-
-	NULL,
 };
 
 static struct class *extcon_class;
@@ -91,17 +89,13 @@
 		return 0;
 
 	for (i = 0; edev->mutually_exclusive[i]; i++) {
-		int count = 0, j;
+		int weight;
 		u32 correspondants = new_state & edev->mutually_exclusive[i];
-		u32 exp = 1;
 
-		for (j = 0; j < 32; j++) {
-			if (exp & correspondants)
-				count++;
-			if (count > 1)
-				return i + 1;
-			exp <<= 1;
-		}
+		/* calculate the total number of bits set */
+		weight = hweight32(correspondants);
+		if (weight > 1)
+			return i + 1;
 	}
 
 	return 0;
@@ -362,7 +356,7 @@
 EXPORT_SYMBOL_GPL(extcon_get_cable_state);
 
 /**
- * extcon_get_cable_state_() - Set the status of a specific cable.
+ * extcon_set_cable_state_() - Set the status of a specific cable.
  * @edev:	the extcon device that has the cable.
  * @index:	cable index that can be retrieved by extcon_find_cable_index().
  * @cable_state:	the new cable status. The default semantics is
@@ -382,7 +376,7 @@
 EXPORT_SYMBOL_GPL(extcon_set_cable_state_);
 
 /**
- * extcon_get_cable_state() - Set the status of a specific cable.
+ * extcon_set_cable_state() - Set the status of a specific cable.
  * @edev:	the extcon device that has the cable.
  * @cable_name:	cable name.
  * @cable_state:	the new cable status. The default semantics is
@@ -447,6 +441,8 @@
  *			      extcon device.
  * @obj:	an empty extcon_specific_cable_nb object to be returned.
  * @extcon_name:	the name of extcon device.
+ *			if NULL, extcon_register_interest will register
+ *			every cable with the target cable_name given.
  * @cable_name:		the target cable name.
  * @nb:		the notifier block to get notified.
  *
@@ -466,22 +462,44 @@
 			     const char *extcon_name, const char *cable_name,
 			     struct notifier_block *nb)
 {
-	if (!obj || !extcon_name || !cable_name || !nb)
+	if (!obj || !cable_name || !nb)
 		return -EINVAL;
 
-	obj->edev = extcon_get_extcon_dev(extcon_name);
-	if (!obj->edev)
+	if (extcon_name) {
+		obj->edev = extcon_get_extcon_dev(extcon_name);
+		if (!obj->edev)
+			return -ENODEV;
+
+		obj->cable_index = extcon_find_cable_index(obj->edev, cable_name);
+		if (obj->cable_index < 0)
+			return -ENODEV;
+
+		obj->user_nb = nb;
+
+		obj->internal_nb.notifier_call = _call_per_cable;
+
+		return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb);
+	} else {
+		struct class_dev_iter iter;
+		struct extcon_dev *extd;
+		struct device *dev;
+
+		if (!extcon_class)
+			return -ENODEV;
+		class_dev_iter_init(&iter, extcon_class, NULL, NULL);
+		while ((dev = class_dev_iter_next(&iter))) {
+			extd = (struct extcon_dev *)dev_get_drvdata(dev);
+
+			if (extcon_find_cable_index(extd, cable_name) < 0)
+				continue;
+
+			class_dev_iter_exit(&iter);
+			return extcon_register_interest(obj, extd->name,
+						cable_name, nb);
+		}
+
 		return -ENODEV;
-
-	obj->cable_index = extcon_find_cable_index(obj->edev, cable_name);
-	if (obj->cable_index < 0)
-		return -ENODEV;
-
-	obj->user_nb = nb;
-
-	obj->internal_nb.notifier_call = _call_per_cable;
-
-	return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb);
+	}
 }
 
 /**
@@ -551,43 +569,9 @@
 	return 0;
 }
 
-static void extcon_cleanup(struct extcon_dev *edev, bool skip)
-{
-	mutex_lock(&extcon_dev_list_lock);
-	list_del(&edev->entry);
-	mutex_unlock(&extcon_dev_list_lock);
-
-	if (!skip && get_device(edev->dev)) {
-		int index;
-
-		if (edev->mutually_exclusive && edev->max_supported) {
-			for (index = 0; edev->mutually_exclusive[index];
-			     index++)
-				kfree(edev->d_attrs_muex[index].attr.name);
-			kfree(edev->d_attrs_muex);
-			kfree(edev->attrs_muex);
-		}
-
-		for (index = 0; index < edev->max_supported; index++)
-			kfree(edev->cables[index].attr_g.name);
-
-		if (edev->max_supported) {
-			kfree(edev->extcon_dev_type.groups);
-			kfree(edev->cables);
-		}
-
-		device_unregister(edev->dev);
-		put_device(edev->dev);
-	}
-
-	kfree(edev->dev);
-}
-
 static void extcon_dev_release(struct device *dev)
 {
-	struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev);
-
-	extcon_cleanup(edev, true);
+	kfree(dev);
 }
 
 static const char *muex_name = "mutually_exclusive";
@@ -813,7 +797,40 @@
  */
 void extcon_dev_unregister(struct extcon_dev *edev)
 {
-	extcon_cleanup(edev, false);
+	int index;
+
+	mutex_lock(&extcon_dev_list_lock);
+	list_del(&edev->entry);
+	mutex_unlock(&extcon_dev_list_lock);
+
+	if (IS_ERR_OR_NULL(get_device(edev->dev))) {
+		dev_err(edev->dev, "Failed to unregister extcon_dev (%s)\n",
+				dev_name(edev->dev));
+		return;
+	}
+
+	if (edev->mutually_exclusive && edev->max_supported) {
+		for (index = 0; edev->mutually_exclusive[index];
+				index++)
+			kfree(edev->d_attrs_muex[index].attr.name);
+		kfree(edev->d_attrs_muex);
+		kfree(edev->attrs_muex);
+	}
+
+	for (index = 0; index < edev->max_supported; index++)
+		kfree(edev->cables[index].attr_g.name);
+
+	if (edev->max_supported) {
+		kfree(edev->extcon_dev_type.groups);
+		kfree(edev->cables);
+	}
+
+#if defined(CONFIG_ANDROID)
+	if (switch_class)
+		class_compat_remove_link(switch_class, edev->dev, NULL);
+#endif
+	device_unregister(edev->dev);
+	put_device(edev->dev);
 }
 EXPORT_SYMBOL_GPL(extcon_dev_unregister);
 
@@ -825,6 +842,9 @@
 
 static void __exit extcon_class_exit(void)
 {
+#if defined(CONFIG_ANDROID)
+	class_compat_unregister(switch_class);
+#endif
 	class_destroy(extcon_class);
 }
 module_exit(extcon_class_exit);
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c
index 3cc152e..71d3ab7b3 100644
--- a/drivers/extcon/extcon-gpio.c
+++ b/drivers/extcon/extcon-gpio.c
@@ -26,7 +26,6 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/extcon.h>
 #include <linux/workqueue.h>
 #include <linux/gpio.h>
 #include <linux/extcon.h>
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
index e21387e..a17d0d9 100644
--- a/drivers/extcon/extcon-max77693.c
+++ b/drivers/extcon/extcon-max77693.c
@@ -239,25 +239,19 @@
 static int max77693_muic_set_debounce_time(struct max77693_muic_info *info,
 		enum max77693_muic_adc_debounce_time time)
 {
-	int ret = 0;
-	u8 ctrl3;
+	int ret;
 
 	switch (time) {
 	case ADC_DEBOUNCE_TIME_5MS:
 	case ADC_DEBOUNCE_TIME_10MS:
 	case ADC_DEBOUNCE_TIME_25MS:
 	case ADC_DEBOUNCE_TIME_38_62MS:
-		ret = max77693_read_reg(info->max77693->regmap_muic,
-				MAX77693_MUIC_REG_CTRL3, &ctrl3);
-		ctrl3 &= ~CONTROL3_ADCDBSET_MASK;
-		ctrl3 |= (time << CONTROL3_ADCDBSET_SHIFT);
-
-		ret = max77693_write_reg(info->max77693->regmap_muic,
-				MAX77693_MUIC_REG_CTRL3, ctrl3);
-		if (ret) {
+		ret = max77693_update_reg(info->max77693->regmap_muic,
+					  MAX77693_MUIC_REG_CTRL3,
+					  time << CONTROL3_ADCDBSET_SHIFT,
+					  CONTROL3_ADCDBSET_MASK);
+		if (ret)
 			dev_err(info->dev, "failed to set ADC debounce time\n");
-			ret = -EINVAL;
-		}
 		break;
 	default:
 		dev_err(info->dev, "invalid ADC debounce time\n");
@@ -657,6 +651,8 @@
 static int __devinit max77693_muic_probe(struct platform_device *pdev)
 {
 	struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
+	struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev);
+	struct max77693_muic_platform_data *muic_pdata = pdata->muic_data;
 	struct max77693_muic_info *info;
 	int ret, i;
 	u8 id;
@@ -727,6 +723,31 @@
 		goto err_extcon;
 	}
 
+	/* Initialize MUIC register by using platform data */
+	for (i = 0 ; i < muic_pdata->num_init_data ; i++) {
+		enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR;
+
+		max77693_write_reg(info->max77693->regmap_muic,
+				muic_pdata->init_data[i].addr,
+				muic_pdata->init_data[i].data);
+
+		switch (muic_pdata->init_data[i].addr) {
+		case MAX77693_MUIC_REG_INTMASK1:
+			irq_src = MUIC_INT1;
+			break;
+		case MAX77693_MUIC_REG_INTMASK2:
+			irq_src = MUIC_INT2;
+			break;
+		case MAX77693_MUIC_REG_INTMASK3:
+			irq_src = MUIC_INT3;
+			break;
+		}
+
+		if (irq_src < MAX77693_IRQ_GROUP_NR)
+			info->max77693->irq_masks_cur[irq_src]
+				= muic_pdata->init_data[i].data;
+	}
+
 	/* Check revision number of MUIC device*/
 	ret = max77693_read_reg(info->max77693->regmap_muic,
 			MAX77693_MUIC_REG_ID, &id);
@@ -762,6 +783,7 @@
 		free_irq(muic_irqs[i].virq, info);
 	cancel_work_sync(&info->irq_work);
 	extcon_dev_unregister(info->edev);
+	kfree(info->edev);
 	kfree(info);
 
 	return 0;
diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c
index ef9090a..77b66b0 100644
--- a/drivers/extcon/extcon-max8997.c
+++ b/drivers/extcon/extcon-max8997.c
@@ -271,8 +271,6 @@
 static int max8997_muic_handle_charger_type_detach(
 				struct max8997_muic_info *info)
 {
-	int ret = 0;
-
 	switch (info->pre_charger_type) {
 	case MAX8997_CHARGER_TYPE_USB:
 		extcon_set_cable_state(info->edev, "USB", false);
@@ -290,11 +288,11 @@
 		extcon_set_cable_state(info->edev, "Fast-charger", false);
 		break;
 	default:
-		ret = -EINVAL;
+		return -EINVAL;
 		break;
 	}
 
-	return ret;
+	return 0;
 }
 
 static int max8997_muic_handle_charger_type(struct max8997_muic_info *info,
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d055cee..998bd7c 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -47,7 +47,7 @@
 
 config OF_GPIO
 	def_bool y
-	depends on OF && !SPARC
+	depends on OF
 
 config DEBUG_GPIO
 	bool "Debug GPIO calls"
@@ -86,11 +86,26 @@
 	help
 	  Say yes here to enable the GPIO driver for the DA9052 chip.
 
+config GPIO_DA9055
+	tristate "Dialog Semiconductor DA9055 GPIO"
+	depends on MFD_DA9055
+	help
+	  Say yes here to enable the GPIO driver for the DA9055 chip.
+
+	  The Dialog DA9055 PMIC chip has 3 GPIO pins that can be
+	  be controller by this driver.
+
+	  If driver is built as a module it will be called gpio-da9055.
+
 config GPIO_MAX730X
 	tristate
 
 comment "Memory mapped GPIO drivers:"
 
+config GPIO_CLPS711X
+	def_bool y
+	depends on ARCH_CLPS711X
+
 config GPIO_GENERIC_PLATFORM
 	tristate "Generic memory-mapped GPIO controller support (MMIO platform device)"
 	select GPIO_GENERIC
@@ -181,6 +196,13 @@
 	help
 	  Say yes here to support the PXA GPIO device
 
+config GPIO_SPEAR_SPICS
+	bool "ST SPEAr13xx SPI Chip Select as GPIO support"
+	depends on PLAT_SPEAR
+	select GENERIC_IRQ_CHIP
+	help
+	  Say yes here to support ST SPEAr SPI Chip Select as GPIO device
+
 config GPIO_STA2X11
 	bool "STA2x11/ConneXt GPIO support"
 	depends on MFD_STA2X11
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 9aeed67..a268d99 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -16,8 +16,10 @@
 obj-$(CONFIG_GPIO_AMD8111)	+= gpio-amd8111.o
 obj-$(CONFIG_GPIO_ARIZONA)	+= gpio-arizona.o
 obj-$(CONFIG_GPIO_BT8XX)	+= gpio-bt8xx.o
+obj-$(CONFIG_GPIO_CLPS711X)	+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_CS5535)	+= gpio-cs5535.o
 obj-$(CONFIG_GPIO_DA9052)	+= gpio-da9052.o
+obj-$(CONFIG_GPIO_DA9055)	+= gpio-da9055.o
 obj-$(CONFIG_ARCH_DAVINCI)	+= gpio-davinci.o
 obj-$(CONFIG_GPIO_EM)		+= gpio-em.o
 obj-$(CONFIG_GPIO_EP93XX)	+= gpio-ep93xx.o
@@ -57,6 +59,7 @@
 obj-$(CONFIG_ARCH_SA1100)	+= gpio-sa1100.o
 obj-$(CONFIG_GPIO_SCH)		+= gpio-sch.o
 obj-$(CONFIG_GPIO_SODAVILLE)	+= gpio-sodaville.o
+obj-$(CONFIG_GPIO_SPEAR_SPICS)	+= gpio-spear-spics.o
 obj-$(CONFIG_GPIO_STA2X11)	+= gpio-sta2x11.o
 obj-$(CONFIG_GPIO_STMPE)	+= gpio-stmpe.o
 obj-$(CONFIG_GPIO_STP_XWAY)	+= gpio-stp-xway.o
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c
index ed3e551..f05e542 100644
--- a/drivers/gpio/gpio-74x164.c
+++ b/drivers/gpio/gpio-74x164.c
@@ -153,7 +153,7 @@
 	}
 
 	chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers;
-	chip->buffer = devm_kzalloc(&spi->dev, chip->gpio_chip.ngpio, GFP_KERNEL);
+	chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL);
 	if (!chip->buffer) {
 		ret = -ENOMEM;
 		goto exit_destroy;
diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c
new file mode 100644
index 0000000..ce63b75
--- /dev/null
+++ b/drivers/gpio/gpio-clps711x.c
@@ -0,0 +1,199 @@
+/*
+ *  CLPS711X GPIO driver
+ *
+ *  Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+
+#define CLPS711X_GPIO_PORTS	5
+#define CLPS711X_GPIO_NAME	"gpio-clps711x"
+
+struct clps711x_gpio {
+	struct gpio_chip	chip[CLPS711X_GPIO_PORTS];
+	spinlock_t		lock;
+};
+
+static void __iomem *clps711x_ports[] = {
+	CLPS711X_VIRT_BASE + PADR,
+	CLPS711X_VIRT_BASE + PBDR,
+	CLPS711X_VIRT_BASE + PCDR,
+	CLPS711X_VIRT_BASE + PDDR,
+	CLPS711X_VIRT_BASE + PEDR,
+};
+
+static void __iomem *clps711x_pdirs[] = {
+	CLPS711X_VIRT_BASE + PADDR,
+	CLPS711X_VIRT_BASE + PBDDR,
+	CLPS711X_VIRT_BASE + PCDDR,
+	CLPS711X_VIRT_BASE + PDDDR,
+	CLPS711X_VIRT_BASE + PEDDR,
+};
+
+#define clps711x_port(x)	clps711x_ports[x->base / 8]
+#define clps711x_pdir(x)	clps711x_pdirs[x->base / 8]
+
+static int gpio_clps711x_get(struct gpio_chip *chip, unsigned offset)
+{
+	return !!(readb(clps711x_port(chip)) & (1 << offset));
+}
+
+static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset,
+			      int value)
+{
+	int tmp;
+	unsigned long flags;
+	struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+
+	spin_lock_irqsave(&gpio->lock, flags);
+	tmp = readb(clps711x_port(chip)) & ~(1 << offset);
+	if (value)
+		tmp |= 1 << offset;
+	writeb(tmp, clps711x_port(chip));
+	spin_unlock_irqrestore(&gpio->lock, flags);
+}
+
+static int gpio_clps711x_dir_in(struct gpio_chip *chip, unsigned offset)
+{
+	int tmp;
+	unsigned long flags;
+	struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+
+	spin_lock_irqsave(&gpio->lock, flags);
+	tmp = readb(clps711x_pdir(chip)) & ~(1 << offset);
+	writeb(tmp, clps711x_pdir(chip));
+	spin_unlock_irqrestore(&gpio->lock, flags);
+
+	return 0;
+}
+
+static int gpio_clps711x_dir_out(struct gpio_chip *chip, unsigned offset,
+				 int value)
+{
+	int tmp;
+	unsigned long flags;
+	struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+
+	spin_lock_irqsave(&gpio->lock, flags);
+	tmp = readb(clps711x_pdir(chip)) | (1 << offset);
+	writeb(tmp, clps711x_pdir(chip));
+	tmp = readb(clps711x_port(chip)) & ~(1 << offset);
+	if (value)
+		tmp |= 1 << offset;
+	writeb(tmp, clps711x_port(chip));
+	spin_unlock_irqrestore(&gpio->lock, flags);
+
+	return 0;
+}
+
+static int gpio_clps711x_dir_in_inv(struct gpio_chip *chip, unsigned offset)
+{
+	int tmp;
+	unsigned long flags;
+	struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+
+	spin_lock_irqsave(&gpio->lock, flags);
+	tmp = readb(clps711x_pdir(chip)) | (1 << offset);
+	writeb(tmp, clps711x_pdir(chip));
+	spin_unlock_irqrestore(&gpio->lock, flags);
+
+	return 0;
+}
+
+static int gpio_clps711x_dir_out_inv(struct gpio_chip *chip, unsigned offset,
+				     int value)
+{
+	int tmp;
+	unsigned long flags;
+	struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+
+	spin_lock_irqsave(&gpio->lock, flags);
+	tmp = readb(clps711x_pdir(chip)) & ~(1 << offset);
+	writeb(tmp, clps711x_pdir(chip));
+	tmp = readb(clps711x_port(chip)) & ~(1 << offset);
+	if (value)
+		tmp |= 1 << offset;
+	writeb(tmp, clps711x_port(chip));
+	spin_unlock_irqrestore(&gpio->lock, flags);
+
+	return 0;
+}
+
+static struct {
+	char	*name;
+	int	nr;
+	int	inv_dir;
+} clps711x_gpio_ports[] __initconst = {
+	{ "PORTA", 8, 0, },
+	{ "PORTB", 8, 0, },
+	{ "PORTC", 8, 0, },
+	{ "PORTD", 8, 1, },
+	{ "PORTE", 3, 0, },
+};
+
+static int __init gpio_clps711x_init(void)
+{
+	int i;
+	struct platform_device *pdev;
+	struct clps711x_gpio *gpio;
+
+	pdev = platform_device_alloc(CLPS711X_GPIO_NAME, 0);
+	if (!pdev) {
+		pr_err("Cannot create platform device: %s\n",
+		       CLPS711X_GPIO_NAME);
+		return -ENOMEM;
+	}
+
+	platform_device_add(pdev);
+
+	gpio = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_gpio),
+			    GFP_KERNEL);
+	if (!gpio) {
+		dev_err(&pdev->dev, "GPIO allocating memory error\n");
+		platform_device_unregister(pdev);
+		return -ENOMEM;
+	}
+
+	platform_set_drvdata(pdev, gpio);
+
+	spin_lock_init(&gpio->lock);
+
+	for (i = 0; i < CLPS711X_GPIO_PORTS; i++) {
+		gpio->chip[i].owner		= THIS_MODULE;
+		gpio->chip[i].dev		= &pdev->dev;
+		gpio->chip[i].label		= clps711x_gpio_ports[i].name;
+		gpio->chip[i].base		= i * 8;
+		gpio->chip[i].ngpio		= clps711x_gpio_ports[i].nr;
+		gpio->chip[i].get		= gpio_clps711x_get;
+		gpio->chip[i].set		= gpio_clps711x_set;
+		if (!clps711x_gpio_ports[i].inv_dir) {
+			gpio->chip[i].direction_input = gpio_clps711x_dir_in;
+			gpio->chip[i].direction_output = gpio_clps711x_dir_out;
+		} else {
+			gpio->chip[i].direction_input = gpio_clps711x_dir_in_inv;
+			gpio->chip[i].direction_output = gpio_clps711x_dir_out_inv;
+		}
+		WARN_ON(gpiochip_add(&gpio->chip[i]));
+	}
+
+	dev_info(&pdev->dev, "GPIO driver initialized\n");
+
+	return 0;
+}
+arch_initcall(gpio_clps711x_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
+MODULE_DESCRIPTION("CLPS711X GPIO driver");
diff --git a/drivers/gpio/gpio-da9055.c b/drivers/gpio/gpio-da9055.c
new file mode 100644
index 0000000..55d83c7
--- /dev/null
+++ b/drivers/gpio/gpio-da9055.c
@@ -0,0 +1,204 @@
+/*
+ * GPIO Driver for Dialog DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <linux/mfd/da9055/core.h>
+#include <linux/mfd/da9055/reg.h>
+#include <linux/mfd/da9055/pdata.h>
+
+#define DA9055_VDD_IO			0x0
+#define DA9055_PUSH_PULL		0x3
+#define DA9055_ACT_LOW			0x0
+#define DA9055_GPI			0x1
+#define DA9055_PORT_MASK		0x3
+#define DA9055_PORT_SHIFT(offset)	(4 * (offset % 2))
+
+#define DA9055_INPUT			DA9055_GPI
+#define DA9055_OUTPUT			DA9055_PUSH_PULL
+#define DA9055_IRQ_GPI0			3
+
+struct da9055_gpio {
+	struct da9055 *da9055;
+	struct gpio_chip gp;
+};
+
+static inline struct da9055_gpio *to_da9055_gpio(struct gpio_chip *chip)
+{
+	return container_of(chip, struct da9055_gpio, gp);
+}
+
+static int da9055_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct da9055_gpio *gpio = to_da9055_gpio(gc);
+	int gpio_direction = 0;
+	int ret;
+
+	/* Get GPIO direction */
+	ret = da9055_reg_read(gpio->da9055, (offset >> 1) + DA9055_REG_GPIO0_1);
+	if (ret < 0)
+		return ret;
+
+	gpio_direction = ret & (DA9055_PORT_MASK) << DA9055_PORT_SHIFT(offset);
+	gpio_direction >>= DA9055_PORT_SHIFT(offset);
+	switch (gpio_direction) {
+	case DA9055_INPUT:
+		ret = da9055_reg_read(gpio->da9055, DA9055_REG_STATUS_B);
+		if (ret < 0)
+			return ret;
+		break;
+	case DA9055_OUTPUT:
+		ret = da9055_reg_read(gpio->da9055, DA9055_REG_GPIO_MODE0_2);
+		if (ret < 0)
+			return ret;
+	}
+
+	return ret & (1 << offset);
+
+}
+
+static void da9055_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct da9055_gpio *gpio = to_da9055_gpio(gc);
+
+	da9055_reg_update(gpio->da9055,
+			DA9055_REG_GPIO_MODE0_2,
+			1 << offset,
+			value << offset);
+}
+
+static int da9055_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct da9055_gpio *gpio = to_da9055_gpio(gc);
+	unsigned char reg_byte;
+
+	reg_byte = (DA9055_ACT_LOW | DA9055_GPI)
+				<< DA9055_PORT_SHIFT(offset);
+
+	return da9055_reg_update(gpio->da9055, (offset >> 1) +
+				DA9055_REG_GPIO0_1,
+				DA9055_PORT_MASK <<
+				DA9055_PORT_SHIFT(offset),
+				reg_byte);
+}
+
+static int da9055_gpio_direction_output(struct gpio_chip *gc,
+					unsigned offset, int value)
+{
+	struct da9055_gpio *gpio = to_da9055_gpio(gc);
+	unsigned char reg_byte;
+	int ret;
+
+	reg_byte = (DA9055_VDD_IO | DA9055_PUSH_PULL)
+					<< DA9055_PORT_SHIFT(offset);
+
+	ret = da9055_reg_update(gpio->da9055, (offset >> 1) +
+				DA9055_REG_GPIO0_1,
+				DA9055_PORT_MASK <<
+				DA9055_PORT_SHIFT(offset),
+				reg_byte);
+	if (ret < 0)
+		return ret;
+
+	da9055_gpio_set(gc, offset, value);
+
+	return 0;
+}
+
+static int da9055_gpio_to_irq(struct gpio_chip *gc, u32 offset)
+{
+	struct da9055_gpio *gpio = to_da9055_gpio(gc);
+	struct da9055 *da9055 = gpio->da9055;
+
+	return regmap_irq_get_virq(da9055->irq_data,
+				  DA9055_IRQ_GPI0 + offset);
+}
+
+static struct gpio_chip reference_gp __devinitdata = {
+	.label = "da9055-gpio",
+	.owner = THIS_MODULE,
+	.get = da9055_gpio_get,
+	.set = da9055_gpio_set,
+	.direction_input = da9055_gpio_direction_input,
+	.direction_output = da9055_gpio_direction_output,
+	.to_irq = da9055_gpio_to_irq,
+	.can_sleep = 1,
+	.ngpio = 3,
+	.base = -1,
+};
+
+static int __devinit da9055_gpio_probe(struct platform_device *pdev)
+{
+	struct da9055_gpio *gpio;
+	struct da9055_pdata *pdata;
+	int ret;
+
+	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
+	if (gpio == NULL)
+		return -ENOMEM;
+
+	gpio->da9055 = dev_get_drvdata(pdev->dev.parent);
+	pdata = gpio->da9055->dev->platform_data;
+
+	gpio->gp = reference_gp;
+	if (pdata && pdata->gpio_base)
+		gpio->gp.base = pdata->gpio_base;
+
+	ret = gpiochip_add(&gpio->gp);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
+		goto err_mem;
+	}
+
+	platform_set_drvdata(pdev, gpio);
+
+	return 0;
+
+err_mem:
+	return ret;
+}
+
+static int __devexit da9055_gpio_remove(struct platform_device *pdev)
+{
+	struct da9055_gpio *gpio = platform_get_drvdata(pdev);
+
+	return gpiochip_remove(&gpio->gp);
+}
+
+static struct platform_driver da9055_gpio_driver = {
+	.probe = da9055_gpio_probe,
+	.remove = __devexit_p(da9055_gpio_remove),
+	.driver = {
+		.name	= "da9055-gpio",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init da9055_gpio_init(void)
+{
+	return platform_driver_register(&da9055_gpio_driver);
+}
+subsys_initcall(da9055_gpio_init);
+
+static void __exit da9055_gpio_exit(void)
+{
+	platform_driver_unregister(&da9055_gpio_driver);
+}
+module_exit(da9055_gpio_exit);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("DA9055 GPIO Device Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9055-gpio");
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c
index efb4c2d..b007063 100644
--- a/drivers/gpio/gpio-em.c
+++ b/drivers/gpio/gpio-em.c
@@ -35,7 +35,6 @@
 struct em_gio_priv {
 	void __iomem *base0;
 	void __iomem *base1;
-	unsigned int irq_base;
 	spinlock_t sense_lock;
 	struct platform_device *pdev;
 	struct gpio_chip gpio_chip;
@@ -214,7 +213,7 @@
 
 static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
-	return irq_find_mapping(gpio_to_priv(chip)->irq_domain, offset);
+	return irq_create_mapping(gpio_to_priv(chip)->irq_domain, offset);
 }
 
 static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq,
@@ -234,40 +233,6 @@
 	.map	= em_gio_irq_domain_map,
 };
 
-static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p)
-{
-	struct platform_device *pdev = p->pdev;
-	struct gpio_em_config *pdata = pdev->dev.platform_data;
-
-	p->irq_base = irq_alloc_descs(pdata->irq_base, 0,
-				      pdata->number_of_pins, numa_node_id());
-	if (p->irq_base < 0) {
-		dev_err(&pdev->dev, "cannot get irq_desc\n");
-		return p->irq_base;
-	}
-	pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n",
-		 pdata->gpio_base, pdata->number_of_pins, p->irq_base);
-
-	p->irq_domain = irq_domain_add_legacy(pdev->dev.of_node,
-					      pdata->number_of_pins,
-					      p->irq_base, 0,
-					      &em_gio_irq_domain_ops, p);
-	if (!p->irq_domain) {
-		irq_free_descs(p->irq_base, pdata->number_of_pins);
-		return -ENXIO;
-	}
-
-	return 0;
-}
-
-static void em_gio_irq_domain_cleanup(struct em_gio_priv *p)
-{
-	struct gpio_em_config *pdata = p->pdev->dev.platform_data;
-
-	irq_free_descs(p->irq_base, pdata->number_of_pins);
-	/* FIXME: irq domain wants to be freed! */
-}
-
 static int __devinit em_gio_probe(struct platform_device *pdev)
 {
 	struct gpio_em_config *pdata = pdev->dev.platform_data;
@@ -334,8 +299,11 @@
 	irq_chip->irq_set_type = em_gio_irq_set_type;
 	irq_chip->flags	= IRQCHIP_SKIP_SET_WAKE;
 
-	ret = em_gio_irq_domain_init(p);
-	if (ret) {
+	p->irq_domain = irq_domain_add_linear(pdev->dev.of_node,
+					      pdata->number_of_pins,
+					      &em_gio_irq_domain_ops, p);
+	if (!p->irq_domain) {
+		ret = -ENXIO;
 		dev_err(&pdev->dev, "cannot initialize irq domain\n");
 		goto err3;
 	}
@@ -364,7 +332,7 @@
 err5:
 	free_irq(irq[0]->start, pdev);
 err4:
-	em_gio_irq_domain_cleanup(p);
+	irq_domain_remove(p->irq_domain);
 err3:
 	iounmap(p->base1);
 err2:
@@ -390,7 +358,7 @@
 
 	free_irq(irq[1]->start, pdev);
 	free_irq(irq[0]->start, pdev);
-	em_gio_irq_domain_cleanup(p);
+	irq_domain_remove(p->irq_domain);
 	iounmap(p->base1);
 	iounmap(p->base0);
 	kfree(p);
diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c
index 05e2dac..c4bf86a 100644
--- a/drivers/gpio/gpio-max730x.c
+++ b/drivers/gpio/gpio-max730x.c
@@ -167,10 +167,6 @@
 	int i, ret;
 
 	pdata = dev->platform_data;
-	if (!pdata || !pdata->base) {
-		dev_err(dev, "incorrect or missing platform data\n");
-		return -EINVAL;
-	}
 
 	mutex_init(&ts->lock);
 	dev_set_drvdata(dev, ts);
@@ -178,7 +174,12 @@
 	/* Power up the chip and disable IRQ output */
 	ts->write(dev, 0x04, 0x01);
 
-	ts->input_pullup_active = pdata->input_pullup_active;
+	if (pdata) {
+		ts->input_pullup_active = pdata->input_pullup_active;
+		ts->chip.base = pdata->base;
+	} else {
+		ts->chip.base = -1;
+	}
 	ts->chip.label = dev->driver->name;
 
 	ts->chip.direction_input = max7301_direction_input;
@@ -186,7 +187,6 @@
 	ts->chip.direction_output = max7301_direction_output;
 	ts->chip.set = max7301_set;
 
-	ts->chip.base = pdata->base;
 	ts->chip.ngpio = PIN_NUMBER;
 	ts->chip.can_sleep = 1;
 	ts->chip.dev = dev;
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 7a87412..75e942f 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -163,12 +163,12 @@
  * Functions implementing the gpio_chip methods
  */
 
-int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin)
+static int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin)
 {
 	return pinctrl_request_gpio(chip->base + pin);
 }
 
-void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin)
+static void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin)
 {
 	pinctrl_free_gpio(chip->base + pin);
 }
@@ -244,6 +244,8 @@
 	if (ret)
 		return ret;
 
+	mvebu_gpio_set(chip, pin, value);
+
 	spin_lock_irqsave(&mvchip->lock, flags);
 	u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip));
 	u &= ~(1 << pin);
@@ -521,6 +523,7 @@
 	mvchip->chip.label = dev_name(&pdev->dev);
 	mvchip->chip.dev = &pdev->dev;
 	mvchip->chip.request = mvebu_gpio_request;
+	mvchip->chip.free = mvebu_gpio_free;
 	mvchip->chip.direction_input = mvebu_gpio_direction_input;
 	mvchip->chip.get = mvebu_gpio_get;
 	mvchip->chip.direction_output = mvebu_gpio_direction_output;
@@ -644,12 +647,12 @@
 	ct->handler = handle_edge_irq;
 	ct->chip.name = mvchip->chip.label;
 
-	irq_setup_generic_chip(gc, IRQ_MSK(ngpios), IRQ_GC_INIT_MASK_CACHE,
+	irq_setup_generic_chip(gc, IRQ_MSK(ngpios), 0,
 			       IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
 
 	/* Setup irq domain on top of the generic chip. */
-	mvchip->domain = irq_domain_add_legacy(np, mvchip->chip.ngpio,
-					       mvchip->irqbase, 0,
+	mvchip->domain = irq_domain_add_simple(np, mvchip->chip.ngpio,
+					       mvchip->irqbase,
 					       &irq_domain_simple_ops,
 					       mvchip);
 	if (!mvchip->domain) {
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 94cbc84..d71e5bd 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -251,6 +251,40 @@
 	}
 }
 
+/**
+ * _clear_gpio_debounce - clear debounce settings for a gpio
+ * @bank: the gpio bank we're acting upon
+ * @gpio: the gpio number on this @gpio
+ *
+ * If a gpio is using debounce, then clear the debounce enable bit and if
+ * this is the only gpio in this bank using debounce, then clear the debounce
+ * time too. The debounce clock will also be disabled when calling this function
+ * if this is the only gpio in the bank using debounce.
+ */
+static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio)
+{
+	u32 gpio_bit = GPIO_BIT(bank, gpio);
+
+	if (!bank->dbck_flag)
+		return;
+
+	if (!(bank->dbck_enable_mask & gpio_bit))
+		return;
+
+	bank->dbck_enable_mask &= ~gpio_bit;
+	bank->context.debounce_en &= ~gpio_bit;
+	__raw_writel(bank->context.debounce_en,
+		     bank->base + bank->regs->debounce_en);
+
+	if (!bank->dbck_enable_mask) {
+		bank->context.debounce = 0;
+		__raw_writel(bank->context.debounce, bank->base +
+			     bank->regs->debounce);
+		clk_disable(bank->dbck);
+		bank->dbck_enabled = false;
+	}
+}
+
 static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
 						unsigned trigger)
 {
@@ -539,6 +573,7 @@
 	_set_gpio_irqenable(bank, gpio, 0);
 	_clear_gpio_irqstatus(bank, gpio);
 	_set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE);
+	_clear_gpio_debounce(bank, gpio);
 }
 
 /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
@@ -1070,7 +1105,7 @@
 	if (!pdata)
 		return -EINVAL;
 
-	bank = devm_kzalloc(&pdev->dev, sizeof(struct gpio_bank), GFP_KERNEL);
+	bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL);
 	if (!bank) {
 		dev_err(dev, "Memory alloc failed\n");
 		return -ENOMEM;
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 9c693ae..0c5eaf5 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -16,6 +16,7 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pca953x.h>
 #include <linux/slab.h>
@@ -83,6 +84,7 @@
 	u32 irq_trig_raise;
 	u32 irq_trig_fall;
 	int	 irq_base;
+	struct irq_domain *domain;
 #endif
 
 	struct i2c_client *client;
@@ -333,14 +335,14 @@
 {
 	struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
 
-	chip->irq_mask &= ~(1 << (d->irq - chip->irq_base));
+	chip->irq_mask &= ~(1 << d->hwirq);
 }
 
 static void pca953x_irq_unmask(struct irq_data *d)
 {
 	struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
 
-	chip->irq_mask |= 1 << (d->irq - chip->irq_base);
+	chip->irq_mask |= 1 << d->hwirq;
 }
 
 static void pca953x_irq_bus_lock(struct irq_data *d)
@@ -372,8 +374,7 @@
 static int pca953x_irq_set_type(struct irq_data *d, unsigned int type)
 {
 	struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
-	u32 level = d->irq - chip->irq_base;
-	u32 mask = 1 << level;
+	u32 mask = 1 << d->hwirq;
 
 	if (!(type & IRQ_TYPE_EDGE_BOTH)) {
 		dev_err(&chip->client->dev, "irq %d: unsupported type %d\n",
@@ -454,7 +455,7 @@
 
 	do {
 		level = __ffs(pending);
-		handle_nested_irq(level + chip->irq_base);
+		handle_nested_irq(irq_find_mapping(chip->domain, level));
 
 		pending &= ~(1 << level);
 	} while (pending);
@@ -499,6 +500,17 @@
 		if (chip->irq_base < 0)
 			goto out_failed;
 
+		chip->domain = irq_domain_add_legacy(client->dev.of_node,
+						chip->gpio_chip.ngpio,
+						chip->irq_base,
+						0,
+						&irq_domain_simple_ops,
+						NULL);
+		if (!chip->domain) {
+			ret = -ENODEV;
+			goto out_irqdesc_free;
+		}
+
 		for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
 			int irq = lvl + chip->irq_base;
 
@@ -521,7 +533,7 @@
 		if (ret) {
 			dev_err(&client->dev, "failed to request irq %d\n",
 				client->irq);
-			goto out_failed;
+			goto out_irqdesc_free;
 		}
 
 		chip->gpio_chip.to_irq = pca953x_gpio_to_irq;
@@ -529,6 +541,8 @@
 
 	return 0;
 
+out_irqdesc_free:
+	irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio);
 out_failed:
 	chip->irq_base = -1;
 	return ret;
@@ -751,9 +765,38 @@
 	return 0;
 }
 
+static const struct of_device_id pca953x_dt_ids[] = {
+	{ .compatible = "nxp,pca9534", },
+	{ .compatible = "nxp,pca9535", },
+	{ .compatible = "nxp,pca9536", },
+	{ .compatible = "nxp,pca9537", },
+	{ .compatible = "nxp,pca9538", },
+	{ .compatible = "nxp,pca9539", },
+	{ .compatible = "nxp,pca9554", },
+	{ .compatible = "nxp,pca9555", },
+	{ .compatible = "nxp,pca9556", },
+	{ .compatible = "nxp,pca9557", },
+	{ .compatible = "nxp,pca9574", },
+	{ .compatible = "nxp,pca9575", },
+
+	{ .compatible = "maxim,max7310", },
+	{ .compatible = "maxim,max7312", },
+	{ .compatible = "maxim,max7313", },
+	{ .compatible = "maxim,max7315", },
+
+	{ .compatible = "ti,pca6107", },
+	{ .compatible = "ti,tca6408", },
+	{ .compatible = "ti,tca6416", },
+	{ .compatible = "ti,tca6424", },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, pca953x_dt_ids);
+
 static struct i2c_driver pca953x_driver = {
 	.driver = {
 		.name	= "pca953x",
+		.of_match_table = pca953x_dt_ids,
 	},
 	.probe		= pca953x_probe,
 	.remove		= pca953x_remove,
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c
index 4ad0c4f..e3a14fe 100644
--- a/drivers/gpio/gpio-pch.c
+++ b/drivers/gpio/gpio-pch.c
@@ -215,6 +215,7 @@
 	struct gpio_chip *gpio = &chip->gpio;
 
 	gpio->label = dev_name(chip->dev);
+	gpio->dev = chip->dev;
 	gpio->owner = THIS_MODULE;
 	gpio->direction_input = pch_gpio_direction_input;
 	gpio->get = pch_gpio_get;
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index b4b5da4..31d9c9e 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -216,39 +216,34 @@
 			       IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
 }
 
-static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
+static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
 {
-	struct pl061_platform_data *pdata;
+	struct device *dev = &adev->dev;
+	struct pl061_platform_data *pdata = dev->platform_data;
 	struct pl061_gpio *chip;
 	int ret, irq, i;
 
-	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 
-	pdata = dev->dev.platform_data;
 	if (pdata) {
 		chip->gc.base = pdata->gpio_base;
 		chip->irq_base = pdata->irq_base;
-	} else if (dev->dev.of_node) {
+	} else if (adev->dev.of_node) {
 		chip->gc.base = -1;
 		chip->irq_base = 0;
-	} else {
-		ret = -ENODEV;
-		goto free_mem;
-	}
+	} else
+		return -ENODEV;
 
-	if (!request_mem_region(dev->res.start,
-				resource_size(&dev->res), "pl061")) {
-		ret = -EBUSY;
-		goto free_mem;
-	}
+	if (!devm_request_mem_region(dev, adev->res.start,
+				resource_size(&adev->res), "pl061"))
+		return -EBUSY;
 
-	chip->base = ioremap(dev->res.start, resource_size(&dev->res));
-	if (chip->base == NULL) {
-		ret = -ENOMEM;
-		goto release_region;
-	}
+	chip->base = devm_ioremap(dev, adev->res.start,
+				resource_size(&adev->res));
+	if (chip->base == NULL)
+		return -ENOMEM;
 
 	spin_lock_init(&chip->lock);
 
@@ -258,13 +253,13 @@
 	chip->gc.set = pl061_set_value;
 	chip->gc.to_irq = pl061_to_irq;
 	chip->gc.ngpio = PL061_GPIO_NR;
-	chip->gc.label = dev_name(&dev->dev);
-	chip->gc.dev = &dev->dev;
+	chip->gc.label = dev_name(dev);
+	chip->gc.dev = dev;
 	chip->gc.owner = THIS_MODULE;
 
 	ret = gpiochip_add(&chip->gc);
 	if (ret)
-		goto iounmap;
+		return ret;
 
 	/*
 	 * irq_chip support
@@ -276,11 +271,10 @@
 	pl061_init_gc(chip, chip->irq_base);
 
 	writeb(0, chip->base + GPIOIE); /* disable irqs */
-	irq = dev->irq[0];
-	if (irq < 0) {
-		ret = -ENODEV;
-		goto iounmap;
-	}
+	irq = adev->irq[0];
+	if (irq < 0)
+		return -ENODEV;
+
 	irq_set_chained_handler(irq, pl061_irq_handler);
 	irq_set_handler_data(irq, chip);
 
@@ -294,18 +288,9 @@
 		}
 	}
 
-	amba_set_drvdata(dev, chip);
+	amba_set_drvdata(adev, chip);
 
 	return 0;
-
-iounmap:
-	iounmap(chip->base);
-release_region:
-	release_mem_region(dev->res.start, resource_size(&dev->res));
-free_mem:
-	kfree(chip);
-
-	return ret;
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c
new file mode 100644
index 0000000..5f45fc4
--- /dev/null
+++ b/drivers/gpio/gpio-spear-spics.c
@@ -0,0 +1,217 @@
+/*
+ * SPEAr platform SPI chipselect abstraction over gpiolib
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+/* maximum chipselects */
+#define NUM_OF_GPIO	4
+
+/*
+ * Provision is available on some SPEAr SoCs to control ARM PL022 spi cs
+ * through system registers. This register lies outside spi (pl022)
+ * address space into system registers.
+ *
+ * It provides control for spi chip select lines so that any chipselect
+ * (out of 4 possible chipselects in pl022) can be made low to select
+ * the particular slave.
+ */
+
+/**
+ * struct spear_spics - represents spi chip select control
+ * @base: base address
+ * @perip_cfg: configuration register
+ * @sw_enable_bit: bit to enable s/w control over chipselects
+ * @cs_value_bit: bit to program high or low chipselect
+ * @cs_enable_mask: mask to select bits required to select chipselect
+ * @cs_enable_shift: bit pos of cs_enable_mask
+ * @use_count: use count of a spi controller cs lines
+ * @last_off: stores last offset caller of set_value()
+ * @chip: gpio_chip abstraction
+ */
+struct spear_spics {
+	void __iomem		*base;
+	u32			perip_cfg;
+	u32			sw_enable_bit;
+	u32			cs_value_bit;
+	u32			cs_enable_mask;
+	u32			cs_enable_shift;
+	unsigned long		use_count;
+	int			last_off;
+	struct gpio_chip	chip;
+};
+
+/* gpio framework specific routines */
+static int spics_get_value(struct gpio_chip *chip, unsigned offset)
+{
+	return -ENXIO;
+}
+
+static void spics_set_value(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct spear_spics *spics = container_of(chip, struct spear_spics,
+			chip);
+	u32 tmp;
+
+	/* select chip select from register */
+	tmp = readl_relaxed(spics->base + spics->perip_cfg);
+	if (spics->last_off != offset) {
+		spics->last_off = offset;
+		tmp &= ~(spics->cs_enable_mask << spics->cs_enable_shift);
+		tmp |= offset << spics->cs_enable_shift;
+	}
+
+	/* toggle chip select line */
+	tmp &= ~(0x1 << spics->cs_value_bit);
+	tmp |= value << spics->cs_value_bit;
+	writel_relaxed(tmp, spics->base + spics->perip_cfg);
+}
+
+static int spics_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return -ENXIO;
+}
+
+static int spics_direction_output(struct gpio_chip *chip, unsigned offset,
+		int value)
+{
+	spics_set_value(chip, offset, value);
+	return 0;
+}
+
+static int spics_request(struct gpio_chip *chip, unsigned offset)
+{
+	struct spear_spics *spics = container_of(chip, struct spear_spics,
+			chip);
+	u32 tmp;
+
+	if (!spics->use_count++) {
+		tmp = readl_relaxed(spics->base + spics->perip_cfg);
+		tmp |= 0x1 << spics->sw_enable_bit;
+		tmp |= 0x1 << spics->cs_value_bit;
+		writel_relaxed(tmp, spics->base + spics->perip_cfg);
+	}
+
+	return 0;
+}
+
+static void spics_free(struct gpio_chip *chip, unsigned offset)
+{
+	struct spear_spics *spics = container_of(chip, struct spear_spics,
+			chip);
+	u32 tmp;
+
+	if (!--spics->use_count) {
+		tmp = readl_relaxed(spics->base + spics->perip_cfg);
+		tmp &= ~(0x1 << spics->sw_enable_bit);
+		writel_relaxed(tmp, spics->base + spics->perip_cfg);
+	}
+}
+
+static int spics_gpio_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct spear_spics *spics;
+	struct resource *res;
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n");
+		return -EBUSY;
+	}
+
+	spics = devm_kzalloc(&pdev->dev, sizeof(*spics), GFP_KERNEL);
+	if (!spics) {
+		dev_err(&pdev->dev, "memory allocation fail\n");
+		return -ENOMEM;
+	}
+
+	spics->base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!spics->base) {
+		dev_err(&pdev->dev, "request and ioremap fail\n");
+		return -ENOMEM;
+	}
+
+	if (of_property_read_u32(np, "st-spics,peripcfg-reg",
+				&spics->perip_cfg))
+		goto err_dt_data;
+	if (of_property_read_u32(np, "st-spics,sw-enable-bit",
+				&spics->sw_enable_bit))
+		goto err_dt_data;
+	if (of_property_read_u32(np, "st-spics,cs-value-bit",
+				&spics->cs_value_bit))
+		goto err_dt_data;
+	if (of_property_read_u32(np, "st-spics,cs-enable-mask",
+				&spics->cs_enable_mask))
+		goto err_dt_data;
+	if (of_property_read_u32(np, "st-spics,cs-enable-shift",
+				&spics->cs_enable_shift))
+		goto err_dt_data;
+
+	platform_set_drvdata(pdev, spics);
+
+	spics->chip.ngpio = NUM_OF_GPIO;
+	spics->chip.base = -1;
+	spics->chip.request = spics_request;
+	spics->chip.free = spics_free;
+	spics->chip.direction_input = spics_direction_input;
+	spics->chip.direction_output = spics_direction_output;
+	spics->chip.get = spics_get_value;
+	spics->chip.set = spics_set_value;
+	spics->chip.label = dev_name(&pdev->dev);
+	spics->chip.dev = &pdev->dev;
+	spics->chip.owner = THIS_MODULE;
+	spics->last_off = -1;
+
+	ret = gpiochip_add(&spics->chip);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to add gpio chip\n");
+		return ret;
+	}
+
+	dev_info(&pdev->dev, "spear spics registered\n");
+	return 0;
+
+err_dt_data:
+	dev_err(&pdev->dev, "DT probe failed\n");
+	return -EINVAL;
+}
+
+static const struct of_device_id spics_gpio_of_match[] = {
+	{ .compatible = "st,spear-spics-gpio" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, spics_gpio_of_match);
+
+static struct platform_driver spics_gpio_driver = {
+	.probe = spics_gpio_probe,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "spear-spics-gpio",
+		.of_match_table = spics_gpio_of_match,
+	},
+};
+
+static int __init spics_gpio_init(void)
+{
+	return platform_driver_register(&spics_gpio_driver);
+}
+subsys_initcall(spics_gpio_init);
+
+MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c
index 1e48317..8c8447c 100644
--- a/drivers/gpio/gpio-tc3589x.c
+++ b/drivers/gpio/gpio-tc3589x.c
@@ -292,17 +292,15 @@
 {
 	int base = tc3589x_gpio->irq_base;
 
-	if (base) {
-		tc3589x_gpio->domain = irq_domain_add_legacy(
-			NULL, tc3589x_gpio->chip.ngpio, base,
-			0, &tc3589x_irq_ops, tc3589x_gpio);
-	}
-	else {
-		tc3589x_gpio->domain = irq_domain_add_linear(
-			np, tc3589x_gpio->chip.ngpio,
-			&tc3589x_irq_ops, tc3589x_gpio);
-	}
-
+	/*
+	 * If this results in a linear domain, irq_create_mapping() will
+	 * take care of allocating IRQ descriptors at runtime. When a base
+	 * is provided, the IRQ descriptors will be allocated when the
+	 * domain is instantiated.
+	 */
+	tc3589x_gpio->domain = irq_domain_add_simple(np,
+			tc3589x_gpio->chip.ngpio, base, &tc3589x_irq_ops,
+			tc3589x_gpio);
 	if (!tc3589x_gpio->domain) {
 		dev_err(tc3589x_gpio->dev, "Failed to create irqdomain\n");
 		return -ENOSYS;
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index d982593..5389be8 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/irqdomain.h>
 #include <linux/pinctrl/consumer.h>
+#include <linux/pm.h>
 
 #include <asm/mach/irq.h>
 
@@ -64,7 +65,7 @@
 	int bank;
 	int irq;
 	spinlock_t lvl_lock[4];
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	u32 cnf[4];
 	u32 out[4];
 	u32 oe[4];
@@ -109,20 +110,18 @@
 {
 	tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1);
 }
-EXPORT_SYMBOL_GPL(tegra_gpio_enable);
 
 static void tegra_gpio_disable(int gpio)
 {
 	tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0);
 }
-EXPORT_SYMBOL_GPL(tegra_gpio_disable);
 
-int tegra_gpio_request(struct gpio_chip *chip, unsigned offset)
+static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset)
 {
 	return pinctrl_request_gpio(offset);
 }
 
-void tegra_gpio_free(struct gpio_chip *chip, unsigned offset)
+static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset)
 {
 	pinctrl_free_gpio(offset);
 	tegra_gpio_disable(offset);
@@ -135,6 +134,11 @@
 
 static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
+	/* If gpio is in output mode then read from the out value */
+	if ((tegra_gpio_readl(GPIO_OE(offset)) >> GPIO_BIT(offset)) & 1)
+		return (tegra_gpio_readl(GPIO_OUT(offset)) >>
+				GPIO_BIT(offset)) & 0x1;
+
 	return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
 }
 
@@ -285,8 +289,8 @@
 
 }
 
-#ifdef CONFIG_PM
-void tegra_gpio_resume(void)
+#ifdef CONFIG_PM_SLEEP
+static int tegra_gpio_resume(struct device *dev)
 {
 	unsigned long flags;
 	int b;
@@ -308,9 +312,10 @@
 	}
 
 	local_irq_restore(flags);
+	return 0;
 }
 
-void tegra_gpio_suspend(void)
+static int tegra_gpio_suspend(struct device *dev)
 {
 	unsigned long flags;
 	int b;
@@ -330,6 +335,7 @@
 		}
 	}
 	local_irq_restore(flags);
+	return 0;
 }
 
 static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable)
@@ -345,11 +351,15 @@
 	.irq_mask	= tegra_gpio_irq_mask,
 	.irq_unmask	= tegra_gpio_irq_unmask,
 	.irq_set_type	= tegra_gpio_irq_set_type,
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	.irq_set_wake	= tegra_gpio_wake_enable,
 #endif
 };
 
+static const struct dev_pm_ops tegra_gpio_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(tegra_gpio_suspend, tegra_gpio_resume)
+};
+
 struct tegra_gpio_soc_config {
 	u32 bank_stride;
 	u32 upper_offset;
@@ -380,7 +390,6 @@
 {
 	const struct of_device_id *match;
 	struct tegra_gpio_soc_config *config;
-	int irq_base;
 	struct resource *res;
 	struct tegra_gpio_bank *bank;
 	int gpio;
@@ -417,14 +426,11 @@
 		return -ENODEV;
 	}
 
-	irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0);
-	if (irq_base < 0) {
-		dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n");
-		return -ENODEV;
-	}
-	irq_domain = irq_domain_add_legacy(pdev->dev.of_node,
-					   tegra_gpio_chip.ngpio, irq_base, 0,
+	irq_domain = irq_domain_add_linear(pdev->dev.of_node,
+					   tegra_gpio_chip.ngpio,
 					   &irq_domain_simple_ops, NULL);
+	if (!irq_domain)
+		return -ENODEV;
 
 	for (i = 0; i < tegra_gpio_bank_count; i++) {
 		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
@@ -464,7 +470,7 @@
 	gpiochip_add(&tegra_gpio_chip);
 
 	for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) {
-		int irq = irq_find_mapping(irq_domain, gpio);
+		int irq = irq_create_mapping(irq_domain, gpio);
 		/* No validity check; all Tegra GPIOs are valid IRQs */
 
 		bank = &tegra_gpio_banks[GPIO_BANK(gpio)];
@@ -493,6 +499,7 @@
 	.driver		= {
 		.name	= "tegra-gpio",
 		.owner	= THIS_MODULE,
+		.pm	= &tegra_gpio_pm_ops,
 		.of_match_table = tegra_gpio_of_match,
 	},
 	.probe		= tegra_gpio_probe,
diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c
index 031c6ad..1a3e2b9 100644
--- a/drivers/gpio/gpio-timberdale.c
+++ b/drivers/gpio/gpio-timberdale.c
@@ -116,7 +116,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&tgpio->lock, flags);
-	tgpio->last_ier &= ~(1 << offset);
+	tgpio->last_ier &= ~(1UL << offset);
 	iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
 	spin_unlock_irqrestore(&tgpio->lock, flags);
 }
@@ -128,7 +128,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&tgpio->lock, flags);
-	tgpio->last_ier |= 1 << offset;
+	tgpio->last_ier |= 1UL << offset;
 	iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
 	spin_unlock_irqrestore(&tgpio->lock, flags);
 }
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index c5f8ca2..d2138b0 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -88,11 +88,15 @@
 /*----------------------------------------------------------------------*/
 
 /*
- * LED register offsets (use TWL4030_MODULE_{LED,PWMA,PWMB}))
+ * LED register offsets from TWL_MODULE_LED base
  * PWMs A and B are dedicated to LEDs A and B, respectively.
  */
 
-#define TWL4030_LED_LEDEN	0x0
+#define TWL4030_LED_LEDEN_REG	0x00
+#define TWL4030_PWMAON_REG	0x01
+#define TWL4030_PWMAOFF_REG	0x02
+#define TWL4030_PWMBON_REG	0x03
+#define TWL4030_PWMBOFF_REG	0x04
 
 /* LEDEN bits */
 #define LEDEN_LEDAON		BIT(0)
@@ -104,9 +108,6 @@
 #define LEDEN_PWM_LENGTHA	BIT(6)
 #define LEDEN_PWM_LENGTHB	BIT(7)
 
-#define TWL4030_PWMx_PWMxON	0x0
-#define TWL4030_PWMx_PWMxOFF	0x1
-
 #define PWMxON_LENGTH		BIT(7)
 
 /*----------------------------------------------------------------------*/
@@ -145,7 +146,7 @@
 	else
 		cached_leden |= mask;
 	status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden,
-			TWL4030_LED_LEDEN);
+				  TWL4030_LED_LEDEN_REG);
 	mutex_unlock(&gpio_lock);
 }
 
@@ -216,33 +217,33 @@
 	if (offset >= TWL4030_GPIO_MAX) {
 		u8	ledclr_mask = LEDEN_LEDAON | LEDEN_LEDAEXT
 				| LEDEN_LEDAPWM | LEDEN_PWM_LENGTHA;
-		u8	module = TWL4030_MODULE_PWMA;
+		u8	reg = TWL4030_PWMAON_REG;
 
 		offset -= TWL4030_GPIO_MAX;
 		if (offset) {
 			ledclr_mask <<= 1;
-			module = TWL4030_MODULE_PWMB;
+			reg = TWL4030_PWMBON_REG;
 		}
 
 		/* initialize PWM to always-drive */
-		status = twl_i2c_write_u8(module, 0x7f,
-				TWL4030_PWMx_PWMxOFF);
+		/* Configure PWM OFF register first */
+		status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg + 1);
 		if (status < 0)
 			goto done;
-		status = twl_i2c_write_u8(module, 0x7f,
-				TWL4030_PWMx_PWMxON);
+
+		/* Followed by PWM ON register */
+		status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg);
 		if (status < 0)
 			goto done;
 
 		/* init LED to not-driven (high) */
-		module = TWL4030_MODULE_LED;
-		status = twl_i2c_read_u8(module, &cached_leden,
-				TWL4030_LED_LEDEN);
+		status = twl_i2c_read_u8(TWL4030_MODULE_LED, &cached_leden,
+					 TWL4030_LED_LEDEN_REG);
 		if (status < 0)
 			goto done;
 		cached_leden &= ~ledclr_mask;
-		status = twl_i2c_write_u8(module, cached_leden,
-				TWL4030_LED_LEDEN);
+		status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden,
+					  TWL4030_LED_LEDEN_REG);
 		if (status < 0)
 			goto done;
 
diff --git a/drivers/gpio/gpio-vt8500.c b/drivers/gpio/gpio-vt8500.c
index bcd8e4a..9ed2a2b 100644
--- a/drivers/gpio/gpio-vt8500.c
+++ b/drivers/gpio/gpio-vt8500.c
@@ -96,6 +96,7 @@
 		VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12),
 		VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16),
 		VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22),
+		VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6),
 	},
 };
 
@@ -115,6 +116,7 @@
 		VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32),
 		VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32),
 		VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32),
+		VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6),
 	},
 };
 
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 5d6c71e..4c07904 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -191,6 +191,32 @@
 	return ret;
 }
 
+/* caller ensures gpio is valid and requested, chip->get_direction may sleep  */
+static int gpio_get_direction(unsigned gpio)
+{
+	struct gpio_chip	*chip;
+	struct gpio_desc	*desc = &gpio_desc[gpio];
+	int			status = -EINVAL;
+
+	chip = gpio_to_chip(gpio);
+	gpio -= chip->base;
+
+	if (!chip->get_direction)
+		return status;
+
+	status = chip->get_direction(chip, gpio);
+	if (status > 0) {
+		/* GPIOF_DIR_IN, or other positive */
+		status = 1;
+		clear_bit(FLAG_IS_OUT, &desc->flags);
+	}
+	if (status == 0) {
+		/* GPIOF_DIR_OUT */
+		set_bit(FLAG_IS_OUT, &desc->flags);
+	}
+	return status;
+}
+
 #ifdef CONFIG_GPIO_SYSFS
 
 /* lock protects against unexport_gpio() being called while
@@ -223,6 +249,7 @@
 		struct device_attribute *attr, char *buf)
 {
 	const struct gpio_desc	*desc = dev_get_drvdata(dev);
+	unsigned		gpio = desc - gpio_desc;
 	ssize_t			status;
 
 	mutex_lock(&sysfs_lock);
@@ -230,6 +257,7 @@
 	if (!test_bit(FLAG_EXPORT, &desc->flags))
 		status = -EIO;
 	else
+		gpio_get_direction(gpio);
 		status = sprintf(buf, "%s\n",
 			test_bit(FLAG_IS_OUT, &desc->flags)
 				? "out" : "in");
@@ -623,9 +651,11 @@
 	 */
 
 	status = gpio_request(gpio, "sysfs");
-	if (status < 0)
+	if (status < 0) {
+		if (status == -EPROBE_DEFER)
+			status = -ENODEV;
 		goto done;
-
+	}
 	status = gpio_export(gpio, true);
 	if (status < 0)
 		gpio_free(gpio);
@@ -702,8 +732,9 @@
 {
 	unsigned long		flags;
 	struct gpio_desc	*desc;
-	int			status = -EINVAL;
+	int			status;
 	const char		*ioname = NULL;
+	struct device		*dev;
 
 	/* can't export until sysfs is available ... */
 	if (!gpio_class.p) {
@@ -711,59 +742,66 @@
 		return -ENOENT;
 	}
 
-	if (!gpio_is_valid(gpio))
-		goto done;
+	if (!gpio_is_valid(gpio)) {
+		pr_debug("%s: gpio %d is not valid\n", __func__, gpio);
+		return -EINVAL;
+	}
 
 	mutex_lock(&sysfs_lock);
 
 	spin_lock_irqsave(&gpio_lock, flags);
 	desc = &gpio_desc[gpio];
-	if (test_bit(FLAG_REQUESTED, &desc->flags)
-			&& !test_bit(FLAG_EXPORT, &desc->flags)) {
-		status = 0;
-		if (!desc->chip->direction_input
-				|| !desc->chip->direction_output)
-			direction_may_change = false;
+	if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
+	     test_bit(FLAG_EXPORT, &desc->flags)) {
+		spin_unlock_irqrestore(&gpio_lock, flags);
+		pr_debug("%s: gpio %d unavailable (requested=%d, exported=%d)\n",
+				__func__, gpio,
+				test_bit(FLAG_REQUESTED, &desc->flags),
+				test_bit(FLAG_EXPORT, &desc->flags));
+		status = -EPERM;
+		goto fail_unlock;
 	}
+
+	if (!desc->chip->direction_input || !desc->chip->direction_output)
+		direction_may_change = false;
 	spin_unlock_irqrestore(&gpio_lock, flags);
 
 	if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])
 		ioname = desc->chip->names[gpio - desc->chip->base];
 
-	if (status == 0) {
-		struct device	*dev;
-
-		dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
-				desc, ioname ? ioname : "gpio%u", gpio);
-		if (!IS_ERR(dev)) {
-			status = sysfs_create_group(&dev->kobj,
-						&gpio_attr_group);
-
-			if (!status && direction_may_change)
-				status = device_create_file(dev,
-						&dev_attr_direction);
-
-			if (!status && gpio_to_irq(gpio) >= 0
-					&& (direction_may_change
-						|| !test_bit(FLAG_IS_OUT,
-							&desc->flags)))
-				status = device_create_file(dev,
-						&dev_attr_edge);
-
-			if (status != 0)
-				device_unregister(dev);
-		} else
-			status = PTR_ERR(dev);
-		if (status == 0)
-			set_bit(FLAG_EXPORT, &desc->flags);
+	dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
+			    desc, ioname ? ioname : "gpio%u", gpio);
+	if (IS_ERR(dev)) {
+		status = PTR_ERR(dev);
+		goto fail_unlock;
 	}
 
-	mutex_unlock(&sysfs_lock);
-
-done:
+	status = sysfs_create_group(&dev->kobj, &gpio_attr_group);
 	if (status)
-		pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
+		goto fail_unregister_device;
 
+	if (direction_may_change) {
+		status = device_create_file(dev, &dev_attr_direction);
+		if (status)
+			goto fail_unregister_device;
+	}
+
+	if (gpio_to_irq(gpio) >= 0 && (direction_may_change ||
+				       !test_bit(FLAG_IS_OUT, &desc->flags))) {
+		status = device_create_file(dev, &dev_attr_edge);
+		if (status)
+			goto fail_unregister_device;
+	}
+
+	set_bit(FLAG_EXPORT, &desc->flags);
+	mutex_unlock(&sysfs_lock);
+	return 0;
+
+fail_unregister_device:
+	device_unregister(dev);
+fail_unlock:
+	mutex_unlock(&sysfs_lock);
+	pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
 	return status;
 }
 EXPORT_SYMBOL_GPL(gpio_export);
@@ -1073,6 +1111,7 @@
 			 * inputs (often with pullups enabled) so power
 			 * usage is minimized.  Linux code should set the
 			 * gpio direction first thing; but until it does,
+			 * and in case chip->get_direction is not set,
 			 * we may expose the wrong direction in sysfs.
 			 */
 			gpio_desc[id].flags = !chip->direction_input
@@ -1191,8 +1230,10 @@
 
 	spin_lock_irqsave(&gpio_lock, flags);
 
-	if (!gpio_is_valid(gpio))
+	if (!gpio_is_valid(gpio)) {
+		status = -EINVAL;
 		goto done;
+	}
 	desc = &gpio_desc[gpio];
 	chip = desc->chip;
 	if (chip == NULL)
@@ -1224,9 +1265,15 @@
 			desc_set_label(desc, NULL);
 			module_put(chip->owner);
 			clear_bit(FLAG_REQUESTED, &desc->flags);
+			goto done;
 		}
 	}
-
+	if (chip->get_direction) {
+		/* chip->get_direction may sleep */
+		spin_unlock_irqrestore(&gpio_lock, flags);
+		gpio_get_direction(gpio);
+		spin_lock_irqsave(&gpio_lock, flags);
+	}
 done:
 	if (status)
 		pr_debug("gpio_request: gpio-%d (%s) status %d\n",
@@ -1762,6 +1809,7 @@
 		if (!test_bit(FLAG_REQUESTED, &gdesc->flags))
 			continue;
 
+		gpio_get_direction(gpio);
 		is_out = test_bit(FLAG_IS_OUT, &gdesc->flags);
 		seq_printf(s, " gpio-%-3d (%-20.20s) %s %s",
 			gpio, gdesc->label,
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index 09e11a5..fd9d0af 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -206,7 +206,7 @@
 	size_t size;
 	int ret;
 
-	DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n",
+	DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n",
 			sizes->surface_width, sizes->surface_height,
 			sizes->surface_bpp);
 
@@ -220,7 +220,7 @@
 
 	size = mode_cmd.pitches[0] * mode_cmd.height;
 	obj = drm_gem_cma_create(dev, size);
-	if (!obj)
+	if (IS_ERR(obj))
 		return -ENOMEM;
 
 	fbi = framebuffer_alloc(0, dev->dev);
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 7ef1b67..133b413 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -121,6 +121,8 @@
 	int minor_id = iminor(inode);
 	struct drm_minor *minor;
 	int retcode = 0;
+	int need_setup = 0;
+	struct address_space *old_mapping;
 
 	minor = idr_find(&drm_minors_idr, minor_id);
 	if (!minor)
@@ -132,23 +134,37 @@
 	if (drm_device_is_unplugged(dev))
 		return -ENODEV;
 
-	retcode = drm_open_helper(inode, filp, dev);
-	if (!retcode) {
-		atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
-		if (!dev->open_count++)
-			retcode = drm_setup(dev);
-	}
-	if (!retcode) {
-		mutex_lock(&dev->struct_mutex);
-		if (dev->dev_mapping == NULL)
-			dev->dev_mapping = &inode->i_data;
-		/* ihold ensures nobody can remove inode with our i_data */
-		ihold(container_of(dev->dev_mapping, struct inode, i_data));
-		inode->i_mapping = dev->dev_mapping;
-		filp->f_mapping = dev->dev_mapping;
-		mutex_unlock(&dev->struct_mutex);
-	}
+	if (!dev->open_count++)
+		need_setup = 1;
+	mutex_lock(&dev->struct_mutex);
+	old_mapping = dev->dev_mapping;
+	if (old_mapping == NULL)
+		dev->dev_mapping = &inode->i_data;
+	/* ihold ensures nobody can remove inode with our i_data */
+	ihold(container_of(dev->dev_mapping, struct inode, i_data));
+	inode->i_mapping = dev->dev_mapping;
+	filp->f_mapping = dev->dev_mapping;
+	mutex_unlock(&dev->struct_mutex);
 
+	retcode = drm_open_helper(inode, filp, dev);
+	if (retcode)
+		goto err_undo;
+	atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
+	if (need_setup) {
+		retcode = drm_setup(dev);
+		if (retcode)
+			goto err_undo;
+	}
+	return 0;
+
+err_undo:
+	mutex_lock(&dev->struct_mutex);
+	filp->f_mapping = old_mapping;
+	inode->i_mapping = old_mapping;
+	iput(container_of(dev->dev_mapping, struct inode, i_data));
+	dev->dev_mapping = old_mapping;
+	mutex_unlock(&dev->struct_mutex);
+	dev->open_count--;
 	return retcode;
 }
 EXPORT_SYMBOL(drm_open);
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index 441ebc1..d4b20ce 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -205,8 +205,6 @@
 	struct drm_gem_object *obj = ptr;
 	struct seq_file *m = data;
 
-	seq_printf(m, "name %d size %zd\n", obj->name, obj->size);
-
 	seq_printf(m, "%6d %8zd %7d %8d\n",
 		   obj->name, obj->size,
 		   atomic_read(&obj->handle_count),
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c
index aaeb6f8..b8a282e 100644
--- a/drivers/gpu/drm/drm_platform.c
+++ b/drivers/gpu/drm/drm_platform.c
@@ -64,7 +64,6 @@
 	}
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-		dev_set_drvdata(&platdev->dev, dev);
 		ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
 		if (ret)
 			goto err_g1;
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 59a26e5..fc345d4 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -1,6 +1,6 @@
 config DRM_EXYNOS
 	tristate "DRM Support for Samsung SoC EXYNOS Series"
-	depends on DRM && PLAT_SAMSUNG
+	depends on DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM)
 	select DRM_KMS_HELPER
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index 18c2718..0f68a28 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -374,6 +374,7 @@
 	exynos_connector->encoder_id = encoder->base.id;
 	exynos_connector->manager = manager;
 	exynos_connector->dpms = DRM_MODE_DPMS_OFF;
+	connector->dpms = DRM_MODE_DPMS_OFF;
 	connector->encoder = encoder;
 
 	err = drm_mode_connector_attach_encoder(connector, encoder);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index e51503f..241ad1e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -43,12 +43,14 @@
  * @manager: specific encoder has its own manager to control a hardware
  *	appropriately and we can access a hardware drawing on this manager.
  * @dpms: store the encoder dpms value.
+ * @updated: indicate whether overlay data updating is needed or not.
  */
 struct exynos_drm_encoder {
 	struct drm_crtc			*old_crtc;
 	struct drm_encoder		drm_encoder;
 	struct exynos_drm_manager	*manager;
-	int dpms;
+	int				dpms;
+	bool				updated;
 };
 
 static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode)
@@ -85,7 +87,9 @@
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
 		if (manager_ops && manager_ops->apply)
-			manager_ops->apply(manager->dev);
+			if (!exynos_encoder->updated)
+				manager_ops->apply(manager->dev);
+
 		exynos_drm_connector_power(encoder, mode);
 		exynos_encoder->dpms = mode;
 		break;
@@ -94,6 +98,7 @@
 	case DRM_MODE_DPMS_OFF:
 		exynos_drm_connector_power(encoder, mode);
 		exynos_encoder->dpms = mode;
+		exynos_encoder->updated = false;
 		break;
 	default:
 		DRM_ERROR("unspecified mode %d\n", mode);
@@ -205,13 +210,22 @@
 
 static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
 {
-	struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
+	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
+	struct exynos_drm_manager *manager = exynos_encoder->manager;
 	struct exynos_drm_manager_ops *manager_ops = manager->ops;
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
 	if (manager_ops && manager_ops->commit)
 		manager_ops->commit(manager->dev);
+
+	/*
+	 * this will avoid one issue that overlay data is updated to
+	 * real hardware two times.
+	 * And this variable will be used to check if the data was
+	 * already updated or not by exynos_drm_encoder_dpms function.
+	 */
+	exynos_encoder->updated = true;
 }
 
 static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
@@ -401,19 +415,6 @@
 		manager_ops->dpms(manager->dev, mode);
 
 	/*
-	 * set current mode to new one so that data aren't updated into
-	 * registers by drm_helper_connector_dpms two times.
-	 *
-	 * in case that drm_crtc_helper_set_mode() is called,
-	 * overlay_ops->commit() and manager_ops->commit() callbacks
-	 * can be called two times, first at drm_crtc_helper_set_mode()
-	 * and second at drm_helper_connector_dpms().
-	 * so with this setting, when drm_helper_connector_dpms() is called
-	 * encoder->funcs->dpms() will be ignored.
-	 */
-	exynos_encoder->dpms = mode;
-
-	/*
 	 * if this condition is ok then it means that the crtc is already
 	 * detached from encoder and last function for detaching is properly
 	 * done, so clear pipe from manager to prevent repeated call.
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 614b2e9..e7fbb82 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1142,7 +1142,7 @@
 		const struct of_device_id *match;
 		match = of_match_node(of_match_ptr(mixer_match_types),
 							  pdev->dev.of_node);
-		drv = match->data;
+		drv = (struct mixer_drv_data *)match->data;
 	} else {
 		drv = (struct mixer_drv_data *)
 			platform_get_device_id(pdev)->driver_data;
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index c9bfd83..61ae104 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1505,7 +1505,8 @@
 		goto put_gmch;
 	}
 
-	i915_kick_out_firmware_fb(dev_priv);
+	if (drm_core_check_feature(dev, DRIVER_MODESET))
+		i915_kick_out_firmware_fb(dev_priv);
 
 	pci_set_master(dev->pdev);
 
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index aac4e5e..6770ee6 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -118,6 +118,13 @@
 MODULE_PARM_DESC(i915_enable_ppgtt,
 		"Enable PPGTT (default: true)");
 
+unsigned int i915_preliminary_hw_support __read_mostly = 0;
+module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600);
+MODULE_PARM_DESC(preliminary_hw_support,
+		"Enable preliminary hardware support. "
+		"Enable Haswell and ValleyView Support. "
+		"(default: false)");
+
 static struct drm_driver driver;
 extern int intel_agp_enabled;
 
@@ -826,6 +833,12 @@
 	struct intel_device_info *intel_info =
 		(struct intel_device_info *) ent->driver_data;
 
+	if (intel_info->is_haswell || intel_info->is_valleyview)
+		if(!i915_preliminary_hw_support) {
+			DRM_ERROR("Preliminary hardware support disabled\n");
+			return -ENODEV;
+		}
+
 	/* Only bind to function 0 of the device. Early generations
 	 * used function 1 as a placeholder for multi-head. This causes
 	 * us confusion instead, especially on the systems where both
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b84f786..f511fa2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1217,6 +1217,7 @@
 extern int i915_enable_fbc __read_mostly;
 extern bool i915_enable_hangcheck __read_mostly;
 extern int i915_enable_ppgtt __read_mostly;
+extern unsigned int i915_preliminary_hw_support __read_mostly;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
 extern int i915_resume(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d33d02d..107f09b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1407,8 +1407,10 @@
 		return VM_FAULT_NOPAGE;
 	case -ENOMEM:
 		return VM_FAULT_OOM;
+	case -ENOSPC:
+		return VM_FAULT_SIGBUS;
 	default:
-		WARN_ON_ONCE(ret);
+		WARN_ONCE(ret, "unhandled error in i915_gem_fault: %i\n", ret);
 		return VM_FAULT_SIGBUS;
 	}
 }
@@ -1822,10 +1824,11 @@
 		sg_set_page(sg, page, PAGE_SIZE, 0);
 	}
 
+	obj->pages = st;
+
 	if (i915_gem_object_needs_bit17_swizzle(obj))
 		i915_gem_object_do_bit_17_swizzle(obj);
 
-	obj->pages = st;
 	return 0;
 
 err_pages:
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 893f301..6345878 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -143,7 +143,7 @@
 	int old_dpms;
 
 	/* PCH platforms and VLV only support on/off. */
-	if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON)
+	if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON)
 		mode = DRM_MODE_DPMS_OFF;
 
 	if (mode == connector->dpms)
@@ -219,20 +219,7 @@
 		intel_encoder_to_crt(to_intel_encoder(encoder));
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	int dpll_md_reg;
-	u32 adpa, dpll_md;
-
-	dpll_md_reg = DPLL_MD(intel_crtc->pipe);
-
-	/*
-	 * Disable separate mode multiplier used when cloning SDVO to CRT
-	 * XXX this needs to be adjusted when we really are cloning
-	 */
-	if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) {
-		dpll_md = I915_READ(dpll_md_reg);
-		I915_WRITE(dpll_md_reg,
-			   dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
-	}
+	u32 adpa;
 
 	adpa = ADPA_HOTPLUG_BITS;
 	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
@@ -742,7 +729,7 @@
 
 	crt->base.type = INTEL_OUTPUT_ANALOG;
 	crt->base.cloneable = true;
-	if (IS_HASWELL(dev))
+	if (IS_HASWELL(dev) || IS_I830(dev))
 		crt->base.crtc_mask = (1 << 0);
 	else
 		crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 682bd37..4154bcd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3841,6 +3841,17 @@
 			}
 		}
 
+		if (intel_encoder->type == INTEL_OUTPUT_EDP) {
+			/* Use VBT settings if we have an eDP panel */
+			unsigned int edp_bpc = dev_priv->edp.bpp / 3;
+
+			if (edp_bpc < display_bpc) {
+				DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
+				display_bpc = edp_bpc;
+			}
+			continue;
+		}
+
 		/*
 		 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
 		 * through, clamp it down.  (Note: >12bpc will be caught below.)
@@ -7892,6 +7903,34 @@
 	void (*hook)(struct drm_device *dev);
 };
 
+/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
+struct intel_dmi_quirk {
+	void (*hook)(struct drm_device *dev);
+	const struct dmi_system_id (*dmi_id_list)[];
+};
+
+static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
+{
+	DRM_INFO("Backlight polarity reversed on %s\n", id->ident);
+	return 1;
+}
+
+static const struct intel_dmi_quirk intel_dmi_quirks[] = {
+	{
+		.dmi_id_list = &(const struct dmi_system_id[]) {
+			{
+				.callback = intel_dmi_reverse_brightness,
+				.ident = "NCR Corporation",
+				.matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"),
+					    DMI_MATCH(DMI_PRODUCT_NAME, ""),
+				},
+			},
+			{ }  /* terminating entry */
+		},
+		.hook = quirk_invert_brightness,
+	},
+};
+
 static struct intel_quirk intel_quirks[] = {
 	/* HP Mini needs pipe A force quirk (LP: #322104) */
 	{ 0x27ae, 0x103c, 0x361a, quirk_pipea_force },
@@ -7931,6 +7970,10 @@
 		     q->subsystem_device == PCI_ANY_ID))
 			q->hook(dev);
 	}
+	for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) {
+		if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0)
+			intel_dmi_quirks[i].hook(dev);
+	}
 }
 
 /* Disable the VGA plane that we never use */
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 1b727a5..368ed8e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1797,7 +1797,8 @@
 			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
 				break;
 		if (i == intel_dp->lane_count && voltage_tries == 5) {
-			if (++loop_tries == 5) {
+			++loop_tries;
+			if (loop_tries == 5) {
 				DRM_DEBUG_KMS("too many full retries, give up\n");
 				break;
 			}
@@ -1807,11 +1808,15 @@
 		}
 
 		/* Check to see if we've tried the same voltage 5 times */
-		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) {
-			voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
-			voltage_tries = 0;
-		} else
+		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
 			++voltage_tries;
+			if (voltage_tries == 5) {
+				DRM_DEBUG_KMS("too many voltage retries, give up\n");
+				break;
+			}
+		} else
+			voltage_tries = 0;
+		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
 		/* Compute new intel_dp->train_set as requested by target */
 		intel_get_adjust_train(intel_dp, link_status);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index e3166df..edba93b 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -777,6 +777,14 @@
 			DMI_MATCH(DMI_BOARD_NAME, "D525TUD"),
 		},
 	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Supermicro X7SPA-H",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"),
+		},
+	},
 
 	{ }	/* terminating entry */
 };
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 4956259..d7bc817 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -341,9 +341,17 @@
 	intel_ring_emit(ring, flip_addr);
 	intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 	/* turn overlay off */
-	intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
-	intel_ring_emit(ring, flip_addr);
-	intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+	if (IS_I830(dev)) {
+		/* Workaround: Don't disable the overlay fully, since otherwise
+		 * it dies on the next OVERLAY_ON cmd. */
+		intel_ring_emit(ring, MI_NOOP);
+		intel_ring_emit(ring, MI_NOOP);
+		intel_ring_emit(ring, MI_NOOP);
+	} else {
+		intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
+		intel_ring_emit(ring, flip_addr);
+		intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+	}
 	intel_ring_advance(ring);
 
 	return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index e019b23..e2aacd3 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -435,7 +435,7 @@
 	props.type = BACKLIGHT_RAW;
 	props.max_brightness = _intel_panel_get_max_backlight(dev);
 	if (props.max_brightness == 0) {
-		DRM_ERROR("Failed to get maximum backlight value\n");
+		DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n");
 		return -ENODEV;
 	}
 	dev_priv->backlight =
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 0007a4d..c600fb0 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -139,6 +139,11 @@
 
 	/* DDC bus used by this SDVO encoder */
 	uint8_t ddc_bus;
+
+	/*
+	 * the sdvo flag gets lost in round trip: dtd->adjusted_mode->dtd
+	 */
+	uint8_t dtd_sdvo_flags;
 };
 
 struct intel_sdvo_connector {
@@ -889,6 +894,45 @@
 }
 #endif
 
+static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo,
+				       unsigned if_index, uint8_t tx_rate,
+				       uint8_t *data, unsigned length)
+{
+	uint8_t set_buf_index[2] = { if_index, 0 };
+	uint8_t hbuf_size, tmp[8];
+	int i;
+
+	if (!intel_sdvo_set_value(intel_sdvo,
+				  SDVO_CMD_SET_HBUF_INDEX,
+				  set_buf_index, 2))
+		return false;
+
+	if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO,
+				  &hbuf_size, 1))
+		return false;
+
+	/* Buffer size is 0 based, hooray! */
+	hbuf_size++;
+
+	DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n",
+		      if_index, length, hbuf_size);
+
+	for (i = 0; i < hbuf_size; i += 8) {
+		memset(tmp, 0, 8);
+		if (i < length)
+			memcpy(tmp, data + i, min_t(unsigned, 8, length - i));
+
+		if (!intel_sdvo_set_value(intel_sdvo,
+					  SDVO_CMD_SET_HBUF_DATA,
+					  tmp, 8))
+			return false;
+	}
+
+	return intel_sdvo_set_value(intel_sdvo,
+				    SDVO_CMD_SET_HBUF_TXRATE,
+				    &tx_rate, 1);
+}
+
 static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
 {
 	struct dip_infoframe avi_if = {
@@ -896,11 +940,7 @@
 		.ver = DIP_VERSION_AVI,
 		.len = DIP_LEN_AVI,
 	};
-	uint8_t tx_rate = SDVO_HBUF_TX_VSYNC;
-	uint8_t set_buf_index[2] = { 1, 0 };
 	uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
-	uint64_t *data = (uint64_t *)sdvo_data;
-	unsigned i;
 
 	intel_dip_infoframe_csum(&avi_if);
 
@@ -910,22 +950,9 @@
 	sdvo_data[3] = avi_if.checksum;
 	memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi));
 
-	if (!intel_sdvo_set_value(intel_sdvo,
-				  SDVO_CMD_SET_HBUF_INDEX,
-				  set_buf_index, 2))
-		return false;
-
-	for (i = 0; i < sizeof(sdvo_data); i += 8) {
-		if (!intel_sdvo_set_value(intel_sdvo,
-					  SDVO_CMD_SET_HBUF_DATA,
-					  data, 8))
-			return false;
-		data++;
-	}
-
-	return intel_sdvo_set_value(intel_sdvo,
-				    SDVO_CMD_SET_HBUF_TXRATE,
-				    &tx_rate, 1);
+	return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF,
+					  SDVO_HBUF_TX_VSYNC,
+					  sdvo_data, sizeof(sdvo_data));
 }
 
 static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)
@@ -984,6 +1011,7 @@
 		return false;
 
 	intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
+	intel_sdvo->dtd_sdvo_flags = input_dtd.part2.sdvo_flags;
 
 	return true;
 }
@@ -1092,6 +1120,8 @@
 	 * adjusted_mode.
 	 */
 	intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
+	if (intel_sdvo->is_tv || intel_sdvo->is_lvds)
+		input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags;
 	if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd))
 		DRM_INFO("Setting input timings on %s failed\n",
 			 SDVO_NAME(intel_sdvo));
@@ -2277,10 +2307,8 @@
 		intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
 	}
 
-	/* SDVO LVDS is cloneable because the SDVO encoder does the upscaling,
-	 * as opposed to native LVDS, where we upscale with the panel-fitter
-	 * (and hence only the native LVDS resolution could be cloned). */
-	intel_sdvo->base.cloneable = true;
+	/* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */
+	intel_sdvo->base.cloneable = false;
 
 	intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
 	if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
@@ -2354,6 +2382,18 @@
 	return true;
 }
 
+static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo)
+{
+	struct drm_device *dev = intel_sdvo->base.base.dev;
+	struct drm_connector *connector, *tmp;
+
+	list_for_each_entry_safe(connector, tmp,
+				 &dev->mode_config.connector_list, head) {
+		if (intel_attached_encoder(connector) == &intel_sdvo->base)
+			intel_sdvo_destroy(connector);
+	}
+}
+
 static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
 					  struct intel_sdvo_connector *intel_sdvo_connector,
 					  int type)
@@ -2677,7 +2717,8 @@
 				    intel_sdvo->caps.output_flags) != true) {
 		DRM_DEBUG_KMS("SDVO output failed to setup on %s\n",
 			      SDVO_NAME(intel_sdvo));
-		goto err;
+		/* Output_setup can leave behind connectors! */
+		goto err_output;
 	}
 
 	/* Only enable the hotplug irq if we need it, to work around noisy
@@ -2690,12 +2731,12 @@
 
 	/* Set the input timing to the screen. Assume always input 0. */
 	if (!intel_sdvo_set_target_input(intel_sdvo))
-		goto err;
+		goto err_output;
 
 	if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo,
 						    &intel_sdvo->pixel_clock_min,
 						    &intel_sdvo->pixel_clock_max))
-		goto err;
+		goto err_output;
 
 	DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
 			"clock range %dMHz - %dMHz, "
@@ -2715,6 +2756,9 @@
 			(SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
 	return true;
 
+err_output:
+	intel_sdvo_output_cleanup(intel_sdvo);
+
 err:
 	drm_encoder_cleanup(&intel_encoder->base);
 	i2c_del_adapter(&intel_sdvo->ddc);
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h
index 9d03014..770bdd6 100644
--- a/drivers/gpu/drm/i915/intel_sdvo_regs.h
+++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h
@@ -708,6 +708,8 @@
 #define SDVO_CMD_SET_AUDIO_STAT		0x91
 #define SDVO_CMD_GET_AUDIO_STAT		0x92
 #define SDVO_CMD_SET_HBUF_INDEX		0x93
+  #define SDVO_HBUF_INDEX_ELD		0
+  #define SDVO_HBUF_INDEX_AVI_IF	1
 #define SDVO_CMD_GET_HBUF_INDEX		0x94
 #define SDVO_CMD_GET_HBUF_INFO		0x95
 #define SDVO_CMD_SET_HBUF_AV_SPLIT	0x96
diff --git a/drivers/gpu/drm/nouveau/core/core/gpuobj.c b/drivers/gpu/drm/nouveau/core/core/gpuobj.c
index 1f34549..70586fd 100644
--- a/drivers/gpu/drm/nouveau/core/core/gpuobj.c
+++ b/drivers/gpu/drm/nouveau/core/core/gpuobj.c
@@ -39,6 +39,11 @@
 			nv_wo32(gpuobj, i, 0x00000000);
 	}
 
+	if (gpuobj->node) {
+		nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap,
+				&gpuobj->node);
+	}
+
 	if (gpuobj->heap.block_size)
 		nouveau_mm_fini(&gpuobj->heap);
 
diff --git a/drivers/gpu/drm/nouveau/core/core/mm.c b/drivers/gpu/drm/nouveau/core/core/mm.c
index bfddf87..a6d3cd6 100644
--- a/drivers/gpu/drm/nouveau/core/core/mm.c
+++ b/drivers/gpu/drm/nouveau/core/core/mm.c
@@ -218,13 +218,16 @@
 	node = kzalloc(sizeof(*node), GFP_KERNEL);
 	if (!node)
 		return -ENOMEM;
-	node->offset = roundup(offset, mm->block_size);
-	node->length = rounddown(offset + length, mm->block_size) - node->offset;
+
+	if (length) {
+		node->offset  = roundup(offset, mm->block_size);
+		node->length  = rounddown(offset + length, mm->block_size);
+		node->length -= node->offset;
+	}
 
 	list_add_tail(&node->nl_entry, &mm->nodes);
 	list_add_tail(&node->fl_entry, &mm->free);
 	mm->heap_nodes++;
-	mm->heap_size += length;
 	return 0;
 }
 
@@ -236,7 +239,7 @@
 	int nodes = 0;
 
 	list_for_each_entry(node, &mm->nodes, nl_entry) {
-		if (nodes++ == mm->heap_nodes)
+		if (WARN_ON(nodes++ == mm->heap_nodes))
 			return -EBUSY;
 	}
 
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index 16a9afb..05a909a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -22,6 +22,8 @@
  * Authors: Ben Skeggs
  */
 
+#include <subdev/bar.h>
+
 #include <engine/software.h>
 #include <engine/disp.h>
 
@@ -37,6 +39,7 @@
 static void
 nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
 {
+	struct nouveau_bar *bar = nouveau_bar(priv);
 	struct nouveau_disp *disp = &priv->base;
 	struct nouveau_software_chan *chan, *temp;
 	unsigned long flags;
@@ -46,18 +49,19 @@
 		if (chan->vblank.crtc != crtc)
 			continue;
 
-		nv_wr32(priv, 0x001704, chan->vblank.channel);
-		nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
-
 		if (nv_device(priv)->chipset == 0x50) {
+			nv_wr32(priv, 0x001704, chan->vblank.channel);
+			nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
+			bar->flush(bar);
 			nv_wr32(priv, 0x001570, chan->vblank.offset);
 			nv_wr32(priv, 0x001574, chan->vblank.value);
 		} else {
-			if (nv_device(priv)->chipset >= 0xc0) {
-				nv_wr32(priv, 0x06000c,
-					upper_32_bits(chan->vblank.offset));
-			}
-			nv_wr32(priv, 0x060010, chan->vblank.offset);
+			nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
+			bar->flush(bar);
+			nv_wr32(priv, 0x06000c,
+				upper_32_bits(chan->vblank.offset));
+			nv_wr32(priv, 0x060010,
+				lower_32_bits(chan->vblank.offset));
 			nv_wr32(priv, 0x060014, chan->vblank.value);
 		}
 
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
index 8d00210..4250012 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
@@ -156,8 +156,8 @@
 static int
 nv40_graph_context_fini(struct nouveau_object *object, bool suspend)
 {
-	struct nv04_graph_priv *priv = (void *)object->engine;
-	struct nv04_graph_chan *chan = (void *)object;
+	struct nv40_graph_priv *priv = (void *)object->engine;
+	struct nv40_graph_chan *chan = (void *)object;
 	u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4;
 	int ret = 0;
 
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
index 1241857..f7c581a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
@@ -38,7 +38,7 @@
 };
 
 struct nv40_mpeg_chan {
-	struct nouveau_mpeg base;
+	struct nouveau_mpeg_chan base;
 };
 
 /*******************************************************************************
diff --git a/drivers/gpu/drm/nouveau/core/include/core/mm.h b/drivers/gpu/drm/nouveau/core/include/core/mm.h
index 9ee9bf4..975137b 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/mm.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/mm.h
@@ -19,7 +19,6 @@
 
 	u32 block_size;
 	int heap_nodes;
-	u32 heap_size;
 };
 
 int  nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
index dcb5c2b..70ca7d5a 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
@@ -72,7 +72,7 @@
 	}
 
 	data = of_get_property(dn, "NVDA,BMP", &size);
-	if (data) {
+	if (data && size) {
 		bios->size = size;
 		bios->data = kmalloc(bios->size, GFP_KERNEL);
 		if (bios->data)
@@ -104,6 +104,9 @@
 		goto out;
 
 	bios->size = nv_rd08(bios, 0x700002) * 512;
+	if (!bios->size)
+		goto out;
+
 	bios->data = kmalloc(bios->size, GFP_KERNEL);
 	if (bios->data) {
 		for (i = 0; i < bios->size; i++)
@@ -155,6 +158,9 @@
 
 	/* read entire bios image to system memory */
 	bios->size = nv_rd08(bios, 0x300002) * 512;
+	if (!bios->size)
+		goto out;
+
 	bios->data = kmalloc(bios->size, GFP_KERNEL);
 	if (bios->data) {
 		for (i = 0; i < bios->size; i++)
@@ -186,14 +192,22 @@
 {
 	struct pci_dev *pdev = nv_device(bios)->pdev;
 	int ret, cnt, i;
-	u8  data[3];
 
-	if (!nouveau_acpi_rom_supported(pdev))
+	if (!nouveau_acpi_rom_supported(pdev)) {
+		bios->data = NULL;
 		return;
+	}
 
 	bios->size = 0;
-	if (nouveau_acpi_get_bios_chunk(data, 0, 3) == 3)
-		bios->size = data[2] * 512;
+	bios->data = kmalloc(4096, GFP_KERNEL);
+	if (bios->data) {
+		if (nouveau_acpi_get_bios_chunk(bios->data, 0, 4096) == 4096)
+			bios->size = bios->data[2] * 512;
+		kfree(bios->data);
+	}
+
+	if (!bios->size)
+		return;
 
 	bios->data = kmalloc(bios->size, GFP_KERNEL);
 	for (i = 0; bios->data && i < bios->size; i += cnt) {
@@ -229,12 +243,14 @@
 static int
 nouveau_bios_score(struct nouveau_bios *bios, const bool writeable)
 {
-	if (!bios->data || bios->data[0] != 0x55 || bios->data[1] != 0xAA) {
+	if (bios->size < 3 || !bios->data || bios->data[0] != 0x55 ||
+			bios->data[1] != 0xAA) {
 		nv_info(bios, "... signature not found\n");
 		return 0;
 	}
 
-	if (nvbios_checksum(bios->data, bios->data[2] * 512)) {
+	if (nvbios_checksum(bios->data,
+			min_t(u32, bios->data[2] * 512, bios->size))) {
 		nv_info(bios, "... checksum invalid\n");
 		/* if a ro image is somewhat bad, it's probably all rubbish */
 		return writeable ? 2 : 1;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
index 5e5f4cd..f835501 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
@@ -157,11 +157,10 @@
 	while (map->reg) {
 		if (map->reg == reg && *ver >= 0x20) {
 			u16 addr = (data += hdr);
+			*type = map->type;
 			while (cnt--) {
-				if (nv_ro32(bios, data) == map->reg) {
-					*type = map->type;
+				if (nv_ro32(bios, data) == map->reg)
 					return data;
-				}
 				data += *len;
 			}
 			return addr;
@@ -200,11 +199,10 @@
 	while (map->reg) {
 		if (map->type == type && *ver >= 0x20) {
 			u16 addr = (data += hdr);
+			*reg = map->reg;
 			while (cnt--) {
-				if (nv_ro32(bios, data) == map->reg) {
-					*reg = map->reg;
+				if (nv_ro32(bios, data) == map->reg)
 					return data;
-				}
 				data += *len;
 			}
 			return addr;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
index 42d7539..5f570806 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
@@ -219,13 +219,11 @@
 			     ((priv->base.ram.size & 0x000000ff) << 32);
 
 	tags = nv_rd32(priv, 0x100320);
-	if (tags) {
-		ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1);
-		if (ret)
-			return ret;
+	ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1);
+	if (ret)
+		return ret;
 
-		nv_debug(priv, "%d compression tags\n", tags);
-	}
+	nv_debug(priv, "%d compression tags\n", tags);
 
 	size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail;
 	switch (device->chipset) {
@@ -237,6 +235,7 @@
 			return ret;
 
 		priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12;
+		priv->base.ram.type = NV_MEM_TYPE_STOLEN;
 		break;
 	default:
 		ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
index 3d2c883..dbfc2abf 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
@@ -292,7 +292,7 @@
 		case DCB_I2C_NVIO_BIT:
 			port->drive = info.drive & 0x0f;
 			if (device->card_type < NV_D0) {
-				if (info.drive >= ARRAY_SIZE(nv50_i2c_port))
+				if (port->drive >= ARRAY_SIZE(nv50_i2c_port))
 					break;
 				port->drive = nv50_i2c_port[port->drive];
 				port->sense = port->drive;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
index 0203e1e..9474cfc 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
@@ -67,7 +67,7 @@
 static void
 nv41_vm_flush(struct nouveau_vm *vm)
 {
-	struct nv04_vm_priv *priv = (void *)vm->vmm;
+	struct nv04_vmmgr_priv *priv = (void *)vm->vmm;
 
 	mutex_lock(&nv_subdev(priv)->mutex);
 	nv_wr32(priv, 0x100810, 0x00000022);
@@ -92,7 +92,8 @@
 	struct nv04_vmmgr_priv *priv;
 	int ret;
 
-	if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
+	if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) ||
+	    !nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
 		return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass,
 					   data, size, pobject);
 	}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c
index 0ac18d0..aa81314 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c
@@ -163,7 +163,8 @@
 	struct nv04_vmmgr_priv *priv;
 	int ret;
 
-	if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
+	if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) ||
+	    !nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
 		return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass,
 					   data, size, pobject);
 	}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 9a6e2cb..d3595b2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -355,7 +355,7 @@
 	 * valid - it's not (rh#613284)
 	 */
 	if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) {
-		if (!(nv_connector->edid = nouveau_acpi_edid(dev, connector))) {
+		if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) {
 			status = connector_status_connected;
 			goto out;
 		}
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 8f98e5a..86124b1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -290,6 +290,7 @@
 	struct nouveau_drm *drm = nouveau_drm(dev);
 	struct nouveau_disp *pdisp = nouveau_disp(drm->device);
 	struct nouveau_display *disp;
+	u32 pclass = dev->pdev->class >> 8;
 	int ret, gen;
 
 	disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL);
@@ -360,23 +361,27 @@
 	drm_kms_helper_poll_init(dev);
 	drm_kms_helper_poll_disable(dev);
 
-	if (nv_device(drm->device)->card_type < NV_50)
-		ret = nv04_display_create(dev);
-	else
-	if (nv_device(drm->device)->card_type < NV_D0)
-		ret = nv50_display_create(dev);
-	else
-		ret = nvd0_display_create(dev);
-	if (ret)
-		goto disp_create_err;
-
-	if (dev->mode_config.num_crtc) {
-		ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+	if (nouveau_modeset == 1 ||
+	    (nouveau_modeset < 0 && pclass == PCI_CLASS_DISPLAY_VGA)) {
+		if (nv_device(drm->device)->card_type < NV_50)
+			ret = nv04_display_create(dev);
+		else
+		if (nv_device(drm->device)->card_type < NV_D0)
+			ret = nv50_display_create(dev);
+		else
+			ret = nvd0_display_create(dev);
 		if (ret)
-			goto vblank_err;
+			goto disp_create_err;
+
+		if (dev->mode_config.num_crtc) {
+			ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+			if (ret)
+				goto vblank_err;
+		}
+
+		nouveau_backlight_init(dev);
 	}
 
-	nouveau_backlight_init(dev);
 	return 0;
 
 vblank_err:
@@ -395,7 +400,8 @@
 	nouveau_backlight_exit(dev);
 	drm_vblank_cleanup(dev);
 
-	disp->dtor(dev);
+	if (disp->dtor)
+		disp->dtor(dev);
 
 	drm_kms_helper_poll_fini(dev);
 	drm_mode_config_cleanup(dev);
@@ -530,9 +536,11 @@
 	if (ret)
 		goto fail;
 
-	ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0);
-	if (ret)
-		goto fail_unreserve;
+	if (likely(old_bo != new_bo)) {
+		ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0);
+		if (ret)
+			goto fail_unreserve;
+	}
 
 	return 0;
 
@@ -551,8 +559,10 @@
 	nouveau_bo_fence(new_bo, fence);
 	ttm_bo_unreserve(&new_bo->bo);
 
-	nouveau_bo_fence(old_bo, fence);
-	ttm_bo_unreserve(&old_bo->bo);
+	if (likely(old_bo != new_bo)) {
+		nouveau_bo_fence(old_bo, fence);
+		ttm_bo_unreserve(&old_bo->bo);
+	}
 
 	nouveau_bo_unpin(old_bo);
 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index ccae8c26..0910125 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -63,8 +63,9 @@
 static int nouveau_noaccel = 0;
 module_param_named(noaccel, nouveau_noaccel, int, 0400);
 
-MODULE_PARM_DESC(modeset, "enable driver");
-static int nouveau_modeset = -1;
+MODULE_PARM_DESC(modeset, "enable driver (default: auto, "
+		          "0 = disabled, 1 = enabled, 2 = headless)");
+int nouveau_modeset = -1;
 module_param_named(modeset, nouveau_modeset, int, 0400);
 
 static struct drm_driver driver;
@@ -363,7 +364,8 @@
 
 	nouveau_pm_fini(dev);
 
-	nouveau_display_fini(dev);
+	if (dev->mode_config.num_crtc)
+		nouveau_display_fini(dev);
 	nouveau_display_destroy(dev);
 
 	nouveau_irq_fini(dev);
@@ -403,13 +405,15 @@
 	    pm_state.event == PM_EVENT_PRETHAW)
 		return 0;
 
-	NV_INFO(drm, "suspending fbcon...\n");
-	nouveau_fbcon_set_suspend(dev, 1);
+	if (dev->mode_config.num_crtc) {
+		NV_INFO(drm, "suspending fbcon...\n");
+		nouveau_fbcon_set_suspend(dev, 1);
 
-	NV_INFO(drm, "suspending display...\n");
-	ret = nouveau_display_suspend(dev);
-	if (ret)
-		return ret;
+		NV_INFO(drm, "suspending display...\n");
+		ret = nouveau_display_suspend(dev);
+		if (ret)
+			return ret;
+	}
 
 	NV_INFO(drm, "evicting buffers...\n");
 	ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM);
@@ -445,8 +449,10 @@
 		nouveau_client_init(&cli->base);
 	}
 
-	NV_INFO(drm, "resuming display...\n");
-	nouveau_display_resume(dev);
+	if (dev->mode_config.num_crtc) {
+		NV_INFO(drm, "resuming display...\n");
+		nouveau_display_resume(dev);
+	}
 	return ret;
 }
 
@@ -486,8 +492,10 @@
 	nouveau_irq_postinstall(dev);
 	nouveau_pm_resume(dev);
 
-	NV_INFO(drm, "resuming display...\n");
-	nouveau_display_resume(dev);
+	if (dev->mode_config.num_crtc) {
+		NV_INFO(drm, "resuming display...\n");
+		nouveau_display_resume(dev);
+	}
 	return 0;
 }
 
@@ -662,9 +670,7 @@
 #ifdef CONFIG_VGA_CONSOLE
 		if (vgacon_text_force())
 			nouveau_modeset = 0;
-		else
 #endif
-			nouveau_modeset = 1;
 	}
 
 	if (!nouveau_modeset)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h
index 8194712..a101699 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.h
@@ -141,4 +141,6 @@
 		nv_info((cli), fmt, ##args);                                   \
 } while (0)
 
+extern int nouveau_modeset;
+
 #endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
index 9ca8afd..1d8cb50 100644
--- a/drivers/gpu/drm/nouveau/nouveau_irq.c
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
@@ -61,13 +61,15 @@
 
 	nv_subdev(pmc)->intr(nv_subdev(pmc));
 
-	if (device->card_type >= NV_D0) {
-		if (nv_rd32(device, 0x000100) & 0x04000000)
-			nvd0_display_intr(dev);
-	} else
-	if (device->card_type >= NV_50) {
-		if (nv_rd32(device, 0x000100) & 0x04000000)
-			nv50_display_intr(dev);
+	if (dev->mode_config.num_crtc) {
+		if (device->card_type >= NV_D0) {
+			if (nv_rd32(device, 0x000100) & 0x04000000)
+				nvd0_display_intr(dev);
+		} else
+		if (device->card_type >= NV_50) {
+			if (nv_rd32(device, 0x000100) & 0x04000000)
+				nv50_display_intr(dev);
+		}
 	}
 
 	return IRQ_HANDLED;
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c
index 347a3bd..64f7020 100644
--- a/drivers/gpu/drm/nouveau/nv04_dac.c
+++ b/drivers/gpu/drm/nouveau/nv04_dac.c
@@ -220,7 +220,7 @@
 	NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode);
 
 	if (blue == 0x18) {
-		NV_INFO(drm, "Load detected on head A\n");
+		NV_DEBUG(drm, "Load detected on head A\n");
 		return connector_status_connected;
 	}
 
@@ -338,8 +338,8 @@
 
 	if (nv17_dac_sample_load(encoder) &
 	    NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
-		NV_INFO(drm, "Load detected on output %c\n",
-			'@' + ffs(dcb->or));
+		NV_DEBUG(drm, "Load detected on output %c\n",
+			 '@' + ffs(dcb->or));
 		return connector_status_connected;
 	} else {
 		return connector_status_disconnected;
@@ -413,9 +413,9 @@
 
 	helper->dpms(encoder, DRM_MODE_DPMS_ON);
 
-	NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n",
-		drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
-		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
+	NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n",
+		 drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
+		 nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
 }
 
 void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable)
@@ -461,8 +461,8 @@
 		return;
 	nv_encoder->last_dpms = mode;
 
-	NV_INFO(drm, "Setting dpms mode %d on vga encoder (output %d)\n",
-		     mode, nv_encoder->dcb->index);
+	NV_DEBUG(drm, "Setting dpms mode %d on vga encoder (output %d)\n",
+		 mode, nv_encoder->dcb->index);
 
 	nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
 }
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c
index da55d76..184cdf8 100644
--- a/drivers/gpu/drm/nouveau/nv04_dfp.c
+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
@@ -476,9 +476,9 @@
 
 	helper->dpms(encoder, DRM_MODE_DPMS_ON);
 
-	NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n",
-		drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
-		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
+	NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n",
+		 drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
+		 nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
 }
 
 static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode)
@@ -520,8 +520,8 @@
 		return;
 	nv_encoder->last_dpms = mode;
 
-	NV_INFO(drm, "Setting dpms mode %d on lvds encoder (output %d)\n",
-		     mode, nv_encoder->dcb->index);
+	NV_DEBUG(drm, "Setting dpms mode %d on lvds encoder (output %d)\n",
+		 mode, nv_encoder->dcb->index);
 
 	if (was_powersaving && is_powersaving_dpms(mode))
 		return;
@@ -565,8 +565,8 @@
 		return;
 	nv_encoder->last_dpms = mode;
 
-	NV_INFO(drm, "Setting dpms mode %d on tmds encoder (output %d)\n",
-		     mode, nv_encoder->dcb->index);
+	NV_DEBUG(drm, "Setting dpms mode %d on tmds encoder (output %d)\n",
+		 mode, nv_encoder->dcb->index);
 
 	nv04_dfp_update_backlight(encoder, mode);
 	nv04_dfp_update_fp_control(encoder, mode);
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c
index 099fbed..62e826a 100644
--- a/drivers/gpu/drm/nouveau/nv04_tv.c
+++ b/drivers/gpu/drm/nouveau/nv04_tv.c
@@ -75,8 +75,8 @@
 	struct nv04_mode_state *state = &nv04_display(dev)->mode_reg;
 	uint8_t crtc1A;
 
-	NV_INFO(drm, "Setting dpms mode %d on TV encoder (output %d)\n",
-		mode, nv_encoder->dcb->index);
+	NV_DEBUG(drm, "Setting dpms mode %d on TV encoder (output %d)\n",
+		 mode, nv_encoder->dcb->index);
 
 	state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK);
 
@@ -167,9 +167,8 @@
 
 	helper->dpms(encoder, DRM_MODE_DPMS_ON);
 
-	NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n",
-		      drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index,
-		      '@' + ffs(nv_encoder->dcb->or));
+	NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n",
+		 drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
 }
 
 static void nv04_tv_destroy(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 2e566e12..3bce029 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1696,35 +1696,43 @@
 			return ATOM_PPLL2;
 		DRM_ERROR("unable to allocate a PPLL\n");
 		return ATOM_PPLL_INVALID;
-	} else {
-		if (ASIC_IS_AVIVO(rdev)) {
-			/* in DP mode, the DP ref clock can come from either PPLL
-			 * depending on the asic:
-			 * DCE3: PPLL1 or PPLL2
-			 */
-			if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
-				/* use the same PPLL for all DP monitors */
-				pll = radeon_get_shared_dp_ppll(crtc);
-				if (pll != ATOM_PPLL_INVALID)
-					return pll;
-			} else {
-				/* use the same PPLL for all monitors with the same clock */
-				pll = radeon_get_shared_nondp_ppll(crtc);
-				if (pll != ATOM_PPLL_INVALID)
-					return pll;
-			}
-			/* all other cases */
-			pll_in_use = radeon_get_pll_use_mask(crtc);
+	} else if (ASIC_IS_AVIVO(rdev)) {
+		/* in DP mode, the DP ref clock can come from either PPLL
+		 * depending on the asic:
+		 * DCE3: PPLL1 or PPLL2
+		 */
+		if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
+			/* use the same PPLL for all DP monitors */
+			pll = radeon_get_shared_dp_ppll(crtc);
+			if (pll != ATOM_PPLL_INVALID)
+				return pll;
+		} else {
+			/* use the same PPLL for all monitors with the same clock */
+			pll = radeon_get_shared_nondp_ppll(crtc);
+			if (pll != ATOM_PPLL_INVALID)
+				return pll;
+		}
+		/* all other cases */
+		pll_in_use = radeon_get_pll_use_mask(crtc);
+		/* the order shouldn't matter here, but we probably
+		 * need this until we have atomic modeset
+		 */
+		if (rdev->flags & RADEON_IS_IGP) {
 			if (!(pll_in_use & (1 << ATOM_PPLL1)))
 				return ATOM_PPLL1;
 			if (!(pll_in_use & (1 << ATOM_PPLL2)))
 				return ATOM_PPLL2;
-			DRM_ERROR("unable to allocate a PPLL\n");
-			return ATOM_PPLL_INVALID;
 		} else {
-			/* on pre-R5xx asics, the crtc to pll mapping is hardcoded */
-			return radeon_crtc->crtc_id;
+			if (!(pll_in_use & (1 << ATOM_PPLL2)))
+				return ATOM_PPLL2;
+			if (!(pll_in_use & (1 << ATOM_PPLL1)))
+				return ATOM_PPLL1;
 		}
+		DRM_ERROR("unable to allocate a PPLL\n");
+		return ATOM_PPLL_INVALID;
+	} else {
+		/* on pre-R5xx asics, the crtc to pll mapping is hardcoded */
+		return radeon_crtc->crtc_id;
 	}
 }
 
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index 49cbb37..010bae1 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -184,6 +184,7 @@
 	struct radeon_backlight_privdata *pdata;
 	struct radeon_encoder_atom_dig *dig;
 	u8 backlight_level;
+	char bl_name[16];
 
 	if (!radeon_encoder->enc_priv)
 		return;
@@ -203,7 +204,9 @@
 	memset(&props, 0, sizeof(props));
 	props.max_brightness = RADEON_MAX_BL_LEVEL;
 	props.type = BACKLIGHT_RAW;
-	bd = backlight_device_register("radeon_bl", &drm_connector->kdev,
+	snprintf(bl_name, sizeof(bl_name),
+		 "radeon_bl%d", dev->primary->index);
+	bd = backlight_device_register(bl_name, &drm_connector->kdev,
 				       pdata, &radeon_atom_backlight_ops, &props);
 	if (IS_ERR(bd)) {
 		DRM_ERROR("Backlight registration failed\n");
@@ -1622,7 +1625,7 @@
 			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
 			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
 			/* some early dce3.2 boards have a bug in their transmitter control table */
-			if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730))
+			if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730))
 				atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
 		}
 		if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 14313ad..af31f82 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1372,7 +1372,7 @@
 	WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
 
 	for (i = 0; i < rdev->num_crtc; i++) {
-		if (save->crtc_enabled) {
+		if (save->crtc_enabled[i]) {
 			if (ASIC_IS_DCE6(rdev)) {
 				tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
 				tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index 573ed1b..c042e49 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -264,7 +264,7 @@
 	/* macro tile width & height */
 	palign = (8 * surf->bankw * track->npipes) * surf->mtilea;
 	halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea;
-	mtileb = (palign / 8) * (halign / 8) * tileb;;
+	mtileb = (palign / 8) * (halign / 8) * tileb;
 	mtile_pr = surf->nbx / palign;
 	mtile_ps = (mtile_pr * surf->nby) / halign;
 	surf->layer_size = mtile_ps * mtileb * slice_pt;
@@ -2725,6 +2725,9 @@
 	/* check config regs */
 	switch (reg) {
 	case GRBM_GFX_INDEX:
+	case CP_STRMOUT_CNTL:
+	case CP_COHER_CNTL:
+	case CP_COHER_SIZE:
 	case VGT_VTX_VECT_EJECT_REG:
 	case VGT_CACHE_INVALIDATION:
 	case VGT_GS_VERTEX_REUSE:
@@ -2829,6 +2832,7 @@
 	case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS:
 		return true;
 	default:
+		DRM_ERROR("Invalid register 0x%x in CS\n", reg);
 		return false;
 	}
 }
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index df542f1..2bc0f6a 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -91,6 +91,10 @@
 #define		FB_READ_EN					(1 << 0)
 #define		FB_WRITE_EN					(1 << 1)
 
+#define	CP_STRMOUT_CNTL					0x84FC
+
+#define	CP_COHER_CNTL					0x85F0
+#define	CP_COHER_SIZE					0x85F4
 #define	CP_COHER_BASE					0x85F8
 #define	CP_STALLED_STAT1			0x8674
 #define	CP_STALLED_STAT2			0x8678
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 8c74c72..81e6a56 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1538,26 +1538,31 @@
 {
 	struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index];
 	uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
-	int i;
 
-	radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, 1 + count * 2));
-	radeon_ring_write(ring, pe);
-	radeon_ring_write(ring, upper_32_bits(pe) & 0xff);
-	for (i = 0; i < count; ++i) {
-		uint64_t value = 0;
-		if (flags & RADEON_VM_PAGE_SYSTEM) {
-			value = radeon_vm_map_gart(rdev, addr);
-			value &= 0xFFFFFFFFFFFFF000ULL;
-			addr += incr;
+	while (count) {
+		unsigned ndw = 1 + count * 2;
+		if (ndw > 0x3FFF)
+			ndw = 0x3FFF;
 
-		} else if (flags & RADEON_VM_PAGE_VALID) {
-			value = addr;
-			addr += incr;
+		radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, ndw));
+		radeon_ring_write(ring, pe);
+		radeon_ring_write(ring, upper_32_bits(pe) & 0xff);
+		for (; ndw > 1; ndw -= 2, --count, pe += 8) {
+			uint64_t value = 0;
+			if (flags & RADEON_VM_PAGE_SYSTEM) {
+				value = radeon_vm_map_gart(rdev, addr);
+				value &= 0xFFFFFFFFFFFFF000ULL;
+				addr += incr;
+
+			} else if (flags & RADEON_VM_PAGE_VALID) {
+				value = addr;
+				addr += incr;
+			}
+
+			value |= r600_flags;
+			radeon_ring_write(ring, value);
+			radeon_ring_write(ring, upper_32_bits(value));
 		}
-
-		value |= r600_flags;
-		radeon_ring_write(ring, value);
-		radeon_ring_write(ring, upper_32_bits(value));
 	}
 }
 
@@ -1586,4 +1591,8 @@
 	/* bits 0-7 are the VM contexts0-7 */
 	radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
 	radeon_ring_write(ring, 1 << vm->id);
+
+	/* sync PFP to ME, otherwise we might get invalid PFP reads */
+	radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
+	radeon_ring_write(ring, 0x0);
 }
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index 2423d1b..cbef681 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -502,6 +502,7 @@
 #define	PACKET3_MPEG_INDEX				0x3A
 #define	PACKET3_WAIT_REG_MEM				0x3C
 #define	PACKET3_MEM_WRITE				0x3D
+#define	PACKET3_PFP_SYNC_ME				0x42
 #define	PACKET3_SURFACE_SYNC				0x43
 #              define PACKET3_CB0_DEST_BASE_ENA    (1 << 6)
 #              define PACKET3_CB1_DEST_BASE_ENA    (1 << 7)
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 1aa3f91..15f5ded 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -87,7 +87,7 @@
 		atpx_arg_elements[1].integer.value = 0;
 	}
 
-	status = acpi_evaluate_object(handle, "ATPX", &atpx_arg, &buffer);
+	status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
 
 	/* Fail only if calling the method fails and ATPX is supported */
 	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
@@ -352,9 +352,9 @@
 }
 
 /**
- * radeon_atpx_switchto - switch to the requested GPU
+ * radeon_atpx_power_state - power down/up the requested GPU
  *
- * @id: GPU to switch to
+ * @id: GPU to power down/up
  * @state: requested power state (0 = off, 1 = on)
  *
  * Execute the necessary ATPX function to power down/up the discrete GPU
@@ -373,11 +373,11 @@
 }
 
 /**
- * radeon_atpx_pci_probe_handle - look up the ATRM and ATPX handles
+ * radeon_atpx_pci_probe_handle - look up the ATPX handle
  *
  * @pdev: pci device
  *
- * Look up the ATPX and ATRM handles (all asics).
+ * Look up the ATPX handles (all asics).
  * Returns true if the handles are found, false if not.
  */
 static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 67cfc17..b884c36 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -941,7 +941,7 @@
 	struct drm_mode_object *obj;
 	int i;
 	enum drm_connector_status ret = connector_status_disconnected;
-	bool dret = false;
+	bool dret = false, broken_edid = false;
 
 	if (!force && radeon_check_hpd_status_unchanged(connector))
 		return connector->status;
@@ -965,6 +965,9 @@
 				ret = connector_status_disconnected;
 				DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector));
 				radeon_connector->ddc_bus = NULL;
+			} else {
+				ret = connector_status_connected;
+				broken_edid = true; /* defer use_digital to later */
 			}
 		} else {
 			radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
@@ -1047,13 +1050,24 @@
 
 			encoder_funcs = encoder->helper_private;
 			if (encoder_funcs->detect) {
-				if (ret != connector_status_connected) {
-					ret = encoder_funcs->detect(encoder, connector);
-					if (ret == connector_status_connected) {
-						radeon_connector->use_digital = false;
+				if (!broken_edid) {
+					if (ret != connector_status_connected) {
+						/* deal with analog monitors without DDC */
+						ret = encoder_funcs->detect(encoder, connector);
+						if (ret == connector_status_connected) {
+							radeon_connector->use_digital = false;
+						}
+						if (ret != connector_status_disconnected)
+							radeon_connector->detected_by_load = true;
 					}
-					if (ret != connector_status_disconnected)
-						radeon_connector->detected_by_load = true;
+				} else {
+					enum drm_connector_status lret;
+					/* assume digital unless load detected otherwise */
+					radeon_connector->use_digital = true;
+					lret = encoder_funcs->detect(encoder, connector);
+					DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret);
+					if (lret == connector_status_connected)
+						radeon_connector->use_digital = false;
 				}
 				break;
 			}
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index bd13ca0..e2f5f88 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -355,6 +355,8 @@
  */
 void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base)
 {
+	uint64_t limit = (uint64_t)radeon_vram_limit << 20;
+
 	mc->vram_start = base;
 	if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) {
 		dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n");
@@ -368,8 +370,8 @@
 		mc->mc_vram_size = mc->aper_size;
 	}
 	mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
-	if (radeon_vram_limit && radeon_vram_limit < mc->real_vram_size)
-		mc->real_vram_size = radeon_vram_limit;
+	if (limit && limit < mc->real_vram_size)
+		mc->real_vram_size = limit;
 	dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
 			mc->mc_vram_size >> 20, mc->vram_start,
 			mc->vram_end, mc->real_vram_size >> 20);
@@ -835,6 +837,19 @@
 }
 
 /**
+ * radeon_check_pot_argument - check that argument is a power of two
+ *
+ * @arg: value to check
+ *
+ * Validates that a certain argument is a power of two (all asics).
+ * Returns true if argument is valid.
+ */
+static bool radeon_check_pot_argument(int arg)
+{
+	return (arg & (arg - 1)) == 0;
+}
+
+/**
  * radeon_check_arguments - validate module params
  *
  * @rdev: radeon_device pointer
@@ -845,52 +860,25 @@
 static void radeon_check_arguments(struct radeon_device *rdev)
 {
 	/* vramlimit must be a power of two */
-	switch (radeon_vram_limit) {
-	case 0:
-	case 4:
-	case 8:
-	case 16:
-	case 32:
-	case 64:
-	case 128:
-	case 256:
-	case 512:
-	case 1024:
-	case 2048:
-	case 4096:
-		break;
-	default:
+	if (!radeon_check_pot_argument(radeon_vram_limit)) {
 		dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n",
 				radeon_vram_limit);
 		radeon_vram_limit = 0;
-		break;
 	}
-	radeon_vram_limit = radeon_vram_limit << 20;
+
 	/* gtt size must be power of two and greater or equal to 32M */
-	switch (radeon_gart_size) {
-	case 4:
-	case 8:
-	case 16:
+	if (radeon_gart_size < 32) {
 		dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n",
 				radeon_gart_size);
 		radeon_gart_size = 512;
-		break;
-	case 32:
-	case 64:
-	case 128:
-	case 256:
-	case 512:
-	case 1024:
-	case 2048:
-	case 4096:
-		break;
-	default:
+
+	} else if (!radeon_check_pot_argument(radeon_gart_size)) {
 		dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n",
 				radeon_gart_size);
 		radeon_gart_size = 512;
-		break;
 	}
-	rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+	rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20;
+
 	/* AGP mode can only be -1, 1, 2, 4, 8 */
 	switch (radeon_agpmode) {
 	case -1:
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index a7677dd..4debd60 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -355,14 +355,13 @@
 	DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n",
 		 rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages);
 	/* Allocate pages table */
-	rdev->gart.pages = kzalloc(sizeof(void *) * rdev->gart.num_cpu_pages,
-				   GFP_KERNEL);
+	rdev->gart.pages = vzalloc(sizeof(void *) * rdev->gart.num_cpu_pages);
 	if (rdev->gart.pages == NULL) {
 		radeon_gart_fini(rdev);
 		return -ENOMEM;
 	}
-	rdev->gart.pages_addr = kzalloc(sizeof(dma_addr_t) *
-					rdev->gart.num_cpu_pages, GFP_KERNEL);
+	rdev->gart.pages_addr = vzalloc(sizeof(dma_addr_t) *
+					rdev->gart.num_cpu_pages);
 	if (rdev->gart.pages_addr == NULL) {
 		radeon_gart_fini(rdev);
 		return -ENOMEM;
@@ -388,8 +387,8 @@
 		radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages);
 	}
 	rdev->gart.ready = false;
-	kfree(rdev->gart.pages);
-	kfree(rdev->gart.pages_addr);
+	vfree(rdev->gart.pages);
+	vfree(rdev->gart.pages_addr);
 	rdev->gart.pages = NULL;
 	rdev->gart.pages_addr = NULL;
 
@@ -577,7 +576,7 @@
  *
  * Global and local mutex must be locked!
  */
-int radeon_vm_evict(struct radeon_device *rdev, struct radeon_vm *vm)
+static int radeon_vm_evict(struct radeon_device *rdev, struct radeon_vm *vm)
 {
 	struct radeon_vm *vm_evict;
 
@@ -1036,8 +1035,7 @@
 		pte = radeon_sa_bo_gpu_addr(vm->page_tables[pt_idx]);
 		pte += (addr & mask) * 8;
 
-		if (((last_pte + 8 * count) != pte) ||
-		    ((count + nptes) > 1 << 11)) {
+		if ((last_pte + 8 * count) != pte) {
 
 			if (count) {
 				radeon_asic_vm_set_page(rdev, last_pte,
@@ -1148,17 +1146,17 @@
 
 	if (RADEON_VM_BLOCK_SIZE > 11)
 		/* reserve space for one header for every 2k dwords */
-		ndw += (nptes >> 11) * 3;
+		ndw += (nptes >> 11) * 4;
 	else
 		/* reserve space for one header for
 		    every (1 << BLOCK_SIZE) entries */
-		ndw += (nptes >> RADEON_VM_BLOCK_SIZE) * 3;
+		ndw += (nptes >> RADEON_VM_BLOCK_SIZE) * 4;
 
 	/* reserve space for pte addresses */
 	ndw += nptes * 2;
 
 	/* reserve space for one header for every 2k dwords */
-	ndw += (npdes >> 11) * 3;
+	ndw += (npdes >> 11) * 4;
 
 	/* reserve space for pde addresses */
 	ndw += npdes * 2;
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index f38fbcc..fe5c1f6 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -53,6 +53,7 @@
 				struct drm_gem_object **obj)
 {
 	struct radeon_bo *robj;
+	unsigned long max_size;
 	int r;
 
 	*obj = NULL;
@@ -60,11 +61,26 @@
 	if (alignment < PAGE_SIZE) {
 		alignment = PAGE_SIZE;
 	}
+
+	/* maximun bo size is the minimun btw visible vram and gtt size */
+	max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size);
+	if (size > max_size) {
+		printk(KERN_WARNING "%s:%d alloc size %dMb bigger than %ldMb limit\n",
+		       __func__, __LINE__, size >> 20, max_size >> 20);
+		return -ENOMEM;
+	}
+
+retry:
 	r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, NULL, &robj);
 	if (r) {
-		if (r != -ERESTARTSYS)
+		if (r != -ERESTARTSYS) {
+			if (initial_domain == RADEON_GEM_DOMAIN_VRAM) {
+				initial_domain |= RADEON_GEM_DOMAIN_GTT;
+				goto retry;
+			}
 			DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n",
 				  size, initial_domain, alignment, r);
+		}
 		return r;
 	}
 	*obj = &robj->gem_base;
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 5677a42..6857cb4 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -295,6 +295,7 @@
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct radeon_device *rdev = dev->dev_private;
+	uint32_t crtc_ext_cntl = 0;
 	uint32_t mask;
 
 	if (radeon_crtc->crtc_id)
@@ -307,6 +308,16 @@
 			RADEON_CRTC_VSYNC_DIS |
 			RADEON_CRTC_HSYNC_DIS);
 
+	/*
+	 * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC.
+	 * Therefore it is set in the DAC DMPS function.
+	 * This is different for GPU's with a single CRTC but a primary and a
+	 * TV DAC: here it controls the single CRTC no matter where it is
+	 * routed. Therefore we set it here.
+	 */
+	if (rdev->flags & RADEON_SINGLE_CRTC)
+		crtc_ext_cntl = RADEON_CRTC_CRT_ON;
+	
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
 		radeon_crtc->enabled = true;
@@ -317,7 +328,7 @@
 		else {
 			WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
 									 RADEON_CRTC_DISP_REQ_EN_B));
-			WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask);
+			WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl));
 		}
 		drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
 		radeon_crtc_load_lut(crtc);
@@ -331,7 +342,7 @@
 		else {
 			WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
 										    RADEON_CRTC_DISP_REQ_EN_B));
-			WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask);
+			WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl));
 		}
 		radeon_crtc->enabled = false;
 		/* adjust pm to dpms changes AFTER disabling crtcs */
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index a13ad9d..f5ba224 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -370,6 +370,7 @@
 	struct backlight_properties props;
 	struct radeon_backlight_privdata *pdata;
 	uint8_t backlight_level;
+	char bl_name[16];
 
 	if (!radeon_encoder->enc_priv)
 		return;
@@ -389,7 +390,9 @@
 	memset(&props, 0, sizeof(props));
 	props.max_brightness = RADEON_MAX_BL_LEVEL;
 	props.type = BACKLIGHT_RAW;
-	bd = backlight_device_register("radeon_bl", &drm_connector->kdev,
+	snprintf(bl_name, sizeof(bl_name),
+		 "radeon_bl%d", dev->primary->index);
+	bd = backlight_device_register(bl_name, &drm_connector->kdev,
 				       pdata, &radeon_backlight_ops, &props);
 	if (IS_ERR(bd)) {
 		DRM_ERROR("Backlight registration failed\n");
@@ -534,7 +537,9 @@
 		break;
 	}
 
-	WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
+	/* handled in radeon_crtc_dpms() */
+	if (!(rdev->flags & RADEON_SINGLE_CRTC))
+		WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
 	WREG32(RADEON_DAC_CNTL, dac_cntl);
 	WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
 
@@ -659,6 +664,8 @@
 
 	if (ASIC_IS_R300(rdev))
 		tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+	else if (ASIC_IS_RV100(rdev))
+		tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT);
 	else
 		tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
 
@@ -668,6 +675,7 @@
 	tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
 	WREG32(RADEON_DAC_CNTL, tmp);
 
+	tmp = dac_macro_cntl;
 	tmp &= ~(RADEON_DAC_PDWN_R |
 		 RADEON_DAC_PDWN_G |
 		 RADEON_DAC_PDWN_B);
@@ -1089,7 +1097,8 @@
 	} else {
 		if (is_tv)
 			WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
-		else
+		/* handled in radeon_crtc_dpms() */
+		else if (!(rdev->flags & RADEON_SINGLE_CRTC))
 			WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
 		WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
 	}
@@ -1413,13 +1422,104 @@
 	return found;
 }
 
+static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder,
+					 struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
+	uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
+	uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
+	uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp;
+	uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
+	bool found = false;
+	int i;
+
+	/* save the regs we need */
+	gpio_monid = RREG32(RADEON_GPIO_MONID);
+	fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
+	disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
+	crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
+	disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A);
+	disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B);
+	disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C);
+	disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D);
+	disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E);
+	disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F);
+	crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP);
+	crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP);
+	crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID);
+	crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+	tmp = RREG32(RADEON_GPIO_MONID);
+	tmp &= ~RADEON_GPIO_A_0;
+	WREG32(RADEON_GPIO_MONID, tmp);
+
+	WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON |
+				     RADEON_FP2_PANEL_FORMAT |
+				     R200_FP2_SOURCE_SEL_TRANS_UNIT |
+				     RADEON_FP2_DVO_EN |
+				     R200_FP2_DVO_RATE_SEL_SDR));
+
+	WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX |
+					 RADEON_DISP_TRANS_MATRIX_GRAPHICS));
+
+	WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN |
+				       RADEON_CRTC2_DISP_REQ_EN_B));
+
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
+
+	WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
+	WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
+	WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+	WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+
+	for (i = 0; i < 200; i++) {
+		tmp = RREG32(RADEON_GPIO_MONID);
+		if (tmp & RADEON_GPIO_Y_0)
+			found = true;
+
+		if (found)
+			break;
+
+		if (!drm_can_sleep())
+			mdelay(1);
+		else
+			msleep(1);
+	}
+
+	/* restore the regs we used */
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
+	WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
+	WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
+	WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
+	WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
+	WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
+	WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+	WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+	WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+	WREG32(RADEON_GPIO_MONID, gpio_monid);
+
+	return found;
+}
+
 static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder,
 							     struct drm_connector *connector)
 {
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
-	uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
-	uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
+	uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
+	uint32_t gpiopad_a = 0, pixclks_cntl, tmp;
+	uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0;
 	enum drm_connector_status found = connector_status_disconnected;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
@@ -1456,12 +1556,27 @@
 		return connector_status_disconnected;
 	}
 
+	/* R200 uses an external DAC for secondary DAC */
+	if (rdev->family == CHIP_R200) {
+		if (radeon_legacy_ext_dac_detect(encoder, connector))
+			found = connector_status_connected;
+		return found;
+	}
+
 	/* save the regs we need */
 	pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
-	gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0;
-	disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0;
-	disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG);
-	crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
+
+	if (rdev->flags & RADEON_SINGLE_CRTC) {
+		crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
+	} else {
+		if (ASIC_IS_R300(rdev)) {
+			gpiopad_a = RREG32(RADEON_GPIOPAD_A);
+			disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
+		} else {
+			disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
+		}
+		crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
+	}
 	tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
 	dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL);
 	dac_cntl2 = RREG32(RADEON_DAC_CNTL2);
@@ -1470,22 +1585,24 @@
 			       | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
 	WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
 
-	if (ASIC_IS_R300(rdev))
-		WREG32_P(RADEON_GPIOPAD_A, 1, ~1);
-
-	tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
-	tmp |= RADEON_CRTC2_CRT2_ON |
-		(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
-
-	WREG32(RADEON_CRTC2_GEN_CNTL, tmp);
-
-	if (ASIC_IS_R300(rdev)) {
-		tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
-		tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
-		WREG32(RADEON_DISP_OUTPUT_CNTL, tmp);
+	if (rdev->flags & RADEON_SINGLE_CRTC) {
+		tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
+		WREG32(RADEON_CRTC_EXT_CNTL, tmp);
 	} else {
-		tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
-		WREG32(RADEON_DISP_HW_DEBUG, tmp);
+		tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
+		tmp |= RADEON_CRTC2_CRT2_ON |
+			(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
+		WREG32(RADEON_CRTC2_GEN_CNTL, tmp);
+
+		if (ASIC_IS_R300(rdev)) {
+			WREG32_P(RADEON_GPIOPAD_A, 1, ~1);
+			tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
+			tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+			WREG32(RADEON_DISP_OUTPUT_CNTL, tmp);
+		} else {
+			tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
+			WREG32(RADEON_DISP_HW_DEBUG, tmp);
+		}
 	}
 
 	tmp = RADEON_TV_DAC_NBLANK |
@@ -1527,14 +1644,19 @@
 	WREG32(RADEON_DAC_CNTL2, dac_cntl2);
 	WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
 	WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
-	WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
 
-	if (ASIC_IS_R300(rdev)) {
-		WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
-		WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
+	if (rdev->flags & RADEON_SINGLE_CRTC) {
+		WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
 	} else {
-		WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
+		WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+		if (ASIC_IS_R300(rdev)) {
+			WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+			WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
+		} else {
+			WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
+		}
 	}
+
 	WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
 
 	return found;
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 8b27dd6..b91118c 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -105,7 +105,6 @@
 	struct radeon_bo *bo;
 	enum ttm_bo_type type;
 	unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
-	unsigned long max_size = 0;
 	size_t acc_size;
 	int r;
 
@@ -121,18 +120,9 @@
 	}
 	*bo_ptr = NULL;
 
-	/* maximun bo size is the minimun btw visible vram and gtt size */
-	max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size);
-	if ((page_align << PAGE_SHIFT) >= max_size) {
-		printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n",
-			__func__, __LINE__, page_align  >> (20 - PAGE_SHIFT), max_size >> 20);
-		return -ENOMEM;
-	}
-
 	acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size,
 				       sizeof(struct radeon_bo));
 
-retry:
 	bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
 	if (bo == NULL)
 		return -ENOMEM;
@@ -154,15 +144,6 @@
 			acc_size, sg, &radeon_ttm_bo_destroy);
 	up_read(&rdev->pm.mclk_lock);
 	if (unlikely(r != 0)) {
-		if (r != -ERESTARTSYS) {
-			if (domain == RADEON_GEM_DOMAIN_VRAM) {
-				domain |= RADEON_GEM_DOMAIN_GTT;
-				goto retry;
-			}
-			dev_err(rdev->dev,
-				"object_init failed for (%lu, 0x%08X)\n",
-				size, domain);
-		}
 		return r;
 	}
 	*bo_ptr = bo;
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index df8dd77..4422d63 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -2474,6 +2474,7 @@
 	/* check config regs */
 	switch (reg) {
 	case GRBM_GFX_INDEX:
+	case CP_STRMOUT_CNTL:
 	case VGT_VTX_VECT_EJECT_REG:
 	case VGT_CACHE_INVALIDATION:
 	case VGT_ESGS_RING_SIZE:
@@ -2808,26 +2809,31 @@
 {
 	struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index];
 	uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
-	int i;
-	uint64_t value;
 
-	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 2 + count * 2));
-	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
-				 WRITE_DATA_DST_SEL(1)));
-	radeon_ring_write(ring, pe);
-	radeon_ring_write(ring, upper_32_bits(pe));
-	for (i = 0; i < count; ++i) {
-		if (flags & RADEON_VM_PAGE_SYSTEM) {
-			value = radeon_vm_map_gart(rdev, addr);
-			value &= 0xFFFFFFFFFFFFF000ULL;
-		} else if (flags & RADEON_VM_PAGE_VALID)
-			value = addr;
-		else
-			value = 0;
-		addr += incr;
-		value |= r600_flags;
-		radeon_ring_write(ring, value);
-		radeon_ring_write(ring, upper_32_bits(value));
+	while (count) {
+		unsigned ndw = 2 + count * 2;
+		if (ndw > 0x3FFE)
+			ndw = 0x3FFE;
+
+		radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, ndw));
+		radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+					 WRITE_DATA_DST_SEL(1)));
+		radeon_ring_write(ring, pe);
+		radeon_ring_write(ring, upper_32_bits(pe));
+		for (; ndw > 2; ndw -= 2, --count, pe += 8) {
+			uint64_t value;
+			if (flags & RADEON_VM_PAGE_SYSTEM) {
+				value = radeon_vm_map_gart(rdev, addr);
+				value &= 0xFFFFFFFFFFFFF000ULL;
+			} else if (flags & RADEON_VM_PAGE_VALID)
+				value = addr;
+			else
+				value = 0;
+			addr += incr;
+			value |= r600_flags;
+			radeon_ring_write(ring, value);
+			radeon_ring_write(ring, upper_32_bits(value));
+		}
 	}
 }
 
@@ -2868,6 +2874,10 @@
 	radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
 	radeon_ring_write(ring, 0);
 	radeon_ring_write(ring, 1 << vm->id);
+
+	/* sync PFP to ME, otherwise we might get invalid PFP reads */
+	radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
+	radeon_ring_write(ring, 0x0);
 }
 
 /*
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index 7d2a20e..a8871af 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -424,6 +424,7 @@
 #       define RDERR_INT_ENABLE                         (1 << 0)
 #       define GUI_IDLE_INT_ENABLE                      (1 << 19)
 
+#define	CP_STRMOUT_CNTL					0x84FC
 #define	SCRATCH_REG0					0x8500
 #define	SCRATCH_REG1					0x8504
 #define	SCRATCH_REG2					0x8508
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
index c71d493..1c350fc 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -201,6 +201,8 @@
 		goto done;
 	}
 
+	platform_set_drvdata(pdev, sdev);
+
 done:
 	if (ret)
 		shmob_drm_unload(dev);
@@ -299,11 +301,9 @@
 #if CONFIG_PM_SLEEP
 static int shmob_drm_pm_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct drm_device *ddev = platform_get_drvdata(pdev);
-	struct shmob_drm_device *sdev = ddev->dev_private;
+	struct shmob_drm_device *sdev = dev_get_drvdata(dev);
 
-	drm_kms_helper_poll_disable(ddev);
+	drm_kms_helper_poll_disable(sdev->ddev);
 	shmob_drm_crtc_suspend(&sdev->crtc);
 
 	return 0;
@@ -311,9 +311,7 @@
 
 static int shmob_drm_pm_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct drm_device *ddev = platform_get_drvdata(pdev);
-	struct shmob_drm_device *sdev = ddev->dev_private;
+	struct shmob_drm_device *sdev = dev_get_drvdata(dev);
 
 	mutex_lock(&sdev->ddev->mode_config.mutex);
 	shmob_drm_crtc_resume(&sdev->crtc);
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 402ab69..bf6e4b5 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -580,6 +580,7 @@
 	if (unlikely(ret != 0))
 		return ret;
 
+retry_reserve:
 	spin_lock(&glob->lru_lock);
 
 	if (unlikely(list_empty(&bo->ddestroy))) {
@@ -587,14 +588,20 @@
 		return 0;
 	}
 
-	ret = ttm_bo_reserve_locked(bo, interruptible,
-				    no_wait_reserve, false, 0);
+	ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
 
-	if (unlikely(ret != 0)) {
+	if (unlikely(ret == -EBUSY)) {
 		spin_unlock(&glob->lru_lock);
-		return ret;
+		if (likely(!no_wait_reserve))
+			ret = ttm_bo_wait_unreserved(bo, interruptible);
+		if (unlikely(ret != 0))
+			return ret;
+
+		goto retry_reserve;
 	}
 
+	BUG_ON(ret != 0);
+
 	/**
 	 * We can re-check for sync object without taking
 	 * the bo::lock since setting the sync object requires
@@ -811,17 +818,14 @@
 					  no_wait_reserve, no_wait_gpu);
 		kref_put(&bo->list_kref, ttm_bo_release_list);
 
-		if (likely(ret == 0 || ret == -ERESTARTSYS))
-			return ret;
-
-		goto retry;
+		return ret;
 	}
 
-	ret = ttm_bo_reserve_locked(bo, false, no_wait_reserve, false, 0);
+	ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
 
 	if (unlikely(ret == -EBUSY)) {
 		spin_unlock(&glob->lru_lock);
-		if (likely(!no_wait_gpu))
+		if (likely(!no_wait_reserve))
 			ret = ttm_bo_wait_unreserved(bo, interruptible);
 
 		kref_put(&bo->list_kref, ttm_bo_release_list);
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index 860dc48..bd2a3b4 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -749,7 +749,10 @@
 	/* clear the pages coming from the pool if requested */
 	if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) {
 		list_for_each_entry(p, &plist, lru) {
-			clear_page(page_address(p));
+			if (PageHighMem(p))
+				clear_highpage(p);
+			else
+				clear_page(page_address(p));
 		}
 	}
 
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index bf82601..7d759a4 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -308,9 +308,7 @@
 		if (unlikely(to_page == NULL))
 			goto out_err;
 
-		preempt_disable();
 		copy_highpage(to_page, from_page);
-		preempt_enable();
 		page_cache_release(from_page);
 	}
 
@@ -358,9 +356,7 @@
 			ret = PTR_ERR(to_page);
 			goto out_err;
 		}
-		preempt_disable();
 		copy_highpage(to_page, from_page);
-		preempt_enable();
 		set_page_dirty(to_page);
 		mark_page_accessed(to_page);
 		page_cache_release(to_page);
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index fccd361..87aa5f5 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -104,7 +104,7 @@
 
 int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
 		     const char *front, char **urb_buf_ptr,
-		     u32 byte_offset, u32 byte_width,
+		     u32 byte_offset, u32 device_byte_offset, u32 byte_width,
 		     int *ident_ptr, int *sent_ptr);
 
 int udl_dumb_create(struct drm_file *file_priv,
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index 69a2b16..d4ab3be 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -114,9 +114,10 @@
 	list_for_each_entry(cur, &fbdefio->pagelist, lru) {
 
 		if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8),
-				  &urb, (char *) info->fix.smem_start,
-				  &cmd, cur->index << PAGE_SHIFT,
-				  PAGE_SIZE, &bytes_identical, &bytes_sent))
+				     &urb, (char *) info->fix.smem_start,
+				     &cmd, cur->index << PAGE_SHIFT,
+				     cur->index << PAGE_SHIFT,
+				     PAGE_SIZE, &bytes_identical, &bytes_sent))
 			goto error;
 		bytes_rendered += PAGE_SIZE;
 	}
@@ -187,10 +188,11 @@
 	for (i = y; i < y + height ; i++) {
 		const int line_offset = fb->base.pitches[0] * i;
 		const int byte_offset = line_offset + (x * bpp);
-
+		const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);
 		if (udl_render_hline(dev, bpp, &urb,
 				     (char *) fb->obj->vmapping,
-				     &cmd, byte_offset, width * bpp,
+				     &cmd, byte_offset, dev_byte_offset,
+				     width * bpp,
 				     &bytes_identical, &bytes_sent))
 			goto error;
 	}
diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c
index dc09552..142fee5 100644
--- a/drivers/gpu/drm/udl/udl_transfer.c
+++ b/drivers/gpu/drm/udl/udl_transfer.c
@@ -213,11 +213,12 @@
  */
 int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
 		     const char *front, char **urb_buf_ptr,
-		     u32 byte_offset, u32 byte_width,
+		     u32 byte_offset, u32 device_byte_offset,
+		     u32 byte_width,
 		     int *ident_ptr, int *sent_ptr)
 {
 	const u8 *line_start, *line_end, *next_pixel;
-	u32 base16 = 0 + (byte_offset / bpp) * 2;
+	u32 base16 = 0 + (device_byte_offset / bpp) * 2;
 	struct urb *urb = *urb_ptr;
 	u8 *cmd = *urb_buf_ptr;
 	u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
index 3ce68a2..d1498bf 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
@@ -306,7 +306,7 @@
 
 	BUG_ON(!atomic_read(&bo->reserved));
 	BUG_ON(old_mem_type != TTM_PL_VRAM &&
-	       old_mem_type != VMW_PL_FLAG_GMR);
+	       old_mem_type != VMW_PL_GMR);
 
 	pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED;
 	if (pin)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index ed3c1e7..2dd185e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1098,6 +1098,11 @@
 	struct drm_device *dev = pci_get_drvdata(pdev);
 	struct vmw_private *dev_priv = vmw_priv(dev);
 
+	mutex_lock(&dev_priv->hw_mutex);
+	vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
+	(void) vmw_read(dev_priv, SVGA_REG_ID);
+	mutex_unlock(&dev_priv->hw_mutex);
+
 	/**
 	 * Reclaim 3d reference held by fbdev and potentially
 	 * start fifo.
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index b07ca2e..7290811 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -110,6 +110,8 @@
 	memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size);
 
 	ret = copy_to_user(buffer, bounce, size);
+	if (ret)
+		ret = -EFAULT;
 	vfree(bounce);
 
 	if (unlikely(ret != 0))
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index 06ebdbb..fd7722a 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -522,6 +522,12 @@
 		.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS),
 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI),
+		.driver_data = APPLE_HAS_FN },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO),
+		.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS),
+		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index bd3971b..f4109fd 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1532,6 +1532,9 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
@@ -2139,6 +2142,9 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
 	{ }
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 269b509..9d7a428 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -118,6 +118,9 @@
 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI	0x0252
 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO	0x0253
 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS	0x0254
+#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI	0x0259
+#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO	0x025a
+#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS	0x025b
 #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI	0x0249
 #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO	0x024a
 #define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS	0x024b
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 3acdcfc..6fcd466d0 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -28,22 +28,30 @@
 #define MS_RDESC		0x08
 #define MS_NOGET		0x10
 #define MS_DUPLICATE_USAGES	0x20
+#define MS_RDESC_3K		0x40
 
-/*
- * Microsoft Wireless Desktop Receiver (Model 1028) has
- * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
- */
 static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		unsigned int *rsize)
 {
 	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
 
+	/*
+	 * Microsoft Wireless Desktop Receiver (Model 1028) has
+	 * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
+	 */
 	if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 &&
 			rdesc[559] == 0x29) {
 		hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n");
 		rdesc[557] = 0x35;
 		rdesc[559] = 0x45;
 	}
+	/* the same as above (s/usage/physical/) */
+	if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 &&
+			rdesc[95] == 0x00 && rdesc[96] == 0x29 &&
+			rdesc[97] == 0xff) {
+		rdesc[94] = 0x35;
+		rdesc[96] = 0x45;
+	}
 	return rdesc;
 }
 
@@ -192,7 +200,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB),
 		.driver_data = MS_PRESENTER },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K),
-		.driver_data = MS_ERGONOMY },
+		.driver_data = MS_ERGONOMY | MS_RDESC_3K },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0),
 		.driver_data = MS_NOGET },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500),
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 3eb02b9..7867d69 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -210,8 +210,7 @@
 	},
 	{ .name	= MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
 		.quirks	= MT_QUIRK_NOT_SEEN_MEANS_UP |
-			MT_QUIRK_SLOT_IS_CONTACTNUMBER,
-		.maxcontacts = 10
+			MT_QUIRK_SLOT_IS_CONTACTNUMBER
 	},
 
 	{ .name = MT_CLS_FLATFROG,
@@ -421,11 +420,11 @@
 			 * contact max are global to the report */
 			td->last_field_index = field->index;
 			return -1;
-		}
 		case HID_DG_TOUCH:
 			/* Legacy devices use TIPSWITCH and not TOUCH.
 			 * Let's just ignore this field. */
 			return -1;
+		}
 		/* let hid-input decide for the others */
 		return 0;
 
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 17d15bb..7c47fc3 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -42,7 +42,6 @@
 static struct class *hidraw_class;
 static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES];
 static DEFINE_MUTEX(minors_lock);
-static void drop_ref(struct hidraw *hid, int exists_bit);
 
 static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
@@ -114,7 +113,7 @@
 	__u8 *buf;
 	int ret = 0;
 
-	if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
+	if (!hidraw_table[minor]) {
 		ret = -ENODEV;
 		goto out;
 	}
@@ -262,7 +261,7 @@
 	}
 
 	mutex_lock(&minors_lock);
-	if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
+	if (!hidraw_table[minor]) {
 		err = -ENODEV;
 		goto out_unlock;
 	}
@@ -299,12 +298,36 @@
 static int hidraw_release(struct inode * inode, struct file * file)
 {
 	unsigned int minor = iminor(inode);
+	struct hidraw *dev;
 	struct hidraw_list *list = file->private_data;
+	int ret;
+	int i;
 
-	drop_ref(hidraw_table[minor], 0);
+	mutex_lock(&minors_lock);
+	if (!hidraw_table[minor]) {
+		ret = -ENODEV;
+		goto unlock;
+	}
+
 	list_del(&list->node);
+	dev = hidraw_table[minor];
+	if (!--dev->open) {
+		if (list->hidraw->exist) {
+			hid_hw_power(dev->hid, PM_HINT_NORMAL);
+			hid_hw_close(dev->hid);
+		} else {
+			kfree(list->hidraw);
+		}
+	}
+
+	for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i)
+		kfree(list->buffer[i].value);
 	kfree(list);
-	return 0;
+	ret = 0;
+unlock:
+	mutex_unlock(&minors_lock);
+
+	return ret;
 }
 
 static long hidraw_ioctl(struct file *file, unsigned int cmd,
@@ -506,7 +529,21 @@
 void hidraw_disconnect(struct hid_device *hid)
 {
 	struct hidraw *hidraw = hid->hidraw;
-	drop_ref(hidraw, 1);
+
+	mutex_lock(&minors_lock);
+	hidraw->exist = 0;
+
+	device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
+
+	hidraw_table[hidraw->minor] = NULL;
+
+	if (hidraw->open) {
+		hid_hw_close(hid);
+		wake_up_interruptible(&hidraw->wait);
+	} else {
+		kfree(hidraw);
+	}
+	mutex_unlock(&minors_lock);
 }
 EXPORT_SYMBOL_GPL(hidraw_disconnect);
 
@@ -555,23 +592,3 @@
 	unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES);
 
 }
-
-static void drop_ref(struct hidraw *hidraw, int exists_bit)
-{
-	mutex_lock(&minors_lock);
-	if (exists_bit) {
-		hid_hw_close(hidraw->hid);
-		hidraw->exist = 0;
-		if (hidraw->open)
-			wake_up_interruptible(&hidraw->wait);
-	} else {
-		--hidraw->open;
-	}
-
-	if (!hidraw->open && !hidraw->exist) {
-		device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
-		hidraw_table[hidraw->minor] = NULL;
-		kfree(hidraw);
-	}
-	mutex_unlock(&minors_lock);
-}
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 4065374..f4c3d28 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -146,14 +146,14 @@
 
 	if (ret != 0) {
 		err = ret;
-		goto errorout;
+		goto error0;
 	}
 
 	ret = hv_ringbuffer_init(
 		&newchannel->inbound, in, recv_ringbuffer_size);
 	if (ret != 0) {
 		err = ret;
-		goto errorout;
+		goto error0;
 	}
 
 
@@ -168,7 +168,7 @@
 
 	if (ret != 0) {
 		err = ret;
-		goto errorout;
+		goto error0;
 	}
 
 	/* Create and init the channel open message */
@@ -177,7 +177,7 @@
 			   GFP_KERNEL);
 	if (!open_info) {
 		err = -ENOMEM;
-		goto errorout;
+		goto error0;
 	}
 
 	init_completion(&open_info->waitevent);
@@ -193,7 +193,7 @@
 
 	if (userdatalen > MAX_USER_DEFINED_BYTES) {
 		err = -EINVAL;
-		goto errorout;
+		goto error0;
 	}
 
 	if (userdatalen)
@@ -208,19 +208,18 @@
 			       sizeof(struct vmbus_channel_open_channel));
 
 	if (ret != 0)
-		goto cleanup;
+		goto error1;
 
 	t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ);
 	if (t == 0) {
 		err = -ETIMEDOUT;
-		goto errorout;
+		goto error1;
 	}
 
 
 	if (open_info->response.open_result.status)
 		err = open_info->response.open_result.status;
 
-cleanup:
 	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
 	list_del(&open_info->msglistentry);
 	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
@@ -228,9 +227,12 @@
 	kfree(open_info);
 	return err;
 
-errorout:
-	hv_ringbuffer_cleanup(&newchannel->outbound);
-	hv_ringbuffer_cleanup(&newchannel->inbound);
+error1:
+	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
+	list_del(&open_info->msglistentry);
+	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+
+error0:
 	free_pages((unsigned long)out,
 		get_order(send_ringbuffer_size + recv_ringbuffer_size));
 	kfree(open_info);
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index a227be4..520e5bf 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -32,7 +32,7 @@
  * ASB100-A supports pwm1, while plain ASB100 does not.  There is no known
  * way for the driver to tell which one is there.
  *
- * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * Chip		#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
  * asb100	7	3	1	4	0x31	0x0694	yes	no
  */
 
diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c
index 68ad7d2..4f41104 100644
--- a/drivers/hwmon/fam15h_power.c
+++ b/drivers/hwmon/fam15h_power.c
@@ -2,7 +2,7 @@
  * fam15h_power.c - AMD Family 15h processor power monitoring
  *
  * Copyright (c) 2011 Advanced Micro Devices, Inc.
- * Author: Andreas Herrmann <andreas.herrmann3@amd.com>
+ * Author: Andreas Herrmann <herrmann.der.user@googlemail.com>
  *
  *
  * This driver is free software; you can redistribute it and/or
@@ -28,7 +28,7 @@
 #include <asm/processor.h>
 
 MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor");
-MODULE_AUTHOR("Andreas Herrmann <andreas.herrmann3@amd.com>");
+MODULE_AUTHOR("Andreas Herrmann <herrmann.der.user@googlemail.com>");
 MODULE_LICENSE("GPL");
 
 /* D18F3 */
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index 36509ae..1381a2e 100644
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -630,7 +630,9 @@
 	.driver	= {
 		.name	= "gpio-fan",
 		.pm	= GPIO_FAN_PM,
+#ifdef CONFIG_OF_GPIO
 		.of_match_table = of_match_ptr(of_gpio_fan_match),
+#endif
 	},
 };
 
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 1821b74..de3c7e0 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -2083,6 +2083,7 @@
 	mutex_init(&data->lock);
 	mutex_init(&data->update_lock);
 	data->name = w83627ehf_device_names[sio_data->kind];
+	data->bank = 0xff;		/* Force initial bank selection */
 	platform_set_drvdata(pdev, data);
 
 	/* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 5b1a6a6..af15899 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -25,7 +25,7 @@
 /*
  * Supports following chips:
  *
- * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * Chip		#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
  * w83627hf	9	3	2	3	0x20	0x5ca3	no	yes(LPC)
  * w83627thf	7	3	3	3	0x90	0x5ca3	no	yes(LPC)
  * w83637hf	7	3	3	3	0x80	0x5ca3	no	yes(LPC)
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 5a5046d..20f11d3 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -24,7 +24,7 @@
 /*
  * Supports following chips:
  *
- * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * Chip		#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
  * as99127f	7	3	0	3	0x31	0x12c3	yes	no
  * as99127f rev.2 (type_name = as99127f)	0x31	0x5ca3	yes	no
  * w83781d	7	3	0	3	0x10-1	0x5ca3	yes	yes
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index 39ab7bc..ed397c6 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -22,7 +22,7 @@
 /*
  * Supports following chips:
  *
- * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * Chip		#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
  * w83791d	10	5	5	3	0x71	0x5ca3	yes	no
  *
  * The w83791d chip appears to be part way between the 83781d and the
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 0536452..301942d 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -31,7 +31,7 @@
 /*
  * Supports following chips:
  *
- * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * Chip		#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
  * w83792d	9	7	7	3	0x7a	0x5ca3	yes	no
  */
 
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c
index f0e8286..79710bc 100644
--- a/drivers/hwmon/w83l786ng.c
+++ b/drivers/hwmon/w83l786ng.c
@@ -20,7 +20,7 @@
 /*
  * Supports following chips:
  *
- * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * Chip		#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
  * w83l786ng	3	2	2	2	0x7b	0x5ca3	yes	no
  */
 
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index beee6b2..1722f50 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -8,6 +8,7 @@
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
 obj-$(CONFIG_I2C_MUX)		+= i2c-mux.o
 obj-y				+= algos/ busses/ muxes/
+obj-$(CONFIG_I2C_STUB)		+= i2c-stub.o
 
 ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG
 CFLAGS_i2c-core.o := -Wno-deprecated-declarations
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 65dd599..e9df461 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -81,7 +81,6 @@
 	tristate "Intel 82801 (ICH/PCH)"
 	depends on PCI
 	select CHECK_SIGNATURE if X86 && DMI
-	select GPIOLIB if I2C_MUX
 	help
 	  If you say yes to this option, support will be included for the Intel
 	  801 family of mainboard I2C interfaces.  Specifically, the following
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 2d33d62..395b516 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -85,7 +85,6 @@
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_I2C_PCA_ISA)	+= i2c-pca-isa.o
 obj-$(CONFIG_I2C_SIBYTE)	+= i2c-sibyte.o
-obj-$(CONFIG_I2C_STUB)		+= i2c-stub.o
 obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
 obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
 
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 3779315..6abc00d 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -82,7 +82,8 @@
 #include <linux/wait.h>
 #include <linux/err.h>
 
-#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
+#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
+		defined CONFIG_DMI
 #include <linux/gpio.h>
 #include <linux/i2c-mux-gpio.h>
 #include <linux/platform_device.h>
@@ -192,7 +193,8 @@
 	int len;
 	u8 *data;
 
-#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
+#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
+		defined CONFIG_DMI
 	const struct i801_mux_config *mux_drvdata;
 	struct platform_device *mux_pdev;
 #endif
@@ -921,7 +923,8 @@
 static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {}
 #endif	/* CONFIG_X86 && CONFIG_DMI */
 
-#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
+#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
+		defined CONFIG_DMI
 static struct i801_mux_config i801_mux_config_asus_z8_d12 = {
 	.gpio_chip = "gpio_ich",
 	.values = { 0x02, 0x03 },
@@ -1059,7 +1062,7 @@
 
 	id = dmi_first_match(mux_dmi_table);
 	if (id) {
-		/* Remove from branch classes from trunk */
+		/* Remove branch classes from trunk */
 		mux_config = id->driver_data;
 		for (i = 0; i < mux_config->n_values; i++)
 			class &= ~mux_config->classes[i];
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 2ef162d..b973474 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -52,8 +52,6 @@
 #include <linux/of_device.h>
 #include <linux/of_i2c.h>
 #include <linux/pinctrl/consumer.h>
-
-#include <mach/hardware.h>
 #include <linux/platform_data/i2c-imx.h>
 
 /** Defines ********************************************************************
@@ -115,6 +113,11 @@
 	{ 3072,	0x1E }, { 3840,	0x1F }
 };
 
+enum imx_i2c_type {
+	IMX1_I2C,
+	IMX21_I2C,
+};
+
 struct imx_i2c_struct {
 	struct i2c_adapter	adapter;
 	struct clk		*clk;
@@ -124,13 +127,33 @@
 	unsigned int 		disable_delay;
 	int			stopped;
 	unsigned int		ifdr; /* IMX_I2C_IFDR */
+	enum imx_i2c_type	devtype;
 };
 
+static struct platform_device_id imx_i2c_devtype[] = {
+	{
+		.name = "imx1-i2c",
+		.driver_data = IMX1_I2C,
+	}, {
+		.name = "imx21-i2c",
+		.driver_data = IMX21_I2C,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
+
 static const struct of_device_id i2c_imx_dt_ids[] = {
-	{ .compatible = "fsl,imx1-i2c", },
+	{ .compatible = "fsl,imx1-i2c", .data = &imx_i2c_devtype[IMX1_I2C], },
+	{ .compatible = "fsl,imx21-i2c", .data = &imx_i2c_devtype[IMX21_I2C], },
 	{ /* sentinel */ }
 };
 
+static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)
+{
+	return i2c_imx->devtype == IMX1_I2C;
+}
+
 /** Functions for IMX I2C adapter driver ***************************************
 *******************************************************************************/
 
@@ -223,7 +246,7 @@
 		temp &= ~(I2CR_MSTA | I2CR_MTX);
 		writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
 	}
-	if (cpu_is_mx1()) {
+	if (is_imx1_i2c(i2c_imx)) {
 		/*
 		 * This delay caused by an i.MXL hardware bug.
 		 * If no (or too short) delay, no "STOP" bit will be generated.
@@ -465,6 +488,8 @@
 
 static int __init i2c_imx_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *of_id = of_match_device(i2c_imx_dt_ids,
+							   &pdev->dev);
 	struct imx_i2c_struct *i2c_imx;
 	struct resource *res;
 	struct imxi2c_platform_data *pdata = pdev->dev.platform_data;
@@ -497,6 +522,10 @@
 		return -ENOMEM;
 	}
 
+	if (of_id)
+		pdev->id_entry = of_id->data;
+	i2c_imx->devtype = pdev->id_entry->driver_data;
+
 	/* Setup i2c_imx driver structure */
 	strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
 	i2c_imx->adapter.owner		= THIS_MODULE;
@@ -593,7 +622,8 @@
 		.name	= DRIVER_NAME,
 		.owner	= THIS_MODULE,
 		.of_match_table = i2c_imx_dt_ids,
-	}
+	},
+	.id_table	= imx_i2c_devtype,
 };
 
 static int __init i2c_adap_imx_init(void)
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 1f58197..286ca19 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -1,7 +1,7 @@
 /*
  * Freescale MXS I2C bus driver
  *
- * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K.
+ * Copyright (C) 2011-2012 Wolfram Sang, Pengutronix e.K.
  *
  * based on a (non-working) driver which was:
  *
@@ -35,10 +35,6 @@
 
 #define DRIVER_NAME "mxs-i2c"
 
-static bool use_pioqueue;
-module_param(use_pioqueue, bool, 0);
-MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA");
-
 #define MXS_I2C_CTRL0		(0x00)
 #define MXS_I2C_CTRL0_SET	(0x04)
 
@@ -75,23 +71,6 @@
 				 MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \
 				 MXS_I2C_CTRL1_SLAVE_IRQ)
 
-#define MXS_I2C_QUEUECTRL	(0x60)
-#define MXS_I2C_QUEUECTRL_SET	(0x64)
-#define MXS_I2C_QUEUECTRL_CLR	(0x68)
-
-#define MXS_I2C_QUEUECTRL_QUEUE_RUN		0x20
-#define MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE	0x04
-
-#define MXS_I2C_QUEUESTAT	(0x70)
-#define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY        0x00002000
-#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK	0x0000001F
-
-#define MXS_I2C_QUEUECMD	(0x80)
-
-#define MXS_I2C_QUEUEDATA	(0x90)
-
-#define MXS_I2C_DATA		(0xa0)
-
 
 #define MXS_CMD_I2C_SELECT	(MXS_I2C_CTRL0_RETAIN_CLOCK |	\
 				 MXS_I2C_CTRL0_PRE_SEND_START |	\
@@ -153,7 +132,6 @@
 	const struct mxs_i2c_speed_config *speed;
 
 	/* DMA support components */
-	bool				dma_mode;
 	int				dma_channel;
 	struct dma_chan         	*dmach;
 	struct mxs_dma_data		dma_data;
@@ -172,99 +150,6 @@
 	writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2);
 
 	writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
-	if (i2c->dma_mode)
-		writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
-			i2c->regs + MXS_I2C_QUEUECTRL_CLR);
-	else
-		writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
-			i2c->regs + MXS_I2C_QUEUECTRL_SET);
-}
-
-static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len,
-					int flags)
-{
-	u32 data;
-
-	writel(MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_QUEUECMD);
-
-	data = (addr << 1) | I2C_SMBUS_READ;
-	writel(data, i2c->regs + MXS_I2C_DATA);
-
-	data = MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(len) | flags;
-	writel(data, i2c->regs + MXS_I2C_QUEUECMD);
-}
-
-static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c,
-				    u8 addr, u8 *buf, int len, int flags)
-{
-	u32 data;
-	int i, shifts_left;
-
-	data = MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(len + 1) | flags;
-	writel(data, i2c->regs + MXS_I2C_QUEUECMD);
-
-	/*
-	 * We have to copy the slave address (u8) and buffer (arbitrary number
-	 * of u8) into the data register (u32). To achieve that, the u8 are put
-	 * into the MSBs of 'data' which is then shifted for the next u8. When
-	 * appropriate, 'data' is written to MXS_I2C_DATA. So, the first u32
-	 * looks like this:
-	 *
-	 *  3          2          1          0
-	 * 10987654|32109876|54321098|76543210
-	 * --------+--------+--------+--------
-	 * buffer+2|buffer+1|buffer+0|slave_addr
-	 */
-
-	data = ((addr << 1) | I2C_SMBUS_WRITE) << 24;
-
-	for (i = 0; i < len; i++) {
-		data >>= 8;
-		data |= buf[i] << 24;
-		if ((i & 3) == 2)
-			writel(data, i2c->regs + MXS_I2C_DATA);
-	}
-
-	/* Write out the remaining bytes if any */
-	shifts_left = 24 - (i & 3) * 8;
-	if (shifts_left)
-		writel(data >> shifts_left, i2c->regs + MXS_I2C_DATA);
-}
-
-/*
- * TODO: should be replaceable with a waitqueue and RD_QUEUE_IRQ (setting the
- * rd_threshold to 1). Couldn't get this to work, though.
- */
-static int mxs_i2c_wait_for_data(struct mxs_i2c_dev *i2c)
-{
-	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
-
-	while (readl(i2c->regs + MXS_I2C_QUEUESTAT)
-			& MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY) {
-			if (time_after(jiffies, timeout))
-				return -ETIMEDOUT;
-			cond_resched();
-	}
-
-	return 0;
-}
-
-static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len)
-{
-	u32 uninitialized_var(data);
-	int i;
-
-	for (i = 0; i < len; i++) {
-		if ((i & 3) == 0) {
-			if (mxs_i2c_wait_for_data(i2c))
-				return -ETIMEDOUT;
-			data = readl(i2c->regs + MXS_I2C_QUEUEDATA);
-		}
-		buf[i] = data & 0xff;
-		data >>= 8;
-	}
-
-	return 0;
 }
 
 static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c)
@@ -432,39 +317,17 @@
 	init_completion(&i2c->cmd_complete);
 	i2c->cmd_err = 0;
 
-	if (i2c->dma_mode) {
-		ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
-		if (ret)
-			return ret;
-	} else {
-		if (msg->flags & I2C_M_RD) {
-			mxs_i2c_pioq_setup_read(i2c, msg->addr,
-						msg->len, flags);
-		} else {
-			mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf,
-						msg->len, flags);
-		}
-
-		writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
-			i2c->regs + MXS_I2C_QUEUECTRL_SET);
-	}
+	ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
+	if (ret)
+		return ret;
 
 	ret = wait_for_completion_timeout(&i2c->cmd_complete,
 						msecs_to_jiffies(1000));
 	if (ret == 0)
 		goto timeout;
 
-	if (!i2c->dma_mode && !i2c->cmd_err && (msg->flags & I2C_M_RD)) {
-		ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len);
-		if (ret)
-			goto timeout;
-	}
-
 	if (i2c->cmd_err == -ENXIO)
 		mxs_i2c_reset(i2c);
-	else
-		writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
-				i2c->regs + MXS_I2C_QUEUECTRL_CLR);
 
 	dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err);
 
@@ -472,8 +335,7 @@
 
 timeout:
 	dev_dbg(i2c->dev, "Timeout!\n");
-	if (i2c->dma_mode)
-		mxs_i2c_dma_finish(i2c);
+	mxs_i2c_dma_finish(i2c);
 	mxs_i2c_reset(i2c);
 	return -ETIMEDOUT;
 }
@@ -502,7 +364,6 @@
 {
 	struct mxs_i2c_dev *i2c = dev_id;
 	u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK;
-	bool is_last_cmd;
 
 	if (!stat)
 		return IRQ_NONE;
@@ -515,14 +376,6 @@
 		/* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */
 		i2c->cmd_err = -EIO;
 
-	if (!i2c->dma_mode) {
-		is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
-			MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
-
-		if (is_last_cmd || i2c->cmd_err)
-			complete(&i2c->cmd_complete);
-	}
-
 	writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR);
 
 	return IRQ_HANDLED;
@@ -556,23 +409,14 @@
 	int ret;
 
 	/*
-	 * The MXS I2C DMA mode is prefered and enabled by default.
-	 * The PIO mode is still supported, but should be used only
-	 * for debuging purposes etc.
-	 */
-	i2c->dma_mode = !use_pioqueue;
-	if (!i2c->dma_mode)
-		dev_info(dev, "Using PIOQUEUE mode for I2C transfers!\n");
-
-	/*
 	 * TODO: This is a temporary solution and should be changed
 	 * to use generic DMA binding later when the helpers get in.
 	 */
 	ret = of_property_read_u32(node, "fsl,i2c-dma-channel",
 				   &i2c->dma_channel);
 	if (ret) {
-		dev_warn(dev, "Failed to get DMA channel, using PIOQUEUE!\n");
-		i2c->dma_mode = 0;
+		dev_err(dev, "Failed to get DMA channel!\n");
+		return -ENODEV;
 	}
 
 	ret = of_property_read_u32(node, "clock-frequency", &speed);
@@ -634,15 +478,13 @@
 	}
 
 	/* Setup the DMA */
-	if (i2c->dma_mode) {
-		dma_cap_zero(mask);
-		dma_cap_set(DMA_SLAVE, mask);
-		i2c->dma_data.chan_irq = dmairq;
-		i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c);
-		if (!i2c->dmach) {
-			dev_err(dev, "Failed to request dma\n");
-			return -ENODEV;
-		}
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	i2c->dma_data.chan_irq = dmairq;
+	i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c);
+	if (!i2c->dmach) {
+		dev_err(dev, "Failed to request dma\n");
+		return -ENODEV;
 	}
 
 	platform_set_drvdata(pdev, i2c);
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 698d7ac..02c3115 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -644,7 +644,11 @@
 
 	pm_runtime_get_sync(&dev->adev->dev);
 
-	clk_enable(dev->clk);
+	status = clk_prepare_enable(dev->clk);
+	if (status) {
+		dev_err(&dev->adev->dev, "can't prepare_enable clock\n");
+		goto out_clk;
+	}
 
 	status = init_hw(dev);
 	if (status)
@@ -671,7 +675,8 @@
 	}
 
 out:
-	clk_disable(dev->clk);
+	clk_disable_unprepare(dev->clk);
+out_clk:
 	pm_runtime_put_sync(&dev->adev->dev);
 
 	dev->busy = false;
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index f981ac4..dcea77b 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -742,7 +742,7 @@
 	}
 
 	ret = devm_request_irq(&pdev->dev, i2c_dev->irq,
-			tegra_i2c_isr, 0, pdev->name, i2c_dev);
+			tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq);
 		return ret;
diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/i2c-stub.c
similarity index 75%
rename from drivers/i2c/busses/i2c-stub.c
rename to drivers/i2c/i2c-stub.c
index b1b34479..d0a9c59 100644
--- a/drivers/i2c/busses/i2c-stub.c
+++ b/drivers/i2c/i2c-stub.c
@@ -2,7 +2,7 @@
     i2c-stub.c - I2C/SMBus chip emulator
 
     Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com>
-    Copyright (C) 2007 Jean Delvare <khali@linux-fr.org>
+    Copyright (C) 2007, 2012 Jean Delvare <khali@linux-fr.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -51,8 +51,8 @@
 static struct stub_chip *stub_chips;
 
 /* Return negative errno on error. */
-static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
-	char read_write, u8 command, int size, union i2c_smbus_data * data)
+static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags,
+	char read_write, u8 command, int size, union i2c_smbus_data *data)
 {
 	s32 ret;
 	int i, len;
@@ -78,14 +78,14 @@
 	case I2C_SMBUS_BYTE:
 		if (read_write == I2C_SMBUS_WRITE) {
 			chip->pointer = command;
-			dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, "
-					"wrote 0x%02x.\n",
-					addr, command);
+			dev_dbg(&adap->dev,
+				"smbus byte - addr 0x%02x, wrote 0x%02x.\n",
+				addr, command);
 		} else {
 			data->byte = chip->words[chip->pointer++] & 0xff;
-			dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, "
-					"read  0x%02x.\n",
-					addr, data->byte);
+			dev_dbg(&adap->dev,
+				"smbus byte - addr 0x%02x, read  0x%02x.\n",
+				addr, data->byte);
 		}
 
 		ret = 0;
@@ -95,14 +95,14 @@
 		if (read_write == I2C_SMBUS_WRITE) {
 			chip->words[command] &= 0xff00;
 			chip->words[command] |= data->byte;
-			dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, "
-					"wrote 0x%02x at 0x%02x.\n",
-					addr, data->byte, command);
+			dev_dbg(&adap->dev,
+				"smbus byte data - addr 0x%02x, wrote 0x%02x at 0x%02x.\n",
+				addr, data->byte, command);
 		} else {
 			data->byte = chip->words[command] & 0xff;
-			dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, "
-					"read  0x%02x at 0x%02x.\n",
-					addr, data->byte, command);
+			dev_dbg(&adap->dev,
+				"smbus byte data - addr 0x%02x, read  0x%02x at 0x%02x.\n",
+				addr, data->byte, command);
 		}
 		chip->pointer = command + 1;
 
@@ -112,14 +112,14 @@
 	case I2C_SMBUS_WORD_DATA:
 		if (read_write == I2C_SMBUS_WRITE) {
 			chip->words[command] = data->word;
-			dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, "
-					"wrote 0x%04x at 0x%02x.\n",
-					addr, data->word, command);
+			dev_dbg(&adap->dev,
+				"smbus word data - addr 0x%02x, wrote 0x%04x at 0x%02x.\n",
+				addr, data->word, command);
 		} else {
 			data->word = chip->words[command];
-			dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, "
-					"read  0x%04x at 0x%02x.\n",
-					addr, data->word, command);
+			dev_dbg(&adap->dev,
+				"smbus word data - addr 0x%02x, read  0x%04x at 0x%02x.\n",
+				addr, data->word, command);
 		}
 
 		ret = 0;
@@ -132,17 +132,17 @@
 				chip->words[command + i] &= 0xff00;
 				chip->words[command + i] |= data->block[1 + i];
 			}
-			dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, "
-					"wrote %d bytes at 0x%02x.\n",
-					addr, len, command);
+			dev_dbg(&adap->dev,
+				"i2c block data - addr 0x%02x, wrote %d bytes at 0x%02x.\n",
+				addr, len, command);
 		} else {
 			for (i = 0; i < len; i++) {
 				data->block[1 + i] =
 					chip->words[command + i] & 0xff;
 			}
-			dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, "
-					"read  %d bytes at 0x%02x.\n",
-					addr, len, command);
+			dev_dbg(&adap->dev,
+				"i2c block data - addr 0x%02x, read  %d bytes at 0x%02x.\n",
+				addr, len, command);
 		}
 
 		ret = 0;
@@ -179,25 +179,24 @@
 	int i, ret;
 
 	if (!chip_addr[0]) {
-		printk(KERN_ERR "i2c-stub: Please specify a chip address\n");
+		pr_err("i2c-stub: Please specify a chip address\n");
 		return -ENODEV;
 	}
 
 	for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) {
 		if (chip_addr[i] < 0x03 || chip_addr[i] > 0x77) {
-			printk(KERN_ERR "i2c-stub: Invalid chip address "
-			       "0x%02x\n", chip_addr[i]);
+			pr_err("i2c-stub: Invalid chip address 0x%02x\n",
+			       chip_addr[i]);
 			return -EINVAL;
 		}
 
-		printk(KERN_INFO "i2c-stub: Virtual chip at 0x%02x\n",
-		       chip_addr[i]);
+		pr_info("i2c-stub: Virtual chip at 0x%02x\n", chip_addr[i]);
 	}
 
 	/* Allocate memory for all chips at once */
 	stub_chips = kzalloc(i * sizeof(struct stub_chip), GFP_KERNEL);
 	if (!stub_chips) {
-		printk(KERN_ERR "i2c-stub: Out of memory\n");
+		pr_err("i2c-stub: Out of memory\n");
 		return -ENOMEM;
 	}
 
@@ -219,4 +218,3 @@
 
 module_init(i2c_stub_init);
 module_exit(i2c_stub_exit);
-
diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
index 5f097f3..7fa5b24 100644
--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
@@ -169,7 +169,7 @@
 	mux->busses = devm_kzalloc(&pdev->dev,
 				   sizeof(mux->busses) * mux->pdata->bus_count,
 				   GFP_KERNEL);
-	if (!mux->states) {
+	if (!mux->busses) {
 		dev_err(&pdev->dev, "Cannot allocate busses\n");
 		ret = -ENOMEM;
 		goto err;
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 6e3f143..fc937ac 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -62,7 +62,6 @@
 source "drivers/iio/dac/Kconfig"
 source "drivers/iio/common/Kconfig"
 source "drivers/iio/gyro/Kconfig"
-source "drivers/iio/light/Kconfig"
 source "drivers/iio/magnetometer/Kconfig"
 
 endif # IIO
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index f7fa3c0..761f2b6 100644
--- a/drivers/iio/Makefile
+++ b/drivers/iio/Makefile
@@ -18,5 +18,4 @@
 obj-y += dac/
 obj-y += common/
 obj-y += gyro/
-obj-y += light/
 obj-y += magnetometer/
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
index 57e07c6..afd8179 100644
--- a/drivers/infiniband/hw/cxgb4/mem.c
+++ b/drivers/infiniband/hw/cxgb4/mem.c
@@ -468,7 +468,7 @@
 	ret = alloc_pbl(mhp, npages);
 	if (ret) {
 		kfree(page_list);
-		goto err_pbl;
+		goto err;
 	}
 
 	ret = write_pbl(&mhp->rhp->rdev, page_list, mhp->attr.pbl_addr,
diff --git a/drivers/infiniband/hw/mlx4/alias_GUID.c b/drivers/infiniband/hw/mlx4/alias_GUID.c
index d2fb38d..2f215b9 100644
--- a/drivers/infiniband/hw/mlx4/alias_GUID.c
+++ b/drivers/infiniband/hw/mlx4/alias_GUID.c
@@ -107,7 +107,7 @@
 {
 	if (index >= NUM_ALIAS_GUID_PER_PORT) {
 		pr_err("%s: ERROR: asked for index:%d\n", __func__, index);
-		return  (__force __be64) ((u64) 0xFFFFFFFFFFFFFFFFUL);
+		return (__force __be64) -1;
 	}
 	return *(__be64 *)&dev->sriov.demux[port - 1].guid_cache[index];
 }
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 21a7941..0a903c1 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -409,38 +409,45 @@
 }
 
 
-static int get_pkey_phys_indices(struct mlx4_ib_dev *ibdev, u8 port, u8 ph_pkey_ix,
-				 u8 *full_pk_ix, u8 *partial_pk_ix,
-				 int *is_full_member)
+static int find_slave_port_pkey_ix(struct mlx4_ib_dev *dev, int slave,
+				   u8 port, u16 pkey, u16 *ix)
 {
-	u16 search_pkey;
-	int fm;
-	int err = 0;
-	u16 pk;
+	int i, ret;
+	u8 unassigned_pkey_ix, pkey_ix, partial_ix = 0xFF;
+	u16 slot_pkey;
 
-	err = ib_get_cached_pkey(&ibdev->ib_dev, port, ph_pkey_ix, &search_pkey);
-	if (err)
-		return err;
+	if (slave == mlx4_master_func_num(dev->dev))
+		return ib_find_cached_pkey(&dev->ib_dev, port, pkey, ix);
 
-	fm = (search_pkey & 0x8000) ? 1 : 0;
-	if (fm) {
-		*full_pk_ix = ph_pkey_ix;
-		search_pkey &= 0x7FFF;
-	} else {
-		*partial_pk_ix = ph_pkey_ix;
-		search_pkey |= 0x8000;
+	unassigned_pkey_ix = dev->dev->phys_caps.pkey_phys_table_len[port] - 1;
+
+	for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) {
+		if (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == unassigned_pkey_ix)
+			continue;
+
+		pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][i];
+
+		ret = ib_get_cached_pkey(&dev->ib_dev, port, pkey_ix, &slot_pkey);
+		if (ret)
+			continue;
+		if ((slot_pkey & 0x7FFF) == (pkey & 0x7FFF)) {
+			if (slot_pkey & 0x8000) {
+				*ix = (u16) pkey_ix;
+				return 0;
+			} else {
+				/* take first partial pkey index found */
+				if (partial_ix == 0xFF)
+					partial_ix = pkey_ix;
+			}
+		}
 	}
 
-	if (ib_find_exact_cached_pkey(&ibdev->ib_dev, port, search_pkey, &pk))
-		pk = 0xFFFF;
+	if (partial_ix < 0xFF) {
+		*ix = (u16) partial_ix;
+		return 0;
+	}
 
-	if (fm)
-		*partial_pk_ix = (pk & 0xFF);
-	else
-		*full_pk_ix = (pk & 0xFF);
-
-	*is_full_member = fm;
-	return err;
+	return -EINVAL;
 }
 
 int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port,
@@ -458,10 +465,8 @@
 	unsigned tun_tx_ix = 0;
 	int dqpn;
 	int ret = 0;
-	int i;
-	int is_full_member = 0;
 	u16 tun_pkey_ix;
-	u8 ph_pkey_ix, full_pk_ix = 0, partial_pk_ix = 0;
+	u16 cached_pkey;
 
 	if (dest_qpt > IB_QPT_GSI)
 		return -EINVAL;
@@ -481,27 +486,17 @@
 	else
 		tun_qp = &tun_ctx->qp[1];
 
-	/* compute pkey index for slave */
-	/* get physical pkey -- virtualized Dom0 pkey to phys*/
+	/* compute P_Key index to put in tunnel header for slave */
 	if (dest_qpt) {
-		ph_pkey_ix =
-			dev->pkeys.virt2phys_pkey[mlx4_master_func_num(dev->dev)][port - 1][wc->pkey_index];
-
-		/* now, translate this to the slave pkey index */
-		ret = get_pkey_phys_indices(dev, port, ph_pkey_ix, &full_pk_ix,
-					    &partial_pk_ix, &is_full_member);
+		u16 pkey_ix;
+		ret = ib_get_cached_pkey(&dev->ib_dev, port, wc->pkey_index, &cached_pkey);
 		if (ret)
 			return -EINVAL;
 
-		for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) {
-			if ((dev->pkeys.virt2phys_pkey[slave][port - 1][i] == full_pk_ix) ||
-			    (is_full_member &&
-			     (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == partial_pk_ix)))
-				break;
-		}
-		if (i == dev->dev->caps.pkey_table_len[port])
+		ret = find_slave_port_pkey_ix(dev, slave, port, cached_pkey, &pkey_ix);
+		if (ret)
 			return -EINVAL;
-		tun_pkey_ix = i;
+		tun_pkey_ix = pkey_ix;
 	} else
 		tun_pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][0];
 
diff --git a/drivers/infiniband/hw/mlx4/mcg.c b/drivers/infiniband/hw/mlx4/mcg.c
index 3c3b54c..25b2cdf 100644
--- a/drivers/infiniband/hw/mlx4/mcg.c
+++ b/drivers/infiniband/hw/mlx4/mcg.c
@@ -233,7 +233,8 @@
 
 	ib_query_ah(dev->sm_ah[ctx->port - 1], &ah_attr);
 
-	wc.pkey_index = 0;
+	if (ib_find_cached_pkey(&dev->ib_dev, ctx->port, IB_DEFAULT_PKEY_FULL, &wc.pkey_index))
+		return -EINVAL;
 	wc.sl = 0;
 	wc.dlid_path_bits = 0;
 	wc.port_num = ctx->port;
@@ -1074,10 +1075,6 @@
 	unsigned long end;
 	int count;
 
-	if (ctx->flushing)
-		return;
-
-	ctx->flushing = 1;
 	for (i = 0; i < MAX_VFS; ++i)
 		clean_vf_mcast(ctx, i);
 
@@ -1107,9 +1104,6 @@
 		force_clean_group(group);
 	}
 	mutex_unlock(&ctx->mcg_table_lock);
-
-	if (!destroy_wq)
-		ctx->flushing = 0;
 }
 
 struct clean_work {
@@ -1123,6 +1117,7 @@
 	struct clean_work *cw = container_of(work, struct clean_work, work);
 
 	_mlx4_ib_mcg_port_cleanup(cw->ctx, cw->destroy_wq);
+	cw->ctx->flushing = 0;
 	kfree(cw);
 }
 
@@ -1130,13 +1125,20 @@
 {
 	struct clean_work *work;
 
+	if (ctx->flushing)
+		return;
+
+	ctx->flushing = 1;
+
 	if (destroy_wq) {
 		_mlx4_ib_mcg_port_cleanup(ctx, destroy_wq);
+		ctx->flushing = 0;
 		return;
 	}
 
 	work = kmalloc(sizeof *work, GFP_KERNEL);
 	if (!work) {
+		ctx->flushing = 0;
 		mcg_warn("failed allocating work for cleanup\n");
 		return;
 	}
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 6ae2ac4..f0f8928 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -292,7 +292,6 @@
 	kfree(client);
 
 	evdev_close_device(evdev);
-	put_device(&evdev->dev);
 
 	return 0;
 }
@@ -331,7 +330,6 @@
 	file->private_data = client;
 	nonseekable_open(inode, file);
 
-	get_device(&evdev->dev);
 	return 0;
 
  err_free_client:
@@ -1001,6 +999,7 @@
 		goto err_free_evdev;
 
 	cdev_init(&evdev->cdev, &evdev_fops);
+	evdev->cdev.kobj.parent = &evdev->dev.kobj;
 	error = cdev_add(&evdev->cdev, evdev->dev.devt, 1);
 	if (error)
 		goto err_unregister_handle;
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index b62b589..f362883 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -243,7 +243,6 @@
 	kfree(client);
 
 	joydev_close_device(joydev);
-	put_device(&joydev->dev);
 
 	return 0;
 }
@@ -270,7 +269,6 @@
 	file->private_data = client;
 	nonseekable_open(inode, file);
 
-	get_device(&joydev->dev);
 	return 0;
 
  err_free_client:
@@ -858,6 +856,7 @@
 		goto err_free_joydev;
 
 	cdev_init(&joydev->cdev, &joydev_fops);
+	joydev->cdev.kobj.parent = &joydev->dev.kobj;
 	error = cdev_add(&joydev->cdev, joydev->dev.devt, 1);
 	if (error)
 		goto err_unregister_handle;
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index b4b65af..de08740 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -335,6 +335,7 @@
 config KEYBOARD_LPC32XX
 	tristate "LPC32XX matrix key scanner support"
 	depends on ARCH_LPC32XX && OF
+	select INPUT_MATRIXKMAP
 	help
 	  Say Y here if you want to use NXP LPC32XX SoC key scanner interface,
 	  connected to a key matrix.
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index 803ff6f..cad9d5d 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -368,6 +368,9 @@
 	unsigned int mask = 0, direct_key_num = 0;
 	unsigned long kpc = 0;
 
+	/* clear pending interrupt bit */
+	keypad_readl(KPC);
+
 	/* enable matrix keys with automatic scan */
 	if (pdata->matrix_key_rows && pdata->matrix_key_cols) {
 		kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL;
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c
index 02ca868..6f7d990 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -311,7 +311,6 @@
 	case XenbusStateReconfiguring:
 	case XenbusStateReconfigured:
 	case XenbusStateUnknown:
-	case XenbusStateClosed:
 		break;
 
 	case XenbusStateInitWait:
@@ -350,6 +349,10 @@
 
 		break;
 
+	case XenbusStateClosed:
+		if (dev->state == XenbusStateClosed)
+			break;
+		/* Missed the backend's CLOSING state -- fallthrough */
 	case XenbusStateClosing:
 		xenbus_frontend_closed(dev);
 		break;
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 3a78f23..2baff1b 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -84,6 +84,10 @@
 #define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI	0x0262
 #define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO	0x0263
 #define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS	0x0264
+/* MacbookPro10,2 (unibody, October 2012) */
+#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI	0x0259
+#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO	0x025a
+#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS	0x025b
 
 #define BCM5974_DEVICE(prod) {					\
 	.match_flags = (USB_DEVICE_ID_MATCH_DEVICE |		\
@@ -137,6 +141,10 @@
 	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI),
 	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO),
 	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS),
+	/* MacbookPro10,2 */
+	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI),
+	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO),
+	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS),
 	/* Terminating entry */
 	{}
 };
@@ -379,6 +387,19 @@
 		{ SN_COORD, -150, 6730 },
 		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
 	},
+	{
+		USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI,
+		USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO,
+		USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS,
+		HAS_INTEGRATED_BUTTON,
+		0x84, sizeof(struct bt_data),
+		0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
+		{ SN_PRESSURE, 0, 300 },
+		{ SN_WIDTH, 0, 2048 },
+		{ SN_COORD, -4750, 5280 },
+		{ SN_COORD, -150, 6730 },
+		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
+	},
 	{}
 };
 
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index a1b4c37..8f02e3d 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -523,7 +523,6 @@
 	kfree(client);
 
 	mousedev_close_device(mousedev);
-	put_device(&mousedev->dev);
 
 	return 0;
 }
@@ -558,7 +557,6 @@
 	file->private_data = client;
 	nonseekable_open(inode, file);
 
-	get_device(&mousedev->dev);
 	return 0;
 
  err_free_client:
@@ -892,6 +890,7 @@
 	}
 
 	cdev_init(&mousedev->cdev, &mousedev_fops);
+	mousedev->cdev.kobj.parent = &mousedev->dev.kobj;
 	error = cdev_add(&mousedev->cdev, mousedev->dev.devt, 1);
 	if (error)
 		goto err_unregister_handle;
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 9edf980..858ad44 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -391,7 +391,7 @@
 							features->pktlen = WACOM_PKGLEN_TPC2FG;
 						}
 
-						if (features->type == MTSCREEN)
+						if (features->type == MTSCREEN || features->type == WACOM_24HDT)
 							features->pktlen = WACOM_PKGLEN_MTOUCH;
 
 						if (features->type == BAMBOO_PT) {
@@ -402,6 +402,14 @@
 							features->x_max =
 								get_unaligned_le16(&report[i + 8]);
 							i += 15;
+						} else if (features->type == WACOM_24HDT) {
+							features->x_max =
+								get_unaligned_le16(&report[i + 3]);
+							features->x_phy =
+								get_unaligned_le16(&report[i + 8]);
+							features->unit = report[i - 1];
+							features->unitExpo = report[i - 3];
+							i += 12;
 						} else {
 							features->x_max =
 								get_unaligned_le16(&report[i + 3]);
@@ -434,6 +442,12 @@
 							features->y_phy =
 								get_unaligned_le16(&report[i + 6]);
 							i += 7;
+						} else if (type == WACOM_24HDT) {
+							features->y_max =
+								get_unaligned_le16(&report[i + 3]);
+							features->y_phy =
+								get_unaligned_le16(&report[i - 2]);
+							i += 7;
 						} else if (type == BAMBOO_PT) {
 							features->y_phy =
 								get_unaligned_le16(&report[i + 3]);
@@ -541,6 +555,9 @@
 			/* MT Tablet PC touch */
 			return wacom_set_device_mode(intf, 3, 4, 4);
 		}
+		else if (features->type == WACOM_24HDT) {
+			return wacom_set_device_mode(intf, 18, 3, 2);
+		}
 	} else if (features->device_type == BTN_TOOL_PEN) {
 		if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
 			return wacom_set_device_mode(intf, 2, 2, 2);
@@ -613,6 +630,30 @@
 static LIST_HEAD(wacom_udev_list);
 static DEFINE_MUTEX(wacom_udev_list_lock);
 
+static struct usb_device *wacom_get_sibling(struct usb_device *dev, int vendor, int product)
+{
+	int port1;
+	struct usb_device *sibling;
+
+	if (vendor == 0 && product == 0)
+		return dev;
+
+	if (dev->parent == NULL)
+		return NULL;
+
+	usb_hub_for_each_child(dev->parent, port1, sibling) {
+		struct usb_device_descriptor *d;
+		if (sibling == NULL)
+			continue;
+
+		d = &sibling->descriptor;
+		if (d->idVendor == vendor && d->idProduct == product)
+			return sibling;
+	}
+
+	return NULL;
+}
+
 static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev)
 {
 	struct wacom_usbdev_data *data;
@@ -1257,13 +1298,19 @@
 	strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
 
 	if (features->quirks & WACOM_QUIRK_MULTI_INPUT) {
+		struct usb_device *other_dev;
+
 		/* Append the device type to the name */
 		strlcat(wacom_wac->name,
 			features->device_type == BTN_TOOL_PEN ?
 				" Pen" : " Finger",
 			sizeof(wacom_wac->name));
 
-		error = wacom_add_shared_data(wacom_wac, dev);
+
+		other_dev = wacom_get_sibling(dev, features->oVid, features->oPid);
+		if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL)
+			other_dev = dev;
+		error = wacom_add_shared_data(wacom_wac, other_dev);
 		if (error)
 			goto fail3;
 	}
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index c3468c8..0a67031 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -806,6 +806,70 @@
 	return -1;
 }
 
+static int int_dist(int x1, int y1, int x2, int y2)
+{
+	int x = x2 - x1;
+	int y = y2 - y1;
+
+	return int_sqrt(x*x + y*y);
+}
+
+static int wacom_24hdt_irq(struct wacom_wac *wacom)
+{
+	struct input_dev *input = wacom->input;
+	char *data = wacom->data;
+	int i;
+	int current_num_contacts = data[61];
+	int contacts_to_send = 0;
+
+	/*
+	 * First packet resets the counter since only the first
+	 * packet in series will have non-zero current_num_contacts.
+	 */
+	if (current_num_contacts)
+		wacom->num_contacts_left = current_num_contacts;
+
+	/* There are at most 4 contacts per packet */
+	contacts_to_send = min(4, wacom->num_contacts_left);
+
+	for (i = 0; i < contacts_to_send; i++) {
+		int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1;
+		bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity;
+		int id = data[offset + 1];
+		int slot = find_slot_from_contactid(wacom, id);
+
+		if (slot < 0)
+			continue;
+		input_mt_slot(input, slot);
+		input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
+
+		if (touch) {
+			int t_x = le16_to_cpup((__le16 *)&data[offset + 2]);
+			int c_x = le16_to_cpup((__le16 *)&data[offset + 4]);
+			int t_y = le16_to_cpup((__le16 *)&data[offset + 6]);
+			int c_y = le16_to_cpup((__le16 *)&data[offset + 8]);
+			int w = le16_to_cpup((__le16 *)&data[offset + 10]);
+			int h = le16_to_cpup((__le16 *)&data[offset + 12]);
+
+			input_report_abs(input, ABS_MT_POSITION_X, t_x);
+			input_report_abs(input, ABS_MT_POSITION_Y, t_y);
+			input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h));
+			input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y));
+			input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
+			input_report_abs(input, ABS_MT_ORIENTATION, w > h);
+		}
+		wacom->slots[slot] = touch ? id : -1;
+	}
+
+	input_mt_report_pointer_emulation(input, true);
+
+	wacom->num_contacts_left -= contacts_to_send;
+	if (wacom->num_contacts_left <= 0)
+		wacom->num_contacts_left = 0;
+
+	return 1;
+}
+
 static int wacom_mt_touch(struct wacom_wac *wacom)
 {
 	struct input_dev *input = wacom->input;
@@ -1255,6 +1319,10 @@
 		sync = wacom_intuos_irq(wacom_wac);
 		break;
 
+	case WACOM_24HDT:
+		sync = wacom_24hdt_irq(wacom_wac);
+		break;
+
 	case INTUOS5S:
 	case INTUOS5:
 	case INTUOS5L:
@@ -1340,7 +1408,8 @@
 
 	/* these device have multiple inputs */
 	if (features->type >= WIRELESS ||
-	    (features->type >= INTUOS5S && features->type <= INTUOS5L))
+	    (features->type >= INTUOS5S && features->type <= INTUOS5L) ||
+	    (features->oVid && features->oPid))
 		features->quirks |= WACOM_QUIRK_MULTI_INPUT;
 
 	/* quirk for bamboo touch with 2 low res touches */
@@ -1449,6 +1518,9 @@
 
 		input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
 		input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
+
+		__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+
 		wacom_setup_cintiq(wacom_wac);
 		break;
 
@@ -1575,6 +1647,15 @@
 		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
 		break;
 
+	case WACOM_24HDT:
+		if (features->device_type == BTN_TOOL_FINGER) {
+			input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0);
+			input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0);
+			input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0);
+			input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);
+		}
+		/* fall through */
+
 	case MTSCREEN:
 		if (features->device_type == BTN_TOOL_FINGER) {
 			wacom_wac->slots = kmalloc(features->touch_max *
@@ -1869,8 +1950,11 @@
 	{ "Wacom Cintiq 24HD",       WACOM_PKGLEN_INTUOS,   104480, 65600, 2047,
 	  63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
 static const struct wacom_features wacom_features_0xF8 =
-	{ "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS,   104480, 65600, 2047,
-	  63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+	{ "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS,   104480, 65600, 2047, /* Pen */
+	  63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
+static const struct wacom_features wacom_features_0xF6 =
+	{ "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
+	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 };
 static const struct wacom_features wacom_features_0x3F =
 	{ "Wacom Cintiq 21UX",    WACOM_PKGLEN_INTUOS,    87200, 65600, 1023,
 	  63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
@@ -2113,6 +2197,7 @@
 	{ USB_DEVICE_WACOM(0x47) },
 	{ USB_DEVICE_WACOM(0xF4) },
 	{ USB_DEVICE_WACOM(0xF8) },
+	{ USB_DEVICE_WACOM(0xF6) },
 	{ USB_DEVICE_WACOM(0xFA) },
 	{ USB_DEVICE_LENOVO(0x6004) },
 	{ }
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 96c185c..345f1e7 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -29,6 +29,7 @@
 
 /* wacom data size per MT contact */
 #define WACOM_BYTES_PER_MT_PACKET	11
+#define WACOM_BYTES_PER_24HDT_PACKET	14
 
 /* device IDs */
 #define STYLUS_DEVICE_ID	0x02
@@ -49,6 +50,7 @@
 #define WACOM_REPORT_TPCHID		15
 #define WACOM_REPORT_TPCST		16
 #define WACOM_REPORT_TPC1FGE		18
+#define WACOM_REPORT_24HDT		1
 
 /* device quirks */
 #define WACOM_QUIRK_MULTI_INPUT		0x0001
@@ -81,6 +83,7 @@
 	WACOM_MO,
 	WIRELESS,
 	BAMBOO_PT,
+	WACOM_24HDT,
 	TABLETPC,   /* add new TPC below */
 	TABLETPCE,
 	TABLETPC2FG,
@@ -109,6 +112,8 @@
 	int distance_fuzz;
 	unsigned quirks;
 	unsigned touch_max;
+	int oVid;
+	int oPid;
 };
 
 struct wacom_shared {
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 1ba232c..f7668b2 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -239,7 +239,7 @@
 
 config TOUCHSCREEN_EGALAX
 	tristate "EETI eGalax multi-touch panel support"
-	depends on I2C
+	depends on I2C && OF
 	help
 	  Say Y here to enable support for I2C connected EETI
 	  eGalax multi-touch panels.
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c
index c1e3460..13fa62f 100644
--- a/drivers/input/touchscreen/egalax_ts.c
+++ b/drivers/input/touchscreen/egalax_ts.c
@@ -28,6 +28,7 @@
 #include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/input/mt.h>
+#include <linux/of_gpio.h>
 
 /*
  * Mouse Mode: some panel may configure the controller to mouse mode,
@@ -122,9 +123,17 @@
 /* wake up controller by an falling edge of interrupt gpio.  */
 static int egalax_wake_up_device(struct i2c_client *client)
 {
-	int gpio = irq_to_gpio(client->irq);
+	struct device_node *np = client->dev.of_node;
+	int gpio;
 	int ret;
 
+	if (!np)
+		return -ENODEV;
+
+	gpio = of_get_named_gpio(np, "wakeup-gpios", 0);
+	if (!gpio_is_valid(gpio))
+		return -ENODEV;
+
 	ret = gpio_request(gpio, "egalax_irq");
 	if (ret < 0) {
 		dev_err(&client->dev,
@@ -181,7 +190,11 @@
 	ts->input_dev = input_dev;
 
 	/* controller may be in sleep, wake it up. */
-	egalax_wake_up_device(client);
+	error = egalax_wake_up_device(client);
+	if (error) {
+		dev_err(&client->dev, "Failed to wake up the controller\n");
+		goto err_free_dev;
+	}
 
 	ret = egalax_firmware_version(client);
 	if (ret < 0) {
@@ -274,11 +287,17 @@
 
 static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume);
 
+static struct of_device_id egalax_ts_dt_ids[] = {
+	{ .compatible = "eeti,egalax_ts" },
+	{ /* sentinel */ }
+};
+
 static struct i2c_driver egalax_ts_driver = {
 	.driver = {
 		.name	= "egalax_ts",
 		.owner	= THIS_MODULE,
 		.pm	= &egalax_ts_pm_ops,
+		.of_match_table	= of_match_ptr(egalax_ts_dt_ids),
 	},
 	.id_table	= egalax_ts_id,
 	.probe		= egalax_ts_probe,
diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c
index 63209aa..eb96f16 100644
--- a/drivers/input/touchscreen/tsc40.c
+++ b/drivers/input/touchscreen/tsc40.c
@@ -107,7 +107,6 @@
 	__set_bit(BTN_TOUCH, input_dev->keybit);
 	input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0);
 	input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0);
-	input_set_abs_params(ptsc->dev, ABS_PRESSURE, 0, 0, 0, 0);
 
 	serio_set_drvdata(serio, ptsc);
 
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 18b0d99..81837b0 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -1599,21 +1599,46 @@
 #endif
 }
 
+/* SB IOAPIC is always on this device in AMD systems */
+#define IOAPIC_SB_DEVID		((0x00 << 8) | PCI_DEVFN(0x14, 0))
+
 static bool __init check_ioapic_information(void)
 {
+	bool ret, has_sb_ioapic;
 	int idx;
 
-	for (idx = 0; idx < nr_ioapics; idx++) {
-		int id = mpc_ioapic_id(idx);
+	has_sb_ioapic = false;
+	ret           = false;
 
-		if (get_ioapic_devid(id) < 0) {
-			pr_err(FW_BUG "AMD-Vi: IO-APIC[%d] not in IVRS table\n", id);
-			pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug\n");
-			return false;
+	for (idx = 0; idx < nr_ioapics; idx++) {
+		int devid, id = mpc_ioapic_id(idx);
+
+		devid = get_ioapic_devid(id);
+		if (devid < 0) {
+			pr_err(FW_BUG "AMD-Vi: IOAPIC[%d] not in IVRS table\n", id);
+			ret = false;
+		} else if (devid == IOAPIC_SB_DEVID) {
+			has_sb_ioapic = true;
+			ret           = true;
 		}
 	}
 
-	return true;
+	if (!has_sb_ioapic) {
+		/*
+		 * We expect the SB IOAPIC to be listed in the IVRS
+		 * table. The system timer is connected to the SB IOAPIC
+		 * and if we don't have it in the list the system will
+		 * panic at boot time.  This situation usually happens
+		 * when the BIOS is buggy and provides us the wrong
+		 * device id for the IOAPIC in the system.
+		 */
+		pr_err(FW_BUG "AMD-Vi: No southbridge IOAPIC found in IVRS table\n");
+	}
+
+	if (!ret)
+		pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug(s)\n");
+
+	return ret;
 }
 
 static void __init free_dma_resources(void)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 0b4d62e..4167863 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -34,13 +34,11 @@
 #include <linux/of_iommu.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/tegra-ahb.h>
 
 #include <asm/page.h>
 #include <asm/cacheflush.h>
 
-#include <mach/iomap.h>
-#include <mach/tegra-ahb.h>
-
 enum smmu_hwgrp {
 	HWGRP_AFI,
 	HWGRP_AVPC,
@@ -200,7 +198,7 @@
 
 #define SMMU_ADDR_TO_PFN(addr)	((addr) >> 12)
 #define SMMU_ADDR_TO_PDN(addr)	((addr) >> 22)
-#define SMMU_PDN_TO_ADDR(addr)	((pdn) << 22)
+#define SMMU_PDN_TO_ADDR(pdn)	((pdn) << 22)
 
 #define _READABLE	(1 << SMMU_PTB_DATA_ASID_READABLE_SHIFT)
 #define _WRITABLE	(1 << SMMU_PTB_DATA_ASID_WRITABLE_SHIFT)
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index e2e6eb5..02bd37a 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
+obj-$(CONFIG_ARCH_SUNXI)   += irq-sunxi.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index dc670cc..16c78f1 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -168,7 +168,8 @@
 }
 
 static struct of_device_id irq_of_match[] __initconst = {
-	{ .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }
+	{ .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init },
+	{ }
 };
 
 void __init bcm2835_init_irq(void)
diff --git a/drivers/irqchip/irq-sunxi.c b/drivers/irqchip/irq-sunxi.c
new file mode 100644
index 0000000..eef41a49
--- /dev/null
+++ b/drivers/irqchip/irq-sunxi.c
@@ -0,0 +1,150 @@
+/*
+ * Allwinner A1X SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * Based on code from
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Benn Huang <benn@allwinnertech.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#include <linux/irqchip/sunxi.h>
+
+#define SUNXI_IRQ_VECTOR_REG		0x00
+#define SUNXI_IRQ_PROTECTION_REG	0x08
+#define SUNXI_IRQ_NMI_CTRL_REG		0x0c
+#define SUNXI_IRQ_PENDING_REG(x)	(0x10 + 0x4 * x)
+#define SUNXI_IRQ_FIQ_PENDING_REG(x)	(0x20 + 0x4 * x)
+#define SUNXI_IRQ_ENABLE_REG(x)		(0x40 + 0x4 * x)
+#define SUNXI_IRQ_MASK_REG(x)		(0x50 + 0x4 * x)
+
+static void __iomem *sunxi_irq_base;
+static struct irq_domain *sunxi_irq_domain;
+
+void sunxi_irq_ack(struct irq_data *irqd)
+{
+	unsigned int irq = irqd_to_hwirq(irqd);
+	unsigned int irq_off = irq % 32;
+	int reg = irq / 32;
+	u32 val;
+
+	val = readl(sunxi_irq_base + SUNXI_IRQ_PENDING_REG(reg));
+	writel(val | (1 << irq_off),
+	       sunxi_irq_base + SUNXI_IRQ_PENDING_REG(reg));
+}
+
+static void sunxi_irq_mask(struct irq_data *irqd)
+{
+	unsigned int irq = irqd_to_hwirq(irqd);
+	unsigned int irq_off = irq % 32;
+	int reg = irq / 32;
+	u32 val;
+
+	val = readl(sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg));
+	writel(val & ~(1 << irq_off),
+	       sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg));
+}
+
+static void sunxi_irq_unmask(struct irq_data *irqd)
+{
+	unsigned int irq = irqd_to_hwirq(irqd);
+	unsigned int irq_off = irq % 32;
+	int reg = irq / 32;
+	u32 val;
+
+	val = readl(sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg));
+	writel(val | (1 << irq_off),
+	       sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg));
+}
+
+static struct irq_chip sunxi_irq_chip = {
+	.name		= "sunxi_irq",
+	.irq_ack	= sunxi_irq_ack,
+	.irq_mask	= sunxi_irq_mask,
+	.irq_unmask	= sunxi_irq_unmask,
+};
+
+static int sunxi_irq_map(struct irq_domain *d, unsigned int virq,
+			 irq_hw_number_t hw)
+{
+	irq_set_chip_and_handler(virq, &sunxi_irq_chip,
+				 handle_level_irq);
+	set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
+
+	return 0;
+}
+
+static struct irq_domain_ops sunxi_irq_ops = {
+	.map = sunxi_irq_map,
+	.xlate = irq_domain_xlate_onecell,
+};
+
+static int __init sunxi_of_init(struct device_node *node,
+				struct device_node *parent)
+{
+	sunxi_irq_base = of_iomap(node, 0);
+	if (!sunxi_irq_base)
+		panic("%s: unable to map IC registers\n",
+			node->full_name);
+
+	/* Disable all interrupts */
+	writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(0));
+	writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(1));
+	writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(2));
+
+	/* Mask all the interrupts */
+	writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(0));
+	writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(1));
+	writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(2));
+
+	/* Clear all the pending interrupts */
+	writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(0));
+	writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(1));
+	writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(2));
+
+	/* Enable protection mode */
+	writel(0x01, sunxi_irq_base + SUNXI_IRQ_PROTECTION_REG);
+
+	/* Configure the external interrupt source type */
+	writel(0x00, sunxi_irq_base + SUNXI_IRQ_NMI_CTRL_REG);
+
+	sunxi_irq_domain = irq_domain_add_linear(node, 3 * 32,
+						 &sunxi_irq_ops, NULL);
+	if (!sunxi_irq_domain)
+		panic("%s: unable to create IRQ domain\n", node->full_name);
+
+	return 0;
+}
+
+static struct of_device_id sunxi_irq_dt_ids[] __initconst = {
+	{ .compatible = "allwinner,sunxi-ic", .data = sunxi_of_init }
+};
+
+void __init sunxi_init_irq(void)
+{
+	of_irq_init(sunxi_irq_dt_ids);
+}
+
+asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs)
+{
+	u32 irq, hwirq;
+
+	hwirq = readl(sunxi_irq_base + SUNXI_IRQ_VECTOR_REG) >> 2;
+	while (hwirq != 0) {
+		irq = irq_find_mapping(sunxi_irq_domain, hwirq);
+		handle_IRQ(irq, regs);
+		hwirq = readl(sunxi_irq_base + SUNXI_IRQ_VECTOR_REG) >> 2;
+	}
+}
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig
index a233ed5..86cd75a 100644
--- a/drivers/isdn/Kconfig
+++ b/drivers/isdn/Kconfig
@@ -4,7 +4,7 @@
 
 menuconfig ISDN
 	bool "ISDN support"
-	depends on NET
+	depends on NET && NETDEVICES
 	depends on !S390 && !UML
 	---help---
 	  ISDN ("Integrated Services Digital Network", called RNIS in France)
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 5275887..c44950d 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -617,7 +617,13 @@
 	if (rc == 0)
 		/* success, resubmit interrupt read URB */
 		rc = usb_submit_urb(urb, GFP_ATOMIC);
-	if (rc != 0 && rc != -ENODEV) {
+
+	switch (rc) {
+	case 0:		/* success */
+	case -ENODEV:	/* device gone */
+	case -EINVAL:	/* URB already resubmitted, or terminal badness */
+		break;
+	default:	/* failure: try to recover by resetting the device */
 		dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc));
 		rc = usb_lock_device_for_reset(ucs->udev, ucs->interface);
 		if (rc == 0) {
@@ -2442,7 +2448,9 @@
 }
 
 /* gigaset_suspend
- * This function is called before the USB connection is suspended.
+ * This function is called before the USB connection is suspended
+ * or before the USB device is reset.
+ * In the latter case, message == PMSG_ON.
  */
 static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
 {
@@ -2498,7 +2506,12 @@
 	del_timer_sync(&ucs->timer_atrdy);
 	del_timer_sync(&ucs->timer_cmd_in);
 	del_timer_sync(&ucs->timer_int_in);
-	cancel_work_sync(&ucs->int_in_wq);
+
+	/* don't try to cancel int_in_wq from within reset as it
+	 * might be the one requesting the reset
+	 */
+	if (message.event != PM_EVENT_ON)
+		cancel_work_sync(&ucs->int_in_wq);
 
 	gig_dbg(DEBUG_SUSPEND, "suspend complete");
 	return 0;
diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig
index 2302fbe..9c6650e 100644
--- a/drivers/isdn/i4l/Kconfig
+++ b/drivers/isdn/i4l/Kconfig
@@ -6,7 +6,7 @@
 
 config ISDN_PPP
 	bool "Support synchronous PPP"
-	depends on INET && NETDEVICES
+	depends on INET
 	select SLHC
 	help
 	  Over digital connections such as ISDN, there is no need to
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 8c610fa..e2a945e 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1312,7 +1312,6 @@
 			} else
 				return -EINVAL;
 			break;
-#ifdef CONFIG_NETDEVICES
 		case IIOCNETGPN:
 			/* Get peer phone number of a connected
 			 * isdn network interface */
@@ -1322,7 +1321,6 @@
 				return isdn_net_getpeer(&phone, argp);
 			} else
 				return -EINVAL;
-#endif
 		default:
 			return -EINVAL;
 		}
@@ -1352,7 +1350,6 @@
 		case IIOCNETLCR:
 			printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n");
 			return -ENODEV;
-#ifdef CONFIG_NETDEVICES
 		case IIOCNETAIF:
 			/* Add a network-interface */
 			if (arg) {
@@ -1491,7 +1488,6 @@
 				return -EFAULT;
 			return isdn_net_force_hangup(name);
 			break;
-#endif                          /* CONFIG_NETDEVICES */
 		case IIOCSETVER:
 			dev->net_verbose = arg;
 			printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose);
diff --git a/drivers/leds/ledtrig-cpu.c b/drivers/leds/ledtrig-cpu.c
index b312056..4239b39 100644
--- a/drivers/leds/ledtrig-cpu.c
+++ b/drivers/leds/ledtrig-cpu.c
@@ -33,8 +33,6 @@
 struct led_trigger_cpu {
 	char name[MAX_NAME_LEN];
 	struct led_trigger *_trig;
-	struct mutex lock;
-	int lock_is_inited;
 };
 
 static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig);
@@ -50,12 +48,6 @@
 {
 	struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig);
 
-	/* mutex lock should be initialized before calling mutex_call() */
-	if (!trig->lock_is_inited)
-		return;
-
-	mutex_lock(&trig->lock);
-
 	/* Locate the correct CPU LED */
 	switch (ledevt) {
 	case CPU_LED_IDLE_END:
@@ -75,8 +67,6 @@
 		/* Will leave the LED as it is */
 		break;
 	}
-
-	mutex_unlock(&trig->lock);
 }
 EXPORT_SYMBOL(ledtrig_cpu);
 
@@ -117,14 +107,9 @@
 	for_each_possible_cpu(cpu) {
 		struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
 
-		mutex_init(&trig->lock);
-
 		snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu);
 
-		mutex_lock(&trig->lock);
 		led_trigger_register_simple(trig->name, &trig->_trig);
-		trig->lock_is_inited = 1;
-		mutex_unlock(&trig->lock);
 	}
 
 	register_syscore_ops(&ledtrig_cpu_syscore_ops);
@@ -142,15 +127,9 @@
 	for_each_possible_cpu(cpu) {
 		struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
 
-		mutex_lock(&trig->lock);
-
 		led_trigger_unregister_simple(trig->_trig);
 		trig->_trig = NULL;
 		memset(trig->name, 0, MAX_NAME_LEN);
-		trig->lock_is_inited = 0;
-
-		mutex_unlock(&trig->lock);
-		mutex_destroy(&trig->lock);
 	}
 
 	unregister_syscore_ops(&ledtrig_cpu_syscore_ops);
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 45135f6..5e7dc77 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -315,8 +315,11 @@
 	}
 	conf->nfaults = 0;
 
-	rdev_for_each(rdev, mddev)
+	rdev_for_each(rdev, mddev) {
 		conf->rdev = rdev;
+		disk_stack_limits(mddev->gendisk, rdev->bdev,
+				  rdev->data_offset << 9);
+	}
 
 	md_set_array_sectors(mddev, faulty_size(mddev, 0, 0));
 	mddev->private = conf;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 8034fbd..636bae0 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2710,7 +2710,7 @@
 		    || disk_idx < 0)
 			continue;
 		if (test_bit(Replacement, &rdev->flags))
-			disk = conf->mirrors + conf->raid_disks + disk_idx;
+			disk = conf->mirrors + mddev->raid_disks + disk_idx;
 		else
 			disk = conf->mirrors + disk_idx;
 
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 906ccbd..d1295af 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1783,7 +1783,7 @@
 		clear_bit(Unmerged, &rdev->flags);
 	}
 	md_integrity_add_rdev(rdev, mddev);
-	if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+	if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev)))
 		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
 
 	print_conf(conf);
@@ -3613,11 +3613,14 @@
 			discard_supported = true;
 	}
 
-	if (discard_supported)
-		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
-	else
-		queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
-
+	if (mddev->queue) {
+		if (discard_supported)
+			queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
+						mddev->queue);
+		else
+			queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD,
+						  mddev->queue);
+	}
 	/* need to check that every block has at least one working mirror */
 	if (!enough(conf, -1)) {
 		printk(KERN_ERR "md/raid10:%s: not enough operational mirrors.\n",
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index 9fd9d1c..558f6a3 100644
--- a/drivers/media/platform/soc_camera/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -41,7 +41,6 @@
 #include <linux/videodev2.h>
 
 #include <linux/platform_data/camera-mx2.h>
-#include <mach/hardware.h>
 
 #include <asm/dma.h>
 
@@ -121,11 +120,13 @@
 
 #define CSICR1			0x00
 #define CSICR2			0x04
-#define CSISR			(cpu_is_mx27() ? 0x08 : 0x18)
+#define CSISR_IMX25		0x18
+#define CSISR_IMX27		0x08
 #define CSISTATFIFO		0x0c
 #define CSIRFIFO		0x10
 #define CSIRXCNT		0x14
-#define CSICR3			(cpu_is_mx27() ? 0x1C : 0x08)
+#define CSICR3_IMX25		0x08
+#define CSICR3_IMX27		0x1c
 #define CSIDMASA_STATFIFO	0x20
 #define CSIDMATA_STATFIFO	0x24
 #define CSIDMASA_FB1		0x28
@@ -268,11 +269,17 @@
 	struct mx2_buf_internal		internal;
 };
 
+enum mx2_camera_type {
+	IMX25_CAMERA,
+	IMX27_CAMERA,
+};
+
 struct mx2_camera_dev {
 	struct device		*dev;
 	struct soc_camera_host	soc_host;
 	struct soc_camera_device *icd;
-	struct clk		*clk_csi, *clk_emma_ahb, *clk_emma_ipg;
+	struct clk		*clk_emma_ahb, *clk_emma_ipg;
+	struct clk		*clk_csi_ahb, *clk_csi_per;
 
 	void __iomem		*base_csi, *base_emma;
 
@@ -291,6 +298,9 @@
 	struct mx2_buffer	*fb2_active;
 
 	u32			csicr1;
+	u32			reg_csisr;
+	u32			reg_csicr3;
+	enum mx2_camera_type	devtype;
 
 	struct mx2_buf_internal buf_discard[2];
 	void			*discard_buffer;
@@ -303,6 +313,29 @@
 	struct vb2_alloc_ctx	*alloc_ctx;
 };
 
+static struct platform_device_id mx2_camera_devtype[] = {
+	{
+		.name = "imx25-camera",
+		.driver_data = IMX25_CAMERA,
+	}, {
+		.name = "imx27-camera",
+		.driver_data = IMX27_CAMERA,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, mx2_camera_devtype);
+
+static inline int is_imx25_camera(struct mx2_camera_dev *pcdev)
+{
+	return pcdev->devtype == IMX25_CAMERA;
+}
+
+static inline int is_imx27_camera(struct mx2_camera_dev *pcdev)
+{
+	return pcdev->devtype == IMX27_CAMERA;
+}
+
 static struct mx2_buffer *mx2_ibuf_to_buf(struct mx2_buf_internal *int_buf)
 {
 	return container_of(int_buf, struct mx2_buffer, internal);
@@ -432,11 +465,12 @@
 {
 	unsigned long flags;
 
-	clk_disable_unprepare(pcdev->clk_csi);
+	clk_disable_unprepare(pcdev->clk_csi_ahb);
+	clk_disable_unprepare(pcdev->clk_csi_per);
 	writel(0, pcdev->base_csi + CSICR1);
-	if (cpu_is_mx27()) {
+	if (is_imx27_camera(pcdev)) {
 		writel(0, pcdev->base_emma + PRP_CNTL);
-	} else if (cpu_is_mx25()) {
+	} else if (is_imx25_camera(pcdev)) {
 		spin_lock_irqsave(&pcdev->lock, flags);
 		pcdev->fb1_active = NULL;
 		pcdev->fb2_active = NULL;
@@ -460,13 +494,17 @@
 	if (pcdev->icd)
 		return -EBUSY;
 
-	ret = clk_prepare_enable(pcdev->clk_csi);
+	ret = clk_prepare_enable(pcdev->clk_csi_ahb);
 	if (ret < 0)
 		return ret;
 
+	ret = clk_prepare_enable(pcdev->clk_csi_per);
+	if (ret < 0)
+		goto exit_csi_ahb;
+
 	csicr1 = CSICR1_MCLKEN;
 
-	if (cpu_is_mx27())
+	if (is_imx27_camera(pcdev))
 		csicr1 |= CSICR1_PRP_IF_EN | CSICR1_FCC |
 			CSICR1_RXFF_LEVEL(0);
 
@@ -480,6 +518,11 @@
 		 icd->devnum);
 
 	return 0;
+
+exit_csi_ahb:
+	clk_disable_unprepare(pcdev->clk_csi_ahb);
+
+	return ret;
 }
 
 static void mx2_camera_remove_device(struct soc_camera_device *icd)
@@ -542,7 +585,7 @@
 static irqreturn_t mx25_camera_irq(int irq_csi, void *data)
 {
 	struct mx2_camera_dev *pcdev = data;
-	u32 status = readl(pcdev->base_csi + CSISR);
+	u32 status = readl(pcdev->base_csi + pcdev->reg_csisr);
 
 	if (status & CSISR_DMA_TSF_FB1_INT)
 		mx25_camera_frame_done(pcdev, 1, MX2_STATE_DONE);
@@ -551,7 +594,7 @@
 
 	/* FIXME: handle CSISR_RFF_OR_INT */
 
-	writel(status, pcdev->base_csi + CSISR);
+	writel(status, pcdev->base_csi + pcdev->reg_csisr);
 
 	return IRQ_HANDLED;
 }
@@ -636,7 +679,7 @@
 	buf->state = MX2_STATE_QUEUED;
 	list_add_tail(&buf->internal.queue, &pcdev->capture);
 
-	if (cpu_is_mx25()) {
+	if (is_imx25_camera(pcdev)) {
 		u32 csicr3, dma_inten = 0;
 
 		if (pcdev->fb1_active == NULL) {
@@ -655,20 +698,20 @@
 			list_del(&buf->internal.queue);
 			buf->state = MX2_STATE_ACTIVE;
 
-			csicr3 = readl(pcdev->base_csi + CSICR3);
+			csicr3 = readl(pcdev->base_csi + pcdev->reg_csicr3);
 
 			/* Reflash DMA */
 			writel(csicr3 | CSICR3_DMA_REFLASH_RFF,
-					pcdev->base_csi + CSICR3);
+					pcdev->base_csi + pcdev->reg_csicr3);
 
 			/* clear & enable interrupts */
-			writel(dma_inten, pcdev->base_csi + CSISR);
+			writel(dma_inten, pcdev->base_csi + pcdev->reg_csisr);
 			pcdev->csicr1 |= dma_inten;
 			writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
 
 			/* enable DMA */
 			csicr3 |= CSICR3_DMA_REQ_EN_RFF | CSICR3_RXFF_LEVEL(1);
-			writel(csicr3, pcdev->base_csi + CSICR3);
+			writel(csicr3, pcdev->base_csi + pcdev->reg_csicr3);
 		}
 	}
 
@@ -712,7 +755,7 @@
 	 */
 
 	spin_lock_irqsave(&pcdev->lock, flags);
-	if (cpu_is_mx25() && buf->state == MX2_STATE_ACTIVE) {
+	if (is_imx25_camera(pcdev) && buf->state == MX2_STATE_ACTIVE) {
 		if (pcdev->fb1_active == buf) {
 			pcdev->csicr1 &= ~CSICR1_FB1_DMA_INTEN;
 			writel(0, pcdev->base_csi + CSIDMASA_FB1);
@@ -835,7 +878,7 @@
 	unsigned long phys;
 	int bytesperline;
 
-	if (cpu_is_mx27()) {
+	if (is_imx27_camera(pcdev)) {
 		unsigned long flags;
 		if (count < 2)
 			return -EINVAL;
@@ -930,7 +973,7 @@
 	void *b;
 	u32 cntl;
 
-	if (cpu_is_mx27()) {
+	if (is_imx27_camera(pcdev)) {
 		spin_lock_irqsave(&pcdev->lock, flags);
 
 		cntl = readl(pcdev->base_emma + PRP_CNTL);
@@ -1082,11 +1125,11 @@
 	if (bytesperline < 0)
 		return bytesperline;
 
-	if (cpu_is_mx27()) {
+	if (is_imx27_camera(pcdev)) {
 		ret = mx27_camera_emma_prp_reset(pcdev);
 		if (ret)
 			return ret;
-	} else if (cpu_is_mx25()) {
+	} else if (is_imx25_camera(pcdev)) {
 		writel((bytesperline * icd->user_height) >> 2,
 				pcdev->base_csi + CSIRXCNT);
 		writel((bytesperline << 16) | icd->user_height,
@@ -1392,7 +1435,7 @@
 	/* FIXME: implement MX27 limits */
 
 	/* limit to MX25 hardware capabilities */
-	if (cpu_is_mx25()) {
+	if (is_imx25_camera(pcdev)) {
 		if (xlate->host_fmt->bits_per_sample <= 8)
 			width_limit = 0xffff * 4;
 		else
@@ -1726,10 +1769,31 @@
 		goto exit;
 	}
 
-	pcdev->clk_csi = devm_clk_get(&pdev->dev, "ahb");
-	if (IS_ERR(pcdev->clk_csi)) {
-		dev_err(&pdev->dev, "Could not get csi clock\n");
-		err = PTR_ERR(pcdev->clk_csi);
+	pcdev->devtype = pdev->id_entry->driver_data;
+	switch (pcdev->devtype) {
+	case IMX25_CAMERA:
+		pcdev->reg_csisr = CSISR_IMX25;
+		pcdev->reg_csicr3 = CSICR3_IMX25;
+		break;
+	case IMX27_CAMERA:
+		pcdev->reg_csisr = CSISR_IMX27;
+		pcdev->reg_csicr3 = CSICR3_IMX27;
+		break;
+	default:
+		break;
+	}
+
+	pcdev->clk_csi_ahb = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(pcdev->clk_csi_ahb)) {
+		dev_err(&pdev->dev, "Could not get csi ahb clock\n");
+		err = PTR_ERR(pcdev->clk_csi_ahb);
+		goto exit;
+	}
+
+	pcdev->clk_csi_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(pcdev->clk_csi_per)) {
+		dev_err(&pdev->dev, "Could not get csi per clock\n");
+		err = PTR_ERR(pcdev->clk_csi_per);
 		goto exit;
 	}
 
@@ -1739,12 +1803,13 @@
 
 		pcdev->platform_flags = pcdev->pdata->flags;
 
-		rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
+		rate = clk_round_rate(pcdev->clk_csi_per,
+						pcdev->pdata->clk * 2);
 		if (rate <= 0) {
 			err = -ENODEV;
 			goto exit;
 		}
-		err = clk_set_rate(pcdev->clk_csi, rate);
+		err = clk_set_rate(pcdev->clk_csi_per, rate);
 		if (err < 0)
 			goto exit;
 	}
@@ -1763,7 +1828,7 @@
 	pcdev->dev = &pdev->dev;
 	platform_set_drvdata(pdev, pcdev);
 
-	if (cpu_is_mx25()) {
+	if (is_imx25_camera(pcdev)) {
 		err = devm_request_irq(&pdev->dev, irq_csi, mx25_camera_irq, 0,
 				       MX2_CAM_DRV_NAME, pcdev);
 		if (err) {
@@ -1772,7 +1837,7 @@
 		}
 	}
 
-	if (cpu_is_mx27()) {
+	if (is_imx27_camera(pcdev)) {
 		err = mx27_camera_emma_init(pdev);
 		if (err)
 			goto exit;
@@ -1789,7 +1854,7 @@
 	pcdev->soc_host.priv		= pcdev;
 	pcdev->soc_host.v4l2_dev.dev	= &pdev->dev;
 	pcdev->soc_host.nr		= pdev->id;
-	if (cpu_is_mx25())
+	if (is_imx25_camera(pcdev))
 		pcdev->soc_host.capabilities = SOCAM_HOST_CAP_STRIDE;
 
 	pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
@@ -1802,14 +1867,14 @@
 		goto exit_free_emma;
 
 	dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
-			clk_get_rate(pcdev->clk_csi));
+			clk_get_rate(pcdev->clk_csi_per));
 
 	return 0;
 
 exit_free_emma:
 	vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
 eallocctx:
-	if (cpu_is_mx27()) {
+	if (is_imx27_camera(pcdev)) {
 		clk_disable_unprepare(pcdev->clk_emma_ipg);
 		clk_disable_unprepare(pcdev->clk_emma_ahb);
 	}
@@ -1827,7 +1892,7 @@
 
 	vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
 
-	if (cpu_is_mx27()) {
+	if (is_imx27_camera(pcdev)) {
 		clk_disable_unprepare(pcdev->clk_emma_ipg);
 		clk_disable_unprepare(pcdev->clk_emma_ahb);
 	}
@@ -1841,6 +1906,7 @@
 	.driver 	= {
 		.name	= MX2_CAM_DRV_NAME,
 	},
+	.id_table	= mx2_camera_devtype,
 	.remove		= __devexit_p(mx2_camera_remove),
 };
 
diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c
index 3557ac9..64d39b1 100644
--- a/drivers/media/platform/soc_camera/mx3_camera.c
+++ b/drivers/media/platform/soc_camera/mx3_camera.c
@@ -17,6 +17,7 @@
 #include <linux/vmalloc.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/dma/ipu-dma.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
@@ -24,7 +25,6 @@
 #include <media/soc_camera.h>
 #include <media/soc_mediabus.h>
 
-#include <mach/ipu.h>
 #include <linux/platform_data/camera-mx3.h>
 #include <linux/platform_data/dma-imx.h>
 
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index acab3ef..637bcdf 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1070,3 +1070,9 @@
 	depends on MCP_UCB1200 && INPUT
 
 endmenu
+
+config VEXPRESS_CONFIG
+	bool
+	help
+	  Platform configuration infrastructure for the ARM Ltd.
+	  Versatile Express.
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d8ccb63..296817c 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -138,3 +138,4 @@
 obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
 obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
 obj-$(CONFIG_MFD_LM3533)	+= lm3533-core.o lm3533-ctrlbank.o
+obj-$(CONFIG_VEXPRESS_CONFIG)	+= vexpress-config.o vexpress-sysreg.o
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 00b8b0f..3167bfd 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -1169,12 +1169,12 @@
 }
 
 /**
- * prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage
+ * db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage
  * @enable: true to request the higher voltage, false to drop a request.
  *
  * Calls to this function to enable and disable requests must be balanced.
  */
-int prcmu_request_ape_opp_100_voltage(bool enable)
+int db8500_prcmu_request_ape_opp_100_voltage(bool enable)
 {
 	int r = 0;
 	u8 header;
diff --git a/drivers/mfd/vexpress-config.c b/drivers/mfd/vexpress-config.c
new file mode 100644
index 0000000..fae15d8
--- /dev/null
+++ b/drivers/mfd/vexpress-config.c
@@ -0,0 +1,277 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#define pr_fmt(fmt) "vexpress-config: " fmt
+
+#include <linux/bitops.h>
+#include <linux/completion.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/vexpress.h>
+
+
+#define VEXPRESS_CONFIG_MAX_BRIDGES 2
+
+struct vexpress_config_bridge {
+	struct device_node *node;
+	struct vexpress_config_bridge_info *info;
+	struct list_head transactions;
+	spinlock_t transactions_lock;
+} vexpress_config_bridges[VEXPRESS_CONFIG_MAX_BRIDGES];
+
+static DECLARE_BITMAP(vexpress_config_bridges_map,
+		ARRAY_SIZE(vexpress_config_bridges));
+static DEFINE_MUTEX(vexpress_config_bridges_mutex);
+
+struct vexpress_config_bridge *vexpress_config_bridge_register(
+		struct device_node *node,
+		struct vexpress_config_bridge_info *info)
+{
+	struct vexpress_config_bridge *bridge;
+	int i;
+
+	pr_debug("Registering bridge '%s'\n", info->name);
+
+	mutex_lock(&vexpress_config_bridges_mutex);
+	i = find_first_zero_bit(vexpress_config_bridges_map,
+			ARRAY_SIZE(vexpress_config_bridges));
+	if (i >= ARRAY_SIZE(vexpress_config_bridges)) {
+		pr_err("Can't register more bridges!\n");
+		mutex_unlock(&vexpress_config_bridges_mutex);
+		return NULL;
+	}
+	__set_bit(i, vexpress_config_bridges_map);
+	bridge = &vexpress_config_bridges[i];
+
+	bridge->node = node;
+	bridge->info = info;
+	INIT_LIST_HEAD(&bridge->transactions);
+	spin_lock_init(&bridge->transactions_lock);
+
+	mutex_unlock(&vexpress_config_bridges_mutex);
+
+	return bridge;
+}
+
+void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge)
+{
+	struct vexpress_config_bridge __bridge = *bridge;
+	int i;
+
+	mutex_lock(&vexpress_config_bridges_mutex);
+	for (i = 0; i < ARRAY_SIZE(vexpress_config_bridges); i++)
+		if (&vexpress_config_bridges[i] == bridge)
+			__clear_bit(i, vexpress_config_bridges_map);
+	mutex_unlock(&vexpress_config_bridges_mutex);
+
+	WARN_ON(!list_empty(&__bridge.transactions));
+	while (!list_empty(&__bridge.transactions))
+		cpu_relax();
+}
+
+
+struct vexpress_config_func {
+	struct vexpress_config_bridge *bridge;
+	void *func;
+};
+
+struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
+		struct device_node *node)
+{
+	struct device_node *bridge_node;
+	struct vexpress_config_func *func;
+	int i;
+
+	if (WARN_ON(dev && node && dev->of_node != node))
+		return NULL;
+	if (dev && !node)
+		node = dev->of_node;
+
+	func = kzalloc(sizeof(*func), GFP_KERNEL);
+	if (!func)
+		return NULL;
+
+	bridge_node = of_node_get(node);
+	while (bridge_node) {
+		const __be32 *prop = of_get_property(bridge_node,
+				"arm,vexpress,config-bridge", NULL);
+
+		if (prop) {
+			bridge_node = of_find_node_by_phandle(
+					be32_to_cpup(prop));
+			break;
+		}
+
+		bridge_node = of_get_next_parent(bridge_node);
+	}
+
+	mutex_lock(&vexpress_config_bridges_mutex);
+	for (i = 0; i < ARRAY_SIZE(vexpress_config_bridges); i++) {
+		struct vexpress_config_bridge *bridge =
+				&vexpress_config_bridges[i];
+
+		if (test_bit(i, vexpress_config_bridges_map) &&
+				bridge->node == bridge_node) {
+			func->bridge = bridge;
+			func->func = bridge->info->func_get(dev, node);
+			break;
+		}
+	}
+	mutex_unlock(&vexpress_config_bridges_mutex);
+
+	if (!func->func) {
+		of_node_put(node);
+		kfree(func);
+		return NULL;
+	}
+
+	return func;
+}
+
+void vexpress_config_func_put(struct vexpress_config_func *func)
+{
+	func->bridge->info->func_put(func->func);
+	of_node_put(func->bridge->node);
+	kfree(func);
+}
+
+
+struct vexpress_config_trans {
+	struct vexpress_config_func *func;
+	int offset;
+	bool write;
+	u32 *data;
+	int status;
+	struct completion completion;
+	struct list_head list;
+};
+
+static void vexpress_config_dump_trans(const char *what,
+		struct vexpress_config_trans *trans)
+{
+	pr_debug("%s %s trans %p func 0x%p offset %d data 0x%x status %d\n",
+			what, trans->write ? "write" : "read", trans,
+			trans->func->func, trans->offset,
+			trans->data ? *trans->data : 0, trans->status);
+}
+
+static int vexpress_config_schedule(struct vexpress_config_trans *trans)
+{
+	int status;
+	struct vexpress_config_bridge *bridge = trans->func->bridge;
+	unsigned long flags;
+
+	init_completion(&trans->completion);
+	trans->status = -EFAULT;
+
+	spin_lock_irqsave(&bridge->transactions_lock, flags);
+
+	vexpress_config_dump_trans("Executing", trans);
+
+	if (list_empty(&bridge->transactions))
+		status = bridge->info->func_exec(trans->func->func,
+				trans->offset, trans->write, trans->data);
+	else
+		status = VEXPRESS_CONFIG_STATUS_WAIT;
+
+	switch (status) {
+	case VEXPRESS_CONFIG_STATUS_DONE:
+		vexpress_config_dump_trans("Finished", trans);
+		trans->status = status;
+		break;
+	case VEXPRESS_CONFIG_STATUS_WAIT:
+		list_add_tail(&trans->list, &bridge->transactions);
+		break;
+	}
+
+	spin_unlock_irqrestore(&bridge->transactions_lock, flags);
+
+	return status;
+}
+
+void vexpress_config_complete(struct vexpress_config_bridge *bridge,
+		int status)
+{
+	struct vexpress_config_trans *trans;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bridge->transactions_lock, flags);
+
+	trans = list_first_entry(&bridge->transactions,
+			struct vexpress_config_trans, list);
+	vexpress_config_dump_trans("Completed", trans);
+
+	trans->status = status;
+	list_del(&trans->list);
+
+	if (!list_empty(&bridge->transactions)) {
+		vexpress_config_dump_trans("Pending", trans);
+
+		bridge->info->func_exec(trans->func->func, trans->offset,
+				trans->write, trans->data);
+	}
+	spin_unlock_irqrestore(&bridge->transactions_lock, flags);
+
+	complete(&trans->completion);
+}
+
+int vexpress_config_wait(struct vexpress_config_trans *trans)
+{
+	wait_for_completion(&trans->completion);
+
+	return trans->status;
+}
+
+
+int vexpress_config_read(struct vexpress_config_func *func, int offset,
+		u32 *data)
+{
+	struct vexpress_config_trans trans = {
+		.func = func,
+		.offset = offset,
+		.write = false,
+		.data = data,
+		.status = 0,
+	};
+	int status = vexpress_config_schedule(&trans);
+
+	if (status == VEXPRESS_CONFIG_STATUS_WAIT)
+		status = vexpress_config_wait(&trans);
+
+	return status;
+}
+EXPORT_SYMBOL(vexpress_config_read);
+
+int vexpress_config_write(struct vexpress_config_func *func, int offset,
+		u32 data)
+{
+	struct vexpress_config_trans trans = {
+		.func = func,
+		.offset = offset,
+		.write = true,
+		.data = &data,
+		.status = 0,
+	};
+	int status = vexpress_config_schedule(&trans);
+
+	if (status == VEXPRESS_CONFIG_STATUS_WAIT)
+		status = vexpress_config_wait(&trans);
+
+	return status;
+}
+EXPORT_SYMBOL(vexpress_config_write);
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
new file mode 100644
index 0000000..059d6b1
--- /dev/null
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -0,0 +1,552 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/timer.h>
+#include <linux/vexpress.h>
+
+#define SYS_ID			0x000
+#define SYS_SW			0x004
+#define SYS_LED			0x008
+#define SYS_100HZ		0x024
+#define SYS_FLAGS		0x030
+#define SYS_FLAGSSET		0x030
+#define SYS_FLAGSCLR		0x034
+#define SYS_NVFLAGS		0x038
+#define SYS_NVFLAGSSET		0x038
+#define SYS_NVFLAGSCLR		0x03c
+#define SYS_MCI			0x048
+#define SYS_FLASH		0x04c
+#define SYS_CFGSW		0x058
+#define SYS_24MHZ		0x05c
+#define SYS_MISC		0x060
+#define SYS_DMA			0x064
+#define SYS_PROCID0		0x084
+#define SYS_PROCID1		0x088
+#define SYS_CFGDATA		0x0a0
+#define SYS_CFGCTRL		0x0a4
+#define SYS_CFGSTAT		0x0a8
+
+#define SYS_HBI_MASK		0xfff
+#define SYS_ID_HBI_SHIFT	16
+#define SYS_PROCIDx_HBI_SHIFT	0
+
+#define SYS_MCI_CARDIN		(1 << 0)
+#define SYS_MCI_WPROT		(1 << 1)
+
+#define SYS_FLASH_WPn		(1 << 0)
+
+#define SYS_MISC_MASTERSITE	(1 << 14)
+
+#define SYS_CFGCTRL_START	(1 << 31)
+#define SYS_CFGCTRL_WRITE	(1 << 30)
+#define SYS_CFGCTRL_DCC(n)	(((n) & 0xf) << 26)
+#define SYS_CFGCTRL_FUNC(n)	(((n) & 0x3f) << 20)
+#define SYS_CFGCTRL_SITE(n)	(((n) & 0x3) << 16)
+#define SYS_CFGCTRL_POSITION(n)	(((n) & 0xf) << 12)
+#define SYS_CFGCTRL_DEVICE(n)	(((n) & 0xfff) << 0)
+
+#define SYS_CFGSTAT_ERR		(1 << 1)
+#define SYS_CFGSTAT_COMPLETE	(1 << 0)
+
+
+static void __iomem *vexpress_sysreg_base;
+static struct device *vexpress_sysreg_dev;
+static int vexpress_master_site;
+
+
+void vexpress_flags_set(u32 data)
+{
+	writel(~0, vexpress_sysreg_base + SYS_FLAGSCLR);
+	writel(data, vexpress_sysreg_base + SYS_FLAGSSET);
+}
+
+u32 vexpress_get_procid(int site)
+{
+	if (site == VEXPRESS_SITE_MASTER)
+		site = vexpress_master_site;
+
+	return readl(vexpress_sysreg_base + (site == VEXPRESS_SITE_DB1 ?
+			SYS_PROCID0 : SYS_PROCID1));
+}
+
+u32 vexpress_get_hbi(int site)
+{
+	u32 id;
+
+	switch (site) {
+	case VEXPRESS_SITE_MB:
+		id = readl(vexpress_sysreg_base + SYS_ID);
+		return (id >> SYS_ID_HBI_SHIFT) & SYS_HBI_MASK;
+	case VEXPRESS_SITE_MASTER:
+	case VEXPRESS_SITE_DB1:
+	case VEXPRESS_SITE_DB2:
+		id = vexpress_get_procid(site);
+		return (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK;
+	}
+
+	return ~0;
+}
+
+void __iomem *vexpress_get_24mhz_clock_base(void)
+{
+	return vexpress_sysreg_base + SYS_24MHZ;
+}
+
+
+static void vexpress_sysreg_find_prop(struct device_node *node,
+		const char *name, u32 *val)
+{
+	of_node_get(node);
+	while (node) {
+		if (of_property_read_u32(node, name, val) == 0) {
+			of_node_put(node);
+			return;
+		}
+		node = of_get_next_parent(node);
+	}
+}
+
+unsigned __vexpress_get_site(struct device *dev, struct device_node *node)
+{
+	u32 site = 0;
+
+	WARN_ON(dev && node && dev->of_node != node);
+	if (dev && !node)
+		node = dev->of_node;
+
+	if (node) {
+		vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site);
+	} else if (dev && dev->bus == &platform_bus_type) {
+		struct platform_device *pdev = to_platform_device(dev);
+
+		if (pdev->num_resources == 1 &&
+				pdev->resource[0].flags == IORESOURCE_BUS)
+			site = pdev->resource[0].start;
+	} else if (dev && strncmp(dev_name(dev), "ct:", 3) == 0) {
+		site = VEXPRESS_SITE_MASTER;
+	}
+
+	if (site == VEXPRESS_SITE_MASTER)
+		site = vexpress_master_site;
+
+	return site;
+}
+
+
+struct vexpress_sysreg_config_func {
+	u32 template;
+	u32 device;
+};
+
+static struct vexpress_config_bridge *vexpress_sysreg_config_bridge;
+static struct timer_list vexpress_sysreg_config_timer;
+static u32 *vexpress_sysreg_config_data;
+static int vexpress_sysreg_config_tries;
+
+static void *vexpress_sysreg_config_func_get(struct device *dev,
+		struct device_node *node)
+{
+	struct vexpress_sysreg_config_func *config_func;
+	u32 site;
+	u32 position = 0;
+	u32 dcc = 0;
+	u32 func_device[2];
+	int err = -EFAULT;
+
+	if (node) {
+		of_node_get(node);
+		vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site);
+		vexpress_sysreg_find_prop(node, "arm,vexpress,position",
+				&position);
+		vexpress_sysreg_find_prop(node, "arm,vexpress,dcc", &dcc);
+		err = of_property_read_u32_array(node,
+				"arm,vexpress-sysreg,func", func_device,
+				ARRAY_SIZE(func_device));
+		of_node_put(node);
+	} else if (dev && dev->bus == &platform_bus_type) {
+		struct platform_device *pdev = to_platform_device(dev);
+
+		if (pdev->num_resources == 1 &&
+				pdev->resource[0].flags == IORESOURCE_BUS) {
+			site = pdev->resource[0].start;
+			func_device[0] = pdev->resource[0].end;
+			func_device[1] = pdev->id;
+			err = 0;
+		}
+	}
+	if (err)
+		return NULL;
+
+	config_func = kzalloc(sizeof(*config_func), GFP_KERNEL);
+	if (!config_func)
+		return NULL;
+
+	config_func->template = SYS_CFGCTRL_DCC(dcc);
+	config_func->template |= SYS_CFGCTRL_FUNC(func_device[0]);
+	config_func->template |= SYS_CFGCTRL_SITE(site == VEXPRESS_SITE_MASTER ?
+			vexpress_master_site : site);
+	config_func->template |= SYS_CFGCTRL_POSITION(position);
+	config_func->device |= func_device[1];
+
+	dev_dbg(vexpress_sysreg_dev, "func 0x%p = 0x%x, %d\n", config_func,
+			config_func->template, config_func->device);
+
+	return config_func;
+}
+
+static void vexpress_sysreg_config_func_put(void *func)
+{
+	kfree(func);
+}
+
+static int vexpress_sysreg_config_func_exec(void *func, int offset,
+		bool write, u32 *data)
+{
+	int status;
+	struct vexpress_sysreg_config_func *config_func = func;
+	u32 command;
+
+	if (WARN_ON(!vexpress_sysreg_base))
+		return -ENOENT;
+
+	command = readl(vexpress_sysreg_base + SYS_CFGCTRL);
+	if (WARN_ON(command & SYS_CFGCTRL_START))
+		return -EBUSY;
+
+	command = SYS_CFGCTRL_START;
+	command |= write ? SYS_CFGCTRL_WRITE : 0;
+	command |= config_func->template;
+	command |= SYS_CFGCTRL_DEVICE(config_func->device + offset);
+
+	/* Use a canary for reads */
+	if (!write)
+		*data = 0xdeadbeef;
+
+	dev_dbg(vexpress_sysreg_dev, "command %x, data %x\n",
+			command, *data);
+	writel(*data, vexpress_sysreg_base + SYS_CFGDATA);
+	writel(0, vexpress_sysreg_base + SYS_CFGSTAT);
+	writel(command, vexpress_sysreg_base + SYS_CFGCTRL);
+	mb();
+
+	if (vexpress_sysreg_dev) {
+		/* Schedule completion check */
+		if (!write)
+			vexpress_sysreg_config_data = data;
+		vexpress_sysreg_config_tries = 100;
+		mod_timer(&vexpress_sysreg_config_timer,
+				jiffies + usecs_to_jiffies(100));
+		status = VEXPRESS_CONFIG_STATUS_WAIT;
+	} else {
+		/* Early execution, no timer available, have to spin */
+		u32 cfgstat;
+
+		do {
+			cpu_relax();
+			cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
+		} while (!cfgstat);
+
+		if (!write && (cfgstat & SYS_CFGSTAT_COMPLETE))
+			*data = readl(vexpress_sysreg_base + SYS_CFGDATA);
+		status = VEXPRESS_CONFIG_STATUS_DONE;
+
+		if (cfgstat & SYS_CFGSTAT_ERR)
+			status = -EINVAL;
+	}
+
+	return status;
+}
+
+struct vexpress_config_bridge_info vexpress_sysreg_config_bridge_info = {
+	.name = "vexpress-sysreg",
+	.func_get = vexpress_sysreg_config_func_get,
+	.func_put = vexpress_sysreg_config_func_put,
+	.func_exec = vexpress_sysreg_config_func_exec,
+};
+
+static void vexpress_sysreg_config_complete(unsigned long data)
+{
+	int status = VEXPRESS_CONFIG_STATUS_DONE;
+	u32 cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
+
+	if (cfgstat & SYS_CFGSTAT_ERR)
+		status = -EINVAL;
+	if (!vexpress_sysreg_config_tries--)
+		status = -ETIMEDOUT;
+
+	if (status < 0) {
+		dev_err(vexpress_sysreg_dev, "error %d\n", status);
+	} else if (!(cfgstat & SYS_CFGSTAT_COMPLETE)) {
+		mod_timer(&vexpress_sysreg_config_timer,
+				jiffies + usecs_to_jiffies(50));
+		return;
+	}
+
+	if (vexpress_sysreg_config_data) {
+		*vexpress_sysreg_config_data = readl(vexpress_sysreg_base +
+				SYS_CFGDATA);
+		dev_dbg(vexpress_sysreg_dev, "read data %x\n",
+				*vexpress_sysreg_config_data);
+		vexpress_sysreg_config_data = NULL;
+	}
+
+	vexpress_config_complete(vexpress_sysreg_config_bridge, status);
+}
+
+
+void __init vexpress_sysreg_early_init(void __iomem *base)
+{
+	struct device_node *node = of_find_compatible_node(NULL, NULL,
+			"arm,vexpress-sysreg");
+
+	if (node)
+		base = of_iomap(node, 0);
+
+	if (WARN_ON(!base))
+		return;
+
+	vexpress_sysreg_base = base;
+
+	if (readl(vexpress_sysreg_base + SYS_MISC) & SYS_MISC_MASTERSITE)
+		vexpress_master_site = VEXPRESS_SITE_DB2;
+	else
+		vexpress_master_site = VEXPRESS_SITE_DB1;
+
+	vexpress_sysreg_config_bridge = vexpress_config_bridge_register(
+			node, &vexpress_sysreg_config_bridge_info);
+	WARN_ON(!vexpress_sysreg_config_bridge);
+}
+
+void __init vexpress_sysreg_of_early_init(void)
+{
+	vexpress_sysreg_early_init(NULL);
+}
+
+
+static struct vexpress_sysreg_gpio {
+	unsigned long reg;
+	u32 value;
+} vexpress_sysreg_gpios[] = {
+	[VEXPRESS_GPIO_MMC_CARDIN] = {
+		.reg = SYS_MCI,
+		.value = SYS_MCI_CARDIN,
+	},
+	[VEXPRESS_GPIO_MMC_WPROT] = {
+		.reg = SYS_MCI,
+		.value = SYS_MCI_WPROT,
+	},
+	[VEXPRESS_GPIO_FLASH_WPn] = {
+		.reg = SYS_FLASH,
+		.value = SYS_FLASH_WPn,
+	},
+};
+
+static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip,
+				       unsigned offset)
+{
+	return 0;
+}
+
+static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip,
+						unsigned offset, int value)
+{
+	return 0;
+}
+
+static int vexpress_sysreg_gpio_get(struct gpio_chip *chip,
+				       unsigned offset)
+{
+	struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset];
+	u32 reg_value = readl(vexpress_sysreg_base + gpio->reg);
+
+	return !!(reg_value & gpio->value);
+}
+
+static void vexpress_sysreg_gpio_set(struct gpio_chip *chip,
+				       unsigned offset, int value)
+{
+	struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset];
+	u32 reg_value = readl(vexpress_sysreg_base + gpio->reg);
+
+	if (value)
+		reg_value |= gpio->value;
+	else
+		reg_value &= ~gpio->value;
+
+	writel(reg_value, vexpress_sysreg_base + gpio->reg);
+}
+
+static struct gpio_chip vexpress_sysreg_gpio_chip = {
+	.label = "vexpress-sysreg",
+	.direction_input = vexpress_sysreg_gpio_direction_input,
+	.direction_output = vexpress_sysreg_gpio_direction_output,
+	.get = vexpress_sysreg_gpio_get,
+	.set = vexpress_sysreg_gpio_set,
+	.ngpio = ARRAY_SIZE(vexpress_sysreg_gpios),
+	.base = 0,
+};
+
+
+static ssize_t vexpress_sysreg_sys_id_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%08x\n", readl(vexpress_sysreg_base + SYS_ID));
+}
+
+DEVICE_ATTR(sys_id, S_IRUGO, vexpress_sysreg_sys_id_show, NULL);
+
+static int __devinit vexpress_sysreg_probe(struct platform_device *pdev)
+{
+	int err;
+	struct resource *res = platform_get_resource(pdev,
+			IORESOURCE_MEM, 0);
+
+	if (!devm_request_mem_region(&pdev->dev, res->start,
+			resource_size(res), pdev->name)) {
+		dev_err(&pdev->dev, "Failed to request memory region!\n");
+		return -EBUSY;
+	}
+
+	if (!vexpress_sysreg_base)
+		vexpress_sysreg_base = devm_ioremap(&pdev->dev, res->start,
+				resource_size(res));
+
+	if (!vexpress_sysreg_base) {
+		dev_err(&pdev->dev, "Failed to obtain base address!\n");
+		return -EFAULT;
+	}
+
+	setup_timer(&vexpress_sysreg_config_timer,
+			vexpress_sysreg_config_complete, 0);
+
+	vexpress_sysreg_gpio_chip.dev = &pdev->dev;
+	err = gpiochip_add(&vexpress_sysreg_gpio_chip);
+	if (err) {
+		vexpress_config_bridge_unregister(
+				vexpress_sysreg_config_bridge);
+		dev_err(&pdev->dev, "Failed to register GPIO chip! (%d)\n",
+				err);
+		return err;
+	}
+
+	vexpress_sysreg_dev = &pdev->dev;
+
+	device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id);
+
+	return 0;
+}
+
+static const struct of_device_id vexpress_sysreg_match[] = {
+	{ .compatible = "arm,vexpress-sysreg", },
+	{},
+};
+
+static struct platform_driver vexpress_sysreg_driver = {
+	.driver = {
+		.name = "vexpress-sysreg",
+		.of_match_table = vexpress_sysreg_match,
+	},
+	.probe = vexpress_sysreg_probe,
+};
+
+static int __init vexpress_sysreg_init(void)
+{
+	return platform_driver_register(&vexpress_sysreg_driver);
+}
+core_initcall(vexpress_sysreg_init);
+
+
+#if defined(CONFIG_LEDS_CLASS)
+
+struct vexpress_sysreg_led {
+	u32 mask;
+	struct led_classdev cdev;
+} vexpress_sysreg_leds[] = {
+	{ .mask = 1 << 0, .cdev.name = "v2m:green:user1",
+			.cdev.default_trigger = "heartbeat", },
+	{ .mask = 1 << 1, .cdev.name = "v2m:green:user2",
+			.cdev.default_trigger = "mmc0", },
+	{ .mask = 1 << 2, .cdev.name = "v2m:green:user3",
+			.cdev.default_trigger = "cpu0", },
+	{ .mask = 1 << 3, .cdev.name = "v2m:green:user4",
+			.cdev.default_trigger = "cpu1", },
+	{ .mask = 1 << 4, .cdev.name = "v2m:green:user5",
+			.cdev.default_trigger = "cpu2", },
+	{ .mask = 1 << 5, .cdev.name = "v2m:green:user6",
+			.cdev.default_trigger = "cpu3", },
+	{ .mask = 1 << 6, .cdev.name = "v2m:green:user7",
+			.cdev.default_trigger = "cpu4", },
+	{ .mask = 1 << 7, .cdev.name = "v2m:green:user8",
+			.cdev.default_trigger = "cpu5", },
+};
+
+static DEFINE_SPINLOCK(vexpress_sysreg_leds_lock);
+
+static void vexpress_sysreg_led_brightness_set(struct led_classdev *cdev,
+		enum led_brightness brightness)
+{
+	struct vexpress_sysreg_led *led = container_of(cdev,
+			struct vexpress_sysreg_led, cdev);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&vexpress_sysreg_leds_lock, flags);
+
+	val = readl(vexpress_sysreg_base + SYS_LED);
+	if (brightness == LED_OFF)
+		val &= ~led->mask;
+	else
+		val |= led->mask;
+	writel(val, vexpress_sysreg_base + SYS_LED);
+
+	spin_unlock_irqrestore(&vexpress_sysreg_leds_lock, flags);
+}
+
+static int __init vexpress_sysreg_init_leds(void)
+{
+	struct vexpress_sysreg_led *led;
+	int i;
+
+	/* Clear all user LEDs */
+	writel(0, vexpress_sysreg_base + SYS_LED);
+
+	for (i = 0, led = vexpress_sysreg_leds;
+			i < ARRAY_SIZE(vexpress_sysreg_leds); i++, led++) {
+		int err;
+
+		led->cdev.brightness_set = vexpress_sysreg_led_brightness_set;
+		err = led_classdev_register(vexpress_sysreg_dev, &led->cdev);
+		if (err) {
+			dev_err(vexpress_sysreg_dev,
+					"Failed to register LED %d! (%d)\n",
+					i, err);
+			while (led--, i--)
+				led_classdev_unregister(&led->cdev);
+			return err;
+		}
+	}
+
+	return 0;
+}
+device_initcall(vexpress_sysreg_init_leds);
+
+#endif
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 660bbc5..4d50da6 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -208,7 +208,7 @@
 	MMC_CAP_CMD23,
 };
 
-static struct dw_mci_drv_data exynos5250_drv_data = {
+static const struct dw_mci_drv_data exynos5250_drv_data = {
 	.caps			= exynos5250_dwmmc_caps,
 	.init			= dw_mci_exynos_priv_init,
 	.setup_clock		= dw_mci_exynos_setup_clock,
@@ -220,14 +220,14 @@
 
 static const struct of_device_id dw_mci_exynos_match[] = {
 	{ .compatible = "samsung,exynos5250-dw-mshc",
-			.data = (void *)&exynos5250_drv_data, },
+			.data = &exynos5250_drv_data, },
 	{},
 };
-MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match);
+MODULE_DEVICE_TABLE(of, dw_mci_exynos_match);
 
 int dw_mci_exynos_probe(struct platform_device *pdev)
 {
-	struct dw_mci_drv_data *drv_data;
+	const struct dw_mci_drv_data *drv_data;
 	const struct of_device_id *match;
 
 	match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node);
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index c960ca7..917936b 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -24,7 +24,7 @@
 #include "dw_mmc.h"
 
 int dw_mci_pltfm_register(struct platform_device *pdev,
-				struct dw_mci_drv_data *drv_data)
+				const struct dw_mci_drv_data *drv_data)
 {
 	struct dw_mci *host;
 	struct resource	*regs;
@@ -50,8 +50,8 @@
 	if (!host->regs)
 		return -ENOMEM;
 
-	if (host->drv_data->init) {
-		ret = host->drv_data->init(host);
+	if (drv_data && drv_data->init) {
+		ret = drv_data->init(host);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/mmc/host/dw_mmc-pltfm.h b/drivers/mmc/host/dw_mmc-pltfm.h
index 301f245..2ac37b8 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.h
+++ b/drivers/mmc/host/dw_mmc-pltfm.h
@@ -13,7 +13,7 @@
 #define _DW_MMC_PLTFM_H_
 
 extern int dw_mci_pltfm_register(struct platform_device *pdev,
-				struct dw_mci_drv_data *drv_data);
+				const struct dw_mci_drv_data *drv_data);
 extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev);
 extern const struct dev_pm_ops dw_mci_pltfm_pmops;
 
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index c2828f3..c0667c8 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -232,6 +232,7 @@
 {
 	struct mmc_data	*data;
 	struct dw_mci_slot *slot = mmc_priv(mmc);
+	struct dw_mci_drv_data *drv_data = slot->host->drv_data;
 	u32 cmdr;
 	cmd->error = -EINPROGRESS;
 
@@ -261,8 +262,8 @@
 			cmdr |= SDMMC_CMD_DAT_WR;
 	}
 
-	if (slot->host->drv_data->prepare_command)
-		slot->host->drv_data->prepare_command(slot->host, &cmdr);
+	if (drv_data && drv_data->prepare_command)
+		drv_data->prepare_command(slot->host, &cmdr);
 
 	return cmdr;
 }
@@ -434,7 +435,7 @@
 	return 0;
 }
 
-static struct dw_mci_dma_ops dw_mci_idmac_ops = {
+static const struct dw_mci_dma_ops dw_mci_idmac_ops = {
 	.init = dw_mci_idmac_init,
 	.start = dw_mci_idmac_start_dma,
 	.stop = dw_mci_idmac_stop_dma,
@@ -772,6 +773,7 @@
 static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct dw_mci_slot *slot = mmc_priv(mmc);
+	struct dw_mci_drv_data *drv_data = slot->host->drv_data;
 	u32 regs;
 
 	/* set default 1 bit mode */
@@ -807,8 +809,8 @@
 		slot->clock = ios->clock;
 	}
 
-	if (slot->host->drv_data->set_ios)
-		slot->host->drv_data->set_ios(slot->host, ios);
+	if (drv_data && drv_data->set_ios)
+		drv_data->set_ios(slot->host, ios);
 
 	switch (ios->power_mode) {
 	case MMC_POWER_UP:
@@ -1815,6 +1817,7 @@
 {
 	struct mmc_host *mmc;
 	struct dw_mci_slot *slot;
+	struct dw_mci_drv_data *drv_data = host->drv_data;
 	int ctrl_id, ret;
 	u8 bus_width;
 
@@ -1854,8 +1857,8 @@
 	} else {
 		ctrl_id = to_platform_device(host->dev)->id;
 	}
-	if (host->drv_data && host->drv_data->caps)
-		mmc->caps |= host->drv_data->caps[ctrl_id];
+	if (drv_data && drv_data->caps)
+		mmc->caps |= drv_data->caps[ctrl_id];
 
 	if (host->pdata->caps2)
 		mmc->caps2 = host->pdata->caps2;
@@ -1867,10 +1870,10 @@
 	else
 		bus_width = 1;
 
-	if (host->drv_data->setup_bus) {
+	if (drv_data && drv_data->setup_bus) {
 		struct device_node *slot_np;
 		slot_np = dw_mci_of_find_slot_node(host->dev, slot->id);
-		ret = host->drv_data->setup_bus(host, slot_np, bus_width);
+		ret = drv_data->setup_bus(host, slot_np, bus_width);
 		if (ret)
 			goto err_setup_bus;
 	}
@@ -1968,7 +1971,7 @@
 	/* Determine which DMA interface to use */
 #ifdef CONFIG_MMC_DW_IDMAC
 	host->dma_ops = &dw_mci_idmac_ops;
-	dev_info(&host->dev, "Using internal DMA controller.\n");
+	dev_info(host->dev, "Using internal DMA controller.\n");
 #endif
 
 	if (!host->dma_ops)
@@ -2035,6 +2038,7 @@
 	struct dw_mci_board *pdata;
 	struct device *dev = host->dev;
 	struct device_node *np = dev->of_node;
+	struct dw_mci_drv_data *drv_data = host->drv_data;
 	int idx, ret;
 
 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
@@ -2062,8 +2066,8 @@
 
 	of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms);
 
-	if (host->drv_data->parse_dt) {
-		ret = host->drv_data->parse_dt(host);
+	if (drv_data && drv_data->parse_dt) {
+		ret = drv_data->parse_dt(host);
 		if (ret)
 			return ERR_PTR(ret);
 	}
@@ -2080,6 +2084,7 @@
 
 int dw_mci_probe(struct dw_mci *host)
 {
+	struct dw_mci_drv_data *drv_data = host->drv_data;
 	int width, i, ret = 0;
 	u32 fifo_size;
 	int init_slots = 0;
@@ -2127,8 +2132,8 @@
 	else
 		host->bus_hz = clk_get_rate(host->ciu_clk);
 
-	if (host->drv_data->setup_clock) {
-		ret = host->drv_data->setup_clock(host);
+	if (drv_data && drv_data->setup_clock) {
+		ret = drv_data->setup_clock(host);
 		if (ret) {
 			dev_err(host->dev,
 				"implementation specific clock setup failed\n");
@@ -2228,6 +2233,21 @@
 	else
 		host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1;
 
+	/*
+	 * Enable interrupts for command done, data over, data empty, card det,
+	 * receive ready and error such as transmit, receive timeout, crc error
+	 */
+	mci_writel(host, RINTSTS, 0xFFFFFFFF);
+	mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
+		   SDMMC_INT_TXDR | SDMMC_INT_RXDR |
+		   DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
+	mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
+
+	dev_info(host->dev, "DW MMC controller at irq %d, "
+		 "%d bit host data width, "
+		 "%u deep fifo\n",
+		 host->irq, width, fifo_size);
+
 	/* We need at least one slot to succeed */
 	for (i = 0; i < host->num_slots; i++) {
 		ret = dw_mci_init_slot(host, i);
@@ -2257,20 +2277,6 @@
 	else
 		host->data_offset = DATA_240A_OFFSET;
 
-	/*
-	 * Enable interrupts for command done, data over, data empty, card det,
-	 * receive ready and error such as transmit, receive timeout, crc error
-	 */
-	mci_writel(host, RINTSTS, 0xFFFFFFFF);
-	mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
-		   SDMMC_INT_TXDR | SDMMC_INT_RXDR |
-		   DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
-	mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
-
-	dev_info(host->dev, "DW MMC controller at irq %d, "
-		 "%d bit host data width, "
-		 "%u deep fifo\n",
-		 host->irq, width, fifo_size);
 	if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO)
 		dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n");
 
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 565c2e4..477f63b 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -41,7 +41,6 @@
 #include <linux/platform_data/mmc-mxcmmc.h>
 
 #include <linux/platform_data/dma-imx.h>
-#include <mach/hardware.h>
 
 #define DRIVER_NAME "mxc-mmc"
 #define MXCMCI_TIMEOUT_MS 10000
@@ -113,6 +112,11 @@
 #define INT_WRITE_OP_DONE_EN		(1 << 1)
 #define INT_READ_OP_EN			(1 << 0)
 
+enum mxcmci_type {
+	IMX21_MMC,
+	IMX31_MMC,
+};
+
 struct mxcmci_host {
 	struct mmc_host		*mmc;
 	struct resource		*res;
@@ -153,8 +157,27 @@
 	struct imx_dma_data	dma_data;
 
 	struct timer_list	watchdog;
+	enum mxcmci_type	devtype;
 };
 
+static struct platform_device_id mxcmci_devtype[] = {
+	{
+		.name = "imx21-mmc",
+		.driver_data = IMX21_MMC,
+	}, {
+		.name = "imx31-mmc",
+		.driver_data = IMX31_MMC,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, mxcmci_devtype);
+
+static inline int is_imx31_mmc(struct mxcmci_host *host)
+{
+	return host->devtype == IMX31_MMC;
+}
+
 static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
 
 static inline void mxcmci_init_ocr(struct mxcmci_host *host)
@@ -843,6 +866,8 @@
 
 static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card)
 {
+	struct mxcmci_host *mxcmci = mmc_priv(host);
+
 	/*
 	 * MX3 SoCs have a silicon bug which corrupts CRC calculation of
 	 * multi-block transfers when connected SDIO peripheral doesn't
@@ -850,7 +875,7 @@
 	 * One way to prevent this is to only allow 1-bit transfers.
 	 */
 
-	if (cpu_is_mx3() && card->type == MMC_TYPE_SDIO)
+	if (is_imx31_mmc(mxcmci) && card->type == MMC_TYPE_SDIO)
 		host->caps &= ~MMC_CAP_4_BIT_DATA;
 	else
 		host->caps |= MMC_CAP_4_BIT_DATA;
@@ -948,6 +973,7 @@
 
 	host->mmc = mmc;
 	host->pdata = pdev->dev.platform_data;
+	host->devtype = pdev->id_entry->driver_data;
 	spin_lock_init(&host->lock);
 
 	mxcmci_init_ocr(host);
@@ -1120,6 +1146,7 @@
 static struct platform_driver mxcmci_driver = {
 	.probe		= mxcmci_probe,
 	.remove		= mxcmci_remove,
+	.id_table	= mxcmci_devtype,
 	.driver		= {
 		.name		= DRIVER_NAME,
 		.owner		= THIS_MODULE,
@@ -1134,4 +1161,4 @@
 MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
 MODULE_AUTHOR("Sascha Hauer, Pengutronix");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-mmc");
+MODULE_ALIAS("platform:mxc-mmc");
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 54bfd0c..fedd258 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -178,7 +178,8 @@
 
 static int omap_hsmmc_card_detect(struct device *dev, int slot)
 {
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+	struct omap_mmc_platform_data *mmc = host->pdata;
 
 	/* NOTE: assumes card detect signal is active-low */
 	return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
@@ -186,7 +187,8 @@
 
 static int omap_hsmmc_get_wp(struct device *dev, int slot)
 {
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+	struct omap_mmc_platform_data *mmc = host->pdata;
 
 	/* NOTE: assumes write protect signal is active-high */
 	return gpio_get_value_cansleep(mmc->slots[0].gpio_wp);
@@ -194,7 +196,8 @@
 
 static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
 {
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+	struct omap_mmc_platform_data *mmc = host->pdata;
 
 	/* NOTE: assumes card detect signal is active-low */
 	return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
@@ -204,7 +207,8 @@
 
 static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot)
 {
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+	struct omap_mmc_platform_data *mmc = host->pdata;
 
 	disable_irq(mmc->slots[0].card_detect_irq);
 	return 0;
@@ -212,7 +216,8 @@
 
 static int omap_hsmmc_resume_cdirq(struct device *dev, int slot)
 {
-	struct omap_mmc_platform_data *mmc = dev->platform_data;
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+	struct omap_mmc_platform_data *mmc = host->pdata;
 
 	enable_irq(mmc->slots[0].card_detect_irq);
 	return 0;
@@ -2009,9 +2014,9 @@
 		clk_put(host->dbclk);
 	}
 
-	mmc_free_host(host->mmc);
+	omap_hsmmc_gpio_free(host->pdata);
 	iounmap(host->base);
-	omap_hsmmc_gpio_free(pdev->dev.platform_data);
+	mmc_free_host(host->mmc);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res)
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 90140eb..8fd50a2 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/err.h>
@@ -84,30 +85,32 @@
 	struct sdhci_dove_priv *priv;
 	int ret;
 
-	ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata);
-	if (ret)
-		goto sdhci_dove_register_fail;
-
 	priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv),
 			    GFP_KERNEL);
 	if (!priv) {
 		dev_err(&pdev->dev, "unable to allocate private data");
-		ret = -ENOMEM;
-		goto sdhci_dove_allocate_fail;
+		return -ENOMEM;
 	}
 
+	priv->clk = clk_get(&pdev->dev, NULL);
+	if (!IS_ERR(priv->clk))
+		clk_prepare_enable(priv->clk);
+
+	ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata);
+	if (ret)
+		goto sdhci_dove_register_fail;
+
 	host = platform_get_drvdata(pdev);
 	pltfm_host = sdhci_priv(host);
 	pltfm_host->priv = priv;
 
-	priv->clk = clk_get(&pdev->dev, NULL);
-	if (!IS_ERR(priv->clk))
-		clk_prepare_enable(priv->clk);
 	return 0;
 
-sdhci_dove_allocate_fail:
-	sdhci_pltfm_unregister(pdev);
 sdhci_dove_register_fail:
+	if (!IS_ERR(priv->clk)) {
+		clk_disable_unprepare(priv->clk);
+		clk_put(priv->clk);
+	}
 	return ret;
 }
 
@@ -117,14 +120,13 @@
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_dove_priv *priv = pltfm_host->priv;
 
-	if (priv->clk) {
-		if (!IS_ERR(priv->clk)) {
-			clk_disable_unprepare(priv->clk);
-			clk_put(priv->clk);
-		}
-		devm_kfree(&pdev->dev, priv->clk);
+	sdhci_pltfm_unregister(pdev);
+
+	if (!IS_ERR(priv->clk)) {
+		clk_disable_unprepare(priv->clk);
+		clk_put(priv->clk);
 	}
-	return sdhci_pltfm_unregister(pdev);
+	return 0;
 }
 
 static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = {
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index ae5fcbf..63d219f 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -169,6 +169,16 @@
 }
 #endif
 
+static void esdhc_of_platform_init(struct sdhci_host *host)
+{
+	u32 vvn;
+
+	vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
+	vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
+	if (vvn == VENDOR_V_22)
+		host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
+}
+
 static struct sdhci_ops sdhci_esdhc_ops = {
 	.read_l = esdhc_readl,
 	.read_w = esdhc_readw,
@@ -180,6 +190,7 @@
 	.enable_dma = esdhc_of_enable_dma,
 	.get_max_clock = esdhc_of_get_max_clock,
 	.get_min_clock = esdhc_of_get_min_clock,
+	.platform_init = esdhc_of_platform_init,
 #ifdef CONFIG_PM
 	.platform_suspend = esdhc_of_suspend,
 	.platform_resume = esdhc_of_resume,
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 4bb74b0..04936f3 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -1196,7 +1196,7 @@
 		return ERR_PTR(-ENODEV);
 	}
 
-	if (pci_resource_len(pdev, bar) != 0x100) {
+	if (pci_resource_len(pdev, bar) < 0x100) {
 		dev_err(&pdev->dev, "Invalid iomem size. You may "
 			"experience problems.\n");
 	}
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 65551a9..2716445 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -150,6 +150,13 @@
 		goto err_remap;
 	}
 
+	/*
+	 * Some platforms need to probe the controller to be able to
+	 * determine which caps should be used.
+	 */
+	if (host->ops && host->ops->platform_init)
+		host->ops->platform_init(host);
+
 	platform_set_drvdata(pdev, host);
 
 	return host;
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 2903949..a54dd5d 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -211,8 +211,8 @@
 	if (ourhost->cur_clk != best_src) {
 		struct clk *clk = ourhost->clk_bus[best_src];
 
-		clk_enable(clk);
-		clk_disable(ourhost->clk_bus[ourhost->cur_clk]);
+		clk_prepare_enable(clk);
+		clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
 
 		/* turn clock off to card before changing clock source */
 		writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
@@ -607,7 +607,7 @@
 	}
 
 	/* enable the local io clock and keep it running for the moment. */
-	clk_enable(sc->clk_io);
+	clk_prepare_enable(sc->clk_io);
 
 	for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
 		struct clk *clk;
@@ -638,7 +638,7 @@
 	}
 
 #ifndef CONFIG_PM_RUNTIME
-	clk_enable(sc->clk_bus[sc->cur_clk]);
+	clk_prepare_enable(sc->clk_bus[sc->cur_clk]);
 #endif
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -747,13 +747,14 @@
 		sdhci_s3c_setup_card_detect_gpio(sc);
 
 #ifdef CONFIG_PM_RUNTIME
-	clk_disable(sc->clk_io);
+	if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
+		clk_disable_unprepare(sc->clk_io);
 #endif
 	return 0;
 
  err_req_regs:
 #ifndef CONFIG_PM_RUNTIME
-	clk_disable(sc->clk_bus[sc->cur_clk]);
+	clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
 #endif
 	for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
 		if (sc->clk_bus[ptr]) {
@@ -762,7 +763,7 @@
 	}
 
  err_no_busclks:
-	clk_disable(sc->clk_io);
+	clk_disable_unprepare(sc->clk_io);
 	clk_put(sc->clk_io);
 
  err_io_clk:
@@ -794,7 +795,8 @@
 		gpio_free(sc->ext_cd_gpio);
 
 #ifdef CONFIG_PM_RUNTIME
-	clk_enable(sc->clk_io);
+	if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
+		clk_prepare_enable(sc->clk_io);
 #endif
 	sdhci_remove_host(host, 1);
 
@@ -802,14 +804,14 @@
 	pm_runtime_disable(&pdev->dev);
 
 #ifndef CONFIG_PM_RUNTIME
-	clk_disable(sc->clk_bus[sc->cur_clk]);
+	clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
 #endif
 	for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
 		if (sc->clk_bus[ptr]) {
 			clk_put(sc->clk_bus[ptr]);
 		}
 	}
-	clk_disable(sc->clk_io);
+	clk_disable_unprepare(sc->clk_io);
 	clk_put(sc->clk_io);
 
 	if (pdev->dev.of_node) {
@@ -849,8 +851,8 @@
 
 	ret = sdhci_runtime_suspend_host(host);
 
-	clk_disable(ourhost->clk_bus[ourhost->cur_clk]);
-	clk_disable(busclk);
+	clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
+	clk_disable_unprepare(busclk);
 	return ret;
 }
 
@@ -861,8 +863,8 @@
 	struct clk *busclk = ourhost->clk_io;
 	int ret;
 
-	clk_enable(busclk);
-	clk_enable(ourhost->clk_bus[ourhost->cur_clk]);
+	clk_prepare_enable(busclk);
+	clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]);
 	ret = sdhci_runtime_resume_host(host);
 	return ret;
 }
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 7922adb..c7851c0 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1315,16 +1315,19 @@
 		 */
 		if ((host->flags & SDHCI_NEEDS_RETUNING) &&
 		    !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
-			/* eMMC uses cmd21 while sd and sdio use cmd19 */
-			tuning_opcode = mmc->card->type == MMC_TYPE_MMC ?
-				MMC_SEND_TUNING_BLOCK_HS200 :
-				MMC_SEND_TUNING_BLOCK;
-			spin_unlock_irqrestore(&host->lock, flags);
-			sdhci_execute_tuning(mmc, tuning_opcode);
-			spin_lock_irqsave(&host->lock, flags);
+			if (mmc->card) {
+				/* eMMC uses cmd21 but sd and sdio use cmd19 */
+				tuning_opcode =
+					mmc->card->type == MMC_TYPE_MMC ?
+					MMC_SEND_TUNING_BLOCK_HS200 :
+					MMC_SEND_TUNING_BLOCK;
+				spin_unlock_irqrestore(&host->lock, flags);
+				sdhci_execute_tuning(mmc, tuning_opcode);
+				spin_lock_irqsave(&host->lock, flags);
 
-			/* Restore original mmc_request structure */
-			host->mrq = mrq;
+				/* Restore original mmc_request structure */
+				host->mrq = mrq;
+			}
 		}
 
 		if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
@@ -2837,6 +2840,9 @@
 	if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
 		mmc->caps |= MMC_CAP_4_BIT_DATA;
 
+	if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23)
+		mmc->caps &= ~MMC_CAP_CMD23;
+
 	if (caps[0] & SDHCI_CAN_DO_HISPD)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 
@@ -2846,9 +2852,12 @@
 
 	/* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
 	host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc");
-	if (IS_ERR(host->vqmmc)) {
-		pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc));
-		host->vqmmc = NULL;
+	if (IS_ERR_OR_NULL(host->vqmmc)) {
+		if (PTR_ERR(host->vqmmc) < 0) {
+			pr_info("%s: no vqmmc regulator found\n",
+				mmc_hostname(mmc));
+			host->vqmmc = NULL;
+		}
 	}
 	else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000))
 		regulator_enable(host->vqmmc);
@@ -2904,9 +2913,12 @@
 	ocr_avail = 0;
 
 	host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
-	if (IS_ERR(host->vmmc)) {
-		pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
-		host->vmmc = NULL;
+	if (IS_ERR_OR_NULL(host->vmmc)) {
+		if (PTR_ERR(host->vmmc) < 0) {
+			pr_info("%s: no vmmc regulator found\n",
+				mmc_hostname(mmc));
+			host->vmmc = NULL;
+		}
 	} else
 		regulator_enable(host->vmmc);
 
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 97653ea..71a4a7ed 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -278,6 +278,7 @@
 	void	(*hw_reset)(struct sdhci_host *host);
 	void	(*platform_suspend)(struct sdhci_host *host);
 	void	(*platform_resume)(struct sdhci_host *host);
+	void	(*platform_init)(struct sdhci_host *host);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 11d2bc3..d25bc97 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1466,9 +1466,9 @@
 
 	platform_set_drvdata(pdev, NULL);
 
+	clk_disable(host->hclk);
 	mmc_free_host(host->mmc);
 	pm_runtime_put_sync(&pdev->dev);
-	clk_disable(host->hclk);
 	pm_runtime_disable(&pdev->dev);
 
 	return 0;
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 2e47c2e..df30486 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -324,13 +324,6 @@
 	  This enables access to the flash chips on the Hitachi SolutionEngine and
 	  similar boards. Say 'Y' if you are building a kernel for such a board.
 
-config MTD_CDB89712
-	tristate "Cirrus CDB89712 evaluation board mappings"
-	depends on MTD_CFI && ARCH_CDB89712
-	help
-	  This enables access to the flash or ROM chips on the CDB89712 board.
-	  If you have such a board, say 'Y'.
-
 config MTD_SA1100
 	tristate "CFI Flash device mapped on StrongARM SA11x0"
 	depends on MTD_CFI && ARCH_SA1100
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index deb43e9..a0240ed 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -7,7 +7,6 @@
 endif
 
 # Chip mappings
-obj-$(CONFIG_MTD_CDB89712)	+= cdb89712.o
 obj-$(CONFIG_MTD_CFI_FLAGADM)	+= cfi_flagadm.o
 obj-$(CONFIG_MTD_DC21285)	+= dc21285.o
 obj-$(CONFIG_MTD_DILNETPC)	+= dilnetpc.o
diff --git a/drivers/mtd/maps/cdb89712.c b/drivers/mtd/maps/cdb89712.c
deleted file mode 100644
index c29cbf8..0000000
--- a/drivers/mtd/maps/cdb89712.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Flash on Cirrus CDB89712
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <mach/hardware.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-/* dynamic ioremap() areas */
-#define FLASH_START      0x00000000
-#define FLASH_SIZE       0x800000
-#define FLASH_WIDTH      4
-
-#define SRAM_START       0x60000000
-#define SRAM_SIZE        0xc000
-#define SRAM_WIDTH       4
-
-#define BOOTROM_START    0x70000000
-#define BOOTROM_SIZE     0x80
-#define BOOTROM_WIDTH    4
-
-
-static struct mtd_info *flash_mtd;
-
-struct map_info cdb89712_flash_map = {
-	.name = "flash",
-	.size = FLASH_SIZE,
-	.bankwidth = FLASH_WIDTH,
-	.phys = FLASH_START,
-};
-
-struct resource cdb89712_flash_resource = {
-	.name =   "Flash",
-	.start =  FLASH_START,
-	.end =    FLASH_START + FLASH_SIZE - 1,
-	.flags =  IORESOURCE_IO | IORESOURCE_BUSY,
-};
-
-static int __init init_cdb89712_flash (void)
-{
-	int err;
-
-	if (request_resource (&ioport_resource, &cdb89712_flash_resource)) {
-		printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n");
-		err = -EBUSY;
-		goto out;
-	}
-
-	cdb89712_flash_map.virt = ioremap(FLASH_START, FLASH_SIZE);
-	if (!cdb89712_flash_map.virt) {
-		printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n");
-		err = -EIO;
-		goto out_resource;
-	}
-	simple_map_init(&cdb89712_flash_map);
-	flash_mtd = do_map_probe("cfi_probe", &cdb89712_flash_map);
-	if (!flash_mtd) {
-		flash_mtd = do_map_probe("map_rom", &cdb89712_flash_map);
-		if (flash_mtd)
-			flash_mtd->erasesize = 0x10000;
-	}
-	if (!flash_mtd) {
-		printk("FLASH probe failed\n");
-		err = -ENXIO;
-		goto out_ioremap;
-	}
-
-	flash_mtd->owner = THIS_MODULE;
-
-	if (mtd_device_register(flash_mtd, NULL, 0)) {
-		printk("FLASH device addition failed\n");
-		err = -ENOMEM;
-		goto out_probe;
-	}
-
-	return 0;
-
-out_probe:
-	map_destroy(flash_mtd);
-	flash_mtd = 0;
-out_ioremap:
-	iounmap((void *)cdb89712_flash_map.virt);
-out_resource:
-	release_resource (&cdb89712_flash_resource);
-out:
-	return err;
-}
-
-
-
-
-
-static struct mtd_info *sram_mtd;
-
-struct map_info cdb89712_sram_map = {
-	.name = "SRAM",
-	.size = SRAM_SIZE,
-	.bankwidth = SRAM_WIDTH,
-	.phys = SRAM_START,
-};
-
-struct resource cdb89712_sram_resource = {
-	.name =   "SRAM",
-	.start =  SRAM_START,
-	.end =    SRAM_START + SRAM_SIZE - 1,
-	.flags =  IORESOURCE_IO | IORESOURCE_BUSY,
-};
-
-static int __init init_cdb89712_sram (void)
-{
-	int err;
-
-	if (request_resource (&ioport_resource, &cdb89712_sram_resource)) {
-		printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n");
-		err = -EBUSY;
-		goto out;
-	}
-
-	cdb89712_sram_map.virt = ioremap(SRAM_START, SRAM_SIZE);
-	if (!cdb89712_sram_map.virt) {
-		printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n");
-		err = -EIO;
-		goto out_resource;
-	}
-	simple_map_init(&cdb89712_sram_map);
-	sram_mtd = do_map_probe("map_ram", &cdb89712_sram_map);
-	if (!sram_mtd) {
-		printk("SRAM probe failed\n");
-		err = -ENXIO;
-		goto out_ioremap;
-	}
-
-	sram_mtd->owner = THIS_MODULE;
-	sram_mtd->erasesize = 16;
-
-	if (mtd_device_register(sram_mtd, NULL, 0)) {
-		printk("SRAM device addition failed\n");
-		err = -ENOMEM;
-		goto out_probe;
-	}
-
-	return 0;
-
-out_probe:
-	map_destroy(sram_mtd);
-	sram_mtd = 0;
-out_ioremap:
-	iounmap((void *)cdb89712_sram_map.virt);
-out_resource:
-	release_resource (&cdb89712_sram_resource);
-out:
-	return err;
-}
-
-
-
-
-
-
-
-static struct mtd_info *bootrom_mtd;
-
-struct map_info cdb89712_bootrom_map = {
-	.name = "BootROM",
-	.size = BOOTROM_SIZE,
-	.bankwidth = BOOTROM_WIDTH,
-	.phys = BOOTROM_START,
-};
-
-struct resource cdb89712_bootrom_resource = {
-	.name =   "BootROM",
-	.start =  BOOTROM_START,
-	.end =    BOOTROM_START + BOOTROM_SIZE - 1,
-	.flags =  IORESOURCE_IO | IORESOURCE_BUSY,
-};
-
-static int __init init_cdb89712_bootrom (void)
-{
-	int err;
-
-	if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) {
-		printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n");
-		err = -EBUSY;
-		goto out;
-	}
-
-	cdb89712_bootrom_map.virt = ioremap(BOOTROM_START, BOOTROM_SIZE);
-	if (!cdb89712_bootrom_map.virt) {
-		printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n");
-		err = -EIO;
-		goto out_resource;
-	}
-	simple_map_init(&cdb89712_bootrom_map);
-	bootrom_mtd = do_map_probe("map_rom", &cdb89712_bootrom_map);
-	if (!bootrom_mtd) {
-		printk("BootROM probe failed\n");
-		err = -ENXIO;
-		goto out_ioremap;
-	}
-
-	bootrom_mtd->owner = THIS_MODULE;
-	bootrom_mtd->erasesize = 0x10000;
-
-	if (mtd_device_register(bootrom_mtd, NULL, 0)) {
-		printk("BootROM device addition failed\n");
-		err = -ENOMEM;
-		goto out_probe;
-	}
-
-	return 0;
-
-out_probe:
-	map_destroy(bootrom_mtd);
-	bootrom_mtd = 0;
-out_ioremap:
-	iounmap((void *)cdb89712_bootrom_map.virt);
-out_resource:
-	release_resource (&cdb89712_bootrom_resource);
-out:
-	return err;
-}
-
-
-
-
-
-static int __init init_cdb89712_maps(void)
-{
-
-       	printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n  Flash 0x%x at 0x%x\n  SRAM 0x%x at 0x%x\n  BootROM 0x%x at 0x%x\n",
-	       FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START);
-
-	init_cdb89712_flash();
-	init_cdb89712_sram();
-	init_cdb89712_bootrom();
-
-	return 0;
-}
-
-
-static void __exit cleanup_cdb89712_maps(void)
-{
-	if (sram_mtd) {
-		mtd_device_unregister(sram_mtd);
-		map_destroy(sram_mtd);
-		iounmap((void *)cdb89712_sram_map.virt);
-		release_resource (&cdb89712_sram_resource);
-	}
-
-	if (flash_mtd) {
-		mtd_device_unregister(flash_mtd);
-		map_destroy(flash_mtd);
-		iounmap((void *)cdb89712_flash_map.virt);
-		release_resource (&cdb89712_flash_resource);
-	}
-
-	if (bootrom_mtd) {
-		mtd_device_unregister(bootrom_mtd);
-		map_destroy(bootrom_mtd);
-		iounmap((void *)cdb89712_bootrom_map.virt);
-		release_resource (&cdb89712_bootrom_resource);
-	}
-}
-
-module_init(init_cdb89712_maps);
-module_exit(cleanup_cdb89712_maps);
-
-MODULE_AUTHOR("Ray L");
-MODULE_DESCRIPTION("ARM CDB89712 map driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 4883139..531807d 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -49,13 +49,6 @@
 	  NAND chips (page size 256 byte, erase size 4-8KiB). The IDs
 	  of these chips were reused by later, larger chips.
 
-config MTD_NAND_AUTCPU12
-	tristate "SmartMediaCard on autronix autcpu12 board"
-	depends on ARCH_AUTCPU12
-	help
-	  This enables the driver for the autronix autcpu12 board to
-	  access the SmartMediaCard.
-
 config MTD_NAND_DENALI
        depends on PCI
         tristate "Support Denali NAND controller on Intel Moorestown"
@@ -86,12 +79,6 @@
 	help
 	  This enables a GPIO based NAND flash driver.
 
-config MTD_NAND_SPIA
-	tristate "NAND Flash device on SPIA board"
-	depends on ARCH_P720T
-	help
-	  If you had to ask, you don't have one. Say 'N'.
-
 config MTD_NAND_AMS_DELTA
 	tristate "NAND Flash device on Amstrad E3"
 	depends on MACH_AMS_DELTA
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 2cbd091..6c7f2b3 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -9,9 +9,7 @@
 obj-$(CONFIG_MTD_SM_COMMON) 		+= sm_common.o
 
 obj-$(CONFIG_MTD_NAND_CAFE)		+= cafe_nand.o
-obj-$(CONFIG_MTD_NAND_SPIA)		+= spia.o
 obj-$(CONFIG_MTD_NAND_AMS_DELTA)	+= ams-delta.o
-obj-$(CONFIG_MTD_NAND_AUTCPU12)		+= autcpu12.o
 obj-$(CONFIG_MTD_NAND_DENALI)		+= denali.o
 obj-$(CONFIG_MTD_NAND_AU1550)		+= au1550nd.o
 obj-$(CONFIG_MTD_NAND_BF5XX)		+= bf5xx_nand.o
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
deleted file mode 100644
index 04769a4..0000000
--- a/drivers/mtd/nand/autcpu12.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- *  drivers/mtd/autcpu12.c
- *
- *  Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
- *
- *  Derived from drivers/mtd/spia.c
- *	 Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  Overview:
- *   This is a device driver for the NAND flash device found on the
- *   autronix autcpu12 board, which is a SmartMediaCard. It supports
- *   16MiB, 32MiB and 64MiB cards.
- *
- *
- *	02-12-2002 TG	Cleanup of module params
- *
- *	02-20-2002 TG	adjusted for different rd/wr address support
- *			added support for read device ready/busy line
- *			added page_cache
- *
- *	10-06-2002 TG	128K card support added
- */
-
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <mach/hardware.h>
-#include <asm/sizes.h>
-#include <mach/autcpu12.h>
-
-/*
- * MTD structure for AUTCPU12 board
- */
-static struct mtd_info *autcpu12_mtd = NULL;
-static void __iomem *autcpu12_fio_base;
-
-/*
- * Define partitions for flash devices
- */
-static struct mtd_partition partition_info16k[] = {
-	{ .name		= "AUTCPU12 flash partition 1",
-	  .offset	= 0,
-	  .size		= 8 * SZ_1M },
-	{ .name		= "AUTCPU12 flash partition 2",
-	  .offset	= 8 * SZ_1M,
-	  .size		= 8 * SZ_1M },
-};
-
-static struct mtd_partition partition_info32k[] = {
-	{ .name		= "AUTCPU12 flash partition 1",
-	  .offset	= 0,
-	  .size		= 8 * SZ_1M },
-	{ .name		= "AUTCPU12 flash partition 2",
-	  .offset	= 8 * SZ_1M,
-	  .size		= 24 * SZ_1M },
-};
-
-static struct mtd_partition partition_info64k[] = {
-	{ .name		= "AUTCPU12 flash partition 1",
-	  .offset	= 0,
-	  .size		= 16 * SZ_1M },
-	{ .name		= "AUTCPU12 flash partition 2",
-	  .offset	= 16 * SZ_1M,
-	  .size		= 48 * SZ_1M },
-};
-
-static struct mtd_partition partition_info128k[] = {
-	{ .name		= "AUTCPU12 flash partition 1",
-	  .offset	= 0,
-	  .size		= 16 * SZ_1M },
-	{ .name		= "AUTCPU12 flash partition 2",
-	  .offset	= 16 * SZ_1M,
-	  .size		= 112 * SZ_1M },
-};
-
-#define NUM_PARTITIONS16K 2
-#define NUM_PARTITIONS32K 2
-#define NUM_PARTITIONS64K 2
-#define NUM_PARTITIONS128K 2
-/*
- *	hardware specific access to control-lines
- *
- *	ALE bit 4 autcpu12_pedr
- *	CLE bit 5 autcpu12_pedr
- *	NCE bit 0 fio_ctrl
- *
- */
-static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd,
-			       unsigned int ctrl)
-{
-	struct nand_chip *chip = mtd->priv;
-
-	if (ctrl & NAND_CTRL_CHANGE) {
-		void __iomem *addr;
-		unsigned char bits;
-
-		bits = clps_readb(AUTCPU12_SMC_PORT_OFFSET) & ~0x30;
-		bits |= (ctrl & NAND_CLE) << 4;
-		bits |= (ctrl & NAND_ALE) << 2;
-		clps_writeb(bits, AUTCPU12_SMC_PORT_OFFSET);
-
-		addr = autcpu12_fio_base + AUTCPU12_SMC_SELECT_OFFSET;
-		writeb((readb(addr) & ~0x1) | (ctrl & NAND_NCE), addr);
-	}
-
-	if (cmd != NAND_CMD_NONE)
-		writeb(cmd, chip->IO_ADDR_W);
-}
-
-/*
- *	read device ready pin
- */
-int autcpu12_device_ready(struct mtd_info *mtd)
-{
-	return clps_readb(AUTCPU12_SMC_PORT_OFFSET) & AUTCPU12_SMC_RDY;
-}
-
-/*
- * Main initialization routine
- */
-static int __init autcpu12_init(void)
-{
-	struct nand_chip *this;
-	int err = 0;
-
-	/* Allocate memory for MTD device structure and private data */
-	autcpu12_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip),
-			       GFP_KERNEL);
-	if (!autcpu12_mtd) {
-		printk("Unable to allocate AUTCPU12 NAND MTD device structure.\n");
-		err = -ENOMEM;
-		goto out;
-	}
-
-	/* map physical address */
-	autcpu12_fio_base = ioremap(AUTCPU12_PHYS_SMC, SZ_1K);
-	if (!autcpu12_fio_base) {
-		printk("Ioremap autcpu12 SmartMedia Card failed\n");
-		err = -EIO;
-		goto out_mtd;
-	}
-
-	/* Get pointer to private data */
-	this = (struct nand_chip *)(&autcpu12_mtd[1]);
-
-	/* Initialize structures */
-	memset(autcpu12_mtd, 0, sizeof(struct mtd_info));
-	memset(this, 0, sizeof(struct nand_chip));
-
-	/* Link the private data with the MTD structure */
-	autcpu12_mtd->priv = this;
-	autcpu12_mtd->owner = THIS_MODULE;
-
-	/* Set address of NAND IO lines */
-	this->IO_ADDR_R = autcpu12_fio_base;
-	this->IO_ADDR_W = autcpu12_fio_base;
-	this->cmd_ctrl = autcpu12_hwcontrol;
-	this->dev_ready = autcpu12_device_ready;
-	/* 20 us command delay time */
-	this->chip_delay = 20;
-	this->ecc.mode = NAND_ECC_SOFT;
-
-	/* Enable the following for a flash based bad block table */
-	/*
-	   this->bbt_options = NAND_BBT_USE_FLASH;
-	 */
-	this->bbt_options = NAND_BBT_USE_FLASH;
-
-	/* Scan to find existence of the device */
-	if (nand_scan(autcpu12_mtd, 1)) {
-		err = -ENXIO;
-		goto out_ior;
-	}
-
-	/* Register the partitions */
-	switch (autcpu12_mtd->size) {
-		case SZ_16M:
-			mtd_device_register(autcpu12_mtd, partition_info16k,
-					    NUM_PARTITIONS16K);
-			break;
-		case SZ_32M:
-			mtd_device_register(autcpu12_mtd, partition_info32k,
-					    NUM_PARTITIONS32K);
-			break;
-		case SZ_64M:
-			mtd_device_register(autcpu12_mtd, partition_info64k,
-					    NUM_PARTITIONS64K);
-			break;
-		case SZ_128M:
-			mtd_device_register(autcpu12_mtd, partition_info128k,
-					    NUM_PARTITIONS128K);
-			break;
-		default:
-			printk("Unsupported SmartMedia device\n");
-			err = -ENXIO;
-			goto out_ior;
-	}
-	goto out;
-
- out_ior:
-	iounmap(autcpu12_fio_base);
- out_mtd:
-	kfree(autcpu12_mtd);
- out:
-	return err;
-}
-
-module_init(autcpu12_init);
-
-/*
- * Clean up routine
- */
-static void __exit autcpu12_cleanup(void)
-{
-	/* Release resources, unregister device */
-	nand_release(autcpu12_mtd);
-
-	/* unmap physical address */
-	iounmap(autcpu12_fio_base);
-
-	/* Free the MTD device structure */
-	kfree(autcpu12_mtd);
-}
-
-module_exit(autcpu12_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
-MODULE_DESCRIPTION("Glue layer for SmartMediaCard on autronix autcpu12");
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 72e31d8..022dcdc 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -37,15 +37,9 @@
 
 #include <asm/mach/flash.h>
 #include <linux/platform_data/mtd-mxc_nand.h>
-#include <mach/hardware.h>
 
 #define DRIVER_NAME "mxc_nand"
 
-#define nfc_is_v21()		(cpu_is_mx25() || cpu_is_mx35())
-#define nfc_is_v1()		(cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
-#define nfc_is_v3_2a()		cpu_is_mx51()
-#define nfc_is_v3_2b()		cpu_is_mx53()
-
 /* Addresses for NFC registers */
 #define NFC_V1_V2_BUF_SIZE		(host->regs + 0x00)
 #define NFC_V1_V2_BUF_ADDR		(host->regs + 0x04)
@@ -1283,6 +1277,53 @@
 	.ppb_shift = 8,
 };
 
+static inline int is_imx21_nfc(struct mxc_nand_host *host)
+{
+	return host->devtype_data == &imx21_nand_devtype_data;
+}
+
+static inline int is_imx27_nfc(struct mxc_nand_host *host)
+{
+	return host->devtype_data == &imx27_nand_devtype_data;
+}
+
+static inline int is_imx25_nfc(struct mxc_nand_host *host)
+{
+	return host->devtype_data == &imx25_nand_devtype_data;
+}
+
+static inline int is_imx51_nfc(struct mxc_nand_host *host)
+{
+	return host->devtype_data == &imx51_nand_devtype_data;
+}
+
+static inline int is_imx53_nfc(struct mxc_nand_host *host)
+{
+	return host->devtype_data == &imx53_nand_devtype_data;
+}
+
+static struct platform_device_id mxcnd_devtype[] = {
+	{
+		.name = "imx21-nand",
+		.driver_data = (kernel_ulong_t) &imx21_nand_devtype_data,
+	}, {
+		.name = "imx27-nand",
+		.driver_data = (kernel_ulong_t) &imx27_nand_devtype_data,
+	}, {
+		.name = "imx25-nand",
+		.driver_data = (kernel_ulong_t) &imx25_nand_devtype_data,
+	}, {
+		.name = "imx51-nand",
+		.driver_data = (kernel_ulong_t) &imx51_nand_devtype_data,
+	}, {
+		.name = "imx53-nand",
+		.driver_data = (kernel_ulong_t) &imx53_nand_devtype_data,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, mxcnd_devtype);
+
 #ifdef CONFIG_OF_MTD
 static const struct of_device_id mxcnd_dt_ids[] = {
 	{
@@ -1337,32 +1378,6 @@
 }
 #endif
 
-static int __init mxcnd_probe_pdata(struct mxc_nand_host *host)
-{
-	struct mxc_nand_platform_data *pdata = host->dev->platform_data;
-
-	if (!pdata)
-		return -ENODEV;
-
-	host->pdata = *pdata;
-
-	if (nfc_is_v1()) {
-		if (cpu_is_mx21())
-			host->devtype_data = &imx21_nand_devtype_data;
-		else
-			host->devtype_data = &imx27_nand_devtype_data;
-	} else if (nfc_is_v21()) {
-		host->devtype_data = &imx25_nand_devtype_data;
-	} else if (nfc_is_v3_2a()) {
-		host->devtype_data = &imx51_nand_devtype_data;
-	} else if (nfc_is_v3_2b()) {
-		host->devtype_data = &imx53_nand_devtype_data;
-	} else
-		BUG();
-
-	return 0;
-}
-
 static int __devinit mxcnd_probe(struct platform_device *pdev)
 {
 	struct nand_chip *this;
@@ -1404,8 +1419,16 @@
 		return PTR_ERR(host->clk);
 
 	err = mxcnd_probe_dt(host);
-	if (err > 0)
-		err = mxcnd_probe_pdata(host);
+	if (err > 0) {
+		struct mxc_nand_platform_data *pdata = pdev->dev.platform_data;
+		if (pdata) {
+			host->pdata = *pdata;
+			host->devtype_data = (struct mxc_nand_devtype_data *)
+						pdev->id_entry->driver_data;
+		} else {
+			err = -ENODEV;
+		}
+	}
 	if (err < 0)
 		return err;
 
@@ -1494,7 +1517,7 @@
 	}
 
 	/* first scan to find the device and get the page size */
-	if (nand_scan_ident(mtd, nfc_is_v21() ? 4 : 1, NULL)) {
+	if (nand_scan_ident(mtd, is_imx25_nfc(host) ? 4 : 1, NULL)) {
 		err = -ENXIO;
 		goto escan;
 	}
@@ -1508,7 +1531,7 @@
 		this->ecc.layout = host->devtype_data->ecclayout_4k;
 
 	if (this->ecc.mode == NAND_ECC_HW) {
-		if (nfc_is_v1())
+		if (is_imx21_nfc(host) || is_imx27_nfc(host))
 			this->ecc.strength = 1;
 		else
 			this->ecc.strength = (host->eccsize == 4) ? 4 : 8;
@@ -1555,6 +1578,7 @@
 		   .owner = THIS_MODULE,
 		   .of_match_table = of_match_ptr(mxcnd_dt_ids),
 	},
+	.id_table = mxcnd_devtype,
 	.probe = mxcnd_probe,
 	.remove = __devexit_p(mxcnd_remove),
 };
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c
deleted file mode 100644
index bef76cd..0000000
--- a/drivers/mtd/nand/spia.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- *  drivers/mtd/nand/spia.c
- *
- *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- *
- *
- *	10-29-2001 TG	change to support hardwarespecific access
- *			to controllines	(due to change in nand.c)
- *			page_cache added
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  Overview:
- *   This is a device driver for the NAND flash device found on the
- *   SPIA board which utilizes the Toshiba TC58V64AFT part. This is
- *   a 64Mibit (8MiB x 8 bits) NAND flash device.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-
-/*
- * MTD structure for SPIA board
- */
-static struct mtd_info *spia_mtd = NULL;
-
-/*
- * Values specific to the SPIA board (used with EP7212 processor)
- */
-#define SPIA_IO_BASE	0xd0000000	/* Start of EP7212 IO address space */
-#define SPIA_FIO_BASE	0xf0000000	/* Address where flash is mapped */
-#define SPIA_PEDR	0x0080	/*
-				 * IO offset to Port E data register
-				 * where the CLE, ALE and NCE pins
-				 * are wired to.
-				 */
-#define SPIA_PEDDR	0x00c0	/*
-				 * IO offset to Port E data direction
-				 * register so we can control the IO
-				 * lines.
-				 */
-
-/*
- * Module stuff
- */
-
-static int spia_io_base = SPIA_IO_BASE;
-static int spia_fio_base = SPIA_FIO_BASE;
-static int spia_pedr = SPIA_PEDR;
-static int spia_peddr = SPIA_PEDDR;
-
-module_param(spia_io_base, int, 0);
-module_param(spia_fio_base, int, 0);
-module_param(spia_pedr, int, 0);
-module_param(spia_peddr, int, 0);
-
-/*
- * Define partitions for flash device
- */
-static const struct mtd_partition partition_info[] = {
-	{
-	 .name = "SPIA flash partition 1",
-	 .offset = 0,
-	 .size = 2 * 1024 * 1024},
-	{
-	 .name = "SPIA flash partition 2",
-	 .offset = 2 * 1024 * 1024,
-	 .size = 6 * 1024 * 1024}
-};
-
-#define NUM_PARTITIONS 2
-
-/*
- *	hardware specific access to control-lines
- *
- *	ctrl:
- *	NAND_CNE: bit 0 -> bit 2
- *	NAND_CLE: bit 1 -> bit 0
- *	NAND_ALE: bit 2 -> bit 1
- */
-static void spia_hwcontrol(struct mtd_info *mtd, int cmd)
-{
-	struct nand_chip *chip = mtd->priv;
-
-	if (ctrl & NAND_CTRL_CHANGE) {
-		void __iomem *addr = spia_io_base + spia_pedr;
-		unsigned char bits;
-
-		bits = (ctrl & NAND_CNE) << 2;
-		bits |= (ctrl & NAND_CLE | NAND_ALE) >> 1;
-		writeb((readb(addr) & ~0x7) | bits, addr);
-	}
-
-	if (cmd != NAND_CMD_NONE)
-		writeb(cmd, chip->IO_ADDR_W);
-}
-
-/*
- * Main initialization routine
- */
-static int __init spia_init(void)
-{
-	struct nand_chip *this;
-
-	/* Allocate memory for MTD device structure and private data */
-	spia_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
-	if (!spia_mtd) {
-		printk("Unable to allocate SPIA NAND MTD device structure.\n");
-		return -ENOMEM;
-	}
-
-	/* Get pointer to private data */
-	this = (struct nand_chip *)(&spia_mtd[1]);
-
-	/* Initialize structures */
-	memset(spia_mtd, 0, sizeof(struct mtd_info));
-	memset(this, 0, sizeof(struct nand_chip));
-
-	/* Link the private data with the MTD structure */
-	spia_mtd->priv = this;
-	spia_mtd->owner = THIS_MODULE;
-
-	/*
-	 * Set GPIO Port E control register so that the pins are configured
-	 * to be outputs for controlling the NAND flash.
-	 */
-	(*(volatile unsigned char *)(spia_io_base + spia_peddr)) = 0x07;
-
-	/* Set address of NAND IO lines */
-	this->IO_ADDR_R = (void __iomem *)spia_fio_base;
-	this->IO_ADDR_W = (void __iomem *)spia_fio_base;
-	/* Set address of hardware control function */
-	this->cmd_ctrl = spia_hwcontrol;
-	/* 15 us command delay time */
-	this->chip_delay = 15;
-
-	/* Scan to find existence of the device */
-	if (nand_scan(spia_mtd, 1)) {
-		kfree(spia_mtd);
-		return -ENXIO;
-	}
-
-	/* Register the partitions */
-	mtd_device_register(spia_mtd, partition_info, NUM_PARTITIONS);
-
-	/* Return happy */
-	return 0;
-}
-
-module_init(spia_init);
-
-/*
- * Clean up routine
- */
-static void __exit spia_cleanup(void)
-{
-	/* Release resources, unregister device */
-	nand_release(spia_mtd);
-
-	/* Free the MTD device structure */
-	kfree(spia_mtd);
-}
-
-module_exit(spia_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com");
-MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on SPIA board");
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index dc15d24..ef8d2a0 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1060,7 +1060,7 @@
 		goto out;
 	}
 
-	sscanf(buf, "%16s", ifname); /* IFNAMSIZ */
+	sscanf(buf, "%15s", ifname); /* IFNAMSIZ */
 
 	/* check to see if we are clearing primary */
 	if (!strlen(ifname) || buf[0] == '\n') {
@@ -1237,7 +1237,7 @@
 		goto out;
 	}
 
-	sscanf(buf, "%16s", ifname); /* IFNAMSIZ */
+	sscanf(buf, "%15s", ifname); /* IFNAMSIZ */
 
 	/* check to see if we are clearing active */
 	if (!strlen(ifname) || buf[0] == '\n') {
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index c78ecfc..a412bf6 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -144,9 +144,22 @@
 
 #define FLEXCAN_MB_CODE_MASK		(0xf0ffffff)
 
-/* FLEXCAN hardware feature flags */
+/*
+ * FLEXCAN hardware feature flags
+ *
+ * Below is some version info we got:
+ *    SOC   Version   IP-Version  Glitch-  [TR]WRN_INT
+ *                                Filter?   connected?
+ *   MX25  FlexCAN2  03.00.00.00     no         no
+ *   MX28  FlexCAN2  03.00.04.00    yes        yes
+ *   MX35  FlexCAN2  03.00.00.00     no         no
+ *   MX53  FlexCAN2  03.00.00.00    yes         no
+ *   MX6s  FlexCAN3  10.00.12.00    yes        yes
+ *
+ * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
+ */
 #define FLEXCAN_HAS_V10_FEATURES	BIT(1) /* For core version >= 10 */
-#define FLEXCAN_HAS_BROKEN_ERR_STATE	BIT(2) /* Broken error state handling */
+#define FLEXCAN_HAS_BROKEN_ERR_STATE	BIT(2) /* [TR]WRN_INT not connected */
 
 /* Structure of the message buffer */
 struct flexcan_mb {
@@ -205,7 +218,7 @@
 };
 static struct flexcan_devtype_data fsl_imx28_devtype_data;
 static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
-	.features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_BROKEN_ERR_STATE,
+	.features = FLEXCAN_HAS_V10_FEATURES,
 };
 
 static const struct can_bittiming_const flexcan_bittiming_const = {
diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c
index f5b82ae..6525dbc 100644
--- a/drivers/net/can/sja1000/peak_pci.c
+++ b/drivers/net/can/sja1000/peak_pci.c
@@ -30,9 +30,10 @@
 
 #include "sja1000.h"
 
-MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>");
 MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCI family cards");
 MODULE_SUPPORTED_DEVICE("PEAK PCAN PCI/PCIe/PCIeC miniPCI CAN cards");
+MODULE_SUPPORTED_DEVICE("PEAK PCAN miniPCIe/cPCI PC/104+ PCI/104e CAN Cards");
 MODULE_LICENSE("GPL v2");
 
 #define DRV_NAME  "peak_pci"
@@ -64,7 +65,11 @@
 #define PEAK_PCI_DEVICE_ID	0x0001	/* for PCI/PCIe slot cards */
 #define PEAK_PCIEC_DEVICE_ID	0x0002	/* for ExpressCard slot cards */
 #define PEAK_PCIE_DEVICE_ID	0x0003	/* for nextgen PCIe slot cards */
-#define PEAK_MPCI_DEVICE_ID	0x0008	/* The miniPCI slot cards */
+#define PEAK_CPCI_DEVICE_ID	0x0004	/* for nextgen cPCI slot cards */
+#define PEAK_MPCI_DEVICE_ID	0x0005	/* for nextgen miniPCI slot cards */
+#define PEAK_PC_104P_DEVICE_ID	0x0006	/* PCAN-PC/104+ cards */
+#define PEAK_PCI_104E_DEVICE_ID	0x0007	/* PCAN-PCI/104 Express cards */
+#define PEAK_MPCIE_DEVICE_ID	0x0008	/* The miniPCIe slot cards */
 
 #define PEAK_PCI_CHAN_MAX	4
 
@@ -76,6 +81,10 @@
 	{PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
 	{PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
 	{PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+	{PEAK_PCI_VENDOR_ID, PEAK_MPCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+	{PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+	{PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+	{PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
 #ifdef CONFIG_CAN_PEAK_PCIEC
 	{PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
 #endif
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index c65295d..6e5bdd1 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -1702,7 +1702,7 @@
 				      SHMEM_EEE_ADV_STATUS_SHIFT);
 	if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) {
 		DP(BNX2X_MSG_ETHTOOL,
-		   "Direct manipulation of EEE advertisment is not supported\n");
+		   "Direct manipulation of EEE advertisement is not supported\n");
 		return -EINVAL;
 	}
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index e2e45ee..f6cfdc6 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -137,7 +137,16 @@
 #define LINK_20GTFD		LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
 #define LINK_20GXFD		LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
 
-
+#define LINK_UPDATE_MASK \
+			(LINK_STATUS_SPEED_AND_DUPLEX_MASK | \
+			 LINK_STATUS_LINK_UP | \
+			 LINK_STATUS_PHYSICAL_LINK_FLAG | \
+			 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \
+			 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \
+			 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \
+			 LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \
+			 LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \
+			 LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
 
 #define SFP_EEPROM_CON_TYPE_ADDR		0x2
 	#define SFP_EEPROM_CON_TYPE_VAL_LC	0x7
@@ -3295,6 +3304,21 @@
 	       DEFAULT_PHY_DEV_ADDR);
 }
 
+static void bnx2x_xgxs_specific_func(struct bnx2x_phy *phy,
+				     struct link_params *params,
+				     u32 action)
+{
+	struct bnx2x *bp = params->bp;
+	switch (action) {
+	case PHY_INIT:
+		/* Set correct devad */
+		REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0);
+		REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
+		       phy->def_md_devad);
+		break;
+	}
+}
+
 static void bnx2x_xgxs_deassert(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
@@ -3309,10 +3333,8 @@
 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
 	udelay(500);
 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
-
-	REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
-	REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
-	       params->phy[INT_PHY].def_md_devad);
+	bnx2x_xgxs_specific_func(&params->phy[INT_PHY], params,
+				 PHY_INIT);
 }
 
 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
@@ -3545,14 +3567,11 @@
 static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
 					struct link_params *params,
 					struct link_vars *vars) {
-	u16 val16 = 0, lane, i;
+	u16 lane, i, cl72_ctrl, an_adv = 0;
+	u16 ucode_ver;
 	struct bnx2x *bp = params->bp;
 	static struct bnx2x_reg_set reg_set[] = {
 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
-		{MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0},
-		{MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0},
-		{MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff},
-		{MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555},
 		{MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0},
 		{MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415},
 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190},
@@ -3565,12 +3584,19 @@
 		bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
 				 reg_set[i].val);
 
+	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
+		MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl);
+	cl72_ctrl &= 0xf8ff;
+	cl72_ctrl |= 0x3800;
+	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+		MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl);
+
 	/* Check adding advertisement for 1G KX */
 	if (((vars->line_speed == SPEED_AUTO_NEG) &&
 	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
 	    (vars->line_speed == SPEED_1000)) {
 		u32 addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2;
-		val16 |= (1<<5);
+		an_adv |= (1<<5);
 
 		/* Enable CL37 1G Parallel Detect */
 		bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, addr, 0x1);
@@ -3580,11 +3606,14 @@
 	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
 	    (vars->line_speed ==  SPEED_10000)) {
 		/* Check adding advertisement for 10G KR */
-		val16 |= (1<<7);
+		an_adv |= (1<<7);
 		/* Enable 10G Parallel Detect */
+		CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
+				  MDIO_AER_BLOCK_AER_REG, 0);
+
 		bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
 				 MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
-
+		bnx2x_set_aer_mmd(params, phy);
 		DP(NETIF_MSG_LINK, "Advertize 10G\n");
 	}
 
@@ -3604,7 +3633,7 @@
 
 	/* Advertised speeds */
 	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
-			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
+			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv);
 
 	/* Advertised and set FEC (Forward Error Correction) */
 	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
@@ -3628,9 +3657,10 @@
 	/* Set KR Autoneg Work-Around flag for Warpcore version older than D108
 	 */
 	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
-			MDIO_WC_REG_UC_INFO_B1_VERSION, &val16);
-	if (val16 < 0xd108) {
-		DP(NETIF_MSG_LINK, "Enable AN KR work-around\n");
+			MDIO_WC_REG_UC_INFO_B1_VERSION, &ucode_ver);
+	if (ucode_ver < 0xd108) {
+		DP(NETIF_MSG_LINK, "Enable AN KR work-around. WC ver:0x%x\n",
+			       ucode_ver);
 		vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
 	}
 	bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
@@ -3651,21 +3681,16 @@
 				      struct link_vars *vars)
 {
 	struct bnx2x *bp = params->bp;
-	u16 i;
+	u16 val16, i, lane;
 	static struct bnx2x_reg_set reg_set[] = {
 		/* Disable Autoneg */
 		{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
-		{MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0},
 		{MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
 			0x3f00},
 		{MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0},
 		{MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0},
 		{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1},
 		{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa},
-		/* Disable CL36 PCS Tx */
-		{MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0},
-		/* Double Wide Single Data Rate @ pll rate */
-		{MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF},
 		/* Leave cl72 training enable, needed for KR */
 		{MDIO_PMA_DEVAD,
 		MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
@@ -3676,11 +3701,24 @@
 		bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
 				 reg_set[i].val);
 
-	/* Leave CL72 enabled */
-	bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
-				 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
-				 0x3800);
+	lane = bnx2x_get_warpcore_lane(phy, params);
+	/* Global registers */
+	CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
+			  MDIO_AER_BLOCK_AER_REG, 0);
+	/* Disable CL36 PCS Tx */
+	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
+			MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
+	val16 &= ~(0x0011 << lane);
+	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+			 MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
 
+	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
+			MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
+	val16 |= (0x0303 << (lane << 1));
+	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+			 MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
+	/* Restore AER */
+	bnx2x_set_aer_mmd(params, phy);
 	/* Set speed via PMA/PMD register */
 	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
@@ -4303,7 +4341,7 @@
 				      struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
-	u16 val16;
+	u16 val16, lane;
 	bnx2x_sfp_e3_set_transmitter(params, phy, 0);
 	bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
 	bnx2x_set_aer_mmd(params, phy);
@@ -4340,6 +4378,30 @@
 			 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
 			 val16 & 0xff00);
 
+	lane = bnx2x_get_warpcore_lane(phy, params);
+	/* Disable CL36 PCS Tx */
+	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
+			MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
+	val16 |= (0x11 << lane);
+	if (phy->flags & FLAGS_WC_DUAL_MODE)
+		val16 |= (0x22 << lane);
+	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+			 MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
+
+	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
+			MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
+	val16 &= ~(0x0303 << (lane << 1));
+	val16 |= (0x0101 << (lane << 1));
+	if (phy->flags & FLAGS_WC_DUAL_MODE) {
+		val16 &= ~(0x0c0c << (lane << 1));
+		val16 |= (0x0404 << (lane << 1));
+	}
+
+	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+			 MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
+	/* Restore AER */
+	bnx2x_set_aer_mmd(params, phy);
+
 }
 
 static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
@@ -6296,15 +6358,7 @@
 	vars->mac_type = MAC_TYPE_NONE;
 
 	/* Update shared memory */
-	vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
-			       LINK_STATUS_LINK_UP |
-			       LINK_STATUS_PHYSICAL_LINK_FLAG |
-			       LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
-			       LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
-			       LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
-			       LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK |
-			       LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE |
-			       LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE);
+	vars->link_status &= ~LINK_UPDATE_MASK;
 	vars->line_speed = 0;
 	bnx2x_update_mng(params, vars->link_status);
 
@@ -6452,6 +6506,7 @@
 	u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
 	u8 active_external_phy = INT_PHY;
 	vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
+	vars->link_status &= ~LINK_UPDATE_MASK;
 	for (phy_index = INT_PHY; phy_index < params->num_phys;
 	      phy_index++) {
 		phy_vars[phy_index].flow_ctrl = 0;
@@ -7579,7 +7634,7 @@
 static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
 						 struct link_params *params,
 						 u16 addr, u8 byte_cnt,
-						 u8 *o_buf)
+						 u8 *o_buf, u8 is_init)
 {
 	int rc = 0;
 	u8 i, j = 0, cnt = 0;
@@ -7596,10 +7651,10 @@
 	/* 4 byte aligned address */
 	addr32 = addr & (~0x3);
 	do {
-		if (cnt == I2C_WA_PWR_ITER) {
+		if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) {
 			bnx2x_warpcore_power_module(params, phy, 0);
 			/* Note that 100us are not enough here */
-			usleep_range(1000,1000);
+			usleep_range(1000, 2000);
 			bnx2x_warpcore_power_module(params, phy, 1);
 		}
 		rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
@@ -7719,7 +7774,7 @@
 	break;
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
 		rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr,
-							   byte_cnt, o_buf);
+							   byte_cnt, o_buf, 0);
 	break;
 	}
 	return rc;
@@ -7923,6 +7978,7 @@
 
 {
 	u8 val;
+	int rc;
 	struct bnx2x *bp = params->bp;
 	u16 timeout;
 	/* Initialization time after hot-plug may take up to 300ms for
@@ -7930,8 +7986,14 @@
 	 */
 
 	for (timeout = 0; timeout < 60; timeout++) {
-		if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
-		    == 0) {
+		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
+			rc = bnx2x_warpcore_read_sfp_module_eeprom(phy,
+								   params, 1,
+								   1, &val, 1);
+		else
+			rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1,
+							  &val);
+		if (rc == 0) {
 			DP(NETIF_MSG_LINK,
 			   "SFP+ module initialization took %d ms\n",
 			   timeout * 5);
@@ -7939,7 +8001,8 @@
 		}
 		usleep_range(5000, 10000);
 	}
-	return -EINVAL;
+	rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val);
+	return rc;
 }
 
 static void bnx2x_8727_power_module(struct bnx2x *bp,
@@ -9878,7 +9941,7 @@
 		else
 			rc = bnx2x_8483x_disable_eee(phy, params, vars);
 		if (rc) {
-			DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n");
+			DP(NETIF_MSG_LINK, "Failed to set EEE advertisement\n");
 			return rc;
 		}
 	} else {
@@ -10993,7 +11056,7 @@
 	.format_fw_ver	= (format_fw_ver_t)NULL,
 	.hw_reset	= (hw_reset_t)NULL,
 	.set_link_led	= (set_link_led_t)NULL,
-	.phy_specific_func = (phy_specific_func_t)NULL
+	.phy_specific_func = (phy_specific_func_t)bnx2x_xgxs_specific_func
 };
 static struct bnx2x_phy phy_warpcore = {
 	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
@@ -11465,6 +11528,11 @@
 			phy->media_type = ETH_PHY_BASE_T;
 			break;
 		case PORT_HW_CFG_NET_SERDES_IF_XFI:
+			phy->supported &= (SUPPORTED_1000baseT_Full |
+					   SUPPORTED_10000baseT_Full |
+					   SUPPORTED_FIBRE |
+					   SUPPORTED_Pause |
+					   SUPPORTED_Asym_Pause);
 			phy->media_type = ETH_PHY_XFP_FIBER;
 			break;
 		case PORT_HW_CFG_NET_SERDES_IF_SFI:
@@ -12919,7 +12987,7 @@
 		DP(NETIF_MSG_LINK, "Analyze TX Fault\n");
 		break;
 	default:
-		DP(NETIF_MSG_LINK, "Analyze UNKOWN\n");
+		DP(NETIF_MSG_LINK, "Analyze UNKNOWN\n");
 	}
 	DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up,
 	   old_status, status);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index d5648fc..bd1fd3d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -6794,8 +6794,9 @@
 
 	bnx2x_init_block(bp, BLOCK_DORQ, init_phase);
 
+	bnx2x_init_block(bp, BLOCK_BRB1, init_phase);
+
 	if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) {
-		bnx2x_init_block(bp, BLOCK_BRB1, init_phase);
 
 		if (IS_MF(bp))
 			low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246);
@@ -11902,7 +11903,15 @@
 	/* disable FCOE L2 queue for E1x */
 	if (CHIP_IS_E1x(bp))
 		bp->flags |= NO_FCOE_FLAG;
-
+	/* disable FCOE for 57840 device, until FW supports it */
+	switch (ent->driver_data) {
+	case BCM57840_O:
+	case BCM57840_4_10:
+	case BCM57840_2_20:
+	case BCM57840_MFO:
+	case BCM57840_MF:
+		bp->flags |= NO_FCOE_FLAG;
+	}
 #endif
 
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index a4da893..378988b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -251,6 +251,8 @@
 	unsigned char rev;                /* chip revision */
 	unsigned char offload;
 
+	unsigned char bypass;
+
 	unsigned int ofldq_wr_cred;
 };
 
@@ -642,6 +644,23 @@
 #define for_each_port(adapter, iter) \
 	for (iter = 0; iter < (adapter)->params.nports; ++iter)
 
+static inline int is_bypass(struct adapter *adap)
+{
+	return adap->params.bypass;
+}
+
+static inline int is_bypass_device(int device)
+{
+	/* this should be set based upon device capabilities */
+	switch (device) {
+	case 0x440b:
+	case 0x440c:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 static inline unsigned int core_ticks_per_usec(const struct adapter *adap)
 {
 	return adap->params.vpd.cclk / 1000;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 604f4f8..0df1284 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3416,16 +3416,6 @@
 			 finicsum, cfcsum);
 
 	/*
-	 * If we're a pure NIC driver then disable all offloading facilities.
-	 * This will allow the firmware to optimize aspects of the hardware
-	 * configuration which will result in improved performance.
-	 */
-	caps_cmd.ofldcaps = 0;
-	caps_cmd.iscsicaps = 0;
-	caps_cmd.rdmacaps = 0;
-	caps_cmd.fcoecaps = 0;
-
-	/*
 	 * And now tell the firmware to use the configuration we just loaded.
 	 */
 	caps_cmd.op_to_write =
@@ -3513,18 +3503,6 @@
 	if (ret < 0)
 		goto bye;
 
-#ifndef CONFIG_CHELSIO_T4_OFFLOAD
-	/*
-	 * If we're a pure NIC driver then disable all offloading facilities.
-	 * This will allow the firmware to optimize aspects of the hardware
-	 * configuration which will result in improved performance.
-	 */
-	caps_cmd.ofldcaps = 0;
-	caps_cmd.iscsicaps = 0;
-	caps_cmd.rdmacaps = 0;
-	caps_cmd.fcoecaps = 0;
-#endif
-
 	if (caps_cmd.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) {
 		if (!vf_acls)
 			caps_cmd.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM);
@@ -3745,6 +3723,7 @@
 	u32 v, port_vec;
 	enum dev_state state;
 	u32 params[7], val[7];
+	struct fw_caps_config_cmd caps_cmd;
 	int reset = 1, j;
 
 	/*
@@ -3898,6 +3877,9 @@
 			goto bye;
 	}
 
+	if (is_bypass_device(adap->pdev->device))
+		adap->params.bypass = 1;
+
 	/*
 	 * Grab some of our basic fundamental operating parameters.
 	 */
@@ -3940,13 +3922,12 @@
 		adap->tids.aftid_end = val[1];
 	}
 
-#ifdef CONFIG_CHELSIO_T4_OFFLOAD
 	/*
 	 * Get device capabilities so we can determine what resources we need
 	 * to manage.
 	 */
 	memset(&caps_cmd, 0, sizeof(caps_cmd));
-	caps_cmd.op_to_write = htonl(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+	caps_cmd.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
 				     FW_CMD_REQUEST | FW_CMD_READ);
 	caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd));
 	ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd),
@@ -3991,15 +3972,6 @@
 		adap->vres.ddp.size = val[4] - val[3] + 1;
 		adap->params.ofldq_wr_cred = val[5];
 
-		params[0] = FW_PARAM_PFVF(ETHOFLD_START);
-		params[1] = FW_PARAM_PFVF(ETHOFLD_END);
-		ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2,
-				      params, val);
-		if ((val[0] != val[1]) && (ret >= 0)) {
-			adap->tids.uotid_base = val[0];
-			adap->tids.nuotids = val[1] - val[0] + 1;
-		}
-
 		adap->params.offload = 1;
 	}
 	if (caps_cmd.rdmacaps) {
@@ -4048,7 +4020,6 @@
 	}
 #undef FW_PARAM_PFVF
 #undef FW_PARAM_DEV
-#endif /* CONFIG_CHELSIO_T4_OFFLOAD */
 
 	/*
 	 * These are finalized by FW initialization, load their values now.
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index 1b899fe..39bec73 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -102,6 +102,9 @@
 	unsigned int ftid_base;
 	unsigned int aftid_base;
 	unsigned int aftid_end;
+	/* Server filter region */
+	unsigned int sftid_base;
+	unsigned int nsftids;
 
 	spinlock_t atid_lock ____cacheline_aligned_in_smp;
 	union aopen_entry *afree;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 32eec15..730ae2c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -2519,6 +2519,7 @@
 {
 	struct fw_bye_cmd c;
 
+	memset(&c, 0, sizeof(c));
 	INIT_CMD(c, BYE, WRITE);
 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
 }
@@ -2535,6 +2536,7 @@
 {
 	struct fw_initialize_cmd c;
 
+	memset(&c, 0, sizeof(c));
 	INIT_CMD(c, INITIALIZE, WRITE);
 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
 }
@@ -2551,6 +2553,7 @@
 {
 	struct fw_reset_cmd c;
 
+	memset(&c, 0, sizeof(c));
 	INIT_CMD(c, RESET, WRITE);
 	c.val = htonl(reset);
 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
@@ -2828,7 +2831,7 @@
 		     HOSTPAGESIZEPF7(sge_hps));
 
 	t4_set_reg_field(adap, SGE_CONTROL,
-			 INGPADBOUNDARY(INGPADBOUNDARY_MASK) |
+			 INGPADBOUNDARY_MASK |
 			 EGRSTATUSPAGESIZE_MASK,
 			 INGPADBOUNDARY(fl_align_log - 5) |
 			 EGRSTATUSPAGESIZE(stat_len != 64));
@@ -3278,6 +3281,7 @@
 {
 	struct fw_vi_enable_cmd c;
 
+	memset(&c, 0, sizeof(c));
 	c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
 			     FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
 	c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c));
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 1d03dcd..19ac096 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -1353,8 +1353,11 @@
 	struct gfar_private *priv = dev_get_drvdata(dev);
 	struct net_device *ndev = priv->ndev;
 
-	if (!netif_running(ndev))
+	if (!netif_running(ndev)) {
+		netif_device_attach(ndev);
+
 		return 0;
+	}
 
 	gfar_init_bds(ndev);
 	init_registers(ndev);
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c
index b9db0e0..2e5daee 100644
--- a/drivers/net/ethernet/freescale/gianfar_ptp.c
+++ b/drivers/net/ethernet/freescale/gianfar_ptp.c
@@ -478,7 +478,7 @@
 		pr_err("no resource\n");
 		goto no_resource;
 	}
-	if (request_resource(&ioport_resource, etsects->rsrc)) {
+	if (request_resource(&iomem_resource, etsects->rsrc)) {
 		pr_err("resource busy\n");
 		goto no_resource;
 	}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 56b20d1..116f0e9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -2673,6 +2673,9 @@
 	case ixgbe_mac_X540:
 	case ixgbe_mac_82599EB:
 		info->so_timestamping =
+			SOF_TIMESTAMPING_TX_SOFTWARE |
+			SOF_TIMESTAMPING_RX_SOFTWARE |
+			SOF_TIMESTAMPING_SOFTWARE |
 			SOF_TIMESTAMPING_TX_HARDWARE |
 			SOF_TIMESTAMPING_RX_HARDWARE |
 			SOF_TIMESTAMPING_RAW_HARDWARE;
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index f8064df..60ac46f 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -1860,10 +1860,14 @@
 	jme_clear_pm(jme);
 	JME_NAPI_ENABLE(jme);
 
-	tasklet_enable(&jme->linkch_task);
-	tasklet_enable(&jme->txclean_task);
-	tasklet_hi_enable(&jme->rxclean_task);
-	tasklet_hi_enable(&jme->rxempty_task);
+	tasklet_init(&jme->linkch_task, jme_link_change_tasklet,
+		     (unsigned long) jme);
+	tasklet_init(&jme->txclean_task, jme_tx_clean_tasklet,
+		     (unsigned long) jme);
+	tasklet_init(&jme->rxclean_task, jme_rx_clean_tasklet,
+		     (unsigned long) jme);
+	tasklet_init(&jme->rxempty_task, jme_rx_empty_tasklet,
+		     (unsigned long) jme);
 
 	rc = jme_request_irq(jme);
 	if (rc)
@@ -1948,10 +1952,10 @@
 
 	JME_NAPI_DISABLE(jme);
 
-	tasklet_disable(&jme->linkch_task);
-	tasklet_disable(&jme->txclean_task);
-	tasklet_disable(&jme->rxclean_task);
-	tasklet_disable(&jme->rxempty_task);
+	tasklet_kill(&jme->linkch_task);
+	tasklet_kill(&jme->txclean_task);
+	tasklet_kill(&jme->rxclean_task);
+	tasklet_kill(&jme->rxempty_task);
 
 	jme_disable_rx_engine(jme);
 	jme_disable_tx_engine(jme);
@@ -3079,22 +3083,6 @@
 	tasklet_init(&jme->pcc_task,
 		     jme_pcc_tasklet,
 		     (unsigned long) jme);
-	tasklet_init(&jme->linkch_task,
-		     jme_link_change_tasklet,
-		     (unsigned long) jme);
-	tasklet_init(&jme->txclean_task,
-		     jme_tx_clean_tasklet,
-		     (unsigned long) jme);
-	tasklet_init(&jme->rxclean_task,
-		     jme_rx_clean_tasklet,
-		     (unsigned long) jme);
-	tasklet_init(&jme->rxempty_task,
-		     jme_rx_empty_tasklet,
-		     (unsigned long) jme);
-	tasklet_disable_nosync(&jme->linkch_task);
-	tasklet_disable_nosync(&jme->txclean_task);
-	tasklet_disable_nosync(&jme->rxclean_task);
-	tasklet_disable_nosync(&jme->rxempty_task);
 	jme->dpi.cur = PCC_P1;
 
 	jme->reg_ghc = 0;
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index 9b9c2ac..d19a143 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -4026,7 +4026,7 @@
 	dev0 = hw->dev[0];
 	unregister_netdev(dev0);
 
-	tasklet_disable(&hw->phy_task);
+	tasklet_kill(&hw->phy_task);
 
 	spin_lock_irq(&hw->hw_lock);
 	hw->intr_mask = 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index c10e3a6..b35094c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -143,7 +143,6 @@
 		mlx4_bf_free(mdev->dev, &ring->bf);
 	mlx4_qp_remove(mdev->dev, &ring->qp);
 	mlx4_qp_free(mdev->dev, &ring->qp);
-	mlx4_qp_release_range(mdev->dev, ring->qpn, 1);
 	mlx4_en_unmap_buffer(&ring->wqres.buf);
 	mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
 	kfree(ring->bounce_buf);
@@ -712,7 +711,7 @@
 	if (bounce)
 		tx_desc = mlx4_en_bounce_to_desc(priv, ring, index, desc_size);
 
-	if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tag) {
+	if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tx_tag_present(skb)) {
 		*(__be32 *) (&tx_desc->ctrl.vlan_tag) |= cpu_to_be32(ring->doorbell_qpn);
 		op_own |= htonl((bf_index & 0xffff) << 8);
 		/* Ensure new descirptor hits memory
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index 51c7649..b84a88b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -329,9 +329,6 @@
 	ctx = &priv->mfunc.master.slave_state[slave];
 	spin_lock_irqsave(&ctx->lock, flags);
 
-	mlx4_dbg(dev, "%s: slave: %d, current state: %d new event :%d\n",
-		 __func__, slave, cur_state, event);
-
 	switch (cur_state) {
 	case SLAVE_PORT_DOWN:
 		if (MLX4_PORT_STATE_DEV_EVENT_PORT_UP == event)
@@ -366,9 +363,6 @@
 			goto out;
 	}
 	ret = mlx4_get_slave_port_state(dev, slave, port);
-	mlx4_dbg(dev, "%s: slave: %d, current state: %d new event"
-		 " :%d gen_event: %d\n",
-		 __func__, slave, cur_state, event, *gen_event);
 
 out:
 	spin_unlock_irqrestore(&ctx->lock, flags);
@@ -843,6 +837,18 @@
 	return priv->eq_table.uar_map[index] + 0x800 + 8 * (eq->eqn % 4);
 }
 
+static void mlx4_unmap_uar(struct mlx4_dev *dev)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	int i;
+
+	for (i = 0; i < mlx4_num_eq_uar(dev); ++i)
+		if (priv->eq_table.uar_map[i]) {
+			iounmap(priv->eq_table.uar_map[i]);
+			priv->eq_table.uar_map[i] = NULL;
+		}
+}
+
 static int mlx4_create_eq(struct mlx4_dev *dev, int nent,
 			  u8 intr, struct mlx4_eq *eq)
 {
@@ -1207,6 +1213,7 @@
 	mlx4_free_irqs(dev);
 
 err_out_bitmap:
+	mlx4_unmap_uar(dev);
 	mlx4_bitmap_cleanup(&priv->eq_table.bitmap);
 
 err_out_free:
@@ -1231,10 +1238,7 @@
 	if (!mlx4_is_slave(dev))
 		mlx4_unmap_clr_int(dev);
 
-	for (i = 0; i < mlx4_num_eq_uar(dev); ++i)
-		if (priv->eq_table.uar_map[i])
-			iounmap(priv->eq_table.uar_map[i]);
-
+	mlx4_unmap_uar(dev);
 	mlx4_bitmap_cleanup(&priv->eq_table.bitmap);
 
 	kfree(priv->eq_table.uar_map);
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 80df2ab..2aa80af 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -1405,7 +1405,10 @@
 	unmap_bf_area(dev);
 
 err_close:
-	mlx4_close_hca(dev);
+	if (mlx4_is_slave(dev))
+		mlx4_slave_exit(dev);
+	else
+		mlx4_CLOSE_HCA(dev, 0);
 
 err_free_icm:
 	if (!mlx4_is_slave(dev))
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 926c911..b05705f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -330,9 +330,6 @@
 
 	new_index = priv->virt2phys_pkey[slave][port - 1][orig_index];
 	*(u8 *)(inbox->buf + 35) = new_index;
-
-	mlx4_dbg(dev, "port = %d, orig pkey index = %d, "
-		 "new pkey index = %d\n", port, orig_index, new_index);
 }
 
 static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox,
@@ -351,9 +348,6 @@
 		if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH)
 			qp_ctx->alt_path.mgid_index = slave & 0x7F;
 	}
-
-	mlx4_dbg(dev, "slave %d, new gid index: 0x%x ",
-		slave, qp_ctx->pri_path.mgid_index);
 }
 
 static int mpt_mask(struct mlx4_dev *dev)
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
index 318fee9..69e0197 100644
--- a/drivers/net/ethernet/micrel/ksz884x.c
+++ b/drivers/net/ethernet/micrel/ksz884x.c
@@ -5407,8 +5407,8 @@
 		/* Delay for receive task to stop scheduling itself. */
 		msleep(2000 / HZ);
 
-		tasklet_disable(&hw_priv->rx_tasklet);
-		tasklet_disable(&hw_priv->tx_tasklet);
+		tasklet_kill(&hw_priv->rx_tasklet);
+		tasklet_kill(&hw_priv->tx_tasklet);
 		free_irq(dev->irq, hw_priv->dev);
 
 		transmit_cleanup(hw_priv, 0);
@@ -5459,8 +5459,10 @@
 	rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev);
 	if (rc)
 		return rc;
-	tasklet_enable(&hw_priv->rx_tasklet);
-	tasklet_enable(&hw_priv->tx_tasklet);
+	tasklet_init(&hw_priv->rx_tasklet, rx_proc_task,
+		     (unsigned long) hw_priv);
+	tasklet_init(&hw_priv->tx_tasklet, tx_proc_task,
+		     (unsigned long) hw_priv);
 
 	hw->promiscuous = 0;
 	hw->all_multi = 0;
@@ -7033,16 +7035,6 @@
 	spin_lock_init(&hw_priv->hwlock);
 	mutex_init(&hw_priv->lock);
 
-	/* tasklet is enabled. */
-	tasklet_init(&hw_priv->rx_tasklet, rx_proc_task,
-		(unsigned long) hw_priv);
-	tasklet_init(&hw_priv->tx_tasklet, tx_proc_task,
-		(unsigned long) hw_priv);
-
-	/* tasklet_enable will decrement the atomic counter. */
-	tasklet_disable(&hw_priv->rx_tasklet);
-	tasklet_disable(&hw_priv->tx_tasklet);
-
 	for (i = 0; i < TOTAL_PORT_NUM; i++)
 		init_waitqueue_head(&hw_priv->counter[i].counter);
 
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
index 53743f7..af8b414 100644
--- a/drivers/net/ethernet/nxp/lpc_eth.c
+++ b/drivers/net/ethernet/nxp/lpc_eth.c
@@ -1524,6 +1524,7 @@
 				  pldat->dma_buff_base_p);
 	free_irq(ndev->irq, ndev);
 	iounmap(pldat->net_base);
+	mdiobus_unregister(pldat->mii_bus);
 	mdiobus_free(pldat->mii_bus);
 	clk_disable(pldat->clk);
 	clk_put(pldat->clk);
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index b2a94d0..4c4fe5b 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -339,26 +339,6 @@
 }
 
 /**
- * pch_gbe_wait_clr_bit_irq - Wait to clear a bit for interrupt context
- * @reg:	Pointer of register
- * @busy:	Busy bit
- */
-static int pch_gbe_wait_clr_bit_irq(void *reg, u32 bit)
-{
-	u32 tmp;
-	int ret = -1;
-	/* wait busy */
-	tmp = 20;
-	while ((ioread32(reg) & bit) && --tmp)
-		udelay(5);
-	if (!tmp)
-		pr_err("Error: busy bit is not cleared\n");
-	else
-		ret = 0;
-	return ret;
-}
-
-/**
  * pch_gbe_mac_mar_set - Set MAC address register
  * @hw:	    Pointer to the HW structure
  * @addr:   Pointer to the MAC address
@@ -409,15 +389,20 @@
 	return;
 }
 
-static void pch_gbe_mac_reset_rx(struct pch_gbe_hw *hw)
+static void pch_gbe_disable_mac_rx(struct pch_gbe_hw *hw)
 {
-	/* Read the MAC addresses. and store to the private data */
-	pch_gbe_mac_read_mac_addr(hw);
-	iowrite32(PCH_GBE_RX_RST, &hw->reg->RESET);
-	pch_gbe_wait_clr_bit_irq(&hw->reg->RESET, PCH_GBE_RX_RST);
-	/* Setup the MAC addresses */
-	pch_gbe_mac_mar_set(hw, hw->mac.addr, 0);
-	return;
+	u32 rctl;
+	/* Disables Receive MAC */
+	rctl = ioread32(&hw->reg->MAC_RX_EN);
+	iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN);
+}
+
+static void pch_gbe_enable_mac_rx(struct pch_gbe_hw *hw)
+{
+	u32 rctl;
+	/* Enables Receive MAC */
+	rctl = ioread32(&hw->reg->MAC_RX_EN);
+	iowrite32((rctl | PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN);
 }
 
 /**
@@ -913,7 +898,7 @@
 static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter)
 {
 	struct pch_gbe_hw *hw = &adapter->hw;
-	u32 rdba, rdlen, rctl, rxdma;
+	u32 rdba, rdlen, rxdma;
 
 	pr_debug("dma adr = 0x%08llx  size = 0x%08x\n",
 		 (unsigned long long)adapter->rx_ring->dma,
@@ -921,9 +906,7 @@
 
 	pch_gbe_mac_force_mac_fc(hw);
 
-	/* Disables Receive MAC */
-	rctl = ioread32(&hw->reg->MAC_RX_EN);
-	iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN);
+	pch_gbe_disable_mac_rx(hw);
 
 	/* Disables Receive DMA */
 	rxdma = ioread32(&hw->reg->DMA_CTRL);
@@ -1316,38 +1299,17 @@
 	spin_unlock_irqrestore(&adapter->stats_lock, flags);
 }
 
-static void pch_gbe_stop_receive(struct pch_gbe_adapter *adapter)
+static void pch_gbe_disable_dma_rx(struct pch_gbe_hw *hw)
 {
-	struct pch_gbe_hw *hw = &adapter->hw;
 	u32 rxdma;
-	u16 value;
-	int ret;
 
 	/* Disable Receive DMA */
 	rxdma = ioread32(&hw->reg->DMA_CTRL);
 	rxdma &= ~PCH_GBE_RX_DMA_EN;
 	iowrite32(rxdma, &hw->reg->DMA_CTRL);
-	/* Wait Rx DMA BUS is IDLE */
-	ret = pch_gbe_wait_clr_bit_irq(&hw->reg->RX_DMA_ST, PCH_GBE_IDLE_CHECK);
-	if (ret) {
-		/* Disable Bus master */
-		pci_read_config_word(adapter->pdev, PCI_COMMAND, &value);
-		value &= ~PCI_COMMAND_MASTER;
-		pci_write_config_word(adapter->pdev, PCI_COMMAND, value);
-		/* Stop Receive */
-		pch_gbe_mac_reset_rx(hw);
-		/* Enable Bus master */
-		value |= PCI_COMMAND_MASTER;
-		pci_write_config_word(adapter->pdev, PCI_COMMAND, value);
-	} else {
-		/* Stop Receive */
-		pch_gbe_mac_reset_rx(hw);
-	}
-	/* reprogram multicast address register after reset */
-	pch_gbe_set_multi(adapter->netdev);
 }
 
-static void pch_gbe_start_receive(struct pch_gbe_hw *hw)
+static void pch_gbe_enable_dma_rx(struct pch_gbe_hw *hw)
 {
 	u32 rxdma;
 
@@ -1355,9 +1317,6 @@
 	rxdma = ioread32(&hw->reg->DMA_CTRL);
 	rxdma |= PCH_GBE_RX_DMA_EN;
 	iowrite32(rxdma, &hw->reg->DMA_CTRL);
-	/* Enables Receive */
-	iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN);
-	return;
 }
 
 /**
@@ -1393,7 +1352,7 @@
 			int_en = ioread32(&hw->reg->INT_EN);
 			iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR),
 				  &hw->reg->INT_EN);
-			pch_gbe_stop_receive(adapter);
+			pch_gbe_disable_dma_rx(&adapter->hw);
 			int_st |= ioread32(&hw->reg->INT_ST);
 			int_st = int_st & ioread32(&hw->reg->INT_EN);
 		}
@@ -1971,12 +1930,12 @@
 	struct net_device *netdev = adapter->netdev;
 	struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
 	struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
-	int err;
+	int err = -EINVAL;
 
 	/* Ensure we have a valid MAC */
 	if (!is_valid_ether_addr(adapter->hw.mac.addr)) {
 		pr_err("Error: Invalid MAC address\n");
-		return -EINVAL;
+		goto out;
 	}
 
 	/* hardware has been reset, we need to reload some things */
@@ -1989,18 +1948,19 @@
 
 	err = pch_gbe_request_irq(adapter);
 	if (err) {
-		pr_err("Error: can't bring device up\n");
-		return err;
+		pr_err("Error: can't bring device up - irq request failed\n");
+		goto out;
 	}
 	err = pch_gbe_alloc_rx_buffers_pool(adapter, rx_ring, rx_ring->count);
 	if (err) {
-		pr_err("Error: can't bring device up\n");
-		return err;
+		pr_err("Error: can't bring device up - alloc rx buffers pool failed\n");
+		goto freeirq;
 	}
 	pch_gbe_alloc_tx_buffers(adapter, tx_ring);
 	pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count);
 	adapter->tx_queue_len = netdev->tx_queue_len;
-	pch_gbe_start_receive(&adapter->hw);
+	pch_gbe_enable_dma_rx(&adapter->hw);
+	pch_gbe_enable_mac_rx(&adapter->hw);
 
 	mod_timer(&adapter->watchdog_timer, jiffies);
 
@@ -2009,6 +1969,11 @@
 	netif_start_queue(adapter->netdev);
 
 	return 0;
+
+freeirq:
+	pch_gbe_free_irq(adapter);
+out:
+	return err;
 }
 
 /**
@@ -2405,7 +2370,6 @@
 	int work_done = 0;
 	bool poll_end_flag = false;
 	bool cleaned = false;
-	u32 int_en;
 
 	pr_debug("budget : %d\n", budget);
 
@@ -2422,19 +2386,13 @@
 
 	if (poll_end_flag) {
 		napi_complete(napi);
-		if (adapter->rx_stop_flag) {
-			adapter->rx_stop_flag = false;
-			pch_gbe_start_receive(&adapter->hw);
-		}
 		pch_gbe_irq_enable(adapter);
-	} else
-		if (adapter->rx_stop_flag) {
-			adapter->rx_stop_flag = false;
-			pch_gbe_start_receive(&adapter->hw);
-			int_en = ioread32(&adapter->hw.reg->INT_EN);
-			iowrite32((int_en | PCH_GBE_INT_RX_FIFO_ERR),
-				&adapter->hw.reg->INT_EN);
-		}
+	}
+
+	if (adapter->rx_stop_flag) {
+		adapter->rx_stop_flag = false;
+		pch_gbe_enable_dma_rx(&adapter->hw);
+	}
 
 	pr_debug("poll_end_flag : %d  work_done : %d  budget : %d\n",
 		 poll_end_flag, work_done, budget);
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index df09b1c..6407d0d 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -2525,6 +2525,13 @@
 	qdev->req_q_size =
 	    (u32) (NUM_REQ_Q_ENTRIES * sizeof(struct ob_mac_iocb_req));
 
+	qdev->rsp_q_size = NUM_RSP_Q_ENTRIES * sizeof(struct net_rsp_iocb);
+
+	/* The barrier is required to ensure request and response queue
+	 * addr writes to the registers.
+	 */
+	wmb();
+
 	qdev->req_q_virt_addr =
 	    pci_alloc_consistent(qdev->pdev,
 				 (size_t) qdev->req_q_size,
@@ -2536,8 +2543,6 @@
 		return -ENOMEM;
 	}
 
-	qdev->rsp_q_size = NUM_RSP_Q_ENTRIES * sizeof(struct net_rsp_iocb);
-
 	qdev->rsp_q_virt_addr =
 	    pci_alloc_consistent(qdev->pdev,
 				 (size_t) qdev->rsp_q_size,
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index e7ff886..927aa33 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3827,6 +3827,8 @@
 	void __iomem *ioaddr = tp->mmio_addr;
 
 	switch (tp->mac_version) {
+	case RTL_GIGA_MAC_VER_25:
+	case RTL_GIGA_MAC_VER_26:
 	case RTL_GIGA_MAC_VER_29:
 	case RTL_GIGA_MAC_VER_30:
 	case RTL_GIGA_MAC_VER_32:
@@ -4519,6 +4521,9 @@
 		mc_filter[1] = swab32(data);
 	}
 
+	if (tp->mac_version == RTL_GIGA_MAC_VER_35)
+		mc_filter[1] = mc_filter[0] = 0xffffffff;
+
 	RTL_W32(MAR0 + 4, mc_filter[1]);
 	RTL_W32(MAR0 + 0, mc_filter[0]);
 
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 62d1baf..c53c0f4 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -2110,7 +2110,7 @@
 static int __devinit smsc911x_init(struct net_device *dev)
 {
 	struct smsc911x_data *pdata = netdev_priv(dev);
-	unsigned int byte_test;
+	unsigned int byte_test, mask;
 	unsigned int to = 100;
 
 	SMSC_TRACE(pdata, probe, "Driver Parameters:");
@@ -2130,9 +2130,22 @@
 	/*
 	 * poll the READY bit in PMT_CTRL. Any other access to the device is
 	 * forbidden while this bit isn't set. Try for 100ms
+	 *
+	 * Note that this test is done before the WORD_SWAP register is
+	 * programmed. So in some configurations the READY bit is at 16 before
+	 * WORD_SWAP is written to. This issue is worked around by waiting
+	 * until either bit 0 or bit 16 gets set in PMT_CTRL.
+	 *
+	 * SMSC has confirmed that checking bit 16 (marked as reserved in
+	 * the datasheet) is fine since these bits "will either never be set
+	 * or can only go high after READY does (so also indicate the device
+	 * is ready)".
 	 */
-	while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to)
+
+	mask = PMT_CTRL_READY_ | swahw32(PMT_CTRL_READY_);
+	while (!(smsc911x_reg_read(pdata, PMT_CTRL) & mask) && --to)
 		udelay(1000);
+
 	if (to == 0) {
 		pr_err("Device not READY in 100ms aborting\n");
 		return -ENODEV;
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index b26cbda..2c41894 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -5,7 +5,7 @@
 config NET_VENDOR_TI
 	bool "Texas Instruments (TI) devices"
 	default y
-	depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3))
+	depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX))
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y
 	  and read the Ethernet-HOWTO, available from
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index 4e2a162..66e025a 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -917,7 +917,7 @@
 	ingress_irq = rc;
 	tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU);
 	rc = request_irq(ingress_irq, tile_net_handle_ingress_irq,
-			 0, NULL, NULL);
+			 0, "tile_net", NULL);
 	if (rc != 0) {
 		netdev_err(dev, "request_irq failed: %d\n", rc);
 		destroy_irq(ingress_irq);
@@ -1334,11 +1334,11 @@
 {
 	struct skb_shared_info *sh = skb_shinfo(skb);
 	unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-	unsigned int data_len = skb->data_len + skb->hdr_len - sh_len;
+	unsigned int data_len = skb->len - sh_len;
 	unsigned int p_len = sh->gso_size;
 	long f_id = -1;    /* id of the current fragment */
-	long f_size = skb->hdr_len;  /* size of the current fragment */
-	long f_used = sh_len;  /* bytes used from the current fragment */
+	long f_size = skb_headlen(skb) - sh_len;  /* current fragment size */
+	long f_used = 0;  /* bytes used from the current fragment */
 	long n;            /* size of the current piece of payload */
 	int num_edescs = 0;
 	int segment;
@@ -1353,7 +1353,7 @@
 			/* Advance as needed. */
 			while (f_used >= f_size) {
 				f_id++;
-				f_size = sh->frags[f_id].size;
+				f_size = skb_frag_size(&sh->frags[f_id]);
 				f_used = 0;
 			}
 
@@ -1384,13 +1384,13 @@
 	struct iphdr *ih;
 	struct tcphdr *th;
 	unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-	unsigned int data_len = skb->data_len + skb->hdr_len - sh_len;
+	unsigned int data_len = skb->len - sh_len;
 	unsigned char *data = skb->data;
 	unsigned int ih_off, th_off, p_len;
 	unsigned int isum_seed, tsum_seed, id, seq;
 	long f_id = -1;    /* id of the current fragment */
-	long f_size = skb->hdr_len;  /* size of the current fragment */
-	long f_used = sh_len;  /* bytes used from the current fragment */
+	long f_size = skb_headlen(skb) - sh_len;  /* current fragment size */
+	long f_used = 0;  /* bytes used from the current fragment */
 	long n;            /* size of the current piece of payload */
 	int segment;
 
@@ -1405,7 +1405,7 @@
 	isum_seed = ((0xFFFF - ih->check) +
 		     (0xFFFF - ih->tot_len) +
 		     (0xFFFF - ih->id));
-	tsum_seed = th->check + (0xFFFF ^ htons(sh_len + data_len));
+	tsum_seed = th->check + (0xFFFF ^ htons(skb->len));
 	id = ntohs(ih->id);
 	seq = ntohl(th->seq);
 
@@ -1444,7 +1444,7 @@
 			/* Advance as needed. */
 			while (f_used >= f_size) {
 				f_id++;
-				f_size = sh->frags[f_id].size;
+				f_size = skb_frag_size(&sh->frags[f_id]);
 				f_used = 0;
 			}
 
@@ -1478,14 +1478,14 @@
 	struct tile_net_priv *priv = netdev_priv(dev);
 	struct skb_shared_info *sh = skb_shinfo(skb);
 	unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-	unsigned int data_len = skb->data_len + skb->hdr_len - sh_len;
+	unsigned int data_len = skb->len - sh_len;
 	unsigned int p_len = sh->gso_size;
 	gxio_mpipe_edesc_t edesc_head = { { 0 } };
 	gxio_mpipe_edesc_t edesc_body = { { 0 } };
 	long f_id = -1;    /* id of the current fragment */
-	long f_size = skb->hdr_len;  /* size of the current fragment */
-	long f_used = sh_len;  /* bytes used from the current fragment */
-	void *f_data = skb->data;
+	long f_size = skb_headlen(skb) - sh_len;  /* current fragment size */
+	long f_used = 0;  /* bytes used from the current fragment */
+	void *f_data = skb->data + sh_len;
 	long n;            /* size of the current piece of payload */
 	unsigned long tx_packets = 0, tx_bytes = 0;
 	unsigned int csum_start;
@@ -1516,15 +1516,18 @@
 
 		/* Egress the payload. */
 		while (p_used < p_len) {
+			void *va;
 
 			/* Advance as needed. */
 			while (f_used >= f_size) {
 				f_id++;
-				f_size = sh->frags[f_id].size;
-				f_used = 0;
+				f_size = skb_frag_size(&sh->frags[f_id]);
 				f_data = tile_net_frag_buf(&sh->frags[f_id]);
+				f_used = 0;
 			}
 
+			va = f_data + f_used;
+
 			/* Use bytes from the current fragment. */
 			n = p_len - p_used;
 			if (n > f_size - f_used)
@@ -1533,7 +1536,7 @@
 			p_used += n;
 
 			/* Egress a piece of the payload. */
-			edesc_body.va = va_to_tile_io_addr(f_data) + f_used;
+			edesc_body.va = va_to_tile_io_addr(va);
 			edesc_body.xfer_size = n;
 			edesc_body.bound = !(p_used < p_len);
 			gxio_mpipe_equeue_put_at(equeue, edesc_body, slot);
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 0793299..77e6db9 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -942,6 +942,10 @@
 		phy_start(lp->phy_dev);
 	}
 
+	/* Enable tasklets for Axi DMA error handling */
+	tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler,
+		     (unsigned long) lp);
+
 	/* Enable interrupts for Axi DMA Tx */
 	ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev);
 	if (ret)
@@ -950,8 +954,7 @@
 	ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev);
 	if (ret)
 		goto err_rx_irq;
-	/* Enable tasklets for Axi DMA error handling */
-	tasklet_enable(&lp->dma_err_tasklet);
+
 	return 0;
 
 err_rx_irq:
@@ -960,6 +963,7 @@
 	if (lp->phy_dev)
 		phy_disconnect(lp->phy_dev);
 	lp->phy_dev = NULL;
+	tasklet_kill(&lp->dma_err_tasklet);
 	dev_err(lp->dev, "request_irq() failed\n");
 	return ret;
 }
@@ -990,7 +994,7 @@
 	axienet_setoptions(ndev, lp->options &
 			   ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
 
-	tasklet_disable(&lp->dma_err_tasklet);
+	tasklet_kill(&lp->dma_err_tasklet);
 
 	free_irq(lp->tx_irq, ndev);
 	free_irq(lp->rx_irq, ndev);
@@ -1613,10 +1617,6 @@
 		goto err_iounmap_2;
 	}
 
-	tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler,
-		     (unsigned long) lp);
-	tasklet_disable(&lp->dma_err_tasklet);
-
 	return 0;
 
 err_iounmap_2:
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 983bbf4..961f0b2 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -15,6 +15,11 @@
 
 comment "MII PHY device drivers"
 
+config AT803X_PHY
+	tristate "Drivers for Atheros AT803X PHYs"
+	---help---
+	  Currently supports the AT8030 and AT8035 model
+
 config AMD_PHY
 	tristate "Drivers for the AMD PHYs"
 	---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 426674d..9645e38 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -25,6 +25,7 @@
 obj-$(CONFIG_MICREL_PHY)	+= micrel.o
 obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
 obj-$(CONFIG_MICREL_KS8995MA)	+= spi_ks8995.o
+obj-$(CONFIG_AT803X_PHY)	+= at803x.o
 obj-$(CONFIG_AMD_PHY)		+= amd.o
 obj-$(CONFIG_MDIO_BUS_MUX)	+= mdio-mux.o
 obj-$(CONFIG_MDIO_BUS_MUX_GPIO)	+= mdio-mux-gpio.o
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
new file mode 100644
index 0000000..45cbc10
--- /dev/null
+++ b/drivers/net/phy/at803x.c
@@ -0,0 +1,176 @@
+/*
+ * drivers/net/phy/at803x.c
+ *
+ * Driver for Atheros 803x PHY
+ *
+ * Author: Matus Ujhelyi <ujhelyi.m@gmail.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/phy.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+
+#define AT803X_INTR_ENABLE			0x12
+#define AT803X_INTR_STATUS			0x13
+#define AT803X_WOL_ENABLE			0x01
+#define AT803X_DEVICE_ADDR			0x03
+#define AT803X_LOC_MAC_ADDR_0_15_OFFSET		0x804C
+#define AT803X_LOC_MAC_ADDR_16_31_OFFSET	0x804B
+#define AT803X_LOC_MAC_ADDR_32_47_OFFSET	0x804A
+#define AT803X_MMD_ACCESS_CONTROL		0x0D
+#define AT803X_MMD_ACCESS_CONTROL_DATA		0x0E
+#define AT803X_FUNC_DATA			0x4003
+
+MODULE_DESCRIPTION("Atheros 803x PHY driver");
+MODULE_AUTHOR("Matus Ujhelyi");
+MODULE_LICENSE("GPL");
+
+static void at803x_set_wol_mac_addr(struct phy_device *phydev)
+{
+	struct net_device *ndev = phydev->attached_dev;
+	const u8 *mac;
+	unsigned int i, offsets[] = {
+		AT803X_LOC_MAC_ADDR_32_47_OFFSET,
+		AT803X_LOC_MAC_ADDR_16_31_OFFSET,
+		AT803X_LOC_MAC_ADDR_0_15_OFFSET,
+	};
+
+	if (!ndev)
+		return;
+
+	mac = (const u8 *) ndev->dev_addr;
+
+	if (!is_valid_ether_addr(mac))
+		return;
+
+	for (i = 0; i < 3; i++) {
+		phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
+				  AT803X_DEVICE_ADDR);
+		phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
+				  offsets[i]);
+		phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
+				  AT803X_FUNC_DATA);
+		phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
+				  mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
+	}
+}
+
+static int at803x_config_init(struct phy_device *phydev)
+{
+	int val;
+	u32 features;
+	int status;
+
+	features = SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_AUI |
+		   SUPPORTED_FIBRE | SUPPORTED_BNC;
+
+	val = phy_read(phydev, MII_BMSR);
+	if (val < 0)
+		return val;
+
+	if (val & BMSR_ANEGCAPABLE)
+		features |= SUPPORTED_Autoneg;
+	if (val & BMSR_100FULL)
+		features |= SUPPORTED_100baseT_Full;
+	if (val & BMSR_100HALF)
+		features |= SUPPORTED_100baseT_Half;
+	if (val & BMSR_10FULL)
+		features |= SUPPORTED_10baseT_Full;
+	if (val & BMSR_10HALF)
+		features |= SUPPORTED_10baseT_Half;
+
+	if (val & BMSR_ESTATEN) {
+		val = phy_read(phydev, MII_ESTATUS);
+		if (val < 0)
+			return val;
+
+		if (val & ESTATUS_1000_TFULL)
+			features |= SUPPORTED_1000baseT_Full;
+		if (val & ESTATUS_1000_THALF)
+			features |= SUPPORTED_1000baseT_Half;
+	}
+
+	phydev->supported = features;
+	phydev->advertising = features;
+
+	/* enable WOL */
+	at803x_set_wol_mac_addr(phydev);
+	status = phy_write(phydev, AT803X_INTR_ENABLE, AT803X_WOL_ENABLE);
+	status = phy_read(phydev, AT803X_INTR_STATUS);
+
+	return 0;
+}
+
+/* ATHEROS 8035 */
+static struct phy_driver at8035_driver = {
+	.phy_id		= 0x004dd072,
+	.name		= "Atheros 8035 ethernet",
+	.phy_id_mask	= 0xffffffef,
+	.config_init	= at803x_config_init,
+	.features	= PHY_GBIT_FEATURES,
+	.flags		= PHY_HAS_INTERRUPT,
+	.config_aneg	= &genphy_config_aneg,
+	.read_status	= &genphy_read_status,
+	.driver		= {
+		.owner = THIS_MODULE,
+	},
+};
+
+/* ATHEROS 8030 */
+static struct phy_driver at8030_driver = {
+	.phy_id		= 0x004dd076,
+	.name		= "Atheros 8030 ethernet",
+	.phy_id_mask	= 0xffffffef,
+	.config_init	= at803x_config_init,
+	.features	= PHY_GBIT_FEATURES,
+	.flags		= PHY_HAS_INTERRUPT,
+	.config_aneg	= &genphy_config_aneg,
+	.read_status	= &genphy_read_status,
+	.driver		= {
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init atheros_init(void)
+{
+	int ret;
+
+	ret = phy_driver_register(&at8035_driver);
+	if (ret)
+		goto err1;
+
+	ret = phy_driver_register(&at8030_driver);
+	if (ret)
+		goto err2;
+
+	return 0;
+
+err2:
+	phy_driver_unregister(&at8035_driver);
+err1:
+	return ret;
+}
+
+static void __exit atheros_exit(void)
+{
+	phy_driver_unregister(&at8035_driver);
+	phy_driver_unregister(&at8030_driver);
+}
+
+module_init(atheros_init);
+module_exit(atheros_exit);
+
+static struct mdio_device_id __maybe_unused atheros_tbl[] = {
+	{ 0x004dd076, 0xffffffef },
+	{ 0x004dd072, 0xffffffef },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(mdio, atheros_tbl);
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c
index c81e278..08d55b6 100644
--- a/drivers/net/usb/cdc_eem.c
+++ b/drivers/net/usb/cdc_eem.c
@@ -31,6 +31,7 @@
 #include <linux/usb/cdc.h>
 #include <linux/usb/usbnet.h>
 #include <linux/gfp.h>
+#include <linux/if_vlan.h>
 
 
 /*
@@ -92,7 +93,7 @@
 
 	/* no jumbogram (16K) support for now */
 
-	dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN;
+	dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN + VLAN_HLEN;
 	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
 
 	return 0;
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index a03de71..d012982 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -592,6 +592,32 @@
 	.driver_info		= 0,
 },
 
+/* Novatel USB551L and MC551 - handled by qmi_wwan */
+{
+	.match_flags    =   USB_DEVICE_ID_MATCH_VENDOR
+		 | USB_DEVICE_ID_MATCH_PRODUCT
+		 | USB_DEVICE_ID_MATCH_INT_INFO,
+	.idVendor               = NOVATEL_VENDOR_ID,
+	.idProduct		= 0xB001,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= USB_CDC_SUBCLASS_ETHERNET,
+	.bInterfaceProtocol	= USB_CDC_PROTO_NONE,
+	.driver_info = 0,
+},
+
+/* Novatel E362 - handled by qmi_wwan */
+{
+	.match_flags    =   USB_DEVICE_ID_MATCH_VENDOR
+		 | USB_DEVICE_ID_MATCH_PRODUCT
+		 | USB_DEVICE_ID_MATCH_INT_INFO,
+	.idVendor               = NOVATEL_VENDOR_ID,
+	.idProduct		= 0x9010,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= USB_CDC_SUBCLASS_ETHERNET,
+	.bInterfaceProtocol	= USB_CDC_PROTO_NONE,
+	.driver_info = 0,
+},
+
 /*
  * WHITELIST!!!
  *
@@ -604,21 +630,6 @@
  * because of bugs/quirks in a given product (like Zaurus, above).
  */
 {
-	/* Novatel USB551L */
-	/* This match must come *before* the generic CDC-ETHER match so that
-	 * we get FLAG_WWAN set on the device, since it's descriptors are
-	 * generic CDC-ETHER.
-	 */
-	.match_flags    =   USB_DEVICE_ID_MATCH_VENDOR
-		 | USB_DEVICE_ID_MATCH_PRODUCT
-		 | USB_DEVICE_ID_MATCH_INT_INFO,
-	.idVendor               = NOVATEL_VENDOR_ID,
-	.idProduct		= 0xB001,
-	.bInterfaceClass	= USB_CLASS_COMM,
-	.bInterfaceSubClass	= USB_CDC_SUBCLASS_ETHERNET,
-	.bInterfaceProtocol	= USB_CDC_PROTO_NONE,
-	.driver_info = (unsigned long)&wwan_info,
-}, {
 	/* ZTE (Vodafone) K3805-Z */
 	.match_flags    =   USB_DEVICE_ID_MATCH_VENDOR
 		 | USB_DEVICE_ID_MATCH_PRODUCT
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 4cd582a..74fab1a 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -540,10 +540,12 @@
 	    (ctx->ether_desc == NULL) || (ctx->control != intf))
 		goto error;
 
-	/* claim interfaces, if any */
-	temp = usb_driver_claim_interface(driver, ctx->data, dev);
-	if (temp)
-		goto error;
+	/* claim data interface, if different from control */
+	if (ctx->data != ctx->control) {
+		temp = usb_driver_claim_interface(driver, ctx->data, dev);
+		if (temp)
+			goto error;
+	}
 
 	iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
 
@@ -623,6 +625,10 @@
 
 	tasklet_kill(&ctx->bh);
 
+	/* handle devices with combined control and data interface */
+	if (ctx->control == ctx->data)
+		ctx->data = NULL;
+
 	/* disconnect master --> disconnect slave */
 	if (intf == ctx->control && ctx->data) {
 		usb_set_intfdata(ctx->data, NULL);
@@ -1245,6 +1251,14 @@
 	  .driver_info = (unsigned long) &wwan_info,
 	},
 
+	/* Huawei NCM devices disguised as vendor specific */
+	{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16),
+	  .driver_info = (unsigned long)&wwan_info,
+	},
+	{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46),
+	  .driver_info = (unsigned long)&wwan_info,
+	},
+
 	/* Generic CDC-NCM devices */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM,
 		USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index a28a983d..534d8be 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -62,6 +62,7 @@
 #define USB_PRODUCT_IPAD 0x129a
 #define USB_PRODUCT_IPHONE_4_VZW 0x129c
 #define USB_PRODUCT_IPHONE_4S	0x12a0
+#define USB_PRODUCT_IPHONE_5	0x12a8
 
 #define IPHETH_USBINTF_CLASS    255
 #define IPHETH_USBINTF_SUBCLASS 253
@@ -113,6 +114,10 @@
 		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S,
 		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
 		IPHETH_USBINTF_PROTO) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(
+		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_5,
+		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+		IPHETH_USBINTF_PROTO) },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, ipheth_table);
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 6883c37..3b566fa 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -369,18 +369,73 @@
 		USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff),
 		.driver_info        = (unsigned long)&qmi_wwan_info,
 	},
+	{	/* Novatel USB551L and MC551 */
+		USB_DEVICE_AND_INTERFACE_INFO(0x1410, 0xb001,
+		                              USB_CLASS_COMM,
+		                              USB_CDC_SUBCLASS_ETHERNET,
+		                              USB_CDC_PROTO_NONE),
+		.driver_info        = (unsigned long)&qmi_wwan_info,
+	},
+	{	/* Novatel E362 */
+		USB_DEVICE_AND_INTERFACE_INFO(0x1410, 0x9010,
+		                              USB_CLASS_COMM,
+		                              USB_CDC_SUBCLASS_ETHERNET,
+		                              USB_CDC_PROTO_NONE),
+		.driver_info        = (unsigned long)&qmi_wwan_info,
+	},
 
 	/* 3. Combined interface devices matching on interface number */
+	{QMI_FIXED_INTF(0x19d2, 0x0002, 1)},
+	{QMI_FIXED_INTF(0x19d2, 0x0012, 1)},
+	{QMI_FIXED_INTF(0x19d2, 0x0017, 3)},
+	{QMI_FIXED_INTF(0x19d2, 0x0021, 4)},
+	{QMI_FIXED_INTF(0x19d2, 0x0025, 1)},
+	{QMI_FIXED_INTF(0x19d2, 0x0031, 4)},
+	{QMI_FIXED_INTF(0x19d2, 0x0042, 4)},
+	{QMI_FIXED_INTF(0x19d2, 0x0049, 5)},
+	{QMI_FIXED_INTF(0x19d2, 0x0052, 4)},
 	{QMI_FIXED_INTF(0x19d2, 0x0055, 1)},	/* ZTE (Vodafone) K3520-Z */
+	{QMI_FIXED_INTF(0x19d2, 0x0058, 4)},
 	{QMI_FIXED_INTF(0x19d2, 0x0063, 4)},	/* ZTE (Vodafone) K3565-Z */
 	{QMI_FIXED_INTF(0x19d2, 0x0104, 4)},	/* ZTE (Vodafone) K4505-Z */
+	{QMI_FIXED_INTF(0x19d2, 0x0113, 5)},
+	{QMI_FIXED_INTF(0x19d2, 0x0118, 5)},
+	{QMI_FIXED_INTF(0x19d2, 0x0121, 5)},
+	{QMI_FIXED_INTF(0x19d2, 0x0123, 4)},
+	{QMI_FIXED_INTF(0x19d2, 0x0124, 5)},
+	{QMI_FIXED_INTF(0x19d2, 0x0125, 6)},
+	{QMI_FIXED_INTF(0x19d2, 0x0126, 5)},
+	{QMI_FIXED_INTF(0x19d2, 0x0130, 1)},
+	{QMI_FIXED_INTF(0x19d2, 0x0133, 3)},
+	{QMI_FIXED_INTF(0x19d2, 0x0141, 5)},
 	{QMI_FIXED_INTF(0x19d2, 0x0157, 5)},	/* ZTE MF683 */
+	{QMI_FIXED_INTF(0x19d2, 0x0158, 3)},
 	{QMI_FIXED_INTF(0x19d2, 0x0167, 4)},	/* ZTE MF820D */
+	{QMI_FIXED_INTF(0x19d2, 0x0168, 4)},
+	{QMI_FIXED_INTF(0x19d2, 0x0176, 3)},
+	{QMI_FIXED_INTF(0x19d2, 0x0178, 3)},
+	{QMI_FIXED_INTF(0x19d2, 0x0191, 4)},	/* ZTE EuFi890 */
+	{QMI_FIXED_INTF(0x19d2, 0x0199, 1)},	/* ZTE MF820S */
+	{QMI_FIXED_INTF(0x19d2, 0x0200, 1)},
+	{QMI_FIXED_INTF(0x19d2, 0x0257, 3)},	/* ZTE MF821 */
 	{QMI_FIXED_INTF(0x19d2, 0x0326, 4)},	/* ZTE MF821D */
 	{QMI_FIXED_INTF(0x19d2, 0x1008, 4)},	/* ZTE (Vodafone) K3570-Z */
 	{QMI_FIXED_INTF(0x19d2, 0x1010, 4)},	/* ZTE (Vodafone) K3571-Z */
+	{QMI_FIXED_INTF(0x19d2, 0x1012, 4)},
 	{QMI_FIXED_INTF(0x19d2, 0x1018, 3)},	/* ZTE (Vodafone) K5006-Z */
+	{QMI_FIXED_INTF(0x19d2, 0x1021, 2)},
+	{QMI_FIXED_INTF(0x19d2, 0x1245, 4)},
+	{QMI_FIXED_INTF(0x19d2, 0x1247, 4)},
+	{QMI_FIXED_INTF(0x19d2, 0x1252, 4)},
+	{QMI_FIXED_INTF(0x19d2, 0x1254, 4)},
+	{QMI_FIXED_INTF(0x19d2, 0x1255, 3)},
+	{QMI_FIXED_INTF(0x19d2, 0x1255, 4)},
+	{QMI_FIXED_INTF(0x19d2, 0x1256, 4)},
+	{QMI_FIXED_INTF(0x19d2, 0x1401, 2)},
 	{QMI_FIXED_INTF(0x19d2, 0x1402, 2)},	/* ZTE MF60 */
+	{QMI_FIXED_INTF(0x19d2, 0x1424, 2)},
+	{QMI_FIXED_INTF(0x19d2, 0x1425, 2)},
+	{QMI_FIXED_INTF(0x19d2, 0x1426, 2)},	/* ZTE MF91 */
 	{QMI_FIXED_INTF(0x19d2, 0x2002, 4)},	/* ZTE (Vodafone) K3765-Z */
 	{QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)},    /* Sierra Wireless MC7700 */
 	{QMI_FIXED_INTF(0x114f, 0x68a2, 8)},    /* Sierra Wireless MC7750 */
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 7479a57..362cb8c 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -184,7 +184,7 @@
 	/* set the address, index & direction (read from PHY) */
 	phy_id &= dev->mii.phy_id_mask;
 	idx &= dev->mii.reg_num_mask;
-	addr = (phy_id << 11) | (idx << 6) | MII_READ_;
+	addr = (phy_id << 11) | (idx << 6) | MII_READ_ | MII_BUSY_;
 	ret = smsc95xx_write_reg(dev, MII_ADDR, addr);
 	check_warn_goto_done(ret, "Error writing MII_ADDR");
 
@@ -221,7 +221,7 @@
 	/* set the address, index & direction (write to PHY) */
 	phy_id &= dev->mii.phy_id_mask;
 	idx &= dev->mii.reg_num_mask;
-	addr = (phy_id << 11) | (idx << 6) | MII_WRITE_;
+	addr = (phy_id << 11) | (idx << 6) | MII_WRITE_ | MII_BUSY_;
 	ret = smsc95xx_write_reg(dev, MII_ADDR, addr);
 	check_warn_goto_done(ret, "Error writing MII_ADDR");
 
@@ -1344,6 +1344,7 @@
 		} else {
 			u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
 			skb_push(skb, 4);
+			cpu_to_le32s(&csum_preamble);
 			memcpy(skb->data, &csum_preamble, 4);
 		}
 	}
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index f9819d1..edb81ed 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -359,10 +359,12 @@
 void usbnet_defer_kevent (struct usbnet *dev, int work)
 {
 	set_bit (work, &dev->flags);
-	if (!schedule_work (&dev->kevent))
-		netdev_err(dev->net, "kevent %d may have been dropped\n", work);
-	else
+	if (!schedule_work (&dev->kevent)) {
+		if (net_ratelimit())
+			netdev_err(dev->net, "kevent %d may have been dropped\n", work);
+	} else {
 		netdev_dbg(dev->net, "kevent %d scheduled\n", work);
+	}
 }
 EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
 
@@ -1158,6 +1160,7 @@
 		usb_anchor_urb(urb, &dev->deferred);
 		/* no use to process more packets */
 		netif_stop_queue(net);
+		usb_put_urb(urb);
 		spin_unlock_irqrestore(&dev->txq.lock, flags);
 		netdev_dbg(dev->net, "Delaying transmission for resumption\n");
 		goto deferred;
@@ -1310,6 +1313,8 @@
 
 	cancel_work_sync(&dev->kevent);
 
+	usb_scuttle_anchored_urbs(&dev->deferred);
+
 	if (dev->driver_info->unbind)
 		dev->driver_info->unbind (dev, intf);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index ce9d4f2..0ae1bcc 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -744,28 +744,43 @@
 
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
+		u32 buf_size;
 
-		tbi = tq->buf_info + tq->tx_ring.next2fill;
-		tbi->map_type = VMXNET3_MAP_PAGE;
-		tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag,
-						 0, skb_frag_size(frag),
-						 DMA_TO_DEVICE);
+		buf_offset = 0;
+		len = skb_frag_size(frag);
+		while (len) {
+			tbi = tq->buf_info + tq->tx_ring.next2fill;
+			if (len < VMXNET3_MAX_TX_BUF_SIZE) {
+				buf_size = len;
+				dw2 |= len;
+			} else {
+				buf_size = VMXNET3_MAX_TX_BUF_SIZE;
+				/* spec says that for TxDesc.len, 0 == 2^14 */
+			}
+			tbi->map_type = VMXNET3_MAP_PAGE;
+			tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag,
+							 buf_offset, buf_size,
+							 DMA_TO_DEVICE);
 
-		tbi->len = skb_frag_size(frag);
+			tbi->len = buf_size;
 
-		gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
-		BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
+			gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
+			BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
 
-		gdesc->txd.addr = cpu_to_le64(tbi->dma_addr);
-		gdesc->dword[2] = cpu_to_le32(dw2 | skb_frag_size(frag));
-		gdesc->dword[3] = 0;
+			gdesc->txd.addr = cpu_to_le64(tbi->dma_addr);
+			gdesc->dword[2] = cpu_to_le32(dw2);
+			gdesc->dword[3] = 0;
 
-		dev_dbg(&adapter->netdev->dev,
-			"txd[%u]: 0x%llu %u %u\n",
-			tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr),
-			le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]);
-		vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
-		dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
+			dev_dbg(&adapter->netdev->dev,
+				"txd[%u]: 0x%llu %u %u\n",
+				tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr),
+				le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]);
+			vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
+			dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
+
+			len -= buf_size;
+			buf_offset += buf_size;
+		}
 	}
 
 	ctx->eop_txd = gdesc;
@@ -886,6 +901,18 @@
 	}
 }
 
+static int txd_estimate(const struct sk_buff *skb)
+{
+	int count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + 1;
+	int i;
+
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
+
+		count += VMXNET3_TXD_NEEDED(skb_frag_size(frag));
+	}
+	return count;
+}
 
 /*
  * Transmits a pkt thru a given tq
@@ -914,9 +941,7 @@
 	union Vmxnet3_GenericDesc tempTxDesc;
 #endif
 
-	/* conservatively estimate # of descriptors to use */
-	count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) +
-		skb_shinfo(skb)->nr_frags + 1;
+	count = txd_estimate(skb);
 
 	ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP));
 
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 607976c..8b5c619 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1,5 +1,5 @@
 /*
- * VXLAN: Virtual eXtensiable Local Area Network
+ * VXLAN: Virtual eXtensible Local Area Network
  *
  * Copyright (c) 2012 Vyatta Inc.
  *
@@ -50,8 +50,8 @@
 
 #define VXLAN_N_VID	(1u << 24)
 #define VXLAN_VID_MASK	(VXLAN_N_VID - 1)
-/* VLAN + IP header + UDP + VXLAN */
-#define VXLAN_HEADROOM (4 + 20 + 8 + 8)
+/* IP header + UDP + VXLAN + Ethernet header */
+#define VXLAN_HEADROOM (20 + 8 + 8 + 14)
 
 #define VXLAN_FLAGS 0x08000000	/* struct vxlanhdr.vx_flags required value. */
 
@@ -816,7 +816,7 @@
 				= container_of(p, struct vxlan_fdb, hlist);
 			unsigned long timeout;
 
-			if (f->state == NUD_PERMANENT)
+			if (f->state & NUD_PERMANENT)
 				continue;
 
 			timeout = f->used + vxlan->age_interval * HZ;
@@ -1102,6 +1102,10 @@
 
 		if (!tb[IFLA_MTU])
 			dev->mtu = lowerdev->mtu - VXLAN_HEADROOM;
+
+		/* update header length based on lower device */
+		dev->hard_header_len = lowerdev->hard_header_len +
+				       VXLAN_HEADROOM;
 	}
 
 	if (data[IFLA_VXLAN_TOS])
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index 89bf94d..6f7cf49 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -534,107 +534,107 @@
 
 static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
 	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-	{0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-	{0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-	{0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+	{0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+	{0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+	{0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
 	{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
 	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
 	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
 	{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
 	{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
-	{0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
-	{0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
-	{0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
-	{0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
-	{0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
-	{0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
-	{0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
-	{0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
-	{0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
-	{0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
-	{0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
-	{0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
-	{0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
-	{0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
-	{0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
-	{0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83},
-	{0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84},
-	{0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
-	{0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
-	{0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
-	{0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
-	{0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-	{0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-	{0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-	{0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-	{0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-	{0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
-	{0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+	{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+	{0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
+	{0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
+	{0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+	{0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+	{0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+	{0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+	{0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+	{0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+	{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+	{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+	{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+	{0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
+	{0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
+	{0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
+	{0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
+	{0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
+	{0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
+	{0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
+	{0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
+	{0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
 	{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
 	{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
 	{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
 	{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
-	{0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202},
-	{0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400},
-	{0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402},
-	{0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404},
-	{0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603},
-	{0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02},
-	{0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04},
-	{0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20},
-	{0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20},
-	{0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22},
-	{0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24},
-	{0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640},
-	{0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660},
-	{0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861},
-	{0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81},
-	{0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83},
-	{0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84},
-	{0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3},
-	{0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5},
-	{0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9},
-	{0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb},
-	{0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-	{0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-	{0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
-	{0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
+	{0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+	{0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+	{0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
+	{0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
+	{0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+	{0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+	{0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+	{0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+	{0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+	{0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+	{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+	{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+	{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+	{0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
+	{0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
+	{0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
+	{0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
+	{0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
+	{0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
+	{0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
+	{0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
+	{0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
 	{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-	{0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-	{0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
-	{0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
-	{0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
-	{0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
-	{0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
-	{0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
-	{0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
-	{0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-	{0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-	{0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-	{0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-	{0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
-	{0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-	{0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-	{0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+	{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+	{0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+	{0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+	{0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+	{0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+	{0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+	{0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+	{0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+	{0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
 	{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-	{0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
-	{0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
-	{0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+	{0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+	{0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+	{0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
 	{0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
 	{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-	{0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
+	{0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
 	{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 	{0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-	{0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
+	{0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
 	{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 	{0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-	{0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
+	{0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
 	{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 };
 
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 924c461..f5dda84 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -38,6 +38,7 @@
 	{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
 	{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */
 	{ USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
+	{ USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */
 	{ USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
 
 	{ USB_DEVICE(0x0cf3, 0x7015),
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 378bd70..741918a 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -312,6 +312,7 @@
 	}
 
 	bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+	bf->bf_next = NULL;
 	list_del(&bf->list);
 
 	spin_unlock_bh(&sc->tx.txbuflock);
@@ -393,7 +394,7 @@
 	u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first;
 	u32 ba[WME_BA_BMP_SIZE >> 5];
 	int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
-	bool rc_update = true;
+	bool rc_update = true, isba;
 	struct ieee80211_tx_rate rates[4];
 	struct ath_frame_info *fi;
 	int nframes;
@@ -437,13 +438,17 @@
 	tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
 	tid = ATH_AN_2_TID(an, tidno);
 	seq_first = tid->seq_start;
+	isba = ts->ts_flags & ATH9K_TX_BA;
 
 	/*
 	 * The hardware occasionally sends a tx status for the wrong TID.
 	 * In this case, the BA status cannot be considered valid and all
 	 * subframes need to be retransmitted
+	 *
+	 * Only BlockAcks have a TID and therefore normal Acks cannot be
+	 * checked
 	 */
-	if (tidno != ts->tid)
+	if (isba && tidno != ts->tid)
 		txok = false;
 
 	isaggr = bf_isaggr(bf);
@@ -1774,6 +1779,7 @@
 	list_add_tail(&bf->list, &bf_head);
 	bf->bf_state.bf_type = 0;
 
+	bf->bf_next = NULL;
 	bf->bf_lastbf = bf;
 	ath_tx_fill_desc(sc, bf, txq, fi->framelen);
 	ath_tx_txqaddbuf(sc, txq, &bf_head, false);
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 73730e9..c5a99c8 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -5404,6 +5404,8 @@
 	cancel_work_sync(&wldev->restart_work);
 
 	B43_WARN_ON(!wl);
+	if (!wldev->fw.ucode.data)
+		return;			/* NULL if firmware never loaded */
 	if (wl->current_dev == wldev && wl->hw_registred) {
 		b43_leds_stop(wldev);
 		ieee80211_unregister_hw(wl->hw);
@@ -5478,6 +5480,8 @@
 	cancel_work_sync(&wldev->restart_work);
 
 	B43_WARN_ON(!wl);
+	if (!wldev->fw.ucode.data)
+		return;			/* NULL if firmware never loaded */
 	if (wl->current_dev == wldev && wl->hw_registred) {
 		b43_leds_stop(wldev);
 		ieee80211_unregister_hw(wl->hw);
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index 192251a..282eede 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -382,7 +382,7 @@
 {
 	struct b43legacy_pio_txpacket *packet, *tmp_packet;
 
-	tasklet_disable(&queue->txtask);
+	tasklet_kill(&queue->txtask);
 
 	list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list)
 		free_txpacket(packet, 0);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index a2b4b1e..7a6dfdc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -1339,7 +1339,7 @@
 	}
 
 	ret = brcmf_bus_start(dev);
-	if (ret == -ENOLINK) {
+	if (ret) {
 		brcmf_dbg(ERROR, "dongle is not responding\n");
 		brcmf_detach(dev);
 		goto fail;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index c1abaa6..481345c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3569,7 +3569,7 @@
 
 	if (!request || !request->n_ssids || !request->n_match_sets) {
 		WL_ERR("Invalid sched scan req!! n_ssids:%d\n",
-		       request->n_ssids);
+		       request ? request->n_ssids : 0);
 		return -EINVAL;
 	}
 
@@ -3972,7 +3972,7 @@
 	u8  *iovar_ie_buf;
 	u8  *curr_ie_buf;
 	u8  *mgmt_ie_buf = NULL;
-	u32 mgmt_ie_buf_len = 0;
+	int mgmt_ie_buf_len;
 	u32 *mgmt_ie_len = 0;
 	u32 del_add_ie_buf_len = 0;
 	u32 total_ie_buf_len = 0;
@@ -3982,7 +3982,7 @@
 	struct parsed_vndr_ie_info *vndrie_info;
 	s32 i;
 	u8 *ptr;
-	u32 remained_buf_len;
+	int remained_buf_len;
 
 	WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag);
 	iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
@@ -4401,7 +4401,7 @@
 
 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
 {
-#ifndef CONFIG_BRCMFISCAN
+#ifndef CONFIG_BRCMISCAN
 	/* scheduled scan settings */
 	wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
 	wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
@@ -4606,12 +4606,13 @@
 	struct brcmf_cfg80211_profile *profile = cfg->profile;
 	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
 	struct wiphy *wiphy = cfg_to_wiphy(cfg);
-	struct brcmf_channel_info_le channel_le;
-	struct ieee80211_channel *notify_channel;
+	struct ieee80211_channel *notify_channel = NULL;
 	struct ieee80211_supported_band *band;
+	struct brcmf_bss_info_le *bi;
 	u32 freq;
 	s32 err = 0;
 	u32 target_channel;
+	u8 *buf;
 
 	WL_TRACE("Enter\n");
 
@@ -4619,11 +4620,22 @@
 	memcpy(profile->bssid, e->addr, ETH_ALEN);
 	brcmf_update_bss_info(cfg);
 
-	brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
-			sizeof(channel_le));
+	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+	if (buf == NULL) {
+		err = -ENOMEM;
+		goto done;
+	}
 
-	target_channel = le32_to_cpu(channel_le.target_channel);
-	WL_CONN("Roamed to channel %d\n", target_channel);
+	/* data sent to dongle has to be little endian */
+	*(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
+	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
+
+	if (err)
+		goto done;
+
+	bi = (struct brcmf_bss_info_le *)(buf + 4);
+	target_channel = bi->ctl_ch ? bi->ctl_ch :
+				      CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
 
 	if (target_channel <= CH_MAX_2G_CHANNEL)
 		band = wiphy->bands[IEEE80211_BAND_2GHZ];
@@ -4633,6 +4645,8 @@
 	freq = ieee80211_channel_to_frequency(target_channel, band->band);
 	notify_channel = ieee80211_get_channel(wiphy, freq);
 
+done:
+	kfree(buf);
 	cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
 			conn_info->req_ie, conn_info->req_ie_len,
 			conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
@@ -5186,41 +5200,6 @@
 		schedule_work(&cfg->event_work);
 }
 
-static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
-{
-	s32 infra = 0;
-	s32 err = 0;
-
-	switch (iftype) {
-	case NL80211_IFTYPE_MONITOR:
-	case NL80211_IFTYPE_WDS:
-		WL_ERR("type (%d) : currently we do not support this mode\n",
-		       iftype);
-		err = -EINVAL;
-		return err;
-	case NL80211_IFTYPE_ADHOC:
-		infra = 0;
-		break;
-	case NL80211_IFTYPE_STATION:
-		infra = 1;
-		break;
-	case NL80211_IFTYPE_AP:
-		infra = 1;
-		break;
-	default:
-		err = -EINVAL;
-		WL_ERR("invalid type (%d)\n", iftype);
-		return err;
-	}
-	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
-	if (err) {
-		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
-		return err;
-	}
-
-	return 0;
-}
-
 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
 {
 	/* Room for "event_msgs" + '\0' + bitvec */
@@ -5439,7 +5418,8 @@
 				WL_BEACON_TIMEOUT);
 	if (err)
 		goto default_conf_out;
-	err = brcmf_dongle_mode(ndev, wdev->iftype);
+	err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
+					  NULL, NULL);
 	if (err && err != -EINPROGRESS)
 		goto default_conf_out;
 	err = brcmf_dongle_probecap(cfg);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 935120f..768bf61 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -10472,7 +10472,7 @@
 		} else
 			len = src->len;
 
-		dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC);
+		dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC);
 		if (!dst)
 			continue;
 
diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c
index 349c205..da58620 100644
--- a/drivers/net/wireless/iwlwifi/dvm/devices.c
+++ b/drivers/net/wireless/iwlwifi/dvm/devices.c
@@ -518,7 +518,7 @@
 	 * See iwlagn_mac_channel_switch.
 	 */
 	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
-	struct iwl6000_channel_switch_cmd cmd;
+	struct iwl6000_channel_switch_cmd *cmd;
 	u32 switch_time_in_usec, ucode_switch_time;
 	u16 ch;
 	u32 tsf_low;
@@ -527,18 +527,25 @@
 	struct ieee80211_vif *vif = ctx->vif;
 	struct iwl_host_cmd hcmd = {
 		.id = REPLY_CHANNEL_SWITCH,
-		.len = { sizeof(cmd), },
+		.len = { sizeof(*cmd), },
 		.flags = CMD_SYNC,
-		.data = { &cmd, },
+		.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
 	};
+	int err;
 
-	cmd.band = priv->band == IEEE80211_BAND_2GHZ;
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	hcmd.data[0] = cmd;
+
+	cmd->band = priv->band == IEEE80211_BAND_2GHZ;
 	ch = ch_switch->channel->hw_value;
 	IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
 		      ctx->active.channel, ch);
-	cmd.channel = cpu_to_le16(ch);
-	cmd.rxon_flags = ctx->staging.flags;
-	cmd.rxon_filter_flags = ctx->staging.filter_flags;
+	cmd->channel = cpu_to_le16(ch);
+	cmd->rxon_flags = ctx->staging.flags;
+	cmd->rxon_filter_flags = ctx->staging.filter_flags;
 	switch_count = ch_switch->count;
 	tsf_low = ch_switch->timestamp & 0x0ffffffff;
 	/*
@@ -554,23 +561,25 @@
 			switch_count = 0;
 	}
 	if (switch_count <= 1)
-		cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
+		cmd->switch_time = cpu_to_le32(priv->ucode_beacon_time);
 	else {
 		switch_time_in_usec =
 			vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
 		ucode_switch_time = iwl_usecs_to_beacons(priv,
 							 switch_time_in_usec,
 							 beacon_interval);
-		cmd.switch_time = iwl_add_beacon_time(priv,
-						      priv->ucode_beacon_time,
-						      ucode_switch_time,
-						      beacon_interval);
+		cmd->switch_time = iwl_add_beacon_time(priv,
+						       priv->ucode_beacon_time,
+						       ucode_switch_time,
+						       beacon_interval);
 	}
 	IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
-		      cmd.switch_time);
-	cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR;
+		      cmd->switch_time);
+	cmd->expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR;
 
-	return iwl_dvm_send_cmd(priv, &hcmd);
+	err = iwl_dvm_send_cmd(priv, &hcmd);
+	kfree(cmd);
+	return err;
 }
 
 struct iwl_lib_ops iwl6000_lib = {
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index ff8162d..fa4d1b8 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -521,7 +521,7 @@
 		     ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
 
 	if (iwlagn_tx_skb(priv, control->sta, skb))
-		dev_kfree_skb_any(skb);
+		ieee80211_free_txskb(hw, skb);
 }
 
 static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 7ff3f14..408132c 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -2114,7 +2114,7 @@
 
 	info = IEEE80211_SKB_CB(skb);
 	iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]);
-	dev_kfree_skb_any(skb);
+	ieee80211_free_txskb(priv->hw, skb);
 }
 
 static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 17c8e5d..bb69f8f 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -321,6 +321,14 @@
 			dma_map_page(trans->dev, page, 0,
 				     PAGE_SIZE << trans_pcie->rx_page_order,
 				     DMA_FROM_DEVICE);
+		if (dma_mapping_error(trans->dev, rxb->page_dma)) {
+			rxb->page = NULL;
+			spin_lock_irqsave(&rxq->lock, flags);
+			list_add(&rxb->list, &rxq->rx_used);
+			spin_unlock_irqrestore(&rxq->lock, flags);
+			__free_pages(page, trans_pcie->rx_page_order);
+			return;
+		}
 		/* dma address must be no more than 36 bits */
 		BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
 		/* and also 256 byte aligned! */
@@ -488,8 +496,19 @@
 			dma_map_page(trans->dev, rxb->page, 0,
 				     PAGE_SIZE << trans_pcie->rx_page_order,
 				     DMA_FROM_DEVICE);
-		list_add_tail(&rxb->list, &rxq->rx_free);
-		rxq->free_count++;
+		if (dma_mapping_error(trans->dev, rxb->page_dma)) {
+			/*
+			 * free the page(s) as well to not break
+			 * the invariant that the items on the used
+			 * list have no page(s)
+			 */
+			__free_pages(rxb->page, trans_pcie->rx_page_order);
+			rxb->page = NULL;
+			list_add_tail(&rxb->list, &rxq->rx_used);
+		} else {
+			list_add_tail(&rxb->list, &rxq->rx_free);
+			rxq->free_count++;
+		}
 	} else
 		list_add_tail(&rxb->list, &rxq->rx_used);
 	spin_unlock_irqrestore(&rxq->lock, flags);
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 0679458..780d3e1 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1825,8 +1825,6 @@
 		return -EBUSY;
 	}
 
-	priv->scan_request = request;
-
 	priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
 				      GFP_KERNEL);
 	if (!priv->user_scan_cfg) {
@@ -1834,6 +1832,8 @@
 		return -ENOMEM;
 	}
 
+	priv->scan_request = request;
+
 	priv->user_scan_cfg->num_ssids = request->n_ssids;
 	priv->user_scan_cfg->ssid_list = request->ssids;
 
@@ -1870,6 +1870,9 @@
 	ret = mwifiex_scan_networks(priv, priv->user_scan_cfg);
 	if (ret) {
 		dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
+		priv->scan_request = NULL;
+		kfree(priv->user_scan_cfg);
+		priv->user_scan_cfg = NULL;
 		return ret;
 	}
 
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 00b658d..9171aae 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1843,21 +1843,18 @@
 				      struct cfg80211_ssid *req_ssid)
 {
 	struct mwifiex_adapter *adapter = priv->adapter;
-	int ret = 0;
+	int ret;
 	struct mwifiex_user_scan_cfg *scan_cfg;
 
-	if (!req_ssid)
-		return -1;
-
 	if (adapter->scan_processing) {
-		dev_dbg(adapter->dev, "cmd: Scan already in process...\n");
-		return ret;
+		dev_err(adapter->dev, "cmd: Scan already in process...\n");
+		return -EBUSY;
 	}
 
 	if (priv->scan_block) {
-		dev_dbg(adapter->dev,
+		dev_err(adapter->dev,
 			"cmd: Scan is blocked during association...\n");
-		return ret;
+		return -EBUSY;
 	}
 
 	scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index a12e84f..6b2e1e43 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1988,6 +1988,7 @@
 	.disconnect	= rt2x00usb_disconnect,
 	.suspend	= rt2x00usb_suspend,
 	.resume		= rt2x00usb_resume,
+	.reset_resume	= rt2x00usb_resume,
 	.disable_hub_initiated_lpm = 1,
 };
 
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 01dc889..59474ae 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2449,7 +2449,7 @@
 	/*
 	 * Check if temperature compensation is supported.
 	 */
-	if (tssi_bounds[4] == 0xff)
+	if (tssi_bounds[4] == 0xff || step == 0xff)
 		return 0;
 
 	/*
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index c9e9370..3b8fb5a 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1282,6 +1282,7 @@
 	.disconnect	= rt2x00usb_disconnect,
 	.suspend	= rt2x00usb_suspend,
 	.resume		= rt2x00usb_resume,
+	.reset_resume	= rt2x00usb_resume,
 	.disable_hub_initiated_lpm = 1,
 };
 
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index e5eb43b..24eec66 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2535,6 +2535,7 @@
 	.disconnect	= rt2x00usb_disconnect,
 	.suspend	= rt2x00usb_suspend,
 	.resume		= rt2x00usb_resume,
+	.reset_resume	= rt2x00usb_resume,
 	.disable_hub_initiated_lpm = 1,
 };
 
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 030beb4..e3ea4b3 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -673,7 +673,7 @@
 		set_hal_start(rtlhal);
 
 		/* Start bulk IN */
-		_rtl_usb_receive(hw);
+		err = _rtl_usb_receive(hw);
 	}
 
 	return err;
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 6241fd0..a543746 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -320,10 +320,7 @@
 		} else
 			next = dev->bus_list.next;
 
-		/* Run device routines with the device locked */
-		device_lock(&dev->dev);
 		retval = cb(dev, userdata);
-		device_unlock(&dev->dev);
 		if (retval)
 			break;
 	}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 94c6e2a..6c94fc9 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -398,6 +398,8 @@
 	struct pci_dev *pci_dev = to_pci_dev(dev);
 	struct pci_driver *drv = pci_dev->driver;
 
+	pm_runtime_resume(dev);
+
 	if (drv && drv->shutdown)
 		drv->shutdown(pci_dev);
 	pci_msi_shutdown(pci_dev);
@@ -408,16 +410,6 @@
 	 * continue to do DMA
 	 */
 	pci_disable_device(pci_dev);
-
-	/*
-	 * Devices may be enabled to wake up by runtime PM, but they need not
-	 * be supposed to wake up the system from its "power off" state (e.g.
-	 * ACPI S5).  Therefore disable wakeup for all devices that aren't
-	 * supposed to wake up the system at this point.  The state argument
-	 * will be ignored by pci_enable_wake().
-	 */
-	if (!device_may_wakeup(dev))
-		pci_enable_wake(pci_dev, PCI_UNKNOWN, false);
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 02d107b..f39378d 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -458,40 +458,6 @@
 }
 struct device_attribute vga_attr = __ATTR_RO(boot_vga);
 
-static void
-pci_config_pm_runtime_get(struct pci_dev *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct device *parent = dev->parent;
-
-	if (parent)
-		pm_runtime_get_sync(parent);
-	pm_runtime_get_noresume(dev);
-	/*
-	 * pdev->current_state is set to PCI_D3cold during suspending,
-	 * so wait until suspending completes
-	 */
-	pm_runtime_barrier(dev);
-	/*
-	 * Only need to resume devices in D3cold, because config
-	 * registers are still accessible for devices suspended but
-	 * not in D3cold.
-	 */
-	if (pdev->current_state == PCI_D3cold)
-		pm_runtime_resume(dev);
-}
-
-static void
-pci_config_pm_runtime_put(struct pci_dev *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct device *parent = dev->parent;
-
-	pm_runtime_put(dev);
-	if (parent)
-		pm_runtime_put_sync(parent);
-}
-
 static ssize_t
 pci_read_config(struct file *filp, struct kobject *kobj,
 		struct bin_attribute *bin_attr,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 5485883..aabf647 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1858,6 +1858,38 @@
 }
 EXPORT_SYMBOL_GPL(pci_dev_run_wake);
 
+void pci_config_pm_runtime_get(struct pci_dev *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device *parent = dev->parent;
+
+	if (parent)
+		pm_runtime_get_sync(parent);
+	pm_runtime_get_noresume(dev);
+	/*
+	 * pdev->current_state is set to PCI_D3cold during suspending,
+	 * so wait until suspending completes
+	 */
+	pm_runtime_barrier(dev);
+	/*
+	 * Only need to resume devices in D3cold, because config
+	 * registers are still accessible for devices suspended but
+	 * not in D3cold.
+	 */
+	if (pdev->current_state == PCI_D3cold)
+		pm_runtime_resume(dev);
+}
+
+void pci_config_pm_runtime_put(struct pci_dev *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device *parent = dev->parent;
+
+	pm_runtime_put(dev);
+	if (parent)
+		pm_runtime_put_sync(parent);
+}
+
 /**
  * pci_pm_init - Initialize PM functions of given PCI device
  * @dev: PCI device to handle.
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index bacbcba..fd92aab 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -72,6 +72,8 @@
 extern int pci_finish_runtime_suspend(struct pci_dev *dev);
 extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign);
 extern void pci_wakeup_bus(struct pci_bus *bus);
+extern void pci_config_pm_runtime_get(struct pci_dev *dev);
+extern void pci_config_pm_runtime_put(struct pci_dev *dev);
 extern void pci_pm_init(struct pci_dev *dev);
 extern void platform_pci_wakeup_init(struct pci_dev *dev);
 extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 06bad96..af4e31c 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -213,6 +213,7 @@
 	struct aer_broadcast_data *result_data;
 	result_data = (struct aer_broadcast_data *) data;
 
+	device_lock(&dev->dev);
 	dev->error_state = result_data->state;
 
 	if (!dev->driver ||
@@ -231,12 +232,14 @@
 				   dev->driver ?
 				   "no AER-aware driver" : "no driver");
 		}
-		return 0;
+		goto out;
 	}
 
 	err_handler = dev->driver->err_handler;
 	vote = err_handler->error_detected(dev, result_data->state);
 	result_data->result = merge_result(result_data->result, vote);
+out:
+	device_unlock(&dev->dev);
 	return 0;
 }
 
@@ -247,14 +250,17 @@
 	struct aer_broadcast_data *result_data;
 	result_data = (struct aer_broadcast_data *) data;
 
+	device_lock(&dev->dev);
 	if (!dev->driver ||
 		!dev->driver->err_handler ||
 		!dev->driver->err_handler->mmio_enabled)
-		return 0;
+		goto out;
 
 	err_handler = dev->driver->err_handler;
 	vote = err_handler->mmio_enabled(dev);
 	result_data->result = merge_result(result_data->result, vote);
+out:
+	device_unlock(&dev->dev);
 	return 0;
 }
 
@@ -265,14 +271,17 @@
 	struct aer_broadcast_data *result_data;
 	result_data = (struct aer_broadcast_data *) data;
 
+	device_lock(&dev->dev);
 	if (!dev->driver ||
 		!dev->driver->err_handler ||
 		!dev->driver->err_handler->slot_reset)
-		return 0;
+		goto out;
 
 	err_handler = dev->driver->err_handler;
 	vote = err_handler->slot_reset(dev);
 	result_data->result = merge_result(result_data->result, vote);
+out:
+	device_unlock(&dev->dev);
 	return 0;
 }
 
@@ -280,15 +289,18 @@
 {
 	const struct pci_error_handlers *err_handler;
 
+	device_lock(&dev->dev);
 	dev->error_state = pci_channel_io_normal;
 
 	if (!dev->driver ||
 		!dev->driver->err_handler ||
 		!dev->driver->err_handler->resume)
-		return 0;
+		goto out;
 
 	err_handler = dev->driver->err_handler;
 	err_handler->resume(dev);
+out:
+	device_unlock(&dev->dev);
 	return 0;
 }
 
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index d03a7a3..ed129b4 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -272,7 +272,8 @@
 	}
 
 	/* Hot-Plug Capable */
-	if (cap_mask & PCIE_PORT_SERVICE_HP) {
+	if ((cap_mask & PCIE_PORT_SERVICE_HP) &&
+	    dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT) {
 		pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, &reg32);
 		if (reg32 & PCI_EXP_SLTCAP_HPC) {
 			services |= PCIE_PORT_SERVICE_HP;
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index eb907a8f..9b8505c 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -76,6 +76,8 @@
 	if (!access_ok(VERIFY_WRITE, buf, cnt))
 		return -EINVAL;
 
+	pci_config_pm_runtime_get(dev);
+
 	if ((pos & 1) && cnt) {
 		unsigned char val;
 		pci_user_read_config_byte(dev, pos, &val);
@@ -121,6 +123,8 @@
 		cnt--;
 	}
 
+	pci_config_pm_runtime_put(dev);
+
 	*ppos = pos;
 	return nbytes;
 }
@@ -146,6 +150,8 @@
 	if (!access_ok(VERIFY_READ, buf, cnt))
 		return -EINVAL;
 
+	pci_config_pm_runtime_get(dev);
+
 	if ((pos & 1) && cnt) {
 		unsigned char val;
 		__get_user(val, buf);
@@ -191,6 +197,8 @@
 		cnt--;
 	}
 
+	pci_config_pm_runtime_put(dev);
+
 	*ppos = pos;
 	i_size_write(ino, dp->size);
 	return nbytes;
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 7bf914d..dd08b49 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -179,13 +179,20 @@
 
 config PINCTRL_SAMSUNG
 	bool "Samsung pinctrl driver"
+	depends on OF && GPIOLIB
 	select PINMUX
 	select PINCONF
 
 config PINCTRL_EXYNOS4
 	bool "Pinctrl driver data for Exynos4 SoC"
+	depends on OF && GPIOLIB
 	select PINCTRL_SAMSUNG
 
+config PINCTRL_EXYNOS5440
+	bool "Samsung EXYNOS5440 SoC pinctrl driver"
+	select PINMUX
+	select PINCONF
+
 config PINCTRL_MVEBU
 	bool
 	depends on ARCH_MVEBU
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index f395ba5..476928b 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -36,6 +36,7 @@
 obj-$(CONFIG_PINCTRL_COH901)	+= pinctrl-coh901.o
 obj-$(CONFIG_PINCTRL_SAMSUNG)	+= pinctrl-samsung.o
 obj-$(CONFIG_PINCTRL_EXYNOS4)	+= pinctrl-exynos.o
+obj-$(CONFIG_PINCTRL_EXYNOS5440)	+= pinctrl-exynos5440.o
 obj-$(CONFIG_PINCTRL_MVEBU)	+= pinctrl-mvebu.o
 obj-$(CONFIG_PINCTRL_DOVE)	+= pinctrl-dove.o
 obj-$(CONFIG_PINCTRL_KIRKWOOD)	+= pinctrl-kirkwood.o
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 0f1ec9e..2e39c04 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -1061,8 +1061,10 @@
 			seq_printf(s, "group: %s\n", gname);
 			for (i = 0; i < num_pins; i++) {
 				pname = pin_get_name(pctldev, pins[i]);
-				if (WARN_ON(!pname))
+				if (WARN_ON(!pname)) {
+					mutex_unlock(&pinctrl_mutex);
 					return -EINVAL;
+				}
 				seq_printf(s, "pin %d (%s)\n", pins[i], pname);
 			}
 			seq_puts(s, "\n");
diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c
index 43f474c..baee2cc 100644
--- a/drivers/pinctrl/pinconf.c
+++ b/drivers/pinctrl/pinconf.c
@@ -537,8 +537,6 @@
 	seq_puts(s, "Pin config settings per pin group\n");
 	seq_puts(s, "Format: group (name): configs\n");
 
-	mutex_lock(&pinctrl_mutex);
-
 	while (selector < ngroups) {
 		const char *gname = pctlops->get_group_name(pctldev, selector);
 
@@ -549,8 +547,6 @@
 		selector++;
 	}
 
-	mutex_unlock(&pinctrl_mutex);
-
 	return 0;
 }
 
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 21362f4..19fab68 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -40,46 +40,46 @@
 
 static void exynos_gpio_irq_unmask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask &= ~(1 << edata->pin);
+	mask &= ~(1 << irqd->hwirq);
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_gpio_irq_mask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask |= 1 << edata->pin;
+	mask |= 1 << irqd->hwirq;
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_gpio_irq_ack(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	unsigned long reg_pend = d->ctrl->geint_pend + edata->eint_offset;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
 
-	writel(1 << edata->pin, d->virt_base + reg_pend);
+	writel(1 << irqd->hwirq, d->virt_base + reg_pend);
 }
 
 static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
 {
-	struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	struct samsung_pin_ctrl *ctrl = d->ctrl;
-	struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
-	struct samsung_pin_bank *bank = edata->bank;
-	unsigned int shift = EXYNOS_EINT_CON_LEN * edata->pin;
+	unsigned int pin = irqd->hwirq;
+	unsigned int shift = EXYNOS_EINT_CON_LEN * pin;
 	unsigned int con, trig_type;
-	unsigned long reg_con = ctrl->geint_con + edata->eint_offset;
+	unsigned long reg_con = ctrl->geint_con + bank->eint_offset;
 	unsigned int mask;
 
 	switch (type) {
@@ -114,7 +114,7 @@
 	writel(con, d->virt_base + reg_con);
 
 	reg_con = bank->pctl_offset;
-	shift = edata->pin * bank->func_width;
+	shift = pin * bank->func_width;
 	mask = (1 << bank->func_width) - 1;
 
 	con = readl(d->virt_base + reg_con);
@@ -136,82 +136,23 @@
 	.irq_set_type	= exynos_gpio_irq_set_type,
 };
 
-/*
- * given a controller-local external gpio interrupt number, prepare the handler
- * data for it.
- */
-static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw,
-				struct samsung_pinctrl_drv_data *d)
-{
-	struct samsung_pin_bank *bank = d->ctrl->pin_banks;
-	struct exynos_geint_data *eint_data;
-	unsigned int nr_banks = d->ctrl->nr_banks, idx;
-	unsigned int irq_base = 0, eint_offset = 0;
-
-	if (hw >= d->ctrl->nr_gint) {
-		dev_err(d->dev, "unsupported ext-gpio interrupt\n");
-		return NULL;
-	}
-
-	for (idx = 0; idx < nr_banks; idx++, bank++) {
-		if (bank->eint_type != EINT_TYPE_GPIO)
-			continue;
-		if ((hw >= irq_base) && (hw < (irq_base + bank->nr_pins)))
-			break;
-		irq_base += bank->nr_pins;
-		eint_offset += 4;
-	}
-
-	if (idx == nr_banks) {
-		dev_err(d->dev, "pin bank not found for ext-gpio interrupt\n");
-		return NULL;
-	}
-
-	eint_data = devm_kzalloc(d->dev, sizeof(*eint_data), GFP_KERNEL);
-	if (!eint_data) {
-		dev_err(d->dev, "no memory for eint-gpio data\n");
-		return NULL;
-	}
-
-	eint_data->bank	= bank;
-	eint_data->pin = hw - irq_base;
-	eint_data->eint_offset = eint_offset;
-	return eint_data;
-}
-
 static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
 					irq_hw_number_t hw)
 {
-	struct samsung_pinctrl_drv_data *d = h->host_data;
-	struct exynos_geint_data *eint_data;
+	struct samsung_pin_bank *b = h->host_data;
 
-	eint_data = exynos_get_eint_data(hw, d);
-	if (!eint_data)
-		return -EINVAL;
-
-	irq_set_handler_data(virq, eint_data);
-	irq_set_chip_data(virq, h->host_data);
+	irq_set_chip_data(virq, b);
 	irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip,
 					handle_level_irq);
 	set_irq_flags(virq, IRQF_VALID);
 	return 0;
 }
 
-static void exynos_gpio_irq_unmap(struct irq_domain *h, unsigned int virq)
-{
-	struct samsung_pinctrl_drv_data *d = h->host_data;
-	struct exynos_geint_data *eint_data;
-
-	eint_data = irq_get_handler_data(virq);
-	devm_kfree(d->dev, eint_data);
-}
-
 /*
  * irq domain callbacks for external gpio interrupt controller.
  */
 static const struct irq_domain_ops exynos_gpio_irqd_ops = {
 	.map	= exynos_gpio_irq_map,
-	.unmap	= exynos_gpio_irq_unmap,
 	.xlate	= irq_domain_xlate_twocell,
 };
 
@@ -230,7 +171,7 @@
 		return IRQ_HANDLED;
 	bank += (group - 1);
 
-	virq = irq_linear_revmap(d->gpio_irqd, bank->irq_base + pin);
+	virq = irq_linear_revmap(bank->irq_domain, pin);
 	if (!virq)
 		return IRQ_NONE;
 	generic_handle_irq(virq);
@@ -243,8 +184,10 @@
  */
 static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 {
+	struct samsung_pin_bank *bank;
 	struct device *dev = d->dev;
 	unsigned int ret;
+	unsigned int i;
 
 	if (!d->irq) {
 		dev_err(dev, "irq number not available\n");
@@ -258,11 +201,16 @@
 		return -ENXIO;
 	}
 
-	d->gpio_irqd = irq_domain_add_linear(dev->of_node, d->ctrl->nr_gint,
-				&exynos_gpio_irqd_ops, d);
-	if (!d->gpio_irqd) {
-		dev_err(dev, "gpio irq domain allocation failed\n");
-		return -ENXIO;
+	bank = d->ctrl->pin_banks;
+	for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+		if (bank->eint_type != EINT_TYPE_GPIO)
+			continue;
+		bank->irq_domain = irq_domain_add_linear(bank->of_node,
+				bank->nr_pins, &exynos_gpio_irqd_ops, bank);
+		if (!bank->irq_domain) {
+			dev_err(dev, "gpio irq domain add failed\n");
+			return -ENXIO;
+		}
 	}
 
 	return 0;
@@ -270,48 +218,46 @@
 
 static void exynos_wkup_irq_unmask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2);
+	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = b->drvdata;
+	unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask &= ~(1 << pin);
+	mask &= ~(1 << irqd->hwirq);
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_wkup_irq_mask(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2);
+	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = b->drvdata;
+	unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
 	unsigned long mask;
 
 	mask = readl(d->virt_base + reg_mask);
-	mask |= 1 << pin;
+	mask |= 1 << irqd->hwirq;
 	writel(mask, d->virt_base + reg_mask);
 }
 
 static void exynos_wkup_irq_ack(struct irq_data *irqd)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long pend = d->ctrl->weint_pend + (bank << 2);
+	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = b->drvdata;
+	unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
 
-	writel(1 << pin, d->virt_base + pend);
+	writel(1 << irqd->hwirq, d->virt_base + pend);
 }
 
 static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
 {
-	struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
-	unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
-	unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
-	unsigned long reg_con = d->ctrl->weint_con + (bank << 2);
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned int pin = irqd->hwirq;
+	unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset;
 	unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
 	unsigned long con, trig_type;
+	unsigned int mask;
 
 	switch (type) {
 	case IRQ_TYPE_EDGE_RISING:
@@ -343,6 +289,16 @@
 	con &= ~(EXYNOS_EINT_CON_MASK << shift);
 	con |= trig_type << shift;
 	writel(con, d->virt_base + reg_con);
+
+	reg_con = bank->pctl_offset;
+	shift = pin * bank->func_width;
+	mask = (1 << bank->func_width) - 1;
+
+	con = readl(d->virt_base + reg_con);
+	con &= ~(mask << shift);
+	con |= EXYNOS_EINT_FUNC << shift;
+	writel(con, d->virt_base + reg_con);
+
 	return 0;
 }
 
@@ -361,6 +317,7 @@
 static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
 {
 	struct exynos_weint_data *eintd = irq_get_handler_data(irq);
+	struct samsung_pin_bank *bank = eintd->bank;
 	struct irq_chip *chip = irq_get_chip(irq);
 	int eint_irq;
 
@@ -370,20 +327,20 @@
 	if (chip->irq_ack)
 		chip->irq_ack(&desc->irq_data);
 
-	eint_irq = irq_linear_revmap(eintd->domain, eintd->irq);
+	eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq);
 	generic_handle_irq(eint_irq);
 	chip->irq_unmask(&desc->irq_data);
 	chained_irq_exit(chip, desc);
 }
 
-static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend,
-					struct irq_domain *domain)
+static inline void exynos_irq_demux_eint(unsigned long pend,
+						struct irq_domain *domain)
 {
 	unsigned int irq;
 
 	while (pend) {
 		irq = fls(pend) - 1;
-		generic_handle_irq(irq_find_mapping(domain, irq_base + irq));
+		generic_handle_irq(irq_find_mapping(domain, irq));
 		pend &= ~(1 << irq);
 	}
 }
@@ -392,18 +349,22 @@
 static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_get_chip(irq);
-	struct exynos_weint_data *eintd = irq_get_handler_data(irq);
-	struct samsung_pinctrl_drv_data *d = eintd->domain->host_data;
+	struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq);
+	struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
+	struct samsung_pin_ctrl *ctrl = d->ctrl;
 	unsigned long pend;
 	unsigned long mask;
+	int i;
 
 	chained_irq_enter(chip, desc);
-	pend = readl(d->virt_base + d->ctrl->weint_pend + 0x8);
-	mask = readl(d->virt_base + d->ctrl->weint_mask + 0x8);
-	exynos_irq_demux_eint(16, pend & ~mask, eintd->domain);
-	pend = readl(d->virt_base + d->ctrl->weint_pend + 0xC);
-	mask = readl(d->virt_base + d->ctrl->weint_mask + 0xC);
-	exynos_irq_demux_eint(24, pend & ~mask, eintd->domain);
+
+	for (i = 0; i < eintd->nr_banks; ++i) {
+		struct samsung_pin_bank *b = eintd->banks[i];
+		pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset);
+		mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset);
+		exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
+	}
+
 	chained_irq_exit(chip, desc);
 }
 
@@ -433,7 +394,11 @@
 	struct device *dev = d->dev;
 	struct device_node *wkup_np = NULL;
 	struct device_node *np;
+	struct samsung_pin_bank *bank;
 	struct exynos_weint_data *weint_data;
+	struct exynos_muxed_weint_data *muxed_data;
+	unsigned int muxed_banks = 0;
+	unsigned int i;
 	int idx, irq;
 
 	for_each_child_of_node(dev->of_node, np) {
@@ -445,90 +410,124 @@
 	if (!wkup_np)
 		return -ENODEV;
 
-	d->wkup_irqd = irq_domain_add_linear(wkup_np, d->ctrl->nr_wint,
-				&exynos_wkup_irqd_ops, d);
-	if (!d->wkup_irqd) {
-		dev_err(dev, "wakeup irq domain allocation failed\n");
-		return -ENXIO;
+	bank = d->ctrl->pin_banks;
+	for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+		if (bank->eint_type != EINT_TYPE_WKUP)
+			continue;
+
+		bank->irq_domain = irq_domain_add_linear(bank->of_node,
+				bank->nr_pins, &exynos_wkup_irqd_ops, bank);
+		if (!bank->irq_domain) {
+			dev_err(dev, "wkup irq domain add failed\n");
+			return -ENXIO;
+		}
+
+		if (!of_find_property(bank->of_node, "interrupts", NULL)) {
+			bank->eint_type = EINT_TYPE_WKUP_MUX;
+			++muxed_banks;
+			continue;
+		}
+
+		weint_data = devm_kzalloc(dev, bank->nr_pins
+					* sizeof(*weint_data), GFP_KERNEL);
+		if (!weint_data) {
+			dev_err(dev, "could not allocate memory for weint_data\n");
+			return -ENOMEM;
+		}
+
+		for (idx = 0; idx < bank->nr_pins; ++idx) {
+			irq = irq_of_parse_and_map(bank->of_node, idx);
+			if (!irq) {
+				dev_err(dev, "irq number for eint-%s-%d not found\n",
+							bank->name, idx);
+				continue;
+			}
+			weint_data[idx].irq = idx;
+			weint_data[idx].bank = bank;
+			irq_set_handler_data(irq, &weint_data[idx]);
+			irq_set_chained_handler(irq, exynos_irq_eint0_15);
+		}
 	}
 
-	weint_data = devm_kzalloc(dev, sizeof(*weint_data) * 17, GFP_KERNEL);
-	if (!weint_data) {
-		dev_err(dev, "could not allocate memory for weint_data\n");
+	if (!muxed_banks)
+		return 0;
+
+	irq = irq_of_parse_and_map(wkup_np, 0);
+	if (!irq) {
+		dev_err(dev, "irq number for muxed EINTs not found\n");
+		return 0;
+	}
+
+	muxed_data = devm_kzalloc(dev, sizeof(*muxed_data)
+		+ muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL);
+	if (!muxed_data) {
+		dev_err(dev, "could not allocate memory for muxed_data\n");
 		return -ENOMEM;
 	}
 
-	irq = irq_of_parse_and_map(wkup_np, 16);
-	if (irq) {
-		weint_data[16].domain = d->wkup_irqd;
-		irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
-		irq_set_handler_data(irq, &weint_data[16]);
-	} else {
-		dev_err(dev, "irq number for EINT16-32 not found\n");
-	}
+	irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
+	irq_set_handler_data(irq, muxed_data);
 
-	for (idx = 0; idx < 16; idx++) {
-		weint_data[idx].domain = d->wkup_irqd;
-		weint_data[idx].irq = idx;
+	bank = d->ctrl->pin_banks;
+	idx = 0;
+	for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+		if (bank->eint_type != EINT_TYPE_WKUP_MUX)
+			continue;
 
-		irq = irq_of_parse_and_map(wkup_np, idx);
-		if (irq) {
-			irq_set_handler_data(irq, &weint_data[idx]);
-			irq_set_chained_handler(irq, exynos_irq_eint0_15);
-		} else {
-			dev_err(dev, "irq number for eint-%x not found\n", idx);
-		}
+		muxed_data->banks[idx++] = bank;
 	}
+	muxed_data->nr_banks = muxed_banks;
+
 	return 0;
 }
 
 /* pin banks of exynos4210 pin-controller 0 */
 static struct samsung_pin_bank exynos4210_pin_banks0[] = {
-	EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_A0, "gpa0"),
-	EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_A1, "gpa1"),
-	EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_B, "gpb"),
-	EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_C0, "gpc0"),
-	EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_C1, "gpc1"),
-	EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_D0, "gpd0"),
-	EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_D1, "gpd1"),
-	EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_E0, "gpe0"),
-	EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_E1, "gpe1"),
-	EXYNOS_PIN_BANK_EINTG(0x120, EXYNOS4210_GPIO_E2, "gpe2"),
-	EXYNOS_PIN_BANK_EINTG(0x140, EXYNOS4210_GPIO_E3, "gpe3"),
-	EXYNOS_PIN_BANK_EINTG(0x160, EXYNOS4210_GPIO_E4, "gpe4"),
-	EXYNOS_PIN_BANK_EINTG(0x180, EXYNOS4210_GPIO_F0, "gpf0"),
-	EXYNOS_PIN_BANK_EINTG(0x1A0, EXYNOS4210_GPIO_F1, "gpf1"),
-	EXYNOS_PIN_BANK_EINTG(0x1C0, EXYNOS4210_GPIO_F2, "gpf2"),
-	EXYNOS_PIN_BANK_EINTG(0x1E0, EXYNOS4210_GPIO_F3, "gpf3"),
+	EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
+	EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
+	EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
+	EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
+	EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
+	EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14),
+	EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18),
+	EXYNOS_PIN_BANK_EINTG(5, 0x0E0, "gpe0", 0x1c),
+	EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpe1", 0x20),
+	EXYNOS_PIN_BANK_EINTG(6, 0x120, "gpe2", 0x24),
+	EXYNOS_PIN_BANK_EINTG(8, 0x140, "gpe3", 0x28),
+	EXYNOS_PIN_BANK_EINTG(8, 0x160, "gpe4", 0x2c),
+	EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30),
+	EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34),
+	EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38),
+	EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c),
 };
 
 /* pin banks of exynos4210 pin-controller 1 */
 static struct samsung_pin_bank exynos4210_pin_banks1[] = {
-	EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_J0, "gpj0"),
-	EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_J1, "gpj1"),
-	EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_K0, "gpk0"),
-	EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_K1, "gpk1"),
-	EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_K2, "gpk2"),
-	EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_K3, "gpk3"),
-	EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_L0, "gpl0"),
-	EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_L1, "gpl1"),
-	EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_L2, "gpl2"),
-	EXYNOS_PIN_BANK_EINTN(0x120, EXYNOS4210_GPIO_Y0, "gpy0"),
-	EXYNOS_PIN_BANK_EINTN(0x140, EXYNOS4210_GPIO_Y1, "gpy1"),
-	EXYNOS_PIN_BANK_EINTN(0x160, EXYNOS4210_GPIO_Y2, "gpy2"),
-	EXYNOS_PIN_BANK_EINTN(0x180, EXYNOS4210_GPIO_Y3, "gpy3"),
-	EXYNOS_PIN_BANK_EINTN(0x1A0, EXYNOS4210_GPIO_Y4, "gpy4"),
-	EXYNOS_PIN_BANK_EINTN(0x1C0, EXYNOS4210_GPIO_Y5, "gpy5"),
-	EXYNOS_PIN_BANK_EINTN(0x1E0, EXYNOS4210_GPIO_Y6, "gpy6"),
-	EXYNOS_PIN_BANK_EINTN(0xC00, EXYNOS4210_GPIO_X0, "gpx0"),
-	EXYNOS_PIN_BANK_EINTN(0xC20, EXYNOS4210_GPIO_X1, "gpx1"),
-	EXYNOS_PIN_BANK_EINTN(0xC40, EXYNOS4210_GPIO_X2, "gpx2"),
-	EXYNOS_PIN_BANK_EINTN(0xC60, EXYNOS4210_GPIO_X3, "gpx3"),
+	EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpj0", 0x00),
+	EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpj1", 0x04),
+	EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08),
+	EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
+	EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
+	EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14),
+	EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpl0", 0x18),
+	EXYNOS_PIN_BANK_EINTG(3, 0x0E0, "gpl1", 0x1c),
+	EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20),
+	EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"),
+	EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"),
+	EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
 };
 
 /* pin banks of exynos4210 pin-controller 2 */
 static struct samsung_pin_bank exynos4210_pin_banks2[] = {
-	EXYNOS_PIN_BANK_EINTN(0x000, EXYNOS4210_GPIO_Z, "gpz"),
+	EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"),
 };
 
 /*
@@ -540,9 +539,6 @@
 		/* pin-controller instance 0 data */
 		.pin_banks	= exynos4210_pin_banks0,
 		.nr_banks	= ARRAY_SIZE(exynos4210_pin_banks0),
-		.base		= EXYNOS4210_GPIO_A0_START,
-		.nr_pins	= EXYNOS4210_GPIOA_NR_PINS,
-		.nr_gint	= EXYNOS4210_GPIOA_NR_GINT,
 		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
 		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
 		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
@@ -553,10 +549,6 @@
 		/* pin-controller instance 1 data */
 		.pin_banks	= exynos4210_pin_banks1,
 		.nr_banks	= ARRAY_SIZE(exynos4210_pin_banks1),
-		.base		= EXYNOS4210_GPIOA_NR_PINS,
-		.nr_pins	= EXYNOS4210_GPIOB_NR_PINS,
-		.nr_gint	= EXYNOS4210_GPIOB_NR_GINT,
-		.nr_wint	= 32,
 		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
 		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
 		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
@@ -571,9 +563,116 @@
 		/* pin-controller instance 2 data */
 		.pin_banks	= exynos4210_pin_banks2,
 		.nr_banks	= ARRAY_SIZE(exynos4210_pin_banks2),
-		.base		= EXYNOS4210_GPIOA_NR_PINS +
-					EXYNOS4210_GPIOB_NR_PINS,
-		.nr_pins	= EXYNOS4210_GPIOC_NR_PINS,
 		.label		= "exynos4210-gpio-ctrl2",
 	},
 };
+
+/* pin banks of exynos4x12 pin-controller 0 */
+static struct samsung_pin_bank exynos4x12_pin_banks0[] = {
+	EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
+	EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
+	EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
+	EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
+	EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
+	EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14),
+	EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18),
+	EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30),
+	EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34),
+	EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38),
+	EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c),
+	EXYNOS_PIN_BANK_EINTG(8, 0x240, "gpj0", 0x40),
+	EXYNOS_PIN_BANK_EINTG(5, 0x260, "gpj1", 0x44),
+};
+
+/* pin banks of exynos4x12 pin-controller 1 */
+static struct samsung_pin_bank exynos4x12_pin_banks1[] = {
+	EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08),
+	EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
+	EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
+	EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14),
+	EXYNOS_PIN_BANK_EINTG(7, 0x0C0, "gpl0", 0x18),
+	EXYNOS_PIN_BANK_EINTG(2, 0x0E0, "gpl1", 0x1c),
+	EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20),
+	EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24),
+	EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28),
+	EXYNOS_PIN_BANK_EINTG(5, 0x2A0, "gpm2", 0x2c),
+	EXYNOS_PIN_BANK_EINTG(8, 0x2C0, "gpm3", 0x30),
+	EXYNOS_PIN_BANK_EINTG(8, 0x2E0, "gpm4", 0x34),
+	EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"),
+	EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"),
+	EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
+};
+
+/* pin banks of exynos4x12 pin-controller 2 */
+static struct samsung_pin_bank exynos4x12_pin_banks2[] = {
+	EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
+};
+
+/* pin banks of exynos4x12 pin-controller 3 */
+static struct samsung_pin_bank exynos4x12_pin_banks3[] = {
+	EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00),
+	EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04),
+	EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpv2", 0x08),
+	EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv3", 0x0c),
+	EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpv4", 0x10),
+};
+
+/*
+ * Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes
+ * four gpio/pin-mux/pinconfig controllers.
+ */
+struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
+	{
+		/* pin-controller instance 0 data */
+		.pin_banks	= exynos4x12_pin_banks0,
+		.nr_banks	= ARRAY_SIZE(exynos4x12_pin_banks0),
+		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
+		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
+		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
+		.svc		= EXYNOS_SVC_OFFSET,
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.label		= "exynos4x12-gpio-ctrl0",
+	}, {
+		/* pin-controller instance 1 data */
+		.pin_banks	= exynos4x12_pin_banks1,
+		.nr_banks	= ARRAY_SIZE(exynos4x12_pin_banks1),
+		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
+		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
+		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
+		.weint_con	= EXYNOS_WKUP_ECON_OFFSET,
+		.weint_mask	= EXYNOS_WKUP_EMASK_OFFSET,
+		.weint_pend	= EXYNOS_WKUP_EPEND_OFFSET,
+		.svc		= EXYNOS_SVC_OFFSET,
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.eint_wkup_init = exynos_eint_wkup_init,
+		.label		= "exynos4x12-gpio-ctrl1",
+	}, {
+		/* pin-controller instance 2 data */
+		.pin_banks	= exynos4x12_pin_banks2,
+		.nr_banks	= ARRAY_SIZE(exynos4x12_pin_banks2),
+		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
+		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
+		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
+		.svc		= EXYNOS_SVC_OFFSET,
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.label		= "exynos4x12-gpio-ctrl2",
+	}, {
+		/* pin-controller instance 3 data */
+		.pin_banks	= exynos4x12_pin_banks3,
+		.nr_banks	= ARRAY_SIZE(exynos4x12_pin_banks3),
+		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
+		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
+		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
+		.svc		= EXYNOS_SVC_OFFSET,
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.label		= "exynos4x12-gpio-ctrl3",
+	},
+};
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h
index 31d0a06..0a70889 100644
--- a/drivers/pinctrl/pinctrl-exynos.h
+++ b/drivers/pinctrl/pinctrl-exynos.h
@@ -17,125 +17,6 @@
  * (at your option) any later version.
  */
 
-#define EXYNOS_GPIO_START(__gpio)	((__gpio##_START) + (__gpio##_NR))
-
-#define EXYNOS4210_GPIO_A0_NR	(8)
-#define EXYNOS4210_GPIO_A1_NR	(6)
-#define EXYNOS4210_GPIO_B_NR	(8)
-#define EXYNOS4210_GPIO_C0_NR	(5)
-#define EXYNOS4210_GPIO_C1_NR	(5)
-#define EXYNOS4210_GPIO_D0_NR	(4)
-#define EXYNOS4210_GPIO_D1_NR	(4)
-#define EXYNOS4210_GPIO_E0_NR	(5)
-#define EXYNOS4210_GPIO_E1_NR	(8)
-#define EXYNOS4210_GPIO_E2_NR	(6)
-#define EXYNOS4210_GPIO_E3_NR	(8)
-#define EXYNOS4210_GPIO_E4_NR	(8)
-#define EXYNOS4210_GPIO_F0_NR	(8)
-#define EXYNOS4210_GPIO_F1_NR	(8)
-#define EXYNOS4210_GPIO_F2_NR	(8)
-#define EXYNOS4210_GPIO_F3_NR	(6)
-#define EXYNOS4210_GPIO_J0_NR	(8)
-#define EXYNOS4210_GPIO_J1_NR	(5)
-#define EXYNOS4210_GPIO_K0_NR	(7)
-#define EXYNOS4210_GPIO_K1_NR	(7)
-#define EXYNOS4210_GPIO_K2_NR	(7)
-#define EXYNOS4210_GPIO_K3_NR	(7)
-#define EXYNOS4210_GPIO_L0_NR	(8)
-#define EXYNOS4210_GPIO_L1_NR	(3)
-#define EXYNOS4210_GPIO_L2_NR	(8)
-#define EXYNOS4210_GPIO_Y0_NR	(6)
-#define EXYNOS4210_GPIO_Y1_NR	(4)
-#define EXYNOS4210_GPIO_Y2_NR	(6)
-#define EXYNOS4210_GPIO_Y3_NR	(8)
-#define EXYNOS4210_GPIO_Y4_NR	(8)
-#define EXYNOS4210_GPIO_Y5_NR	(8)
-#define EXYNOS4210_GPIO_Y6_NR	(8)
-#define EXYNOS4210_GPIO_X0_NR	(8)
-#define EXYNOS4210_GPIO_X1_NR	(8)
-#define EXYNOS4210_GPIO_X2_NR	(8)
-#define EXYNOS4210_GPIO_X3_NR	(8)
-#define EXYNOS4210_GPIO_Z_NR	(7)
-
-enum exynos4210_gpio_xa_start {
-	EXYNOS4210_GPIO_A0_START	= 0,
-	EXYNOS4210_GPIO_A1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_A0),
-	EXYNOS4210_GPIO_B_START		= EXYNOS_GPIO_START(EXYNOS4210_GPIO_A1),
-	EXYNOS4210_GPIO_C0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_B),
-	EXYNOS4210_GPIO_C1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_C0),
-	EXYNOS4210_GPIO_D0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_C1),
-	EXYNOS4210_GPIO_D1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_D0),
-	EXYNOS4210_GPIO_E0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_D1),
-	EXYNOS4210_GPIO_E1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E0),
-	EXYNOS4210_GPIO_E2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E1),
-	EXYNOS4210_GPIO_E3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E2),
-	EXYNOS4210_GPIO_E4_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E3),
-	EXYNOS4210_GPIO_F0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_E4),
-	EXYNOS4210_GPIO_F1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_F0),
-	EXYNOS4210_GPIO_F2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_F1),
-	EXYNOS4210_GPIO_F3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_F2),
-};
-
-enum exynos4210_gpio_xb_start {
-	EXYNOS4210_GPIO_J0_START	= 0,
-	EXYNOS4210_GPIO_J1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_J0),
-	EXYNOS4210_GPIO_K0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_J1),
-	EXYNOS4210_GPIO_K1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K0),
-	EXYNOS4210_GPIO_K2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K1),
-	EXYNOS4210_GPIO_K3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K2),
-	EXYNOS4210_GPIO_L0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_K3),
-	EXYNOS4210_GPIO_L1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_L0),
-	EXYNOS4210_GPIO_L2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_L1),
-	EXYNOS4210_GPIO_Y0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2),
-	EXYNOS4210_GPIO_Y1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y0),
-	EXYNOS4210_GPIO_Y2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y1),
-	EXYNOS4210_GPIO_Y3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y2),
-	EXYNOS4210_GPIO_Y4_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y3),
-	EXYNOS4210_GPIO_Y5_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y4),
-	EXYNOS4210_GPIO_Y6_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y5),
-	EXYNOS4210_GPIO_X0_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_Y6),
-	EXYNOS4210_GPIO_X1_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_X0),
-	EXYNOS4210_GPIO_X2_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_X1),
-	EXYNOS4210_GPIO_X3_START	= EXYNOS_GPIO_START(EXYNOS4210_GPIO_X2),
-};
-
-enum exynos4210_gpio_xc_start {
-	EXYNOS4210_GPIO_Z_START		= 0,
-};
-
-#define	EXYNOS4210_GPIO_A0_IRQ		EXYNOS4210_GPIO_A0_START
-#define	EXYNOS4210_GPIO_A1_IRQ		EXYNOS4210_GPIO_A1_START
-#define	EXYNOS4210_GPIO_B_IRQ		EXYNOS4210_GPIO_B_START
-#define	EXYNOS4210_GPIO_C0_IRQ		EXYNOS4210_GPIO_C0_START
-#define	EXYNOS4210_GPIO_C1_IRQ		EXYNOS4210_GPIO_C1_START
-#define	EXYNOS4210_GPIO_D0_IRQ		EXYNOS4210_GPIO_D0_START
-#define	EXYNOS4210_GPIO_D1_IRQ		EXYNOS4210_GPIO_D1_START
-#define	EXYNOS4210_GPIO_E0_IRQ		EXYNOS4210_GPIO_E0_START
-#define	EXYNOS4210_GPIO_E1_IRQ		EXYNOS4210_GPIO_E1_START
-#define	EXYNOS4210_GPIO_E2_IRQ		EXYNOS4210_GPIO_E2_START
-#define	EXYNOS4210_GPIO_E3_IRQ		EXYNOS4210_GPIO_E3_START
-#define	EXYNOS4210_GPIO_E4_IRQ		EXYNOS4210_GPIO_E4_START
-#define	EXYNOS4210_GPIO_F0_IRQ		EXYNOS4210_GPIO_F0_START
-#define	EXYNOS4210_GPIO_F1_IRQ		EXYNOS4210_GPIO_F1_START
-#define	EXYNOS4210_GPIO_F2_IRQ		EXYNOS4210_GPIO_F2_START
-#define	EXYNOS4210_GPIO_F3_IRQ		EXYNOS4210_GPIO_F3_START
-#define	EXYNOS4210_GPIO_J0_IRQ		EXYNOS4210_GPIO_J0_START
-#define	EXYNOS4210_GPIO_J1_IRQ		EXYNOS4210_GPIO_J1_START
-#define	EXYNOS4210_GPIO_K0_IRQ		EXYNOS4210_GPIO_K0_START
-#define	EXYNOS4210_GPIO_K1_IRQ		EXYNOS4210_GPIO_K1_START
-#define	EXYNOS4210_GPIO_K2_IRQ		EXYNOS4210_GPIO_K2_START
-#define	EXYNOS4210_GPIO_K3_IRQ		EXYNOS4210_GPIO_K3_START
-#define	EXYNOS4210_GPIO_L0_IRQ		EXYNOS4210_GPIO_L0_START
-#define	EXYNOS4210_GPIO_L1_IRQ		EXYNOS4210_GPIO_L1_START
-#define	EXYNOS4210_GPIO_L2_IRQ		EXYNOS4210_GPIO_L2_START
-#define	EXYNOS4210_GPIO_Z_IRQ		EXYNOS4210_GPIO_Z_START
-
-#define EXYNOS4210_GPIOA_NR_PINS	EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3)
-#define EXYNOS4210_GPIOA_NR_GINT	EXYNOS_GPIO_START(EXYNOS4210_GPIO_F3)
-#define EXYNOS4210_GPIOB_NR_PINS	EXYNOS_GPIO_START(EXYNOS4210_GPIO_X3)
-#define EXYNOS4210_GPIOB_NR_GINT	EXYNOS_GPIO_START(EXYNOS4210_GPIO_L2)
-#define EXYNOS4210_GPIOC_NR_PINS	EXYNOS_GPIO_START(EXYNOS4210_GPIO_Z)
-
 /* External GPIO and wakeup interrupt related definitions */
 #define EXYNOS_GPIO_ECON_OFFSET		0x700
 #define EXYNOS_GPIO_EMASK_OFFSET	0x900
@@ -165,11 +46,10 @@
 #define EXYNOS_EINT_MAX_PER_BANK	8
 #define EXYNOS_EINT_NR_WKUP_EINT
 
-#define EXYNOS_PIN_BANK_EINTN(reg, __gpio, id)		\
+#define EXYNOS_PIN_BANK_EINTN(pins, reg, id)		\
 	{						\
 		.pctl_offset	= reg,			\
-		.pin_base	= (__gpio##_START),	\
-		.nr_pins	= (__gpio##_NR),	\
+		.nr_pins	= pins,			\
 		.func_width	= 4,			\
 		.pud_width	= 2,			\
 		.drv_width	= 2,			\
@@ -179,40 +59,50 @@
 		.name		= id			\
 	}
 
-#define EXYNOS_PIN_BANK_EINTG(reg, __gpio, id)		\
+#define EXYNOS_PIN_BANK_EINTG(pins, reg, id, offs)	\
 	{						\
 		.pctl_offset	= reg,			\
-		.pin_base	= (__gpio##_START),	\
-		.nr_pins	= (__gpio##_NR),	\
+		.nr_pins	= pins,			\
 		.func_width	= 4,			\
 		.pud_width	= 2,			\
 		.drv_width	= 2,			\
 		.conpdn_width	= 2,			\
 		.pudpdn_width	= 2,			\
 		.eint_type	= EINT_TYPE_GPIO,	\
-		.irq_base	= (__gpio##_IRQ),	\
+		.eint_offset	= offs,			\
+		.name		= id			\
+	}
+
+#define EXYNOS_PIN_BANK_EINTW(pins, reg, id, offs)	\
+	{						\
+		.pctl_offset	= reg,			\
+		.nr_pins	= pins,			\
+		.func_width	= 4,			\
+		.pud_width	= 2,			\
+		.drv_width	= 2,			\
+		.eint_type	= EINT_TYPE_WKUP,	\
+		.eint_offset	= offs,			\
 		.name		= id			\
 	}
 
 /**
- * struct exynos_geint_data: gpio eint specific data for irq_chip callbacks.
- * @bank: pin bank from which this gpio interrupt originates.
- * @pin: pin number within the bank.
- * @eint_offset: offset to be added to the con/pend/mask register bank base.
+ * struct exynos_weint_data: irq specific data for all the wakeup interrupts
+ * generated by the external wakeup interrupt controller.
+ * @irq: interrupt number within the domain.
+ * @bank: bank responsible for this interrupt
  */
-struct exynos_geint_data {
-	struct samsung_pin_bank	*bank;
-	u32			pin;
-	u32			eint_offset;
+struct exynos_weint_data {
+	unsigned int irq;
+	struct samsung_pin_bank *bank;
 };
 
 /**
- * struct exynos_weint_data: irq specific data for all the wakeup interrupts
+ * struct exynos_muxed_weint_data: irq specific data for muxed wakeup interrupts
  * generated by the external wakeup interrupt controller.
- * @domain: irq domain representing the external wakeup interrupts
- * @irq: interrupt number within the domain.
+ * @nr_banks: count of banks being part of the mux
+ * @banks: array of banks being part of the mux
  */
-struct exynos_weint_data {
-	struct irq_domain	*domain;
-	u32			irq;
+struct exynos_muxed_weint_data {
+	unsigned int nr_banks;
+	struct samsung_pin_bank *banks[];
 };
diff --git a/drivers/pinctrl/pinctrl-exynos5440.c b/drivers/pinctrl/pinctrl-exynos5440.c
new file mode 100644
index 0000000..b8635f6
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-exynos5440.c
@@ -0,0 +1,919 @@
+/*
+ * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's EXYNOS5440 SoC.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include "core.h"
+
+/* EXYNOS5440 GPIO and Pinctrl register offsets */
+#define GPIO_MUX		0x00
+#define GPIO_IE			0x04
+#define GPIO_INT		0x08
+#define GPIO_TYPE		0x0C
+#define GPIO_VAL		0x10
+#define GPIO_OE			0x14
+#define GPIO_IN			0x18
+#define GPIO_PE			0x1C
+#define GPIO_PS			0x20
+#define GPIO_SR			0x24
+#define GPIO_DS0		0x28
+#define GPIO_DS1		0x2C
+
+#define EXYNOS5440_MAX_PINS		23
+#define PIN_NAME_LENGTH		10
+
+#define GROUP_SUFFIX		"-grp"
+#define GSUFFIX_LEN		sizeof(GROUP_SUFFIX)
+#define FUNCTION_SUFFIX		"-mux"
+#define FSUFFIX_LEN		sizeof(FUNCTION_SUFFIX)
+
+/*
+ * pin configuration type and its value are packed together into a 16-bits.
+ * The upper 8-bits represent the configuration type and the lower 8-bits
+ * hold the value of the configuration type.
+ */
+#define PINCFG_TYPE_MASK		0xFF
+#define PINCFG_VALUE_SHIFT		8
+#define PINCFG_VALUE_MASK		(0xFF << PINCFG_VALUE_SHIFT)
+#define PINCFG_PACK(type, value)	(((value) << PINCFG_VALUE_SHIFT) | type)
+#define PINCFG_UNPACK_TYPE(cfg)		((cfg) & PINCFG_TYPE_MASK)
+#define PINCFG_UNPACK_VALUE(cfg)	(((cfg) & PINCFG_VALUE_MASK) >> \
+						PINCFG_VALUE_SHIFT)
+
+/**
+ * enum pincfg_type - possible pin configuration types supported.
+ * @PINCFG_TYPE_PUD: Pull up/down configuration.
+ * @PINCFG_TYPE_DRV: Drive strength configuration.
+ * @PINCFG_TYPE_SKEW_RATE: Skew rate configuration.
+ * @PINCFG_TYPE_INPUT_TYPE: Pin input type configuration.
+ */
+enum pincfg_type {
+	PINCFG_TYPE_PUD,
+	PINCFG_TYPE_DRV,
+	PINCFG_TYPE_SKEW_RATE,
+	PINCFG_TYPE_INPUT_TYPE
+};
+
+/**
+ * struct exynos5440_pin_group: represent group of pins for pincfg setting.
+ * @name: name of the pin group, used to lookup the group.
+ * @pins: the pins included in this group.
+ * @num_pins: number of pins included in this group.
+ */
+struct exynos5440_pin_group {
+	const char		*name;
+	const unsigned int	*pins;
+	u8			num_pins;
+};
+
+/**
+ * struct exynos5440_pmx_func: represent a pin function.
+ * @name: name of the pin function, used to lookup the function.
+ * @groups: one or more names of pin groups that provide this function.
+ * @num_groups: number of groups included in @groups.
+ * @function: the function number to be programmed when selected.
+ */
+struct exynos5440_pmx_func {
+	const char		*name;
+	const char		**groups;
+	u8			num_groups;
+	unsigned long		function;
+};
+
+/**
+ * struct exynos5440_pinctrl_priv_data: driver's private runtime data.
+ * @reg_base: ioremapped based address of the register space.
+ * @gc: gpio chip registered with gpiolib.
+ * @pin_groups: list of pin groups parsed from device tree.
+ * @nr_groups: number of pin groups available.
+ * @pmx_functions: list of pin functions parsed from device tree.
+ * @nr_functions: number of pin functions available.
+ */
+struct exynos5440_pinctrl_priv_data {
+	void __iomem			*reg_base;
+	struct gpio_chip		*gc;
+
+	const struct exynos5440_pin_group	*pin_groups;
+	unsigned int			nr_groups;
+	const struct exynos5440_pmx_func	*pmx_functions;
+	unsigned int			nr_functions;
+};
+
+/* list of all possible config options supported */
+struct pin_config {
+	char		*prop_cfg;
+	unsigned int	cfg_type;
+} pcfgs[] = {
+	{ "samsung,exynos5440-pin-pud", PINCFG_TYPE_PUD },
+	{ "samsung,exynos5440-pin-drv", PINCFG_TYPE_DRV },
+	{ "samsung,exynos5440-pin-skew-rate", PINCFG_TYPE_SKEW_RATE },
+	{ "samsung,exynos5440-pin-input-type", PINCFG_TYPE_INPUT_TYPE },
+};
+
+/* check if the selector is a valid pin group selector */
+static int exynos5440_get_group_count(struct pinctrl_dev *pctldev)
+{
+	struct exynos5440_pinctrl_priv_data *priv;
+
+	priv = pinctrl_dev_get_drvdata(pctldev);
+	return priv->nr_groups;
+}
+
+/* return the name of the group selected by the group selector */
+static const char *exynos5440_get_group_name(struct pinctrl_dev *pctldev,
+						unsigned selector)
+{
+	struct exynos5440_pinctrl_priv_data *priv;
+
+	priv = pinctrl_dev_get_drvdata(pctldev);
+	return priv->pin_groups[selector].name;
+}
+
+/* return the pin numbers associated with the specified group */
+static int exynos5440_get_group_pins(struct pinctrl_dev *pctldev,
+		unsigned selector, const unsigned **pins, unsigned *num_pins)
+{
+	struct exynos5440_pinctrl_priv_data *priv;
+
+	priv = pinctrl_dev_get_drvdata(pctldev);
+	*pins = priv->pin_groups[selector].pins;
+	*num_pins = priv->pin_groups[selector].num_pins;
+	return 0;
+}
+
+/* create pinctrl_map entries by parsing device tree nodes */
+static int exynos5440_dt_node_to_map(struct pinctrl_dev *pctldev,
+			struct device_node *np, struct pinctrl_map **maps,
+			unsigned *nmaps)
+{
+	struct device *dev = pctldev->dev;
+	struct pinctrl_map *map;
+	unsigned long *cfg = NULL;
+	char *gname, *fname;
+	int cfg_cnt = 0, map_cnt = 0, idx = 0;
+
+	/* count the number of config options specfied in the node */
+	for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++)
+		if (of_find_property(np, pcfgs[idx].prop_cfg, NULL))
+			cfg_cnt++;
+
+	/*
+	 * Find out the number of map entries to create. All the config options
+	 * can be accomadated into a single config map entry.
+	 */
+	if (cfg_cnt)
+		map_cnt = 1;
+	if (of_find_property(np, "samsung,exynos5440-pin-function", NULL))
+		map_cnt++;
+	if (!map_cnt) {
+		dev_err(dev, "node %s does not have either config or function "
+				"configurations\n", np->name);
+		return -EINVAL;
+	}
+
+	/* Allocate memory for pin-map entries */
+	map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL);
+	if (!map) {
+		dev_err(dev, "could not alloc memory for pin-maps\n");
+		return -ENOMEM;
+	}
+	*nmaps = 0;
+
+	/*
+	 * Allocate memory for pin group name. The pin group name is derived
+	 * from the node name from which these map entries are be created.
+	 */
+	gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL);
+	if (!gname) {
+		dev_err(dev, "failed to alloc memory for group name\n");
+		goto free_map;
+	}
+	sprintf(gname, "%s%s", np->name, GROUP_SUFFIX);
+
+	/*
+	 * don't have config options? then skip over to creating function
+	 * map entries.
+	 */
+	if (!cfg_cnt)
+		goto skip_cfgs;
+
+	/* Allocate memory for config entries */
+	cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL);
+	if (!cfg) {
+		dev_err(dev, "failed to alloc memory for configs\n");
+		goto free_gname;
+	}
+
+	/* Prepare a list of config settings */
+	for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
+		u32 value;
+		if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value))
+			cfg[cfg_cnt++] =
+				PINCFG_PACK(pcfgs[idx].cfg_type, value);
+	}
+
+	/* create the config map entry */
+	map[*nmaps].data.configs.group_or_pin = gname;
+	map[*nmaps].data.configs.configs = cfg;
+	map[*nmaps].data.configs.num_configs = cfg_cnt;
+	map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
+	*nmaps += 1;
+
+skip_cfgs:
+	/* create the function map entry */
+	if (of_find_property(np, "samsung,exynos5440-pin-function", NULL)) {
+		fname = kzalloc(strlen(np->name) + FSUFFIX_LEN,	GFP_KERNEL);
+		if (!fname) {
+			dev_err(dev, "failed to alloc memory for func name\n");
+			goto free_cfg;
+		}
+		sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX);
+
+		map[*nmaps].data.mux.group = gname;
+		map[*nmaps].data.mux.function = fname;
+		map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
+		*nmaps += 1;
+	}
+
+	*maps = map;
+	return 0;
+
+free_cfg:
+	kfree(cfg);
+free_gname:
+	kfree(gname);
+free_map:
+	kfree(map);
+	return -ENOMEM;
+}
+
+/* free the memory allocated to hold the pin-map table */
+static void exynos5440_dt_free_map(struct pinctrl_dev *pctldev,
+			     struct pinctrl_map *map, unsigned num_maps)
+{
+	int idx;
+
+	for (idx = 0; idx < num_maps; idx++) {
+		if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) {
+			kfree(map[idx].data.mux.function);
+			if (!idx)
+				kfree(map[idx].data.mux.group);
+		} else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) {
+			kfree(map[idx].data.configs.configs);
+			if (!idx)
+				kfree(map[idx].data.configs.group_or_pin);
+		}
+	};
+
+	kfree(map);
+}
+
+/* list of pinctrl callbacks for the pinctrl core */
+static struct pinctrl_ops exynos5440_pctrl_ops = {
+	.get_groups_count	= exynos5440_get_group_count,
+	.get_group_name		= exynos5440_get_group_name,
+	.get_group_pins		= exynos5440_get_group_pins,
+	.dt_node_to_map		= exynos5440_dt_node_to_map,
+	.dt_free_map		= exynos5440_dt_free_map,
+};
+
+/* check if the selector is a valid pin function selector */
+static int exynos5440_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	struct exynos5440_pinctrl_priv_data *priv;
+
+	priv = pinctrl_dev_get_drvdata(pctldev);
+	return priv->nr_functions;
+}
+
+/* return the name of the pin function specified */
+static const char *exynos5440_pinmux_get_fname(struct pinctrl_dev *pctldev,
+						unsigned selector)
+{
+	struct exynos5440_pinctrl_priv_data *priv;
+
+	priv = pinctrl_dev_get_drvdata(pctldev);
+	return priv->pmx_functions[selector].name;
+}
+
+/* return the groups associated for the specified function selector */
+static int exynos5440_pinmux_get_groups(struct pinctrl_dev *pctldev,
+		unsigned selector, const char * const **groups,
+		unsigned * const num_groups)
+{
+	struct exynos5440_pinctrl_priv_data *priv;
+
+	priv = pinctrl_dev_get_drvdata(pctldev);
+	*groups = priv->pmx_functions[selector].groups;
+	*num_groups = priv->pmx_functions[selector].num_groups;
+	return 0;
+}
+
+/* enable or disable a pinmux function */
+static void exynos5440_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
+					unsigned group, bool enable)
+{
+	struct exynos5440_pinctrl_priv_data *priv;
+	void __iomem *base;
+	u32 function;
+	u32 data;
+
+	priv = pinctrl_dev_get_drvdata(pctldev);
+	base = priv->reg_base;
+	function = priv->pmx_functions[selector].function;
+
+	data = readl(base + GPIO_MUX);
+	if (enable)
+		data |= (1 << function);
+	else
+		data &= ~(1 << function);
+	writel(data, base + GPIO_MUX);
+}
+
+/* enable a specified pinmux by writing to registers */
+static int exynos5440_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
+					unsigned group)
+{
+	exynos5440_pinmux_setup(pctldev, selector, group, true);
+	return 0;
+}
+
+/* disable a specified pinmux by writing to registers */
+static void exynos5440_pinmux_disable(struct pinctrl_dev *pctldev,
+					unsigned selector, unsigned group)
+{
+	exynos5440_pinmux_setup(pctldev, selector, group, false);
+}
+
+/*
+ * The calls to gpio_direction_output() and gpio_direction_input()
+ * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
+ * function called from the gpiolib interface).
+ */
+static int exynos5440_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
+		struct pinctrl_gpio_range *range, unsigned offset, bool input)
+{
+	return 0;
+}
+
+/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
+static struct pinmux_ops exynos5440_pinmux_ops = {
+	.get_functions_count	= exynos5440_get_functions_count,
+	.get_function_name	= exynos5440_pinmux_get_fname,
+	.get_function_groups	= exynos5440_pinmux_get_groups,
+	.enable			= exynos5440_pinmux_enable,
+	.disable		= exynos5440_pinmux_disable,
+	.gpio_set_direction	= exynos5440_pinmux_gpio_set_direction,
+};
+
+/* set the pin config settings for a specified pin */
+static int exynos5440_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+				unsigned long config)
+{
+	struct exynos5440_pinctrl_priv_data *priv;
+	void __iomem *base;
+	enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(config);
+	u32 cfg_value = PINCFG_UNPACK_VALUE(config);
+	u32 data;
+
+	priv = pinctrl_dev_get_drvdata(pctldev);
+	base = priv->reg_base;
+
+	switch (cfg_type) {
+	case PINCFG_TYPE_PUD:
+		/* first set pull enable/disable bit */
+		data = readl(base + GPIO_PE);
+		data &= ~(1 << pin);
+		if (cfg_value)
+			data |= (1 << pin);
+		writel(data, base + GPIO_PE);
+
+		/* then set pull up/down bit */
+		data = readl(base + GPIO_PS);
+		data &= ~(1 << pin);
+		if (cfg_value == 2)
+			data |= (1 << pin);
+		writel(data, base + GPIO_PS);
+		break;
+
+	case PINCFG_TYPE_DRV:
+		/* set the first bit of the drive strength */
+		data = readl(base + GPIO_DS0);
+		data &= ~(1 << pin);
+		data |= ((cfg_value & 1) << pin);
+		writel(data, base + GPIO_DS0);
+		cfg_value >>= 1;
+
+		/* set the second bit of the driver strength */
+		data = readl(base + GPIO_DS1);
+		data &= ~(1 << pin);
+		data |= ((cfg_value & 1) << pin);
+		writel(data, base + GPIO_DS1);
+		break;
+	case PINCFG_TYPE_SKEW_RATE:
+		data = readl(base + GPIO_SR);
+		data &= ~(1 << pin);
+		data |= ((cfg_value & 1) << pin);
+		writel(data, base + GPIO_SR);
+		break;
+	case PINCFG_TYPE_INPUT_TYPE:
+		data = readl(base + GPIO_TYPE);
+		data &= ~(1 << pin);
+		data |= ((cfg_value & 1) << pin);
+		writel(data, base + GPIO_TYPE);
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* get the pin config settings for a specified pin */
+static int exynos5440_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
+					unsigned long *config)
+{
+	struct exynos5440_pinctrl_priv_data *priv;
+	void __iomem *base;
+	enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config);
+	u32 data;
+
+	priv = pinctrl_dev_get_drvdata(pctldev);
+	base = priv->reg_base;
+
+	switch (cfg_type) {
+	case PINCFG_TYPE_PUD:
+		data = readl(base + GPIO_PE);
+		data = (data >> pin) & 1;
+		if (!data)
+			*config = 0;
+		else
+			*config = ((readl(base + GPIO_PS) >> pin) & 1) + 1;
+		break;
+	case PINCFG_TYPE_DRV:
+		data = readl(base + GPIO_DS0);
+		data = (data >> pin) & 1;
+		*config = data;
+		data = readl(base + GPIO_DS1);
+		data = (data >> pin) & 1;
+		*config |= (data << 1);
+		break;
+	case PINCFG_TYPE_SKEW_RATE:
+		data = readl(base + GPIO_SR);
+		*config = (data >> pin) & 1;
+		break;
+	case PINCFG_TYPE_INPUT_TYPE:
+		data = readl(base + GPIO_TYPE);
+		*config = (data >> pin) & 1;
+		break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* set the pin config settings for a specified pin group */
+static int exynos5440_pinconf_group_set(struct pinctrl_dev *pctldev,
+			unsigned group, unsigned long config)
+{
+	struct exynos5440_pinctrl_priv_data *priv;
+	const unsigned int *pins;
+	unsigned int cnt;
+
+	priv = pinctrl_dev_get_drvdata(pctldev);
+	pins = priv->pin_groups[group].pins;
+
+	for (cnt = 0; cnt < priv->pin_groups[group].num_pins; cnt++)
+		exynos5440_pinconf_set(pctldev, pins[cnt], config);
+
+	return 0;
+}
+
+/* get the pin config settings for a specified pin group */
+static int exynos5440_pinconf_group_get(struct pinctrl_dev *pctldev,
+				unsigned int group, unsigned long *config)
+{
+	struct exynos5440_pinctrl_priv_data *priv;
+	const unsigned int *pins;
+
+	priv = pinctrl_dev_get_drvdata(pctldev);
+	pins = priv->pin_groups[group].pins;
+	exynos5440_pinconf_get(pctldev, pins[0], config);
+	return 0;
+}
+
+/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
+static struct pinconf_ops exynos5440_pinconf_ops = {
+	.pin_config_get		= exynos5440_pinconf_get,
+	.pin_config_set		= exynos5440_pinconf_set,
+	.pin_config_group_get	= exynos5440_pinconf_group_get,
+	.pin_config_group_set	= exynos5440_pinconf_group_set,
+};
+
+/* gpiolib gpio_set callback function */
+static void exynos5440_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
+	void __iomem *base = priv->reg_base;
+	u32 data;
+
+	data = readl(base + GPIO_VAL);
+	data &= ~(1 << offset);
+	if (value)
+		data |= 1 << offset;
+	writel(data, base + GPIO_VAL);
+}
+
+/* gpiolib gpio_get callback function */
+static int exynos5440_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
+	void __iomem *base = priv->reg_base;
+	u32 data;
+
+	data = readl(base + GPIO_IN);
+	data >>= offset;
+	data &= 1;
+	return data;
+}
+
+/* gpiolib gpio_direction_input callback function */
+static int exynos5440_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
+	void __iomem *base = priv->reg_base;
+	u32 data;
+
+	/* first disable the data output enable on this pin */
+	data = readl(base + GPIO_OE);
+	data &= ~(1 << offset);
+	writel(data, base + GPIO_OE);
+
+	/* now enable input on this pin */
+	data =  readl(base + GPIO_IE);
+	data |= 1 << offset;
+	writel(data, base + GPIO_IE);
+	return 0;
+}
+
+/* gpiolib gpio_direction_output callback function */
+static int exynos5440_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
+							int value)
+{
+	struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
+	void __iomem *base = priv->reg_base;
+	u32 data;
+
+	exynos5440_gpio_set(gc, offset, value);
+
+	/* first disable the data input enable on this pin */
+	data = readl(base + GPIO_IE);
+	data &= ~(1 << offset);
+	writel(data, base + GPIO_IE);
+
+	/* now enable output on this pin */
+	data =  readl(base + GPIO_OE);
+	data |= 1 << offset;
+	writel(data, base + GPIO_OE);
+	return 0;
+}
+
+/* parse the pin numbers listed in the 'samsung,exynos5440-pins' property */
+static int __init exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev,
+			struct device_node *cfg_np, unsigned int **pin_list,
+			unsigned int *npins)
+{
+	struct device *dev = &pdev->dev;
+	struct property *prop;
+
+	prop = of_find_property(cfg_np, "samsung,exynos5440-pins", NULL);
+	if (!prop)
+		return -ENOENT;
+
+	*npins = prop->length / sizeof(unsigned long);
+	if (!*npins) {
+		dev_err(dev, "invalid pin list in %s node", cfg_np->name);
+		return -EINVAL;
+	}
+
+	*pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL);
+	if (!*pin_list) {
+		dev_err(dev, "failed to allocate memory for pin list\n");
+		return -ENOMEM;
+	}
+
+	return of_property_read_u32_array(cfg_np, "samsung,exynos5440-pins",
+			*pin_list, *npins);
+}
+
+/*
+ * Parse the information about all the available pin groups and pin functions
+ * from device node of the pin-controller.
+ */
+static int __init exynos5440_pinctrl_parse_dt(struct platform_device *pdev,
+				struct exynos5440_pinctrl_priv_data *priv)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *dev_np = dev->of_node;
+	struct device_node *cfg_np;
+	struct exynos5440_pin_group *groups, *grp;
+	struct exynos5440_pmx_func *functions, *func;
+	unsigned *pin_list;
+	unsigned int npins, grp_cnt, func_idx = 0;
+	char *gname, *fname;
+	int ret;
+
+	grp_cnt = of_get_child_count(dev_np);
+	if (!grp_cnt)
+		return -EINVAL;
+
+	groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL);
+	if (!groups) {
+		dev_err(dev, "failed allocate memory for ping group list\n");
+		return -EINVAL;
+	}
+	grp = groups;
+
+	functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL);
+	if (!functions) {
+		dev_err(dev, "failed to allocate memory for function list\n");
+		return -EINVAL;
+	}
+	func = functions;
+
+	/*
+	 * Iterate over all the child nodes of the pin controller node
+	 * and create pin groups and pin function lists.
+	 */
+	for_each_child_of_node(dev_np, cfg_np) {
+		u32 function;
+
+		ret = exynos5440_pinctrl_parse_dt_pins(pdev, cfg_np,
+					&pin_list, &npins);
+		if (ret)
+			return ret;
+
+		/* derive pin group name from the node name */
+		gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN,
+					GFP_KERNEL);
+		if (!gname) {
+			dev_err(dev, "failed to alloc memory for group name\n");
+			return -ENOMEM;
+		}
+		sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX);
+
+		grp->name = gname;
+		grp->pins = pin_list;
+		grp->num_pins = npins;
+		grp++;
+
+		ret = of_property_read_u32(cfg_np, "samsung,exynos5440-pin-function",
+						&function);
+		if (ret)
+			continue;
+
+		/* derive function name from the node name */
+		fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN,
+					GFP_KERNEL);
+		if (!fname) {
+			dev_err(dev, "failed to alloc memory for func name\n");
+			return -ENOMEM;
+		}
+		sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX);
+
+		func->name = fname;
+		func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
+		if (!func->groups) {
+			dev_err(dev, "failed to alloc memory for group list "
+					"in pin function");
+			return -ENOMEM;
+		}
+		func->groups[0] = gname;
+		func->num_groups = 1;
+		func->function = function;
+		func++;
+		func_idx++;
+	}
+
+	priv->pin_groups = groups;
+	priv->nr_groups = grp_cnt;
+	priv->pmx_functions = functions;
+	priv->nr_functions = func_idx;
+	return 0;
+}
+
+/* register the pinctrl interface with the pinctrl subsystem */
+static int __init exynos5440_pinctrl_register(struct platform_device *pdev,
+				struct exynos5440_pinctrl_priv_data *priv)
+{
+	struct device *dev = &pdev->dev;
+	struct pinctrl_desc *ctrldesc;
+	struct pinctrl_dev *pctl_dev;
+	struct pinctrl_pin_desc *pindesc, *pdesc;
+	struct pinctrl_gpio_range grange;
+	char *pin_names;
+	int pin, ret;
+
+	ctrldesc = devm_kzalloc(dev, sizeof(*ctrldesc), GFP_KERNEL);
+	if (!ctrldesc) {
+		dev_err(dev, "could not allocate memory for pinctrl desc\n");
+		return -ENOMEM;
+	}
+
+	ctrldesc->name = "exynos5440-pinctrl";
+	ctrldesc->owner = THIS_MODULE;
+	ctrldesc->pctlops = &exynos5440_pctrl_ops;
+	ctrldesc->pmxops = &exynos5440_pinmux_ops;
+	ctrldesc->confops = &exynos5440_pinconf_ops;
+
+	pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
+				EXYNOS5440_MAX_PINS, GFP_KERNEL);
+	if (!pindesc) {
+		dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
+		return -ENOMEM;
+	}
+	ctrldesc->pins = pindesc;
+	ctrldesc->npins = EXYNOS5440_MAX_PINS;
+
+	/* dynamically populate the pin number and pin name for pindesc */
+	for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)
+		pdesc->number = pin;
+
+	/*
+	 * allocate space for storing the dynamically generated names for all
+	 * the pins which belong to this pin-controller.
+	 */
+	pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH *
+					ctrldesc->npins, GFP_KERNEL);
+	if (!pin_names) {
+		dev_err(&pdev->dev, "mem alloc for pin names failed\n");
+		return -ENOMEM;
+	}
+
+	/* for each pin, set the name of the pin */
+	for (pin = 0; pin < ctrldesc->npins; pin++) {
+		sprintf(pin_names, "gpio%02d", pin);
+		pdesc = pindesc + pin;
+		pdesc->name = pin_names;
+		pin_names += PIN_NAME_LENGTH;
+	}
+
+	ret = exynos5440_pinctrl_parse_dt(pdev, priv);
+	if (ret)
+		return ret;
+
+	pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, priv);
+	if (!pctl_dev) {
+		dev_err(&pdev->dev, "could not register pinctrl driver\n");
+		return -EINVAL;
+	}
+
+	grange.name = "exynos5440-pctrl-gpio-range";
+	grange.id = 0;
+	grange.base = 0;
+	grange.npins = EXYNOS5440_MAX_PINS;
+	grange.gc = priv->gc;
+	pinctrl_add_gpio_range(pctl_dev, &grange);
+	return 0;
+}
+
+/* register the gpiolib interface with the gpiolib subsystem */
+static int __init exynos5440_gpiolib_register(struct platform_device *pdev,
+				struct exynos5440_pinctrl_priv_data *priv)
+{
+	struct gpio_chip *gc;
+	int ret;
+
+	gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
+	if (!gc) {
+		dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n");
+		return -ENOMEM;
+	}
+
+	priv->gc = gc;
+	gc->base = 0;
+	gc->ngpio = EXYNOS5440_MAX_PINS;
+	gc->dev = &pdev->dev;
+	gc->set = exynos5440_gpio_set;
+	gc->get = exynos5440_gpio_get;
+	gc->direction_input = exynos5440_gpio_direction_input;
+	gc->direction_output = exynos5440_gpio_direction_output;
+	gc->label = "gpiolib-exynos5440";
+	gc->owner = THIS_MODULE;
+	ret = gpiochip_add(gc);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register gpio_chip %s, error "
+					"code: %d\n", gc->label, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/* unregister the gpiolib interface with the gpiolib subsystem */
+static int __init exynos5440_gpiolib_unregister(struct platform_device *pdev,
+				struct exynos5440_pinctrl_priv_data *priv)
+{
+	int ret = gpiochip_remove(priv->gc);
+	if (ret) {
+		dev_err(&pdev->dev, "gpio chip remove failed\n");
+		return ret;
+	}
+	return 0;
+}
+
+static int __devinit exynos5440_pinctrl_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct exynos5440_pinctrl_priv_data *priv;
+	struct resource *res;
+	int ret;
+
+	if (!dev->of_node) {
+		dev_err(dev, "device tree node not found\n");
+		return -ENODEV;
+	}
+
+	priv = devm_kzalloc(dev, sizeof(priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(dev, "could not allocate memory for private data\n");
+		return -ENOMEM;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "cannot find IO resource\n");
+		return -ENOENT;
+	}
+
+	priv->reg_base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!priv->reg_base) {
+		dev_err(dev, "ioremap failed\n");
+		return -ENODEV;
+	}
+
+	ret = exynos5440_gpiolib_register(pdev, priv);
+	if (ret)
+		return ret;
+
+	ret = exynos5440_pinctrl_register(pdev, priv);
+	if (ret) {
+		exynos5440_gpiolib_unregister(pdev, priv);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, priv);
+	dev_info(dev, "EXYNOS5440 pinctrl driver registered\n");
+	return 0;
+}
+
+static const struct of_device_id exynos5440_pinctrl_dt_match[] = {
+	{ .compatible = "samsung,exynos5440-pinctrl" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos5440_pinctrl_dt_match);
+
+static struct platform_driver exynos5440_pinctrl_driver = {
+	.probe		= exynos5440_pinctrl_probe,
+	.driver = {
+		.name	= "exynos5440-pinctrl",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(exynos5440_pinctrl_dt_match),
+	},
+};
+
+static int __init exynos5440_pinctrl_drv_register(void)
+{
+	return platform_driver_register(&exynos5440_pinctrl_driver);
+}
+postcore_initcall(exynos5440_pinctrl_drv_register);
+
+static void __exit exynos5440_pinctrl_drv_unregister(void)
+{
+	platform_driver_unregister(&exynos5440_pinctrl_driver);
+}
+module_exit(exynos5440_pinctrl_drv_unregister);
+
+MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
+MODULE_DESCRIPTION("Samsung EXYNOS5440 SoC pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index 01aea1c..cf82d9c 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -1056,7 +1056,7 @@
 	struct nmk_gpio_chip *nmk_chip =
 		container_of(chip, struct nmk_gpio_chip, chip);
 
-	return irq_find_mapping(nmk_chip->domain, offset);
+	return irq_create_mapping(nmk_chip->domain, offset);
 }
 
 #ifdef CONFIG_DEBUG_FS
@@ -1281,7 +1281,7 @@
 	struct clk *clk;
 	int secondary_irq;
 	void __iomem *base;
-	int irq_start = -1;
+	int irq_start = 0;
 	int irq;
 	int ret;
 
@@ -1387,7 +1387,7 @@
 
 	if (!np)
 		irq_start = NOMADIK_GPIO_TO_IRQ(pdata->first_gpio);
-	nmk_chip->domain = irq_domain_add_simple(NULL,
+	nmk_chip->domain = irq_domain_add_simple(np,
 				NMK_GPIO_PER_CHIP, irq_start,
 				&nmk_gpio_irq_simple_ops, nmk_chip);
 	if (!nmk_chip->domain) {
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 861cd5f..8f31b65 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/irqdomain.h>
 
 #include "core.h"
 #include "pinctrl-samsung.h"
@@ -46,6 +47,13 @@
 	{ "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
 };
 
+static unsigned int pin_base;
+
+static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
+{
+	return container_of(gc, struct samsung_pin_bank, gpio_chip);
+}
+
 /* check if the selector is a valid pin group selector */
 static int samsung_get_group_count(struct pinctrl_dev *pctldev)
 {
@@ -250,14 +258,12 @@
  * given a pin number that is local to a pin controller, find out the pin bank
  * and the register base of the pin bank.
  */
-static void pin_to_reg_bank(struct gpio_chip *gc, unsigned pin,
-			void __iomem **reg, u32 *offset,
+static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
+			unsigned pin, void __iomem **reg, u32 *offset,
 			struct samsung_pin_bank **bank)
 {
-	struct samsung_pinctrl_drv_data *drvdata;
 	struct samsung_pin_bank *b;
 
-	drvdata = dev_get_drvdata(gc->dev);
 	b = drvdata->ctrl->pin_banks;
 
 	while ((pin >= b->pin_base) &&
@@ -292,7 +298,7 @@
 	 * pin function number in the config register.
 	 */
 	for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
-		pin_to_reg_bank(drvdata->gc, pins[cnt] - drvdata->ctrl->base,
+		pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base,
 				&reg, &pin_offset, &bank);
 		mask = (1 << bank->func_width) - 1;
 		shift = pin_offset * bank->func_width;
@@ -329,10 +335,16 @@
 		struct pinctrl_gpio_range *range, unsigned offset, bool input)
 {
 	struct samsung_pin_bank *bank;
+	struct samsung_pinctrl_drv_data *drvdata;
 	void __iomem *reg;
 	u32 data, pin_offset, mask, shift;
 
-	pin_to_reg_bank(range->gc, offset, &reg, &pin_offset, &bank);
+	bank = gc_to_pin_bank(range->gc);
+	drvdata = pinctrl_dev_get_drvdata(pctldev);
+
+	pin_offset = offset - bank->pin_base;
+	reg = drvdata->virt_base + bank->pctl_offset;
+
 	mask = (1 << bank->func_width) - 1;
 	shift = pin_offset * bank->func_width;
 
@@ -366,7 +378,7 @@
 	u32 cfg_value, cfg_reg;
 
 	drvdata = pinctrl_dev_get_drvdata(pctldev);
-	pin_to_reg_bank(drvdata->gc, pin - drvdata->ctrl->base, &reg_base,
+	pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, &reg_base,
 					&pin_offset, &bank);
 
 	switch (cfg_type) {
@@ -391,6 +403,9 @@
 		return -EINVAL;
 	}
 
+	if (!width)
+		return -EINVAL;
+
 	mask = (1 << width) - 1;
 	shift = pin_offset * width;
 	data = readl(reg_base + cfg_reg);
@@ -463,14 +478,16 @@
 /* gpiolib gpio_set callback function */
 static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 {
+	struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
 	void __iomem *reg;
-	u32 pin_offset, data;
+	u32 data;
 
-	pin_to_reg_bank(gc, offset, &reg, &pin_offset, NULL);
+	reg = bank->drvdata->virt_base + bank->pctl_offset;
+
 	data = readl(reg + DAT_REG);
-	data &= ~(1 << pin_offset);
+	data &= ~(1 << offset);
 	if (value)
-		data |= 1 << pin_offset;
+		data |= 1 << offset;
 	writel(data, reg + DAT_REG);
 }
 
@@ -478,11 +495,13 @@
 static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
 {
 	void __iomem *reg;
-	u32 pin_offset, data;
+	u32 data;
+	struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
 
-	pin_to_reg_bank(gc, offset, &reg, &pin_offset, NULL);
+	reg = bank->drvdata->virt_base + bank->pctl_offset;
+
 	data = readl(reg + DAT_REG);
-	data >>= pin_offset;
+	data >>= offset;
 	data &= 1;
 	return data;
 }
@@ -510,6 +529,23 @@
 }
 
 /*
+ * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin
+ * and a virtual IRQ, if not already present.
+ */
+static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+	struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
+	unsigned int virq;
+
+	if (!bank->irq_domain)
+		return -ENXIO;
+
+	virq = irq_create_mapping(bank->irq_domain, offset);
+
+	return (virq) ? : -ENXIO;
+}
+
+/*
  * Parse the pin names listed in the 'samsung,pins' property and convert it
  * into a list of gpio numbers are create a pin group from it.
  */
@@ -524,7 +560,7 @@
 	const char *pin_name;
 
 	*npins = of_property_count_strings(cfg_np, "samsung,pins");
-	if (*npins < 0) {
+	if (IS_ERR_VALUE(*npins)) {
 		dev_err(dev, "invalid pin list in %s node", cfg_np->name);
 		return -EINVAL;
 	}
@@ -597,7 +633,7 @@
 	 */
 	for_each_child_of_node(dev_np, cfg_np) {
 		u32 function;
-		if (of_find_property(cfg_np, "interrupt-controller", NULL))
+		if (!of_find_property(cfg_np, "samsung,pins", NULL))
 			continue;
 
 		ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
@@ -712,12 +748,16 @@
 		return -EINVAL;
 	}
 
-	drvdata->grange.name = "samsung-pctrl-gpio-range";
-	drvdata->grange.id = 0;
-	drvdata->grange.base = drvdata->ctrl->base;
-	drvdata->grange.npins = drvdata->ctrl->nr_pins;
-	drvdata->grange.gc = drvdata->gc;
-	pinctrl_add_gpio_range(drvdata->pctl_dev, &drvdata->grange);
+	for (bank = 0; bank < drvdata->ctrl->nr_banks; ++bank) {
+		pin_bank = &drvdata->ctrl->pin_banks[bank];
+		pin_bank->grange.name = pin_bank->name;
+		pin_bank->grange.id = bank;
+		pin_bank->grange.pin_base = pin_bank->pin_base;
+		pin_bank->grange.base = pin_bank->gpio_chip.base;
+		pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
+		pin_bank->grange.gc = &pin_bank->gpio_chip;
+		pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange);
+	}
 
 	ret = samsung_pinctrl_parse_dt(pdev, drvdata);
 	if (ret) {
@@ -728,68 +768,117 @@
 	return 0;
 }
 
+static const struct gpio_chip samsung_gpiolib_chip = {
+	.set = samsung_gpio_set,
+	.get = samsung_gpio_get,
+	.direction_input = samsung_gpio_direction_input,
+	.direction_output = samsung_gpio_direction_output,
+	.to_irq = samsung_gpio_to_irq,
+	.owner = THIS_MODULE,
+};
+
 /* register the gpiolib interface with the gpiolib subsystem */
 static int __devinit samsung_gpiolib_register(struct platform_device *pdev,
 				struct samsung_pinctrl_drv_data *drvdata)
 {
+	struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+	struct samsung_pin_bank *bank = ctrl->pin_banks;
 	struct gpio_chip *gc;
 	int ret;
+	int i;
 
-	gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
-	if (!gc) {
-		dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n");
-		return -ENOMEM;
-	}
+	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		bank->gpio_chip = samsung_gpiolib_chip;
 
-	drvdata->gc = gc;
-	gc->base = drvdata->ctrl->base;
-	gc->ngpio = drvdata->ctrl->nr_pins;
-	gc->dev = &pdev->dev;
-	gc->set = samsung_gpio_set;
-	gc->get = samsung_gpio_get;
-	gc->direction_input = samsung_gpio_direction_input;
-	gc->direction_output = samsung_gpio_direction_output;
-	gc->label = drvdata->ctrl->label;
-	gc->owner = THIS_MODULE;
-	ret = gpiochip_add(gc);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to register gpio_chip %s, error "
-					"code: %d\n", gc->label, ret);
-		return ret;
+		gc = &bank->gpio_chip;
+		gc->base = ctrl->base + bank->pin_base;
+		gc->ngpio = bank->nr_pins;
+		gc->dev = &pdev->dev;
+		gc->of_node = bank->of_node;
+		gc->label = bank->name;
+
+		ret = gpiochip_add(gc);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
+							gc->label, ret);
+			goto fail;
+		}
 	}
 
 	return 0;
+
+fail:
+	for (--i, --bank; i >= 0; --i, --bank)
+		if (gpiochip_remove(&bank->gpio_chip))
+			dev_err(&pdev->dev, "gpio chip %s remove failed\n",
+							bank->gpio_chip.label);
+	return ret;
 }
 
 /* unregister the gpiolib interface with the gpiolib subsystem */
 static int __devinit samsung_gpiolib_unregister(struct platform_device *pdev,
 				struct samsung_pinctrl_drv_data *drvdata)
 {
-	int ret = gpiochip_remove(drvdata->gc);
-	if (ret) {
+	struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+	struct samsung_pin_bank *bank = ctrl->pin_banks;
+	int ret = 0;
+	int i;
+
+	for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank)
+		ret = gpiochip_remove(&bank->gpio_chip);
+
+	if (ret)
 		dev_err(&pdev->dev, "gpio chip remove failed\n");
-		return ret;
-	}
-	return 0;
+
+	return ret;
 }
 
 static const struct of_device_id samsung_pinctrl_dt_match[];
 
 /* retrieve the soc specific data */
 static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
+				struct samsung_pinctrl_drv_data *d,
 				struct platform_device *pdev)
 {
 	int id;
 	const struct of_device_id *match;
-	const struct device_node *node = pdev->dev.of_node;
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *np;
+	struct samsung_pin_ctrl *ctrl;
+	struct samsung_pin_bank *bank;
+	int i;
 
-	id = of_alias_get_id(pdev->dev.of_node, "pinctrl");
+	id = of_alias_get_id(node, "pinctrl");
 	if (id < 0) {
 		dev_err(&pdev->dev, "failed to get alias id\n");
 		return NULL;
 	}
 	match = of_match_node(samsung_pinctrl_dt_match, node);
-	return (struct samsung_pin_ctrl *)match->data + id;
+	ctrl = (struct samsung_pin_ctrl *)match->data + id;
+
+	bank = ctrl->pin_banks;
+	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		bank->drvdata = d;
+		bank->pin_base = ctrl->nr_pins;
+		ctrl->nr_pins += bank->nr_pins;
+	}
+
+	for_each_child_of_node(node, np) {
+		if (!of_find_property(np, "gpio-controller", NULL))
+			continue;
+		bank = ctrl->pin_banks;
+		for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+			if (!strcmp(bank->name, np->name)) {
+				bank->of_node = np;
+				break;
+			}
+		}
+	}
+
+	ctrl->base = pin_base;
+	pin_base += ctrl->nr_pins;
+
+	return ctrl;
 }
 
 static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
@@ -805,18 +894,18 @@
 		return -ENODEV;
 	}
 
-	ctrl = samsung_pinctrl_get_soc_data(pdev);
-	if (!ctrl) {
-		dev_err(&pdev->dev, "driver data not available\n");
-		return -EINVAL;
-	}
-
 	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
 	if (!drvdata) {
 		dev_err(dev, "failed to allocate memory for driver's "
 				"private data\n");
 		return -ENOMEM;
 	}
+
+	ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev);
+	if (!ctrl) {
+		dev_err(&pdev->dev, "driver data not available\n");
+		return -EINVAL;
+	}
 	drvdata->ctrl = ctrl;
 	drvdata->dev = dev;
 
@@ -858,6 +947,8 @@
 static const struct of_device_id samsung_pinctrl_dt_match[] = {
 	{ .compatible = "samsung,pinctrl-exynos4210",
 		.data = (void *)exynos4210_pin_ctrl },
+	{ .compatible = "samsung,pinctrl-exynos4x12",
+		.data = (void *)exynos4x12_pin_ctrl },
 	{},
 };
 MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match);
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index b895693..5addfd1 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -23,6 +23,8 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/machine.h>
 
+#include <linux/gpio.h>
+
 /* register offsets within a pin bank */
 #define DAT_REG		0x4
 #define PUD_REG		0x8
@@ -64,6 +66,7 @@
  * @EINT_TYPE_NONE: bank does not support external interrupts
  * @EINT_TYPE_GPIO: bank supportes external gpio interrupts
  * @EINT_TYPE_WKUP: bank supportes external wakeup interrupts
+ * @EINT_TYPE_WKUP_MUX: bank supports multiplexed external wakeup interrupts
  *
  * Samsung GPIO controller groups all the available pins into banks. The pins
  * in a pin bank can support external gpio interrupts or external wakeup
@@ -76,6 +79,7 @@
 	EINT_TYPE_NONE,
 	EINT_TYPE_GPIO,
 	EINT_TYPE_WKUP,
+	EINT_TYPE_WKUP_MUX,
 };
 
 /* maximum length of a pin in pin descriptor (example: "gpa0-0") */
@@ -109,8 +113,12 @@
  * @conpdn_width: width of the sleep mode function selector bin field.
  * @pudpdn_width: width of the sleep mode pull up/down selector bit field.
  * @eint_type: type of the external interrupt supported by the bank.
- * @irq_base: starting controller local irq number of the bank.
  * @name: name to be prefixed for each pin in this pin bank.
+ * @of_node: OF node of the bank.
+ * @drvdata: link to controller driver data
+ * @irq_domain: IRQ domain of the bank.
+ * @gpio_chip: GPIO chip of the bank.
+ * @grange: linux gpio pin range supported by this bank.
  */
 struct samsung_pin_bank {
 	u32		pctl_offset;
@@ -122,8 +130,13 @@
 	u8		conpdn_width;
 	u8		pudpdn_width;
 	enum eint_type	eint_type;
-	u32		irq_base;
+	u32		eint_offset;
 	char		*name;
+	struct device_node *of_node;
+	struct samsung_pinctrl_drv_data *drvdata;
+	struct irq_domain *irq_domain;
+	struct gpio_chip gpio_chip;
+	struct pinctrl_gpio_range grange;
 };
 
 /**
@@ -132,8 +145,6 @@
  * @nr_banks: number of pin banks.
  * @base: starting system wide pin number.
  * @nr_pins: number of pins supported by the controller.
- * @nr_gint: number of external gpio interrupts supported.
- * @nr_wint: number of external wakeup interrupts supported.
  * @geint_con: offset of the ext-gpio controller registers.
  * @geint_mask: offset of the ext-gpio interrupt mask registers.
  * @geint_pend: offset of the ext-gpio interrupt pending registers.
@@ -153,8 +164,6 @@
 
 	u32		base;
 	u32		nr_pins;
-	u32		nr_gint;
-	u32		nr_wint;
 
 	u32		geint_con;
 	u32		geint_mask;
@@ -183,8 +192,6 @@
  * @nr_groups: number of such pin groups.
  * @pmx_functions: list of pin functions available to the driver.
  * @nr_function: number of such pin functions.
- * @gc: gpio_chip instance registered with gpiolib.
- * @grange: linux gpio pin range supported by this controller.
  */
 struct samsung_pinctrl_drv_data {
 	void __iomem			*virt_base;
@@ -199,12 +206,6 @@
 	unsigned int			nr_groups;
 	const struct samsung_pmx_func	*pmx_functions;
 	unsigned int			nr_functions;
-
-	struct irq_domain		*gpio_irqd;
-	struct irq_domain		*wkup_irqd;
-
-	struct gpio_chip		*gc;
-	struct pinctrl_gpio_range	grange;
 };
 
 /**
@@ -235,5 +236,6 @@
 
 /* list of all exported SoC specific data */
 extern struct samsung_pin_ctrl exynos4210_pin_ctrl[];
+extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
 
 #endif /* __PINCTRL_SAMSUNG_H */
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c
index 729b686..7da0b37 100644
--- a/drivers/pinctrl/pinctrl-tegra.c
+++ b/drivers/pinctrl/pinctrl-tegra.c
@@ -464,7 +464,7 @@
 		*bank = g->drv_bank;
 		*reg = g->drv_reg;
 		*bit = g->lpmd_bit;
-		*width = 1;
+		*width = 2;
 		break;
 	case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH:
 		*bank = g->drv_bank;
diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c
index 0386fdf..7894f14 100644
--- a/drivers/pinctrl/pinctrl-tegra30.c
+++ b/drivers/pinctrl/pinctrl-tegra30.c
@@ -3345,10 +3345,10 @@
 	FUNCTION(vi_alt3),
 };
 
-#define MUXCTL_REG_A	0x3000
-#define PINGROUP_REG_A	0x868
+#define DRV_PINGROUP_REG_A	0x868	/* bank 0 */
+#define PINGROUP_REG_A		0x3000	/* bank 1 */
 
-#define PINGROUP_REG_Y(r) ((r) - MUXCTL_REG_A)
+#define PINGROUP_REG_Y(r) ((r) - PINGROUP_REG_A)
 #define PINGROUP_REG_N(r) -1
 
 #define PINGROUP(pg_name, f0, f1, f2, f3, f_safe, r, od, ior)	\
@@ -3364,25 +3364,25 @@
 		},						\
 		.func_safe = TEGRA_MUX_ ## f_safe,		\
 		.mux_reg = PINGROUP_REG_Y(r),			\
-		.mux_bank = 0,					\
+		.mux_bank = 1,					\
 		.mux_bit = 0,					\
 		.pupd_reg = PINGROUP_REG_Y(r),			\
-		.pupd_bank = 0,					\
+		.pupd_bank = 1,					\
 		.pupd_bit = 2,					\
 		.tri_reg = PINGROUP_REG_Y(r),			\
-		.tri_bank = 0,					\
+		.tri_bank = 1,					\
 		.tri_bit = 4,					\
 		.einput_reg = PINGROUP_REG_Y(r),		\
-		.einput_bank = 0,				\
+		.einput_bank = 1,				\
 		.einput_bit = 5,				\
 		.odrain_reg = PINGROUP_REG_##od(r),		\
-		.odrain_bank = 0,				\
+		.odrain_bank = 1,				\
 		.odrain_bit = 6,				\
 		.lock_reg = PINGROUP_REG_Y(r),			\
-		.lock_bank = 0,					\
+		.lock_bank = 1,					\
 		.lock_bit = 7,					\
 		.ioreset_reg = PINGROUP_REG_##ior(r),		\
-		.ioreset_bank = 0,				\
+		.ioreset_bank = 1,				\
 		.ioreset_bit = 8,				\
 		.drv_reg = -1,					\
 	}
@@ -3401,8 +3401,8 @@
 		.odrain_reg = -1,				\
 		.lock_reg = -1,					\
 		.ioreset_reg = -1,				\
-		.drv_reg = ((r) - PINGROUP_REG_A),		\
-		.drv_bank = 1,					\
+		.drv_reg = ((r) - DRV_PINGROUP_REG_A),		\
+		.drv_bank = 0,					\
 		.hsm_bit = hsm_b,				\
 		.schmitt_bit = schmitt_b,			\
 		.lpmd_bit = lpmd_b,				\
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
index 5d4f44f..b1fd6ee 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.c
+++ b/drivers/pinctrl/spear/pinctrl-spear.c
@@ -244,7 +244,7 @@
 			else
 				temp = ~muxreg->val;
 
-			val |= temp;
+			val |= muxreg->mask & temp;
 			pmx_writel(pmx, val, muxreg->reg);
 		}
 	}
diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c
index d6cca8c..0436fc7 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1310.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1310.c
@@ -25,8 +25,8 @@
 };
 
 /* registers */
-#define PERIP_CFG					0x32C
-	#define MCIF_SEL_SHIFT				3
+#define PERIP_CFG					0x3B0
+	#define MCIF_SEL_SHIFT				5
 	#define MCIF_SEL_SD				(0x1 << MCIF_SEL_SHIFT)
 	#define MCIF_SEL_CF				(0x2 << MCIF_SEL_SHIFT)
 	#define MCIF_SEL_XD				(0x3 << MCIF_SEL_SHIFT)
@@ -164,6 +164,10 @@
 	#define PMX_SSP0_CS0_MASK			(1 << 29)
 	#define PMX_SSP0_CS1_2_MASK			(1 << 30)
 
+#define PAD_DIRECTION_SEL_0				0x65C
+#define PAD_DIRECTION_SEL_1				0x660
+#define PAD_DIRECTION_SEL_2				0x664
+
 /* combined macros */
 #define PMX_GMII_MASK		(PMX_GMIICLK_MASK |			\
 				PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK |	\
@@ -237,6 +241,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_I2C0_MASK,
 		.val = PMX_I2C0_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_I2C0_MASK,
+		.val = PMX_I2C0_MASK,
 	},
 };
 
@@ -269,6 +277,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_SSP0_MASK,
 		.val = PMX_SSP0_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_SSP0_MASK,
+		.val = PMX_SSP0_MASK,
 	},
 };
 
@@ -294,6 +306,10 @@
 		.reg = PAD_FUNCTION_EN_2,
 		.mask = PMX_SSP0_CS0_MASK,
 		.val = PMX_SSP0_CS0_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_SSP0_CS0_MASK,
+		.val = PMX_SSP0_CS0_MASK,
 	},
 };
 
@@ -319,6 +335,10 @@
 		.reg = PAD_FUNCTION_EN_2,
 		.mask = PMX_SSP0_CS1_2_MASK,
 		.val = PMX_SSP0_CS1_2_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_SSP0_CS1_2_MASK,
+		.val = PMX_SSP0_CS1_2_MASK,
 	},
 };
 
@@ -352,6 +372,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_I2S0_MASK,
 		.val = PMX_I2S0_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_I2S0_MASK,
+		.val = PMX_I2S0_MASK,
 	},
 };
 
@@ -384,6 +408,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_I2S1_MASK,
 		.val = PMX_I2S1_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_I2S1_MASK,
+		.val = PMX_I2S1_MASK,
 	},
 };
 
@@ -418,6 +446,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_CLCD1_MASK,
 		.val = PMX_CLCD1_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_CLCD1_MASK,
+		.val = PMX_CLCD1_MASK,
 	},
 };
 
@@ -443,6 +475,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_CLCD2_MASK,
 		.val = PMX_CLCD2_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_CLCD2_MASK,
+		.val = PMX_CLCD2_MASK,
 	},
 };
 
@@ -461,7 +497,7 @@
 	.nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux),
 };
 
-static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res" };
+static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res_grp" };
 static struct spear_function clcd_function = {
 	.name = "clcd",
 	.groups = clcd_grps,
@@ -479,6 +515,14 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_EGPIO_1_GRP_MASK,
 		.val = PMX_EGPIO_1_GRP_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_EGPIO_0_GRP_MASK,
+		.val = PMX_EGPIO_0_GRP_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_EGPIO_1_GRP_MASK,
+		.val = PMX_EGPIO_1_GRP_MASK,
 	},
 };
 
@@ -511,6 +555,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_SMI_MASK,
 		.val = PMX_SMI_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_SMI_MASK,
+		.val = PMX_SMI_MASK,
 	},
 };
 
@@ -539,6 +587,14 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
 		.val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_SMI_MASK,
+		.val = PMX_SMI_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
+		.val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
 	},
 };
 
@@ -573,6 +629,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_GMII_MASK,
 		.val = PMX_GMII_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_GMII_MASK,
+		.val = PMX_GMII_MASK,
 	},
 };
 
@@ -615,6 +675,18 @@
 		.reg = PAD_FUNCTION_EN_2,
 		.mask = PMX_RGMII_REG2_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_RGMII_REG0_MASK,
+		.val = PMX_RGMII_REG0_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_RGMII_REG1_MASK,
+		.val = PMX_RGMII_REG1_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_RGMII_REG2_MASK,
+		.val = PMX_RGMII_REG2_MASK,
 	},
 };
 
@@ -649,6 +721,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_SMII_0_1_2_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_SMII_0_1_2_MASK,
+		.val = PMX_SMII_0_1_2_MASK,
 	},
 };
 
@@ -681,6 +757,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_NFCE2_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_NFCE2_MASK,
+		.val = PMX_NFCE2_MASK,
 	},
 };
 
@@ -721,6 +801,14 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_NAND8BIT_1_MASK,
 		.val = PMX_NAND8BIT_1_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_NAND8BIT_0_MASK,
+		.val = PMX_NAND8BIT_0_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_NAND8BIT_1_MASK,
+		.val = PMX_NAND8BIT_1_MASK,
 	},
 };
 
@@ -747,6 +835,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_NAND16BIT_1_MASK,
 		.val = PMX_NAND16BIT_1_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_NAND16BIT_1_MASK,
+		.val = PMX_NAND16BIT_1_MASK,
 	},
 };
 
@@ -772,6 +864,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_NAND_4CHIPS_MASK,
 		.val = PMX_NAND_4CHIPS_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_NAND_4CHIPS_MASK,
+		.val = PMX_NAND_4CHIPS_MASK,
 	},
 };
 
@@ -833,6 +929,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_KBD_ROWCOL68_MASK,
 		.val = PMX_KBD_ROWCOL68_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_KBD_ROWCOL68_MASK,
+		.val = PMX_KBD_ROWCOL68_MASK,
 	},
 };
 
@@ -866,6 +966,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_UART0_MASK,
 		.val = PMX_UART0_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_UART0_MASK,
+		.val = PMX_UART0_MASK,
 	},
 };
 
@@ -891,6 +995,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_UART0_MODEM_MASK,
 		.val = PMX_UART0_MODEM_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = PMX_UART0_MODEM_MASK,
 	},
 };
 
@@ -923,6 +1031,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_GPT0_TMR0_MASK,
 		.val = PMX_GPT0_TMR0_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_GPT0_TMR0_MASK,
+		.val = PMX_GPT0_TMR0_MASK,
 	},
 };
 
@@ -948,6 +1060,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_GPT0_TMR1_MASK,
 		.val = PMX_GPT0_TMR1_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_GPT0_TMR1_MASK,
+		.val = PMX_GPT0_TMR1_MASK,
 	},
 };
 
@@ -980,6 +1096,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_GPT1_TMR0_MASK,
 		.val = PMX_GPT1_TMR0_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_GPT1_TMR0_MASK,
+		.val = PMX_GPT1_TMR0_MASK,
 	},
 };
 
@@ -1005,6 +1125,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_GPT1_TMR1_MASK,
 		.val = PMX_GPT1_TMR1_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_GPT1_TMR1_MASK,
+		.val = PMX_GPT1_TMR1_MASK,
 	},
 };
 
@@ -1049,6 +1173,20 @@
 		.reg = PAD_FUNCTION_EN_2,			\
 		.mask = PMX_MCIFALL_2_MASK,			\
 		.val = PMX_MCIFALL_2_MASK,			\
+	}, {							\
+		.reg = PAD_DIRECTION_SEL_0,			\
+		.mask = PMX_MCI_DATA8_15_MASK,			\
+		.val = PMX_MCI_DATA8_15_MASK,			\
+	}, {							\
+		.reg = PAD_DIRECTION_SEL_1,			\
+		.mask = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK |	\
+			PMX_NFWPRT2_MASK,			\
+		.val = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK |  \
+			PMX_NFWPRT2_MASK,			\
+	}, {							\
+		.reg = PAD_DIRECTION_SEL_2,			\
+		.mask = PMX_MCIFALL_2_MASK,			\
+		.val = PMX_MCIFALL_2_MASK,			\
 	}
 
 /* sdhci device */
@@ -1154,6 +1292,10 @@
 		.reg = PAD_FUNCTION_EN_2,
 		.mask = PMX_TOUCH_XY_MASK,
 		.val = PMX_TOUCH_XY_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_TOUCH_XY_MASK,
+		.val = PMX_TOUCH_XY_MASK,
 	},
 };
 
@@ -1187,6 +1329,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_I2C0_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_I2C0_MASK,
+		.val = PMX_I2C0_MASK,
 	},
 };
 
@@ -1213,6 +1359,12 @@
 		.mask = PMX_MCIDATA1_MASK |
 			PMX_MCIDATA2_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_MCIDATA1_MASK |
+			PMX_MCIDATA2_MASK,
+		.val = PMX_MCIDATA1_MASK |
+			PMX_MCIDATA2_MASK,
 	},
 };
 
@@ -1246,6 +1398,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_I2S0_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_I2S0_MASK,
+		.val = PMX_I2S0_MASK,
 	},
 };
 
@@ -1278,6 +1434,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_I2S0_MASK | PMX_CLCD1_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_I2S0_MASK | PMX_CLCD1_MASK,
+		.val = PMX_I2S0_MASK | PMX_CLCD1_MASK,
 	},
 };
 
@@ -1310,6 +1470,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_CLCD1_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_CLCD1_MASK,
+		.val = PMX_CLCD1_MASK,
 	},
 };
 
@@ -1344,6 +1508,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_CLCD1_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_CLCD1_MASK,
+		.val = PMX_CLCD1_MASK,
 	},
 };
 
@@ -1376,6 +1544,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_CLCD1_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_CLCD1_MASK,
+		.val = PMX_CLCD1_MASK,
 	},
 };
 
@@ -1409,6 +1581,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_CLCD1_MASK | PMX_SMI_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_CLCD1_MASK | PMX_SMI_MASK,
+		.val = PMX_CLCD1_MASK | PMX_SMI_MASK,
 	},
 };
 
@@ -1435,6 +1611,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK,
+		.val = PMX_I2S1_MASK | PMX_MCIDATA3_MASK,
 	},
 };
 
@@ -1469,6 +1649,10 @@
 		.reg = PAD_FUNCTION_EN_0,
 		.mask = PMX_SMI_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_SMI_MASK,
+		.val = PMX_SMI_MASK,
 	},
 };
 
@@ -1499,6 +1683,14 @@
 		.reg = PAD_FUNCTION_EN_2,
 		.mask = PMX_MCIDATA5_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_MCIDATA4_MASK,
+		.val = PMX_MCIDATA4_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_MCIDATA5_MASK,
+		.val = PMX_MCIDATA5_MASK,
 	},
 };
 
@@ -1526,6 +1718,12 @@
 		.mask = PMX_MCIDATA6_MASK |
 			PMX_MCIDATA7_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_MCIDATA6_MASK |
+			PMX_MCIDATA7_MASK,
+		.val = PMX_MCIDATA6_MASK |
+			PMX_MCIDATA7_MASK,
 	},
 };
 
@@ -1560,6 +1758,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_KBD_ROWCOL25_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_KBD_ROWCOL25_MASK,
+		.val = PMX_KBD_ROWCOL25_MASK,
 	},
 };
 
@@ -1587,6 +1789,12 @@
 		.mask = PMX_MCIIORDRE_MASK |
 			PMX_MCIIOWRWE_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_MCIIORDRE_MASK |
+			PMX_MCIIOWRWE_MASK,
+		.val = PMX_MCIIORDRE_MASK |
+			PMX_MCIIOWRWE_MASK,
 	},
 };
 
@@ -1613,6 +1821,12 @@
 		.mask = PMX_MCIRESETCF_MASK |
 			PMX_MCICS0CE_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_MCIRESETCF_MASK |
+			PMX_MCICS0CE_MASK,
+		.val = PMX_MCIRESETCF_MASK |
+			PMX_MCICS0CE_MASK,
 	},
 };
 
@@ -1651,6 +1865,14 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_NFRSTPWDWN3_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_NFRSTPWDWN2_MASK,
+		.val = PMX_NFRSTPWDWN2_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_NFRSTPWDWN3_MASK,
+		.val = PMX_NFRSTPWDWN3_MASK,
 	},
 };
 
@@ -1677,6 +1899,10 @@
 		.reg = PAD_FUNCTION_EN_2,
 		.mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK,
+		.val = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK,
 	},
 };
 
@@ -1711,6 +1937,10 @@
 		.reg = PAD_FUNCTION_EN_2,
 		.mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK,
+		.val = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK,
 	},
 };
 
@@ -1737,6 +1967,10 @@
 		.reg = PAD_FUNCTION_EN_1,
 		.mask = PMX_KBD_ROWCOL25_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_KBD_ROWCOL25_MASK,
+		.val = PMX_KBD_ROWCOL25_MASK,
 	},
 };
 
@@ -1763,29 +1997,64 @@
 	.ngroups = ARRAY_SIZE(can1_grps),
 };
 
-/* Pad multiplexing for pci device */
-static const unsigned pci_sata_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18,
+/* Pad multiplexing for (ras-ip) pci device */
+static const unsigned pci_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18,
 	19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
 	37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
 	55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 };
-#define PCI_SATA_MUXREG				\
-	{					\
-		.reg = PAD_FUNCTION_EN_0,	\
-		.mask = PMX_MCI_DATA8_15_MASK,	\
-		.val = 0,			\
-	}, {					\
-		.reg = PAD_FUNCTION_EN_1,	\
-		.mask = PMX_PCI_REG1_MASK,	\
-		.val = 0,			\
-	}, {					\
-		.reg = PAD_FUNCTION_EN_2,	\
-		.mask = PMX_PCI_REG2_MASK,	\
-		.val = 0,			\
-	}
 
-/* pad multiplexing for pcie0 device */
+static struct spear_muxreg pci_muxreg[] = {
+	{
+		.reg = PAD_FUNCTION_EN_0,
+		.mask = PMX_MCI_DATA8_15_MASK,
+		.val = 0,
+	}, {
+		.reg = PAD_FUNCTION_EN_1,
+		.mask = PMX_PCI_REG1_MASK,
+		.val = 0,
+	}, {
+		.reg = PAD_FUNCTION_EN_2,
+		.mask = PMX_PCI_REG2_MASK,
+		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_0,
+		.mask = PMX_MCI_DATA8_15_MASK,
+		.val = PMX_MCI_DATA8_15_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_PCI_REG1_MASK,
+		.val = PMX_PCI_REG1_MASK,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_PCI_REG2_MASK,
+		.val = PMX_PCI_REG2_MASK,
+	},
+};
+
+static struct spear_modemux pci_modemux[] = {
+	{
+		.muxregs = pci_muxreg,
+		.nmuxregs = ARRAY_SIZE(pci_muxreg),
+	},
+};
+
+static struct spear_pingroup pci_pingroup = {
+	.name = "pci_grp",
+	.pins = pci_pins,
+	.npins = ARRAY_SIZE(pci_pins),
+	.modemuxs = pci_modemux,
+	.nmodemuxs = ARRAY_SIZE(pci_modemux),
+};
+
+static const char *const pci_grps[] = { "pci_grp" };
+static struct spear_function pci_function = {
+	.name = "pci",
+	.groups = pci_grps,
+	.ngroups = ARRAY_SIZE(pci_grps),
+};
+
+/* pad multiplexing for (fix-part) pcie0 device */
 static struct spear_muxreg pcie0_muxreg[] = {
-	PCI_SATA_MUXREG,
 	{
 		.reg = PCIE_SATA_CFG,
 		.mask = PCIE_CFG_VAL(0),
@@ -1802,15 +2071,12 @@
 
 static struct spear_pingroup pcie0_pingroup = {
 	.name = "pcie0_grp",
-	.pins = pci_sata_pins,
-	.npins = ARRAY_SIZE(pci_sata_pins),
 	.modemuxs = pcie0_modemux,
 	.nmodemuxs = ARRAY_SIZE(pcie0_modemux),
 };
 
-/* pad multiplexing for pcie1 device */
+/* pad multiplexing for (fix-part) pcie1 device */
 static struct spear_muxreg pcie1_muxreg[] = {
-	PCI_SATA_MUXREG,
 	{
 		.reg = PCIE_SATA_CFG,
 		.mask = PCIE_CFG_VAL(1),
@@ -1827,15 +2093,12 @@
 
 static struct spear_pingroup pcie1_pingroup = {
 	.name = "pcie1_grp",
-	.pins = pci_sata_pins,
-	.npins = ARRAY_SIZE(pci_sata_pins),
 	.modemuxs = pcie1_modemux,
 	.nmodemuxs = ARRAY_SIZE(pcie1_modemux),
 };
 
-/* pad multiplexing for pcie2 device */
+/* pad multiplexing for (fix-part) pcie2 device */
 static struct spear_muxreg pcie2_muxreg[] = {
-	PCI_SATA_MUXREG,
 	{
 		.reg = PCIE_SATA_CFG,
 		.mask = PCIE_CFG_VAL(2),
@@ -1852,22 +2115,20 @@
 
 static struct spear_pingroup pcie2_pingroup = {
 	.name = "pcie2_grp",
-	.pins = pci_sata_pins,
-	.npins = ARRAY_SIZE(pci_sata_pins),
 	.modemuxs = pcie2_modemux,
 	.nmodemuxs = ARRAY_SIZE(pcie2_modemux),
 };
 
-static const char *const pci_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" };
-static struct spear_function pci_function = {
-	.name = "pci",
-	.groups = pci_grps,
-	.ngroups = ARRAY_SIZE(pci_grps),
+static const char *const pcie_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp"
+};
+static struct spear_function pcie_function = {
+	.name = "pci_express",
+	.groups = pcie_grps,
+	.ngroups = ARRAY_SIZE(pcie_grps),
 };
 
 /* pad multiplexing for sata0 device */
 static struct spear_muxreg sata0_muxreg[] = {
-	PCI_SATA_MUXREG,
 	{
 		.reg = PCIE_SATA_CFG,
 		.mask = SATA_CFG_VAL(0),
@@ -1884,15 +2145,12 @@
 
 static struct spear_pingroup sata0_pingroup = {
 	.name = "sata0_grp",
-	.pins = pci_sata_pins,
-	.npins = ARRAY_SIZE(pci_sata_pins),
 	.modemuxs = sata0_modemux,
 	.nmodemuxs = ARRAY_SIZE(sata0_modemux),
 };
 
 /* pad multiplexing for sata1 device */
 static struct spear_muxreg sata1_muxreg[] = {
-	PCI_SATA_MUXREG,
 	{
 		.reg = PCIE_SATA_CFG,
 		.mask = SATA_CFG_VAL(1),
@@ -1909,15 +2167,12 @@
 
 static struct spear_pingroup sata1_pingroup = {
 	.name = "sata1_grp",
-	.pins = pci_sata_pins,
-	.npins = ARRAY_SIZE(pci_sata_pins),
 	.modemuxs = sata1_modemux,
 	.nmodemuxs = ARRAY_SIZE(sata1_modemux),
 };
 
 /* pad multiplexing for sata2 device */
 static struct spear_muxreg sata2_muxreg[] = {
-	PCI_SATA_MUXREG,
 	{
 		.reg = PCIE_SATA_CFG,
 		.mask = SATA_CFG_VAL(2),
@@ -1934,8 +2189,6 @@
 
 static struct spear_pingroup sata2_pingroup = {
 	.name = "sata2_grp",
-	.pins = pci_sata_pins,
-	.npins = ARRAY_SIZE(pci_sata_pins),
 	.modemuxs = sata2_modemux,
 	.nmodemuxs = ARRAY_SIZE(sata2_modemux),
 };
@@ -1957,6 +2210,14 @@
 			PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK |
 			PMX_NFCE2_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_1,
+		.mask = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK |
+			PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK |
+			PMX_NFCE2_MASK,
+		.val = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK |
+			PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK |
+			PMX_NFCE2_MASK,
 	},
 };
 
@@ -1983,6 +2244,12 @@
 		.mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK |
 			PMX_MCICECF_MASK | PMX_MCICEXD_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK |
+			PMX_MCICECF_MASK | PMX_MCICEXD_MASK,
+		.val = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK |
+			PMX_MCICECF_MASK | PMX_MCICEXD_MASK,
 	},
 };
 
@@ -2017,6 +2284,12 @@
 		.mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK
 			| PMX_MCILEDS_MASK,
 		.val = 0,
+	}, {
+		.reg = PAD_DIRECTION_SEL_2,
+		.mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK
+			| PMX_MCILEDS_MASK,
+		.val = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK
+			| PMX_MCILEDS_MASK,
 	},
 };
 
@@ -2093,6 +2366,7 @@
 	&can0_dis_sd_pingroup,
 	&can1_dis_sd_pingroup,
 	&can1_dis_kbd_pingroup,
+	&pci_pingroup,
 	&pcie0_pingroup,
 	&pcie1_pingroup,
 	&pcie2_pingroup,
@@ -2138,6 +2412,7 @@
 	&can0_function,
 	&can1_function,
 	&pci_function,
+	&pcie_function,
 	&sata_function,
 	&ssp1_function,
 	&gpt64_function,
diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c
index a0eb057..0606b8c 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1340.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1340.c
@@ -213,7 +213,7 @@
  * Pad multiplexing for making all pads as gpio's. This is done to override the
  * values passed from bootloader and start from scratch.
  */
-static const unsigned pads_as_gpio_pins[] = { 251 };
+static const unsigned pads_as_gpio_pins[] = { 12, 88, 89, 251 };
 static struct spear_muxreg pads_as_gpio_muxreg[] = {
 	{
 		.reg = PAD_FUNCTION_EN_1,
@@ -1692,7 +1692,43 @@
 	.nmodemuxs = ARRAY_SIZE(clcd_modemux),
 };
 
-static const char *const clcd_grps[] = { "clcd_grp" };
+/* Disable cld runtime to save panel damage */
+static struct spear_muxreg clcd_sleep_muxreg[] = {
+	{
+		.reg = PAD_SHARED_IP_EN_1,
+		.mask = ARM_TRACE_MASK | MIPHY_DBG_MASK,
+		.val = 0,
+	}, {
+		.reg = PAD_FUNCTION_EN_5,
+		.mask = CLCD_REG4_MASK | CLCD_AND_ARM_TRACE_REG4_MASK,
+		.val = 0x0,
+	}, {
+		.reg = PAD_FUNCTION_EN_6,
+		.mask = CLCD_AND_ARM_TRACE_REG5_MASK,
+		.val = 0x0,
+	}, {
+		.reg = PAD_FUNCTION_EN_7,
+		.mask = CLCD_AND_ARM_TRACE_REG6_MASK,
+		.val = 0x0,
+	},
+};
+
+static struct spear_modemux clcd_sleep_modemux[] = {
+	{
+		.muxregs = clcd_sleep_muxreg,
+		.nmuxregs = ARRAY_SIZE(clcd_sleep_muxreg),
+	},
+};
+
+static struct spear_pingroup clcd_sleep_pingroup = {
+	.name = "clcd_sleep_grp",
+	.pins = clcd_pins,
+	.npins = ARRAY_SIZE(clcd_pins),
+	.modemuxs = clcd_sleep_modemux,
+	.nmodemuxs = ARRAY_SIZE(clcd_sleep_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_grp", "clcd_sleep_grp" };
 static struct spear_function clcd_function = {
 	.name = "clcd",
 	.groups = clcd_grps,
@@ -1893,6 +1929,7 @@
 	&sdhci_pingroup,
 	&cf_pingroup,
 	&xd_pingroup,
+	&clcd_sleep_pingroup,
 	&clcd_pingroup,
 	&arm_trace_pingroup,
 	&miphy_dbg_pingroup,
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c
index 020b1e0..ca47b0e 100644
--- a/drivers/pinctrl/spear/pinctrl-spear320.c
+++ b/drivers/pinctrl/spear/pinctrl-spear320.c
@@ -2240,6 +2240,10 @@
 		.mask = PMX_SSP_CS_MASK,
 		.val = 0,
 	}, {
+		.reg = MODE_CONFIG_REG,
+		.mask = PMX_PWM_MASK,
+		.val = PMX_PWM_MASK,
+	}, {
 		.reg = IP_SEL_PAD_30_39_REG,
 		.mask = PMX_PL_34_MASK,
 		.val = PMX_PWM2_PL_34_VAL,
@@ -2956,9 +2960,9 @@
 };
 
 /* 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,
+static const unsigned rmii0_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 const unsigned smii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 };
 static struct spear_muxreg mii0_1_muxreg[] = {
 	{
 		.reg = PMX_CONFIG_REG,
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h
index 31f4434..7860b36 100644
--- a/drivers/pinctrl/spear/pinctrl-spear3xx.h
+++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h
@@ -15,6 +15,7 @@
 #include "pinctrl-spear.h"
 
 /* pad mux declarations */
+#define PMX_PWM_MASK		(1 << 16)
 #define PMX_FIRDA_MASK		(1 << 14)
 #define PMX_I2C_MASK		(1 << 13)
 #define PMX_SSP_CS_MASK		(1 << 12)
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index c17ae22..0c6fcb4 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -401,7 +401,7 @@
 /**
  * rio_map_inb_region -- Map inbound memory region.
  * @mport: Master port.
- * @lstart: physical address of memory region to be mapped
+ * @local: physical address of memory region to be mapped
  * @rbase: RIO base address assigned to this window
  * @size: Size of the memory region
  * @rflags: Flags for mapping.
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 5c4829c..e872c8b 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1381,22 +1381,14 @@
 }
 EXPORT_SYMBOL_GPL(regulator_get_exclusive);
 
-/**
- * regulator_put - "free" the regulator source
- * @regulator: regulator source
- *
- * Note: drivers must ensure that all regulator_enable calls made on this
- * regulator source are balanced by regulator_disable calls prior to calling
- * this function.
- */
-void regulator_put(struct regulator *regulator)
+/* Locks held by regulator_put() */
+static void _regulator_put(struct regulator *regulator)
 {
 	struct regulator_dev *rdev;
 
 	if (regulator == NULL || IS_ERR(regulator))
 		return;
 
-	mutex_lock(&regulator_list_mutex);
 	rdev = regulator->rdev;
 
 	debugfs_remove_recursive(regulator->debugfs);
@@ -1412,6 +1404,20 @@
 	rdev->exclusive = 0;
 
 	module_put(rdev->owner);
+}
+
+/**
+ * regulator_put - "free" the regulator source
+ * @regulator: regulator source
+ *
+ * Note: drivers must ensure that all regulator_enable calls made on this
+ * regulator source are balanced by regulator_disable calls prior to calling
+ * this function.
+ */
+void regulator_put(struct regulator *regulator)
+{
+	mutex_lock(&regulator_list_mutex);
+	_regulator_put(regulator);
 	mutex_unlock(&regulator_list_mutex);
 }
 EXPORT_SYMBOL_GPL(regulator_put);
@@ -1974,7 +1980,7 @@
 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
 		ret = regulator_get_voltage(regulator);
 		if (ret >= 0)
-			return (min_uV >= ret && ret <= max_uV);
+			return (min_uV <= ret && ret <= max_uV);
 		else
 			return ret;
 	}
@@ -3365,7 +3371,7 @@
 		if (ret != 0) {
 			rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
 				 config->ena_gpio, ret);
-			goto clean;
+			goto wash;
 		}
 
 		rdev->ena_gpio = config->ena_gpio;
@@ -3445,10 +3451,11 @@
 
 scrub:
 	if (rdev->supply)
-		regulator_put(rdev->supply);
+		_regulator_put(rdev->supply);
 	if (rdev->ena_gpio)
 		gpio_free(rdev->ena_gpio);
 	kfree(rdev->constraints);
+wash:
 	device_unregister(&rdev->dev);
 	/* device core frees rdev */
 	rdev = ERR_PTR(ret);
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c
index 891cd6c..4eed510 100644
--- a/drivers/rtc/rtc-imxdi.c
+++ b/drivers/rtc/rtc-imxdi.c
@@ -392,6 +392,8 @@
 	if (imxdi->ioaddr == NULL)
 		return -ENOMEM;
 
+	spin_lock_init(&imxdi->irq_lock);
+
 	imxdi->irq = platform_get_irq(pdev, 0);
 	if (imxdi->irq < 0)
 		return imxdi->irq;
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index cd01062..7304139 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -17,8 +17,6 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 
-#include <mach/hardware.h>
-
 #define RTC_INPUT_CLK_32768HZ	(0x00 << 5)
 #define RTC_INPUT_CLK_32000HZ	(0x01 << 5)
 #define RTC_INPUT_CLK_38400HZ	(0x02 << 5)
@@ -72,14 +70,38 @@
 #define RTC_TEST2	0x2C	/*  32bit rtc test reg 2 */
 #define RTC_TEST3	0x30	/*  32bit rtc test reg 3 */
 
+enum imx_rtc_type {
+	IMX1_RTC,
+	IMX21_RTC,
+};
+
 struct rtc_plat_data {
 	struct rtc_device *rtc;
 	void __iomem *ioaddr;
 	int irq;
 	struct clk *clk;
 	struct rtc_time g_rtc_alarm;
+	enum imx_rtc_type devtype;
 };
 
+static struct platform_device_id imx_rtc_devtype[] = {
+	{
+		.name = "imx1-rtc",
+		.driver_data = IMX1_RTC,
+	}, {
+		.name = "imx21-rtc",
+		.driver_data = IMX21_RTC,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, imx_rtc_devtype);
+
+static inline int is_imx1_rtc(struct rtc_plat_data *data)
+{
+	return data->devtype == IMX1_RTC;
+}
+
 /*
  * This function is used to obtain the RTC time or the alarm value in
  * second.
@@ -278,10 +300,13 @@
  */
 static int mxc_rtc_set_mmss(struct device *dev, unsigned long time)
 {
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
 	/*
 	 * TTC_DAYR register is 9-bit in MX1 SoC, save time and day of year only
 	 */
-	if (cpu_is_mx1()) {
+	if (is_imx1_rtc(pdata)) {
 		struct rtc_time tm;
 
 		rtc_time_to_tm(time, &tm);
@@ -360,6 +385,8 @@
 	if (!pdata)
 		return -ENOMEM;
 
+	pdata->devtype = pdev->id_entry->driver_data;
+
 	if (!devm_request_mem_region(&pdev->dev, res->start,
 				     resource_size(res), pdev->name))
 		return -EBUSY;
@@ -480,6 +507,7 @@
 #endif
 		   .owner	= THIS_MODULE,
 	},
+	.id_table = imx_rtc_devtype,
 	.probe = mxc_rtc_probe,
 	.remove = __devexit_p(mxc_rtc_remove),
 };
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 9ffb6d5..4ed343e 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -44,7 +44,6 @@
 #define RAW3215_NR_CCWS	    3
 #define RAW3215_TIMEOUT	    HZ/10     /* time for delayed output */
 
-#define RAW3215_FIXED	    1	      /* 3215 console device is not be freed */
 #define RAW3215_WORKING	    4	      /* set if a request is being worked on */
 #define RAW3215_THROTTLED   8	      /* set if reading is disabled */
 #define RAW3215_STOPPED	    16	      /* set if writing is disabled */
@@ -339,8 +338,10 @@
 	struct tty_struct *tty;
 
 	tty = tty_port_tty_get(&raw->port);
-	tty_wakeup(tty);
-	tty_kref_put(tty);
+	if (tty) {
+		tty_wakeup(tty);
+		tty_kref_put(tty);
+	}
 }
 
 /*
@@ -629,8 +630,7 @@
 	DECLARE_WAITQUEUE(wait, current);
 	unsigned long flags;
 
-	if (!(raw->port.flags & ASYNC_INITIALIZED) ||
-			(raw->flags & RAW3215_FIXED))
+	if (!(raw->port.flags & ASYNC_INITIALIZED))
 		return;
 	/* Wait for outstanding requests, then free irq */
 	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
@@ -926,8 +926,6 @@
 	dev_set_drvdata(&cdev->dev, raw);
 	cdev->handler = raw3215_irq;
 
-	raw->flags |= RAW3215_FIXED;
-
 	/* Request the console irq */
 	if (raw3215_startup(raw) != 0) {
 		raw3215_free_info(raw);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index b4d572f..fd00afd 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -377,7 +377,11 @@
 		/* Will be done on the slow path. */
 		return -EAGAIN;
 	}
-	if (stsch_err(schid, &schib) || !css_sch_is_valid(&schib)) {
+	if (stsch_err(schid, &schib)) {
+		/* Subchannel is not provided. */
+		return -ENXIO;
+	}
+	if (!css_sch_is_valid(&schib)) {
 		/* Unusable - ignore. */
 		return 0;
 	}
@@ -536,6 +540,7 @@
 		case -ENOMEM:
 		case -EIO:
 			/* These should abort looping */
+			idset_sch_del_subseq(slow_subchannel_set, schid);
 			break;
 		default:
 			rc = 0;
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 33bb4d8..4af3dfe 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -112,9 +112,6 @@
 extern void css_reiterate_subchannels(void);
 void css_update_ssd_info(struct subchannel *sch);
 
-#define __MAX_SUBCHANNEL 65535
-#define __MAX_SSID 3
-
 struct channel_subsystem {
 	u8 cssid;
 	int valid;
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index fc916f5..fd3143c 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1424,7 +1424,7 @@
 	}
 	if (device_is_disconnected(cdev))
 		return IO_SCH_REPROBE;
-	if (cdev->online)
+	if (cdev->online && !cdev->private->flags.resuming)
 		return IO_SCH_VERIFY;
 	if (cdev->private->state == DEV_STATE_NOT_OPER)
 		return IO_SCH_UNREG_ATTACH;
@@ -1469,12 +1469,6 @@
 		rc = 0;
 		goto out_unlock;
 	case IO_SCH_VERIFY:
-		if (cdev->private->flags.resuming == 1) {
-			if (cio_enable_subchannel(sch, (u32)(addr_t)sch)) {
-				ccw_device_set_notoper(cdev);
-				break;
-			}
-		}
 		/* Trigger path verification. */
 		io_subchannel_verify(sch);
 		rc = 0;
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c
index e6d5f8c..65d13e3 100644
--- a/drivers/s390/cio/idset.c
+++ b/drivers/s390/cio/idset.c
@@ -1,9 +1,10 @@
 /*
- *    Copyright IBM Corp. 2007
+ *    Copyright IBM Corp. 2007, 2012
  *    Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  */
 
 #include <linux/vmalloc.h>
+#include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include "idset.h"
 #include "css.h"
@@ -89,6 +90,14 @@
 	idset_del(set, schid.ssid, schid.sch_no);
 }
 
+/* Clear ids starting from @schid up to end of subchannel set. */
+void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid)
+{
+	int pos = schid.ssid * set->num_id + schid.sch_no;
+
+	bitmap_clear(set->bitmap, pos, set->num_id - schid.sch_no);
+}
+
 int idset_sch_contains(struct idset *set, struct subchannel_id schid)
 {
 	return idset_contains(set, schid.ssid, schid.sch_no);
@@ -111,20 +120,12 @@
 
 int idset_is_empty(struct idset *set)
 {
-	int bitnum;
-
-	bitnum = find_first_bit(set->bitmap, set->num_ssid * set->num_id);
-	if (bitnum >= set->num_ssid * set->num_id)
-		return 1;
-	return 0;
+	return bitmap_empty(set->bitmap, set->num_ssid * set->num_id);
 }
 
 void idset_add_set(struct idset *to, struct idset *from)
 {
-	unsigned long i, len;
+	int len = min(to->num_ssid * to->num_id, from->num_ssid * from->num_id);
 
-	len = min(__BITOPS_WORDS(to->num_ssid * to->num_id),
-		  __BITOPS_WORDS(from->num_ssid * from->num_id));
-	for (i = 0; i < len ; i++)
-		to->bitmap[i] |= from->bitmap[i];
+	bitmap_or(to->bitmap, to->bitmap, from->bitmap, len);
 }
diff --git a/drivers/s390/cio/idset.h b/drivers/s390/cio/idset.h
index 3d943f0..06d3bc0 100644
--- a/drivers/s390/cio/idset.h
+++ b/drivers/s390/cio/idset.h
@@ -1,5 +1,5 @@
 /*
- *    Copyright IBM Corp. 2007
+ *    Copyright IBM Corp. 2007, 2012
  *    Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  */
 
@@ -17,6 +17,7 @@
 struct idset *idset_sch_new(void);
 void idset_sch_add(struct idset *set, struct subchannel_id id);
 void idset_sch_del(struct idset *set, struct subchannel_id id);
+void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid);
 int idset_sch_contains(struct idset *set, struct subchannel_id id);
 int idset_sch_get_first(struct idset *set, struct subchannel_id *id);
 int idset_is_empty(struct idset *set);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 3e25d315..4d6ba00 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2942,13 +2942,33 @@
 	QETH_DBF_TEXT(SETUP, 2, "qipasscb");
 
 	cmd = (struct qeth_ipa_cmd *) data;
+
+	switch (cmd->hdr.return_code) {
+	case IPA_RC_NOTSUPP:
+	case IPA_RC_L2_UNSUPPORTED_CMD:
+		QETH_DBF_TEXT(SETUP, 2, "ipaunsup");
+		card->options.ipa4.supported_funcs |= IPA_SETADAPTERPARMS;
+		card->options.ipa6.supported_funcs |= IPA_SETADAPTERPARMS;
+		return -0;
+	default:
+		if (cmd->hdr.return_code) {
+			QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Unhandled "
+						"rc=%d\n",
+						dev_name(&card->gdev->dev),
+						cmd->hdr.return_code);
+			return 0;
+		}
+	}
+
 	if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
 		card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
 		card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
-	} else {
+	} else if (cmd->hdr.prot_version == QETH_PROT_IPV6) {
 		card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
 		card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
-	}
+	} else
+		QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Flawed LIC detected"
+					"\n", dev_name(&card->gdev->dev));
 	QETH_DBF_TEXT(SETUP, 2, "suppenbl");
 	QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_supported);
 	QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_enabled);
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index e67e025..fddb626 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -626,10 +626,13 @@
 	QETH_DBF_TEXT(SETUP, 2, "doL2init");
 	QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card));
 
-	rc = qeth_query_setadapterparms(card);
-	if (rc) {
-		QETH_DBF_MESSAGE(2, "could not query adapter parameters on "
-			"device %s: x%x\n", CARD_BUS_ID(card), rc);
+	if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
+		rc = qeth_query_setadapterparms(card);
+		if (rc) {
+			QETH_DBF_MESSAGE(2, "could not query adapter "
+				"parameters on device %s: x%x\n",
+				CARD_BUS_ID(card), rc);
+		}
 	}
 
 	if (card->info.type == QETH_CARD_TYPE_IQD ||
@@ -676,7 +679,7 @@
 		return -ERESTARTSYS;
 	}
 	rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]);
-	if (!rc)
+	if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND))
 		rc = qeth_l2_send_setmac(card, addr->sa_data);
 	return rc ? -EINVAL : 0;
 }
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index bd4708a..20fd974 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -149,6 +149,7 @@
 int
 qla24xx_disable_vp(scsi_qla_host_t *vha)
 {
+	unsigned long flags;
 	int ret;
 
 	ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
@@ -156,7 +157,9 @@
 	atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
 
 	/* Remove port id from vp target map */
+	spin_lock_irqsave(&vha->hw->vport_slock, flags);
 	qlt_update_vp_map(vha, RESET_AL_PA);
+	spin_unlock_irqrestore(&vha->hw->vport_slock, flags);
 
 	qla2x00_mark_vp_devices_dead(vha);
 	atomic_set(&vha->vp_state, VP_FAILED);
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 0e09d8f..62aa558 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -557,6 +557,7 @@
 	int pmap_len;
 	fc_port_t *fcport;
 	int global_resets;
+	unsigned long flags;
 
 retry:
 	global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count);
@@ -625,10 +626,10 @@
 	    sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain,
 	    fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id);
 
-	sess->s_id = fcport->d_id;
-	sess->loop_id = fcport->loop_id;
-	sess->conf_compl_supported = !!(fcport->flags &
-	    FCF_CONF_COMP_SUPPORTED);
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id,
+				(fcport->flags & FCF_CONF_COMP_SUPPORTED));
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	res = true;
 
@@ -740,10 +741,9 @@
 				qlt_undelete_sess(sess);
 
 			kref_get(&sess->se_sess->sess_kref);
-			sess->s_id = fcport->d_id;
-			sess->loop_id = fcport->loop_id;
-			sess->conf_compl_supported = !!(fcport->flags &
-			    FCF_CONF_COMP_SUPPORTED);
+			ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id,
+						(fcport->flags & FCF_CONF_COMP_SUPPORTED));
+
 			if (sess->local && !local)
 				sess->local = 0;
 			spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -796,8 +796,7 @@
 	 */
 	kref_get(&sess->se_sess->sess_kref);
 
-	sess->conf_compl_supported = !!(fcport->flags &
-	    FCF_CONF_COMP_SUPPORTED);
+	sess->conf_compl_supported = (fcport->flags & FCF_CONF_COMP_SUPPORTED);
 	BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name));
 	memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name));
 
@@ -869,10 +868,8 @@
 			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007,
 			    "Reappeared sess %p\n", sess);
 		}
-		sess->s_id = fcport->d_id;
-		sess->loop_id = fcport->loop_id;
-		sess->conf_compl_supported = !!(fcport->flags &
-		    FCF_CONF_COMP_SUPPORTED);
+		ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id,
+					(fcport->flags & FCF_CONF_COMP_SUPPORTED));
 	}
 
 	if (sess && sess->local) {
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 170af15..bad7495 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -648,6 +648,7 @@
 
 	int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *,
 					void *, uint8_t *, uint16_t);
+	void (*update_sess)(struct qla_tgt_sess *, port_id_t, uint16_t, bool);
 	struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *,
 						const uint16_t);
 	struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *,
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 2358c16..3d74f2f 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -237,7 +237,7 @@
 				struct tcm_qla2xxx_tpg, se_tpg);
 	struct tcm_qla2xxx_lport *lport = tpg->lport;
 
-	return &lport->lport_name[0];
+	return lport->lport_naa_name;
 }
 
 static char *tcm_qla2xxx_npiv_get_fabric_wwn(struct se_portal_group *se_tpg)
@@ -1457,6 +1457,78 @@
 	return 0;
 }
 
+static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id,
+				    uint16_t loop_id, bool conf_compl_supported)
+{
+	struct qla_tgt *tgt = sess->tgt;
+	struct qla_hw_data *ha = tgt->ha;
+	struct tcm_qla2xxx_lport *lport = ha->tgt.target_lport_ptr;
+	struct se_node_acl *se_nacl = sess->se_sess->se_node_acl;
+	struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl,
+			struct tcm_qla2xxx_nacl, se_node_acl);
+	u32 key;
+
+
+	if (sess->loop_id != loop_id || sess->s_id.b24 != s_id.b24)
+		pr_info("Updating session %p from port %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x loop_id %d -> %d s_id %x:%x:%x -> %x:%x:%x\n",
+			sess,
+			sess->port_name[0], sess->port_name[1],
+			sess->port_name[2], sess->port_name[3],
+			sess->port_name[4], sess->port_name[5],
+			sess->port_name[6], sess->port_name[7],
+			sess->loop_id, loop_id,
+			sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa,
+			s_id.b.domain, s_id.b.area, s_id.b.al_pa);
+
+	if (sess->loop_id != loop_id) {
+		/*
+		 * Because we can shuffle loop IDs around and we
+		 * update different sessions non-atomically, we might
+		 * have overwritten this session's old loop ID
+		 * already, and we might end up overwriting some other
+		 * session that will be updated later.  So we have to
+		 * be extra careful and we can't warn about those things...
+		 */
+		if (lport->lport_loopid_map[sess->loop_id].se_nacl == se_nacl)
+			lport->lport_loopid_map[sess->loop_id].se_nacl = NULL;
+
+		lport->lport_loopid_map[loop_id].se_nacl = se_nacl;
+
+		sess->loop_id = loop_id;
+	}
+
+	if (sess->s_id.b24 != s_id.b24) {
+		key = (((u32) sess->s_id.b.domain << 16) |
+		       ((u32) sess->s_id.b.area   <<  8) |
+		       ((u32) sess->s_id.b.al_pa));
+
+		if (btree_lookup32(&lport->lport_fcport_map, key))
+			WARN(btree_remove32(&lport->lport_fcport_map, key) != se_nacl,
+			     "Found wrong se_nacl when updating s_id %x:%x:%x\n",
+			     sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa);
+		else
+			WARN(1, "No lport_fcport_map entry for s_id %x:%x:%x\n",
+			     sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa);
+
+		key = (((u32) s_id.b.domain << 16) |
+		       ((u32) s_id.b.area   <<  8) |
+		       ((u32) s_id.b.al_pa));
+
+		if (btree_lookup32(&lport->lport_fcport_map, key)) {
+			WARN(1, "Already have lport_fcport_map entry for s_id %x:%x:%x\n",
+			     s_id.b.domain, s_id.b.area, s_id.b.al_pa);
+			btree_update32(&lport->lport_fcport_map, key, se_nacl);
+		} else {
+			btree_insert32(&lport->lport_fcport_map, key, se_nacl, GFP_ATOMIC);
+		}
+
+		sess->s_id = s_id;
+		nacl->nport_id = key;
+	}
+
+	sess->conf_compl_supported = conf_compl_supported;
+}
+
 /*
  * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path.
  */
@@ -1467,6 +1539,7 @@
 	.free_cmd		= tcm_qla2xxx_free_cmd,
 	.free_mcmd		= tcm_qla2xxx_free_mcmd,
 	.free_session		= tcm_qla2xxx_free_session,
+	.update_sess		= tcm_qla2xxx_update_sess,
 	.check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl,
 	.find_sess_by_s_id	= tcm_qla2xxx_find_sess_by_s_id,
 	.find_sess_by_loop_id	= tcm_qla2xxx_find_sess_by_loop_id,
@@ -1534,6 +1607,7 @@
 	lport->lport_wwpn = wwpn;
 	tcm_qla2xxx_format_wwn(&lport->lport_name[0], TCM_QLA2XXX_NAMELEN,
 				wwpn);
+	sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) wwpn);
 
 	ret = tcm_qla2xxx_init_lport(lport);
 	if (ret != 0)
@@ -1601,6 +1675,7 @@
 	lport->lport_npiv_wwnn = npiv_wwnn;
 	tcm_qla2xxx_npiv_format_wwn(&lport->lport_npiv_name[0],
 			TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn);
+	sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn);
 
 /* FIXME: tcm_qla2xxx_npiv_make_lport */
 	ret = -ENOSYS;
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/drivers/scsi/qla2xxx/tcm_qla2xxx.h
index 8254981..9ba075f 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.h
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.h
@@ -61,6 +61,8 @@
 	u64 lport_npiv_wwnn;
 	/* ASCII formatted WWPN for FC Target Lport */
 	char lport_name[TCM_QLA2XXX_NAMELEN];
+	/* ASCII formatted naa WWPN for VPD page 83 etc */
+	char lport_naa_name[TCM_QLA2XXX_NAMELEN];
 	/* ASCII formatted WWPN+WWNN for NPIV FC Target Lport */
 	char lport_npiv_name[TCM_QLA2XXX_NPIV_NAMELEN];
 	/* map for fc_port pointers in 24-bit FC Port ID space */
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index b191dd5..71fddbc 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -1294,26 +1294,19 @@
 static const struct of_device_id qpti_match[];
 static int __devinit qpti_sbus_probe(struct platform_device *op)
 {
-	const struct of_device_id *match;
-	struct scsi_host_template *tpnt;
 	struct device_node *dp = op->dev.of_node;
 	struct Scsi_Host *host;
 	struct qlogicpti *qpti;
 	static int nqptis;
 	const char *fcode;
 
-	match = of_match_device(qpti_match, &op->dev);
-	if (!match)
-		return -EINVAL;
-	tpnt = match->data;
-
 	/* Sometimes Antares cards come up not completely
 	 * setup, and we get a report of a zero IRQ.
 	 */
 	if (op->archdata.irqs[0] == 0)
 		return -ENODEV;
 
-	host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti));
+	host = scsi_host_alloc(&qpti_template, sizeof(struct qlogicpti));
 	if (!host)
 		return -ENOMEM;
 
@@ -1445,19 +1438,15 @@
 static const struct of_device_id qpti_match[] = {
 	{
 		.name = "ptisp",
-		.data = &qpti_template,
 	},
 	{
 		.name = "PTI,ptisp",
-		.data = &qpti_template,
 	},
 	{
 		.name = "QLGC,isp",
-		.data = &qpti_template,
 	},
 	{
 		.name = "SUNW,isp",
-		.data = &qpti_template,
 	},
 	{},
 };
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
index 07e9fb4..b3dc441 100644
--- a/drivers/sh/clk/cpg.c
+++ b/drivers/sh/clk/cpg.c
@@ -361,3 +361,89 @@
 	return sh_clk_div_register_ops(clks, nr, table,
 				       &sh_clk_div4_reparent_clk_ops);
 }
+
+/* FSI-DIV */
+static unsigned long fsidiv_recalc(struct clk *clk)
+{
+	u32 value;
+
+	value = __raw_readl(clk->mapping->base);
+
+	value >>= 16;
+	if (value < 2)
+		return clk->parent->rate;
+
+	return clk->parent->rate / value;
+}
+
+static long fsidiv_round_rate(struct clk *clk, unsigned long rate)
+{
+	return clk_rate_div_range_round(clk, 1, 0xffff, rate);
+}
+
+static void fsidiv_disable(struct clk *clk)
+{
+	__raw_writel(0, clk->mapping->base);
+}
+
+static int fsidiv_enable(struct clk *clk)
+{
+	u32 value;
+
+	value  = __raw_readl(clk->mapping->base) >> 16;
+	if (value < 2)
+		return 0;
+
+	__raw_writel((value << 16) | 0x3, clk->mapping->base);
+
+	return 0;
+}
+
+static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 val;
+	int idx;
+
+	idx = (clk->parent->rate / rate) & 0xffff;
+	if (idx < 2)
+		__raw_writel(0, clk->mapping->base);
+	else
+		__raw_writel(idx << 16, clk->mapping->base);
+
+	return 0;
+}
+
+static struct sh_clk_ops fsidiv_clk_ops = {
+	.recalc		= fsidiv_recalc,
+	.round_rate	= fsidiv_round_rate,
+	.set_rate	= fsidiv_set_rate,
+	.enable		= fsidiv_enable,
+	.disable	= fsidiv_disable,
+};
+
+int __init sh_clk_fsidiv_register(struct clk *clks, int nr)
+{
+	struct clk_mapping *map;
+	int i;
+
+	for (i = 0; i < nr; i++) {
+
+		map = kzalloc(sizeof(struct clk_mapping), GFP_KERNEL);
+		if (!map) {
+			pr_err("%s: unable to alloc memory\n", __func__);
+			return -ENOMEM;
+		}
+
+		/* clks[i].enable_reg came from SH_CLK_FSIDIV() */
+		map->phys		= (phys_addr_t)clks[i].enable_reg;
+		map->len		= 8;
+
+		clks[i].enable_reg	= 0; /* remove .enable_reg */
+		clks[i].ops		= &fsidiv_clk_ops;
+		clks[i].mapping		= map;
+
+		clk_register(&clks[i]);
+	}
+
+	return 0;
+}
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
index edf1360..86dd04d 100644
--- a/drivers/spi/spi-mxs.c
+++ b/drivers/spi/spi-mxs.c
@@ -323,6 +323,7 @@
 	if (!ret) {
 		dev_err(ssp->dev, "DMA transfer timeout\n");
 		ret = -ETIMEDOUT;
+		dmaengine_terminate_all(ssp->dmach);
 		goto err_vmalloc;
 	}
 
@@ -480,7 +481,7 @@
 		first = last = 0;
 	}
 
-	m->status = 0;
+	m->status = status;
 	spi_finalize_current_message(master);
 
 	return status;
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 9194641..a1db91a 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2186,8 +2186,6 @@
 	printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n",
 	       adev->res.start, pl022->virtbase);
 
-	pm_runtime_resume(dev);
-
 	pl022->clk = devm_clk_get(&adev->dev, NULL);
 	if (IS_ERR(pl022->clk)) {
 		status = PTR_ERR(pl022->clk);
@@ -2292,7 +2290,6 @@
 
 	clk_disable(pl022->clk);
 	clk_unprepare(pl022->clk);
-	pm_runtime_disable(&adev->dev);
 	amba_release_regions(adev);
 	tasklet_disable(&pl022->pump_transfers);
 	spi_unregister_master(pl022->master);
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 4894bde..30faf6d 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -147,8 +147,6 @@
 	unsigned char spsr;
 
 	/* for dmaengine */
-	struct sh_dmae_slave dma_tx;
-	struct sh_dmae_slave dma_rx;
 	struct dma_chan *chan_tx;
 	struct dma_chan *chan_rx;
 	int irq;
@@ -663,20 +661,16 @@
 	return ret;
 }
 
-static bool rspi_filter(struct dma_chan *chan, void *filter_param)
-{
-	chan->private = filter_param;
-	return true;
-}
-
-static void __devinit rspi_request_dma(struct rspi_data *rspi,
-				       struct platform_device *pdev)
+static int __devinit rspi_request_dma(struct rspi_data *rspi,
+				      struct platform_device *pdev)
 {
 	struct rspi_plat_data *rspi_pd = pdev->dev.platform_data;
 	dma_cap_mask_t mask;
+	struct dma_slave_config cfg;
+	int ret;
 
 	if (!rspi_pd)
-		return;
+		return 0;	/* The driver assumes no error. */
 
 	rspi->dma_width_16bit = rspi_pd->dma_width_16bit;
 
@@ -684,21 +678,35 @@
 	if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) {
 		dma_cap_zero(mask);
 		dma_cap_set(DMA_SLAVE, mask);
-		rspi->dma_rx.slave_id = rspi_pd->dma_rx_id;
-		rspi->chan_rx = dma_request_channel(mask, rspi_filter,
-						    &rspi->dma_rx);
-		if (rspi->chan_rx)
-			dev_info(&pdev->dev, "Use DMA when rx.\n");
+		rspi->chan_rx = dma_request_channel(mask, shdma_chan_filter,
+						    (void *)rspi_pd->dma_rx_id);
+		if (rspi->chan_rx) {
+			cfg.slave_id = rspi_pd->dma_rx_id;
+			cfg.direction = DMA_DEV_TO_MEM;
+			ret = dmaengine_slave_config(rspi->chan_rx, &cfg);
+			if (!ret)
+				dev_info(&pdev->dev, "Use DMA when rx.\n");
+			else
+				return ret;
+		}
 	}
 	if (rspi_pd->dma_tx_id) {
 		dma_cap_zero(mask);
 		dma_cap_set(DMA_SLAVE, mask);
-		rspi->dma_tx.slave_id = rspi_pd->dma_tx_id;
-		rspi->chan_tx = dma_request_channel(mask, rspi_filter,
-						    &rspi->dma_tx);
-		if (rspi->chan_tx)
-			dev_info(&pdev->dev, "Use DMA when tx\n");
+		rspi->chan_tx = dma_request_channel(mask, shdma_chan_filter,
+						    (void *)rspi_pd->dma_tx_id);
+		if (rspi->chan_tx) {
+			cfg.slave_id = rspi_pd->dma_tx_id;
+			cfg.direction = DMA_MEM_TO_DEV;
+			ret = dmaengine_slave_config(rspi->chan_tx, &cfg);
+			if (!ret)
+				dev_info(&pdev->dev, "Use DMA when tx\n");
+			else
+				return ret;
+		}
 	}
+
+	return 0;
 }
 
 static void __devexit rspi_release_dma(struct rspi_data *rspi)
@@ -788,7 +796,11 @@
 	}
 
 	rspi->irq = irq;
-	rspi_request_dma(rspi, pdev);
+	ret = rspi_request_dma(rspi, pdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "rspi_request_dma failed.\n");
+		goto error4;
+	}
 
 	ret = spi_register_master(master);
 	if (ret < 0) {
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h
index f2ffd96..d0cafd6 100644
--- a/drivers/staging/android/android_alarm.h
+++ b/drivers/staging/android/android_alarm.h
@@ -51,12 +51,10 @@
 #define ANDROID_ALARM_WAIT                  _IO('a', 1)
 
 #define ALARM_IOW(c, type, size)            _IOW('a', (c) | ((type) << 4), size)
-#define ALARM_IOR(c, type, size)            _IOR('a', (c) | ((type) << 4), size)
-
 /* Set alarm */
 #define ANDROID_ALARM_SET(type)             ALARM_IOW(2, type, struct timespec)
 #define ANDROID_ALARM_SET_AND_WAIT(type)    ALARM_IOW(3, type, struct timespec)
-#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOR(4, type, struct timespec)
+#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOW(4, type, struct timespec)
 #define ANDROID_ALARM_SET_RTC               _IOW('a', 5, struct timespec)
 #define ANDROID_ALARM_BASE_CMD(cmd)         (cmd & ~(_IOC(0, 0, 0xf0, 0)))
 #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd)    (_IOC_NR(cmd) >> 4)
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 7b0ba92..5d4610b 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -567,7 +567,7 @@
 		page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE];
 
 		BUG_ON(*page);
-		*page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+		*page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
 		if (*page == NULL) {
 			pr_err("binder: %d: binder_alloc_buf failed "
 			       "for page at %p\n", proc->pid, page_addr);
@@ -2419,14 +2419,38 @@
 			struct binder_transaction *t;
 
 			t = container_of(w, struct binder_transaction, work);
-			if (t->buffer->target_node && !(t->flags & TF_ONE_WAY))
+			if (t->buffer->target_node &&
+			    !(t->flags & TF_ONE_WAY)) {
 				binder_send_failed_reply(t, BR_DEAD_REPLY);
+			} else {
+				binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+					"binder: undelivered transaction %d\n",
+					t->debug_id);
+				t->buffer->transaction = NULL;
+				kfree(t);
+				binder_stats_deleted(BINDER_STAT_TRANSACTION);
+			}
 		} break;
 		case BINDER_WORK_TRANSACTION_COMPLETE: {
+			binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+				"binder: undelivered TRANSACTION_COMPLETE\n");
 			kfree(w);
 			binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
 		} break;
+		case BINDER_WORK_DEAD_BINDER_AND_CLEAR:
+		case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: {
+			struct binder_ref_death *death;
+
+			death = container_of(w, struct binder_ref_death, work);
+			binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+				"binder: undelivered death notification, %p\n",
+				death->cookie);
+			kfree(death);
+			binder_stats_deleted(BINDER_STAT_DEATH);
+		} break;
 		default:
+			pr_err("binder: unexpected work type, %d, not freed\n",
+			       w->type);
 			break;
 		}
 	}
@@ -2899,6 +2923,7 @@
 		nodes++;
 		rb_erase(&node->rb_node, &proc->nodes);
 		list_del_init(&node->work.entry);
+		binder_release_work(&node->async_todo);
 		if (hlist_empty(&node->refs)) {
 			kfree(node);
 			binder_stats_deleted(BINDER_STAT_NODE);
@@ -2937,6 +2962,7 @@
 		binder_delete_ref(ref);
 	}
 	binder_release_work(&proc->todo);
+	binder_release_work(&proc->delivered_death);
 	buffers = 0;
 
 	while ((n = rb_first(&proc->allocated_buffers))) {
diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c
index 7dff3c0..d00aff6 100644
--- a/drivers/staging/comedi/drivers/8255_pci.c
+++ b/drivers/staging/comedi/drivers/8255_pci.c
@@ -289,6 +289,8 @@
 	struct comedi_subdevice *s;
 	int i;
 
+	if (!board || !devpriv)
+		return;
 	if (dev->subdevices) {
 		for (i = 0; i < board->n_8255; i++) {
 			s = &dev->subdevices[i];
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index 08f3052..29eb52d 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -1410,6 +1410,8 @@
 	const struct dio200_layout_struct *layout;
 	unsigned n;
 
+	if (!thisboard)
+		return;
 	if (dev->irq)
 		free_irq(dev->irq, dev);
 	if (dev->subdevices) {
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
index eacb5e4..4e4f3c1 100644
--- a/drivers/staging/comedi/drivers/amplc_pc236.c
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -573,9 +573,10 @@
 static void pc236_detach(struct comedi_device *dev)
 {
 	const struct pc236_board *thisboard = comedi_board(dev);
-	struct pc236_private *devpriv = dev->private;
 
-	if (devpriv)
+	if (!thisboard)
+		return;
+	if (dev->iobase)
 		pc236_intr_disable(dev);
 	if (dev->irq)
 		free_irq(dev->irq, dev);
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
index 60830cc..d0a4c44 100644
--- a/drivers/staging/comedi/drivers/amplc_pc263.c
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -323,6 +323,8 @@
 {
 	const struct pc263_board *thisboard = comedi_board(dev);
 
+	if (!thisboard)
+		return;
 	if (is_isa_board(thisboard)) {
 		if (dev->iobase)
 			release_region(dev->iobase, PC263_IO_SIZE);
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
index 5fd21fa..c304528 100644
--- a/drivers/staging/comedi/drivers/das08.c
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -846,6 +846,8 @@
 {
 	const struct das08_board_struct *thisboard = comedi_board(dev);
 
+	if (!thisboard)
+		return;
 	das08_common_detach(dev);
 	if (is_isa_board(thisboard)) {
 		if (dev->iobase)
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index 2ba0ade..68d7c6a 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -95,7 +95,7 @@
 	}
 
 	data[1] = s->state & 0xff;
-	data[1] |= inb(dev->iobase + DIO_R);
+	data[1] |= inb(dev->iobase + DIO_R) << 8;
 
 	return insn->n;
 }
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index 28b91a6..b5a19a0 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -772,6 +772,8 @@
 {
 	struct comedi_subdevice *s;
 
+	if (!thisboard)
+		return;
 	if (dev->subdevices) {
 		s = &dev->subdevices[2];
 		subdev_8255_cleanup(dev, s);
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index 8e37d6e..b12ca68 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -310,30 +310,32 @@
 	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_VOLTAGE:
-			*val = 0;
-			if (chan->channel == 0)
-				*val2 = 1220;
-			else
-				*val2 = 610;
+			if (chan->channel == 0) {
+				*val = 1;
+				*val2 = 220000; /* 1.22 mV */
+			} else {
+				*val = 0;
+				*val2 = 610000; /* 0.610 mV */
+			}
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_TEMP:
-			*val = 0;
-			*val2 = -470000;
+			*val = -470; /* 0.47 C */
+			*val2 = 0;
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_ACCEL:
 			*val = 0;
-			*val2 = 462500;
-			return IIO_VAL_INT_PLUS_MICRO;
+			*val2 = IIO_G_TO_M_S_2(462400); /* 0.4624 mg */
+			return IIO_VAL_INT_PLUS_NANO;
 		case IIO_INCLI:
 			*val = 0;
-			*val2 = 100000;
+			*val2 = 100000; /* 0.1 degree */
 			return IIO_VAL_INT_PLUS_MICRO;
 		default:
 			return -EINVAL;
 		}
 		break;
 	case IIO_CHAN_INFO_OFFSET:
-		*val = 25;
+		*val = 25000 / -470 - 1278; /* 25 C = 1278 */
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBBIAS:
 		switch (chan->type) {
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index 002fa9d..e7b3441 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -316,25 +316,27 @@
 	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_VOLTAGE:
-			*val = 0;
-			if (chan->channel == 0)
-				*val2 = 1220;
-			else
-				*val2 = 610;
+			if (chan->channel == 0) {
+				*val = 1;
+				*val2 = 220000; /* 1.22 mV */
+			} else {
+				*val = 0;
+				*val2 = 610000; /* 0.61 mV */
+			}
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_TEMP:
-			*val = 0;
-			*val2 = -470000;
+			*val = -470; /* -0.47 C */
+			*val2 = 0;
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_INCLI:
 			*val = 0;
-			*val2 = 25000;
+			*val2 = 25000; /* 0.025 degree */
 			return IIO_VAL_INT_PLUS_MICRO;
 		default:
 			return -EINVAL;
 		}
 	case IIO_CHAN_INFO_OFFSET:
-		*val = 25;
+		*val = 25000 / -470 - 1278; /* 25 C = 1278 */
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBBIAS:
 		bits = 14;
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index 05bdb7c..c6234c2 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -317,26 +317,28 @@
 	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_VOLTAGE:
-			*val = 0;
-			if (chan->channel == 0)
-				*val2 = 1220;
-			else
-				*val2 = 610;
+			if (chan->channel == 0) {
+				*val = 1;
+				*val2 = 220000; /* 1.22 mV */
+			} else {
+				*val = 0;
+				*val2 = 610000; /* 0.61 mV */
+			}
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_TEMP:
-			*val = 0;
-			*val2 = -470000;
+			*val = -470; /* 0.47 C */
+			*val2 = 0;
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_ACCEL:
 			*val = 0;
 			switch (chan->channel2) {
 			case IIO_MOD_X:
 			case IIO_MOD_ROOT_SUM_SQUARED_X_Y:
-				*val2 = 17125;
+				*val2 = IIO_G_TO_M_S_2(17125); /* 17.125 mg */
 				break;
 			case IIO_MOD_Y:
 			case IIO_MOD_Z:
-				*val2 = 8407;
+				*val2 = IIO_G_TO_M_S_2(8407); /* 8.407 mg */
 				break;
 			}
 			return IIO_VAL_INT_PLUS_MICRO;
@@ -345,7 +347,7 @@
 		}
 		break;
 	case IIO_CHAN_INFO_OFFSET:
-		*val = 25;
+		*val = 25000 / -470 - 1278; /* 25 C = 1278 */
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBBIAS:
 	case IIO_CHAN_INFO_PEAK:
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index b7333bf..7ee974b 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -343,28 +343,29 @@
 		case IIO_VOLTAGE:
 			*val = 0;
 			if (chan->channel == 0)
-				*val2 = 305180;
+				*val2 = 305180; /* 0.30518 mV */
 			else
-				*val2 = 610500;
+				*val2 = 610500; /* 0.6105 mV */
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_TEMP:
-			*val = 0;
-			*val2 = -470000;
+			*val = -470; /* -0.47 C */
+			*val2 = 0;
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_ACCEL:
 			*val = 0;
-			*val2 = 2394;
-			return IIO_VAL_INT_PLUS_MICRO;
+			*val2 = IIO_G_TO_M_S_2(244140); /* 0.244140 mg */
+			return IIO_VAL_INT_PLUS_NANO;
 		case IIO_INCLI:
+		case IIO_ROT:
 			*val = 0;
-			*val2 = 436;
+			*val2 = 25000; /* 0.025 degree */
 			return IIO_VAL_INT_PLUS_MICRO;
 		default:
 			return -EINVAL;
 		}
 		break;
 	case IIO_CHAN_INFO_OFFSET:
-		*val = 25;
+		*val = 25000 / -470 - 0x4FE; /* 25 C = 0x4FE */
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBBIAS:
 		switch (chan->type) {
@@ -491,6 +492,7 @@
 		.modified = 1,
 		.channel2 = IIO_MOD_X,
 		.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.address = rot,
 		.scan_index = ADIS16209_SCAN_ROT,
 		.scan_type = {
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index c755089..eaadd9d 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -486,7 +486,7 @@
 		break;
 	case IIO_CHAN_INFO_OFFSET:
 		if (chan->type == IIO_TEMP) {
-			*val = 25;
+			*val = 25000 / -470 - 1278; /* 25 C = 1278 */
 			return IIO_VAL_INT;
 		}
 		addrind = 1;
@@ -495,19 +495,22 @@
 		addrind = 2;
 		break;
 	case IIO_CHAN_INFO_SCALE:
-		*val = 0;
 		switch (chan->type) {
 		case IIO_TEMP:
-			*val2 = -470000;
+			*val = -470; /* -0.47 C */
+			*val2 = 0;
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_ACCEL:
-			*val2 = 1887042;
+			*val2 = IIO_G_TO_M_S_2(19073); /* 19.073 g */
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_VOLTAGE:
-			if (chan->channel == 0)
-				*val2 = 0012221;
-			else /* Should really be dependent on VDD */
-				*val2 = 305;
+			if (chan->channel == 0) {
+				*val = 1;
+				*val2 = 220700; /* 1.2207 mV */
+			} else {
+				/* Should really be dependent on VDD */
+				*val2 = 305180; /* 305.18 uV */
+			}
 			return IIO_VAL_INT_PLUS_MICRO;
 		default:
 			return -EINVAL;
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index 0fc26a49..35e0939 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -373,30 +373,31 @@
 	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_VOLTAGE:
-			*val = 0;
-			if (chan->channel == 0)
-				*val2 = 4880;
-			else
+			if (chan->channel == 0) {
+				*val = 4;
+				*val2 = 880000; /* 4.88 mV */
+				return IIO_VAL_INT_PLUS_MICRO;
+			} else {
 				return -EINVAL;
-			return IIO_VAL_INT_PLUS_MICRO;
+			}
 		case IIO_TEMP:
-			*val = 0;
-			*val2 = 244000;
+			*val = 244; /* 0.244 C */
+			*val2 = 0;
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_ACCEL:
 			*val = 0;
-			*val2 = 504062;
+			*val2 = IIO_G_TO_M_S_2(51400); /* 51.4 mg */
 			return IIO_VAL_INT_PLUS_MICRO;
 		default:
 			return -EINVAL;
 		}
 		break;
 	case IIO_CHAN_INFO_PEAK_SCALE:
-		*val = 6;
-		*val2 = 629295;
+		*val = 0;
+		*val2 = IIO_G_TO_M_S_2(51400); /* 51.4 mg */
 		return IIO_VAL_INT_PLUS_MICRO;
 	case IIO_CHAN_INFO_OFFSET:
-		*val = 25;
+		*val = 25000 / 244 - 0x133; /* 25 C = 0x133 */
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBBIAS:
 		bits = 10;
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index 9571c03..aa964a2 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -498,28 +498,33 @@
 		switch (chan->type) {
 		case IIO_ANGL_VEL:
 			*val = 0;
-			if (spi_get_device_id(st->us)->driver_data)
-				*val2 = 320;
-			else
-				*val2 = 1278;
+			if (spi_get_device_id(st->us)->driver_data) {
+				/* 0.01832 degree / sec */
+				*val2 = IIO_DEGREE_TO_RAD(18320);
+			} else {
+				/* 0.07326 degree / sec */
+				*val2 = IIO_DEGREE_TO_RAD(73260);
+			}
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_VOLTAGE:
-			*val = 0;
-			if (chan->channel == 0)
-				*val2 = 18315;
-			else
-				*val2 = 610500;
+			if (chan->channel == 0) {
+				*val = 1;
+				*val2 = 831500; /* 1.8315 mV */
+			} else {
+				*val = 0;
+				*val2 = 610500; /* 610.5 uV */
+			}
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_TEMP:
-			*val = 0;
-			*val2 = 145300;
+			*val = 145;
+			*val2 = 300000; /* 0.1453 C */
 			return IIO_VAL_INT_PLUS_MICRO;
 		default:
 			return -EINVAL;
 		}
 		break;
 	case IIO_CHAN_INFO_OFFSET:
-		*val = 25;
+		*val = 250000 / 1453; /* 25 C = 0x00 */
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBBIAS:
 		switch (chan->type) {
diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h
index d59d7ac..77c601d 100644
--- a/drivers/staging/iio/imu/adis16400.h
+++ b/drivers/staging/iio/imu/adis16400.h
@@ -139,6 +139,8 @@
 	const long flags;
 	unsigned int gyro_scale_micro;
 	unsigned int accel_scale_micro;
+	int temp_scale_nano;
+	int temp_offset;
 	unsigned long default_scan_mask;
 };
 
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index b302c9b..3144a7b 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -553,10 +553,13 @@
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_VOLTAGE:
 			*val = 0;
-			if (chan->channel == 0)
-				*val2 = 2418;
-			else
-				*val2 = 806;
+			if (chan->channel == 0) {
+				*val = 2;
+				*val2 = 418000; /* 2.418 mV */
+			} else {
+				*val = 0;
+				*val2 = 805800; /* 805.8 uV */
+			}
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_ACCEL:
 			*val = 0;
@@ -564,11 +567,11 @@
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_MAGN:
 			*val = 0;
-			*val2 = 500;
+			*val2 = 500; /* 0.5 mgauss */
 			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_TEMP:
-			*val = 0;
-			*val2 = 140000;
+			*val = st->variant->temp_scale_nano / 1000000;
+			*val2 = (st->variant->temp_scale_nano % 1000000);
 			return IIO_VAL_INT_PLUS_MICRO;
 		default:
 			return -EINVAL;
@@ -586,9 +589,8 @@
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_OFFSET:
 		/* currently only temperature */
-		*val = 198;
-		*val2 = 160000;
-		return IIO_VAL_INT_PLUS_MICRO;
+		*val = st->variant->temp_offset;
+		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
 		mutex_lock(&indio_dev->mlock);
 		/* Need both the number of taps and the sampling frequency */
@@ -1035,7 +1037,7 @@
 		.indexed = 1,
 		.channel = 0,
 		.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-		IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
 		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.address = temp0,
 		.scan_index = ADIS16400_SCAN_TEMP,
@@ -1058,8 +1060,10 @@
 	[ADIS16300] = {
 		.channels = adis16300_channels,
 		.num_channels = ARRAY_SIZE(adis16300_channels),
-		.gyro_scale_micro = 873,
+		.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
 		.accel_scale_micro = 5884,
+		.temp_scale_nano = 140000000, /* 0.14 C */
+		.temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
 		.default_scan_mask = (1 << ADIS16400_SCAN_SUPPLY) |
 		(1 << ADIS16400_SCAN_GYRO_X) | (1 << ADIS16400_SCAN_ACC_X) |
 		(1 << ADIS16400_SCAN_ACC_Y) | (1 << ADIS16400_SCAN_ACC_Z) |
@@ -1070,8 +1074,10 @@
 	[ADIS16334] = {
 		.channels = adis16334_channels,
 		.num_channels = ARRAY_SIZE(adis16334_channels),
-		.gyro_scale_micro = 873,
-		.accel_scale_micro = 981,
+		.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
+		.accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
+		.temp_scale_nano = 67850000, /* 0.06785 C */
+		.temp_offset = 25000000 / 67850, /* 25 C = 0x00 */
 		.default_scan_mask = (1 << ADIS16400_SCAN_GYRO_X) |
 		(1 << ADIS16400_SCAN_GYRO_Y) | (1 << ADIS16400_SCAN_GYRO_Z) |
 		(1 << ADIS16400_SCAN_ACC_X) | (1 << ADIS16400_SCAN_ACC_Y) |
@@ -1080,8 +1086,10 @@
 	[ADIS16350] = {
 		.channels = adis16350_channels,
 		.num_channels = ARRAY_SIZE(adis16350_channels),
-		.gyro_scale_micro = 872664,
-		.accel_scale_micro = 24732,
+		.gyro_scale_micro = IIO_DEGREE_TO_RAD(73260), /* 0.07326 deg/s */
+		.accel_scale_micro = IIO_G_TO_M_S_2(2522), /* 0.002522 g */
+		.temp_scale_nano = 145300000, /* 0.1453 C */
+		.temp_offset = 25000000 / 145300, /* 25 C = 0x00 */
 		.default_scan_mask = 0x7FF,
 		.flags = ADIS16400_NO_BURST,
 	},
@@ -1090,8 +1098,10 @@
 		.num_channels = ARRAY_SIZE(adis16350_channels),
 		.flags = ADIS16400_HAS_PROD_ID,
 		.product_id = 0x3FE8,
-		.gyro_scale_micro = 1279,
-		.accel_scale_micro = 24732,
+		.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
+		.accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
+		.temp_scale_nano = 136000000, /* 0.136 C */
+		.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
 		.default_scan_mask = 0x7FF,
 	},
 	[ADIS16362] = {
@@ -1099,8 +1109,10 @@
 		.num_channels = ARRAY_SIZE(adis16350_channels),
 		.flags = ADIS16400_HAS_PROD_ID,
 		.product_id = 0x3FEA,
-		.gyro_scale_micro = 1279,
-		.accel_scale_micro = 24732,
+		.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
+		.accel_scale_micro = IIO_G_TO_M_S_2(333), /* 0.333 mg */
+		.temp_scale_nano = 136000000, /* 0.136 C */
+		.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
 		.default_scan_mask = 0x7FF,
 	},
 	[ADIS16364] = {
@@ -1108,8 +1120,10 @@
 		.num_channels = ARRAY_SIZE(adis16350_channels),
 		.flags = ADIS16400_HAS_PROD_ID,
 		.product_id = 0x3FEC,
-		.gyro_scale_micro = 1279,
-		.accel_scale_micro = 24732,
+		.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
+		.accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
+		.temp_scale_nano = 136000000, /* 0.136 C */
+		.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
 		.default_scan_mask = 0x7FF,
 	},
 	[ADIS16365] = {
@@ -1117,8 +1131,10 @@
 		.num_channels = ARRAY_SIZE(adis16350_channels),
 		.flags = ADIS16400_HAS_PROD_ID,
 		.product_id = 0x3FED,
-		.gyro_scale_micro = 1279,
-		.accel_scale_micro = 24732,
+		.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
+		.accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
+		.temp_scale_nano = 136000000, /* 0.136 C */
+		.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
 		.default_scan_mask = 0x7FF,
 	},
 	[ADIS16400] = {
@@ -1126,9 +1142,11 @@
 		.num_channels = ARRAY_SIZE(adis16400_channels),
 		.flags = ADIS16400_HAS_PROD_ID,
 		.product_id = 0x4015,
-		.gyro_scale_micro = 873,
-		.accel_scale_micro = 32656,
+		.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
+		.accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
 		.default_scan_mask = 0xFFF,
+		.temp_scale_nano = 140000000, /* 0.14 C */
+		.temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
 	}
 };
 
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c
index bb8aa70..46d6657 100644
--- a/drivers/staging/ipack/bridges/tpci200.c
+++ b/drivers/staging/ipack/bridges/tpci200.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include "tpci200.h"
 
 static u16 tpci200_status_timeout[] = {
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c
index 094fdc3..97cdf08 100644
--- a/drivers/staging/nvec/nvec.c
+++ b/drivers/staging/nvec/nvec.c
@@ -39,7 +39,6 @@
 #include <linux/workqueue.h>
 
 #include <mach/clk.h>
-#include <mach/iomap.h>
 
 #include "nvec.h"
 
diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c
index 3434e6e..66e2c2f 100644
--- a/drivers/staging/omapdrm/omap_gem.c
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -246,7 +246,7 @@
 	 * DSS, GPU, etc. are not cache coherent:
 	 */
 	if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) {
-		addrs = kmalloc(npages * sizeof(addrs), GFP_KERNEL);
+		addrs = kmalloc(npages * sizeof(*addrs), GFP_KERNEL);
 		if (!addrs) {
 			ret = -ENOMEM;
 			goto free_pages;
@@ -257,7 +257,7 @@
 					0, PAGE_SIZE, DMA_BIDIRECTIONAL);
 		}
 	} else {
-		addrs = kzalloc(npages * sizeof(addrs), GFP_KERNEL);
+		addrs = kzalloc(npages * sizeof(*addrs), GFP_KERNEL);
 		if (!addrs) {
 			ret = -ENOMEM;
 			goto free_pages;
diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig
index 843c541..3abf661 100644
--- a/drivers/staging/ramster/Kconfig
+++ b/drivers/staging/ramster/Kconfig
@@ -18,6 +18,7 @@
 config RAMSTER
 	bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem"
 	depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE2=y
+	depends on NET
 	# must ensure struct page is 8-byte aligned
 	select HAVE_ALIGNED_STRUCT_PAGE if !64_BIT
 	default n
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
index 066a3ce..f619fb3 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430.c
@@ -126,7 +126,8 @@
 				  u32 ul_num_bytes,
 				  struct hw_mmu_map_attrs_t *hw_attrs);
 
-bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr);
+bool wait_for_start(struct bridge_dev_context *dev_context,
+			void __iomem *sync_addr);
 
 /*  ----------------------------------- Globals */
 
@@ -363,10 +364,11 @@
 {
 	int status = 0;
 	struct bridge_dev_context *dev_context = dev_ctxt;
-	u32 dw_sync_addr = 0;
+	void __iomem *sync_addr;
 	u32 ul_shm_base;	/* Gpp Phys SM base addr(byte) */
 	u32 ul_shm_base_virt;	/* Dsp Virt SM base addr */
 	u32 ul_tlb_base_virt;	/* Base of MMU TLB entry */
+	u32 shm_sync_pa;
 	/* Offset of shm_base_virt from tlb_base_virt */
 	u32 ul_shm_offset_virt;
 	s32 entry_ndx;
@@ -397,15 +399,22 @@
 	/* Kernel logical address */
 	ul_shm_base = dev_context->atlb_entry[0].gpp_va + ul_shm_offset_virt;
 
+	/* SHM physical sync address */
+	shm_sync_pa = dev_context->atlb_entry[0].gpp_pa + ul_shm_offset_virt +
+			SHMSYNCOFFSET;
+
 	/* 2nd wd is used as sync field */
-	dw_sync_addr = ul_shm_base + SHMSYNCOFFSET;
+	sync_addr = ioremap(shm_sync_pa, SZ_32);
+	if (!sync_addr)
+		return -ENOMEM;
+
 	/* Write a signature into the shm base + offset; this will
 	 * get cleared when the DSP program starts. */
 	if ((ul_shm_base_virt == 0) || (ul_shm_base == 0)) {
 		pr_err("%s: Illegal SM base\n", __func__);
 		status = -EPERM;
 	} else
-		__raw_writel(0xffffffff, dw_sync_addr);
+		__raw_writel(0xffffffff, sync_addr);
 
 	if (!status) {
 		resources = dev_context->resources;
@@ -419,8 +428,10 @@
 			 * function is made available.
 			 */
 			void __iomem *ctrl = ioremap(0x48002000, SZ_4K);
-			if (!ctrl)
+			if (!ctrl) {
+				iounmap(sync_addr);
 				return -ENOMEM;
+			}
 
 			(*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK,
 					OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD,
@@ -588,15 +599,15 @@
 		(*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0,
 					OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
 
-		dev_dbg(bridge, "Waiting for Sync @ 0x%x\n", dw_sync_addr);
+		dev_dbg(bridge, "Waiting for Sync @ 0x%x\n", *(u32 *)sync_addr);
 		dev_dbg(bridge, "DSP c_int00 Address =  0x%x\n", dsp_addr);
 		if (dsp_debug)
-			while (__raw_readw(dw_sync_addr))
+			while (__raw_readw(sync_addr))
 				;
 
 		/* Wait for DSP to clear word in shared memory */
 		/* Read the Location */
-		if (!wait_for_start(dev_context, dw_sync_addr))
+		if (!wait_for_start(dev_context, sync_addr))
 			status = -ETIMEDOUT;
 
 		dev_get_symbol(dev_context->dev_obj, "_WDT_enable", &wdt_en);
@@ -612,7 +623,7 @@
 			/* Write the synchronization bit to indicate the
 			 * completion of OPP table update to DSP
 			 */
-			__raw_writel(0XCAFECAFE, dw_sync_addr);
+			__raw_writel(0XCAFECAFE, sync_addr);
 
 			/* update board state */
 			dev_context->brd_state = BRD_RUNNING;
@@ -621,6 +632,9 @@
 			dev_context->brd_state = BRD_UNKNOWN;
 		}
 	}
+
+	iounmap(sync_addr);
+
 	return status;
 }
 
@@ -1796,12 +1810,13 @@
  *  ======== wait_for_start ========
  *      Wait for the singal from DSP that it has started, or time out.
  */
-bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr)
+bool wait_for_start(struct bridge_dev_context *dev_context,
+			void __iomem *sync_addr)
 {
 	u16 timeout = TIHELEN_ACKTIMEOUT;
 
 	/*  Wait for response from board */
-	while (__raw_readw(dw_sync_addr) && --timeout)
+	while (__raw_readw(sync_addr) && --timeout)
 		udelay(10);
 
 	/*  If timed out: return false */
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.c b/drivers/staging/tidspbridge/hw/hw_mmu.c
index 71cb822..50244a4 100644
--- a/drivers/staging/tidspbridge/hw/hw_mmu.c
+++ b/drivers/staging/tidspbridge/hw/hw_mmu.c
@@ -48,37 +48,12 @@
 };
 
 /*
- * FUNCTION	      : mmu_flush_entry
- *
- * INPUTS:
- *
- *       Identifier      : base_address
- *       Type		: const u32
- *       Description     : Base Address of instance of MMU module
- *
- * RETURNS:
- *
- *       Type		: hw_status
- *       Description     : 0		 -- No errors occurred
- *			 RET_BAD_NULL_PARAM     -- A Pointer
- *						Parameter was set to NULL
- *
- * PURPOSE:	      : Flush the TLB entry pointed by the
- *			lock counter register
- *			even if this entry is set protected
- *
- * METHOD:	       : Check the Input parameter and Flush a
- *			 single entry in the TLB.
- */
-static hw_status mmu_flush_entry(const void __iomem *base_address);
-
-/*
  * FUNCTION	      : mmu_set_cam_entry
  *
  * INPUTS:
  *
  *       Identifier      : base_address
- *       TypE		: const u32
+ *       Type		 : void __iomem *
  *       Description     : Base Address of instance of MMU module
  *
  *       Identifier      : page_sz
@@ -112,7 +87,7 @@
  *
  * METHOD:	       	: Check the Input parameters and set the CAM entry.
  */
-static hw_status mmu_set_cam_entry(const void __iomem *base_address,
+static hw_status mmu_set_cam_entry(void __iomem *base_address,
 				   const u32 page_sz,
 				   const u32 preserved_bit,
 				   const u32 valid_bit,
@@ -124,7 +99,7 @@
  * INPUTS:
  *
  *       Identifier      : base_address
- *       Type	    	: const u32
+ *       Type		 : void __iomem *
  *       Description     : Base Address of instance of MMU module
  *
  *       Identifier      : physical_addr
@@ -157,7 +132,7 @@
  *
  * METHOD:	       : Check the Input parameters and set the RAM entry.
  */
-static hw_status mmu_set_ram_entry(const void __iomem *base_address,
+static hw_status mmu_set_ram_entry(void __iomem *base_address,
 				   const u32 physical_addr,
 				   enum hw_endianism_t endianism,
 				   enum hw_element_size_t element_size,
@@ -165,7 +140,7 @@
 
 /* HW FUNCTIONS */
 
-hw_status hw_mmu_enable(const void __iomem *base_address)
+hw_status hw_mmu_enable(void __iomem *base_address)
 {
 	hw_status status = 0;
 
@@ -174,7 +149,7 @@
 	return status;
 }
 
-hw_status hw_mmu_disable(const void __iomem *base_address)
+hw_status hw_mmu_disable(void __iomem *base_address)
 {
 	hw_status status = 0;
 
@@ -183,7 +158,7 @@
 	return status;
 }
 
-hw_status hw_mmu_num_locked_set(const void __iomem *base_address,
+hw_status hw_mmu_num_locked_set(void __iomem *base_address,
 				u32 num_locked_entries)
 {
 	hw_status status = 0;
@@ -193,7 +168,7 @@
 	return status;
 }
 
-hw_status hw_mmu_victim_num_set(const void __iomem *base_address,
+hw_status hw_mmu_victim_num_set(void __iomem *base_address,
 				u32 victim_entry_num)
 {
 	hw_status status = 0;
@@ -203,7 +178,7 @@
 	return status;
 }
 
-hw_status hw_mmu_event_ack(const void __iomem *base_address, u32 irq_mask)
+hw_status hw_mmu_event_ack(void __iomem *base_address, u32 irq_mask)
 {
 	hw_status status = 0;
 
@@ -212,7 +187,7 @@
 	return status;
 }
 
-hw_status hw_mmu_event_disable(const void __iomem *base_address, u32 irq_mask)
+hw_status hw_mmu_event_disable(void __iomem *base_address, u32 irq_mask)
 {
 	hw_status status = 0;
 	u32 irq_reg;
@@ -224,7 +199,7 @@
 	return status;
 }
 
-hw_status hw_mmu_event_enable(const void __iomem *base_address, u32 irq_mask)
+hw_status hw_mmu_event_enable(void __iomem *base_address, u32 irq_mask)
 {
 	hw_status status = 0;
 	u32 irq_reg;
@@ -236,7 +211,7 @@
 	return status;
 }
 
-hw_status hw_mmu_event_status(const void __iomem *base_address, u32 *irq_mask)
+hw_status hw_mmu_event_status(void __iomem *base_address, u32 *irq_mask)
 {
 	hw_status status = 0;
 
@@ -245,7 +220,7 @@
 	return status;
 }
 
-hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, u32 *addr)
+hw_status hw_mmu_fault_addr_read(void __iomem *base_address, u32 *addr)
 {
 	hw_status status = 0;
 
@@ -255,7 +230,7 @@
 	return status;
 }
 
-hw_status hw_mmu_ttb_set(const void __iomem *base_address, u32 ttb_phys_addr)
+hw_status hw_mmu_ttb_set(void __iomem *base_address, u32 ttb_phys_addr)
 {
 	hw_status status = 0;
 	u32 load_ttb;
@@ -267,7 +242,7 @@
 	return status;
 }
 
-hw_status hw_mmu_twl_enable(const void __iomem *base_address)
+hw_status hw_mmu_twl_enable(void __iomem *base_address)
 {
 	hw_status status = 0;
 
@@ -276,7 +251,7 @@
 	return status;
 }
 
-hw_status hw_mmu_twl_disable(const void __iomem *base_address)
+hw_status hw_mmu_twl_disable(void __iomem *base_address)
 {
 	hw_status status = 0;
 
@@ -285,45 +260,7 @@
 	return status;
 }
 
-hw_status hw_mmu_tlb_flush(const void __iomem *base_address, u32 virtual_addr,
-			   u32 page_sz)
-{
-	hw_status status = 0;
-	u32 virtual_addr_tag;
-	enum hw_mmu_page_size_t pg_size_bits;
-
-	switch (page_sz) {
-	case HW_PAGE_SIZE4KB:
-		pg_size_bits = HW_MMU_SMALL_PAGE;
-		break;
-
-	case HW_PAGE_SIZE64KB:
-		pg_size_bits = HW_MMU_LARGE_PAGE;
-		break;
-
-	case HW_PAGE_SIZE1MB:
-		pg_size_bits = HW_MMU_SECTION;
-		break;
-
-	case HW_PAGE_SIZE16MB:
-		pg_size_bits = HW_MMU_SUPERSECTION;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/* Generate the 20-bit tag from virtual address */
-	virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12);
-
-	mmu_set_cam_entry(base_address, pg_size_bits, 0, 0, virtual_addr_tag);
-
-	mmu_flush_entry(base_address);
-
-	return status;
-}
-
-hw_status hw_mmu_tlb_add(const void __iomem *base_address,
+hw_status hw_mmu_tlb_add(void __iomem *base_address,
 			 u32 physical_addr,
 			 u32 virtual_addr,
 			 u32 page_sz,
@@ -503,20 +440,8 @@
 	return status;
 }
 
-/* mmu_flush_entry */
-static hw_status mmu_flush_entry(const void __iomem *base_address)
-{
-	hw_status status = 0;
-	u32 flush_entry_data = 0x1;
-
-	/* write values to register */
-	MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, flush_entry_data);
-
-	return status;
-}
-
 /* mmu_set_cam_entry */
-static hw_status mmu_set_cam_entry(const void __iomem *base_address,
+static hw_status mmu_set_cam_entry(void __iomem *base_address,
 				   const u32 page_sz,
 				   const u32 preserved_bit,
 				   const u32 valid_bit,
@@ -536,7 +461,7 @@
 }
 
 /* mmu_set_ram_entry */
-static hw_status mmu_set_ram_entry(const void __iomem *base_address,
+static hw_status mmu_set_ram_entry(void __iomem *base_address,
 				   const u32 physical_addr,
 				   enum hw_endianism_t endianism,
 				   enum hw_element_size_t element_size,
@@ -556,7 +481,7 @@
 
 }
 
-void hw_mmu_tlb_flush_all(const void __iomem *base)
+void hw_mmu_tlb_flush_all(void __iomem *base)
 {
 	__raw_writel(1, base + MMU_GFLUSH);
 }
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.h b/drivers/staging/tidspbridge/hw/hw_mmu.h
index 1458a2c..1c50bb3 100644
--- a/drivers/staging/tidspbridge/hw/hw_mmu.h
+++ b/drivers/staging/tidspbridge/hw/hw_mmu.h
@@ -42,44 +42,41 @@
 	bool donotlockmpupage;
 };
 
-extern hw_status hw_mmu_enable(const void __iomem *base_address);
+extern hw_status hw_mmu_enable(void __iomem *base_address);
 
-extern hw_status hw_mmu_disable(const void __iomem *base_address);
+extern hw_status hw_mmu_disable(void __iomem *base_address);
 
-extern hw_status hw_mmu_num_locked_set(const void __iomem *base_address,
+extern hw_status hw_mmu_num_locked_set(void __iomem *base_address,
 				       u32 num_locked_entries);
 
-extern hw_status hw_mmu_victim_num_set(const void __iomem *base_address,
+extern hw_status hw_mmu_victim_num_set(void __iomem *base_address,
 				       u32 victim_entry_num);
 
 /* For MMU faults */
-extern hw_status hw_mmu_event_ack(const void __iomem *base_address,
+extern hw_status hw_mmu_event_ack(void __iomem *base_address,
 				  u32 irq_mask);
 
-extern hw_status hw_mmu_event_disable(const void __iomem *base_address,
+extern hw_status hw_mmu_event_disable(void __iomem *base_address,
 				      u32 irq_mask);
 
-extern hw_status hw_mmu_event_enable(const void __iomem *base_address,
+extern hw_status hw_mmu_event_enable(void __iomem *base_address,
 				     u32 irq_mask);
 
-extern hw_status hw_mmu_event_status(const void __iomem *base_address,
+extern hw_status hw_mmu_event_status(void __iomem *base_address,
 				     u32 *irq_mask);
 
-extern hw_status hw_mmu_fault_addr_read(const void __iomem *base_address,
+extern hw_status hw_mmu_fault_addr_read(void __iomem *base_address,
 					u32 *addr);
 
 /* Set the TT base address */
-extern hw_status hw_mmu_ttb_set(const void __iomem *base_address,
+extern hw_status hw_mmu_ttb_set(void __iomem *base_address,
 				u32 ttb_phys_addr);
 
-extern hw_status hw_mmu_twl_enable(const void __iomem *base_address);
+extern hw_status hw_mmu_twl_enable(void __iomem *base_address);
 
-extern hw_status hw_mmu_twl_disable(const void __iomem *base_address);
+extern hw_status hw_mmu_twl_disable(void __iomem *base_address);
 
-extern hw_status hw_mmu_tlb_flush(const void __iomem *base_address,
-				  u32 virtual_addr, u32 page_sz);
-
-extern hw_status hw_mmu_tlb_add(const void __iomem *base_address,
+extern hw_status hw_mmu_tlb_add(void __iomem *base_address,
 				u32 physical_addr,
 				u32 virtual_addr,
 				u32 page_sz,
@@ -97,7 +94,7 @@
 extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va,
 				  u32 virtual_addr, u32 page_size);
 
-void hw_mmu_tlb_flush_all(const void __iomem *base);
+void hw_mmu_tlb_flush_all(void __iomem *base);
 
 static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va)
 {
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h
index 60a2781..b32c756 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h
@@ -53,8 +53,8 @@
 	u32 chnl_buf_size;
 	u32 num_chnls;
 	void __iomem *per_base;
-	u32 per_pm_base;
-	u32 core_pm_base;
+	void __iomem *per_pm_base;
+	void __iomem *core_pm_base;
 	void __iomem *dmmu_base;
 };
 
diff --git a/drivers/staging/tidspbridge/include/dspbridge/host_os.h b/drivers/staging/tidspbridge/include/dspbridge/host_os.h
index ed00d3d..5e2f4d8 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/host_os.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/host_os.h
@@ -47,8 +47,8 @@
 #include <asm/cacheflush.h>
 #include <linux/dma-mapping.h>
 
-/* TODO -- Remove, once BP defines them */
-#define INT_DSP_MMU_IRQ        28
+/* TODO -- Remove, once omap-iommu is used */
+#define INT_DSP_MMU_IRQ        (28 + NR_IRQS)
 
 #define PRCM_VDD1 1
 
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
index 6795205..db1da28 100644
--- a/drivers/staging/tidspbridge/rmgr/drv.c
+++ b/drivers/staging/tidspbridge/rmgr/drv.c
@@ -667,10 +667,10 @@
 							 OMAP_DSP_MEM3_SIZE);
 		host_res->per_base = ioremap(OMAP_PER_CM_BASE,
 						OMAP_PER_CM_SIZE);
-		host_res->per_pm_base = (u32) ioremap(OMAP_PER_PRM_BASE,
-							 OMAP_PER_PRM_SIZE);
-		host_res->core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE,
-							  OMAP_CORE_PRM_SIZE);
+		host_res->per_pm_base = ioremap(OMAP_PER_PRM_BASE,
+						OMAP_PER_PRM_SIZE);
+		host_res->core_pm_base = ioremap(OMAP_CORE_PRM_BASE,
+							OMAP_CORE_PRM_SIZE);
 		host_res->dmmu_base = ioremap(OMAP_DMMU_BASE,
 						 OMAP_DMMU_SIZE);
 
diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c
index c2fc613..294e9b4 100644
--- a/drivers/staging/tidspbridge/rmgr/node.c
+++ b/drivers/staging/tidspbridge/rmgr/node.c
@@ -304,8 +304,7 @@
 	u32 pul_value;
 	u32 dynext_base;
 	u32 off_set = 0;
-	u32 ul_stack_seg_addr, ul_stack_seg_val;
-	u32 ul_gpp_mem_base;
+	u32 ul_stack_seg_val;
 	struct cfg_hostres *host_res;
 	struct bridge_dev_context *pbridge_context;
 	u32 mapped_addr = 0;
@@ -581,6 +580,9 @@
 		if (strcmp((char *)
 			   pnode->dcd_props.obj_data.node_obj.ndb_props.
 			   stack_seg_name, STACKSEGLABEL) == 0) {
+			void __iomem *stack_seg;
+			u32 stack_seg_pa;
+
 			status =
 			    hnode_mgr->nldr_fxns.
 			    get_fxn_addr(pnode->nldr_node_obj, "DYNEXT_BEG",
@@ -608,14 +610,21 @@
 				goto func_end;
 			}
 
-			ul_gpp_mem_base = (u32) host_res->mem_base[1];
 			off_set = pul_value - dynext_base;
-			ul_stack_seg_addr = ul_gpp_mem_base + off_set;
-			ul_stack_seg_val = readl(ul_stack_seg_addr);
+			stack_seg_pa = host_res->mem_phys[1] + off_set;
+			stack_seg = ioremap(stack_seg_pa, SZ_32);
+			if (!stack_seg) {
+				status = -ENOMEM;
+				goto func_end;
+			}
+
+			ul_stack_seg_val = readl(stack_seg);
+
+			iounmap(stack_seg);
 
 			dev_dbg(bridge, "%s: StackSegVal = 0x%x, StackSegAddr ="
 				" 0x%x\n", __func__, ul_stack_seg_val,
-				ul_stack_seg_addr);
+				host_res->mem_base[1] + off_set);
 
 			pnode->create_args.asa.task_arg_obj.stack_seg =
 			    ul_stack_seg_val;
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 653b0740..6edefde 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -223,8 +223,13 @@
 	cmem = zs_map_object(zram->mem_pool, zram->table[index].handle,
 				ZS_MM_RO);
 
-	ret = lzo1x_decompress_safe(cmem, zram->table[index].size,
+	if (zram->table[index].size == PAGE_SIZE) {
+		memcpy(uncmem, cmem, PAGE_SIZE);
+		ret = LZO_E_OK;
+	} else {
+		ret = lzo1x_decompress_safe(cmem, zram->table[index].size,
 				    uncmem, &clen);
+	}
 
 	if (is_partial_io(bvec)) {
 		memcpy(user_mem + bvec->bv_offset, uncmem + offset,
@@ -342,8 +347,11 @@
 		goto out;
 	}
 
-	if (unlikely(clen > max_zpage_size))
+	if (unlikely(clen > max_zpage_size)) {
 		zram_stat_inc(&zram->stats.bad_compress);
+		src = uncmem;
+		clen = PAGE_SIZE;
+	}
 
 	handle = zs_malloc(zram->mem_pool, clen);
 	if (!handle) {
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index d6ce218..035c2c7 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -3719,7 +3719,9 @@
 		 */
 		iscsit_thread_check_cpumask(conn, current, 1);
 
-		schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
+		wait_event_interruptible(conn->queues_wq,
+					 !iscsit_conn_all_queues_empty(conn) ||
+					 ts->status == ISCSI_THREAD_SET_RESET);
 
 		if ((ts->status == ISCSI_THREAD_SET_RESET) ||
 		     signal_pending(current))
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h
index 2ba9f9b..21048db 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -486,6 +486,7 @@
 };
 
 struct iscsi_conn {
+	wait_queue_head_t	queues_wq;
 	/* Authentication Successful for this connection */
 	u8			auth_complete;
 	/* State connection is currently in */
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index cdc8a10..f8dbec0 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -41,6 +41,7 @@
 
 static int iscsi_login_init_conn(struct iscsi_conn *conn)
 {
+	init_waitqueue_head(&conn->queues_wq);
 	INIT_LIST_HEAD(&conn->conn_list);
 	INIT_LIST_HEAD(&conn->conn_cmd_list);
 	INIT_LIST_HEAD(&conn->immed_queue_list);
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index afd98cc..1a91195 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -488,7 +488,7 @@
 	atomic_set(&conn->check_immediate_queue, 1);
 	spin_unlock_bh(&conn->immed_queue_lock);
 
-	wake_up_process(conn->thread_set->tx_thread);
+	wake_up(&conn->queues_wq);
 }
 
 struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn)
@@ -562,7 +562,7 @@
 	atomic_inc(&cmd->response_queue_count);
 	spin_unlock_bh(&conn->response_queue_lock);
 
-	wake_up_process(conn->thread_set->tx_thread);
+	wake_up(&conn->queues_wq);
 }
 
 struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn)
@@ -616,6 +616,24 @@
 	}
 }
 
+bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn)
+{
+	bool empty;
+
+	spin_lock_bh(&conn->immed_queue_lock);
+	empty = list_empty(&conn->immed_queue_list);
+	spin_unlock_bh(&conn->immed_queue_lock);
+
+	if (!empty)
+		return empty;
+
+	spin_lock_bh(&conn->response_queue_lock);
+	empty = list_empty(&conn->response_queue_list);
+	spin_unlock_bh(&conn->response_queue_lock);
+
+	return empty;
+}
+
 void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn)
 {
 	struct iscsi_queue_req *qr, *qr_tmp;
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h
index 44054bd3..894d0f8 100644
--- a/drivers/target/iscsi/iscsi_target_util.h
+++ b/drivers/target/iscsi/iscsi_target_util.h
@@ -25,6 +25,7 @@
 extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
 extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *);
 extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *);
+extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *);
 extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *);
 extern void iscsit_release_cmd(struct iscsi_cmd *);
 extern void iscsit_free_cmd(struct iscsi_cmd *);
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 015f5be..c123327 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -3206,7 +3206,8 @@
 	if (ret < 0)
 		goto out;
 
-	if (core_dev_setup_virtual_lun0() < 0)
+	ret = core_dev_setup_virtual_lun0();
+	if (ret < 0)
 		goto out;
 
 	return 0;
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 8d774da..9abef9f 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -850,20 +850,20 @@
 
 static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)
 {
-	u32 tmp, aligned_max_sectors;
+	u32 aligned_max_sectors;
+	u32 alignment;
 	/*
 	 * Limit max_sectors to a PAGE_SIZE aligned value for modern
 	 * transport_allocate_data_tasks() operation.
 	 */
-	tmp = rounddown((max_sectors * block_size), PAGE_SIZE);
-	aligned_max_sectors = (tmp / block_size);
-	if (max_sectors != aligned_max_sectors) {
-		printk(KERN_INFO "Rounding down aligned max_sectors from %u"
-				" to %u\n", max_sectors, aligned_max_sectors);
-		return aligned_max_sectors;
-	}
+	alignment = max(1ul, PAGE_SIZE / block_size);
+	aligned_max_sectors = rounddown(max_sectors, alignment);
 
-	return max_sectors;
+	if (max_sectors != aligned_max_sectors)
+		pr_info("Rounding down aligned max_sectors from %u to %u\n",
+			max_sectors, aligned_max_sectors);
+
+	return aligned_max_sectors;
 }
 
 void se_dev_set_default_attribs(
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 868f8aa..a6e27d9 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -135,6 +135,12 @@
 	return 0;
 }
 
+static int sbc_emulate_noop(struct se_cmd *cmd)
+{
+	target_complete_cmd(cmd, GOOD);
+	return 0;
+}
+
 static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors)
 {
 	return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors;
@@ -531,6 +537,18 @@
 		size = 0;
 		cmd->execute_cmd = sbc_emulate_verify;
 		break;
+	case REZERO_UNIT:
+	case SEEK_6:
+	case SEEK_10:
+		/*
+		 * There are still clients out there which use these old SCSI-2
+		 * commands. This mainly happens when running VMs with legacy
+		 * guest systems, connected via SCSI command pass-through to
+		 * iSCSI targets. Make them happy and return status GOOD.
+		 */
+		size = 0;
+		cmd->execute_cmd = sbc_emulate_noop;
+		break;
 	default:
 		ret = spc_parse_cdb(cmd, &size);
 		if (ret)
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 9229bd9..6fd434d 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -605,6 +605,8 @@
 	unsigned char buf[SE_INQUIRY_BUF];
 	int p, ret;
 
+	memset(buf, 0, SE_INQUIRY_BUF);
+
 	if (dev == tpg->tpg_virt_lun0.lun_se_dev)
 		buf[0] = 0x3f; /* Not connected */
 	else
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index 1c59a3c..be75c43 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -140,15 +140,15 @@
 		printk("ABORT_TASK: Found referenced %s task_tag: %u\n",
 			se_cmd->se_tfo->get_fabric_name(), ref_tag);
 
-		spin_lock_irq(&se_cmd->t_state_lock);
+		spin_lock(&se_cmd->t_state_lock);
 		if (se_cmd->transport_state & CMD_T_COMPLETE) {
 			printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag);
-			spin_unlock_irq(&se_cmd->t_state_lock);
+			spin_unlock(&se_cmd->t_state_lock);
 			spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
 			goto out;
 		}
 		se_cmd->transport_state |= CMD_T_ABORTED;
-		spin_unlock_irq(&se_cmd->t_state_lock);
+		spin_unlock(&se_cmd->t_state_lock);
 
 		list_del_init(&se_cmd->se_cmd_list);
 		kref_get(&se_cmd->cmd_kref);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index c33baff..9097155 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1616,7 +1616,6 @@
 
 	se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST;
 	se_cmd->se_tfo->queue_tm_rsp(se_cmd);
-	transport_generic_free_cmd(se_cmd, 0);
 }
 
 /**
diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
index fd03e85..6dd29e4 100644
--- a/drivers/thermal/exynos_thermal.c
+++ b/drivers/thermal/exynos_thermal.c
@@ -815,7 +815,7 @@
 	},
 	{ },
 };
-MODULE_DEVICE_TABLE(platform, exynos4_tmu_driver_ids);
+MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids);
 
 static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
 			struct platform_device *pdev)
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index d445271..f7a1b57 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -210,7 +210,7 @@
 		goto error_free_priv;
 	}
 
-	zone = thermal_zone_device_register("rcar_thermal", 0, priv,
+	zone = thermal_zone_device_register("rcar_thermal", 0, 0, priv,
 					    &rcar_thermal_zone_ops, 0, 0);
 	if (IS_ERR(zone)) {
 		dev_err(&pdev->dev, "thermal zone device is NULL\n");
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index a5dec1c..13ee53b 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -424,7 +424,6 @@
 {
 	struct hvc_struct *hp = tty->driver_data;
 	unsigned long flags;
-	int temp_open_count;
 
 	if (!hp)
 		return;
@@ -444,7 +443,6 @@
 		return;
 	}
 
-	temp_open_count = hp->port.count;
 	hp->port.count = 0;
 	spin_unlock_irqrestore(&hp->port.lock, flags);
 	tty_port_tty_set(&hp->port, NULL);
@@ -453,11 +451,6 @@
 
 	if (hp->ops->notifier_hangup)
 		hp->ops->notifier_hangup(hp, hp->data);
-
-	while(temp_open_count) {
-		--temp_open_count;
-		tty_port_put(&hp->port);
-	}
 }
 
 /*
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index 2bc28a5..1ab1d2c 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -1239,6 +1239,7 @@
 static const struct spi_device_id max310x_id_table[] = {
 	{ "max3107",	MAX310X_TYPE_MAX3107 },
 	{ "max3108",	MAX310X_TYPE_MAX3108 },
+	{ }
 };
 MODULE_DEVICE_TABLE(spi, max310x_id_table);
 
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 6ede6fd..6d3d26a 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -671,19 +671,19 @@
 
 	/*
 	 * IXON Flag:
-	 * Flow control for OMAP.TX
-	 * OMAP.RX should listen for XON/XOFF
+	 * Enable XON/XOFF flow control on output.
+	 * Transmit XON1, XOFF1
 	 */
 	if (termios->c_iflag & IXON)
-		up->efr |= OMAP_UART_SW_RX;
+		up->efr |= OMAP_UART_SW_TX;
 
 	/*
 	 * IXOFF Flag:
-	 * Flow control for OMAP.RX
-	 * OMAP.TX should send XON/XOFF
+	 * Enable XON/XOFF flow control on input.
+	 * Receiver compares XON1, XOFF1.
 	 */
 	if (termios->c_iflag & IXOFF)
-		up->efr |= OMAP_UART_SW_TX;
+		up->efr |= OMAP_UART_SW_RX;
 
 	serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index 7f04717..0e26a16 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -1646,7 +1646,8 @@
 #endif
 
 #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212) || \
-	defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250)
+	defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) || \
+	defined(CONFIG_SOC_EXYNOS5440)
 static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
 	.info = &(struct s3c24xx_uart_info) {
 		.name		= "Samsung Exynos4 UART",
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 6f3ea9b..c48b938 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -97,6 +97,7 @@
 config UIO_PRUSS
 	tristate "Texas Instruments PRUSS driver"
 	depends on ARCH_DAVINCI_DA850
+	select GENERIC_ALLOCATOR
 	help
 	  PRUSS driver for OMAPL138/DA850/AM18XX devices
 	  PRUSS driver requires user space components, examples and user space
diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
index 33a7a27..f8738de 100644
--- a/drivers/uio/uio_pruss.c
+++ b/drivers/uio/uio_pruss.c
@@ -25,7 +25,7 @@
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
-#include <mach/sram.h>
+#include <linux/genalloc.h>
 
 #define DRV_NAME "pruss_uio"
 #define DRV_VERSION "1.0"
@@ -65,10 +65,11 @@
 	dma_addr_t sram_paddr;
 	dma_addr_t ddr_paddr;
 	void __iomem *prussio_vaddr;
-	void *sram_vaddr;
+	unsigned long sram_vaddr;
 	void *ddr_vaddr;
 	unsigned int hostirq_start;
 	unsigned int pintc_base;
+	struct gen_pool *sram_pool;
 };
 
 static irqreturn_t pruss_handler(int irq, struct uio_info *info)
@@ -106,7 +107,9 @@
 			gdev->ddr_paddr);
 	}
 	if (gdev->sram_vaddr)
-		sram_free(gdev->sram_vaddr, sram_pool_sz);
+		gen_pool_free(gdev->sram_pool,
+			      gdev->sram_vaddr,
+			      sram_pool_sz);
 	kfree(gdev->info);
 	clk_put(gdev->pruss_clk);
 	kfree(gdev);
@@ -152,10 +155,17 @@
 		goto out_free;
 	}
 
-	gdev->sram_vaddr = sram_alloc(sram_pool_sz, &(gdev->sram_paddr));
-	if (!gdev->sram_vaddr) {
-		dev_err(&dev->dev, "Could not allocate SRAM pool\n");
-		goto out_free;
+	if (pdata->sram_pool) {
+		gdev->sram_pool = pdata->sram_pool;
+		gdev->sram_vaddr =
+			gen_pool_alloc(gdev->sram_pool, sram_pool_sz);
+		if (!gdev->sram_vaddr) {
+			dev_err(&dev->dev, "Could not allocate SRAM pool\n");
+			goto out_free;
+		}
+		gdev->sram_paddr =
+			gen_pool_virt_to_phys(gdev->sram_pool,
+					      gdev->sram_vaddr);
 	}
 
 	gdev->ddr_vaddr = dma_alloc_coherent(&dev->dev, extram_pool_sz,
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 1e741bc..f034716 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2151,8 +2151,15 @@
 irqreturn_t usb_hcd_irq (int irq, void *__hcd)
 {
 	struct usb_hcd		*hcd = __hcd;
+	unsigned long		flags;
 	irqreturn_t		rc;
 
+	/* IRQF_DISABLED doesn't work correctly with shared IRQs
+	 * when the first handler doesn't use it.  So let's just
+	 * assume it's never used.
+	 */
+	local_irq_save(flags);
+
 	if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd)))
 		rc = IRQ_NONE;
 	else if (hcd->driver->irq(hcd) == IRQ_NONE)
@@ -2160,6 +2167,7 @@
 	else
 		rc = IRQ_HANDLED;
 
+	local_irq_restore(flags);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(usb_hcd_irq);
@@ -2347,6 +2355,14 @@
 	int retval;
 
 	if (hcd->driver->irq) {
+
+		/* IRQF_DISABLED doesn't work as advertised when used together
+		 * with IRQF_SHARED. As usb_hcd_irq() will always disable
+		 * interrupts we can remove it here.
+		 */
+		if (irqflags & IRQF_SHARED)
+			irqflags &= ~IRQF_DISABLED;
+
 		snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
 				hcd->driver->description, hcd->self.busnum);
 		retval = request_irq(irqnum, &usb_hcd_irq, irqflags,
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 64854d7..1af04bd 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -739,13 +739,16 @@
 	int			limit = 100;
 
 	spin_lock_irqsave (&hub->tt.lock, flags);
-	while (--limit && !list_empty (&hub->tt.clear_list)) {
+	while (!list_empty(&hub->tt.clear_list)) {
 		struct list_head	*next;
 		struct usb_tt_clear	*clear;
 		struct usb_device	*hdev = hub->hdev;
 		const struct hc_driver	*drv;
 		int			status;
 
+		if (!hub->quiescing && --limit < 0)
+			break;
+
 		next = hub->tt.clear_list.next;
 		clear = list_entry (next, struct usb_tt_clear, clear_list);
 		list_del (&clear->clear_list);
@@ -1210,7 +1213,7 @@
 	if (hub->has_indicators)
 		cancel_delayed_work_sync(&hub->leds);
 	if (hub->tt.hub)
-		cancel_work_sync(&hub->tt.clear_work);
+		flush_work(&hub->tt.clear_work);
 }
 
 /* caller has locked the hub device */
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c
index e426ad6..4bfa78a 100644
--- a/drivers/usb/early/ehci-dbgp.c
+++ b/drivers/usb/early/ehci-dbgp.c
@@ -20,6 +20,7 @@
 #include <linux/usb/ehci_def.h>
 #include <linux/delay.h>
 #include <linux/serial_core.h>
+#include <linux/kconfig.h>
 #include <linux/kgdb.h>
 #include <linux/kthread.h>
 #include <asm/io.h>
@@ -614,12 +615,6 @@
 	return -ENODEV;
 }
 
-int dbgp_external_startup(struct usb_hcd *hcd)
-{
-	return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
-}
-EXPORT_SYMBOL_GPL(dbgp_external_startup);
-
 static int ehci_reset_port(int port)
 {
 	u32 portsc;
@@ -979,6 +974,7 @@
 	.index =	-1,
 };
 
+#if IS_ENABLED(CONFIG_USB_EHCI_HCD)
 int dbgp_reset_prep(struct usb_hcd *hcd)
 {
 	int ret = xen_dbgp_reset_prep(hcd);
@@ -1007,6 +1003,13 @@
 }
 EXPORT_SYMBOL_GPL(dbgp_reset_prep);
 
+int dbgp_external_startup(struct usb_hcd *hcd)
+{
+	return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
+}
+EXPORT_SYMBOL_GPL(dbgp_external_startup);
+#endif /* USB_EHCI_HCD */
+
 #ifdef CONFIG_KGDB
 
 static char kgdbdbgp_buf[DBGP_MAX_PACKET];
diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c
index 43ac748..c009263 100644
--- a/drivers/usb/gadget/net2272.c
+++ b/drivers/usb/gadget/net2272.c
@@ -2069,8 +2069,10 @@
 #if defined(PLX_PCI_RDK2)
 	/* see if PCI int for us by checking irqstat */
 	intcsr = readl(dev->rdk2.fpga_base_addr + RDK2_IRQSTAT);
-	if (!intcsr & (1 << NET2272_PCI_IRQ))
+	if (!intcsr & (1 << NET2272_PCI_IRQ)) {
+		spin_unlock(&dev->lock);
 		return IRQ_NONE;
+	}
 	/* check dma interrupts */
 #endif
 	/* Platform/devcice interrupt handler */
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 6458764..4ec3c0d 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -20,6 +20,7 @@
 #include <linux/ctype.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
+#include <linux/if_vlan.h>
 
 #include "u_ether.h"
 
@@ -295,7 +296,7 @@
 		while (skb2) {
 			if (status < 0
 					|| ETH_HLEN > skb2->len
-					|| skb2->len > ETH_FRAME_LEN) {
+					|| skb2->len > VLAN_ETH_FRAME_LEN) {
 				dev->net->stats.rx_errors++;
 				dev->net->stats.rx_length_errors++;
 				DBG(dev, "rx length %d\n", skb2->len);
diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c
index ca75965..aa0f328 100644
--- a/drivers/usb/host/ehci-ls1x.c
+++ b/drivers/usb/host/ehci-ls1x.c
@@ -113,7 +113,7 @@
 		goto err_put_hcd;
 	}
 
-	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
 	if (ret)
 		goto err_put_hcd;
 
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index 4a08fc0..8e58a5f 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -24,7 +24,6 @@
 #include <linux/usb/ulpi.h>
 #include <linux/slab.h>
 
-#include <mach/hardware.h>
 #include <linux/platform_data/usb-ehci-mxc.h>
 
 #include <asm/mach-types.h>
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 6223d175..2de0890 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -28,7 +28,10 @@
 #include <linux/pm_runtime.h>
 
 #include <linux/usb/tegra_usb_phy.h>
-#include <mach/iomap.h>
+
+#define TEGRA_USB_BASE			0xC5000000
+#define TEGRA_USB2_BASE			0xC5004000
+#define TEGRA_USB3_BASE			0xC5008000
 
 #define TEGRA_USB_DMA_ALIGN 32
 
diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c
index 84201cd..41e378f 100644
--- a/drivers/usb/host/ohci-xls.c
+++ b/drivers/usb/host/ohci-xls.c
@@ -56,7 +56,7 @@
 		goto err3;
 	}
 
-	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
 	if (retval != 0)
 		goto err4;
 	return retval;
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 966d148..39f9e4a 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -545,7 +545,14 @@
 		/*  Pegatron Lucid (Ordissimo AIRIS) */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "M11JB"),
-			DMI_MATCH(DMI_BIOS_VERSION, "Lucid-GE-133"),
+			DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"),
+		},
+	},
+	{
+		/*  Pegatron Lucid (Ordissimo) */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "Ordissimo"),
+			DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"),
 		},
 	},
 	{ }
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index 4b436f5..5f3a7c7 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -544,7 +544,6 @@
 	int i;
 	/* Fields are 32 bits wide, DMA addresses are in bytes */
 	int field_size = 32 / 8;
-	struct xhci_slot_ctx *slot_ctx;
 	dma_addr_t dma = ctx->dma;
 	int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
 
@@ -570,7 +569,6 @@
 			dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma);
 	}
 
-	slot_ctx = xhci_get_slot_ctx(xhci, ctx);
 	xhci_dbg_slot_ctx(xhci, ctx);
 	xhci_dbg_ep_ctx(xhci, ctx, last_ep);
 }
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index aa90ad4..a686cf4 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -151,9 +151,8 @@
 		if (portsc & PORT_DEV_REMOVE)
 			port_removable |= 1 << (i + 1);
 	}
-	memset(&desc->u.ss.DeviceRemovable,
-			(__force __u16) cpu_to_le16(port_removable),
-			sizeof(__u16));
+
+	desc->u.ss.DeviceRemovable = cpu_to_le16(port_removable);
 }
 
 static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
@@ -809,11 +808,13 @@
 			temp = xhci_readl(xhci, port_array[wIndex]);
 			xhci_dbg(xhci, "set port power, actual port %d status  = 0x%x\n", wIndex, temp);
 
+			spin_unlock_irqrestore(&xhci->lock, flags);
 			temp = usb_acpi_power_manageable(hcd->self.root_hub,
 					wIndex);
 			if (temp)
 				usb_acpi_set_power_state(hcd->self.root_hub,
 						wIndex, true);
+			spin_lock_irqsave(&xhci->lock, flags);
 			break;
 		case USB_PORT_FEAT_RESET:
 			temp = (temp | PORT_RESET);
@@ -917,11 +918,13 @@
 			xhci_writel(xhci, temp & ~PORT_POWER,
 				port_array[wIndex]);
 
+			spin_unlock_irqrestore(&xhci->lock, flags);
 			temp = usb_acpi_power_manageable(hcd->self.root_hub,
 					wIndex);
 			if (temp)
 				usb_acpi_set_power_state(hcd->self.root_hub,
 						wIndex, false);
+			spin_lock_irqsave(&xhci->lock, flags);
 			break;
 		default:
 			goto error;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index c6ebb17..4e1a894 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1228,6 +1228,17 @@
 	cur_seg = find_trb_seg(xhci->cmd_ring->first_seg,
 			xhci->cmd_ring->dequeue, &cycle_state);
 
+	if (!cur_seg) {
+		xhci_warn(xhci, "Command ring mismatch, dequeue = %p %llx (dma)\n",
+				xhci->cmd_ring->dequeue,
+				(unsigned long long)
+				xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
+					xhci->cmd_ring->dequeue));
+		xhci_debug_ring(xhci, xhci->cmd_ring);
+		xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
+		return;
+	}
+
 	/* find the command trb matched by cd from command ring */
 	for (cmd_trb = xhci->cmd_ring->dequeue;
 			cmd_trb != xhci->cmd_ring->enqueue;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 7d462bf..c9e419f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1627,7 +1627,6 @@
 	struct xhci_hcd *xhci;
 	struct xhci_container_ctx *in_ctx, *out_ctx;
 	unsigned int ep_index;
-	struct xhci_ep_ctx *ep_ctx;
 	struct xhci_slot_ctx *slot_ctx;
 	struct xhci_input_control_ctx *ctrl_ctx;
 	u32 added_ctxs;
@@ -1663,7 +1662,6 @@
 	out_ctx = virt_dev->out_ctx;
 	ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
 	ep_index = xhci_get_endpoint_index(&ep->desc);
-	ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
 
 	/* If this endpoint is already in use, and the upper layers are trying
 	 * to add it again without dropping it, reject the addition.
@@ -1817,6 +1815,8 @@
 	case COMP_EBADSLT:
 		dev_warn(&udev->dev, "WARN: slot not enabled for"
 				"evaluate context command.\n");
+		ret = -EINVAL;
+		break;
 	case COMP_CTX_STATE:
 		dev_warn(&udev->dev, "WARN: invalid context state for "
 				"evaluate context command.\n");
@@ -4021,7 +4021,7 @@
 static unsigned long long xhci_service_interval_to_ns(
 		struct usb_endpoint_descriptor *desc)
 {
-	return (1 << (desc->bInterval - 1)) * 125 * 1000;
+	return (1ULL << (desc->bInterval - 1)) * 125 * 1000;
 }
 
 static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev,
@@ -4142,7 +4142,7 @@
 			(xhci_service_interval_to_ns(desc) > timeout_ns))
 		timeout_ns = xhci_service_interval_to_ns(desc);
 
-	u2_del_ns = udev->bos->ss_cap->bU2DevExitLat * 1000;
+	u2_del_ns = le16_to_cpu(udev->bos->ss_cap->bU2DevExitLat) * 1000ULL;
 	if (u2_del_ns > timeout_ns)
 		timeout_ns = u2_del_ns;
 
diff --git a/drivers/usb/misc/ezusb.c b/drivers/usb/misc/ezusb.c
index 4223d76..6589268 100644
--- a/drivers/usb/misc/ezusb.c
+++ b/drivers/usb/misc/ezusb.c
@@ -158,3 +158,4 @@
 }
 EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download);
 
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 444346e1..ff5f112 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -458,11 +458,11 @@
 	struct platform_device	*musb;
 	struct resource *res;
 	struct resource	resources[2];
-	char res_name[10];
+	char res_name[11];
 	int ret, musbid;
 
 	/* get memory resource */
-	sprintf(res_name, "musb%d", id);
+	snprintf(res_name, sizeof(res_name), "musb%d", id);
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
 	if (!res) {
 		dev_err(dev, "%s get mem resource failed\n", res_name);
@@ -473,7 +473,7 @@
 	resources[0] = *res;
 
 	/* get irq resource */
-	sprintf(res_name, "musb%d-irq", id);
+	snprintf(res_name, sizeof(res_name), "musb%d-irq", id);
 	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
 	if (!res) {
 		dev_err(dev, "%s get irq resource failed\n", res_name);
@@ -530,7 +530,7 @@
 
 		of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
 		of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
-		sprintf(res_name, "port%d-mode", id);
+		snprintf(res_name, sizeof(res_name), "port%d-mode", id);
 		of_property_read_u32(np, res_name, (u32 *)&pdata->mode);
 		of_property_read_u32(np, "power", (u32 *)&pdata->power);
 		config->multipoint = of_property_read_bool(np, "multipoint");
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index d0b87e7..b6b84da 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -707,11 +707,12 @@
 		fifo_count = musb_readw(epio, MUSB_RXCOUNT);
 
 		/*
-		 *  use mode 1 only if we expect data of at least ep packet_sz
-		 *  and have not yet received a short packet
+		 * Enable Mode 1 on RX transfers only when short_not_ok flag
+		 * is set. Currently short_not_ok flag is set only from
+		 * file_storage and f_mass_storage drivers
 		 */
-		if ((request->length - request->actual >= musb_ep->packet_sz) &&
-			(fifo_count >= musb_ep->packet_sz))
+
+		if (request->short_not_ok && fifo_count == musb_ep->packet_sz)
 			use_mode_1 = 1;
 		else
 			use_mode_1 = 0;
@@ -727,6 +728,27 @@
 				c = musb->dma_controller;
 				channel = musb_ep->dma;
 
+	/* We use DMA Req mode 0 in rx_csr, and DMA controller operates in
+	 * mode 0 only. So we do not get endpoint interrupts due to DMA
+	 * completion. We only get interrupts from DMA controller.
+	 *
+	 * We could operate in DMA mode 1 if we knew the size of the tranfer
+	 * in advance. For mass storage class, request->length = what the host
+	 * sends, so that'd work.  But for pretty much everything else,
+	 * request->length is routinely more than what the host sends. For
+	 * most these gadgets, end of is signified either by a short packet,
+	 * or filling the last byte of the buffer.  (Sending extra data in
+	 * that last pckate should trigger an overflow fault.)  But in mode 1,
+	 * we don't get DMA completion interrupt for short packets.
+	 *
+	 * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1),
+	 * to get endpoint interrupt on every DMA req, but that didn't seem
+	 * to work reliably.
+	 *
+	 * REVISIT an updated g_file_storage can set req->short_not_ok, which
+	 * then becomes usable as a runtime "use mode 1" hint...
+	 */
+
 				/* Experimental: Mode1 works with mass storage use cases */
 				if (use_mode_1) {
 					csr |= MUSB_RXCSR_AUTOCLEAR;
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c
index d62a91f..0e62f50 100644
--- a/drivers/usb/musb/ux500.c
+++ b/drivers/usb/musb/ux500.c
@@ -65,7 +65,7 @@
 	struct platform_device		*musb;
 	struct ux500_glue		*glue;
 	struct clk			*clk;
-
+	int				musbid;
 	int				ret = -ENOMEM;
 
 	glue = kzalloc(sizeof(*glue), GFP_KERNEL);
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index d8c8a42..6223062 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -58,7 +58,7 @@
 
 config TWL4030_USB
 	tristate "TWL4030 USB Transceiver Driver"
-	depends on TWL4030_CORE && REGULATOR_TWL4030
+	depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
 	select USB_OTG_UTILS
 	help
 	  Enable this to support the USB OTG transceiver on TWL4030
@@ -68,7 +68,7 @@
 
 config TWL6030_USB
 	tristate "TWL6030 USB Transceiver Driver"
-	depends on TWL4030_CORE && OMAP_USB2
+	depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS
 	select USB_OTG_UTILS
 	help
 	  Enable this to support the USB OTG transceiver on TWL6030
diff --git a/drivers/usb/phy/tegra_usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c
index 987116f9..9d13c81 100644
--- a/drivers/usb/phy/tegra_usb_phy.c
+++ b/drivers/usb/phy/tegra_usb_phy.c
@@ -29,7 +29,9 @@
 #include <linux/usb/ulpi.h>
 #include <asm/mach-types.h>
 #include <linux/usb/tegra_usb_phy.h>
-#include <mach/iomap.h>
+
+#define TEGRA_USB_BASE		0xC5000000
+#define TEGRA_USB_SIZE		SZ_16K
 
 #define ULPI_VIEWPORT		0x170
 
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 143c4e9..c021b20 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -795,6 +795,7 @@
 	dev_dbg(dev, "  %s %d (%d/ %d)\n",
 		fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
 
+	usbhs_pipe_enable(pipe);
 	usbhsf_dma_start(pipe, fifo);
 	dma_async_issue_pending(chan);
 }
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index 9b69a13..069cd76 100644
--- a/drivers/usb/renesas_usbhs/mod_host.c
+++ b/drivers/usb/renesas_usbhs/mod_host.c
@@ -334,6 +334,11 @@
 	struct device *dev = usbhs_priv_to_dev(priv);
 	unsigned long flags;
 
+	if (unlikely(!uep)) {
+		dev_err(dev, "no uep\n");
+		return;
+	}
+
 	/********************  spin lock ********************/
 	usbhs_lock(priv, flags);
 
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index e9c7046..d255f66 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -242,13 +242,11 @@
 	return r;
 }
 
-/* allocate private data */
-static int ch341_attach(struct usb_serial *serial)
+static int ch341_port_probe(struct usb_serial_port *port)
 {
 	struct ch341_private *priv;
 	int r;
 
-	/* private data */
 	priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
@@ -258,17 +256,27 @@
 	priv->baud_rate = DEFAULT_BAUD_RATE;
 	priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
 
-	r = ch341_configure(serial->dev, priv);
+	r = ch341_configure(port->serial->dev, priv);
 	if (r < 0)
 		goto error;
 
-	usb_set_serial_port_data(serial->port[0], priv);
+	usb_set_serial_port_data(port, priv);
 	return 0;
 
 error:	kfree(priv);
 	return r;
 }
 
+static int ch341_port_remove(struct usb_serial_port *port)
+{
+	struct ch341_private *priv;
+
+	priv = usb_get_serial_port_data(port);
+	kfree(priv);
+
+	return 0;
+}
+
 static int ch341_carrier_raised(struct usb_serial_port *port)
 {
 	struct ch341_private *priv = usb_get_serial_port_data(port);
@@ -304,7 +312,7 @@
 static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
-	struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]);
+	struct ch341_private *priv = usb_get_serial_port_data(port);
 	int r;
 
 	priv->baud_rate = DEFAULT_BAUD_RATE;
@@ -608,7 +616,8 @@
 	.tiocmget          = ch341_tiocmget,
 	.tiocmset          = ch341_tiocmset,
 	.read_int_callback = ch341_read_int_callback,
-	.attach            = ch341_attach,
+	.port_probe        = ch341_port_probe,
+	.port_remove       = ch341_port_remove,
 	.reset_resume      = ch341_reset_resume,
 };
 
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index c86f68c..b50fa1c 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -244,6 +244,8 @@
 static int digi_startup(struct usb_serial *serial);
 static void digi_disconnect(struct usb_serial *serial);
 static void digi_release(struct usb_serial *serial);
+static int digi_port_probe(struct usb_serial_port *port);
+static int digi_port_remove(struct usb_serial_port *port);
 static void digi_read_bulk_callback(struct urb *urb);
 static int digi_read_inb_callback(struct urb *urb);
 static int digi_read_oob_callback(struct urb *urb);
@@ -294,6 +296,8 @@
 	.attach =			digi_startup,
 	.disconnect =			digi_disconnect,
 	.release =			digi_release,
+	.port_probe =			digi_port_probe,
+	.port_remove =			digi_port_remove,
 };
 
 static struct usb_serial_driver digi_acceleport_4_device = {
@@ -320,6 +324,8 @@
 	.attach =			digi_startup,
 	.disconnect =			digi_disconnect,
 	.release =			digi_release,
+	.port_probe =			digi_port_probe,
+	.port_remove =			digi_port_remove,
 };
 
 static struct usb_serial_driver * const serial_drivers[] = {
@@ -1240,59 +1246,50 @@
 	return ret;
 }
 
+static int digi_port_init(struct usb_serial_port *port, unsigned port_num)
+{
+	struct digi_port *priv;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	spin_lock_init(&priv->dp_port_lock);
+	priv->dp_port_num = port_num;
+	init_waitqueue_head(&priv->dp_modem_change_wait);
+	init_waitqueue_head(&priv->dp_transmit_idle_wait);
+	init_waitqueue_head(&priv->dp_flush_wait);
+	init_waitqueue_head(&priv->dp_close_wait);
+	INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock);
+	priv->dp_port = port;
+
+	init_waitqueue_head(&port->write_wait);
+
+	usb_set_serial_port_data(port, priv);
+
+	return 0;
+}
 
 static int digi_startup(struct usb_serial *serial)
 {
-
-	int i;
-	struct digi_port *priv;
 	struct digi_serial *serial_priv;
+	int ret;
 
-	/* allocate the private data structures for all ports */
-	/* number of regular ports + 1 for the out-of-band port */
-	for (i = 0; i < serial->type->num_ports + 1; i++) {
-		/* allocate port private structure */
-		priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL);
-		if (priv == NULL) {
-			while (--i >= 0)
-				kfree(usb_get_serial_port_data(serial->port[i]));
-			return 1;			/* error */
-		}
+	serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL);
+	if (!serial_priv)
+		return -ENOMEM;
 
-		/* initialize port private structure */
-		spin_lock_init(&priv->dp_port_lock);
-		priv->dp_port_num = i;
-		priv->dp_out_buf_len = 0;
-		priv->dp_write_urb_in_use = 0;
-		priv->dp_modem_signals = 0;
-		init_waitqueue_head(&priv->dp_modem_change_wait);
-		priv->dp_transmit_idle = 0;
-		init_waitqueue_head(&priv->dp_transmit_idle_wait);
-		priv->dp_throttled = 0;
-		priv->dp_throttle_restart = 0;
-		init_waitqueue_head(&priv->dp_flush_wait);
-		init_waitqueue_head(&priv->dp_close_wait);
-		INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock);
-		priv->dp_port = serial->port[i];
-		/* initialize write wait queue for this port */
-		init_waitqueue_head(&serial->port[i]->write_wait);
-
-		usb_set_serial_port_data(serial->port[i], priv);
-	}
-
-	/* allocate serial private structure */
-	serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL);
-	if (serial_priv == NULL) {
-		for (i = 0; i < serial->type->num_ports + 1; i++)
-			kfree(usb_get_serial_port_data(serial->port[i]));
-		return 1;			/* error */
-	}
-
-	/* initialize serial private structure */
 	spin_lock_init(&serial_priv->ds_serial_lock);
 	serial_priv->ds_oob_port_num = serial->type->num_ports;
 	serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num];
-	serial_priv->ds_device_started = 0;
+
+	ret = digi_port_init(serial_priv->ds_oob_port,
+						serial_priv->ds_oob_port_num);
+	if (ret) {
+		kfree(serial_priv);
+		return ret;
+	}
+
 	usb_set_serial_data(serial, serial_priv);
 
 	return 0;
@@ -1313,15 +1310,35 @@
 
 static void digi_release(struct usb_serial *serial)
 {
-	int i;
+	struct digi_serial *serial_priv;
+	struct digi_port *priv;
 
-	/* free the private data structures for all ports */
-	/* number of regular ports + 1 for the out-of-band port */
-	for (i = 0; i < serial->type->num_ports + 1; i++)
-		kfree(usb_get_serial_port_data(serial->port[i]));
-	kfree(usb_get_serial_data(serial));
+	serial_priv = usb_get_serial_data(serial);
+
+	priv = usb_get_serial_port_data(serial_priv->ds_oob_port);
+	kfree(priv);
+
+	kfree(serial_priv);
 }
 
+static int digi_port_probe(struct usb_serial_port *port)
+{
+	unsigned port_num;
+
+	port_num = port->number - port->serial->minor;
+
+	return digi_port_init(port, port_num);
+}
+
+static int digi_port_remove(struct usb_serial_port *port)
+{
+	struct digi_port *priv;
+
+	priv = usb_get_serial_port_data(port);
+	kfree(priv);
+
+	return 0;
+}
 
 static void digi_read_bulk_callback(struct urb *urb)
 {
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 20a132e..4264821 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -203,8 +203,7 @@
 	return 0;
 }
 
-/* fake probe - only to allocate data structures */
-static int ipw_probe(struct usb_serial *serial, const struct usb_device_id *id)
+static int ipw_attach(struct usb_serial *serial)
 {
 	struct usb_wwan_intf_private *data;
 
@@ -303,9 +302,9 @@
 	.num_ports =		1,
 	.open =			ipw_open,
 	.close =		ipw_close,
-	.probe =		ipw_probe,
-	.attach =		usb_wwan_startup,
+	.attach =		ipw_attach,
 	.release =		ipw_release,
+	.port_probe =		usb_wwan_port_probe,
 	.port_remove =		usb_wwan_port_remove,
 	.dtr_rts =		ipw_dtr_rts,
 	.write =		usb_wwan_write,
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 29c943d..cff8dd5 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -1374,13 +1374,9 @@
 	   data in device_details */
 static void keyspan_setup_urbs(struct usb_serial *serial)
 {
-	int				i, j;
 	struct keyspan_serial_private 	*s_priv;
 	const struct keyspan_device_details	*d_details;
-	struct usb_serial_port		*port;
-	struct keyspan_port_private	*p_priv;
 	struct callbacks		*cback;
-	int				endp;
 
 	s_priv = usb_get_serial_data(serial);
 	d_details = s_priv->device_details;
@@ -1404,45 +1400,6 @@
 		(serial, d_details->glocont_endpoint, USB_DIR_OUT,
 		 serial, s_priv->glocont_buf, GLOCONT_BUFLEN,
 		 cback->glocont_callback);
-
-	/* Setup endpoints for each port specific thing */
-	for (i = 0; i < d_details->num_ports; i++) {
-		port = serial->port[i];
-		p_priv = usb_get_serial_port_data(port);
-
-		/* Do indat endpoints first, once for each flip */
-		endp = d_details->indat_endpoints[i];
-		for (j = 0; j <= d_details->indat_endp_flip; ++j, ++endp) {
-			p_priv->in_urbs[j] = keyspan_setup_urb
-				(serial, endp, USB_DIR_IN, port,
-				 p_priv->in_buffer[j], 64,
-				 cback->indat_callback);
-		}
-		for (; j < 2; ++j)
-			p_priv->in_urbs[j] = NULL;
-
-		/* outdat endpoints also have flip */
-		endp = d_details->outdat_endpoints[i];
-		for (j = 0; j <= d_details->outdat_endp_flip; ++j, ++endp) {
-			p_priv->out_urbs[j] = keyspan_setup_urb
-				(serial, endp, USB_DIR_OUT, port,
-				 p_priv->out_buffer[j], 64,
-				 cback->outdat_callback);
-		}
-		for (; j < 2; ++j)
-			p_priv->out_urbs[j] = NULL;
-
-		/* inack endpoint */
-		p_priv->inack_urb = keyspan_setup_urb
-			(serial, d_details->inack_endpoints[i], USB_DIR_IN,
-			 port, p_priv->inack_buffer, 1, cback->inack_callback);
-
-		/* outcont endpoint */
-		p_priv->outcont_urb = keyspan_setup_urb
-			(serial, d_details->outcont_endpoints[i], USB_DIR_OUT,
-			 port, p_priv->outcont_buffer, 64,
-			 cback->outcont_callback);
-	}
 }
 
 /* usa19 function doesn't require prescaler */
@@ -2407,9 +2364,7 @@
 static int keyspan_startup(struct usb_serial *serial)
 {
 	int				i, err;
-	struct usb_serial_port		*port;
 	struct keyspan_serial_private 	*s_priv;
-	struct keyspan_port_private	*p_priv;
 	const struct keyspan_device_details	*d_details;
 
 	for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
@@ -2432,19 +2387,6 @@
 	s_priv->device_details = d_details;
 	usb_set_serial_data(serial, s_priv);
 
-	/* Now setup per port private data */
-	for (i = 0; i < serial->num_ports; i++) {
-		port = serial->port[i];
-		p_priv = kzalloc(sizeof(struct keyspan_port_private),
-								GFP_KERNEL);
-		if (!p_priv) {
-			dev_dbg(&port->dev, "%s - kmalloc for keyspan_port_private (%d) failed!.\n", __func__, i);
-			return 1;
-		}
-		p_priv->device_details = d_details;
-		usb_set_serial_port_data(port, p_priv);
-	}
-
 	keyspan_setup_urbs(serial);
 
 	if (s_priv->instat_urb != NULL) {
@@ -2463,59 +2405,111 @@
 
 static void keyspan_disconnect(struct usb_serial *serial)
 {
-	int				i, j;
-	struct usb_serial_port		*port;
-	struct keyspan_serial_private 	*s_priv;
-	struct keyspan_port_private	*p_priv;
+	struct keyspan_serial_private *s_priv;
 
 	s_priv = usb_get_serial_data(serial);
 
-	/* Stop reading/writing urbs */
 	stop_urb(s_priv->instat_urb);
 	stop_urb(s_priv->glocont_urb);
 	stop_urb(s_priv->indat_urb);
-	for (i = 0; i < serial->num_ports; ++i) {
-		port = serial->port[i];
-		p_priv = usb_get_serial_port_data(port);
-		stop_urb(p_priv->inack_urb);
-		stop_urb(p_priv->outcont_urb);
-		for (j = 0; j < 2; j++) {
-			stop_urb(p_priv->in_urbs[j]);
-			stop_urb(p_priv->out_urbs[j]);
-		}
-	}
-
-	/* Now free them */
-	usb_free_urb(s_priv->instat_urb);
-	usb_free_urb(s_priv->indat_urb);
-	usb_free_urb(s_priv->glocont_urb);
-	for (i = 0; i < serial->num_ports; ++i) {
-		port = serial->port[i];
-		p_priv = usb_get_serial_port_data(port);
-		usb_free_urb(p_priv->inack_urb);
-		usb_free_urb(p_priv->outcont_urb);
-		for (j = 0; j < 2; j++) {
-			usb_free_urb(p_priv->in_urbs[j]);
-			usb_free_urb(p_priv->out_urbs[j]);
-		}
-	}
 }
 
 static void keyspan_release(struct usb_serial *serial)
 {
-	int				i;
-	struct usb_serial_port		*port;
-	struct keyspan_serial_private 	*s_priv;
+	struct keyspan_serial_private *s_priv;
 
 	s_priv = usb_get_serial_data(serial);
 
-	kfree(s_priv);
+	usb_free_urb(s_priv->instat_urb);
+	usb_free_urb(s_priv->indat_urb);
+	usb_free_urb(s_priv->glocont_urb);
 
-	/* Now free per port private data */
-	for (i = 0; i < serial->num_ports; i++) {
-		port = serial->port[i];
-		kfree(usb_get_serial_port_data(port));
+	kfree(s_priv);
+}
+
+static int keyspan_port_probe(struct usb_serial_port *port)
+{
+	struct usb_serial *serial = port->serial;
+	struct keyspan_serial_private *s_priv;
+	struct keyspan_port_private *p_priv;
+	const struct keyspan_device_details *d_details;
+	struct callbacks *cback;
+	int endp;
+	int port_num;
+	int i;
+
+	s_priv = usb_get_serial_data(serial);
+	d_details = s_priv->device_details;
+
+	p_priv = kzalloc(sizeof(*p_priv), GFP_KERNEL);
+	if (!p_priv)
+		return -ENOMEM;
+
+	p_priv->device_details = d_details;
+
+	/* Setup values for the various callback routines */
+	cback = &keyspan_callbacks[d_details->msg_format];
+
+	port_num = port->number - port->serial->minor;
+
+	/* Do indat endpoints first, once for each flip */
+	endp = d_details->indat_endpoints[port_num];
+	for (i = 0; i <= d_details->indat_endp_flip; ++i, ++endp) {
+		p_priv->in_urbs[i] = keyspan_setup_urb(serial, endp,
+						USB_DIR_IN, port,
+						p_priv->in_buffer[i], 64,
+						cback->indat_callback);
 	}
+	/* outdat endpoints also have flip */
+	endp = d_details->outdat_endpoints[port_num];
+	for (i = 0; i <= d_details->outdat_endp_flip; ++i, ++endp) {
+		p_priv->out_urbs[i] = keyspan_setup_urb(serial, endp,
+						USB_DIR_OUT, port,
+						p_priv->out_buffer[i], 64,
+						cback->outdat_callback);
+	}
+	/* inack endpoint */
+	p_priv->inack_urb = keyspan_setup_urb(serial,
+					d_details->inack_endpoints[port_num],
+					USB_DIR_IN, port,
+					p_priv->inack_buffer, 1,
+					cback->inack_callback);
+	/* outcont endpoint */
+	p_priv->outcont_urb = keyspan_setup_urb(serial,
+					d_details->outcont_endpoints[port_num],
+					USB_DIR_OUT, port,
+					p_priv->outcont_buffer, 64,
+					 cback->outcont_callback);
+
+	usb_set_serial_port_data(port, p_priv);
+
+	return 0;
+}
+
+static int keyspan_port_remove(struct usb_serial_port *port)
+{
+	struct keyspan_port_private *p_priv;
+	int i;
+
+	p_priv = usb_get_serial_port_data(port);
+
+	stop_urb(p_priv->inack_urb);
+	stop_urb(p_priv->outcont_urb);
+	for (i = 0; i < 2; i++) {
+		stop_urb(p_priv->in_urbs[i]);
+		stop_urb(p_priv->out_urbs[i]);
+	}
+
+	usb_free_urb(p_priv->inack_urb);
+	usb_free_urb(p_priv->outcont_urb);
+	for (i = 0; i < 2; i++) {
+		usb_free_urb(p_priv->in_urbs[i]);
+		usb_free_urb(p_priv->out_urbs[i]);
+	}
+
+	kfree(p_priv);
+
+	return 0;
 }
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index 0a8a40b..0273dda 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -42,6 +42,8 @@
 static int  keyspan_startup		(struct usb_serial *serial);
 static void keyspan_disconnect		(struct usb_serial *serial);
 static void keyspan_release		(struct usb_serial *serial);
+static int keyspan_port_probe(struct usb_serial_port *port);
+static int keyspan_port_remove(struct usb_serial_port *port);
 static int  keyspan_write_room		(struct tty_struct *tty);
 
 static int  keyspan_write		(struct tty_struct *tty,
@@ -567,6 +569,8 @@
 	.attach			= keyspan_startup,
 	.disconnect		= keyspan_disconnect,
 	.release		= keyspan_release,
+	.port_probe		= keyspan_port_probe,
+	.port_remove		= keyspan_port_remove,
 };
 
 static struct usb_serial_driver keyspan_2port_device = {
@@ -589,6 +593,8 @@
 	.attach			= keyspan_startup,
 	.disconnect		= keyspan_disconnect,
 	.release		= keyspan_release,
+	.port_probe		= keyspan_port_probe,
+	.port_remove		= keyspan_port_remove,
 };
 
 static struct usb_serial_driver keyspan_4port_device = {
@@ -611,6 +617,8 @@
 	.attach			= keyspan_startup,
 	.disconnect		= keyspan_disconnect,
 	.release		= keyspan_release,
+	.port_probe		= keyspan_port_probe,
+	.port_remove		= keyspan_port_remove,
 };
 
 static struct usb_serial_driver * const serial_drivers[] = {
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index f394771..8a20810 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -49,7 +49,8 @@
  * Function prototypes
  */
 static int  mct_u232_startup(struct usb_serial *serial);
-static void mct_u232_release(struct usb_serial *serial);
+static int  mct_u232_port_probe(struct usb_serial_port *port);
+static int  mct_u232_port_remove(struct usb_serial_port *remove);
 static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void mct_u232_close(struct usb_serial_port *port);
 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
@@ -99,7 +100,8 @@
 	.tiocmget =	     mct_u232_tiocmget,
 	.tiocmset =	     mct_u232_tiocmset,
 	.attach =	     mct_u232_startup,
-	.release =	     mct_u232_release,
+	.port_probe =        mct_u232_port_probe,
+	.port_remove =       mct_u232_port_remove,
 	.ioctl =             mct_u232_ioctl,
 	.get_icount =        mct_u232_get_icount,
 };
@@ -388,18 +390,8 @@
 
 static int mct_u232_startup(struct usb_serial *serial)
 {
-	struct mct_u232_private *priv;
 	struct usb_serial_port *port, *rport;
 
-	priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-	spin_lock_init(&priv->lock);
-	init_waitqueue_head(&priv->msr_wait);
-	usb_set_serial_port_data(serial->port[0], priv);
-
-	init_waitqueue_head(&serial->port[0]->write_wait);
-
 	/* Puh, that's dirty */
 	port = serial->port[0];
 	rport = serial->port[1];
@@ -412,18 +404,31 @@
 	return 0;
 } /* mct_u232_startup */
 
-
-static void mct_u232_release(struct usb_serial *serial)
+static int mct_u232_port_probe(struct usb_serial_port *port)
 {
 	struct mct_u232_private *priv;
-	int i;
 
-	for (i = 0; i < serial->num_ports; ++i) {
-		/* My special items, the standard routines free my urbs */
-		priv = usb_get_serial_port_data(serial->port[i]);
-		kfree(priv);
-	}
-} /* mct_u232_release */
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	spin_lock_init(&priv->lock);
+	init_waitqueue_head(&priv->msr_wait);
+
+	usb_set_serial_port_data(port, priv);
+
+	return 0;
+}
+
+static int mct_u232_port_remove(struct usb_serial_port *port)
+{
+	struct mct_u232_private *priv;
+
+	priv = usb_get_serial_port_data(port);
+	kfree(priv);
+
+	return 0;
+}
 
 static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
@@ -515,12 +520,14 @@
 
 static void mct_u232_close(struct usb_serial_port *port)
 {
-	if (port->serial->dev) {
-		/* shutdown our urbs */
-		usb_kill_urb(port->write_urb);
-		usb_kill_urb(port->read_urb);
-		usb_kill_urb(port->interrupt_in_urb);
-	}
+	/*
+	 * Must kill the read urb as it is actually an interrupt urb, which
+	 * generic close thus fails to kill.
+	 */
+	usb_kill_urb(port->read_urb);
+	usb_kill_urb(port->interrupt_in_urb);
+
+	usb_serial_generic_close(port);
 } /* mct_u232_close */
 
 
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c
index 0b257dd..6f29c74 100644
--- a/drivers/usb/serial/metro-usb.c
+++ b/drivers/usb/serial/metro-usb.c
@@ -179,16 +179,13 @@
 {
 	dev_dbg(&port->dev, "%s\n", __func__);
 
-	if (port->serial->dev) {
-		/* Shutdown any interrupt in urbs. */
-		if (port->interrupt_in_urb) {
-			usb_unlink_urb(port->interrupt_in_urb);
-			usb_kill_urb(port->interrupt_in_urb);
-		}
+	usb_unlink_urb(port->interrupt_in_urb);
+	usb_kill_urb(port->interrupt_in_urb);
 
-		/* Send deactivate cmd to device */
+	mutex_lock(&port->serial->disc_mutex);
+	if (!port->serial->disconnected)
 		metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port);
-	}
+	mutex_unlock(&port->serial->disc_mutex);
 }
 
 static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
@@ -271,51 +268,27 @@
 	return retval;
 }
 
-static void metrousb_shutdown(struct usb_serial *serial)
-{
-	int i = 0;
-
-	dev_dbg(&serial->dev->dev, "%s\n", __func__);
-
-	/* Stop reading and writing on all ports. */
-	for (i = 0; i < serial->num_ports; ++i) {
-		/* Close any open urbs. */
-		metrousb_cleanup(serial->port[i]);
-
-		/* Free memory. */
-		kfree(usb_get_serial_port_data(serial->port[i]));
-		usb_set_serial_port_data(serial->port[i], NULL);
-
-		dev_dbg(&serial->dev->dev, "%s - freed port number=%d\n",
-			__func__, serial->port[i]->number);
-	}
-}
-
-static int metrousb_startup(struct usb_serial *serial)
+static int metrousb_port_probe(struct usb_serial_port *port)
 {
 	struct metrousb_private *metro_priv;
-	struct usb_serial_port *port;
-	int i = 0;
 
-	dev_dbg(&serial->dev->dev, "%s\n", __func__);
+	metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL);
+	if (!metro_priv)
+		return -ENOMEM;
 
-	/* Loop through the serial ports setting up the private structures.
-	 * Currently we only use one port. */
-	for (i = 0; i < serial->num_ports; ++i) {
-		port = serial->port[i];
+	spin_lock_init(&metro_priv->lock);
 
-		/* Declare memory. */
-		metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL);
-		if (!metro_priv)
-			return -ENOMEM;
+	usb_set_serial_port_data(port, metro_priv);
 
-		/* Initialize memory. */
-		spin_lock_init(&metro_priv->lock);
-		usb_set_serial_port_data(port, metro_priv);
+	return 0;
+}
 
-		dev_dbg(&serial->dev->dev, "%s - port number=%d\n ",
-			__func__, port->number);
-	}
+static int metrousb_port_remove(struct usb_serial_port *port)
+{
+	struct metrousb_private *metro_priv;
+
+	metro_priv = usb_get_serial_port_data(port);
+	kfree(metro_priv);
 
 	return 0;
 }
@@ -414,8 +387,8 @@
 	.close			= metrousb_cleanup,
 	.read_int_callback	= metrousb_read_int_callback,
 	.write_int_callback	= metrousb_write_int_callback,
-	.attach			= metrousb_startup,
-	.release		= metrousb_shutdown,
+	.port_probe		= metrousb_port_probe,
+	.port_remove		= metrousb_port_remove,
 	.throttle		= metrousb_throttle,
 	.unthrottle		= metrousb_unthrottle,
 	.tiocmget		= metrousb_tiocmget,
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 1bf1ad0..7526742 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -1966,9 +1966,7 @@
 
 static int mos7720_startup(struct usb_serial *serial)
 {
-	struct moschip_port *mos7720_port;
 	struct usb_device *dev;
-	int i;
 	char data;
 	u16 product;
 	int ret_val;
@@ -1999,29 +1997,6 @@
 		serial->port[1]->interrupt_in_buffer = NULL;
 	}
 
-
-	/* set up serial port private structures */
-	for (i = 0; i < serial->num_ports; ++i) {
-		mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
-		if (mos7720_port == NULL) {
-			dev_err(&dev->dev, "%s - Out of memory\n", __func__);
-			return -ENOMEM;
-		}
-
-		/* Initialize all port interrupt end point to port 0 int
-		 * endpoint.  Our device has only one interrupt endpoint
-		 * common to all ports */
-		serial->port[i]->interrupt_in_endpointAddress =
-				serial->port[0]->interrupt_in_endpointAddress;
-
-		mos7720_port->port = serial->port[i];
-		usb_set_serial_port_data(serial->port[i], mos7720_port);
-
-		dev_dbg(&dev->dev, "port number is %d\n", serial->port[i]->number);
-		dev_dbg(&dev->dev, "serial number is %d\n", serial->minor);
-	}
-
-
 	/* setting configuration feature to one */
 	usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 			(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
@@ -2049,8 +2024,6 @@
 
 static void mos7720_release(struct usb_serial *serial)
 {
-	int i;
-
 #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
 	/* close the parallel port */
 
@@ -2089,9 +2062,36 @@
 		kref_put(&mos_parport->ref_count, destroy_mos_parport);
 	}
 #endif
-	/* free private structure allocated for serial port */
-	for (i = 0; i < serial->num_ports; ++i)
-		kfree(usb_get_serial_port_data(serial->port[i]));
+}
+
+static int mos7720_port_probe(struct usb_serial_port *port)
+{
+	struct moschip_port *mos7720_port;
+
+	mos7720_port = kzalloc(sizeof(*mos7720_port), GFP_KERNEL);
+	if (!mos7720_port)
+		return -ENOMEM;
+
+	/* Initialize all port interrupt end point to port 0 int endpoint.
+	 * Our device has only one interrupt endpoint common to all ports.
+	 */
+	port->interrupt_in_endpointAddress =
+		port->serial->port[0]->interrupt_in_endpointAddress;
+	mos7720_port->port = port;
+
+	usb_set_serial_port_data(port, mos7720_port);
+
+	return 0;
+}
+
+static int mos7720_port_remove(struct usb_serial_port *port)
+{
+	struct moschip_port *mos7720_port;
+
+	mos7720_port = usb_get_serial_port_data(port);
+	kfree(mos7720_port);
+
+	return 0;
 }
 
 static struct usb_serial_driver moschip7720_2port_driver = {
@@ -2109,6 +2109,8 @@
 	.probe			= mos77xx_probe,
 	.attach			= mos7720_startup,
 	.release		= mos7720_release,
+	.port_probe		= mos7720_port_probe,
+	.port_remove		= mos7720_port_remove,
 	.ioctl			= mos7720_ioctl,
 	.tiocmget		= mos7720_tiocmget,
 	.tiocmset		= mos7720_tiocmset,
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index d6d4eec..1cf3375 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -218,12 +218,10 @@
 	int port_num;		/*Actual port number in the device(1,2,etc) */
 	struct urb *write_urb;	/* write URB for this port */
 	struct urb *read_urb;	/* read URB for this port */
-	struct urb *int_urb;
 	__u8 shadowLCR;		/* last LCR value received */
 	__u8 shadowMCR;		/* last MCR value received */
 	char open;
 	char open_ports;
-	char zombie;
 	wait_queue_head_t wait_chase;	/* for handling sleeping while waiting for chase to finish */
 	wait_queue_head_t delta_msr_wait;	/* for handling sleeping while waiting for msr change to happen */
 	int delta_msr_cond;
@@ -478,7 +476,6 @@
 	struct moschip_port *mos7840_port;
 	struct device *dev = &urb->dev->dev;
 	__u8 regval = 0x0;
-	int result = 0;
 	int status = urb->status;
 
 	mos7840_port = urb->context;
@@ -495,7 +492,7 @@
 		return;
 	default:
 		dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status);
-		goto exit;
+		return;
 	}
 
 	dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length);
@@ -508,16 +505,6 @@
 		mos7840_handle_new_msr(mos7840_port, regval);
 	else if (mos7840_port->MsrLsr == 1)
 		mos7840_handle_new_lsr(mos7840_port, regval);
-
-exit:
-	spin_lock(&mos7840_port->pool_lock);
-	if (!mos7840_port->zombie)
-		result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC);
-	spin_unlock(&mos7840_port->pool_lock);
-	if (result) {
-		dev_err(dev, "%s - Error %d submitting interrupt urb\n",
-			__func__, result);
-	}
 }
 
 static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
@@ -686,14 +673,7 @@
 					wreg = MODEM_STATUS_REGISTER;
 					break;
 				}
-				spin_lock(&mos7840_port->pool_lock);
-				if (!mos7840_port->zombie) {
-					rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data);
-				} else {
-					spin_unlock(&mos7840_port->pool_lock);
-					return;
-				}
-				spin_unlock(&mos7840_port->pool_lock);
+				rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data);
 			}
 		}
 	}
@@ -2347,309 +2327,249 @@
 	return mos7840_num_ports;
 }
 
-/****************************************************************************
- * mos7840_startup
- ****************************************************************************/
-
-static int mos7840_startup(struct usb_serial *serial)
+static int mos7840_port_probe(struct usb_serial_port *port)
 {
+	struct usb_serial *serial = port->serial;
 	struct moschip_port *mos7840_port;
-	struct usb_device *dev;
-	int i, status;
+	int status;
+	int pnum;
 	__u16 Data;
 
-	dev = serial->dev;
-
 	/* we set up the pointers to the endpoints in the mos7840_open *
 	 * function, as the structures aren't created yet.             */
 
-	/* set up port private structures */
-	for (i = 0; i < serial->num_ports; ++i) {
-		dev_dbg(&dev->dev, "mos7840_startup: configuring port %d............\n", i);
-		mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
-		if (mos7840_port == NULL) {
-			dev_err(&dev->dev, "%s - Out of memory\n", __func__);
-			status = -ENOMEM;
-			i--; /* don't follow NULL pointer cleaning up */
-			goto error;
-		}
+	pnum = port->number - serial->minor;
 
-		/* Initialize all port interrupt end point to port 0 int
-		 * endpoint. Our device has only one interrupt end point
-		 * common to all port */
-
-		mos7840_port->port = serial->port[i];
-		mos7840_set_port_private(serial->port[i], mos7840_port);
-		spin_lock_init(&mos7840_port->pool_lock);
-
-		/* minor is not initialised until later by
-		 * usb-serial.c:get_free_serial() and cannot therefore be used
-		 * to index device instances */
-		mos7840_port->port_num = i + 1;
-		dev_dbg(&dev->dev, "serial->port[i]->number = %d\n", serial->port[i]->number);
-		dev_dbg(&dev->dev, "serial->port[i]->serial->minor = %d\n", serial->port[i]->serial->minor);
-		dev_dbg(&dev->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num);
-		dev_dbg(&dev->dev, "serial->minor = %d\n", serial->minor);
-
-		if (mos7840_port->port_num == 1) {
-			mos7840_port->SpRegOffset = 0x0;
-			mos7840_port->ControlRegOffset = 0x1;
-			mos7840_port->DcrRegOffset = 0x4;
-		} else if ((mos7840_port->port_num == 2)
-			   && (serial->num_ports == 4)) {
-			mos7840_port->SpRegOffset = 0x8;
-			mos7840_port->ControlRegOffset = 0x9;
-			mos7840_port->DcrRegOffset = 0x16;
-		} else if ((mos7840_port->port_num == 2)
-			   && (serial->num_ports == 2)) {
-			mos7840_port->SpRegOffset = 0xa;
-			mos7840_port->ControlRegOffset = 0xb;
-			mos7840_port->DcrRegOffset = 0x19;
-		} else if ((mos7840_port->port_num == 3)
-			   && (serial->num_ports == 4)) {
-			mos7840_port->SpRegOffset = 0xa;
-			mos7840_port->ControlRegOffset = 0xb;
-			mos7840_port->DcrRegOffset = 0x19;
-		} else if ((mos7840_port->port_num == 4)
-			   && (serial->num_ports == 4)) {
-			mos7840_port->SpRegOffset = 0xc;
-			mos7840_port->ControlRegOffset = 0xd;
-			mos7840_port->DcrRegOffset = 0x1c;
-		}
-		mos7840_dump_serial_port(serial->port[i], mos7840_port);
-		mos7840_set_port_private(serial->port[i], mos7840_port);
-
-		/* enable rx_disable bit in control register */
-		status = mos7840_get_reg_sync(serial->port[i],
-				 mos7840_port->ControlRegOffset, &Data);
-		if (status < 0) {
-			dev_dbg(&dev->dev, "Reading ControlReg failed status-0x%x\n", status);
-			break;
-		} else
-			dev_dbg(&dev->dev, "ControlReg Reading success val is %x, status%d\n", Data, status);
-		Data |= 0x08;	/* setting driver done bit */
-		Data |= 0x04;	/* sp1_bit to have cts change reflect in
-				   modem status reg */
-
-		/* Data |= 0x20; //rx_disable bit */
-		status = mos7840_set_reg_sync(serial->port[i],
-					 mos7840_port->ControlRegOffset, Data);
-		if (status < 0) {
-			dev_dbg(&dev->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status);
-			break;
-		} else
-			dev_dbg(&dev->dev, "ControlReg Writing success(rx_disable) status%d\n", status);
-
-		/* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
-		   and 0x24 in DCR3 */
-		Data = 0x01;
-		status = mos7840_set_reg_sync(serial->port[i],
-			 (__u16) (mos7840_port->DcrRegOffset + 0), Data);
-		if (status < 0) {
-			dev_dbg(&dev->dev, "Writing DCR0 failed status-0x%x\n", status);
-			break;
-		} else
-			dev_dbg(&dev->dev, "DCR0 Writing success status%d\n", status);
-
-		Data = 0x05;
-		status = mos7840_set_reg_sync(serial->port[i],
-			 (__u16) (mos7840_port->DcrRegOffset + 1), Data);
-		if (status < 0) {
-			dev_dbg(&dev->dev, "Writing DCR1 failed status-0x%x\n", status);
-			break;
-		} else
-			dev_dbg(&dev->dev, "DCR1 Writing success status%d\n", status);
-
-		Data = 0x24;
-		status = mos7840_set_reg_sync(serial->port[i],
-			 (__u16) (mos7840_port->DcrRegOffset + 2), Data);
-		if (status < 0) {
-			dev_dbg(&dev->dev, "Writing DCR2 failed status-0x%x\n", status);
-			break;
-		} else
-			dev_dbg(&dev->dev, "DCR2 Writing success status%d\n", status);
-
-		/* write values in clkstart0x0 and clkmulti 0x20 */
-		Data = 0x0;
-		status = mos7840_set_reg_sync(serial->port[i],
-					 CLK_START_VALUE_REGISTER, Data);
-		if (status < 0) {
-			dev_dbg(&dev->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status);
-			break;
-		} else
-			dev_dbg(&dev->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status);
-
-		Data = 0x20;
-		status = mos7840_set_reg_sync(serial->port[i],
-					CLK_MULTI_REGISTER, Data);
-		if (status < 0) {
-			dev_dbg(&dev->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status);
-			goto error;
-		} else
-			dev_dbg(&dev->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status);
-
-		/* write value 0x0 to scratchpad register */
-		Data = 0x00;
-		status = mos7840_set_uart_reg(serial->port[i],
-						SCRATCH_PAD_REGISTER, Data);
-		if (status < 0) {
-			dev_dbg(&dev->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status);
-			break;
-		} else
-			dev_dbg(&dev->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status);
-
-		/* Zero Length flag register */
-		if ((mos7840_port->port_num != 1)
-		    && (serial->num_ports == 2)) {
-
-			Data = 0xff;
-			status = mos7840_set_reg_sync(serial->port[i],
-				      (__u16) (ZLP_REG1 +
-				      ((__u16)mos7840_port->port_num)), Data);
-			dev_dbg(&dev->dev, "ZLIP offset %x\n",
-				(__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num)));
-			if (status < 0) {
-				dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 2, status);
-				break;
-			} else
-				dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 2, status);
-		} else {
-			Data = 0xff;
-			status = mos7840_set_reg_sync(serial->port[i],
-			      (__u16) (ZLP_REG1 +
-			      ((__u16)mos7840_port->port_num) - 0x1), Data);
-			dev_dbg(&dev->dev, "ZLIP offset %x\n",
-				(__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1));
-			if (status < 0) {
-				dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 1, status);
-				break;
-			} else
-				dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 1, status);
-
-		}
-		mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
-		mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
-		mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest),
-								GFP_KERNEL);
-		if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf ||
-							!mos7840_port->dr) {
-			status = -ENOMEM;
-			goto error;
-		}
-
-		mos7840_port->has_led = false;
-
-		/* Initialize LED timers */
-		if (device_type == MOSCHIP_DEVICE_ID_7810) {
-			mos7840_port->has_led = true;
-
-			init_timer(&mos7840_port->led_timer1);
-			mos7840_port->led_timer1.function = mos7840_led_off;
-			mos7840_port->led_timer1.expires =
-					jiffies + msecs_to_jiffies(LED_ON_MS);
-			mos7840_port->led_timer1.data =
-						(unsigned long)mos7840_port;
-
-			init_timer(&mos7840_port->led_timer2);
-			mos7840_port->led_timer2.function =
-						mos7840_led_flag_off;
-			mos7840_port->led_timer2.expires =
-					jiffies + msecs_to_jiffies(LED_OFF_MS);
-			mos7840_port->led_timer2.data =
-						(unsigned long)mos7840_port;
-
-			mos7840_port->led_flag = false;
-
-			/* Turn off LED */
-			mos7840_set_led_sync(serial->port[i],
-						MODEM_CONTROL_REGISTER, 0x0300);
-		}
+	dev_dbg(&port->dev, "mos7840_startup: configuring port %d\n", pnum);
+	mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
+	if (mos7840_port == NULL) {
+		dev_err(&port->dev, "%s - Out of memory\n", __func__);
+		return -ENOMEM;
 	}
 
-	/* Zero Length flag enable */
-	Data = 0x0f;
-	status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
+	/* Initialize all port interrupt end point to port 0 int
+	 * endpoint. Our device has only one interrupt end point
+	 * common to all port */
+
+	mos7840_port->port = port;
+	mos7840_set_port_private(port, mos7840_port);
+	spin_lock_init(&mos7840_port->pool_lock);
+
+	/* minor is not initialised until later by
+	 * usb-serial.c:get_free_serial() and cannot therefore be used
+	 * to index device instances */
+	mos7840_port->port_num = pnum + 1;
+	dev_dbg(&port->dev, "port->number = %d\n", port->number);
+	dev_dbg(&port->dev, "port->serial->minor = %d\n", port->serial->minor);
+	dev_dbg(&port->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num);
+	dev_dbg(&port->dev, "serial->minor = %d\n", serial->minor);
+
+	if (mos7840_port->port_num == 1) {
+		mos7840_port->SpRegOffset = 0x0;
+		mos7840_port->ControlRegOffset = 0x1;
+		mos7840_port->DcrRegOffset = 0x4;
+	} else if ((mos7840_port->port_num == 2) && (serial->num_ports == 4)) {
+		mos7840_port->SpRegOffset = 0x8;
+		mos7840_port->ControlRegOffset = 0x9;
+		mos7840_port->DcrRegOffset = 0x16;
+	} else if ((mos7840_port->port_num == 2) && (serial->num_ports == 2)) {
+		mos7840_port->SpRegOffset = 0xa;
+		mos7840_port->ControlRegOffset = 0xb;
+		mos7840_port->DcrRegOffset = 0x19;
+	} else if ((mos7840_port->port_num == 3) && (serial->num_ports == 4)) {
+		mos7840_port->SpRegOffset = 0xa;
+		mos7840_port->ControlRegOffset = 0xb;
+		mos7840_port->DcrRegOffset = 0x19;
+	} else if ((mos7840_port->port_num == 4) && (serial->num_ports == 4)) {
+		mos7840_port->SpRegOffset = 0xc;
+		mos7840_port->ControlRegOffset = 0xd;
+		mos7840_port->DcrRegOffset = 0x1c;
+	}
+	mos7840_dump_serial_port(port, mos7840_port);
+	mos7840_set_port_private(port, mos7840_port);
+
+	/* enable rx_disable bit in control register */
+	status = mos7840_get_reg_sync(port,
+			mos7840_port->ControlRegOffset, &Data);
 	if (status < 0) {
-		dev_dbg(&dev->dev, "Writing ZLP_REG5 failed status-0x%x\n", status);
+		dev_dbg(&port->dev, "Reading ControlReg failed status-0x%x\n", status);
+		goto out;
+	} else
+		dev_dbg(&port->dev, "ControlReg Reading success val is %x, status%d\n", Data, status);
+	Data |= 0x08;	/* setting driver done bit */
+	Data |= 0x04;	/* sp1_bit to have cts change reflect in
+			   modem status reg */
+
+	/* Data |= 0x20; //rx_disable bit */
+	status = mos7840_set_reg_sync(port,
+			mos7840_port->ControlRegOffset, Data);
+	if (status < 0) {
+		dev_dbg(&port->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status);
+		goto out;
+	} else
+		dev_dbg(&port->dev, "ControlReg Writing success(rx_disable) status%d\n", status);
+
+	/* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
+	   and 0x24 in DCR3 */
+	Data = 0x01;
+	status = mos7840_set_reg_sync(port,
+			(__u16) (mos7840_port->DcrRegOffset + 0), Data);
+	if (status < 0) {
+		dev_dbg(&port->dev, "Writing DCR0 failed status-0x%x\n", status);
+		goto out;
+	} else
+		dev_dbg(&port->dev, "DCR0 Writing success status%d\n", status);
+
+	Data = 0x05;
+	status = mos7840_set_reg_sync(port,
+			(__u16) (mos7840_port->DcrRegOffset + 1), Data);
+	if (status < 0) {
+		dev_dbg(&port->dev, "Writing DCR1 failed status-0x%x\n", status);
+		goto out;
+	} else
+		dev_dbg(&port->dev, "DCR1 Writing success status%d\n", status);
+
+	Data = 0x24;
+	status = mos7840_set_reg_sync(port,
+			(__u16) (mos7840_port->DcrRegOffset + 2), Data);
+	if (status < 0) {
+		dev_dbg(&port->dev, "Writing DCR2 failed status-0x%x\n", status);
+		goto out;
+	} else
+		dev_dbg(&port->dev, "DCR2 Writing success status%d\n", status);
+
+	/* write values in clkstart0x0 and clkmulti 0x20 */
+	Data = 0x0;
+	status = mos7840_set_reg_sync(port, CLK_START_VALUE_REGISTER, Data);
+	if (status < 0) {
+		dev_dbg(&port->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status);
+		goto out;
+	} else
+		dev_dbg(&port->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status);
+
+	Data = 0x20;
+	status = mos7840_set_reg_sync(port, CLK_MULTI_REGISTER, Data);
+	if (status < 0) {
+		dev_dbg(&port->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status);
 		goto error;
 	} else
-		dev_dbg(&dev->dev, "ZLP_REG5 Writing success status%d\n", status);
+		dev_dbg(&port->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status);
 
-	/* setting configuration feature to one */
-	usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			(__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT);
+	/* write value 0x0 to scratchpad register */
+	Data = 0x00;
+	status = mos7840_set_uart_reg(port, SCRATCH_PAD_REGISTER, Data);
+	if (status < 0) {
+		dev_dbg(&port->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status);
+		goto out;
+	} else
+		dev_dbg(&port->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status);
+
+	/* Zero Length flag register */
+	if ((mos7840_port->port_num != 1) && (serial->num_ports == 2)) {
+		Data = 0xff;
+		status = mos7840_set_reg_sync(port,
+				(__u16) (ZLP_REG1 +
+					((__u16)mos7840_port->port_num)), Data);
+		dev_dbg(&port->dev, "ZLIP offset %x\n",
+				(__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num)));
+		if (status < 0) {
+			dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 2, status);
+			goto out;
+		} else
+			dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 2, status);
+	} else {
+		Data = 0xff;
+		status = mos7840_set_reg_sync(port,
+				(__u16) (ZLP_REG1 +
+					((__u16)mos7840_port->port_num) - 0x1), Data);
+		dev_dbg(&port->dev, "ZLIP offset %x\n",
+				(__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1));
+		if (status < 0) {
+			dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 1, status);
+			goto out;
+		} else
+			dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 1, status);
+
+	}
+	mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
+	mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
+	mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest),
+			GFP_KERNEL);
+	if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf ||
+			!mos7840_port->dr) {
+		status = -ENOMEM;
+		goto error;
+	}
+
+	mos7840_port->has_led = false;
+
+	/* Initialize LED timers */
+	if (device_type == MOSCHIP_DEVICE_ID_7810) {
+		mos7840_port->has_led = true;
+
+		init_timer(&mos7840_port->led_timer1);
+		mos7840_port->led_timer1.function = mos7840_led_off;
+		mos7840_port->led_timer1.expires =
+			jiffies + msecs_to_jiffies(LED_ON_MS);
+		mos7840_port->led_timer1.data = (unsigned long)mos7840_port;
+
+		init_timer(&mos7840_port->led_timer2);
+		mos7840_port->led_timer2.function = mos7840_led_flag_off;
+		mos7840_port->led_timer2.expires =
+			jiffies + msecs_to_jiffies(LED_OFF_MS);
+		mos7840_port->led_timer2.data = (unsigned long)mos7840_port;
+
+		mos7840_port->led_flag = false;
+
+		/* Turn off LED */
+		mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
+	}
+out:
+	if (pnum == serial->num_ports - 1) {
+		/* Zero Length flag enable */
+		Data = 0x0f;
+		status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
+		if (status < 0) {
+			dev_dbg(&port->dev, "Writing ZLP_REG5 failed status-0x%x\n", status);
+			goto error;
+		} else
+			dev_dbg(&port->dev, "ZLP_REG5 Writing success status%d\n", status);
+
+		/* setting configuration feature to one */
+		usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+				0x03, 0x00, 0x01, 0x00, NULL, 0x00,
+				MOS_WDR_TIMEOUT);
+	}
 	return 0;
 error:
-	for (/* nothing */; i >= 0; i--) {
-		mos7840_port = mos7840_get_port_private(serial->port[i]);
+	kfree(mos7840_port->dr);
+	kfree(mos7840_port->ctrl_buf);
+	usb_free_urb(mos7840_port->control_urb);
+	kfree(mos7840_port);
 
-		kfree(mos7840_port->dr);
-		kfree(mos7840_port->ctrl_buf);
-		usb_free_urb(mos7840_port->control_urb);
-		kfree(mos7840_port);
-		serial->port[i] = NULL;
-	}
 	return status;
 }
 
-/****************************************************************************
- * mos7840_disconnect
- *	This function is called whenever the device is removed from the usb bus.
- ****************************************************************************/
-
-static void mos7840_disconnect(struct usb_serial *serial)
+static int mos7840_port_remove(struct usb_serial_port *port)
 {
-	int i;
-	unsigned long flags;
 	struct moschip_port *mos7840_port;
 
-	/* check for the ports to be closed,close the ports and disconnect */
+	mos7840_port = mos7840_get_port_private(port);
 
-	/* free private structure allocated for serial port  *
-	 * stop reads and writes on all ports                */
+	if (mos7840_port->has_led) {
+		/* Turn off LED */
+		mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
 
-	for (i = 0; i < serial->num_ports; ++i) {
-		mos7840_port = mos7840_get_port_private(serial->port[i]);
-		if (mos7840_port) {
-			spin_lock_irqsave(&mos7840_port->pool_lock, flags);
-			mos7840_port->zombie = 1;
-			spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
-			usb_kill_urb(mos7840_port->control_urb);
-		}
+		del_timer_sync(&mos7840_port->led_timer1);
+		del_timer_sync(&mos7840_port->led_timer2);
 	}
-}
+	usb_kill_urb(mos7840_port->control_urb);
+	usb_free_urb(mos7840_port->control_urb);
+	kfree(mos7840_port->ctrl_buf);
+	kfree(mos7840_port->dr);
+	kfree(mos7840_port);
 
-/****************************************************************************
- * mos7840_release
- *	This function is called when the usb_serial structure is freed.
- ****************************************************************************/
-
-static void mos7840_release(struct usb_serial *serial)
-{
-	int i;
-	struct moschip_port *mos7840_port;
-
-	/* check for the ports to be closed,close the ports and disconnect */
-
-	/* free private structure allocated for serial port  *
-	 * stop reads and writes on all ports                */
-
-	for (i = 0; i < serial->num_ports; ++i) {
-		mos7840_port = mos7840_get_port_private(serial->port[i]);
-		if (mos7840_port) {
-			if (mos7840_port->has_led) {
-				/* Turn off LED */
-				mos7840_set_led_sync(mos7840_port->port,
-						MODEM_CONTROL_REGISTER, 0x0300);
-
-				del_timer_sync(&mos7840_port->led_timer1);
-				del_timer_sync(&mos7840_port->led_timer2);
-			}
-			kfree(mos7840_port->ctrl_buf);
-			kfree(mos7840_port->dr);
-			kfree(mos7840_port);
-		}
-	}
+	return 0;
 }
 
 static struct usb_serial_driver moschip7840_4port_device = {
@@ -2677,9 +2597,8 @@
 	.tiocmget = mos7840_tiocmget,
 	.tiocmset = mos7840_tiocmset,
 	.get_icount = mos7840_get_icount,
-	.attach = mos7840_startup,
-	.disconnect = mos7840_disconnect,
-	.release = mos7840_release,
+	.port_probe = mos7840_port_probe,
+	.port_remove = mos7840_port_remove,
 	.read_bulk_callback = mos7840_bulk_in_callback,
 	.read_int_callback = mos7840_interrupt_callback,
 };
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 6def58b..9ab73d2 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -44,8 +44,8 @@
 				const unsigned char *buf, int count);
 static int  omninet_write_room(struct tty_struct *tty);
 static void omninet_disconnect(struct usb_serial *serial);
-static void omninet_release(struct usb_serial *serial);
-static int omninet_attach(struct usb_serial *serial);
+static int omninet_port_probe(struct usb_serial_port *port);
+static int omninet_port_remove(struct usb_serial_port *port);
 
 static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) },
@@ -62,7 +62,8 @@
 	.description =		"ZyXEL - omni.net lcd plus usb",
 	.id_table =		id_table,
 	.num_ports =		1,
-	.attach =		omninet_attach,
+	.port_probe =		omninet_port_probe,
+	.port_remove =		omninet_port_remove,
 	.open =			omninet_open,
 	.close =		omninet_close,
 	.write =		omninet_write,
@@ -70,7 +71,6 @@
 	.read_bulk_callback =	omninet_read_bulk_callback,
 	.write_bulk_callback =	omninet_write_bulk_callback,
 	.disconnect =		omninet_disconnect,
-	.release =		omninet_release,
 };
 
 static struct usb_serial_driver * const serial_drivers[] = {
@@ -112,18 +112,26 @@
 	__u8	od_outseq;	/* Sequence number for bulk_out URBs */
 };
 
-static int omninet_attach(struct usb_serial *serial)
+static int omninet_port_probe(struct usb_serial_port *port)
 {
 	struct omninet_data *od;
-	struct usb_serial_port *port = serial->port[0];
 
 	od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL);
-	if (!od) {
-		dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n",
-			__func__, sizeof(struct omninet_data));
+	if (!od)
 		return -ENOMEM;
-	}
+
 	usb_set_serial_port_data(port, od);
+
+	return 0;
+}
+
+static int omninet_port_remove(struct usb_serial_port *port)
+{
+	struct omninet_data *od;
+
+	od = usb_get_serial_port_data(port);
+	kfree(od);
+
 	return 0;
 }
 
@@ -279,14 +287,6 @@
 	usb_kill_urb(wport->write_urb);
 }
 
-
-static void omninet_release(struct usb_serial *serial)
-{
-	struct usb_serial_port *port = serial->port[0];
-
-	kfree(usb_get_serial_port_data(port));
-}
-
 module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 41b1647..6aba731 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -155,7 +155,11 @@
 {
 	struct usb_serial *serial = port->serial;
 	int retval;
-	u8 buffer[2];
+	u8 *buffer;
+
+	buffer = kzalloc(1, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
 
 	buffer[0] = val;
 	/* Send the message to the vendor control endpoint
@@ -164,6 +168,7 @@
 				requesttype,
 				USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
 				0, 0, buffer, 1, 0);
+	kfree(buffer);
 
 	return retval;
 }
@@ -281,7 +286,7 @@
 	if (!dr) {
 		dev_err(&port->dev, "out of memory\n");
 		count = -ENOMEM;
-		goto error;
+		goto error_no_dr;
 	}
 
 	dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT;
@@ -311,6 +316,8 @@
 
 	return count;
 error:
+	kfree(dr);
+error_no_dr:
 	usb_free_urb(urb);
 error_no_urb:
 	kfree(buffer);
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 54d4148..edc64bb 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -47,6 +47,7 @@
 /* Function prototypes */
 static int  option_probe(struct usb_serial *serial,
 			const struct usb_device_id *id);
+static int option_attach(struct usb_serial *serial);
 static void option_release(struct usb_serial *serial);
 static int option_send_setup(struct usb_serial_port *port);
 static void option_instat_callback(struct urb *urb);
@@ -157,6 +158,7 @@
 #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED	0x8001
 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED	0x9000
 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED	0x9001
+#define NOVATELWIRELESS_PRODUCT_E362		0x9010
 #define NOVATELWIRELESS_PRODUCT_G1		0xA001
 #define NOVATELWIRELESS_PRODUCT_G1_M		0xA002
 #define NOVATELWIRELESS_PRODUCT_G2		0xA010
@@ -192,6 +194,9 @@
 #define DELL_PRODUCT_5730_MINICARD_TELUS	0x8181
 #define DELL_PRODUCT_5730_MINICARD_VZW		0x8182
 
+#define DELL_PRODUCT_5800_MINICARD_VZW		0x8195  /* Novatel E362 */
+#define DELL_PRODUCT_5800_V2_MINICARD_VZW	0x8196  /* Novatel E362 */
+
 #define KYOCERA_VENDOR_ID			0x0c88
 #define KYOCERA_PRODUCT_KPC650			0x17da
 #define KYOCERA_PRODUCT_KPC680			0x180a
@@ -282,6 +287,7 @@
 /* ALCATEL PRODUCTS */
 #define ALCATEL_VENDOR_ID			0x1bbb
 #define ALCATEL_PRODUCT_X060S_X200		0x0000
+#define ALCATEL_PRODUCT_X220_X500D		0x0017
 
 #define PIRELLI_VENDOR_ID			0x1266
 #define PIRELLI_PRODUCT_C100_1			0x1002
@@ -705,6 +711,7 @@
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) },
 	/* Novatel Ovation MC551 a.k.a. Verizon USB551L */
 	{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
 
 	{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
 	{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
@@ -727,6 +734,8 @@
 	{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) },	/* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
 	{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) },	/* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
 	{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, 	/* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
+	{ USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },	/* ADU-E100, ADU-310 */
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
@@ -1156,6 +1165,7 @@
 	{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
 	  .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
 	},
+	{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) },
 	{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
 	{ USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
 	{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
@@ -1288,8 +1298,9 @@
 	.tiocmget          = usb_wwan_tiocmget,
 	.tiocmset          = usb_wwan_tiocmset,
 	.ioctl             = usb_wwan_ioctl,
-	.attach            = usb_wwan_startup,
+	.attach            = option_attach,
 	.release           = option_release,
+	.port_probe        = usb_wwan_port_probe,
 	.port_remove	   = usb_wwan_port_remove,
 	.read_int_callback = option_instat_callback,
 #ifdef CONFIG_PM
@@ -1335,8 +1346,6 @@
 static int option_probe(struct usb_serial *serial,
 			const struct usb_device_id *id)
 {
-	struct usb_wwan_intf_private *data;
-	struct option_private *priv;
 	struct usb_interface_descriptor *iface_desc =
 				&serial->interface->cur_altsetting->desc;
 	struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
@@ -1374,6 +1383,19 @@
 		iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
 		return -ENODEV;
 
+	/* Store device id so we can use it during attach. */
+	usb_set_serial_data(serial, (void *)id);
+
+	return 0;
+}
+
+static int option_attach(struct usb_serial *serial)
+{
+	struct usb_interface_descriptor *iface_desc;
+	const struct usb_device_id *id;
+	struct usb_wwan_intf_private *data;
+	struct option_private *priv;
+
 	data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
@@ -1384,6 +1406,10 @@
 		return -ENOMEM;
 	}
 
+	/* Retrieve device id stored at probe. */
+	id = usb_get_serial_data(serial);
+	iface_desc = &serial->interface->cur_altsetting->desc;
+
 	priv->bInterfaceNumber = iface_desc->bInterfaceNumber;
 	data->private = priv;
 
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index c3ddb65..aa148c2 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -138,7 +138,6 @@
 
 static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 {
-	struct usb_wwan_intf_private *data;
 	struct usb_host_interface *intf = serial->interface->cur_altsetting;
 	struct device *dev = &serial->dev->dev;
 	int retval = -ENODEV;
@@ -154,13 +153,6 @@
 	ifnum = intf->desc.bInterfaceNumber;
 	dev_dbg(dev, "This Interface = %d\n", ifnum);
 
-	data = kzalloc(sizeof(struct usb_wwan_intf_private),
-					 GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	spin_lock_init(&data->susp_lock);
-
 	if (nintf == 1) {
 		/* QDL mode */
 		/* Gobi 2000 has a single altsetting, older ones have two */
@@ -253,20 +245,28 @@
 		}
 	}
 
-	/* Set serial->private if not returning error */
-	if (retval == 0)
-		usb_set_serial_data(serial, data);
-	else
-		kfree(data);
-
 	return retval;
 }
 
+static int qc_attach(struct usb_serial *serial)
+{
+	struct usb_wwan_intf_private *data;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	spin_lock_init(&data->susp_lock);
+
+	usb_set_serial_data(serial, data);
+
+	return 0;
+}
+
 static void qc_release(struct usb_serial *serial)
 {
 	struct usb_wwan_intf_private *priv = usb_get_serial_data(serial);
 
-	/* Free the private data allocated in qcprobe */
 	usb_set_serial_data(serial, NULL);
 	kfree(priv);
 }
@@ -285,8 +285,9 @@
 	.write		     = usb_wwan_write,
 	.write_room	     = usb_wwan_write_room,
 	.chars_in_buffer     = usb_wwan_chars_in_buffer,
-	.attach		     = usb_wwan_startup,
+	.attach              = qc_attach,
 	.release	     = qc_release,
+	.port_probe          = usb_wwan_port_probe,
 	.port_remove	     = usb_wwan_port_remove,
 #ifdef CONFIG_PM
 	.suspend	     = usb_wwan_suspend,
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
index 2cdfdcc..ffcfc96 100644
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -143,12 +143,12 @@
 
 static void qt2_release(struct usb_serial *serial)
 {
-	int i;
+	struct qt2_serial_private *serial_priv;
 
-	kfree(usb_get_serial_data(serial));
+	serial_priv = usb_get_serial_data(serial);
 
-	for (i = 0; i < serial->num_ports; i++)
-		kfree(usb_get_serial_port_data(serial->port[i]));
+	usb_free_urb(serial_priv->read_urb);
+	kfree(serial_priv);
 }
 
 static inline int calc_baud_divisor(int baudrate)
@@ -423,11 +423,16 @@
 	port_priv->is_open = false;
 
 	spin_lock_irqsave(&port_priv->urb_lock, flags);
-	if (port_priv->write_urb->status == -EINPROGRESS)
-		usb_kill_urb(port_priv->write_urb);
+	usb_kill_urb(port_priv->write_urb);
 	port_priv->urb_in_use = false;
 	spin_unlock_irqrestore(&port_priv->urb_lock, flags);
 
+	mutex_lock(&port->serial->disc_mutex);
+	if (port->serial->disconnected) {
+		mutex_unlock(&port->serial->disc_mutex);
+		return;
+	}
+
 	/* flush the port transmit buffer */
 	i = usb_control_msg(serial->dev,
 			    usb_rcvctrlpipe(serial->dev, 0),
@@ -459,26 +464,14 @@
 		dev_err(&port->dev, "%s - close port failed %i\n",
 			__func__, i);
 
+	mutex_unlock(&port->serial->disc_mutex);
 }
 
 static void qt2_disconnect(struct usb_serial *serial)
 {
 	struct qt2_serial_private *serial_priv = usb_get_serial_data(serial);
-	struct qt2_port_private *port_priv;
-	int i;
 
-	if (serial_priv->read_urb->status == -EINPROGRESS)
-		usb_kill_urb(serial_priv->read_urb);
-
-	usb_free_urb(serial_priv->read_urb);
-
-	for (i = 0; i < serial->num_ports; i++) {
-		port_priv = usb_get_serial_port_data(serial->port[i]);
-
-		if (port_priv->write_urb->status == -EINPROGRESS)
-			usb_kill_urb(port_priv->write_urb);
-		usb_free_urb(port_priv->write_urb);
-	}
+	usb_kill_urb(serial_priv->read_urb);
 }
 
 static int get_serial_info(struct usb_serial_port *port,
@@ -773,11 +766,9 @@
 
 static int qt2_setup_urbs(struct usb_serial *serial)
 {
-	struct usb_serial_port *port;
 	struct usb_serial_port *port0;
 	struct qt2_serial_private *serial_priv;
-	struct qt2_port_private *port_priv;
-	int pcount, status;
+	int status;
 
 	port0 = serial->port[0];
 
@@ -795,46 +786,21 @@
 			  sizeof(serial_priv->read_buffer),
 			  qt2_read_bulk_callback, serial);
 
-	/* setup write_urb for each port */
-	for (pcount = 0; pcount < serial->num_ports; pcount++) {
-
-		port = serial->port[pcount];
-		port_priv = usb_get_serial_port_data(port);
-
-		port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!port_priv->write_urb) {
-			dev_err(&serial->dev->dev,
-				"failed to alloc write_urb for port %i\n",
-				pcount);
-			return -ENOMEM;
-		}
-
-		usb_fill_bulk_urb(port_priv->write_urb,
-				  serial->dev,
-				  usb_sndbulkpipe(serial->dev,
-						  port0->
-						  bulk_out_endpointAddress),
-				  port_priv->write_buffer,
-				  sizeof(port_priv->write_buffer),
-				  qt2_write_bulk_callback, port);
-	}
-
 	status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL);
 	if (status != 0) {
 		dev_err(&serial->dev->dev,
 			"%s - submit read urb failed %i\n", __func__, status);
+		usb_free_urb(serial_priv->read_urb);
 		return status;
 	}
 
 	return 0;
-
 }
 
 static int qt2_attach(struct usb_serial *serial)
 {
 	struct qt2_serial_private *serial_priv;
-	struct qt2_port_private *port_priv;
-	int status, pcount;
+	int status;
 
 	/* power on unit */
 	status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
@@ -854,26 +820,6 @@
 
 	usb_set_serial_data(serial, serial_priv);
 
-	for (pcount = 0; pcount < serial->num_ports; pcount++) {
-		port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
-		if (!port_priv) {
-			dev_err(&serial->dev->dev,
-				"%s- kmalloc(%Zd) failed.\n", __func__,
-				sizeof(*port_priv));
-			pcount--;
-			status = -ENOMEM;
-			goto attach_failed;
-		}
-
-		spin_lock_init(&port_priv->lock);
-		spin_lock_init(&port_priv->urb_lock);
-		init_waitqueue_head(&port_priv->delta_msr_wait);
-
-		port_priv->port = serial->port[pcount];
-
-		usb_set_serial_port_data(serial->port[pcount], port_priv);
-	}
-
 	status = qt2_setup_urbs(serial);
 	if (status != 0)
 		goto attach_failed;
@@ -881,14 +827,53 @@
 	return 0;
 
 attach_failed:
-	for (/* empty */; pcount >= 0; pcount--) {
-		port_priv = usb_get_serial_port_data(serial->port[pcount]);
-		kfree(port_priv);
-	}
 	kfree(serial_priv);
 	return status;
 }
 
+static int qt2_port_probe(struct usb_serial_port *port)
+{
+	struct usb_serial *serial = port->serial;
+	struct qt2_port_private *port_priv;
+	u8 bEndpointAddress;
+
+	port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
+	if (!port_priv)
+		return -ENOMEM;
+
+	spin_lock_init(&port_priv->lock);
+	spin_lock_init(&port_priv->urb_lock);
+	init_waitqueue_head(&port_priv->delta_msr_wait);
+	port_priv->port = port;
+
+	port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!port_priv->write_urb) {
+		kfree(port_priv);
+		return -ENOMEM;
+	}
+	bEndpointAddress = serial->port[0]->bulk_out_endpointAddress;
+	usb_fill_bulk_urb(port_priv->write_urb, serial->dev,
+				usb_sndbulkpipe(serial->dev, bEndpointAddress),
+				port_priv->write_buffer,
+				sizeof(port_priv->write_buffer),
+				qt2_write_bulk_callback, port);
+
+	usb_set_serial_port_data(port, port_priv);
+
+	return 0;
+}
+
+static int qt2_port_remove(struct usb_serial_port *port)
+{
+	struct qt2_port_private *port_priv;
+
+	port_priv = usb_get_serial_port_data(port);
+	usb_free_urb(port_priv->write_urb);
+	kfree(port_priv);
+
+	return 0;
+}
+
 static int qt2_tiocmget(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
@@ -1127,6 +1112,8 @@
 	.attach              = qt2_attach,
 	.release             = qt2_release,
 	.disconnect          = qt2_disconnect,
+	.port_probe          = qt2_port_probe,
+	.port_remove         = qt2_port_remove,
 	.dtr_rts             = qt2_dtr_rts,
 	.break_ctl           = qt2_break_ctl,
 	.tiocmget            = qt2_tiocmget,
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 01d882c..270860f 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -161,7 +161,6 @@
 {
 	int result = 0;
 	struct usb_device *udev;
-	struct sierra_intf_private *data;
 	u8 ifnum;
 
 	udev = serial->dev;
@@ -188,11 +187,6 @@
 		return -ENODEV;
 	}
 
-	data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-	spin_lock_init(&data->susp_lock);
-
 	return result;
 }
 
@@ -884,11 +878,15 @@
 
 static int sierra_startup(struct usb_serial *serial)
 {
-	struct usb_serial_port *port;
-	struct sierra_port_private *portdata;
-	struct sierra_iface_info *himemoryp = NULL;
-	int i;
-	u8 ifnum;
+	struct sierra_intf_private *intfdata;
+
+	intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL);
+	if (!intfdata)
+		return -ENOMEM;
+
+	spin_lock_init(&intfdata->susp_lock);
+
+	usb_set_serial_data(serial, intfdata);
 
 	/* Set Device mode to D0 */
 	sierra_set_power_state(serial->dev, 0x0000);
@@ -897,68 +895,71 @@
 	if (nmea)
 		sierra_vsc_set_nmea(serial->dev, 1);
 
-	/* Now setup per port private data */
-	for (i = 0; i < serial->num_ports; i++) {
-		port = serial->port[i];
-		portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
-		if (!portdata) {
-			dev_dbg(&port->dev, "%s: kmalloc for "
-				"sierra_port_private (%d) failed!\n",
-				__func__, i);
-			return -ENOMEM;
-		}
-		spin_lock_init(&portdata->lock);
-		init_usb_anchor(&portdata->active);
-		init_usb_anchor(&portdata->delayed);
-		ifnum = i;
-		/* Assume low memory requirements */
-		portdata->num_out_urbs = N_OUT_URB;
-		portdata->num_in_urbs  = N_IN_URB;
-
-		/* Determine actual memory requirements */
-		if (serial->num_ports == 1) {
-			/* Get interface number for composite device */
-			ifnum = sierra_calc_interface(serial);
-			himemoryp =
-			    (struct sierra_iface_info *)&typeB_interface_list;
-			if (is_himemory(ifnum, himemoryp)) {
-				portdata->num_out_urbs = N_OUT_URB_HM;
-				portdata->num_in_urbs  = N_IN_URB_HM;
-			}
-		}
-		else {
-			himemoryp =
-			    (struct sierra_iface_info *)&typeA_interface_list;
-			if (is_himemory(i, himemoryp)) {
-				portdata->num_out_urbs = N_OUT_URB_HM;
-				portdata->num_in_urbs  = N_IN_URB_HM;
-			}
-		}
-		dev_dbg(&serial->dev->dev,
-			"Memory usage (urbs) interface #%d, in=%d, out=%d\n",
-			ifnum,portdata->num_in_urbs, portdata->num_out_urbs );
-		/* Set the port private data pointer */
-		usb_set_serial_port_data(port, portdata);
-	}
-
 	return 0;
 }
 
 static void sierra_release(struct usb_serial *serial)
 {
-	int i;
-	struct usb_serial_port *port;
+	struct sierra_intf_private *intfdata;
+
+	intfdata = usb_get_serial_data(serial);
+	kfree(intfdata);
+}
+
+static int sierra_port_probe(struct usb_serial_port *port)
+{
+	struct usb_serial *serial = port->serial;
+	struct sierra_port_private *portdata;
+	const struct sierra_iface_info *himemoryp;
+	u8 ifnum;
+
+	portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
+	if (!portdata)
+		return -ENOMEM;
+
+	spin_lock_init(&portdata->lock);
+	init_usb_anchor(&portdata->active);
+	init_usb_anchor(&portdata->delayed);
+
+	/* Assume low memory requirements */
+	portdata->num_out_urbs = N_OUT_URB;
+	portdata->num_in_urbs  = N_IN_URB;
+
+	/* Determine actual memory requirements */
+	if (serial->num_ports == 1) {
+		/* Get interface number for composite device */
+		ifnum = sierra_calc_interface(serial);
+		himemoryp = &typeB_interface_list;
+	} else {
+		/* This is really the usb-serial port number of the interface
+		 * rather than the interface number.
+		 */
+		ifnum = port->number - serial->minor;
+		himemoryp = &typeA_interface_list;
+	}
+
+	if (is_himemory(ifnum, himemoryp)) {
+		portdata->num_out_urbs = N_OUT_URB_HM;
+		portdata->num_in_urbs  = N_IN_URB_HM;
+	}
+
+	dev_dbg(&port->dev,
+			"Memory usage (urbs) interface #%d, in=%d, out=%d\n",
+			ifnum, portdata->num_in_urbs, portdata->num_out_urbs);
+
+	usb_set_serial_port_data(port, portdata);
+
+	return 0;
+}
+
+static int sierra_port_remove(struct usb_serial_port *port)
+{
 	struct sierra_port_private *portdata;
 
-	for (i = 0; i < serial->num_ports; ++i) {
-		port = serial->port[i];
-		if (!port)
-			continue;
-		portdata = usb_get_serial_port_data(port);
-		if (!portdata)
-			continue;
-		kfree(portdata);
-	}
+	portdata = usb_get_serial_port_data(port);
+	kfree(portdata);
+
+	return 0;
 }
 
 #ifdef CONFIG_PM
@@ -1062,6 +1063,8 @@
 	.tiocmset          = sierra_tiocmset,
 	.attach            = sierra_startup,
 	.release           = sierra_release,
+	.port_probe        = sierra_port_probe,
+	.port_remove       = sierra_port_remove,
 	.suspend	   = sierra_suspend,
 	.resume		   = sierra_resume,
 	.read_int_callback = sierra_instat_callback,
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h
index 1f034d2..684739b 100644
--- a/drivers/usb/serial/usb-wwan.h
+++ b/drivers/usb/serial/usb-wwan.h
@@ -8,7 +8,7 @@
 extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on);
 extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port);
 extern void usb_wwan_close(struct usb_serial_port *port);
-extern int usb_wwan_startup(struct usb_serial *serial);
+extern int usb_wwan_port_probe(struct usb_serial_port *port);
 extern int usb_wwan_port_remove(struct usb_serial_port *port);
 extern int usb_wwan_write_room(struct tty_struct *tty);
 extern void usb_wwan_set_termios(struct tty_struct *tty,
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index e42aa39..a3e9c09 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -447,15 +447,14 @@
 EXPORT_SYMBOL(usb_wwan_close);
 
 /* Helper functions used by usb_wwan_setup_urbs */
-static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint,
+static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
+				      int endpoint,
 				      int dir, void *ctx, char *buf, int len,
 				      void (*callback) (struct urb *))
 {
+	struct usb_serial *serial = port->serial;
 	struct urb *urb;
 
-	if (endpoint == -1)
-		return NULL;	/* endpoint not needed */
-
 	urb = usb_alloc_urb(0, GFP_KERNEL);	/* No ISO */
 	if (urb == NULL) {
 		dev_dbg(&serial->interface->dev,
@@ -472,101 +471,78 @@
 	return urb;
 }
 
-/* Setup urbs */
-static void usb_wwan_setup_urbs(struct usb_serial *serial)
+int usb_wwan_port_probe(struct usb_serial_port *port)
 {
-	int i, j;
-	struct usb_serial_port *port;
 	struct usb_wwan_port_private *portdata;
-
-	for (i = 0; i < serial->num_ports; i++) {
-		port = serial->port[i];
-		portdata = usb_get_serial_port_data(port);
-
-		/* Do indat endpoints first */
-		for (j = 0; j < N_IN_URB; ++j) {
-			portdata->in_urbs[j] = usb_wwan_setup_urb(serial,
-								  port->
-								  bulk_in_endpointAddress,
-								  USB_DIR_IN,
-								  port,
-								  portdata->
-								  in_buffer[j],
-								  IN_BUFLEN,
-								  usb_wwan_indat_callback);
-		}
-
-		/* outdat endpoints */
-		for (j = 0; j < N_OUT_URB; ++j) {
-			portdata->out_urbs[j] = usb_wwan_setup_urb(serial,
-								   port->
-								   bulk_out_endpointAddress,
-								   USB_DIR_OUT,
-								   port,
-								   portdata->
-								   out_buffer
-								   [j],
-								   OUT_BUFLEN,
-								   usb_wwan_outdat_callback);
-		}
-	}
-}
-
-int usb_wwan_startup(struct usb_serial *serial)
-{
-	int i, j, err;
-	struct usb_serial_port *port;
-	struct usb_wwan_port_private *portdata;
+	struct urb *urb;
 	u8 *buffer;
+	int err;
+	int i;
 
-	/* Now setup per port private data */
-	for (i = 0; i < serial->num_ports; i++) {
-		port = serial->port[i];
-		portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
-		if (!portdata) {
-			dev_dbg(&port->dev, "%s: kmalloc for usb_wwan_port_private (%d) failed!.\n",
-				__func__, i);
-			return 1;
-		}
-		init_usb_anchor(&portdata->delayed);
+	portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
+	if (!portdata)
+		return -ENOMEM;
 
-		for (j = 0; j < N_IN_URB; j++) {
-			buffer = (u8 *) __get_free_page(GFP_KERNEL);
-			if (!buffer)
-				goto bail_out_error;
-			portdata->in_buffer[j] = buffer;
-		}
+	init_usb_anchor(&portdata->delayed);
 
-		for (j = 0; j < N_OUT_URB; j++) {
-			buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
-			if (!buffer)
-				goto bail_out_error2;
-			portdata->out_buffer[j] = buffer;
-		}
+	for (i = 0; i < N_IN_URB; i++) {
+		if (!port->bulk_in_size)
+			break;
 
-		usb_set_serial_port_data(port, portdata);
+		buffer = (u8 *)__get_free_page(GFP_KERNEL);
+		if (!buffer)
+			goto bail_out_error;
+		portdata->in_buffer[i] = buffer;
 
-		if (!port->interrupt_in_urb)
-			continue;
+		urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress,
+						USB_DIR_IN, port,
+						buffer, IN_BUFLEN,
+						usb_wwan_indat_callback);
+		portdata->in_urbs[i] = urb;
+	}
+
+	for (i = 0; i < N_OUT_URB; i++) {
+		if (!port->bulk_out_size)
+			break;
+
+		buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
+		if (!buffer)
+			goto bail_out_error2;
+		portdata->out_buffer[i] = buffer;
+
+		urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress,
+						USB_DIR_OUT, port,
+						buffer, OUT_BUFLEN,
+						usb_wwan_outdat_callback);
+		portdata->out_urbs[i] = urb;
+	}
+
+	usb_set_serial_port_data(port, portdata);
+
+	if (port->interrupt_in_urb) {
 		err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 		if (err)
 			dev_dbg(&port->dev, "%s: submit irq_in urb failed %d\n",
 				__func__, err);
 	}
-	usb_wwan_setup_urbs(serial);
+
 	return 0;
 
 bail_out_error2:
-	for (j = 0; j < N_OUT_URB; j++)
-		kfree(portdata->out_buffer[j]);
+	for (i = 0; i < N_OUT_URB; i++) {
+		usb_free_urb(portdata->out_urbs[i]);
+		kfree(portdata->out_buffer[i]);
+	}
 bail_out_error:
-	for (j = 0; j < N_IN_URB; j++)
-		if (portdata->in_buffer[j])
-			free_page((unsigned long)portdata->in_buffer[j]);
+	for (i = 0; i < N_IN_URB; i++) {
+		usb_free_urb(portdata->in_urbs[i]);
+		free_page((unsigned long)portdata->in_buffer[i]);
+	}
 	kfree(portdata);
-	return 1;
+
+	return -ENOMEM;
 }
-EXPORT_SYMBOL(usb_wwan_startup);
+EXPORT_SYMBOL_GPL(usb_wwan_port_probe);
 
 int usb_wwan_port_remove(struct usb_serial_port *port)
 {
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 346c7ef..b9fca35 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -83,6 +83,8 @@
 /* function prototypes for the Connect Tech WhiteHEAT serial converter */
 static int  whiteheat_attach(struct usb_serial *serial);
 static void whiteheat_release(struct usb_serial *serial);
+static int  whiteheat_port_probe(struct usb_serial_port *port);
+static int  whiteheat_port_remove(struct usb_serial_port *port);
 static int  whiteheat_open(struct tty_struct *tty,
 			struct usb_serial_port *port);
 static void whiteheat_close(struct usb_serial_port *port);
@@ -117,6 +119,8 @@
 	.num_ports =		4,
 	.attach =		whiteheat_attach,
 	.release =		whiteheat_release,
+	.port_probe =		whiteheat_port_probe,
+	.port_remove =		whiteheat_port_remove,
 	.open =			whiteheat_open,
 	.close =		whiteheat_close,
 	.ioctl =		whiteheat_ioctl,
@@ -218,15 +222,12 @@
 {
 	struct usb_serial_port *command_port;
 	struct whiteheat_command_private *command_info;
-	struct usb_serial_port *port;
-	struct whiteheat_private *info;
 	struct whiteheat_hw_info *hw_info;
 	int pipe;
 	int ret;
 	int alen;
 	__u8 *command;
 	__u8 *result;
-	int i;
 
 	command_port = serial->port[COMMAND_PORT];
 
@@ -285,22 +286,6 @@
 		 serial->type->description,
 		 hw_info->sw_major_rev, hw_info->sw_minor_rev);
 
-	for (i = 0; i < serial->num_ports; i++) {
-		port = serial->port[i];
-
-		info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
-		if (info == NULL) {
-			dev_err(&port->dev,
-				"%s: Out of memory for port structures\n",
-				serial->type->description);
-			goto no_private;
-		}
-
-		info->mcr = 0;
-
-		usb_set_serial_port_data(port, info);
-	}
-
 	command_info = kmalloc(sizeof(struct whiteheat_command_private),
 								GFP_KERNEL);
 	if (command_info == NULL) {
@@ -333,16 +318,10 @@
 		"%s: please contact support@connecttech.com\n",
 		serial->type->description);
 	kfree(result);
+	kfree(command);
 	return -ENODEV;
 
 no_command_private:
-	for (i = serial->num_ports - 1; i >= 0; i--) {
-		port = serial->port[i];
-		info = usb_get_serial_port_data(port);
-		kfree(info);
-no_private:
-		;
-	}
 	kfree(result);
 no_result_buffer:
 	kfree(command);
@@ -350,21 +329,36 @@
 	return -ENOMEM;
 }
 
-
 static void whiteheat_release(struct usb_serial *serial)
 {
 	struct usb_serial_port *command_port;
-	struct whiteheat_private *info;
-	int i;
 
 	/* free up our private data for our command port */
 	command_port = serial->port[COMMAND_PORT];
 	kfree(usb_get_serial_port_data(command_port));
+}
 
-	for (i = 0; i < serial->num_ports; i++) {
-		info = usb_get_serial_port_data(serial->port[i]);
-		kfree(info);
-	}
+static int whiteheat_port_probe(struct usb_serial_port *port)
+{
+	struct whiteheat_private *info;
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	usb_set_serial_port_data(port, info);
+
+	return 0;
+}
+
+static int whiteheat_port_remove(struct usb_serial_port *port)
+{
+	struct whiteheat_private *info;
+
+	info = usb_get_serial_port_data(port);
+	kfree(info);
+
+	return 0;
 }
 
 static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 779cd95..d305a5a 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1004,6 +1004,12 @@
 		USB_SC_8070, USB_PR_CB, NULL,
 		US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ),
 
+/* Submitted by Oleksandr Chumachenko <ledest@gmail.com> */
+UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100,
+		"Casio",
+		"EX-N1 DigitalCamera",
+		USB_SC_8070, USB_PR_DEVICE, NULL, 0),
+
 /* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/
 UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001,
 		"Samsung",
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 072cbba..7f93f34 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -379,7 +379,8 @@
 		.hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE
 	};
 	size_t total_len = 0;
-	int err, headcount, mergeable;
+	int err, mergeable;
+	s16 headcount;
 	size_t vhost_hlen, sock_hlen;
 	size_t vhost_len, sock_len;
 	/* TODO: check that we are running from vhost_worker? */
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index c101697..765a945 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -60,7 +60,8 @@
 	  The LTV350QV panel is present on all ATSTK1000 boards.
 
 config LCD_ILI9320
-	tristate
+	tristate "ILI Technology ILI9320 controller support"
+	depends on SPI
 	help
 	  If you have a panel based on the ILI9320 controller chip
 	  then say y to include a power driver for it.
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
index f994c8b..63ecdf8 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/clps711xfb.c
@@ -22,19 +22,15 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
 #include <linux/delay.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <linux/uaccess.h>
 
-#include <mach/syspld.h>
-
 struct fb_info	*cfb;
 
 #define CMAP_MAX_SIZE	16
@@ -162,44 +158,12 @@
 
 static int clps7111fb_blank(int blank, struct fb_info *info)
 {
-    	if (blank) {
-		if (machine_is_edb7211()) {
-			/* Turn off the LCD backlight. */
-			clps_writeb(clps_readb(PDDR) & ~EDB_PD3_LCDBL, PDDR);
+	/* Enable/Disable LCD controller. */
+	if (blank)
+		clps_writel(clps_readl(SYSCON1) & ~SYSCON1_LCDEN, SYSCON1);
+	else
+		clps_writel(clps_readl(SYSCON1) | SYSCON1_LCDEN, SYSCON1);
 
-			/* Power off the LCD DC-DC converter. */
-			clps_writeb(clps_readb(PDDR) & ~EDB_PD1_LCD_DC_DC_EN, PDDR);
-
-			/* Delay for a little while (half a second). */
-			udelay(100);
-
-			/* Power off the LCD panel. */
-			clps_writeb(clps_readb(PDDR) & ~EDB_PD2_LCDEN, PDDR);
-
-			/* Power off the LCD controller. */
-			clps_writel(clps_readl(SYSCON1) & ~SYSCON1_LCDEN, 
-					SYSCON1);
-		}
-	} else {
-		if (machine_is_edb7211()) {
-			/* Power up the LCD controller. */
-			clps_writel(clps_readl(SYSCON1) | SYSCON1_LCDEN,
-					SYSCON1);
-
-			/* Power up the LCD panel. */
-			clps_writeb(clps_readb(PDDR) | EDB_PD2_LCDEN, PDDR);
-
-			/* Delay for a little while. */
-			udelay(100);
-
-			/* Power up the LCD DC-DC converter. */
-			clps_writeb(clps_readb(PDDR) | EDB_PD1_LCD_DC_DC_EN,
-					PDDR);
-
-			/* Turn on the LCD backlight. */
-			clps_writeb(clps_readb(PDDR) | EDB_PD3_LCDBL, PDDR);
-		}
-	}
 	return 0;
 }
 
@@ -214,63 +178,7 @@
 	.fb_imageblit	= cfb_imageblit,
 };
 
-static int backlight_proc_show(struct seq_file *m, void *v)
-{
-	if (machine_is_edb7211()) {
-		seq_printf(m, "%d\n",
-				(clps_readb(PDDR) & EDB_PD3_LCDBL) ? 1 : 0);
-	}
-
-	return 0;
-}
-
-static int backlight_proc_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, backlight_proc_show, NULL);
-}
-
-static ssize_t backlight_proc_write(struct file *file, const char *buffer,
-				    size_t count, loff_t *pos)
-{
-	unsigned char char_value;
-	int value;
-
-	if (count < 1) {
-		return -EINVAL;
-	}
-
-	if (copy_from_user(&char_value, buffer, 1)) 
-		return -EFAULT;
-
-	value = char_value - '0';
-
-	if (machine_is_edb7211()) {
-		unsigned char port_d;
-
-		port_d = clps_readb(PDDR);
-
-		if (value) {
-			port_d |= EDB_PD3_LCDBL;
-		} else {
-			port_d &= ~EDB_PD3_LCDBL;
-		}
-
-		clps_writeb(port_d, PDDR);
-	}
-
-	return count;
-}
-
-static const struct file_operations backlight_proc_fops = {
-	.owner		= THIS_MODULE,
-	.open		= backlight_proc_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-	.write		= backlight_proc_write,
-};
-
-static void __init clps711x_guess_lcd_params(struct fb_info *info)
+static void __devinit clps711x_guess_lcd_params(struct fb_info *info)
 {
 	unsigned int lcdcon, syscon, size;
 	unsigned long phys_base = PAGE_OFFSET;
@@ -358,7 +266,7 @@
 	info->fix.type       = FB_TYPE_PACKED_PIXELS;
 }
 
-int __init clps711xfb_init(void)
+static int __devinit clps711x_fb_probe(struct platform_device *pdev)
 {
 	int err = -ENOMEM;
 
@@ -378,55 +286,29 @@
 
 	fb_alloc_cmap(&cfb->cmap, CMAP_MAX_SIZE, 0);
 
-	if (!proc_create("backlight", 0444, NULL, &backlight_proc_fops)) {
-		printk("Couldn't create the /proc entry for the backlight.\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * Power up the LCD
-	 */
-	if (machine_is_p720t()) {
-		PLD_LCDEN = PLD_LCDEN_EN;
-		PLD_PWR |= (PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON);
-	}
-
-	if (machine_is_edb7211()) {
-		/* Power up the LCD panel. */
-		clps_writeb(clps_readb(PDDR) | EDB_PD2_LCDEN, PDDR);
-
-		/* Delay for a little while. */
-		udelay(100);
-
-		/* Power up the LCD DC-DC converter. */
-		clps_writeb(clps_readb(PDDR) | EDB_PD1_LCD_DC_DC_EN, PDDR);
-
-		/* Turn on the LCD backlight. */
-		clps_writeb(clps_readb(PDDR) | EDB_PD3_LCDBL, PDDR);
-	}
-
 	err = register_framebuffer(cfb);
 
 out:	return err;
 }
 
-static void __exit clps711xfb_exit(void)
+static int __devexit clps711x_fb_remove(struct platform_device *pdev)
 {
 	unregister_framebuffer(cfb);
 	kfree(cfb);
 
-	/*
-	 * Power down the LCD
-	 */
-	if (machine_is_p720t()) {
-		PLD_LCDEN = 0;
-		PLD_PWR &= ~(PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON);
-	}
+	return 0;
 }
 
-module_init(clps711xfb_init);
-module_exit(clps711xfb_exit);
+static struct platform_driver clps711x_fb_driver = {
+	.driver	= {
+		.name	= "video-clps711x",
+		.owner	= THIS_MODULE,
+	},
+	.probe	= clps711x_fb_probe,
+	.remove	= __devexit_p(clps711x_fb_remove),
+};
+module_platform_driver(clps711x_fb_driver);
 
 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION("CLPS711x framebuffer driver");
+MODULE_DESCRIPTION("CLPS711X framebuffer driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index cf2688d..e501dbc 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -33,7 +33,6 @@
 #include <linux/math64.h>
 
 #include <linux/platform_data/video-imxfb.h>
-#include <mach/hardware.h>
 
 /*
  * Complain if VAR is out of range.
@@ -53,8 +52,8 @@
 #define LCDC_SIZE	0x04
 #define SIZE_XMAX(x)	((((x) >> 4) & 0x3f) << 20)
 
-#define YMAX_MASK       (cpu_is_mx1() ? 0x1ff : 0x3ff)
-#define SIZE_YMAX(y)	((y) & YMAX_MASK)
+#define YMAX_MASK_IMX1	0x1ff
+#define YMAX_MASK_IMX21	0x3ff
 
 #define LCDC_VPW	0x08
 #define VPW_VPW(x)	((x) & 0x3ff)
@@ -128,12 +127,18 @@
 	struct fb_bitfield	transp;
 };
 
+enum imxfb_type {
+	IMX1_FB,
+	IMX21_FB,
+};
+
 struct imxfb_info {
 	struct platform_device  *pdev;
 	void __iomem		*regs;
 	struct clk		*clk_ipg;
 	struct clk		*clk_ahb;
 	struct clk		*clk_per;
+	enum imxfb_type		devtype;
 
 	/*
 	 * These are the addresses we mapped
@@ -168,6 +173,24 @@
 	void (*backlight_power)(int);
 };
 
+static struct platform_device_id imxfb_devtype[] = {
+	{
+		.name = "imx1-fb",
+		.driver_data = IMX1_FB,
+	}, {
+		.name = "imx21-fb",
+		.driver_data = IMX21_FB,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, imxfb_devtype);
+
+static inline int is_imx1_fb(struct imxfb_info *fbi)
+{
+	return fbi->devtype == IMX1_FB;
+}
+
 #define IMX_NAME	"IMX"
 
 /*
@@ -366,7 +389,7 @@
 		break;
 	case 16:
 	default:
-		if (cpu_is_mx1())
+		if (is_imx1_fb(fbi))
 			pcr |= PCR_BPIX_12;
 		else
 			pcr |= PCR_BPIX_16;
@@ -596,6 +619,7 @@
 static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
 	struct imxfb_info *fbi = info->par;
+	u32 ymax_mask = is_imx1_fb(fbi) ? YMAX_MASK_IMX1 : YMAX_MASK_IMX21;
 
 	pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
 		var->xres, var->hsync_len,
@@ -617,7 +641,7 @@
 	if (var->right_margin > 255)
 		printk(KERN_ERR "%s: invalid right_margin %d\n",
 			info->fix.id, var->right_margin);
-	if (var->yres < 1 || var->yres > YMAX_MASK)
+	if (var->yres < 1 || var->yres > ymax_mask)
 		printk(KERN_ERR "%s: invalid yres %d\n",
 			info->fix.id, var->yres);
 	if (var->vsync_len > 100)
@@ -645,7 +669,7 @@
 		VCR_V_WAIT_2(var->upper_margin),
 		fbi->regs + LCDC_VCR);
 
-	writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres),
+	writel(SIZE_XMAX(var->xres) | (var->yres & ymax_mask),
 			fbi->regs + LCDC_SIZE);
 
 	writel(fbi->pcr, fbi->regs + LCDC_PCR);
@@ -765,6 +789,7 @@
 		return -ENOMEM;
 
 	fbi = info->par;
+	fbi->devtype = pdev->id_entry->driver_data;
 
 	if (!fb_mode)
 		fb_mode = pdata->mode[0].mode.name;
@@ -939,6 +964,7 @@
 	.driver		= {
 		.name	= DRIVER_NAME,
 	},
+	.id_table	= imxfb_devtype,
 };
 
 static int imxfb_setup(void)
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index ce1d452..7368872 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -26,10 +26,9 @@
 #include <linux/console.h>
 #include <linux/clk.h>
 #include <linux/mutex.h>
+#include <linux/dma/ipu-dma.h>
 
 #include <linux/platform_data/dma-imx.h>
-#include <mach/hardware.h>
-#include <mach/ipu.h>
 #include <linux/platform_data/video-mx3fb.h>
 
 #include <asm/io.h>
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index b7f5173..917bb56 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -641,7 +641,6 @@
 	case XenbusStateReconfiguring:
 	case XenbusStateReconfigured:
 	case XenbusStateUnknown:
-	case XenbusStateClosed:
 		break;
 
 	case XenbusStateInitWait:
@@ -670,6 +669,10 @@
 		info->feature_resize = val;
 		break;
 
+	case XenbusStateClosed:
+		if (dev->state == XenbusStateClosed)
+			break;
+		/* Missed the backend's CLOSING state -- fallthrough */
 	case XenbusStateClosing:
 		xenbus_frontend_closed(dev);
 		break;
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 1e8659c..809b0de 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -225,8 +225,10 @@
 
 void unregister_virtio_device(struct virtio_device *dev)
 {
+	int index = dev->index; /* save for after device release */
+
 	device_unregister(&dev->dev);
-	ida_simple_remove(&virtio_index_ida, dev->index);
+	ida_simple_remove(&virtio_index_ida, index);
 }
 EXPORT_SYMBOL_GPL(unregister_virtio_device);
 
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index bcfab2b..9a45d029 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -33,7 +33,6 @@
 #include <linux/uaccess.h>
 #include <linux/timer.h>
 #include <linux/jiffies.h>
-#include <mach/hardware.h>
 
 #define DRIVER_NAME "imx2-wdt"
 
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index d4dffcd..126d8ce 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -3,6 +3,7 @@
 
 config XEN_BALLOON
 	bool "Xen memory balloon driver"
+	depends on !ARM
 	default y
 	help
 	  The balloon driver allows the Xen domain to request more memory from
@@ -145,6 +146,7 @@
 
 config XEN_TMEM
 	bool
+	depends on !ARM
 	default y if (CLEANCACHE || FRONTSWAP)
 	help
 	  Shim to interface in-kernel Transcendent Memory hooks
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 0e863703..7435470 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -2,6 +2,7 @@
 obj-y	+= manage.o balloon.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= cpu_hotplug.o
 endif
+obj-$(CONFIG_X86)			+= fallback.o
 obj-y	+= grant-table.o features.o events.o
 obj-y	+= xenbus/
 
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 31ab82f..d6886d9 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -55,7 +55,6 @@
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/tlb.h>
-#include <asm/e820.h>
 
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
@@ -88,7 +87,7 @@
 EXPORT_SYMBOL_GPL(balloon_stats);
 
 /* We increase/decrease in batches which fit in a page */
-static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)];
+static xen_pfn_t frame_list[PAGE_SIZE / sizeof(unsigned long)];
 
 #ifdef CONFIG_HIGHMEM
 #define inc_totalhigh_pages() (totalhigh_pages++)
diff --git a/drivers/xen/dbgp.c b/drivers/xen/dbgp.c
index 42569c7..f3ccc80 100644
--- a/drivers/xen/dbgp.c
+++ b/drivers/xen/dbgp.c
@@ -8,7 +8,9 @@
 
 static int xen_dbgp_op(struct usb_hcd *hcd, int op)
 {
+#ifdef CONFIG_PCI
 	const struct device *ctrlr = hcd_to_bus(hcd)->controller;
+#endif
 	struct physdev_dbgp_op dbgp;
 
 	if (!xen_initial_domain())
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 59e10a1..0be4df3 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -115,7 +115,9 @@
 #define PIRQ_SHAREABLE	(1 << 1)
 
 static int *evtchn_to_irq;
+#ifdef CONFIG_X86
 static unsigned long *pirq_eoi_map;
+#endif
 static bool (*pirq_needs_eoi)(unsigned irq);
 
 static DEFINE_PER_CPU(unsigned long [NR_EVENT_CHANNELS/BITS_PER_LONG],
@@ -277,10 +279,12 @@
 	return ret;
 }
 
+#ifdef CONFIG_X86
 static bool pirq_check_eoi_map(unsigned irq)
 {
 	return test_bit(pirq_from_irq(irq), pirq_eoi_map);
 }
+#endif
 
 static bool pirq_needs_eoi_flag(unsigned irq)
 {
@@ -1391,10 +1395,10 @@
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
+	irq_enter();
 #ifdef CONFIG_X86
 	exit_idle();
 #endif
-	irq_enter();
 
 	__xen_evtchn_do_upcall();
 
diff --git a/drivers/xen/fallback.c b/drivers/xen/fallback.c
new file mode 100644
index 0000000..0ef7c4d
--- /dev/null
+++ b/drivers/xen/fallback.c
@@ -0,0 +1,80 @@
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/bug.h>
+#include <linux/export.h>
+#include <asm/hypervisor.h>
+#include <asm/xen/hypercall.h>
+
+int xen_event_channel_op_compat(int cmd, void *arg)
+{
+	struct evtchn_op op;
+	int rc;
+
+	op.cmd = cmd;
+	memcpy(&op.u, arg, sizeof(op.u));
+	rc = _hypercall1(int, event_channel_op_compat, &op);
+
+	switch (cmd) {
+	case EVTCHNOP_close:
+	case EVTCHNOP_send:
+	case EVTCHNOP_bind_vcpu:
+	case EVTCHNOP_unmask:
+		/* no output */
+		break;
+
+#define COPY_BACK(eop) \
+	case EVTCHNOP_##eop: \
+		memcpy(arg, &op.u.eop, sizeof(op.u.eop)); \
+		break
+
+	COPY_BACK(bind_interdomain);
+	COPY_BACK(bind_virq);
+	COPY_BACK(bind_pirq);
+	COPY_BACK(status);
+	COPY_BACK(alloc_unbound);
+	COPY_BACK(bind_ipi);
+#undef COPY_BACK
+
+	default:
+		WARN_ON(rc != -ENOSYS);
+		break;
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(xen_event_channel_op_compat);
+
+int HYPERVISOR_physdev_op_compat(int cmd, void *arg)
+{
+	struct physdev_op op;
+	int rc;
+
+	op.cmd = cmd;
+	memcpy(&op.u, arg, sizeof(op.u));
+	rc = _hypercall1(int, physdev_op_compat, &op);
+
+	switch (cmd) {
+	case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
+	case PHYSDEVOP_set_iopl:
+	case PHYSDEVOP_set_iobitmap:
+	case PHYSDEVOP_apic_write:
+		/* no output */
+		break;
+
+#define COPY_BACK(pop, fld) \
+	case PHYSDEVOP_##pop: \
+		memcpy(arg, &op.u.fld, sizeof(op.u.fld)); \
+		break
+
+	COPY_BACK(irq_status_query, irq_status_query);
+	COPY_BACK(apic_read, apic_op);
+	COPY_BACK(ASSIGN_VECTOR, irq_op);
+#undef COPY_BACK
+
+	default:
+		WARN_ON(rc != -ENOSYS);
+		break;
+	}
+
+	return rc;
+}
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 610bfc6be..2e22df2 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -105,6 +105,21 @@
 #endif
 }
 
+static void gntdev_free_map(struct grant_map *map)
+{
+	if (map == NULL)
+		return;
+
+	if (map->pages)
+		free_xenballooned_pages(map->count, map->pages);
+	kfree(map->pages);
+	kfree(map->grants);
+	kfree(map->map_ops);
+	kfree(map->unmap_ops);
+	kfree(map->kmap_ops);
+	kfree(map);
+}
+
 static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
 {
 	struct grant_map *add;
@@ -142,12 +157,7 @@
 	return add;
 
 err:
-	kfree(add->pages);
-	kfree(add->grants);
-	kfree(add->map_ops);
-	kfree(add->unmap_ops);
-	kfree(add->kmap_ops);
-	kfree(add);
+	gntdev_free_map(add);
 	return NULL;
 }
 
@@ -198,17 +208,9 @@
 		evtchn_put(map->notify.event);
 	}
 
-	if (map->pages) {
-		if (!use_ptemod)
-			unmap_grant_pages(map, 0, map->count);
-
-		free_xenballooned_pages(map->count, map->pages);
-	}
-	kfree(map->pages);
-	kfree(map->grants);
-	kfree(map->map_ops);
-	kfree(map->unmap_ops);
-	kfree(map);
+	if (map->pages && !use_ptemod)
+		unmap_grant_pages(map, 0, map->count);
+	gntdev_free_map(map);
 }
 
 /* ------------------------------------------------------------------ */
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index b2b0a37..b91f14e 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -84,7 +84,7 @@
 	 * nr_gframes is the number of frames to map grant table. Returning
 	 * GNTST_okay means success and negative value means failure.
 	 */
-	int (*map_frames)(unsigned long *frames, unsigned int nr_gframes);
+	int (*map_frames)(xen_pfn_t *frames, unsigned int nr_gframes);
 	/*
 	 * Release a list of frames which are mapped in map_frames for grant
 	 * entry status.
@@ -960,7 +960,7 @@
 	return (nr_grant_frames * GREFS_PER_GRANT_FRAME + SPP - 1) / SPP;
 }
 
-static int gnttab_map_frames_v1(unsigned long *frames, unsigned int nr_gframes)
+static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes)
 {
 	int rc;
 
@@ -977,7 +977,7 @@
 	arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames);
 }
 
-static int gnttab_map_frames_v2(unsigned long *frames, unsigned int nr_gframes)
+static int gnttab_map_frames_v2(xen_pfn_t *frames, unsigned int nr_gframes)
 {
 	uint64_t *sframes;
 	unsigned int nr_sframes;
@@ -1029,7 +1029,7 @@
 static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
 {
 	struct gnttab_setup_table setup;
-	unsigned long *frames;
+	xen_pfn_t *frames;
 	unsigned int nr_gframes = end_idx + 1;
 	int rc;
 
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c
index 5e5ad7e2..96453f8 100644
--- a/drivers/xen/sys-hypervisor.c
+++ b/drivers/xen/sys-hypervisor.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/kobject.h>
+#include <linux/err.h>
 
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
@@ -284,7 +285,8 @@
 		ret = HYPERVISOR_xen_version(XENVER_platform_parameters,
 					     parms);
 		if (!ret)
-			ret = sprintf(buffer, "%lx\n", parms->virt_start);
+			ret = sprintf(buffer, "%"PRI_xen_ulong"\n",
+				      parms->virt_start);
 		kfree(parms);
 	}
 
diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c
index 46d140b..0f478ac 100644
--- a/drivers/xen/xen-pciback/vpci.c
+++ b/drivers/xen/xen-pciback/vpci.c
@@ -89,9 +89,15 @@
 
 	mutex_lock(&vpci_dev->lock);
 
-	/* Keep multi-function devices together on the virtual PCI bus */
-	for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
-		if (!list_empty(&vpci_dev->dev_list[slot])) {
+	/*
+	 * Keep multi-function devices together on the virtual PCI bus, except
+	 * virtual functions.
+	 */
+	if (!dev->is_virtfn) {
+		for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
+			if (list_empty(&vpci_dev->dev_list[slot]))
+				continue;
+
 			t = list_entry(list_first(&vpci_dev->dev_list[slot]),
 				       struct pci_dev_entry, list);
 
@@ -116,7 +122,7 @@
 			       pci_name(dev), slot);
 			list_add_tail(&dev_entry->list,
 				      &vpci_dev->dev_list[slot]);
-			func = PCI_FUNC(dev->devfn);
+			func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn);
 			goto unlock;
 		}
 	}
diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c
index 89f7625..ac72702 100644
--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
+++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
@@ -458,7 +458,7 @@
 		goto out;
 
 	/* Can't write a xenbus message larger we can buffer */
-	if ((len + u->len) > sizeof(u->u.buffer)) {
+	if (len > sizeof(u->u.buffer) - u->len) {
 		/* On error, dump existing buffer */
 		u->len = 0;
 		rc = -EINVAL;
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index f5dda83..acedeab 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -627,6 +627,7 @@
  */
 static bool xen_strict_xenbus_quirk(void)
 {
+#ifdef CONFIG_X86
 	uint32_t eax, ebx, ecx, edx, base;
 
 	base = xen_cpuid_base();
@@ -634,6 +635,7 @@
 
 	if ((eax >> 16) < 4)
 		return true;
+#endif
 	return false;
 
 }
diff --git a/fs/bio.c b/fs/bio.c
index 9298c65..b96fc6c 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -75,6 +75,7 @@
 	unsigned int sz = sizeof(struct bio) + extra_size;
 	struct kmem_cache *slab = NULL;
 	struct bio_slab *bslab, *new_bio_slabs;
+	unsigned int new_bio_slab_max;
 	unsigned int i, entry = -1;
 
 	mutex_lock(&bio_slab_lock);
@@ -97,12 +98,13 @@
 		goto out_unlock;
 
 	if (bio_slab_nr == bio_slab_max && entry == -1) {
-		bio_slab_max <<= 1;
+		new_bio_slab_max = bio_slab_max << 1;
 		new_bio_slabs = krealloc(bio_slabs,
-					 bio_slab_max * sizeof(struct bio_slab),
+					 new_bio_slab_max * sizeof(struct bio_slab),
 					 GFP_KERNEL);
 		if (!new_bio_slabs)
 			goto out_unlock;
+		bio_slab_max = new_bio_slab_max;
 		bio_slabs = new_bio_slabs;
 	}
 	if (entry == -1)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index b3c1d3d..1a1e5e3 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1661,6 +1661,39 @@
 	return ret;
 }
 
+static ssize_t blkdev_splice_read(struct file *file, loff_t *ppos,
+				  struct pipe_inode_info *pipe, size_t len,
+				  unsigned int flags)
+{
+	ssize_t ret;
+	struct block_device *bdev = I_BDEV(file->f_mapping->host);
+
+	percpu_down_read(&bdev->bd_block_size_semaphore);
+
+	ret = generic_file_splice_read(file, ppos, pipe, len, flags);
+
+	percpu_up_read(&bdev->bd_block_size_semaphore);
+
+	return ret;
+}
+
+static ssize_t blkdev_splice_write(struct pipe_inode_info *pipe,
+				   struct file *file, loff_t *ppos, size_t len,
+				   unsigned int flags)
+{
+	ssize_t ret;
+	struct block_device *bdev = I_BDEV(file->f_mapping->host);
+
+	percpu_down_read(&bdev->bd_block_size_semaphore);
+
+	ret = generic_file_splice_write(pipe, file, ppos, len, flags);
+
+	percpu_up_read(&bdev->bd_block_size_semaphore);
+
+	return ret;
+}
+
+
 /*
  * Try to release a page associated with block device when the system
  * is under memory pressure.
@@ -1699,8 +1732,8 @@
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= compat_blkdev_ioctl,
 #endif
-	.splice_read	= generic_file_splice_read,
-	.splice_write	= generic_file_splice_write,
+	.splice_read	= blkdev_splice_read,
+	.splice_write	= blkdev_splice_write,
 };
 
 int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index f318793..208d8aa 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -283,9 +283,7 @@
 		goto out;
 	}
 
-	rcu_read_lock();
-	root_level = btrfs_header_level(root->node);
-	rcu_read_unlock();
+	root_level = btrfs_old_root_level(root, time_seq);
 
 	if (root_level + 1 == level)
 		goto out;
@@ -1177,16 +1175,15 @@
 	return ret;
 }
 
-static char *ref_to_path(struct btrfs_root *fs_root,
-			 struct btrfs_path *path,
-			 u32 name_len, unsigned long name_off,
-			 struct extent_buffer *eb_in, u64 parent,
-			 char *dest, u32 size)
+char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
+			u32 name_len, unsigned long name_off,
+			struct extent_buffer *eb_in, u64 parent,
+			char *dest, u32 size)
 {
 	int slot;
 	u64 next_inum;
 	int ret;
-	s64 bytes_left = size - 1;
+	s64 bytes_left = ((s64)size) - 1;
 	struct extent_buffer *eb = eb_in;
 	struct btrfs_key found_key;
 	int leave_spinning = path->leave_spinning;
@@ -1266,10 +1263,10 @@
 			 struct extent_buffer *eb_in, u64 parent,
 			 char *dest, u32 size)
 {
-	return ref_to_path(fs_root, path,
-			   btrfs_inode_ref_name_len(eb_in, iref),
-			   (unsigned long)(iref + 1),
-			   eb_in, parent, dest, size);
+	return btrfs_ref_to_path(fs_root, path,
+				 btrfs_inode_ref_name_len(eb_in, iref),
+				 (unsigned long)(iref + 1),
+				 eb_in, parent, dest, size);
 }
 
 /*
@@ -1715,9 +1712,8 @@
 					ipath->fspath->bytes_left - s_ptr : 0;
 
 	fspath_min = (char *)ipath->fspath->val + (i + 1) * s_ptr;
-	fspath = ref_to_path(ipath->fs_root, ipath->btrfs_path, name_len,
-			     name_off, eb, inum, fspath_min,
-			     bytes_left);
+	fspath = btrfs_ref_to_path(ipath->fs_root, ipath->btrfs_path, name_len,
+				   name_off, eb, inum, fspath_min, bytes_left);
 	if (IS_ERR(fspath))
 		return PTR_ERR(fspath);
 
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
index e755330..d61feca7 100644
--- a/fs/btrfs/backref.h
+++ b/fs/btrfs/backref.h
@@ -62,6 +62,10 @@
 char *btrfs_iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
 			 struct btrfs_inode_ref *iref, struct extent_buffer *eb,
 			 u64 parent, char *dest, u32 size);
+char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
+			u32 name_len, unsigned long name_off,
+			struct extent_buffer *eb_in, u64 parent,
+			char *dest, u32 size);
 
 struct btrfs_data_container *init_data_container(u32 total_bytes);
 struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index b334362..cdfb4c4 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -596,6 +596,11 @@
 	if (tree_mod_dont_log(fs_info, eb))
 		return 0;
 
+	/*
+	 * When we override something during the move, we log these removals.
+	 * This can only happen when we move towards the beginning of the
+	 * buffer, i.e. dst_slot < src_slot.
+	 */
 	for (i = 0; i + dst_slot < src_slot && i < nr_items; i++) {
 		ret = tree_mod_log_insert_key_locked(fs_info, eb, i + dst_slot,
 					      MOD_LOG_KEY_REMOVE_WHILE_MOVING);
@@ -647,8 +652,6 @@
 	if (tree_mod_dont_log(fs_info, NULL))
 		return 0;
 
-	__tree_mod_log_free_eb(fs_info, old_root);
-
 	ret = tree_mod_alloc(fs_info, flags, &tm);
 	if (ret < 0)
 		goto out;
@@ -926,12 +929,7 @@
 			ret = btrfs_dec_ref(trans, root, buf, 1, 1);
 			BUG_ON(ret); /* -ENOMEM */
 		}
-		/*
-		 * don't log freeing in case we're freeing the root node, this
-		 * is done by tree_mod_log_set_root_pointer later
-		 */
-		if (buf != root->node && btrfs_header_level(buf) != 0)
-			tree_mod_log_free_eb(root->fs_info, buf);
+		tree_mod_log_free_eb(root->fs_info, buf);
 		clean_tree_block(trans, root, buf);
 		*last_ref = 1;
 	}
@@ -1225,6 +1223,8 @@
 	free_extent_buffer(eb);
 
 	__tree_mod_log_rewind(eb_rewin, time_seq, tm);
+	WARN_ON(btrfs_header_nritems(eb_rewin) >
+		BTRFS_NODEPTRS_PER_BLOCK(fs_info->fs_root));
 
 	return eb_rewin;
 }
@@ -1241,9 +1241,11 @@
 {
 	struct tree_mod_elem *tm;
 	struct extent_buffer *eb;
+	struct extent_buffer *old;
 	struct tree_mod_root *old_root = NULL;
 	u64 old_generation = 0;
 	u64 logical;
+	u32 blocksize;
 
 	eb = btrfs_read_lock_root_node(root);
 	tm = __tree_mod_log_oldest_root(root->fs_info, root, time_seq);
@@ -1259,14 +1261,32 @@
 	}
 
 	tm = tree_mod_log_search(root->fs_info, logical, time_seq);
-	if (old_root)
+	if (old_root && tm && tm->op != MOD_LOG_KEY_REMOVE_WHILE_FREEING) {
+		btrfs_tree_read_unlock(root->node);
+		free_extent_buffer(root->node);
+		blocksize = btrfs_level_size(root, old_root->level);
+		old = read_tree_block(root, logical, blocksize, 0);
+		if (!old) {
+			pr_warn("btrfs: failed to read tree block %llu from get_old_root\n",
+				logical);
+			WARN_ON(1);
+		} else {
+			eb = btrfs_clone_extent_buffer(old);
+			free_extent_buffer(old);
+		}
+	} else if (old_root) {
+		btrfs_tree_read_unlock(root->node);
+		free_extent_buffer(root->node);
 		eb = alloc_dummy_extent_buffer(logical, root->nodesize);
-	else
+	} else {
 		eb = btrfs_clone_extent_buffer(root->node);
-	btrfs_tree_read_unlock(root->node);
-	free_extent_buffer(root->node);
+		btrfs_tree_read_unlock(root->node);
+		free_extent_buffer(root->node);
+	}
+
 	if (!eb)
 		return NULL;
+	extent_buffer_get(eb);
 	btrfs_tree_read_lock(eb);
 	if (old_root) {
 		btrfs_set_header_bytenr(eb, eb->start);
@@ -1279,11 +1299,28 @@
 		__tree_mod_log_rewind(eb, time_seq, tm);
 	else
 		WARN_ON(btrfs_header_level(eb) != 0);
-	extent_buffer_get(eb);
+	WARN_ON(btrfs_header_nritems(eb) > BTRFS_NODEPTRS_PER_BLOCK(root));
 
 	return eb;
 }
 
+int btrfs_old_root_level(struct btrfs_root *root, u64 time_seq)
+{
+	struct tree_mod_elem *tm;
+	int level;
+
+	tm = __tree_mod_log_oldest_root(root->fs_info, root, time_seq);
+	if (tm && tm->op == MOD_LOG_ROOT_REPLACE) {
+		level = tm->old_root.level;
+	} else {
+		rcu_read_lock();
+		level = btrfs_header_level(root->node);
+		rcu_read_unlock();
+	}
+
+	return level;
+}
+
 static inline int should_cow_block(struct btrfs_trans_handle *trans,
 				   struct btrfs_root *root,
 				   struct extent_buffer *buf)
@@ -1725,6 +1762,7 @@
 			goto enospc;
 		}
 
+		tree_mod_log_free_eb(root->fs_info, root->node);
 		tree_mod_log_set_root_pointer(root, child);
 		rcu_assign_pointer(root->node, child);
 
@@ -2970,8 +3008,10 @@
 			   push_items * sizeof(struct btrfs_key_ptr));
 
 	if (push_items < src_nritems) {
-		tree_mod_log_eb_move(root->fs_info, src, 0, push_items,
-				     src_nritems - push_items);
+		/*
+		 * don't call tree_mod_log_eb_move here, key removal was already
+		 * fully logged by tree_mod_log_eb_copy above.
+		 */
 		memmove_extent_buffer(src, btrfs_node_key_ptr_offset(0),
 				      btrfs_node_key_ptr_offset(push_items),
 				      (src_nritems - push_items) *
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 926c9ff..c72ead8 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3120,6 +3120,7 @@
 {
 	return atomic_inc_return(&fs_info->tree_mod_seq);
 }
+int btrfs_old_root_level(struct btrfs_root *root, u64 time_seq);
 
 /* root-item.c */
 int btrfs_find_root_ref(struct btrfs_root *tree_root,
@@ -3338,6 +3339,8 @@
 int btrfs_update_inode(struct btrfs_trans_handle *trans,
 			      struct btrfs_root *root,
 			      struct inode *inode);
+int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans,
+				struct btrfs_root *root, struct inode *inode);
 int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode);
 int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode);
 int btrfs_orphan_cleanup(struct btrfs_root *root);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 8036d3a..472873a 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -4110,8 +4110,8 @@
 
 	return eb;
 err:
-	for (i--; i >= 0; i--)
-		__free_page(eb->pages[i]);
+	for (; i > 0; i--)
+		__free_page(eb->pages[i - 1]);
 	__free_extent_buffer(eb);
 	return NULL;
 }
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 85a1e50..95542a1 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -94,8 +94,6 @@
 				   struct page *locked_page,
 				   u64 start, u64 end, int *page_started,
 				   unsigned long *nr_written, int unlock);
-static noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans,
-				struct btrfs_root *root, struct inode *inode);
 
 static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
 				     struct inode *inode,  struct inode *dir,
@@ -2746,8 +2744,9 @@
 	return btrfs_update_inode_item(trans, root, inode);
 }
 
-static noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans,
-				struct btrfs_root *root, struct inode *inode)
+noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans,
+					 struct btrfs_root *root,
+					 struct inode *inode)
 {
 	int ret;
 
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 6116880..8fcf9a5 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -343,7 +343,8 @@
 		return -EOPNOTSUPP;
 	if (copy_from_user(&range, arg, sizeof(range)))
 		return -EFAULT;
-	if (range.start > total_bytes)
+	if (range.start > total_bytes ||
+	    range.len < fs_info->sb->s_blocksize)
 		return -EINVAL;
 
 	range.len = min(range.len, total_bytes - range.start);
@@ -570,7 +571,8 @@
 		ret = btrfs_commit_transaction(trans,
 					       root->fs_info->extent_root);
 	}
-	BUG_ON(ret);
+	if (ret)
+		goto fail;
 
 	ret = pending_snapshot->error;
 	if (ret)
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 5039686..fe9d02c 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -790,8 +790,10 @@
 	}
 
 	path = btrfs_alloc_path();
-	if (!path)
-		return -ENOMEM;
+	if (!path) {
+		ret = -ENOMEM;
+		goto out_free_root;
+	}
 
 	key.objectid = 0;
 	key.type = BTRFS_QGROUP_STATUS_KEY;
@@ -800,7 +802,7 @@
 	ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
 				      sizeof(*ptr));
 	if (ret)
-		goto out;
+		goto out_free_path;
 
 	leaf = path->nodes[0];
 	ptr = btrfs_item_ptr(leaf, path->slots[0],
@@ -818,8 +820,15 @@
 	fs_info->quota_root = quota_root;
 	fs_info->pending_quota_state = 1;
 	spin_unlock(&fs_info->qgroup_lock);
-out:
+out_free_path:
 	btrfs_free_path(path);
+out_free_root:
+	if (ret) {
+		free_extent_buffer(quota_root->node);
+		free_extent_buffer(quota_root->commit_root);
+		kfree(quota_root);
+	}
+out:
 	return ret;
 }
 
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index c7beb54..e78b297 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -745,31 +745,36 @@
 				   void *ctx);
 
 /*
- * Helper function to iterate the entries in ONE btrfs_inode_ref.
+ * Helper function to iterate the entries in ONE btrfs_inode_ref or
+ * btrfs_inode_extref.
  * The iterate callback may return a non zero value to stop iteration. This can
  * be a negative value for error codes or 1 to simply stop it.
  *
- * path must point to the INODE_REF when called.
+ * path must point to the INODE_REF or INODE_EXTREF when called.
  */
 static int iterate_inode_ref(struct send_ctx *sctx,
 			     struct btrfs_root *root, struct btrfs_path *path,
 			     struct btrfs_key *found_key, int resolve,
 			     iterate_inode_ref_t iterate, void *ctx)
 {
-	struct extent_buffer *eb;
+	struct extent_buffer *eb = path->nodes[0];
 	struct btrfs_item *item;
 	struct btrfs_inode_ref *iref;
+	struct btrfs_inode_extref *extref;
 	struct btrfs_path *tmp_path;
 	struct fs_path *p;
-	u32 cur;
-	u32 len;
+	u32 cur = 0;
 	u32 total;
-	int slot;
+	int slot = path->slots[0];
 	u32 name_len;
 	char *start;
 	int ret = 0;
-	int num;
+	int num = 0;
 	int index;
+	u64 dir;
+	unsigned long name_off;
+	unsigned long elem_size;
+	unsigned long ptr;
 
 	p = fs_path_alloc_reversed(sctx);
 	if (!p)
@@ -781,24 +786,40 @@
 		return -ENOMEM;
 	}
 
-	eb = path->nodes[0];
-	slot = path->slots[0];
-	item = btrfs_item_nr(eb, slot);
-	iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
-	cur = 0;
-	len = 0;
-	total = btrfs_item_size(eb, item);
 
-	num = 0;
+	if (found_key->type == BTRFS_INODE_REF_KEY) {
+		ptr = (unsigned long)btrfs_item_ptr(eb, slot,
+						    struct btrfs_inode_ref);
+		item = btrfs_item_nr(eb, slot);
+		total = btrfs_item_size(eb, item);
+		elem_size = sizeof(*iref);
+	} else {
+		ptr = btrfs_item_ptr_offset(eb, slot);
+		total = btrfs_item_size_nr(eb, slot);
+		elem_size = sizeof(*extref);
+	}
+
 	while (cur < total) {
 		fs_path_reset(p);
 
-		name_len = btrfs_inode_ref_name_len(eb, iref);
-		index = btrfs_inode_ref_index(eb, iref);
+		if (found_key->type == BTRFS_INODE_REF_KEY) {
+			iref = (struct btrfs_inode_ref *)(ptr + cur);
+			name_len = btrfs_inode_ref_name_len(eb, iref);
+			name_off = (unsigned long)(iref + 1);
+			index = btrfs_inode_ref_index(eb, iref);
+			dir = found_key->offset;
+		} else {
+			extref = (struct btrfs_inode_extref *)(ptr + cur);
+			name_len = btrfs_inode_extref_name_len(eb, extref);
+			name_off = (unsigned long)&extref->name;
+			index = btrfs_inode_extref_index(eb, extref);
+			dir = btrfs_inode_extref_parent(eb, extref);
+		}
+
 		if (resolve) {
-			start = btrfs_iref_to_path(root, tmp_path, iref, eb,
-						found_key->offset, p->buf,
-						p->buf_len);
+			start = btrfs_ref_to_path(root, tmp_path, name_len,
+						  name_off, eb, dir,
+						  p->buf, p->buf_len);
 			if (IS_ERR(start)) {
 				ret = PTR_ERR(start);
 				goto out;
@@ -809,9 +830,10 @@
 						p->buf_len + p->buf - start);
 				if (ret < 0)
 					goto out;
-				start = btrfs_iref_to_path(root, tmp_path, iref,
-						eb, found_key->offset, p->buf,
-						p->buf_len);
+				start = btrfs_ref_to_path(root, tmp_path,
+							  name_len, name_off,
+							  eb, dir,
+							  p->buf, p->buf_len);
 				if (IS_ERR(start)) {
 					ret = PTR_ERR(start);
 					goto out;
@@ -820,21 +842,16 @@
 			}
 			p->start = start;
 		} else {
-			ret = fs_path_add_from_extent_buffer(p, eb,
-					(unsigned long)(iref + 1), name_len);
+			ret = fs_path_add_from_extent_buffer(p, eb, name_off,
+							     name_len);
 			if (ret < 0)
 				goto out;
 		}
 
-
-		len = sizeof(*iref) + name_len;
-		iref = (struct btrfs_inode_ref *)((char *)iref + len);
-		cur += len;
-
-		ret = iterate(num, found_key->offset, index, p, ctx);
+		cur += elem_size + name_len;
+		ret = iterate(num, dir, index, p, ctx);
 		if (ret)
 			goto out;
-
 		num++;
 	}
 
@@ -998,7 +1015,8 @@
 	}
 	btrfs_item_key_to_cpu(p->nodes[0], &found_key, p->slots[0]);
 	if (found_key.objectid != ino ||
-		found_key.type != BTRFS_INODE_REF_KEY) {
+	    (found_key.type != BTRFS_INODE_REF_KEY &&
+	     found_key.type != BTRFS_INODE_EXTREF_KEY)) {
 		ret = -ENOENT;
 		goto out;
 	}
@@ -1551,8 +1569,8 @@
 	struct btrfs_key key;
 	struct btrfs_key found_key;
 	struct btrfs_path *path;
-	struct btrfs_inode_ref *iref;
 	int len;
+	u64 parent_dir;
 
 	path = alloc_path_for_send();
 	if (!path)
@@ -1568,27 +1586,41 @@
 	if (!ret)
 		btrfs_item_key_to_cpu(path->nodes[0], &found_key,
 				path->slots[0]);
-	if (ret || found_key.objectid != key.objectid ||
-	    found_key.type != key.type) {
+	if (ret || found_key.objectid != ino ||
+	    (found_key.type != BTRFS_INODE_REF_KEY &&
+	     found_key.type != BTRFS_INODE_EXTREF_KEY)) {
 		ret = -ENOENT;
 		goto out;
 	}
 
-	iref = btrfs_item_ptr(path->nodes[0], path->slots[0],
-			struct btrfs_inode_ref);
-	len = btrfs_inode_ref_name_len(path->nodes[0], iref);
-	ret = fs_path_add_from_extent_buffer(name, path->nodes[0],
-			(unsigned long)(iref + 1), len);
+	if (key.type == BTRFS_INODE_REF_KEY) {
+		struct btrfs_inode_ref *iref;
+		iref = btrfs_item_ptr(path->nodes[0], path->slots[0],
+				      struct btrfs_inode_ref);
+		len = btrfs_inode_ref_name_len(path->nodes[0], iref);
+		ret = fs_path_add_from_extent_buffer(name, path->nodes[0],
+						     (unsigned long)(iref + 1),
+						     len);
+		parent_dir = found_key.offset;
+	} else {
+		struct btrfs_inode_extref *extref;
+		extref = btrfs_item_ptr(path->nodes[0], path->slots[0],
+					struct btrfs_inode_extref);
+		len = btrfs_inode_extref_name_len(path->nodes[0], extref);
+		ret = fs_path_add_from_extent_buffer(name, path->nodes[0],
+					(unsigned long)&extref->name, len);
+		parent_dir = btrfs_inode_extref_parent(path->nodes[0], extref);
+	}
 	if (ret < 0)
 		goto out;
 	btrfs_release_path(path);
 
-	ret = get_inode_info(root, found_key.offset, NULL, dir_gen, NULL, NULL,
+	ret = get_inode_info(root, parent_dir, NULL, dir_gen, NULL, NULL,
 			NULL, NULL);
 	if (ret < 0)
 		goto out;
 
-	*dir = found_key.offset;
+	*dir = parent_dir;
 
 out:
 	btrfs_free_path(path);
@@ -2430,7 +2462,8 @@
 		TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, p);
 	} else if (S_ISCHR(mode) || S_ISBLK(mode) ||
 		   S_ISFIFO(mode) || S_ISSOCK(mode)) {
-		TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, rdev);
+		TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, new_encode_dev(rdev));
+		TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode);
 	}
 
 	ret = send_cmd(sctx);
@@ -3226,7 +3259,8 @@
 		btrfs_item_key_to_cpu(eb, &found_key, slot);
 
 		if (found_key.objectid != key.objectid ||
-		    found_key.type != key.type)
+		    (found_key.type != BTRFS_INODE_REF_KEY &&
+		     found_key.type != BTRFS_INODE_EXTREF_KEY))
 			break;
 
 		ret = iterate_inode_ref(sctx, root, path, &found_key, 0, cb,
@@ -3987,7 +4021,7 @@
 	if (sctx->cur_ino == 0)
 		goto out;
 	if (!at_end && sctx->cur_ino == sctx->cmp_key->objectid &&
-	    sctx->cmp_key->type <= BTRFS_INODE_REF_KEY)
+	    sctx->cmp_key->type <= BTRFS_INODE_EXTREF_KEY)
 		goto out;
 	if (list_empty(&sctx->new_refs) && list_empty(&sctx->deleted_refs))
 		goto out;
@@ -4033,22 +4067,21 @@
 	if (ret < 0)
 		goto out;
 
-	if (!S_ISLNK(sctx->cur_inode_mode)) {
-		if (!sctx->parent_root || sctx->cur_inode_new) {
+	if (!sctx->parent_root || sctx->cur_inode_new) {
+		need_chown = 1;
+		if (!S_ISLNK(sctx->cur_inode_mode))
 			need_chmod = 1;
-			need_chown = 1;
-		} else {
-			ret = get_inode_info(sctx->parent_root, sctx->cur_ino,
-					NULL, NULL, &right_mode, &right_uid,
-					&right_gid, NULL);
-			if (ret < 0)
-				goto out;
+	} else {
+		ret = get_inode_info(sctx->parent_root, sctx->cur_ino,
+				NULL, NULL, &right_mode, &right_uid,
+				&right_gid, NULL);
+		if (ret < 0)
+			goto out;
 
-			if (left_uid != right_uid || left_gid != right_gid)
-				need_chown = 1;
-			if (left_mode != right_mode)
-				need_chmod = 1;
-		}
+		if (left_uid != right_uid || left_gid != right_gid)
+			need_chown = 1;
+		if (!S_ISLNK(sctx->cur_inode_mode) && left_mode != right_mode)
+			need_chmod = 1;
 	}
 
 	if (S_ISREG(sctx->cur_inode_mode)) {
@@ -4335,7 +4368,8 @@
 
 	if (key->type == BTRFS_INODE_ITEM_KEY)
 		ret = changed_inode(sctx, result);
-	else if (key->type == BTRFS_INODE_REF_KEY)
+	else if (key->type == BTRFS_INODE_REF_KEY ||
+		 key->type == BTRFS_INODE_EXTREF_KEY)
 		ret = changed_ref(sctx, result);
 	else if (key->type == BTRFS_XATTR_ITEM_KEY)
 		ret = changed_xattr(sctx, result);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 77db875..04bbfb1 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1200,7 +1200,7 @@
 	btrfs_i_size_write(parent_inode, parent_inode->i_size +
 					 dentry->d_name.len * 2);
 	parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME;
-	ret = btrfs_update_inode(trans, parent_root, parent_inode);
+	ret = btrfs_update_inode_fallback(trans, parent_root, parent_inode);
 	if (ret)
 		btrfs_abort_transaction(trans, root, ret);
 fail:
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 029b903..0f5ebb7 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1819,6 +1819,13 @@
 				    "Failed to relocate sys chunks after "
 				    "device initialization. This can be fixed "
 				    "using the \"btrfs balance\" command.");
+		trans = btrfs_attach_transaction(root);
+		if (IS_ERR(trans)) {
+			if (PTR_ERR(trans) == -ENOENT)
+				return 0;
+			return PTR_ERR(trans);
+		}
+		ret = btrfs_commit_transaction(trans, root);
 	}
 
 	return ret;
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index 02ce909..9349bb3 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -90,6 +90,8 @@
 		*max_len = handle_length;
 		type = 255;
 	}
+	if (dentry)
+		dput(dentry);
 	return type;
 }
 
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 3f152b9..afc2bb6 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -471,9 +471,19 @@
  */
 int cdev_add(struct cdev *p, dev_t dev, unsigned count)
 {
+	int error;
+
 	p->dev = dev;
 	p->count = count;
-	return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
+
+	error = kobj_map(cdev_map, dev, count, NULL,
+			 exact_match, exact_lock, p);
+	if (error)
+		return error;
+
+	kobject_get(p->kobj.parent);
+
+	return 0;
 }
 
 static void cdev_unmap(dev_t dev, unsigned count)
@@ -498,14 +508,20 @@
 static void cdev_default_release(struct kobject *kobj)
 {
 	struct cdev *p = container_of(kobj, struct cdev, kobj);
+	struct kobject *parent = kobj->parent;
+
 	cdev_purge(p);
+	kobject_put(parent);
 }
 
 static void cdev_dynamic_release(struct kobject *kobj)
 {
 	struct cdev *p = container_of(kobj, struct cdev, kobj);
+	struct kobject *parent = kobj->parent;
+
 	cdev_purge(p);
 	kfree(p);
+	kobject_put(parent);
 }
 
 static struct kobj_type ktype_cdev_default = {
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index fc783e2..0fb15bb 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -225,6 +225,13 @@
 }
 
 static void
+cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
+{
+	memcpy(dst, src, sizeof(*dst));
+	dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS);
+}
+
+static void
 id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
 		struct cifs_sid_id **psidid, char *typestr)
 {
@@ -248,7 +255,7 @@
 		}
 	}
 
-	memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid));
+	cifs_copy_sid(&(*psidid)->sid, sidptr);
 	(*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
 	(*psidid)->refcount = 0;
 
@@ -354,7 +361,7 @@
 	 * any fields of the node after a reference is put .
 	 */
 	if (test_bit(SID_ID_MAPPED, &psidid->state)) {
-		memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
+		cifs_copy_sid(ssid, &psidid->sid);
 		psidid->time = jiffies; /* update ts for accessing */
 		goto id_sid_out;
 	}
@@ -370,14 +377,14 @@
 		if (IS_ERR(sidkey)) {
 			rc = -EINVAL;
 			cFYI(1, "%s: Can't map and id to a SID", __func__);
+		} else if (sidkey->datalen < sizeof(struct cifs_sid)) {
+			rc = -EIO;
+			cFYI(1, "%s: Downcall contained malformed key "
+				"(datalen=%hu)", __func__, sidkey->datalen);
 		} else {
 			lsid = (struct cifs_sid *)sidkey->payload.data;
-			memcpy(&psidid->sid, lsid,
-				sidkey->datalen < sizeof(struct cifs_sid) ?
-				sidkey->datalen : sizeof(struct cifs_sid));
-			memcpy(ssid, &psidid->sid,
-				sidkey->datalen < sizeof(struct cifs_sid) ?
-				sidkey->datalen : sizeof(struct cifs_sid));
+			cifs_copy_sid(&psidid->sid, lsid);
+			cifs_copy_sid(ssid, &psidid->sid);
 			set_bit(SID_ID_MAPPED, &psidid->state);
 			key_put(sidkey);
 			kfree(psidid->sidstr);
@@ -396,7 +403,7 @@
 			return rc;
 		}
 		if (test_bit(SID_ID_MAPPED, &psidid->state))
-			memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
+			cifs_copy_sid(ssid, &psidid->sid);
 		else
 			rc = -EINVAL;
 	}
@@ -675,8 +682,6 @@
 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
 				struct cifs_ntsd *pnntsd, __u32 sidsoffset)
 {
-	int i;
-
 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
 	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
 
@@ -692,26 +697,14 @@
 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 				le32_to_cpu(pntsd->osidoffset));
 	nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
-
-	nowner_sid_ptr->revision = owner_sid_ptr->revision;
-	nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
-	for (i = 0; i < 6; i++)
-		nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
-	for (i = 0; i < 5; i++)
-		nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
+	cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
 
 	/* copy group sid */
 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
 				le32_to_cpu(pntsd->gsidoffset));
 	ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
 					sizeof(struct cifs_sid));
-
-	ngroup_sid_ptr->revision = group_sid_ptr->revision;
-	ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
-	for (i = 0; i < 6; i++)
-		ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
-	for (i = 0; i < 5; i++)
-		ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
+	cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
 
 	return;
 }
@@ -1120,8 +1113,7 @@
 				kfree(nowner_sid_ptr);
 				return rc;
 			}
-			memcpy(owner_sid_ptr, nowner_sid_ptr,
-					sizeof(struct cifs_sid));
+			cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
 			kfree(nowner_sid_ptr);
 			*aclflag = CIFS_ACL_OWNER;
 		}
@@ -1139,8 +1131,7 @@
 				kfree(ngroup_sid_ptr);
 				return rc;
 			}
-			memcpy(group_sid_ptr, ngroup_sid_ptr,
-					sizeof(struct cifs_sid));
+			cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
 			kfree(ngroup_sid_ptr);
 			*aclflag = CIFS_ACL_GROUP;
 		}
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 7c0a812..d3671f2 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -398,7 +398,16 @@
 	 * in network traffic in the other paths.
 	 */
 	if (!(oflags & O_CREAT)) {
-		struct dentry *res = cifs_lookup(inode, direntry, 0);
+		struct dentry *res;
+
+		/*
+		 * Check for hashed negative dentry. We have already revalidated
+		 * the dentry and it is fine. No need to perform another lookup.
+		 */
+		if (!d_unhashed(direntry))
+			return -ENOENT;
+
+		res = cifs_lookup(inode, direntry, 0);
 		if (IS_ERR(res))
 			return PTR_ERR(res);
 
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index f505402..4c6285f 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -210,6 +210,8 @@
 
 	err  = get_user(palp, &up->palette);
 	err |= get_user(length, &up->length);
+	if (err)
+		return -EFAULT;
 
 	up_native = compat_alloc_user_space(sizeof(struct video_spu_palette));
 	err  = put_user(compat_ptr(palp), &up_native->palette);
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index da72250..cd96649 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -346,7 +346,7 @@
 /* Tells if the epoll_ctl(2) operation needs an event copy from userspace */
 static inline int ep_op_has_event(int op)
 {
-	return op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD;
+	return op != EPOLL_CTL_DEL;
 }
 
 /* Initialize the poll safe wake up structure */
@@ -676,34 +676,6 @@
 	return 0;
 }
 
-/*
- * Disables a "struct epitem" in the eventpoll set. Returns -EBUSY if the item
- * had no event flags set, indicating that another thread may be currently
- * handling that item's events (in the case that EPOLLONESHOT was being
- * used). Otherwise a zero result indicates that the item has been disabled
- * from receiving events. A disabled item may be re-enabled via
- * EPOLL_CTL_MOD. Must be called with "mtx" held.
- */
-static int ep_disable(struct eventpoll *ep, struct epitem *epi)
-{
-	int result = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&ep->lock, flags);
-	if (epi->event.events & ~EP_PRIVATE_BITS) {
-		if (ep_is_linked(&epi->rdllink))
-			list_del_init(&epi->rdllink);
-		/* Ensure ep_poll_callback will not add epi back onto ready
-		   list: */
-		epi->event.events &= EP_PRIVATE_BITS;
-		}
-	else
-		result = -EBUSY;
-	spin_unlock_irqrestore(&ep->lock, flags);
-
-	return result;
-}
-
 static void ep_free(struct eventpoll *ep)
 {
 	struct rb_node *rbp;
@@ -1048,6 +1020,8 @@
 	rb_insert_color(&epi->rbn, &ep->rbr);
 }
 
+
+
 #define PATH_ARR_SIZE 5
 /*
  * These are the number paths of length 1 to 5, that we are allowing to emanate
@@ -1813,12 +1787,6 @@
 		} else
 			error = -ENOENT;
 		break;
-	case EPOLL_CTL_DISABLE:
-		if (epi)
-			error = ep_disable(ep, epi);
-		else
-			error = -ENOENT;
-		break;
 	}
 	mutex_unlock(&ep->mtx);
 
diff --git a/fs/exec.c b/fs/exec.c
index 8b9011b..0039055 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1083,7 +1083,8 @@
 	bprm->mm = NULL;		/* We're using it now */
 
 	set_fs(USER_DS);
-	current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD);
+	current->flags &=
+		~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | PF_NOFREEZE);
 	flush_thread();
 	current->personality &= ~bprm->per_clear;
 
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 1b50890..cf18217 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -174,8 +174,7 @@
 		ext4_free_inodes_set(sb, gdp, 0);
 		ext4_itable_unused_set(sb, gdp, 0);
 		memset(bh->b_data, 0xff, sb->s_blocksize);
-		ext4_block_bitmap_csum_set(sb, block_group, gdp, bh,
-					   EXT4_BLOCKS_PER_GROUP(sb) / 8);
+		ext4_block_bitmap_csum_set(sb, block_group, gdp, bh);
 		return;
 	}
 	memset(bh->b_data, 0, sb->s_blocksize);
@@ -212,8 +211,7 @@
 	 */
 	ext4_mark_bitmap_end(num_clusters_in_group(sb, block_group),
 			     sb->s_blocksize * 8, bh->b_data);
-	ext4_block_bitmap_csum_set(sb, block_group, gdp, bh,
-				   EXT4_BLOCKS_PER_GROUP(sb) / 8);
+	ext4_block_bitmap_csum_set(sb, block_group, gdp, bh);
 	ext4_group_desc_csum_set(sb, block_group, gdp);
 }
 
@@ -350,7 +348,7 @@
 		return;
 	}
 	if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group,
-			desc, bh, EXT4_BLOCKS_PER_GROUP(sb) / 8))) {
+			desc, bh))) {
 		ext4_unlock_group(sb, block_group);
 		ext4_error(sb, "bg %u: bad block bitmap checksum", block_group);
 		return;
diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c
index 5c2d181..3285aa5 100644
--- a/fs/ext4/bitmap.c
+++ b/fs/ext4/bitmap.c
@@ -58,11 +58,12 @@
 
 int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
 				  struct ext4_group_desc *gdp,
-				  struct buffer_head *bh, int sz)
+				  struct buffer_head *bh)
 {
 	__u32 hi;
 	__u32 provided, calculated;
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
 
 	if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
 					EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
@@ -84,8 +85,9 @@
 
 void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
 				struct ext4_group_desc *gdp,
-				struct buffer_head *bh, int sz)
+				struct buffer_head *bh)
 {
+	int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8;
 	__u32 csum;
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 3ab2539..3c20de1 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1882,10 +1882,10 @@
 				  struct buffer_head *bh, int sz);
 void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group,
 				struct ext4_group_desc *gdp,
-				struct buffer_head *bh, int sz);
+				struct buffer_head *bh);
 int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
 				  struct ext4_group_desc *gdp,
-				  struct buffer_head *bh, int sz);
+				  struct buffer_head *bh);
 
 /* balloc.c */
 extern void ext4_validate_block_bitmap(struct super_block *sb,
@@ -2063,8 +2063,7 @@
 extern int ext4_calculate_overhead(struct super_block *sb);
 extern int ext4_superblock_csum_verify(struct super_block *sb,
 				       struct ext4_super_block *es);
-extern void ext4_superblock_csum_set(struct super_block *sb,
-				     struct ext4_super_block *es);
+extern void ext4_superblock_csum_set(struct super_block *sb);
 extern void *ext4_kvmalloc(size_t size, gfp_t flags);
 extern void *ext4_kvzalloc(size_t size, gfp_t flags);
 extern void ext4_kvfree(void *ptr);
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
index bfa65b4..b4323ba 100644
--- a/fs/ext4/ext4_jbd2.c
+++ b/fs/ext4/ext4_jbd2.c
@@ -143,17 +143,13 @@
 	struct buffer_head *bh = EXT4_SB(sb)->s_sbh;
 	int err = 0;
 
+	ext4_superblock_csum_set(sb);
 	if (ext4_handle_valid(handle)) {
-		ext4_superblock_csum_set(sb,
-				(struct ext4_super_block *)bh->b_data);
 		err = jbd2_journal_dirty_metadata(handle, bh);
 		if (err)
 			ext4_journal_abort_handle(where, line, __func__,
 						  bh, handle, err);
-	} else {
-		ext4_superblock_csum_set(sb,
-				(struct ext4_super_block *)bh->b_data);
+	} else
 		mark_buffer_dirty(bh);
-	}
 	return err;
 }
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 1c94cca..7011ac9 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -52,6 +52,9 @@
 #define EXT4_EXT_MARK_UNINIT1	0x2  /* mark first half uninitialized */
 #define EXT4_EXT_MARK_UNINIT2	0x4  /* mark second half uninitialized */
 
+#define EXT4_EXT_DATA_VALID1	0x8  /* first half contains valid data */
+#define EXT4_EXT_DATA_VALID2	0x10 /* second half contains valid data */
+
 static __le32 ext4_extent_block_csum(struct inode *inode,
 				     struct ext4_extent_header *eh)
 {
@@ -2914,6 +2917,9 @@
 	unsigned int ee_len, depth;
 	int err = 0;
 
+	BUG_ON((split_flag & (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2)) ==
+	       (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2));
+
 	ext_debug("ext4_split_extents_at: inode %lu, logical"
 		"block %llu\n", inode->i_ino, (unsigned long long)split);
 
@@ -2972,7 +2978,14 @@
 
 	err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
 	if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
-		err = ext4_ext_zeroout(inode, &orig_ex);
+		if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) {
+			if (split_flag & EXT4_EXT_DATA_VALID1)
+				err = ext4_ext_zeroout(inode, ex2);
+			else
+				err = ext4_ext_zeroout(inode, ex);
+		} else
+			err = ext4_ext_zeroout(inode, &orig_ex);
+
 		if (err)
 			goto fix_extent_len;
 		/* update the extent length and mark as initialized */
@@ -3025,12 +3038,13 @@
 	uninitialized = ext4_ext_is_uninitialized(ex);
 
 	if (map->m_lblk + map->m_len < ee_block + ee_len) {
-		split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT ?
-			      EXT4_EXT_MAY_ZEROOUT : 0;
+		split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT;
 		flags1 = flags | EXT4_GET_BLOCKS_PRE_IO;
 		if (uninitialized)
 			split_flag1 |= EXT4_EXT_MARK_UNINIT1 |
 				       EXT4_EXT_MARK_UNINIT2;
+		if (split_flag & EXT4_EXT_DATA_VALID2)
+			split_flag1 |= EXT4_EXT_DATA_VALID1;
 		err = ext4_split_extent_at(handle, inode, path,
 				map->m_lblk + map->m_len, split_flag1, flags1);
 		if (err)
@@ -3043,8 +3057,8 @@
 		return PTR_ERR(path);
 
 	if (map->m_lblk >= ee_block) {
-		split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT ?
-			      EXT4_EXT_MAY_ZEROOUT : 0;
+		split_flag1 = split_flag & (EXT4_EXT_MAY_ZEROOUT |
+					    EXT4_EXT_DATA_VALID2);
 		if (uninitialized)
 			split_flag1 |= EXT4_EXT_MARK_UNINIT1;
 		if (split_flag & EXT4_EXT_MARK_UNINIT2)
@@ -3323,26 +3337,47 @@
 
 	split_flag |= ee_block + ee_len <= eof_block ? EXT4_EXT_MAY_ZEROOUT : 0;
 	split_flag |= EXT4_EXT_MARK_UNINIT2;
-
+	if (flags & EXT4_GET_BLOCKS_CONVERT)
+		split_flag |= EXT4_EXT_DATA_VALID2;
 	flags |= EXT4_GET_BLOCKS_PRE_IO;
 	return ext4_split_extent(handle, inode, path, map, split_flag, flags);
 }
 
 static int ext4_convert_unwritten_extents_endio(handle_t *handle,
-					      struct inode *inode,
-					      struct ext4_ext_path *path)
+						struct inode *inode,
+						struct ext4_map_blocks *map,
+						struct ext4_ext_path *path)
 {
 	struct ext4_extent *ex;
+	ext4_lblk_t ee_block;
+	unsigned int ee_len;
 	int depth;
 	int err = 0;
 
 	depth = ext_depth(inode);
 	ex = path[depth].p_ext;
+	ee_block = le32_to_cpu(ex->ee_block);
+	ee_len = ext4_ext_get_actual_len(ex);
 
 	ext_debug("ext4_convert_unwritten_extents_endio: inode %lu, logical"
 		"block %llu, max_blocks %u\n", inode->i_ino,
-		(unsigned long long)le32_to_cpu(ex->ee_block),
-		ext4_ext_get_actual_len(ex));
+		  (unsigned long long)ee_block, ee_len);
+
+	/* If extent is larger than requested then split is required */
+	if (ee_block != map->m_lblk || ee_len > map->m_len) {
+		err = ext4_split_unwritten_extents(handle, inode, map, path,
+						   EXT4_GET_BLOCKS_CONVERT);
+		if (err < 0)
+			goto out;
+		ext4_ext_drop_refs(path);
+		path = ext4_ext_find_extent(inode, map->m_lblk, path);
+		if (IS_ERR(path)) {
+			err = PTR_ERR(path);
+			goto out;
+		}
+		depth = ext_depth(inode);
+		ex = path[depth].p_ext;
+	}
 
 	err = ext4_ext_get_access(handle, inode, path + depth);
 	if (err)
@@ -3652,7 +3687,7 @@
 	}
 	/* IO end_io complete, convert the filled extent to written */
 	if ((flags & EXT4_GET_BLOCKS_CONVERT)) {
-		ret = ext4_convert_unwritten_extents_endio(handle, inode,
+		ret = ext4_convert_unwritten_extents_endio(handle, inode, map,
 							path);
 		if (ret >= 0) {
 			ext4_update_inode_fsync_trans(handle, inode, 1);
@@ -4428,6 +4463,9 @@
 	 */
 	if (len <= EXT_UNINIT_MAX_LEN << blkbits)
 		flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
+
+	/* Prevent race condition between unwritten */
+	ext4_flush_unwritten_io(inode);
 retry:
 	while (ret >= 0 && ret < max_blocks) {
 		map.m_lblk = map.m_lblk + ret;
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index fa36372..3a100e7 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -725,6 +725,10 @@
 				   "inode=%lu", ino + 1);
 			continue;
 		}
+		BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
+		err = ext4_journal_get_write_access(handle, inode_bitmap_bh);
+		if (err)
+			goto fail;
 		ext4_lock_group(sb, group);
 		ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data);
 		ext4_unlock_group(sb, group);
@@ -738,6 +742,11 @@
 	goto out;
 
 got:
+	BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata");
+	err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh);
+	if (err)
+		goto fail;
+
 	/* We may have to initialize the block bitmap if it isn't already */
 	if (ext4_has_group_desc_csum(sb) &&
 	    gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
@@ -762,9 +771,7 @@
 			ext4_free_group_clusters_set(sb, gdp,
 				ext4_free_clusters_after_init(sb, group, gdp));
 			ext4_block_bitmap_csum_set(sb, group, gdp,
-						   block_bitmap_bh,
-						   EXT4_BLOCKS_PER_GROUP(sb) /
-						   8);
+						   block_bitmap_bh);
 			ext4_group_desc_csum_set(sb, group, gdp);
 		}
 		ext4_unlock_group(sb, group);
@@ -773,11 +780,6 @@
 			goto fail;
 	}
 
-	BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
-	err = ext4_journal_get_write_access(handle, inode_bitmap_bh);
-	if (err)
-		goto fail;
-
 	BUFFER_TRACE(group_desc_bh, "get_write_access");
 	err = ext4_journal_get_write_access(handle, group_desc_bh);
 	if (err)
@@ -825,11 +827,6 @@
 	}
 	ext4_unlock_group(sb, group);
 
-	BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata");
-	err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh);
-	if (err)
-		goto fail;
-
 	BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata");
 	err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh);
 	if (err)
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index f8b27bf..526e553 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2805,8 +2805,7 @@
 	}
 	len = ext4_free_group_clusters(sb, gdp) - ac->ac_b_ex.fe_len;
 	ext4_free_group_clusters_set(sb, gdp, len);
-	ext4_block_bitmap_csum_set(sb, ac->ac_b_ex.fe_group, gdp, bitmap_bh,
-				   EXT4_BLOCKS_PER_GROUP(sb) / 8);
+	ext4_block_bitmap_csum_set(sb, ac->ac_b_ex.fe_group, gdp, bitmap_bh);
 	ext4_group_desc_csum_set(sb, ac->ac_b_ex.fe_group, gdp);
 
 	ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
@@ -4666,8 +4665,7 @@
 
 	ret = ext4_free_group_clusters(sb, gdp) + count_clusters;
 	ext4_free_group_clusters_set(sb, gdp, ret);
-	ext4_block_bitmap_csum_set(sb, block_group, gdp, bitmap_bh,
-				   EXT4_BLOCKS_PER_GROUP(sb) / 8);
+	ext4_block_bitmap_csum_set(sb, block_group, gdp, bitmap_bh);
 	ext4_group_desc_csum_set(sb, block_group, gdp);
 	ext4_unlock_group(sb, block_group);
 	percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters);
@@ -4811,8 +4809,7 @@
 	mb_free_blocks(NULL, &e4b, bit, count);
 	blk_free_count = blocks_freed + ext4_free_group_clusters(sb, desc);
 	ext4_free_group_clusters_set(sb, desc, blk_free_count);
-	ext4_block_bitmap_csum_set(sb, block_group, desc, bitmap_bh,
-				   EXT4_BLOCKS_PER_GROUP(sb) / 8);
+	ext4_block_bitmap_csum_set(sb, block_group, desc, bitmap_bh);
 	ext4_group_desc_csum_set(sb, block_group, desc);
 	ext4_unlock_group(sb, block_group);
 	percpu_counter_add(&sbi->s_freeclusters_counter,
@@ -4993,8 +4990,9 @@
 	minlen = EXT4_NUM_B2C(EXT4_SB(sb),
 			      range->minlen >> sb->s_blocksize_bits);
 
-	if (unlikely(minlen > EXT4_CLUSTERS_PER_GROUP(sb)) ||
-	    unlikely(start >= max_blks))
+	if (minlen > EXT4_CLUSTERS_PER_GROUP(sb) ||
+	    start >= max_blks ||
+	    range->len < sb->s_blocksize)
 		return -EINVAL;
 	if (end >= max_blks)
 		end = max_blks - 1;
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 7a75e10..47bf06a 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1212,8 +1212,7 @@
 	bh = ext4_get_bitmap(sb, group_data->block_bitmap);
 	if (!bh)
 		return -EIO;
-	ext4_block_bitmap_csum_set(sb, group, gdp, bh,
-				   EXT4_BLOCKS_PER_GROUP(sb) / 8);
+	ext4_block_bitmap_csum_set(sb, group, gdp, bh);
 	brelse(bh);
 
 	return 0;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 7265a03..80928f7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -143,9 +143,10 @@
 	return es->s_checksum == ext4_superblock_csum(sb, es);
 }
 
-void ext4_superblock_csum_set(struct super_block *sb,
-			      struct ext4_super_block *es)
+void ext4_superblock_csum_set(struct super_block *sb)
 {
+	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+
 	if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
 		EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
 		return;
@@ -1963,7 +1964,7 @@
 		sbi->s_log_groups_per_flex = 0;
 		return 1;
 	}
-	groups_per_flex = 1 << sbi->s_log_groups_per_flex;
+	groups_per_flex = 1U << sbi->s_log_groups_per_flex;
 
 	err = ext4_alloc_flex_bg_array(sb, sbi->s_groups_count);
 	if (err)
@@ -4381,7 +4382,7 @@
 		cpu_to_le32(percpu_counter_sum_positive(
 				&EXT4_SB(sb)->s_freeinodes_counter));
 	BUFFER_TRACE(sbh, "marking dirty");
-	ext4_superblock_csum_set(sb, es);
+	ext4_superblock_csum_set(sb);
 	mark_buffer_dirty(sbh);
 	if (sync) {
 		error = sync_dirty_buffer(sbh);
diff --git a/fs/file.c b/fs/file.c
index d3b5fa8..708d997 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -900,7 +900,7 @@
 		return __close_fd(files, fd);
 
 	if (fd >= rlimit(RLIMIT_NOFILE))
-		return -EMFILE;
+		return -EBADF;
 
 	spin_lock(&files->file_lock);
 	err = expand_files(files, fd);
@@ -926,7 +926,7 @@
 		return -EINVAL;
 
 	if (newfd >= rlimit(RLIMIT_NOFILE))
-		return -EMFILE;
+		return -EBADF;
 
 	spin_lock(&files->file_lock);
 	err = expand_files(files, newfd);
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 0def050..e056b4c 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -516,15 +516,13 @@
 		struct gfs2_holder i_gh;
 		int error;
 
-		gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
-		error = gfs2_glock_nq(&i_gh);
-		if (error == 0) {
-			file_accessed(file);
-			gfs2_glock_dq(&i_gh);
-		}
-		gfs2_holder_uninit(&i_gh);
+		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
+					   &i_gh);
 		if (error)
 			return error;
+		/* grab lock to update inode */
+		gfs2_glock_dq_uninit(&i_gh);
+		file_accessed(file);
 	}
 	vma->vm_ops = &gfs2_vm_ops;
 
@@ -677,10 +675,8 @@
 	size_t writesize = iov_length(iov, nr_segs);
 	struct dentry *dentry = file->f_dentry;
 	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
-	struct gfs2_sbd *sdp;
 	int ret;
 
-	sdp = GFS2_SB(file->f_mapping->host);
 	ret = gfs2_rs_alloc(ip);
 	if (ret)
 		return ret;
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 8ff95a2..9ceccb1 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -393,12 +393,10 @@
 	struct gfs2_meta_header *mh;
 	struct gfs2_trans *tr;
 
-	lock_buffer(bd->bd_bh);
-	gfs2_log_lock(sdp);
 	tr = current->journal_info;
 	tr->tr_touched = 1;
 	if (!list_empty(&bd->bd_list))
-		goto out;
+		return;
 	set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
 	set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
 	mh = (struct gfs2_meta_header *)bd->bd_bh->b_data;
@@ -414,9 +412,6 @@
 	sdp->sd_log_num_buf++;
 	list_add(&bd->bd_list, &sdp->sd_log_le_buf);
 	tr->tr_num_buf_new++;
-out:
-	gfs2_log_unlock(sdp);
-	unlock_buffer(bd->bd_bh);
 }
 
 static void gfs2_check_magic(struct buffer_head *bh)
@@ -621,7 +616,6 @@
 
 static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
 {
-	struct gfs2_log_descriptor *ld;
 	struct gfs2_meta_header *mh;
 	unsigned int offset;
 	struct list_head *head = &sdp->sd_log_le_revoke;
@@ -634,7 +628,6 @@
 
 	length = gfs2_struct2blk(sdp, sdp->sd_log_num_revoke, sizeof(u64));
 	page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE, length, sdp->sd_log_num_revoke);
-	ld = page_address(page);
 	offset = sizeof(struct gfs2_log_descriptor);
 
 	list_for_each_entry(bd, head, bd_list) {
@@ -777,12 +770,10 @@
 	struct address_space *mapping = bd->bd_bh->b_page->mapping;
 	struct gfs2_inode *ip = GFS2_I(mapping->host);
 
-	lock_buffer(bd->bd_bh);
-	gfs2_log_lock(sdp);
 	if (tr)
 		tr->tr_touched = 1;
 	if (!list_empty(&bd->bd_list))
-		goto out;
+		return;
 	set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
 	set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
 	if (gfs2_is_jdata(ip)) {
@@ -793,9 +784,6 @@
 	} else {
 		list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered);
 	}
-out:
-	gfs2_log_unlock(sdp);
-	unlock_buffer(bd->bd_bh);
 }
 
 /**
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 40c4b0d..c5af8e1 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -497,8 +497,11 @@
 	struct gfs2_quota_data **qd;
 	int error;
 
-	if (ip->i_res == NULL)
-		gfs2_rs_alloc(ip);
+	if (ip->i_res == NULL) {
+		error = gfs2_rs_alloc(ip);
+		if (error)
+			return error;
+	}
 
 	qd = ip->i_res->rs_qa_qd;
 
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 3cc402c..38fe18f 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -553,7 +553,6 @@
  */
 int gfs2_rs_alloc(struct gfs2_inode *ip)
 {
-	int error = 0;
 	struct gfs2_blkreserv *res;
 
 	if (ip->i_res)
@@ -561,7 +560,7 @@
 
 	res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS);
 	if (!res)
-		error = -ENOMEM;
+		return -ENOMEM;
 
 	RB_CLEAR_NODE(&res->rs_node);
 
@@ -571,7 +570,7 @@
 	else
 		ip->i_res = res;
 	up_write(&ip->i_rw_mutex);
-	return error;
+	return 0;
 }
 
 static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs)
@@ -1263,7 +1262,9 @@
 	int ret = 0;
 	u64 amt;
 	u64 trimmed = 0;
+	u64 start, end, minlen;
 	unsigned int x;
+	unsigned bs_shift = sdp->sd_sb.sb_bsize_shift;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -1271,19 +1272,25 @@
 	if (!blk_queue_discard(q))
 		return -EOPNOTSUPP;
 
-	if (argp == NULL) {
-		r.start = 0;
-		r.len = ULLONG_MAX;
-		r.minlen = 0;
-	} else if (copy_from_user(&r, argp, sizeof(r)))
+	if (copy_from_user(&r, argp, sizeof(r)))
 		return -EFAULT;
 
 	ret = gfs2_rindex_update(sdp);
 	if (ret)
 		return ret;
 
-	rgd = gfs2_blk2rgrpd(sdp, r.start, 0);
-	rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0);
+	start = r.start >> bs_shift;
+	end = start + (r.len >> bs_shift);
+	minlen = max_t(u64, r.minlen,
+		       q->limits.discard_granularity) >> bs_shift;
+
+	rgd = gfs2_blk2rgrpd(sdp, start, 0);
+	rgd_end = gfs2_blk2rgrpd(sdp, end - 1, 0);
+
+	if (end <= start ||
+	    minlen > sdp->sd_max_rg_data ||
+	    start > rgd_end->rd_data0 + rgd_end->rd_data)
+		return -EINVAL;
 
 	while (1) {
 
@@ -1295,7 +1302,9 @@
 			/* Trim each bitmap in the rgrp */
 			for (x = 0; x < rgd->rd_length; x++) {
 				struct gfs2_bitmap *bi = rgd->rd_bits + x;
-				ret = gfs2_rgrp_send_discards(sdp, rgd->rd_data0, NULL, bi, r.minlen, &amt);
+				ret = gfs2_rgrp_send_discards(sdp,
+						rgd->rd_data0, NULL, bi, minlen,
+						&amt);
 				if (ret) {
 					gfs2_glock_dq_uninit(&gh);
 					goto out;
@@ -1324,7 +1333,7 @@
 
 out:
 	r.len = trimmed << 9;
-	if (argp && copy_to_user(argp, &r, sizeof(r)))
+	if (copy_to_user(argp, &r, sizeof(r)))
 		return -EFAULT;
 
 	return ret;
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index bc73726..d648867 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -810,7 +810,8 @@
 			return;
 		}
 		need_unlock = 1;
-	}
+	} else if (WARN_ON_ONCE(ip->i_gl->gl_state != LM_ST_EXCLUSIVE))
+		return;
 
 	if (current->journal_info == NULL) {
 		ret = gfs2_trans_begin(sdp, RES_DINODE, 0);
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index adbd278..4136270 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
@@ -155,14 +155,22 @@
 	struct gfs2_sbd *sdp = gl->gl_sbd;
 	struct gfs2_bufdata *bd;
 
+	lock_buffer(bh);
+	gfs2_log_lock(sdp);
 	bd = bh->b_private;
 	if (bd)
 		gfs2_assert(sdp, bd->bd_gl == gl);
 	else {
+		gfs2_log_unlock(sdp);
+		unlock_buffer(bh);
 		gfs2_attach_bufdata(gl, bh, meta);
 		bd = bh->b_private;
+		lock_buffer(bh);
+		gfs2_log_lock(sdp);
 	}
 	lops_add(sdp, bd);
+	gfs2_log_unlock(sdp);
+	unlock_buffer(bh);
 }
 
 void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
diff --git a/fs/jfs/jfs_discard.c b/fs/jfs/jfs_discard.c
index 9947563..dfcd503 100644
--- a/fs/jfs/jfs_discard.c
+++ b/fs/jfs/jfs_discard.c
@@ -83,7 +83,7 @@
 	struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap;
 	struct super_block *sb = ipbmap->i_sb;
 	int agno, agno_end;
-	s64 start, end, minlen;
+	u64 start, end, minlen;
 	u64 trimmed = 0;
 
 	/**
@@ -93,14 +93,18 @@
 	 * minlen:	minimum extent length in Bytes
 	 */
 	start = range->start >> sb->s_blocksize_bits;
-	if (start < 0)
-		start = 0;
 	end = start + (range->len >> sb->s_blocksize_bits) - 1;
+	minlen = range->minlen >> sb->s_blocksize_bits;
+	if (minlen == 0)
+		minlen = 1;
+
+	if (minlen > bmp->db_agsize ||
+	    start >= bmp->db_mapsize ||
+	    range->len < sb->s_blocksize)
+		return -EINVAL;
+
 	if (end >= bmp->db_mapsize)
 		end = bmp->db_mapsize - 1;
-	minlen = range->minlen >> sb->s_blocksize_bits;
-	if (minlen <= 0)
-		minlen = 1;
 
 	/**
 	 * we trim all ag's within the range
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index e4fb3ba..3d7e09b 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -85,29 +85,38 @@
 	return rpc_create(&args);
 }
 
+static struct rpc_clnt *nsm_client_set(struct lockd_net *ln,
+		struct rpc_clnt *clnt)
+{
+	spin_lock(&ln->nsm_clnt_lock);
+	if (ln->nsm_users == 0) {
+		if (clnt == NULL)
+			goto out;
+		ln->nsm_clnt = clnt;
+	}
+	clnt = ln->nsm_clnt;
+	ln->nsm_users++;
+out:
+	spin_unlock(&ln->nsm_clnt_lock);
+	return clnt;
+}
+
 static struct rpc_clnt *nsm_client_get(struct net *net)
 {
-	static DEFINE_MUTEX(nsm_create_mutex);
-	struct rpc_clnt	*clnt;
+	struct rpc_clnt	*clnt, *new;
 	struct lockd_net *ln = net_generic(net, lockd_net_id);
 
-	spin_lock(&ln->nsm_clnt_lock);
-	if (ln->nsm_users) {
-		ln->nsm_users++;
-		clnt = ln->nsm_clnt;
-		spin_unlock(&ln->nsm_clnt_lock);
+	clnt = nsm_client_set(ln, NULL);
+	if (clnt != NULL)
 		goto out;
-	}
-	spin_unlock(&ln->nsm_clnt_lock);
 
-	mutex_lock(&nsm_create_mutex);
-	clnt = nsm_create(net);
-	if (!IS_ERR(clnt)) {
-		ln->nsm_clnt = clnt;
-		smp_wmb();
-		ln->nsm_users = 1;
-	}
-	mutex_unlock(&nsm_create_mutex);
+	clnt = new = nsm_create(net);
+	if (IS_ERR(clnt))
+		goto out;
+
+	clnt = nsm_client_set(ln, new);
+	if (clnt != new)
+		rpc_shutdown_client(new);
 out:
 	return clnt;
 }
@@ -115,18 +124,16 @@
 static void nsm_client_put(struct net *net)
 {
 	struct lockd_net *ln = net_generic(net, lockd_net_id);
-	struct rpc_clnt	*clnt = ln->nsm_clnt;
-	int shutdown = 0;
+	struct rpc_clnt	*clnt = NULL;
 
 	spin_lock(&ln->nsm_clnt_lock);
-	if (ln->nsm_users) {
-		if (--ln->nsm_users)
-			ln->nsm_clnt = NULL;
-		shutdown = !ln->nsm_users;
+	ln->nsm_users--;
+	if (ln->nsm_users == 0) {
+		clnt = ln->nsm_clnt;
+		ln->nsm_clnt = NULL;
 	}
 	spin_unlock(&ln->nsm_clnt_lock);
-
-	if (shutdown)
+	if (clnt != NULL)
 		rpc_shutdown_client(clnt);
 }
 
diff --git a/fs/namei.c b/fs/namei.c
index d1895f3..937f9d5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -705,8 +705,8 @@
 	path_put(link);
 }
 
-int sysctl_protected_symlinks __read_mostly = 1;
-int sysctl_protected_hardlinks __read_mostly = 1;
+int sysctl_protected_symlinks __read_mostly = 0;
+int sysctl_protected_hardlinks __read_mostly = 0;
 
 /**
  * may_follow_link - Check symlink following for unsafe situations
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 9a521fb..5088b57 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -241,7 +241,7 @@
 		svc_exit_thread(cb_info->rqst);
 		cb_info->rqst = NULL;
 		cb_info->task = NULL;
-		return PTR_ERR(cb_info->task);
+		return ret;
 	}
 	dprintk("nfs_callback_up: service started\n");
 	return 0;
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index 31c26c4..ca4b11e 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -217,7 +217,7 @@
 {
 	char buf1[NFS_DNS_HOSTNAME_MAXLEN+1];
 	struct nfs_dns_ent key, *item;
-	unsigned long ttl;
+	unsigned int ttl;
 	ssize_t len;
 	int ret = -EINVAL;
 
@@ -240,7 +240,8 @@
 	key.namelen = len;
 	memset(&key.h, 0, sizeof(key.h));
 
-	ttl = get_expiry(&buf);
+	if (get_uint(&buf, &ttl) < 0)
+		goto out;
 	if (ttl == 0)
 		goto out;
 	key.h.expiry_time = ttl + seconds_since_boot();
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 5c7325c..6fa01ae 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -685,7 +685,10 @@
 	if (ctx->cred != NULL)
 		put_rpccred(ctx->cred);
 	dput(ctx->dentry);
-	nfs_sb_deactive(sb);
+	if (is_sync)
+		nfs_sb_deactive(sb);
+	else
+		nfs_sb_deactive_async(sb);
 	kfree(ctx->mdsthreshold);
 	kfree(ctx);
 }
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 59b133c..05521ca 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -351,10 +351,12 @@
 extern void __exit unregister_nfs_fs(void);
 extern void nfs_sb_active(struct super_block *sb);
 extern void nfs_sb_deactive(struct super_block *sb);
+extern void nfs_sb_deactive_async(struct super_block *sb);
 
 /* namespace.c */
+#define NFS_PATH_CANONICAL 1
 extern char *nfs_path(char **p, struct dentry *dentry,
-		      char *buffer, ssize_t buflen);
+		      char *buffer, ssize_t buflen, unsigned flags);
 extern struct vfsmount *nfs_d_automount(struct path *path);
 struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *,
 			      struct nfs_fh *, struct nfs_fattr *);
@@ -498,7 +500,7 @@
 				char *buffer, ssize_t buflen)
 {
 	char *dummy;
-	return nfs_path(&dummy, dentry, buffer, buflen);
+	return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL);
 }
 
 /*
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 8e65c7f..015f71f 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -181,7 +181,7 @@
 	else
 		msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT];
 
-	status = rpc_call_sync(mnt_clnt, &msg, 0);
+	status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT);
 	rpc_shutdown_client(mnt_clnt);
 
 	if (status < 0)
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 6559253..dd057bc 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -33,6 +33,7 @@
  * @dentry - pointer to dentry
  * @buffer - result buffer
  * @buflen - length of buffer
+ * @flags - options (see below)
  *
  * Helper function for constructing the server pathname
  * by arbitrary hashed dentry.
@@ -40,8 +41,14 @@
  * This is mainly for use in figuring out the path on the
  * server side when automounting on top of an existing partition
  * and in generating /proc/mounts and friends.
+ *
+ * Supported flags:
+ * NFS_PATH_CANONICAL: ensure there is exactly one slash after
+ *		       the original device (export) name
+ *		       (if unset, the original name is returned verbatim)
  */
-char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen)
+char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen,
+	       unsigned flags)
 {
 	char *end;
 	int namelen;
@@ -74,7 +81,7 @@
 		rcu_read_unlock();
 		goto rename_retry;
 	}
-	if (*end != '/') {
+	if ((flags & NFS_PATH_CANONICAL) && *end != '/') {
 		if (--buflen < 0) {
 			spin_unlock(&dentry->d_lock);
 			rcu_read_unlock();
@@ -91,9 +98,11 @@
 		return end;
 	}
 	namelen = strlen(base);
-	/* Strip off excess slashes in base string */
-	while (namelen > 0 && base[namelen - 1] == '/')
-		namelen--;
+	if (flags & NFS_PATH_CANONICAL) {
+		/* Strip off excess slashes in base string */
+		while (namelen > 0 && base[namelen - 1] == '/')
+			namelen--;
+	}
 	buflen -= namelen;
 	if (buflen < 0) {
 		spin_unlock(&dentry->d_lock);
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 52d8472..2e45fd9 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -122,12 +122,21 @@
 	}
 }
 
+static void filelayout_fenceme(struct inode *inode, struct pnfs_layout_hdr *lo)
+{
+	if (!test_and_clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
+		return;
+	clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags);
+	pnfs_return_layout(inode);
+}
+
 static int filelayout_async_handle_error(struct rpc_task *task,
 					 struct nfs4_state *state,
 					 struct nfs_client *clp,
 					 struct pnfs_layout_segment *lseg)
 {
-	struct inode *inode = lseg->pls_layout->plh_inode;
+	struct pnfs_layout_hdr *lo = lseg->pls_layout;
+	struct inode *inode = lo->plh_inode;
 	struct nfs_server *mds_server = NFS_SERVER(inode);
 	struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
 	struct nfs_client *mds_client = mds_server->nfs_client;
@@ -204,10 +213,8 @@
 		dprintk("%s DS connection error %d\n", __func__,
 			task->tk_status);
 		nfs4_mark_deviceid_unavailable(devid);
-		clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags);
-		_pnfs_return_layout(inode);
+		set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
 		rpc_wake_up(&tbl->slot_tbl_waitq);
-		nfs4_ds_disconnect(clp);
 		/* fall through */
 	default:
 reset:
@@ -331,7 +338,9 @@
 static void filelayout_read_release(void *data)
 {
 	struct nfs_read_data *rdata = data;
+	struct pnfs_layout_hdr *lo = rdata->header->lseg->pls_layout;
 
+	filelayout_fenceme(lo->plh_inode, lo);
 	nfs_put_client(rdata->ds_clp);
 	rdata->header->mds_ops->rpc_release(data);
 }
@@ -429,7 +438,9 @@
 static void filelayout_write_release(void *data)
 {
 	struct nfs_write_data *wdata = data;
+	struct pnfs_layout_hdr *lo = wdata->header->lseg->pls_layout;
 
+	filelayout_fenceme(lo->plh_inode, lo);
 	nfs_put_client(wdata->ds_clp);
 	wdata->header->mds_ops->rpc_release(data);
 }
@@ -739,7 +750,7 @@
 		goto out_err;
 
 	if (fl->num_fh > 0) {
-		fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *),
+		fl->fh_array = kcalloc(fl->num_fh, sizeof(fl->fh_array[0]),
 				       gfp_flags);
 		if (!fl->fh_array)
 			goto out_err;
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index dca47d78..8c07241 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -149,6 +149,5 @@
 extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
 struct nfs4_file_layout_dsaddr *
 filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags);
-void nfs4_ds_disconnect(struct nfs_client *clp);
 
 #endif /* FS_NFS_NFS4FILELAYOUT_H */
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 3336d5e..a8eaa9b 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -149,28 +149,6 @@
 }
 
 /*
- * Lookup DS by nfs_client pointer. Zero data server client pointer
- */
-void nfs4_ds_disconnect(struct nfs_client *clp)
-{
-	struct nfs4_pnfs_ds *ds;
-	struct nfs_client *found = NULL;
-
-	dprintk("%s clp %p\n", __func__, clp);
-	spin_lock(&nfs4_ds_cache_lock);
-	list_for_each_entry(ds, &nfs4_data_server_cache, ds_node)
-		if (ds->ds_clp && ds->ds_clp == clp) {
-			found = ds->ds_clp;
-			ds->ds_clp = NULL;
-		}
-	spin_unlock(&nfs4_ds_cache_lock);
-	if (found) {
-		set_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
-		nfs_put_client(clp);
-	}
-}
-
-/*
  * Create an rpc connection to the nfs4_pnfs_ds data server
  * Currently only supports IPv4 and IPv6 addresses
  */
diff --git a/fs/nfs/nfs4getroot.c b/fs/nfs/nfs4getroot.c
index 6a83780..549462e 100644
--- a/fs/nfs/nfs4getroot.c
+++ b/fs/nfs/nfs4getroot.c
@@ -5,6 +5,7 @@
 
 #include <linux/nfs_fs.h>
 #include "nfs4_fs.h"
+#include "internal.h"
 
 #define NFSDBG_FACILITY		NFSDBG_CLIENT
 
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 79fbb61..1e09eb7 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -81,7 +81,8 @@
 static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)
 {
 	char *limit;
-	char *path = nfs_path(&limit, dentry, buffer, buflen);
+	char *path = nfs_path(&limit, dentry, buffer, buflen,
+			      NFS_PATH_CANONICAL);
 	if (!IS_ERR(path)) {
 		char *path_component = nfs_path_component(path, limit);
 		if (path_component)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 68b21d8..5eec442 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -339,8 +339,7 @@
 			dprintk("%s ERROR: %d Reset session\n", __func__,
 				errorcode);
 			nfs4_schedule_session_recovery(clp->cl_session, errorcode);
-			exception->retry = 1;
-			break;
+			goto wait_on_recovery;
 #endif /* defined(CONFIG_NFS_V4_1) */
 		case -NFS4ERR_FILE_OPEN:
 			if (exception->timeout > HZ) {
@@ -1572,9 +1571,11 @@
 	data->timestamp = jiffies;
 	if (nfs4_setup_sequence(data->o_arg.server,
 				&data->o_arg.seq_args,
-				&data->o_res.seq_res, task))
-		return;
-	rpc_call_start(task);
+				&data->o_res.seq_res,
+				task) != 0)
+		nfs_release_seqid(data->o_arg.seqid);
+	else
+		rpc_call_start(task);
 	return;
 unlock_no_action:
 	rcu_read_unlock();
@@ -1748,7 +1749,7 @@
 
 	/* even though OPEN succeeded, access is denied. Close the file */
 	nfs4_close_state(state, fmode);
-	return -NFS4ERR_ACCESS;
+	return -EACCES;
 }
 
 /*
@@ -2196,7 +2197,7 @@
 	nfs4_put_open_state(calldata->state);
 	nfs_free_seqid(calldata->arg.seqid);
 	nfs4_put_state_owner(sp);
-	nfs_sb_deactive(sb);
+	nfs_sb_deactive_async(sb);
 	kfree(calldata);
 }
 
@@ -2296,9 +2297,10 @@
 	if (nfs4_setup_sequence(NFS_SERVER(inode),
 				&calldata->arg.seq_args,
 				&calldata->res.seq_res,
-				task))
-		goto out;
-	rpc_call_start(task);
+				task) != 0)
+		nfs_release_seqid(calldata->arg.seqid);
+	else
+		rpc_call_start(task);
 out:
 	dprintk("%s: done!\n", __func__);
 }
@@ -4529,6 +4531,7 @@
 			if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
 				rpc_restart_call_prepare(task);
 	}
+	nfs_release_seqid(calldata->arg.seqid);
 }
 
 static void nfs4_locku_prepare(struct rpc_task *task, void *data)
@@ -4545,9 +4548,11 @@
 	calldata->timestamp = jiffies;
 	if (nfs4_setup_sequence(calldata->server,
 				&calldata->arg.seq_args,
-				&calldata->res.seq_res, task))
-		return;
-	rpc_call_start(task);
+				&calldata->res.seq_res,
+				task) != 0)
+		nfs_release_seqid(calldata->arg.seqid);
+	else
+		rpc_call_start(task);
 }
 
 static const struct rpc_call_ops nfs4_locku_ops = {
@@ -4692,7 +4697,7 @@
 	/* Do we need to do an open_to_lock_owner? */
 	if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) {
 		if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0)
-			return;
+			goto out_release_lock_seqid;
 		data->arg.open_stateid = &state->stateid;
 		data->arg.new_lock_owner = 1;
 		data->res.open_seqid = data->arg.open_seqid;
@@ -4701,10 +4706,15 @@
 	data->timestamp = jiffies;
 	if (nfs4_setup_sequence(data->server,
 				&data->arg.seq_args,
-				&data->res.seq_res, task))
+				&data->res.seq_res,
+				task) == 0) {
+		rpc_call_start(task);
 		return;
-	rpc_call_start(task);
-	dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
+	}
+	nfs_release_seqid(data->arg.open_seqid);
+out_release_lock_seqid:
+	nfs_release_seqid(data->arg.lock_seqid);
+	dprintk("%s: done!, ret = %d\n", __func__, task->tk_status);
 }
 
 static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
@@ -5667,7 +5677,7 @@
 		tbl->slots = new;
 		tbl->max_slots = max_slots;
 	}
-	tbl->highest_used_slotid = -1;	/* no slot is currently used */
+	tbl->highest_used_slotid = NFS4_NO_SLOT;
 	for (i = 0; i < tbl->max_slots; i++)
 		tbl->slots[i].seq_nr = ivalue;
 	spin_unlock(&tbl->slot_tbl_lock);
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index be731e6..c6f9906 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -369,7 +369,7 @@
 	kfree(objios);
 }
 
-enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep)
+static enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep)
 {
 	switch (oep) {
 	case OSD_ERR_PRI_NO_ERROR:
@@ -574,7 +574,7 @@
 			(unsigned long)pgio->pg_layout_private;
 }
 
-void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
+static void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
 {
 	pnfs_generic_pg_init_read(pgio, req);
 	if (unlikely(pgio->pg_lseg == NULL))
@@ -604,7 +604,7 @@
 	return false;
 }
 
-void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
+static void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
 {
 	unsigned long stripe_end = 0;
 	u64 wb_size;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index fe624c9..2878f97 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -925,8 +925,8 @@
 	if (likely(nfsi->layout == NULL)) {	/* Won the race? */
 		nfsi->layout = new;
 		return new;
-	}
-	pnfs_free_layout_hdr(new);
+	} else if (new != NULL)
+		pnfs_free_layout_hdr(new);
 out_existing:
 	pnfs_get_layout_hdr(nfsi->layout);
 	return nfsi->layout;
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 2d722db..dbf7bba 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -62,6 +62,7 @@
 	NFS_LAYOUT_RW_FAILED,		/* get rw layout failed stop trying */
 	NFS_LAYOUT_BULK_RECALL,		/* bulk recall affecting layout */
 	NFS_LAYOUT_ROC,			/* some lseg had roc bit set */
+	NFS_LAYOUT_RETURN,		/* Return this layout ASAP */
 };
 
 enum layoutdriver_policy_flags {
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index e831bce..652d3f7 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -54,6 +54,7 @@
 #include <linux/parser.h>
 #include <linux/nsproxy.h>
 #include <linux/rcupdate.h>
+#include <linux/kthread.h>
 
 #include <asm/uaccess.h>
 
@@ -415,6 +416,54 @@
 }
 EXPORT_SYMBOL_GPL(nfs_sb_deactive);
 
+static int nfs_deactivate_super_async_work(void *ptr)
+{
+	struct super_block *sb = ptr;
+
+	deactivate_super(sb);
+	module_put_and_exit(0);
+	return 0;
+}
+
+/*
+ * same effect as deactivate_super, but will do final unmount in kthread
+ * context
+ */
+static void nfs_deactivate_super_async(struct super_block *sb)
+{
+	struct task_struct *task;
+	char buf[INET6_ADDRSTRLEN + 1];
+	struct nfs_server *server = NFS_SB(sb);
+	struct nfs_client *clp = server->nfs_client;
+
+	if (!atomic_add_unless(&sb->s_active, -1, 1)) {
+		rcu_read_lock();
+		snprintf(buf, sizeof(buf),
+			rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR));
+		rcu_read_unlock();
+
+		__module_get(THIS_MODULE);
+		task = kthread_run(nfs_deactivate_super_async_work, sb,
+				"%s-deactivate-super", buf);
+		if (IS_ERR(task)) {
+			pr_err("%s: kthread_run: %ld\n",
+				__func__, PTR_ERR(task));
+			/* make synchronous call and hope for the best */
+			deactivate_super(sb);
+			module_put(THIS_MODULE);
+		}
+	}
+}
+
+void nfs_sb_deactive_async(struct super_block *sb)
+{
+	struct nfs_server *server = NFS_SB(sb);
+
+	if (atomic_dec_and_test(&server->active))
+		nfs_deactivate_super_async(sb);
+}
+EXPORT_SYMBOL_GPL(nfs_sb_deactive_async);
+
 /*
  * Deliver file system statistics to userspace
  */
@@ -771,7 +820,7 @@
 	int err = 0;
 	if (!page)
 		return -ENOMEM;
-	devname = nfs_path(&dummy, root, page, PAGE_SIZE);
+	devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0);
 	if (IS_ERR(devname))
 		err = PTR_ERR(devname);
 	else
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 13cea63..3f79c77 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -95,7 +95,7 @@
 
 	nfs_dec_sillycount(data->dir);
 	nfs_free_unlinkdata(data);
-	nfs_sb_deactive(sb);
+	nfs_sb_deactive_async(sb);
 }
 
 static void nfs_unlink_prepare(struct rpc_task *task, void *calldata)
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index f35794b..a506360 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -21,6 +21,7 @@
 			if ((old->path.mnt == new->path.mnt) &&
 			    (old->path.dentry == new->path.dentry))
 				return true;
+			break;
 		case (FSNOTIFY_EVENT_NONE):
 			return true;
 		default:
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 144a967..3c231ad 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -873,6 +873,113 @@
 	.release	= mem_release,
 };
 
+static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
+			    loff_t *ppos)
+{
+	struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
+	char buffer[PROC_NUMBUF];
+	int oom_adj = OOM_ADJUST_MIN;
+	size_t len;
+	unsigned long flags;
+
+	if (!task)
+		return -ESRCH;
+	if (lock_task_sighand(task, &flags)) {
+		if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX)
+			oom_adj = OOM_ADJUST_MAX;
+		else
+			oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) /
+				  OOM_SCORE_ADJ_MAX;
+		unlock_task_sighand(task, &flags);
+	}
+	put_task_struct(task);
+	len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj);
+	return simple_read_from_buffer(buf, count, ppos, buffer, len);
+}
+
+static ssize_t oom_adj_write(struct file *file, const char __user *buf,
+			     size_t count, loff_t *ppos)
+{
+	struct task_struct *task;
+	char buffer[PROC_NUMBUF];
+	int oom_adj;
+	unsigned long flags;
+	int err;
+
+	memset(buffer, 0, sizeof(buffer));
+	if (count > sizeof(buffer) - 1)
+		count = sizeof(buffer) - 1;
+	if (copy_from_user(buffer, buf, count)) {
+		err = -EFAULT;
+		goto out;
+	}
+
+	err = kstrtoint(strstrip(buffer), 0, &oom_adj);
+	if (err)
+		goto out;
+	if ((oom_adj < OOM_ADJUST_MIN || oom_adj > OOM_ADJUST_MAX) &&
+	     oom_adj != OOM_DISABLE) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	task = get_proc_task(file->f_path.dentry->d_inode);
+	if (!task) {
+		err = -ESRCH;
+		goto out;
+	}
+
+	task_lock(task);
+	if (!task->mm) {
+		err = -EINVAL;
+		goto err_task_lock;
+	}
+
+	if (!lock_task_sighand(task, &flags)) {
+		err = -ESRCH;
+		goto err_task_lock;
+	}
+
+	/*
+	 * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
+	 * value is always attainable.
+	 */
+	if (oom_adj == OOM_ADJUST_MAX)
+		oom_adj = OOM_SCORE_ADJ_MAX;
+	else
+		oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
+
+	if (oom_adj < task->signal->oom_score_adj &&
+	    !capable(CAP_SYS_RESOURCE)) {
+		err = -EACCES;
+		goto err_sighand;
+	}
+
+	/*
+	 * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
+	 * /proc/pid/oom_score_adj instead.
+	 */
+	printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n",
+		  current->comm, task_pid_nr(current), task_pid_nr(task),
+		  task_pid_nr(task));
+
+	task->signal->oom_score_adj = oom_adj;
+	trace_oom_score_adj_update(task);
+err_sighand:
+	unlock_task_sighand(task, &flags);
+err_task_lock:
+	task_unlock(task);
+	put_task_struct(task);
+out:
+	return err < 0 ? err : count;
+}
+
+static const struct file_operations proc_oom_adj_operations = {
+	.read		= oom_adj_read,
+	.write		= oom_adj_write,
+	.llseek		= generic_file_llseek,
+};
+
 static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
 					size_t count, loff_t *ppos)
 {
@@ -2598,6 +2705,7 @@
 	REG("cgroup",  S_IRUGO, proc_cgroup_operations),
 #endif
 	INF("oom_score",  S_IRUGO, proc_oom_score),
+	REG("oom_adj",    S_IRUGO|S_IWUSR, proc_oom_adj_operations),
 	REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
 #ifdef CONFIG_AUDITSYSCALL
 	REG("loginuid",   S_IWUSR|S_IRUGO, proc_loginuid_operations),
@@ -2964,6 +3072,7 @@
 	REG("cgroup",  S_IRUGO, proc_cgroup_operations),
 #endif
 	INF("oom_score", S_IRUGO, proc_oom_score),
+	REG("oom_adj",   S_IRUGO|S_IWUSR, proc_oom_adj_operations),
 	REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
 #ifdef CONFIG_AUDITSYSCALL
 	REG("loginuid",  S_IWUSR|S_IRUGO, proc_loginuid_operations),
diff --git a/fs/proc/stat.c b/fs/proc/stat.c
index 64c3b31..e296572 100644
--- a/fs/proc/stat.c
+++ b/fs/proc/stat.c
@@ -45,10 +45,13 @@
 
 static u64 get_idle_time(int cpu)
 {
-	u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL);
+	u64 idle, idle_time = -1ULL;
+
+	if (cpu_online(cpu))
+		idle_time = get_cpu_idle_time_us(cpu, NULL);
 
 	if (idle_time == -1ULL)
-		/* !NO_HZ so we can rely on cpustat.idle */
+		/* !NO_HZ or cpu offline so we can rely on cpustat.idle */
 		idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
 	else
 		idle = usecs_to_cputime64(idle_time);
@@ -58,10 +61,13 @@
 
 static u64 get_iowait_time(int cpu)
 {
-	u64 iowait, iowait_time = get_cpu_iowait_time_us(cpu, NULL);
+	u64 iowait, iowait_time = -1ULL;
+
+	if (cpu_online(cpu))
+		iowait_time = get_cpu_iowait_time_us(cpu, NULL);
 
 	if (iowait_time == -1ULL)
-		/* !NO_HZ so we can rely on cpustat.iowait */
+		/* !NO_HZ or cpu offline so we can rely on cpustat.iowait */
 		iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT];
 	else
 		iowait = usecs_to_cputime64(iowait_time);
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index a40da07..947fbe0 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -161,6 +161,7 @@
 
 	while (s < e) {
 		unsigned long flags;
+		u64 id;
 
 		if (c > psinfo->bufsize)
 			c = psinfo->bufsize;
@@ -172,7 +173,7 @@
 			spin_lock_irqsave(&psinfo->buf_lock, flags);
 		}
 		memcpy(psinfo->buf, s, c);
-		psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo);
+		psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo);
 		spin_unlock_irqrestore(&psinfo->buf_lock, flags);
 		s += c;
 		c = e - s;
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 6b0bb00..2fbdff6 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -485,20 +485,18 @@
 /**
  *	sysfs_pathname - return full path to sysfs dirent
  *	@sd: sysfs_dirent whose path we want
- *	@path: caller allocated buffer
+ *	@path: caller allocated buffer of size PATH_MAX
  *
  *	Gives the name "/" to the sysfs_root entry; any path returned
  *	is relative to wherever sysfs is mounted.
- *
- *	XXX: does no error checking on @path size
  */
 static char *sysfs_pathname(struct sysfs_dirent *sd, char *path)
 {
 	if (sd->s_parent) {
 		sysfs_pathname(sd->s_parent, path);
-		strcat(path, "/");
+		strlcat(path, "/", PATH_MAX);
 	}
-	strcat(path, sd->s_name);
+	strlcat(path, sd->s_name, PATH_MAX);
 	return path;
 }
 
@@ -531,9 +529,11 @@
 		char *path = kzalloc(PATH_MAX, GFP_KERNEL);
 		WARN(1, KERN_WARNING
 		     "sysfs: cannot create duplicate filename '%s'\n",
-		     (path == NULL) ? sd->s_name :
-		     strcat(strcat(sysfs_pathname(acxt->parent_sd, path), "/"),
-		            sd->s_name));
+		     (path == NULL) ? sd->s_name
+				    : (sysfs_pathname(acxt->parent_sd, path),
+				       strlcat(path, "/", PATH_MAX),
+				       strlcat(path, sd->s_name, PATH_MAX),
+				       path));
 		kfree(path);
 	}
 
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c
index 28ec13a..2dcf3d4 100644
--- a/fs/ubifs/find.c
+++ b/fs/ubifs/find.c
@@ -681,8 +681,16 @@
 	if (!lprops) {
 		lprops = ubifs_fast_find_freeable(c);
 		if (!lprops) {
-			ubifs_assert(c->freeable_cnt == 0);
-			if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
+			/*
+			 * The first condition means the following: go scan the
+			 * LPT if there are uncategorized lprops, which means
+			 * there may be freeable LEBs there (UBIFS does not
+			 * store the information about freeable LEBs in the
+			 * master node).
+			 */
+			if (c->in_a_category_cnt != c->main_lebs ||
+			    c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
+				ubifs_assert(c->freeable_cnt == 0);
 				lprops = scan_for_leb_for_idx(c);
 				if (IS_ERR(lprops)) {
 					err = PTR_ERR(lprops);
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index e5a2a35..46190a7 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -300,8 +300,11 @@
 	default:
 		ubifs_assert(0);
 	}
+
 	lprops->flags &= ~LPROPS_CAT_MASK;
 	lprops->flags |= cat;
+	c->in_a_category_cnt += 1;
+	ubifs_assert(c->in_a_category_cnt <= c->main_lebs);
 }
 
 /**
@@ -334,6 +337,9 @@
 	default:
 		ubifs_assert(0);
 	}
+
+	c->in_a_category_cnt -= 1;
+	ubifs_assert(c->in_a_category_cnt >= 0);
 }
 
 /**
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 5486346..d133c27 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1183,6 +1183,8 @@
  * @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size)
  * @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size)
  * @freeable_cnt: number of freeable LEBs in @freeable_list
+ * @in_a_category_cnt: count of lprops which are in a certain category, which
+ *                     basically meants that they were loaded from the flash
  *
  * @ltab_lnum: LEB number of LPT's own lprops table
  * @ltab_offs: offset of LPT's own lprops table
@@ -1412,6 +1414,7 @@
 	struct list_head freeable_list;
 	struct list_head frdi_idx_list;
 	int freeable_cnt;
+	int in_a_category_cnt;
 
 	int ltab_lnum;
 	int ltab_offs;
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 4f33c32..335206a 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -1866,6 +1866,7 @@
 	/*
 	 * Initialize the args structure.
 	 */
+	memset(&targs, 0, sizeof(targs));
 	targs.tp = tp;
 	targs.mp = mp;
 	targs.agbp = agbp;
@@ -2207,7 +2208,7 @@
  * group or loop over the allocation groups to find the result.
  */
 int				/* error */
-__xfs_alloc_vextent(
+xfs_alloc_vextent(
 	xfs_alloc_arg_t	*args)	/* allocation argument structure */
 {
 	xfs_agblock_t	agsize;	/* allocation group size */
@@ -2417,46 +2418,6 @@
 	return error;
 }
 
-static void
-xfs_alloc_vextent_worker(
-	struct work_struct	*work)
-{
-	struct xfs_alloc_arg	*args = container_of(work,
-						struct xfs_alloc_arg, work);
-	unsigned long		pflags;
-
-	/* we are in a transaction context here */
-	current_set_flags_nested(&pflags, PF_FSTRANS);
-
-	args->result = __xfs_alloc_vextent(args);
-	complete(args->done);
-
-	current_restore_flags_nested(&pflags, PF_FSTRANS);
-}
-
-/*
- * Data allocation requests often come in with little stack to work on. Push
- * them off to a worker thread so there is lots of stack to use. Metadata
- * requests, OTOH, are generally from low stack usage paths, so avoid the
- * context switch overhead here.
- */
-int
-xfs_alloc_vextent(
-	struct xfs_alloc_arg	*args)
-{
-	DECLARE_COMPLETION_ONSTACK(done);
-
-	if (!args->userdata)
-		return __xfs_alloc_vextent(args);
-
-
-	args->done = &done;
-	INIT_WORK_ONSTACK(&args->work, xfs_alloc_vextent_worker);
-	queue_work(xfs_alloc_wq, &args->work);
-	wait_for_completion(&done);
-	return args->result;
-}
-
 /*
  * Free an extent.
  * Just break up the extent address and hand off to xfs_free_ag_extent
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 93be4a6..feacb06 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -120,9 +120,6 @@
 	char		isfl;		/* set if is freelist blocks - !acctg */
 	char		userdata;	/* set if this is user data */
 	xfs_fsblock_t	firstblock;	/* io first block allocated */
-	struct completion *done;
-	struct work_struct work;
-	int		result;
 } xfs_alloc_arg_t;
 
 /*
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index f1647ca..f7876c6 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -121,6 +121,8 @@
 	xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1,
 			      XFS_EXTENT_BUSY_SKIP_DISCARD);
 	xfs_trans_agbtree_delta(cur->bc_tp, -1);
+
+	xfs_trans_binval(cur->bc_tp, bp);
 	return 0;
 }
 
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 848ffa77..83d0cf3 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2437,6 +2437,7 @@
 	 * Normal allocation, done through xfs_alloc_vextent.
 	 */
 	tryagain = isaligned = 0;
+	memset(&args, 0, sizeof(args));
 	args.tp = ap->tp;
 	args.mp = mp;
 	args.fsbno = ap->blkno;
@@ -3082,6 +3083,7 @@
 	 * Convert to a btree with two levels, one record in root.
 	 */
 	XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
+	memset(&args, 0, sizeof(args));
 	args.tp = tp;
 	args.mp = mp;
 	args.firstblock = *firstblock;
@@ -3237,6 +3239,7 @@
 		xfs_buf_t	*bp;	/* buffer for extent block */
 		xfs_bmbt_rec_host_t *ep;/* extent record pointer */
 
+		memset(&args, 0, sizeof(args));
 		args.tp = tp;
 		args.mp = ip->i_mount;
 		args.firstblock = *firstblock;
@@ -4616,12 +4619,11 @@
 
 
 STATIC int
-xfs_bmapi_allocate(
-	struct xfs_bmalloca	*bma,
-	int			flags)
+__xfs_bmapi_allocate(
+	struct xfs_bmalloca	*bma)
 {
 	struct xfs_mount	*mp = bma->ip->i_mount;
-	int			whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
+	int			whichfork = (bma->flags & XFS_BMAPI_ATTRFORK) ?
 						XFS_ATTR_FORK : XFS_DATA_FORK;
 	struct xfs_ifork	*ifp = XFS_IFORK_PTR(bma->ip, whichfork);
 	int			tmp_logflags = 0;
@@ -4654,24 +4656,27 @@
 	 * Indicate if this is the first user data in the file, or just any
 	 * user data.
 	 */
-	if (!(flags & XFS_BMAPI_METADATA)) {
+	if (!(bma->flags & XFS_BMAPI_METADATA)) {
 		bma->userdata = (bma->offset == 0) ?
 			XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA;
 	}
 
-	bma->minlen = (flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
+	bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
 
 	/*
 	 * Only want to do the alignment at the eof if it is userdata and
 	 * allocation length is larger than a stripe unit.
 	 */
 	if (mp->m_dalign && bma->length >= mp->m_dalign &&
-	    !(flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) {
+	    !(bma->flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) {
 		error = xfs_bmap_isaeof(bma, whichfork);
 		if (error)
 			return error;
 	}
 
+	if (bma->flags & XFS_BMAPI_STACK_SWITCH)
+		bma->stack_switch = 1;
+
 	error = xfs_bmap_alloc(bma);
 	if (error)
 		return error;
@@ -4706,7 +4711,7 @@
 	 * A wasdelay extent has been initialized, so shouldn't be flagged
 	 * as unwritten.
 	 */
-	if (!bma->wasdel && (flags & XFS_BMAPI_PREALLOC) &&
+	if (!bma->wasdel && (bma->flags & XFS_BMAPI_PREALLOC) &&
 	    xfs_sb_version_hasextflgbit(&mp->m_sb))
 		bma->got.br_state = XFS_EXT_UNWRITTEN;
 
@@ -4734,6 +4739,45 @@
 	return 0;
 }
 
+static void
+xfs_bmapi_allocate_worker(
+	struct work_struct	*work)
+{
+	struct xfs_bmalloca	*args = container_of(work,
+						struct xfs_bmalloca, work);
+	unsigned long		pflags;
+
+	/* we are in a transaction context here */
+	current_set_flags_nested(&pflags, PF_FSTRANS);
+
+	args->result = __xfs_bmapi_allocate(args);
+	complete(args->done);
+
+	current_restore_flags_nested(&pflags, PF_FSTRANS);
+}
+
+/*
+ * Some allocation requests often come in with little stack to work on. Push
+ * them off to a worker thread so there is lots of stack to use. Otherwise just
+ * call directly to avoid the context switch overhead here.
+ */
+int
+xfs_bmapi_allocate(
+	struct xfs_bmalloca	*args)
+{
+	DECLARE_COMPLETION_ONSTACK(done);
+
+	if (!args->stack_switch)
+		return __xfs_bmapi_allocate(args);
+
+
+	args->done = &done;
+	INIT_WORK_ONSTACK(&args->work, xfs_bmapi_allocate_worker);
+	queue_work(xfs_alloc_wq, &args->work);
+	wait_for_completion(&done);
+	return args->result;
+}
+
 STATIC int
 xfs_bmapi_convert_unwritten(
 	struct xfs_bmalloca	*bma,
@@ -4919,6 +4963,7 @@
 			bma.conv = !!(flags & XFS_BMAPI_CONVERT);
 			bma.wasdel = wasdelay;
 			bma.offset = bno;
+			bma.flags = flags;
 
 			/*
 			 * There's a 32/64 bit type mismatch between the
@@ -4934,7 +4979,7 @@
 
 			ASSERT(len > 0);
 			ASSERT(bma.length > 0);
-			error = xfs_bmapi_allocate(&bma, flags);
+			error = xfs_bmapi_allocate(&bma);
 			if (error)
 				goto error0;
 			if (bma.blkno == NULLFSBLOCK)
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 803b56d..5f469c3 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -77,6 +77,7 @@
  * from written to unwritten, otherwise convert from unwritten to written.
  */
 #define XFS_BMAPI_CONVERT	0x040
+#define XFS_BMAPI_STACK_SWITCH	0x080
 
 #define XFS_BMAPI_FLAGS \
 	{ XFS_BMAPI_ENTIRE,	"ENTIRE" }, \
@@ -85,7 +86,8 @@
 	{ XFS_BMAPI_PREALLOC,	"PREALLOC" }, \
 	{ XFS_BMAPI_IGSTATE,	"IGSTATE" }, \
 	{ XFS_BMAPI_CONTIG,	"CONTIG" }, \
-	{ XFS_BMAPI_CONVERT,	"CONVERT" }
+	{ XFS_BMAPI_CONVERT,	"CONVERT" }, \
+	{ XFS_BMAPI_STACK_SWITCH, "STACK_SWITCH" }
 
 
 static inline int xfs_bmapi_aflag(int w)
@@ -133,6 +135,11 @@
 	char			userdata;/* set if is user data */
 	char			aeof;	/* allocated space at eof */
 	char			conv;	/* overwriting unwritten extents */
+	char			stack_switch;
+	int			flags;
+	struct completion	*done;
+	struct work_struct	work;
+	int			result;
 } xfs_bmalloca_t;
 
 /*
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index a8d0ed9..becf4a9 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -526,7 +526,25 @@
 		}
 		xfs_buf_relse(bp);
 	} else if (freed && remove) {
+		/*
+		 * There are currently two references to the buffer - the active
+		 * LRU reference and the buf log item. What we are about to do
+		 * here - simulate a failed IO completion - requires 3
+		 * references.
+		 *
+		 * The LRU reference is removed by the xfs_buf_stale() call. The
+		 * buf item reference is removed by the xfs_buf_iodone()
+		 * callback that is run by xfs_buf_do_callbacks() during ioend
+		 * processing (via the bp->b_iodone callback), and then finally
+		 * the ioend processing will drop the IO reference if the buffer
+		 * is marked XBF_ASYNC.
+		 *
+		 * Hence we need to take an additional reference here so that IO
+		 * completion processing doesn't free the buffer prematurely.
+		 */
 		xfs_buf_lock(bp);
+		xfs_buf_hold(bp);
+		bp->b_flags |= XBF_ASYNC;
 		xfs_buf_ioerror(bp, EIO);
 		XFS_BUF_UNDONE(bp);
 		xfs_buf_stale(bp);
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index c25b094..4beaede 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -399,9 +399,26 @@
 
 	/* update secondary superblocks. */
 	for (agno = 1; agno < nagcount; agno++) {
-		error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
+		error = 0;
+		/*
+		 * new secondary superblocks need to be zeroed, not read from
+		 * disk as the contents of the new area we are growing into is
+		 * completely unknown.
+		 */
+		if (agno < oagcount) {
+			error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
 				  XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
 				  XFS_FSS_TO_BB(mp, 1), 0, &bp);
+		} else {
+			bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp,
+				  XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
+				  XFS_FSS_TO_BB(mp, 1), 0);
+			if (bp)
+				xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
+			else
+				error = ENOMEM;
+		}
+
 		if (error) {
 			xfs_warn(mp,
 		"error %d reading secondary superblock for ag %d",
@@ -423,7 +440,7 @@
 			break; /* no point in continuing */
 		}
 	}
-	return 0;
+	return error;
 
  error0:
 	xfs_trans_cancel(tp, XFS_TRANS_ABORT);
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 445bf1a..c5c4ef4 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -250,6 +250,7 @@
 					/* boundary */
 	struct xfs_perag *pag;
 
+	memset(&args, 0, sizeof(args));
 	args.tp = tp;
 	args.mp = tp->t_mountp;
 
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 2778258..1938b41 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1509,7 +1509,8 @@
 		 * to mark all the active inodes on the buffer stale.
 		 */
 		bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,
-					mp->m_bsize * blks_per_cluster, 0);
+					mp->m_bsize * blks_per_cluster,
+					XBF_UNMAPPED);
 
 		if (!bp)
 			return ENOMEM;
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 8305f2a..c1df3c6 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -70,7 +70,7 @@
 	int			hsize;
 	xfs_handle_t		handle;
 	struct inode		*inode;
-	struct fd		f;
+	struct fd		f = {0};
 	struct path		path;
 	int			error;
 	struct xfs_inode	*ip;
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 973dff6..7f53766 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -584,7 +584,9 @@
 			 * pointer that the caller gave to us.
 			 */
 			error = xfs_bmapi_write(tp, ip, map_start_fsb,
-						count_fsb, 0, &first_block, 1,
+						count_fsb,
+						XFS_BMAPI_STACK_SWITCH,
+						&first_block, 1,
 						imap, &nimaps, &free_list);
 			if (error)
 				goto trans_cancel;
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 7f4f937..4dad756 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -2387,14 +2387,27 @@
 
 
 				/*
-				 * update the last_sync_lsn before we drop the
+				 * Completion of a iclog IO does not imply that
+				 * a transaction has completed, as transactions
+				 * can be large enough to span many iclogs. We
+				 * cannot change the tail of the log half way
+				 * through a transaction as this may be the only
+				 * transaction in the log and moving th etail to
+				 * point to the middle of it will prevent
+				 * recovery from finding the start of the
+				 * transaction. Hence we should only update the
+				 * last_sync_lsn if this iclog contains
+				 * transaction completion callbacks on it.
+				 *
+				 * We have to do this before we drop the
 				 * icloglock to ensure we are the only one that
 				 * can update it.
 				 */
 				ASSERT(XFS_LSN_CMP(atomic64_read(&log->l_last_sync_lsn),
 					be64_to_cpu(iclog->ic_header.h_lsn)) <= 0);
-				atomic64_set(&log->l_last_sync_lsn,
-					be64_to_cpu(iclog->ic_header.h_lsn));
+				if (iclog->ic_callback)
+					atomic64_set(&log->l_last_sync_lsn,
+						be64_to_cpu(iclog->ic_header.h_lsn));
 
 			} else
 				ioerrors++;
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 5da3ace..d308749 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3541,7 +3541,7 @@
 				 *   - order is important.
 				 */
 				error = xlog_bread_offset(log, 0,
-						bblks - split_bblks, hbp,
+						bblks - split_bblks, dbp,
 						offset + BBTOB(split_bblks));
 				if (error)
 					goto bread_err2;
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index a9432fc..eb70ca2 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -56,6 +56,8 @@
  *	enabling module power and clock; may sleep
  * @free: optional hook for chip-specific deactivation, such as
  *	disabling module power and clock; may sleep
+ * @get_direction: returns direction for signal "offset", 0=out, 1=in,
+ *	(same as GPIOF_DIR_XXX), or negative error
  * @direction_input: configures signal "offset" as input, or returns error
  * @get: returns value for signal "offset"; for output signals this
  *	returns either the value actually sensed, or zero
@@ -100,7 +102,8 @@
 						unsigned offset);
 	void			(*free)(struct gpio_chip *chip,
 						unsigned offset);
-
+	int			(*get_direction)(struct gpio_chip *chip,
+						unsigned offset);
 	int			(*direction_input)(struct gpio_chip *chip,
 						unsigned offset);
 	int			(*get)(struct gpio_chip *chip,
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index c78bb99..af1cbaf 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -205,6 +205,8 @@
 	{0x1002, 0x6788, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x678A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6790, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
+	{0x1002, 0x6791, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
+	{0x1002, 0x6792, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6798, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6799, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x679A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
@@ -217,6 +219,7 @@
 	{0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
+	{0x1002, 0x6811, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6816, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6817, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
 	{0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index c127315..172d5bd 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -53,9 +53,13 @@
  * @disable:	Disable the clock atomically. Called with enable_lock held.
  * 		This function must not sleep.
  *
- * @recalc_rate	Recalculate the rate of this clock, by quering hardware.  The
+ * @is_enabled:	Queries the hardware to determine if the clock is enabled.
+ * 		This function must not sleep. Optional, if this op is not
+ * 		set then the enable count will be used.
+ *
+ * @recalc_rate	Recalculate the rate of this clock, by querying hardware. The
  * 		parent rate is an input parameter.  It is up to the caller to
- * 		insure that the prepare_mutex is held across this call.
+ * 		ensure that the prepare_mutex is held across this call.
  * 		Returns the calculated rate.  Optional, but recommended - if
  * 		this op is not set then clock rate will be initialized to 0.
  *
@@ -89,7 +93,7 @@
  * implementations to split any work between atomic (enable) and sleepable
  * (prepare) contexts.  If enabling a clock requires code that might sleep,
  * this must be done in clk_prepare.  Clock enable code that will never be
- * called in a sleepable context may be implement in clk_enable.
+ * called in a sleepable context may be implemented in clk_enable.
  *
  * Typically, drivers will call clk_prepare when a clock may be needed later
  * (eg. when a device is opened), and clk_enable when the clock is actually
@@ -335,11 +339,11 @@
 struct clk_hw *__clk_get_hw(struct clk *clk);
 u8 __clk_get_num_parents(struct clk *clk);
 struct clk *__clk_get_parent(struct clk *clk);
-inline int __clk_get_enable_count(struct clk *clk);
-inline int __clk_get_prepare_count(struct clk *clk);
+unsigned int __clk_get_enable_count(struct clk *clk);
+unsigned int __clk_get_prepare_count(struct clk *clk);
 unsigned long __clk_get_rate(struct clk *clk);
 unsigned long __clk_get_flags(struct clk *clk);
-int __clk_is_enabled(struct clk *clk);
+bool __clk_is_enabled(struct clk *clk);
 struct clk *__clk_lookup(const char *name);
 
 /*
diff --git a/arch/arm/plat-mxc/include/mach/timex.h b/include/linux/clk/sunxi.h
similarity index 65%
copy from arch/arm/plat-mxc/include/mach/timex.h
copy to include/linux/clk/sunxi.h
index 10343d1..e074fdd 100644
--- a/arch/arm/plat-mxc/include/mach/timex.h
+++ b/include/linux/clk/sunxi.h
@@ -1,6 +1,7 @@
 /*
- *  Copyright (C) 1999 ARM Limited
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -13,10 +14,9 @@
  * GNU General Public License for more details.
  */
 
-#ifndef __ASM_ARCH_MXC_TIMEX_H__
-#define __ASM_ARCH_MXC_TIMEX_H__
+#ifndef __LINUX_CLK_SUNXI_H_
+#define __LINUX_CLK_SUNXI_H_
 
-/* Bogus value */
-#define CLOCK_TICK_RATE	12345678
+void __init sunxi_init_clocks(void);
 
-#endif				/* __ASM_ARCH_MXC_TIMEX_H__ */
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/ipu.h b/include/linux/dma/ipu-dma.h
similarity index 96%
rename from arch/arm/plat-mxc/include/mach/ipu.h
rename to include/linux/dma/ipu-dma.h
index 539e559..1803111 100644
--- a/arch/arm/plat-mxc/include/mach/ipu.h
+++ b/include/linux/dma/ipu-dma.h
@@ -9,8 +9,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef _IPU_H_
-#define _IPU_H_
+#ifndef __LINUX_DMA_IPU_DMA_H
+#define __LINUX_DMA_IPU_DMA_H
 
 #include <linux/types.h>
 #include <linux/dmaengine.h>
@@ -174,4 +174,4 @@
 #define to_tx_desc(tx) container_of(tx, struct idmac_tx_desc, txd)
 #define to_idmac_chan(c) container_of(c, struct idmac_channel, dma_chan)
 
-#endif
+#endif /* __LINUX_DMA_IPU_DMA_H */
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index c18257b..6dd4787 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -61,7 +61,7 @@
 			 const char *fmt, ...);
 
 #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)		\
-	static struct _ddebug __used __aligned(8)		\
+	static struct _ddebug  __aligned(8)			\
 	__attribute__((section("__verbose"))) name = {		\
 		.modname = KBUILD_MODNAME,			\
 		.function = __func__,				\
diff --git a/include/linux/extcon.h b/include/linux/extcon.h
index 7443a56..2c26c14 100644
--- a/include/linux/extcon.h
+++ b/include/linux/extcon.h
@@ -68,7 +68,7 @@
 	EXTCON_VIDEO_OUT,
 	EXTCON_MECHANICAL,
 };
-extern const char *extcon_cable_name[];
+extern const char extcon_cable_name[][CABLE_NAME_MAX + 1];
 
 struct extcon_cable;
 
diff --git a/include/linux/hashtable.h b/include/linux/hashtable.h
new file mode 100644
index 0000000..227c624
--- /dev/null
+++ b/include/linux/hashtable.h
@@ -0,0 +1,192 @@
+/*
+ * Statically sized hash table implementation
+ * (C) 2012  Sasha Levin <levinsasha928@gmail.com>
+ */
+
+#ifndef _LINUX_HASHTABLE_H
+#define _LINUX_HASHTABLE_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/hash.h>
+#include <linux/rculist.h>
+
+#define DEFINE_HASHTABLE(name, bits)						\
+	struct hlist_head name[1 << (bits)] =					\
+			{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
+
+#define DECLARE_HASHTABLE(name, bits)                                   	\
+	struct hlist_head name[1 << (bits)]
+
+#define HASH_SIZE(name) (ARRAY_SIZE(name))
+#define HASH_BITS(name) ilog2(HASH_SIZE(name))
+
+/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */
+#define hash_min(val, bits)							\
+	(sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits))
+
+static inline void __hash_init(struct hlist_head *ht, unsigned int sz)
+{
+	unsigned int i;
+
+	for (i = 0; i < sz; i++)
+		INIT_HLIST_HEAD(&ht[i]);
+}
+
+/**
+ * hash_init - initialize a hash table
+ * @hashtable: hashtable to be initialized
+ *
+ * Calculates the size of the hashtable from the given parameter, otherwise
+ * same as hash_init_size.
+ *
+ * This has to be a macro since HASH_BITS() will not work on pointers since
+ * it calculates the size during preprocessing.
+ */
+#define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable))
+
+/**
+ * hash_add - add an object to a hashtable
+ * @hashtable: hashtable to add to
+ * @node: the &struct hlist_node of the object to be added
+ * @key: the key of the object to be added
+ */
+#define hash_add(hashtable, node, key)						\
+	hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
+
+/**
+ * hash_add_rcu - add an object to a rcu enabled hashtable
+ * @hashtable: hashtable to add to
+ * @node: the &struct hlist_node of the object to be added
+ * @key: the key of the object to be added
+ */
+#define hash_add_rcu(hashtable, node, key)					\
+	hlist_add_head_rcu(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
+
+/**
+ * hash_hashed - check whether an object is in any hashtable
+ * @node: the &struct hlist_node of the object to be checked
+ */
+static inline bool hash_hashed(struct hlist_node *node)
+{
+	return !hlist_unhashed(node);
+}
+
+static inline bool __hash_empty(struct hlist_head *ht, unsigned int sz)
+{
+	unsigned int i;
+
+	for (i = 0; i < sz; i++)
+		if (!hlist_empty(&ht[i]))
+			return false;
+
+	return true;
+}
+
+/**
+ * hash_empty - check whether a hashtable is empty
+ * @hashtable: hashtable to check
+ *
+ * This has to be a macro since HASH_BITS() will not work on pointers since
+ * it calculates the size during preprocessing.
+ */
+#define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable))
+
+/**
+ * hash_del - remove an object from a hashtable
+ * @node: &struct hlist_node of the object to remove
+ */
+static inline void hash_del(struct hlist_node *node)
+{
+	hlist_del_init(node);
+}
+
+/**
+ * hash_del_rcu - remove an object from a rcu enabled hashtable
+ * @node: &struct hlist_node of the object to remove
+ */
+static inline void hash_del_rcu(struct hlist_node *node)
+{
+	hlist_del_init_rcu(node);
+}
+
+/**
+ * hash_for_each - iterate over a hashtable
+ * @name: hashtable to iterate
+ * @bkt: integer to use as bucket loop cursor
+ * @node: the &struct list_head to use as a loop cursor for each entry
+ * @obj: the type * to use as a loop cursor for each entry
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each(name, bkt, node, obj, member)				\
+	for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\
+		hlist_for_each_entry(obj, node, &name[bkt], member)
+
+/**
+ * hash_for_each_rcu - iterate over a rcu enabled hashtable
+ * @name: hashtable to iterate
+ * @bkt: integer to use as bucket loop cursor
+ * @node: the &struct list_head to use as a loop cursor for each entry
+ * @obj: the type * to use as a loop cursor for each entry
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each_rcu(name, bkt, node, obj, member)				\
+	for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\
+		hlist_for_each_entry_rcu(obj, node, &name[bkt], member)
+
+/**
+ * hash_for_each_safe - iterate over a hashtable safe against removal of
+ * hash entry
+ * @name: hashtable to iterate
+ * @bkt: integer to use as bucket loop cursor
+ * @node: the &struct list_head to use as a loop cursor for each entry
+ * @tmp: a &struct used for temporary storage
+ * @obj: the type * to use as a loop cursor for each entry
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each_safe(name, bkt, node, tmp, obj, member)			\
+	for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\
+		hlist_for_each_entry_safe(obj, node, tmp, &name[bkt], member)
+
+/**
+ * hash_for_each_possible - iterate over all possible objects hashing to the
+ * same bucket
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each entry
+ * @node: the &struct list_head to use as a loop cursor for each entry
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible(name, obj, node, member, key)			\
+	hlist_for_each_entry(obj, node,	&name[hash_min(key, HASH_BITS(name))], member)
+
+/**
+ * hash_for_each_possible_rcu - iterate over all possible objects hashing to the
+ * same bucket in an rcu enabled hashtable
+ * in a rcu enabled hashtable
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each entry
+ * @node: the &struct list_head to use as a loop cursor for each entry
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible_rcu(name, obj, node, member, key)		\
+	hlist_for_each_entry_rcu(obj, node, &name[hash_min(key, HASH_BITS(name))], member)
+
+/**
+ * hash_for_each_possible_safe - iterate over all possible objects hashing to the
+ * same bucket safe against removals
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each entry
+ * @node: the &struct list_head to use as a loop cursor for each entry
+ * @tmp: a &struct used for temporary storage
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible_safe(name, obj, node, tmp, member, key)		\
+	hlist_for_each_entry_safe(obj, node, tmp,				\
+		&name[hash_min(key, HASH_BITS(name))], member)
+
+
+#endif
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index c0ae76a..7806c24 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -618,4 +618,20 @@
 };
 #endif
 
+/**
+ * IIO_DEGREE_TO_RAD() - Convert degree to rad
+ * @deg: A value in degree
+ *
+ * Returns the given value converted from degree to rad
+ */
+#define IIO_DEGREE_TO_RAD(deg) (((deg) * 314159ULL + 9000000ULL) / 18000000ULL)
+
+/**
+ * IIO_G_TO_M_S_2() - Convert g to meter / second**2
+ * @g: A value in g
+ *
+ * Returns the given value converted from g to meter / second**2
+ */
+#define IIO_G_TO_M_S_2(g) ((g) * 980665ULL / 100000ULL)
+
 #endif /* _INDUSTRIAL_IO_H_ */
diff --git a/arch/arm/plat-mxc/include/mach/timex.h b/include/linux/irqchip/sunxi.h
similarity index 62%
copy from arch/arm/plat-mxc/include/mach/timex.h
copy to include/linux/irqchip/sunxi.h
index 10343d1..1fe2c22 100644
--- a/arch/arm/plat-mxc/include/mach/timex.h
+++ b/include/linux/irqchip/sunxi.h
@@ -1,6 +1,7 @@
 /*
- *  Copyright (C) 1999 ARM Limited
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -13,10 +14,14 @@
  * GNU General Public License for more details.
  */
 
-#ifndef __ASM_ARCH_MXC_TIMEX_H__
-#define __ASM_ARCH_MXC_TIMEX_H__
+#ifndef __LINUX_IRQCHIP_SUNXI_H
+#define __LINUX_IRQCHIP_SUNXI_H
 
-/* Bogus value */
-#define CLOCK_TICK_RATE	12345678
+#include <asm/exception.h>
 
-#endif				/* __ASM_ARCH_MXC_TIMEX_H__ */
+extern void sunxi_init_irq(void);
+
+extern asmlinkage void __exception_irq_entry sunxi_handle_irq(
+	struct pt_regs *regs);
+
+#endif
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 93bfc9f..ecc5543 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -42,19 +42,8 @@
  */
 #define KVM_MEMSLOT_INVALID	(1UL << 16)
 
-/*
- * If we support unaligned MMIO, at most one fragment will be split into two:
- */
-#ifdef KVM_UNALIGNED_MMIO
-#  define KVM_EXTRA_MMIO_FRAGMENTS 1
-#else
-#  define KVM_EXTRA_MMIO_FRAGMENTS 0
-#endif
-
-#define KVM_USER_MMIO_SIZE 8
-
-#define KVM_MAX_MMIO_FRAGMENTS \
-	(KVM_MMIO_SIZE / KVM_USER_MMIO_SIZE + KVM_EXTRA_MMIO_FRAGMENTS)
+/* Two fragments for cross MMIO pages. */
+#define KVM_MAX_MMIO_FRAGMENTS	2
 
 /*
  * For the normal pfn, the highest 12 bits should be zero,
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 569d67d..d452ee1 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -57,6 +57,7 @@
 int memblock_remove(phys_addr_t base, phys_addr_t size);
 int memblock_free(phys_addr_t base, phys_addr_t size);
 int memblock_reserve(phys_addr_t base, phys_addr_t size);
+void memblock_trim_memory(phys_addr_t align);
 
 #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
 void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn,
diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h
index b82f6ee..6ee4247 100644
--- a/include/linux/mfd/db8500-prcmu.h
+++ b/include/linux/mfd/db8500-prcmu.h
@@ -515,7 +515,6 @@
 enum ap_pwrst prcmu_get_xp70_current_state(void);
 bool prcmu_has_arm_maxopp(void);
 struct prcmu_fw_version *prcmu_get_fw_version(void);
-int prcmu_request_ape_opp_100_voltage(bool enable);
 int prcmu_release_usb_wakeup_state(void);
 void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep,
 	struct prcmu_auto_pm_config *idle);
@@ -564,6 +563,7 @@
 int db8500_prcmu_get_arm_opp(void);
 int db8500_prcmu_set_ape_opp(u8 opp);
 int db8500_prcmu_get_ape_opp(void);
+int db8500_prcmu_request_ape_opp_100_voltage(bool enable);
 int db8500_prcmu_set_ddr_opp(u8 opp);
 int db8500_prcmu_get_ddr_opp(void);
 
@@ -610,7 +610,7 @@
 	return APE_100_OPP;
 }
 
-static inline int prcmu_request_ape_opp_100_voltage(bool enable)
+static inline int db8500_prcmu_request_ape_opp_100_voltage(bool enable)
 {
 	return 0;
 }
diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h
index c410d99..c202d6c 100644
--- a/include/linux/mfd/dbx500-prcmu.h
+++ b/include/linux/mfd/dbx500-prcmu.h
@@ -336,6 +336,11 @@
 	return db8500_prcmu_get_ape_opp();
 }
 
+static inline int prcmu_request_ape_opp_100_voltage(bool enable)
+{
+	return db8500_prcmu_request_ape_opp_100_voltage(enable);
+}
+
 static inline void prcmu_system_reset(u16 reset_code)
 {
 	return db8500_prcmu_system_reset(reset_code);
@@ -507,6 +512,11 @@
 	return APE_100_OPP;
 }
 
+static inline int prcmu_request_ape_opp_100_voltage(bool enable)
+{
+	return 0;
+}
+
 static inline int prcmu_set_arm_opp(u8 opp)
 {
 	return 0;
diff --git a/include/linux/mfd/max77693.h b/include/linux/mfd/max77693.h
index 1d28ae9..fe03b2d 100644
--- a/include/linux/mfd/max77693.h
+++ b/include/linux/mfd/max77693.h
@@ -30,7 +30,20 @@
 #ifndef __LINUX_MFD_MAX77693_H
 #define __LINUX_MFD_MAX77693_H
 
+struct max77693_reg_data {
+	u8 addr;
+	u8 data;
+};
+
+struct max77693_muic_platform_data {
+	struct max77693_reg_data *init_data;
+	int num_init_data;
+};
+
 struct max77693_platform_data {
 	int wakeup;
+
+	/* muic data */
+	struct max77693_muic_platform_data *muic_data;
 };
 #endif	/* __LINUX_MFD_MAX77693_H */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index fa06804..bcaab4e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1684,9 +1684,5 @@
 static inline bool page_is_guard(struct page *page) { return false; }
 #endif /* CONFIG_DEBUG_PAGEALLOC */
 
-extern void reset_zone_present_pages(void);
-extern void fixup_zone_present_pages(int nid, unsigned long start_pfn,
-				unsigned long end_pfn);
-
 #endif /* __KERNEL__ */
 #endif /* _LINUX_MM_H */
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 7c6a113..9653166 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -137,7 +137,7 @@
 
 	dma_addr_t		sg_dma;
 	void			*sg_cpu;
-	struct dw_mci_dma_ops	*dma_ops;
+	const struct dw_mci_dma_ops	*dma_ops;
 #ifdef CONFIG_MMC_DW_IDMAC
 	unsigned int		ring_size;
 #else
@@ -162,7 +162,7 @@
 	u16			data_offset;
 	struct device		*dev;
 	struct dw_mci_board	*pdata;
-	struct dw_mci_drv_data	*drv_data;
+	const struct dw_mci_drv_data	*drv_data;
 	void			*priv;
 	struct clk		*biu_clk;
 	struct clk		*ciu_clk;
@@ -186,7 +186,7 @@
 
 	struct regulator	*vmmc;	/* Power regulator */
 	unsigned long		irq_flags; /* IRQ flags */
-	unsigned int		irq;
+	int			irq;
 };
 
 /* DMA ops for Internal/External DMAC interface */
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index fa8529a..1edcb4d 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -91,6 +91,7 @@
 	unsigned int quirks2;	/* More deviations from spec. */
 
 #define SDHCI_QUIRK2_HOST_OFF_CARD_ON			(1<<0)
+#define SDHCI_QUIRK2_HOST_NO_CMD23			(1<<1)
 
 	int irq;		/* Device IRQ */
 	void __iomem *ioaddr;	/* Mapped address */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 50aaca8..a23923b 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -752,7 +752,7 @@
 				     unsigned long size,
 				     enum memmap_context context);
 
-extern void lruvec_init(struct lruvec *lruvec, struct zone *zone);
+extern void lruvec_init(struct lruvec *lruvec);
 
 static inline struct zone *lruvec_zone(struct lruvec *lruvec)
 {
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index a1984dd..e20e3af 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -28,11 +28,13 @@
 #endif
 
 #else /* CONFIG_OF_ADDRESS */
+#ifndef of_address_to_resource
 static inline int of_address_to_resource(struct device_node *dev, int index,
 					 struct resource *r)
 {
 	return -EINVAL;
 }
+#endif
 static inline struct device_node *of_find_matching_node_by_address(
 					struct device_node *from,
 					const struct of_device_id *matches,
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h
index cf80f7e..250a4ac 100644
--- a/include/linux/percpu-rwsem.h
+++ b/include/linux/percpu-rwsem.h
@@ -12,34 +12,27 @@
 	struct mutex mtx;
 };
 
+#define light_mb()	barrier()
+#define heavy_mb()	synchronize_sched()
+
 static inline void percpu_down_read(struct percpu_rw_semaphore *p)
 {
-	rcu_read_lock();
+	rcu_read_lock_sched();
 	if (unlikely(p->locked)) {
-		rcu_read_unlock();
+		rcu_read_unlock_sched();
 		mutex_lock(&p->mtx);
 		this_cpu_inc(*p->counters);
 		mutex_unlock(&p->mtx);
 		return;
 	}
 	this_cpu_inc(*p->counters);
-	rcu_read_unlock();
+	rcu_read_unlock_sched();
+	light_mb(); /* A, between read of p->locked and read of data, paired with D */
 }
 
 static inline void percpu_up_read(struct percpu_rw_semaphore *p)
 {
-	/*
-	 * On X86, write operation in this_cpu_dec serves as a memory unlock
-	 * barrier (i.e. memory accesses may be moved before the write, but
-	 * no memory accesses are moved past the write).
-	 * On other architectures this may not be the case, so we need smp_mb()
-	 * there.
-	 */
-#if defined(CONFIG_X86) && (!defined(CONFIG_X86_PPRO_FENCE) && !defined(CONFIG_X86_OOSTORE))
-	barrier();
-#else
-	smp_mb();
-#endif
+	light_mb(); /* B, between read of the data and write to p->counter, paired with C */
 	this_cpu_dec(*p->counters);
 }
 
@@ -58,14 +51,15 @@
 {
 	mutex_lock(&p->mtx);
 	p->locked = true;
-	synchronize_rcu();
+	synchronize_sched(); /* make sure that all readers exit the rcu_read_lock_sched region */
 	while (__percpu_count(p->counters))
 		msleep(1);
-	smp_rmb(); /* paired with smp_mb() in percpu_sem_up_read() */
+	heavy_mb(); /* C, between read of p->counter and write to data, paired with B */
 }
 
 static inline void percpu_up_write(struct percpu_rw_semaphore *p)
 {
+	heavy_mb(); /* D, between write to data and write to p->locked, paired with A */
 	p->locked = false;
 	mutex_unlock(&p->mtx);
 }
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 2e90235..6bfb2faa 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -803,12 +803,16 @@
 do {									\
 	static struct notifier_block fn##_nb __cpuinitdata =		\
 		{ .notifier_call = fn, .priority = CPU_PRI_PERF };	\
+	unsigned long cpu = smp_processor_id();				\
+	unsigned long flags;						\
 	fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE,			\
-		(void *)(unsigned long)smp_processor_id());		\
+		(void *)(unsigned long)cpu);				\
+	local_irq_save(flags);						\
 	fn(&fn##_nb, (unsigned long)CPU_STARTING,			\
-		(void *)(unsigned long)smp_processor_id());		\
+		(void *)(unsigned long)cpu);				\
+	local_irq_restore(flags);					\
 	fn(&fn##_nb, (unsigned long)CPU_ONLINE,				\
-		(void *)(unsigned long)smp_processor_id());		\
+		(void *)(unsigned long)cpu);				\
 	register_cpu_notifier(&fn##_nb);				\
 } while (0)
 
diff --git a/include/linux/platform_data/asoc-imx-ssi.h b/include/linux/platform_data/asoc-imx-ssi.h
index 63f3c28..92c7fd7 100644
--- a/include/linux/platform_data/asoc-imx-ssi.h
+++ b/include/linux/platform_data/asoc-imx-ssi.h
@@ -17,5 +17,7 @@
 	void (*ac97_warm_reset)(struct snd_ac97 *ac97);
 };
 
+extern int mxc_set_irq_fiq(unsigned int irq, unsigned int type);
+
 #endif /* __MACH_SSI_H */
 
diff --git a/include/linux/platform_data/dma-imx.h b/include/linux/platform_data/dma-imx.h
index 1b90803..f6d30cc 100644
--- a/include/linux/platform_data/dma-imx.h
+++ b/include/linux/platform_data/dma-imx.h
@@ -61,7 +61,9 @@
 static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
 {
 	return strstr(dev_name(chan->device->dev), "sdma") ||
-		!strcmp(dev_name(chan->device->dev), "imx-dma");
+		!strcmp(dev_name(chan->device->dev), "imx1-dma") ||
+		!strcmp(dev_name(chan->device->dev), "imx21-dma") ||
+		!strcmp(dev_name(chan->device->dev), "imx27-dma");
 }
 
 #endif
diff --git a/include/linux/platform_data/omap_ocp2scp.h b/include/linux/platform_data/omap_ocp2scp.h
new file mode 100644
index 0000000..5c6c393
--- /dev/null
+++ b/include/linux/platform_data/omap_ocp2scp.h
@@ -0,0 +1,31 @@
+/*
+ * omap_ocp2scp.h -- ocp2scp header file
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DRIVERS_OMAP_OCP2SCP_H
+#define __DRIVERS_OMAP_OCP2SCP_H
+
+struct omap_ocp2scp_dev {
+	const char			*drv_name;
+	struct resource			*res;
+};
+
+struct omap_ocp2scp_platform_data {
+	int				dev_cnt;
+	struct omap_ocp2scp_dev		**devices;
+};
+#endif /* __DRIVERS_OMAP_OCP2SCP_H */
diff --git a/include/linux/platform_data/uio_pruss.h b/include/linux/platform_data/uio_pruss.h
index f39140a..3d47d21 100644
--- a/include/linux/platform_data/uio_pruss.h
+++ b/include/linux/platform_data/uio_pruss.h
@@ -20,6 +20,7 @@
 
 /* To configure the PRUSS INTC base offset for UIO driver */
 struct uio_pruss_pdata {
-	u32	pintc_base;
+	u32		pintc_base;
+	struct gen_pool *sram_pool;
 };
 #endif /* _UIO_PRUSS_H_ */
diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h
index f2dc6d8..38a9935 100644
--- a/include/linux/ptp_clock_kernel.h
+++ b/include/linux/ptp_clock_kernel.h
@@ -54,7 +54,8 @@
  * clock operations
  *
  * @adjfreq:  Adjusts the frequency of the hardware clock.
- *            parameter delta: Desired period change in parts per billion.
+ *            parameter delta: Desired frequency offset from nominal frequency
+ *            in parts per billion
  *
  * @adjtime:  Shifts the time of the hardware clock.
  *            parameter delta: Desired change in nanoseconds.
diff --git a/include/linux/raid/Kbuild b/include/linux/raid/Kbuild
index 2415a64..e69de29 100644
--- a/include/linux/raid/Kbuild
+++ b/include/linux/raid/Kbuild
@@ -1,2 +0,0 @@
-header-y += md_p.h
-header-y += md_u.h
diff --git a/include/linux/raid/md_u.h b/include/linux/raid/md_u.h
index fb1abb3..358c04b 100644
--- a/include/linux/raid/md_u.h
+++ b/include/linux/raid/md_u.h
@@ -11,149 +11,10 @@
    (for example /usr/src/linux/COPYING); if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
 */
-
 #ifndef _MD_U_H
 #define _MD_U_H
 
-/*
- * Different major versions are not compatible.
- * Different minor versions are only downward compatible.
- * Different patchlevel versions are downward and upward compatible.
- */
-#define MD_MAJOR_VERSION                0
-#define MD_MINOR_VERSION                90
-/*
- * MD_PATCHLEVEL_VERSION indicates kernel functionality.
- * >=1 means different superblock formats are selectable using SET_ARRAY_INFO
- *     and major_version/minor_version accordingly
- * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT
- *     in the super status byte
- * >=3 means that bitmap superblock version 4 is supported, which uses
- *     little-ending representation rather than host-endian
- */
-#define MD_PATCHLEVEL_VERSION           3
+#include <uapi/linux/raid/md_u.h>
 
-/* ioctls */
-
-/* status */
-#define RAID_VERSION		_IOR (MD_MAJOR, 0x10, mdu_version_t)
-#define GET_ARRAY_INFO		_IOR (MD_MAJOR, 0x11, mdu_array_info_t)
-#define GET_DISK_INFO		_IOR (MD_MAJOR, 0x12, mdu_disk_info_t)
-#define PRINT_RAID_DEBUG	_IO (MD_MAJOR, 0x13)
-#define RAID_AUTORUN		_IO (MD_MAJOR, 0x14)
-#define GET_BITMAP_FILE		_IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t)
-
-/* configuration */
-#define CLEAR_ARRAY		_IO (MD_MAJOR, 0x20)
-#define ADD_NEW_DISK		_IOW (MD_MAJOR, 0x21, mdu_disk_info_t)
-#define HOT_REMOVE_DISK		_IO (MD_MAJOR, 0x22)
-#define SET_ARRAY_INFO		_IOW (MD_MAJOR, 0x23, mdu_array_info_t)
-#define SET_DISK_INFO		_IO (MD_MAJOR, 0x24)
-#define WRITE_RAID_INFO		_IO (MD_MAJOR, 0x25)
-#define UNPROTECT_ARRAY		_IO (MD_MAJOR, 0x26)
-#define PROTECT_ARRAY		_IO (MD_MAJOR, 0x27)
-#define HOT_ADD_DISK		_IO (MD_MAJOR, 0x28)
-#define SET_DISK_FAULTY		_IO (MD_MAJOR, 0x29)
-#define HOT_GENERATE_ERROR	_IO (MD_MAJOR, 0x2a)
-#define SET_BITMAP_FILE		_IOW (MD_MAJOR, 0x2b, int)
-
-/* usage */
-#define RUN_ARRAY		_IOW (MD_MAJOR, 0x30, mdu_param_t)
-/*  0x31 was START_ARRAY  */
-#define STOP_ARRAY		_IO (MD_MAJOR, 0x32)
-#define STOP_ARRAY_RO		_IO (MD_MAJOR, 0x33)
-#define RESTART_ARRAY_RW	_IO (MD_MAJOR, 0x34)
-
-/* 63 partitions with the alternate major number (mdp) */
-#define MdpMinorShift 6
-#ifdef __KERNEL__
 extern int mdp_major;
-#endif
-
-typedef struct mdu_version_s {
-	int major;
-	int minor;
-	int patchlevel;
-} mdu_version_t;
-
-typedef struct mdu_array_info_s {
-	/*
-	 * Generic constant information
-	 */
-	int major_version;
-	int minor_version;
-	int patch_version;
-	int ctime;
-	int level;
-	int size;
-	int nr_disks;
-	int raid_disks;
-	int md_minor;
-	int not_persistent;
-
-	/*
-	 * Generic state information
-	 */
-	int utime;		/*  0 Superblock update time		      */
-	int state;		/*  1 State bits (clean, ...)		      */
-	int active_disks;	/*  2 Number of currently active disks	      */
-	int working_disks;	/*  3 Number of working disks		      */
-	int failed_disks;	/*  4 Number of failed disks		      */
-	int spare_disks;	/*  5 Number of spare disks		      */
-
-	/*
-	 * Personality information
-	 */
-	int layout;		/*  0 the array's physical layout	      */
-	int chunk_size;	/*  1 chunk size in bytes		      */
-
-} mdu_array_info_t;
-
-/* non-obvious values for 'level' */
-#define	LEVEL_MULTIPATH		(-4)
-#define	LEVEL_LINEAR		(-1)
-#define	LEVEL_FAULTY		(-5)
-
-/* we need a value for 'no level specified' and 0
- * means 'raid0', so we need something else.  This is
- * for internal use only
- */
-#define	LEVEL_NONE		(-1000000)
-
-typedef struct mdu_disk_info_s {
-	/*
-	 * configuration/status of one particular disk
-	 */
-	int number;
-	int major;
-	int minor;
-	int raid_disk;
-	int state;
-
-} mdu_disk_info_t;
-
-typedef struct mdu_start_info_s {
-	/*
-	 * configuration/status of one particular disk
-	 */
-	int major;
-	int minor;
-	int raid_disk;
-	int state;
-
-} mdu_start_info_t;
-
-typedef struct mdu_bitmap_file_s
-{
-	char pathname[4096];
-} mdu_bitmap_file_t;
-
-typedef struct mdu_param_s
-{
-	int			personality;	/* 1,2,3,4 */
-	int			chunk_size;	/* in bytes */
-	int			max_fault;	/* unused for now */
-} mdu_param_t;
-
 #endif 
-
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h
index 214caa3..2ac60c9 100644
--- a/include/linux/rbtree_augmented.h
+++ b/include/linux/rbtree_augmented.h
@@ -24,6 +24,7 @@
 #ifndef _LINUX_RBTREE_AUGMENTED_H
 #define _LINUX_RBTREE_AUGMENTED_H
 
+#include <linux/compiler.h>
 #include <linux/rbtree.h>
 
 /*
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 4187da5..a3e7842 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -275,9 +275,11 @@
  * struct rio_net - RIO network info
  * @node: Node in global list of RIO networks
  * @devices: List of devices in this network
+ * @switches: List of switches in this netowrk
  * @mports: List of master ports accessing this network
  * @hport: Default port for accessing this network
  * @id: RIO network ID
+ * @destid_table: destID allocation table
  */
 struct rio_net {
 	struct list_head node;	/* node in list of networks */
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h
index 5091091..60c7239 100644
--- a/include/linux/sh_clk.h
+++ b/include/linux/sh_clk.h
@@ -199,4 +199,13 @@
 #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
 #define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
 
+/* .enable_reg will be updated to .mapping on sh_clk_fsidiv_register() */
+#define SH_CLK_FSIDIV(_reg, _parent)		\
+{						\
+	.enable_reg = (void __iomem *)_reg,	\
+	.parent		= _parent,		\
+}
+
+int sh_clk_fsidiv_register(struct clk *clks, int nr);
+
 #endif /* __SH_CLOCK_H */
diff --git a/include/linux/spi/tsc2005.h b/include/linux/spi/tsc2005.h
index d9b0c84..8f721e4 100644
--- a/include/linux/spi/tsc2005.h
+++ b/include/linux/spi/tsc2005.h
@@ -3,8 +3,6 @@
  *
  * Copyright (C) 2009-2010 Nokia Corporation
  *
- * Contact: Aaro Koskinen <aaro.koskinen@nokia.com>
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
diff --git a/arch/arm/plat-mxc/include/mach/timex.h b/include/linux/sunxi_timer.h
similarity index 65%
rename from arch/arm/plat-mxc/include/mach/timex.h
rename to include/linux/sunxi_timer.h
index 10343d1..b9165bb 100644
--- a/arch/arm/plat-mxc/include/mach/timex.h
+++ b/include/linux/sunxi_timer.h
@@ -1,6 +1,7 @@
 /*
- *  Copyright (C) 1999 ARM Limited
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -13,10 +14,11 @@
  * GNU General Public License for more details.
  */
 
-#ifndef __ASM_ARCH_MXC_TIMEX_H__
-#define __ASM_ARCH_MXC_TIMEX_H__
+#ifndef __SUNXI_TIMER_H
+#define __SUNXI_TIMER_H
 
-/* Bogus value */
-#define CLOCK_TICK_RATE	12345678
+#include <asm/mach/time.h>
 
-#endif				/* __ASM_ARCH_MXC_TIMEX_H__ */
+extern struct sys_timer sunxi_timer;
+
+#endif
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 8a7fc4b..60b7aac 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -191,7 +191,8 @@
 	u8	do_early_retrans:1,/* Enable RFC5827 early-retransmit  */
 		early_retrans_delayed:1, /* Delayed ER timer installed */
 		syn_data:1,	/* SYN includes data */
-		syn_fastopen:1;	/* SYN includes Fast Open option */
+		syn_fastopen:1,	/* SYN includes Fast Open option */
+		syn_data_acked:1;/* data in SYN is acked by SYN-ACK */
 
 /* RTT measurement */
 	u32	srtt;		/* smoothed round trip time << 3	*/
diff --git a/arch/arm/mach-tegra/include/mach/tegra-ahb.h b/include/linux/tegra-ahb.h
similarity index 86%
rename from arch/arm/mach-tegra/include/mach/tegra-ahb.h
rename to include/linux/tegra-ahb.h
index e0f8c84..f1cd075 100644
--- a/arch/arm/mach-tegra/include/mach/tegra-ahb.h
+++ b/include/linux/tegra-ahb.h
@@ -11,9 +11,9 @@
  * more details.
  */
 
-#ifndef __MACH_TEGRA_AHB_H__
-#define __MACH_TEGRA_AHB_H__
+#ifndef __LINUX_AHB_H__
+#define __LINUX_AHB_H__
 
 extern int tegra_ahb_enable_smmu(struct device_node *ahb);
 
-#endif	/* __MACH_TEGRA_AHB_H__ */
+#endif	/* __LINUX_AHB_H__ */
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index e6f0331..2459457 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -35,16 +35,6 @@
 # include <asm/uprobes.h>
 #endif
 
-/* flags that denote/change uprobes behaviour */
-
-/* Have a copy of original instruction */
-#define UPROBE_COPY_INSN	0x1
-
-/* Dont run handlers when first register/ last unregister in progress*/
-#define UPROBE_RUN_HANDLER	0x2
-/* Can skip singlestep */
-#define UPROBE_SKIP_SSTEP	0x4
-
 struct uprobe_consumer {
 	int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs);
 	/*
@@ -59,7 +49,6 @@
 #ifdef CONFIG_UPROBES
 enum uprobe_task_state {
 	UTASK_RUNNING,
-	UTASK_BP_HIT,
 	UTASK_SSTEP,
 	UTASK_SSTEP_ACK,
 	UTASK_SSTEP_TRAPPED,
diff --git a/include/linux/vexpress.h b/include/linux/vexpress.h
new file mode 100644
index 0000000..c52215f
--- /dev/null
+++ b/include/linux/vexpress.h
@@ -0,0 +1,121 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#ifndef _LINUX_VEXPRESS_H
+#define _LINUX_VEXPRESS_H
+
+#include <linux/device.h>
+
+#define VEXPRESS_SITE_MB		0
+#define VEXPRESS_SITE_DB1		1
+#define VEXPRESS_SITE_DB2		2
+#define VEXPRESS_SITE_MASTER		0xf
+
+#define VEXPRESS_CONFIG_STATUS_DONE	0
+#define VEXPRESS_CONFIG_STATUS_WAIT	1
+
+#define VEXPRESS_GPIO_MMC_CARDIN	0
+#define VEXPRESS_GPIO_MMC_WPROT		1
+#define VEXPRESS_GPIO_FLASH_WPn		2
+
+#define VEXPRESS_RES_FUNC(_site, _func)	\
+{					\
+	.start = (_site),		\
+	.end = (_func),			\
+	.flags = IORESOURCE_BUS,	\
+}
+
+/* Config bridge API */
+
+/**
+ * struct vexpress_config_bridge_info - description of the platform
+ * configuration infrastructure bridge.
+ *
+ * @name:	Bridge name
+ *
+ * @func_get:	Obtains pointer to a configuration function for a given
+ *		device or a Device Tree node, to be used with @func_put
+ *		and @func_exec. The node pointer should take precedence
+ *		over device pointer when both are passed.
+ *
+ * @func_put:	Tells the bridge that the function will not be used any
+ *		more, so all allocated resources can be released.
+ *
+ * @func_exec:	Executes a configuration function read or write operation.
+ *		The offset selects a 32 bit word of the value accessed.
+ *		Must return VEXPRESS_CONFIG_STATUS_DONE when operation
+ *		is finished immediately, VEXPRESS_CONFIG_STATUS_WAIT when
+ *		will be completed in some time or negative value in case
+ *		of error.
+ */
+struct vexpress_config_bridge_info {
+	const char *name;
+	void *(*func_get)(struct device *dev, struct device_node *node);
+	void (*func_put)(void *func);
+	int (*func_exec)(void *func, int offset, bool write, u32 *data);
+};
+
+struct vexpress_config_bridge;
+
+struct vexpress_config_bridge *vexpress_config_bridge_register(
+		struct device_node *node,
+		struct vexpress_config_bridge_info *info);
+void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge);
+
+void vexpress_config_complete(struct vexpress_config_bridge *bridge,
+		int status);
+
+/* Config function API */
+
+struct vexpress_config_func;
+
+struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
+		struct device_node *node);
+#define vexpress_config_func_get_by_dev(dev) \
+		__vexpress_config_func_get(dev, NULL)
+#define vexpress_config_func_get_by_node(node) \
+		__vexpress_config_func_get(NULL, node)
+void vexpress_config_func_put(struct vexpress_config_func *func);
+
+/* Both may sleep! */
+int vexpress_config_read(struct vexpress_config_func *func, int offset,
+		u32 *data);
+int vexpress_config_write(struct vexpress_config_func *func, int offset,
+		u32 data);
+
+/* Platform control */
+
+u32 vexpress_get_procid(int site);
+u32 vexpress_get_hbi(int site);
+void *vexpress_get_24mhz_clock_base(void);
+void vexpress_flags_set(u32 data);
+
+#define vexpress_get_site_by_node(node) __vexpress_get_site(NULL, node)
+#define vexpress_get_site_by_dev(dev) __vexpress_get_site(dev, NULL)
+unsigned __vexpress_get_site(struct device *dev, struct device_node *node);
+
+void vexpress_sysreg_early_init(void __iomem *base);
+void vexpress_sysreg_of_early_init(void);
+
+void vexpress_power_off(void);
+void vexpress_restart(char str, const char *cmd);
+
+/* Clocks */
+
+struct clk *vexpress_osc_setup(struct device *dev);
+void vexpress_osc_of_setup(struct device_node *node);
+
+void vexpress_clk_init(void __iomem *sp810_base);
+void vexpress_clk_of_init(void);
+
+#endif
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1b49890..7d5b600 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1218,6 +1218,7 @@
 	const u8 *ie;
 	size_t ie_len;
 	u16 reason_code;
+	bool local_state_change;
 };
 
 /**
@@ -2651,6 +2652,15 @@
 unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);
 
 /**
+ * ieee80211_get_mesh_hdrlen - get mesh extension header length
+ * @meshhdr: the mesh extension header, only the flags field
+ *	(first byte) will be accessed
+ * Returns the length of the extension header, which is always at
+ * least 6 bytes and at most 18 if address 5 and 6 are present.
+ */
+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
+
+/**
  * DOC: Data path helpers
  *
  * In addition to generic utilities, cfg80211 also offers
diff --git a/include/sound/core.h b/include/sound/core.h
index bc05668..93896ad 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -132,6 +132,7 @@
 	int shutdown;			/* this card is going down */
 	int free_on_last_close;		/* free in context of file_release */
 	wait_queue_head_t shutdown_sleep;
+	atomic_t refcount;		/* refcount for disconnection */
 	struct device *dev;		/* device assigned to this card */
 	struct device *card_dev;	/* cardX object for sysfs */
 
@@ -189,6 +190,7 @@
 	const struct file_operations *f_ops;	/* file operations */
 	void *private_data;		/* private data for f_ops->open */
 	struct device *dev;		/* device for sysfs */
+	struct snd_card *card_ptr;	/* assigned card instance */
 };
 
 /* return a device pointer linked to each sound device as a parent */
@@ -295,6 +297,7 @@
 int snd_component_add(struct snd_card *card, const char *component);
 int snd_card_file_add(struct snd_card *card, struct file *file);
 int snd_card_file_remove(struct snd_card *card, struct file *file);
+void snd_card_unref(struct snd_card *card);
 
 #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
 
diff --git a/include/trace/events/xen.h b/include/trace/events/xen.h
index 15ba03b..d06b6da 100644
--- a/include/trace/events/xen.h
+++ b/include/trace/events/xen.h
@@ -377,6 +377,14 @@
 DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin);
 DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin);
 
+TRACE_EVENT(xen_mmu_flush_tlb_all,
+	    TP_PROTO(int x),
+	    TP_ARGS(x),
+	    TP_STRUCT__entry(__array(char, x, 0)),
+	    TP_fast_assign((void)x),
+	    TP_printk("%s", "")
+	);
+
 TRACE_EVENT(xen_mmu_flush_tlb,
 	    TP_PROTO(int x),
 	    TP_ARGS(x),
diff --git a/include/uapi/linux/eventpoll.h b/include/uapi/linux/eventpoll.h
index 8c99ce7..2c267bc 100644
--- a/include/uapi/linux/eventpoll.h
+++ b/include/uapi/linux/eventpoll.h
@@ -25,7 +25,6 @@
 #define EPOLL_CTL_ADD 1
 #define EPOLL_CTL_DEL 2
 #define EPOLL_CTL_MOD 3
-#define EPOLL_CTL_DISABLE 4
 
 /*
  * Request the handling of system wakeup events so as to prevent system suspends
diff --git a/include/uapi/linux/oom.h b/include/uapi/linux/oom.h
index a49c4af..b29272d 100644
--- a/include/uapi/linux/oom.h
+++ b/include/uapi/linux/oom.h
@@ -8,4 +8,13 @@
 #define OOM_SCORE_ADJ_MIN	(-1000)
 #define OOM_SCORE_ADJ_MAX	1000
 
+/*
+ * /proc/<pid>/oom_adj set to -17 protects from the oom killer for legacy
+ * purposes.
+ */
+#define OOM_DISABLE (-17)
+/* inclusive */
+#define OOM_ADJUST_MIN (-16)
+#define OOM_ADJUST_MAX 15
+
 #endif /* _UAPI__INCLUDE_LINUX_OOM_H */
diff --git a/include/uapi/linux/raid/Kbuild b/include/uapi/linux/raid/Kbuild
index aafaa5a..e2c3d25 100644
--- a/include/uapi/linux/raid/Kbuild
+++ b/include/uapi/linux/raid/Kbuild
@@ -1 +1,3 @@
 # UAPI Header export list
+header-y += md_p.h
+header-y += md_u.h
diff --git a/include/linux/raid/md_p.h b/include/uapi/linux/raid/md_p.h
similarity index 100%
rename from include/linux/raid/md_p.h
rename to include/uapi/linux/raid/md_p.h
diff --git a/include/uapi/linux/raid/md_u.h b/include/uapi/linux/raid/md_u.h
new file mode 100644
index 0000000..4133e74
--- /dev/null
+++ b/include/uapi/linux/raid/md_u.h
@@ -0,0 +1,155 @@
+/*
+   md_u.h : user <=> kernel API between Linux raidtools and RAID drivers
+          Copyright (C) 1998 Ingo Molnar
+	  
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+   
+   You should have received a copy of the GNU General Public License
+   (for example /usr/src/linux/COPYING); if not, write to the Free
+   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
+*/
+
+#ifndef _UAPI_MD_U_H
+#define _UAPI_MD_U_H
+
+/*
+ * Different major versions are not compatible.
+ * Different minor versions are only downward compatible.
+ * Different patchlevel versions are downward and upward compatible.
+ */
+#define MD_MAJOR_VERSION                0
+#define MD_MINOR_VERSION                90
+/*
+ * MD_PATCHLEVEL_VERSION indicates kernel functionality.
+ * >=1 means different superblock formats are selectable using SET_ARRAY_INFO
+ *     and major_version/minor_version accordingly
+ * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT
+ *     in the super status byte
+ * >=3 means that bitmap superblock version 4 is supported, which uses
+ *     little-ending representation rather than host-endian
+ */
+#define MD_PATCHLEVEL_VERSION           3
+
+/* ioctls */
+
+/* status */
+#define RAID_VERSION		_IOR (MD_MAJOR, 0x10, mdu_version_t)
+#define GET_ARRAY_INFO		_IOR (MD_MAJOR, 0x11, mdu_array_info_t)
+#define GET_DISK_INFO		_IOR (MD_MAJOR, 0x12, mdu_disk_info_t)
+#define PRINT_RAID_DEBUG	_IO (MD_MAJOR, 0x13)
+#define RAID_AUTORUN		_IO (MD_MAJOR, 0x14)
+#define GET_BITMAP_FILE		_IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t)
+
+/* configuration */
+#define CLEAR_ARRAY		_IO (MD_MAJOR, 0x20)
+#define ADD_NEW_DISK		_IOW (MD_MAJOR, 0x21, mdu_disk_info_t)
+#define HOT_REMOVE_DISK		_IO (MD_MAJOR, 0x22)
+#define SET_ARRAY_INFO		_IOW (MD_MAJOR, 0x23, mdu_array_info_t)
+#define SET_DISK_INFO		_IO (MD_MAJOR, 0x24)
+#define WRITE_RAID_INFO		_IO (MD_MAJOR, 0x25)
+#define UNPROTECT_ARRAY		_IO (MD_MAJOR, 0x26)
+#define PROTECT_ARRAY		_IO (MD_MAJOR, 0x27)
+#define HOT_ADD_DISK		_IO (MD_MAJOR, 0x28)
+#define SET_DISK_FAULTY		_IO (MD_MAJOR, 0x29)
+#define HOT_GENERATE_ERROR	_IO (MD_MAJOR, 0x2a)
+#define SET_BITMAP_FILE		_IOW (MD_MAJOR, 0x2b, int)
+
+/* usage */
+#define RUN_ARRAY		_IOW (MD_MAJOR, 0x30, mdu_param_t)
+/*  0x31 was START_ARRAY  */
+#define STOP_ARRAY		_IO (MD_MAJOR, 0x32)
+#define STOP_ARRAY_RO		_IO (MD_MAJOR, 0x33)
+#define RESTART_ARRAY_RW	_IO (MD_MAJOR, 0x34)
+
+/* 63 partitions with the alternate major number (mdp) */
+#define MdpMinorShift 6
+
+typedef struct mdu_version_s {
+	int major;
+	int minor;
+	int patchlevel;
+} mdu_version_t;
+
+typedef struct mdu_array_info_s {
+	/*
+	 * Generic constant information
+	 */
+	int major_version;
+	int minor_version;
+	int patch_version;
+	int ctime;
+	int level;
+	int size;
+	int nr_disks;
+	int raid_disks;
+	int md_minor;
+	int not_persistent;
+
+	/*
+	 * Generic state information
+	 */
+	int utime;		/*  0 Superblock update time		      */
+	int state;		/*  1 State bits (clean, ...)		      */
+	int active_disks;	/*  2 Number of currently active disks	      */
+	int working_disks;	/*  3 Number of working disks		      */
+	int failed_disks;	/*  4 Number of failed disks		      */
+	int spare_disks;	/*  5 Number of spare disks		      */
+
+	/*
+	 * Personality information
+	 */
+	int layout;		/*  0 the array's physical layout	      */
+	int chunk_size;	/*  1 chunk size in bytes		      */
+
+} mdu_array_info_t;
+
+/* non-obvious values for 'level' */
+#define	LEVEL_MULTIPATH		(-4)
+#define	LEVEL_LINEAR		(-1)
+#define	LEVEL_FAULTY		(-5)
+
+/* we need a value for 'no level specified' and 0
+ * means 'raid0', so we need something else.  This is
+ * for internal use only
+ */
+#define	LEVEL_NONE		(-1000000)
+
+typedef struct mdu_disk_info_s {
+	/*
+	 * configuration/status of one particular disk
+	 */
+	int number;
+	int major;
+	int minor;
+	int raid_disk;
+	int state;
+
+} mdu_disk_info_t;
+
+typedef struct mdu_start_info_s {
+	/*
+	 * configuration/status of one particular disk
+	 */
+	int major;
+	int minor;
+	int raid_disk;
+	int state;
+
+} mdu_start_info_t;
+
+typedef struct mdu_bitmap_file_s
+{
+	char pathname[4096];
+} mdu_bitmap_file_t;
+
+typedef struct mdu_param_s
+{
+	int			personality;	/* 1,2,3,4 */
+	int			chunk_size;	/* in bytes */
+	int			max_fault;	/* unused for now */
+} mdu_param_t;
+
+#endif /* _UAPI_MD_U_H */
diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
index c4b89a5..e962faa 100644
--- a/include/uapi/linux/tcp.h
+++ b/include/uapi/linux/tcp.h
@@ -130,6 +130,7 @@
 #define TCPI_OPT_WSCALE		4
 #define TCPI_OPT_ECN		8 /* ECN was negociated at TCP session init */
 #define TCPI_OPT_ECN_SEEN	16 /* we received at least one packet with ECT */
+#define TCPI_OPT_SYN_DATA	32 /* SYN-ACK acked data in SYN sent or rcvd */
 
 enum tcp_ca_state {
 	TCP_CA_Open = 0,
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index aecee9d..694dcaf 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -170,7 +170,7 @@
 	unmap->dev_bus_addr = 0;
 }
 
-int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
+int arch_gnttab_map_shared(xen_pfn_t *frames, unsigned long nr_gframes,
 			   unsigned long max_nr_gframes,
 			   void **__shared);
 int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes,
diff --git a/include/xen/hvm.h b/include/xen/hvm.h
index b193fa2..13e43e4 100644
--- a/include/xen/hvm.h
+++ b/include/xen/hvm.h
@@ -5,6 +5,36 @@
 #include <xen/interface/hvm/params.h>
 #include <asm/xen/hypercall.h>
 
+static const char *param_name(int op)
+{
+#define PARAM(x) [HVM_PARAM_##x] = #x
+	static const char *const names[] = {
+		PARAM(CALLBACK_IRQ),
+		PARAM(STORE_PFN),
+		PARAM(STORE_EVTCHN),
+		PARAM(PAE_ENABLED),
+		PARAM(IOREQ_PFN),
+		PARAM(BUFIOREQ_PFN),
+		PARAM(TIMER_MODE),
+		PARAM(HPET_ENABLED),
+		PARAM(IDENT_PT),
+		PARAM(DM_DOMAIN),
+		PARAM(ACPI_S_STATE),
+		PARAM(VM86_TSS),
+		PARAM(VPT_ALIGN),
+		PARAM(CONSOLE_PFN),
+		PARAM(CONSOLE_EVTCHN),
+	};
+#undef PARAM
+
+	if (op >= ARRAY_SIZE(names))
+		return "unknown";
+
+	if (!names[op])
+		return "reserved";
+
+	return names[op];
+}
 static inline int hvm_get_parameter(int idx, uint64_t *value)
 {
 	struct xen_hvm_param xhv;
@@ -14,8 +44,8 @@
 	xhv.index = idx;
 	r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
 	if (r < 0) {
-		printk(KERN_ERR "Cannot get hvm parameter %d: %d!\n",
-			idx, r);
+		printk(KERN_ERR "Cannot get hvm parameter %s (%d): %d!\n",
+			param_name(idx), idx, r);
 		return r;
 	}
 	*value = xhv.value;
diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h
index f9f8b97..e40fae9 100644
--- a/include/xen/interface/grant_table.h
+++ b/include/xen/interface/grant_table.h
@@ -310,7 +310,7 @@
     uint32_t nr_frames;
     /* OUT parameters. */
     int16_t  status;              /* GNTST_* */
-    GUEST_HANDLE(ulong) frame_list;
+    GUEST_HANDLE(xen_pfn_t) frame_list;
 };
 DEFINE_GUEST_HANDLE_STRUCT(gnttab_setup_table);
 
diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h
index b66d04c..90712e2 100644
--- a/include/xen/interface/memory.h
+++ b/include/xen/interface/memory.h
@@ -179,28 +179,8 @@
 };
 DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
 
-/*
- * Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error
- * code on failure. This call only works for auto-translated guests.
- */
-#define XENMEM_translate_gpfn_list  8
-struct xen_translate_gpfn_list {
-    /* Which domain to translate for? */
-    domid_t domid;
-
-    /* Length of list. */
-    xen_ulong_t nr_gpfns;
-
-    /* List of GPFNs to translate. */
-    GUEST_HANDLE(ulong) gpfn_list;
-
-    /*
-     * Output list to contain MFN translations. May be the same as the input
-     * list (in which case each input GPFN is overwritten with the output MFN).
-     */
-    GUEST_HANDLE(ulong) mfn_list;
-};
-DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list);
+/*** REMOVED ***/
+/*#define XENMEM_translate_gpfn_list  8*/
 
 /*
  * Returns the pseudo-physical memory map as it was when the domain
diff --git a/init/main.c b/init/main.c
index 9cf77ab..e33e09d 100644
--- a/init/main.c
+++ b/init/main.c
@@ -442,9 +442,11 @@
 {
 }
 
+# if THREAD_SIZE >= PAGE_SIZE
 void __init __weak thread_info_cache_init(void)
 {
 }
+#endif
 
 /*
  * Set up kernel memory allocators
diff --git a/kernel/Makefile b/kernel/Makefile
index 0dfeca4..86e3285 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -174,10 +174,8 @@
 	@echo "###"
 	@echo "### If this takes a long time, you might wish to run rngd in the"
 	@echo "### background to keep the supply of entropy topped up.  It"
-	@echo "### needs to be run as root, and should use a hardware random"
-	@echo "### number generator if one is available, eg:"
-	@echo "###"
-	@echo "###     rngd -r /dev/hwrandom"
+	@echo "### needs to be run as root, and uses a hardware random"
+	@echo "### number generator if one is available."
 	@echo "###"
 	openssl req -new -nodes -utf8 $(sign_key_with_hash) -days 36500 -batch \
 		-x509 -config x509.genkey \
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 13774b3..f24f724 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1962,9 +1962,8 @@
 	 * trading it for newcg is protected by cgroup_mutex, we're safe to drop
 	 * it here; it will be freed under RCU.
 	 */
-	put_css_set(oldcg);
-
 	set_bit(CGRP_RELEASABLE, &oldcgrp->flags);
+	put_css_set(oldcg);
 }
 
 /**
@@ -4815,31 +4814,20 @@
  *
  * A pointer to the shared css_set was automatically copied in
  * fork.c by dup_task_struct().  However, we ignore that copy, since
- * it was not made under the protection of RCU, cgroup_mutex or
- * threadgroup_change_begin(), so it might no longer be a valid
- * cgroup pointer.  cgroup_attach_task() might have already changed
- * current->cgroups, allowing the previously referenced cgroup
- * group to be removed and freed.
- *
- * Outside the pointer validity we also need to process the css_set
- * inheritance between threadgoup_change_begin() and
- * threadgoup_change_end(), this way there is no leak in any process
- * wide migration performed by cgroup_attach_proc() that could otherwise
- * miss a thread because it is too early or too late in the fork stage.
+ * it was not made under the protection of RCU or cgroup_mutex, so
+ * might no longer be a valid cgroup pointer.  cgroup_attach_task() might
+ * have already changed current->cgroups, allowing the previously
+ * referenced cgroup group to be removed and freed.
  *
  * At the point that cgroup_fork() is called, 'current' is the parent
  * task, and the passed argument 'child' points to the child task.
  */
 void cgroup_fork(struct task_struct *child)
 {
-	/*
-	 * We don't need to task_lock() current because current->cgroups
-	 * can't be changed concurrently here. The parent obviously hasn't
-	 * exited and called cgroup_exit(), and we are synchronized against
-	 * cgroup migration through threadgroup_change_begin().
-	 */
+	task_lock(current);
 	child->cgroups = current->cgroups;
 	get_css_set(child->cgroups);
+	task_unlock(current);
 	INIT_LIST_HEAD(&child->cg_list);
 }
 
@@ -4895,19 +4883,10 @@
 	 */
 	if (use_task_css_set_links) {
 		write_lock(&css_set_lock);
-		if (list_empty(&child->cg_list)) {
-			/*
-			 * It's safe to use child->cgroups without task_lock()
-			 * here because we are protected through
-			 * threadgroup_change_begin() against concurrent
-			 * css_set change in cgroup_task_migrate(). Also
-			 * the task can't exit at that point until
-			 * wake_up_new_task() is called, so we are protected
-			 * against cgroup_exit() setting child->cgroup to
-			 * init_css_set.
-			 */
+		task_lock(child);
+		if (list_empty(&child->cg_list))
 			list_add(&child->cg_list, &child->cgroups->tasks);
-		}
+		task_unlock(child);
 		write_unlock(&css_set_lock);
 	}
 }
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 98256bc..5cc4e7e 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -78,15 +78,23 @@
  */
 static atomic_t uprobe_events = ATOMIC_INIT(0);
 
+/* Have a copy of original instruction */
+#define UPROBE_COPY_INSN	0
+/* Dont run handlers when first register/ last unregister in progress*/
+#define UPROBE_RUN_HANDLER	1
+/* Can skip singlestep */
+#define UPROBE_SKIP_SSTEP	2
+
 struct uprobe {
 	struct rb_node		rb_node;	/* node in the rb tree */
 	atomic_t		ref;
 	struct rw_semaphore	consumer_rwsem;
+	struct mutex		copy_mutex;	/* TODO: kill me and UPROBE_COPY_INSN */
 	struct list_head	pending_list;
 	struct uprobe_consumer	*consumers;
 	struct inode		*inode;		/* Also hold a ref to inode */
 	loff_t			offset;
-	int			flags;
+	unsigned long		flags;
 	struct arch_uprobe	arch;
 };
 
@@ -100,17 +108,12 @@
  */
 static bool valid_vma(struct vm_area_struct *vma, bool is_register)
 {
-	if (!vma->vm_file)
-		return false;
+	vm_flags_t flags = VM_HUGETLB | VM_MAYEXEC | VM_SHARED;
 
-	if (!is_register)
-		return true;
+	if (is_register)
+		flags |= VM_WRITE;
 
-	if ((vma->vm_flags & (VM_HUGETLB|VM_READ|VM_WRITE|VM_EXEC|VM_SHARED))
-				== (VM_READ|VM_EXEC))
-		return true;
-
-	return false;
+	return vma->vm_file && (vma->vm_flags & flags) == VM_MAYEXEC;
 }
 
 static unsigned long offset_to_vaddr(struct vm_area_struct *vma, loff_t offset)
@@ -193,19 +196,44 @@
 	return *insn == UPROBE_SWBP_INSN;
 }
 
+static void copy_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *opcode)
+{
+	void *kaddr = kmap_atomic(page);
+	memcpy(opcode, kaddr + (vaddr & ~PAGE_MASK), UPROBE_SWBP_INSN_SIZE);
+	kunmap_atomic(kaddr);
+}
+
+static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *new_opcode)
+{
+	uprobe_opcode_t old_opcode;
+	bool is_swbp;
+
+	copy_opcode(page, vaddr, &old_opcode);
+	is_swbp = is_swbp_insn(&old_opcode);
+
+	if (is_swbp_insn(new_opcode)) {
+		if (is_swbp)		/* register: already installed? */
+			return 0;
+	} else {
+		if (!is_swbp)		/* unregister: was it changed by us? */
+			return 0;
+	}
+
+	return 1;
+}
+
 /*
  * NOTE:
  * Expect the breakpoint instruction to be the smallest size instruction for
  * the architecture. If an arch has variable length instruction and the
  * breakpoint instruction is not of the smallest length instruction
- * supported by that architecture then we need to modify read_opcode /
+ * supported by that architecture then we need to modify is_swbp_at_addr and
  * write_opcode accordingly. This would never be a problem for archs that
  * have fixed length instructions.
  */
 
 /*
  * write_opcode - write the opcode at a given virtual address.
- * @auprobe: arch breakpointing information.
  * @mm: the probed process address space.
  * @vaddr: the virtual address to store the opcode.
  * @opcode: opcode to be written at @vaddr.
@@ -216,8 +244,8 @@
  * For mm @mm, write the opcode at @vaddr.
  * Return 0 (success) or a negative errno.
  */
-static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
-			unsigned long vaddr, uprobe_opcode_t opcode)
+static int write_opcode(struct mm_struct *mm, unsigned long vaddr,
+			uprobe_opcode_t opcode)
 {
 	struct page *old_page, *new_page;
 	void *vaddr_old, *vaddr_new;
@@ -226,10 +254,14 @@
 
 retry:
 	/* Read the page with vaddr into memory */
-	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma);
+	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &old_page, &vma);
 	if (ret <= 0)
 		return ret;
 
+	ret = verify_opcode(old_page, vaddr, &opcode);
+	if (ret <= 0)
+		goto put_old;
+
 	ret = -ENOMEM;
 	new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr);
 	if (!new_page)
@@ -264,63 +296,6 @@
 }
 
 /**
- * read_opcode - read the opcode at a given virtual address.
- * @mm: the probed process address space.
- * @vaddr: the virtual address to read the opcode.
- * @opcode: location to store the read opcode.
- *
- * Called with mm->mmap_sem held (for read and with a reference to
- * mm.
- *
- * For mm @mm, read the opcode at @vaddr and store it in @opcode.
- * Return 0 (success) or a negative errno.
- */
-static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t *opcode)
-{
-	struct page *page;
-	void *vaddr_new;
-	int ret;
-
-	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL);
-	if (ret <= 0)
-		return ret;
-
-	vaddr_new = kmap_atomic(page);
-	vaddr &= ~PAGE_MASK;
-	memcpy(opcode, vaddr_new + vaddr, UPROBE_SWBP_INSN_SIZE);
-	kunmap_atomic(vaddr_new);
-
-	put_page(page);
-
-	return 0;
-}
-
-static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr)
-{
-	uprobe_opcode_t opcode;
-	int result;
-
-	if (current->mm == mm) {
-		pagefault_disable();
-		result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr,
-								sizeof(opcode));
-		pagefault_enable();
-
-		if (likely(result == 0))
-			goto out;
-	}
-
-	result = read_opcode(mm, vaddr, &opcode);
-	if (result)
-		return result;
-out:
-	if (is_swbp_insn(&opcode))
-		return 1;
-
-	return 0;
-}
-
-/**
  * set_swbp - store breakpoint at a given address.
  * @auprobe: arch specific probepoint information.
  * @mm: the probed process address space.
@@ -331,18 +306,7 @@
  */
 int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
 {
-	int result;
-	/*
-	 * See the comment near uprobes_hash().
-	 */
-	result = is_swbp_at_addr(mm, vaddr);
-	if (result == 1)
-		return 0;
-
-	if (result)
-		return result;
-
-	return write_opcode(auprobe, mm, vaddr, UPROBE_SWBP_INSN);
+	return write_opcode(mm, vaddr, UPROBE_SWBP_INSN);
 }
 
 /**
@@ -357,16 +321,7 @@
 int __weak
 set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
 {
-	int result;
-
-	result = is_swbp_at_addr(mm, vaddr);
-	if (!result)
-		return -EINVAL;
-
-	if (result != 1)
-		return result;
-
-	return write_opcode(auprobe, mm, vaddr, *(uprobe_opcode_t *)auprobe->insn);
+	return write_opcode(mm, vaddr, *(uprobe_opcode_t *)auprobe->insn);
 }
 
 static int match_uprobe(struct uprobe *l, struct uprobe *r)
@@ -473,7 +428,7 @@
 	spin_unlock(&uprobes_treelock);
 
 	/* For now assume that the instruction need not be single-stepped */
-	uprobe->flags |= UPROBE_SKIP_SSTEP;
+	__set_bit(UPROBE_SKIP_SSTEP, &uprobe->flags);
 
 	return u;
 }
@@ -495,6 +450,7 @@
 	uprobe->inode = igrab(inode);
 	uprobe->offset = offset;
 	init_rwsem(&uprobe->consumer_rwsem);
+	mutex_init(&uprobe->copy_mutex);
 
 	/* add to uprobes_tree, sorted on inode:offset */
 	cur_uprobe = insert_uprobe(uprobe);
@@ -515,7 +471,7 @@
 {
 	struct uprobe_consumer *uc;
 
-	if (!(uprobe->flags & UPROBE_RUN_HANDLER))
+	if (!test_bit(UPROBE_RUN_HANDLER, &uprobe->flags))
 		return;
 
 	down_read(&uprobe->consumer_rwsem);
@@ -621,29 +577,43 @@
 	return __copy_insn(mapping, filp, uprobe->arch.insn, bytes, uprobe->offset);
 }
 
-/*
- * How mm->uprobes_state.count gets updated
- * uprobe_mmap() increments the count if
- * 	- it successfully adds a breakpoint.
- * 	- it cannot add a breakpoint, but sees that there is a underlying
- * 	  breakpoint (via a is_swbp_at_addr()).
- *
- * uprobe_munmap() decrements the count if
- * 	- it sees a underlying breakpoint, (via is_swbp_at_addr)
- * 	  (Subsequent uprobe_unregister wouldnt find the breakpoint
- * 	  unless a uprobe_mmap kicks in, since the old vma would be
- * 	  dropped just after uprobe_munmap.)
- *
- * uprobe_register increments the count if:
- * 	- it successfully adds a breakpoint.
- *
- * uprobe_unregister decrements the count if:
- * 	- it sees a underlying breakpoint and removes successfully.
- * 	  (via is_swbp_at_addr)
- * 	  (Subsequent uprobe_munmap wouldnt find the breakpoint
- * 	  since there is no underlying breakpoint after the
- * 	  breakpoint removal.)
- */
+static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
+				struct mm_struct *mm, unsigned long vaddr)
+{
+	int ret = 0;
+
+	if (test_bit(UPROBE_COPY_INSN, &uprobe->flags))
+		return ret;
+
+	mutex_lock(&uprobe->copy_mutex);
+	if (test_bit(UPROBE_COPY_INSN, &uprobe->flags))
+		goto out;
+
+	ret = copy_insn(uprobe, file);
+	if (ret)
+		goto out;
+
+	ret = -ENOTSUPP;
+	if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn))
+		goto out;
+
+	ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr);
+	if (ret)
+		goto out;
+
+	/* write_opcode() assumes we don't cross page boundary */
+	BUG_ON((uprobe->offset & ~PAGE_MASK) +
+			UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
+
+	smp_wmb(); /* pairs with rmb() in find_active_uprobe() */
+	set_bit(UPROBE_COPY_INSN, &uprobe->flags);
+
+ out:
+	mutex_unlock(&uprobe->copy_mutex);
+
+	return ret;
+}
+
 static int
 install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
 			struct vm_area_struct *vma, unsigned long vaddr)
@@ -661,24 +631,9 @@
 	if (!uprobe->consumers)
 		return 0;
 
-	if (!(uprobe->flags & UPROBE_COPY_INSN)) {
-		ret = copy_insn(uprobe, vma->vm_file);
-		if (ret)
-			return ret;
-
-		if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn))
-			return -ENOTSUPP;
-
-		ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr);
-		if (ret)
-			return ret;
-
-		/* write_opcode() assumes we don't cross page boundary */
-		BUG_ON((uprobe->offset & ~PAGE_MASK) +
-				UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
-
-		uprobe->flags |= UPROBE_COPY_INSN;
-	}
+	ret = prepare_uprobe(uprobe, vma->vm_file, mm, vaddr);
+	if (ret)
+		return ret;
 
 	/*
 	 * set MMF_HAS_UPROBES in advance for uprobe_pre_sstep_notifier(),
@@ -697,15 +652,15 @@
 	return ret;
 }
 
-static void
+static int
 remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vaddr)
 {
 	/* can happen if uprobe_register() fails */
 	if (!test_bit(MMF_HAS_UPROBES, &mm->flags))
-		return;
+		return 0;
 
 	set_bit(MMF_RECALC_UPROBES, &mm->flags);
-	set_orig_insn(&uprobe->arch, mm, vaddr);
+	return set_orig_insn(&uprobe->arch, mm, vaddr);
 }
 
 /*
@@ -820,7 +775,7 @@
 		struct mm_struct *mm = info->mm;
 		struct vm_area_struct *vma;
 
-		if (err)
+		if (err && is_register)
 			goto free;
 
 		down_write(&mm->mmap_sem);
@@ -836,7 +791,7 @@
 		if (is_register)
 			err = install_breakpoint(uprobe, mm, vma, info->vaddr);
 		else
-			remove_breakpoint(uprobe, mm, info->vaddr);
+			err |= remove_breakpoint(uprobe, mm, info->vaddr);
 
  unlock:
 		up_write(&mm->mmap_sem);
@@ -893,13 +848,15 @@
 	mutex_lock(uprobes_hash(inode));
 	uprobe = alloc_uprobe(inode, offset);
 
-	if (uprobe && !consumer_add(uprobe, uc)) {
+	if (!uprobe) {
+		ret = -ENOMEM;
+	} else if (!consumer_add(uprobe, uc)) {
 		ret = __uprobe_register(uprobe);
 		if (ret) {
 			uprobe->consumers = NULL;
 			__uprobe_unregister(uprobe);
 		} else {
-			uprobe->flags |= UPROBE_RUN_HANDLER;
+			set_bit(UPROBE_RUN_HANDLER, &uprobe->flags);
 		}
 	}
 
@@ -932,7 +889,7 @@
 	if (consumer_del(uprobe, uc)) {
 		if (!uprobe->consumers) {
 			__uprobe_unregister(uprobe);
-			uprobe->flags &= ~UPROBE_RUN_HANDLER;
+			clear_bit(UPROBE_RUN_HANDLER, &uprobe->flags);
 		}
 	}
 
@@ -1393,10 +1350,11 @@
  */
 static bool can_skip_sstep(struct uprobe *uprobe, struct pt_regs *regs)
 {
-	if (arch_uprobe_skip_sstep(&uprobe->arch, regs))
-		return true;
-
-	uprobe->flags &= ~UPROBE_SKIP_SSTEP;
+	if (test_bit(UPROBE_SKIP_SSTEP, &uprobe->flags)) {
+		if (arch_uprobe_skip_sstep(&uprobe->arch, regs))
+			return true;
+		clear_bit(UPROBE_SKIP_SSTEP, &uprobe->flags);
+	}
 	return false;
 }
 
@@ -1419,6 +1377,30 @@
 	clear_bit(MMF_HAS_UPROBES, &mm->flags);
 }
 
+static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr)
+{
+	struct page *page;
+	uprobe_opcode_t opcode;
+	int result;
+
+	pagefault_disable();
+	result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr,
+							sizeof(opcode));
+	pagefault_enable();
+
+	if (likely(result == 0))
+		goto out;
+
+	result = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL);
+	if (result < 0)
+		return result;
+
+	copy_opcode(page, vaddr, &opcode);
+	put_page(page);
+ out:
+	return is_swbp_insn(&opcode);
+}
+
 static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp)
 {
 	struct mm_struct *mm = current->mm;
@@ -1489,38 +1471,41 @@
 		}
 		return;
 	}
+	/*
+	 * TODO: move copy_insn/etc into _register and remove this hack.
+	 * After we hit the bp, _unregister + _register can install the
+	 * new and not-yet-analyzed uprobe at the same address, restart.
+	 */
+	smp_rmb(); /* pairs with wmb() in install_breakpoint() */
+	if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags)))
+		goto restart;
 
 	utask = current->utask;
 	if (!utask) {
 		utask = add_utask();
 		/* Cannot allocate; re-execute the instruction. */
 		if (!utask)
-			goto cleanup_ret;
+			goto restart;
 	}
-	utask->active_uprobe = uprobe;
-	handler_chain(uprobe, regs);
-	if (uprobe->flags & UPROBE_SKIP_SSTEP && can_skip_sstep(uprobe, regs))
-		goto cleanup_ret;
 
-	utask->state = UTASK_SSTEP;
+	handler_chain(uprobe, regs);
+	if (can_skip_sstep(uprobe, regs))
+		goto out;
+
 	if (!pre_ssout(uprobe, regs, bp_vaddr)) {
 		arch_uprobe_enable_step(&uprobe->arch);
+		utask->active_uprobe = uprobe;
+		utask->state = UTASK_SSTEP;
 		return;
 	}
 
-cleanup_ret:
-	if (utask) {
-		utask->active_uprobe = NULL;
-		utask->state = UTASK_RUNNING;
-	}
-	if (!(uprobe->flags & UPROBE_SKIP_SSTEP))
-
-		/*
-		 * cannot singlestep; cannot skip instruction;
-		 * re-execute the instruction.
-		 */
-		instruction_pointer_set(regs, bp_vaddr);
-
+restart:
+	/*
+	 * cannot singlestep; cannot skip instruction;
+	 * re-execute the instruction.
+	 */
+	instruction_pointer_set(regs, bp_vaddr);
+out:
 	put_uprobe(uprobe);
 }
 
@@ -1552,13 +1537,12 @@
 }
 
 /*
- * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag.  (and on
- * subsequent probe hits on the thread sets the state to UTASK_BP_HIT) and
- * allows the thread to return from interrupt.
+ * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag and
+ * allows the thread to return from interrupt. After that handle_swbp()
+ * sets utask->active_uprobe.
  *
- * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag and
- * also sets the state to UTASK_SSTEP_ACK and allows the thread to return from
- * interrupt.
+ * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag
+ * and allows the thread to return from interrupt.
  *
  * While returning to userspace, thread notices the TIF_UPROBE flag and calls
  * uprobe_notify_resume().
@@ -1567,11 +1551,13 @@
 {
 	struct uprobe_task *utask;
 
+	clear_thread_flag(TIF_UPROBE);
+
 	utask = current->utask;
-	if (!utask || utask->state == UTASK_BP_HIT)
-		handle_swbp(regs);
-	else
+	if (utask && utask->active_uprobe)
 		handle_singlestep(utask, regs);
+	else
+		handle_swbp(regs);
 }
 
 /*
@@ -1580,17 +1566,10 @@
  */
 int uprobe_pre_sstep_notifier(struct pt_regs *regs)
 {
-	struct uprobe_task *utask;
-
 	if (!current->mm || !test_bit(MMF_HAS_UPROBES, &current->mm->flags))
 		return 0;
 
-	utask = current->utask;
-	if (utask)
-		utask->state = UTASK_BP_HIT;
-
 	set_thread_flag(TIF_UPROBE);
-
 	return 1;
 }
 
diff --git a/kernel/futex.c b/kernel/futex.c
index 3717e7b..20ef219 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -716,7 +716,7 @@
 				struct futex_pi_state **ps,
 				struct task_struct *task, int set_waiters)
 {
-	int lock_taken, ret, ownerdied = 0;
+	int lock_taken, ret, force_take = 0;
 	u32 uval, newval, curval, vpid = task_pid_vnr(task);
 
 retry:
@@ -755,17 +755,15 @@
 	newval = curval | FUTEX_WAITERS;
 
 	/*
-	 * There are two cases, where a futex might have no owner (the
-	 * owner TID is 0): OWNER_DIED. We take over the futex in this
-	 * case. We also do an unconditional take over, when the owner
-	 * of the futex died.
-	 *
-	 * This is safe as we are protected by the hash bucket lock !
+	 * Should we force take the futex? See below.
 	 */
-	if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
-		/* Keep the OWNER_DIED bit */
+	if (unlikely(force_take)) {
+		/*
+		 * Keep the OWNER_DIED and the WAITERS bit and set the
+		 * new TID value.
+		 */
 		newval = (curval & ~FUTEX_TID_MASK) | vpid;
-		ownerdied = 0;
+		force_take = 0;
 		lock_taken = 1;
 	}
 
@@ -775,7 +773,7 @@
 		goto retry;
 
 	/*
-	 * We took the lock due to owner died take over.
+	 * We took the lock due to forced take over.
 	 */
 	if (unlikely(lock_taken))
 		return 1;
@@ -790,20 +788,25 @@
 		switch (ret) {
 		case -ESRCH:
 			/*
-			 * No owner found for this futex. Check if the
-			 * OWNER_DIED bit is set to figure out whether
-			 * this is a robust futex or not.
+			 * We failed to find an owner for this
+			 * futex. So we have no pi_state to block
+			 * on. This can happen in two cases:
+			 *
+			 * 1) The owner died
+			 * 2) A stale FUTEX_WAITERS bit
+			 *
+			 * Re-read the futex value.
 			 */
 			if (get_futex_value_locked(&curval, uaddr))
 				return -EFAULT;
 
 			/*
-			 * We simply start over in case of a robust
-			 * futex. The code above will take the futex
-			 * and return happy.
+			 * If the owner died or we have a stale
+			 * WAITERS bit the owner TID in the user space
+			 * futex is 0.
 			 */
-			if (curval & FUTEX_OWNER_DIED) {
-				ownerdied = 1;
+			if (!(curval & FUTEX_TID_MASK)) {
+				force_take = 1;
 				goto retry;
 			}
 		default:
diff --git a/kernel/module.c b/kernel/module.c
index 6085f5e..6e48c3a 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2293,12 +2293,17 @@
 	src = (void *)info->hdr + symsect->sh_offset;
 	nsrc = symsect->sh_size / sizeof(*src);
 
+	/* strtab always starts with a nul, so offset 0 is the empty string. */
+	strtab_size = 1;
+
 	/* Compute total space required for the core symbols' strtab. */
-	for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src)
-		if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) {
-			strtab_size += strlen(&info->strtab[src->st_name]) + 1;
+	for (ndst = i = 0; i < nsrc; i++) {
+		if (i == 0 ||
+		    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
+			strtab_size += strlen(&info->strtab[src[i].st_name])+1;
 			ndst++;
 		}
+	}
 
 	/* Append room for core symbols at end of core part. */
 	info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
@@ -2332,15 +2337,15 @@
 	mod->core_symtab = dst = mod->module_core + info->symoffs;
 	mod->core_strtab = s = mod->module_core + info->stroffs;
 	src = mod->symtab;
-	*dst = *src;
 	*s++ = 0;
-	for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) {
-		if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum))
-			continue;
-
-		dst[ndst] = *src;
-		dst[ndst++].st_name = s - mod->core_strtab;
-		s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1;
+	for (ndst = i = 0; i < mod->num_symtab; i++) {
+		if (i == 0 ||
+		    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
+			dst[ndst] = src[i];
+			dst[ndst++].st_name = s - mod->core_strtab;
+			s += strlcpy(s, &mod->strtab[src[i].st_name],
+				     KSYM_NAME_LEN) + 1;
+		}
 	}
 	mod->core_num_syms = ndst;
 }
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
index d492a23..ea1b1df 100644
--- a/kernel/module_signing.c
+++ b/kernel/module_signing.c
@@ -192,7 +192,7 @@
 	size_t modlen = *_modlen, sig_len;
 	int ret;
 
-	pr_devel("==>%s(,%lu)\n", __func__, modlen);
+	pr_devel("==>%s(,%zu)\n", __func__, modlen);
 
 	if (modlen <= sizeof(ms))
 		return -EBADMSG;
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index eb00be2..7b07cc0 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -71,12 +71,22 @@
 	return NULL;
 }
 
+/* MAX_PID_NS_LEVEL is needed for limiting size of 'struct pid' */
+#define MAX_PID_NS_LEVEL 32
+
 static struct pid_namespace *create_pid_namespace(struct pid_namespace *parent_pid_ns)
 {
 	struct pid_namespace *ns;
 	unsigned int level = parent_pid_ns->level + 1;
-	int i, err = -ENOMEM;
+	int i;
+	int err;
 
+	if (level > MAX_PID_NS_LEVEL) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	err = -ENOMEM;
 	ns = kmem_cache_zalloc(pid_ns_cachep, GFP_KERNEL);
 	if (ns == NULL)
 		goto out;
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index b32ed0e..b979426 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -1567,6 +1567,10 @@
 
 		put_online_cpus();
 	} else {
+		/* Make sure this CPU has been intitialized */
+		if (!cpumask_test_cpu(cpu_id, buffer->cpumask))
+			goto out;
+
 		cpu_buffer = buffer->buffers[cpu_id];
 
 		if (nr_pages == cpu_buffer->nr_pages)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index d951daa..042d221 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -2982,7 +2982,7 @@
 
 	set_work_cpu_and_clear_pending(&dwork->work, work_cpu(&dwork->work));
 	local_irq_restore(flags);
-	return true;
+	return ret;
 }
 EXPORT_SYMBOL(cancel_delayed_work);
 
diff --git a/lib/genalloc.c b/lib/genalloc.c
index ca208a9..5492043 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -178,7 +178,7 @@
 	struct gen_pool_chunk *chunk;
 	int nbits = size >> pool->min_alloc_order;
 	int nbytes = sizeof(struct gen_pool_chunk) +
-				(nbits + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
+				BITS_TO_LONGS(nbits) * sizeof(long);
 
 	chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid);
 	if (unlikely(chunk == NULL))
diff --git a/mm/bootmem.c b/mm/bootmem.c
index 434be4a..f468185 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -198,8 +198,6 @@
 			int order = ilog2(BITS_PER_LONG);
 
 			__free_pages_bootmem(pfn_to_page(start), order);
-			fixup_zone_present_pages(page_to_nid(pfn_to_page(start)),
-					start, start + BITS_PER_LONG);
 			count += BITS_PER_LONG;
 			start += BITS_PER_LONG;
 		} else {
@@ -210,9 +208,6 @@
 				if (vec & 1) {
 					page = pfn_to_page(start + off);
 					__free_pages_bootmem(page, 0);
-					fixup_zone_present_pages(
-						page_to_nid(page),
-						start + off, start + off + 1);
 					count++;
 				}
 				vec >>= 1;
@@ -226,11 +221,8 @@
 	pages = bdata->node_low_pfn - bdata->node_min_pfn;
 	pages = bootmem_bootmap_pages(pages);
 	count += pages;
-	while (pages--) {
-		fixup_zone_present_pages(page_to_nid(page),
-				page_to_pfn(page), page_to_pfn(page) + 1);
+	while (pages--)
 		__free_pages_bootmem(page++, 0);
-	}
 
 	bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count);
 
diff --git a/mm/highmem.c b/mm/highmem.c
index d517cd1..2da13a5 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -98,7 +98,7 @@
 {
 	unsigned long addr = (unsigned long)vaddr;
 
-	if (addr >= PKMAP_ADDR(0) && addr <= PKMAP_ADDR(LAST_PKMAP)) {
+	if (addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP)) {
 		int i = (addr - PKMAP_ADDR(0)) >> PAGE_SHIFT;
 		return pte_page(pkmap_page_table[i]);
 	}
diff --git a/mm/memblock.c b/mm/memblock.c
index 931eef1..6259055 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -930,6 +930,30 @@
 	return memblock_overlaps_region(&memblock.reserved, base, size) >= 0;
 }
 
+void __init_memblock memblock_trim_memory(phys_addr_t align)
+{
+	int i;
+	phys_addr_t start, end, orig_start, orig_end;
+	struct memblock_type *mem = &memblock.memory;
+
+	for (i = 0; i < mem->cnt; i++) {
+		orig_start = mem->regions[i].base;
+		orig_end = mem->regions[i].base + mem->regions[i].size;
+		start = round_up(orig_start, align);
+		end = round_down(orig_end, align);
+
+		if (start == orig_start && end == orig_end)
+			continue;
+
+		if (start < end) {
+			mem->regions[i].base = start;
+			mem->regions[i].size = end - start;
+		} else {
+			memblock_remove_region(mem, i);
+			i--;
+		}
+	}
+}
 
 void __init_memblock memblock_set_current_limit(phys_addr_t limit)
 {
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 7acf43b..dd39ba0 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1055,12 +1055,24 @@
 				      struct mem_cgroup *memcg)
 {
 	struct mem_cgroup_per_zone *mz;
+	struct lruvec *lruvec;
 
-	if (mem_cgroup_disabled())
-		return &zone->lruvec;
+	if (mem_cgroup_disabled()) {
+		lruvec = &zone->lruvec;
+		goto out;
+	}
 
 	mz = mem_cgroup_zoneinfo(memcg, zone_to_nid(zone), zone_idx(zone));
-	return &mz->lruvec;
+	lruvec = &mz->lruvec;
+out:
+	/*
+	 * Since a node can be onlined after the mem_cgroup was created,
+	 * we have to be prepared to initialize lruvec->zone here;
+	 * and if offlined then reonlined, we need to reinitialize it.
+	 */
+	if (unlikely(lruvec->zone != zone))
+		lruvec->zone = zone;
+	return lruvec;
 }
 
 /*
@@ -1087,9 +1099,12 @@
 	struct mem_cgroup_per_zone *mz;
 	struct mem_cgroup *memcg;
 	struct page_cgroup *pc;
+	struct lruvec *lruvec;
 
-	if (mem_cgroup_disabled())
-		return &zone->lruvec;
+	if (mem_cgroup_disabled()) {
+		lruvec = &zone->lruvec;
+		goto out;
+	}
 
 	pc = lookup_page_cgroup(page);
 	memcg = pc->mem_cgroup;
@@ -1107,7 +1122,16 @@
 		pc->mem_cgroup = memcg = root_mem_cgroup;
 
 	mz = page_cgroup_zoneinfo(memcg, page);
-	return &mz->lruvec;
+	lruvec = &mz->lruvec;
+out:
+	/*
+	 * Since a node can be onlined after the mem_cgroup was created,
+	 * we have to be prepared to initialize lruvec->zone here;
+	 * and if offlined then reonlined, we need to reinitialize it.
+	 */
+	if (unlikely(lruvec->zone != zone))
+		lruvec->zone = zone;
+	return lruvec;
 }
 
 /**
@@ -1452,17 +1476,26 @@
 static u64 mem_cgroup_get_limit(struct mem_cgroup *memcg)
 {
 	u64 limit;
-	u64 memsw;
 
 	limit = res_counter_read_u64(&memcg->res, RES_LIMIT);
-	limit += total_swap_pages << PAGE_SHIFT;
 
-	memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT);
 	/*
-	 * If memsw is finite and limits the amount of swap space available
-	 * to this memcg, return that limit.
+	 * Do not consider swap space if we cannot swap due to swappiness
 	 */
-	return min(limit, memsw);
+	if (mem_cgroup_swappiness(memcg)) {
+		u64 memsw;
+
+		limit += total_swap_pages << PAGE_SHIFT;
+		memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT);
+
+		/*
+		 * If memsw is finite and limits the amount of swap space
+		 * available to this memcg, return that limit.
+		 */
+		limit = min(limit, memsw);
+	}
+
+	return limit;
 }
 
 void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
@@ -3688,17 +3721,17 @@
 static bool mem_cgroup_force_empty_list(struct mem_cgroup *memcg,
 				int node, int zid, enum lru_list lru)
 {
-	struct mem_cgroup_per_zone *mz;
+	struct lruvec *lruvec;
 	unsigned long flags, loop;
 	struct list_head *list;
 	struct page *busy;
 	struct zone *zone;
 
 	zone = &NODE_DATA(node)->node_zones[zid];
-	mz = mem_cgroup_zoneinfo(memcg, node, zid);
-	list = &mz->lruvec.lists[lru];
+	lruvec = mem_cgroup_zone_lruvec(zone, memcg);
+	list = &lruvec->lists[lru];
 
-	loop = mz->lru_size[lru];
+	loop = mem_cgroup_get_lru_size(lruvec, lru);
 	/* give some margin against EBUSY etc...*/
 	loop += 256;
 	busy = NULL;
@@ -4736,7 +4769,7 @@
 
 	for (zone = 0; zone < MAX_NR_ZONES; zone++) {
 		mz = &pn->zoneinfo[zone];
-		lruvec_init(&mz->lruvec, &NODE_DATA(node)->node_zones[zone]);
+		lruvec_init(&mz->lruvec);
 		mz->usage_in_excess = 0;
 		mz->on_tree = false;
 		mz->memcg = memcg;
diff --git a/mm/memory.c b/mm/memory.c
index fb135ba..221fc9f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2527,9 +2527,8 @@
 	int ret = 0;
 	int page_mkwrite = 0;
 	struct page *dirty_page = NULL;
-	unsigned long mmun_start;	/* For mmu_notifiers */
-	unsigned long mmun_end;		/* For mmu_notifiers */
-	bool mmun_called = false;	/* For mmu_notifiers */
+	unsigned long mmun_start = 0;	/* For mmu_notifiers */
+	unsigned long mmun_end = 0;	/* For mmu_notifiers */
 
 	old_page = vm_normal_page(vma, address, orig_pte);
 	if (!old_page) {
@@ -2708,8 +2707,7 @@
 		goto oom_free_new;
 
 	mmun_start  = address & PAGE_MASK;
-	mmun_end    = (address & PAGE_MASK) + PAGE_SIZE;
-	mmun_called = true;
+	mmun_end    = mmun_start + PAGE_SIZE;
 	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 
 	/*
@@ -2778,7 +2776,7 @@
 		page_cache_release(new_page);
 unlock:
 	pte_unmap_unlock(page_table, ptl);
-	if (mmun_called)
+	if (mmun_end > mmun_start)
 		mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 	if (old_page) {
 		/*
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 56b758a..e4eeaca 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -106,7 +106,6 @@
 void __ref put_page_bootmem(struct page *page)
 {
 	unsigned long type;
-	struct zone *zone;
 
 	type = (unsigned long) page->lru.next;
 	BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE ||
@@ -117,12 +116,6 @@
 		set_page_private(page, 0);
 		INIT_LIST_HEAD(&page->lru);
 		__free_pages_bootmem(page, 0);
-
-		zone = page_zone(page);
-		zone_span_writelock(zone);
-		zone->present_pages++;
-		zone_span_writeunlock(zone);
-		totalram_pages++;
 	}
 
 }
diff --git a/mm/mmap.c b/mm/mmap.c
index 2d94235..9a796c4 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -334,8 +334,10 @@
 	struct vm_area_struct *vma = mm->mmap;
 	while (vma) {
 		struct anon_vma_chain *avc;
+		vma_lock_anon_vma(vma);
 		list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
 			anon_vma_interval_tree_verify(avc);
+		vma_unlock_anon_vma(vma);
 		vma = vma->vm_next;
 		i++;
 	}
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
index 479a1e7..8a5ac8c 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -196,28 +196,28 @@
 	BUG_ON(atomic_read(&mm->mm_users) <= 0);
 
 	/*
-	* Verify that mmu_notifier_init() already run and the global srcu is
-	* initialized.
-	*/
+	 * Verify that mmu_notifier_init() already run and the global srcu is
+	 * initialized.
+	 */
 	BUG_ON(!srcu.per_cpu_ref);
 
+	ret = -ENOMEM;
+	mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm), GFP_KERNEL);
+	if (unlikely(!mmu_notifier_mm))
+		goto out;
+
 	if (take_mmap_sem)
 		down_write(&mm->mmap_sem);
 	ret = mm_take_all_locks(mm);
 	if (unlikely(ret))
-		goto out;
+		goto out_clean;
 
 	if (!mm_has_notifiers(mm)) {
-		mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm),
-					GFP_KERNEL);
-		if (unlikely(!mmu_notifier_mm)) {
-			ret = -ENOMEM;
-			goto out_of_mem;
-		}
 		INIT_HLIST_HEAD(&mmu_notifier_mm->list);
 		spin_lock_init(&mmu_notifier_mm->lock);
 
 		mm->mmu_notifier_mm = mmu_notifier_mm;
+		mmu_notifier_mm = NULL;
 	}
 	atomic_inc(&mm->mm_count);
 
@@ -233,12 +233,12 @@
 	hlist_add_head(&mn->hlist, &mm->mmu_notifier_mm->list);
 	spin_unlock(&mm->mmu_notifier_mm->lock);
 
-out_of_mem:
 	mm_drop_all_locks(mm);
-out:
+out_clean:
 	if (take_mmap_sem)
 		up_write(&mm->mmap_sem);
-
+	kfree(mmu_notifier_mm);
+out:
 	BUG_ON(atomic_read(&mm->mm_users) <= 0);
 	return ret;
 }
diff --git a/mm/mmzone.c b/mm/mmzone.c
index 3cef80f..4596d81 100644
--- a/mm/mmzone.c
+++ b/mm/mmzone.c
@@ -87,7 +87,7 @@
 }
 #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */
 
-void lruvec_init(struct lruvec *lruvec, struct zone *zone)
+void lruvec_init(struct lruvec *lruvec)
 {
 	enum lru_list lru;
 
@@ -95,8 +95,4 @@
 
 	for_each_lru(lru)
 		INIT_LIST_HEAD(&lruvec->lists[lru]);
-
-#ifdef CONFIG_MEMCG
-	lruvec->zone = zone;
-#endif
 }
diff --git a/mm/nobootmem.c b/mm/nobootmem.c
index 714d5d6..bd82f6b 100644
--- a/mm/nobootmem.c
+++ b/mm/nobootmem.c
@@ -116,8 +116,6 @@
 		return 0;
 
 	__free_pages_memory(start_pfn, end_pfn);
-	fixup_zone_present_pages(pfn_to_nid(start >> PAGE_SHIFT),
-			start_pfn, end_pfn);
 
 	return end_pfn - start_pfn;
 }
@@ -128,7 +126,6 @@
 	phys_addr_t start, end, size;
 	u64 i;
 
-	reset_zone_present_pages();
 	for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL)
 		count += __free_memory_core(start, end);
 
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index bb90971..7bb35ac 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1809,10 +1809,10 @@
 	int i;
 
 	for_each_online_node(i)
-		if (node_distance(nid, i) <= RECLAIM_DISTANCE) {
+		if (node_distance(nid, i) <= RECLAIM_DISTANCE)
 			node_set(i, NODE_DATA(nid)->reclaim_nodes);
+		else
 			zone_reclaim_mode = 1;
-		}
 }
 
 #else	/* CONFIG_NUMA */
@@ -4505,7 +4505,7 @@
 		zone->zone_pgdat = pgdat;
 
 		zone_pcp_init(zone);
-		lruvec_init(&zone->lruvec, zone);
+		lruvec_init(&zone->lruvec);
 		if (!size)
 			continue;
 
@@ -5825,7 +5825,7 @@
 	ret = start_isolate_page_range(pfn_max_align_down(start),
 				       pfn_max_align_up(end), migratetype);
 	if (ret)
-		goto done;
+		return ret;
 
 	ret = __alloc_contig_migrate_range(&cc, start, end);
 	if (ret)
@@ -6098,37 +6098,3 @@
 	dump_page_flags(page->flags);
 	mem_cgroup_print_bad_page(page);
 }
-
-/* reset zone->present_pages */
-void reset_zone_present_pages(void)
-{
-	struct zone *z;
-	int i, nid;
-
-	for_each_node_state(nid, N_HIGH_MEMORY) {
-		for (i = 0; i < MAX_NR_ZONES; i++) {
-			z = NODE_DATA(nid)->node_zones + i;
-			z->present_pages = 0;
-		}
-	}
-}
-
-/* calculate zone's present pages in buddy system */
-void fixup_zone_present_pages(int nid, unsigned long start_pfn,
-				unsigned long end_pfn)
-{
-	struct zone *z;
-	unsigned long zone_start_pfn, zone_end_pfn;
-	int i;
-
-	for (i = 0; i < MAX_NR_ZONES; i++) {
-		z = NODE_DATA(nid)->node_zones + i;
-		zone_start_pfn = z->zone_start_pfn;
-		zone_end_pfn = zone_start_pfn + z->spanned_pages;
-
-		/* if the two regions intersect */
-		if (!(zone_start_pfn >= end_pfn	|| zone_end_pfn <= start_pfn))
-			z->present_pages += min(end_pfn, zone_end_pfn) -
-					    max(start_pfn, zone_start_pfn);
-	}
-}
diff --git a/mm/rmap.c b/mm/rmap.c
index 7df7984..2ee1ef0 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -56,6 +56,7 @@
 #include <linux/mmu_notifier.h>
 #include <linux/migrate.h>
 #include <linux/hugetlb.h>
+#include <linux/backing-dev.h>
 
 #include <asm/tlbflush.h>
 
@@ -926,11 +927,8 @@
 
 	if (page_mapped(page)) {
 		struct address_space *mapping = page_mapping(page);
-		if (mapping) {
+		if (mapping)
 			ret = page_mkclean_file(mapping, page);
-			if (page_test_and_clear_dirty(page_to_pfn(page), 1))
-				ret = 1;
-		}
 	}
 
 	return ret;
@@ -1116,6 +1114,7 @@
  */
 void page_remove_rmap(struct page *page)
 {
+	struct address_space *mapping = page_mapping(page);
 	bool anon = PageAnon(page);
 	bool locked;
 	unsigned long flags;
@@ -1138,8 +1137,19 @@
 	 * this if the page is anon, so about to be freed; but perhaps
 	 * not if it's in swapcache - there might be another pte slot
 	 * containing the swap entry, but page not yet written to swap.
+	 *
+	 * And we can skip it on file pages, so long as the filesystem
+	 * participates in dirty tracking; but need to catch shm and tmpfs
+	 * and ramfs pages which have been modified since creation by read
+	 * fault.
+	 *
+	 * Note that mapping must be decided above, before decrementing
+	 * mapcount (which luckily provides a barrier): once page is unmapped,
+	 * it could be truncated and page->mapping reset to NULL at any moment.
+	 * Note also that we are relying on page_mapping(page) to set mapping
+	 * to &swapper_space when PageSwapCache(page).
 	 */
-	if ((!anon || PageSwapCache(page)) &&
+	if (mapping && !mapping_cap_account_dirty(mapping) &&
 	    page_test_and_clear_dirty(page_to_pfn(page), 1))
 		set_page_dirty(page);
 	/*
diff --git a/mm/shmem.c b/mm/shmem.c
index 67afba5..89341b6 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -643,7 +643,7 @@
 		kfree(info->symlink);
 
 	simple_xattrs_free(&info->xattrs);
-	BUG_ON(inode->i_blocks);
+	WARN_ON(inode->i_blocks);
 	shmem_free_inode(inode->i_sb);
 	clear_inode(inode);
 }
@@ -1145,8 +1145,20 @@
 		if (!error) {
 			error = shmem_add_to_page_cache(page, mapping, index,
 						gfp, swp_to_radix_entry(swap));
-			/* We already confirmed swap, and make no allocation */
-			VM_BUG_ON(error);
+			/*
+			 * We already confirmed swap under page lock, and make
+			 * no memory allocation here, so usually no possibility
+			 * of error; but free_swap_and_cache() only trylocks a
+			 * page, so it is just possible that the entry has been
+			 * truncated or holepunched since swap was confirmed.
+			 * shmem_undo_range() will have done some of the
+			 * unaccounting, now delete_from_swap_cache() will do
+			 * the rest (including mem_cgroup_uncharge_swapcache).
+			 * Reset swap.val? No, leave it so "failed" goes back to
+			 * "repeat": reading a hole and writing should succeed.
+			 */
+			if (error)
+				delete_from_swap_cache(page);
 		}
 		if (error)
 			goto failed;
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 71cd288..f91a255 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1494,9 +1494,8 @@
 	BUG_ON(!current->mm);
 
 	pathname = getname(specialfile);
-	err = PTR_ERR(pathname);
 	if (IS_ERR(pathname))
-		goto out;
+		return PTR_ERR(pathname);
 
 	victim = file_open_name(pathname, O_RDWR|O_LARGEFILE, 0);
 	err = PTR_ERR(victim);
@@ -1608,6 +1607,7 @@
 out_dput:
 	filp_close(victim, NULL);
 out:
+	putname(pathname);
 	return err;
 }
 
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 2624edc..48550c6 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1760,28 +1760,6 @@
 	return false;
 }
 
-#ifdef CONFIG_COMPACTION
-/*
- * If compaction is deferred for sc->order then scale the number of pages
- * reclaimed based on the number of consecutive allocation failures
- */
-static unsigned long scale_for_compaction(unsigned long pages_for_compaction,
-			struct lruvec *lruvec, struct scan_control *sc)
-{
-	struct zone *zone = lruvec_zone(lruvec);
-
-	if (zone->compact_order_failed <= sc->order)
-		pages_for_compaction <<= zone->compact_defer_shift;
-	return pages_for_compaction;
-}
-#else
-static unsigned long scale_for_compaction(unsigned long pages_for_compaction,
-			struct lruvec *lruvec, struct scan_control *sc)
-{
-	return pages_for_compaction;
-}
-#endif
-
 /*
  * Reclaim/compaction is used for high-order allocation requests. It reclaims
  * order-0 pages before compacting the zone. should_continue_reclaim() returns
@@ -1829,9 +1807,6 @@
 	 * inactive lists are large enough, continue reclaiming
 	 */
 	pages_for_compaction = (2UL << sc->order);
-
-	pages_for_compaction = scale_for_compaction(pages_for_compaction,
-						    lruvec, sc);
 	inactive_lru_pages = get_lru_size(lruvec, LRU_INACTIVE_FILE);
 	if (nr_swap_pages > 0)
 		inactive_lru_pages += get_lru_size(lruvec, LRU_INACTIVE_ANON);
@@ -3017,6 +2992,8 @@
 						&balanced_classzone_idx);
 		}
 	}
+
+	current->reclaim_state = NULL;
 	return 0;
 }
 
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 9096bcb..ee07072 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -463,7 +463,9 @@
 
 	case NETDEV_PRE_TYPE_CHANGE:
 		/* Forbid underlaying device to change its type. */
-		return NOTIFY_BAD;
+		if (vlan_uses_dev(dev))
+			return NOTIFY_BAD;
+		break;
 
 	case NETDEV_NOTIFY_PEERS:
 	case NETDEV_BONDING_FAILOVER:
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 0a9084a..fd8d5af 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -1167,6 +1167,8 @@
 	uint16_t crc;
 	unsigned long entrytime;
 
+	spin_lock_init(&bat_priv->bla.bcast_duplist_lock);
+
 	batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n");
 
 	/* setting claim destination address */
@@ -1210,8 +1212,8 @@
 /**
  * batadv_bla_check_bcast_duplist
  * @bat_priv: the bat priv with all the soft interface information
- * @bcast_packet: originator mac address
- * @hdr_size: maximum length of the frame
+ * @bcast_packet: encapsulated broadcast frame plus batman header
+ * @bcast_packet_len: length of encapsulated broadcast frame plus batman header
  *
  * check if it is on our broadcast list. Another gateway might
  * have sent the same packet because it is connected to the same backbone,
@@ -1224,20 +1226,22 @@
  */
 int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
 				   struct batadv_bcast_packet *bcast_packet,
-				   int hdr_size)
+				   int bcast_packet_len)
 {
-	int i, length, curr;
+	int i, length, curr, ret = 0;
 	uint8_t *content;
 	uint16_t crc;
 	struct batadv_bcast_duplist_entry *entry;
 
-	length = hdr_size - sizeof(*bcast_packet);
+	length = bcast_packet_len - sizeof(*bcast_packet);
 	content = (uint8_t *)bcast_packet;
 	content += sizeof(*bcast_packet);
 
 	/* calculate the crc ... */
 	crc = crc16(0, content, length);
 
+	spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
+
 	for (i = 0; i < BATADV_DUPLIST_SIZE; i++) {
 		curr = (bat_priv->bla.bcast_duplist_curr + i);
 		curr %= BATADV_DUPLIST_SIZE;
@@ -1259,9 +1263,12 @@
 		/* this entry seems to match: same crc, not too old,
 		 * and from another gw. therefore return 1 to forbid it.
 		 */
-		return 1;
+		ret = 1;
+		goto out;
 	}
-	/* not found, add a new entry (overwrite the oldest entry) */
+	/* not found, add a new entry (overwrite the oldest entry)
+	 * and allow it, its the first occurence.
+	 */
 	curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1);
 	curr %= BATADV_DUPLIST_SIZE;
 	entry = &bat_priv->bla.bcast_duplist[curr];
@@ -1270,8 +1277,10 @@
 	memcpy(entry->orig, bcast_packet->orig, ETH_ALEN);
 	bat_priv->bla.bcast_duplist_curr = curr;
 
-	/* allow it, its the first occurence. */
-	return 0;
+out:
+	spin_unlock_bh(&bat_priv->bla.bcast_duplist_lock);
+
+	return ret;
 }
 
 
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 939fc01..376b4cc 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -1124,8 +1124,14 @@
 
 	spin_unlock_bh(&orig_node->bcast_seqno_lock);
 
+	/* keep skb linear for crc calculation */
+	if (skb_linearize(skb) < 0)
+		goto out;
+
+	bcast_packet = (struct batadv_bcast_packet *)skb->data;
+
 	/* check whether this has been sent by another originator before */
-	if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size))
+	if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len))
 		goto out;
 
 	/* rebroadcast packet */
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index b9a28d2..ce0684a 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -325,6 +325,12 @@
 
 	soft_iface->last_rx = jiffies;
 
+	/* Let the bridge loop avoidance check the packet. If will
+	 * not handle it, we can safely push it up.
+	 */
+	if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
+		goto out;
+
 	if (orig_node)
 		batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
 						     ethhdr->h_source);
@@ -332,12 +338,6 @@
 	if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
 		goto dropped;
 
-	/* Let the bridge loop avoidance check the packet. If will
-	 * not handle it, we can safely push it up.
-	 */
-	if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
-		goto out;
-
 	netif_rx(skb);
 	goto out;
 
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 112edd3..baae715 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -769,6 +769,12 @@
 		 */
 		tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP;
 
+		/* the change can carry possible "attribute" flags like the
+		 * TT_CLIENT_WIFI, therefore they have to be copied in the
+		 * client entry
+		 */
+		tt_global_entry->common.flags |= flags;
+
 		/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
 		 * one originator left in the list and we previously received a
 		 * delete + roaming change for this originator.
@@ -1496,7 +1502,7 @@
 
 			memcpy(tt_change->addr, tt_common_entry->addr,
 			       ETH_ALEN);
-			tt_change->flags = BATADV_NO_FLAGS;
+			tt_change->flags = tt_common_entry->flags;
 
 			tt_count++;
 			tt_change++;
@@ -2450,6 +2456,13 @@
 {
 	bool ret = false;
 
+	/* if the originator is a backbone node (meaning it belongs to the same
+	 * LAN of this node) the temporary client must not be added because to
+	 * reach such destination the node must use the LAN instead of the mesh
+	 */
+	if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
+		goto out;
+
 	if (!batadv_tt_global_add(bat_priv, orig_node, addr,
 				  BATADV_TT_CLIENT_TEMP,
 				  atomic_read(&orig_node->last_ttvn)))
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 2ed82ca..ac1e07a 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -205,6 +205,8 @@
 	struct batadv_hashtable *backbone_hash;
 	struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE];
 	int bcast_duplist_curr;
+	/* protects bcast_duplist and bcast_duplist_curr */
+	spinlock_t bcast_duplist_lock;
 	struct batadv_bla_claim_dst claim_dest;
 	struct delayed_work work;
 };
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8a0ce70..a0a2f97b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1754,11 +1754,11 @@
 	if (hdev->dev_type != HCI_AMP)
 		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
 
-	schedule_work(&hdev->power_on);
-
 	hci_notify(hdev, HCI_DEV_REG);
 	hci_dev_hold(hdev);
 
+	schedule_work(&hdev->power_on);
+
 	return id;
 
 err_wqueue:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index aa2ea0a..91de423 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -326,7 +326,7 @@
 	struct hci_dev *d;
 	size_t rp_len;
 	u16 count;
-	int i, err;
+	int err;
 
 	BT_DBG("sock %p", sk);
 
@@ -347,9 +347,7 @@
 		return -ENOMEM;
 	}
 
-	rp->num_controllers = cpu_to_le16(count);
-
-	i = 0;
+	count = 0;
 	list_for_each_entry(d, &hci_dev_list, list) {
 		if (test_bit(HCI_SETUP, &d->dev_flags))
 			continue;
@@ -357,10 +355,13 @@
 		if (!mgmt_valid_hdev(d))
 			continue;
 
-		rp->index[i++] = cpu_to_le16(d->id);
+		rp->index[count++] = cpu_to_le16(d->id);
 		BT_DBG("Added hci%u", d->id);
 	}
 
+	rp->num_controllers = cpu_to_le16(count);
+	rp_len = sizeof(*rp) + (2 * count);
+
 	read_unlock(&hci_dev_list_lock);
 
 	err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp,
@@ -1366,6 +1367,7 @@
 			continue;
 
 		list_del(&match->list);
+		kfree(match);
 		found++;
 	}
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 8c225ef..a592337 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -32,6 +32,8 @@
 
 #define SMP_TIMEOUT	msecs_to_jiffies(30000)
 
+#define AUTH_REQ_MASK   0x07
+
 static inline void swap128(u8 src[16], u8 dst[16])
 {
 	int i;
@@ -230,7 +232,7 @@
 		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
 		req->init_key_dist = 0;
 		req->resp_key_dist = dist_keys;
-		req->auth_req = authreq;
+		req->auth_req = (authreq & AUTH_REQ_MASK);
 		return;
 	}
 
@@ -239,7 +241,7 @@
 	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
 	rsp->init_key_dist = 0;
 	rsp->resp_key_dist = req->resp_key_dist & dist_keys;
-	rsp->auth_req = authreq;
+	rsp->auth_req = (authreq & AUTH_REQ_MASK);
 }
 
 static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
@@ -265,7 +267,7 @@
 
 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags);
 	mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type,
-			 hcon->dst_type, reason);
+			 hcon->dst_type, HCI_ERROR_AUTH_FAILURE);
 
 	cancel_delayed_work_sync(&conn->security_timer);
 
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 159aa8b..3ef1759 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -2300,10 +2300,11 @@
 			mutex_unlock(&con->mutex);
 			return;
 		} else {
-			con->ops->put(con);
 			dout("con_work %p FAILED to back off %lu\n", con,
 			     con->delay);
+			set_bit(CON_FLAG_BACKOFF, &con->flags);
 		}
+		goto done;
 	}
 
 	if (con->state == CON_STATE_STANDBY) {
@@ -2749,7 +2750,8 @@
 		msg = con->ops->alloc_msg(con, hdr, skip);
 		mutex_lock(&con->mutex);
 		if (con->state != CON_STATE_OPEN) {
-			ceph_msg_put(msg);
+			if (msg)
+				ceph_msg_put(msg);
 			return -EAGAIN;
 		}
 		con->in_msg = msg;
diff --git a/net/core/dev.c b/net/core/dev.c
index 09cb3f6..c0946cb 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1666,7 +1666,7 @@
 
 static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb)
 {
-	if (ptype->af_packet_priv == NULL)
+	if (!ptype->af_packet_priv || !skb->sk)
 		return false;
 
 	if (ptype->id_match)
@@ -2818,8 +2818,10 @@
 		if (unlikely(tcpu != next_cpu) &&
 		    (tcpu == RPS_NO_CPU || !cpu_online(tcpu) ||
 		     ((int)(per_cpu(softnet_data, tcpu).input_queue_head -
-		      rflow->last_qtail)) >= 0))
+		      rflow->last_qtail)) >= 0)) {
+			tcpu = next_cpu;
 			rflow = set_rps_cpu(dev, skb, rflow, next_cpu);
+		}
 
 		if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) {
 			*rflowp = rflow;
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index 87cc17d..b079c7b 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -319,7 +319,8 @@
 	 */
 	ha = list_first_entry(&dev->dev_addrs.list,
 			      struct netdev_hw_addr, list);
-	if (ha->addr == dev->dev_addr && ha->refcount == 1)
+	if (!memcmp(ha->addr, addr, dev->addr_len) &&
+	    ha->type == addr_type && ha->refcount == 1)
 		return -ENOENT;
 
 	err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len,
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 76d4c2c..fad649a 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2192,7 +2192,8 @@
 			goto skip;
 
 		err = nlmsg_populate_fdb_fill(skb, dev, ha->addr,
-					      portid, seq, 0, NTF_SELF);
+					      portid, seq,
+					      RTM_NEWNEIGH, NTF_SELF);
 		if (err < 0)
 			return err;
 skip:
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 6e04b1f..4007c14 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3379,10 +3379,12 @@
 
 void kfree_skb_partial(struct sk_buff *skb, bool head_stolen)
 {
-	if (head_stolen)
+	if (head_stolen) {
+		skb_release_head_state(skb);
 		kmem_cache_free(skbuff_head_cache, skb);
-	else
+	} else {
 		__kfree_skb(skb);
+	}
 }
 EXPORT_SYMBOL(kfree_skb_partial);
 
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 535584c..0c34bfa 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -892,13 +892,16 @@
 		struct inet_diag_req_v2 *r, struct nlattr *bc)
 {
 	const struct inet_diag_handler *handler;
+	int err = 0;
 
 	handler = inet_diag_lock_handler(r->sdiag_protocol);
 	if (!IS_ERR(handler))
 		handler->dump(skb, cb, r, bc);
+	else
+		err = PTR_ERR(handler);
 	inet_diag_unlock_handler(handler);
 
-	return skb->len;
+	return err ? : skb->len;
 }
 
 static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 5eea4a8..14bbfcf 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -457,19 +457,28 @@
 	struct inet_sock *inet = inet_sk(sk);
 	int val = 0, err;
 
-	if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
-			     (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
-			     (1<<IP_RETOPTS) | (1<<IP_TOS) |
-			     (1<<IP_TTL) | (1<<IP_HDRINCL) |
-			     (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
-			     (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
-			     (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
-			     (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
-	    optname == IP_UNICAST_IF ||
-	    optname == IP_MULTICAST_TTL ||
-	    optname == IP_MULTICAST_ALL ||
-	    optname == IP_MULTICAST_LOOP ||
-	    optname == IP_RECVORIGDSTADDR) {
+	switch (optname) {
+	case IP_PKTINFO:
+	case IP_RECVTTL:
+	case IP_RECVOPTS:
+	case IP_RECVTOS:
+	case IP_RETOPTS:
+	case IP_TOS:
+	case IP_TTL:
+	case IP_HDRINCL:
+	case IP_MTU_DISCOVER:
+	case IP_RECVERR:
+	case IP_ROUTER_ALERT:
+	case IP_FREEBIND:
+	case IP_PASSSEC:
+	case IP_TRANSPARENT:
+	case IP_MINTTL:
+	case IP_NODEFRAG:
+	case IP_UNICAST_IF:
+	case IP_MULTICAST_TTL:
+	case IP_MULTICAST_ALL:
+	case IP_MULTICAST_LOOP:
+	case IP_RECVORIGDSTADDR:
 		if (optlen >= sizeof(int)) {
 			if (get_user(val, (int __user *) optval))
 				return -EFAULT;
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 1831092..858fddf 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -338,12 +338,17 @@
 	if (tunnel != NULL) {
 		struct pcpu_tstats *tstats;
 
+		if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
+			return -1;
+
 		tstats = this_cpu_ptr(tunnel->dev->tstats);
 		u64_stats_update_begin(&tstats->syncp);
 		tstats->rx_packets++;
 		tstats->rx_bytes += skb->len;
 		u64_stats_update_end(&tstats->syncp);
 
+		skb->mark = 0;
+		secpath_reset(skb);
 		skb->dev = tunnel->dev;
 		return 1;
 	}
diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
index 9e0ffaf..a820472 100644
--- a/net/ipv4/netfilter/iptable_nat.c
+++ b/net/ipv4/netfilter/iptable_nat.c
@@ -184,7 +184,8 @@
 
 		if ((ct->tuplehash[dir].tuple.src.u3.ip !=
 		     ct->tuplehash[!dir].tuple.dst.u3.ip) ||
-		    (ct->tuplehash[dir].tuple.src.u.all !=
+		    (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
+		     ct->tuplehash[dir].tuple.src.u.all !=
 		     ct->tuplehash[!dir].tuple.dst.u.all))
 			if (nf_xfrm_me_harder(skb, AF_INET) < 0)
 				ret = NF_DROP;
@@ -221,6 +222,7 @@
 		}
 #ifdef CONFIG_XFRM
 		else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
+			 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
 			 ct->tuplehash[dir].tuple.dst.u.all !=
 			 ct->tuplehash[!dir].tuple.src.u.all)
 			if (nf_xfrm_me_harder(skb, AF_INET) < 0)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 432f4bb..a8c65121 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1163,8 +1163,12 @@
 	spin_lock_bh(&fnhe_lock);
 
 	if (daddr == fnhe->fnhe_daddr) {
-		struct rtable *orig;
-
+		struct rtable *orig = rcu_dereference(fnhe->fnhe_rth);
+		if (orig && rt_is_expired(orig)) {
+			fnhe->fnhe_gw = 0;
+			fnhe->fnhe_pmtu = 0;
+			fnhe->fnhe_expires = 0;
+		}
 		if (fnhe->fnhe_pmtu) {
 			unsigned long expires = fnhe->fnhe_expires;
 			unsigned long diff = expires - jiffies;
@@ -1181,7 +1185,6 @@
 		} else if (!rt->rt_gateway)
 			rt->rt_gateway = daddr;
 
-		orig = rcu_dereference(fnhe->fnhe_rth);
 		rcu_assign_pointer(fnhe->fnhe_rth, rt);
 		if (orig)
 			rt_free(orig);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index f32c02e..083092e 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -549,14 +549,12 @@
 			 !tp->urg_data ||
 			 before(tp->urg_seq, tp->copied_seq) ||
 			 !before(tp->urg_seq, tp->rcv_nxt)) {
-			struct sk_buff *skb;
 
 			answ = tp->rcv_nxt - tp->copied_seq;
 
-			/* Subtract 1, if FIN is in queue. */
-			skb = skb_peek_tail(&sk->sk_receive_queue);
-			if (answ && skb)
-				answ -= tcp_hdr(skb)->fin;
+			/* Subtract 1, if FIN was received */
+			if (answ && sock_flag(sk, SOCK_DONE))
+				answ--;
 		} else
 			answ = tp->urg_seq - tp->copied_seq;
 		release_sock(sk);
@@ -1214,7 +1212,7 @@
 wait_for_sndbuf:
 			set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 wait_for_memory:
-			if (copied && likely(!tp->repair))
+			if (copied)
 				tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
 
 			if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
@@ -1225,7 +1223,7 @@
 	}
 
 out:
-	if (copied && likely(!tp->repair))
+	if (copied)
 		tcp_push(sk, flags, mss_now, tp->nonagle);
 	release_sock(sk);
 	return copied + copied_syn;
@@ -2766,6 +2764,8 @@
 		info->tcpi_options |= TCPI_OPT_ECN;
 	if (tp->ecn_flags & TCP_ECN_SEEN)
 		info->tcpi_options |= TCPI_OPT_ECN_SEEN;
+	if (tp->syn_data_acked)
+		info->tcpi_options |= TCPI_OPT_SYN_DATA;
 
 	info->tcpi_rto = jiffies_to_usecs(icsk->icsk_rto);
 	info->tcpi_ato = jiffies_to_usecs(icsk->icsk_ack.ato);
diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c
index 813b43a..834857f 100644
--- a/net/ipv4/tcp_illinois.c
+++ b/net/ipv4/tcp_illinois.c
@@ -313,11 +313,13 @@
 			.tcpv_rttcnt = ca->cnt_rtt,
 			.tcpv_minrtt = ca->base_rtt,
 		};
-		u64 t = ca->sum_rtt;
 
-		do_div(t, ca->cnt_rtt);
-		info.tcpv_rtt = t;
+		if (info.tcpv_rttcnt > 0) {
+			u64 t = ca->sum_rtt;
 
+			do_div(t, info.tcpv_rttcnt);
+			info.tcpv_rtt = t;
+		}
 		nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
 	}
 }
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 432c366..609ff98 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4529,6 +4529,9 @@
 	struct tcphdr *th;
 	bool fragstolen;
 
+	if (size == 0)
+		return 0;
+
 	skb = alloc_skb(size + sizeof(*th), sk->sk_allocation);
 	if (!skb)
 		goto err;
@@ -5310,11 +5313,6 @@
 		goto discard;
 	}
 
-	/* ts_recent update must be made after we are sure that the packet
-	 * is in window.
-	 */
-	tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
-
 	/* step 3: check security and precedence [ignored] */
 
 	/* step 4: Check for a SYN
@@ -5549,6 +5547,11 @@
 	if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0)
 		goto discard;
 
+	/* ts_recent update must be made after we are sure that the packet
+	 * is in window.
+	 */
+	tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
+
 	tcp_rcv_rtt_measure_ts(sk, skb);
 
 	/* Process urgent data. */
@@ -5646,6 +5649,7 @@
 		tcp_rearm_rto(sk);
 		return true;
 	}
+	tp->syn_data_acked = tp->syn_data;
 	return false;
 }
 
@@ -5963,7 +5967,7 @@
 
 	req = tp->fastopen_rsk;
 	if (req != NULL) {
-		BUG_ON(sk->sk_state != TCP_SYN_RECV &&
+		WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV &&
 		    sk->sk_state != TCP_FIN_WAIT1);
 
 		if (tcp_check_req(sk, skb, req, NULL, true) == NULL)
@@ -6052,7 +6056,15 @@
 			 * ACK we have received, this would have acknowledged
 			 * our SYNACK so stop the SYNACK timer.
 			 */
-			if (acceptable && req != NULL) {
+			if (req != NULL) {
+				/* Return RST if ack_seq is invalid.
+				 * Note that RFC793 only says to generate a
+				 * DUPACK for it but for TCP Fast Open it seems
+				 * better to treat this case like TCP_SYN_RECV
+				 * above.
+				 */
+				if (!acceptable)
+					return 1;
 				/* We no longer need the request sock. */
 				reqsk_fastopen_remove(sk, req, false);
 				tcp_rearm_rto(sk);
@@ -6118,6 +6130,11 @@
 	} else
 		goto discard;
 
+	/* ts_recent update must be made after we are sure that the packet
+	 * is in window.
+	 */
+	tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
+
 	/* step 6: check the URG bit */
 	tcp_urg(sk, skb, th);
 
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index ef998b0..0c4a643 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1461,6 +1461,7 @@
 		skb_set_owner_r(skb, child);
 		__skb_queue_tail(&child->sk_receive_queue, skb);
 		tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+		tp->syn_data_acked = 1;
 	}
 	sk->sk_data_ready(sk, 0);
 	bh_unlock_sock(child);
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 4c752a6..f696d7c 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -1,7 +1,6 @@
 #include <linux/rcupdate.h>
 #include <linux/spinlock.h>
 #include <linux/jiffies.h>
-#include <linux/bootmem.h>
 #include <linux/module.h>
 #include <linux/cache.h>
 #include <linux/slab.h>
@@ -9,6 +8,7 @@
 #include <linux/tcp.h>
 #include <linux/hash.h>
 #include <linux/tcp_metrics.h>
+#include <linux/vmalloc.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/net_namespace.h>
@@ -864,7 +864,7 @@
 	}
 	a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6];
 	if (a) {
-		if (nla_len(a) != sizeof(sizeof(struct in6_addr)))
+		if (nla_len(a) != sizeof(struct in6_addr))
 			return -EINVAL;
 		addr->family = AF_INET6;
 		memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6));
@@ -1034,7 +1034,10 @@
 	net->ipv4.tcp_metrics_hash_log = order_base_2(slots);
 	size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log;
 
-	net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL);
+	net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
+	if (!net->ipv4.tcp_metrics_hash)
+		net->ipv4.tcp_metrics_hash = vzalloc(size);
+
 	if (!net->ipv4.tcp_metrics_hash)
 		return -ENOMEM;
 
@@ -1055,7 +1058,10 @@
 			tm = next;
 		}
 	}
-	kfree(net->ipv4.tcp_metrics_hash);
+	if (is_vmalloc_addr(net->ipv4.tcp_metrics_hash))
+		vfree(net->ipv4.tcp_metrics_hash);
+	else
+		kfree(net->ipv4.tcp_metrics_hash);
 }
 
 static __net_initdata struct pernet_operations tcp_net_metrics_ops = {
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 27536ba..a7302d9 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -510,6 +510,7 @@
 		newtp->rx_opt.mss_clamp = req->mss;
 		TCP_ECN_openreq_child(newtp, req);
 		newtp->fastopen_rsk = NULL;
+		newtp->syn_data_acked = 0;
 
 		TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_PASSIVEOPENS);
 	}
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index cfe6ffe..2798706 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1986,6 +1986,9 @@
 		tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
 		BUG_ON(!tso_segs);
 
+		if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE)
+			goto repair; /* Skip network transmission */
+
 		cwnd_quota = tcp_cwnd_test(tp, skb);
 		if (!cwnd_quota)
 			break;
@@ -2026,6 +2029,7 @@
 		if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp)))
 			break;
 
+repair:
 		/* Advance the send_head.  This one is sent out.
 		 * This call will increment packets_out.
 		 */
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index fc04711..d47c1b4 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -347,8 +347,8 @@
 		return;
 	}
 	if (tp->fastopen_rsk) {
-		BUG_ON(sk->sk_state != TCP_SYN_RECV &&
-		    sk->sk_state != TCP_FIN_WAIT1);
+		WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV &&
+			     sk->sk_state != TCP_FIN_WAIT1);
 		tcp_fastopen_synack_timer(sk);
 		/* Before we receive ACK to our SYN-ACK don't retransmit
 		 * anything else (e.g., data or FIN segments).
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 0185679..d5cb3c4 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -1633,9 +1633,9 @@
 		/* IFLA_GRE_OKEY */
 		nla_total_size(4) +
 		/* IFLA_GRE_LOCAL */
-		nla_total_size(4) +
+		nla_total_size(sizeof(struct in6_addr)) +
 		/* IFLA_GRE_REMOTE */
-		nla_total_size(4) +
+		nla_total_size(sizeof(struct in6_addr)) +
 		/* IFLA_GRE_TTL */
 		nla_total_size(1) +
 		/* IFLA_GRE_TOS */
@@ -1659,8 +1659,8 @@
 	    nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) ||
 	    nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
 	    nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
-	    nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->raddr) ||
-	    nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->laddr) ||
+	    nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->laddr) ||
+	    nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->raddr) ||
 	    nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) ||
 	    /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/
 	    nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) ||
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index ba6d13d..e02faed 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -827,6 +827,7 @@
 		if (val < 0 || val > 255)
 			goto e_inval;
 		np->min_hopcount = val;
+		retv = 0;
 		break;
 	case IPV6_DONTFRAG:
 		np->dontfrag = valbool;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index ff36194..2edce30 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -535,7 +535,7 @@
 {
 	struct inet6_dev *idev;
 	struct inet6_ifaddr *ifa;
-	struct in6_addr mcaddr;
+	struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
 
 	idev = in6_dev_get(dev);
 	if (!idev)
@@ -543,7 +543,6 @@
 
 	read_lock_bh(&idev->lock);
 	list_for_each_entry(ifa, &idev->addr_list, if_list) {
-		addrconf_addr_solict_mult(&ifa->addr, &mcaddr);
 		ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr,
 			      /*router=*/ !!idev->cnf.forwarding,
 			      /*solicited=*/ false, /*override=*/ true,
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
index e418bd6..d57dab1 100644
--- a/net/ipv6/netfilter/ip6table_nat.c
+++ b/net/ipv6/netfilter/ip6table_nat.c
@@ -186,7 +186,8 @@
 
 		if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
 				      &ct->tuplehash[!dir].tuple.dst.u3) ||
-		    (ct->tuplehash[dir].tuple.src.u.all !=
+		    (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
+		     ct->tuplehash[dir].tuple.src.u.all !=
 		     ct->tuplehash[!dir].tuple.dst.u.all))
 			if (nf_xfrm_me_harder(skb, AF_INET6) < 0)
 				ret = NF_DROP;
@@ -222,6 +223,7 @@
 		}
 #ifdef CONFIG_XFRM
 		else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
+			 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
 			 ct->tuplehash[dir].tuple.dst.u.all !=
 			 ct->tuplehash[!dir].tuple.src.u.all)
 			if (nf_xfrm_me_harder(skb, AF_INET6))
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 18bd9bb..22c8ea9 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -85,7 +85,7 @@
 	{ }
 };
 
-static int __net_init nf_ct_frag6_sysctl_register(struct net *net)
+static int nf_ct_frag6_sysctl_register(struct net *net)
 {
 	struct ctl_table *table;
 	struct ctl_table_header *hdr;
@@ -127,7 +127,7 @@
 }
 
 #else
-static int __net_init nf_ct_frag6_sysctl_register(struct net *net)
+static int nf_ct_frag6_sysctl_register(struct net *net)
 {
 	return 0;
 }
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 7c7e963..b1e6cf0 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -219,7 +219,7 @@
 };
 
 static const u32 ip6_template_metrics[RTAX_MAX] = {
-	[RTAX_HOPLIMIT - 1] = 255,
+	[RTAX_HOPLIMIT - 1] = 0,
 };
 
 static const struct rt6_info ip6_null_entry_template = {
@@ -1232,7 +1232,7 @@
 	rt->rt6i_dst.addr = fl6->daddr;
 	rt->rt6i_dst.plen = 128;
 	rt->rt6i_idev     = idev;
-	dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
+	dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 0);
 
 	spin_lock_bh(&icmp6_dst_lock);
 	rt->dst.next = icmp6_dst_gc_list;
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index 37b8b8b..76125c5 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -291,6 +291,7 @@
 
 out_del_dev:
 	free_netdev(dev);
+	spriv->dev = NULL;
 out_del_session:
 	l2tp_session_delete(session);
 out:
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 05f3a31..7371f67 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2594,6 +2594,9 @@
 		else
 			local->probe_req_reg--;
 
+		if (!local->open_count)
+			break;
+
 		ieee80211_queue_work(&local->hw, &local->reconfig_filter);
 		break;
 	default:
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 5f3620f..bf87c70 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1108,7 +1108,7 @@
 	sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
 	sdata->u.ibss.ibss_join_req = jiffies;
 
-	memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
+	memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
 	sdata->u.ibss.ssid_len = params->ssid_len;
 
 	mutex_unlock(&sdata->u.ibss.mtx);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8c80455..156e583 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1314,6 +1314,8 @@
 					 struct net_device *dev);
 netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 				       struct net_device *dev);
+void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
+			      struct sk_buff_head *skbs);
 
 /* HT */
 void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 6f8a73c..7de7717 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -853,7 +853,7 @@
 			struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 			if (info->control.vif == &sdata->vif) {
 				__skb_unlink(skb, &local->pending[i]);
-				dev_kfree_skb_irq(skb);
+				ieee80211_free_txskb(&local->hw, skb);
 			}
 		}
 	}
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index c80c449..f57f597 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -871,8 +871,10 @@
 				local->hw.wiphy->cipher_suites,
 				sizeof(u32) * local->hw.wiphy->n_cipher_suites,
 				GFP_KERNEL);
-			if (!suites)
-				return -ENOMEM;
+			if (!suites) {
+				result = -ENOMEM;
+				goto fail_wiphy_register;
+			}
 			for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
 				u32 suite = local->hw.wiphy->cipher_suites[r];
 				if (suite == WLAN_CIPHER_SUITE_WEP40 ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index e714ed8..1b7eed2 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3099,22 +3099,32 @@
 				   ht_cfreq, ht_oper->primary_chan,
 				   cbss->channel->band);
 			ht_oper = NULL;
+		} else {
+			channel_type = NL80211_CHAN_HT20;
 		}
 	}
 
-	if (ht_oper) {
-		channel_type = NL80211_CHAN_HT20;
+	if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
+		/*
+		 * cfg80211 already verified that the channel itself can
+		 * be used, but it didn't check that we can do the right
+		 * HT type, so do that here as well. If HT40 isn't allowed
+		 * on this channel, disable 40 MHz operation.
+		 */
 
-		if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
-			switch (ht_oper->ht_param &
-					IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
-			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+		switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+		case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+			if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS)
+				ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ;
+			else
 				channel_type = NL80211_CHAN_HT40PLUS;
-				break;
-			case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+			break;
+		case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+			if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS)
+				ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ;
+			else
 				channel_type = NL80211_CHAN_HT40MINUS;
-				break;
-			}
+			break;
 		}
 	}
 
@@ -3549,6 +3559,7 @@
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
+	bool tx = !req->local_state_change;
 
 	mutex_lock(&ifmgd->mtx);
 
@@ -3565,12 +3576,12 @@
 	if (ifmgd->associated &&
 	    ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
 		ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
-				       req->reason_code, true, frame_buf);
+				       req->reason_code, tx, frame_buf);
 	} else {
 		drv_mgd_prepare_tx(sdata->local, sdata);
 		ieee80211_send_deauth_disassoc(sdata, req->bssid,
 					       IEEE80211_STYPE_DEAUTH,
-					       req->reason_code, true,
+					       req->reason_code, tx,
 					       frame_buf);
 	}
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 61c621e..00ade7f 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -531,6 +531,11 @@
 
 		if (ieee80211_is_action(hdr->frame_control)) {
 			u8 category;
+
+			/* make sure category field is present */
+			if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
+				return RX_DROP_MONITOR;
+
 			mgmt = (struct ieee80211_mgmt *)hdr;
 			category = mgmt->u.action.category;
 			if (category != WLAN_CATEGORY_MESH_ACTION &&
@@ -883,14 +888,16 @@
 		 */
 		if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
 		    ieee80211_is_data_present(hdr->frame_control)) {
-			u16 ethertype;
-			u8 *payload;
+			unsigned int hdrlen;
+			__be16 ethertype;
 
-			payload = rx->skb->data +
-				ieee80211_hdrlen(hdr->frame_control);
-			ethertype = (payload[6] << 8) | payload[7];
-			if (cpu_to_be16(ethertype) ==
-			    rx->sdata->control_port_protocol)
+			hdrlen = ieee80211_hdrlen(hdr->frame_control);
+
+			if (rx->skb->len < hdrlen + 8)
+				return RX_DROP_MONITOR;
+
+			skb_copy_bits(rx->skb, hdrlen + 6, &ethertype, 2);
+			if (ethertype == rx->sdata->control_port_protocol)
 				return RX_CONTINUE;
 		}
 
@@ -1462,11 +1469,14 @@
 
 	hdr = (struct ieee80211_hdr *)rx->skb->data;
 	fc = hdr->frame_control;
+
+	if (ieee80211_is_ctl(fc))
+		return RX_CONTINUE;
+
 	sc = le16_to_cpu(hdr->seq_ctrl);
 	frag = sc & IEEE80211_SCTL_FRAG;
 
 	if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
-		   (rx->skb)->len < 24 ||
 		   is_multicast_ether_addr(hdr->addr1))) {
 		/* not fragmented */
 		goto out;
@@ -1889,6 +1899,20 @@
 
 	hdr = (struct ieee80211_hdr *) skb->data;
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
+
+	/* make sure fixed part of mesh header is there, also checks skb len */
+	if (!pskb_may_pull(rx->skb, hdrlen + 6))
+		return RX_DROP_MONITOR;
+
+	mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
+
+	/* make sure full mesh header is there, also checks skb len */
+	if (!pskb_may_pull(rx->skb,
+			   hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))
+		return RX_DROP_MONITOR;
+
+	/* reload pointers */
+	hdr = (struct ieee80211_hdr *) skb->data;
 	mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
 
 	/* frame is in RMC, don't forward */
@@ -1897,7 +1921,8 @@
 	    mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata))
 		return RX_DROP_MONITOR;
 
-	if (!ieee80211_is_data(hdr->frame_control))
+	if (!ieee80211_is_data(hdr->frame_control) ||
+	    !(status->rx_flags & IEEE80211_RX_RA_MATCH))
 		return RX_CONTINUE;
 
 	if (!mesh_hdr->ttl)
@@ -1911,9 +1936,12 @@
 		if (is_multicast_ether_addr(hdr->addr1)) {
 			mpp_addr = hdr->addr3;
 			proxied_addr = mesh_hdr->eaddr1;
-		} else {
+		} else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {
+			/* has_a4 already checked in ieee80211_rx_mesh_check */
 			mpp_addr = hdr->addr4;
 			proxied_addr = mesh_hdr->eaddr2;
+		} else {
+			return RX_DROP_MONITOR;
 		}
 
 		rcu_read_lock();
@@ -1941,12 +1969,9 @@
 	}
 	skb_set_queue_mapping(skb, q);
 
-	if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
-		goto out;
-
 	if (!--mesh_hdr->ttl) {
 		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
-		return RX_DROP_MONITOR;
+		goto out;
 	}
 
 	if (!ifmsh->mshcfg.dot11MeshForwarding)
@@ -2353,6 +2378,10 @@
 		}
 		break;
 	case WLAN_CATEGORY_SELF_PROTECTED:
+		if (len < (IEEE80211_MIN_ACTION_SIZE +
+			   sizeof(mgmt->u.action.u.self_prot.action_code)))
+			break;
+
 		switch (mgmt->u.action.u.self_prot.action_code) {
 		case WLAN_SP_MESH_PEERING_OPEN:
 		case WLAN_SP_MESH_PEERING_CLOSE:
@@ -2371,6 +2400,10 @@
 		}
 		break;
 	case WLAN_CATEGORY_MESH_ACTION:
+		if (len < (IEEE80211_MIN_ACTION_SIZE +
+			   sizeof(mgmt->u.action.u.mesh_action.action_code)))
+			break;
+
 		if (!ieee80211_vif_is_mesh(&sdata->vif))
 			break;
 		if (mesh_action_is_path_sel(mgmt) &&
@@ -2913,10 +2946,15 @@
 	if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
 		local->dot11ReceivedFragmentCount++;
 
-	if (ieee80211_is_mgmt(fc))
-		err = skb_linearize(skb);
-	else
+	if (ieee80211_is_mgmt(fc)) {
+		/* drop frame if too short for header */
+		if (skb->len < ieee80211_hdrlen(fc))
+			err = -ENOBUFS;
+		else
+			err = skb_linearize(skb);
+	} else {
 		err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
+	}
 
 	if (err) {
 		dev_kfree_skb(skb);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index c4cdbde..43e60b5 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -917,7 +917,7 @@
 				       struct cfg80211_sched_scan_request *req)
 {
 	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_sched_scan_ies sched_scan_ies;
+	struct ieee80211_sched_scan_ies sched_scan_ies = {};
 	int ret, i;
 
 	mutex_lock(&local->mtx);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 797dd36..d2eb64e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -117,8 +117,8 @@
 
 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
 		local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
-		__skb_queue_purge(&sta->ps_tx_buf[ac]);
-		__skb_queue_purge(&sta->tx_filtered[ac]);
+		ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]);
+		ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]);
 	}
 
 #ifdef CONFIG_MAC80211_MESH
@@ -141,7 +141,7 @@
 		tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
 		if (!tid_tx)
 			continue;
-		__skb_queue_purge(&tid_tx->pending);
+		ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending);
 		kfree(tid_tx);
 	}
 
@@ -650,7 +650,7 @@
 		 */
 		if (!skb)
 			break;
-		dev_kfree_skb(skb);
+		ieee80211_free_txskb(&local->hw, skb);
 	}
 
 	/*
@@ -679,7 +679,7 @@
 		local->total_ps_buffered--;
 		ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n",
 		       sta->sta.addr);
-		dev_kfree_skb(skb);
+		ieee80211_free_txskb(&local->hw, skb);
 	}
 
 	/*
@@ -961,6 +961,7 @@
 	struct ieee80211_local *local = sdata->local;
 	struct sk_buff_head pending;
 	int filtered = 0, buffered = 0, ac;
+	unsigned long flags;
 
 	clear_sta_flag(sta, WLAN_STA_SP);
 
@@ -976,12 +977,16 @@
 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
 		int count = skb_queue_len(&pending), tmp;
 
+		spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags);
 		skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending);
+		spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags);
 		tmp = skb_queue_len(&pending);
 		filtered += tmp - count;
 		count = tmp;
 
+		spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags);
 		skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending);
+		spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags);
 		tmp = skb_queue_len(&pending);
 		buffered += tmp - count;
 	}
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 3af0cc4..101eb88 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -668,3 +668,12 @@
 	dev_kfree_skb_any(skb);
 }
 EXPORT_SYMBOL(ieee80211_free_txskb);
+
+void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
+			      struct sk_buff_head *skbs)
+{
+	struct sk_buff *skb;
+
+	while ((skb = __skb_dequeue(skbs)))
+		ieee80211_free_txskb(hw, skb);
+}
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c9bf83f..b858ebe 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1358,7 +1358,7 @@
 		if (tx->skb)
 			ieee80211_free_txskb(&tx->local->hw, tx->skb);
 		else
-			__skb_queue_purge(&tx->skbs);
+			ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs);
 		return -1;
 	} else if (unlikely(res == TX_QUEUED)) {
 		I802_DEBUG_INC(tx->local->tx_handlers_queued);
@@ -2120,10 +2120,13 @@
  */
 void ieee80211_clear_tx_pending(struct ieee80211_local *local)
 {
+	struct sk_buff *skb;
 	int i;
 
-	for (i = 0; i < local->hw.queues; i++)
-		skb_queue_purge(&local->pending[i]);
+	for (i = 0; i < local->hw.queues; i++) {
+		while ((skb = skb_dequeue(&local->pending[i])) != NULL)
+			ieee80211_free_txskb(&local->hw, skb);
+	}
 }
 
 /*
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 22ca350..0151ae3 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -406,7 +406,7 @@
 	int queue = info->hw_queue;
 
 	if (WARN_ON(!info->control.vif)) {
-		kfree_skb(skb);
+		ieee80211_free_txskb(&local->hw, skb);
 		return;
 	}
 
@@ -431,7 +431,7 @@
 		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
 		if (WARN_ON(!info->control.vif)) {
-			kfree_skb(skb);
+			ieee80211_free_txskb(&local->hw, skb);
 			continue;
 		}
 
@@ -643,13 +643,41 @@
 			break;
 		}
 
-		if (id != WLAN_EID_VENDOR_SPECIFIC &&
-		    id != WLAN_EID_QUIET &&
-		    test_bit(id, seen_elems)) {
-			elems->parse_error = true;
-			left -= elen;
-			pos += elen;
-			continue;
+		switch (id) {
+		case WLAN_EID_SSID:
+		case WLAN_EID_SUPP_RATES:
+		case WLAN_EID_FH_PARAMS:
+		case WLAN_EID_DS_PARAMS:
+		case WLAN_EID_CF_PARAMS:
+		case WLAN_EID_TIM:
+		case WLAN_EID_IBSS_PARAMS:
+		case WLAN_EID_CHALLENGE:
+		case WLAN_EID_RSN:
+		case WLAN_EID_ERP_INFO:
+		case WLAN_EID_EXT_SUPP_RATES:
+		case WLAN_EID_HT_CAPABILITY:
+		case WLAN_EID_HT_OPERATION:
+		case WLAN_EID_VHT_CAPABILITY:
+		case WLAN_EID_VHT_OPERATION:
+		case WLAN_EID_MESH_ID:
+		case WLAN_EID_MESH_CONFIG:
+		case WLAN_EID_PEER_MGMT:
+		case WLAN_EID_PREQ:
+		case WLAN_EID_PREP:
+		case WLAN_EID_PERR:
+		case WLAN_EID_RANN:
+		case WLAN_EID_CHANNEL_SWITCH:
+		case WLAN_EID_EXT_CHANSWITCH_ANN:
+		case WLAN_EID_COUNTRY:
+		case WLAN_EID_PWR_CONSTRAINT:
+		case WLAN_EID_TIMEOUT_INTERVAL:
+			if (test_bit(id, seen_elems)) {
+				elems->parse_error = true;
+				left -= elen;
+				pos += elen;
+				continue;
+			}
+			break;
 		}
 
 		if (calc_crc && id < 64 && (filter & (1ULL << id)))
@@ -1463,6 +1491,8 @@
 		list_for_each_entry(sdata, &local->interfaces, list) {
 			if (sdata->vif.type != NL80211_IFTYPE_STATION)
 				continue;
+			if (!sdata->u.mgd.associated)
+				continue;
 
 			ieee80211_send_nullfunc(local, sdata, 0);
 		}
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index bdb53ab..8bd2f5c 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -106,7 +106,8 @@
 		if (status->flag & RX_FLAG_MMIC_ERROR)
 			goto mic_fail;
 
-		if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key)
+		if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key &&
+		    rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)
 			goto update_iv;
 
 		return RX_CONTINUE;
@@ -545,14 +546,19 @@
 
 static void bip_aad(struct sk_buff *skb, u8 *aad)
 {
+	__le16 mask_fc;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+
 	/* BIP AAD: FC(masked) || A1 || A2 || A3 */
 
 	/* FC type/subtype */
-	aad[0] = skb->data[0];
 	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
-	aad[1] = skb->data[1] & ~(BIT(4) | BIT(5) | BIT(6));
+	mask_fc = hdr->frame_control;
+	mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | IEEE80211_FCTL_PM |
+				IEEE80211_FCTL_MOREDATA);
+	put_unaligned(mask_fc, (__le16 *) &aad[0]);
 	/* A1 || A2 || A3 */
-	memcpy(aad + 2, skb->data + 4, 3 * ETH_ALEN);
+	memcpy(aad + 2, &hdr->addr1, 3 * ETH_ALEN);
 }
 
 
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 7e7198b..c4ee437 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -2589,6 +2589,8 @@
 	struct ip_vs_proto_data *pd;
 #endif
 
+	memset(u, 0, sizeof (*u));
+
 #ifdef CONFIG_IP_VS_PROTO_TCP
 	pd = ip_vs_proto_data_get(net, IPPROTO_TCP);
 	u->tcp_timeout = pd->timeout_table[IP_VS_TCP_S_ESTABLISHED] / HZ;
@@ -2766,7 +2768,6 @@
 	{
 		struct ip_vs_timeout_user t;
 
-		memset(&t, 0, sizeof(t));
 		__ip_vs_get_timeouts(net, &t);
 		if (copy_to_user(user, &t, sizeof(t)) != 0)
 			ret = -EFAULT;
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 1b30b0d..962795e 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -753,7 +753,8 @@
 				   flowi4_to_flowi(&fl1), false)) {
 			if (!afinfo->route(&init_net, (struct dst_entry **)&rt2,
 					   flowi4_to_flowi(&fl2), false)) {
-				if (rt1->rt_gateway == rt2->rt_gateway &&
+				if (rt_nexthop(rt1, fl1.daddr) ==
+				    rt_nexthop(rt2, fl2.daddr) &&
 				    rt1->dst.dev  == rt2->dst.dev)
 					ret = 1;
 				dst_release(&rt2->dst);
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index 16c7125..ae7f5da 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -180,9 +180,9 @@
 	typeof(nf_ct_timeout_find_get_hook) timeout_find_get;
 	struct ctnl_timeout *timeout;
 	struct nf_conn_timeout *timeout_ext;
-	const struct ipt_entry *e = par->entryinfo;
 	struct nf_conntrack_l4proto *l4proto;
 	int ret = 0;
+	u8 proto;
 
 	rcu_read_lock();
 	timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook);
@@ -192,9 +192,11 @@
 		goto out;
 	}
 
-	if (e->ip.invflags & IPT_INV_PROTO) {
+	proto = xt_ct_find_proto(par);
+	if (!proto) {
 		ret = -EINVAL;
-		pr_info("You cannot use inversion on L4 protocol\n");
+		pr_info("You must specify a L4 protocol, and not use "
+			"inversions on it.\n");
 		goto out;
 	}
 
@@ -214,7 +216,7 @@
 	/* Make sure the timeout policy matches any existing protocol tracker,
 	 * otherwise default to generic.
 	 */
-	l4proto = __nf_ct_l4proto_find(par->family, e->ip.proto);
+	l4proto = __nf_ct_l4proto_find(par->family, proto);
 	if (timeout->l4proto->l4proto != l4proto->l4proto) {
 		ret = -EINVAL;
 		pr_info("Timeout policy `%s' can only be used by L4 protocol "
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
index ee2e5bc..bd93e51 100644
--- a/net/netfilter/xt_TEE.c
+++ b/net/netfilter/xt_TEE.c
@@ -70,6 +70,7 @@
 	fl4.daddr = info->gw.ip;
 	fl4.flowi4_tos = RT_TOS(iph->tos);
 	fl4.flowi4_scope = RT_SCOPE_UNIVERSE;
+	fl4.flowi4_flags = FLOWI_FLAG_KNOWN_NH;
 	rt = ip_route_output_key(net, &fl4);
 	if (IS_ERR(rt))
 		return false;
diff --git a/net/netfilter/xt_nat.c b/net/netfilter/xt_nat.c
index 81aafa8..bea7464c 100644
--- a/net/netfilter/xt_nat.c
+++ b/net/netfilter/xt_nat.c
@@ -111,7 +111,7 @@
 		.family		= NFPROTO_IPV4,
 		.table		= "nat",
 		.hooks		= (1 << NF_INET_POST_ROUTING) |
-				  (1 << NF_INET_LOCAL_OUT),
+				  (1 << NF_INET_LOCAL_IN),
 		.me		= THIS_MODULE,
 	},
 	{
@@ -123,7 +123,7 @@
 		.family		= NFPROTO_IPV4,
 		.table		= "nat",
 		.hooks		= (1 << NF_INET_PRE_ROUTING) |
-				  (1 << NF_INET_LOCAL_IN),
+				  (1 << NF_INET_LOCAL_OUT),
 		.me		= THIS_MODULE,
 	},
 	{
@@ -133,7 +133,7 @@
 		.targetsize	= sizeof(struct nf_nat_range),
 		.table		= "nat",
 		.hooks		= (1 << NF_INET_POST_ROUTING) |
-				  (1 << NF_INET_LOCAL_OUT),
+				  (1 << NF_INET_LOCAL_IN),
 		.me		= THIS_MODULE,
 	},
 	{
@@ -143,7 +143,7 @@
 		.targetsize	= sizeof(struct nf_nat_range),
 		.table		= "nat",
 		.hooks		= (1 << NF_INET_PRE_ROUTING) |
-				  (1 << NF_INET_LOCAL_IN),
+				  (1 << NF_INET_LOCAL_OUT),
 		.me		= THIS_MODULE,
 	},
 };
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 01e944a..4da797f 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -138,6 +138,8 @@
 static DEFINE_RWLOCK(nl_table_lock);
 static atomic_t nl_table_users = ATOMIC_INIT(0);
 
+#define nl_deref_protected(X) rcu_dereference_protected(X, lockdep_is_held(&nl_table_lock));
+
 static ATOMIC_NOTIFIER_HEAD(netlink_chain);
 
 static inline u32 netlink_group_mask(u32 group)
@@ -345,6 +347,11 @@
 	struct hlist_node *node;
 	unsigned long mask;
 	unsigned int i;
+	struct listeners *listeners;
+
+	listeners = nl_deref_protected(tbl->listeners);
+	if (!listeners)
+		return;
 
 	for (i = 0; i < NLGRPLONGS(tbl->groups); i++) {
 		mask = 0;
@@ -352,7 +359,7 @@
 			if (i < NLGRPLONGS(nlk_sk(sk)->ngroups))
 				mask |= nlk_sk(sk)->groups[i];
 		}
-		tbl->listeners->masks[i] = mask;
+		listeners->masks[i] = mask;
 	}
 	/* this function is only called with the netlink table "grabbed", which
 	 * makes sure updates are visible before bind or setsockopt return. */
@@ -536,7 +543,11 @@
 	if (netlink_is_kernel(sk)) {
 		BUG_ON(nl_table[sk->sk_protocol].registered == 0);
 		if (--nl_table[sk->sk_protocol].registered == 0) {
-			kfree(nl_table[sk->sk_protocol].listeners);
+			struct listeners *old;
+
+			old = nl_deref_protected(nl_table[sk->sk_protocol].listeners);
+			RCU_INIT_POINTER(nl_table[sk->sk_protocol].listeners, NULL);
+			kfree_rcu(old, rcu);
 			nl_table[sk->sk_protocol].module = NULL;
 			nl_table[sk->sk_protocol].bind = NULL;
 			nl_table[sk->sk_protocol].flags = 0;
@@ -982,7 +993,7 @@
 	rcu_read_lock();
 	listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners);
 
-	if (group - 1 < nl_table[sk->sk_protocol].groups)
+	if (listeners && group - 1 < nl_table[sk->sk_protocol].groups)
 		res = test_bit(group - 1, listeners->masks);
 
 	rcu_read_unlock();
@@ -1625,7 +1636,7 @@
 		new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC);
 		if (!new)
 			return -ENOMEM;
-		old = rcu_dereference_protected(tbl->listeners, 1);
+		old = nl_deref_protected(tbl->listeners);
 		memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups));
 		rcu_assign_pointer(tbl->listeners, new);
 
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index f0dd83c..9687fa1 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -84,18 +84,19 @@
  * grp->index is the index of the group; and grp->slot_shift
  * is the shift for the corresponding (scaled) sigma_i.
  */
-#define QFQ_MAX_INDEX		19
-#define QFQ_MAX_WSHIFT		16
+#define QFQ_MAX_INDEX		24
+#define QFQ_MAX_WSHIFT		12
 
 #define	QFQ_MAX_WEIGHT		(1<<QFQ_MAX_WSHIFT)
-#define QFQ_MAX_WSUM		(2*QFQ_MAX_WEIGHT)
+#define QFQ_MAX_WSUM		(16*QFQ_MAX_WEIGHT)
 
 #define FRAC_BITS		30	/* fixed point arithmetic */
 #define ONE_FP			(1UL << FRAC_BITS)
 #define IWSUM			(ONE_FP/QFQ_MAX_WSUM)
 
-#define QFQ_MTU_SHIFT		11
+#define QFQ_MTU_SHIFT		16	/* to support TSO/GSO */
 #define QFQ_MIN_SLOT_SHIFT	(FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX)
+#define QFQ_MIN_LMAX		256	/* min possible lmax for a class */
 
 /*
  * Possible group states.  These values are used as indexes for the bitmaps
@@ -231,6 +232,32 @@
 	q->wsum += delta_w;
 }
 
+static void qfq_update_reactivate_class(struct qfq_sched *q,
+					struct qfq_class *cl,
+					u32 inv_w, u32 lmax, int delta_w)
+{
+	bool need_reactivation = false;
+	int i = qfq_calc_index(inv_w, lmax);
+
+	if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) {
+		/*
+		 * shift cl->F back, to not charge the
+		 * class for the not-yet-served head
+		 * packet
+		 */
+		cl->F = cl->S;
+		/* remove class from its slot in the old group */
+		qfq_deactivate_class(q, cl);
+		need_reactivation = true;
+	}
+
+	qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
+
+	if (need_reactivation) /* activate in new group */
+		qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc));
+}
+
+
 static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 			    struct nlattr **tca, unsigned long *arg)
 {
@@ -238,7 +265,7 @@
 	struct qfq_class *cl = (struct qfq_class *)*arg;
 	struct nlattr *tb[TCA_QFQ_MAX + 1];
 	u32 weight, lmax, inv_w;
-	int i, err;
+	int err;
 	int delta_w;
 
 	if (tca[TCA_OPTIONS] == NULL) {
@@ -270,16 +297,14 @@
 
 	if (tb[TCA_QFQ_LMAX]) {
 		lmax = nla_get_u32(tb[TCA_QFQ_LMAX]);
-		if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) {
+		if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) {
 			pr_notice("qfq: invalid max length %u\n", lmax);
 			return -EINVAL;
 		}
 	} else
-		lmax = 1UL << QFQ_MTU_SHIFT;
+		lmax = psched_mtu(qdisc_dev(sch));
 
 	if (cl != NULL) {
-		bool need_reactivation = false;
-
 		if (tca[TCA_RATE]) {
 			err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
 						    qdisc_root_sleeping_lock(sch),
@@ -291,24 +316,8 @@
 		if (lmax == cl->lmax && inv_w == cl->inv_w)
 			return 0; /* nothing to update */
 
-		i = qfq_calc_index(inv_w, lmax);
 		sch_tree_lock(sch);
-		if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) {
-			/*
-			 * shift cl->F back, to not charge the
-			 * class for the not-yet-served head
-			 * packet
-			 */
-			cl->F = cl->S;
-			/* remove class from its slot in the old group */
-			qfq_deactivate_class(q, cl);
-			need_reactivation = true;
-		}
-
-		qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
-
-		if (need_reactivation) /* activate in new group */
-			qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc));
+		qfq_update_reactivate_class(q, cl, inv_w, lmax, delta_w);
 		sch_tree_unlock(sch);
 
 		return 0;
@@ -663,15 +672,48 @@
 
 
 /*
- * XXX we should make sure that slot becomes less than 32.
- * This is guaranteed by the input values.
- * roundedS is always cl->S rounded on grp->slot_shift bits.
+ * If the weight and lmax (max_pkt_size) of the classes do not change,
+ * then QFQ guarantees that the slot index is never higher than
+ * 2 + ((1<<QFQ_MTU_SHIFT)/QFQ_MIN_LMAX) * (QFQ_MAX_WEIGHT/QFQ_MAX_WSUM).
+ *
+ * With the current values of the above constants, the index is
+ * then guaranteed to never be higher than 2 + 256 * (1 / 16) = 18.
+ *
+ * When the weight of a class is increased or the lmax of the class is
+ * decreased, a new class with smaller slot size may happen to be
+ * activated. The activation of this class should be properly delayed
+ * to when the service of the class has finished in the ideal system
+ * tracked by QFQ. If the activation of the class is not delayed to
+ * this reference time instant, then this class may be unjustly served
+ * before other classes waiting for service. This may cause
+ * (unfrequently) the above bound to the slot index to be violated for
+ * some of these unlucky classes.
+ *
+ * Instead of delaying the activation of the new class, which is quite
+ * complex, the following inaccurate but simple solution is used: if
+ * the slot index is higher than QFQ_MAX_SLOTS-2, then the timestamps
+ * of the class are shifted backward so as to let the slot index
+ * become equal to QFQ_MAX_SLOTS-2. This threshold is used because, if
+ * the slot index is above it, then the data structure implementing
+ * the bucket list either gets immediately corrupted or may get
+ * corrupted on a possible next packet arrival that causes the start
+ * time of the group to be shifted backward.
  */
 static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl,
 			    u64 roundedS)
 {
 	u64 slot = (roundedS - grp->S) >> grp->slot_shift;
-	unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS;
+	unsigned int i; /* slot index in the bucket list */
+
+	if (unlikely(slot > QFQ_MAX_SLOTS - 2)) {
+		u64 deltaS = roundedS - grp->S -
+			((u64)(QFQ_MAX_SLOTS - 2)<<grp->slot_shift);
+		cl->S -= deltaS;
+		cl->F -= deltaS;
+		slot = QFQ_MAX_SLOTS - 2;
+	}
+
+	i = (grp->front + slot) % QFQ_MAX_SLOTS;
 
 	hlist_add_head(&cl->next, &grp->slots[i]);
 	__set_bit(slot, &grp->full_slots);
@@ -892,6 +934,13 @@
 	}
 	pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid);
 
+	if (unlikely(cl->lmax < qdisc_pkt_len(skb))) {
+		pr_debug("qfq: increasing maxpkt from %u to %u for class %u",
+			  cl->lmax, qdisc_pkt_len(skb), cl->common.classid);
+		qfq_update_reactivate_class(q, cl, cl->inv_w,
+					    qdisc_pkt_len(skb), 0);
+	}
+
 	err = qdisc_enqueue(skb, cl->qdisc);
 	if (unlikely(err != NET_XMIT_SUCCESS)) {
 		pr_debug("qfq_enqueue: enqueue failed %d\n", err);
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index c3bea26..9966e7b 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -102,7 +102,7 @@
 	.open	 = sctp_snmp_seq_open,
 	.read	 = seq_read,
 	.llseek	 = seq_lseek,
-	.release = single_release,
+	.release = single_release_net,
 };
 
 /* Set up the proc fs entry for 'snmp' object. */
@@ -251,7 +251,7 @@
 	.open	 = sctp_eps_seq_open,
 	.read	 = seq_read,
 	.llseek	 = seq_lseek,
-	.release = seq_release,
+	.release = seq_release_net,
 };
 
 /* Set up the proc fs entry for 'eps' object. */
@@ -372,7 +372,7 @@
 	.open	 = sctp_assocs_seq_open,
 	.read	 = seq_read,
 	.llseek	 = seq_lseek,
-	.release = seq_release,
+	.release = seq_release_net,
 };
 
 /* Set up the proc fs entry for 'assocs' object. */
@@ -517,7 +517,7 @@
 	.open = sctp_remaddr_seq_open,
 	.read = seq_read,
 	.llseek = seq_lseek,
-	.release = seq_release,
+	.release = seq_release_net,
 };
 
 int __net_init sctp_remaddr_proc_init(struct net *net)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 59d16ea..a60d1f8 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -974,7 +974,7 @@
 	void *addr_buf;
 	struct sctp_af *af;
 
-	SCTP_DEBUG_PRINTK("sctp_setsocktopt_bindx: sk %p addrs %p"
+	SCTP_DEBUG_PRINTK("sctp_setsockopt_bindx: sk %p addrs %p"
 			  " addrs_size %d opt %d\n", sk, addrs, addrs_size, op);
 
 	if (unlikely(addrs_size <= 0))
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
index 5a3d675..a9c0bbc 100644
--- a/net/sunrpc/backchannel_rqst.c
+++ b/net/sunrpc/backchannel_rqst.c
@@ -172,7 +172,7 @@
 		xprt_free_allocation(req);
 
 	dprintk("RPC:       setup backchannel transport failed\n");
-	return -1;
+	return -ENOMEM;
 }
 EXPORT_SYMBOL_GPL(xprt_setup_backchannel);
 
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index aaaadfb..75853ca 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -254,7 +254,6 @@
 	void			(*old_data_ready)(struct sock *, int);
 	void			(*old_state_change)(struct sock *);
 	void			(*old_write_space)(struct sock *);
-	void			(*old_error_report)(struct sock *);
 };
 
 /*
@@ -737,10 +736,10 @@
 		dprintk("RPC:       sendmsg returned unrecognized error %d\n",
 			-status);
 	case -ECONNRESET:
-	case -EPIPE:
 		xs_tcp_shutdown(xprt);
 	case -ECONNREFUSED:
 	case -ENOTCONN:
+	case -EPIPE:
 		clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
 	}
 
@@ -781,7 +780,6 @@
 	transport->old_data_ready = sk->sk_data_ready;
 	transport->old_state_change = sk->sk_state_change;
 	transport->old_write_space = sk->sk_write_space;
-	transport->old_error_report = sk->sk_error_report;
 }
 
 static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk)
@@ -789,7 +787,6 @@
 	sk->sk_data_ready = transport->old_data_ready;
 	sk->sk_state_change = transport->old_state_change;
 	sk->sk_write_space = transport->old_write_space;
-	sk->sk_error_report = transport->old_error_report;
 }
 
 static void xs_reset_transport(struct sock_xprt *transport)
@@ -1453,7 +1450,7 @@
 	xprt_clear_connecting(xprt);
 }
 
-static void xs_sock_mark_closed(struct rpc_xprt *xprt)
+static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt)
 {
 	smp_mb__before_clear_bit();
 	clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
@@ -1461,6 +1458,11 @@
 	clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
 	clear_bit(XPRT_CLOSING, &xprt->state);
 	smp_mb__after_clear_bit();
+}
+
+static void xs_sock_mark_closed(struct rpc_xprt *xprt)
+{
+	xs_sock_reset_connection_flags(xprt);
 	/* Mark transport as closed and wake up all pending tasks */
 	xprt_disconnect_done(xprt);
 }
@@ -1516,6 +1518,7 @@
 	case TCP_CLOSE_WAIT:
 		/* The server initiated a shutdown of the socket */
 		xprt->connect_cookie++;
+		clear_bit(XPRT_CONNECTED, &xprt->state);
 		xs_tcp_force_close(xprt);
 	case TCP_CLOSING:
 		/*
@@ -1540,25 +1543,6 @@
 	read_unlock_bh(&sk->sk_callback_lock);
 }
 
-/**
- * xs_error_report - callback mainly for catching socket errors
- * @sk: socket
- */
-static void xs_error_report(struct sock *sk)
-{
-	struct rpc_xprt *xprt;
-
-	read_lock_bh(&sk->sk_callback_lock);
-	if (!(xprt = xprt_from_sock(sk)))
-		goto out;
-	dprintk("RPC:       %s client %p...\n"
-			"RPC:       error %d\n",
-			__func__, xprt, sk->sk_err);
-	xprt_wake_pending_tasks(xprt, -EAGAIN);
-out:
-	read_unlock_bh(&sk->sk_callback_lock);
-}
-
 static void xs_write_space(struct sock *sk)
 {
 	struct socket *sock;
@@ -1858,7 +1842,6 @@
 		sk->sk_user_data = xprt;
 		sk->sk_data_ready = xs_local_data_ready;
 		sk->sk_write_space = xs_udp_write_space;
-		sk->sk_error_report = xs_error_report;
 		sk->sk_allocation = GFP_ATOMIC;
 
 		xprt_clear_connected(xprt);
@@ -1983,7 +1966,6 @@
 		sk->sk_user_data = xprt;
 		sk->sk_data_ready = xs_udp_data_ready;
 		sk->sk_write_space = xs_udp_write_space;
-		sk->sk_error_report = xs_error_report;
 		sk->sk_no_check = UDP_CSUM_NORCV;
 		sk->sk_allocation = GFP_ATOMIC;
 
@@ -2050,10 +2032,8 @@
 	any.sa_family = AF_UNSPEC;
 	result = kernel_connect(transport->sock, &any, sizeof(any), 0);
 	if (!result)
-		xs_sock_mark_closed(&transport->xprt);
-	else
-		dprintk("RPC:       AF_UNSPEC connect return code %d\n",
-				result);
+		xs_sock_reset_connection_flags(&transport->xprt);
+	dprintk("RPC:       AF_UNSPEC connect return code %d\n", result);
 }
 
 static void xs_tcp_reuse_connection(struct sock_xprt *transport)
@@ -2098,7 +2078,6 @@
 		sk->sk_data_ready = xs_tcp_data_ready;
 		sk->sk_state_change = xs_tcp_state_change;
 		sk->sk_write_space = xs_tcp_write_space;
-		sk->sk_error_report = xs_error_report;
 		sk->sk_allocation = GFP_ATOMIC;
 
 		/* socket options */
diff --git a/net/tipc/handler.c b/net/tipc/handler.c
index 111ff83..b36f0fc 100644
--- a/net/tipc/handler.c
+++ b/net/tipc/handler.c
@@ -116,7 +116,6 @@
 		return;
 
 	handler_enabled = 0;
-	tasklet_disable(&tipc_tasklet);
 	tasklet_kill(&tipc_tasklet);
 
 	spin_lock_bh(&qitem_lock);
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 443d4d7..3f72530 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -526,8 +526,7 @@
 		for (i = 0; i < sband->n_channels; i++) {
 			sband->channels[i].orig_flags =
 				sband->channels[i].flags;
-			sband->channels[i].orig_mag =
-				sband->channels[i].max_antenna_gain;
+			sband->channels[i].orig_mag = INT_MAX;
 			sband->channels[i].orig_mpwr =
 				sband->channels[i].max_power;
 			sband->channels[i].band = band;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 8016fee..904a7f3 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -457,20 +457,14 @@
 		.reason_code = reason,
 		.ie = ie,
 		.ie_len = ie_len,
+		.local_state_change = local_state_change,
 	};
 
 	ASSERT_WDEV_LOCK(wdev);
 
-	if (local_state_change) {
-		if (wdev->current_bss &&
-		    ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
-			cfg80211_unhold_bss(wdev->current_bss);
-			cfg80211_put_bss(&wdev->current_bss->pub);
-			wdev->current_bss = NULL;
-		}
-
+	if (local_state_change && (!wdev->current_bss ||
+	    !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
 		return 0;
-	}
 
 	return rdev->ops->deauth(&rdev->wiphy, dev, &req);
 }
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 3b8cbbc..b75756b 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -141,9 +141,8 @@
 	.reg_rules = {
 		/* IEEE 802.11b/g, channels 1..11 */
 		REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
-		/* IEEE 802.11b/g, channels 12..13. No HT40
-		 * channel fits here. */
-		REG_RULE(2467-10, 2472+10, 20, 6, 20,
+		/* IEEE 802.11b/g, channels 12..13. */
+		REG_RULE(2467-10, 2472+10, 40, 6, 20,
 			NL80211_RRF_PASSIVE_SCAN |
 			NL80211_RRF_NO_IBSS),
 		/* IEEE 802.11 channel 14 - Only JP enables
@@ -908,7 +907,7 @@
 			map_regdom_flags(reg_rule->flags) | bw_flags;
 		chan->max_antenna_gain = chan->orig_mag =
 			(int) MBI_TO_DBI(power_rule->max_antenna_gain);
-		chan->max_power = chan->orig_mpwr =
+		chan->max_reg_power = chan->max_power = chan->orig_mpwr =
 			(int) MBM_TO_DBM(power_rule->max_eirp);
 		return;
 	}
@@ -1331,7 +1330,8 @@
 
 	chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags;
 	chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
-	chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
+	chan->max_reg_power = chan->max_power =
+		(int) MBM_TO_DBM(power_rule->max_eirp);
 }
 
 static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index ef35f4e..2762e83 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -309,23 +309,21 @@
 }
 EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
 
-static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
 {
 	int ae = meshhdr->flags & MESH_FLAGS_AE;
-	/* 7.1.3.5a.2 */
+	/* 802.11-2012, 8.2.4.7.3 */
 	switch (ae) {
+	default:
 	case 0:
 		return 6;
 	case MESH_FLAGS_AE_A4:
 		return 12;
 	case MESH_FLAGS_AE_A5_A6:
 		return 18;
-	case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6):
-		return 24;
-	default:
-		return 6;
 	}
 }
+EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
 
 int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
 			   enum nl80211_iftype iftype)
@@ -373,6 +371,8 @@
 			/* make sure meshdr->flags is on the linear part */
 			if (!pskb_may_pull(skb, hdrlen + 1))
 				return -1;
+			if (meshdr->flags & MESH_FLAGS_AE_A4)
+				return -1;
 			if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
 				skb_copy_bits(skb, hdrlen +
 					offsetof(struct ieee80211s_hdr, eaddr1),
@@ -397,6 +397,8 @@
 			/* make sure meshdr->flags is on the linear part */
 			if (!pskb_may_pull(skb, hdrlen + 1))
 				return -1;
+			if (meshdr->flags & MESH_FLAGS_AE_A5_A6)
+				return -1;
 			if (meshdr->flags & MESH_FLAGS_AE_A4)
 				skb_copy_bits(skb, hdrlen +
 					offsetof(struct ieee80211s_hdr, eaddr1),
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index dda4b2b..ecbb447 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -16,8 +16,9 @@
 __modinst: $(modules)
 	@:
 
+# Don't stop modules_install if we can't sign external modules.
 quiet_cmd_modules_install = INSTALL $@
-      cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@)
+      cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD))
 
 # Modules built outside the kernel source tree go into extra by default
 INSTALL_MOD_DIR ?= extra
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 21a9f5d..f18750e 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1890,8 +1890,10 @@
 		}
 
 		if ($realfile =~ m@^(drivers/net/|net/)@ &&
-		    $rawline !~ m@^\+[ \t]*(\/\*|\*\/)@ &&
-		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {
+		    $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
+		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
+		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
+		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
 			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
 			     "networking block comments put the trailing */ on a separate line\n" . $herecurr);
 		}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index bd2e098..cdd4860 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -12,7 +12,7 @@
 
 #include <assert.h>
 #include <stdio.h>
-#include <sys/queue.h>
+#include "list.h"
 #ifndef __cplusplus
 #include <stdbool.h>
 #endif
@@ -175,12 +175,11 @@
 #define MENU_ROOT		0x0002
 
 struct jump_key {
-	CIRCLEQ_ENTRY(jump_key) entries;
+	struct list_head entries;
 	size_t offset;
 	struct menu *target;
 	int index;
 };
-CIRCLEQ_HEAD(jk_head, jump_key);
 
 #define JUMP_NB			9
 
diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h
new file mode 100644
index 0000000..0ae730b
--- /dev/null
+++ b/scripts/kconfig/list.h
@@ -0,0 +1,91 @@
+#ifndef LIST_H
+#define LIST_H
+
+/*
+ * Copied from include/linux/...
+ */
+
+#undef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr:        the pointer to the member.
+ * @type:       the type of the container struct this is embedded in.
+ * @member:     the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({                      \
+	const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+	(type *)( (char *)__mptr - offsetof(type,member) );})
+
+
+struct list_head {
+	struct list_head *next, *prev;
+};
+
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+	struct list_head name = LIST_HEAD_INIT(name)
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:	the &struct list_head pointer.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+	container_of(ptr, type, member)
+
+/**
+ * list_for_each_entry	-	iterate over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)				\
+	for (pos = list_entry((head)->next, typeof(*pos), member);	\
+	     &pos->member != (head); 	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+	return head->next == head;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *_new,
+			      struct list_head *prev,
+			      struct list_head *next)
+{
+	next->prev = _new;
+	_new->next = next;
+	_new->prev = prev;
+	prev->next = _new;
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *_new, struct list_head *head)
+{
+	__list_add(_new, head->prev, head);
+}
+
+#endif
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 1d1c085..ef1a738 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -21,9 +21,9 @@
 P(menu_get_parent_menu,struct menu *,(struct menu *menu));
 P(menu_has_help,bool,(struct menu *menu));
 P(menu_get_help,const char *,(struct menu *menu));
-P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head
+P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head
 			 *head));
-P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head
+P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head
 				   *head));
 P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
 
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 48f6744..53975cf 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -312,7 +312,7 @@
 
 
 struct search_data {
-	struct jk_head *head;
+	struct list_head *head;
 	struct menu **targets;
 	int *keys;
 };
@@ -323,7 +323,7 @@
 	struct jump_key *pos;
 	int k = 0;
 
-	CIRCLEQ_FOREACH(pos, data->head, entries) {
+	list_for_each_entry(pos, data->head, entries) {
 		if (pos->offset >= start && pos->offset < end) {
 			char header[4];
 
@@ -375,7 +375,7 @@
 
 	sym_arr = sym_re_search(dialog_input);
 	do {
-		struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head);
+		LIST_HEAD(head);
 		struct menu *targets[JUMP_NB];
 		int keys[JUMP_NB + 1], i;
 		struct search_data data = {
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index a3cade6..e98a05c 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -508,7 +508,7 @@
 }
 
 static void get_prompt_str(struct gstr *r, struct property *prop,
-			   struct jk_head *head)
+			   struct list_head *head)
 {
 	int i, j;
 	struct menu *submenu[8], *menu, *location = NULL;
@@ -544,12 +544,13 @@
 		} else
 			jump->target = location;
 
-		if (CIRCLEQ_EMPTY(head))
+		if (list_empty(head))
 			jump->index = 0;
 		else
-			jump->index = CIRCLEQ_LAST(head)->index + 1;
+			jump->index = list_entry(head->prev, struct jump_key,
+						 entries)->index + 1;
 
-		CIRCLEQ_INSERT_TAIL(head, jump, entries);
+		list_add_tail(&jump->entries, head);
 	}
 
 	if (i > 0) {
@@ -573,7 +574,8 @@
 /*
  * head is optional and may be NULL
  */
-void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head)
+void get_symbol_str(struct gstr *r, struct symbol *sym,
+		    struct list_head *head)
 {
 	bool hit;
 	struct property *prop;
@@ -612,7 +614,7 @@
 	str_append(r, "\n\n");
 }
 
-struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head)
+struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head)
 {
 	struct symbol *sym;
 	struct gstr res = str_new();
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index cf5fd22..8132003 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -724,6 +724,8 @@
  */
 static void free_profile(struct aa_profile *profile)
 {
+	struct aa_profile *p;
+
 	AA_DEBUG("%s(%p)\n", __func__, profile);
 
 	if (!profile)
@@ -751,7 +753,27 @@
 	aa_put_dfa(profile->xmatch);
 	aa_put_dfa(profile->policy.dfa);
 
-	aa_put_profile(profile->replacedby);
+	/* put the profile reference for replacedby, but not via
+	 * put_profile(kref_put).
+	 * replacedby can form a long chain that can result in cascading
+	 * frees that blows the stack because kref_put makes a nested fn
+	 * call (it looks like recursion, with free_profile calling
+	 * free_profile) for each profile in the chain lp#1056078.
+	 */
+	for (p = profile->replacedby; p; ) {
+		if (atomic_dec_and_test(&p->base.count.refcount)) {
+			/* no more refs on p, grab its replacedby */
+			struct aa_profile *next = p->replacedby;
+			/* break the chain */
+			p->replacedby = NULL;
+			/* now free p, chain is broken */
+			free_profile(p);
+
+			/* follow up with next profile in the chain */
+			p = next;
+		} else
+			break;
+	}
 
 	kzfree(profile);
 }
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 44dfc41..b08d20c 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -42,7 +42,10 @@
 struct dev_cgroup {
 	struct cgroup_subsys_state css;
 	struct list_head exceptions;
-	bool deny_all;
+	enum {
+		DEVCG_DEFAULT_ALLOW,
+		DEVCG_DEFAULT_DENY,
+	} behavior;
 };
 
 static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s)
@@ -161,8 +164,8 @@
 	struct dev_exception_item *ex, *tmp;
 
 	list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) {
-		list_del(&ex->list);
-		kfree(ex);
+		list_del_rcu(&ex->list);
+		kfree_rcu(ex, rcu);
 	}
 }
 
@@ -182,13 +185,13 @@
 	parent_cgroup = cgroup->parent;
 
 	if (parent_cgroup == NULL)
-		dev_cgroup->deny_all = false;
+		dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW;
 	else {
 		parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup);
 		mutex_lock(&devcgroup_mutex);
 		ret = dev_exceptions_copy(&dev_cgroup->exceptions,
 					  &parent_dev_cgroup->exceptions);
-		dev_cgroup->deny_all = parent_dev_cgroup->deny_all;
+		dev_cgroup->behavior = parent_dev_cgroup->behavior;
 		mutex_unlock(&devcgroup_mutex);
 		if (ret) {
 			kfree(dev_cgroup);
@@ -260,7 +263,7 @@
 	 * - List the exceptions in case the default policy is to deny
 	 * This way, the file remains as a "whitelist of devices"
 	 */
-	if (devcgroup->deny_all == false) {
+	if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) {
 		set_access(acc, ACC_MASK);
 		set_majmin(maj, ~0);
 		set_majmin(min, ~0);
@@ -295,7 +298,7 @@
 	struct dev_exception_item *ex;
 	bool match = false;
 
-	list_for_each_entry(ex, &dev_cgroup->exceptions, list) {
+	list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) {
 		if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK))
 			continue;
 		if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR))
@@ -314,12 +317,12 @@
 	 * In two cases we'll consider this new exception valid:
 	 * - the dev cgroup has its default policy to allow + exception list:
 	 *   the new exception should *not* match any of the exceptions
-	 *   (!deny_all, !match)
+	 *   (behavior == DEVCG_DEFAULT_ALLOW, !match)
 	 * - the dev cgroup has its default policy to deny + exception list:
 	 *   the new exception *should* match the exceptions
-	 *   (deny_all, match)
+	 *   (behavior == DEVCG_DEFAULT_DENY, match)
 	 */
-	if (dev_cgroup->deny_all == match)
+	if ((dev_cgroup->behavior == DEVCG_DEFAULT_DENY) == match)
 		return 1;
 	return 0;
 }
@@ -341,6 +344,19 @@
 	return may_access(parent, ex);
 }
 
+/**
+ * may_allow_all - checks if it's possible to change the behavior to
+ *		   allow based on parent's rules.
+ * @parent: device cgroup's parent
+ * returns: != 0 in case it's allowed, 0 otherwise
+ */
+static inline int may_allow_all(struct dev_cgroup *parent)
+{
+	if (!parent)
+		return 1;
+	return parent->behavior == DEVCG_DEFAULT_ALLOW;
+}
+
 /*
  * Modify the exception list using allow/deny rules.
  * CAP_SYS_ADMIN is needed for this.  It's at least separate from CAP_MKNOD
@@ -358,13 +374,18 @@
 				   int filetype, const char *buffer)
 {
 	const char *b;
-	char *endp;
-	int count;
+	char temp[12];		/* 11 + 1 characters needed for a u32 */
+	int count, rc;
 	struct dev_exception_item ex;
+	struct cgroup *p = devcgroup->css.cgroup;
+	struct dev_cgroup *parent = NULL;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
+	if (p->parent)
+		parent = cgroup_to_devcgroup(p->parent);
+
 	memset(&ex, 0, sizeof(ex));
 	b = buffer;
 
@@ -372,14 +393,21 @@
 	case 'a':
 		switch (filetype) {
 		case DEVCG_ALLOW:
-			if (!parent_has_perm(devcgroup, &ex))
+			if (!may_allow_all(parent))
 				return -EPERM;
 			dev_exception_clean(devcgroup);
-			devcgroup->deny_all = false;
+			devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
+			if (!parent)
+				break;
+
+			rc = dev_exceptions_copy(&devcgroup->exceptions,
+						 &parent->exceptions);
+			if (rc)
+				return rc;
 			break;
 		case DEVCG_DENY:
 			dev_exception_clean(devcgroup);
-			devcgroup->deny_all = true;
+			devcgroup->behavior = DEVCG_DEFAULT_DENY;
 			break;
 		default:
 			return -EINVAL;
@@ -402,8 +430,16 @@
 		ex.major = ~0;
 		b++;
 	} else if (isdigit(*b)) {
-		ex.major = simple_strtoul(b, &endp, 10);
-		b = endp;
+		memset(temp, 0, sizeof(temp));
+		for (count = 0; count < sizeof(temp) - 1; count++) {
+			temp[count] = *b;
+			b++;
+			if (!isdigit(*b))
+				break;
+		}
+		rc = kstrtou32(temp, 10, &ex.major);
+		if (rc)
+			return -EINVAL;
 	} else {
 		return -EINVAL;
 	}
@@ -416,8 +452,16 @@
 		ex.minor = ~0;
 		b++;
 	} else if (isdigit(*b)) {
-		ex.minor = simple_strtoul(b, &endp, 10);
-		b = endp;
+		memset(temp, 0, sizeof(temp));
+		for (count = 0; count < sizeof(temp) - 1; count++) {
+			temp[count] = *b;
+			b++;
+			if (!isdigit(*b))
+				break;
+		}
+		rc = kstrtou32(temp, 10, &ex.minor);
+		if (rc)
+			return -EINVAL;
 	} else {
 		return -EINVAL;
 	}
@@ -452,7 +496,7 @@
 		 * an matching exception instead. And be silent about it: we
 		 * don't want to break compatibility
 		 */
-		if (devcgroup->deny_all == false) {
+		if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) {
 			dev_exception_rm(devcgroup, &ex);
 			return 0;
 		}
@@ -463,7 +507,7 @@
 		 * an matching exception instead. And be silent about it: we
 		 * don't want to break compatibility
 		 */
-		if (devcgroup->deny_all == true) {
+		if (devcgroup->behavior == DEVCG_DEFAULT_DENY) {
 			dev_exception_rm(devcgroup, &ex);
 			return 0;
 		}
@@ -533,10 +577,10 @@
  *
  * returns 0 on success, -EPERM case the operation is not permitted
  */
-static int __devcgroup_check_permission(struct dev_cgroup *dev_cgroup,
-					short type, u32 major, u32 minor,
+static int __devcgroup_check_permission(short type, u32 major, u32 minor,
 				        short access)
 {
+	struct dev_cgroup *dev_cgroup;
 	struct dev_exception_item ex;
 	int rc;
 
@@ -547,6 +591,7 @@
 	ex.access = access;
 
 	rcu_read_lock();
+	dev_cgroup = task_devcgroup(current);
 	rc = may_access(dev_cgroup, &ex);
 	rcu_read_unlock();
 
@@ -558,7 +603,6 @@
 
 int __devcgroup_inode_permission(struct inode *inode, int mask)
 {
-	struct dev_cgroup *dev_cgroup = task_devcgroup(current);
 	short type, access = 0;
 
 	if (S_ISBLK(inode->i_mode))
@@ -570,13 +614,12 @@
 	if (mask & MAY_READ)
 		access |= ACC_READ;
 
-	return __devcgroup_check_permission(dev_cgroup, type, imajor(inode),
-					    iminor(inode), access);
+	return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
+			access);
 }
 
 int devcgroup_inode_mknod(int mode, dev_t dev)
 {
-	struct dev_cgroup *dev_cgroup = task_devcgroup(current);
 	short type;
 
 	if (!S_ISBLK(mode) && !S_ISCHR(mode))
@@ -587,7 +630,7 @@
 	else
 		type = DEV_CHAR;
 
-	return __devcgroup_check_permission(dev_cgroup, type, MAJOR(dev),
-					    MINOR(dev), ACC_MKNOD);
+	return __devcgroup_check_permission(type, MAJOR(dev), MINOR(dev),
+			ACC_MKNOD);
 
 }
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index c40ae57..ad11dc9 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -100,12 +100,15 @@
 
 	if (dirn != compr->direction) {
 		pr_err("this device doesn't support this direction\n");
+		snd_card_unref(compr->card);
 		return -EINVAL;
 	}
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data)
+	if (!data) {
+		snd_card_unref(compr->card);
 		return -ENOMEM;
+	}
 	data->stream.ops = compr->ops;
 	data->stream.direction = dirn;
 	data->stream.private_data = compr->private_data;
@@ -113,6 +116,7 @@
 	runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
 	if (!runtime) {
 		kfree(data);
+		snd_card_unref(compr->card);
 		return -ENOMEM;
 	}
 	runtime->state = SNDRV_PCM_STATE_OPEN;
@@ -126,7 +130,8 @@
 		kfree(runtime);
 		kfree(data);
 	}
-	return ret;
+	snd_card_unref(compr->card);
+	return 0;
 }
 
 static int snd_compr_free(struct inode *inode, struct file *f)
diff --git a/sound/core/control.c b/sound/core/control.c
index 7e86a5b9..8c7c2c9 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -86,6 +86,7 @@
 	write_lock_irqsave(&card->ctl_files_rwlock, flags);
 	list_add_tail(&ctl->list, &card->ctl_files);
 	write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
+	snd_card_unref(card);
 	return 0;
 
       __error:
@@ -93,6 +94,8 @@
       __error2:
 	snd_card_file_remove(card, file);
       __error1:
+	if (card)
+		snd_card_unref(card);
       	return err;
 }
 
@@ -1434,6 +1437,8 @@
 			spin_unlock_irq(&ctl->read_lock);
 			schedule();
 			remove_wait_queue(&ctl->change_sleep, &wait);
+			if (ctl->card->shutdown)
+				return -ENODEV;
 			if (signal_pending(current))
 				return -ERESTARTSYS;
 			spin_lock_irq(&ctl->read_lock);
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 75ea16f..3f7f662 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -100,8 +100,10 @@
 	if (hw == NULL)
 		return -ENODEV;
 
-	if (!try_module_get(hw->card->module))
+	if (!try_module_get(hw->card->module)) {
+		snd_card_unref(hw->card);
 		return -EFAULT;
+	}
 
 	init_waitqueue_entry(&wait, current);
 	add_wait_queue(&hw->open_wait, &wait);
@@ -129,6 +131,10 @@
 		mutex_unlock(&hw->open_mutex);
 		schedule();
 		mutex_lock(&hw->open_mutex);
+		if (hw->card->shutdown) {
+			err = -ENODEV;
+			break;
+		}
 		if (signal_pending(current)) {
 			err = -ERESTARTSYS;
 			break;
@@ -148,6 +154,7 @@
 	mutex_unlock(&hw->open_mutex);
 	if (err < 0)
 		module_put(hw->card->module);
+	snd_card_unref(hw->card);
 	return err;
 }
 
@@ -459,12 +466,15 @@
 		mutex_unlock(&register_mutex);
 		return -EINVAL;
 	}
+	mutex_lock(&hwdep->open_mutex);
+	wake_up(&hwdep->open_wait);
 #ifdef CONFIG_SND_OSSEMUL
 	if (hwdep->ossreg)
 		snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device);
 #endif
 	snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device);
 	list_del_init(&hwdep->list);
+	mutex_unlock(&hwdep->open_mutex);
 	mutex_unlock(&register_mutex);
 	return 0;
 }
diff --git a/sound/core/init.c b/sound/core/init.c
index d8ec849..7b012d1 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -213,6 +213,7 @@
 	spin_lock_init(&card->files_lock);
 	INIT_LIST_HEAD(&card->files_list);
 	init_waitqueue_head(&card->shutdown_sleep);
+	atomic_set(&card->refcount, 0);
 #ifdef CONFIG_PM
 	mutex_init(&card->power_lock);
 	init_waitqueue_head(&card->power_sleep);
@@ -446,21 +447,36 @@
 	return 0;
 }
 
+/**
+ * snd_card_unref - release the reference counter
+ * @card: the card instance
+ *
+ * Decrements the reference counter.  When it reaches to zero, wake up
+ * the sleeper and call the destructor if needed.
+ */
+void snd_card_unref(struct snd_card *card)
+{
+	if (atomic_dec_and_test(&card->refcount)) {
+		wake_up(&card->shutdown_sleep);
+		if (card->free_on_last_close)
+			snd_card_do_free(card);
+	}
+}
+EXPORT_SYMBOL(snd_card_unref);
+
 int snd_card_free_when_closed(struct snd_card *card)
 {
-	int free_now = 0;
-	int ret = snd_card_disconnect(card);
-	if (ret)
+	int ret;
+
+	atomic_inc(&card->refcount);
+	ret = snd_card_disconnect(card);
+	if (ret) {
+		atomic_dec(&card->refcount);
 		return ret;
+	}
 
-	spin_lock(&card->files_lock);
-	if (list_empty(&card->files_list))
-		free_now = 1;
-	else
-		card->free_on_last_close = 1;
-	spin_unlock(&card->files_lock);
-
-	if (free_now)
+	card->free_on_last_close = 1;
+	if (atomic_dec_and_test(&card->refcount))
 		snd_card_do_free(card);
 	return 0;
 }
@@ -474,7 +490,7 @@
 		return ret;
 
 	/* wait, until all devices are ready for the free operation */
-	wait_event(card->shutdown_sleep, list_empty(&card->files_list));
+	wait_event(card->shutdown_sleep, !atomic_read(&card->refcount));
 	snd_card_do_free(card);
 	return 0;
 }
@@ -886,6 +902,7 @@
 		return -ENODEV;
 	}
 	list_add(&mfile->list, &card->files_list);
+	atomic_inc(&card->refcount);
 	spin_unlock(&card->files_lock);
 	return 0;
 }
@@ -908,7 +925,6 @@
 int snd_card_file_remove(struct snd_card *card, struct file *file)
 {
 	struct snd_monitor_file *mfile, *found = NULL;
-	int last_close = 0;
 
 	spin_lock(&card->files_lock);
 	list_for_each_entry(mfile, &card->files_list, list) {
@@ -923,19 +939,13 @@
 			break;
 		}
 	}
-	if (list_empty(&card->files_list))
-		last_close = 1;
 	spin_unlock(&card->files_lock);
-	if (last_close) {
-		wake_up(&card->shutdown_sleep);
-		if (card->free_on_last_close)
-			snd_card_do_free(card);
-	}
 	if (!found) {
 		snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
 		return -ENOENT;
 	}
 	kfree(found);
+	snd_card_unref(card);
 	return 0;
 }
 
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 29f6ded..e8a1d18 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -52,14 +52,19 @@
 					 SNDRV_OSS_DEVICE_TYPE_MIXER);
 	if (card == NULL)
 		return -ENODEV;
-	if (card->mixer_oss == NULL)
+	if (card->mixer_oss == NULL) {
+		snd_card_unref(card);
 		return -ENODEV;
+	}
 	err = snd_card_file_add(card, file);
-	if (err < 0)
+	if (err < 0) {
+		snd_card_unref(card);
 		return err;
+	}
 	fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL);
 	if (fmixer == NULL) {
 		snd_card_file_remove(card, file);
+		snd_card_unref(card);
 		return -ENOMEM;
 	}
 	fmixer->card = card;
@@ -68,8 +73,10 @@
 	if (!try_module_get(card->module)) {
 		kfree(fmixer);
 		snd_card_file_remove(card, file);
+		snd_card_unref(card);
 		return -EFAULT;
 	}
+	snd_card_unref(card);
 	return 0;
 }
 
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 08fde00..4c1cc51 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2441,6 +2441,10 @@
 		mutex_unlock(&pcm->open_mutex);
 		schedule();
 		mutex_lock(&pcm->open_mutex);
+		if (pcm->card->shutdown) {
+			err = -ENODEV;
+			break;
+		}
 		if (signal_pending(current)) {
 			err = -ERESTARTSYS;
 			break;
@@ -2450,6 +2454,7 @@
 	mutex_unlock(&pcm->open_mutex);
 	if (err < 0)
 		goto __error;
+	snd_card_unref(pcm->card);
 	return err;
 
       __error:
@@ -2457,6 +2462,8 @@
       __error2:
       	snd_card_file_remove(pcm->card, file);
       __error1:
+	if (pcm)
+		snd_card_unref(pcm->card);
 	return err;
 }
 
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index f299194..030102c 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -1086,11 +1086,19 @@
 	if (list_empty(&pcm->list))
 		goto unlock;
 
+	mutex_lock(&pcm->open_mutex);
+	wake_up(&pcm->open_wait);
 	list_del_init(&pcm->list);
 	for (cidx = 0; cidx < 2; cidx++)
-		for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
-			if (substream->runtime)
+		for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {
+			snd_pcm_stream_lock_irq(substream);
+			if (substream->runtime) {
 				substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
+				wake_up(&substream->runtime->sleep);
+				wake_up(&substream->runtime->tsleep);
+			}
+			snd_pcm_stream_unlock_irq(substream);
+		}
 	list_for_each_entry(notify, &snd_pcm_notify_list, list) {
 		notify->n_disconnect(pcm);
 	}
@@ -1110,6 +1118,7 @@
 			pcm->streams[cidx].chmap_kctl = NULL;
 		}
 	}
+	mutex_unlock(&pcm->open_mutex);
  unlock:
 	mutex_unlock(&register_mutex);
 	return 0;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 5e12e5b..f9ddecf 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -369,6 +369,14 @@
 	return usecs;
 }
 
+static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state)
+{
+	snd_pcm_stream_lock_irq(substream);
+	if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED)
+		substream->runtime->status->state = state;
+	snd_pcm_stream_unlock_irq(substream);
+}
+
 static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params)
 {
@@ -452,7 +460,7 @@
 		runtime->boundary *= 2;
 
 	snd_pcm_timer_resolution_change(substream);
-	runtime->status->state = SNDRV_PCM_STATE_SETUP;
+	snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP);
 
 	if (pm_qos_request_active(&substream->latency_pm_qos_req))
 		pm_qos_remove_request(&substream->latency_pm_qos_req);
@@ -464,7 +472,7 @@
 	/* hardware might be unusable from this time,
 	   so we force application to retry to set
 	   the correct hardware parameter settings */
-	runtime->status->state = SNDRV_PCM_STATE_OPEN;
+	snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
 	if (substream->ops->hw_free != NULL)
 		substream->ops->hw_free(substream);
 	return err;
@@ -512,7 +520,7 @@
 		return -EBADFD;
 	if (substream->ops->hw_free)
 		result = substream->ops->hw_free(substream);
-	runtime->status->state = SNDRV_PCM_STATE_OPEN;
+	snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
 	pm_qos_remove_request(&substream->latency_pm_qos_req);
 	return result;
 }
@@ -1320,7 +1328,7 @@
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	runtime->control->appl_ptr = runtime->status->hw_ptr;
-	runtime->status->state = SNDRV_PCM_STATE_PREPARED;
+	snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED);
 }
 
 static struct action_ops snd_pcm_action_prepare = {
@@ -1510,6 +1518,10 @@
 		down_read(&snd_pcm_link_rwsem);
 		snd_pcm_stream_lock_irq(substream);
 		remove_wait_queue(&to_check->sleep, &wait);
+		if (card->shutdown) {
+			result = -ENODEV;
+			break;
+		}
 		if (tout == 0) {
 			if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
 				result = -ESTRPIPE;
@@ -1634,6 +1646,7 @@
 	write_unlock_irq(&snd_pcm_link_rwlock);
 	up_write(&snd_pcm_link_rwsem);
  _nolock:
+	snd_card_unref(substream1->pcm->card);
 	fput_light(file, fput_needed);
 	if (res < 0)
 		kfree(group);
@@ -2108,7 +2121,10 @@
 		return err;
 	pcm = snd_lookup_minor_data(iminor(inode),
 				    SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
-	return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
+	err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
+	if (pcm)
+		snd_card_unref(pcm->card);
+	return err;
 }
 
 static int snd_pcm_capture_open(struct inode *inode, struct file *file)
@@ -2119,7 +2135,10 @@
 		return err;
 	pcm = snd_lookup_minor_data(iminor(inode),
 				    SNDRV_DEVICE_TYPE_PCM_CAPTURE);
-	return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
+	err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
+	if (pcm)
+		snd_card_unref(pcm->card);
+	return err;
 }
 
 static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
@@ -2156,6 +2175,10 @@
 		mutex_unlock(&pcm->open_mutex);
 		schedule();
 		mutex_lock(&pcm->open_mutex);
+		if (pcm->card->shutdown) {
+			err = -ENODEV;
+			break;
+		}
 		if (signal_pending(current)) {
 			err = -ERESTARTSYS;
 			break;
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index ebf6e49..1bb95ae 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -379,8 +379,10 @@
 	if (rmidi == NULL)
 		return -ENODEV;
 
-	if (!try_module_get(rmidi->card->module))
+	if (!try_module_get(rmidi->card->module)) {
+		snd_card_unref(rmidi->card);
 		return -ENXIO;
+	}
 
 	mutex_lock(&rmidi->open_mutex);
 	card = rmidi->card;
@@ -422,6 +424,10 @@
 		mutex_unlock(&rmidi->open_mutex);
 		schedule();
 		mutex_lock(&rmidi->open_mutex);
+		if (rmidi->card->shutdown) {
+			err = -ENODEV;
+			break;
+		}
 		if (signal_pending(current)) {
 			err = -ERESTARTSYS;
 			break;
@@ -440,6 +446,7 @@
 #endif
 	file->private_data = rawmidi_file;
 	mutex_unlock(&rmidi->open_mutex);
+	snd_card_unref(rmidi->card);
 	return 0;
 
  __error:
@@ -447,6 +454,7 @@
  __error_card:
 	mutex_unlock(&rmidi->open_mutex);
 	module_put(rmidi->card->module);
+	snd_card_unref(rmidi->card);
 	return err;
 }
 
@@ -991,6 +999,8 @@
 			spin_unlock_irq(&runtime->lock);
 			schedule();
 			remove_wait_queue(&runtime->sleep, &wait);
+			if (rfile->rmidi->card->shutdown)
+				return -ENODEV;
 			if (signal_pending(current))
 				return result > 0 ? result : -ERESTARTSYS;
 			if (!runtime->avail)
@@ -1234,6 +1244,8 @@
 			spin_unlock_irq(&runtime->lock);
 			timeout = schedule_timeout(30 * HZ);
 			remove_wait_queue(&runtime->sleep, &wait);
+			if (rfile->rmidi->card->shutdown)
+				return -ENODEV;
 			if (signal_pending(current))
 				return result > 0 ? result : -ERESTARTSYS;
 			if (!runtime->avail && !timeout)
@@ -1609,9 +1621,20 @@
 static int snd_rawmidi_dev_disconnect(struct snd_device *device)
 {
 	struct snd_rawmidi *rmidi = device->device_data;
+	int dir;
 
 	mutex_lock(&register_mutex);
+	mutex_lock(&rmidi->open_mutex);
+	wake_up(&rmidi->open_wait);
 	list_del_init(&rmidi->list);
+	for (dir = 0; dir < 2; dir++) {
+		struct snd_rawmidi_substream *s;
+		list_for_each_entry(s, &rmidi->streams[dir].substreams, list) {
+			if (s->runtime)
+				wake_up(&s->runtime->sleep);
+		}
+	}
+
 #ifdef CONFIG_SND_OSSEMUL
 	if (rmidi->ossreg) {
 		if ((int)rmidi->device == midi_map[rmidi->card->number]) {
@@ -1626,6 +1649,7 @@
 	}
 #endif /* CONFIG_SND_OSSEMUL */
 	snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
+	mutex_unlock(&rmidi->open_mutex);
 	mutex_unlock(&register_mutex);
 	return 0;
 }
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 6439760..70ccdab 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -98,6 +98,10 @@
  *
  * Checks that a minor device with the specified type is registered, and returns
  * its user data pointer.
+ *
+ * This function increments the reference counter of the card instance
+ * if an associated instance with the given minor number and type is found.
+ * The caller must call snd_card_unref() appropriately later.
  */
 void *snd_lookup_minor_data(unsigned int minor, int type)
 {
@@ -108,9 +112,11 @@
 		return NULL;
 	mutex_lock(&sound_mutex);
 	mreg = snd_minors[minor];
-	if (mreg && mreg->type == type)
+	if (mreg && mreg->type == type) {
 		private_data = mreg->private_data;
-	else
+		if (private_data && mreg->card_ptr)
+			atomic_inc(&mreg->card_ptr->refcount);
+	} else
 		private_data = NULL;
 	mutex_unlock(&sound_mutex);
 	return private_data;
@@ -275,6 +281,7 @@
 	preg->device = dev;
 	preg->f_ops = f_ops;
 	preg->private_data = private_data;
+	preg->card_ptr = card;
 	mutex_lock(&sound_mutex);
 #ifdef CONFIG_SND_DYNAMIC_MINORS
 	minor = snd_find_free_minor(type);
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index e952833..726a49a 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -40,6 +40,9 @@
 static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
 static DEFINE_MUTEX(sound_oss_mutex);
 
+/* NOTE: This function increments the refcount of the associated card like
+ * snd_lookup_minor_data(); the caller must call snd_card_unref() appropriately
+ */
 void *snd_lookup_oss_minor_data(unsigned int minor, int type)
 {
 	struct snd_minor *mreg;
@@ -49,9 +52,11 @@
 		return NULL;
 	mutex_lock(&sound_oss_mutex);
 	mreg = snd_oss_minors[minor];
-	if (mreg && mreg->type == type)
+	if (mreg && mreg->type == type) {
 		private_data = mreg->private_data;
-	else
+		if (private_data && mreg->card_ptr)
+			atomic_inc(&mreg->card_ptr->refcount);
+	} else
 		private_data = NULL;
 	mutex_unlock(&sound_oss_mutex);
 	return private_data;
@@ -123,6 +128,7 @@
 	preg->device = dev;
 	preg->f_ops = f_ops;
 	preg->private_data = private_data;
+	preg->card_ptr = card;
 	mutex_lock(&sound_oss_mutex);
 	snd_oss_minors[minor] = preg;
 	minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index ef68d71..e04e750 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -426,7 +426,7 @@
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
-	.name =		"IEC958 Preample Capture Default",
+	.name =		"IEC958 Preamble Capture Default",
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ |
 		SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4113_spdif_pinfo,
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index 816e7d2..5bf4fca 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -401,7 +401,7 @@
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
-	.name =		"IEC958 Preample Capture Default",
+	.name =		"IEC958 Preamble Capture Default",
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4114_spdif_pinfo,
 	.get =		snd_ak4114_spdif_pget,
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index b4b2a51..40e33c9 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -380,7 +380,7 @@
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
-	.name =		"IEC958 Preample Capture Default",
+	.name =		"IEC958 Preamble Capture Default",
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4117_spdif_pinfo,
 	.get =		snd_ak4117_spdif_pget,
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 3d1afb6..4a7ff4e 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -1286,7 +1286,6 @@
 
 	error = snd_card_miro_aci_detect(card, miro);
 	if (error < 0) {
-		snd_card_free(card);
 		snd_printk(KERN_ERR "unable to detect aci chip\n");
 		return -ENODEV;
 	}
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 00f157a..5af3cb6 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -394,6 +394,8 @@
 	struct snd_als300_substream_data *data = kzalloc(sizeof(*data),
 								GFP_KERNEL);
 
+	if (!data)
+		return -ENOMEM;
 	snd_als300_dbgcallenter();
 	chip->playback_substream = substream;
 	runtime->hw = snd_als300_playback_hw;
@@ -425,6 +427,8 @@
 	struct snd_als300_substream_data *data = kzalloc(sizeof(*data),
 								GFP_KERNEL);
 
+	if (!data)
+		return -ENOMEM;
 	snd_als300_dbgcallenter();
 	chip->capture_substream = substream;
 	runtime->hw = snd_als300_capture_hw;
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 5d0e568..7266020 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -2581,9 +2581,14 @@
 	struct es1968 *chip = tea->private_data;
 	unsigned long io = chip->io_port + GPIO_DATA;
 	u16 val = inw(io);
+	u8 ret;
 
-	return  (val & STR_DATA) ? TEA575X_DATA : 0 |
-		(val & STR_MOST) ? TEA575X_MOST : 0;
+	ret = 0;
+	if (val & STR_DATA)
+		ret |= TEA575X_DATA;
+	if (val & STR_MOST)
+		ret |= TEA575X_MOST;
+	return ret;
 }
 
 static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output)
@@ -2655,6 +2660,8 @@
 	{ TYPE_MAESTRO2E, 0x1179 },
 	{ TYPE_MAESTRO2E, 0x14c0 },	/* HP omnibook 4150 */
 	{ TYPE_MAESTRO2E, 0x1558 },
+	{ TYPE_MAESTRO2E, 0x125d },	/* a PCI card, e.g. Terratec DMX */
+	{ TYPE_MAESTRO2, 0x125d },	/* a PCI card, e.g. SF64-PCE2 */
 };
 
 static struct ess_device_list mpu_blacklist[] __devinitdata = {
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index cc2e91d..c5806f8 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -767,9 +767,14 @@
 	struct fm801 *chip = tea->private_data;
 	unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
 	struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip);
+	u8 ret;
 
-	return  (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 |
-		(reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0;
+	ret = 0;
+	if (reg & FM801_GPIO_GP(gpio.data))
+		ret |= TEA575X_DATA;
+	if (reg & FM801_GPIO_GP(gpio.most))
+		ret |= TEA575X_MOST;
+	return ret;
 }
 
 static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 72b085a..cd2dbaf 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -3563,6 +3563,8 @@
 	/* Teradici */
 	{ PCI_DEVICE(0x6549, 0x1200),
 	  .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
+	{ PCI_DEVICE(0x6549, 0x2200),
+	  .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
 	/* Creative X-Fi (CA0110-IBG) */
 	/* CTHDA chips */
 	{ PCI_DEVICE(0x1102, 0x0010),
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index cdd43ea..1eeba73 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -545,6 +545,7 @@
 	if (spec->multiout.dig_out_nid) {
 		info++;
 		codec->num_pcms++;
+		codec->spdif_status_reset = 1;
 		info->name = "AD198x Digital";
 		info->pcm_type = HDA_PCM_TYPE_SPDIF;
 		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 61a7113..d5f3a26 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -101,8 +101,8 @@
 #define CS420X_VENDOR_NID	0x11
 #define CS_DIG_OUT1_PIN_NID	0x10
 #define CS_DIG_OUT2_PIN_NID	0x15
-#define CS_DMIC1_PIN_NID	0x12
-#define CS_DMIC2_PIN_NID	0x0e
+#define CS_DMIC1_PIN_NID	0x0e
+#define CS_DMIC2_PIN_NID	0x12
 
 /* coef indices */
 #define IDX_SPDIF_STAT		0x0000
@@ -1079,14 +1079,18 @@
 			cs_automic(codec, NULL);
 
 		coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
+		cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
+
+		coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG);
 		if (is_active_pin(codec, CS_DMIC2_PIN_NID))
-			coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */
+			coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */
 		if (is_active_pin(codec, CS_DMIC1_PIN_NID))
-			coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off
+			coef |= 1 << 3; /* DMIC1 2 chan on, GPIO0 off
 					 * No effect if SPDIF_OUT2 is
 					 * selected in IDX_SPDIF_CTL.
 					*/
-		cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
+
+		cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef);
 	} else {
 		if (spec->mic_detect)
 			cs_automic(codec, NULL);
@@ -1107,7 +1111,7 @@
 	  | 0x0400 /* Disable Coefficient Auto increment */
 	  )},
 	/* Beep */
-	{0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG},
+	{0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG},
 	{0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */
 
 	{} /* terminator */
@@ -1728,8 +1732,7 @@
 
 }
 
-static struct snd_kcontrol_new cs421x_capture_source = {
-
+static const struct snd_kcontrol_new cs421x_capture_source = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Capture Source",
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -1946,7 +1949,7 @@
 }
 #endif
 
-static struct hda_codec_ops cs421x_patch_ops = {
+static const struct hda_codec_ops cs421x_patch_ops = {
 	.build_controls = cs421x_build_controls,
 	.build_pcms = cs_build_pcms,
 	.init = cs421x_init,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 48d9d60..68fd492 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5407,6 +5407,7 @@
 	SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
 	SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
 	SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
+	SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
 	SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
 	SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
 	SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
@@ -5677,6 +5678,7 @@
 
 enum {
 	ALC268_FIXUP_INV_DMIC,
+	ALC268_FIXUP_HP_EAPD,
 };
 
 static const struct alc_fixup alc268_fixups[] = {
@@ -5684,10 +5686,26 @@
 		.type = ALC_FIXUP_FUNC,
 		.v.func = alc_fixup_inv_dmic_0x12,
 	},
+	[ALC268_FIXUP_HP_EAPD] = {
+		.type = ALC_FIXUP_VERBS,
+		.v.verbs = (const struct hda_verb[]) {
+			{0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
+			{}
+		}
+	},
 };
 
 static const struct alc_model_fixup alc268_fixup_models[] = {
 	{.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
+	{.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
+	{}
+};
+
+static const struct snd_pci_quirk alc268_fixup_tbl[] = {
+	/* below is codec SSID since multiple Toshiba laptops have the
+	 * same PCI SSID 1179:ff00
+	 */
+	SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
 	{}
 };
 
@@ -5722,7 +5740,7 @@
 
 	spec = codec->spec;
 
-	alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups);
+	alc_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
 	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
 	/* automatic parse from the BIOS config */
@@ -5823,7 +5841,7 @@
 	return alc_parse_auto_config(codec, alc269_ignore, ssids);
 }
 
-static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
+static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
 {
 	int val = alc_read_coef_idx(codec, 0x04);
 	if (power_up)
@@ -5840,10 +5858,10 @@
 	if (spec->codec_variant != ALC269_TYPE_ALC269VB)
 		return;
 
-	if ((alc_get_coef0(codec) & 0x00ff) == 0x017)
-		alc269_toggle_power_output(codec, 0);
-	if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
-		alc269_toggle_power_output(codec, 0);
+	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
+		alc269vb_toggle_power_output(codec, 0);
+	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
+			(alc_get_coef0(codec) & 0x00ff) == 0x018) {
 		msleep(150);
 	}
 }
@@ -5853,24 +5871,22 @@
 {
 	struct alc_spec *spec = codec->spec;
 
-	if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
+	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
+		alc269vb_toggle_power_output(codec, 0);
+	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
 			(alc_get_coef0(codec) & 0x00ff) == 0x018) {
-		alc269_toggle_power_output(codec, 0);
 		msleep(150);
 	}
 
 	codec->patch_ops.init(codec);
 
-	if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
+	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
+		alc269vb_toggle_power_output(codec, 1);
+	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
 			(alc_get_coef0(codec) & 0x00ff) == 0x017) {
-		alc269_toggle_power_output(codec, 1);
 		msleep(200);
 	}
 
-	if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
-			(alc_get_coef0(codec) & 0x00ff) == 0x018)
-		alc269_toggle_power_output(codec, 1);
-
 	snd_hda_codec_resume_amp(codec);
 	snd_hda_codec_resume_cache(codec);
 	hda_call_check_power_status(codec, 0x01);
@@ -6188,6 +6204,7 @@
 	SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
 	SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
+	SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
 	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
@@ -7061,6 +7078,7 @@
 	  .patch = patch_alc662 },
 	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
 	{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
+	{ .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
 	{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
 	{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
 	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
@@ -7078,6 +7096,7 @@
 	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
 	{ .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
 	{ .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
+	{ .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 },
 	{} /* terminator */
 };
 
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 770013f..9ba8af0 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1763,6 +1763,8 @@
 			  "HP", STAC_HP_ZEPHYR),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660,
 			  "HP Mini", STAC_92HD83XXX_HP_LED),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E,
+			  "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED),
 	{} /* terminator */
 };
 
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 72a2f60..019e1a0 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1809,11 +1809,11 @@
 {
 	struct via_spec *spec = codec->spec;
 	const struct auto_pin_cfg *cfg = &spec->autocfg;
-	int i, dac_num;
+	int i;
 	hda_nid_t nid;
 
+	spec->multiout.num_dacs = 0;
 	spec->multiout.dac_nids = spec->private_dac_nids;
-	dac_num = 0;
 	for (i = 0; i < cfg->line_outs; i++) {
 		hda_nid_t dac = 0;
 		nid = cfg->line_out_pins[i];
@@ -1824,16 +1824,13 @@
 		if (!i && parse_output_path(codec, nid, dac, 1,
 					    &spec->out_mix_path))
 			dac = spec->out_mix_path.path[0];
-		if (dac) {
-			spec->private_dac_nids[i] = dac;
-			dac_num++;
-		}
+		if (dac)
+			spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
 	}
 	if (!spec->out_path[0].depth && spec->out_mix_path.depth) {
 		spec->out_path[0] = spec->out_mix_path;
 		spec->out_mix_path.depth = 0;
 	}
-	spec->multiout.num_dacs = dac_num;
 	return 0;
 }
 
@@ -3628,6 +3625,7 @@
  */
 enum {
 	VIA_FIXUP_INTMIC_BOOST,
+	VIA_FIXUP_ASUS_G75,
 };
 
 static void via_fixup_intmic_boost(struct hda_codec *codec,
@@ -3642,13 +3640,35 @@
 		.type = HDA_FIXUP_FUNC,
 		.v.func = via_fixup_intmic_boost,
 	},
+	[VIA_FIXUP_ASUS_G75] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			/* set 0x24 and 0x33 as speakers */
+			{ 0x24, 0x991301f0 },
+			{ 0x33, 0x991301f1 }, /* subwoofer */
+			{ }
+		}
+	},
 };
 
 static const struct snd_pci_quirk vt2002p_fixups[] = {
+	SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75),
 	SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST),
 	{}
 };
 
+/* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e
+ * Replace this with mixer NID 0x1c
+ */
+static void fix_vt1802_connections(struct hda_codec *codec)
+{
+	static hda_nid_t conn_24[] = { 0x14, 0x1c };
+	static hda_nid_t conn_33[] = { 0x1c };
+
+	snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24);
+	snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33);
+}
+
 /* patch for vt2002P */
 static int patch_vt2002P(struct hda_codec *codec)
 {
@@ -3663,6 +3683,8 @@
 	spec->aa_mix_nid = 0x21;
 	override_mic_boost(codec, 0x2b, 0, 3, 40);
 	override_mic_boost(codec, 0x29, 0, 3, 40);
+	if (spec->codec_type == VT1802)
+		fix_vt1802_connections(codec);
 	add_secret_dac_path(codec);
 
 	snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups);
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 3050a52..245d874 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2859,7 +2859,12 @@
 		ice->set_spdif_clock(ice, 0);
 	} else {
 		/* internal on-card clock */
-		snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1);
+		int rate;
+		if (ice->cur_rate)
+			rate = ice->cur_rate;
+		else
+			rate = ice->pro_rate_default;
+		snd_vt1724_set_pro_rate(ice, rate, 1);
 	}
 
 	update_spdif_bits(ice, ice->pm_saved_spdif_ctrl);
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index b12308b..748e36c 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -971,6 +971,7 @@
 static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm);
 static int hdspm_autosync_ref(struct hdspm *hdspm);
 static int snd_hdspm_set_defaults(struct hdspm *hdspm);
+static int hdspm_system_clock_mode(struct hdspm *hdspm);
 static void hdspm_set_sgbuf(struct hdspm *hdspm,
 			    struct snd_pcm_substream *substream,
 			     unsigned int reg, int channels);
@@ -1989,10 +1990,14 @@
 	rate = hdspm_calc_dds_value(hdspm, period);
 
 	if (rate > 207000) {
-		/* Unreasonable high sample rate as seen on PCI MADI cards.
-		 * Use the cached value instead.
-		 */
-		rate = hdspm->system_sample_rate;
+		/* Unreasonable high sample rate as seen on PCI MADI cards. */
+		if (0 == hdspm_system_clock_mode(hdspm)) {
+			/* master mode, return internal sample rate */
+			rate = hdspm->system_sample_rate;
+		} else {
+			/* slave mode, return external sample rate */
+			rate = hdspm_external_sample_rate(hdspm);
+		}
 	}
 
 	return rate;
@@ -2000,12 +2005,14 @@
 
 
 #define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .access = SNDRV_CTL_ELEM_ACCESS_READ, \
-  .info = snd_hdspm_info_system_sample_rate, \
-  .get = snd_hdspm_get_system_sample_rate \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
+		SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
+	.info = snd_hdspm_info_system_sample_rate, \
+	.put = snd_hdspm_put_system_sample_rate, \
+	.get = snd_hdspm_get_system_sample_rate \
 }
 
 static int snd_hdspm_info_system_sample_rate(struct snd_kcontrol *kcontrol,
@@ -2030,6 +2037,16 @@
 	return 0;
 }
 
+static int snd_hdspm_put_system_sample_rate(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *
+					    ucontrol)
+{
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
+
+	hdspm_set_dds_value(hdspm, ucontrol->value.enumerated.item[0]);
+	return 0;
+}
+
 
 /**
  * Returns the WordClock sample rate class for the given card.
@@ -2163,6 +2180,7 @@
 				hdspm_get_s1_sample_rate(hdspm,
 						kcontrol->private_value-1);
 		}
+		break;
 
 	case AIO:
 		switch (kcontrol->private_value) {
@@ -2183,6 +2201,7 @@
 				hdspm_get_s1_sample_rate(hdspm,
 						ucontrol->id.index-1);
 		}
+		break;
 
 	case AES32:
 
@@ -2204,8 +2223,23 @@
 				hdspm_get_s1_sample_rate(hdspm,
 						kcontrol->private_value-1);
 			break;
-
 		}
+		break;
+
+	case MADI:
+	case MADIface:
+		{
+			int rate = hdspm_external_sample_rate(hdspm);
+			int i, selected_rate = 0;
+			for (i = 1; i < 10; i++)
+				if (HDSPM_bit2freq(i) == rate) {
+					selected_rate = i;
+					break;
+				}
+			ucontrol->value.enumerated.item[0] = selected_rate;
+		}
+		break;
+
 	default:
 		break;
 	}
@@ -2430,7 +2464,7 @@
 
 
 #define HDSPM_PREF_SYNC_REF(xname, xindex) \
-{.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
 	.name = xname, \
 	.index = xindex, \
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
@@ -2766,12 +2800,12 @@
 
 
 #define HDSPM_AUTOSYNC_REF(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .access = SNDRV_CTL_ELEM_ACCESS_READ, \
-  .info = snd_hdspm_info_autosync_ref, \
-  .get = snd_hdspm_get_autosync_ref, \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.access = SNDRV_CTL_ELEM_ACCESS_READ, \
+	.info = snd_hdspm_info_autosync_ref, \
+	.get = snd_hdspm_get_autosync_ref, \
 }
 
 static int hdspm_autosync_ref(struct hdspm *hdspm)
@@ -2855,12 +2889,12 @@
 
 
 #define HDSPM_LINE_OUT(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdspm_info_line_out, \
-  .get = snd_hdspm_get_line_out, \
-  .put = snd_hdspm_put_line_out \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.info = snd_hdspm_info_line_out, \
+	.get = snd_hdspm_get_line_out, \
+	.put = snd_hdspm_put_line_out \
 }
 
 static int hdspm_line_out(struct hdspm * hdspm)
@@ -2912,12 +2946,12 @@
 
 
 #define HDSPM_TX_64(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdspm_info_tx_64, \
-  .get = snd_hdspm_get_tx_64, \
-  .put = snd_hdspm_put_tx_64 \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.info = snd_hdspm_info_tx_64, \
+	.get = snd_hdspm_get_tx_64, \
+	.put = snd_hdspm_put_tx_64 \
 }
 
 static int hdspm_tx_64(struct hdspm * hdspm)
@@ -2968,12 +3002,12 @@
 
 
 #define HDSPM_C_TMS(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdspm_info_c_tms, \
-  .get = snd_hdspm_get_c_tms, \
-  .put = snd_hdspm_put_c_tms \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.info = snd_hdspm_info_c_tms, \
+	.get = snd_hdspm_get_c_tms, \
+	.put = snd_hdspm_put_c_tms \
 }
 
 static int hdspm_c_tms(struct hdspm * hdspm)
@@ -3024,12 +3058,12 @@
 
 
 #define HDSPM_SAFE_MODE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdspm_info_safe_mode, \
-  .get = snd_hdspm_get_safe_mode, \
-  .put = snd_hdspm_put_safe_mode \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.info = snd_hdspm_info_safe_mode, \
+	.get = snd_hdspm_get_safe_mode, \
+	.put = snd_hdspm_put_safe_mode \
 }
 
 static int hdspm_safe_mode(struct hdspm * hdspm)
@@ -3080,12 +3114,12 @@
 
 
 #define HDSPM_EMPHASIS(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdspm_info_emphasis, \
-  .get = snd_hdspm_get_emphasis, \
-  .put = snd_hdspm_put_emphasis \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.info = snd_hdspm_info_emphasis, \
+	.get = snd_hdspm_get_emphasis, \
+	.put = snd_hdspm_put_emphasis \
 }
 
 static int hdspm_emphasis(struct hdspm * hdspm)
@@ -3136,12 +3170,12 @@
 
 
 #define HDSPM_DOLBY(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdspm_info_dolby, \
-  .get = snd_hdspm_get_dolby, \
-  .put = snd_hdspm_put_dolby \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.info = snd_hdspm_info_dolby, \
+	.get = snd_hdspm_get_dolby, \
+	.put = snd_hdspm_put_dolby \
 }
 
 static int hdspm_dolby(struct hdspm * hdspm)
@@ -3192,12 +3226,12 @@
 
 
 #define HDSPM_PROFESSIONAL(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdspm_info_professional, \
-  .get = snd_hdspm_get_professional, \
-  .put = snd_hdspm_put_professional \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.info = snd_hdspm_info_professional, \
+	.get = snd_hdspm_get_professional, \
+	.put = snd_hdspm_put_professional \
 }
 
 static int hdspm_professional(struct hdspm * hdspm)
@@ -3247,12 +3281,12 @@
 }
 
 #define HDSPM_INPUT_SELECT(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdspm_info_input_select, \
-  .get = snd_hdspm_get_input_select, \
-  .put = snd_hdspm_put_input_select \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.info = snd_hdspm_info_input_select, \
+	.get = snd_hdspm_get_input_select, \
+	.put = snd_hdspm_put_input_select \
 }
 
 static int hdspm_input_select(struct hdspm * hdspm)
@@ -3319,12 +3353,12 @@
 
 
 #define HDSPM_DS_WIRE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdspm_info_ds_wire, \
-  .get = snd_hdspm_get_ds_wire, \
-  .put = snd_hdspm_put_ds_wire \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.info = snd_hdspm_info_ds_wire, \
+	.get = snd_hdspm_get_ds_wire, \
+	.put = snd_hdspm_put_ds_wire \
 }
 
 static int hdspm_ds_wire(struct hdspm * hdspm)
@@ -3391,12 +3425,12 @@
 
 
 #define HDSPM_QS_WIRE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .index = xindex, \
-  .info = snd_hdspm_info_qs_wire, \
-  .get = snd_hdspm_get_qs_wire, \
-  .put = snd_hdspm_put_qs_wire \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.name = xname, \
+	.index = xindex, \
+	.info = snd_hdspm_info_qs_wire, \
+	.get = snd_hdspm_get_qs_wire, \
+	.put = snd_hdspm_put_qs_wire \
 }
 
 static int hdspm_qs_wire(struct hdspm * hdspm)
@@ -3563,15 +3597,15 @@
 }
 
 #define HDSPM_MIXER(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
-  .name = xname, \
-  .index = xindex, \
-  .device = 0, \
-  .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
-		 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
-  .info = snd_hdspm_info_mixer, \
-  .get = snd_hdspm_get_mixer, \
-  .put = snd_hdspm_put_mixer \
+{	.iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+	.name = xname, \
+	.index = xindex, \
+	.device = 0, \
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
+		SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
+	.info = snd_hdspm_info_mixer, \
+	.get = snd_hdspm_get_mixer, \
+	.put = snd_hdspm_put_mixer \
 }
 
 static int snd_hdspm_info_mixer(struct snd_kcontrol *kcontrol,
@@ -3670,12 +3704,12 @@
 */
 
 #define HDSPM_PLAYBACK_MIXER \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | \
-		 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
-  .info = snd_hdspm_info_playback_mixer, \
-  .get = snd_hdspm_get_playback_mixer, \
-  .put = snd_hdspm_put_playback_mixer \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | \
+		SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
+	.info = snd_hdspm_info_playback_mixer, \
+	.get = snd_hdspm_get_playback_mixer, \
+	.put = snd_hdspm_put_playback_mixer \
 }
 
 static int snd_hdspm_info_playback_mixer(struct snd_kcontrol *kcontrol,
@@ -3851,12 +3885,17 @@
 		break;
 
 	case MADI:
-	case AES32:
-		status = hdspm_read(hdspm, HDSPM_statusRegister2);
+		status = hdspm_read(hdspm, HDSPM_statusRegister);
 		lock = (status & HDSPM_syncInLock) ? 1 : 0;
 		sync = (status & HDSPM_syncInSync) ? 1 : 0;
 		break;
 
+	case AES32:
+		status = hdspm_read(hdspm, HDSPM_statusRegister2);
+		lock = (status & 0x100000) ? 1 : 0;
+		sync = (status & 0x200000) ? 1 : 0;
+		break;
+
 	case MADIface:
 		break;
 	}
@@ -3940,8 +3979,10 @@
 		case 8: /* SYNC IN */
 			val = hdspm_sync_in_sync_check(hdspm); break;
 		default:
-			val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1);
+			val = hdspm_s1_sync_check(hdspm,
+					kcontrol->private_value-1);
 		}
+		break;
 
 	case AIO:
 		switch (kcontrol->private_value) {
@@ -3954,6 +3995,7 @@
 		default:
 			val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1);
 		}
+		break;
 
 	case MADI:
 		switch (kcontrol->private_value) {
@@ -3966,6 +4008,7 @@
 		case 3: /* SYNC_IN */
 			val = hdspm_sync_in_sync_check(hdspm); break;
 		}
+		break;
 
 	case MADIface:
 		val = hdspm_madi_sync_check(hdspm); /* MADI */
@@ -3983,6 +4026,7 @@
 			 val = hdspm_aes_sync_check(hdspm,
 					 kcontrol->private_value-1);
 		}
+		break;
 
 	}
 
@@ -4427,9 +4471,10 @@
 	HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
 	HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
 	HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
+	HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
 	HDSPM_SYNC_CHECK("WC SyncCheck", 0),
 	HDSPM_SYNC_CHECK("MADI SyncCheck", 1),
-	HDSPM_SYNC_CHECK("TCO SyncCHeck", 2),
+	HDSPM_SYNC_CHECK("TCO SyncCheck", 2),
 	HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3),
 	HDSPM_LINE_OUT("Line Out", 0),
 	HDSPM_TX_64("TX 64 channels mode", 0),
@@ -4855,7 +4900,7 @@
 		insel = "Coaxial";
 		break;
 	default:
-		insel = "Unkown";
+		insel = "Unknown";
 	}
 
 	snd_iprintf(buffer,
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 6159929..97a8105 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -763,7 +763,7 @@
 	if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) {
 		cs42l52->sysclk = freq;
 	} else {
-		dev_err(codec->dev, "Invalid freq paramter\n");
+		dev_err(codec->dev, "Invalid freq parameter\n");
 		return -EINVAL;
 	}
 	return 0;
@@ -773,7 +773,6 @@
 {
 	struct snd_soc_codec *codec = codec_dai->codec;
 	struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
-	int ret = 0;
 	u8 iface = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -822,7 +821,7 @@
 	case SND_SOC_DAIFMT_NB_IF:
 		break;
 	default:
-		ret = -EINVAL;
+		return -EINVAL;
 	}
 	cs42l52->config.format = iface;
 	snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format);
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 1722b58..7394e73 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -42,6 +42,556 @@
 static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
 static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
 
+static const struct reg_default wm5102_sysclk_reva_patch[] = {
+	{ 0x3000, 0x2225 },
+	{ 0x3001, 0x3a03 },
+	{ 0x3002, 0x0225 },
+	{ 0x3003, 0x0801 },
+	{ 0x3004, 0x6249 },
+	{ 0x3005, 0x0c04 },
+	{ 0x3006, 0x0225 },
+	{ 0x3007, 0x5901 },
+	{ 0x3008, 0xe249 },
+	{ 0x3009, 0x030d },
+	{ 0x300a, 0x0249 },
+	{ 0x300b, 0x2c01 },
+	{ 0x300c, 0xe249 },
+	{ 0x300d, 0x4342 },
+	{ 0x300e, 0xe249 },
+	{ 0x300f, 0x73c0 },
+	{ 0x3010, 0x4249 },
+	{ 0x3011, 0x0c00 },
+	{ 0x3012, 0x0225 },
+	{ 0x3013, 0x1f01 },
+	{ 0x3014, 0x0225 },
+	{ 0x3015, 0x1e01 },
+	{ 0x3016, 0x0225 },
+	{ 0x3017, 0xfa00 },
+	{ 0x3018, 0x0000 },
+	{ 0x3019, 0xf000 },
+	{ 0x301a, 0x0000 },
+	{ 0x301b, 0xf000 },
+	{ 0x301c, 0x0000 },
+	{ 0x301d, 0xf000 },
+	{ 0x301e, 0x0000 },
+	{ 0x301f, 0xf000 },
+	{ 0x3020, 0x0000 },
+	{ 0x3021, 0xf000 },
+	{ 0x3022, 0x0000 },
+	{ 0x3023, 0xf000 },
+	{ 0x3024, 0x0000 },
+	{ 0x3025, 0xf000 },
+	{ 0x3026, 0x0000 },
+	{ 0x3027, 0xf000 },
+	{ 0x3028, 0x0000 },
+	{ 0x3029, 0xf000 },
+	{ 0x302a, 0x0000 },
+	{ 0x302b, 0xf000 },
+	{ 0x302c, 0x0000 },
+	{ 0x302d, 0xf000 },
+	{ 0x302e, 0x0000 },
+	{ 0x302f, 0xf000 },
+	{ 0x3030, 0x0225 },
+	{ 0x3031, 0x1a01 },
+	{ 0x3032, 0x0225 },
+	{ 0x3033, 0x1e00 },
+	{ 0x3034, 0x0225 },
+	{ 0x3035, 0x1f00 },
+	{ 0x3036, 0x6225 },
+	{ 0x3037, 0xf800 },
+	{ 0x3038, 0x0000 },
+	{ 0x3039, 0xf000 },
+	{ 0x303a, 0x0000 },
+	{ 0x303b, 0xf000 },
+	{ 0x303c, 0x0000 },
+	{ 0x303d, 0xf000 },
+	{ 0x303e, 0x0000 },
+	{ 0x303f, 0xf000 },
+	{ 0x3040, 0x2226 },
+	{ 0x3041, 0x3a03 },
+	{ 0x3042, 0x0226 },
+	{ 0x3043, 0x0801 },
+	{ 0x3044, 0x6249 },
+	{ 0x3045, 0x0c06 },
+	{ 0x3046, 0x0226 },
+	{ 0x3047, 0x5901 },
+	{ 0x3048, 0xe249 },
+	{ 0x3049, 0x030d },
+	{ 0x304a, 0x0249 },
+	{ 0x304b, 0x2c01 },
+	{ 0x304c, 0xe249 },
+	{ 0x304d, 0x4342 },
+	{ 0x304e, 0xe249 },
+	{ 0x304f, 0x73c0 },
+	{ 0x3050, 0x4249 },
+	{ 0x3051, 0x0c00 },
+	{ 0x3052, 0x0226 },
+	{ 0x3053, 0x1f01 },
+	{ 0x3054, 0x0226 },
+	{ 0x3055, 0x1e01 },
+	{ 0x3056, 0x0226 },
+	{ 0x3057, 0xfa00 },
+	{ 0x3058, 0x0000 },
+	{ 0x3059, 0xf000 },
+	{ 0x305a, 0x0000 },
+	{ 0x305b, 0xf000 },
+	{ 0x305c, 0x0000 },
+	{ 0x305d, 0xf000 },
+	{ 0x305e, 0x0000 },
+	{ 0x305f, 0xf000 },
+	{ 0x3060, 0x0000 },
+	{ 0x3061, 0xf000 },
+	{ 0x3062, 0x0000 },
+	{ 0x3063, 0xf000 },
+	{ 0x3064, 0x0000 },
+	{ 0x3065, 0xf000 },
+	{ 0x3066, 0x0000 },
+	{ 0x3067, 0xf000 },
+	{ 0x3068, 0x0000 },
+	{ 0x3069, 0xf000 },
+	{ 0x306a, 0x0000 },
+	{ 0x306b, 0xf000 },
+	{ 0x306c, 0x0000 },
+	{ 0x306d, 0xf000 },
+	{ 0x306e, 0x0000 },
+	{ 0x306f, 0xf000 },
+	{ 0x3070, 0x0226 },
+	{ 0x3071, 0x1a01 },
+	{ 0x3072, 0x0226 },
+	{ 0x3073, 0x1e00 },
+	{ 0x3074, 0x0226 },
+	{ 0x3075, 0x1f00 },
+	{ 0x3076, 0x6226 },
+	{ 0x3077, 0xf800 },
+	{ 0x3078, 0x0000 },
+	{ 0x3079, 0xf000 },
+	{ 0x307a, 0x0000 },
+	{ 0x307b, 0xf000 },
+	{ 0x307c, 0x0000 },
+	{ 0x307d, 0xf000 },
+	{ 0x307e, 0x0000 },
+	{ 0x307f, 0xf000 },
+	{ 0x3080, 0x2227 },
+	{ 0x3081, 0x3a03 },
+	{ 0x3082, 0x0227 },
+	{ 0x3083, 0x0801 },
+	{ 0x3084, 0x6255 },
+	{ 0x3085, 0x0c04 },
+	{ 0x3086, 0x0227 },
+	{ 0x3087, 0x5901 },
+	{ 0x3088, 0xe255 },
+	{ 0x3089, 0x030d },
+	{ 0x308a, 0x0255 },
+	{ 0x308b, 0x2c01 },
+	{ 0x308c, 0xe255 },
+	{ 0x308d, 0x4342 },
+	{ 0x308e, 0xe255 },
+	{ 0x308f, 0x73c0 },
+	{ 0x3090, 0x4255 },
+	{ 0x3091, 0x0c00 },
+	{ 0x3092, 0x0227 },
+	{ 0x3093, 0x1f01 },
+	{ 0x3094, 0x0227 },
+	{ 0x3095, 0x1e01 },
+	{ 0x3096, 0x0227 },
+	{ 0x3097, 0xfa00 },
+	{ 0x3098, 0x0000 },
+	{ 0x3099, 0xf000 },
+	{ 0x309a, 0x0000 },
+	{ 0x309b, 0xf000 },
+	{ 0x309c, 0x0000 },
+	{ 0x309d, 0xf000 },
+	{ 0x309e, 0x0000 },
+	{ 0x309f, 0xf000 },
+	{ 0x30a0, 0x0000 },
+	{ 0x30a1, 0xf000 },
+	{ 0x30a2, 0x0000 },
+	{ 0x30a3, 0xf000 },
+	{ 0x30a4, 0x0000 },
+	{ 0x30a5, 0xf000 },
+	{ 0x30a6, 0x0000 },
+	{ 0x30a7, 0xf000 },
+	{ 0x30a8, 0x0000 },
+	{ 0x30a9, 0xf000 },
+	{ 0x30aa, 0x0000 },
+	{ 0x30ab, 0xf000 },
+	{ 0x30ac, 0x0000 },
+	{ 0x30ad, 0xf000 },
+	{ 0x30ae, 0x0000 },
+	{ 0x30af, 0xf000 },
+	{ 0x30b0, 0x0227 },
+	{ 0x30b1, 0x1a01 },
+	{ 0x30b2, 0x0227 },
+	{ 0x30b3, 0x1e00 },
+	{ 0x30b4, 0x0227 },
+	{ 0x30b5, 0x1f00 },
+	{ 0x30b6, 0x6227 },
+	{ 0x30b7, 0xf800 },
+	{ 0x30b8, 0x0000 },
+	{ 0x30b9, 0xf000 },
+	{ 0x30ba, 0x0000 },
+	{ 0x30bb, 0xf000 },
+	{ 0x30bc, 0x0000 },
+	{ 0x30bd, 0xf000 },
+	{ 0x30be, 0x0000 },
+	{ 0x30bf, 0xf000 },
+	{ 0x30c0, 0x2228 },
+	{ 0x30c1, 0x3a03 },
+	{ 0x30c2, 0x0228 },
+	{ 0x30c3, 0x0801 },
+	{ 0x30c4, 0x6255 },
+	{ 0x30c5, 0x0c06 },
+	{ 0x30c6, 0x0228 },
+	{ 0x30c7, 0x5901 },
+	{ 0x30c8, 0xe255 },
+	{ 0x30c9, 0x030d },
+	{ 0x30ca, 0x0255 },
+	{ 0x30cb, 0x2c01 },
+	{ 0x30cc, 0xe255 },
+	{ 0x30cd, 0x4342 },
+	{ 0x30ce, 0xe255 },
+	{ 0x30cf, 0x73c0 },
+	{ 0x30d0, 0x4255 },
+	{ 0x30d1, 0x0c00 },
+	{ 0x30d2, 0x0228 },
+	{ 0x30d3, 0x1f01 },
+	{ 0x30d4, 0x0228 },
+	{ 0x30d5, 0x1e01 },
+	{ 0x30d6, 0x0228 },
+	{ 0x30d7, 0xfa00 },
+	{ 0x30d8, 0x0000 },
+	{ 0x30d9, 0xf000 },
+	{ 0x30da, 0x0000 },
+	{ 0x30db, 0xf000 },
+	{ 0x30dc, 0x0000 },
+	{ 0x30dd, 0xf000 },
+	{ 0x30de, 0x0000 },
+	{ 0x30df, 0xf000 },
+	{ 0x30e0, 0x0000 },
+	{ 0x30e1, 0xf000 },
+	{ 0x30e2, 0x0000 },
+	{ 0x30e3, 0xf000 },
+	{ 0x30e4, 0x0000 },
+	{ 0x30e5, 0xf000 },
+	{ 0x30e6, 0x0000 },
+	{ 0x30e7, 0xf000 },
+	{ 0x30e8, 0x0000 },
+	{ 0x30e9, 0xf000 },
+	{ 0x30ea, 0x0000 },
+	{ 0x30eb, 0xf000 },
+	{ 0x30ec, 0x0000 },
+	{ 0x30ed, 0xf000 },
+	{ 0x30ee, 0x0000 },
+	{ 0x30ef, 0xf000 },
+	{ 0x30f0, 0x0228 },
+	{ 0x30f1, 0x1a01 },
+	{ 0x30f2, 0x0228 },
+	{ 0x30f3, 0x1e00 },
+	{ 0x30f4, 0x0228 },
+	{ 0x30f5, 0x1f00 },
+	{ 0x30f6, 0x6228 },
+	{ 0x30f7, 0xf800 },
+	{ 0x30f8, 0x0000 },
+	{ 0x30f9, 0xf000 },
+	{ 0x30fa, 0x0000 },
+	{ 0x30fb, 0xf000 },
+	{ 0x30fc, 0x0000 },
+	{ 0x30fd, 0xf000 },
+	{ 0x30fe, 0x0000 },
+	{ 0x30ff, 0xf000 },
+	{ 0x3100, 0x222b },
+	{ 0x3101, 0x3a03 },
+	{ 0x3102, 0x222b },
+	{ 0x3103, 0x5803 },
+	{ 0x3104, 0xe26f },
+	{ 0x3105, 0x030d },
+	{ 0x3106, 0x626f },
+	{ 0x3107, 0x2c01 },
+	{ 0x3108, 0xe26f },
+	{ 0x3109, 0x4342 },
+	{ 0x310a, 0xe26f },
+	{ 0x310b, 0x73c0 },
+	{ 0x310c, 0x026f },
+	{ 0x310d, 0x0c00 },
+	{ 0x310e, 0x022b },
+	{ 0x310f, 0x1f01 },
+	{ 0x3110, 0x022b },
+	{ 0x3111, 0x1e01 },
+	{ 0x3112, 0x022b },
+	{ 0x3113, 0xfa00 },
+	{ 0x3114, 0x0000 },
+	{ 0x3115, 0xf000 },
+	{ 0x3116, 0x0000 },
+	{ 0x3117, 0xf000 },
+	{ 0x3118, 0x0000 },
+	{ 0x3119, 0xf000 },
+	{ 0x311a, 0x0000 },
+	{ 0x311b, 0xf000 },
+	{ 0x311c, 0x0000 },
+	{ 0x311d, 0xf000 },
+	{ 0x311e, 0x0000 },
+	{ 0x311f, 0xf000 },
+	{ 0x3120, 0x022b },
+	{ 0x3121, 0x0a01 },
+	{ 0x3122, 0x022b },
+	{ 0x3123, 0x1e00 },
+	{ 0x3124, 0x022b },
+	{ 0x3125, 0x1f00 },
+	{ 0x3126, 0x622b },
+	{ 0x3127, 0xf800 },
+	{ 0x3128, 0x0000 },
+	{ 0x3129, 0xf000 },
+	{ 0x312a, 0x0000 },
+	{ 0x312b, 0xf000 },
+	{ 0x312c, 0x0000 },
+	{ 0x312d, 0xf000 },
+	{ 0x312e, 0x0000 },
+	{ 0x312f, 0xf000 },
+	{ 0x3130, 0x0000 },
+	{ 0x3131, 0xf000 },
+	{ 0x3132, 0x0000 },
+	{ 0x3133, 0xf000 },
+	{ 0x3134, 0x0000 },
+	{ 0x3135, 0xf000 },
+	{ 0x3136, 0x0000 },
+	{ 0x3137, 0xf000 },
+	{ 0x3138, 0x0000 },
+	{ 0x3139, 0xf000 },
+	{ 0x313a, 0x0000 },
+	{ 0x313b, 0xf000 },
+	{ 0x313c, 0x0000 },
+	{ 0x313d, 0xf000 },
+	{ 0x313e, 0x0000 },
+	{ 0x313f, 0xf000 },
+	{ 0x3140, 0x0000 },
+	{ 0x3141, 0xf000 },
+	{ 0x3142, 0x0000 },
+	{ 0x3143, 0xf000 },
+	{ 0x3144, 0x0000 },
+	{ 0x3145, 0xf000 },
+	{ 0x3146, 0x0000 },
+	{ 0x3147, 0xf000 },
+	{ 0x3148, 0x0000 },
+	{ 0x3149, 0xf000 },
+	{ 0x314a, 0x0000 },
+	{ 0x314b, 0xf000 },
+	{ 0x314c, 0x0000 },
+	{ 0x314d, 0xf000 },
+	{ 0x314e, 0x0000 },
+	{ 0x314f, 0xf000 },
+	{ 0x3150, 0x0000 },
+	{ 0x3151, 0xf000 },
+	{ 0x3152, 0x0000 },
+	{ 0x3153, 0xf000 },
+	{ 0x3154, 0x0000 },
+	{ 0x3155, 0xf000 },
+	{ 0x3156, 0x0000 },
+	{ 0x3157, 0xf000 },
+	{ 0x3158, 0x0000 },
+	{ 0x3159, 0xf000 },
+	{ 0x315a, 0x0000 },
+	{ 0x315b, 0xf000 },
+	{ 0x315c, 0x0000 },
+	{ 0x315d, 0xf000 },
+	{ 0x315e, 0x0000 },
+	{ 0x315f, 0xf000 },
+	{ 0x3160, 0x0000 },
+	{ 0x3161, 0xf000 },
+	{ 0x3162, 0x0000 },
+	{ 0x3163, 0xf000 },
+	{ 0x3164, 0x0000 },
+	{ 0x3165, 0xf000 },
+	{ 0x3166, 0x0000 },
+	{ 0x3167, 0xf000 },
+	{ 0x3168, 0x0000 },
+	{ 0x3169, 0xf000 },
+	{ 0x316a, 0x0000 },
+	{ 0x316b, 0xf000 },
+	{ 0x316c, 0x0000 },
+	{ 0x316d, 0xf000 },
+	{ 0x316e, 0x0000 },
+	{ 0x316f, 0xf000 },
+	{ 0x3170, 0x0000 },
+	{ 0x3171, 0xf000 },
+	{ 0x3172, 0x0000 },
+	{ 0x3173, 0xf000 },
+	{ 0x3174, 0x0000 },
+	{ 0x3175, 0xf000 },
+	{ 0x3176, 0x0000 },
+	{ 0x3177, 0xf000 },
+	{ 0x3178, 0x0000 },
+	{ 0x3179, 0xf000 },
+	{ 0x317a, 0x0000 },
+	{ 0x317b, 0xf000 },
+	{ 0x317c, 0x0000 },
+	{ 0x317d, 0xf000 },
+	{ 0x317e, 0x0000 },
+	{ 0x317f, 0xf000 },
+	{ 0x3180, 0x2001 },
+	{ 0x3181, 0xf101 },
+	{ 0x3182, 0x0000 },
+	{ 0x3183, 0xf000 },
+	{ 0x3184, 0x0000 },
+	{ 0x3185, 0xf000 },
+	{ 0x3186, 0x0000 },
+	{ 0x3187, 0xf000 },
+	{ 0x3188, 0x0000 },
+	{ 0x3189, 0xf000 },
+	{ 0x318a, 0x0000 },
+	{ 0x318b, 0xf000 },
+	{ 0x318c, 0x0000 },
+	{ 0x318d, 0xf000 },
+	{ 0x318e, 0x0000 },
+	{ 0x318f, 0xf000 },
+	{ 0x3190, 0x0000 },
+	{ 0x3191, 0xf000 },
+	{ 0x3192, 0x0000 },
+	{ 0x3193, 0xf000 },
+	{ 0x3194, 0x0000 },
+	{ 0x3195, 0xf000 },
+	{ 0x3196, 0x0000 },
+	{ 0x3197, 0xf000 },
+	{ 0x3198, 0x0000 },
+	{ 0x3199, 0xf000 },
+	{ 0x319a, 0x0000 },
+	{ 0x319b, 0xf000 },
+	{ 0x319c, 0x0000 },
+	{ 0x319d, 0xf000 },
+	{ 0x319e, 0x0000 },
+	{ 0x319f, 0xf000 },
+	{ 0x31a0, 0x0000 },
+	{ 0x31a1, 0xf000 },
+	{ 0x31a2, 0x0000 },
+	{ 0x31a3, 0xf000 },
+	{ 0x31a4, 0x0000 },
+	{ 0x31a5, 0xf000 },
+	{ 0x31a6, 0x0000 },
+	{ 0x31a7, 0xf000 },
+	{ 0x31a8, 0x0000 },
+	{ 0x31a9, 0xf000 },
+	{ 0x31aa, 0x0000 },
+	{ 0x31ab, 0xf000 },
+	{ 0x31ac, 0x0000 },
+	{ 0x31ad, 0xf000 },
+	{ 0x31ae, 0x0000 },
+	{ 0x31af, 0xf000 },
+	{ 0x31b0, 0x0000 },
+	{ 0x31b1, 0xf000 },
+	{ 0x31b2, 0x0000 },
+	{ 0x31b3, 0xf000 },
+	{ 0x31b4, 0x0000 },
+	{ 0x31b5, 0xf000 },
+	{ 0x31b6, 0x0000 },
+	{ 0x31b7, 0xf000 },
+	{ 0x31b8, 0x0000 },
+	{ 0x31b9, 0xf000 },
+	{ 0x31ba, 0x0000 },
+	{ 0x31bb, 0xf000 },
+	{ 0x31bc, 0x0000 },
+	{ 0x31bd, 0xf000 },
+	{ 0x31be, 0x0000 },
+	{ 0x31bf, 0xf000 },
+	{ 0x31c0, 0x0000 },
+	{ 0x31c1, 0xf000 },
+	{ 0x31c2, 0x0000 },
+	{ 0x31c3, 0xf000 },
+	{ 0x31c4, 0x0000 },
+	{ 0x31c5, 0xf000 },
+	{ 0x31c6, 0x0000 },
+	{ 0x31c7, 0xf000 },
+	{ 0x31c8, 0x0000 },
+	{ 0x31c9, 0xf000 },
+	{ 0x31ca, 0x0000 },
+	{ 0x31cb, 0xf000 },
+	{ 0x31cc, 0x0000 },
+	{ 0x31cd, 0xf000 },
+	{ 0x31ce, 0x0000 },
+	{ 0x31cf, 0xf000 },
+	{ 0x31d0, 0x0000 },
+	{ 0x31d1, 0xf000 },
+	{ 0x31d2, 0x0000 },
+	{ 0x31d3, 0xf000 },
+	{ 0x31d4, 0x0000 },
+	{ 0x31d5, 0xf000 },
+	{ 0x31d6, 0x0000 },
+	{ 0x31d7, 0xf000 },
+	{ 0x31d8, 0x0000 },
+	{ 0x31d9, 0xf000 },
+	{ 0x31da, 0x0000 },
+	{ 0x31db, 0xf000 },
+	{ 0x31dc, 0x0000 },
+	{ 0x31dd, 0xf000 },
+	{ 0x31de, 0x0000 },
+	{ 0x31df, 0xf000 },
+	{ 0x31e0, 0x0000 },
+	{ 0x31e1, 0xf000 },
+	{ 0x31e2, 0x0000 },
+	{ 0x31e3, 0xf000 },
+	{ 0x31e4, 0x0000 },
+	{ 0x31e5, 0xf000 },
+	{ 0x31e6, 0x0000 },
+	{ 0x31e7, 0xf000 },
+	{ 0x31e8, 0x0000 },
+	{ 0x31e9, 0xf000 },
+	{ 0x31ea, 0x0000 },
+	{ 0x31eb, 0xf000 },
+	{ 0x31ec, 0x0000 },
+	{ 0x31ed, 0xf000 },
+	{ 0x31ee, 0x0000 },
+	{ 0x31ef, 0xf000 },
+	{ 0x31f0, 0x0000 },
+	{ 0x31f1, 0xf000 },
+	{ 0x31f2, 0x0000 },
+	{ 0x31f3, 0xf000 },
+	{ 0x31f4, 0x0000 },
+	{ 0x31f5, 0xf000 },
+	{ 0x31f6, 0x0000 },
+	{ 0x31f7, 0xf000 },
+	{ 0x31f8, 0x0000 },
+	{ 0x31f9, 0xf000 },
+	{ 0x31fa, 0x0000 },
+	{ 0x31fb, 0xf000 },
+	{ 0x31fc, 0x0000 },
+	{ 0x31fd, 0xf000 },
+	{ 0x31fe, 0x0000 },
+	{ 0x31ff, 0xf000 },
+	{ 0x024d, 0xff50 },
+	{ 0x0252, 0xff50 },
+	{ 0x0259, 0x0112 },
+	{ 0x025e, 0x0112 },
+};
+
+static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
+			    struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct arizona *arizona = dev_get_drvdata(codec->dev);
+	struct regmap *regmap = codec->control_data;
+	const struct reg_default *patch = NULL;
+	int i, patch_size;
+
+	switch (arizona->rev) {
+	case 0:
+		patch = wm5102_sysclk_reva_patch;
+		patch_size = ARRAY_SIZE(wm5102_sysclk_reva_patch);
+		break;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		if (patch)
+			for (i = 0; i < patch_size; i++)
+				regmap_write(regmap, patch[i].reg,
+					     patch[i].def);
+		break;
+
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static const struct snd_kcontrol_new wm5102_snd_controls[] = {
 SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL,
 	   ARIZONA_IN1_OSR_SHIFT, 1, 0),
@@ -297,7 +847,7 @@
 
 static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = {
 SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
-		    0, NULL, 0),
+		    0, wm5102_sysclk_ev, SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
 		    ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 5421fd9..4c0a8e4 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -782,7 +782,7 @@
 		wm8978->mclk_idx = -1;
 		f_sel = wm8978->f_mclk;
 	} else {
-		if (!wm8978->f_pllout) {
+		if (!wm8978->f_opclk) {
 			/* We only enter here, if OPCLK is not used */
 			int ret = wm8978_configure_pll(codec);
 			if (ret < 0)
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 2b2dadc..b2b2b37 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -1045,6 +1045,7 @@
 		      struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
+	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994 *control = codec->control_data;
 	int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
 	int i;
@@ -1063,6 +1064,10 @@
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
+		/* Don't enable timeslot 2 if not in use */
+		if (wm8994->channels[0] <= 2)
+			mask &= ~(WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
+
 		val = snd_soc_read(codec, WM8994_AIF1_CONTROL_1);
 		if ((val & WM8994_AIF1ADCL_SRC) &&
 		    (val & WM8994_AIF1ADCR_SRC))
@@ -2687,7 +2692,7 @@
 		return -EINVAL;
 	}
 
-	bclk_rate = params_rate(params) * 4;
+	bclk_rate = params_rate(params);
 	switch (params_format(params)) {
 	case SNDRV_PCM_FORMAT_S16_LE:
 		bclk_rate *= 16;
@@ -2708,6 +2713,17 @@
 		return -EINVAL;
 	}
 
+	wm8994->channels[id] = params_channels(params);
+	switch (params_channels(params)) {
+	case 1:
+	case 2:
+		bclk_rate *= 2;
+		break;
+	default:
+		bclk_rate *= 4;
+		break;
+	}
+
 	/* Try to find an appropriate sample rate; look for an exact match. */
 	for (i = 0; i < ARRAY_SIZE(srs); i++)
 		if (srs[i].rate == params_rate(params))
@@ -3706,7 +3722,7 @@
 	} while (count--);
 
 	if (count == 0)
-		dev_warn(codec->dev, "No impedence range reported for jack\n");
+		dev_warn(codec->dev, "No impedance range reported for jack\n");
 
 #ifndef CONFIG_SND_SOC_WM8994_MODULE
 	trace_snd_soc_jack_irq(dev_name(codec->dev));
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index f142ec1..ccbce57 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -77,6 +77,7 @@
 	int sysclk_rate[2];
 	int mclk[2];
 	int aifclk[2];
+	int channels[2];
 	struct wm8994_fll_config fll[2], fll_suspend[2];
 	struct completion fll_locked[2];
 	bool fll_locked_irq;
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 22c6130..9ffc9e6 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -29,7 +29,6 @@
 
 #include <asm/fiq.h>
 
-#include <mach/irqs.h>
 #include <linux/platform_data/asoc-imx-ssi.h>
 
 #include "imx-ssi.h"
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 006f7d4..dd56644 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -48,7 +48,6 @@
 #include <sound/soc.h>
 
 #include <linux/platform_data/asoc-imx-ssi.h>
-#include <mach/hardware.h>
 
 #include "imx-ssi.h"
 
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index aa037b2..c294fbb 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -523,16 +523,24 @@
 
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 			/*
-			 * write a data to saif data register to trigger
-			 * the transfer
+			 * write data to saif data register to trigger
+			 * the transfer.
+			 * For 24-bit format the 32-bit FIFO register stores
+			 * only one channel, so we need to write twice.
+			 * This is also safe for the other non 24-bit formats.
 			 */
 			__raw_writel(0, saif->base + SAIF_DATA);
+			__raw_writel(0, saif->base + SAIF_DATA);
 		} else {
 			/*
-			 * read a data from saif data register to trigger
-			 * the receive
+			 * read data from saif data register to trigger
+			 * the receive.
+			 * For 24-bit format the 32-bit FIFO register stores
+			 * only one channel, so we need to read twice.
+			 * This is also safe for the other non 24-bit formats.
 			 */
 			__raw_readl(saif->base + SAIF_DATA);
+			__raw_readl(saif->base + SAIF_DATA);
 		}
 
 		master_saif->ongoing = 1;
@@ -812,3 +820,4 @@
 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
 MODULE_DESCRIPTION("MXS ASoC SAIF driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mxs-saif");
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index 68f2cd1..5a6aeaf 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -464,9 +464,9 @@
 
 	mutex_init(&dmic->mutex);
 
-	dmic->fclk = clk_get(dmic->dev, "dmic_fck");
+	dmic->fclk = clk_get(dmic->dev, "fck");
 	if (IS_ERR(dmic->fclk)) {
-		dev_err(dmic->dev, "cant get dmic_fck\n");
+		dev_err(dmic->dev, "cant get fck\n");
 		return -ENODEV;
 	}
 
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 677b567..1ff6bb9 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -21,15 +21,14 @@
 
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 
 #include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <mach/board-zoom.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
+#include <linux/platform_data/gpio-omap.h>
 
 /* Register descriptions for twl4030 codec part */
 #include <linux/mfd/twl4030-audio.h>
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index e7b8317..3c7c3a5 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -207,6 +207,8 @@
 	select SND_SOC_WM5102
 	select SND_SOC_WM5110
 	select SND_SOC_WM9081
+	select SND_SOC_WM0010
+	select SND_SOC_WM1250_EV1
 
 config SND_SOC_LOWLAND
 	tristate "Audio support for Wolfson Lowland"
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
index b0d46d6..b56b9a3 100644
--- a/sound/soc/samsung/bells.c
+++ b/sound/soc/samsung/bells.c
@@ -247,7 +247,7 @@
 	{
 		.name = "Sub",
 		.stream_name = "Sub",
-		.cpu_dai_name = "wm5110-aif3",
+		.cpu_dai_name = "wm5102-aif3",
 		.codec_dai_name = "wm9081-hifi",
 		.codec_name = "wm9081.1-006c",
 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d119862..10d21be 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2786,8 +2786,9 @@
 	val = (ucontrol->value.integer.value[0] + min) & mask;
 	val = val << shift;
 
-	if (snd_soc_update_bits_locked(codec, reg, val_mask, val))
-			return err;
+	err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
+	if (err < 0)
+		return err;
 
 	if (snd_soc_volsw_is_stereo(mc)) {
 		val_mask = mask << rshift;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d0a4be3..6e35bca 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3745,7 +3745,7 @@
 {
 	struct snd_soc_codec *codec;
 
-	list_for_each_entry(codec, &card->codec_dev_list, list) {
+	list_for_each_entry(codec, &card->codec_dev_list, card_list) {
 		soc_dapm_shutdown_codec(&codec->dapm);
 		if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
 			snd_soc_dapm_set_bias_level(&codec->dapm,
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index bf56101..64b67a3 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -26,7 +26,6 @@
 #include <linux/regmap.h>
 #include <linux/slab.h>
 #include <mach/clk.h>
-#include <mach/dma.h>
 #include <sound/soc.h>
 #include "tegra30_ahub.h"
 
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
index b40279b..bc8b46a 100644
--- a/sound/soc/tegra/tegra_pcm.h
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -31,8 +31,6 @@
 #ifndef __TEGRA_PCM_H__
 #define __TEGRA_PCM_H__
 
-#include <mach/dma.h>
-
 struct tegra_pcm_dma_params {
 	unsigned long addr;
 	unsigned long wrap;
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index 356611d..54f7e25 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -57,6 +57,20 @@
 	.num_links = ARRAY_SIZE(mop500_dai_links),
 };
 
+static void mop500_of_node_put(void)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (mop500_dai_links[i].cpu_of_node)
+			of_node_put((struct device_node *)
+				mop500_dai_links[i].cpu_of_node);
+		if (mop500_dai_links[i].codec_of_node)
+			of_node_put((struct device_node *)
+				mop500_dai_links[i].codec_of_node);
+	}
+}
+
 static int __devinit mop500_of_probe(struct platform_device *pdev,
 				struct device_node *np)
 {
@@ -69,6 +83,7 @@
 
 	if (!(msp_np[0] && msp_np[1] && codec_np)) {
 		dev_err(&pdev->dev, "Phandle missing or invalid\n");
+		mop500_of_node_put();
 		return -EINVAL;
 	}
 
@@ -83,6 +98,7 @@
 
 	return 0;
 }
+
 static int __devinit mop500_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
@@ -128,6 +144,7 @@
 
 	snd_soc_unregister_card(mop500_card);
 	mop500_ab8500_remove(mop500_card);
+	mop500_of_node_put();
 
 	return 0;
 }
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index b7c996e..a26c6bf 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -18,6 +18,7 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <linux/of.h>
 
 #include <mach/hardware.h>
@@ -697,14 +698,11 @@
 			platform_data = devm_kzalloc(&pdev->dev,
 				sizeof(struct msp_i2s_platform_data), GFP_KERNEL);
 			if (!platform_data)
-				ret = -ENOMEM;
+				return -ENOMEM;
 		}
 	} else
 		if (!platform_data)
-			ret = -EINVAL;
-
-	if (ret)
-		goto err_res;
+			return -EINVAL;
 
 	dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
 		pdev->name, platform_data->id);
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 561bb74..dbf7999 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -339,7 +339,7 @@
 	}
 
 	mutex_init(&chip->mutex);
-	mutex_init(&chip->shutdown_mutex);
+	init_rwsem(&chip->shutdown_rwsem);
 	chip->index = idx;
 	chip->dev = dev;
 	chip->card = card;
@@ -559,9 +559,11 @@
 		return;
 
 	card = chip->card;
-	mutex_lock(&register_mutex);
-	mutex_lock(&chip->shutdown_mutex);
+	down_write(&chip->shutdown_rwsem);
 	chip->shutdown = 1;
+	up_write(&chip->shutdown_rwsem);
+
+	mutex_lock(&register_mutex);
 	chip->num_interfaces--;
 	if (chip->num_interfaces <= 0) {
 		snd_card_disconnect(card);
@@ -582,11 +584,9 @@
 			snd_usb_mixer_disconnect(p);
 		}
 		usb_chip[chip->index] = NULL;
-		mutex_unlock(&chip->shutdown_mutex);
 		mutex_unlock(&register_mutex);
 		snd_card_free_when_closed(card);
 	} else {
-		mutex_unlock(&chip->shutdown_mutex);
 		mutex_unlock(&register_mutex);
 	}
 }
@@ -618,16 +618,20 @@
 {
 	int err = -ENODEV;
 
+	down_read(&chip->shutdown_rwsem);
 	if (!chip->shutdown && !chip->probing)
 		err = usb_autopm_get_interface(chip->pm_intf);
+	up_read(&chip->shutdown_rwsem);
 
 	return err;
 }
 
 void snd_usb_autosuspend(struct snd_usb_audio *chip)
 {
+	down_read(&chip->shutdown_rwsem);
 	if (!chip->shutdown && !chip->probing)
 		usb_autopm_put_interface(chip->pm_intf);
+	up_read(&chip->shutdown_rwsem);
 }
 
 static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
diff --git a/sound/usb/card.h b/sound/usb/card.h
index afa4f9e..814cb35 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -126,6 +126,7 @@
 	struct snd_usb_endpoint *sync_endpoint;
 	unsigned long flags;
 	bool need_setup_ep;		/* (re)configure EP at prepare? */
+	unsigned int speed;		/* USB_SPEED_XXX */
 
 	u64 formats;			/* format bitmasks (all or'ed) */
 	unsigned int num_formats;		/* number of supported audio formats (list) */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 7f78c6d..34de6f2 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -35,6 +35,7 @@
 
 #define EP_FLAG_ACTIVATED	0
 #define EP_FLAG_RUNNING		1
+#define EP_FLAG_STOPPING	2
 
 /*
  * snd_usb_endpoint is a model that abstracts everything related to an
@@ -502,10 +503,20 @@
 	if (alive)
 		snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n",
 					alive, ep->ep_num);
+	clear_bit(EP_FLAG_STOPPING, &ep->flags);
 
 	return 0;
 }
 
+/* sync the pending stop operation;
+ * this function itself doesn't trigger the stop operation
+ */
+void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep)
+{
+	if (ep && test_bit(EP_FLAG_STOPPING, &ep->flags))
+		wait_clear_urbs(ep);
+}
+
 /*
  * unlink active urbs.
  */
@@ -918,6 +929,8 @@
 
 		if (wait)
 			wait_clear_urbs(ep);
+		else
+			set_bit(EP_FLAG_STOPPING, &ep->flags);
 	}
 }
 
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index 6376ccf..3d4c970 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -19,6 +19,7 @@
 int  snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep);
 void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
 			   int force, int can_sleep, int wait);
+void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep);
 int  snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
 int  snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);
 void snd_usb_endpoint_free(struct list_head *head);
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index fe56c9d..298070e 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -287,25 +287,32 @@
 	unsigned char buf[2];
 	int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
 	int timeout = 10;
-	int err;
+	int idx = 0, err;
 
 	err = snd_usb_autoresume(cval->mixer->chip);
 	if (err < 0)
 		return -EIO;
+	down_read(&chip->shutdown_rwsem);
 	while (timeout-- > 0) {
+		if (chip->shutdown)
+			break;
+		idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
 		if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
 				    USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-				    validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
-				    buf, val_len) >= val_len) {
+				    validx, idx, buf, val_len) >= val_len) {
 			*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
-			snd_usb_autosuspend(cval->mixer->chip);
-			return 0;
+			err = 0;
+			goto out;
 		}
 	}
-	snd_usb_autosuspend(cval->mixer->chip);
 	snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
-		    request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
-	return -EINVAL;
+		    request, validx, idx, cval->val_type);
+	err = -EINVAL;
+
+ out:
+	up_read(&chip->shutdown_rwsem);
+	snd_usb_autosuspend(cval->mixer->chip);
+	return err;
 }
 
 static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
@@ -313,7 +320,7 @@
 	struct snd_usb_audio *chip = cval->mixer->chip;
 	unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
 	unsigned char *val;
-	int ret, size;
+	int idx = 0, ret, size;
 	__u8 bRequest;
 
 	if (request == UAC_GET_CUR) {
@@ -330,16 +337,22 @@
 	if (ret)
 		goto error;
 
-	ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
+	down_read(&chip->shutdown_rwsem);
+	if (chip->shutdown)
+		ret = -ENODEV;
+	else {
+		idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
+		ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
 			      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-			      validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
-			      buf, size);
+			      validx, idx, buf, size);
+	}
+	up_read(&chip->shutdown_rwsem);
 	snd_usb_autosuspend(chip);
 
 	if (ret < 0) {
 error:
 		snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
-			   request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
+			   request, validx, idx, cval->val_type);
 		return ret;
 	}
 
@@ -417,7 +430,7 @@
 {
 	struct snd_usb_audio *chip = cval->mixer->chip;
 	unsigned char buf[2];
-	int val_len, err, timeout = 10;
+	int idx = 0, val_len, err, timeout = 10;
 
 	if (cval->mixer->protocol == UAC_VERSION_1) {
 		val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
@@ -440,19 +453,27 @@
 	err = snd_usb_autoresume(chip);
 	if (err < 0)
 		return -EIO;
-	while (timeout-- > 0)
+	down_read(&chip->shutdown_rwsem);
+	while (timeout-- > 0) {
+		if (chip->shutdown)
+			break;
+		idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
 		if (snd_usb_ctl_msg(chip->dev,
 				    usb_sndctrlpipe(chip->dev, 0), request,
 				    USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-				    validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
-				    buf, val_len) >= 0) {
-			snd_usb_autosuspend(chip);
-			return 0;
+				    validx, idx, buf, val_len) >= 0) {
+			err = 0;
+			goto out;
 		}
-	snd_usb_autosuspend(chip);
+	}
 	snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
-		    request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]);
-	return -EINVAL;
+		    request, validx, idx, cval->val_type, buf[0], buf[1]);
+	err = -EINVAL;
+
+ out:
+	up_read(&chip->shutdown_rwsem);
+	snd_usb_autosuspend(chip);
+	return err;
 }
 
 static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 690000d..ae2b714 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -283,6 +283,11 @@
 	if (value > 1)
 		return -EINVAL;
 	changed = value != mixer->audigy2nx_leds[index];
+	down_read(&mixer->chip->shutdown_rwsem);
+	if (mixer->chip->shutdown) {
+		err = -ENODEV;
+		goto out;
+	}
 	if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
 		err = snd_usb_ctl_msg(mixer->chip->dev,
 			      usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
@@ -299,6 +304,8 @@
 			      usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
 			      value, index + 2, NULL, 0);
+ out:
+	up_read(&mixer->chip->shutdown_rwsem);
 	if (err < 0)
 		return err;
 	mixer->audigy2nx_leds[index] = value;
@@ -392,11 +399,16 @@
 
 	for (i = 0; jacks[i].name; ++i) {
 		snd_iprintf(buffer, "%s: ", jacks[i].name);
-		err = snd_usb_ctl_msg(mixer->chip->dev,
+		down_read(&mixer->chip->shutdown_rwsem);
+		if (mixer->chip->shutdown)
+			err = 0;
+		else
+			err = snd_usb_ctl_msg(mixer->chip->dev,
 				      usb_rcvctrlpipe(mixer->chip->dev, 0),
 				      UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
 				      USB_RECIP_INTERFACE, 0,
 				      jacks[i].unitid << 8, buf, 3);
+		up_read(&mixer->chip->shutdown_rwsem);
 		if (err == 3 && (buf[0] == 3 || buf[0] == 6))
 			snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
 		else
@@ -426,10 +438,15 @@
 	else
 		new_status = old_status & ~0x02;
 	changed = new_status != old_status;
-	err = snd_usb_ctl_msg(mixer->chip->dev,
+	down_read(&mixer->chip->shutdown_rwsem);
+	if (mixer->chip->shutdown)
+		err = -ENODEV;
+	else
+		err = snd_usb_ctl_msg(mixer->chip->dev,
 			      usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
 			      50, 0, &new_status, 1);
+	up_read(&mixer->chip->shutdown_rwsem);
 	if (err < 0)
 		return err;
 	mixer->xonar_u1_status = new_status;
@@ -468,11 +485,17 @@
 	u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
 	u16 wIndex = kcontrol->private_value & 0xffff;
 	u8 tmp;
+	int ret;
 
-	int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
+	down_read(&mixer->chip->shutdown_rwsem);
+	if (mixer->chip->shutdown)
+		ret = -ENODEV;
+	else
+		ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
 				  USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
 				  0, cpu_to_le16(wIndex),
 				  &tmp, sizeof(tmp), 1000);
+	up_read(&mixer->chip->shutdown_rwsem);
 
 	if (ret < 0) {
 		snd_printk(KERN_ERR
@@ -493,11 +516,17 @@
 	u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
 	u16 wIndex = kcontrol->private_value & 0xffff;
 	u16 wValue = ucontrol->value.integer.value[0];
+	int ret;
 
-	int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
+	down_read(&mixer->chip->shutdown_rwsem);
+	if (mixer->chip->shutdown)
+		ret = -ENODEV;
+	else
+		ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
 				  USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
 				  cpu_to_le16(wValue), cpu_to_le16(wIndex),
 				  NULL, 0, 1000);
+	up_read(&mixer->chip->shutdown_rwsem);
 
 	if (ret < 0) {
 		snd_printk(KERN_ERR
@@ -656,11 +685,16 @@
 		return -EINVAL;
 
 
-	err = snd_usb_ctl_msg(chip->dev,
+	down_read(&mixer->chip->shutdown_rwsem);
+	if (mixer->chip->shutdown)
+		err = -ENODEV;
+	else
+		err = snd_usb_ctl_msg(chip->dev,
 			usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
 			USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
 			validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
 			value, val_len);
+	up_read(&mixer->chip->shutdown_rwsem);
 	if (err < 0)
 		return err;
 
@@ -703,11 +737,16 @@
 
 	if (!pval->is_cached) {
 		/* Read current value */
-		err = snd_usb_ctl_msg(chip->dev,
+		down_read(&mixer->chip->shutdown_rwsem);
+		if (mixer->chip->shutdown)
+			err = -ENODEV;
+		else
+			err = snd_usb_ctl_msg(chip->dev,
 				usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
 				USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
 				validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
 				value, val_len);
+		up_read(&mixer->chip->shutdown_rwsem);
 		if (err < 0)
 			return err;
 
@@ -719,11 +758,16 @@
 	if (cur_val != new_val) {
 		value[0] = new_val;
 		value[1] = 0;
-		err = snd_usb_ctl_msg(chip->dev,
+		down_read(&mixer->chip->shutdown_rwsem);
+		if (mixer->chip->shutdown)
+			err = -ENODEV;
+		else
+			err = snd_usb_ctl_msg(chip->dev,
 				usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
 				USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
 				validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
 				value, val_len);
+		up_read(&mixer->chip->shutdown_rwsem);
 		if (err < 0)
 			return err;
 
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 55e19e1..5c12a3f 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -71,6 +71,8 @@
 	unsigned int hwptr_done;
 
 	subs = (struct snd_usb_substream *)substream->runtime->private_data;
+	if (subs->stream->chip->shutdown)
+		return SNDRV_PCM_POS_XRUN;
 	spin_lock(&subs->lock);
 	hwptr_done = subs->hwptr_done;
 	substream->runtime->delay = snd_usb_pcm_delay(subs,
@@ -444,7 +446,6 @@
 {
 	int ret;
 
-	mutex_lock(&subs->stream->chip->shutdown_mutex);
 	/* format changed */
 	stop_endpoints(subs, 0, 0, 0);
 	ret = snd_usb_endpoint_set_params(subs->data_endpoint,
@@ -455,7 +456,7 @@
 					  subs->cur_audiofmt,
 					  subs->sync_endpoint);
 	if (ret < 0)
-		goto unlock;
+		return ret;
 
 	if (subs->sync_endpoint)
 		ret = snd_usb_endpoint_set_params(subs->data_endpoint,
@@ -465,9 +466,6 @@
 						  subs->cur_rate,
 						  subs->cur_audiofmt,
 						  NULL);
-
-unlock:
-	mutex_unlock(&subs->stream->chip->shutdown_mutex);
 	return ret;
 }
 
@@ -505,7 +503,13 @@
 		return -EINVAL;
 	}
 
-	if ((ret = set_format(subs, fmt)) < 0)
+	down_read(&subs->stream->chip->shutdown_rwsem);
+	if (subs->stream->chip->shutdown)
+		ret = -ENODEV;
+	else
+		ret = set_format(subs, fmt);
+	up_read(&subs->stream->chip->shutdown_rwsem);
+	if (ret < 0)
 		return ret;
 
 	subs->interface = fmt->iface;
@@ -527,10 +531,12 @@
 	subs->cur_audiofmt = NULL;
 	subs->cur_rate = 0;
 	subs->period_bytes = 0;
-	mutex_lock(&subs->stream->chip->shutdown_mutex);
-	stop_endpoints(subs, 0, 1, 1);
-	deactivate_endpoints(subs);
-	mutex_unlock(&subs->stream->chip->shutdown_mutex);
+	down_read(&subs->stream->chip->shutdown_rwsem);
+	if (!subs->stream->chip->shutdown) {
+		stop_endpoints(subs, 0, 1, 1);
+		deactivate_endpoints(subs);
+	}
+	up_read(&subs->stream->chip->shutdown_rwsem);
 	return snd_pcm_lib_free_vmalloc_buffer(substream);
 }
 
@@ -552,12 +558,22 @@
 		return -ENXIO;
 	}
 
-	if (snd_BUG_ON(!subs->data_endpoint))
-		return -EIO;
+	down_read(&subs->stream->chip->shutdown_rwsem);
+	if (subs->stream->chip->shutdown) {
+		ret = -ENODEV;
+		goto unlock;
+	}
+	if (snd_BUG_ON(!subs->data_endpoint)) {
+		ret = -EIO;
+		goto unlock;
+	}
+
+	snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
+	snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
 
 	ret = set_format(subs, subs->cur_audiofmt);
 	if (ret < 0)
-		return ret;
+		goto unlock;
 
 	iface = usb_ifnum_to_if(subs->dev, subs->cur_audiofmt->iface);
 	alts = &iface->altsetting[subs->cur_audiofmt->altset_idx];
@@ -567,12 +583,12 @@
 				       subs->cur_audiofmt,
 				       subs->cur_rate);
 	if (ret < 0)
-		return ret;
+		goto unlock;
 
 	if (subs->need_setup_ep) {
 		ret = configure_endpoint(subs);
 		if (ret < 0)
-			return ret;
+			goto unlock;
 		subs->need_setup_ep = false;
 	}
 
@@ -592,9 +608,11 @@
 	/* for playback, submit the URBs now; otherwise, the first hwptr_done
 	 * updates for all URBs would happen at the same time when starting */
 	if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
-		return start_endpoints(subs, 1);
+		ret = start_endpoints(subs, 1);
 
-	return 0;
+ unlock:
+	up_read(&subs->stream->chip->shutdown_rwsem);
+	return ret;
 }
 
 static struct snd_pcm_hardware snd_usb_hardware =
@@ -647,7 +665,7 @@
 		return 0;
 	}
 	/* check whether the period time is >= the data packet interval */
-	if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) {
+	if (subs->speed != USB_SPEED_FULL) {
 		ptime = 125 * (1 << fp->datainterval);
 		if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
 			hwc_debug("   > check: ptime %u > max %u\n", ptime, pt->max);
@@ -925,7 +943,7 @@
 		return err;
 
 	param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
-	if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
+	if (subs->speed == USB_SPEED_FULL)
 		/* full speed devices have fixed data packet interval */
 		ptmin = 1000;
 	if (ptmin == 1000)
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
index ebc1a5b..d218f76 100644
--- a/sound/usb/proc.c
+++ b/sound/usb/proc.c
@@ -108,7 +108,7 @@
 			}
 			snd_iprintf(buffer, "\n");
 		}
-		if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
+		if (subs->speed != USB_SPEED_FULL)
 			snd_iprintf(buffer, "    Data packet interval: %d us\n",
 				    125 * (1 << fp->datainterval));
 		// snd_iprintf(buffer, "    Max Packet Size = %d\n", fp->maxpacksize);
@@ -124,7 +124,7 @@
 		return;
 	snd_iprintf(buffer, "    Packet Size = %d\n", ep->curpacksize);
 	snd_iprintf(buffer, "    Momentary freq = %u Hz (%#x.%04x)\n",
-		    snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
+		    subs->speed == USB_SPEED_FULL
 		    ? get_full_speed_hz(ep->freqm)
 		    : get_high_speed_hz(ep->freqm),
 		    ep->freqm >> 16, ep->freqm & 0xffff);
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 083ed81..1de0c8c 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -90,6 +90,7 @@
 	subs->direction = stream;
 	subs->dev = as->chip->dev;
 	subs->txfr_quirk = as->chip->txfr_quirk;
+	subs->speed = snd_usb_get_speed(subs->dev);
 
 	snd_usb_set_pcm_ops(as->pcm, stream);
 
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index b8233eb..ef42797 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -37,7 +37,7 @@
 	struct usb_interface *pm_intf;
 	u32 usb_id;
 	struct mutex mutex;
-	struct mutex shutdown_mutex;
+	struct rw_semaphore shutdown_rwsem;
 	unsigned int shutdown:1;
 	unsigned int probing:1;
 	unsigned int autosuspended:1;	
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 411ee56..178b88a 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -414,7 +414,7 @@
 int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	bool show_all = false;
-	enum help_format help_format = HELP_FORMAT_NONE;
+	enum help_format help_format = HELP_FORMAT_MAN;
 	struct option builtin_help_options[] = {
 	OPT_BOOLEAN('a', "all", &show_all, "print all available commands"),
 	OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN),
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index dec8ced..7aaee39 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -56,6 +56,10 @@
 {
 	char tp_name[128];
 	struct syscall *sc;
+	const char *name = audit_syscall_to_name(id, trace->audit_machine);
+
+	if (name == NULL)
+		return -1;
 
 	if (id > trace->syscalls.max) {
 		struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc));
@@ -75,11 +79,8 @@
 	}
 
 	sc = trace->syscalls.table + id;
-	sc->name = audit_syscall_to_name(id, trace->audit_machine);
-	if (sc->name == NULL)
-		return -1;
-
-	sc->fmt = syscall_fmt__find(sc->name);
+	sc->name = name;
+	sc->fmt  = syscall_fmt__find(sc->name);
 
 	snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name);
 	sc->tp_format = event_format__new("syscalls", tp_name);
@@ -267,6 +268,13 @@
 			if (evlist->threads->map[0] == -1 || evlist->threads->nr > 1)
 				printf("%d ", sample.tid);
 
+			if (sample.raw_data == NULL) {
+				printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
+				       perf_evsel__name(evsel), sample.tid,
+				       sample.cpu, sample.raw_size);
+				continue;
+			}
+
 			handler = evsel->handler.func;
 			handler(trace, evsel, &sample);
 		}
diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c
index 28c18d1..516ecd9 100644
--- a/tools/perf/util/parse-events-test.c
+++ b/tools/perf/util/parse-events-test.c
@@ -513,7 +513,8 @@
 	TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
 	TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
 	TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
-	TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
+	/* use of precise requires exclude_guest */
+	TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
 	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
 	TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2);
 	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
@@ -599,7 +600,8 @@
 	TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
 	TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
 	TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
-	TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
+	/* use of precise requires exclude_guest */
+	TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
 	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
 	TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 3);
 	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
@@ -662,7 +664,8 @@
 	TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
 	TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
 	TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
-	TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
+	/* use of precise requires exclude_guest */
+	TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
 	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
 	TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 1);
 	TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
@@ -676,7 +679,8 @@
 	TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
 	TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
 	TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
-	TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
+	/* use of precise requires exclude_guest */
+	TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
 	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
 	TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2);
 	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index fb4b7ea..8b3e593 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -39,7 +39,6 @@
 	err = self->comm == NULL ? -ENOMEM : 0;
 	if (!err) {
 		self->comm_set = true;
-		map_groups__flush(&self->mg);
 	}
 	return err;
 }
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 2655ae9..ea095ab 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -206,8 +206,10 @@
 	retval = pread(fd, msr, sizeof *msr, offset);
 	close(fd);
 
-	if (retval != sizeof *msr)
+	if (retval != sizeof *msr) {
+		fprintf(stderr, "%s offset 0x%zx read failed\n", pathname, offset);
 		return -1;
+	}
 
 	return 0;
 }
@@ -1101,7 +1103,9 @@
 
 restart:
 	retval = for_all_cpus(get_counters, EVEN_COUNTERS);
-	if (retval) {
+	if (retval < -1) {
+		exit(retval);
+	} else if (retval == -1) {
 		re_initialize();
 		goto restart;
 	}
@@ -1114,7 +1118,9 @@
 		}
 		sleep(interval_sec);
 		retval = for_all_cpus(get_counters, ODD_COUNTERS);
-		if (retval) {
+		if (retval < -1) {
+			exit(retval);
+		} else if (retval == -1) {
 			re_initialize();
 			goto restart;
 		}
@@ -1126,7 +1132,9 @@
 		flush_stdout();
 		sleep(interval_sec);
 		retval = for_all_cpus(get_counters, EVEN_COUNTERS);
-		if (retval) {
+		if (retval < -1) {
+			exit(retval);
+		} else if (retval == -1) {
 			re_initialize();
 			goto restart;
 		}
@@ -1545,8 +1553,11 @@
 int fork_it(char **argv)
 {
 	pid_t child_pid;
+	int status;
 
-	for_all_cpus(get_counters, EVEN_COUNTERS);
+	status = for_all_cpus(get_counters, EVEN_COUNTERS);
+	if (status)
+		exit(status);
 	/* clear affinity side-effect of get_counters() */
 	sched_setaffinity(0, cpu_present_setsize, cpu_present_set);
 	gettimeofday(&tv_even, (struct timezone *)NULL);
@@ -1556,7 +1567,6 @@
 		/* child */
 		execvp(argv[0], argv);
 	} else {
-		int status;
 
 		/* parent */
 		if (child_pid == -1) {
@@ -1568,7 +1578,7 @@
 		signal(SIGQUIT, SIG_IGN);
 		if (waitpid(child_pid, &status, 0) == -1) {
 			perror("wait");
-			exit(1);
+			exit(status);
 		}
 	}
 	/*
@@ -1585,7 +1595,7 @@
 
 	fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);
 
-	return 0;
+	return status;
 }
 
 void cmdline(int argc, char **argv)
@@ -1594,7 +1604,7 @@
 
 	progname = argv[0];
 
-	while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) {
+	while ((opt = getopt(argc, argv, "+pPSvi:sc:sC:m:M:")) != -1) {
 		switch (opt) {
 		case 'p':
 			show_core_only++;
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index b51d787..c7ba761 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -1740,8 +1740,10 @@
     open(IN, "$output_config") or dodie("Can't read config file");
     while (<IN>) {
 	if (/CONFIG_MODULES(=y)?/) {
-	    $install_mods = 1 if (defined($1));
-	    last;
+	    if (defined($1)) {
+		$install_mods = 1;
+		last;
+	    }
 	}
     }
     close(IN);
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 4348014..85baf11 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,4 +1,4 @@
-TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug epoll
+TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug
 
 all:
 	for TARGET in $(TARGETS); do \
diff --git a/tools/testing/selftests/epoll/Makefile b/tools/testing/selftests/epoll/Makefile
deleted file mode 100644
index 19806ed..0000000
--- a/tools/testing/selftests/epoll/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# Makefile for epoll selftests
-
-all: test_epoll
-%: %.c
-	gcc -pthread -g -o $@ $^
-
-run_tests: all
-	./test_epoll
-
-clean:
-	$(RM) test_epoll
diff --git a/tools/testing/selftests/epoll/test_epoll.c b/tools/testing/selftests/epoll/test_epoll.c
deleted file mode 100644
index e0fcff1e..0000000
--- a/tools/testing/selftests/epoll/test_epoll.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- *  tools/testing/selftests/epoll/test_epoll.c
- *
- *  Copyright 2012 Adobe Systems Incorporated
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  Paton J. Lewis <palewis@adobe.com>
- *
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-
-/*
- * A pointer to an epoll_item_private structure will be stored in the epoll
- * item's event structure so that we can get access to the epoll_item_private
- * data after calling epoll_wait:
- */
-struct epoll_item_private {
-	int index;  /* Position of this struct within the epoll_items array. */
-	int fd;
-	uint32_t events;
-	pthread_mutex_t mutex;  /* Guards the following variables... */
-	int stop;
-	int status;  /* Stores any error encountered while handling item. */
-	/* The following variable allows us to test whether we have encountered
-	   a problem while attempting to cancel and delete the associated
-	   event. When the test program exits, 'deleted' should be exactly
-	   one. If it is greater than one, then the failed test reflects a real
-	   world situation where we would have tried to access the epoll item's
-	   private data after deleting it: */
-	int deleted;
-};
-
-struct epoll_item_private *epoll_items;
-
-/*
- * Delete the specified item from the epoll set. In a real-world secneario this
- * is where we would free the associated data structure, but in this testing
- * environment we retain the structure so that we can test for double-deletion:
- */
-void delete_item(int index)
-{
-	__sync_fetch_and_add(&epoll_items[index].deleted, 1);
-}
-
-/*
- * A pointer to a read_thread_data structure will be passed as the argument to
- * each read thread:
- */
-struct read_thread_data {
-	int stop;
-	int status;  /* Indicates any error encountered by the read thread. */
-	int epoll_set;
-};
-
-/*
- * The function executed by the read threads:
- */
-void *read_thread_function(void *function_data)
-{
-	struct read_thread_data *thread_data =
-		(struct read_thread_data *)function_data;
-	struct epoll_event event_data;
-	struct epoll_item_private *item_data;
-	char socket_data;
-
-	/* Handle events until we encounter an error or this thread's 'stop'
-	   condition is set: */
-	while (1) {
-		int result = epoll_wait(thread_data->epoll_set,
-					&event_data,
-					1,	/* Number of desired events */
-					1000);  /* Timeout in ms */
-		if (result < 0) {
-			/* Breakpoints signal all threads. Ignore that while
-			   debugging: */
-			if (errno == EINTR)
-				continue;
-			thread_data->status = errno;
-			return 0;
-		} else if (thread_data->stop)
-			return 0;
-		else if (result == 0)  /* Timeout */
-			continue;
-
-		/* We need the mutex here because checking for the stop
-		   condition and re-enabling the epoll item need to be done
-		   together as one atomic operation when EPOLL_CTL_DISABLE is
-		   available: */
-		item_data = (struct epoll_item_private *)event_data.data.ptr;
-		pthread_mutex_lock(&item_data->mutex);
-
-		/* Remove the item from the epoll set if we want to stop
-		   handling that event: */
-		if (item_data->stop)
-			delete_item(item_data->index);
-		else {
-			/* Clear the data that was written to the other end of
-			   our non-blocking socket: */
-			do {
-				if (read(item_data->fd, &socket_data, 1) < 1) {
-					if ((errno == EAGAIN) ||
-					    (errno == EWOULDBLOCK))
-						break;
-					else
-						goto error_unlock;
-				}
-			} while (item_data->events & EPOLLET);
-
-			/* The item was one-shot, so re-enable it: */
-			event_data.events = item_data->events;
-			if (epoll_ctl(thread_data->epoll_set,
-						  EPOLL_CTL_MOD,
-						  item_data->fd,
-						  &event_data) < 0)
-				goto error_unlock;
-		}
-
-		pthread_mutex_unlock(&item_data->mutex);
-	}
-
-error_unlock:
-	thread_data->status = item_data->status = errno;
-	pthread_mutex_unlock(&item_data->mutex);
-	return 0;
-}
-
-/*
- * A pointer to a write_thread_data structure will be passed as the argument to
- * the write thread:
- */
-struct write_thread_data {
-	int stop;
-	int status;  /* Indicates any error encountered by the write thread. */
-	int n_fds;
-	int *fds;
-};
-
-/*
- * The function executed by the write thread. It writes a single byte to each
- * socket in turn until the stop condition for this thread is set. If writing to
- * a socket would block (i.e. errno was EAGAIN), we leave that socket alone for
- * the moment and just move on to the next socket in the list. We don't care
- * about the order in which we deliver events to the epoll set. In fact we don't
- * care about the data we're writing to the pipes at all; we just want to
- * trigger epoll events:
- */
-void *write_thread_function(void *function_data)
-{
-	const char data = 'X';
-	int index;
-	struct write_thread_data *thread_data =
-		(struct write_thread_data *)function_data;
-	while (!write_thread_data->stop)
-		for (index = 0;
-		     !thread_data->stop && (index < thread_data->n_fds);
-		     ++index)
-			if ((write(thread_data->fds[index], &data, 1) < 1) &&
-				(errno != EAGAIN) &&
-				(errno != EWOULDBLOCK)) {
-				write_thread_data->status = errno;
-				return;
-			}
-}
-
-/*
- * Arguments are currently ignored:
- */
-int main(int argc, char **argv)
-{
-	const int n_read_threads = 100;
-	const int n_epoll_items = 500;
-	int index;
-	int epoll_set = epoll_create1(0);
-	struct write_thread_data write_thread_data = {
-		0, 0, n_epoll_items, malloc(n_epoll_items * sizeof(int))
-	};
-	struct read_thread_data *read_thread_data =
-		malloc(n_read_threads * sizeof(struct read_thread_data));
-	pthread_t *read_threads = malloc(n_read_threads * sizeof(pthread_t));
-	pthread_t write_thread;
-
-	printf("-----------------\n");
-	printf("Runing test_epoll\n");
-	printf("-----------------\n");
-
-	epoll_items = malloc(n_epoll_items * sizeof(struct epoll_item_private));
-
-	if (epoll_set < 0 || epoll_items == 0 || write_thread_data.fds == 0 ||
-		read_thread_data == 0 || read_threads == 0)
-		goto error;
-
-	if (sysconf(_SC_NPROCESSORS_ONLN) < 2) {
-		printf("Error: please run this test on a multi-core system.\n");
-		goto error;
-	}
-
-	/* Create the socket pairs and epoll items: */
-	for (index = 0; index < n_epoll_items; ++index) {
-		int socket_pair[2];
-		struct epoll_event event_data;
-		if (socketpair(AF_UNIX,
-			       SOCK_STREAM | SOCK_NONBLOCK,
-			       0,
-			       socket_pair) < 0)
-			goto error;
-		write_thread_data.fds[index] = socket_pair[0];
-		epoll_items[index].index = index;
-		epoll_items[index].fd = socket_pair[1];
-		if (pthread_mutex_init(&epoll_items[index].mutex, NULL) != 0)
-			goto error;
-		/* We always use EPOLLONESHOT because this test is currently
-		   structured to demonstrate the need for EPOLL_CTL_DISABLE,
-		   which only produces useful information in the EPOLLONESHOT
-		   case (without EPOLLONESHOT, calling epoll_ctl with
-		   EPOLL_CTL_DISABLE will never return EBUSY). If support for
-		   testing events without EPOLLONESHOT is desired, it should
-		   probably be implemented in a separate unit test. */
-		epoll_items[index].events = EPOLLIN | EPOLLONESHOT;
-		if (index < n_epoll_items / 2)
-			epoll_items[index].events |= EPOLLET;
-		epoll_items[index].stop = 0;
-		epoll_items[index].status = 0;
-		epoll_items[index].deleted = 0;
-		event_data.events = epoll_items[index].events;
-		event_data.data.ptr = &epoll_items[index];
-		if (epoll_ctl(epoll_set,
-			      EPOLL_CTL_ADD,
-			      epoll_items[index].fd,
-			      &event_data) < 0)
-			goto error;
-	}
-
-	/* Create and start the read threads: */
-	for (index = 0; index < n_read_threads; ++index) {
-		read_thread_data[index].stop = 0;
-		read_thread_data[index].status = 0;
-		read_thread_data[index].epoll_set = epoll_set;
-		if (pthread_create(&read_threads[index],
-				   NULL,
-				   read_thread_function,
-				   &read_thread_data[index]) != 0)
-			goto error;
-	}
-
-	if (pthread_create(&write_thread,
-			   NULL,
-			   write_thread_function,
-			   &write_thread_data) != 0)
-		goto error;
-
-	/* Cancel all event pollers: */
-#ifdef EPOLL_CTL_DISABLE
-	for (index = 0; index < n_epoll_items; ++index) {
-		pthread_mutex_lock(&epoll_items[index].mutex);
-		++epoll_items[index].stop;
-		if (epoll_ctl(epoll_set,
-			      EPOLL_CTL_DISABLE,
-			      epoll_items[index].fd,
-			      NULL) == 0)
-			delete_item(index);
-		else if (errno != EBUSY) {
-			pthread_mutex_unlock(&epoll_items[index].mutex);
-			goto error;
-		}
-		/* EBUSY means events were being handled; allow the other thread
-		   to delete the item. */
-		pthread_mutex_unlock(&epoll_items[index].mutex);
-	}
-#else
-	for (index = 0; index < n_epoll_items; ++index) {
-		pthread_mutex_lock(&epoll_items[index].mutex);
-		++epoll_items[index].stop;
-		pthread_mutex_unlock(&epoll_items[index].mutex);
-		/* Wait in case a thread running read_thread_function is
-		   currently executing code between epoll_wait and
-		   pthread_mutex_lock with this item. Note that a longer delay
-		   would make double-deletion less likely (at the expense of
-		   performance), but there is no guarantee that any delay would
-		   ever be sufficient. Note also that we delete all event
-		   pollers at once for testing purposes, but in a real-world
-		   environment we are likely to want to be able to cancel event
-		   pollers at arbitrary times. Therefore we can't improve this
-		   situation by just splitting this loop into two loops
-		   (i.e. signal 'stop' for all items, sleep, and then delete all
-		   items). We also can't fix the problem via EPOLL_CTL_DEL
-		   because that command can't prevent the case where some other
-		   thread is executing read_thread_function within the region
-		   mentioned above: */
-		usleep(1);
-		pthread_mutex_lock(&epoll_items[index].mutex);
-		if (!epoll_items[index].deleted)
-			delete_item(index);
-		pthread_mutex_unlock(&epoll_items[index].mutex);
-	}
-#endif
-
-	/* Shut down the read threads: */
-	for (index = 0; index < n_read_threads; ++index)
-		__sync_fetch_and_add(&read_thread_data[index].stop, 1);
-	for (index = 0; index < n_read_threads; ++index) {
-		if (pthread_join(read_threads[index], NULL) != 0)
-			goto error;
-		if (read_thread_data[index].status)
-			goto error;
-	}
-
-	/* Shut down the write thread: */
-	__sync_fetch_and_add(&write_thread_data.stop, 1);
-	if ((pthread_join(write_thread, NULL) != 0) || write_thread_data.status)
-		goto error;
-
-	/* Check for final error conditions: */
-	for (index = 0; index < n_epoll_items; ++index) {
-		if (epoll_items[index].status != 0)
-			goto error;
-		if (pthread_mutex_destroy(&epoll_items[index].mutex) < 0)
-			goto error;
-	}
-	for (index = 0; index < n_epoll_items; ++index)
-		if (epoll_items[index].deleted != 1) {
-			printf("Error: item data deleted %1d times.\n",
-				   epoll_items[index].deleted);
-			goto error;
-		}
-
-	printf("[PASS]\n");
-	return 0;
-
- error:
-	printf("[FAIL]\n");
-	return errno;
-}
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c
index cd1b03e..b76edf2 100644
--- a/tools/vm/page-types.c
+++ b/tools/vm/page-types.c
@@ -35,7 +35,7 @@
 #include <sys/mount.h>
 #include <sys/statfs.h>
 #include "../../include/uapi/linux/magic.h"
-#include "../../include/linux/kernel-page-flags.h"
+#include "../../include/uapi/linux/kernel-page-flags.h"
 
 
 #ifndef MAX_PATH
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index af0f22f..aca6edc 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -303,7 +303,7 @@
 	int retval;
 	int rc = -1;
 	int namesize;
-	int i;
+	unsigned int i;
 
 	mode |= S_IFREG;
 
@@ -381,25 +381,28 @@
 
 static char *cpio_replace_env(char *new_location)
 {
-       char expanded[PATH_MAX + 1];
-       char env_var[PATH_MAX + 1];
-       char *start;
-       char *end;
+	char expanded[PATH_MAX + 1];
+	char env_var[PATH_MAX + 1];
+	char *start;
+	char *end;
 
-       for (start = NULL; (start = strstr(new_location, "${")); ) {
-               end = strchr(start, '}');
-               if (start < end) {
-                       *env_var = *expanded = '\0';
-                       strncat(env_var, start + 2, end - start - 2);
-                       strncat(expanded, new_location, start - new_location);
-                       strncat(expanded, getenv(env_var), PATH_MAX);
-                       strncat(expanded, end + 1, PATH_MAX);
-                       strncpy(new_location, expanded, PATH_MAX);
-               } else
-                       break;
-       }
+	for (start = NULL; (start = strstr(new_location, "${")); ) {
+		end = strchr(start, '}');
+		if (start < end) {
+			*env_var = *expanded = '\0';
+			strncat(env_var, start + 2, end - start - 2);
+			strncat(expanded, new_location, start - new_location);
+			strncat(expanded, getenv(env_var),
+				PATH_MAX - strlen(expanded));
+			strncat(expanded, end + 1,
+				PATH_MAX - strlen(expanded));
+			strncpy(new_location, expanded, PATH_MAX);
+			new_location[PATH_MAX] = 0;
+		} else
+			break;
+	}
 
-       return new_location;
+	return new_location;
 }
 
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index e59bb63..be70035 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1322,9 +1322,7 @@
 
 void kvm_release_pfn_clean(pfn_t pfn)
 {
-	WARN_ON(is_error_pfn(pfn));
-
-	if (!kvm_is_mmio_pfn(pfn))
+	if (!is_error_pfn(pfn) && !kvm_is_mmio_pfn(pfn))
 		put_page(pfn_to_page(pfn));
 }
 EXPORT_SYMBOL_GPL(kvm_release_pfn_clean);