Merge "radio: iris: Added IOCTLS to get/set AF Jump, Search Thresholds"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
index 5d1fafb..b4093de 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
@@ -21,6 +21,13 @@
 - qcom,limit-temp: Threshold temperature to start stepping CPU down, in degC.
 - qcom,temp-hysteresis: Degrees below threshold temperature to step CPU up.
 - qcom,freq-step: Number of frequency steps to take on each CPU mitigation.
+- qcom,core-limit-temp: Threshold temperature to start shutting down cores
+			in degC
+- qcom,core-temp-hysterisis: Degrees below core-limit-temp, the cores will be
+			brought online in sequence.
+- qcom,core-control-mask: The cpu mask that will be used to determine if a
+			core can be controlled or not. A mask of 0 indicates
+			the feature is disabled.
 
 Example:
 
@@ -31,4 +38,7 @@
 		qcom,limit-temp = <60>;
 		qcom,temp-hysteresis = <10>;
 		qcom,freq-step = <2>;
+		qcom,core-limit-temp = <90>;
+		qcom,core-temp-hysterisis = <10>;
+		qcom,core-control-mask = <7>;
 	};
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt b/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt
new file mode 100644
index 0000000..2b5e143
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt
@@ -0,0 +1,73 @@
+TSPP Driver
+
+For information on the TSPP driver, please refer to the TSPP driver
+documentation: Documentation/arm/msm/tspp.txt.
+
+The devicetree representation of the TSPP block should be:
+
+Required properties:
+
+- compatible: "qcom,msm_tspp"
+- cell-index: <0> - represents device ID.
+- reg: physical memory base addresses and sizes for the following:
+	TSIF0, TSIF1, TSPP and TSPP_BAM.
+- reg-names: names of the memory regions.
+- interrupts: represents IRQ numbers for the following:
+	TSIF_TSPP_IRQ, TSIF0_IRQ, TSIF1_IRQ, TSIF_BAM_IRQ.
+- interrupt-names: TSPP, TSIF and BAM interrupt names.
+- qcom,tsif-pclk: interface clock name.
+- qcom,tsif-ref-clk: reference clock name.
+	The driver uses clk_get to get the clocks by name. The clocks
+	should be defined in the relevant clock file (e.g. clock-8974.c).
+- gpios: GPIO numbers for TSIF0 (CLK, EN, DATA and SYNC) and TSIF1 (same).
+- qcom,gpio-names: GPIO names - strings describing the GPIO functionality.
+- qcom,gpios-func: GPIO functionality according to the GPIO functionality table.
+	GPIO pins can have more than a single functionality, and the TSPP driver
+	is responsible for configuring the GPIOs to work in TSIF functionality
+	based on this parameter.
+	Note: it is assumed that the functionality value (e.g. 1 in 8974 case)
+	is applicable to all TSIF GPIOs.
+
+Example (for 8974 platform, avaialble at msm8974.dtsi):
+
+	tspp: msm_tspp@f99d8000 {
+		compatible = "qcom,msm_tspp";
+		cell-index = <0>;
+		reg = <0xf99d8000 0x1000>, /* MSM_TSIF0_PHYS */
+		      <0xf99d9000 0x1000>, /* MSM_TSIF1_PHYS */
+		      <0xf99da000 0x1000>, /* MSM_TSPP_PHYS  */
+		      <0xf99c4000 0x14000>; /* MSM_TSPP_BAM_PHYS */
+		reg-names = "MSM_TSIF0_PHYS",
+			"MSM_TSIF1_PHYS",
+			"MSM_TSPP_PHYS",
+			"MSM_TSPP_BAM_PHYS";
+		interrupts = <0 153 0>, /* TSIF_TSPP_IRQ */
+			<0 151 0>, /* TSIF0_IRQ */
+			<0 152 0>, /* TSIF1_IRQ */
+			<0 154 0>; /* TSIF_BAM_IRQ */
+		interrupt-names = "TSIF_TSPP_IRQ",
+			"TSIF0_IRQ",
+			"TSIF1_IRQ",
+			"TSIF_BAM_IRQ";
+		qcom,tsif-pclk = "iface_clk";
+		qcom,tsif-ref-clk = "ref_clk";
+		gpios = <&msmgpio 89 0>, /* TSIF0 CLK  */
+			<&msmgpio 90 0>, /* TSIF0 EN   */
+			<&msmgpio 91 0>, /* TSIF0 DATA */
+			<&msmgpio 92 0>, /* TSIF0 SYNC */
+			<&msmgpio 93 0>, /* TSIF1 CLK  */
+			<&msmgpio 94 0>, /* TSIF1 EN   */
+			<&msmgpio 95 0>, /* TSIF1 DATA */
+			<&msmgpio 96 0>; /* TSIF1 SYNC */
+		qcom,gpio-names = "tsif_clk",
+				"tsif_en",
+				"tsif_data",
+				"tsif_sync",
+				"tsif_clk",
+				"tsif_en",
+				"tsif_data",
+				"tsif_sync";
+		qcom,gpios-func = <1>;
+	};
+
+
diff --git a/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt b/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
new file mode 100644
index 0000000..b31ec30
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
@@ -0,0 +1,52 @@
+Synaptics touch controller
+
+Required properties:
+
+ - compatible	: should be "synaptics,rmi4"
+ - reg			: i2c slave address of the device
+ - interrupt-parent	: parent of interrupt
+ - interrupts		: touch sample interrupt to indicate presense or release
+				of fingers on the panel.
+ - synaptics,irq-gpio	: irq gpio
+ - synaptics,reset-gpio	: reset gpio
+
+Optional property:
+ - vdd-supply		: Analog power supply needed to power device
+ - synaptics,reg-en	: specify to indicate regulator is needed
+ - vcc_i2c-supply		: Power source required to pull up i2c bus
+ - synaptics,i2c-pull-up	: specify to indicate pull up is needed
+ - synaptics,button-map		: virtual key code mappings to be used
+ - synaptics,x-flip		: modify orientation of the x axis
+ - synaptics,y-flip		: modify orientation of the y axis
+ - synaptics,panel-x		: panel x dimension
+ - synaptics,panel-y		: panel y dimension
+
+Example:
+	i2c@f9927000 { /* BLSP1 QUP5 */
+		cell-index = <5>;
+		compatible = "qcom,i2c-qup";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg-names = "qup_phys_addr";
+		reg = <0xf9927000 0x1000>;
+		interrupt-names = "qup_err_intr";
+		interrupts = <0 99 0>;
+		gpios = <&msmgpio 19 0>, /* SCL */
+			<&msmgpio 18 0>; /* SDA */
+		qcom,i2c-bus-freq = <100000>;
+		qcom,i2c-src-freq = <19200000>;
+
+		synaptics@20 {
+			compatible = "synaptics,rmi4"
+			reg = <0x20>;
+			interrupt-parent = <&msmgpio>;
+			interrupts = <17 0x2>;
+			vdd-supply = <&pm8226_l19>;
+			vcc_i2c-supply = <&pm8226_lvs1>;
+			synaptics,reset-gpio = <&msmgpio 16 0x00>;
+			synaptics,irq-gpio = <&msmgpio 17 0x00>;
+			synaptics,button-map = [8B 66 9E];
+			synaptics,i2c-pull-up;
+			synaptics,reg-en;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/misc/isa1200.txt b/Documentation/devicetree/bindings/misc/isa1200.txt
new file mode 100644
index 0000000..b30782d
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/isa1200.txt
@@ -0,0 +1,65 @@
+Imagis ISA1200 Haptics Vibrator
+
+Required properties:
+ - reg:	slave address of bus
+ - compatible: should be "imagis,isa1200"
+ - label: name for vibrator directory
+ - imagis,hap-en-gpio: haptic enable gpio
+ - imagis,mode-ctrl: mode of the controller, 0 = POWER_DOWN_MODE,
+	1 = PWM_INPUT_MODE, 2 = PWM_GEN_MODE, 3 = WAVE_GEN_MODE
+ - imagis,max-timeout: maximum timeout for vibration
+ - imagis,chip-en: chip enable
+ - vcc_i2c-supply: regulator supplying i2c bus
+
+Regulator described as a child of the main device:
+ - regulator-name: A string used as a descriptive name for regulator outputs,
+	should match vcc_i2c above
+ - regulator-min-microvolt: smallest voltage consumers may set
+ - regulator-max-microvolt: largest voltage consumers may set
+ - regulator-max-microamp: largest current consumers may set
+
+Optional properties:
+ - imagis,smart-en: automatically control haptic power based on pwm/clk signal
+ - imagis,is-erm: controlled by dc motor, use ERM driving method
+ - imagis,overdrive-high: overdrive high
+ - imagis,overdrive-en: enable overdrive
+ - imagis,pwm-freq: pwm frequency (hZ)
+ - imagis,pwm-ch-id: pwm channel id
+ - imagis,pwm-div: pwm division to be used for vibration
+ - imagis,need-pwm-clk: use "pwm_clk"
+ - imagis,hap-len-gpio: haptic ldo enable gpio
+ - imagis,etc-clk-en: use external clock
+ - xyz-supply: to be used if additional regulators are require beyond
+		"imagis,regulator" above
+
+Any additional regulators are described as child nodes of main device:
+ - regulator-name: A string used as a descriptive name for regulator outputs,
+	should match supply "xyz"
+ - regulator-min-microvolt: smallest voltage consumers may set
+ - regulator-max-microvolt: largest voltage consumers may set
+ - regulator-max-microamp: largest current consumers may set
+
+Example:
+	i2c@f9967000 {
+		isa1200@48 {
+			status = "okay";
+			reg = <0x48>;
+			vcc_i2c-supply = <&pm8941_s3>;
+			compatible = "imagis,isa1200";
+			label = "vibrator";
+			imagis,chip-en;
+			imagis,smart-en;
+			imagis,need-pwm-clk;
+			imagis,ext-clk-en;
+			imagis,hap-en-gpio = <&msmgpio 86 0x00>;
+			imagis,max-timeout = <15000>;
+			imagis,pwm-div = <256>;
+			imagis,mode-ctrl = <2>;
+			imagis,regulator {
+				regulator-name = "vcc_i2c";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-max-microamp = <9360>;
+			};
+		};
+	};
diff --git a/Documentation/mmc/mmc-dev-attrs.txt b/Documentation/mmc/mmc-dev-attrs.txt
index 7dde34f..6b712dd 100644
--- a/Documentation/mmc/mmc-dev-attrs.txt
+++ b/Documentation/mmc/mmc-dev-attrs.txt
@@ -25,14 +25,14 @@
 	running parallel lmdd write and lmdd read operations and calculating
 	the max number of packed writes requests.
 
-	min_sectors_to_check_bkops_status	This attribute is used to
-	determine whether the status bit that indicates the need for BKOPS
-	should be checked. The value is stored in this attribute represents
-	the minimum number of sectors that needs to be changed in the device
-	(written or discarded) in order to require the status-bit of BKOPS
-	to be checked. The value can modified via sysfs by writing the
-	required value to:
-	/sys/block/<block_dev_name>/min_sectors_to_check_bkops_status
+	bkops_check_threshold	This attribute is used to determine whether
+	the status bit that indicates the need for BKOPS should be checked.
+	The value should be given in percentages of the card size.
+	This value is used to calculate the minimum number of sectors that
+	needs to be changed in the device (written or discarded) in order to
+	require the status-bit of BKOPS to be checked.
+	The value can modified via sysfs by writing the required value to:
+	/sys/block/<block_dev_name>/bkops_check_threshold
 
 SD and MMC Device Attributes
 ============================
diff --git a/arch/Kconfig b/arch/Kconfig
index 0d88760..0a3ffe4 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -169,13 +169,6 @@
 	bool
 	depends on PERF_EVENTS
 
-config HAVE_HW_BRKPT_RESERVED_RW_ACCESS
-	bool
-	depends on HAVE_HW_BREAKPOINT
-	help
-	  Some of the hardware might not have r/w access beyond a certain number
-	  of breakpoint register access.
-
 config HAVE_MIXED_BREAKPOINTS_REGS
 	bool
 	depends on HAVE_HW_BREAKPOINT
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d7ebcfe..221b898 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -29,7 +29,7 @@
 	select HAVE_PERF_EVENTS
 	select PERF_USE_VMALLOC
 	select HAVE_REGS_AND_STACK_ACCESS_API
-	#select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
+	select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
 	select HAVE_C_RECORDMCOUNT
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_SHOW
@@ -1861,19 +1861,10 @@
 config ENABLE_DMM
 	def_bool n
 
-config FIX_MOVABLE_ZONE
-	def_bool n
-
 config DONT_MAP_HOLE_AFTER_MEMBANK0
 	def_bool n
 	depends on SPARSEMEM
 
-config ARCH_ENABLE_MEMORY_HOTPLUG
-	def_bool n
-
-config ARCH_ENABLE_MEMORY_HOTREMOVE
-	def_bool n
-
 config HOLES_IN_ZONE
 	def_bool n
 	depends on SPARSEMEM
@@ -2026,7 +2017,7 @@
 	  Provide support for Coprocessor register access using /sys
 	  interface. Read and write to CP registers from userspace
 	  through sysfs interface. A sys file (cp_rw) will be created under
-	  /sys/devices/system/cpaccess/cpaccess0.
+	  /sys/devices/cpaccess/cpaccess0.
 
 	  If unsure, say N.
 
diff --git a/arch/arm/boot/dts/dsi-panel-sim-video.dtsi b/arch/arm/boot/dts/dsi-panel-sim-video.dtsi
index 1e5c26c..a484372 100644
--- a/arch/arm/boot/dts/dsi-panel-sim-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-sim-video.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
index 1f7e488..815d1ae 100644
--- a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm-gdsc.dtsi b/arch/arm/boot/dts/msm-gdsc.dtsi
index f83fe76..0b60216 100644
--- a/arch/arm/boot/dts/msm-gdsc.dtsi
+++ b/arch/arm/boot/dts/msm-gdsc.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm-iommu.dtsi b/arch/arm/boot/dts/msm-iommu.dtsi
index e907de8..f263033 100755
--- a/arch/arm/boot/dts/msm-iommu.dtsi
+++ b/arch/arm/boot/dts/msm-iommu.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm-pm8841.dtsi b/arch/arm/boot/dts/msm-pm8841.dtsi
index 967d5ec..30d64f4 100644
--- a/arch/arm/boot/dts/msm-pm8841.dtsi
+++ b/arch/arm/boot/dts/msm-pm8841.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 310d23b..1333c39 100755
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm-pm8x41-rpm-regulator.dtsi b/arch/arm/boot/dts/msm-pm8x41-rpm-regulator.dtsi
index aced482..6e67dd8 100644
--- a/arch/arm/boot/dts/msm-pm8x41-rpm-regulator.dtsi
+++ b/arch/arm/boot/dts/msm-pm8x41-rpm-regulator.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974-camera.dtsi b/arch/arm/boot/dts/msm8974-camera.dtsi
index 0375e93..1a92554 100644
--- a/arch/arm/boot/dts/msm8974-camera.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974-cdp.dts b/arch/arm/boot/dts/msm8974-cdp.dts
index 95f3e89..6140730 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dts
+++ b/arch/arm/boot/dts/msm8974-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974-coresight.dtsi b/arch/arm/boot/dts/msm8974-coresight.dtsi
index ef6bf34..d4fd4f9 100644
--- a/arch/arm/boot/dts/msm8974-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8974-coresight.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974-gpio.dtsi b/arch/arm/boot/dts/msm8974-gpio.dtsi
index 5d93fa3..7d947ab 100644
--- a/arch/arm/boot/dts/msm8974-gpio.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpio.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974-iommu.dtsi b/arch/arm/boot/dts/msm8974-iommu.dtsi
index 184826e..6a88992 100755
--- a/arch/arm/boot/dts/msm8974-iommu.dtsi
+++ b/arch/arm/boot/dts/msm8974-iommu.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974-ion.dtsi b/arch/arm/boot/dts/msm8974-ion.dtsi
index 1893ae4..82b41f1 100644
--- a/arch/arm/boot/dts/msm8974-ion.dtsi
+++ b/arch/arm/boot/dts/msm8974-ion.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index 7c36bcf..ae82106 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index eb269eb..7d50900 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974-rumi.dts b/arch/arm/boot/dts/msm8974-rumi.dts
index 3533151..694a918 100644
--- a/arch/arm/boot/dts/msm8974-rumi.dts
+++ b/arch/arm/boot/dts/msm8974-rumi.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974-sim.dts b/arch/arm/boot/dts/msm8974-sim.dts
index d5368fa..b019a8a 100644
--- a/arch/arm/boot/dts/msm8974-sim.dts
+++ b/arch/arm/boot/dts/msm8974-sim.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index db46f1b..4db04b9 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm8974_pm.dtsi b/arch/arm/boot/dts/msm8974_pm.dtsi
index 007a76b..743120d 100644
--- a/arch/arm/boot/dts/msm8974_pm.dtsi
+++ b/arch/arm/boot/dts/msm8974_pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm9625-cdp.dts b/arch/arm/boot/dts/msm9625-cdp.dts
index 6733f59..2a9e5a2 100644
--- a/arch/arm/boot/dts/msm9625-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm9625-mtp.dts b/arch/arm/boot/dts/msm9625-mtp.dts
index 32185dc..af26b58 100644
--- a/arch/arm/boot/dts/msm9625-mtp.dts
+++ b/arch/arm/boot/dts/msm9625-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm9625-rumi.dts b/arch/arm/boot/dts/msm9625-rumi.dts
index e4fa000..00e5d82 100644
--- a/arch/arm/boot/dts/msm9625-rumi.dts
+++ b/arch/arm/boot/dts/msm9625-rumi.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 7b7adca..996dcee 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/common/cpaccess.c b/arch/arm/common/cpaccess.c
index 85cd09f..3572e5a 100644
--- a/arch/arm/common/cpaccess.c
+++ b/arch/arm/common/cpaccess.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -260,14 +260,10 @@
 /*
  * cp_register_write_sysfs - sysfs interface for writing to
  * CP register
- * @dev:	sys device
- * @attr:	device attribute
- * @buf:	write value
- * @cnt:	not used
- *
  */
-static ssize_t cp_register_write_sysfs(struct sys_device *dev,
-	struct sysdev_attribute *attr, const char *buf, size_t cnt)
+static ssize_t cp_register_write_sysfs(
+	struct kobject *kobj, struct kobj_attribute *attr,
+	const char *buf, size_t cnt)
 {
 	char *str_tmp = (char *)buf;
 
@@ -280,18 +276,24 @@
 }
 
 /*
+ * wrapper for deprecated sysdev write interface
+ */
+static ssize_t sysdev_cp_register_write_sysfs(struct sys_device *dev,
+	struct sysdev_attribute *attr, const char *buf, size_t cnt)
+{
+	return cp_register_write_sysfs(NULL, NULL, buf, cnt);
+}
+
+/*
  * cp_register_read_sysfs - sysfs interface for reading CP registers
- * @dev:        sys device
- * @attr:       device attribute
- * @buf:        write value
  *
  * Code to read in the CPxx crn, crm, op1, op2 variables, or into
  * the base MRC opcode, store to executable memory, clean/invalidate
  * caches and then execute the new instruction and provide the
  * result to the caller.
  */
-static ssize_t cp_register_read_sysfs(struct sys_device *dev,
-	struct sysdev_attribute *attr, char *buf)
+static ssize_t cp_register_read_sysfs(
+	struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 {
 	int ret;
 
@@ -310,20 +312,52 @@
 }
 
 /*
+ * wrapper for deprecated sysdev read interface
+ */
+static ssize_t sysdev_cp_register_read_sysfs(struct sys_device *dev,
+	struct sysdev_attribute *attr, char *buf)
+{
+	return cp_register_read_sysfs(NULL, NULL, buf);
+}
+
+/*
  * Setup sysfs files
  */
-SYSDEV_ATTR(cp_rw, 0644, cp_register_read_sysfs, cp_register_write_sysfs);
+SYSDEV_ATTR(cp_rw, 0644, sysdev_cp_register_read_sysfs,
+	    sysdev_cp_register_write_sysfs);
 
 static struct sys_device device_cpaccess = {
 	.id     = 0,
 	.cls    = &cpaccess_sysclass,
 };
 
+static struct device cpaccess_dev = {
+	.init_name = "cpaccess",
+};
+
+static struct kobj_attribute cp_rw_attribute =
+	__ATTR(cp_rw, 0644, cp_register_read_sysfs, cp_register_write_sysfs);
+
+static struct attribute *attrs[] = {
+	&cp_rw_attribute.attr,
+	NULL,
+};
+
+static struct attribute_group attr_group = {
+	.name = "cpaccess0",
+	.attrs = attrs,
+};
+
 /*
  * init_cpaccess_sysfs - initialize sys devices
  */
 static int __init init_cpaccess_sysfs(void)
 {
+	/*
+	 * sysdev interface is deprecated and will be removed
+	 * after migration to new sysfs entry
+	 */
+
 	int error = sysdev_class_register(&cpaccess_sysclass);
 
 	if (!error)
@@ -336,12 +370,28 @@
 		 &attr_cp_rw);
 	else {
 		pr_err("Error initializing cpaccess interface\n");
-		sysdev_unregister(&device_cpaccess);
-		sysdev_class_unregister(&cpaccess_sysclass);
+		goto exit0;
+	}
+
+	error = device_register(&cpaccess_dev);
+	if (error) {
+		pr_err("Error registering cpaccess device\n");
+		goto exit0;
+	}
+	error = sysfs_create_group(&cpaccess_dev.kobj, &attr_group);
+	if (error) {
+		pr_err("Error creating cpaccess sysfs group\n");
+		goto exit1;
 	}
 
 	sema_init(&cp_sem, 1);
+	return 0;
 
+exit1:
+	device_unregister(&cpaccess_dev);
+exit0:
+	sysdev_unregister(&device_cpaccess);
+	sysdev_class_unregister(&cpaccess_sysclass);
 	return error;
 }
 
@@ -350,6 +400,9 @@
 	sysdev_remove_file(&device_cpaccess, &attr_cp_rw);
 	sysdev_unregister(&device_cpaccess);
 	sysdev_class_unregister(&cpaccess_sysclass);
+
+	sysfs_remove_group(&cpaccess_dev.kobj, &attr_group);
+	device_unregister(&cpaccess_dev);
 }
 
 module_init(init_cpaccess_sysfs);
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index d78dbc8..6f8a664 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -50,6 +50,7 @@
 CONFIG_MACH_MSM8930_CDP=y
 CONFIG_MACH_MSM8930_MTP=y
 CONFIG_MACH_MSM8930_FLUID=y
+CONFIG_MACH_MSM8930_EVT=y
 CONFIG_MACH_MSM8627_CDP=y
 CONFIG_MACH_MSM8627_MTP=y
 CONFIG_MACH_APQ8064_SIM=y
@@ -71,6 +72,7 @@
 CONFIG_MSM_DSPS=y
 CONFIG_MSM_IPC_ROUTER=y
 CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_IPC_ROUTER_SECURITY=y
 CONFIG_MSM_AVS_HW=y
 # CONFIG_MSM_HW3D is not set
 CONFIG_MSM_PIL_QDSP6V4=y
@@ -97,6 +99,7 @@
 CONFIG_MSM_EBI_ERP=y
 CONFIG_MSM_CACHE_ERP=y
 CONFIG_MSM_L1_ERR_PANIC=y
+CONFIG_MSM_L1_RECOV_ERR_PANIC=y
 CONFIG_MSM_L1_ERR_LOG=y
 CONFIG_MSM_L2_ERP_2BIT_PANIC=y
 CONFIG_MSM_EVENT_TIMER=y
@@ -297,6 +300,8 @@
 CONFIG_JOYSTICK_XPAD=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
 CONFIG_TOUCHSCREEN_CYTTSP_I2C_QC=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_PMIC8XXX_PWRKEY=y
@@ -366,6 +371,8 @@
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
 CONFIG_MSM_CAMERA_FLASH_TPS61310=y
 CONFIG_OV2720=y
+CONFIG_OV8825=y
+CONFIG_OV9724=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_ACTUATOR=y
 CONFIG_MSM_EEPROM=y
@@ -376,6 +383,7 @@
 CONFIG_MSM_CSI20_HEADER=y
 CONFIG_S5K3L1YX=y
 CONFIG_IMX091=y
+CONFIG_IMX135=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
 CONFIG_ION=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 82b29c5..38b438b 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -49,6 +49,7 @@
 CONFIG_MACH_MSM8930_CDP=y
 CONFIG_MACH_MSM8930_MTP=y
 CONFIG_MACH_MSM8930_FLUID=y
+CONFIG_MACH_MSM8930_EVT=y
 CONFIG_MACH_MSM8627_CDP=y
 CONFIG_MACH_MSM8627_MTP=y
 CONFIG_MACH_APQ8064_SIM=y
@@ -70,6 +71,7 @@
 CONFIG_MSM_DSPS=y
 CONFIG_MSM_IPC_ROUTER=y
 CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_IPC_ROUTER_SECURITY=y
 CONFIG_MSM_AVS_HW=y
 # CONFIG_MSM_HW3D is not set
 CONFIG_MSM_PIL_QDSP6V4=y
@@ -98,6 +100,7 @@
 CONFIG_MSM_EBI_ERP=y
 CONFIG_MSM_CACHE_ERP=y
 CONFIG_MSM_L1_ERR_PANIC=y
+CONFIG_MSM_L1_RECOV_ERR_PANIC=y
 CONFIG_MSM_L1_ERR_LOG=y
 CONFIG_MSM_L2_ERP_PRINT_ACCESS_ERRORS=y
 CONFIG_MSM_L2_ERP_1BIT_PANIC=y
@@ -302,6 +305,8 @@
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_CYTTSP_I2C_QC=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_PMIC8XXX_PWRKEY=y
 CONFIG_INPUT_UINPUT=y
@@ -369,6 +374,8 @@
 CONFIG_IMX074_ACT=y
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
 CONFIG_OV2720=y
+CONFIG_OV8825=y
+CONFIG_OV9724=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_ACTUATOR=y
 CONFIG_MSM_EEPROM=y
@@ -379,6 +386,7 @@
 CONFIG_MSM_CSI20_HEADER=y
 CONFIG_S5K3L1YX=y
 CONFIG_IMX091=y
+CONFIG_IMX135=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
 CONFIG_ION=y
@@ -522,6 +530,7 @@
 CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
 CONFIG_DEBUG_PAGEALLOC=y
 CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_CPU_FREQ_SWITCH_PROFILER=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_PID_IN_CONTEXTIDR=y
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index b216a00..6c88a86 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -2,7 +2,7 @@
  *  arch/arm/include/asm/domain.h
  *
  *  Copyright (C) 1999 Russell King.
- *  Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2009, The Linux Foundation. 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
diff --git a/arch/arm/include/asm/mmu_writeable.h b/arch/arm/include/asm/mmu_writeable.h
index 96d348c..8c64b7f 100644
--- a/arch/arm/include/asm/mmu_writeable.h
+++ b/arch/arm/include/asm/mmu_writeable.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/include/asm/perftypes.h b/arch/arm/include/asm/perftypes.h
index 8d21dcd..6716a65 100644
--- a/arch/arm/include/asm/perftypes.h
+++ b/arch/arm/include/asm/perftypes.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 0d0103a..d1a3e61 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -32,6 +32,10 @@
  *	interrupt and passed the address of the low level handler,
  *	and can be used to implement any platform specific handling
  *	before or after calling it.
+ * @request_pmu_irq: an optional handler in case the platform wants
+ *	to use a percpu IRQ API call. e.g. request_percpu_irq
+ * @free_pmu_irq: an optional handler in case the platform wants
+ *	to use a percpu IRQ API call. e.g. free_percpu_irq
  * @enable_irq: an optional handler which will be called after
  *	request_irq and be used to handle some platform specific
  *	irq enablement
@@ -42,6 +46,8 @@
 struct arm_pmu_platdata {
 	irqreturn_t (*handle_irq)(int irq, void *dev,
 				  irq_handler_t pmu_handler);
+	int	(*request_pmu_irq)(int irq, irq_handler_t *irq_h);
+	void	(*free_pmu_irq)(int irq);
 	void (*enable_irq)(int irq);
 	void (*disable_irq)(int irq);
 };
@@ -113,10 +119,9 @@
 	struct mutex	reserve_mutex;
 	u64		max_period;
 	struct platform_device	*plat_device;
-	u32		from_idle;
 	irqreturn_t	(*handle_irq)(int irq_num, void *dev);
-	int     	(*request_pmu_irq)(int irq, irq_handler_t *irq_h);
-	void    	(*free_pmu_irq)(int irq);
+	int		(*request_pmu_irq)(int irq, irq_handler_t *irq_h);
+	void		(*free_pmu_irq)(int irq);
 	void		(*enable)(struct hw_perf_event *evt, int idx, int cpu);
 	void		(*disable)(struct hw_perf_event *evt, int idx);
 	int		(*get_event_idx)(struct pmu_hw_events *hw_events,
@@ -146,6 +151,9 @@
 			    struct hw_perf_event *hwc,
 			    int idx);
 
+extern void enable_irq_callback(void *);
+extern void disable_irq_callback(void *);
+
 #endif /* CONFIG_HW_PERF_EVENTS */
 
 #endif /* __ARM_PMU_H__ */
diff --git a/arch/arm/include/asm/remote_spinlock.h b/arch/arm/include/asm/remote_spinlock.h
index 702b669..6a895c2 100644
--- a/arch/arm/include/asm/remote_spinlock.h
+++ b/arch/arm/include/asm/remote_spinlock.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 0f04d84..67d6443 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -153,7 +153,7 @@
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK	20
 #define TIF_SECCOMP		21
-
+#define TIF_MM_RELEASED		22	/* task MM has been released */
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 8fa8b20..1692129 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -216,6 +216,20 @@
 	return core_has_mismatch_brps() ? brps - 1 : brps;
 }
 
+/* Determine if halting mode is enabled */
+static int halting_mode_enabled(void)
+{
+	u32 dscr;
+
+	ARM_DBG_READ(c1, 0, dscr);
+
+	if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
+		      "halting debug mode enabled. "
+		      "Unable to access hardware resources.\n"))
+		return -EPERM;
+	return 0;
+}
+
 /*
  * In order to access the breakpoint/watchpoint control registers,
  * we must be running in debug monitor mode. Unfortunately, we can
@@ -225,16 +239,14 @@
 static int enable_monitor_mode(void)
 {
 	u32 dscr;
-	int ret = 0;
+	int ret;
 
 	ARM_DBG_READ(c1, 0, dscr);
 
 	/* Ensure that halting mode is disabled. */
-	if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
-		"halting debug mode enabled. Unable to access hardware resources.\n")) {
-		ret = -EPERM;
+	ret = halting_mode_enabled();
+	if (ret)
 		goto out;
-	}
 
 	/* If monitor mode is already enabled, just return. */
 	if (dscr & ARM_DSCR_MDBGEN)
@@ -853,18 +865,6 @@
 	return ret;
 }
 
-static void reset_brps_reserved_reg(int n)
-{
-	int i;
-
-	/* we must also reset any reserved registers. */
-	for (i = 0; i < n; ++i) {
-		write_wb_reg(ARM_BASE_BCR + i, 0UL);
-		write_wb_reg(ARM_BASE_BVR + i, 0UL);
-	}
-
-}
-
 /*
  * One-time initialisation.
  */
@@ -891,7 +891,7 @@
 
 static void reset_ctrl_regs(void *unused)
 {
-	int i, err = 0, cpu = smp_processor_id();
+	int i, raw_num_brps, err = 0, cpu = smp_processor_id();
 	u32 dbg_power;
 
 	/*
@@ -947,19 +947,21 @@
 	isb();
 
 reset_regs:
-	if (enable_monitor_mode())
+	if (halting_mode_enabled())
 		return;
 
-#ifdef CONFIG_HAVE_HW_BRKPT_RESERVED_RW_ACCESS
-	reset_brps_reserved_reg(core_num_brps);
-#else
-	reset_brps_reserved_reg(core_num_brps + core_num_reserved_brps);
-#endif
+	/* We must also reset any reserved registers. */
+	raw_num_brps = get_num_brp_resources();
+	for (i = 0; i < raw_num_brps; ++i) {
+		write_wb_reg(ARM_BASE_BCR + i, 0UL);
+		write_wb_reg(ARM_BASE_BVR + i, 0UL);
+	}
 
 	for (i = 0; i < core_num_wrps; ++i) {
 		write_wb_reg(ARM_BASE_WCR + i, 0UL);
 		write_wb_reg(ARM_BASE_WVR + i, 0UL);
 	}
+	enable_monitor_mode();
 }
 
 static int __cpuinit dbg_reset_notify(struct notifier_block *self,
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index e97aef2..8fb93d0 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -41,6 +41,7 @@
  */
 #define ARMPMU_MAX_HWEVENTS		32
 
+static DEFINE_PER_CPU(u32, from_idle);
 static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
 static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
 static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
@@ -436,6 +437,16 @@
 	else
 		handle_irq = armpmu->handle_irq;
 
+	if (plat && plat->request_pmu_irq)
+		armpmu->request_pmu_irq = plat->request_pmu_irq;
+	else if (!armpmu->request_pmu_irq)
+		armpmu->request_pmu_irq = armpmu_generic_request_irq;
+
+	if (plat && plat->free_pmu_irq)
+		armpmu->free_pmu_irq = plat->free_pmu_irq;
+	else if (!armpmu->free_pmu_irq)
+		armpmu->free_pmu_irq = armpmu_generic_free_irq;
+
 	irqs = min(pmu_device->num_resources, num_possible_cpus());
 	if (irqs < 1) {
 		pr_err("no irqs for PMUs defined\n");
@@ -602,7 +613,7 @@
 	int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
 	int idx;
 
-	if (armpmu->from_idle) {
+	if (__get_cpu_var(from_idle)) {
 		for (idx = 0; idx <= cpu_pmu->num_events; ++idx) {
 			struct perf_event *event = hw_events->events[idx];
 
@@ -613,9 +624,12 @@
 		}
 
 		/* Reset bit so we don't needlessly re-enable counters.*/
-		armpmu->from_idle = 0;
+		__get_cpu_var(from_idle) = 0;
 	}
 
+	/* So we don't start the PMU before enabling counters after idle. */
+	barrier();
+
 	if (enabled)
 		armpmu->start();
 }
@@ -725,22 +739,89 @@
 	armpmu->type = ARM_PMU_DEVICE_CPU;
 }
 
+static int cpu_has_active_perf(void)
+{
+	struct pmu_hw_events *hw_events;
+	int enabled;
+
+	if (!cpu_pmu)
+		return 0;
+
+	hw_events = cpu_pmu->get_hw_events();
+	enabled = bitmap_weight(hw_events->used_mask, cpu_pmu->num_events);
+
+	if (enabled)
+		/*Even one event's existence is good enough.*/
+		return 1;
+
+	return 0;
+}
+
+void enable_irq_callback(void *info)
+{
+	int irq = *(unsigned int *)info;
+	enable_percpu_irq(irq, IRQ_TYPE_EDGE_RISING);
+}
+
+void disable_irq_callback(void *info)
+{
+	int irq = *(unsigned int *)info;
+	disable_percpu_irq(irq);
+}
+
 /*
  * PMU hardware loses all context when a CPU goes offline.
  * When a CPU is hotplugged back in, since some hardware registers are
  * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
  * junk values out of them.
  */
-
 static int __cpuinit pmu_cpu_notify(struct notifier_block *b,
 					unsigned long action, void *hcpu)
 {
+	int irq;
+
+	if (cpu_has_active_perf()) {
+		switch ((action & ~CPU_TASKS_FROZEN)) {
+
+		case CPU_DOWN_PREPARE:
+			/*
+			 * If this is on a multicore CPU, we need
+			 * to disarm the PMU IRQ before disappearing.
+			 */
+			if (cpu_pmu &&
+				cpu_pmu->plat_device->dev.platform_data) {
+				irq = platform_get_irq(cpu_pmu->plat_device, 0);
+				smp_call_function_single((int)hcpu,
+						disable_irq_callback, &irq, 1);
+			}
+			return NOTIFY_DONE;
+
+		case CPU_UP_PREPARE:
+			/*
+			 * If this is on a multicore CPU, we need
+			 * to arm the PMU IRQ before appearing.
+			 */
+			if (cpu_pmu &&
+				cpu_pmu->plat_device->dev.platform_data) {
+				irq = platform_get_irq(cpu_pmu->plat_device, 0);
+				smp_call_function_single((int)hcpu,
+						enable_irq_callback, &irq, 1);
+			}
+			return NOTIFY_DONE;
+
+		case CPU_STARTING:
+			if (cpu_pmu && cpu_pmu->reset) {
+				cpu_pmu->reset(NULL);
+				return NOTIFY_OK;
+			}
+		default:
+			return NOTIFY_DONE;
+		}
+	}
+
 	if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
 		return NOTIFY_DONE;
 
-	if (cpu_pmu && cpu_pmu->reset)
-		cpu_pmu->reset(NULL);
-
 	return NOTIFY_OK;
 }
 
@@ -764,24 +845,6 @@
 	}
 }
 
-static int cpu_has_active_perf(void)
-{
-	struct pmu_hw_events *hw_events;
-	int enabled;
-
-	if (!cpu_pmu)
-		return 0;
-
-	hw_events = cpu_pmu->get_hw_events();
-	enabled = bitmap_weight(hw_events->used_mask, cpu_pmu->num_events);
-
-	if (enabled)
-		/*Even one event's existence is good enough.*/
-		return 1;
-
-	return 0;
-}
-
 static struct notifier_block __cpuinitdata pmu_cpu_notifier = {
 	.notifier_call = pmu_cpu_notify,
 };
@@ -805,7 +868,7 @@
 			 * Flip this bit so armpmu_enable knows it needs
 			 * to re-enable active counters.
 			 */
-			cpu_pmu->from_idle = 1;
+			__get_cpu_var(from_idle) = 1;
 			cpu_pmu->reset(NULL);
 			perf_pmu_enable(&cpu_pmu->pmu);
 		}
diff --git a/arch/arm/kernel/perf_event_msm.c b/arch/arm/kernel/perf_event_msm.c
index 90c9c9e..92dc7c7 100644
--- a/arch/arm/kernel/perf_event_msm.c
+++ b/arch/arm/kernel/perf_event_msm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -709,8 +709,6 @@
 
 static struct arm_pmu scorpion_pmu = {
 	.handle_irq		= armv7pmu_handle_irq,
-	.request_pmu_irq	= msm_request_irq,
-	.free_pmu_irq		= msm_free_irq,
 	.enable			= scorpion_pmu_enable_event,
 	.disable		= scorpion_pmu_disable_event,
 	.read_counter		= armv7pmu_read_counter,
diff --git a/arch/arm/kernel/perf_event_msm_krait.c b/arch/arm/kernel/perf_event_msm_krait.c
index 8d8f47a..5708d74 100644
--- a/arch/arm/kernel/perf_event_msm_krait.c
+++ b/arch/arm/kernel/perf_event_msm_krait.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -520,53 +520,6 @@
 	armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
 }
 
-static void enable_irq_callback(void *info)
-{
-        int irq = *(unsigned int *)info;
-
-        enable_percpu_irq(irq, IRQ_TYPE_EDGE_RISING);
-}
-
-static void disable_irq_callback(void *info)
-{
-        int irq = *(unsigned int *)info;
-
-        disable_percpu_irq(irq);
-}
-
-static int
-msm_request_irq(int irq, irq_handler_t *handle_irq)
-{
-        int err = 0;
-        int cpu;
-
-        err = request_percpu_irq(irq, *handle_irq, "krait-l1-armpmu",
-                        &cpu_hw_events);
-
-        if (!err) {
-                for_each_cpu(cpu, cpu_online_mask) {
-                        smp_call_function_single(cpu,
-                                        enable_irq_callback, &irq, 1);
-                }
-        }
-
-        return err;
-}
-
-static void
-msm_free_irq(int irq)
-{
-        int cpu;
-
-        if (irq >= 0) {
-                for_each_cpu(cpu, cpu_online_mask) {
-                        smp_call_function_single(cpu,
-                                        disable_irq_callback, &irq, 1);
-                }
-                free_percpu_irq(irq, &cpu_hw_events);
-        }
-}
-
 /*
  * We check for column exclusion constraints here.
  * Two events cant have same reg and same group.
@@ -621,8 +574,6 @@
 
 static struct arm_pmu krait_pmu = {
 	.handle_irq		= armv7pmu_handle_irq,
-	.request_pmu_irq	= msm_request_irq,
-	.free_pmu_irq		= msm_free_irq,
 	.enable			= krait_pmu_enable_event,
 	.disable		= krait_pmu_disable_event,
 	.read_counter		= armv7pmu_read_counter,
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 678c55d..58e9068 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -997,6 +997,7 @@
 {
 	unsigned long flags;
 	struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+	unsigned long long prev_count = local64_read(&hwc->prev_count);
 
 	/*
 	 * Enable counter and interrupt, and set the counter to count
@@ -1022,6 +1023,9 @@
 	 */
 	armv7_pmnc_enable_intens(idx);
 
+	/* Restore prev val */
+	armv7pmu_write_counter(idx, prev_count & 0xffffffff);
+
 	/*
 	 * Enable counter
 	 */
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 0ff45bd..55c683a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -252,11 +252,6 @@
 		tick_nohz_idle_enter();
 		rcu_idle_enter();
 		while (!need_resched()) {
-#ifdef CONFIG_HOTPLUG_CPU
-			if (cpu_is_offline(smp_processor_id()))
-				cpu_die();
-#endif
-
 			/*
 			 * We need to disable interrupts here
 			 * to ensure we don't miss a wakeup call.
@@ -285,6 +280,10 @@
 		tick_nohz_idle_exit();
 		idle_notifier_call_chain(IDLE_END);
 		schedule_preempt_disabled();
+#ifdef CONFIG_HOTPLUG_CPU
+		if (cpu_is_offline(smp_processor_id()))
+			cpu_die();
+#endif
 	}
 }
 
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index e46fd92..f3a19fa 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -208,7 +208,7 @@
 	mb();
 
 	/* Tell __cpu_die() that this CPU is now safe to dispose of */
-	RCU_NONIDLE(complete(&cpu_died));
+	complete(&cpu_died);
 
 	/*
 	 * actual CPU shutdown procedure is at least platform (if not
diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
index fc9a37c..a35b6f1 100644
--- a/arch/arm/lib/delay.c
+++ b/arch/arm/lib/delay.c
@@ -2,7 +2,7 @@
  *  Originally from linux/arch/arm/lib/delay.S
  *
  *  Copyright (C) 1995, 1996 Russell King
- *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *  Copyright (C) 1993 Linus Torvalds
  *  Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  *  Copyright (C) 2005-2006 Atmel Corporation
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 120a4e9..d227e72 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -50,13 +50,7 @@
 	select MSM_REMOTE_SPINLOCK_DEKKERS
 	select ARCH_SPARSEMEM_ENABLE
 	select ARCH_HAS_HOLES_MEMORYMODEL
-	select MEMORY_HOTPLUG
-	select MEMORY_HOTREMOVE
-	select ARCH_ENABLE_MEMORY_HOTPLUG
-	select ARCH_ENABLE_MEMORY_HOTREMOVE
 	select MIGRATION
-	select ARCH_MEMORY_PROBE
-	select ARCH_MEMORY_REMOVE
 	select MSM_GPIOMUX
 	select RESERVE_FIRST_PAGE
 	select MSM_DALRPC
@@ -414,7 +408,6 @@
 	select HAVE_ARCH_HAS_CURRENT_TIMER
 	select MSM_JTAG if CORESIGHT_ETM
 	bool
-	select HAVE_HW_BRKPT_RESERVED_RW_ACCESS
 
 config  ARCH_MSM_CORTEXMP
 	select MSM_SMP
@@ -425,7 +418,6 @@
 
 config  ARCH_MSM_CORTEX_A5
 	bool
-	select HAVE_HW_BRKPT_RESERVED_RW_ACCESS
 
 config ARCH_MSM7X27A
 	bool
@@ -830,6 +822,12 @@
 	help
 	  Support for the Qualcomm MSM8930 FLUID device.
 
+config MACH_MSM8930_EVT
+	depends on ARCH_MSM8930
+	bool "MSM8930 QRD EVT"
+	help
+	  Support for the Qualcomm Reference Design 8930 EVT device.
+
 config MACH_MSM8627_CDP
 	depends on ARCH_MSM8930
 	bool "MSM8627 CDP"
@@ -1492,6 +1490,16 @@
 	help
 	  SMD Transport Layer for IPC Router
 
+config MSM_IPC_ROUTER_SECURITY
+	depends on MSM_IPC_ROUTER
+	bool "MSM IPC Router Security support"
+	help
+	  This feature of IPC Router will enforce security rules
+	  configured by a security script from the user-space. IPC Router
+	  once configured with the security rules will ensure that the
+	  sender of the message to a service belongs to the relevant
+	  Linux group as configured by the security script.
+
 config MSM_ONCRPCROUTER_DEBUG
 	depends on MSM_ONCRPCROUTER
 	default y
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 4418595..7ad142b 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -30,6 +30,7 @@
 obj-$(CONFIG_ARCH_MSM_KRAIT) += msm-krait-l2-accessors.o pmu.o perf_event_msm_krait_l2.o
 obj-$(CONFIG_ARCH_MSM_KRAIT) += krait-scm.o
 obj-$(CONFIG_ARCH_MSM7X27A) += pmu.o
+obj-$(CONFIG_DEBUG_FS) += perf_debug.o
 
 ifndef CONFIG_MSM_SMP
 obj-$(CONFIG_ARCH_MSM_SCORPION) += msm_fault_handlers.o
@@ -137,6 +138,7 @@
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_device.o
 obj-$(CONFIG_MSM_IPC_ROUTER) += ipc_router.o
 obj-$(CONFIG_MSM_IPC_ROUTER)+= ipc_socket.o
+obj-$(CONFIG_MSM_IPC_ROUTER_SECURITY)+= msm_ipc_router_security.o
 obj-$(CONFIG_DEBUG_FS) += smd_rpc_sym.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_servers.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_clients.o
@@ -281,6 +283,7 @@
 obj-$(CONFIG_MACH_MSM8930_CDP) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
 obj-$(CONFIG_MACH_MSM8930_MTP) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
 obj-$(CONFIG_MACH_MSM8930_FLUID) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
+obj-$(CONFIG_MACH_MSM8930_EVT) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
 obj-$(CONFIG_PM8921_BMS) += bms-batterydata.o bms-batterydata-desay.o batterydata-lib.o
 obj-$(CONFIG_MACH_APQ8064_CDP) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_MACH_APQ8064_MTP) += board-8064-all.o board-8064-regulator.o
diff --git a/arch/arm/mach-msm/acpuclock-7627.c b/arch/arm/mach-msm/acpuclock-7627.c
index b0f09b7..0718a0a 100644
--- a/arch/arm/mach-msm/acpuclock-7627.c
+++ b/arch/arm/mach-msm/acpuclock-7627.c
@@ -2,7 +2,7 @@
  * MSM architecture clock driver
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/acpuclock-7x30.c b/arch/arm/mach-msm/acpuclock-7x30.c
index 5b947e6..9f24538 100644
--- a/arch/arm/mach-msm/acpuclock-7x30.c
+++ b/arch/arm/mach-msm/acpuclock-7x30.c
@@ -1,7 +1,7 @@
 /*
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c
index 359a156..0fe1793 100644
--- a/arch/arm/mach-msm/acpuclock-8064.c
+++ b/arch/arm/mach-msm/acpuclock-8064.c
@@ -131,7 +131,6 @@
 	[12] = { { 1026000, HFPLL, 1, 0x26 }, 1150000, 1150000, 5 },
 	[13] = { { 1080000, HFPLL, 1, 0x28 }, 1150000, 1150000, 5 },
 	[14] = { { 1134000, HFPLL, 1, 0x2A }, 1150000, 1150000, 5 },
-	[15] = { { 1188000, HFPLL, 1, 0x2C }, 1150000, 1150000, 5 },
 	{ }
 };
 
@@ -149,15 +148,15 @@
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1100000 },
 	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1125000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1125000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
+	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(14), 1175000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1175000 },
+	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(14), 1200000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1200000 },
+	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(14), 1225000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1225000 },
+	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(14), 1237500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1237500 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1250000 },
 	{ 0, { 0 } }
 };
 
@@ -175,15 +174,15 @@
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1050000 },
 	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1075000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1075000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1125000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1125000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1150000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1150000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1175000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1175000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1187500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1187500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1200000 },
+	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(14), 1125000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1125000 },
+	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(14), 1150000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1150000 },
+	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(14), 1175000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1175000 },
+	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(14), 1187500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1187500 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1200000 },
 	{ 0, { 0 } }
 };
 
@@ -201,15 +200,15 @@
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1000000 },
 	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1025000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1025000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1075000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1100000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1100000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1125000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1125000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1137500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1137500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1150000 },
+	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(14), 1075000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1075000 },
+	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(14), 1100000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1100000 },
+	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(14), 1125000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1125000 },
+	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(14), 1137500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1137500 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1150000 },
 	{ 0, { 0 } }
 };
 
@@ -227,15 +226,15 @@
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   975000 },
 	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1000000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1000000 },
-	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1050000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1050000 },
-	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1075000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1075000 },
-	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(15), 1100000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1100000 },
-	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(15), 1112500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1112500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1125000 },
+	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(14), 1050000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1050000 },
+	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(14), 1075000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1075000 },
+	{ 0, {  1296000, HFPLL, 1, 0x30 }, L2(14), 1100000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1100000 },
+	{ 0, {  1404000, HFPLL, 1, 0x34 }, L2(14), 1112500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1112500 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1125000 },
 	{ 0, { 0 } }
 };
 
@@ -247,11 +246,11 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1000000 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1025000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1037500 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1087500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1125000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1150000 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1162500 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1075000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1087500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1125000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1150000 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1162500 },
 	{ 0, { 0 } }
 };
 
@@ -263,11 +262,11 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   975000 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1000000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1012500 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1037500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1050000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1087500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1112500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1125000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1037500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1050000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1087500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1112500 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1125000 },
 	{ 0, { 0 } }
 };
 
@@ -279,11 +278,11 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   937500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   950000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   975000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1000000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1012500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1037500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1075000 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1087500 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1000000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1012500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1037500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1075000 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1087500 },
 	{ 0, { 0 } }
 };
 
@@ -295,11 +294,11 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   900000 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   925000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   950000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  975000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  987500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1000000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1037500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1050000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  975000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  987500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1000000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1037500 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1050000 },
 	{ 0, { 0 } }
 };
 
@@ -311,11 +310,11 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  950000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  962500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  975000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1000000 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1012500 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  950000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  962500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  975000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1000000 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1012500 },
 	{ 0, { 0 } }
 };
 
@@ -327,11 +326,11 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15),  987500 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15), 1000000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  987500 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14), 1000000 },
 	{ 0, { 0 } }
 };
 
@@ -343,11 +342,11 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15),  975000 },
-	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(15),  987500 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  975000 },
+	{ 1, {  1512000, HFPLL, 1, 0x38 }, L2(14),  987500 },
 	{ 0, { 0 } }
 };
 
@@ -359,13 +358,13 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1000000 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1025000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1037500 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1087500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1125000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1150000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1175000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1225000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1250000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1075000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1087500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1125000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1150000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1175000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1225000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1250000 },
 	{ 0, { 0 } }
 };
 
@@ -377,13 +376,13 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   975000 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1000000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1012500 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1037500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1050000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1087500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1112500 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1150000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1187500 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1200000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1037500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1050000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1087500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1112500 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1150000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1187500 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1200000 },
 	{ 0, { 0 } }
 };
 
@@ -395,13 +394,13 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   937500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   950000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   975000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1000000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1012500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1037500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1075000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1100000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1137500 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1162500 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1000000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1012500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1037500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1075000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1100000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1137500 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1162500 },
 	{ 0, { 0 } }
 };
 
@@ -413,13 +412,13 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   900000 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   925000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   950000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  975000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  987500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1000000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1037500 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1062500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1100000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1125000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  975000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  987500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1000000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1037500 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1062500 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1100000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1125000 },
 	{ 0, { 0 } }
 };
 
@@ -431,13 +430,13 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  950000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  962500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  975000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1000000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1037500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1075000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1100000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  950000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  962500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  975000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1000000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1037500 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1075000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1100000 },
 	{ 0, { 0 } }
 };
 
@@ -449,13 +448,13 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15),  987500 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1012500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1050000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1075000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  987500 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1012500 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1050000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1075000 },
 	{ 0, { 0 } }
 };
 
@@ -467,13 +466,13 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15),  975000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1000000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1025000 },
-	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(15), 1050000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  975000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1000000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1025000 },
+	{ 1, {  1728000, HFPLL, 1, 0x40 }, L2(14), 1050000 },
 	{ 0, { 0 } }
 };
 
@@ -485,14 +484,14 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   962500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   975000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1000000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1025000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1037500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1062500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1100000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1125000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1175000 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(15), 1225000 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(15), 1287500 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1025000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1037500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1062500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1100000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1125000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1175000 },
+	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1225000 },
+	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1287500 },
 	{ 0, { 0 } }
 };
 
@@ -504,14 +503,14 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   937500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   950000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   975000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1000000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1012500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1037500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1075000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1100000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1137500 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(15), 1187500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(15), 1250000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14), 1000000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14), 1012500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1037500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1075000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1100000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1137500 },
+	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1187500 },
+	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1250000 },
 	{ 0, { 0 } }
 };
 
@@ -523,14 +522,14 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   912500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   925000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   950000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  975000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  987500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1012500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1050000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1075000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1112500 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(15), 1162500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(15), 1212500 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  975000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  987500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1012500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1050000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1075000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1112500 },
+	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1162500 },
+	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1212500 },
 	{ 0, { 0 } }
 };
 
@@ -542,14 +541,14 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   900000 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   912500 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   937500 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  962500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  975000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1000000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1025000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1050000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1087500 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(15), 1137500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(15), 1175000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  962500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  975000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14), 1000000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1025000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1050000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1087500 },
+	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1137500 },
+	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1175000 },
 	{ 0, { 0 } }
 };
 
@@ -561,14 +560,14 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  950000 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  962500 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  975000 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15), 1000000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1037500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1075000 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(15), 1112500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(15), 1150000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  950000 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  962500 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  975000 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14), 1000000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1037500 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1075000 },
+	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1112500 },
+	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1150000 },
 	{ 0, { 0 } }
 };
 
@@ -580,14 +579,14 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15),  987500 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1012500 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1050000 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(15), 1087500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(15), 1125000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  987500 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1012500 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1050000 },
+	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1087500 },
+	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1125000 },
 	{ 0, { 0 } }
 };
 
@@ -599,14 +598,14 @@
 	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
 	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
 	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
-	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
-	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
-	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
-	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(15),  975000 },
-	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(15), 1000000 },
-	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(15), 1025000 },
-	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(15), 1062500 },
-	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(15), 1100000 },
+	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(14),  937500 },
+	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(14),  950000 },
+	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(14),  962500 },
+	{ 1, {  1458000, HFPLL, 1, 0x36 }, L2(14),  975000 },
+	{ 1, {  1566000, HFPLL, 1, 0x3A }, L2(14), 1000000 },
+	{ 1, {  1674000, HFPLL, 1, 0x3E }, L2(14), 1025000 },
+	{ 1, {  1782000, HFPLL, 1, 0x42 }, L2(14), 1062500 },
+	{ 1, {  1890000, HFPLL, 1, 0x46 }, L2(14), 1100000 },
 	{ 0, { 0 } }
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8627.c b/arch/arm/mach-msm/acpuclock-8627.c
index ac29cac..8d2e86b 100644
--- a/arch/arm/mach-msm/acpuclock-8627.c
+++ b/arch/arm/mach-msm/acpuclock-8627.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
index 40326cb..2dfb3dd 100644
--- a/arch/arm/mach-msm/acpuclock-8930.c
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock-8930aa.c b/arch/arm/mach-msm/acpuclock-8930aa.c
index 7d1ce09..ce72249 100644
--- a/arch/arm/mach-msm/acpuclock-8930aa.c
+++ b/arch/arm/mach-msm/acpuclock-8930aa.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock-8930ab.c b/arch/arm/mach-msm/acpuclock-8930ab.c
index 55de66a..d15acf1 100644
--- a/arch/arm/mach-msm/acpuclock-8930ab.c
+++ b/arch/arm/mach-msm/acpuclock-8930ab.c
@@ -130,9 +130,8 @@
 	.name = "acpuclk-8930ab",
 };
 
-/* TODO: Update new L2 freqs once they are available */
 static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_NOM, 1050000, 1 },
+	[0]  = { {  384000, PLL_8, 0, 0x00 },  LVL_LOW, 1050000, 1 },
 	[1]  = { {  432000, HFPLL, 2, 0x20 },  LVL_NOM, 1050000, 2 },
 	[2]  = { {  486000, HFPLL, 2, 0x24 },  LVL_NOM, 1050000, 2 },
 	[3]  = { {  540000, HFPLL, 2, 0x28 },  LVL_NOM, 1050000, 2 },
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index d7d3edd..d81cc4d 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index d2e88fb..c77a4c1 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index 3563aca..bb426d7 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock-8x50.c b/arch/arm/mach-msm/acpuclock-8x50.c
index eed8000..4d63c04 100644
--- a/arch/arm/mach-msm/acpuclock-8x50.c
+++ b/arch/arm/mach-msm/acpuclock-8x50.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock-8x60.c b/arch/arm/mach-msm/acpuclock-8x60.c
index f94f0b2..de63feb 100644
--- a/arch/arm/mach-msm/acpuclock-8x60.c
+++ b/arch/arm/mach-msm/acpuclock-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock-9615.c b/arch/arm/mach-msm/acpuclock-9615.c
index db7bab3..2163830 100644
--- a/arch/arm/mach-msm/acpuclock-9615.c
+++ b/arch/arm/mach-msm/acpuclock-9615.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock-fsm9xxx.c b/arch/arm/mach-msm/acpuclock-fsm9xxx.c
index af1c0eb..6e1eb7e 100644
--- a/arch/arm/mach-msm/acpuclock-fsm9xxx.c
+++ b/arch/arm/mach-msm/acpuclock-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock-krait.h b/arch/arm/mach-msm/acpuclock-krait.h
index 4db95b3..9e2996a 100644
--- a/arch/arm/mach-msm/acpuclock-krait.h
+++ b/arch/arm/mach-msm/acpuclock-krait.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock.c b/arch/arm/mach-msm/acpuclock.c
index 2b33c4c..13c7b21 100644
--- a/arch/arm/mach-msm/acpuclock.c
+++ b/arch/arm/mach-msm/acpuclock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/acpuclock.h b/arch/arm/mach-msm/acpuclock.h
index 841f717..510a62e 100644
--- a/arch/arm/mach-msm/acpuclock.h
+++ b/arch/arm/mach-msm/acpuclock.h
@@ -2,7 +2,7 @@
  * MSM architecture CPU clock driver header
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/arch-init-scorpion.S b/arch/arm/mach-msm/arch-init-scorpion.S
index 82a6db8..db0a1e6 100644
--- a/arch/arm/mach-msm/arch-init-scorpion.S
+++ b/arch/arm/mach-msm/arch-init-scorpion.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  * Copyright (c) 2008-2009, Google Inc.
  * All rights reserved.
  *
diff --git a/arch/arm/mach-msm/avs.c b/arch/arm/mach-msm/avs.c
index aa257ef..b2185e3 100644
--- a/arch/arm/mach-msm/avs.c
+++ b/arch/arm/mach-msm/avs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -16,6 +16,7 @@
 #include <asm/mach-types.h>
 #include <asm/cputype.h>
 #include "avs.h"
+#include "spm.h"
 
 u32 avs_get_avscsr(void)
 {
@@ -72,7 +73,10 @@
 
 static void avs_disable_local(void *data)
 {
+	int cpu = smp_processor_id();
+
 	avs_set_avscsr(0);
+	msm_spm_set_vdd(cpu, msm_spm_get_vdd(cpu));
 }
 
 void avs_enable(int cpu, u32 avsdscr)
diff --git a/arch/arm/mach-msm/bms-batterydata-desay.c b/arch/arm/mach-msm/bms-batterydata-desay.c
index d9fa061..dd3f346 100644
--- a/arch/arm/mach-msm/bms-batterydata-desay.c
+++ b/arch/arm/mach-msm/bms-batterydata-desay.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -83,4 +83,5 @@
 	.pc_temp_ocv_lut	= &desay_5200_pc_temp_ocv,
 	.pc_sf_lut		= &desay_5200_pc_sf,
 	.default_rbatt_mohm	= 156,
+	.rbatt_capacitive_mohm	= 50,
 };
diff --git a/arch/arm/mach-msm/bms-batterydata.c b/arch/arm/mach-msm/bms-batterydata.c
index fb4f967..0c39df6 100644
--- a/arch/arm/mach-msm/bms-batterydata.c
+++ b/arch/arm/mach-msm/bms-batterydata.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -105,4 +105,5 @@
 	.pc_temp_ocv_lut	= &pc_temp_ocv,
 	.rbatt_sf_lut		= &rbatt_sf,
 	.default_rbatt_mohm	= 236,
+	.rbatt_capacitive_mohm	= 50,
 };
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 3e309d3..da395da 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -19,6 +19,7 @@
 #include <mach/camera.h>
 #include <mach/msm_bus_board.h>
 #include <mach/gpiomux.h>
+#include <mach/socinfo.h>
 
 #include "devices.h"
 #include "board-8064.h"
@@ -525,6 +526,35 @@
 	.i2c_mux_mode = MODE_L,
 };
 
+static struct msm_camera_sensor_flash_data flash_imx135 = {
+	.flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_csi_lane_params imx135_csi_lane_params = {
+	.csi_lane_assign = 0xE4,
+	.csi_lane_mask = 0xF,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_imx135 = {
+	.mount_angle    = 90,
+	.cam_vreg = apq_8064_cam_vreg,
+	.num_vreg = ARRAY_SIZE(apq_8064_cam_vreg),
+	.gpio_conf = &apq8064_back_cam_gpio_conf,
+	.i2c_conf = &apq8064_back_cam_i2c_conf,
+	.csi_lane_params = &imx135_csi_lane_params,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_imx135_data = {
+	.sensor_name    = "imx135",
+	.pdata  = &msm_camera_csi_device_data[0],
+	.flash_data = &flash_imx135,
+	.sensor_platform_info = &sensor_board_info_imx135,
+	.csi_if = 1,
+	.camera_type = BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
+	.actuator_info = &msm_act_main_cam_1_info,
+};
+
 static struct msm_camera_sensor_flash_data flash_imx074 = {
 	.flash_type	= MSM_CAMERA_FLASH_LED,
 	.flash_src	= &msm_flash_src
@@ -695,8 +725,12 @@
 
 void __init apq8064_init_cam(void)
 {
-	msm_gpiomux_install(apq8064_cam_common_configs,
+	/* for SGLTE2 platform, do not configure i2c/gpiomux gsbi4 is used for
+	 * some other purpose */
+	if (socinfo_get_platform_subtype() != PLATFORM_SUBTYPE_SGLTE2) {
+		msm_gpiomux_install(apq8064_cam_common_configs,
 			ARRAY_SIZE(apq8064_cam_common_configs));
+	}
 
 	if (machine_is_apq8064_cdp()) {
 		sensor_board_info_imx074.mount_angle = 0;
@@ -705,7 +739,8 @@
 		sensor_board_info_imx074.mount_angle = 180;
 
 	platform_device_register(&msm_camera_server);
-	platform_device_register(&msm8960_device_i2c_mux_gsbi4);
+	if (socinfo_get_platform_subtype() != PLATFORM_SUBTYPE_SGLTE2)
+		platform_device_register(&msm8960_device_i2c_mux_gsbi4);
 	platform_device_register(&msm8960_device_csiphy0);
 	platform_device_register(&msm8960_device_csiphy1);
 	platform_device_register(&msm8960_device_csid0);
@@ -722,6 +757,10 @@
 	.platform_data = &msm_camera_sensor_imx074_data,
 	},
 	{
+	I2C_BOARD_INFO("imx135", 0x10),
+	.platform_data = &msm_camera_sensor_imx135_data,
+	},
+	{
 	I2C_BOARD_INFO("mt9m114", 0x48),
 	.platform_data = &msm_camera_sensor_mt9m114_data,
 	},
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 265f7f0..b6e6cdf 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -247,6 +247,9 @@
 static struct msm_panel_common_pdata mdp_pdata = {
 	.gpio = MDP_VSYNC_GPIO,
 	.mdp_max_clk = 266667000,
+	.mdp_max_bw = 2000000000,
+	.mdp_bw_ab_factor = 115,
+	.mdp_bw_ib_factor = 125,
 	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
 	.mdp_rev = MDP_REV_44,
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index 2cb2f43..41eee63 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -797,38 +797,38 @@
 
 static struct gpiomux_setting ap2mdm_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
+	.drv = GPIOMUX_DRV_4MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
 static struct gpiomux_setting mdm2ap_status_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
+	.drv = GPIOMUX_DRV_2MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
 static struct gpiomux_setting mdm2ap_errfatal_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_16MA,
+	.drv = GPIOMUX_DRV_2MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
 static struct gpiomux_setting mdm2ap_pblrdy = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_16MA,
+	.drv = GPIOMUX_DRV_2MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
 
 static struct gpiomux_setting ap2mdm_soft_reset_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
+	.drv = GPIOMUX_DRV_4MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
 static struct gpiomux_setting ap2mdm_wakeup = {
 	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
+	.drv = GPIOMUX_DRV_4MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
@@ -1366,6 +1366,109 @@
 	},
 };
 
+static struct msm_gpiomux_config sglte2_qsc_configs[] __initdata = {
+	/* MDM2AP_STATUS */
+	{
+		.gpio = 51,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
+		}
+	},
+	/* MDM2AP_ERRFATAL */
+	{
+		.gpio = 52,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mdm2ap_errfatal_cfg,
+		}
+	},
+};
+
+static struct gpiomux_setting gsbi4_uartdm_active = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi4_uartdm_suspended = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting gsbi6_uartdm_active = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi6_uartdm_suspended = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct msm_gpiomux_config apq8064_uartdm_gsbi4_configs[] __initdata = {
+	{
+		.gpio      = 11,        /* GSBI4 UARTDM RX */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &gsbi4_uartdm_active,
+			[GPIOMUX_SUSPENDED] = &gsbi4_uartdm_suspended,
+		},
+	},
+	{
+		.gpio      = 10,       /* GSBI4 UARTDM TX */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &gsbi4_uartdm_active,
+			[GPIOMUX_SUSPENDED] = &gsbi4_uartdm_suspended,
+		},
+	},
+	{
+		.gpio      = 13,        /* GSBI4 UARTDM RFR */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &gsbi4_uartdm_active,
+			[GPIOMUX_SUSPENDED] = &gsbi4_uartdm_suspended,
+		},
+	},
+	{
+		.gpio      = 12,        /* GSBI4 UARTDM CTS */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &gsbi4_uartdm_active,
+			[GPIOMUX_SUSPENDED] = &gsbi4_uartdm_suspended,
+		},
+	},
+};
+
+static struct msm_gpiomux_config mpq8064_uartdm_configs[] __initdata = {
+	{ /* UARTDM_TX */
+		.gpio      = 14,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &gsbi6_uartdm_active,
+			[GPIOMUX_SUSPENDED] = &gsbi6_uartdm_suspended,
+		},
+	},
+	{ /* UARTDM_RX */
+		.gpio      = 15,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &gsbi6_uartdm_active,
+			[GPIOMUX_SUSPENDED] = &gsbi6_uartdm_suspended,
+		},
+	},
+	{ /* UARTDM_CTS */
+		.gpio      = 16,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &gsbi6_uartdm_active,
+			[GPIOMUX_SUSPENDED] = &gsbi6_uartdm_suspended,
+		},
+	},
+	{ /* UARTDM_RFR */
+		.gpio      = 17,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &gsbi6_uartdm_active,
+			[GPIOMUX_SUSPENDED] = &gsbi6_uartdm_suspended,
+		},
+	},
+};
+
 void __init apq8064_init_gpiomux(void)
 {
 	int rc;
@@ -1430,12 +1533,23 @@
 					ARRAY_SIZE(amdm_configs));
 			msm_gpiomux_install(bmdm_configs,
 				ARRAY_SIZE(bmdm_configs));
-		} else if (SOCINFO_VERSION_MINOR(platform_version) == 1)
-			msm_gpiomux_install(mdm_i2s_configs,
-					ARRAY_SIZE(mdm_i2s_configs));
-		else
+		} else if (socinfo_get_platform_subtype() ==
+					PLATFORM_SUBTYPE_SGLTE2) {
 			msm_gpiomux_install(mdm_configs,
 					ARRAY_SIZE(mdm_configs));
+			msm_gpiomux_install(sglte2_qsc_configs,
+					ARRAY_SIZE(sglte2_qsc_configs));
+
+			/* GSBI4 UART GPIOs for Primary IPC */
+			msm_gpiomux_install(apq8064_uartdm_gsbi4_configs,
+				ARRAY_SIZE(apq8064_uartdm_gsbi4_configs));
+		} else if (SOCINFO_VERSION_MINOR(platform_version) == 1) {
+			msm_gpiomux_install(mdm_i2s_configs,
+					ARRAY_SIZE(mdm_i2s_configs));
+		} else {
+			msm_gpiomux_install(mdm_configs,
+					ARRAY_SIZE(mdm_configs));
+		}
 	}
 
 	if (machine_is_apq8064_mtp()) {
@@ -1477,4 +1591,7 @@
 
 	msm_gpiomux_install(apq8064_sdc3_configs,
 			ARRAY_SIZE(apq8064_sdc3_configs));
+	 if (machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv())
+		msm_gpiomux_install(mpq8064_uartdm_configs,
+				ARRAY_SIZE(mpq8064_uartdm_configs));
 }
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 342cc88..2d06031 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -115,7 +115,6 @@
 /* Initial PM8921 GPIO configurations */
 static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
 	PM8921_GPIO_OUTPUT(14, 1, HIGH),	/* HDMI Mux Selector */
-	PM8921_GPIO_OUTPUT(23, 0, HIGH),	/* touchscreen power FET */
 	PM8921_GPIO_OUTPUT_BUFCONF(25, 0, LOW, CMOS), /* DISP_RESET_N */
 	PM8921_GPIO_OUTPUT_FUNC(26, 0, PM_GPIO_FUNC_2), /* Bl: Off, PWM mode */
 	PM8921_GPIO_OUTPUT_VIN(30, 1, PM_GPIO_VIN_VPH), /* SMB349 susp line */
@@ -142,10 +141,13 @@
 	PM8921_GPIO_INPUT(17, PM_GPIO_PULL_UP_1P5),	/* SD_WP */
 };
 
+static struct pm8xxx_gpio_init pm8921_mpq8064_hrd_gpios[] __initdata = {
+	PM8921_GPIO_OUTPUT(37, 0, LOW),	/* MUX1_SEL */
+};
+
 /* Initial PM8917 GPIO configurations */
 static struct pm8xxx_gpio_init pm8917_gpios[] __initdata = {
 	PM8921_GPIO_OUTPUT(14, 1, HIGH),	/* HDMI Mux Selector */
-	PM8921_GPIO_OUTPUT(23, 0, HIGH),	/* touchscreen power FET */
 	PM8921_GPIO_OUTPUT_BUFCONF(25, 0, LOW, CMOS), /* DISP_RESET_N */
 	PM8921_GPIO_OUTPUT(26, 1, HIGH), /* Backlight: on */
 	PM8921_GPIO_OUTPUT_BUFCONF(36, 1, LOW, OPEN_DRAIN),
@@ -167,6 +169,10 @@
 	PM8921_GPIO_INPUT(17, PM_GPIO_PULL_UP_1P5),	/* SD_WP */
 };
 
+static struct pm8xxx_gpio_init pm8921_8917_cdp_ts_gpios[] __initdata = {
+	PM8921_GPIO_OUTPUT(23, 0, HIGH),	/* touchscreen power FET */
+};
+
 static struct pm8xxx_gpio_init pm8921_mpq_gpios[] __initdata = {
 	PM8921_GPIO_INIT(27, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0,
 			PM_GPIO_PULL_NO, PM_GPIO_VIN_VPH, PM_GPIO_STRENGTH_NO,
@@ -185,6 +191,10 @@
 	PM8921_MPP_INIT(1, D_OUTPUT, PM8921_MPP_DIG_LEVEL_VPH, DOUT_CTRL_HIGH),
 };
 
+static struct pm8xxx_gpio_init pm8921_sglte2_gpios[] __initdata = {
+	PM8921_GPIO_OUTPUT(23, 1, HIGH),		/* PM2QSC_SOFT_RESET */
+	PM8921_GPIO_OUTPUT(21, 1, HIGH),		/* PM2QSC_KEYPADPWR */
+};
 
 void __init apq8064_configure_gpios(struct pm8xxx_gpio_init *data, int len)
 {
@@ -214,17 +224,30 @@
 		else
 			apq8064_configure_gpios(pm8917_cdp_kp_gpios,
 					ARRAY_SIZE(pm8917_cdp_kp_gpios));
+
+		apq8064_configure_gpios(pm8921_8917_cdp_ts_gpios,
+				ARRAY_SIZE(pm8921_8917_cdp_ts_gpios));
 	}
 
-	if (machine_is_apq8064_mtp())
+	if (machine_is_apq8064_mtp()) {
 		apq8064_configure_gpios(pm8921_mtp_kp_gpios,
 					ARRAY_SIZE(pm8921_mtp_kp_gpios));
+		if (socinfo_get_platform_subtype() ==
+					PLATFORM_SUBTYPE_SGLTE2) {
+			apq8064_configure_gpios(pm8921_sglte2_gpios,
+					ARRAY_SIZE(pm8921_sglte2_gpios));
+		}
+	}
 
 	if (machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd()
 	    || machine_is_mpq8064_dtv())
 		apq8064_configure_gpios(pm8921_mpq_gpios,
 					ARRAY_SIZE(pm8921_mpq_gpios));
 
+	if (machine_is_mpq8064_hrd())
+		apq8064_configure_gpios(pm8921_mpq8064_hrd_gpios,
+					ARRAY_SIZE(pm8921_mpq8064_hrd_gpios));
+
 	for (i = 0; i < ARRAY_SIZE(pm8xxx_mpps); i++) {
 		rc = pm8xxx_mpp_config(pm8xxx_mpps[i].mpp,
 					&pm8xxx_mpps[i].config);
@@ -423,6 +446,11 @@
 	.chg_term_ua			= CHG_TERM_MA * 1000,
 	.normal_voltage_calc_ms		= 20000,
 	.low_voltage_calc_ms		= 1000,
+	.alarm_low_mv			= 3400,
+	.alarm_high_mv			= 4000,
+	.high_ocv_correction_limit_uv	= 50,
+	.low_ocv_correction_limit_uv	= 100,
+	.hold_soc_est			= 3,
 };
 
 static struct pm8921_platform_data
@@ -505,4 +533,7 @@
 
 	if (!machine_is_apq8064_mtp() && !machine_is_apq8064_liquid())
 		apq8064_pm8921_chg_pdata.battery_less_hardware = 1;
+
+	if (machine_is_mpq8064_hrd())
+		apq8064_pm8921_chg_pdata.disable_chg_rmvl_wrkarnd = 1;
 }
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index a82be16..f3750d2 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -33,6 +33,7 @@
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_csid.2"),
 	REGULATOR_SUPPLY("lvds_pll_vdda",	"lvds.0"),
 	REGULATOR_SUPPLY("dsi1_pll_vdda",	"mipi_dsi.1"),
+	REGULATOR_SUPPLY("dsi_pll_vdda",	"mdp.0"),
 };
 VREG_CONSUMERS(L3) = {
 	REGULATOR_SUPPLY("8921_l3",		NULL),
@@ -60,6 +61,7 @@
 VREG_CONSUMERS(L8) = {
 	REGULATOR_SUPPLY("8921_l8",		NULL),
 	REGULATOR_SUPPLY("cam_vana",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vana",		"4-0010"),
 	REGULATOR_SUPPLY("cam_vana",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vana",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vana",		"4-0034"),
@@ -79,6 +81,7 @@
 };
 VREG_CONSUMERS(L12) = {
 	REGULATOR_SUPPLY("cam_vdig",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vdig",		"4-0010"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-0034"),
@@ -98,6 +101,7 @@
 VREG_CONSUMERS(L16) = {
 	REGULATOR_SUPPLY("8921_l16",		NULL),
 	REGULATOR_SUPPLY("cam_vaf",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vaf",		"4-0010"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-0034"),
@@ -178,6 +182,7 @@
 	REGULATOR_SUPPLY("vcc_i2c",		"3-0024"),
 	REGULATOR_SUPPLY("vddp",		"0-0048"),
 	REGULATOR_SUPPLY("hdmi_lvl_tsl",	"hdmi_msm.0"),
+	REGULATOR_SUPPLY("vdd-io",		"spi0.2"),
 };
 VREG_CONSUMERS(S5) = {
 	REGULATOR_SUPPLY("8921_s5",		NULL),
@@ -206,6 +211,7 @@
 VREG_CONSUMERS(LVS5) = {
 	REGULATOR_SUPPLY("8921_lvs5",		NULL),
 	REGULATOR_SUPPLY("cam_vio",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vio",		"4-0010"),
 	REGULATOR_SUPPLY("cam_vio",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vio",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vio",		"4-0034"),
@@ -220,6 +226,7 @@
 	REGULATOR_SUPPLY("pll_vdd",		"pil_riva"),
 	REGULATOR_SUPPLY("lvds_vdda",		"lvds.0"),
 	REGULATOR_SUPPLY("dsi1_vddio",		"mipi_dsi.1"),
+	REGULATOR_SUPPLY("dsi_pll_vddio",	"mdp.0"),
 	REGULATOR_SUPPLY("hdmi_vdda",		"hdmi_msm.0"),
 };
 VREG_CONSUMERS(USB_OTG) = {
@@ -240,7 +247,7 @@
 };
 VREG_CONSUMERS(EXT_3P3V) = {
 	REGULATOR_SUPPLY("ext_3p3v",		NULL),
-	REGULATOR_SUPPLY("vdd_io",		"spi0.2"),
+	REGULATOR_SUPPLY("vdd-phy",		"spi0.2"),
 	REGULATOR_SUPPLY("mhl_usb_hs_switch",	"msm_otg"),
 	REGULATOR_SUPPLY("lvds_vccs_3p3v",      "lvds.0"),
 	REGULATOR_SUPPLY("dsi1_vccs_3p3v",      "mipi_dsi.1"),
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index a73198e..6f71492 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 392205e..a076ed6 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -69,12 +69,14 @@
 #include <linux/msm_tsens.h>
 #include <mach/msm_xo.h>
 #include <mach/msm_rtb.h>
+#include <mach/msm_serial_hs.h>
 #include <sound/cs8427.h>
 #include <media/gpio-ir-recv.h>
 #include <linux/fmem.h>
 #include <mach/msm_pcie.h>
 #include <mach/restart.h>
 #include <mach/msm_iomap.h>
+#include <mach/msm_serial_hs.h>
 
 #include "msm_watchdog.h"
 #include "board-8064.h"
@@ -218,6 +220,13 @@
 #endif /* CONFIG_MSM_MULTIMEDIA_USE_ION */
 #endif /* CONFIG_ANDROID_PMEM */
 
+#ifdef CONFIG_BATTERY_BCL
+static struct platform_device battery_bcl_device = {
+	.name = "battery_current_limit",
+	.id = -1,
+	};
+#endif
+
 struct fmem_platform_data apq8064_fmem_pdata = {
 };
 
@@ -526,7 +535,7 @@
 
 			if (fixed_position != NOT_FIXED)
 				fixed_size += heap->size;
-			else
+			else if (!use_cma)
 				reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
 
 			if (fixed_position == FIXED_LOW) {
@@ -684,53 +693,6 @@
 	.paddr_to_memtype = apq8064_paddr_to_memtype,
 };
 
-static int apq8064_memory_bank_size(void)
-{
-	return 1<<29;
-}
-
-static void __init locate_unstable_memory(void)
-{
-	struct membank *mb = &meminfo.bank[meminfo.nr_banks - 1];
-	unsigned long bank_size;
-	unsigned long low, high;
-
-	bank_size = apq8064_memory_bank_size();
-	low = meminfo.bank[0].start;
-	high = mb->start + mb->size;
-
-	/* Check if 32 bit overflow occured */
-	if (high < mb->start)
-		high = -PAGE_SIZE;
-
-	low &= ~(bank_size - 1);
-
-	if (high - low <= bank_size)
-		goto no_dmm;
-
-#ifdef CONFIG_ENABLE_DMM
-	apq8064_reserve_info.low_unstable_address = mb->start -
-					MIN_MEMORY_BLOCK_SIZE + mb->size;
-	apq8064_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
-
-	apq8064_reserve_info.bank_size = bank_size;
-	pr_info("low unstable address %lx max size %lx bank size %lx\n",
-		apq8064_reserve_info.low_unstable_address,
-		apq8064_reserve_info.max_unstable_size,
-		apq8064_reserve_info.bank_size);
-	return;
-#endif
-no_dmm:
-	apq8064_reserve_info.low_unstable_address = high;
-	apq8064_reserve_info.max_unstable_size = 0;
-}
-
-static int apq8064_change_memory_power(u64 start, u64 size,
-	int change_type)
-{
-	return soc_change_memory_power(start, size, change_type);
-}
-
 static char prim_panel_name[PANEL_NAME_MAX_LEN];
 static char ext_panel_name[PANEL_NAME_MAX_LEN];
 
@@ -767,22 +729,9 @@
 	msm_reserve();
 }
 
-static void __init place_movable_zone(void)
-{
-#ifdef CONFIG_ENABLE_DMM
-	movable_reserved_start = apq8064_reserve_info.low_unstable_address;
-	movable_reserved_size = apq8064_reserve_info.max_unstable_size;
-	pr_info("movable zone start %lx size %lx\n",
-		movable_reserved_start, movable_reserved_size);
-#endif
-}
-
 static void __init apq8064_early_reserve(void)
 {
 	reserve_info = &apq8064_reserve_info;
-	locate_unstable_memory();
-	place_movable_zone();
-
 }
 #ifdef CONFIG_USB_EHCI_MSM_HSIC
 /* Bandwidth requests (zero) if no vote placed */
@@ -1847,6 +1796,7 @@
 	.ramdump_delay_ms = 2000,
 	.early_power_on = 1,
 	.sfr_query = 1,
+	.send_shdn = 1,
 	.vddmin_resource = &mdm_vddmin_rscs,
 	.peripheral_platform_device = &apq8064_device_hsic_host,
 	.ramdump_timeout_ms = 120000,
@@ -1855,6 +1805,21 @@
 	.sysmon_subsys_id = SYSMON_SS_EXT_MODEM,
 };
 
+static struct mdm_platform_data amdm_platform_data = {
+	.mdm_version = "3.0",
+	.ramdump_delay_ms = 2000,
+	.early_power_on = 1,
+	.sfr_query = 1,
+	.send_shdn = 1,
+	.vddmin_resource = &mdm_vddmin_rscs,
+	.peripheral_platform_device = &apq8064_device_hsic_host,
+	.ramdump_timeout_ms = 120000,
+	.mdm2ap_status_gpio_run_cfg = &mdm2ap_status_gpio_run_cfg,
+	.sysmon_subsys_id_valid = 1,
+	.sysmon_subsys_id = SYSMON_SS_EXT_MODEM,
+	.no_a2m_errfatal_on_ssr = 1,
+};
+
 static struct mdm_vddmin_resource bmdm_vddmin_rscs = {
 	.rpm_id = MSM_RPM_ID_VDDMIN_GPIO,
 	.ap2mdm_vddmin_gpio = 30,
@@ -1872,6 +1837,37 @@
 	.peripheral_platform_device = &apq8064_device_ehci_host3,
 	.ramdump_timeout_ms = 120000,
 	.mdm2ap_status_gpio_run_cfg = &mdm2ap_status_gpio_run_cfg,
+	.sysmon_subsys_id_valid = 1,
+	.sysmon_subsys_id = SYSMON_SS_EXT_MODEM2,
+	.no_a2m_errfatal_on_ssr = 1,
+};
+
+static struct mdm_platform_data sglte2_mdm_platform_data = {
+	.mdm_version = "3.0",
+	.ramdump_delay_ms = 2000,
+	.early_power_on = 1,
+	.sfr_query = 1,
+	.vddmin_resource = &mdm_vddmin_rscs,
+	.peripheral_platform_device = &apq8064_device_hsic_host,
+	.ramdump_timeout_ms = 120000,
+	.mdm2ap_status_gpio_run_cfg = &mdm2ap_status_gpio_run_cfg,
+	.sysmon_subsys_id_valid = 1,
+	.sysmon_subsys_id = SYSMON_SS_EXT_MODEM,
+	.no_a2m_errfatal_on_ssr = 1,
+	.subsys_name = "external_modem_mdm",
+};
+
+static struct mdm_platform_data sglte2_qsc_platform_data = {
+	.mdm_version = "3.0",
+	.ramdump_delay_ms = 2000,
+     /* delay between two PS_HOLDs */
+	.ps_hold_delay_ms = 500,
+	.ramdump_timeout_ms = 600000,
+	.no_powerdown_after_ramdumps = 1,
+	.image_upgrade_supported = 1,
+	.no_a2m_errfatal_on_ssr = 1,
+	.kpd_not_inverted = 1,
+	.subsys_name = "external_modem",
 };
 
 static struct tsens_platform_data apq_tsens_pdata  = {
@@ -1893,6 +1889,9 @@
 	.limit_temp_degC = 60,
 	.temp_hysteresis_degC = 10,
 	.freq_step = 2,
+	.core_limit_temp_degC = 80,
+	.core_temp_hysteresis_degC = 10,
+	.core_control_mask = 0xe,
 };
 
 #define MSM_SHARED_RAM_PHYS 0x80000000
@@ -2062,6 +2061,13 @@
 	0x0B, 0x00, 0x0f,
 };
 
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+	0x42, 0x1B, 0x00,
+	0x05, 0x03, 0x0D, 0x0B,
+	0x00, 0x42, 0x1B,
+	0x0f,
+};
+
 static uint8_t spm_power_collapse_with_rpm[] __initdata = {
 	0x00, 0x24, 0x54, 0x10,
 	0x09, 0x07, 0x01, 0x0B,
@@ -2113,11 +2119,16 @@
 		.cmd = spm_wfi_cmd_sequence,
 	},
 	[1] = {
+		.mode = MSM_SPM_MODE_POWER_RETENTION,
+		.notify_rpm = false,
+		.cmd = spm_retention_cmd_sequence,
+	},
+	[2] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = false,
 		.cmd = spm_power_collapse_without_rpm,
 	},
-	[2] = {
+	[3] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = true,
 		.cmd = spm_power_collapse_with_rpm,
@@ -2197,9 +2208,9 @@
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
 #endif
 		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020204,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x03020004,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0084009C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A4001C,
 		.vctl_timeout_us = 50,
 		.num_modes = ARRAY_SIZE(msm_spm_nonboot_cpu_seq_list),
 		.modes = msm_spm_nonboot_cpu_seq_list,
@@ -2212,9 +2223,9 @@
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
 #endif
 		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020204,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x03020004,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0084009C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A4001C,
 		.vctl_timeout_us = 50,
 		.num_modes = ARRAY_SIZE(msm_spm_nonboot_cpu_seq_list),
 		.modes = msm_spm_nonboot_cpu_seq_list,
@@ -2227,9 +2238,9 @@
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
 #endif
 		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020204,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x03020004,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0084009C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A4001C,
 		.vctl_timeout_us = 50,
 		.num_modes = ARRAY_SIZE(msm_spm_nonboot_cpu_seq_list),
 		.modes = msm_spm_nonboot_cpu_seq_list,
@@ -2368,7 +2379,6 @@
 static struct platform_device *common_not_mpq_devices[] __initdata = {
 	&apq8064_device_qup_i2c_gsbi1,
 	&apq8064_device_qup_i2c_gsbi3,
-	&apq8064_device_qup_i2c_gsbi4,
 };
 
 static struct platform_device *early_common_devices[] __initdata = {
@@ -2383,7 +2393,6 @@
 	&apq8064_device_ext_3p3v_vreg,
 	&apq8064_device_ssbi_pmic1,
 	&apq8064_device_ssbi_pmic2,
-	&apq8064_device_ext_ts_sw_vreg,
 };
 
 static struct platform_device *pm8917_common_devices[] __initdata = {
@@ -2391,7 +2400,6 @@
 	&apq8064_device_ext_3p3v_vreg,
 	&apq8064_device_ssbi_pmic1,
 	&apq8064_device_ssbi_pmic2,
-	&apq8064_device_ext_ts_sw_vreg,
 };
 
 static struct platform_device *common_devices[] __initdata = {
@@ -2610,6 +2618,20 @@
 }
 late_initcall(rf4ce_gpio_init);
 
+#ifdef CONFIG_SERIAL_MSM_HS
+static struct msm_serial_hs_platform_data mpq8064_gsbi6_uartdm_pdata = {
+	.config_gpio		= 4,
+	.uart_tx_gpio		= 14,
+	.uart_rx_gpio		= 15,
+	.uart_cts_gpio		= 16,
+	.uart_rfr_gpio		= 17,
+	.inject_rx_on_wakeup	= 1,
+	.rx_to_inject		= 0xFD,
+};
+#else
+static struct msm_serial_hs_platform_data msm_uart_dm9_pdata;
+#endif
+
 static struct platform_device *mpq_devices[] __initdata = {
 	&msm_device_sps_apq8064,
 	&mpq8064_device_qup_i2c_gsbi5,
@@ -2702,8 +2724,13 @@
 					&apq8064_i2c_qup_gsbi3_pdata;
 	apq8064_device_qup_i2c_gsbi1.dev.platform_data =
 					&apq8064_i2c_qup_gsbi1_pdata;
-	apq8064_device_qup_i2c_gsbi4.dev.platform_data =
+
+	/* Add GSBI4 I2C pdata for non-fusion3 SGLTE2 */
+	if (socinfo_get_platform_subtype() !=
+				PLATFORM_SUBTYPE_SGLTE2) {
+		apq8064_device_qup_i2c_gsbi4.dev.platform_data =
 					&apq8064_i2c_qup_gsbi4_pdata;
+	}
 	mpq8064_device_qup_i2c_gsbi5.dev.platform_data =
 					&mpq8064_i2c_qup_gsbi5_pdata;
 }
@@ -3168,6 +3195,35 @@
 	cdp_keys_data.nbuttons = ARRAY_SIZE(cdp_keys_pm8917);
 }
 
+#ifdef CONFIG_SERIAL_MSM_HS
+static struct msm_serial_hs_platform_data apq8064_uartdm_gsbi4_pdata = {
+	.config_gpio	= 4,
+	.uart_tx_gpio	= 10,
+	.uart_rx_gpio	= 11,
+	.uart_cts_gpio	= 12,
+	.uart_rfr_gpio	= 13,
+};
+#else
+static struct msm_serial_hs_platform_data apq8064_uartdm_gsbi4_pdata;
+#endif
+
+static void __init apq8064ab_update_retention_spm(void)
+{
+	int i;
+
+	/* Update the SPM sequences for krait retention on all cores */
+	for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+		int j;
+		struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+		for (j = 0; j < pdata->num_modes; j++) {
+			if (pdata->modes[j].cmd ==
+					spm_retention_cmd_sequence)
+				pdata->modes[j].cmd =
+				spm_retention_with_krait_v3_cmd_sequence;
+		}
+	}
+}
+
 static void __init apq8064_common_init(void)
 {
 	u32 platform_version = socinfo_get_platform_version();
@@ -3175,6 +3231,16 @@
 	if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
 		apq8064_pm8917_pdata_fixup();
 	platform_device_register(&msm_gpio_device);
+	if (cpu_is_apq8064ab())
+		apq8064ab_update_krait_spm();
+	if (cpu_is_krait_v3()) {
+		msm_pm_set_tz_retention_flag(0);
+		apq8064ab_update_retention_spm();
+	} else {
+		msm_pm_set_tz_retention_flag(1);
+	}
+	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
+	msm_spm_l2_init(msm_spm_l2_data);
 	msm_tsens_early_init(&apq_tsens_pdata);
 	msm_thermal_init(&msm_thermal_pdata);
 	if (socinfo_init() < 0)
@@ -3215,11 +3281,23 @@
 	else
 		platform_add_devices(pm8917_common_devices,
 					ARRAY_SIZE(pm8917_common_devices));
+
+	if (!machine_is_apq8064_mtp())
+		platform_device_register(&apq8064_device_ext_ts_sw_vreg);
+
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
 	if (!(machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
-			machine_is_mpq8064_dtv()))
+			machine_is_mpq8064_dtv())) {
 		platform_add_devices(common_not_mpq_devices,
 			ARRAY_SIZE(common_not_mpq_devices));
+
+		/* Add GSBI4 I2C Device for non-fusion3 platform */
+		if (socinfo_get_platform_subtype() !=
+					PLATFORM_SUBTYPE_SGLTE2) {
+			platform_device_register(&apq8064_device_qup_i2c_gsbi4);
+		}
+	}
+
 	msm_hsic_pdata.swfi_latency =
 		msm_rpmrs_levels[0].latency_us;
 	if (machine_is_apq8064_mtp()) {
@@ -3237,11 +3315,26 @@
 
 	if (machine_is_apq8064_mtp()) {
 		if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_DSDA2) {
-			amdm_8064_device.dev.platform_data = &mdm_platform_data;
+			amdm_8064_device.dev.platform_data =
+				&amdm_platform_data;
 			platform_device_register(&amdm_8064_device);
 			bmdm_8064_device.dev.platform_data =
 				&bmdm_platform_data;
 			platform_device_register(&bmdm_8064_device);
+		} else if (socinfo_get_platform_subtype() ==
+				   PLATFORM_SUBTYPE_SGLTE2) {
+			sglte_mdm_8064_device.dev.platform_data =
+				&sglte2_mdm_platform_data;
+			platform_device_register(&sglte_mdm_8064_device);
+			sglte2_qsc_8064_device.dev.platform_data =
+				&sglte2_qsc_platform_data;
+			platform_device_register(&sglte2_qsc_8064_device);
+
+			/* GSBI4 UART device for Primay IPC */
+			apq8064_uartdm_gsbi4_pdata.wakeup_irq = gpio_to_irq(11);
+			apq8064_device_uartdm_gsbi4.dev.platform_data =
+						&apq8064_uartdm_gsbi4_pdata;
+			platform_device_register(&apq8064_device_uartdm_gsbi4);
 		} else if (SOCINFO_VERSION_MINOR(platform_version) == 1) {
 			i2s_mdm_8064_device.dev.platform_data =
 				&mdm_platform_data;
@@ -3258,13 +3351,8 @@
 		apq8064_init_dsps();
 		platform_device_register(&msm_8960_riva);
 	}
-	if (cpu_is_apq8064ab())
-		apq8064ab_update_krait_spm();
-	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
-	msm_spm_l2_init(msm_spm_l2_data);
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
 	apq8064_epm_adc_init();
-	msm_pm_set_tz_retention_flag(1);
 }
 
 static void __init apq8064_allocate_memory_regions(void)
@@ -3300,14 +3388,22 @@
 	apq8064_init_cam();
 #endif
 
+	if (machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv()) {
+#ifdef CONFIG_SERIAL_MSM_HS
+		/* GSBI6(2) - UARTDM_RX */
+		mpq8064_gsbi6_uartdm_pdata.wakeup_irq = gpio_to_irq(15);
+		mpq8064_device_uartdm_gsbi6.dev.platform_data =
+					&mpq8064_gsbi6_uartdm_pdata;
+#endif
+		platform_device_register(&mpq8064_device_uartdm_gsbi6);
+	}
+
 	if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid())
 		platform_device_register(&cdp_kp_pdev);
 
 	if (machine_is_apq8064_mtp())
 		platform_device_register(&mtp_kp_pdev);
 
-	change_memory_power = &apq8064_change_memory_power;
-
 	if (machine_is_mpq8064_cdp()) {
 		platform_device_register(&mpq_gpio_keys_pdev);
 		platform_device_register(&mpq_keypad_device);
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 1437b3b..256fac9 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-8092-gpiomux.c b/arch/arm/mach-msm/board-8092-gpiomux.c
index 823ef70..2e598e9 100644
--- a/arch/arm/mach-msm/board-8092-gpiomux.c
+++ b/arch/arm/mach-msm/board-8092-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-8092.c b/arch/arm/mach-msm/board-8092.c
index 0471ff4..058581d 100644
--- a/arch/arm/mach-msm/board-8092.c
+++ b/arch/arm/mach-msm/board-8092.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
old mode 100644
new mode 100755
index 8af0062..cb54a7b
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -13,6 +13,7 @@
 
 #include <asm/mach-types.h>
 #include <linux/gpio.h>
+#include <mach/socinfo.h>
 #include <mach/camera.h>
 #include <mach/msm_bus_board.h>
 #include <mach/gpiomux.h>
@@ -154,6 +155,16 @@
 	},
 };
 
+static struct msm_gpiomux_config msm8930_evt_cam_configs[] = {
+	{
+		.gpio = 75,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+};
+
 static struct msm_gpiomux_config msm8930_cam_2d_configs[] = {
 	{
 		.gpio = 18,
@@ -185,6 +196,23 @@
 	},
 };
 
+static struct msm_gpiomux_config msm8930_evt_cam_2d_configs[] = {
+	{
+		.gpio = 36,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+	{
+		.gpio = 37,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+};
+
 #define VFE_CAMIF_TIMER1_GPIO 2
 #define VFE_CAMIF_TIMER2_GPIO 3
 #define VFE_CAMIF_TIMER3_GPIO_INT 4
@@ -203,6 +231,12 @@
 	._fsrc.ext_driver_src.led_flash_en = VFE_CAMIF_TIMER2_GPIO,
 	._fsrc.ext_driver_src.flash_id = MAM_CAMERA_EXT_LED_FLASH_TPS61310,
 };
+
+static struct msm_camera_sensor_flash_src msm_flash_src_led = {
+	.flash_sr_type = MSM_CAMERA_FLASH_SRC_LED1,
+	._fsrc.ext_driver_src.led_en = VFE_CAMIF_TIMER1_GPIO,
+	._fsrc.ext_driver_src.led_flash_en = VFE_CAMIF_TIMER2_GPIO,
+};
 #endif
 
 static struct msm_bus_vectors cam_init_vectors[] = {
@@ -410,16 +444,34 @@
 	{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
 };
 
+static struct camera_vreg_t msm_8930_evt_cam_vreg[] = {
+	{"cam_vdig", REG_LDO, 1500000, 1500000, 105000},
+	{"cam_vio", REG_VS, 0, 0, 0},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
 static struct gpio msm8930_common_cam_gpio[] = {
 	{20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
 	{21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
 };
 
+static struct gpio msm8930_evt_common_cam_gpio[] = {
+	{36, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+	{37, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+};
+
 static struct gpio msm8930_front_cam_gpio[] = {
 	{4, GPIOF_DIR_IN, "CAMIF_MCLK"},
 	{76, GPIOF_DIR_OUT, "CAM_RESET"},
 };
 
+static struct gpio msm8930_evt_front_cam_gpio[] = {
+	{4, GPIOF_DIR_IN, "CAMIF_MCLK"},
+	{76, GPIOF_DIR_OUT, "CAM_RESET"},
+	{75, GPIOF_DIR_OUT, "CAM_STBY_N"},
+};
+
 static struct gpio msm8930_back_cam_gpio[] = {
 	{5, GPIOF_DIR_IN, "CAMIF_MCLK"},
 	{107, GPIOF_DIR_OUT, "CAM_RESET"},
@@ -431,6 +483,13 @@
 	{76, GPIOF_OUT_INIT_HIGH, 4000},
 };
 
+static struct msm_gpio_set_tbl msm8930_evt_front_cam_gpio_set_tbl[] = {
+	{75, GPIOF_OUT_INIT_LOW, 1000},
+	{75, GPIOF_OUT_INIT_HIGH, 4000},
+	{76, GPIOF_OUT_INIT_LOW, 1000},
+	{76, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
 static struct msm_gpio_set_tbl msm8930_back_cam_gpio_set_tbl[] = {
 	{54, GPIOF_OUT_INIT_LOW, 1000},
 	{54, GPIOF_OUT_INIT_HIGH, 4000},
@@ -449,6 +508,17 @@
 	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8930_front_cam_gpio_set_tbl),
 };
 
+static struct msm_camera_gpio_conf msm_8930_evt__front_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8930_evt_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8930_evt_cam_2d_configs),
+	.cam_gpio_common_tbl = msm8930_evt_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(msm8930_evt_common_cam_gpio),
+	.cam_gpio_req_tbl = msm8930_evt_front_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(msm8930_evt_front_cam_gpio),
+	.cam_gpio_set_tbl = msm8930_evt_front_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8930_evt_front_cam_gpio_set_tbl),
+};
+
 static struct msm_camera_gpio_conf msm_8930_back_cam_gpio_conf = {
 	.cam_gpiomux_conf_tbl = msm8930_cam_2d_configs,
 	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8930_cam_2d_configs),
@@ -460,10 +530,89 @@
 	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8930_back_cam_gpio_set_tbl),
 };
 
+static struct msm_camera_gpio_conf msm_8930_evt_back_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8930_evt_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8930_evt_cam_2d_configs),
+	.cam_gpio_common_tbl = msm8930_evt_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(msm8930_evt_common_cam_gpio),
+	.cam_gpio_req_tbl = msm8930_back_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(msm8930_back_cam_gpio),
+	.cam_gpio_set_tbl = msm8930_back_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8930_back_cam_gpio_set_tbl),
+};
+
 static struct i2c_board_info msm_act_main_cam_i2c_info = {
 	I2C_BOARD_INFO("msm_actuator", 0x11),
 };
 
+static struct msm_actuator_info msm_act_main_cam_3_info = {
+	.board_info     = &msm_act_main_cam_i2c_info,
+	.cam_name       = MSM_ACTUATOR_MAIN_CAM_3,
+	/* bus_id GSBI8 is specific to 8930 sglte evt */
+	.bus_id         = MSM_8930_GSBI8_QUP_I2C_BUS_ID,
+	.vcm_pwd        = 0,
+	.vcm_enable     = 0,
+};
+
+
+static struct msm_camera_sensor_flash_data flash_ov8825 = {
+	.flash_type = MSM_CAMERA_FLASH_LED,
+#ifdef CONFIG_MSM_CAMERA_FLASH
+	.flash_src	= &msm_flash_src_led
+#endif
+};
+
+static struct msm_camera_csi_lane_params ov8825_csi_lane_params = {
+	.csi_lane_assign = 0xE4,
+	.csi_lane_mask = 0x3,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_ov8825 = {
+	.mount_angle = 90,
+	.cam_vreg = msm_8930_evt_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8930_evt_cam_vreg),
+	.gpio_conf = &msm_8930_evt_back_cam_gpio_conf,
+	.csi_lane_params = &ov8825_csi_lane_params,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov8825_data = {
+	.sensor_name = "ov8825",
+	.pdata = &msm_camera_csi_device_data[0],
+	.flash_data = &flash_ov8825,
+	.sensor_platform_info = &sensor_board_info_ov8825,
+	.csi_if = 1,
+	.camera_type = BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
+	.actuator_info = &msm_act_main_cam_3_info,
+};
+
+static struct msm_camera_sensor_flash_data flash_ov9724 = {
+	.flash_type = MSM_CAMERA_FLASH_NONE
+};
+
+static struct msm_camera_csi_lane_params ov9724_csi_lane_params = {
+	.csi_lane_assign = 0xE4,
+	.csi_lane_mask = 0x1,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_ov9724 = {
+	.mount_angle = 90,
+	.cam_vreg = msm_8930_evt_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8930_evt_cam_vreg),
+	.gpio_conf = &msm_8930_evt__front_cam_gpio_conf,
+	.csi_lane_params = &ov9724_csi_lane_params,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov9724_data = {
+	.sensor_name = "ov9724",
+	.pdata = &msm_camera_csi_device_data[1],
+	.flash_data = &flash_ov9724,
+	.sensor_platform_info = &sensor_board_info_ov9724,
+	.csi_if = 1,
+	.camera_type = FRONT_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
+};
+
 static struct msm_actuator_info msm_act_main_cam_0_info = {
 	.board_info     = &msm_act_main_cam_i2c_info,
 	.cam_name   = MSM_ACTUATOR_MAIN_CAM_0,
@@ -514,7 +663,7 @@
 };
 
 static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
-	.mount_angle = 90,
+	.mount_angle = 270,
 	.cam_vreg = msm_8930_cam_vreg,
 	.num_vreg = ARRAY_SIZE(msm_8930_cam_vreg),
 	.gpio_conf = &msm_8930_front_cam_gpio_conf,
@@ -600,11 +749,65 @@
 	.id = 0,
 };
 
+#ifdef CONFIG_I2C
+struct i2c_board_info msm8930_camera_i2c_boardinfo[] = {
+	{
+	I2C_BOARD_INFO("imx074", 0x1A),
+	.platform_data = &msm_camera_sensor_imx074_data,
+	},
+	{
+	I2C_BOARD_INFO("ov2720", 0x6C),
+	.platform_data = &msm_camera_sensor_ov2720_data,
+	},
+	{
+	I2C_BOARD_INFO("mt9m114", 0x48),
+	.platform_data = &msm_camera_sensor_mt9m114_data,
+	},
+	{
+	I2C_BOARD_INFO("s5k3l1yx", 0x20),
+	.platform_data = &msm_camera_sensor_s5k3l1yx_data,
+	},
+	{
+	I2C_BOARD_INFO("tps61310", 0x66),
+	},
+};
+
+/* 8930 SGLTE device */
+struct i2c_board_info msm8930_evt_camera_i2c_boardinfo[] = {
+	{
+	I2C_BOARD_INFO("ov8825", 0x6c>>1),
+	.platform_data = &msm_camera_sensor_ov8825_data,
+	},
+	{
+	I2C_BOARD_INFO("ov9724", 0x20>>1),
+	.platform_data = &msm_camera_sensor_ov9724_data,
+	},
+};
+
+struct msm_camera_board_info msm8930_camera_board_info = {
+	.board_info = msm8930_camera_i2c_boardinfo,
+	.num_i2c_board_info = ARRAY_SIZE(msm8930_camera_i2c_boardinfo),
+};
+#endif
+
 void __init msm8930_init_cam(void)
 {
 	msm_gpiomux_install(msm8930_cam_common_configs,
 			ARRAY_SIZE(msm8930_cam_common_configs));
 
+	if (machine_is_msm8930_evt() &&
+			(socinfo_get_platform_subtype() ==
+			 PLATFORM_SUBTYPE_SGLTE)) {
+		msm_gpiomux_install(msm8930_evt_cam_configs,
+				ARRAY_SIZE(msm8930_evt_cam_configs));
+
+		/* Load ov8825 & ov9724 only for SGLTE device */
+		msm8930_camera_board_info.board_info =
+			msm8930_evt_camera_i2c_boardinfo;
+		msm8930_camera_board_info.num_i2c_board_info =
+			ARRAY_SIZE(msm8930_evt_camera_i2c_boardinfo);
+	}
+
 	if (machine_is_msm8930_cdp()) {
 		struct msm_camera_sensor_info *s_info;
 		s_info = &msm_camera_sensor_s5k3l1yx_data;
@@ -630,33 +833,4 @@
 	platform_device_register(&msm8960_device_vfe);
 	platform_device_register(&msm8960_device_vpe);
 }
-
-#ifdef CONFIG_I2C
-struct i2c_board_info msm8930_camera_i2c_boardinfo[] = {
-	{
-	I2C_BOARD_INFO("imx074", 0x1A),
-	.platform_data = &msm_camera_sensor_imx074_data,
-	},
-	{
-	I2C_BOARD_INFO("ov2720", 0x6C),
-	.platform_data = &msm_camera_sensor_ov2720_data,
-	},
-	{
-	I2C_BOARD_INFO("mt9m114", 0x48),
-	.platform_data = &msm_camera_sensor_mt9m114_data,
-	},
-	{
-	I2C_BOARD_INFO("s5k3l1yx", 0x20),
-	.platform_data = &msm_camera_sensor_s5k3l1yx_data,
-	},
-	{
-	I2C_BOARD_INFO("tps61310", 0x66),
-	},
-};
-
-struct msm_camera_board_info msm8930_camera_board_info = {
-	.board_info = msm8930_camera_i2c_boardinfo,
-	.num_i2c_board_info = ARRAY_SIZE(msm8930_camera_i2c_boardinfo),
-};
-#endif
 #endif
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index fc0c638..bb301b3 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -58,6 +58,7 @@
 #define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME	"mipi_video_chimei_wxga"
 #define MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME	"mipi_video_simulator_vga"
 #define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME	"mipi_cmd_renesas_fwvga"
+#define MIPI_VIDEO_NT_HD_PANEL_NAME		"mipi_video_nt35590_720p"
 #define HDMI_PANEL_NAME	"hdmi_msm"
 #define TVOUT_PANEL_NAME	"tvout_msm"
 
@@ -69,10 +70,17 @@
 
 static int msm_fb_detect_panel(const char *name)
 {
-	if (!strncmp(name, MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
+	if (machine_is_msm8930_evt()) {
+		if (!strncmp(name, MIPI_VIDEO_NT_HD_PANEL_NAME,
+			strnlen(MIPI_VIDEO_NT_HD_PANEL_NAME,
+				PANEL_NAME_MAX_LEN)))
+			return 0;
+	} else {
+		if (!strncmp(name, MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
 			strnlen(MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
 				PANEL_NAME_MAX_LEN)))
-		return 0;
+			return 0;
+	}
 
 #if !defined(CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT) && \
 	!defined(CONFIG_FB_MSM_MIPI_PANEL_DETECT)
@@ -195,18 +203,29 @@
 			gpio_free(DISP_RST_GPIO);
 			return -ENODEV;
 		}
-		rc = gpio_request(DISP_3D_2D_MODE, "disp_3d_2d");
-		if (rc) {
-			pr_err("request gpio DISP_3D_2D_MODE failed, rc=%d\n",
-				 rc);
-			gpio_free(DISP_3D_2D_MODE);
-			return -ENODEV;
+		if (machine_is_msm8930_evt()) {
+			rc = gpio_direction_output(DISP_RST_GPIO, 1);
+			if (rc) {
+				pr_err("gpio_direction_output failed for %d gpio rc=%d\n",
+						DISP_RST_GPIO, rc);
+				return -ENODEV;
+			}
 		}
-		rc = gpio_direction_output(DISP_3D_2D_MODE, 0);
-		if (rc) {
-			pr_err("gpio_direction_output failed for %d gpio rc=%d\n",
-			DISP_3D_2D_MODE, rc);
-			return -ENODEV;
+
+		if (!machine_is_msm8930_evt()) {
+			rc = gpio_request(DISP_3D_2D_MODE, "disp_3d_2d");
+			if (rc) {
+				pr_err("request gpio DISP_3D_2D_MODE failed, rc=%d\n",
+				 rc);
+				gpio_free(DISP_3D_2D_MODE);
+				return -ENODEV;
+			}
+			rc = gpio_direction_output(DISP_3D_2D_MODE, 0);
+			if (rc) {
+				pr_err("gpio_direction_output failed for %d gpio rc=%d\n",
+						DISP_3D_2D_MODE, rc);
+				return -ENODEV;
+			}
 		}
 		if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917) {
 			rc = gpio_request(gpio24, "disp_bl");
@@ -259,7 +278,8 @@
 		gpio_set_value(DISP_RST_GPIO, 0);
 		usleep(20);
 		gpio_set_value(DISP_RST_GPIO, 1);
-		gpio_set_value(DISP_3D_2D_MODE, 1);
+		if (!machine_is_msm8930_evt())
+			gpio_set_value(DISP_3D_2D_MODE, 1);
 		usleep(20);
 	} else {
 
@@ -295,7 +315,8 @@
 			pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
 			return -EINVAL;
 		}
-		gpio_set_value(DISP_3D_2D_MODE, 0);
+		if (!machine_is_msm8930_evt())
+			gpio_set_value(DISP_3D_2D_MODE, 0);
 		usleep(20);
 	}
 	return 0;
@@ -439,6 +460,9 @@
 static struct msm_panel_common_pdata mdp_pdata = {
 	.gpio = MDP_VSYNC_GPIO,
 	.mdp_max_clk = 200000000,
+	.mdp_max_bw = 2000000000,
+	.mdp_bw_ab_factor = 115,
+	.mdp_bw_ib_factor = 125,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
 #endif
@@ -478,6 +502,12 @@
 	}
 };
 
+static struct platform_device mipi_dsi_NT35590_panel_device = {
+	.name = "mipi_NT35590",
+	.id = 0,
+	/* todo: add any platform data */
+};
+
 #define FPGA_3D_GPIO_CONFIG_ADDR	0xB5
 
 static struct mipi_dsi_phy_ctrl dsi_novatek_cmd_mode_phy_db = {
@@ -492,7 +522,7 @@
 	/* pll control */
 	{0x0, 0xe, 0x30, 0xda, 0x00, 0x10, 0x0f, 0x61,
 	0x40, 0x07, 0x03,
-	0x00, 0x1a, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x02},
+	0x00, 0x1a, 0x00, 0x00, 0x02, 0x0e, 0x01, 0x00, 0x02},
 };
 
 static struct mipi_dsi_panel_platform_data novatek_pdata = {
@@ -555,6 +585,8 @@
 	.resource = hdmi_msm_resources,
 	.dev.platform_data = &hdmi_msm_data,
 };
+#else
+static int hdmi_panel_power(int on) { return 0; }
 #endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
 
 #ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
@@ -620,19 +652,6 @@
 	.bus_scale_table = &dtv_bus_scale_pdata,
 	.lcdc_power_save = hdmi_panel_power,
 };
-
-static int hdmi_panel_power(int on)
-{
-	int rc;
-
-	pr_debug("%s: HDMI Core: %s\n", __func__, (on ? "ON" : "OFF"));
-	rc = hdmi_core_power(on, 1);
-	if (rc)
-		rc = hdmi_cec_power(on);
-
-	pr_debug("%s: HDMI Core: %s Success\n", __func__, (on ? "ON" : "OFF"));
-	return rc;
-}
 #endif
 
 #ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
@@ -804,12 +823,26 @@
 error:
 	return rc;
 }
+
+static int hdmi_panel_power(int on)
+{
+	int rc;
+
+	pr_debug("%s: HDMI Core: %s\n", __func__, (on ? "ON" : "OFF"));
+	rc = hdmi_core_power(on, 1);
+	if (rc)
+		rc = hdmi_cec_power(on);
+
+	pr_debug("%s: HDMI Core: %s Success\n", __func__, (on ? "ON" : "OFF"));
+	return rc;
+}
 #endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
 
 void __init msm8930_init_fb(void)
 {
 	platform_device_register(&msm_fb_device);
 
+	platform_device_register(&mipi_dsi_NT35590_panel_device);
 #ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
 	platform_device_register(&wfd_panel_device);
 	platform_device_register(&wfd_device);
diff --git a/arch/arm/mach-msm/board-8930-gpiomux.c b/arch/arm/mach-msm/board-8930-gpiomux.c
index 19e7223..53432e1 100644
--- a/arch/arm/mach-msm/board-8930-gpiomux.c
+++ b/arch/arm/mach-msm/board-8930-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -43,6 +43,18 @@
 	.pull = GPIOMUX_PULL_NONE,
 };
 
+static struct gpiomux_setting gsbi9_active_cfg = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting gsbi9_suspended_cfg = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
 static struct gpiomux_setting gsbi5 = {
 	.func = GPIOMUX_FUNC_1,
 	.drv = GPIOMUX_DRV_8MA,
@@ -67,6 +79,21 @@
 	.pull = GPIOMUX_PULL_NONE,
 };
 
+static struct gpiomux_setting external_vfr[] = {
+	/* Suspended state */
+	{
+		.func = GPIOMUX_FUNC_3,
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_KEEPER,
+	},
+	/* Active state */
+	{
+		.func = GPIOMUX_FUNC_3,
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_KEEPER,
+	},
+};
+
 static struct gpiomux_setting cdc_mclk = {
 	.func = GPIOMUX_FUNC_1,
 	.drv = GPIOMUX_DRV_2MA,
@@ -100,6 +127,12 @@
 	.pull = GPIOMUX_PULL_NONE,
 };
 
+static struct gpiomux_setting audio_useuro_switch = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
 #if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
 static struct gpiomux_setting gpio_eth_config = {
 	.pull = GPIOMUX_PULL_NONE,
@@ -161,6 +194,31 @@
 	.drv = GPIOMUX_DRV_2MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
+
+static struct gpiomux_setting synaptic_rmi4_resout_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting synaptic_rmi4_resout_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting synaptic_rmi4_attn_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting synaptic_rmi4_attn_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
 #ifdef MSM8930_PHASE_2
 static struct gpiomux_setting hsusb_sus_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
@@ -281,6 +339,12 @@
 	.dir = GPIOMUX_OUT_LOW,
 };
 
+static struct gpiomux_setting usbsw_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
 #if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
 static struct msm_gpiomux_config msm8960_ethernet_configs[] = {
 	{
@@ -391,6 +455,78 @@
 	},
 };
 
+static struct msm_gpiomux_config msm8930_sglte_gsbi_configs[] __initdata = {
+	/* Add the I2C/SPI GPIOs Here */
+	{
+		.gpio      = 6,		/* GSBI1 TX */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 7,		/* GSBI1 RX */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 8,		/* GSBI1 CTS_N */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 9,		/* GSBI1 RFR_N */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 16,	/* GSBI3 I2C QUP SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
+			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
+		},
+	},
+	{
+		.gpio      = 17,	/* GSBI3 I2C QUP SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
+			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
+		},
+	},
+	{
+		.gpio      = 44,	/* GSBI12 I2C QUP SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi12,
+		},
+	},
+	{
+		.gpio      = 45,	/* GSBI12 I2C QUP SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi12,
+		},
+	},
+	{
+		.gpio      = 73,	/* GSBI10 I2C QUP SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi10,
+		},
+	},
+	{
+		.gpio      = 74,	/* GSBI10 I2C QUP SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi10,
+		},
+	},
+
+};
+
+
 static struct msm_gpiomux_config msm8960_slimbus_config[] __initdata = {
 	{
 		.gpio	= 60,		/* slimbus data */
@@ -422,6 +558,27 @@
 			[GPIOMUX_SUSPENDED] = &audio_mbhc,
 		},
 	},
+	{
+		.gpio = 80,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_useuro_switch,
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_audio_mbhc_configs_sglte[] __initdata = {
+	{
+		.gpio = 50,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_mbhc,
+		},
+	},
+	{
+		.gpio = 66,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_useuro_switch,
+		},
+	},
 };
 
 static struct msm_gpiomux_config msm8960_audio_spkr_configs[] __initdata = {
@@ -433,7 +590,6 @@
 	},
 };
 
-
 static struct msm_gpiomux_config msm8960_audio_auxpcm_configs[] __initdata = {
 	{
 		.gpio = 63,
@@ -527,6 +683,23 @@
 	},
 };
 
+static struct msm_gpiomux_config msm8960_synaptic_rmi4_configs[] __initdata = {
+	{       /* TS INTERRUPT */
+		.gpio = 11,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &synaptic_rmi4_attn_act_cfg,
+			[GPIOMUX_SUSPENDED] = &synaptic_rmi4_attn_sus_cfg,
+		},
+	},
+	{       /* TS RESOUT */
+		.gpio = 52,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &synaptic_rmi4_resout_act_cfg,
+			[GPIOMUX_SUSPENDED] = &synaptic_rmi4_resout_sus_cfg,
+		},
+	},
+};
+
 static struct msm_gpiomux_config hap_lvl_shft_config[] __initdata = {
 	{
 		.gpio = 47,
@@ -695,6 +868,16 @@
 	},
 };
 
+static struct msm_gpiomux_config msm8930_sd_det_config_evt[] __initdata = {
+	{
+		.gpio = 90,	/* SD Card Detect Line */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &sd_det_line,
+			[GPIOMUX_ACTIVE] = &sd_det_line,
+		},
+	},
+};
+
 static struct gpiomux_setting gyro_int_line = {
 	.func = GPIOMUX_FUNC_GPIO,
 	.drv = GPIOMUX_DRV_2MA,
@@ -720,6 +903,146 @@
 	}
 };
 
+static struct msm_gpiomux_config sglte_8930_configs[] __initdata = {
+	/* AP2MDM_STATUS */
+	{
+		.gpio = 77,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+		}
+	},
+	/* MDM2AP_STATUS */
+	{
+		.gpio = 24,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
+		}
+	},
+	/* MDM2AP_ERRFATAL */
+	{
+		.gpio = 40,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mdm2ap_errfatal_cfg,
+		}
+	},
+	/* AP2MDM_ERRFATAL */
+	{
+		.gpio = 80,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+		}
+	},
+	/* AP2MDM_KPDPWR_N */
+	{
+		.gpio = 79,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
+		}
+	},
+	/* AP2MDM_PMIC_PWR_EN */
+	{
+		.gpio = 22,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
+		}
+	},
+	/* AP2MDM_SOFT_RESET */
+	{
+		.gpio = 78,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+		}
+	},
+	/* USB_SW */
+	{
+		.gpio = 25,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &usbsw_cfg,
+		}
+	}
+};
+
+static struct msm_gpiomux_config msm8930_fusion_gsbi_configs[] = {
+	{
+		.gpio = 93,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi9_suspended_cfg,
+			[GPIOMUX_ACTIVE] = &gsbi9_active_cfg,
+		}
+	},
+	{
+		.gpio = 94,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi9_suspended_cfg,
+			[GPIOMUX_ACTIVE] = &gsbi9_active_cfg,
+		}
+	},
+	{
+		.gpio = 95,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi9_suspended_cfg,
+			[GPIOMUX_ACTIVE] = &gsbi9_active_cfg,
+		}
+	},
+	{
+		.gpio = 96,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi9_suspended_cfg,
+			[GPIOMUX_ACTIVE] = &gsbi9_active_cfg,
+		}
+	},
+};
+
+static struct msm_gpiomux_config msm8930_external_vfr_configs[] __initdata = {
+	{
+		.gpio      = 23,        /* EXTERNAL VFR */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &external_vfr[0],
+			[GPIOMUX_ACTIVE] = &external_vfr[1],
+		},
+	},
+};
+
+int __init sglte8930_init_gpiomux(void)
+{
+	/* For 8960 Fusion 2.2 Primary IPC */
+	msm_gpiomux_install(msm8930_fusion_gsbi_configs,
+			ARRAY_SIZE(msm8930_fusion_gsbi_configs));
+	/* For SGLTE 8960 Fusion External VFR */
+	msm_gpiomux_install(msm8930_external_vfr_configs,
+			ARRAY_SIZE(msm8930_external_vfr_configs));
+	msm_gpiomux_install(sglte_8930_configs,
+			ARRAY_SIZE(sglte_8930_configs));
+
+	msm_gpiomux_install(msm8930_sglte_gsbi_configs,
+			ARRAY_SIZE(msm8930_sglte_gsbi_configs));
+
+	msm_gpiomux_install(msm8960_slimbus_config,
+			ARRAY_SIZE(msm8960_slimbus_config));
+
+	msm_gpiomux_install(msm8960_audio_codec_configs,
+			ARRAY_SIZE(msm8960_audio_codec_configs));
+
+	msm_gpiomux_install(wcnss_5wire_interface,
+			ARRAY_SIZE(wcnss_5wire_interface));
+
+	msm_gpiomux_install(msm8960_mdp_vsync_configs,
+			ARRAY_SIZE(msm8960_mdp_vsync_configs));
+
+	msm_gpiomux_install(msm_sitar_config, ARRAY_SIZE(msm_sitar_config));
+
+	msm_gpiomux_install(msm8960_synaptic_rmi4_configs,
+			ARRAY_SIZE(msm8960_synaptic_rmi4_configs));
+
+	msm_gpiomux_install(msm8930_sd_det_config_evt,
+			ARRAY_SIZE(msm8930_sd_det_config_evt));
+
+	msm_gpiomux_install(msm8960_audio_mbhc_configs_sglte,
+			ARRAY_SIZE(msm8960_audio_mbhc_configs_sglte));
+
+	return 0;
+}
+
 int __init msm8930_init_gpiomux(void)
 {
 	int rc = msm_gpiomux_init(NR_GPIO_IRQS);
@@ -728,6 +1051,9 @@
 		return rc;
 	}
 
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
+		return sglte8930_init_gpiomux();
+
 #if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
 	msm_gpiomux_install(msm8960_ethernet_configs,
 			ARRAY_SIZE(msm8960_ethernet_configs));
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index f3436ac..06e4ce4 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -340,6 +340,12 @@
 	.rconn_mohm		= 18,
 };
 
+static struct pm8xxx_vibrator_platform_data pm8038_vib_pdata = {
+	.initial_vibrate_ms = 500,
+	.level_mV = 3000,
+	.max_timeout_ms = 15000,
+};
+
 #define PM8038_WLED_MAX_CURRENT		25
 #define PM8XXX_LED_PWM_PERIOD		1000
 #define PM8XXX_LED_PWM_DUTY_MS		20
@@ -476,6 +482,11 @@
 	.rconn_mohm			= 18,
 	.normal_voltage_calc_ms		= 20000,
 	.low_voltage_calc_ms		= 1000,
+	.alarm_low_mv			= 3400,
+	.alarm_high_mv			= 4000,
+	.high_ocv_correction_limit_uv	= 50,
+	.low_ocv_correction_limit_uv	= 100,
+	.hold_soc_est			= 3,
 };
 
 static struct pm8038_platform_data pm8038_platform_data __devinitdata = {
@@ -585,6 +596,9 @@
 			pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
 		else if (machine_is_msm8930_cdp())
 			pm8921_chg_pdata.has_dc_supply = true;
+		if (machine_is_msm8930_evt())
+			pm8038_platform_data.vibrator_pdata =
+				&pm8038_vib_pdata;
 	} else {
 		/* PM8917 configuration */
 		pmic_reset_irq = PM8917_IRQ_BASE + PM8921_RESOUT_IRQ;
diff --git a/arch/arm/mach-msm/board-8930-regulator-pm8038.c b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
index b14d74c..0ecb030 100644
--- a/arch/arm/mach-msm/board-8930-regulator-pm8038.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -35,6 +35,7 @@
 	REGULATOR_SUPPLY("8038_l2",		NULL),
 	REGULATOR_SUPPLY("iris_vdddig",		"wcnss_wlan.0"),
 	REGULATOR_SUPPLY("dsi_vdda",		"mipi_dsi.1"),
+	REGULATOR_SUPPLY("dsi_pll_vdda",	"mdp.0"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_csid.0"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_csid.1"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_csid.2"),
@@ -67,6 +68,7 @@
 	REGULATOR_SUPPLY("8038_l9",		NULL),
 	REGULATOR_SUPPLY("vdd_ana",		"3-004a"),
 	REGULATOR_SUPPLY("vdd",			"3-0024"),
+	REGULATOR_SUPPLY("vdd",			"3-0020"),
 	REGULATOR_SUPPLY("cam_vana",		"4-001a"),
 	REGULATOR_SUPPLY("cam_vana",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vana",		"4-0048"),
@@ -75,8 +77,22 @@
 	REGULATOR_SUPPLY("cam_vaf",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vana",            "4-0020"),
 	REGULATOR_SUPPLY("cam_vaf",             "4-0020"),
+/* Regulators for 8930 QRD SGLTE EVT */
+	REGULATOR_SUPPLY("cam_vana",		"8-001a"),
+	REGULATOR_SUPPLY("cam_vana",		"8-006c"),
+	REGULATOR_SUPPLY("cam_vana",		"8-0048"),
+	REGULATOR_SUPPLY("cam_vana",		"8-0020"),
+	REGULATOR_SUPPLY("cam_vana",		"8-0036"),
+	REGULATOR_SUPPLY("cam_vana",		"8-0010"),
+	REGULATOR_SUPPLY("cam_vaf",		"8-001a"),
+	REGULATOR_SUPPLY("cam_vaf",		"8-006c"),
+	REGULATOR_SUPPLY("cam_vaf",		"8-0048"),
+	REGULATOR_SUPPLY("cam_vaf",		"8-0020"),
+	REGULATOR_SUPPLY("cam_vaf",		"8-0036"),
+	REGULATOR_SUPPLY("cam_vaf",		"8-0010"),
 	REGULATOR_SUPPLY("vdd",			"12-0018"),
 	REGULATOR_SUPPLY("vdd",			"12-0068"),
+	REGULATOR_SUPPLY("CDC_VDDA_A_L9_2P85V",	"sitar1p1-slim"),
 };
 VREG_CONSUMERS(L10) = {
 	REGULATOR_SUPPLY("8038_l10",		NULL),
@@ -102,7 +118,14 @@
 	REGULATOR_SUPPLY("cam_vdig",		"4-001a"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-0048"),
-	REGULATOR_SUPPLY("cam_vdig",            "4-0020"),
+	REGULATOR_SUPPLY("cam_vdig",		"4-0020"),
+/* Regulators for 8930 QRD SGLTE EVT */
+	REGULATOR_SUPPLY("cam_vdig",		"8-001a"),
+	REGULATOR_SUPPLY("cam_vdig",		"8-006c"),
+	REGULATOR_SUPPLY("cam_vdig",		"8-0048"),
+	REGULATOR_SUPPLY("cam_vdig",		"8-0020"),
+	REGULATOR_SUPPLY("cam_vdig",		"8-0036"),
+	REGULATOR_SUPPLY("cam_vdig",		"8-0010"),
 };
 VREG_CONSUMERS(L13) = {
 	REGULATOR_SUPPLY("8038_l13",		NULL),
@@ -146,6 +169,7 @@
 VREG_CONSUMERS(L23) = {
 	REGULATOR_SUPPLY("8038_l23",		NULL),
 	REGULATOR_SUPPLY("dsi_vddio",		"mipi_dsi.1"),
+	REGULATOR_SUPPLY("dsi_pll_vddio",	"mdp.0"),
 	REGULATOR_SUPPLY("hdmi_avdd",		"hdmi_msm.0"),
 	REGULATOR_SUPPLY("hdmi_vcc",		"hdmi_msm.0"),
 	REGULATOR_SUPPLY("pll_vdd",		"pil_riva"),
@@ -200,12 +224,20 @@
 	REGULATOR_SUPPLY("cam_vio",		"4-001a"),
 	REGULATOR_SUPPLY("cam_vio",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vio",		"4-0048"),
-	REGULATOR_SUPPLY("cam_vio",             "4-0020"),
+	REGULATOR_SUPPLY("cam_vio",		"4-0020"),
+/* Regulators for 8930 QRD SGLTE EVT */
+	REGULATOR_SUPPLY("cam_vio",		"8-001a"),
+	REGULATOR_SUPPLY("cam_vio",		"8-006c"),
+	REGULATOR_SUPPLY("cam_vio",		"8-0048"),
+	REGULATOR_SUPPLY("cam_vio",		"8-0020"),
+	REGULATOR_SUPPLY("cam_vio",		"8-0036"),
+	REGULATOR_SUPPLY("cam_vio",		"8-0010"),
 };
 VREG_CONSUMERS(LVS2) = {
 	REGULATOR_SUPPLY("8038_lvs2",		NULL),
 	REGULATOR_SUPPLY("vcc_i2c",		"3-004a"),
 	REGULATOR_SUPPLY("vcc_i2c",		"3-0024"),
+	REGULATOR_SUPPLY("vcc_i2c",		"3-0020"),
 	REGULATOR_SUPPLY("vcc_i2c",		"0-0048"),
 	REGULATOR_SUPPLY("vddio",		"12-0018"),
 	REGULATOR_SUPPLY("vlogic",		"12-0068"),
@@ -504,7 +536,7 @@
 	RPM_LDO(L9,	 0, 1, 0, 2850000, 2850000, NULL,      0, 0),
 	RPM_LDO(L10,	 0, 1, 0, 2900000, 2900000, NULL,      0, 0),
 	RPM_LDO(L11,	 1, 1, 0, 1800000, 1800000, "8038_s4", 10000, 10000),
-	RPM_LDO(L12,	 0, 1, 0, 1200000, 1200000, "8038_s2", 0, 0),
+	RPM_LDO(L12,	 0, 1, 0, 1200000, 1500000, "8038_s2", 0, 0),
 	RPM_LDO(L13,	 0, 0, 0, 2220000, 2220000, NULL,      0, 0),
 	RPM_LDO(L14,	 0, 1, 0, 1800000, 1800000, NULL,      0, 0),
 	RPM_LDO(L15,	 0, 1, 0, 1800000, 2950000, NULL,      0, 0),
diff --git a/arch/arm/mach-msm/board-8930-regulator-pm8917.c b/arch/arm/mach-msm/board-8930-regulator-pm8917.c
index 75e73a2..f9b6b01 100644
--- a/arch/arm/mach-msm/board-8930-regulator-pm8917.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8917.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index 57c884a..a72f69f 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -63,11 +63,9 @@
 		 * hardware revisions - maybe once that is done, this can be
 		 * reverted.
 		 */
-		.always_on = 1,
 		.lpm_sup = 1,
 		.hpm_uA = 800000, /* 800mA */
 		.lpm_uA = 9000,
-		.reset_at_init = true,
 	},
 };
 
@@ -312,19 +310,22 @@
 	 * This change to the boards will be true for newer versions of the SoC
 	 * as well.
 	 */
-	if ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 1 &&
-			SOCINFO_VERSION_MINOR(socinfo_get_version()) >= 2) ||
-			machine_is_msm8930_cdp()) {
-		msm8960_sdc3_data.vreg_data->vdd_data->always_on = false;
-		msm8960_sdc3_data.vreg_data->vdd_data->reset_at_init = false;
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1 &&
+			SOCINFO_VERSION_MINOR(socinfo_get_version()) < 2) {
+		msm8960_sdc3_data.vreg_data->vdd_data->always_on = true;
+		msm8960_sdc3_data.vreg_data->vdd_data->reset_at_init = true;
 	}
-
 	/* SDC3: External card slot */
 	if (!machine_is_msm8930_cdp()) {
 		msm8960_sdc3_data.wpswitch_gpio = 0;
 		msm8960_sdc3_data.is_wpswitch_active_low = false;
 	}
 
+	if (machine_is_msm8930_evt()) {
+		msm8960_sdc3_data.status_gpio = 90;
+		msm8960_sdc3_data.status_irq = MSM_GPIO_TO_INT(90);
+	}
+
 	msm_add_sdcc(3, &msm8960_sdc3_data);
 #endif
 }
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index e7ea95f..a14050f 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -43,6 +43,7 @@
 #include <linux/memory.h>
 #include <linux/memblock.h>
 #include <linux/msm_thermal.h>
+#include <linux/input/synaptics_dsx.h>
 
 #include <linux/slimbus/slimbus.h>
 #include <linux/mfd/wcd9xxx/core.h>
@@ -74,6 +75,7 @@
 #include <mach/msm_bus_board.h>
 #include <mach/msm_memtypes.h>
 #include <mach/dma.h>
+#include <mach/msm_serial_hs.h>
 #include <mach/msm_xo.h>
 #include <mach/restart.h>
 
@@ -584,7 +586,7 @@
 
 			if (fixed_position != NOT_FIXED)
 				fixed_size += heap->size;
-			else
+			else if (!use_cma)
 				reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
 
 			if (fixed_position == FIXED_LOW) {
@@ -734,64 +736,9 @@
 	.paddr_to_memtype = msm8930_paddr_to_memtype,
 };
 
-static int msm8930_memory_bank_size(void)
-{
-	return 1<<29;
-}
-
-static void __init locate_unstable_memory(void)
-{
-	struct membank *mb = &meminfo.bank[meminfo.nr_banks - 1];
-	unsigned long bank_size;
-	unsigned long low, high;
-
-	bank_size = msm8930_memory_bank_size();
-	low = meminfo.bank[0].start;
-	high = mb->start + mb->size;
-
-	/* Check if 32 bit overflow occured */
-	if (high < mb->start)
-		high -= PAGE_SIZE;
-
-	if (high < MAX_FIXED_AREA_SIZE + MSM8930_FIXED_AREA_START)
-		panic("fixed area extends beyond end of memory\n");
-
-	low &= ~(bank_size - 1);
-
-	if (high - low <= bank_size)
-		goto no_dmm;
-
-	msm8930_reserve_info.bank_size = bank_size;
-#ifdef CONFIG_ENABLE_DMM
-	msm8930_reserve_info.low_unstable_address = mb->start -
-					MIN_MEMORY_BLOCK_SIZE + mb->size;
-	msm8930_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
-	pr_info("low unstable address %lx max size %lx bank size %lx\n",
-		msm8930_reserve_info.low_unstable_address,
-		msm8930_reserve_info.max_unstable_size,
-		msm8930_reserve_info.bank_size);
-	return;
-#endif
-no_dmm:
-	msm8930_reserve_info.low_unstable_address = high;
-	msm8930_reserve_info.max_unstable_size = 0;
-}
-
-static void __init place_movable_zone(void)
-{
-#ifdef CONFIG_ENABLE_DMM
-	movable_reserved_start = msm8930_reserve_info.low_unstable_address;
-	movable_reserved_size = msm8930_reserve_info.max_unstable_size;
-	pr_info("movable zone start %lx size %lx\n",
-		movable_reserved_start, movable_reserved_size);
-#endif
-}
-
 static void __init msm8930_early_memory(void)
 {
 	reserve_info = &msm8930_reserve_info;
-	locate_unstable_memory();
-	place_movable_zone();
 }
 
 static void __init msm8930_reserve(void)
@@ -799,12 +746,6 @@
 	msm_reserve();
 }
 
-static int msm8930_change_memory_power(u64 start, u64 size,
-	int change_type)
-{
-	return soc_change_memory_power(start, size, change_type);
-}
-
 static void __init msm8930_allocate_memory_regions(void)
 {
 	msm8930_allocate_fb_region();
@@ -844,7 +785,7 @@
 	.regulator = {
 	{
 		.name = "CDC_VDD_CP",
-		.min_uV = 1800000,
+		.min_uV = 2200000,
 		.max_uV = 2200000,
 		.optimum_uA = WCD9XXX_CDC_VDDA_CP_CUR_MAX,
 	},
@@ -910,7 +851,7 @@
 	.regulator = {
 	{
 		.name = "CDC_VDD_CP",
-		.min_uV = 1800000,
+		.min_uV = 2200000,
 		.max_uV = 2200000,
 		.optimum_uA = WCD9XXX_CDC_VDDA_CP_CUR_MAX,
 	},
@@ -1355,6 +1296,16 @@
 	},
 };
 
+static struct mdm_platform_data sglte_platform_data = {
+	.mdm_version = "4.0",
+	.ramdump_delay_ms = 1000,
+	.soft_reset_inverted = 1,
+	.peripheral_platform_device = NULL,
+	.ramdump_timeout_ms = 600000,
+	.no_powerdown_after_ramdumps = 1,
+	.image_upgrade_supported = 1,
+};
+
 static struct platform_device *mdm_devices[] __initdata = {
 	&mdm_device,
 };
@@ -1646,11 +1597,18 @@
 	0x03, 0x0f,
 };
 
+
 static uint8_t spm_retention_cmd_sequence[] __initdata = {
 	0x00, 0x05, 0x03, 0x0D,
 	0x0B, 0x00, 0x0f,
 };
 
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+	0x42, 0x1B, 0x00,
+	0x05, 0x03, 0x0D, 0x0B,
+	0x00, 0x42, 0x1B,
+	0x0f,
+};
 static uint8_t spm_power_collapse_without_rpm[] __initdata = {
 	0x00, 0x24, 0x54, 0x10,
 	0x09, 0x03, 0x01,
@@ -1695,11 +1653,16 @@
 		.cmd = spm_wfi_cmd_sequence,
 	},
 	[1] = {
+		.mode = MSM_SPM_MODE_POWER_RETENTION,
+		.notify_rpm = false,
+		.cmd = spm_retention_cmd_sequence,
+	},
+	[2] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = false,
 		.cmd = spm_power_collapse_without_rpm,
 	},
-	[2] = {
+	[3] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = true,
 		.cmd = spm_power_collapse_with_rpm,
@@ -1730,9 +1693,9 @@
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
 #endif
 		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020204,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x03020004,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0084009C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A4001C,
 		.vctl_timeout_us = 50,
 		.num_modes = ARRAY_SIZE(msm_spm_nonboot_cpu_seq_list),
 		.modes = msm_spm_nonboot_cpu_seq_list,
@@ -2083,6 +2046,37 @@
 	},
 };
 
+/*»     Synaptics Thin Driver»  */
+
+#define CLEARPAD3202_ADDR 0x20
+#define CLEARPAD3202_ATTEN_GPIO (11)
+#define CLEARPAD3202_RESET_GPIO (52)
+
+static unsigned char synaptic_rmi4_button_codes[] = {KEY_MENU, KEY_HOME,
+							KEY_BACK};
+
+static struct synaptics_rmi4_capacitance_button_map synaptic_rmi4_button_map = {
+	.nbuttons = ARRAY_SIZE(synaptic_rmi4_button_codes),
+	.map = synaptic_rmi4_button_codes,
+};
+
+static struct synaptics_rmi4_platform_data rmi4_platformdata = {
+	.irq_flags = IRQF_TRIGGER_FALLING,
+	.irq_gpio = CLEARPAD3202_ATTEN_GPIO,
+	.reset_gpio = CLEARPAD3202_RESET_GPIO,
+	.regulator_en = true,
+	.i2c_pull_up = true,
+	.capacitance_button_map = &synaptic_rmi4_button_map,
+};
+
+static struct i2c_board_info rmi4_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("synaptics_rmi4_i2c",
+		CLEARPAD3202_ADDR),
+		.platform_data = &rmi4_platformdata,
+	},
+};
+
 #define MHL_POWER_GPIO_PM8038	PM8038_GPIO_PM_TO_SYS(MHL_GPIO_PWR_EN)
 #define MHL_POWER_GPIO_PM8917	PM8917_GPIO_PM_TO_SYS(25)
 static struct msm_mhl_platform_data mhl_platform_data = {
@@ -2221,6 +2215,11 @@
 	.src_clk_rate = 24000000,
 };
 
+
+static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi8_pdata = {
+	.clk_freq = 100000,
+	.src_clk_rate = 24000000,
+};
 static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi9_pdata = {
 	.clk_freq = 100000,
 	.src_clk_rate = 24000000,
@@ -2384,6 +2383,15 @@
 	&msm8960_device_ssbi_pmic,
 };
 
+static struct platform_device *i2c_qup_devices[] __initdata = {
+	&msm8960_device_qup_i2c_gsbi4,
+	&msm8960_device_qup_i2c_gsbi9,
+};
+
+static struct platform_device *i2c_qup_sglte_devices[] __initdata = {
+	&msm8960_device_qup_i2c_gsbi8,
+};
+
 static struct platform_device *common_devices[] __initdata = {
 	&msm_8960_q6_lpass,
 	&msm_8960_q6_mss_fw,
@@ -2393,8 +2401,6 @@
 	&msm_pil_vidc,
 	&msm8960_device_qup_spi_gsbi1,
 	&msm8960_device_qup_i2c_gsbi3,
-	&msm8960_device_qup_i2c_gsbi4,
-	&msm8960_device_qup_i2c_gsbi9,
 	&msm8960_device_qup_i2c_gsbi10,
 	&msm8960_device_qup_i2c_gsbi12,
 	&msm_slim_ctrl,
@@ -2510,8 +2516,11 @@
 
 	msm8960_device_qup_i2c_gsbi3.dev.platform_data =
 					&msm8960_i2c_qup_gsbi3_pdata;
-
-	msm8960_device_qup_i2c_gsbi9.dev.platform_data =
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
+		msm8960_device_qup_i2c_gsbi8.dev.platform_data =
+					&msm8960_i2c_qup_gsbi8_pdata;
+	else
+		msm8960_device_qup_i2c_gsbi9.dev.platform_data =
 					&msm8960_i2c_qup_gsbi9_pdata;
 
 	msm8960_device_qup_i2c_gsbi10.dev.platform_data =
@@ -2651,6 +2660,7 @@
 #define I2C_SIM  (1 << 3)
 #define I2C_FLUID (1 << 4)
 #define I2C_LIQUID (1 << 5)
+#define I2C_EVT (1 << 6)
 
 struct i2c_registry {
 	u8                     machs;
@@ -2720,10 +2730,18 @@
 };
 #endif /* CONFIG_STM_LIS3DH */
 
+#ifdef CONFIG_BMP18X_I2C
+static struct i2c_board_info __initdata bmp18x_i2c_boardinfo[] = {
+	{
+		I2C_BOARD_INFO("bmp18x", 0x77),
+	},
+};
+#endif
+
 static struct i2c_registry msm8960_i2c_devices[] __initdata = {
 #ifdef CONFIG_ISL9519_CHARGER
 	{
-		I2C_LIQUID,
+		I2C_LIQUID | I2C_EVT,
 		MSM_8930_GSBI10_QUP_I2C_BUS_ID,
 		isl_charger_i2c_info,
 		ARRAY_SIZE(isl_charger_i2c_info),
@@ -2731,7 +2749,7 @@
 #endif /* CONFIG_ISL9519_CHARGER */
 #ifdef CONFIG_INPUT_MPU3050
 	{
-		I2C_FFA | I2C_FLUID,
+		I2C_FFA | I2C_FLUID | I2C_EVT,
 		MSM_8930_GSBI12_QUP_I2C_BUS_ID,
 		mpu3050_i2c_boardinfo,
 		ARRAY_SIZE(mpu3050_i2c_boardinfo),
@@ -2744,12 +2762,18 @@
 		ARRAY_SIZE(msm_isa1200_board_info),
 	},
 	{
-		I2C_SURF | I2C_FFA | I2C_FLUID,
+		I2C_SURF | I2C_FFA | I2C_FLUID | I2C_EVT,
 		MSM_8930_GSBI3_QUP_I2C_BUS_ID,
 		mxt_device_info_8930,
 		ARRAY_SIZE(mxt_device_info_8930),
 	},
 	{
+		I2C_EVT,
+		MSM_8930_GSBI3_QUP_I2C_BUS_ID,
+		rmi4_i2c_devices,
+		ARRAY_SIZE(rmi4_i2c_devices),
+	},
+	{
 		I2C_SURF | I2C_FFA | I2C_LIQUID | I2C_FLUID,
 		MSM_8930_GSBI9_QUP_I2C_BUS_ID,
 		sii_device_info,
@@ -2757,12 +2781,22 @@
 	},
 #ifdef CONFIG_STM_LIS3DH
 	{
-		I2C_FFA | I2C_FLUID,
+		I2C_FFA | I2C_FLUID | I2C_EVT,
 		MSM_8930_GSBI12_QUP_I2C_BUS_ID,
 		lis3dh_i2c_boardinfo,
 		ARRAY_SIZE(lis3dh_i2c_boardinfo),
 	},
 #endif
+#ifdef CONFIG_BMP18X_I2C
+	{
+		I2C_FFA | I2C_FLUID | I2C_EVT,
+		MSM_8930_GSBI12_QUP_I2C_BUS_ID,
+		bmp18x_i2c_boardinfo,
+		ARRAY_SIZE(bmp18x_i2c_boardinfo),
+	},
+#endif
+
+
 };
 #endif /* CONFIG_I2C */
 
@@ -2773,11 +2807,17 @@
 	int i;
 #ifdef CONFIG_MSM_CAMERA
 	struct i2c_registry msm8930_camera_i2c_devices = {
-		I2C_SURF | I2C_FFA | I2C_FLUID | I2C_LIQUID | I2C_RUMI,
+		I2C_SURF | I2C_FFA | I2C_FLUID | I2C_LIQUID | I2C_RUMI
+			| I2C_EVT,
 		MSM_8930_GSBI4_QUP_I2C_BUS_ID,
 		msm8930_camera_board_info.board_info,
 		msm8930_camera_board_info.num_i2c_board_info,
 	};
+	if (machine_is_msm8930_evt() &&
+		(socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)) {
+		msm8930_camera_i2c_devices.machs |= I2C_EVT;
+		msm8930_camera_i2c_devices.bus = MSM_8930_GSBI8_QUP_I2C_BUS_ID;
+	}
 #endif
 
 	/* Build the matching 'supported_machs' bitmask */
@@ -2787,6 +2827,8 @@
 		mach_mask = I2C_FLUID;
 	else if (machine_is_msm8930_mtp() || machine_is_msm8627_mtp())
 		mach_mask = I2C_FFA;
+	else if (machine_is_msm8930_evt())
+		mach_mask = I2C_EVT;
 	else
 		pr_err("unmatched machine ID in register_i2c_devices\n");
 
@@ -2806,11 +2848,34 @@
 #endif
 }
 
+/*Modify the WCD9xxx platform data to support supplies from PM8917 */
+static void __init msm8930_pm8917_wcd9xxx_pdata_fixup(
+		struct wcd9xxx_pdata *cdc_pdata)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(cdc_pdata->regulator); i++) {
+
+		if (cdc_pdata->regulator[i].name != NULL
+			&& strncmp(cdc_pdata->regulator[i].name,
+				"CDC_VDD_CP", 10) == 0) {
+			cdc_pdata->regulator[i].min_uV =
+				cdc_pdata->regulator[i].max_uV = 1800000;
+			pr_info("%s: CDC_VDD_CP forced to 1.8 volts for PM8917\n",
+				__func__);
+			return;
+		}
+	}
+}
+
 /* Modify platform data values to match requirements for PM8917. */
 static void __init msm8930_pm8917_pdata_fixup(void)
 {
 	struct acpuclk_platform_data *pdata;
 
+	msm8930_pm8917_wcd9xxx_pdata_fixup(&sitar_platform_data);
+	msm8930_pm8917_wcd9xxx_pdata_fixup(&sitar1p1_platform_data);
+
 	mhl_platform_data.gpio_mhl_power = MHL_POWER_GPIO_PM8917;
 
 	gpio_keys_8930_pdata.buttons = keys_8930_pm8917;
@@ -2831,8 +2896,39 @@
 	pdata->uses_pm8917 = true;
 }
 
+static void __init msm8930ab_update_retention_spm(void)
+{
+	int i;
+
+	/* Update the SPM sequences for krait retention on all cores */
+	for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+		int j;
+		struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+		for (j = 0; j < pdata->num_modes; j++) {
+			if (pdata->modes[j].cmd ==
+					spm_retention_cmd_sequence)
+				pdata->modes[j].cmd =
+				spm_retention_with_krait_v3_cmd_sequence;
+		}
+	}
+}
+
+#ifdef CONFIG_SERIAL_MSM_HS
+static struct msm_serial_hs_platform_data msm_uart_dm9_pdata = {
+	.config_gpio	= 4,
+	.uart_tx_gpio	= 93,
+	.uart_rx_gpio	= 94,
+	.uart_cts_gpio	= 95,
+	.uart_rfr_gpio	= 96,
+};
+#else
+static struct msm_serial_hs_platform_data msm_uart_dm9_pdata;
+#endif
+
+
 static void __init msm8930_cdp_init(void)
 {
+	int i, reg_size = 0;
 	if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
 		msm8930_pm8917_pdata_fixup();
 	if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
@@ -2878,6 +2974,15 @@
 				PM8038_USB_ID_IN_IRQ(PM8038_IRQ_BASE);
 	}
 
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE &&
+						machine_is_msm8930_evt()) {
+#ifdef CONFIG_SERIAL_MSM_HS
+		msm_uart_dm9_pdata.wakeup_irq = gpio_to_irq(94); /* GSBI9(2) */
+		msm_device_uart_dm9.dev.platform_data = &msm_uart_dm9_pdata;
+#endif
+		platform_device_register(&msm_device_uart_dm9);
+	}
+
 	msm_otg_pdata.phy_init_seq = hsusb_phy_init_seq;
 	msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
 	android_usb_pdata.swfi_latency =
@@ -2899,6 +3004,12 @@
 #endif
 	msm8930_i2c_init();
 	msm8930_init_gpu();
+	if (cpu_is_krait_v3()) {
+		msm_pm_set_tz_retention_flag(0);
+		msm8930ab_update_retention_spm();
+	} else {
+		msm_pm_set_tz_retention_flag(1);
+	}
 	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
 	msm_spm_l2_init(msm_spm_l2_data);
 	msm8930_init_buses();
@@ -2929,7 +3040,28 @@
 	else
 		platform_add_devices(pmic_pm8917_devices,
 					ARRAY_SIZE(pmic_pm8917_devices));
+
+	if (machine_is_msm8930_evt()) {
+	        /* It is QRD Device, clock should be set appropraitely */
+		if ((SOCINFO_VERSION_MAJOR(socinfo_get_platform_version()) == 1)
+		&& (SOCINFO_VERSION_MINOR(socinfo_get_platform_version()) == 1))
+			/* For evt2a, which supports 48 MHz */
+			qcom_wcnss_pdata.has_48mhz_xo = 1;
+		else
+			/* Assuming all other versions do not support 48MHz */
+			qcom_wcnss_pdata.has_48mhz_xo = 0;
+	}
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+	if (machine_is_msm8930_evt() &&
+		(socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)) {
+		/* Removing GSBI4 and GSBI9 and initializing GSBI8
+		 * as per SGLTE platform requirement */
+		platform_add_devices(i2c_qup_sglte_devices,
+					ARRAY_SIZE(i2c_qup_sglte_devices));
+	} else {
+		platform_add_devices(i2c_qup_devices,
+					ARRAY_SIZE(i2c_qup_devices));
+	}
 	msm8930_add_vidc_device();
 	/*
 	 * TODO: When physical 8930/PM8038 hardware becomes
@@ -2949,14 +3081,41 @@
 	msm8930_init_cam();
 #endif
 	msm8930_init_mmc();
-	mxt_init_vkeys_8930();
+	if (!machine_is_msm8930_evt())
+		mxt_init_vkeys_8930();
 	register_i2c_devices();
 	msm8930_init_fb();
+
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE) {
+		reg_size = ARRAY_SIZE((
+			(struct wcd9xxx_pdata *)msm_slim_devices[1].
+			slim_slave->dev.platform_data)->regulator);
+
+		for (i = 0; i < reg_size; i++) {
+			if (!(((struct wcd9xxx_pdata *)msm_slim_devices[1].
+				slim_slave->dev.platform_data)->
+				regulator[i].name))
+				break;
+		}
+
+		((struct wcd9xxx_pdata *)msm_slim_devices[1].slim_slave->dev.
+			platform_data)->regulator[i].name =
+							"CDC_VDDA_A_L9_2P85V";
+		((struct wcd9xxx_pdata *)msm_slim_devices[1].slim_slave->dev.
+				platform_data)->regulator[i].min_uV = 2850000;
+		((struct wcd9xxx_pdata *)msm_slim_devices[1].slim_slave->dev.
+				platform_data)->regulator[i].max_uV = 2850000;
+		((struct wcd9xxx_pdata *)msm_slim_devices[1].slim_slave->dev.
+			platform_data)->regulator[i].optimum_uA = 300000;
+	}
 	slim_register_board_info(msm_slim_devices,
 		ARRAY_SIZE(msm_slim_devices));
-	change_memory_power = &msm8930_change_memory_power;
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
-	msm_pm_set_tz_retention_flag(1);
+
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE) {
+		mdm_sglte_device.dev.platform_data = &sglte_platform_data;
+		platform_device_register(&mdm_sglte_device);
+	}
 
 	if (PLATFORM_IS_CHARM25())
 		platform_add_devices(mdm_devices, ARRAY_SIZE(mdm_devices));
@@ -3021,3 +3180,15 @@
 	.init_very_early = msm8930_early_memory,
 	.restart = msm_restart,
 MACHINE_END
+
+MACHINE_START(MSM8930_EVT, "QRD8930 SGLTE EVT")
+	.map_io = msm8930_map_io,
+	.reserve = msm8930_reserve,
+	.init_irq = msm8930_init_irq,
+	.handle_irq = gic_handle_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8930_cdp_init,
+	.init_early = msm8930_allocate_memory_regions,
+	.init_very_early = msm8930_early_memory,
+	.restart = msm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index 7c1ad5b..cb9398c 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -158,6 +158,7 @@
 
 #define MSM_8930_GSBI3_QUP_I2C_BUS_ID 3
 #define MSM_8930_GSBI4_QUP_I2C_BUS_ID 4
+#define MSM_8930_GSBI8_QUP_I2C_BUS_ID 8
 #define MSM_8930_GSBI9_QUP_I2C_BUS_ID 0
 #define MSM_8930_GSBI10_QUP_I2C_BUS_ID 10
 #define MSM_8930_GSBI12_QUP_I2C_BUS_ID 12
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 31a99e7..935ccaf 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -769,6 +769,34 @@
 	.eeprom_info = &imx091_eeprom_info,
 };
 
+static struct msm_camera_sensor_flash_data flash_imx135 = {
+	.flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_csi_lane_params imx135_csi_lane_params = {
+	.csi_lane_assign = 0xE4,
+	.csi_lane_mask = 0xF,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_imx135 = {
+	.mount_angle = 90,
+	.cam_vreg = msm_8960_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8960_cam_vreg),
+	.gpio_conf = &msm_8960_back_cam_gpio_conf,
+	.csi_lane_params = &imx135_csi_lane_params,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_imx135_data = {
+	.sensor_name = "imx135",
+	.pdata = &msm_camera_csi_device_data[0],
+	.flash_data = &flash_imx135,
+	.sensor_platform_info = &sensor_board_info_imx135,
+	.csi_if = 1,
+	.camera_type = BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
+	.actuator_info = &msm_act_main_cam_1_info,
+};
+
 static struct pm8xxx_mpp_config_data privacy_light_on_config = {
 	.type		= PM8XXX_MPP_TYPE_SINK,
 	.level		= PM8XXX_MPP_CS_OUT_5MA,
@@ -863,6 +891,10 @@
 	.platform_data = &msm_camera_sensor_imx074_data,
 	},
 	{
+	I2C_BOARD_INFO("imx135", 0x10),
+	.platform_data = &msm_camera_sensor_imx135_data,
+	},
+	{
 	I2C_BOARD_INFO("ov2720", 0x6C),
 	.platform_data = &msm_camera_sensor_ov2720_data,
 	},
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index 75ae5ce..e28b451 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -576,6 +576,9 @@
 static struct msm_panel_common_pdata mdp_pdata = {
 	.gpio = MDP_VSYNC_GPIO,
 	.mdp_max_clk = 200000000,
+	.mdp_max_bw = 2000000000,
+	.mdp_bw_ab_factor = 115,
+	.mdp_bw_ib_factor = 125,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
 #endif
@@ -586,6 +589,8 @@
 	.mem_hid = MEMTYPE_EBI1,
 #endif
 	.cont_splash_enabled = 0x01,
+	.splash_screen_addr = 0x00,
+	.splash_screen_size = 0x00,
 	.mdp_iommu_split_domain = 0,
 };
 
@@ -718,6 +723,8 @@
 	.resource = hdmi_msm_resources,
 	.dev.platform_data = &hdmi_msm_data,
 };
+#else
+static int hdmi_panel_power(int on) { return 0; }
 #endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
 
 #ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
@@ -772,19 +779,6 @@
 	.bus_scale_table = &dtv_bus_scale_pdata,
 	.lcdc_power_save = hdmi_panel_power,
 };
-
-static int hdmi_panel_power(int on)
-{
-	int rc;
-
-	pr_debug("%s: HDMI Core: %s\n", __func__, (on ? "ON" : "OFF"));
-	rc = hdmi_core_power(on, 1);
-	if (rc)
-		rc = hdmi_cec_power(on);
-
-	pr_debug("%s: HDMI Core: %s Success\n", __func__, (on ? "ON" : "OFF"));
-	return rc;
-}
 #endif
 
 #ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
@@ -982,6 +976,19 @@
 error:
 	return rc;
 }
+
+static int hdmi_panel_power(int on)
+{
+	int rc;
+
+	pr_debug("%s: HDMI Core: %s\n", __func__, (on ? "ON" : "OFF"));
+	rc = hdmi_core_power(on, 1);
+	if (rc)
+		rc = hdmi_cec_power(on);
+
+	pr_debug("%s: HDMI Core: %s Success\n", __func__, (on ? "ON" : "OFF"));
+	return rc;
+}
 #endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
 
 void __init msm8960_init_fb(void)
diff --git a/arch/arm/mach-msm/board-8960-gpiomux.c b/arch/arm/mach-msm/board-8960-gpiomux.c
index fe37f2a..e6e676c 100644
--- a/arch/arm/mach-msm/board-8960-gpiomux.c
+++ b/arch/arm/mach-msm/board-8960-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -108,7 +108,7 @@
 };
 
 static struct gpiomux_setting gsbi9_suspended_cfg = {
-	.func = GPIOMUX_FUNC_2,
+	.func = GPIOMUX_FUNC_GPIO,
 	.drv = GPIOMUX_DRV_2MA,
 	.pull = GPIOMUX_PULL_DOWN,
 };
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index abf88e1..c87d966 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -249,8 +249,8 @@
 static const unsigned int keymap[] = {
 	KEY(0, 0, KEY_VOLUMEUP),
 	KEY(0, 1, KEY_VOLUMEDOWN),
-	KEY(0, 2, KEY_CAMERA_SNAPSHOT),
-	KEY(0, 3, KEY_CAMERA_FOCUS),
+	KEY(0, 2, KEY_CAMERA_FOCUS),
+	KEY(0, 3, KEY_CAMERA_SNAPSHOT),
 };
 
 static struct matrix_keymap_data keymap_data = {
@@ -433,6 +433,11 @@
 	.chg_term_ua			= CHG_TERM_MA * 1000,
 	.normal_voltage_calc_ms		= 20000,
 	.low_voltage_calc_ms		= 1000,
+	.alarm_low_mv			= 3400,
+	.alarm_high_mv			= 4000,
+	.high_ocv_correction_limit_uv	= 50,
+	.low_ocv_correction_limit_uv	= 100,
+	.hold_soc_est			= 3,
 };
 
 #define	PM8921_LC_LED_MAX_CURRENT	4	/* I = 4mA */
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index b666ae9..7187bcf 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -31,6 +31,7 @@
 VREG_CONSUMERS(L2) = {
 	REGULATOR_SUPPLY("8921_l2",		NULL),
 	REGULATOR_SUPPLY("dsi_vdda",		"mipi_dsi.1"),
+	REGULATOR_SUPPLY("dsi_pll_vdda",	"mdp.0"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_csid.0"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_csid.1"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_csid.2"),
@@ -73,6 +74,7 @@
 VREG_CONSUMERS(L11) = {
 	REGULATOR_SUPPLY("8921_l11",		NULL),
 	REGULATOR_SUPPLY("cam_vana",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vana",		"4-0010"),
 	REGULATOR_SUPPLY("cam_vana",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vana",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vana",		"4-0020"),
@@ -81,6 +83,7 @@
 VREG_CONSUMERS(L12) = {
 	REGULATOR_SUPPLY("8921_l12",		NULL),
 	REGULATOR_SUPPLY("cam_vdig",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vdig",		"4-0010"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-0020"),
@@ -97,6 +100,7 @@
 VREG_CONSUMERS(L16) = {
 	REGULATOR_SUPPLY("8921_l16",		NULL),
 	REGULATOR_SUPPLY("cam_vaf",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vaf",		"4-0010"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-0020"),
@@ -117,6 +121,7 @@
 VREG_CONSUMERS(L23) = {
 	REGULATOR_SUPPLY("8921_l23",		NULL),
 	REGULATOR_SUPPLY("dsi_vddio",		"mipi_dsi.1"),
+	REGULATOR_SUPPLY("dsi_pll_vddio",	"mdp.0"),
 	REGULATOR_SUPPLY("hdmi_avdd",		"hdmi_msm.0"),
 	REGULATOR_SUPPLY("pll_vdd",		"pil_riva"),
 	REGULATOR_SUPPLY("pll_vdd",		"pil_qdsp6v4.1"),
@@ -216,6 +221,7 @@
 VREG_CONSUMERS(LVS5) = {
 	REGULATOR_SUPPLY("8921_lvs5",		NULL),
 	REGULATOR_SUPPLY("cam_vio",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vio",		"4-0010"),
 	REGULATOR_SUPPLY("cam_vio",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vio",		"4-0048"),
 	REGULATOR_SUPPLY("cam_vio",		"4-0020"),
diff --git a/arch/arm/mach-msm/board-8960-storage.c b/arch/arm/mach-msm/board-8960-storage.c
index 678474d..44fc88d 100644
--- a/arch/arm/mach-msm/board-8960-storage.c
+++ b/arch/arm/mach-msm/board-8960-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 7a94e74..bd3cf4c 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -649,7 +649,7 @@
 
 			if (fixed_position != NOT_FIXED)
 				fixed_size += heap->size;
-			else
+			else if (!use_cma)
 				reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
 
 			if (fixed_position == FIXED_LOW) {
@@ -769,29 +769,6 @@
 #endif
 }
 
-static void ion_adjust_secure_allocation(void)
-{
-	int i;
-
-	for (i = 0; i < msm8960_ion_pdata.nr; i++) {
-		struct ion_platform_heap *heap =
-			&(msm8960_ion_pdata.heaps[i]);
-
-
-		if (heap->extra_data) {
-			switch ((int) heap->type) {
-			case ION_HEAP_TYPE_CP:
-				if (cpu_is_msm8960()) {
-					((struct ion_cp_heap_pdata *)
-					heap->extra_data)->no_nonsecure_alloc =
-						0;
-				}
-
-			}
-		}
-	}
-}
-
 static void __init reserve_mdp_memory(void)
 {
 	msm8960_mdp_writeback(msm8960_reserve_table);
@@ -825,65 +802,9 @@
 	.paddr_to_memtype = msm8960_paddr_to_memtype,
 };
 
-static int msm8960_memory_bank_size(void)
-{
-	return 1<<29;
-}
-
-static void __init locate_unstable_memory(void)
-{
-	struct membank *mb = &meminfo.bank[meminfo.nr_banks - 1];
-	unsigned long bank_size;
-	unsigned long low, high;
-
-	bank_size = msm8960_memory_bank_size();
-	msm8960_reserve_info.bank_size = bank_size;
-
-	low = meminfo.bank[0].start;
-	high = mb->start + mb->size;
-
-	/* Check if 32 bit overflow occured */
-	if (high < mb->start)
-		high = ~0UL;
-
-	if (high < MAX_FIXED_AREA_SIZE + MSM8960_FIXED_AREA_START)
-		panic("fixed area extends beyond end of memory\n");
-
-	low &= ~(bank_size - 1);
-
-	if (high - low <= bank_size)
-		goto no_dmm;
-
-#ifdef CONFIG_ENABLE_DMM
-	msm8960_reserve_info.low_unstable_address = mb->start -
-					MIN_MEMORY_BLOCK_SIZE + mb->size;
-	msm8960_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
-	pr_info("low unstable address %lx max size %lx bank size %lx\n",
-		msm8960_reserve_info.low_unstable_address,
-		msm8960_reserve_info.max_unstable_size,
-		msm8960_reserve_info.bank_size);
-	return;
-#endif
-no_dmm:
-	msm8960_reserve_info.low_unstable_address = high;
-	msm8960_reserve_info.max_unstable_size = 0;
-}
-
-static void __init place_movable_zone(void)
-{
-#ifdef CONFIG_ENABLE_DMM
-	movable_reserved_start = msm8960_reserve_info.low_unstable_address;
-	movable_reserved_size = msm8960_reserve_info.max_unstable_size;
-	pr_info("movable zone start %lx size %lx\n",
-		movable_reserved_start, movable_reserved_size);
-#endif
-}
-
 static void __init msm8960_early_memory(void)
 {
 	reserve_info = &msm8960_reserve_info;
-	locate_unstable_memory();
-	place_movable_zone();
 }
 
 static char prim_panel_name[PANEL_NAME_MAX_LEN];
@@ -910,12 +831,6 @@
 	msm_reserve();
 }
 
-static int msm8960_change_memory_power(u64 start, u64 size,
-	int change_type)
-{
-	return soc_change_memory_power(start, size, change_type);
-}
-
 static void __init msm8960_allocate_memory_regions(void)
 {
 	msm8960_allocate_fb_region();
@@ -1410,6 +1325,8 @@
 static struct mdm_platform_data sglte_platform_data = {
 	.mdm_version = "4.0",
 	.ramdump_delay_ms = 1000,
+	/* delay between two PS_HOLDs */
+	.ps_hold_delay_ms = 500,
 	.soft_reset_inverted = 1,
 	.peripheral_platform_device = NULL,
 	.ramdump_timeout_ms = 600000,
@@ -1455,26 +1372,49 @@
 
 static struct resource tspp_resources[] = {
 	[0] = {
+		.name = "TSIF_TSPP_IRQ",
 		.flags = IORESOURCE_IRQ,
 		.start = TSIF_TSPP_IRQ,
-		.end   = TSIF1_IRQ,
+		.end   = TSIF_TSPP_IRQ,
 	},
 	[1] = {
+		.name = "TSIF0_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF1_IRQ,
+		.end   = TSIF1_IRQ,
+	},
+	[2] = {
+		.name = "TSIF1_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF2_IRQ,
+		.end   = TSIF2_IRQ,
+	},
+	[3] = {
+		.name = "TSIF_BAM_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF_BAM_IRQ,
+		.end   = TSIF_BAM_IRQ,
+	},
+	[4] = {
+		.name = "MSM_TSIF0_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSIF0_PHYS,
 		.end   = MSM_TSIF0_PHYS + MSM_TSIF_SIZE - 1,
 	},
-	[2] = {
+	[5] = {
+		.name = "MSM_TSIF1_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSIF1_PHYS,
 		.end   = MSM_TSIF1_PHYS + MSM_TSIF_SIZE - 1,
 	},
-	[3] = {
+	[6] = {
+		.name = "MSM_TSPP_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSPP_PHYS,
 		.end   = MSM_TSPP_PHYS + MSM_TSPP_SIZE - 1,
 	},
-	[4] = {
+	[7] = {
+		.name = "MSM_TSPP_BAM_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSPP_BAM_PHYS,
 		.end   = MSM_TSPP_BAM_PHYS + MSM_TSPP_BAM_SIZE - 1,
@@ -1730,6 +1670,13 @@
 			0x0B, 0x00, 0x0f,
 };
 
+static uint8_t spm_retention_with_krait_v3_cmd_sequence[] __initdata = {
+	0x42, 0x1B, 0x00,
+	0x05, 0x03, 0x0D, 0x0B,
+	0x00, 0x42, 0x1B,
+	0x0f,
+};
+
 static uint8_t spm_power_collapse_without_rpm[] __initdata = {
 			0x00, 0x24, 0x54, 0x10,
 			0x09, 0x03, 0x01,
@@ -1790,12 +1737,20 @@
 		.notify_rpm = false,
 		.cmd = spm_wfi_cmd_sequence,
 	},
+
 	[1] = {
+		.mode = MSM_SPM_MODE_POWER_RETENTION,
+		.notify_rpm = false,
+		.cmd = spm_retention_cmd_sequence,
+	},
+
+	[2] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = false,
 		.cmd = spm_power_collapse_without_rpm,
 	},
-	[2] = {
+
+	[3] = {
 		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
 		.notify_rpm = true,
 		.cmd = spm_power_collapse_with_rpm,
@@ -1826,9 +1781,9 @@
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00020000,
 #endif
 		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020204,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x03020004,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0084009C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A4001C,
 		.vctl_timeout_us = 50,
 		.num_modes = ARRAY_SIZE(msm_spm_nonboot_cpu_seq_list),
 		.modes = msm_spm_nonboot_cpu_seq_list,
@@ -2585,6 +2540,13 @@
 };
 #endif
 
+#ifdef CONFIG_BATTERY_BCL
+static struct platform_device battery_bcl_device = {
+	.name = "battery_current_limit",
+	.id = -1,
+	};
+#endif
+
 static struct platform_device msm8960_device_ext_5v_vreg __devinitdata = {
 	.name	= GPIO_REGULATOR_DEV_NAME,
 	.id	= PM8921_MPP_PM_TO_SYS(7),
@@ -2627,60 +2589,20 @@
 	},
 };
 #ifdef CONFIG_SERIAL_MSM_HS
-static int configure_uart_gpios(int on)
-{
-	int ret = 0, i;
-	int uart_gpios[] = {93, 94, 95, 96};
-
-	for (i = 0; i < ARRAY_SIZE(uart_gpios); i++) {
-		if (on) {
-			ret = gpio_request(uart_gpios[i], NULL);
-			if (ret) {
-				pr_err("%s: unable to request uart gpio[%d]\n",
-						__func__, uart_gpios[i]);
-				break;
-			}
-		} else {
-			gpio_free(uart_gpios[i]);
-		}
-	}
-
-	if (ret && on && i)
-		for (; i >= 0; i--)
-			gpio_free(uart_gpios[i]);
-	return ret;
-}
-
 static struct msm_serial_hs_platform_data msm_uart_dm9_pdata = {
-	.gpio_config	= configure_uart_gpios,
+	.config_gpio		= 4,
+	.uart_tx_gpio		= 93,
+	.uart_rx_gpio		= 94,
+	.uart_cts_gpio		= 95,
+	.uart_rfr_gpio		= 96,
 };
 
-static int configure_gsbi8_uart_gpios(int on)
-{
-	int ret = 0, i;
-	int uart_gpios[] = {34, 35, 36, 37};
-
-	for (i = 0; i < ARRAY_SIZE(uart_gpios); i++) {
-		if (on) {
-			ret = gpio_request(uart_gpios[i], NULL);
-			if (ret) {
-				pr_err("%s: unable to request uart gpio[%d]\n",
-						__func__, uart_gpios[i]);
-				break;
-			}
-		} else {
-			gpio_free(uart_gpios[i]);
-		}
-	}
-
-	if (ret && on && i)
-		for (; i >= 0; i--)
-			gpio_free(uart_gpios[i]);
-	return ret;
-}
-
 static struct msm_serial_hs_platform_data msm_uart_dm8_pdata = {
-	.gpio_config	= configure_gsbi8_uart_gpios,
+	.config_gpio		= 4,
+	.uart_tx_gpio		= 34,
+	.uart_rx_gpio		= 35,
+	.uart_cts_gpio		= 36,
+	.uart_rfr_gpio		= 37,
 };
 #else
 static struct msm_serial_hs_platform_data msm_uart_dm8_pdata;
@@ -2884,6 +2806,9 @@
 #ifdef CONFIG_MSM_FAKE_BATTERY
 	&fish_battery_device,
 #endif
+#ifdef CONFIG_BATTERY_BCL
+	&battery_bcl_device,
+#endif
 	&msm8960_fmem_device,
 #ifdef CONFIG_ANDROID_PMEM
 #ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
@@ -3374,6 +3299,23 @@
 	}
 }
 
+static void __init msm8960ab_update_retention_spm(void)
+{
+	int i;
+
+	/* Update the SPM sequences for krait retention on all cores */
+	for (i = 0; i < ARRAY_SIZE(msm_spm_data); i++) {
+		int j;
+		struct msm_spm_platform_data *pdata = &msm_spm_data[i];
+		for (j = 0; j < pdata->num_modes; j++) {
+			if (pdata->modes[j].cmd ==
+					spm_retention_cmd_sequence)
+				pdata->modes[j].cmd =
+				spm_retention_with_krait_v3_cmd_sequence;
+		}
+	}
+}
+
 static void __init msm8960_cdp_init(void)
 {
 	if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
@@ -3430,6 +3372,12 @@
 	msm8960_gfx_init();
  	if (cpu_is_msm8960ab())
 		msm8960ab_update_krait_spm();
+	if (cpu_is_krait_v3()) {
+		msm_pm_set_tz_retention_flag(0);
+		msm8960ab_update_retention_spm();
+	} else {
+		msm_pm_set_tz_retention_flag(1);
+	}
 	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
 	msm_spm_l2_init(msm_spm_l2_data);
 	msm8960_init_buses();
@@ -3489,15 +3437,12 @@
 	slim_register_board_info(msm_slim_devices,
 		ARRAY_SIZE(msm_slim_devices));
 	msm8960_init_dsps();
-	change_memory_power = &msm8960_change_memory_power;
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
 	bt_power_init();
 	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE) {
 		mdm_sglte_device.dev.platform_data = &sglte_platform_data;
 		platform_device_register(&mdm_sglte_device);
 	}
-	msm_pm_set_tz_retention_flag(1);
-	ion_adjust_secure_allocation();
 }
 
 MACHINE_START(MSM8960_CDP, "QCT MSM8960 CDP")
diff --git a/arch/arm/mach-msm/board-8960.h b/arch/arm/mach-msm/board-8960.h
index 6fb09b7..ee0f25d 100644
--- a/arch/arm/mach-msm/board-8960.h
+++ b/arch/arm/mach-msm/board-8960.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index 458816b..9e416db 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-8974.c b/arch/arm/mach-msm/board-8974.c
index dba06f0..90b78e5 100644
--- a/arch/arm/mach-msm/board-8974.c
+++ b/arch/arm/mach-msm/board-8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-9615-display.c b/arch/arm/mach-msm/board-9615-display.c
index 4e4ce7a..4b355d0 100644
--- a/arch/arm/mach-msm/board-9615-display.c
+++ b/arch/arm/mach-msm/board-9615-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-9615-gpiomux.c b/arch/arm/mach-msm/board-9615-gpiomux.c
index 9339638..8138ed0 100644
--- a/arch/arm/mach-msm/board-9615-gpiomux.c
+++ b/arch/arm/mach-msm/board-9615-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-9615-regulator.c b/arch/arm/mach-msm/board-9615-regulator.c
index 2561def..0a900e1 100644
--- a/arch/arm/mach-msm/board-9615-regulator.c
+++ b/arch/arm/mach-msm/board-9615-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-9615-storage.c b/arch/arm/mach-msm/board-9615-storage.c
index 6cb34f8..1a05c08 100644
--- a/arch/arm/mach-msm/board-9615-storage.c
+++ b/arch/arm/mach-msm/board-9615-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index ffe5955..64635b2 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-9615.h b/arch/arm/mach-msm/board-9615.h
index 68d9951..685e413 100644
--- a/arch/arm/mach-msm/board-9615.h
+++ b/arch/arm/mach-msm/board-9615.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-9625-gpiomux.c b/arch/arm/mach-msm/board-9625-gpiomux.c
index 2919f06..82c412a 100644
--- a/arch/arm/mach-msm/board-9625-gpiomux.c
+++ b/arch/arm/mach-msm/board-9625-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index 99b9f16..0201a18 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index b2a4ce2..9dcd5f6 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-fsm9xxx.c b/arch/arm/mach-msm/board-fsm9xxx.c
index b4f6968..09f5934 100644
--- a/arch/arm/mach-msm/board-fsm9xxx.c
+++ b/arch/arm/mach-msm/board-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7627-regulator.c b/arch/arm/mach-msm/board-msm7627-regulator.c
index 7437911..3ef748d 100644
--- a/arch/arm/mach-msm/board-msm7627-regulator.c
+++ b/arch/arm/mach-msm/board-msm7627-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7627-regulator.h b/arch/arm/mach-msm/board-msm7627-regulator.h
index d82c5c0..aaf9598 100644
--- a/arch/arm/mach-msm/board-msm7627-regulator.h
+++ b/arch/arm/mach-msm/board-msm7627-regulator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index e4edf9b..fed25bb 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 1e198a7..3761651 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index e305fe6..7f03356 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7627a-io.c b/arch/arm/mach-msm/board-msm7627a-io.c
index 47e8381..09c1b2c 100644
--- a/arch/arm/mach-msm/board-msm7627a-io.c
+++ b/arch/arm/mach-msm/board-msm7627a-io.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7627a-storage.c b/arch/arm/mach-msm/board-msm7627a-storage.c
index 49ff393..b1ab6e4 100644
--- a/arch/arm/mach-msm/board-msm7627a-storage.c
+++ b/arch/arm/mach-msm/board-msm7627a-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7627a-wlan.c b/arch/arm/mach-msm/board-msm7627a-wlan.c
index 79f213e..73cb915 100644
--- a/arch/arm/mach-msm/board-msm7627a-wlan.c
+++ b/arch/arm/mach-msm/board-msm7627a-wlan.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7627a.h b/arch/arm/mach-msm/board-msm7627a.h
index 4357e01..b239d82 100644
--- a/arch/arm/mach-msm/board-msm7627a.h
+++ b/arch/arm/mach-msm/board-msm7627a.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index a7fed3e..5f0d75f 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/board-msm7x27a-regulator.c b/arch/arm/mach-msm/board-msm7x27a-regulator.c
index c67ab7f..7c140cb 100644
--- a/arch/arm/mach-msm/board-msm7x27a-regulator.c
+++ b/arch/arm/mach-msm/board-msm7x27a-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7x27a-regulator.h b/arch/arm/mach-msm/board-msm7x27a-regulator.h
index 01dc70e..999e2eb 100644
--- a/arch/arm/mach-msm/board-msm7x27a-regulator.h
+++ b/arch/arm/mach-msm/board-msm7x27a-regulator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index b668330..3a38fc1 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7x30-regulator.c b/arch/arm/mach-msm/board-msm7x30-regulator.c
index a3f5ee1..193da15 100644
--- a/arch/arm/mach-msm/board-msm7x30-regulator.c
+++ b/arch/arm/mach-msm/board-msm7x30-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7x30-regulator.h b/arch/arm/mach-msm/board-msm7x30-regulator.h
index bd9b02d..12a9122 100644
--- a/arch/arm/mach-msm/board-msm7x30-regulator.h
+++ b/arch/arm/mach-msm/board-msm7x30-regulator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 167bbe9..920f2c5 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm8x60-camera.c b/arch/arm/mach-msm/board-msm8x60-camera.c
index cd95630..1790937 100644
--- a/arch/arm/mach-msm/board-msm8x60-camera.c
+++ b/arch/arm/mach-msm/board-msm8x60-camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm8x60-vcm.c b/arch/arm/mach-msm/board-msm8x60-vcm.c
index 6078367..de1c1e2 100644
--- a/arch/arm/mach-msm/board-msm8x60-vcm.c
+++ b/arch/arm/mach-msm/board-msm8x60-vcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 08e6a0d..f2f41cf 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -3600,30 +3600,14 @@
 };
 
 #ifdef CONFIG_SERIAL_MSM_HS
-static int configure_uart_gpios(int on)
-{
-	int ret = 0, i;
-	int uart_gpios[] = {53, 54, 55, 56};
-	for (i = 0; i < ARRAY_SIZE(uart_gpios); i++) {
-		if (on) {
-			ret = msm_gpiomux_get(uart_gpios[i]);
-			if (unlikely(ret))
-				break;
-		} else {
-			ret = msm_gpiomux_put(uart_gpios[i]);
-			if (unlikely(ret))
-				return ret;
-		}
-	}
-	if (ret)
-		for (; i >= 0; i--)
-			msm_gpiomux_put(uart_gpios[i]);
-	return ret;
-}
 static struct msm_serial_hs_platform_data msm_uart_dm1_pdata = {
-       .inject_rx_on_wakeup = 1,
-       .rx_to_inject = 0xFD,
-       .gpio_config = configure_uart_gpios,
+	.inject_rx_on_wakeup	= 1,
+	.rx_to_inject		= 0xFD,
+	.config_gpio		= 4,
+	.uart_tx_gpio		= 53,
+	.uart_rx_gpio		= 54,
+	.uart_cts_gpio		= 55,
+	.uart_rfr_gpio		= 56,
 };
 #endif
 
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 52f41fa..b58c7cd 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index 146c8a8..27773fc 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/board-storage-common-a.h b/arch/arm/mach-msm/board-storage-common-a.h
index 7737819..f651677 100644
--- a/arch/arm/mach-msm/board-storage-common-a.h
+++ b/arch/arm/mach-msm/board-storage-common-a.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/btpintest.c b/arch/arm/mach-msm/btpintest.c
index 97a511e..543d557 100644
--- a/arch/arm/mach-msm/btpintest.c
+++ b/arch/arm/mach-msm/btpintest.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/cache_erp.c b/arch/arm/mach-msm/cache_erp.c
index 8a73c84..4170fd8 100644
--- a/arch/arm/mach-msm/cache_erp.c
+++ b/arch/arm/mach-msm/cache_erp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index e1390db..7b4ca31 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-7x30.h b/arch/arm/mach-msm/clock-7x30.h
index 1410445..9fb3240 100644
--- a/arch/arm/mach-msm/clock-7x30.h
+++ b/arch/arm/mach-msm/clock-7x30.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
old mode 100644
new mode 100755
index 7be143c..e802bf2
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4111,6 +4111,7 @@
 };
 #else
 static struct clk_freq_tbl clk_tbl_tv[] = {
+	F_END
 };
 #endif
 
@@ -5111,6 +5112,8 @@
 		writel_relaxed(0x80|BVAL(5, 3, clk_sel), GCC_APCS_CLK_DIAG);
 		measure->sample_ticks = 0x4000;
 		measure->multiplier = 2;
+		if (cpu_is_krait_v3())
+			measure->multiplier = 8;
 		break;
 	default:
 		ret = -EPERM;
@@ -5305,10 +5308,10 @@
 #ifdef CONFIG_MACH_LGE
 	CLK_LOOKUP("core_clk",		gsbi4_uart_clk.c,	"msm_serial_hsl.0"),
 #else
-	CLK_LOOKUP("core_clk",		gsbi4_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi4_uart_clk.c, "msm_serial_hs.1"),
 #endif
 	CLK_LOOKUP("core_clk",		gsbi5_uart_clk.c,	""),
-	CLK_LOOKUP("core_clk",		gsbi6_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi6_uart_clk.c, "msm_serial_hs.0"),
 #ifdef CONFIG_MACH_LGE
 	CLK_LOOKUP("core_clk",		gsbi7_uart_clk.c,	""),
 #else
@@ -5367,9 +5370,10 @@
 	CLK_LOOKUP("iface_clk",		gsbi4_p_clk.c,		"msm_serial_hsl.0"),
 #endif
 	CLK_LOOKUP("iface_clk",		gsbi4_p_clk.c,		"qup_i2c.4"),
+	CLK_LOOKUP("iface_clk",		gsbi4_p_clk.c,	"msm_serial_hs.1"),
 	CLK_LOOKUP("iface_clk",		gsbi5_p_clk.c,		"spi_qsd.0"),
 	CLK_LOOKUP("iface_clk",		gsbi5_p_clk.c,		"qup_i2c.5"),
-	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,	"msm_serial_hs.0"),
 #ifdef CONFIG_MACH_LGE
 	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,		""),
 #else
@@ -5397,6 +5401,7 @@
 	CLK_LOOKUP("core_clk",		pmic_ssbi2_clk.c,	""),
 	CLK_LOOKUP("mem_clk",		rpm_msg_ram_p_clk.c,	""),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-001a"),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0010"),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0034"),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0020"),
 	CLK_LOOKUP("cam_clk",		cam1_clk.c,	"4-0048"),
@@ -5758,6 +5763,7 @@
 	CLK_LOOKUP("core_clk",		pmic_ssbi2_clk.c,	""),
 	CLK_LOOKUP("mem_clk",		rpm_msg_ram_p_clk.c,	""),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-001a"),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0010"),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-006c"),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0048"),
 	CLK_LOOKUP("cam_clk",		cam2_clk.c,		NULL),
@@ -6036,7 +6042,8 @@
 	CLK_LOOKUP("core_clk",		gsbi6_uart_clk.c, "msm_serial_hs.0"),
 	CLK_LOOKUP("core_clk",		gsbi7_uart_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi8_uart_clk.c,	""),
-	CLK_LOOKUP("core_clk",		gsbi9_uart_clk.c,	""),
+	/* used on 8930 SGLTE for Primary IPC */
+	CLK_LOOKUP("core_clk",		gsbi9_uart_clk.c, "msm_serial_hs.1"),
 	CLK_LOOKUP("core_clk",		gsbi10_uart_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi11_uart_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi12_uart_clk.c,	""),
@@ -6047,7 +6054,7 @@
 	CLK_LOOKUP("core_clk",		gsbi5_qup_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi6_qup_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi7_qup_clk.c,	""),
-	CLK_LOOKUP("core_clk",		gsbi8_qup_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi8_qup_clk.c,	"qup_i2c.8"),
 	CLK_LOOKUP("core_clk",		gsbi9_qup_clk.c,	"qup_i2c.0"),
 	CLK_LOOKUP("core_clk",		gsbi10_qup_clk.c,	"qup_i2c.10"),
 	CLK_LOOKUP("core_clk",		gsbi11_qup_clk.c,	""),
@@ -6087,7 +6094,10 @@
 	CLK_LOOKUP("iface_clk",		gsbi5_p_clk.c,	"msm_serial_hsl.0"),
 	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,  "msm_serial_hs.0"),
 	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,		""),
-	CLK_LOOKUP("iface_clk",		gsbi8_p_clk.c,		""),
+	/* used on 8930 SGLTE for Camera */
+	CLK_LOOKUP("iface_clk",		gsbi8_p_clk.c,		"qup_i2c.8"),
+	/* used on 8930 SGLTE for Primary IPC */
+	CLK_LOOKUP("iface_clk",         gsbi9_p_clk.c,	"msm_serial_hs.1"),
 	CLK_LOOKUP("iface_clk",		gsbi9_p_clk.c,		"qup_i2c.0"),
 	CLK_LOOKUP("iface_clk",		gsbi10_p_clk.c,		"qup_i2c.10"),
 	CLK_LOOKUP("iface_clk",		gsbi11_p_clk.c,		""),
@@ -6112,6 +6122,13 @@
 	CLK_LOOKUP("cam_clk",		cam1_clk.c,	"4-0048"),
 	CLK_LOOKUP("cam_clk",		cam2_clk.c,		NULL),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0020"),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"8-001a"),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"8-0036"),
+	CLK_LOOKUP("cam_clk",		cam1_clk.c,	"8-006c"),
+	CLK_LOOKUP("cam_clk",		cam1_clk.c,	"8-0010"),
+	CLK_LOOKUP("cam_clk",		cam1_clk.c,	"8-0048"),
+	CLK_LOOKUP("cam_clk",		cam2_clk.c,		NULL),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"8-0020"),
 	CLK_LOOKUP("csi_src_clk",	csi0_src_clk.c,		"msm_csid.0"),
 	CLK_LOOKUP("csi_src_clk",	csi1_src_clk.c,		"msm_csid.1"),
 	CLK_LOOKUP("csi_src_clk",	csi2_src_clk.c,		"msm_csid.2"),
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 8969be9..5708d60 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -5071,8 +5071,8 @@
 	CLK_LOOKUP("core_clk", gcc_sdcc4_apps_clk.c, "msm_sdcc.4"),
 	CLK_LOOKUP("bus_clk", pnoc_sdcc4_clk.c, "msm_sdcc.4"),
 
-	CLK_LOOKUP("iface_clk", gcc_tsif_ahb_clk.c, ""),
-	CLK_LOOKUP("ref_clk", gcc_tsif_ref_clk.c, ""),
+	CLK_LOOKUP("iface_clk", gcc_tsif_ahb_clk.c, "f99d8000.msm_tspp"),
+	CLK_LOOKUP("ref_clk", gcc_tsif_ref_clk.c, "f99d8000.msm_tspp"),
 
 	CLK_LOOKUP("core_clk", gcc_usb30_master_clk.c,    "msm_dwc3"),
 	CLK_LOOKUP("utmi_clk", gcc_usb30_mock_utmi_clk.c, "msm_dwc3"),
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 3816b54..04df842 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 3884390..ffa8f77 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
index da12b34..33a6bab 100644
--- a/arch/arm/mach-msm/clock-debug.c
+++ b/arch/arm/mach-msm/clock-debug.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/clock-dss-8960.h b/arch/arm/mach-msm/clock-dss-8960.h
index 72e70fc..eb48c7f 100644
--- a/arch/arm/mach-msm/clock-dss-8960.h
+++ b/arch/arm/mach-msm/clock-dss-8960.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-dummy.c b/arch/arm/mach-msm/clock-dummy.c
index fda7a92..883a5c2 100644
--- a/arch/arm/mach-msm/clock-dummy.c
+++ b/arch/arm/mach-msm/clock-dummy.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-fsm9xxx.c b/arch/arm/mach-msm/clock-fsm9xxx.c
index 2900d45..e3a4818 100644
--- a/arch/arm/mach-msm/clock-fsm9xxx.c
+++ b/arch/arm/mach-msm/clock-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index ca031ad..1f590a0 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index 1873343..be1a593 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index 4b4da61..1ae5f50 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-local2.h b/arch/arm/mach-msm/clock-local2.h
index 101dc2d..bfb5894 100644
--- a/arch/arm/mach-msm/clock-local2.h
+++ b/arch/arm/mach-msm/clock-local2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-pcom-lookup.c b/arch/arm/mach-msm/clock-pcom-lookup.c
index 2a2cc01..376af36 100644
--- a/arch/arm/mach-msm/clock-pcom-lookup.c
+++ b/arch/arm/mach-msm/clock-pcom-lookup.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c
index 801b40a..72bb0b4 100644
--- a/arch/arm/mach-msm/clock-pcom.c
+++ b/arch/arm/mach-msm/clock-pcom.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h
index 82a90ab..dcf5736 100644
--- a/arch/arm/mach-msm/clock-pcom.h
+++ b/arch/arm/mach-msm/clock-pcom.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index 23941d7..aeb1c5e 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-pll.h b/arch/arm/mach-msm/clock-pll.h
index 5c7c304..2b68eb3 100644
--- a/arch/arm/mach-msm/clock-pll.h
+++ b/arch/arm/mach-msm/clock-pll.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index e06eb4b..adb055d 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-rpm.h b/arch/arm/mach-msm/clock-rpm.h
index 2f0b729..a989437 100644
--- a/arch/arm/mach-msm/clock-rpm.h
+++ b/arch/arm/mach-msm/clock-rpm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-voter.c b/arch/arm/mach-msm/clock-voter.c
index fa170bf4..7abe9ea 100644
--- a/arch/arm/mach-msm/clock-voter.c
+++ b/arch/arm/mach-msm/clock-voter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock-voter.h b/arch/arm/mach-msm/clock-voter.h
index 82c071b..a184f0b 100644
--- a/arch/arm/mach-msm/clock-voter.h
+++ b/arch/arm/mach-msm/clock-voter.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 3cb3d60..4d2d6a2 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/clock.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index 48f897b..34dae77 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index 77bb00f..f270335 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -3,7 +3,7 @@
  * MSM architecture cpufreq driver
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  * Author: Mike A. Chan <mikechan@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -32,6 +32,17 @@
 
 #include "acpuclock.h"
 
+struct cpufreq_work_struct {
+	struct work_struct work;
+	struct cpufreq_policy *policy;
+	struct completion complete;
+	int frequency;
+	int status;
+};
+
+static DEFINE_PER_CPU(struct cpufreq_work_struct, cpufreq_work);
+static struct workqueue_struct *msm_cpufreq_wq;
+
 struct cpufreq_suspend_t {
 	struct mutex suspend_mutex;
 	int device_suspended;
@@ -52,8 +63,11 @@
 static int set_cpu_freq(struct cpufreq_policy *policy, unsigned int new_freq)
 {
 	int ret = 0;
+	int saved_sched_policy = -EINVAL;
+	int saved_sched_rt_prio = -EINVAL;
 	struct cpufreq_freqs freqs;
 	struct cpu_freq *limit = &per_cpu(cpu_freq_info, policy->cpu);
+	struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
 
 	if (limit->limits_init) {
 		if (new_freq > limit->allowed_max) {
@@ -70,14 +84,41 @@
 	freqs.old = policy->cur;
 	freqs.new = new_freq;
 	freqs.cpu = policy->cpu;
+
+	/*
+	 * Put the caller into SCHED_FIFO priority to avoid cpu starvation
+	 * in the acpuclk_set_rate path while increasing frequencies
+	 */
+
+	if (freqs.new > freqs.old && current->policy != SCHED_FIFO) {
+		saved_sched_policy = current->policy;
+		saved_sched_rt_prio = current->rt_priority;
+		sched_setscheduler_nocheck(current, SCHED_FIFO, &param);
+	}
+
 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
 	ret = acpuclk_set_rate(policy->cpu, new_freq, SETRATE_CPUFREQ);
 	if (!ret)
 		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
+	/* Restore priority after clock ramp-up */
+	if (freqs.new > freqs.old && saved_sched_policy >= 0) {
+		param.sched_priority = saved_sched_rt_prio;
+		sched_setscheduler_nocheck(current, saved_sched_policy, &param);
+	}
 	return ret;
 }
 
+static void set_cpu_work(struct work_struct *work)
+{
+	struct cpufreq_work_struct *cpu_work =
+		container_of(work, struct cpufreq_work_struct, work);
+
+	cpu_work->status = set_cpu_freq(cpu_work->policy, cpu_work->frequency);
+	complete(&cpu_work->complete);
+}
+
 static int msm_cpufreq_target(struct cpufreq_policy *policy,
 				unsigned int target_freq,
 				unsigned int relation)
@@ -86,11 +127,17 @@
 	int index;
 	struct cpufreq_frequency_table *table;
 
+	struct cpufreq_work_struct *cpu_work = NULL;
+	cpumask_var_t mask;
+
 	if (!cpu_active(policy->cpu)) {
 		pr_info("cpufreq: cpu %d is not active.\n", policy->cpu);
 		return -ENODEV;
 	}
 
+	if (!alloc_cpumask_var(&mask, GFP_KERNEL))
+		return -ENOMEM;
+
 	mutex_lock(&per_cpu(cpufreq_suspend, policy->cpu).suspend_mutex);
 
 	if (per_cpu(cpufreq_suspend, policy->cpu).device_suspended) {
@@ -112,9 +159,27 @@
 		policy->cpu, target_freq, relation,
 		policy->min, policy->max, table[index].frequency);
 
-	ret = set_cpu_freq(policy, table[index].frequency);
+	cpu_work = &per_cpu(cpufreq_work, policy->cpu);
+	cpu_work->policy = policy;
+	cpu_work->frequency = table[index].frequency;
+	cpu_work->status = -ENODEV;
+
+	cpumask_clear(mask);
+	cpumask_set_cpu(policy->cpu, mask);
+	if (cpumask_equal(mask, &current->cpus_allowed)) {
+		ret = set_cpu_freq(cpu_work->policy, cpu_work->frequency);
+		goto done;
+	} else {
+		cancel_work_sync(&cpu_work->work);
+		INIT_COMPLETION(cpu_work->complete);
+		queue_work_on(policy->cpu, msm_cpufreq_wq, &cpu_work->work);
+		wait_for_completion(&cpu_work->complete);
+	}
+
+	ret = cpu_work->status;
 
 done:
+	free_cpumask_var(mask);
 	mutex_unlock(&per_cpu(cpufreq_suspend, policy->cpu).suspend_mutex);
 	return ret;
 }
@@ -197,6 +262,7 @@
 	int cur_freq;
 	int index;
 	struct cpufreq_frequency_table *table;
+	struct cpufreq_work_struct *cpu_work = NULL;
 
 	table = cpufreq_frequency_get_table(policy->cpu);
 	if (table == NULL)
@@ -225,7 +291,7 @@
 	    CPUFREQ_RELATION_H, &index) &&
 	    cpufreq_frequency_table_target(policy, table, cur_freq,
 	    CPUFREQ_RELATION_L, &index)) {
-		pr_info("%s: cpu%d at invalid freq: %d\n", __func__,
+		pr_info("cpufreq: cpu%d at invalid freq: %d\n",
 				policy->cpu, cur_freq);
 		return -EINVAL;
 	}
@@ -246,6 +312,10 @@
 	policy->cpuinfo.transition_latency =
 		acpuclk_get_switch_time() * NSEC_PER_USEC;
 
+	cpu_work = &per_cpu(cpufreq_work, policy->cpu);
+	INIT_WORK(&cpu_work->work, set_cpu_work);
+	init_completion(&cpu_work->complete);
+
 	return 0;
 }
 
@@ -333,6 +403,7 @@
 		per_cpu(cpufreq_suspend, cpu).device_suspended = 0;
 	}
 
+	msm_cpufreq_wq = create_workqueue("msm-cpufreq");
 	register_hotcpu_notifier(&msm_cpufreq_cpu_notifier);
 
 	return cpufreq_register_driver(&msm_cpufreq_driver);
diff --git a/arch/arm/mach-msm/cpuidle.c b/arch/arm/mach-msm/cpuidle.c
index dd2dc1d..15804ba 100644
--- a/arch/arm/mach-msm/cpuidle.c
+++ b/arch/arm/mach-msm/cpuidle.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/dal.c b/arch/arm/mach-msm/dal.c
index 94c02f0..74dfe37 100644
--- a/arch/arm/mach-msm/dal.c
+++ b/arch/arm/mach-msm/dal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/dal_axi.c b/arch/arm/mach-msm/dal_axi.c
index 1d873ca..7ef154d 100644
--- a/arch/arm/mach-msm/dal_axi.c
+++ b/arch/arm/mach-msm/dal_axi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/dal_remotetest.c b/arch/arm/mach-msm/dal_remotetest.c
index d7a3f34..b6fc8da 100644
--- a/arch/arm/mach-msm/dal_remotetest.c
+++ b/arch/arm/mach-msm/dal_remotetest.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/dal_remotetest.h b/arch/arm/mach-msm/dal_remotetest.h
index cb998c9..4fe4079 100644
--- a/arch/arm/mach-msm/dal_remotetest.h
+++ b/arch/arm/mach-msm/dal_remotetest.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index c1f7f65..d9dd2b1 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -44,6 +44,7 @@
 #include "msm_watchdog.h"
 #include "rpm_stats.h"
 #include "rpm_log.h"
+#include "board-8064.h"
 #include <mach/mpm.h>
 #include <mach/iommu_domains.h>
 #include <mach/msm_cache_dump.h>
@@ -335,6 +336,50 @@
 	.resource = resources_uart_gsbi4,
 };
 
+/* GSBI 4 used into UARTDM Mode for 8064 SGLTE */
+static struct resource msm_uart_dm4_resources[] = {
+	{
+		.start  = MSM_UART4DM_PHYS,
+		.end    = MSM_UART4DM_PHYS + PAGE_SIZE - 1,
+		.name   = "uartdm_resource",
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = GSBI4_UARTDM_IRQ,
+		.end    = GSBI4_UARTDM_IRQ,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.start  = MSM_GSBI4_PHYS,
+		.end    = MSM_GSBI4_PHYS + 4 - 1,
+		.name   = "gsbi_resource",
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = DMOV_APQ8064_HSUART_GSBI4_TX_CHAN,
+		.end    = DMOV_APQ8064_HSUART_GSBI4_RX_CHAN,
+		.name   = "uartdm_channels",
+		.flags  = IORESOURCE_DMA,
+	},
+	{
+		.start  = DMOV_APQ8064_HSUART_GSBI4_TX_CRCI,
+		.end    = DMOV_APQ8064_HSUART_GSBI4_RX_CRCI,
+		.name   = "uartdm_crci",
+		.flags  = IORESOURCE_DMA,
+	},
+};
+static u64 msm_uart_dm4_dma_mask = DMA_BIT_MASK(32);
+struct platform_device apq8064_device_uartdm_gsbi4 = {
+	.name   = "msm_serial_hs",
+	.id     = 1,
+	.num_resources  = ARRAY_SIZE(msm_uart_dm4_resources),
+	.resource       = msm_uart_dm4_resources,
+	.dev    = {
+		.dma_mask		= &msm_uart_dm4_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
 static struct resource resources_qup_i2c_gsbi4[] = {
 	{
 		.name	= "gsbi_qup_i2c_addr",
@@ -443,6 +488,50 @@
 	.resource	= resources_qup_i2c_gsbi5,
 };
 
+/* GSBI 6 used into UARTDM Mode */
+static struct resource msm_uart_dm6_resources[] = {
+	{
+		.start  = MSM_UART6DM_PHYS,
+		.end    = MSM_UART6DM_PHYS + PAGE_SIZE - 1,
+		.name   = "uartdm_resource",
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = GSBI6_UARTDM_IRQ,
+		.end    = GSBI6_UARTDM_IRQ,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.start  = MSM_GSBI6_PHYS,
+		.end    = MSM_GSBI6_PHYS + 4 - 1,
+		.name   = "gsbi_resource",
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = DMOV_MPQ8064_HSUART_GSBI6_TX_CHAN,
+		.end    = DMOV_MPQ8064_HSUART_GSBI6_RX_CHAN,
+		.name   = "uartdm_channels",
+		.flags  = IORESOURCE_DMA,
+	},
+	{
+		.start  = DMOV_MPQ8064_HSUART_GSBI6_TX_CRCI,
+		.end    = DMOV_MPQ8064_HSUART_GSBI6_RX_CRCI,
+		.name   = "uartdm_crci",
+		.flags  = IORESOURCE_DMA,
+	},
+};
+static u64 msm_uart_dm6_dma_mask = DMA_BIT_MASK(32);
+struct platform_device mpq8064_device_uartdm_gsbi6 = {
+	.name   = "msm_serial_hs",
+	.id     = 0,
+	.num_resources  = ARRAY_SIZE(msm_uart_dm6_resources),
+	.resource       = msm_uart_dm6_resources,
+	.dev    = {
+		.dma_mask		= &msm_uart_dm6_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
 static struct resource resources_uart_gsbi7[] = {
 	{
 		.start	= GSBI7_UARTDM_IRQ,
@@ -652,26 +741,49 @@
 
 static struct resource tspp_resources[] = {
 	[0] = {
+		.name = "TSIF_TSPP_IRQ",
 		.flags = IORESOURCE_IRQ,
 		.start = TSIF_TSPP_IRQ,
-		.end   = TSIF1_IRQ,
+		.end   = TSIF_TSPP_IRQ,
 	},
 	[1] = {
+		.name = "TSIF0_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF1_IRQ,
+		.end   = TSIF1_IRQ,
+	},
+	[2] = {
+		.name = "TSIF1_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF2_IRQ,
+		.end   = TSIF2_IRQ,
+	},
+	[3] = {
+		.name = "TSIF_BAM_IRQ",
+		.flags = IORESOURCE_IRQ,
+		.start = TSIF_BAM_IRQ,
+		.end   = TSIF_BAM_IRQ,
+	},
+	[4] = {
+		.name = "MSM_TSIF0_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSIF0_PHYS,
 		.end   = MSM_TSIF0_PHYS + MSM_TSIF_SIZE - 1,
 	},
-	[2] = {
+	[5] = {
+		.name = "MSM_TSIF1_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSIF1_PHYS,
 		.end   = MSM_TSIF1_PHYS + MSM_TSIF_SIZE - 1,
 	},
-	[3] = {
+	[6] = {
+		.name = "MSM_TSPP_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSPP_PHYS,
 		.end   = MSM_TSPP_PHYS + MSM_TSPP_SIZE - 1,
 	},
-	[4] = {
+	[7] = {
+		.name = "MSM_TSPP_BAM_PHYS",
 		.flags = IORESOURCE_MEM,
 		.start = MSM_TSPP_BAM_PHYS,
 		.end   = MSM_TSPP_BAM_PHYS + MSM_TSPP_BAM_SIZE - 1,
@@ -1298,26 +1410,26 @@
 	{
 		.src = MSM_BUS_MASTER_VIDEO_ENC,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 222298112,
+		.ab  = 372244480,
 		.ib  = 3522000000U,
 	},
 	{
 		.src = MSM_BUS_MASTER_VIDEO_DEC,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 330301440,
+		.ab  = 501219328,
 		.ib  = 3522000000U,
 	},
 	{
 		.src = MSM_BUS_MASTER_AMPSS_M0,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
 		.ab  = 2500000,
-		.ib  = 700000000,
+		.ib  = 5000000,
 	},
 	{
 		.src = MSM_BUS_MASTER_AMPSS_M0,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
 		.ab  = 2500000,
-		.ib  = 10000000,
+		.ib  = 5000000,
 	},
 };
 static struct msm_bus_vectors vidc_vdec_1080p_turbo_vectors[] = {
@@ -2349,8 +2461,8 @@
 		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
 	},
 	.phys_size = SZ_8K,
-	.log_len = 4096,		  /* log's buffer length in bytes */
-	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
+	.log_len = 6144,		  /* log's buffer length in bytes */
+	.log_len_mask = (6144 >> 2) - 1,  /* length mask in units of u32 */
 };
 
 struct platform_device apq8064_rpm_log_device = {
@@ -2547,6 +2659,11 @@
 #define AP2BMDM_SOFT_RESET		3
 #define AP2BMDM_WAKEUP			29
 
+#define SGLTE2_QSC2AP_STATUS	51
+#define SGLTE2_QSC2AP_ERRFATAL	52
+#define SGLTE2_PM2QSC_SOFT_RESET	PM8921_GPIO_PM_TO_SYS(23)
+#define SGLTE2_PM2QSC_KEYPADPWR		PM8921_GPIO_PM_TO_SYS(21)
+
 static struct resource mdm_resources[] = {
 	{
 		.start	= MDM2AP_ERRFATAL,
@@ -2721,6 +2838,45 @@
 	},
 };
 
+static struct resource sglte2_qsc_resources[] = {
+	{
+		.start	= SGLTE2_QSC2AP_ERRFATAL,
+		.end	= SGLTE2_QSC2AP_ERRFATAL,
+		.name	= "MDM2AP_ERRFATAL",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_ERRFATAL,
+		.end	= AP2MDM_ERRFATAL,
+		.name	= "AP2MDM_ERRFATAL",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= SGLTE2_QSC2AP_STATUS,
+		.end	= SGLTE2_QSC2AP_STATUS,
+		.name	= "MDM2AP_STATUS",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_STATUS,
+		.end	= AP2MDM_STATUS,
+		.name	= "AP2MDM_STATUS",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= SGLTE2_PM2QSC_KEYPADPWR,
+		.end	= SGLTE2_PM2QSC_KEYPADPWR,
+		.name	= "AP2MDM_KPDPWR_N",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= SGLTE2_PM2QSC_SOFT_RESET,
+		.end	= SGLTE2_PM2QSC_SOFT_RESET,
+		.name	= "AP2MDM_SOFT_RESET",
+		.flags	= IORESOURCE_IO,
+	},
+};
+
 struct platform_device mdm_8064_device = {
 	.name		= "mdm2_modem",
 	.id		= -1,
@@ -2749,6 +2905,20 @@
 	.resource	= i2s_mdm_resources,
 };
 
+struct platform_device sglte_mdm_8064_device = {
+	.name		= "mdm2_modem",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mdm_resources),
+	.resource	= mdm_resources,
+};
+
+struct platform_device sglte2_qsc_8064_device = {
+	.name		= "mdm2_modem",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(sglte2_qsc_resources),
+	.resource	= sglte2_qsc_resources,
+};
+
 static struct msm_dcvs_sync_rule apq8064_dcvs_sync_rules[] = {
 	{1026000,	400000},
 	{384000,	200000},
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index a617796..7f7b09e 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -528,14 +528,14 @@
 };
 
 static struct msm_rpm_log_platform_data msm_rpm_log_pdata = {
-	.phys_addr_base = 0x0010C000,
+	.phys_addr_base = 0x10B6A0,
 	.reg_offsets = {
 		[MSM_RPM_LOG_PAGE_INDICES] = 0x00000080,
 		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
 	},
 	.phys_size = SZ_8K,
-	.log_len = 4096,		  /* log's buffer length in bytes */
-	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
+	.log_len = 8192,		  /* log's buffer length in bytes */
+	.log_len_mask = (8192 >> 2) - 1,  /* length mask in units of u32 */
 };
 
 struct platform_device msm8930_rpm_log_device = {
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 84b72d0..8fa555b 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1734,6 +1734,34 @@
 	.resource	= resources_qup_i2c_gsbi4,
 };
 
+static struct resource resources_qup_i2c_gsbi8[] = {
+	{
+		.name	= "gsbi_qup_i2c_addr",
+		.start	= MSM_GSBI8_PHYS,
+		.end	= MSM_GSBI8_PHYS + 4 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "qup_phys_addr",
+		.start	= MSM_GSBI8_QUP_PHYS,
+		.end	= MSM_GSBI8_QUP_PHYS + MSM_QUP_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "qup_err_intr",
+		.start	= GSBI8_QUP_IRQ,
+		.end	= GSBI8_QUP_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device msm8960_device_qup_i2c_gsbi8 = {
+	.name		= "qup_i2c",
+	.id		= 8,
+	.num_resources	= ARRAY_SIZE(resources_qup_i2c_gsbi8),
+	.resource	= resources_qup_i2c_gsbi8,
+};
+
 static struct resource resources_qup_i2c_gsbi3[] = {
 	{
 		.name	= "gsbi_qup_i2c_addr",
@@ -3803,8 +3831,8 @@
 		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
 	},
 	.phys_size = SZ_8K,
-	.log_len = 4096,		  /* log's buffer length in bytes */
-	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
+	.log_len = 6144,		  /* log's buffer length in bytes */
+	.log_len_mask = (6144 >> 2) - 1,  /* length mask in units of u32 */
 };
 
 struct platform_device msm8960_rpm_log_device = {
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index b08bf8a..94b1717 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/devices-fsm9xxx.c b/arch/arm/mach-msm/devices-fsm9xxx.c
index 639eeae..950c1da 100644
--- a/arch/arm/mach-msm/devices-fsm9xxx.c
+++ b/arch/arm/mach-msm/devices-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c
index 63c1dbd..f3492b1 100644
--- a/arch/arm/mach-msm/devices-iommu.c
+++ b/arch/arm/mach-msm/devices-iommu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/devices-msm7x01a.c b/arch/arm/mach-msm/devices-msm7x01a.c
index 1b9eb86..8bdf510 100644
--- a/arch/arm/mach-msm/devices-msm7x01a.c
+++ b/arch/arm/mach-msm/devices-msm7x01a.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/devices-msm7x25.c b/arch/arm/mach-msm/devices-msm7x25.c
index 99b2960..5a15938 100644
--- a/arch/arm/mach-msm/devices-msm7x25.c
+++ b/arch/arm/mach-msm/devices-msm7x25.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/devices-msm7x27.c b/arch/arm/mach-msm/devices-msm7x27.c
index 82c5eed..d8c3455 100644
--- a/arch/arm/mach-msm/devices-msm7x27.c
+++ b/arch/arm/mach-msm/devices-msm7x27.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 49c3557..c08de76 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/devices-msm7x2xa.h b/arch/arm/mach-msm/devices-msm7x2xa.h
index 8b59b14..9469133 100644
--- a/arch/arm/mach-msm/devices-msm7x2xa.h
+++ b/arch/arm/mach-msm/devices-msm7x2xa.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index 263d7a1..fd4e56d 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index c71ecb9..d4c5390 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -348,6 +348,7 @@
 	.uart_tx_gpio	= 67,
 	.uart_rx_gpio	= 66,
 	.line		= 1,
+	.set_uart_clk_zero = true,
 };
 
 static struct resource msm_uart_gsbi9_resources[] = {
diff --git a/arch/arm/mach-msm/devices-msm8x60.h b/arch/arm/mach-msm/devices-msm8x60.h
index 9bfaeee..fafe4e4 100644
--- a/arch/arm/mach-msm/devices-msm8x60.h
+++ b/arch/arm/mach-msm/devices-msm8x60.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
index 03ffa2f..b77b012 100644
--- a/arch/arm/mach-msm/devices-qsd8x50.c
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 5f3aa3a..d10aa0a 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -55,6 +55,7 @@
 extern struct platform_device msm_device_uart_dm6;
 extern struct platform_device msm_device_uart_dm8;
 extern struct platform_device msm_device_uart_dm9;
+extern struct platform_device mpq8064_device_uartdm_gsbi6;
 
 extern struct platform_device msm8960_device_uart_gsbi2;
 extern struct platform_device msm8960_device_uart_gsbi5;
@@ -62,6 +63,7 @@
 extern struct platform_device msm8960_device_ssbi_pmic;
 extern struct platform_device msm8960_device_qup_i2c_gsbi3;
 extern struct platform_device msm8960_device_qup_i2c_gsbi4;
+extern struct platform_device msm8960_device_qup_i2c_gsbi8;
 extern struct platform_device msm8960_device_qup_i2c_gsbi9;
 extern struct platform_device msm8960_device_qup_i2c_gsbi10;
 extern struct platform_device msm8960_device_qup_i2c_gsbi12;
@@ -85,6 +87,7 @@
 extern struct platform_device apq8064_device_uart_gsbi1;
 extern struct platform_device apq8064_device_uart_gsbi3;
 extern struct platform_device apq8064_device_uart_gsbi4;
+extern struct platform_device apq8064_device_uartdm_gsbi4;
 extern struct platform_device apq8064_device_uart_gsbi7;
 extern struct platform_device apq8064_device_qup_i2c_gsbi1;
 extern struct platform_device apq8064_device_qup_i2c_gsbi3;
@@ -456,3 +459,6 @@
 
 extern struct platform_device amdm_8064_device;
 extern struct platform_device bmdm_8064_device;
+
+extern struct platform_device sglte_mdm_8064_device;
+extern struct platform_device sglte2_qsc_8064_device;
diff --git a/arch/arm/mach-msm/dfe-fsm9xxx.c b/arch/arm/mach-msm/dfe-fsm9xxx.c
index 1a956e3..66272d2 100644
--- a/arch/arm/mach-msm/dfe-fsm9xxx.c
+++ b/arch/arm/mach-msm/dfe-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 12f5aa9..c99f420 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-msm/dma.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/dma_test.c b/arch/arm/mach-msm/dma_test.c
index de1ee0a..3d13e4e 100644
--- a/arch/arm/mach-msm/dma_test.c
+++ b/arch/arm/mach-msm/dma_test.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ebi_erp.c b/arch/arm/mach-msm/ebi_erp.c
index cd9119d..6b300d8 100644
--- a/arch/arm/mach-msm/ebi_erp.c
+++ b/arch/arm/mach-msm/ebi_erp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -18,6 +18,9 @@
 #include <linux/errno.h>
 #include <linux/proc_fs.h>
 #include <linux/cpu.h>
+#include <mach/usb_trace.h>
+
+DEFINE_TRACE(usb_daytona_invalid_access);
 
 #define MODULE_NAME "msm_ebi_erp"
 
@@ -113,6 +116,11 @@
 	err_cntl |= CNTL_CLEAR_ERR;
 	writel_relaxed(err_cntl, base + SLV_ERR_CNTL);
 	mb();	/* Ensure interrupt is cleared before returning */
+
+	if ((err_apacket0 & AMID_MASK) == 0x00000102)
+		trace_usb_daytona_invalid_access(err_addr, err_apacket0,
+							 err_apacket1);
+
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index a7b26c1..d5fe866 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/footswitch-pcom.c b/arch/arm/mach-msm/footswitch-pcom.c
index 8903859..83c8c84 100644
--- a/arch/arm/mach-msm/footswitch-pcom.c
+++ b/arch/arm/mach-msm/footswitch-pcom.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/footswitch.h b/arch/arm/mach-msm/footswitch.h
index 1809b2e..2a49426 100644
--- a/arch/arm/mach-msm/footswitch.h
+++ b/arch/arm/mach-msm/footswitch.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gdsc.c b/arch/arm/mach-msm/gdsc.c
index 4665aec..53a6616 100644
--- a/arch/arm/mach-msm/gdsc.c
+++ b/arch/arm/mach-msm/gdsc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gpio.h b/arch/arm/mach-msm/gpio.h
index 59ee8f8..397be6e 100644
--- a/arch/arm/mach-msm/gpio.h
+++ b/arch/arm/mach-msm/gpio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gpiomux-7x27.c b/arch/arm/mach-msm/gpiomux-7x27.c
index 822cd04..010c94d 100644
--- a/arch/arm/mach-msm/gpiomux-7x27.c
+++ b/arch/arm/mach-msm/gpiomux-7x27.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gpiomux-7x30.c b/arch/arm/mach-msm/gpiomux-7x30.c
index 822cd04..010c94d 100644
--- a/arch/arm/mach-msm/gpiomux-7x30.c
+++ b/arch/arm/mach-msm/gpiomux-7x30.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gpiomux-8x50.c b/arch/arm/mach-msm/gpiomux-8x50.c
index 822cd04..010c94d 100644
--- a/arch/arm/mach-msm/gpiomux-8x50.c
+++ b/arch/arm/mach-msm/gpiomux-8x50.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gpiomux-8x60.c b/arch/arm/mach-msm/gpiomux-8x60.c
index c23a41c..4b0b8f1 100644
--- a/arch/arm/mach-msm/gpiomux-8x60.c
+++ b/arch/arm/mach-msm/gpiomux-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gpiomux-8x60.h b/arch/arm/mach-msm/gpiomux-8x60.h
index cacd1ba..619b5c0 100644
--- a/arch/arm/mach-msm/gpiomux-8x60.h
+++ b/arch/arm/mach-msm/gpiomux-8x60.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gpiomux-v1.c b/arch/arm/mach-msm/gpiomux-v1.c
index 1163669..8338cd8 100644
--- a/arch/arm/mach-msm/gpiomux-v1.c
+++ b/arch/arm/mach-msm/gpiomux-v1.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gpiomux-v1.h b/arch/arm/mach-msm/gpiomux-v1.h
index 7cf4582..6468d3d 100644
--- a/arch/arm/mach-msm/gpiomux-v1.h
+++ b/arch/arm/mach-msm/gpiomux-v1.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gpiomux-v2.c b/arch/arm/mach-msm/gpiomux-v2.c
index ee1e17a..92b9148 100644
--- a/arch/arm/mach-msm/gpiomux-v2.c
+++ b/arch/arm/mach-msm/gpiomux-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gpiomux-v2.h b/arch/arm/mach-msm/gpiomux-v2.h
index b200501..526ea21 100644
--- a/arch/arm/mach-msm/gpiomux-v2.h
+++ b/arch/arm/mach-msm/gpiomux-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
index 85936ba..7e46134 100644
--- a/arch/arm/mach-msm/gpiomux.c
+++ b/arch/arm/mach-msm/gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/gss-8064.c b/arch/arm/mach-msm/gss-8064.c
index dea1af5..d1f7811 100644
--- a/arch/arm/mach-msm/gss-8064.c
+++ b/arch/arm/mach-msm/gss-8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/headsmp.S b/arch/arm/mach-msm/headsmp.S
index e5ad312..6ae2129 100644
--- a/arch/arm/mach-msm/headsmp.S
+++ b/arch/arm/mach-msm/headsmp.S
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) 2003 ARM Limited
  *  All Rights Reserved
- *  Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2010, 2012 The Linux Foundation. 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
@@ -35,8 +35,6 @@
 	 * we've been released from the holding pen: secondary_stack
 	 * should now contain the SVC stack for this core
 	 */
-	mvn	r7, #0			@ -1 to registers
-	str r7,[r6]			@ back to the pen for ack
 	b	secondary_startup
 ENDPROC(msm_secondary_startup)
 
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index d1d9f4b..5cd5057 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 2002 ARM Ltd.
  *  All Rights Reserved
- *  Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2011-2012, The Linux Foundation. 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
@@ -43,7 +43,7 @@
 {
 }
 
-static inline void platform_do_lowpower(unsigned int cpu)
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
 {
 	/* Just enter wfi for now. TODO: Properly shut off the cpu. */
 	for (;;) {
@@ -53,9 +53,6 @@
 			/*
 			 * OK, proper wakeup, we're done
 			 */
-			pen_release = -1;
-			dmac_flush_range((char *)&pen_release,
-				(char *)&pen_release + sizeof(pen_release));
 			break;
 		}
 
@@ -67,9 +64,7 @@
 		 * possible, since we are currently running incoherently, and
 		 * therefore cannot safely call printk() or anything else
 		 */
-		dmac_inv_range((char *)&pen_release,
-			       (char *)&pen_release + sizeof(pen_release));
-		pr_debug("CPU%u: spurious wakeup call\n", cpu);
+		(*spurious)++;
 	}
 }
 
@@ -85,6 +80,8 @@
  */
 void platform_cpu_die(unsigned int cpu)
 {
+	int spurious = 0;
+
 	if (unlikely(cpu != smp_processor_id())) {
 		pr_crit("%s: running on %u, should be %u\n",
 			__func__, smp_processor_id(), cpu);
@@ -95,10 +92,13 @@
 	 * we're ready for shutdown now, so do it
 	 */
 	cpu_enter_lowpower();
-	platform_do_lowpower(cpu);
+	platform_do_lowpower(cpu, &spurious);
 
 	pr_debug("CPU%u: %s: normal wakeup\n", cpu, __func__);
 	cpu_leave_lowpower();
+
+	if (spurious)
+		pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
 }
 
 int platform_cpu_disable(unsigned int cpu)
diff --git a/arch/arm/mach-msm/hsic_sysmon.c b/arch/arm/mach-msm/hsic_sysmon.c
index 153e1b4..0a9e2e3 100644
--- a/arch/arm/mach-msm/hsic_sysmon.c
+++ b/arch/arm/mach-msm/hsic_sysmon.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -239,7 +239,7 @@
 		if (!hs)
 			continue;
 
-		ret += scnprintf(buf, DEBUG_BUF_SIZE,
+		ret += scnprintf(buf + ret, DEBUG_BUF_SIZE - ret,
 				"---HSIC Sysmon #%d---\n"
 				"epin:%d, epout:%d\n"
 				"bytes to host: %d\n"
@@ -324,15 +324,6 @@
 	struct usb_endpoint_descriptor	*ep_desc;
 	int				i;
 	int				ret = -ENOMEM;
-	__u8				ifc_num;
-
-	pr_debug("id:%lu", id->driver_info);
-
-	ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber;
-
-	/* is this the interface we're looking for? */
-	if (ifc_num != id->driver_info)
-		return -ENODEV;
 
 	hs = kzalloc(sizeof(*hs), GFP_KERNEL);
 	if (!hs) {
@@ -367,12 +358,17 @@
 		goto error;
 	}
 
-	hs->id = HSIC_SYSMON_DEV_EXT_MODEM;
-	hsic_sysmon_devices[HSIC_SYSMON_DEV_EXT_MODEM] = hs;
+	hs->id = HSIC_SYSMON_DEV_EXT_MODEM + id->driver_info;
+	if (hs->id >= NUM_HSIC_SYSMON_DEVS) {
+		pr_warn("invalid dev id(%d)", hs->id);
+		hs->id = 0;
+	}
+
+	hsic_sysmon_devices[hs->id] = hs;
 	usb_set_intfdata(ifc, hs);
 
 	hs->pdev.name = "sys_mon";
-	hs->pdev.id = SYSMON_SS_EXT_MODEM;
+	hs->pdev.id = SYSMON_SS_EXT_MODEM + hs->id;
 	hs->pdev.dev.release = hsic_sysmon_pdev_release;
 	platform_device_register(&hs->pdev);
 
@@ -406,10 +402,11 @@
 	return 0;
 }
 
-/* driver_info maps to the interface number corresponding to sysmon */
+/* driver_info is the instance number when multiple devices are present */
 static const struct usb_device_id hsic_sysmon_ids[] = {
-	{ USB_DEVICE(0x5c6, 0x9048), .driver_info = 1, },
-	{ USB_DEVICE(0x5c6, 0x904C), .driver_info = 1, },
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 1), .driver_info = 0, },
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x904C, 1), .driver_info = 0, },
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9079, 1), .driver_info = 1, },
 	{} /* terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, hsic_sysmon_ids);
diff --git a/arch/arm/mach-msm/hsic_sysmon.h b/arch/arm/mach-msm/hsic_sysmon.h
index aa57b93..9655dc0 100644
--- a/arch/arm/mach-msm/hsic_sysmon.h
+++ b/arch/arm/mach-msm/hsic_sysmon.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013 The Linux Foundation. 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 and
@@ -18,6 +18,7 @@
  */
 enum hsic_sysmon_device_id {
 	HSIC_SYSMON_DEV_EXT_MODEM,
+	HSIC_SYSMON_DEV_EXT_MODEM_2,
 	NUM_HSIC_SYSMON_DEVS
 };
 
diff --git a/arch/arm/mach-msm/hsic_sysmon_test.c b/arch/arm/mach-msm/hsic_sysmon_test.c
index 9929cb7..fac6575 100644
--- a/arch/arm/mach-msm/hsic_sysmon_test.c
+++ b/arch/arm/mach-msm/hsic_sysmon_test.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -15,6 +15,7 @@
 
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
@@ -36,13 +37,14 @@
 				 size_t count, loff_t *ppos)
 {
 	struct sysmon_test_dev *dev = sysmon_dev;
+	enum hsic_sysmon_device_id id =
+				(enum hsic_sysmon_device_id)file->private_data;
 	int ret;
 
 	if (!dev)
 		return -ENODEV;
 
-	ret = hsic_sysmon_read(HSIC_SYSMON_DEV_EXT_MODEM, dev->buf, RD_BUF_SIZE,
-				&dev->buflen, 3000);
+	ret = hsic_sysmon_read(id, dev->buf, RD_BUF_SIZE, &dev->buflen, 3000);
 	if (!ret)
 		return simple_read_from_buffer(ubuf, count, ppos,
 					dev->buf, dev->buflen);
@@ -53,7 +55,9 @@
 static ssize_t sysmon_test_write(struct file *file, const char __user *ubuf,
 				 size_t count, loff_t *ppos)
 {
-	struct sysmon_test_dev	*dev = sysmon_dev;
+	struct sysmon_test_dev *dev = sysmon_dev;
+	enum hsic_sysmon_device_id id =
+				(enum hsic_sysmon_device_id)file->private_data;
 	int ret;
 
 	if (!dev)
@@ -64,8 +68,7 @@
 		return 0;
 	}
 
-	ret = hsic_sysmon_write(HSIC_SYSMON_DEV_EXT_MODEM,
-				dev->buf, count, 1000);
+	ret = hsic_sysmon_write(id, dev->buf, count, 1000);
 	if (ret < 0) {
 		pr_err("error writing to hsic_sysmon");
 		return ret;
@@ -76,38 +79,44 @@
 
 static int sysmon_test_open(struct inode *inode, struct file *file)
 {
-	return hsic_sysmon_open(HSIC_SYSMON_DEV_EXT_MODEM);
+	file->private_data = inode->i_private;
+	return hsic_sysmon_open((enum hsic_sysmon_device_id)inode->i_private);
 }
 
 static int sysmon_test_release(struct inode *inode, struct file *file)
 {
-	hsic_sysmon_close(HSIC_SYSMON_DEV_EXT_MODEM);
+	hsic_sysmon_close((enum hsic_sysmon_device_id)inode->i_private);
 	return 0;
 }
 
-static struct dentry *dfile;
-const struct file_operations sysmon_test_ops = {
+static const struct file_operations sysmon_test_ops = {
 	.read = sysmon_test_read,
 	.write = sysmon_test_write,
 	.open = sysmon_test_open,
 	.release = sysmon_test_release
 };
 
+static struct dentry *dfile0, *dfile1;
+
 static int __init sysmon_test_init(void)
 {
 	sysmon_dev = kzalloc(sizeof(*sysmon_dev), GFP_KERNEL);
 	if (!sysmon_dev)
 		return -ENOMEM;
 
-	dfile = debugfs_create_file("hsic_sysmon_test", 0666, NULL,
-			0, &sysmon_test_ops);
+	dfile0 = debugfs_create_file("hsic_sysmon_test.0", 0666, NULL,
+			(void *)HSIC_SYSMON_DEV_EXT_MODEM, &sysmon_test_ops);
+	dfile1 = debugfs_create_file("hsic_sysmon_test.1", 0666, NULL,
+			(void *)HSIC_SYSMON_DEV_EXT_MODEM_2, &sysmon_test_ops);
 	return 0;
 }
 
 static void __exit sysmon_test_exit(void)
 {
-	if (dfile)
-		debugfs_remove(dfile);
+	if (dfile0)
+		debugfs_remove(dfile0);
+	if (dfile1)
+		debugfs_remove(dfile1);
 	kfree(sysmon_dev);
 }
 
diff --git a/arch/arm/mach-msm/hsic_tty.c b/arch/arm/mach-msm/hsic_tty.c
index 22147ce..dd3db91 100644
--- a/arch/arm/mach-msm/hsic_tty.c
+++ b/arch/arm/mach-msm/hsic_tty.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/hsic_tty.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/idle-macros.S b/arch/arm/mach-msm/idle-macros.S
index 1622e13..3d0c937 100644
--- a/arch/arm/mach-msm/idle-macros.S
+++ b/arch/arm/mach-msm/idle-macros.S
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/idle-v6.S b/arch/arm/mach-msm/idle-v6.S
index 8160877..35db96c 100644
--- a/arch/arm/mach-msm/idle-v6.S
+++ b/arch/arm/mach-msm/idle-v6.S
@@ -3,7 +3,7 @@
  * Work around bugs with SWFI.
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/idle.h b/arch/arm/mach-msm/idle.h
index 456f7fd..ac8bbe9 100644
--- a/arch/arm/mach-msm/idle.h
+++ b/arch/arm/mach-msm/idle.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2009,2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2007-2009,2012 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/idle_stats_device.c b/arch/arm/mach-msm/idle_stats_device.c
index 01b464a..54b8382 100644
--- a/arch/arm/mach-msm/idle_stats_device.c
+++ b/arch/arm/mach-msm/idle_stats_device.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h b/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h
index 1970d0b..bbe4961 100644
--- a/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h
+++ b/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/bam_dmux.h b/arch/arm/mach-msm/include/mach/bam_dmux.h
index f11b72c..5a31525 100644
--- a/arch/arm/mach-msm/include/mach/bam_dmux.h
+++ b/arch/arm/mach-msm/include/mach/bam_dmux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/barriers.h b/arch/arm/mach-msm/include/mach/barriers.h
index 2d4792c..89734ad 100644
--- a/arch/arm/mach-msm/include/mach/barriers.h
+++ b/arch/arm/mach-msm/include/mach/barriers.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/board-msm8660.h b/arch/arm/mach-msm/include/mach/board-msm8660.h
index 22e378c..e1e1b17 100644
--- a/arch/arm/mach-msm/include/mach/board-msm8660.h
+++ b/arch/arm/mach-msm/include/mach/board-msm8660.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 0f1bf5f..46b12e2 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -387,6 +387,9 @@
 	int (*vga_switch)(int select_vga);
 	int *gpio_num;
 	u32 mdp_max_clk;
+	u32 mdp_max_bw;
+	u32 mdp_bw_ab_factor;
+	u32 mdp_bw_ib_factor;
 #ifdef CONFIG_MSM_BUS_SCALING
 	struct msm_bus_scale_pdata *mdp_bus_scale_table;
 #endif
diff --git a/arch/arm/mach-msm/include/mach/board_lge.h b/arch/arm/mach-msm/include/mach/board_lge.h
index 08cfa61..ecee368 100644
--- a/arch/arm/mach-msm/include/mach/board_lge.h
+++ b/arch/arm/mach-msm/include/mach/board_lge.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/include/mach/board_lge.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012, LGE Inc.
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index ae496f9..1518cee 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
index d69b372..3895aff 100644
--- a/arch/arm/mach-msm/include/mach/clk.h
+++ b/arch/arm/mach-msm/include/mach/clk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2012 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/cpufreq.h b/arch/arm/mach-msm/include/mach/cpufreq.h
index 8c2be11..1a6f2d9 100644
--- a/arch/arm/mach-msm/include/mach/cpufreq.h
+++ b/arch/arm/mach-msm/include/mach/cpufreq.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/cpuidle.h b/arch/arm/mach-msm/include/mach/cpuidle.h
index af773a0..fef7a5a 100644
--- a/arch/arm/mach-msm/include/mach/cpuidle.h
+++ b/arch/arm/mach-msm/include/mach/cpuidle.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/dal.h b/arch/arm/mach-msm/include/mach/dal.h
index d0c754d..c28a5e5 100644
--- a/arch/arm/mach-msm/include/mach/dal.h
+++ b/arch/arm/mach-msm/include/mach/dal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/dal_axi.h b/arch/arm/mach-msm/include/mach/dal_axi.h
index 84cd37f..9431060 100644
--- a/arch/arm/mach-msm/include/mach/dal_axi.h
+++ b/arch/arm/mach-msm/include/mach/dal_axi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/debug_mm.h b/arch/arm/mach-msm/include/mach/debug_mm.h
index 091798c..6b27ded 100644
--- a/arch/arm/mach-msm/include/mach/debug_mm.h
+++ b/arch/arm/mach-msm/include/mach/debug_mm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/dma-fsm9xxx.h b/arch/arm/mach-msm/include/mach/dma-fsm9xxx.h
index e284267..c8c6cdf 100644
--- a/arch/arm/mach-msm/include/mach/dma-fsm9xxx.h
+++ b/arch/arm/mach-msm/include/mach/dma-fsm9xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 6a389de..361dce2 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-msm/dma.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -272,6 +272,19 @@
 #define DMOV8064_TSIF_CHAN         2
 #define DMOV8064_TSIF_CRCI         1
 
+/* channels for APQ8064 SGLTE*/
+#define DMOV_APQ8064_HSUART_GSBI4_TX_CHAN	11
+#define DMOV_APQ8064_HSUART_GSBI4_TX_CRCI	8
+
+#define DMOV_APQ8064_HSUART_GSBI4_RX_CHAN	10
+#define DMOV_APQ8064_HSUART_GSBI4_RX_CRCI	7
+
+/* channels for MPQ8064 */
+#define DMOV_MPQ8064_HSUART_GSBI6_TX_CHAN	7
+#define DMOV_MPQ8064_HSUART_GSBI6_TX_CRCI	6
+
+#define DMOV_MPQ8064_HSUART_GSBI6_RX_CHAN	6
+#define DMOV_MPQ8064_HSUART_GSBI6_RX_CRCI	11
 
 /* no client rate control ifc (eg, ram) */
 #define DMOV_NONE_CRCI        0
diff --git a/arch/arm/mach-msm/include/mach/dma_test.h b/arch/arm/mach-msm/include/mach/dma_test.h
index c0464fa..a1b35c1 100644
--- a/arch/arm/mach-msm/include/mach/dma_test.h
+++ b/arch/arm/mach-msm/include/mach/dma_test.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/entry-macro.S b/arch/arm/mach-msm/include/mach/entry-macro.S
index dd1b54d..5b43f2a 100644
--- a/arch/arm/mach-msm/include/mach/entry-macro.S
+++ b/arch/arm/mach-msm/include/mach/entry-macro.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/gpio-tlmm-v1.h b/arch/arm/mach-msm/include/mach/gpio-tlmm-v1.h
index e41fe72..04e5e75 100644
--- a/arch/arm/mach-msm/include/mach/gpio-tlmm-v1.h
+++ b/arch/arm/mach-msm/include/mach/gpio-tlmm-v1.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
  * Author: Mike Lockwood <lockwood@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/gpio-v1.h b/arch/arm/mach-msm/include/mach/gpio-v1.h
index eea4c88..ec62f15 100644
--- a/arch/arm/mach-msm/include/mach/gpio-v1.h
+++ b/arch/arm/mach-msm/include/mach/gpio-v1.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
  * Author: Mike Lockwood <lockwood@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h
index a0bcd2b..3cb2888 100644
--- a/arch/arm/mach-msm/include/mach/gpio.h
+++ b/arch/arm/mach-msm/include/mach/gpio.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Mike Lockwood <lockwood@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/gpiomux.h b/arch/arm/mach-msm/include/mach/gpiomux.h
index f75b0e0..3900df4 100644
--- a/arch/arm/mach-msm/include/mach/gpiomux.h
+++ b/arch/arm/mach-msm/include/mach/gpiomux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/hardware.h b/arch/arm/mach-msm/include/mach/hardware.h
index 7b7cbaa..fbf289e 100644
--- a/arch/arm/mach-msm/include/mach/hardware.h
+++ b/arch/arm/mach-msm/include/mach/hardware.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/include/mach/hardware.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index e929189..3c44fad 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/iommu_domains.h b/arch/arm/mach-msm/include/mach/iommu_domains.h
index 1d538f2..59d430f 100644
--- a/arch/arm/mach-msm/include/mach/iommu_domains.h
+++ b/arch/arm/mach-msm/include/mach/iommu_domains.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
index af82fd9..3ed4b16 100644
--- a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-v2.h b/arch/arm/mach-msm/include/mach/iommu_hw-v2.h
index b01dbd8..e2ae9c3 100644
--- a/arch/arm/mach-msm/include/mach/iommu_hw-v2.h
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/ion.h b/arch/arm/mach-msm/include/mach/ion.h
index 9fbc720..b472d27 100644
--- a/arch/arm/mach-msm/include/mach/ion.h
+++ b/arch/arm/mach-msm/include/mach/ion.h
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x00.h b/arch/arm/mach-msm/include/mach/irqs-7x00.h
index a8e1da2..5b39c4c 100644
--- a/arch/arm/mach-msm/include/mach/irqs-7x00.h
+++ b/arch/arm/mach-msm/include/mach/irqs-7x00.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  */
 
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x30.h b/arch/arm/mach-msm/include/mach/irqs-7x30.h
index a624bbf..d88fa17 100644
--- a/arch/arm/mach-msm/include/mach/irqs-7x30.h
+++ b/arch/arm/mach-msm/include/mach/irqs-7x30.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-7xxx.h b/arch/arm/mach-msm/include/mach/irqs-7xxx.h
index c90b4ee..f4f894d 100644
--- a/arch/arm/mach-msm/include/mach/irqs-7xxx.h
+++ b/arch/arm/mach-msm/include/mach/irqs-7xxx.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  */
 
diff --git a/arch/arm/mach-msm/include/mach/irqs-8064.h b/arch/arm/mach-msm/include/mach/irqs-8064.h
index 973034b..4c48372 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8064.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8064.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-8625.h b/arch/arm/mach-msm/include/mach/irqs-8625.h
index 413a778..a8b2716 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8625.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8625.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-8930.h b/arch/arm/mach-msm/include/mach/irqs-8930.h
index bfc32f6..6648548 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8930.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8930.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-8960.h b/arch/arm/mach-msm/include/mach/irqs-8960.h
index 012dd74..08b1d47 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8960.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8960.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-8974.h b/arch/arm/mach-msm/include/mach/irqs-8974.h
index d10b537..135ba83 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8974.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8974.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x50.h b/arch/arm/mach-msm/include/mach/irqs-8x50.h
index f0d70f9..7f62ee4 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8x50.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8x50.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x60.h b/arch/arm/mach-msm/include/mach/irqs-8x60.h
index c9729f4..8d3f0c5 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8x60.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8x60.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-9615.h b/arch/arm/mach-msm/include/mach/irqs-9615.h
index 39058a6..a034af2 100644
--- a/arch/arm/mach-msm/include/mach/irqs-9615.h
+++ b/arch/arm/mach-msm/include/mach/irqs-9615.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-9625.h b/arch/arm/mach-msm/include/mach/irqs-9625.h
index f50606d..9d745bb 100644
--- a/arch/arm/mach-msm/include/mach/irqs-9625.h
+++ b/arch/arm/mach-msm/include/mach/irqs-9625.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h b/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h
index 721db1d..5b36bde 100644
--- a/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h
+++ b/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h
index 63c81a8..e49484d 100644
--- a/arch/arm/mach-msm/include/mach/irqs.h
+++ b/arch/arm/mach-msm/include/mach/irqs.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/kgsl.h b/arch/arm/mach-msm/include/mach/kgsl.h
index a51cc46..a22b628 100644
--- a/arch/arm/mach-msm/include/mach/kgsl.h
+++ b/arch/arm/mach-msm/include/mach/kgsl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/lge/board_mako.h b/arch/arm/mach-msm/include/mach/lge/board_mako.h
index 947ea54..992c0d1 100644
--- a/arch/arm/mach-msm/include/mach/lge/board_mako.h
+++ b/arch/arm/mach-msm/include/mach/lge/board_mako.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/include/mach/board_mako.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012, LGE.
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/include/mach/mdm-peripheral.h b/arch/arm/mach-msm/include/mach/mdm-peripheral.h
index 0f3bd33..ef44659 100644
--- a/arch/arm/mach-msm/include/mach/mdm-peripheral.h
+++ b/arch/arm/mach-msm/include/mach/mdm-peripheral.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/mdm.h b/arch/arm/mach-msm/include/mach/mdm.h
index f0100fe..9757d31 100644
--- a/arch/arm/mach-msm/include/mach/mdm.h
+++ b/arch/arm/mach-msm/include/mach/mdm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/mdm2.h b/arch/arm/mach-msm/include/mach/mdm2.h
index c6c03e4..1afc763 100644
--- a/arch/arm/mach-msm/include/mach/mdm2.h
+++ b/arch/arm/mach-msm/include/mach/mdm2.h
@@ -12,7 +12,7 @@
 
 #ifndef _ARCH_ARM_MACH_MSM_MDM2_H
 #define _ARCH_ARM_MACH_MSM_MDM2_H
-#include "sysmon.h"
+#include "../../sysmon.h"
 
 struct mdm_vddmin_resource {
 	int rpm_id;
@@ -39,6 +39,10 @@
 	int cascading_ssr;
 	int sysmon_subsys_id_valid;
 	enum subsys_id sysmon_subsys_id;
+	int no_a2m_errfatal_on_ssr;
+	int no_reset_on_first_powerup;
+	int kpd_not_inverted;
+	char *subsys_name;
 };
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index 1cfbb38..18518b7 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/include/mach/memory.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -75,14 +75,9 @@
 void clean_and_invalidate_caches(unsigned long, unsigned long, unsigned long);
 void clean_caches(unsigned long, unsigned long, unsigned long);
 void invalidate_caches(unsigned long, unsigned long, unsigned long);
-int platform_physical_remove_pages(u64, u64);
-int platform_physical_active_pages(u64, u64);
-int platform_physical_low_power_pages(u64, u64);
 int msm_get_memory_type_from_name(const char *memtype_name);
 unsigned long get_ddr_size(void);
 
-extern int (*change_memory_power)(u64, u64, int);
-
 #if defined(CONFIG_ARCH_MSM_ARM11) || defined(CONFIG_ARCH_MSM_CORTEX_A5)
 void write_to_strongly_ordered_memory(void);
 void map_page_strongly_ordered(void);
diff --git a/arch/arm/mach-msm/include/mach/mpm.h b/arch/arm/mach-msm/include/mach/mpm.h
index fabaa09..b92c039 100644
--- a/arch/arm/mach-msm/include/mach/mpm.h
+++ b/arch/arm/mach-msm/include/mach/mpm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/mpp.h b/arch/arm/mach-msm/include/mach/mpp.h
index 8ac1f54..040312c 100644
--- a/arch/arm/mach-msm/include/mach/mpp.h
+++ b/arch/arm/mach-msm/include/mach/mpp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm-krait-l2-accessors.h b/arch/arm/mach-msm/include/mach/msm-krait-l2-accessors.h
index f835e82..e7e3619 100644
--- a/arch/arm/mach-msm/include/mach/msm-krait-l2-accessors.h
+++ b/arch/arm/mach-msm/include/mach/msm-krait-l2-accessors.h
@@ -2,7 +2,7 @@
 #define __ASM_ARCH_MSM_MSM_KRAIT_L2_ACCESSORS_H
 
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm72k_otg.h b/arch/arm/mach-msm/include/mach/msm72k_otg.h
index 623de2a..b2e0304 100644
--- a/arch/arm/mach-msm/include/mach/msm72k_otg.h
+++ b/arch/arm/mach-msm/include/mach/msm72k_otg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_adsp.h b/arch/arm/mach-msm/include/mach/msm_adsp.h
index e40c07d..28b851a 100644
--- a/arch/arm/mach-msm/include/mach/msm_adsp.h
+++ b/arch/arm/mach-msm/include/mach/msm_adsp.h
@@ -1,7 +1,7 @@
 /* include/asm-arm/arch-msm/msm_adsp.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_audio_aac.h b/arch/arm/mach-msm/include/mach/msm_audio_aac.h
index 8c4d91b..ac54173 100644
--- a/arch/arm/mach-msm/include/mach/msm_audio_aac.h
+++ b/arch/arm/mach-msm/include/mach/msm_audio_aac.h
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/include/mach/msm_audio_aac.h
  *
- * Copyright (c) 2009 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_battery.h b/arch/arm/mach-msm/include/mach/msm_battery.h
index fe496d5..959d8a8 100644
--- a/arch/arm/mach-msm/include/mach/msm_battery.h
+++ b/arch/arm/mach-msm/include/mach/msm_battery.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_bus.h b/arch/arm/mach-msm/include/mach/msm_bus.h
index 6b94a43..41b46a9 100644
--- a/arch/arm/mach-msm/include/mach/msm_bus.h
+++ b/arch/arm/mach-msm/include/mach/msm_bus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_bus_board.h b/arch/arm/mach-msm/include/mach/msm_bus_board.h
index 0a53b46..bc073cd 100644
--- a/arch/arm/mach-msm/include/mach/msm_bus_board.h
+++ b/arch/arm/mach-msm/include/mach/msm_bus_board.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_cache_dump.h b/arch/arm/mach-msm/include/mach/msm_cache_dump.h
index 80f4159..a79bcbd 100644
--- a/arch/arm/mach-msm/include/mach/msm_cache_dump.h
+++ b/arch/arm/mach-msm/include/mach/msm_cache_dump.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_dsps.h b/arch/arm/mach-msm/include/mach/msm_dsps.h
index a876798..fcc72fc 100644
--- a/arch/arm/mach-msm/include/mach/msm_dsps.h
+++ b/arch/arm/mach-msm/include/mach/msm_dsps.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_gpiomux.h b/arch/arm/mach-msm/include/mach/msm_gpiomux.h
index 0c7d393..b70a449 100644
--- a/arch/arm/mach-msm/include/mach/msm_gpiomux.h
+++ b/arch/arm/mach-msm/include/mach/msm_gpiomux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h b/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h
index 2455e93..28ba9fe 100644
--- a/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h
+++ b/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb.h b/arch/arm/mach-msm/include/mach/msm_hsusb.h
index 4e22b0f..1dd7a7d 100644
--- a/arch/arm/mach-msm/include/mach/msm_hsusb.h
+++ b/arch/arm/mach-msm/include/mach/msm_hsusb.h
@@ -1,7 +1,7 @@
 /* linux/include/mach/hsusb.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb_hw.h b/arch/arm/mach-msm/include/mach/msm_hsusb_hw.h
index 82542b2..b96372e 100644
--- a/arch/arm/mach-msm/include/mach/msm_hsusb_hw.h
+++ b/arch/arm/mach-msm/include/mach/msm_hsusb_hw.h
@@ -1,6 +1,6 @@
  /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_i2ckbd.h b/arch/arm/mach-msm/include/mach/msm_i2ckbd.h
index dc33c75..ba42b15 100644
--- a/arch/arm/mach-msm/include/mach/msm_i2ckbd.h
+++ b/arch/arm/mach-msm/include/mach/msm_i2ckbd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
index dfc6f23..4f3d969 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012 The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
index 4c26d08..ae7334e 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
index 08b45cd..8058a27 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8625.h b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
index 43250f5..5cc544a 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8930.h b/arch/arm/mach-msm/include/mach/msm_iomap-8930.h
index f3f8b8f..456c39d 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8930.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8930.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
index 2cea3c3..2329540 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8974.h b/arch/arm/mach-msm/include/mach/msm_iomap-8974.h
index 1458afe..978ffd1 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8974.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8974.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
index a1b32ec..281b602 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
index 17156b1..9d04f31 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-9615.h b/arch/arm/mach-msm/include/mach/msm_iomap-9615.h
index fc9b198..c815294 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-9615.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-9615.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-9625.h b/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
index 493cf36..d81915d 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-9625.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h b/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h
index a99f1f7..9b4204d 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 4c849d4..893f9c0 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_ipc_logging.h b/arch/arm/mach-msm/include/mach/msm_ipc_logging.h
index 0a203a5..ec9fdb0 100644
--- a/arch/arm/mach-msm/include/mach/msm_ipc_logging.h
+++ b/arch/arm/mach-msm/include/mach/msm_ipc_logging.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -185,47 +185,49 @@
 				      struct decode_context *));
 #else
 
-void *ipc_log_context_create(int max_num_pages, const char *modname)
+static inline void *ipc_log_context_create(int max_num_pages,
+	const char *modname)
 { return NULL; }
 
-void msg_encode_start(struct encode_context *ectxt, uint32_t type) { }
+static inline void msg_encode_start(struct encode_context *ectxt,
+	uint32_t type) { }
 
-int tsv_timestamp_write(struct encode_context *ectxt)
+static inline int tsv_timestamp_write(struct encode_context *ectxt)
 { return -EINVAL; }
 
-int tsv_pointer_write(struct encode_context *ectxt, void *pointer)
+static inline int tsv_pointer_write(struct encode_context *ectxt, void *pointer)
 { return -EINVAL; }
 
-int tsv_int32_write(struct encode_context *ectxt, int32_t n)
+static inline int tsv_int32_write(struct encode_context *ectxt, int32_t n)
 { return -EINVAL; }
 
-int tsv_byte_array_write(struct encode_context *ectxt,
+static inline int tsv_byte_array_write(struct encode_context *ectxt,
 			 void *data, int data_size)
 { return -EINVAL; }
 
-void msg_encode_end(struct encode_context *ectxt) { }
+static inline void msg_encode_end(struct encode_context *ectxt) { }
 
-void ipc_log_write(void *ctxt, struct encode_context *ectxt) { }
+static inline void ipc_log_write(void *ctxt, struct encode_context *ectxt) { }
 
-int ipc_log_string(void *ilctxt, const char *fmt, ...)
+static inline int ipc_log_string(void *ilctxt, const char *fmt, ...)
 { return -EINVAL; }
 
 #define IPC_SPRINTF_DECODE(dctxt, args...) do { } while (0)
 
-void tsv_timestamp_read(struct encode_context *ectxt,
+static inline void tsv_timestamp_read(struct encode_context *ectxt,
 			struct decode_context *dctxt, const char *format) { }
 
-void tsv_pointer_read(struct encode_context *ectxt,
+static inline void tsv_pointer_read(struct encode_context *ectxt,
 		      struct decode_context *dctxt, const char *format) { }
 
-int32_t tsv_int32_read(struct encode_context *ectxt,
+static inline int32_t tsv_int32_read(struct encode_context *ectxt,
 		       struct decode_context *dctxt, const char *format)
 { return 0; }
 
-void tsv_byte_array_read(struct encode_context *ectxt,
+static inline void tsv_byte_array_read(struct encode_context *ectxt,
 			 struct decode_context *dctxt, const char *format) { }
 
-int add_deserialization_func(void *ctxt, int type,
+static inline int add_deserialization_func(void *ctxt, int type,
 			void (*dfunc)(struct encode_context *,
 				      struct decode_context *))
 { return 0; }
diff --git a/arch/arm/mach-msm/include/mach/msm_memory_dump.h b/arch/arm/mach-msm/include/mach/msm_memory_dump.h
index 5e686bf..7fd5c3a 100644
--- a/arch/arm/mach-msm/include/mach/msm_memory_dump.h
+++ b/arch/arm/mach-msm/include/mach/msm_memory_dump.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_memtypes.h b/arch/arm/mach-msm/include/mach/msm_memtypes.h
index 5ca5861..fbb3aa9 100644
--- a/arch/arm/mach-msm/include/mach/msm_memtypes.h
+++ b/arch/arm/mach-msm/include/mach/msm_memtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
@@ -29,7 +29,6 @@
 unsigned int get_num_memory_banks(void);
 unsigned int get_memory_bank_size(unsigned int);
 unsigned int get_memory_bank_start(unsigned int);
-int soc_change_memory_power(u64, u64, int);
 
 enum {
 	MEMTYPE_NONE = -1,
diff --git a/arch/arm/mach-msm/include/mach/msm_migrate_pages.h b/arch/arm/mach-msm/include/mach/msm_migrate_pages.h
index 5812a64..51d98ba 100644
--- a/arch/arm/mach-msm/include/mach/msm_migrate_pages.h
+++ b/arch/arm/mach-msm/include/mach/msm_migrate_pages.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_otg.h b/arch/arm/mach-msm/include/mach/msm_otg.h
index 178b65a..9d30cb9 100644
--- a/arch/arm/mach-msm/include/mach/msm_otg.h
+++ b/arch/arm/mach-msm/include/mach/msm_otg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_pcie.h b/arch/arm/mach-msm/include/mach/msm_pcie.h
index 74f0f5b..06b7e87 100644
--- a/arch/arm/mach-msm/include/mach/msm_pcie.h
+++ b/arch/arm/mach-msm/include/mach/msm_pcie.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_qdsp6_audiov2.h b/arch/arm/mach-msm/include/mach/msm_qdsp6_audiov2.h
index 90a6b56..f862c36 100644
--- a/arch/arm/mach-msm/include/mach/msm_qdsp6_audiov2.h
+++ b/arch/arm/mach-msm/include/mach/msm_qdsp6_audiov2.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/include/mach/msm_qdsp6_audio.h
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/include/mach/msm_rotator_imem.h b/arch/arm/mach-msm/include/mach/msm_rotator_imem.h
index 580bc81..c027ab7 100644
--- a/arch/arm/mach-msm/include/mach/msm_rotator_imem.h
+++ b/arch/arm/mach-msm/include/mach/msm_rotator_imem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_rpcrouter.h b/arch/arm/mach-msm/include/mach/msm_rpcrouter.h
index 28841a9..b055e94 100644
--- a/arch/arm/mach-msm/include/mach/msm_rpcrouter.h
+++ b/arch/arm/mach-msm/include/mach/msm_rpcrouter.h
@@ -1,7 +1,7 @@
 /** include/asm-arm/arch-msm/msm_rpcrouter.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2011, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_rtb.h b/arch/arm/mach-msm/include/mach/msm_rtb.h
index 74ddfbd..19d171e 100644
--- a/arch/arm/mach-msm/include/mach/msm_rtb.h
+++ b/arch/arm/mach-msm/include/mach/msm_rtb.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_serial_hs.h b/arch/arm/mach-msm/include/mach/msm_serial_hs.h
index d2905d4..d4223d1 100644
--- a/arch/arm/mach-msm/include/mach/msm_serial_hs.h
+++ b/arch/arm/mach-msm/include/mach/msm_serial_hs.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2010-2013, The Linux Foundation. All rights reserved.
  * Author: Nick Pelly <npelly@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -17,14 +18,32 @@
 
 #include<linux/serial_core.h>
 
-/* Optional platform device data for msm_serial_hs driver.
- * Used to configure low power wakeup */
+/**
+ * struct msm_serial_hs_platform_data - platform device data
+ *                                      for msm hsuart device
+ * @wakeup_irq : IRQ line to be configured as Wakeup source.
+ * @inject_rx_on_wakeup : Set 1 if specific character to be inserted on wakeup
+ * @rx_to_inject : Character to be inserted on wakeup
+ * @config_gpio : Pass number of GPIOs to configure
+		 (2 for 2-wire UART, 4 for 4-wire UART)
+ * @userid : User-defined number to be used to enumerate device as tty<userid>
+ * @uart_tx_gpio: GPIO number for UART Tx Line.
+ * @uart_rx_gpio: GPIO number for UART Rx Line.
+ * @uart_cts_gpio: GPIO number for UART CTS Line.
+ * @uart_rfr_gpio: GPIO number for UART RFR Line.
+ * @userid: Number to be used as ttyHS<userid> instead of ttyHS<id>
+*/
+
 struct msm_serial_hs_platform_data {
 	int wakeup_irq;  /* wakeup irq */
 	/* bool: inject char into rx tty on wakeup */
 	unsigned char inject_rx_on_wakeup;
 	char rx_to_inject;
-	int (*gpio_config)(int);
+	unsigned config_gpio;
+	int uart_tx_gpio;
+	int uart_rx_gpio;
+	int uart_cts_gpio;
+	int uart_rfr_gpio;
 	int userid;
 };
 
diff --git a/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h b/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h
index 577a097..7a24190 100644
--- a/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h
+++ b/arch/arm/mach-msm/include/mach/msm_serial_hs_lite.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013 The Linux Foundation. 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 and
@@ -13,11 +13,30 @@
 
 #ifndef __ASM_ARCH_MSM_SERIAL_HS_LITE_H
 #define __ASM_ARCH_MSM_SERIAL_HS_LITE_H
-
+/**
+ * struct msm_serial_hslite_platform_data - platform device data
+ *              for msm_hs_lite.
+ * @config_gpio: Select GPIOs to configure.
+ *		Set 4 if 4-wire UART used (for Tx, Rx, CTS, RFR GPIOs).
+ *		Set 1 if 2-wire UART used (for Tx, Rx GPIOs).
+ * @uart_tx_gpio: GPIO number for UART Tx Line.
+ * @uart_rx_gpio: GPIO number for UART Rx Line.
+ * @uart_cts_gpio: GPIO number for UART CTS Line.
+ * @uart_rfr_gpio: GPIO number for UART RFR Line.
+ * @set_uart_clk_zero: use this if setting UART Clock to zero is required
+ * It is mainly required where same UART is used across different processor.
+ * Make sure that Clock driver for platform support setting clock rate to zero.
+ * @use_pm: use this to enable power management
+ * @line: Used to set UART Port number.
+ */
 struct msm_serial_hslite_platform_data {
 	unsigned config_gpio;
 	unsigned uart_tx_gpio;
 	unsigned uart_rx_gpio;
+	unsigned uart_cts_gpio;
+	unsigned uart_rfr_gpio;
+	bool set_uart_clk_zero;
+	bool use_pm;
 	int line;
 };
 
diff --git a/arch/arm/mach-msm/include/mach/msm_serial_hsl_regs.h b/arch/arm/mach-msm/include/mach/msm_serial_hsl_regs.h
index b465b56..774c91d 100644
--- a/arch/arm/mach-msm/include/mach/msm_serial_hsl_regs.h
+++ b/arch/arm/mach-msm/include/mach/msm_serial_hsl_regs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_serial_pdata.h b/arch/arm/mach-msm/include/mach/msm_serial_pdata.h
index 4153cb2..7d2fb40 100644
--- a/arch/arm/mach-msm/include/mach/msm_serial_pdata.h
+++ b/arch/arm/mach-msm/include/mach/msm_serial_pdata.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
index 0c452f8..2748636 100644
--- a/arch/arm/mach-msm/include/mach/msm_smd.h
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -1,7 +1,7 @@
 /* linux/include/asm-arm/arch-msm/msm_smd.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index 53fca91..c053192 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_spi.h b/arch/arm/mach-msm/include/mach/msm_spi.h
index 11d3014..e469e9f 100644
--- a/arch/arm/mach-msm/include/mach/msm_spi.h
+++ b/arch/arm/mach-msm/include/mach/msm_spi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_sps.h b/arch/arm/mach-msm/include/mach/msm_sps.h
index 3af6f71..da12ced 100644
--- a/arch/arm/mach-msm/include/mach/msm_sps.h
+++ b/arch/arm/mach-msm/include/mach/msm_sps.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_subsystem_map.h b/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
index ebb2327..3119023 100644
--- a/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
+++ b/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_touch.h b/arch/arm/mach-msm/include/mach/msm_touch.h
index 763d6a8..cd895d4 100644
--- a/arch/arm/mach-msm/include/mach/msm_touch.h
+++ b/arch/arm/mach-msm/include/mach/msm_touch.h
@@ -2,7 +2,7 @@
  *
  * Platform data for MSM touchscreen driver.
  *
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/msm_touchpad.h b/arch/arm/mach-msm/include/mach/msm_touchpad.h
index 4b2d537..2cc6e05 100644
--- a/arch/arm/mach-msm/include/mach/msm_touchpad.h
+++ b/arch/arm/mach-msm/include/mach/msm_touchpad.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_tsif.h b/arch/arm/mach-msm/include/mach/msm_tsif.h
index 62595e3..d260ec1 100644
--- a/arch/arm/mach-msm/include/mach/msm_tsif.h
+++ b/arch/arm/mach-msm/include/mach/msm_tsif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/msm_xo.h b/arch/arm/mach-msm/include/mach/msm_xo.h
index f9795b4..f9ccfee 100644
--- a/arch/arm/mach-msm/include/mach/msm_xo.h
+++ b/arch/arm/mach-msm/include/mach/msm_xo.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/ocmem.h b/arch/arm/mach-msm/include/mach/ocmem.h
index 904de5e..753443b 100644
--- a/arch/arm/mach-msm/include/mach/ocmem.h
+++ b/arch/arm/mach-msm/include/mach/ocmem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/ocmem_priv.h b/arch/arm/mach-msm/include/mach/ocmem_priv.h
index e963c88..d581c13 100644
--- a/arch/arm/mach-msm/include/mach/ocmem_priv.h
+++ b/arch/arm/mach-msm/include/mach/ocmem_priv.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/oem_rapi_client.h b/arch/arm/mach-msm/include/mach/oem_rapi_client.h
index d7a2416..374124f 100644
--- a/arch/arm/mach-msm/include/mach/oem_rapi_client.h
+++ b/arch/arm/mach-msm/include/mach/oem_rapi_client.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/peripheral-loader.h b/arch/arm/mach-msm/include/mach/peripheral-loader.h
index 327c82f..64538dd 100644
--- a/arch/arm/mach-msm/include/mach/peripheral-loader.h
+++ b/arch/arm/mach-msm/include/mach/peripheral-loader.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/pmic.h b/arch/arm/mach-msm/include/mach/pmic.h
index b143a59..03b523b 100644
--- a/arch/arm/mach-msm/include/mach/pmic.h
+++ b/arch/arm/mach-msm/include/mach/pmic.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/proc_comm.h b/arch/arm/mach-msm/include/mach/proc_comm.h
index 8a0a218..655692a 100644
--- a/arch/arm/mach-msm/include/mach/proc_comm.h
+++ b/arch/arm/mach-msm/include/mach/proc_comm.h
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/include/mach/proc_comm.h
  *
- * Copyright (c) 2007-2009,2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2009,2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaycmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaycmdi.h
index 575a286..67ee549 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaycmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaycmdi.h
@@ -17,7 +17,7 @@
     Send buffer to AUDPLAY task
 	
   
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaymsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaymsg.h
index 0bf2468..e79554a 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaymsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audplaymsg.h
@@ -12,7 +12,7 @@
   None
 
   
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
index 3115299..83fea39 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright(c) 1992-2009, 2012 Code Aurora Forum. All rights reserved.
+Copyright(c) 1992-2009, 2012 The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h
index 0ba8261..746b98e 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppmsg.h
@@ -14,7 +14,7 @@
 EXTERNALIZED FUNCTIONS
   None  
   
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h
index 234c4ac..ae1bc27 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h
index 8efc916..fd3b3d9 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreproccmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h
index 0696066..d91b046 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audpreprocmsg.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audreccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audreccmdi.h
index 5045de0..72f12c9 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audreccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audreccmdi.h
@@ -15,7 +15,7 @@
  * EXTERNALIZED FUNCTIONS
  *  None
  *
- * Copyright (c) 1992-2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 1992-2009, 2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audrecmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audrecmsg.h
index 339e4f7..22bdaa2 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audrecmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audrecmsg.h
@@ -15,7 +15,7 @@
  * EXTERNALIZED FUNCTIONS
  *  None
  *
- * Copyright (c) 1992-2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 1992-2009, 2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegcmdi.h
index 7f25f47..40e96d7 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegcmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegmsg.h
index 993af42..9b5ce77 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5jpegmsg.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmcmdi.h
index 4ab6cbf4..3d4fe56 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmcmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmmsg.h
index 68f8874..81f766d 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5lpmmsg.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtcmdi.h
index 7a66b68..9b9521f 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtcmdi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtmsg.h
index a890e76..4e7ed33 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5rmtmsg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdeccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdeccmdi.h
index 1064b17..89af4aa 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdeccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdeccmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdecmsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdecmsg.h
index 2d3ab89..ccd129d 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdecmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vdecmsg.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5venccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5venccmdi.h
index b3c018f..34e00a6 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5venccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5venccmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
 *====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
 /*===========================================================================
 
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfecmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfecmdi.h
index 4c5d752..18ea21c 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfecmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfecmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfemsg.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfemsg.h
index a628f92..7d7f731 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfemsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5vfemsg.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/snd_adie.h b/arch/arm/mach-msm/include/mach/qdsp5/snd_adie.h
index bf1714e..2bad3b0 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/snd_adie.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/snd_adie.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/acdb_commands.h b/arch/arm/mach-msm/include/mach/qdsp5v2/acdb_commands.h
index 2e6fcdb..9386307 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/acdb_commands.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/acdb_commands.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/adie_marimba.h b/arch/arm/mach-msm/include/mach/qdsp5v2/adie_marimba.h
index 919da65..1851322 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/adie_marimba.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/adie_marimba.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/afe.h b/arch/arm/mach-msm/include/mach/qdsp5v2/afe.h
index c15facc..e4e2933 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/afe.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/afe.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdb_def.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdb_def.h
index a2a15dc..0a0c308 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdb_def.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdb_def.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010 - 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010 - 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdbi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdbi.h
index 559073c..f05ebaa 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdbi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_acdbi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_def.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_def.h
index 236c6f6..35a4d5c 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_def.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_def.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009,2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009,2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_dev_ctl.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_dev_ctl.h
index 7c0abcc..976d9ae 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_dev_ctl.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_dev_ctl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_interct.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_interct.h
index 2a7b89e..2690bf5 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audio_interct.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audio_interct.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audpp.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audpp.h
index bdec256..763a651 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audpp.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audpp.h
@@ -1,7 +1,7 @@
 /*arch/arm/mach-msm/qdsp5iv2/audpp.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/audpreproc.h b/arch/arm/mach-msm/include/mach/qdsp5v2/audpreproc.h
index 6abeae1..16a0a8f 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/audpreproc.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/audpreproc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/aux_pcm.h b/arch/arm/mach-msm/include/mach/qdsp5v2/aux_pcm.h
index 100ddea..d9b9427 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/aux_pcm.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/aux_pcm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h b/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
index 92dfe12..f780441 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa.h b/arch/arm/mach-msm/include/mach/qdsp5v2/lpa.h
index d71cf72..d9d9ab1 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/lpa.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa_hw.h b/arch/arm/mach-msm/include/mach/qdsp5v2/lpa_hw.h
index bfff384..beb4aee 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/lpa_hw.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/lpa_hw.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/marimba_profile.h b/arch/arm/mach-msm/include/mach/qdsp5v2/marimba_profile.h
index c1cb3fe..7e455a1 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/marimba_profile.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/marimba_profile.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011,  Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011,  The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/mi2s.h b/arch/arm/mach-msm/include/mach/qdsp5v2/mi2s.h
index e304e25..2106bfc 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/mi2s.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/mi2s.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/mp3_funcs.h b/arch/arm/mach-msm/include/mach/qdsp5v2/mp3_funcs.h
index ac06d3b..b3f7c54 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/mp3_funcs.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/mp3_funcs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/msm_lpa.h b/arch/arm/mach-msm/include/mach/qdsp5v2/msm_lpa.h
index 0dced94..cdfa19b 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/msm_lpa.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/msm_lpa.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/pcm_funcs.h b/arch/arm/mach-msm/include/mach/qdsp5v2/pcm_funcs.h
index fa65000..b8fe2ba 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/pcm_funcs.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/pcm_funcs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afecmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afecmdi.h
index 25fe3a0..b4ff5b8 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afecmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afecmdi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afemsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afemsg.h
index 16134e3..292683a 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afemsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5afemsg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaycmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaycmdi.h
index 53128d3..dad7fab 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaycmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaycmdi.h
@@ -16,7 +16,7 @@
   Send buffer to AUDPLAY task
 
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaymsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaymsg.h
index 2eeb557..653f0e7 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaymsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audplaymsg.h
@@ -11,7 +11,7 @@
   None
 
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppcmdi.h
index 0416f52..bdcf5d8 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppcmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright(c) 1992-2011, Code Aurora Forum. All rights reserved.
+Copyright(c) 1992-2011, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppmsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppmsg.h
index b27bd83..300232d 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audppmsg.h
@@ -14,7 +14,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright (c) 1992-2009, The Linux Foundation. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreproccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreproccmdi.h
index f579e1a..3d5cf84 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreproccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreproccmdi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreprocmsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreprocmsg.h
index 29da664..d3efbcd 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreprocmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audpreprocmsg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audreccmdi.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audreccmdi.h
index 9ba8645..49642df 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audreccmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audreccmdi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audrecmsg.h b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audrecmsg.h
index 32ccbbc..eb46235 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audrecmsg.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/qdsp5audrecmsg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_ecodec.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_ecodec.h
index 35c1edb..8e7d96c 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_ecodec.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_ecodec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_icodec.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_icodec.h
index 7f9938e..7a811a0 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_icodec.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_icodec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_mi2s.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_mi2s.h
index cd834a5..a8f5234 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_mi2s.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_mi2s.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_virtual.h b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_virtual.h
index 695b19d..639e981 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_virtual.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/snddev_virtual.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/voice.h b/arch/arm/mach-msm/include/mach/qdsp5v2/voice.h
index 5ca2d6d..93f9bad 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/voice.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
index 296f222..f3024cb 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_tal.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_tal.h
index 163ba7b..dd64424 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_tal.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_tal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
index 487e814..3145d26 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
index 3d33350..be190f9 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
index 20c6fc4..6b2d7cc 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_dev_ctl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/dsp_debug.h b/arch/arm/mach-msm/include/mach/qdsp6v2/dsp_debug.h
index 94f4ab4..bc1cd9e 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/dsp_debug.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/dsp_debug.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
index 674cfe8..7165998 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h b/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
index f5bea31..07be428 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
index f747a80..ff39929 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/qpnp-int.h b/arch/arm/mach-msm/include/mach/qpnp-int.h
index 21d95e6..8818bf2 100644
--- a/arch/arm/mach-msm/include/mach/qpnp-int.h
+++ b/arch/arm/mach-msm/include/mach/qpnp-int.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/remote_spinlock.h b/arch/arm/mach-msm/include/mach/remote_spinlock.h
index 75b70f3..16f78aa 100644
--- a/arch/arm/mach-msm/include/mach/remote_spinlock.h
+++ b/arch/arm/mach-msm/include/mach/remote_spinlock.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2011 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/restart.h b/arch/arm/mach-msm/include/mach/restart.h
index 4d7b558..618f94a 100644
--- a/arch/arm/mach-msm/include/mach/restart.h
+++ b/arch/arm/mach-msm/include/mach/restart.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpc_hsusb.h b/arch/arm/mach-msm/include/mach/rpc_hsusb.h
index 88d7650..9627e2b 100644
--- a/arch/arm/mach-msm/include/mach/rpc_hsusb.h
+++ b/arch/arm/mach-msm/include/mach/rpc_hsusb.h
@@ -1,6 +1,6 @@
 /* linux/include/mach/rpc_hsusb.h
  *
- * Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/arch/arm/mach-msm/include/mach/rpc_pmapp.h b/arch/arm/mach-msm/include/mach/rpc_pmapp.h
index 86f04bf..5a62f1d 100644
--- a/arch/arm/mach-msm/include/mach/rpc_pmapp.h
+++ b/arch/arm/mach-msm/include/mach/rpc_pmapp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpc_server_handset.h b/arch/arm/mach-msm/include/mach/rpc_server_handset.h
index e1dc841..ac28ad0 100644
--- a/arch/arm/mach-msm/include/mach/rpc_server_handset.h
+++ b/arch/arm/mach-msm/include/mach/rpc_server_handset.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-8064.h b/arch/arm/mach-msm/include/mach/rpm-8064.h
index 39ec7ff..69c6b1e 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8064.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8064.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-8660.h b/arch/arm/mach-msm/include/mach/rpm-8660.h
index 5e3b404..a9fdcbe 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8660.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8660.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-8930.h b/arch/arm/mach-msm/include/mach/rpm-8930.h
index bc1b918..02696c9 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8930.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8930.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-8960.h b/arch/arm/mach-msm/include/mach/rpm-8960.h
index 6fe8832..eab1bce 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8960.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8960.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-9615.h b/arch/arm/mach-msm/include/mach/rpm-9615.h
index 4ca5eea..5c9d882 100644
--- a/arch/arm/mach-msm/include/mach/rpm-9615.h
+++ b/arch/arm/mach-msm/include/mach/rpm-9615.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-8660.h b/arch/arm/mach-msm/include/mach/rpm-regulator-8660.h
index 85dcd89..44e7cd9 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-8660.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-8660.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h b/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h
index f8f53f6..cbe6b45 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-8960.h b/arch/arm/mach-msm/include/mach/rpm-regulator-8960.h
index abcdbb8..8134173 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-8960.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-8960.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-8974.h b/arch/arm/mach-msm/include/mach/rpm-regulator-8974.h
index 07ae600..1bb7eed 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-8974.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-8974.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-9615.h b/arch/arm/mach-msm/include/mach/rpm-regulator-9615.h
index 6a7fae5..3299be2 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-9615.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-9615.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h b/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h
index a32e168..9e70510 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator.h b/arch/arm/mach-msm/include/mach/rpm-regulator.h
index b063b97..ecfbe0d 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm-smd.h b/arch/arm/mach-msm/include/mach/rpm-smd.h
index 0239e36..e340256 100644
--- a/arch/arm/mach-msm/include/mach/rpm-smd.h
+++ b/arch/arm/mach-msm/include/mach/rpm-smd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/rpm.h b/arch/arm/mach-msm/include/mach/rpm.h
index 200a8cf..0adb453 100644
--- a/arch/arm/mach-msm/include/mach/rpm.h
+++ b/arch/arm/mach-msm/include/mach/rpm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/scm-io.h b/arch/arm/mach-msm/include/mach/scm-io.h
index 5393da1..a5c36cb 100644
--- a/arch/arm/mach-msm/include/mach/scm-io.h
+++ b/arch/arm/mach-msm/include/mach/scm-io.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/scm.h b/arch/arm/mach-msm/include/mach/scm.h
index 7cc5f7a..8a06fe3 100644
--- a/arch/arm/mach-msm/include/mach/scm.h
+++ b/arch/arm/mach-msm/include/mach/scm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/sdio_al.h b/arch/arm/mach-msm/include/mach/sdio_al.h
index 8b8ee5a..c75d12b 100644
--- a/arch/arm/mach-msm/include/mach/sdio_al.h
+++ b/arch/arm/mach-msm/include/mach/sdio_al.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/sdio_cmux.h b/arch/arm/mach-msm/include/mach/sdio_cmux.h
index 4bcd607..0297f07 100644
--- a/arch/arm/mach-msm/include/mach/sdio_cmux.h
+++ b/arch/arm/mach-msm/include/mach/sdio_cmux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/sdio_dmux.h b/arch/arm/mach-msm/include/mach/sdio_dmux.h
index afc1b11..bb8cd51 100644
--- a/arch/arm/mach-msm/include/mach/sdio_dmux.h
+++ b/arch/arm/mach-msm/include/mach/sdio_dmux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/sdio_smem.h b/arch/arm/mach-msm/include/mach/sdio_smem.h
index b47001f..eed0671 100644
--- a/arch/arm/mach-msm/include/mach/sdio_smem.h
+++ b/arch/arm/mach-msm/include/mach/sdio_smem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/sirc-fsm9xxx.h b/arch/arm/mach-msm/include/mach/sirc-fsm9xxx.h
index b862211..ddbfd02 100644
--- a/arch/arm/mach-msm/include/mach/sirc-fsm9xxx.h
+++ b/arch/arm/mach-msm/include/mach/sirc-fsm9xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/sirc.h b/arch/arm/mach-msm/include/mach/sirc.h
index 607bab5..7b19d15 100644
--- a/arch/arm/mach-msm/include/mach/sirc.h
+++ b/arch/arm/mach-msm/include/mach/sirc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/smem_log.h b/arch/arm/mach-msm/include/mach/smem_log.h
index a94ae76..992ab05 100644
--- a/arch/arm/mach-msm/include/mach/smem_log.h
+++ b/arch/arm/mach-msm/include/mach/smem_log.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index 7c3f74a..806f362 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
@@ -71,6 +71,7 @@
 
 #define PLATFORM_SUBTYPE_SGLTE	6
 #define PLATFORM_SUBTYPE_DSDA2	8
+#define PLATFORM_SUBTYPE_SGLTE2	9
 
 enum msm_cpu {
 	MSM_CPU_UNKNOWN = 0,
diff --git a/arch/arm/mach-msm/include/mach/sps.h b/arch/arm/mach-msm/include/mach/sps.h
index a000c3e..d31dcf0 100644
--- a/arch/arm/mach-msm/include/mach/sps.h
+++ b/arch/arm/mach-msm/include/mach/sps.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -1253,13 +1253,13 @@
  *
  * @tb_sel - testbus selection
  *
- * @pre_level - prescreening level
+ * @desc_sel - selection of descriptors
  *
  * @return 0 on success, negative value on error
  *
  */
 int sps_get_bam_debug_info(u32 dev, u32 option, u32 para,
-		u32 tb_sel, u8 pre_level);
+		u32 tb_sel, u8 desc_sel);
 
 #else
 static inline int sps_register_bam_device(const struct sps_bam_props
diff --git a/arch/arm/mach-msm/include/mach/subsystem_notif.h b/arch/arm/mach-msm/include/mach/subsystem_notif.h
index 37d4eec..3d8ae55 100644
--- a/arch/arm/mach-msm/include/mach/subsystem_notif.h
+++ b/arch/arm/mach-msm/include/mach/subsystem_notif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/subsystem_restart.h b/arch/arm/mach-msm/include/mach/subsystem_restart.h
index 6d15f47..582d7dc 100644
--- a/arch/arm/mach-msm/include/mach/subsystem_restart.h
+++ b/arch/arm/mach-msm/include/mach/subsystem_restart.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/tpm_st_i2c.h b/arch/arm/mach-msm/include/mach/tpm_st_i2c.h
index 362acbb..e1d9bc1 100644
--- a/arch/arm/mach-msm/include/mach/tpm_st_i2c.h
+++ b/arch/arm/mach-msm/include/mach/tpm_st_i2c.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/uncompress.h b/arch/arm/mach-msm/include/mach/uncompress.h
index dc20df5..d1f89f5 100644
--- a/arch/arm/mach-msm/include/mach/uncompress.h
+++ b/arch/arm/mach-msm/include/mach/uncompress.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/include/mach/usb_bam.h b/arch/arm/mach-msm/include/mach/usb_bam.h
index 47313a7..62093ef 100644
--- a/arch/arm/mach-msm/include/mach/usb_bam.h
+++ b/arch/arm/mach-msm/include/mach/usb_bam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/include/mach/usb_bridge.h b/arch/arm/mach-msm/include/mach/usb_bridge.h
index 5b9fa74..c3f8c55 100644
--- a/arch/arm/mach-msm/include/mach/usb_bridge.h
+++ b/arch/arm/mach-msm/include/mach/usb_bridge.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -17,10 +17,8 @@
 #include <linux/netdevice.h>
 #include <linux/usb.h>
 
-/* bridge device 0: DUN
- * bridge device 1 : Tethered RMNET
- */
-#define MAX_BRIDGE_DEVICES 2
+#define MAX_BRIDGE_DEVICES 4
+#define BRIDGE_NAME_MAX_LEN 20
 
 struct bridge_ops {
 	int (*send_pkt)(void *, void *, size_t actual);
@@ -37,11 +35,12 @@
 	/* context of the gadget port using bridge driver */
 	void *ctx;
 
-	/* bridge device array index mapped to the gadget port array index.
-	 * data bridge[ch_id] <-- bridge --> gadget port[ch_id]
-	 */
+	/*to maps bridge driver instance*/
 	unsigned int ch_id;
 
+	/*to match against bridge xport name to get bridge driver instance*/
+	char *name;
+
 	/* flow control bits */
 	unsigned long flags;
 
@@ -103,7 +102,8 @@
 /* defined in control bridge */
 int ctrl_bridge_init(void);
 void ctrl_bridge_exit(void);
-int ctrl_bridge_probe(struct usb_interface *, struct usb_host_endpoint *, int);
+int ctrl_bridge_probe(struct usb_interface *, struct usb_host_endpoint *,
+		char *, int);
 void ctrl_bridge_disconnect(unsigned int);
 int ctrl_bridge_resume(unsigned int);
 int ctrl_bridge_suspend(unsigned int);
diff --git a/arch/arm/mach-msm/include/mach/usb_gadget_xport.h b/arch/arm/mach-msm/include/mach/usb_gadget_xport.h
index be11989..04e9a1a 100644
--- a/arch/arm/mach-msm/include/mach/usb_gadget_xport.h
+++ b/arch/arm/mach-msm/include/mach/usb_gadget_xport.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -79,8 +79,8 @@
 	USB_GADGET_RMNET,
 };
 
-#define NUM_RMNET_HSIC_PORTS 1
-#define NUM_DUN_HSIC_PORTS 1
+#define NUM_RMNET_HSIC_PORTS 2
+#define NUM_DUN_HSIC_PORTS 2
 #define NUM_PORTS (NUM_RMNET_HSIC_PORTS \
 	+ NUM_DUN_HSIC_PORTS)
 
@@ -92,9 +92,11 @@
 int ghsic_ctrl_connect(void *, int);
 void ghsic_ctrl_disconnect(void *, int);
 int ghsic_ctrl_setup(unsigned int, enum gadget_type);
+void ghsic_ctrl_set_port_name(const char *, const char *);
 int ghsic_data_connect(void *, int);
 void ghsic_data_disconnect(void *, int);
 int ghsic_data_setup(unsigned int, enum gadget_type);
+void ghsic_data_set_port_name(const char *, const char *);
 
 int ghsuart_ctrl_connect(void *, int);
 void ghsuart_ctrl_disconnect(void *, int);
diff --git a/arch/arm/mach-msm/include/mach/usb_trace.h b/arch/arm/mach-msm/include/mach/usb_trace.h
new file mode 100644
index 0000000..02ca8ca
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/usb_trace.h
@@ -0,0 +1,27 @@
+/* include/asm-arm/arch-msm/usbtrace.h
+ *
+ * Copyright (c) 2013, The Linux Foundation. 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 and
+ * only 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.
+ *
+ */
+
+#ifndef _USB_TRACE_H_
+#define _USB_TRACE_H_
+
+#include <linux/tracepoint.h>
+
+DECLARE_TRACE(usb_daytona_invalid_access,
+	TP_PROTO(unsigned int ebi_addr,
+	 unsigned int ebi_apacket0, unsigned int ebi_apacket1),
+	TP_ARGS(ebi_addr, ebi_apacket0, ebi_apacket1));
+
+#endif
+
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 89964de..615d577 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -3,7 +3,7 @@
  * MSM7K, QSD io support
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index d1b0130..6053be3 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ipc_logging.c b/arch/arm/mach-msm/ipc_logging.c
index 2cd30de..1260a1a 100644
--- a/arch/arm/mach-msm/ipc_logging.c
+++ b/arch/arm/mach-msm/ipc_logging.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ipc_logging.h b/arch/arm/mach-msm/ipc_logging.h
index 5e614ab..0eb82a5 100644
--- a/arch/arm/mach-msm/ipc_logging.h
+++ b/arch/arm/mach-msm/ipc_logging.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ipc_logging_debug.c b/arch/arm/mach-msm/ipc_logging_debug.c
index ee3672e..ff947ef 100644
--- a/arch/arm/mach-msm/ipc_logging_debug.c
+++ b/arch/arm/mach-msm/ipc_logging_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index 7dc8d0f..a2da3a5 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -36,6 +36,7 @@
 
 #include "ipc_router.h"
 #include "modem_notifier.h"
+#include "msm_ipc_router_security.h"
 
 enum {
 	SMEM_LOG = 1U << 0,
@@ -96,6 +97,13 @@
 static struct list_head local_ports[LP_HASH_SIZE];
 static DEFINE_MUTEX(local_ports_lock);
 
+/*
+ * Server info is organized as a hash table. The server's service ID is
+ * used to index into the hash table. The instance ID of most of the servers
+ * are 1 or 2. The service IDs are well distributed compared to the instance
+ * IDs and hence choosing service ID to index into this hash table optimizes
+ * the hash table operations like add, lookup, destroy.
+ */
 #define SRV_HASH_SIZE 32
 static struct list_head server_list[SRV_HASH_SIZE];
 static DEFINE_MUTEX(server_list_lock);
@@ -104,6 +112,7 @@
 struct msm_ipc_server {
 	struct list_head list;
 	struct msm_ipc_port_name name;
+	int synced_sec_rule;
 	struct list_head server_port_list;
 };
 
@@ -122,6 +131,7 @@
 	wait_queue_head_t quota_wait;
 	uint32_t tx_quota_cnt;
 	struct mutex quota_lock;
+	void *sec_rule;
 };
 
 struct msm_ipc_router_xprt_info {
@@ -174,7 +184,6 @@
 static LIST_HEAD(xprt_info_list);
 static DEFINE_MUTEX(xprt_info_list_lock);
 
-DECLARE_COMPLETION(msm_ipc_remote_router_up);
 static DECLARE_COMPLETION(msm_ipc_local_router_up);
 #define IPC_ROUTER_INIT_TIMEOUT (10 * HZ)
 
@@ -185,12 +194,6 @@
 static struct workqueue_struct *msm_ipc_router_workqueue;
 
 enum {
-	CLIENT_PORT,
-	SERVER_PORT,
-	CONTROL_PORT,
-};
-
-enum {
 	DOWN,
 	UP,
 };
@@ -546,6 +549,7 @@
 	rport_ptr->port_id = port_id;
 	rport_ptr->node_id = node_id;
 	rport_ptr->restart_state = RESTART_NORMAL;
+	rport_ptr->sec_rule = NULL;
 	rport_ptr->tx_quota_cnt = 0;
 	init_waitqueue_head(&rport_ptr->quota_wait);
 	mutex_init(&rport_ptr->quota_lock);
@@ -582,6 +586,20 @@
 	return;
 }
 
+/**
+ * msm_ipc_router_lookup_server() - Lookup server information
+ * @service: Service ID of the server info to be looked up.
+ * @instance: Instance ID of the server info to be looked up.
+ * @node_id: Node/Processor ID in which the server is hosted.
+ * @port_id: Port ID within the node in which the server is hosted.
+ *
+ * @return: If found Pointer to server structure, else NULL.
+ *
+ * Note1: Lock the server_list_lock before accessing this function.
+ * Note2: If the <node_id:port_id> are <0:0>, then the lookup is restricted
+ *        to <service:instance>. Used only when a client wants to send a
+ *        message to any QMI server.
+ */
 static struct msm_ipc_server *msm_ipc_router_lookup_server(
 				uint32_t service,
 				uint32_t instance,
@@ -590,30 +608,39 @@
 {
 	struct msm_ipc_server *server;
 	struct msm_ipc_server_port *server_port;
-	int key = (instance & (SRV_HASH_SIZE - 1));
+	int key = (service & (SRV_HASH_SIZE - 1));
 
-	mutex_lock(&server_list_lock);
 	list_for_each_entry(server, &server_list[key], list) {
 		if ((server->name.service != service) ||
 		    (server->name.instance != instance))
 			continue;
-		if ((node_id == 0) && (port_id == 0)) {
-			mutex_unlock(&server_list_lock);
+		if ((node_id == 0) && (port_id == 0))
 			return server;
-		}
 		list_for_each_entry(server_port, &server->server_port_list,
 				    list) {
 			if ((server_port->server_addr.node_id == node_id) &&
-			    (server_port->server_addr.port_id == port_id)) {
-				mutex_unlock(&server_list_lock);
+			    (server_port->server_addr.port_id == port_id))
 				return server;
-			}
 		}
 	}
-	mutex_unlock(&server_list_lock);
 	return NULL;
 }
 
+/**
+ * msm_ipc_router_create_server() - Add server info to hash table
+ * @service: Service ID of the server info to be created.
+ * @instance: Instance ID of the server info to be created.
+ * @node_id: Node/Processor ID in which the server is hosted.
+ * @port_id: Port ID within the node in which the server is hosted.
+ * @xprt_info: XPRT through which the node hosting the server is reached.
+ *
+ * @return: Pointer to server structure on success, else NULL.
+ *
+ * This function adds the server info to the hash table. If the same
+ * server(i.e. <service_id:instance_id>) is hosted in different nodes,
+ * they are maintained as list of "server_port" under "server" structure.
+ * Note: Lock the server_list_lock before accessing this function.
+ */
 static struct msm_ipc_server *msm_ipc_router_create_server(
 					uint32_t service,
 					uint32_t instance,
@@ -623,9 +650,8 @@
 {
 	struct msm_ipc_server *server = NULL;
 	struct msm_ipc_server_port *server_port;
-	int key = (instance & (SRV_HASH_SIZE - 1));
+	int key = (service & (SRV_HASH_SIZE - 1));
 
-	mutex_lock(&server_list_lock);
 	list_for_each_entry(server, &server_list[key], list) {
 		if ((server->name.service == service) &&
 		    (server->name.instance == instance))
@@ -634,12 +660,12 @@
 
 	server = kmalloc(sizeof(struct msm_ipc_server), GFP_KERNEL);
 	if (!server) {
-		mutex_unlock(&server_list_lock);
 		pr_err("%s: Server allocation failed\n", __func__);
 		return NULL;
 	}
 	server->name.service = service;
 	server->name.instance = instance;
+	server->synced_sec_rule = 0;
 	INIT_LIST_HEAD(&server->server_port_list);
 	list_add_tail(&server->list, &server_list[key]);
 
@@ -650,7 +676,6 @@
 			list_del(&server->list);
 			kfree(server);
 		}
-		mutex_unlock(&server_list_lock);
 		pr_err("%s: Server Port allocation failed\n", __func__);
 		return NULL;
 	}
@@ -658,11 +683,22 @@
 	server_port->server_addr.port_id = port_id;
 	server_port->xprt_info = xprt_info;
 	list_add_tail(&server_port->list, &server->server_port_list);
-	mutex_unlock(&server_list_lock);
 
 	return server;
 }
 
+/**
+ * msm_ipc_router_destroy_server() - Remove server info from hash table
+ * @server: Server info to be removed.
+ * @node_id: Node/Processor ID in which the server is hosted.
+ * @port_id: Port ID within the node in which the server is hosted.
+ *
+ * This function removes the server_port identified using <node_id:port_id>
+ * from the server structure. If the server_port list under server structure
+ * is empty after removal, then remove the server structure from the server
+ * hash table.
+ * Note: Lock the server_list_lock before accessing this function.
+ */
 static void msm_ipc_router_destroy_server(struct msm_ipc_server *server,
 					  uint32_t node_id, uint32_t port_id)
 {
@@ -671,7 +707,6 @@
 	if (!server)
 		return;
 
-	mutex_lock(&server_list_lock);
 	list_for_each_entry(server_port, &server->server_port_list, list) {
 		if ((server_port->server_addr.node_id == node_id) &&
 		    (server_port->server_addr.port_id == port_id))
@@ -685,7 +720,6 @@
 		list_del(&server->list);
 		kfree(server);
 	}
-	mutex_unlock(&server_list_lock);
 	return;
 }
 
@@ -765,7 +799,7 @@
 	return ret;
 }
 
-static int msm_ipc_router_send_server_list(
+static int msm_ipc_router_send_server_list(uint32_t node_id,
 		struct msm_ipc_router_xprt_info *xprt_info)
 {
 	union rr_control_msg ctl;
@@ -780,15 +814,14 @@
 
 	ctl.cmd = IPC_ROUTER_CTRL_CMD_NEW_SERVER;
 
-	mutex_lock(&server_list_lock);
 	for (i = 0; i < SRV_HASH_SIZE; i++) {
 		list_for_each_entry(server, &server_list[i], list) {
 			ctl.srv.service = server->name.service;
 			ctl.srv.instance = server->name.instance;
 			list_for_each_entry(server_port,
 					    &server->server_port_list, list) {
-				if (server_port->server_addr.node_id ==
-				    xprt_info->remote_node_id)
+				if (server_port->server_addr.node_id !=
+				    node_id)
 					continue;
 
 				ctl.srv.node_id =
@@ -800,7 +833,6 @@
 			}
 		}
 	}
-	mutex_unlock(&server_list_lock);
 
 	return 0;
 }
@@ -1166,14 +1198,179 @@
 	msm_ipc_cleanup_routing_table(xprt_info);
 }
 
+/**
+ * sync_sec_rule() - Synchrnoize the security rule into the server structure
+ * @server: Server structure where the rule has to be synchronized.
+ * @rule: Security tule to be synchronized.
+ *
+ * This function is used to update the server structure with the security
+ * rule configured for the <service:instance> corresponding to that server.
+ */
+static void sync_sec_rule(struct msm_ipc_server *server, void *rule)
+{
+	struct msm_ipc_server_port *server_port;
+	struct msm_ipc_router_remote_port *rport_ptr = NULL;
+
+	list_for_each_entry(server_port, &server->server_port_list, list) {
+		rport_ptr = msm_ipc_router_lookup_remote_port(
+				server_port->server_addr.node_id,
+				server_port->server_addr.port_id);
+		if (!rport_ptr)
+			continue;
+		rport_ptr->sec_rule = rule;
+	}
+	server->synced_sec_rule = 1;
+}
+
+/**
+ * msm_ipc_sync_sec_rule() - Sync the security rule to the service
+ * @service: Service for which the rule has to be synchronized.
+ * @instance: Instance for which the rule has to be synchronized.
+ * @rule: Security rule to be synchronized.
+ *
+ * This function is used to syncrhonize the security rule with the server
+ * hash table, if the user-space script configures the rule after the service
+ * has come up. This function is used to synchronize the security rule to a
+ * specific service and optionally a specific instance.
+ */
+void msm_ipc_sync_sec_rule(uint32_t service, uint32_t instance, void *rule)
+{
+	int key = (service & (SRV_HASH_SIZE - 1));
+	struct msm_ipc_server *server;
+
+	mutex_lock(&server_list_lock);
+	list_for_each_entry(server, &server_list[key], list) {
+		if (server->name.service != service)
+			continue;
+
+		if (server->name.instance != instance &&
+		    instance != ALL_INSTANCE)
+			continue;
+
+		/*
+		 * If the rule applies to all instances and if the specific
+		 * instance of a service has a rule synchronized already,
+		 * do not apply the rule for that specific instance.
+		 */
+		if (instance == ALL_INSTANCE && server->synced_sec_rule)
+			continue;
+
+		sync_sec_rule(server, rule);
+	}
+	mutex_unlock(&server_list_lock);
+}
+
+/**
+ * msm_ipc_sync_default_sec_rule() - Default security rule to all services
+ * @rule: Security rule to be synchronized.
+ *
+ * This function is used to syncrhonize the security rule with the server
+ * hash table, if the user-space script configures the rule after the service
+ * has come up. This function is used to synchronize the security rule that
+ * applies to all services, if the concerned service do not have any rule
+ * defined.
+ */
+void msm_ipc_sync_default_sec_rule(void *rule)
+{
+	int key;
+	struct msm_ipc_server *server;
+
+	mutex_lock(&server_list_lock);
+	for (key = 0; key < SRV_HASH_SIZE; key++) {
+		list_for_each_entry(server, &server_list[key], list) {
+			if (server->synced_sec_rule)
+				continue;
+
+			sync_sec_rule(server, rule);
+		}
+	}
+	mutex_unlock(&server_list_lock);
+}
+
+static int process_hello_msg(struct msm_ipc_router_xprt_info *xprt_info,
+			     struct rr_header *hdr)
+{
+	int i, rc = 0;
+	union rr_control_msg ctl;
+	struct msm_ipc_routing_table_entry *rt_entry;
+
+	if (!hdr)
+		return -EINVAL;
+
+	RR("o HELLO NID %d\n", hdr->src_node_id);
+
+	xprt_info->remote_node_id = hdr->src_node_id;
+	/*
+	 * Find the entry from Routing Table corresponding to Node ID.
+	 * Under SSR, an entry will be found. When the system boots up
+	 * for the 1st time, an entry will not be found and hence allocate
+	 * an entry. Update the entry with the Node ID that it corresponds
+	 * to and the XPRT through which it can be reached.
+	 */
+	mutex_lock(&routing_table_lock);
+	rt_entry = lookup_routing_table(hdr->src_node_id);
+	if (!rt_entry) {
+		rt_entry = alloc_routing_table_entry(hdr->src_node_id);
+		if (!rt_entry) {
+			mutex_unlock(&routing_table_lock);
+			pr_err("%s: rt_entry allocation failed\n", __func__);
+			return -ENOMEM;
+		}
+		add_routing_table_entry(rt_entry);
+	}
+	mutex_lock(&rt_entry->lock);
+	rt_entry->neighbor_node_id = xprt_info->remote_node_id;
+	rt_entry->xprt_info = xprt_info;
+	mutex_unlock(&rt_entry->lock);
+	mutex_unlock(&routing_table_lock);
+
+	/* Cleanup any remote ports, if the node is coming out of reset */
+	msm_ipc_cleanup_remote_port_info(xprt_info->remote_node_id);
+
+	/* Send a reply HELLO message */
+	memset(&ctl, 0, sizeof(ctl));
+	ctl.cmd = IPC_ROUTER_CTRL_CMD_HELLO;
+	rc = msm_ipc_router_send_control_msg(xprt_info, &ctl);
+	if (rc < 0) {
+		pr_err("%s: Error sending reply HELLO message\n", __func__);
+		return rc;
+	}
+	xprt_info->initialized = 1;
+
+	/*
+	 * Send list of servers from the local node and from nodes
+	 * outside the mesh network in which this XPRT is part of.
+	 */
+	mutex_lock(&server_list_lock);
+	mutex_lock(&routing_table_lock);
+	for (i = 0; i < RT_HASH_SIZE; i++) {
+		list_for_each_entry(rt_entry, &routing_table[i], list) {
+			if ((rt_entry->node_id != IPC_ROUTER_NID_LOCAL) &&
+			    (!rt_entry->xprt_info ||
+			     (rt_entry->xprt_info->xprt->link_id ==
+			      xprt_info->xprt->link_id)))
+				continue;
+			rc = msm_ipc_router_send_server_list(rt_entry->node_id,
+							     xprt_info);
+			if (rc < 0) {
+				mutex_unlock(&routing_table_lock);
+				mutex_unlock(&server_list_lock);
+				return rc;
+			}
+		}
+	}
+	mutex_unlock(&routing_table_lock);
+	mutex_unlock(&server_list_lock);
+	RR("HELLO message processed\n");
+	return rc;
+}
+
 static int process_control_msg(struct msm_ipc_router_xprt_info *xprt_info,
 			       struct rr_packet *pkt)
 {
-	union rr_control_msg ctl;
 	union rr_control_msg *msg;
 	struct msm_ipc_router_remote_port *rport_ptr;
 	int rc = 0;
-	static uint32_t first = 1;
 	struct sk_buff *temp_ptr;
 	struct rr_header *hdr;
 	struct msm_ipc_server *server;
@@ -1199,43 +1396,9 @@
 
 	switch (msg->cmd) {
 	case IPC_ROUTER_CTRL_CMD_HELLO:
-		RR("o HELLO NID %d\n", hdr->src_node_id);
-		xprt_info->remote_node_id = hdr->src_node_id;
-
-		mutex_lock(&routing_table_lock);
-		rt_entry = lookup_routing_table(hdr->src_node_id);
-		if (!rt_entry) {
-			rt_entry = alloc_routing_table_entry(hdr->src_node_id);
-			if (!rt_entry) {
-				mutex_unlock(&routing_table_lock);
-				pr_err("%s: rt_entry allocation failed\n",
-					__func__);
-				return -ENOMEM;
-			}
-			add_routing_table_entry(rt_entry);
-		}
-		mutex_lock(&rt_entry->lock);
-		rt_entry->neighbor_node_id = xprt_info->remote_node_id;
-		rt_entry->xprt_info = xprt_info;
-		mutex_unlock(&rt_entry->lock);
-		mutex_unlock(&routing_table_lock);
-		msm_ipc_cleanup_remote_port_info(xprt_info->remote_node_id);
-
-		memset(&ctl, 0, sizeof(ctl));
-		ctl.cmd = IPC_ROUTER_CTRL_CMD_HELLO;
-		msm_ipc_router_send_control_msg(xprt_info, &ctl);
-
-		xprt_info->initialized = 1;
-
-		/* Send list of servers one at a time */
-		msm_ipc_router_send_server_list(xprt_info);
-
-		if (first) {
-			first = 0;
-			complete_all(&msm_ipc_remote_router_up);
-		}
-		RR("HELLO message processed\n");
+		rc = process_hello_msg(xprt_info, hdr);
 		break;
+
 	case IPC_ROUTER_CTRL_CMD_RESUME_TX:
 		RR("o RESUME_TX id=%d:%08x\n",
 		   msg->cli.node_id, msg->cli.port_id);
@@ -1282,6 +1445,7 @@
 		}
 		mutex_unlock(&routing_table_lock);
 
+		mutex_lock(&server_list_lock);
 		server = msm_ipc_router_lookup_server(msg->srv.service,
 						      msg->srv.instance,
 						      msg->srv.node_id,
@@ -1291,6 +1455,7 @@
 				msg->srv.service, msg->srv.instance,
 				msg->srv.node_id, msg->srv.port_id, xprt_info);
 			if (!server) {
+				mutex_unlock(&server_list_lock);
 				pr_err("%s: Server Create failed\n", __func__);
 				return -ENOMEM;
 			}
@@ -1302,9 +1467,13 @@
 				if (!rport_ptr)
 					pr_err("%s: Remote port create "
 					       "failed\n", __func__);
+				rport_ptr->sec_rule =
+					msm_ipc_get_security_rule(
+					msg->srv.service, msg->srv.instance);
 			}
 			wake_up(&newserver_wait);
 		}
+		mutex_unlock(&server_list_lock);
 
 		relay_msg(xprt_info, pkt);
 		post_control_ports(pkt);
@@ -1312,6 +1481,7 @@
 	case IPC_ROUTER_CTRL_CMD_REMOVE_SERVER:
 		RR("o REMOVE_SERVER service=%08x:%d\n",
 		   msg->srv.service, msg->srv.instance);
+		mutex_lock(&server_list_lock);
 		server = msm_ipc_router_lookup_server(msg->srv.service,
 						      msg->srv.instance,
 						      msg->srv.node_id,
@@ -1323,6 +1493,7 @@
 			relay_msg(xprt_info, pkt);
 			post_control_ports(pkt);
 		}
+		mutex_unlock(&server_list_lock);
 		break;
 	case IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT:
 		RR("o REMOVE_CLIENT id=%d:%08x\n",
@@ -1507,11 +1678,13 @@
 	if (name->addrtype != MSM_IPC_ADDR_NAME)
 		return -EINVAL;
 
+	mutex_lock(&server_list_lock);
 	server = msm_ipc_router_lookup_server(name->addr.port_name.service,
 					      name->addr.port_name.instance,
 					      IPC_ROUTER_NID_LOCAL,
 					      port_ptr->this_port.port_id);
 	if (server) {
+		mutex_unlock(&server_list_lock);
 		pr_err("%s: Server already present\n", __func__);
 		return -EINVAL;
 	}
@@ -1522,6 +1695,7 @@
 					      port_ptr->this_port.port_id,
 					      NULL);
 	if (!server) {
+		mutex_unlock(&server_list_lock);
 		pr_err("%s: Server Creation failed\n", __func__);
 		return -EINVAL;
 	}
@@ -1531,6 +1705,7 @@
 	ctl.srv.instance = server->name.instance;
 	ctl.srv.node_id = IPC_ROUTER_NID_LOCAL;
 	ctl.srv.port_id = port_ptr->this_port.port_id;
+	mutex_unlock(&server_list_lock);
 	broadcast_ctl_msg(&ctl);
 	spin_lock_irqsave(&port_ptr->port_lock, flags);
 	port_ptr->type = SERVER_PORT;
@@ -1561,11 +1736,13 @@
 		return -EINVAL;
 	}
 
+	mutex_lock(&server_list_lock);
 	server = msm_ipc_router_lookup_server(port_ptr->port_name.service,
 					      port_ptr->port_name.instance,
 					      port_ptr->this_port.node_id,
 					      port_ptr->this_port.port_id);
 	if (!server) {
+		mutex_unlock(&server_list_lock);
 		pr_err("%s: Server lookup failed\n", __func__);
 		return -ENODEV;
 	}
@@ -1575,9 +1752,10 @@
 	ctl.srv.instance = server->name.instance;
 	ctl.srv.node_id = IPC_ROUTER_NID_LOCAL;
 	ctl.srv.port_id = port_ptr->this_port.port_id;
-	broadcast_ctl_msg(&ctl);
 	msm_ipc_router_destroy_server(server, port_ptr->this_port.node_id,
 				      port_ptr->this_port.port_id);
+	mutex_unlock(&server_list_lock);
+	broadcast_ctl_msg(&ctl);
 	spin_lock_irqsave(&port_ptr->port_lock, flags);
 	port_ptr->type = CLIENT_PORT;
 	spin_unlock_irqrestore(&port_ptr->port_lock, flags);
@@ -1592,6 +1770,7 @@
 	struct rr_header *hdr;
 	struct msm_ipc_port *port_ptr;
 	struct rr_packet *pkt;
+	int ret_len;
 
 	if (!data) {
 		pr_err("%s: Invalid pkt pointer\n", __func__);
@@ -1637,11 +1816,12 @@
 	mutex_lock(&port_ptr->port_rx_q_lock);
 	wake_lock(&port_ptr->port_rx_wake_lock);
 	list_add_tail(&pkt->list, &port_ptr->port_rx_q);
+	ret_len = pkt->length;
 	wake_up(&port_ptr->port_rx_wait_q);
 	mutex_unlock(&port_ptr->port_rx_q_lock);
 	mutex_unlock(&local_ports_lock);
 
-	return pkt->length;
+	return ret_len;
 }
 
 static int msm_ipc_router_write_pkt(struct msm_ipc_port *src,
@@ -1776,15 +1956,16 @@
 		dst_node_id = dest->addr.port_addr.node_id;
 		dst_port_id = dest->addr.port_addr.port_id;
 	} else if (dest->addrtype == MSM_IPC_ADDR_NAME) {
+		mutex_lock(&server_list_lock);
 		server = msm_ipc_router_lookup_server(
 					dest->addr.port_name.service,
 					dest->addr.port_name.instance,
 					0, 0);
 		if (!server) {
+			mutex_unlock(&server_list_lock);
 			pr_err("%s: Destination not reachable\n", __func__);
 			return -ENODEV;
 		}
-		mutex_lock(&server_list_lock);
 		server_port = list_first_entry(&server->server_port_list,
 					       struct msm_ipc_server_port,
 					       list);
@@ -1805,6 +1986,15 @@
 		return -ENOMEM;
 	}
 
+	if (src->check_send_permissions) {
+		ret = src->check_send_permissions(rport_ptr->sec_rule);
+		if (ret <= 0) {
+			pr_err("%s: permission failure for %s\n",
+				__func__, current->comm);
+			return -EPERM;
+		}
+	}
+
 	pkt = create_pkt(data);
 	if (!pkt) {
 		pr_err("%s: Pkt creation failed\n", __func__);
@@ -1945,19 +2135,30 @@
 			RR("x REMOVE_SERVER Name=%d:%08x Id=%d:%08x\n",
 			   msg.srv.service, msg.srv.instance,
 			   msg.srv.node_id, msg.srv.port_id);
-		} else if (port_ptr->type == CLIENT_PORT) {
-			msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT;
-			msg.cli.node_id = port_ptr->this_port.node_id;
-			msg.cli.port_id = port_ptr->this_port.port_id;
-			RR("x REMOVE_CLIENT id=%d:%08x\n",
-			   msg.cli.node_id, msg.cli.port_id);
+			broadcast_ctl_msg(&msg);
+			broadcast_ctl_msg_locally(&msg);
 		}
+
+		/*
+		 * Server port could have been a client port earlier.
+		 * Send REMOVE_CLIENT message in either case.
+		 */
+		msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT;
+		msg.cli.node_id = port_ptr->this_port.node_id;
+		msg.cli.port_id = port_ptr->this_port.port_id;
+		RR("x REMOVE_CLIENT id=%d:%08x\n",
+		   msg.cli.node_id, msg.cli.port_id);
 		broadcast_ctl_msg(&msg);
 		broadcast_ctl_msg_locally(&msg);
 	} else if (port_ptr->type == CONTROL_PORT) {
 		mutex_lock(&control_ports_lock);
 		list_del(&port_ptr->list);
 		mutex_unlock(&control_ports_lock);
+	} else if (port_ptr->type == IRSC_PORT) {
+		mutex_lock(&local_ports_lock);
+		list_del(&port_ptr->list);
+		mutex_unlock(&local_ports_lock);
+		signal_irsc_completion();
 	}
 
 	mutex_lock(&port_ptr->port_rx_q_lock);
@@ -1968,6 +2169,7 @@
 	mutex_unlock(&port_ptr->port_rx_q_lock);
 
 	if (port_ptr->type == SERVER_PORT) {
+		mutex_lock(&server_list_lock);
 		server = msm_ipc_router_lookup_server(
 				port_ptr->port_name.service,
 				port_ptr->port_name.instance,
@@ -1977,6 +2179,7 @@
 			msm_ipc_router_destroy_server(server,
 				port_ptr->this_port.node_id,
 				port_ptr->this_port.port_id);
+		mutex_unlock(&server_list_lock);
 	}
 
 	wake_lock_destroy(&port_ptr->port_rx_wake_lock);
@@ -2041,27 +2244,24 @@
 	mutex_lock(&server_list_lock);
 	if (!lookup_mask)
 		lookup_mask = 0xFFFFFFFF;
-	for (key = 0; key < SRV_HASH_SIZE; key++) {
-		list_for_each_entry(server, &server_list[key], list) {
-			if ((server->name.service != srv_name->service) ||
-			    ((server->name.instance & lookup_mask) !=
-				srv_name->instance))
-				continue;
+	key = (srv_name->service & (SRV_HASH_SIZE - 1));
+	list_for_each_entry(server, &server_list[key], list) {
+		if ((server->name.service != srv_name->service) ||
+		    ((server->name.instance & lookup_mask) !=
+			srv_name->instance))
+			continue;
 
-			list_for_each_entry(server_port,
-				&server->server_port_list, list) {
-				if (i < num_entries_in_array) {
-					srv_info[i].node_id =
+		list_for_each_entry(server_port,
+			&server->server_port_list, list) {
+			if (i < num_entries_in_array) {
+				srv_info[i].node_id =
 					  server_port->server_addr.node_id;
-					srv_info[i].port_id =
+				srv_info[i].port_id =
 					  server_port->server_addr.port_id;
-					srv_info[i].service =
-					  server->name.service;
-					srv_info[i].instance =
-					  server->name.instance;
-				}
-				i++;
+				srv_info[i].service = server->name.service;
+				srv_info[i].instance = server->name.instance;
 			}
+			i++;
 		}
 	}
 	mutex_unlock(&server_list_lock);
@@ -2096,7 +2296,7 @@
 			mutex_lock(&rt_entry->lock);
 			i += scnprintf(buf + i, max - i,
 				       "Node Id: 0x%08x\n", rt_entry->node_id);
-			if (j == IPC_ROUTER_NID_LOCAL) {
+			if (rt_entry->node_id == IPC_ROUTER_NID_LOCAL) {
 				i += scnprintf(buf + i, max - i,
 				       "XPRT Name: Loopback\n");
 				i += scnprintf(buf + i, max - i,
@@ -2545,6 +2745,10 @@
 	if (ret < 0)
 		pr_err("%s: Init sockets failed\n", __func__);
 
+	ret = msm_ipc_router_security_init();
+	if (ret < 0)
+		pr_err("%s: Security Init failed\n", __func__);
+
 	complete_all(&msm_ipc_local_router_up);
 	return ret;
 }
diff --git a/arch/arm/mach-msm/ipc_router.h b/arch/arm/mach-msm/ipc_router.h
index 07bc5e0..d56c0dd 100644
--- a/arch/arm/mach-msm/ipc_router.h
+++ b/arch/arm/mach-msm/ipc_router.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -58,11 +58,21 @@
 
 #define ALIGN_SIZE(x) ((4 - ((x) & 3)) & 3)
 
+#define ALL_SERVICE 0xFFFFFFFF
+#define ALL_INSTANCE 0xFFFFFFFF
+
 enum {
 	MSM_IPC_ROUTER_READ_CB = 0,
 	MSM_IPC_ROUTER_WRITE_DONE,
 };
 
+enum {
+	CLIENT_PORT,
+	SERVER_PORT,
+	CONTROL_PORT,
+	IRSC_PORT,
+};
+
 union rr_control_msg {
 	uint32_t cmd;
 	struct {
@@ -127,6 +137,7 @@
 
 	void *endpoint;
 	void (*notify)(unsigned event, void *data, void *addr, void *priv);
+	int (*check_send_permissions)(void *data);
 
 	uint32_t num_tx;
 	uint32_t num_rx;
@@ -206,6 +217,10 @@
 int msm_ipc_router_init_sockets(void);
 void msm_ipc_router_exit_sockets(void);
 
+void msm_ipc_sync_sec_rule(uint32_t service, uint32_t instance, void *rule);
+
+void msm_ipc_sync_default_sec_rule(void *rule);
+
 #if defined CONFIG_MSM_IPC_ROUTER_SMD_XPRT
 extern void *msm_ipc_load_default_node(void);
 
diff --git a/arch/arm/mach-msm/ipc_router_smd_xprt.c b/arch/arm/mach-msm/ipc_router_smd_xprt.c
index b2e6490..7509df4 100644
--- a/arch/arm/mach-msm/ipc_router_smd_xprt.c
+++ b/arch/arm/mach-msm/ipc_router_smd_xprt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index d3917f1..839fa47 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -21,16 +21,13 @@
 #include <linux/gfp.h>
 #include <linux/msm_ipc.h>
 
-#ifdef CONFIG_ANDROID_PARANOID_NETWORK
-#include <linux/android_aid.h>
-#endif
-
 #include <asm/string.h>
 #include <asm/atomic.h>
 
 #include <net/sock.h>
 
 #include "ipc_router.h"
+#include "msm_ipc_router_security.h"
 
 #define msm_ipc_sk(sk) ((struct msm_ipc_sock *)(sk))
 #define msm_ipc_sk_port(sk) ((struct msm_ipc_port *)(msm_ipc_sk(sk)->port))
@@ -39,21 +36,6 @@
 static struct proto msm_ipc_proto;
 static const struct proto_ops msm_ipc_proto_ops;
 
-#ifdef CONFIG_ANDROID_PARANOID_NETWORK
-static inline int check_permissions(void)
-{
-	int rc = 0;
-	if (!current_euid() || in_egroup_p(AID_NET_RAW))
-		rc = 1;
-	return rc;
-}
-# else
-static inline int check_permissions(void)
-{
-	return 1;
-}
-#endif
-
 static struct sk_buff_head *msm_ipc_router_build_msg(unsigned int num_sect,
 					  struct iovec const *msg_sect,
 					  size_t total_len)
@@ -190,11 +172,6 @@
 	struct msm_ipc_port *port_ptr;
 	void *pil;
 
-	if (!check_permissions()) {
-		pr_err("%s: Do not have permissions\n", __func__);
-		return -EPERM;
-	}
-
 	if (unlikely(protocol != 0)) {
 		pr_err("%s: Protocol not supported\n", __func__);
 		return -EPROTONOSUPPORT;
@@ -221,6 +198,7 @@
 		return -ENOMEM;
 	}
 
+	port_ptr->check_send_permissions = msm_ipc_check_send_permissions;
 	sock->ops = &msm_ipc_proto_ops;
 	sock_init_data(sock, sk);
 	sk->sk_rcvtimeo = DEFAULT_RCV_TIMEO;
@@ -243,6 +221,12 @@
 	if (!sk)
 		return -EINVAL;
 
+	if (!check_permissions()) {
+		pr_err("%s: %s Do not have permissions\n",
+			__func__, current->comm);
+		return -EPERM;
+	}
+
 	if (!uaddr_len) {
 		pr_err("%s: Invalid address length\n", __func__);
 		return -EINVAL;
@@ -296,6 +280,9 @@
 		goto out_sendmsg;
 	}
 
+	if (port_ptr->type == CLIENT_PORT)
+		wait_for_irsc_completion();
+
 	ret = msm_ipc_router_send_to(port_ptr, msg, &dest->address);
 	if (ret == (IPC_ROUTER_HDR_SIZE + total_len))
 		ret = total_len;
@@ -443,6 +430,12 @@
 		ret = msm_ipc_router_bind_control_port(port_ptr);
 		break;
 
+	case IPC_ROUTER_IOCTL_CONFIG_SEC_RULES:
+		ret = msm_ipc_config_sec_rules((void *)arg);
+		if (ret != -EPERM)
+			port_ptr->type = IRSC_PORT;
+		break;
+
 	default:
 		ret = -EINVAL;
 	}
diff --git a/arch/arm/mach-msm/irq-vic.c b/arch/arm/mach-msm/irq-vic.c
index 489faa3..7e485ed 100644
--- a/arch/arm/mach-msm/irq-vic.c
+++ b/arch/arm/mach-msm/irq-vic.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/irq.h b/arch/arm/mach-msm/irq.h
index 8b0fbc0..67ff446 100644
--- a/arch/arm/mach-msm/irq.h
+++ b/arch/arm/mach-msm/irq.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/keypad-surf-ffa.c b/arch/arm/mach-msm/keypad-surf-ffa.c
index 711cdbb..5d7763f 100644
--- a/arch/arm/mach-msm/keypad-surf-ffa.c
+++ b/arch/arm/mach-msm/keypad-surf-ffa.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index 96c4809..c1ca764 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/krait-scm.c b/arch/arm/mach-msm/krait-scm.c
index eb48d35..a67c3df 100644
--- a/arch/arm/mach-msm/krait-scm.c
+++ b/arch/arm/mach-msm/krait-scm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/lge/mako/board-mako-camera.c b/arch/arm/mach-msm/lge/mako/board-mako-camera.c
index 9176ace..a16b002 100644
--- a/arch/arm/mach-msm/lge/mako/board-mako-camera.c
+++ b/arch/arm/mach-msm/lge/mako/board-mako-camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012, LGE Inc.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/mach-msm/lge/mako/board-mako-display.c b/arch/arm/mach-msm/lge/mako/board-mako-display.c
index 123547c..26c3d29 100644
--- a/arch/arm/mach-msm/lge/mako/board-mako-display.c
+++ b/arch/arm/mach-msm/lge/mako/board-mako-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012, LGE Inc.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/mach-msm/lge/mako/board-mako-gpiomux.c b/arch/arm/mach-msm/lge/mako/board-mako-gpiomux.c
index 9a8ced3..95f1a83 100644
--- a/arch/arm/mach-msm/lge/mako/board-mako-gpiomux.c
+++ b/arch/arm/mach-msm/lge/mako/board-mako-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012, LGE Inc.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/mach-msm/lge/mako/board-mako-gpu.c b/arch/arm/mach-msm/lge/mako/board-mako-gpu.c
index 5ffcbb1..d4c0b3e 100644
--- a/arch/arm/mach-msm/lge/mako/board-mako-gpu.c
+++ b/arch/arm/mach-msm/lge/mako/board-mako-gpu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012, LGE Inc.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/mach-msm/lge/mako/board-mako-input.c b/arch/arm/mach-msm/lge/mako/board-mako-input.c
index 5120963..269a746 100644
--- a/arch/arm/mach-msm/lge/mako/board-mako-input.c
+++ b/arch/arm/mach-msm/lge/mako/board-mako-input.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012, LGE Inc.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/mach-msm/lge/mako/board-mako-pmic.c b/arch/arm/mach-msm/lge/mako/board-mako-pmic.c
index 875a6c7..bdb4fc1 100644
--- a/arch/arm/mach-msm/lge/mako/board-mako-pmic.c
+++ b/arch/arm/mach-msm/lge/mako/board-mako-pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012, LGE Inc.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/mach-msm/lge/mako/board-mako-regulator.c b/arch/arm/mach-msm/lge/mako/board-mako-regulator.c
index 3f3ab67..68aaf74 100644
--- a/arch/arm/mach-msm/lge/mako/board-mako-regulator.c
+++ b/arch/arm/mach-msm/lge/mako/board-mako-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012, LGE Inc.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/mach-msm/lge/mako/board-mako-storage.c b/arch/arm/mach-msm/lge/mako/board-mako-storage.c
index f249493..c71c87a 100644
--- a/arch/arm/mach-msm/lge/mako/board-mako-storage.c
+++ b/arch/arm/mach-msm/lge/mako/board-mako-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012, LGE Inc.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/mach-msm/lge/mako/board-mako.c b/arch/arm/mach-msm/lge/mako/board-mako.c
index df52783..787ddfe 100644
--- a/arch/arm/mach-msm/lge/mako/board-mako.c
+++ b/arch/arm/mach-msm/lge/mako/board-mako.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012, LGE Inc.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/mach-msm/lge/mako/board-mako.h b/arch/arm/mach-msm/lge/mako/board-mako.h
index 48c0e8d..77d72db 100644
--- a/arch/arm/mach-msm/lge/mako/board-mako.h
+++ b/arch/arm/mach-msm/lge/mako/board-mako.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  * Copyright (c) 2012 LGE Inc.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/mach-msm/lpass-8660.c b/arch/arm/mach-msm/lpass-8660.c
index be18b68..fbb080a 100644
--- a/arch/arm/mach-msm/lpass-8660.c
+++ b/arch/arm/mach-msm/lpass-8660.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/lpass-8960.c b/arch/arm/mach-msm/lpass-8960.c
index 794eb52..4bf9a9d 100644
--- a/arch/arm/mach-msm/lpass-8960.c
+++ b/arch/arm/mach-msm/lpass-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index 8218a42..57d9f28 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/lpm_resources.c b/arch/arm/mach-msm/lpm_resources.c
index 48d31f3..c22d3cd 100644
--- a/arch/arm/mach-msm/lpm_resources.c
+++ b/arch/arm/mach-msm/lpm_resources.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/lpm_resources.h b/arch/arm/mach-msm/lpm_resources.h
index 120832f..46362c5 100644
--- a/arch/arm/mach-msm/lpm_resources.h
+++ b/arch/arm/mach-msm/lpm_resources.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/mdm.c b/arch/arm/mach-msm/mdm.c
index 02978cf..4cb179b 100644
--- a/arch/arm/mach-msm/mdm.c
+++ b/arch/arm/mach-msm/mdm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index a9fad9d..e41c669 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -117,11 +117,13 @@
 		}
 		msleep(100);
 	}
-	if (i == 0) {
-		pr_err("%s:id %d: MDM2AP_STATUS never went low. Doing a hard reset\n",
-			   __func__, mdm_drv->device_id);
-		gpio_direction_output(mdm_drv->ap2mdm_soft_reset_gpio,
+
+	/* Assert the soft reset line whether mdm2ap_status went low or not */
+	gpio_direction_output(mdm_drv->ap2mdm_soft_reset_gpio,
 					soft_reset_direction);
+	if (i == 0) {
+		pr_err("%s: MDM2AP_STATUS never went low. Doing a hard reset\n",
+			   __func__);
 		/*
 		* Currently, there is a debounce timer on the charm PMIC. It is
 		* necessary to hold the PMIC RESET low for ~3.5 seconds
@@ -136,6 +138,14 @@
 {
 	int i;
 	int pblrdy;
+	int kpd_direction_assert = 1,
+		kpd_direction_de_assert = 0;
+
+	if (mdm_drv->pdata->kpd_not_inverted) {
+		kpd_direction_assert = 0;
+		kpd_direction_de_assert = 1;
+	}
+
 	if (mdm_drv->power_on_count != 1) {
 		pr_err("%s:id %d: Calling fn when power_on_count != 1\n",
 			   __func__, mdm_drv->device_id);
@@ -151,7 +161,9 @@
 	 * instead of just de-asserting it. No harm done if the modem was
 	 * powered down.
 	 */
-	mdm_toggle_soft_reset(mdm_drv);
+	if (!mdm_drv->pdata->no_reset_on_first_powerup)
+		mdm_toggle_soft_reset(mdm_drv);
+
 	/* If the device has a kpd pwr gpio then toggle it. */
 	if (GPIO_IS_VALID(mdm_drv->ap2mdm_kpdpwr_n_gpio)) {
 		/* Pull AP2MDM_KPDPWR gpio high and wait for PS_HOLD to settle,
@@ -159,9 +171,11 @@
 		 */
 		pr_debug("%s:id %d: Pulling AP2MDM_KPDPWR gpio high\n",
 				 __func__, mdm_drv->device_id);
-		gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 1);
+		gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio,
+				kpd_direction_assert);
 		msleep(1000);
-		gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 0);
+		gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio,
+				kpd_direction_de_assert);
 	}
 
 	if (!GPIO_IS_VALID(mdm_drv->mdm2ap_pblrdy))
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 536e859..9e53002 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -138,41 +138,6 @@
 	spin_unlock_irqrestore(&mdm_devices_lock, flags);
 }
 
-struct mdm_device *mdm_get_device_by_device_id(int device_id)
-{
-	unsigned long flags;
-	struct mdm_device *mdev = NULL;
-
-	spin_lock_irqsave(&mdm_devices_lock, flags);
-	list_for_each_entry(mdev, &mdm_devices, link) {
-		if (mdev && mdev->mdm_data.device_id == device_id) {
-			spin_unlock_irqrestore(&mdm_devices_lock, flags);
-			return mdev;
-		}
-	}
-	spin_unlock_irqrestore(&mdm_devices_lock, flags);
-	return NULL;
-}
-
-struct mdm_device *mdm_get_device_by_name(const char *name)
-{
-	unsigned long flags;
-	struct mdm_device *mdev;
-
-	if (!name)
-		return NULL;
-	spin_lock_irqsave(&mdm_devices_lock, flags);
-	list_for_each_entry(mdev, &mdm_devices, link) {
-		if (mdev && !strncmp(mdev->device_name, name,
-				sizeof(mdev->device_name))) {
-			spin_unlock_irqrestore(&mdm_devices_lock, flags);
-			return mdev;
-		}
-	}
-	spin_unlock_irqrestore(&mdm_devices_lock, flags);
-	return NULL;
-}
-
 /* If the platform's cascading_ssr flag is set, the subsystem
  * restart module will restart the other modems so stop
  * monitoring them as well.
@@ -396,19 +361,13 @@
 	}
 }
 
-long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
+static long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
 				unsigned long arg)
 {
 	int status, ret = 0;
-	struct mdm_device *mdev;
+	struct mdm_device *mdev = filp->private_data;
 	struct mdm_modem_drv *mdm_drv;
 
-	mdev = mdm_get_device_by_name(filp->f_path.dentry->d_iname);
-	if (!mdev) {
-		pr_err("%s: mdm_device not found\n", __func__);
-		return -ENODEV;
-	}
-
 	if (_IOC_TYPE(cmd) != CHARM_CODE) {
 		pr_err("%s: invalid ioctl code to mdm id %d\n",
 			   __func__, mdev->mdm_data.device_id);
@@ -499,15 +458,20 @@
 			pr_debug("%s Image upgrade not supported\n", __func__);
 		break;
 	case SHUTDOWN_CHARM:
-		if (!mdm_drv->pdata->send_shdn)
+		if (!mdm_drv->pdata->send_shdn ||
+				!mdm_drv->pdata->sysmon_subsys_id_valid) {
+			pr_debug("%s shutdown not supported for this mdm\n",
+					__func__);
 			break;
+		}
 		atomic_set(&mdm_drv->mdm_ready, 0);
 		if (mdm_debug_mask & MDM_DEBUG_MASK_SHDN_LOG)
 			pr_info("Sending shutdown request to mdm\n");
-		ret = sysmon_send_shutdown(SYSMON_SS_EXT_MODEM);
+		ret = sysmon_send_shutdown(mdm_drv->pdata->sysmon_subsys_id);
 		if (ret)
-			pr_err("%s: Graceful shutdown of the external modem failed, ret = %d\n",
+			pr_err("%s:Graceful shutdown of mdm failed, ret = %d\n",
 			   __func__, ret);
+		put_user(ret, (unsigned long __user *) arg);
 		break;
 	default:
 		pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
@@ -563,6 +527,11 @@
 /* set the mdm_device as the file's private data */
 static int mdm_modem_open(struct inode *inode, struct file *file)
 {
+	struct miscdevice *misc = file->private_data;
+	struct mdm_device *mdev = container_of(misc,
+			struct mdm_device, misc_device);
+
+	file->private_data = mdev;
 	return 0;
 }
 
@@ -651,7 +620,10 @@
 
 	mdm_ssr_started(mdev);
 	cancel_delayed_work(&mdev->mdm2ap_status_check_work);
-	gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 1);
+
+	if (!mdm_drv->pdata->no_a2m_errfatal_on_ssr)
+		gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 1);
+
 	if (mdm_drv->pdata->ramdump_delay_ms > 0) {
 		/* Wait for the external modem to complete
 		 * its preparation for ramdumps.
@@ -723,7 +695,6 @@
 		if (!wait_for_completion_timeout(&mdev->mdm_ram_dumps,
 				msecs_to_jiffies(mdev->dump_timeout_ms))) {
 			mdm_drv->mdm_ram_dump_status = -ETIMEDOUT;
-			mdm_ssr_completed(mdev);
 			pr_err("%s: mdm modem ramdumps timed out.\n",
 					__func__);
 		} else
@@ -801,12 +772,18 @@
 
 	memset((void *)&mdev->mdm_subsys, 0,
 		   sizeof(struct subsys_desc));
-	if (mdev->mdm_data.device_id <= 0)
-		snprintf(mdev->subsys_name, sizeof(mdev->subsys_name),
-			 "%s",  EXTERNAL_MODEM);
-	else
-		snprintf(mdev->subsys_name, sizeof(mdev->subsys_name),
-			 "%s.%d",  EXTERNAL_MODEM, mdev->mdm_data.device_id);
+	if (mdm_drv->pdata->subsys_name) {
+		strlcpy(mdev->subsys_name, mdm_drv->pdata->subsys_name,
+				sizeof(mdev->subsys_name));
+	} else {
+		if (mdev->mdm_data.device_id <= 0)
+			snprintf(mdev->subsys_name, sizeof(mdev->subsys_name),
+				"%s",  EXTERNAL_MODEM);
+		else
+			snprintf(mdev->subsys_name, sizeof(mdev->subsys_name),
+				"%s.%d",  EXTERNAL_MODEM,
+				mdev->mdm_data.device_id);
+	}
 	mdev->mdm_subsys.shutdown = mdm_subsys_shutdown;
 	mdev->mdm_subsys.ramdump = mdm_subsys_ramdumps;
 	mdev->mdm_subsys.powerup = mdm_subsys_powerup;
@@ -887,7 +864,7 @@
 
 	mdm_drv->boot_type                  = CHARM_NORMAL_BOOT;
 
-	mdm_drv->dump_timeout_ms = mdm_drv->pdata->ramdump_timeout_ms > 0 ?
+	mdev->dump_timeout_ms = mdm_drv->pdata->ramdump_timeout_ms > 0 ?
 		mdm_drv->pdata->ramdump_timeout_ms : MDM_RDUMP_TIMEOUT;
 
 	init_completion(&mdev->mdm_needs_reload);
@@ -1075,6 +1052,7 @@
 		goto init_err;
 	}
 
+	platform_set_drvdata(pdev, mdev);
 	mdm_modem_initialize_data(pdev, mdev);
 
 	if (mdm_ops->debug_state_changed_cb)
@@ -1121,10 +1099,7 @@
 static int __devexit mdm_modem_remove(struct platform_device *pdev)
 {
 	int ret;
-	struct mdm_device *mdev = mdm_get_device_by_device_id(pdev->id);
-
-	if (!mdev)
-		return -ENODEV;
+	struct mdm_device *mdev = platform_get_drvdata(pdev);
 
 	pr_debug("%s: removing device id %d\n",
 			__func__, mdev->mdm_data.device_id);
@@ -1138,9 +1113,7 @@
 static void mdm_modem_shutdown(struct platform_device *pdev)
 {
 	struct mdm_modem_drv *mdm_drv;
-	struct mdm_device *mdev = mdm_get_device_by_device_id(pdev->id);
-	if (!mdev)
-		return;
+	struct mdm_device *mdev = platform_get_drvdata(pdev);
 
 	pr_debug("%s: shutting down device id %d\n",
 		 __func__, mdev->mdm_data.device_id);
diff --git a/arch/arm/mach-msm/mdm_private.h b/arch/arm/mach-msm/mdm_private.h
index 147094c..40525f7 100644
--- a/arch/arm/mach-msm/mdm_private.h
+++ b/arch/arm/mach-msm/mdm_private.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -51,7 +51,6 @@
 	int mdm_debug_on;
 	int mdm_unexpected_reset_occurred;
 	int disable_status_check;
-	unsigned int dump_timeout_ms;
 	int power_on_count;
 	int peripheral_status;
 	struct mutex peripheral_status_lock;
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 74c1c4a..b09ec01 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/memory.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -141,29 +141,6 @@
 	return (void *)addr;
 }
 
-int (*change_memory_power)(u64, u64, int);
-
-int platform_physical_remove_pages(u64 start, u64 size)
-{
-	if (!change_memory_power)
-		return 0;
-	return change_memory_power(start, size, MEMORY_DEEP_POWERDOWN);
-}
-
-int platform_physical_active_pages(u64 start, u64 size)
-{
-	if (!change_memory_power)
-		return 0;
-	return change_memory_power(start, size, MEMORY_ACTIVE);
-}
-
-int platform_physical_low_power_pages(u64 start, u64 size)
-{
-	if (!change_memory_power)
-		return 0;
-	return change_memory_power(start, size, MEMORY_SELF_REFRESH);
-}
-
 char *memtype_name[] = {
 	"SMI_KERNEL",
 	"SMI",
diff --git a/arch/arm/mach-msm/memory_topology.c b/arch/arm/mach-msm/memory_topology.c
index 70aaf4a..781cd69 100644
--- a/arch/arm/mach-msm/memory_topology.c
+++ b/arch/arm/mach-msm/memory_topology.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
@@ -66,136 +66,6 @@
 }
 #endif
 
-#if (defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_MSM8930)) \
-	&& defined(CONFIG_ENABLE_DMM)
-static int rpm_change_memory_state(int retention_mask,
-					int active_mask)
-{
-	int ret;
-	struct msm_rpm_iv_pair cmd[2];
-	struct msm_rpm_iv_pair status[2];
-
-	cmd[0].id = MSM_RPM_ID_DDR_DMM_0;
-	cmd[1].id = MSM_RPM_ID_DDR_DMM_1;
-
-	status[0].id = MSM_RPM_STATUS_ID_DDR_DMM_0;
-	status[1].id = MSM_RPM_STATUS_ID_DDR_DMM_1;
-
-	cmd[0].value = retention_mask;
-	cmd[1].value = active_mask;
-
-	ret = msm_rpm_set(MSM_RPM_CTX_SET_0, cmd, 2);
-	if (ret < 0) {
-		pr_err("rpm set failed");
-		return -EINVAL;
-	}
-
-	ret = msm_rpm_get_status(status, 2);
-	if (ret < 0) {
-		pr_err("rpm status failed");
-		return -EINVAL;
-	}
-	if (status[0].value == retention_mask &&
-		status[1].value == active_mask)
-		return 0;
-	else {
-		pr_err("rpm failed to change memory state");
-		return -EINVAL;
-	}
-}
-
-static int switch_memory_state(int mask, int new_state, int start_region,
-				int end_region)
-{
-	int final_mask = 0;
-	int i;
-
-	mutex_lock(&mem_regions_mutex);
-
-	for (i = start_region; i <= end_region; i++) {
-		if (new_state == mem_regions[i].state)
-			goto no_change;
-		/* All region states must be the same to change them */
-		if (mem_regions[i].state != mem_regions[start_region].state)
-			goto no_change;
-	}
-
-	if (new_state == STATE_POWER_DOWN)
-		final_mask = mem_regions_mask & mask;
-	else if (new_state == STATE_ACTIVE)
-		final_mask = mem_regions_mask | ~mask;
-	else
-		goto no_change;
-
-	pr_info("request memory %d to %d state switch (%d->%d)\n",
-		start_region, end_region, mem_regions[start_region].state,
-		new_state);
-	if (rpm_change_memory_state(final_mask, final_mask) == 0) {
-		for (i = start_region; i <= end_region; i++)
-			mem_regions[i].state = new_state;
-		mem_regions_mask = final_mask;
-
-		pr_info("completed memory %d to %d state switch to %d\n",
-			start_region, end_region, new_state);
-		mutex_unlock(&mem_regions_mutex);
-		return 0;
-	}
-
-	pr_err("failed memory %d to %d state switch (%d->%d)\n",
-		start_region, end_region, mem_regions[start_region].state,
-		new_state);
-
-no_change:
-	mutex_unlock(&mem_regions_mutex);
-	return -EINVAL;
-}
-#else
-
-static int switch_memory_state(int mask, int new_state, int start_region,
-				int end_region)
-{
-	return -EINVAL;
-}
-#endif
-
-/* The hotplug code expects the number of bytes that switched state successfully
- * as the return value, so a return value of zero indicates an error
-*/
-int soc_change_memory_power(u64 start, u64 size, int change)
-{
-	int i = 0;
-	int mask = default_mask;
-	u64 end = start + size;
-	int start_region = 0;
-	int end_region = 0;
-
-	if (change != STATE_ACTIVE && change != STATE_POWER_DOWN) {
-		pr_info("requested state transition invalid\n");
-		return 0;
-	}
-	/* Find the memory regions that fall within the range */
-	for (i = 0; i < nr_mem_regions; i++) {
-		if (mem_regions[i].start <= start &&
-			mem_regions[i].start >=
-			mem_regions[start_region].start) {
-			start_region = i;
-		}
-		if (end <= mem_regions[i].start + mem_regions[i].size) {
-			end_region = i;
-			break;
-		}
-	}
-
-	/* Set the bitmask for each region in the range */
-	for (i = start_region; i <= end_region; i++)
-		mask &= ~(0x1 << i);
-
-	if (!switch_memory_state(mask, change, start_region, end_region))
-		return size;
-	else
-		return 0;
-}
-
 unsigned int get_num_memory_banks(void)
 {
 	return nr_mem_regions;
diff --git a/arch/arm/mach-msm/mkrpcsym.pl b/arch/arm/mach-msm/mkrpcsym.pl
index f4abb5f..52b6fcf 100644
--- a/arch/arm/mach-msm/mkrpcsym.pl
+++ b/arch/arm/mach-msm/mkrpcsym.pl
@@ -2,7 +2,7 @@
 #
 # Generate the smd_rpc_sym.c symbol file for ONCRPC SMEM Logging
 #
-# Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+# Copyright (c) 2009, The Linux Foundation. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
@@ -13,7 +13,7 @@
 #       copyright notice, this list of conditions and the following
 #       disclaimer in the documentation and/or other materials provided
 #       with the distribution.
-#     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+#     * Neither the name of The Linux Foundation nor the names of its
 #       contributors may be used to endorse or promote products derived
 #       from this software without specific prior written permission.
 #
diff --git a/arch/arm/mach-msm/modem-8660.c b/arch/arm/mach-msm/modem-8660.c
index 096ed9c..eca5645 100644
--- a/arch/arm/mach-msm/modem-8660.c
+++ b/arch/arm/mach-msm/modem-8660.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/modem-8960.c b/arch/arm/mach-msm/modem-8960.c
index c7cbac1..cda3237 100644
--- a/arch/arm/mach-msm/modem-8960.c
+++ b/arch/arm/mach-msm/modem-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/modem_notifier.c b/arch/arm/mach-msm/modem_notifier.c
index 2f4f6af..56aedfd 100644
--- a/arch/arm/mach-msm/modem_notifier.c
+++ b/arch/arm/mach-msm/modem_notifier.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/modem_notifier.h b/arch/arm/mach-msm/modem_notifier.h
index e39c163..96ad047 100644
--- a/arch/arm/mach-msm/modem_notifier.h
+++ b/arch/arm/mach-msm/modem_notifier.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/mpm-8625.c b/arch/arm/mach-msm/mpm-8625.c
index fe7ffff..8962965 100644
--- a/arch/arm/mach-msm/mpm-8625.c
+++ b/arch/arm/mach-msm/mpm-8625.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/mpm-8625.h b/arch/arm/mach-msm/mpm-8625.h
index 1c28390..884f6c9 100644
--- a/arch/arm/mach-msm/mpm-8625.h
+++ b/arch/arm/mach-msm/mpm-8625.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/mpm-of.c b/arch/arm/mach-msm/mpm-of.c
index e4c0e4e..792504c 100644
--- a/arch/arm/mach-msm/mpm-of.c
+++ b/arch/arm/mach-msm/mpm-of.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/mpm.c b/arch/arm/mach-msm/mpm.c
index 1c39415..3c884a9 100644
--- a/arch/arm/mach-msm/mpm.c
+++ b/arch/arm/mach-msm/mpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/mpp.c b/arch/arm/mach-msm/mpp.c
index bd70e9a..82e0f34 100644
--- a/arch/arm/mach-msm/mpp.c
+++ b/arch/arm/mach-msm/mpp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm-buspm-dev.c b/arch/arm/mach-msm/msm-buspm-dev.c
index a818eed..a329add 100644
--- a/arch/arm/mach-msm/msm-buspm-dev.c
+++ b/arch/arm/mach-msm/msm-buspm-dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm-buspm-dev.h b/arch/arm/mach-msm/msm-buspm-dev.h
index 5839087..5754771 100644
--- a/arch/arm/mach-msm/msm-buspm-dev.h
+++ b/arch/arm/mach-msm/msm-buspm-dev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm-keypad-devices.h b/arch/arm/mach-msm/msm-keypad-devices.h
index 469564a..153c69a 100644
--- a/arch/arm/mach-msm/msm-keypad-devices.h
+++ b/arch/arm/mach-msm/msm-keypad-devices.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/msm-krait-l2-accessors.c b/arch/arm/mach-msm/msm-krait-l2-accessors.c
index 2c66ea0..7498e7f 100644
--- a/arch/arm/mach-msm/msm-krait-l2-accessors.c
+++ b/arch/arm/mach-msm/msm-krait-l2-accessors.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
index 65539c6..e5616b9 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
index e0ab983..a3f9559 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h
index 249e8bb..6df0bea 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c
index 5a3d722..b45efad 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
index 296c6dc..b593439 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c
index 0f37c6d..91d106e 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
index d079e77..056763c 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8974.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8974.c
index 265716d..64ed136 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8974.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
index 34cb2db..b3c3e7f 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_config.c b/arch/arm/mach-msm/msm_bus/msm_bus_config.c
index 28f3073..c6fa250 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_config.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_config.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_core.c b/arch/arm/mach-msm/msm_bus/msm_bus_core.c
index 4d73b03..6f65bcc 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_core.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_core.h b/arch/arm/mach-msm/msm_bus/msm_bus_core.h
index 12d6862..721d019 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_core.h
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -36,7 +36,7 @@
 	(((slv >= MSM_BUS_SLAVE_FIRST) && (slv <= MSM_BUS_SLAVE_LAST)) ? 1 : 0)
 
 #define INTERLEAVED_BW(fab_pdata, bw, ports) \
-	((fab_pdata->il_flag) ? msm_bus_div64((bw), (ports)) : (bw))
+	((fab_pdata->il_flag) ? msm_bus_div64((ports), (bw)) : (bw))
 #define INTERLEAVED_VAL(fab_pdata, n) \
 	((fab_pdata->il_flag) ? (n) : 1)
 
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c b/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c
index a44c53a..001c733 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_dbg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
index 7169440..0e92ee4 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_noc.c b/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
index fb2e5da..5f2ba6e 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_noc.h b/arch/arm/mach-msm/msm_bus/msm_bus_noc.h
index 35af884..00479c6 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_noc.h
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_noc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c b/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c
index fc38ef7..fd1aacd 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c b/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
index 88fab96..424eb3f 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_cache_dump.c b/arch/arm/mach-msm/msm_cache_dump.c
index 9759d5a..d4699b1 100644
--- a/arch/arm/mach-msm/msm_cache_dump.c
+++ b/arch/arm/mach-msm/msm_cache_dump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_cpr-debug.c b/arch/arm/mach-msm/msm_cpr-debug.c
index 723423c..3564bbe 100644
--- a/arch/arm/mach-msm/msm_cpr-debug.c
+++ b/arch/arm/mach-msm/msm_cpr-debug.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_cpr.c b/arch/arm/mach-msm/msm_cpr.c
index 3ef39c7..6551762 100644
--- a/arch/arm/mach-msm/msm_cpr.c
+++ b/arch/arm/mach-msm/msm_cpr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_cpr.h b/arch/arm/mach-msm/msm_cpr.h
index 2642b9c..fd9ec14 100644
--- a/arch/arm/mach-msm/msm_cpr.h
+++ b/arch/arm/mach-msm/msm_cpr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_dsps.c b/arch/arm/mach-msm/msm_dsps.c
index c39829b..69d1a7b 100644
--- a/arch/arm/mach-msm/msm_dsps.c
+++ b/arch/arm/mach-msm/msm_dsps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_fault_handlers.c b/arch/arm/mach-msm/msm_fault_handlers.c
index c975856..7b2dc8c 100644
--- a/arch/arm/mach-msm/msm_fault_handlers.c
+++ b/arch/arm/mach-msm/msm_fault_handlers.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1995  Linus Torvalds
  *  Modifications for ARM processor (c) 1995-2004 Russell King
- *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2010, The Linux Foundation. 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
diff --git a/arch/arm/mach-msm/msm_ipc_router_security.c b/arch/arm/mach-msm/msm_ipc_router_security.c
new file mode 100644
index 0000000..756e24e
--- /dev/null
+++ b/arch/arm/mach-msm/msm_ipc_router_security.c
@@ -0,0 +1,297 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
+ * only 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.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/net.h>
+#include <linux/socket.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/gfp.h>
+#include <linux/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/msm_ipc.h>
+
+#include <asm/uaccess.h>
+
+#include <net/sock.h>
+#include "ipc_router.h"
+#include "msm_ipc_router_security.h"
+
+#define IRSC_COMPLETION_TIMEOUT_MS 30000
+#define SEC_RULES_HASH_SZ 32
+struct security_rule {
+	struct list_head list;
+	uint32_t service_id;
+	uint32_t instance_id;
+	unsigned reserved;
+	int num_group_info;
+	int *group_id;
+};
+
+static DEFINE_MUTEX(security_rules_lock);
+static struct list_head security_rules[SEC_RULES_HASH_SZ];
+static DECLARE_COMPLETION(irsc_completion);
+
+/**
+ * wait_for_irsc_completion() - Wait for IPC Router Security Configuration
+ *                              (IRSC) to complete
+ */
+void wait_for_irsc_completion(void)
+{
+	unsigned long rem_jiffies;
+	do {
+		rem_jiffies = wait_for_completion_timeout(&irsc_completion,
+				msecs_to_jiffies(IRSC_COMPLETION_TIMEOUT_MS));
+		if (rem_jiffies)
+			return;
+		pr_err("%s: waiting for IPC Security Conf.\n", __func__);
+	} while (1);
+}
+
+/**
+ * signal_irsc_completion() - Signal the completion of IRSC
+ */
+void signal_irsc_completion(void)
+{
+	complete_all(&irsc_completion);
+}
+
+/**
+ * check_permisions() - Check whether the process has permissions to
+ *                      create an interface handle with IPC Router
+ *
+ * @return: true if the process has permissions, else false.
+ */
+int check_permissions(void)
+{
+	int rc = 0;
+	if (!current_euid() || in_egroup_p(AID_NET_RAW))
+		rc = 1;
+	return rc;
+}
+EXPORT_SYMBOL(check_permissions);
+
+/**
+ * msm_ipc_config_sec_rules() - Add a security rule to the database
+ * @arg: Pointer to the buffer containing the rule.
+ *
+ * @return: 0 if successfully added, < 0 for error.
+ *
+ * A security rule is defined using <Service_ID: Group_ID> tuple. The rule
+ * implies that a user-space process in order to send a QMI message to
+ * service Service_ID should belong to the Linux group Group_ID.
+ */
+int msm_ipc_config_sec_rules(void *arg)
+{
+	struct config_sec_rules_args sec_rules_arg;
+	struct security_rule *rule, *temp_rule;
+	int key;
+	int ret;
+
+	if (current_euid())
+		return -EPERM;
+
+	ret = copy_from_user(&sec_rules_arg, (void *)arg,
+			     sizeof(sec_rules_arg));
+	if (ret)
+		return -EFAULT;
+
+	if (sec_rules_arg.num_group_info <= 0)
+		return -EINVAL;
+
+	rule = kzalloc(sizeof(struct security_rule), GFP_KERNEL);
+	if (!rule) {
+		pr_err("%s: security_rule alloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	rule->group_id = kzalloc((sec_rules_arg.num_group_info * sizeof(int)),
+				 GFP_KERNEL);
+	if (!rule->group_id) {
+		pr_err("%s: group_id alloc failed\n", __func__);
+		kfree(rule);
+		return -ENOMEM;
+	}
+
+	rule->service_id = sec_rules_arg.service_id;
+	rule->instance_id = sec_rules_arg.instance_id;
+	rule->reserved = sec_rules_arg.reserved;
+	rule->num_group_info = sec_rules_arg.num_group_info;
+	ret = copy_from_user(rule->group_id,
+			     ((void *)(arg + sizeof(sec_rules_arg))),
+			     (rule->num_group_info * sizeof(uint32_t)));
+	if (ret) {
+		kfree(rule->group_id);
+		kfree(rule);
+		return -EFAULT;
+	}
+
+	key = rule->service_id & (SEC_RULES_HASH_SZ - 1);
+	mutex_lock(&security_rules_lock);
+	if (rule->service_id == ALL_SERVICE) {
+		temp_rule = list_first_entry(&security_rules[key],
+					     struct security_rule, list);
+		list_del(&temp_rule->list);
+		kfree(temp_rule->group_id);
+		kfree(temp_rule);
+	}
+	list_add_tail(&rule->list, &security_rules[key]);
+	mutex_unlock(&security_rules_lock);
+
+	if (rule->service_id == ALL_SERVICE)
+		msm_ipc_sync_default_sec_rule((void *)rule);
+	else
+		msm_ipc_sync_sec_rule(rule->service_id, rule->instance_id,
+				      (void *)rule);
+
+	return 0;
+}
+EXPORT_SYMBOL(msm_ipc_config_sec_rules);
+
+/**
+ * msm_ipc_add_default_rule() - Add default security rule
+ *
+ * @return: 0 on success, < 0 on error/
+ *
+ * This function is used to ensure the basic security, if there is no
+ * security rule defined for a service. It can be overwritten by the
+ * default security rule from user-space script.
+ */
+static int msm_ipc_add_default_rule(void)
+{
+	struct security_rule *rule;
+	int key;
+
+	rule = kzalloc(sizeof(struct security_rule), GFP_KERNEL);
+	if (!rule) {
+		pr_err("%s: security_rule alloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	rule->group_id = kzalloc(sizeof(int), GFP_KERNEL);
+	if (!rule->group_id) {
+		pr_err("%s: group_id alloc failed\n", __func__);
+		kfree(rule);
+		return -ENOMEM;
+	}
+
+	rule->service_id = ALL_SERVICE;
+	rule->instance_id = ALL_INSTANCE;
+	rule->num_group_info = 1;
+	*(rule->group_id) = AID_NET_RAW;
+	mutex_lock(&security_rules_lock);
+	key = (ALL_SERVICE & (SEC_RULES_HASH_SZ - 1));
+	list_add_tail(&rule->list, &security_rules[key]);
+	mutex_unlock(&security_rules_lock);
+	return 0;
+}
+
+/**
+ * msm_ipc_get_security_rule() - Get the security rule corresponding to a
+ *                               service
+ * @service_id: Service ID for which the rule has to be got.
+ * @instance_id: Instance ID for which the rule has to be got.
+ *
+ * @return: Returns the rule info on success, NULL on error.
+ *
+ * This function is used when the service comes up and gets registered with
+ * the IPC Router.
+ */
+void *msm_ipc_get_security_rule(uint32_t service_id, uint32_t instance_id)
+{
+	int key;
+	struct security_rule *rule;
+
+	key = (service_id & (SEC_RULES_HASH_SZ - 1));
+	mutex_lock(&security_rules_lock);
+	/* Return the rule for a specific <service:instance>, if found. */
+	list_for_each_entry(rule, &security_rules[key], list) {
+		if ((rule->service_id == service_id) &&
+		    (rule->instance_id == instance_id)) {
+			mutex_unlock(&security_rules_lock);
+			return (void *)rule;
+		}
+	}
+
+	/* Return the rule for a specific service, if found. */
+	list_for_each_entry(rule, &security_rules[key], list) {
+		if ((rule->service_id == service_id) &&
+		    (rule->instance_id == ALL_INSTANCE)) {
+			mutex_unlock(&security_rules_lock);
+			return (void *)rule;
+		}
+	}
+
+	/* Return the default rule, if no rule defined for a service. */
+	key = (ALL_SERVICE & (SEC_RULES_HASH_SZ - 1));
+	list_for_each_entry(rule, &security_rules[key], list) {
+		if ((rule->service_id == ALL_SERVICE) &&
+		    (rule->instance_id == ALL_INSTANCE)) {
+			mutex_unlock(&security_rules_lock);
+			return (void *)rule;
+		}
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(msm_ipc_get_security_rule);
+
+/**
+ * msm_ipc_check_send_permissions() - Check if the sendng process has
+ *                                    permissions specified as per the rule
+ * @data: Security rule to be checked.
+ *
+ * @return: true if the process has permissions, else false.
+ *
+ * This function is used to check if the current executing process has
+ * permissions to send message to the remote entity. The security rule
+ * corresponding to the remote entity is specified by "data" parameter
+ */
+int msm_ipc_check_send_permissions(void *data)
+{
+	int i;
+	struct security_rule *rule = (struct security_rule *)data;
+
+	/* Source/Sender is Root user */
+	if (!current_euid())
+		return 1;
+
+	/* Destination has no rules defined, possibly a client. */
+	if (!rule)
+		return 1;
+
+	for (i = 0; i < rule->num_group_info; i++) {
+		if (in_egroup_p(rule->group_id[i]))
+			return 1;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(msm_ipc_check_send_permissions);
+
+/**
+ * msm_ipc_router_security_init() - Initialize the security rule database
+ *
+ * @return: 0 if successful, < 0 for error.
+ */
+int msm_ipc_router_security_init(void)
+{
+	int i;
+
+	for (i = 0; i < SEC_RULES_HASH_SZ; i++)
+		INIT_LIST_HEAD(&security_rules[i]);
+
+	msm_ipc_add_default_rule();
+	return 0;
+}
+EXPORT_SYMBOL(msm_ipc_router_security_init);
diff --git a/arch/arm/mach-msm/msm_ipc_router_security.h b/arch/arm/mach-msm/msm_ipc_router_security.h
new file mode 100644
index 0000000..9cc61e9
--- /dev/null
+++ b/arch/arm/mach-msm/msm_ipc_router_security.h
@@ -0,0 +1,120 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
+ * only 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.
+ */
+
+#ifndef _MSM_IPC_ROUTER_SECURITY_H
+#define _MSM_IPC_ROUTER_SECURITY_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/errno.h>
+
+#ifdef CONFIG_MSM_IPC_ROUTER_SECURITY
+#include <linux/android_aid.h>
+
+/**
+ * check_permisions() - Check whether the process has permissions to
+ *                      create an interface handle with IPC Router
+ *
+ * @return: true if the process has permissions, else false.
+ */
+int check_permissions(void);
+
+/**
+ * msm_ipc_config_sec_rules() - Add a security rule to the database
+ * @arg: Pointer to the buffer containing the rule.
+ *
+ * @return: 0 if successfully added, < 0 for error.
+ *
+ * A security rule is defined using <Service_ID: Group_ID> tuple. The rule
+ * implies that a user-space process in order to send a QMI message to
+ * service Service_ID should belong to the Linux group Group_ID.
+ */
+int msm_ipc_config_sec_rules(void *arg);
+
+/**
+ * msm_ipc_get_security_rule() - Get the security rule corresponding to a
+ *                               service
+ * @service_id: Service ID for which the rule has to be got.
+ * @instance_id: Instance ID for which the rule has to be got.
+ *
+ * @return: Returns the rule info on success, NULL on error.
+ *
+ * This function is used when the service comes up and gets registered with
+ * the IPC Router.
+ */
+void *msm_ipc_get_security_rule(uint32_t service_id, uint32_t instance_id);
+
+/**
+ * msm_ipc_check_send_permissions() - Check if the sendng process has
+ *                                    permissions specified as per the rule
+ * @data: Security rule to be checked.
+ *
+ * @return: true if the process has permissions, else false.
+ *
+ * This function is used to check if the current executing process has
+ * permissions to send message to the remote entity. The security rule
+ * corresponding to the remote entity is specified by "data" parameter
+ */
+int msm_ipc_check_send_permissions(void *data);
+
+/**
+ * msm_ipc_router_security_init() - Initialize the security rule database
+ *
+ * @return: 0 if successful, < 0 for error.
+ */
+int msm_ipc_router_security_init(void);
+
+/**
+ * wait_for_irsc_completion() - Wait for IPC Router Security Configuration
+ *                              (IRSC) to complete
+ */
+void wait_for_irsc_completion(void);
+
+/**
+ * signal_irsc_completion() - Signal the completion of IRSC
+ */
+void signal_irsc_completion(void);
+
+#else
+
+static inline int check_permissions(void)
+{
+	return 1;
+}
+
+static inline int msm_ipc_config_sec_rules(void *arg)
+{
+	return -ENODEV;
+}
+
+static inline void *msm_ipc_get_security_rule(uint32_t service_id,
+					      uint32_t instance_id)
+{
+	return NULL;
+}
+
+static inline int msm_ipc_check_send_permissions(void *data)
+{
+	return 1;
+}
+
+static inline int msm_ipc_router_security_init(void)
+{
+	return 0;
+}
+
+static inline void wait_for_irsc_completion(void) { }
+
+static inline void signal_irsc_completion(void) { }
+
+#endif
+#endif
diff --git a/arch/arm/mach-msm/msm_kexec.c b/arch/arm/mach-msm/msm_kexec.c
index 4597cf0..a1b19ff 100644
--- a/arch/arm/mach-msm/msm_kexec.c
+++ b/arch/arm/mach-msm/msm_kexec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_memory_dump.c b/arch/arm/mach-msm/msm_memory_dump.c
index 17cb2da..0265a3f 100644
--- a/arch/arm/mach-msm/msm_memory_dump.c
+++ b/arch/arm/mach-msm/msm_memory_dump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_rq_stats.c b/arch/arm/mach-msm/msm_rq_stats.c
index ea08f4b..f70022e 100644
--- a/arch/arm/mach-msm/msm_rq_stats.c
+++ b/arch/arm/mach-msm/msm_rq_stats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -30,6 +30,8 @@
 #include <linux/kernel_stat.h>
 #include <linux/tick.h>
 #include <asm/smp_plat.h>
+#include "acpuclock.h"
+#include <linux/suspend.h>
 
 #define MAX_LONG_SIZE 24
 #define DEFAULT_RQ_POLL_JIFFIES 1
@@ -196,6 +198,8 @@
 
 	switch (val) {
 	case CPU_ONLINE:
+		if (!this_cpu->cur_freq)
+			this_cpu->cur_freq = acpuclk_get_rate(cpu);
 	case CPU_ONLINE_FROZEN:
 		this_cpu->avg_load_maxfreq = 0;
 	}
@@ -203,6 +207,36 @@
 	return NOTIFY_OK;
 }
 
+static int system_suspend_handler(struct notifier_block *nb,
+				unsigned long val, void *data)
+{
+	switch (val) {
+	case PM_POST_HIBERNATION:
+	case PM_POST_SUSPEND:
+	case PM_POST_RESTORE:
+		rq_info.hotplug_disabled = 0;
+		break;
+	case PM_HIBERNATION_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		rq_info.hotplug_disabled = 1;
+		break;
+	default:
+		return NOTIFY_DONE;
+	}
+	return NOTIFY_OK;
+}
+
+
+static ssize_t hotplug_disable_show(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
+{
+	unsigned int val = 0;
+	val = rq_info.hotplug_disabled;
+	return snprintf(buf, MAX_LONG_SIZE, "%d\n", val);
+}
+
+static struct kobj_attribute hotplug_disabled_attr = __ATTR_RO(hotplug_disable);
+
 static void def_work_fn(struct work_struct *work)
 {
 	int64_t diff;
@@ -307,6 +341,7 @@
 	&def_timer_ms_attr.attr,
 	&run_queue_avg_attr.attr,
 	&run_queue_poll_ms_attr.attr,
+	&hotplug_disabled_attr.attr,
 	NULL,
 };
 
@@ -355,6 +390,7 @@
 	rq_info.def_timer_jiffies = DEFAULT_DEF_TIMER_JIFFIES;
 	rq_info.rq_poll_last_jiffy = 0;
 	rq_info.def_timer_last_jiffy = 0;
+	rq_info.hotplug_disabled = 0;
 	ret = init_rq_attribs();
 
 	rq_info.init = 1;
@@ -364,6 +400,8 @@
 		mutex_init(&pcpu->cpu_load_mutex);
 		cpufreq_get_policy(&cpu_policy, i);
 		pcpu->policy_max = cpu_policy.cpuinfo.max_freq;
+		if (cpu_online(i))
+			pcpu->cur_freq = acpuclk_get_rate(i);
 		cpumask_copy(pcpu->related_cpus, cpu_policy.cpus);
 	}
 	freq_transition.notifier_call = cpufreq_transition_handler;
@@ -375,3 +413,16 @@
 	return ret;
 }
 late_initcall(msm_rq_stats_init);
+
+static int __init msm_rq_stats_early_init(void)
+{
+	/* Bail out if this is not an SMP Target */
+	if (!is_smp()) {
+		rq_info.init = 0;
+		return -ENOSYS;
+	}
+
+	pm_notifier(system_suspend_handler, 0);
+	return 0;
+}
+core_initcall(msm_rq_stats_early_init);
diff --git a/arch/arm/mach-msm/msm_rtb.c b/arch/arm/mach-msm/msm_rtb.c
index 5082c74..9faeabc 100644
--- a/arch/arm/mach-msm/msm_rtb.c
+++ b/arch/arm/mach-msm/msm_rtb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_show_resume_irq.c b/arch/arm/mach-msm/msm_show_resume_irq.c
index 8209367..6fc06d5 100644
--- a/arch/arm/mach-msm/msm_show_resume_irq.c
+++ b/arch/arm/mach-msm/msm_show_resume_irq.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_smem_iface.c b/arch/arm/mach-msm/msm_smem_iface.c
index b09fda5..35d0923 100644
--- a/arch/arm/mach-msm/msm_smem_iface.c
+++ b/arch/arm/mach-msm/msm_smem_iface.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_smem_iface.h b/arch/arm/mach-msm/msm_smem_iface.h
index 2da0232..f95f701 100644
--- a/arch/arm/mach-msm/msm_smem_iface.h
+++ b/arch/arm/mach-msm/msm_smem_iface.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_vibrator.c b/arch/arm/mach-msm/msm_vibrator.c
index 5595ba0..9f811ac 100644
--- a/arch/arm/mach-msm/msm_vibrator.c
+++ b/arch/arm/mach-msm/msm_vibrator.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 HTC Corporation.
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/msm_vp.c b/arch/arm/mach-msm/msm_vp.c
index 2569474..47748c8 100644
--- a/arch/arm/mach-msm/msm_vp.c
+++ b/arch/arm/mach-msm/msm_vp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index aca7667..b1c8b30 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_watchdog.h b/arch/arm/mach-msm/msm_watchdog.h
index 5fb82ee..0063036 100644
--- a/arch/arm/mach-msm/msm_watchdog.h
+++ b/arch/arm/mach-msm/msm_watchdog.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_watchdog_asm.S b/arch/arm/mach-msm/msm_watchdog_asm.S
index c0377d6..ea6cc38 100644
--- a/arch/arm/mach-msm/msm_watchdog_asm.S
+++ b/arch/arm/mach-msm/msm_watchdog_asm.S
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_watchdog_v2.c b/arch/arm/mach-msm/msm_watchdog_v2.c
index dccedea..31ed020 100644
--- a/arch/arm/mach-msm/msm_watchdog_v2.c
+++ b/arch/arm/mach-msm/msm_watchdog_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/msm_xo.c b/arch/arm/mach-msm/msm_xo.c
index 46d4a12..e7c4a6a 100644
--- a/arch/arm/mach-msm/msm_xo.c
+++ b/arch/arm/mach-msm/msm_xo.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/nand_partitions.c b/arch/arm/mach-msm/nand_partitions.c
index 499ad99..ea5fb9c 100644
--- a/arch/arm/mach-msm/nand_partitions.c
+++ b/arch/arm/mach-msm/nand_partitions.c
@@ -4,7 +4,7 @@
  * bootloader.
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2009,2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009,2011 The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/no-pm.c b/arch/arm/mach-msm/no-pm.c
index d38b416..c28163f 100644
--- a/arch/arm/mach-msm/no-pm.c
+++ b/arch/arm/mach-msm/no-pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/nohlt.c b/arch/arm/mach-msm/nohlt.c
index 532d57d..e598ed0 100644
--- a/arch/arm/mach-msm/nohlt.c
+++ b/arch/arm/mach-msm/nohlt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ocmem.c b/arch/arm/mach-msm/ocmem.c
index 82fe2f8..61f973a 100644
--- a/arch/arm/mach-msm/ocmem.c
+++ b/arch/arm/mach-msm/ocmem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ocmem_allocator.c b/arch/arm/mach-msm/ocmem_allocator.c
index 71cacda..203bb60 100644
--- a/arch/arm/mach-msm/ocmem_allocator.c
+++ b/arch/arm/mach-msm/ocmem_allocator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ocmem_api.c b/arch/arm/mach-msm/ocmem_api.c
index 6e094fd..f14a777 100644
--- a/arch/arm/mach-msm/ocmem_api.c
+++ b/arch/arm/mach-msm/ocmem_api.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ocmem_core.c b/arch/arm/mach-msm/ocmem_core.c
index 114c3f1..9677356 100644
--- a/arch/arm/mach-msm/ocmem_core.c
+++ b/arch/arm/mach-msm/ocmem_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ocmem_notifier.c b/arch/arm/mach-msm/ocmem_notifier.c
index 644c809..e7271a9 100644
--- a/arch/arm/mach-msm/ocmem_notifier.c
+++ b/arch/arm/mach-msm/ocmem_notifier.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ocmem_rdm.c b/arch/arm/mach-msm/ocmem_rdm.c
index 85dc85d..5c66fdd 100644
--- a/arch/arm/mach-msm/ocmem_rdm.c
+++ b/arch/arm/mach-msm/ocmem_rdm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ocmem_sched.c b/arch/arm/mach-msm/ocmem_sched.c
index 2d968aa..90d0630 100644
--- a/arch/arm/mach-msm/ocmem_sched.c
+++ b/arch/arm/mach-msm/ocmem_sched.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/oem_rapi_client.c b/arch/arm/mach-msm/oem_rapi_client.c
index bcf6e57..2e1e741 100644
--- a/arch/arm/mach-msm/oem_rapi_client.c
+++ b/arch/arm/mach-msm/oem_rapi_client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pcie.c b/arch/arm/mach-msm/pcie.c
index 709c8e8..dfe4b47 100644
--- a/arch/arm/mach-msm/pcie.c
+++ b/arch/arm/mach-msm/pcie.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pcie.h b/arch/arm/mach-msm/pcie.h
index d7cce3e..8e4253b 100644
--- a/arch/arm/mach-msm/pcie.h
+++ b/arch/arm/mach-msm/pcie.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pcie_irq.c b/arch/arm/mach-msm/pcie_irq.c
index 5a44a17..f590827 100644
--- a/arch/arm/mach-msm/pcie_irq.c
+++ b/arch/arm/mach-msm/pcie_irq.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/perf_debug.c b/arch/arm/mach-msm/perf_debug.c
new file mode 100644
index 0000000..bbd0852
--- /dev/null
+++ b/arch/arm/mach-msm/perf_debug.c
@@ -0,0 +1,67 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 and
+ * only 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.
+ */
+
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+
+/*
+ * Subsequent patches should add an entry to end of this string.
+ * Format is incrementing sequence number followed by text of
+ * patch commit title with newline.
+ * Note trailing ';' is on its own line to simplify addition of
+ * future strings.
+ */
+static char *descriptions =
+	"0  msm: perf: add debug patch logging framework\n"
+	"1  Perf: Restore counter after powercollapse for generic ARM PMU's\n"
+	"2  Perf: Toggle PMU IRQ when CPU's are hotplugged\n"
+	"3  Perf: Correct irq for CPU hotplug detection\n"
+;
+
+static ssize_t desc_read(struct file *fp, char __user *buf,
+			 size_t count, loff_t *pos)
+{
+	return simple_read_from_buffer(buf, count, pos, descriptions,
+				       strlen(descriptions));
+}
+
+static const struct file_operations perf_debug_desc_fops = {
+	.read = desc_read,
+};
+
+static int msm_perf_debugfs_init(void)
+{
+	int ret = 0;
+	struct dentry *dir;
+	struct dentry *file;
+
+	dir = debugfs_create_dir("msm-perf-patches", NULL);
+	if (IS_ERR_OR_NULL(dir)) {
+		pr_err("failed to create msm-perf-patches dir in debugfs\n");
+		ret = PTR_ERR(dir);
+		goto init_exit;
+	}
+
+	file = debugfs_create_file("descriptions", 0444, dir, NULL,
+				   &perf_debug_desc_fops);
+	if (IS_ERR_OR_NULL(file)) {
+		debugfs_remove(dir);
+		pr_err("failed to create descriptions file for msm-perf-patches\n");
+		ret = PTR_ERR(file);
+		goto init_exit;
+	}
+
+init_exit:
+	return ret;
+}
+late_initcall(msm_perf_debugfs_init);
diff --git a/arch/arm/mach-msm/perf_event_msm_krait_l2.c b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
index 103eef0..34b9426 100644
--- a/arch/arm/mach-msm/perf_event_msm_krait_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, 2012 The Linux Foundation. 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 and
@@ -72,9 +72,11 @@
  */
 struct pmu_constraints {
 	u64 pmu_bitmap;
+	u8 codes[64];
 	raw_spinlock_t lock;
 } l2_pmu_constraints = {
 	.pmu_bitmap = 0,
+	.codes = {-1},
 	.lock = __RAW_SPIN_LOCK_UNLOCKED(l2_pmu_constraints.lock),
 };
 
@@ -335,8 +337,10 @@
 	int ctr = 0;
 
 	if (hwc->config_base == L2CYCLE_CTR_RAW_CODE) {
-		if (!test_and_set_bit(l2_cycle_ctr_idx, cpuc->used_mask))
-			return l2_cycle_ctr_idx;
+		if (test_and_set_bit(l2_cycle_ctr_idx, cpuc->used_mask))
+			return -EAGAIN;
+
+		return l2_cycle_ctr_idx;
 	}
 
 	for (ctr = 0; ctr < total_l2_ctrs - 1; ctr++) {
@@ -453,22 +457,48 @@
 {
 	u32 evt_type = event->attr.config & L2_EVT_MASK;
 	u8 reg   = (evt_type & 0x0F000) >> 12;
-	u8 group =  evt_type & 0x0000F;
+	u8 group = evt_type & 0x0000F;
+	u8 code = (evt_type & 0x00FF0) >> 4;
 	unsigned long flags;
 	u32 err = 0;
 	u64 bitmap_t;
+	u32 shift_idx;
+
+	/*
+	 * Cycle counter collision is detected in
+	 * get_event_idx().
+	 */
+	if (evt_type == L2CYCLE_CTR_RAW_CODE)
+		return err;
 
 	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
 
-	bitmap_t = 1 << ((reg * 4) + group);
+	shift_idx = ((reg * 4) + group);
+
+	bitmap_t = 1 << shift_idx;
 
 	if (!(l2_pmu_constraints.pmu_bitmap & bitmap_t)) {
 		l2_pmu_constraints.pmu_bitmap |= bitmap_t;
+		l2_pmu_constraints.codes[shift_idx] = code;
 		goto out;
+	} else {
+		/*
+		 * If NRCCG's are identical,
+		 * its not column exclusion.
+		 */
+		if (l2_pmu_constraints.codes[shift_idx] != code)
+			err = -EPERM;
+		else
+			/*
+			 * If the event is counted in syswide mode
+			 * then we want to count only on one CPU
+			 * and set its filter to count from all.
+			 * This sets the event OFF on all but one
+			 * CPU.
+			 */
+			if (!(event->cpu < 0))
+				event->state = PERF_EVENT_STATE_OFF;
 	}
-
-	/* Bit is already set. Constraint failed. */
-	err = -EPERM;
 out:
 	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
 	return err;
@@ -481,14 +511,20 @@
 	u8 group =  evt_type & 0x0000F;
 	unsigned long flags;
 	u64 bitmap_t;
+	u32 shift_idx;
 
 	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
 
-	bitmap_t = 1 << ((reg * 4) + group);
+	shift_idx = ((reg * 4) + group);
+
+	bitmap_t = 1 << shift_idx;
 
 	/* Clear constraint bit. */
 	l2_pmu_constraints.pmu_bitmap &= ~bitmap_t;
 
+	/* Clear code. */
+	l2_pmu_constraints.codes[shift_idx] = -1;
+
 	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
 	return 1;
 }
diff --git a/arch/arm/mach-msm/perf_event_msm_l2.c b/arch/arm/mach-msm/perf_event_msm_l2.c
index 2ad36df..f78487a 100644
--- a/arch/arm/mach-msm/perf_event_msm_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_l2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, 2012 The Linux Foundation. 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 and
@@ -38,9 +38,11 @@
  */
 struct pmu_constraints {
 	u64 pmu_bitmap;
+	u8 codes[64];
 	raw_spinlock_t lock;
 } l2_pmu_constraints = {
 	.pmu_bitmap = 0,
+	.codes = {-1},
 	.lock = __RAW_SPIN_LOCK_UNLOCKED(l2_pmu_constraints.lock),
 };
 
@@ -667,9 +669,11 @@
 	int ctr = 0;
 
 	if (hwc->config_base == SCORPION_L2CYCLE_CTR_RAW_CODE) {
-		if (!test_and_set_bit(l2_cycle_ctr_idx,
+		if (test_and_set_bit(l2_cycle_ctr_idx,
 					cpuc->used_mask))
-			return l2_cycle_ctr_idx;
+			return -EAGAIN;
+
+		return l2_cycle_ctr_idx;
 	}
 
 	for (ctr = 0; ctr < total_l2_ctrs - 1; ctr++) {
@@ -792,25 +796,50 @@
 	u8 prefix = (evt_type & 0xF0000) >> 16;
 	u8 reg   = (evt_type & 0x0F000) >> 12;
 	u8 group =  evt_type & 0x0000F;
+	u8 code = (evt_type & 0x00FF0) >> 4;
 	unsigned long flags;
 	u32 err = 0;
 	u64 bitmap_t;
+	u32 shift_idx;
 
 	if (!prefix)
 		return 0;
+	/*
+	 * Cycle counter collision is detected in
+	 * get_event_idx().
+	 */
+	if (evt_type == SCORPION_L2CYCLE_CTR_RAW_CODE)
+		return err;
 
 	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
 
-	bitmap_t = 1 << ((reg * 4) + group);
+	shift_idx = ((reg * 4) + group);
+
+	bitmap_t = 1 << shift_idx;
 
 	if (!(l2_pmu_constraints.pmu_bitmap & bitmap_t)) {
 		l2_pmu_constraints.pmu_bitmap |= bitmap_t;
+		l2_pmu_constraints.codes[shift_idx] = code;
 		goto out;
+	} else {
+		/*
+		 * If NRCCG's are identical,
+		 * its not column exclusion.
+		 */
+		if (l2_pmu_constraints.codes[shift_idx] != code)
+			err = -EPERM;
+		else
+			/*
+			 * If the event is counted in syswide mode
+			 * then we want to count only on one CPU
+			 * and set its filter to count from all.
+			 * This sets the event OFF on all but one
+			 * CPU.
+			 */
+			if (!(event->cpu < 0))
+				event->state = PERF_EVENT_STATE_OFF;
 	}
 
-	/* Bit is already set. Constraint failed. */
-	err = -EPERM;
-
 out:
 	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
 	return err;
@@ -824,13 +853,16 @@
 	u8 group =  evt_type & 0x0000F;
 	unsigned long flags;
 	u64 bitmap_t;
+	u32 shift_idx;
 
 	if (!prefix)
 		return 0;
 
 	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
 
-	bitmap_t = 1 << ((reg * 4) + group);
+	shift_idx = ((reg * 4) + group);
+
+	bitmap_t = 1 << shift_idx;
 
 	/* Clear constraint bit. */
 	l2_pmu_constraints.pmu_bitmap &= ~bitmap_t;
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index 4ff34bf..17f2835 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/peripheral-loader.h b/arch/arm/mach-msm/peripheral-loader.h
index e3b250b..6113ed6 100644
--- a/arch/arm/mach-msm/peripheral-loader.h
+++ b/arch/arm/mach-msm/peripheral-loader.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-dsps.c b/arch/arm/mach-msm/pil-dsps.c
index 81f5330..e33b24a 100644
--- a/arch/arm/mach-msm/pil-dsps.c
+++ b/arch/arm/mach-msm/pil-dsps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c
index 73248db..c7f8fb0 100644
--- a/arch/arm/mach-msm/pil-gss.c
+++ b/arch/arm/mach-msm/pil-gss.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-mba.c b/arch/arm/mach-msm/pil-mba.c
index 5e67d4f..b95d502 100644
--- a/arch/arm/mach-msm/pil-mba.c
+++ b/arch/arm/mach-msm/pil-mba.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index 8344496..3326d47 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-pronto.c b/arch/arm/mach-msm/pil-pronto.c
index 01cdb0b..0d8deab 100644
--- a/arch/arm/mach-msm/pil-pronto.c
+++ b/arch/arm/mach-msm/pil-pronto.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-q6v3.c b/arch/arm/mach-msm/pil-q6v3.c
index 28b9dee..a25bc89 100644
--- a/arch/arm/mach-msm/pil-q6v3.c
+++ b/arch/arm/mach-msm/pil-q6v3.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
index 32cce1d..cb28dfa 100644
--- a/arch/arm/mach-msm/pil-q6v4.c
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-q6v4.h b/arch/arm/mach-msm/pil-q6v4.h
index b0b97d0..a791996 100644
--- a/arch/arm/mach-msm/pil-q6v4.h
+++ b/arch/arm/mach-msm/pil-q6v4.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-q6v5-lpass.c b/arch/arm/mach-msm/pil-q6v5-lpass.c
index ed072ea..d5a552b 100644
--- a/arch/arm/mach-msm/pil-q6v5-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v5-lpass.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index 1720729..1027918 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-q6v5.c b/arch/arm/mach-msm/pil-q6v5.c
index 772031b..2089101 100644
--- a/arch/arm/mach-msm/pil-q6v5.c
+++ b/arch/arm/mach-msm/pil-q6v5.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-q6v5.h b/arch/arm/mach-msm/pil-q6v5.h
index 03f93fa..75e8bb5 100644
--- a/arch/arm/mach-msm/pil-q6v5.h
+++ b/arch/arm/mach-msm/pil-q6v5.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 3040a31..c7ae22b 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-tzapps.c b/arch/arm/mach-msm/pil-tzapps.c
index 2345453..b526e5a 100644
--- a/arch/arm/mach-msm/pil-tzapps.c
+++ b/arch/arm/mach-msm/pil-tzapps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-venus.c b/arch/arm/mach-msm/pil-venus.c
index 49c39ec..1249522 100644
--- a/arch/arm/mach-msm/pil-venus.c
+++ b/arch/arm/mach-msm/pil-venus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pil-vidc.c b/arch/arm/mach-msm/pil-vidc.c
index e4c6a2d..93bf04f 100644
--- a/arch/arm/mach-msm/pil-vidc.c
+++ b/arch/arm/mach-msm/pil-vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ping_apps_server.c b/arch/arm/mach-msm/ping_apps_server.c
index 0a85600..4499f76 100644
--- a/arch/arm/mach-msm/ping_apps_server.c
+++ b/arch/arm/mach-msm/ping_apps_server.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ping_mdm_rpc_client.c b/arch/arm/mach-msm/ping_mdm_rpc_client.c
index 57ac85d..4044836 100644
--- a/arch/arm/mach-msm/ping_mdm_rpc_client.c
+++ b/arch/arm/mach-msm/ping_mdm_rpc_client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
index 700f966..8e7e7d2 100644
--- a/arch/arm/mach-msm/platsmp-8625.c
+++ b/arch/arm/mach-msm/platsmp-8625.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index aca1fb1..d3c7797 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 2002 ARM Ltd.
  *  All Rights Reserved
- *  Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2010-2012, The Linux Foundation. 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
@@ -42,6 +42,19 @@
  */
 volatile int pen_release = -1;
 
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not.  This is necessary for the hotplug code to work reliably.
+ */
+static void __cpuinit write_pen_release(int val)
+{
+	pen_release = val;
+	smp_wmb();
+	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
 static DEFINE_SPINLOCK(boot_lock);
 
 void __cpuinit platform_secondary_init(unsigned int cpu)
@@ -56,6 +69,12 @@
 	gic_secondary_init(0);
 
 	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	write_pen_release(-1);
+
+	/*
 	 * Synchronise with the boot thread.
 	 */
 	spin_lock(&boot_lock);
@@ -220,9 +239,7 @@
 	 * Note that "pen_release" is the hardware CPU ID, whereas
 	 * "cpu" is Linux's internal ID.
 	 */
-	pen_release = cpu_logical_map(cpu);
-	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
-	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+	write_pen_release(cpu_logical_map(cpu));
 
 	/*
 	 * Send the secondary CPU a soft interrupt, thereby causing
@@ -237,8 +254,6 @@
 		if (pen_release == -1)
 			break;
 
-		dmac_inv_range((char *)&pen_release,
-			       (char *)&pen_release + sizeof(pen_release));
 		udelay(10);
 	}
 
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 6c2db6e..c931ac7 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -790,11 +790,17 @@
 
 		switch (mode) {
 		case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
+			if (num_online_cpus() > 1) {
+				allow = false;
+				break;
+			}
+			/* fall through */
 		case MSM_PM_SLEEP_MODE_RETENTION:
 			if (!allow)
 				break;
 
-			if (num_online_cpus() > 1) {
+			if (msm_pm_retention_tz_call &&
+				num_online_cpus() > 1) {
 				allow = false;
 				break;
 			}
@@ -1108,18 +1114,11 @@
 	},
 };
 
-static int __init msm_pm_init(void)
+static int __init msm_pm_setup_saved_state(void)
 {
 	pgd_t *pc_pgd;
 	pmd_t *pmd;
 	unsigned long pmdval;
-	enum msm_pm_time_stats_id enable_stats[] = {
-		MSM_PM_STAT_IDLE_WFI,
-		MSM_PM_STAT_RETENTION,
-		MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE,
-		MSM_PM_STAT_IDLE_POWER_COLLAPSE,
-		MSM_PM_STAT_SUSPEND,
-	};
 	unsigned long exit_phys;
 
 	/* Page table for cores to come back up safely. */
@@ -1160,6 +1159,20 @@
 	clean_caches((unsigned long)&msm_pm_pc_pgd, sizeof(msm_pm_pc_pgd),
 		     virt_to_phys(&msm_pm_pc_pgd));
 
+	return 0;
+}
+core_initcall(msm_pm_setup_saved_state);
+
+static int __init msm_pm_init(void)
+{
+	enum msm_pm_time_stats_id enable_stats[] = {
+		MSM_PM_STAT_IDLE_WFI,
+		MSM_PM_STAT_RETENTION,
+		MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE,
+		MSM_PM_STAT_IDLE_POWER_COLLAPSE,
+		MSM_PM_STAT_SUSPEND,
+	};
+
 	msm_pm_mode_sysfs_add();
 	msm_pm_add_stats(enable_stats, ARRAY_SIZE(enable_stats));
 
diff --git a/arch/arm/mach-msm/pm-boot.c b/arch/arm/mach-msm/pm-boot.c
index ed15a0c..38023e3 100644
--- a/arch/arm/mach-msm/pm-boot.c
+++ b/arch/arm/mach-msm/pm-boot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pm-boot.h b/arch/arm/mach-msm/pm-boot.h
index 30b67c21..d0a833b 100644
--- a/arch/arm/mach-msm/pm-boot.h
+++ b/arch/arm/mach-msm/pm-boot.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pm-data.c b/arch/arm/mach-msm/pm-data.c
index 6f4743f..7fe7795 100644
--- a/arch/arm/mach-msm/pm-data.c
+++ b/arch/arm/mach-msm/pm-data.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -46,7 +46,7 @@
 		.idle_supported = 0,
 		.suspend_supported = 1,
 		.idle_enabled = 0,
-		.suspend_enabled = 0,
+		.suspend_enabled = 1,
 	},
 
 	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
@@ -74,7 +74,7 @@
 		.idle_supported = 0,
 		.suspend_supported = 1,
 		.idle_enabled = 0,
-		.suspend_enabled = 0,
+		.suspend_enabled = 1,
 	},
 
 	[MSM_PM_MODE(2, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
@@ -102,7 +102,7 @@
 		.idle_supported = 0,
 		.suspend_supported = 1,
 		.idle_enabled = 0,
-		.suspend_enabled = 0,
+		.suspend_enabled = 1,
 	},
 
 	[MSM_PM_MODE(3, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
diff --git a/arch/arm/mach-msm/pm-stats.c b/arch/arm/mach-msm/pm-stats.c
index 675febb..1bd9b46 100644
--- a/arch/arm/mach-msm/pm-stats.c
+++ b/arch/arm/mach-msm/pm-stats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index 51256ca..fa99918 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/pm.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 10c5445..ac79e2a 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -3,7 +3,7 @@
  * MSM Power Management Routines
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/pmic.c b/arch/arm/mach-msm/pmic.c
index 1e92710..dc0f7bf 100644
--- a/arch/arm/mach-msm/pmic.c
+++ b/arch/arm/mach-msm/pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2011 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pmic.h b/arch/arm/mach-msm/pmic.h
index e6ef960..b73e654 100644
--- a/arch/arm/mach-msm/pmic.h
+++ b/arch/arm/mach-msm/pmic.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pmic_debugfs.c b/arch/arm/mach-msm/pmic_debugfs.c
index c52cf9b..b91eef5 100644
--- a/arch/arm/mach-msm/pmic_debugfs.c
+++ b/arch/arm/mach-msm/pmic_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/pmu.c b/arch/arm/mach-msm/pmu.c
index 5e339da..8d65eea 100644
--- a/arch/arm/mach-msm/pmu.c
+++ b/arch/arm/mach-msm/pmu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
@@ -13,6 +13,49 @@
 #include <linux/platform_device.h>
 #include <asm/pmu.h>
 #include <mach/irqs.h>
+#include <mach/socinfo.h>
+
+#if defined(CONFIG_ARCH_MSM_KRAITMP) || defined(CONFIG_ARCH_MSM_SCORPIONMP)
+static DEFINE_PER_CPU(u32, pmu_irq_cookie);
+
+static int
+multicore_request_irq(int irq, irq_handler_t *handle_irq)
+{
+	int err = 0;
+	int cpu;
+
+	err = request_percpu_irq(irq, *handle_irq, "l1-armpmu",
+			&pmu_irq_cookie);
+
+	if (!err) {
+		for_each_cpu(cpu, cpu_online_mask) {
+			smp_call_function_single(cpu,
+					enable_irq_callback, &irq, 1);
+		}
+	}
+
+	return err;
+}
+
+static void
+multicore_free_irq(int irq)
+{
+	int cpu;
+
+	if (irq >= 0) {
+		for_each_cpu(cpu, cpu_online_mask) {
+			smp_call_function_single(cpu,
+					disable_irq_callback, &irq, 1);
+		}
+		free_percpu_irq(irq, &pmu_irq_cookie);
+	}
+}
+
+static struct arm_pmu_platdata multicore_data = {
+	.request_pmu_irq = multicore_request_irq,
+	.free_pmu_irq = multicore_free_irq,
+};
+#endif
 
 static struct resource cpu_pmu_resource[] = {
 	{
@@ -47,6 +90,7 @@
 	.num_resources	= ARRAY_SIZE(cpu_pmu_resource),
 };
 
+
 static struct platform_device *pmu_devices[] = {
 	&cpu_pmu_device,
 #ifdef CONFIG_CPU_HAS_L2_PMU
@@ -56,6 +100,16 @@
 
 static int __init msm_pmu_init(void)
 {
+	/*
+	 * For the targets we know are multicore's set the request/free IRQ
+	 * handlers to call the percpu API.
+	 * Defaults to unicore API {request,free}_irq().
+	 * See arch/arm/kernel/perf_event.c
+	 */
+#if defined(CONFIG_ARCH_MSM_KRAITMP) || defined(CONFIG_ARCH_MSM_SCORPIONMP)
+	cpu_pmu_device.dev.platform_data = &multicore_data;
+#endif
+
 	return platform_add_devices(pmu_devices, ARRAY_SIZE(pmu_devices));
 }
 
diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c
index 421e7de..c7705e7 100644
--- a/arch/arm/mach-msm/proc_comm.c
+++ b/arch/arm/mach-msm/proc_comm.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/proc_comm.c
  *
  * Copyright (C) 2007-2008 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/proc_comm_test.c b/arch/arm/mach-msm/proc_comm_test.c
index e4eca11..7593ff2 100644
--- a/arch/arm/mach-msm/proc_comm_test.c
+++ b/arch/arm/mach-msm/proc_comm_test.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/proccomm-regulator.c b/arch/arm/mach-msm/proccomm-regulator.c
index 21a4f84..74d15dd 100644
--- a/arch/arm/mach-msm/proccomm-regulator.c
+++ b/arch/arm/mach-msm/proccomm-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/proccomm-regulator.h b/arch/arm/mach-msm/proccomm-regulator.h
index 46d3b13..8a08e3e 100644
--- a/arch/arm/mach-msm/proccomm-regulator.h
+++ b/arch/arm/mach-msm/proccomm-regulator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5/adsp.c b/arch/arm/mach-msm/qdsp5/adsp.c
index 6189da8..85dc6ba 100644
--- a/arch/arm/mach-msm/qdsp5/adsp.c
+++ b/arch/arm/mach-msm/qdsp5/adsp.c
@@ -3,7 +3,7 @@
  * Register/Interrupt access for userspace aDSP library.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5/adsp.h b/arch/arm/mach-msm/qdsp5/adsp.h
index 50f5b83..9b4b682 100644
--- a/arch/arm/mach-msm/qdsp5/adsp.h
+++ b/arch/arm/mach-msm/qdsp5/adsp.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp5/adsp.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5/adsp_6210.c b/arch/arm/mach-msm/qdsp5/adsp_6210.c
index 322ba68..bf69ce2 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_6210.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_6210.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/qdsp5/adsp_6210.h
  *
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_6220.c b/arch/arm/mach-msm/qdsp5/adsp_6220.c
index f947cd7..0073790 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_6220.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_6220.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/qdsp5/adsp_6220.h
  *
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_6225.c b/arch/arm/mach-msm/qdsp5/adsp_6225.c
index 6f8d3f4..6a402b7 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_6225.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_6225.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/qdsp5/adsp_6225.h
  *
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_debug.c b/arch/arm/mach-msm/qdsp5/adsp_debug.c
index 03deab9..ccddd43 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_debug.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_driver.c b/arch/arm/mach-msm/qdsp5/adsp_driver.c
index 6419bd0..d83a140 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_driver.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_driver.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp5/adsp_driver.c
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2012 The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5/adsp_info.c b/arch/arm/mach-msm/qdsp5/adsp_info.c
index dea52bb..69a2d18 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_info.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_info.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/adsp_info.c
  *
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c b/arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c
index 8fb2e06..768ac31 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c
@@ -3,7 +3,7 @@
  * Verification code for aDSP JPEG events.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c
index 87d5dc3..a5dd4ad 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c
@@ -3,7 +3,7 @@
  * Verification code for aDSP JPEG packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c
index 06b70de..6424975 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c
@@ -3,7 +3,7 @@
  * Verificion code for aDSP LPM packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_rm.c b/arch/arm/mach-msm/qdsp5/adsp_rm.c
index f67946c..95489f8 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_rm.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_rm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c b/arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c
index 68ae380..c89a37d 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c
@@ -3,7 +3,7 @@
  * Verification code for aDSP VFE packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
index dcd3d96..dba012e 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
@@ -3,7 +3,7 @@
  * Verification code for aDSP VFE packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
index af259b5..4d03dca 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
@@ -3,7 +3,7 @@
  * Verificion code for aDSP VDEC packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/adsp_videoenc_verify_cmd.c b/arch/arm/mach-msm/qdsp5/adsp_videoenc_verify_cmd.c
index 290a14c..1b16628 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_videoenc_verify_cmd.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_videoenc_verify_cmd.c
@@ -3,7 +3,7 @@
  * Verificion code for aDSP VENC packets from userspace.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac.c b/arch/arm/mach-msm/qdsp5/audio_aac.c
index 824afbd..c89d88b 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac_in.c b/arch/arm/mach-msm/qdsp5/audio_aac_in.c
index 6f15605..1e6ef60 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac_in.c
@@ -2,7 +2,7 @@
  *
  * aac audio input device
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_aac_in.c,
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_ac3.c b/arch/arm/mach-msm/qdsp5/audio_ac3.c
index 87e269c..d936812 100644
--- a/arch/arm/mach-msm/qdsp5/audio_ac3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_ac3.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/audio_ac3.c
  *
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This code also borrows from audio_aac.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb.c b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
index a54cfec..622890b 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
@@ -2,7 +2,7 @@
  *
  * amrnb audio decoder device
  *
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c b/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
index 79c6a12..43df851 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
@@ -2,7 +2,7 @@
  *
  * amrnb encoder device
  *
- * Copyright (c) 2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5/audio_in.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrwb.c b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
index f58539b..71100a6 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
@@ -6,7 +6,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc.c b/arch/arm/mach-msm/qdsp5/audio_evrc.c
index b50b1a8..d79da15 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/audio_evrc.c
  *
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This code also borrows from audio_aac.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
index 353413c..fc90fae 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
@@ -2,7 +2,7 @@
  *
  * evrc audio input device
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c,
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_fm.c b/arch/arm/mach-msm/qdsp5/audio_fm.c
index 2ab7cad..957a407 100644
--- a/arch/arm/mach-msm/qdsp5/audio_fm.c
+++ b/arch/arm/mach-msm/qdsp5/audio_fm.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audio_in.c b/arch/arm/mach-msm/qdsp5/audio_in.c
index 6fc5d6b..6fc2ac0 100644
--- a/arch/arm/mach-msm/qdsp5/audio_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_in.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audio_lpa.c b/arch/arm/mach-msm/qdsp5/audio_lpa.c
index 05a08fb..d2244d5 100644
--- a/arch/arm/mach-msm/qdsp5/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5/audio_lpa.c
@@ -1,7 +1,7 @@
 
 /* audio_lpa.c - low power audio driver
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * Based on the PCM decoder driver in arch/arm/mach-msm/qdsp5/audio_pcm.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audio_mp3.c b/arch/arm/mach-msm/qdsp5/audio_mp3.c
index 2dbbd84..62524ff 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mp3.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audio_mvs.c b/arch/arm/mach-msm/qdsp5/audio_mvs.c
index 158dd46..982c719 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mvs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5/audio_out.c b/arch/arm/mach-msm/qdsp5/audio_out.c
index 0c8034c..9e9d89b 100644
--- a/arch/arm/mach-msm/qdsp5/audio_out.c
+++ b/arch/arm/mach-msm/qdsp5/audio_out.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm.c b/arch/arm/mach-msm/qdsp5/audio_pcm.c
index 1f1d992..554af09 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm.c
@@ -1,7 +1,7 @@
 
 /* audio_pcm.c - pcm audio decoder driver
  *
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 decoder driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
index 669407f..201ee37 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
@@ -2,7 +2,7 @@
  *
  * pcm audio input device
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c,
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp.c b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
index 78b0175..0871ffe 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
@@ -2,7 +2,7 @@
  *
  * qcelp 13k audio decoder device
  *
- * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This code is based in part on audio_mp3.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
index 454359d..0b1775e 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
@@ -2,7 +2,7 @@
  *
  * qcelp audio input device
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c,
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5/audio_voice_lb.c b/arch/arm/mach-msm/qdsp5/audio_voice_lb.c
index 08fa487..a73defd 100644
--- a/arch/arm/mach-msm/qdsp5/audio_voice_lb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_voice_lb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5/audio_voicememo.c b/arch/arm/mach-msm/qdsp5/audio_voicememo.c
index 34e5b81..ae63f0d 100644
--- a/arch/arm/mach-msm/qdsp5/audio_voicememo.c
+++ b/arch/arm/mach-msm/qdsp5/audio_voicememo.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audio_wma.c b/arch/arm/mach-msm/qdsp5/audio_wma.c
index 94d43bd..d999953 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wma.c
@@ -1,6 +1,6 @@
 /* audio_wma.c - wma audio decoder driver
  *
- * Copyright (c) 2009, 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audio_wmapro.c b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
index 5e0dc09..4480bc0 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/arch/arm/mach-msm/qdsp5/audmgr.c b/arch/arm/mach-msm/qdsp5/audmgr.c
index 231a28c..f7fb883 100644
--- a/arch/arm/mach-msm/qdsp5/audmgr.c
+++ b/arch/arm/mach-msm/qdsp5/audmgr.c
@@ -3,7 +3,7 @@
  * interface to "audmgr" service on the baseband cpu
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audmgr.h b/arch/arm/mach-msm/qdsp5/audmgr.h
index 3d8c560..472394b 100644
--- a/arch/arm/mach-msm/qdsp5/audmgr.h
+++ b/arch/arm/mach-msm/qdsp5/audmgr.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp5/audmgr.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audmgr_new.h b/arch/arm/mach-msm/qdsp5/audmgr_new.h
index 2453022..a5188dc 100644
--- a/arch/arm/mach-msm/qdsp5/audmgr_new.h
+++ b/arch/arm/mach-msm/qdsp5/audmgr_new.h
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/qdsp5/audmgr.h
  *
- * Copyright 2008 (c) Code Aurora Forum. All rights reserved.
+ * Copyright 2008 (c) The Linux Foundation. All rights reserved.
  * Copyright (C) 2008 Google, Inc.
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5/audpp.c b/arch/arm/mach-msm/qdsp5/audpp.c
index 1616ad0..b781286 100644
--- a/arch/arm/mach-msm/qdsp5/audpp.c
+++ b/arch/arm/mach-msm/qdsp5/audpp.c
@@ -4,7 +4,7 @@
  * common code to deal with the AUDPP dsp task (audio postproc)
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/audpreproc.c b/arch/arm/mach-msm/qdsp5/audpreproc.c
index 230429f..3dfa179 100644
--- a/arch/arm/mach-msm/qdsp5/audpreproc.c
+++ b/arch/arm/mach-msm/qdsp5/audpreproc.c
@@ -1,7 +1,7 @@
 /*
  * Common code to deal with the AUDPREPROC dsp task (audio preprocessing)
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * Based on the audpp layer in arch/arm/mach-msm/qdsp5/audpp.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/audrec.c b/arch/arm/mach-msm/qdsp5/audrec.c
index d5cb168..0f68e08 100644
--- a/arch/arm/mach-msm/qdsp5/audrec.c
+++ b/arch/arm/mach-msm/qdsp5/audrec.c
@@ -2,7 +2,7 @@
  *
  * common code to deal with the AUDREC dsp task (audio recording)
  *
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Based on the audpp layer in arch/arm/mach-msm/qdsp5/audpp.c
  *
diff --git a/arch/arm/mach-msm/qdsp5/dsp_debug.c b/arch/arm/mach-msm/qdsp5/dsp_debug.c
index 331ba00..6e73a60 100644
--- a/arch/arm/mach-msm/qdsp5/dsp_debug.c
+++ b/arch/arm/mach-msm/qdsp5/dsp_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/dsp_debug.h b/arch/arm/mach-msm/qdsp5/dsp_debug.h
index bd40682..15c14ca 100644
--- a/arch/arm/mach-msm/qdsp5/dsp_debug.h
+++ b/arch/arm/mach-msm/qdsp5/dsp_debug.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/snd.c b/arch/arm/mach-msm/qdsp5/snd.c
index f1db012..3f379dc 100644
--- a/arch/arm/mach-msm/qdsp5/snd.c
+++ b/arch/arm/mach-msm/qdsp5/snd.c
@@ -3,7 +3,7 @@
  * interface to "snd" service on the baseband cpu
  *
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5/snd_adie.c b/arch/arm/mach-msm/qdsp5/snd_adie.c
index ba7efc3..160ed93 100644
--- a/arch/arm/mach-msm/qdsp5/snd_adie.c
+++ b/arch/arm/mach-msm/qdsp5/snd_adie.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5/snd_pcm_client.c b/arch/arm/mach-msm/qdsp5/snd_pcm_client.c
index b58d3a2..5c59601 100644
--- a/arch/arm/mach-msm/qdsp5/snd_pcm_client.c
+++ b/arch/arm/mach-msm/qdsp5/snd_pcm_client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp.c b/arch/arm/mach-msm/qdsp5v2/adsp.c
index 8c1413c..371ef00 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp.c
+++ b/arch/arm/mach-msm/qdsp5v2/adsp.c
@@ -2,7 +2,7 @@
  * Register/Interrupt access for userspace aDSP library.
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009,2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009,2011-2012 The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp.h b/arch/arm/mach-msm/qdsp5v2/adsp.h
index 5aceff9..b5a574b 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp.h
+++ b/arch/arm/mach-msm/qdsp5v2/adsp.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp_driver.c b/arch/arm/mach-msm/qdsp5v2/adsp_driver.c
index 2a4e4ec..7249bb1 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp_driver.c
+++ b/arch/arm/mach-msm/qdsp5v2/adsp_driver.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp5v2/adsp_info.c b/arch/arm/mach-msm/qdsp5v2/adsp_info.c
index 4026367..03b810d 100644
--- a/arch/arm/mach-msm/qdsp5v2/adsp_info.c
+++ b/arch/arm/mach-msm/qdsp5v2/adsp_info.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/afe.c b/arch/arm/mach-msm/qdsp5v2/afe.c
index 20c9898..1e856e5 100644
--- a/arch/arm/mach-msm/qdsp5v2/afe.c
+++ b/arch/arm/mach-msm/qdsp5v2/afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c b/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c
index 733b7a1..076a03e 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  *
  * sbc/pcm audio input driver
  * Based on the pcm input driver in arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_aac.c b/arch/arm/mach-msm/qdsp5v2/audio_aac.c
index 05bca03..883da2b 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_aac.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c b/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
index 8aee946..a878e12 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_aac_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_acdb.c b/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
index 89957a4..5d7cfd7 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_acdb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
index 95f0547..7cc3e29 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
index 55c49b3..c8b4171 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
@@ -1,7 +1,7 @@
 /*
  * amrnb audio decoder device
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
index 790c510..8b731d1 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
index a653d5b..66d0a9e 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
@@ -1,6 +1,6 @@
 /* amrwb audio decoder device
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_dev_ctl.c b/arch/arm/mach-msm/qdsp5v2/audio_dev_ctl.c
index b6d6e5e..b1446e8 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_dev_ctl.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_dev_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
index 7306e98..2d9327e 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This code also borrows from audio_aac.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
index 1ee5029..1a2d420 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_fm.c b/arch/arm/mach-msm/qdsp5v2/audio_fm.c
index af65c80..cffa7e7 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_fm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_fm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_interct.c b/arch/arm/mach-msm/qdsp5v2/audio_interct.c
index 785ed8e..4e4c5d6 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_interct.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_interct.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2011 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_lpa.c b/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
index 60f43b9..8a72dea 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
index 53ae0a4..0390edf 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mvs.c b/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
index 1884b3c..f211fa0 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_out.c b/arch/arm/mach-msm/qdsp5v2/audio_out.c
index 147ac77..c62f2e1 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_out.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_out.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
index 4b308b0..ea8fc83 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c
index ce67ebb..b41995a 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
index c53922b..bb360be 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
@@ -1,7 +1,7 @@
 /*
  * qcelp 13k audio decoder device
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on audio_mp3.c, which is
  * Copyright (C) 2008 Google, Inc.
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
index e1af2ad..d42f717 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wma.c b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
index 80adebd..131df22 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
index ca072b3..84cfed6 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/audpp.c b/arch/arm/mach-msm/qdsp5v2/audpp.c
index 31ce643..7a40156 100644
--- a/arch/arm/mach-msm/qdsp5v2/audpp.c
+++ b/arch/arm/mach-msm/qdsp5v2/audpp.c
@@ -3,7 +3,7 @@
  * common code to deal with the AUDPP dsp task (audio postproc)
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp5v2/audpreproc.c b/arch/arm/mach-msm/qdsp5v2/audpreproc.c
index c9abdab..28eead0 100644
--- a/arch/arm/mach-msm/qdsp5v2/audpreproc.c
+++ b/arch/arm/mach-msm/qdsp5v2/audpreproc.c
@@ -1,7 +1,7 @@
 /*
  * Common code to deal with the AUDPREPROC dsp task (audio preprocessing)
  *
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
  *
  * Based on the audpp layer in arch/arm/mach-msm/qdsp5/audpp.c
  *
diff --git a/arch/arm/mach-msm/qdsp5v2/aux_pcm.c b/arch/arm/mach-msm/qdsp5v2/aux_pcm.c
index 4cc834d..06318bc 100644
--- a/arch/arm/mach-msm/qdsp5v2/aux_pcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/aux_pcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/lpa.c b/arch/arm/mach-msm/qdsp5v2/lpa.c
index 98297e3..5ffda8a 100644
--- a/arch/arm/mach-msm/qdsp5v2/lpa.c
+++ b/arch/arm/mach-msm/qdsp5v2/lpa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/mi2s.c b/arch/arm/mach-msm/qdsp5v2/mi2s.c
index e38f164..b649ec1 100644
--- a/arch/arm/mach-msm/qdsp5v2/mi2s.c
+++ b/arch/arm/mach-msm/qdsp5v2/mi2s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009,2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009,2011 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/mp3_funcs.c b/arch/arm/mach-msm/qdsp5v2/mp3_funcs.c
index 0b20be0..f857e5c 100644
--- a/arch/arm/mach-msm/qdsp5v2/mp3_funcs.c
+++ b/arch/arm/mach-msm/qdsp5v2/mp3_funcs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/pcm_funcs.c b/arch/arm/mach-msm/qdsp5v2/pcm_funcs.c
index d7935a7..866b71d 100644
--- a/arch/arm/mach-msm/qdsp5v2/pcm_funcs.c
+++ b/arch/arm/mach-msm/qdsp5v2/pcm_funcs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_data_marimba.c b/arch/arm/mach-msm/qdsp5v2/snddev_data_marimba.c
index b15d4c4..b11cdb0 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_data_marimba.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_data_marimba.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_data_timpani.c b/arch/arm/mach-msm/qdsp5v2/snddev_data_timpani.c
index c0a48c8..a4e4dad 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_data_timpani.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_data_timpani.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_ecodec.c b/arch/arm/mach-msm/qdsp5v2/snddev_ecodec.c
index 943489a..d8009aa 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_ecodec.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_ecodec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009,2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009,2011 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_icodec.c b/arch/arm/mach-msm/qdsp5v2/snddev_icodec.c
index c416c07..cbb0587 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_icodec.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_icodec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_mi2s.c b/arch/arm/mach-msm/qdsp5v2/snddev_mi2s.c
index b5f3b66..7f4ee26 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_mi2s.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_mi2s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/snddev_virtual.c b/arch/arm/mach-msm/qdsp5v2/snddev_virtual.c
index cd93345..aa1d557 100644
--- a/arch/arm/mach-msm/qdsp5v2/snddev_virtual.c
+++ b/arch/arm/mach-msm/qdsp5v2/snddev_virtual.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/timpani_profile_7x30.h b/arch/arm/mach-msm/qdsp5v2/timpani_profile_7x30.h
index d9003cd..e4cf131 100644
--- a/arch/arm/mach-msm/qdsp5v2/timpani_profile_7x30.h
+++ b/arch/arm/mach-msm/qdsp5v2/timpani_profile_7x30.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp5v2/voice.c b/arch/arm/mach-msm/qdsp5v2/voice.c
index 026acb3..1ac79d4 100644
--- a/arch/arm/mach-msm/qdsp5v2/voice.c
+++ b/arch/arm/mach-msm/qdsp5v2/voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/aac_in.c b/arch/arm/mach-msm/qdsp6/aac_in.c
index 9e1d5b6..6e3bf94 100644
--- a/arch/arm/mach-msm/qdsp6/aac_in.c
+++ b/arch/arm/mach-msm/qdsp6/aac_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/amrnb_in.c b/arch/arm/mach-msm/qdsp6/amrnb_in.c
index e7756e1..e20bf5b 100644
--- a/arch/arm/mach-msm/qdsp6/amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp6/amrnb_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/analog_audio.c b/arch/arm/mach-msm/qdsp6/analog_audio.c
index 688f57e..d3a6baa 100644
--- a/arch/arm/mach-msm/qdsp6/analog_audio.c
+++ b/arch/arm/mach-msm/qdsp6/analog_audio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/aac_in.c b/arch/arm/mach-msm/qdsp6/audiov2/aac_in.c
index fe6c049..ef566c9 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/aac_in.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/aac_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/amrnb_in.c b/arch/arm/mach-msm/qdsp6/audiov2/amrnb_in.c
index b877977..e552ada 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/amrnb_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/analog_audio.c b/arch/arm/mach-msm/qdsp6/audiov2/analog_audio.c
index 1df4f5d..5bf2cea 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/analog_audio.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/analog_audio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/audio_ctl.c b/arch/arm/mach-msm/qdsp6/audiov2/audio_ctl.c
index 286d85d..4ebfc02 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/audio_ctl.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/audio_ctl.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_acdb.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_acdb.h
index d88b7ad..b4949f9 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/dal_acdb.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/dal_acdb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_adie.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_adie.h
index e828e9c..aac484c 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/dal_adie.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/dal_adie.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_audio.h
index 52de785..2f9510b 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/dal_audio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio_format.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_audio_format.h
index 348aad1..218fa53 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/dal_audio_format.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/dal_audio_format.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/dal_voice.h b/arch/arm/mach-msm/qdsp6/audiov2/dal_voice.h
index 62c1122..6836de4 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/dal_voice.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/dal_voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/evrc_in.c b/arch/arm/mach-msm/qdsp6/audiov2/evrc_in.c
index 88f19b7..9c54455 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/evrc_in.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/evrc_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/mp3.c b/arch/arm/mach-msm/qdsp6/audiov2/mp3.c
index 0781eda..7d9cfa2 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/mp3.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/mp3.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c b/arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c
index 6ef2195..4de2199 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/pcm_in.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c b/arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c
index 6743c6c..effd119 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp6/audiov2/pcm_out.c
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c b/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c
index af411f1..5895867 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/q6audio.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp6/audiov2/q6audio.c
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h b/arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h
index aa8a699..3786cca 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h
+++ b/arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp6/audiov2/q6audio_devices.h
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/qcelp_in.c b/arch/arm/mach-msm/qdsp6/audiov2/qcelp_in.c
index a13084f..40ae37d 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/qcelp_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/routing.c b/arch/arm/mach-msm/qdsp6/audiov2/routing.c
index 1a2476b..1ba128c 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/routing.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/routing.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp6/audiov2/routing.c
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6/audiov2/voice.c b/arch/arm/mach-msm/qdsp6/audiov2/voice.c
index 906c534..ccb2bad 100644
--- a/arch/arm/mach-msm/qdsp6/audiov2/voice.c
+++ b/arch/arm/mach-msm/qdsp6/audiov2/voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c b/arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c
index 4195454..ff254a6 100644
--- a/arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c
+++ b/arch/arm/mach-msm/qdsp6/auxpcm_lb_in.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c b/arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c
index b680597..bba6b94 100644
--- a/arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c
+++ b/arch/arm/mach-msm/qdsp6/auxpcm_lb_out.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2009 Google, Inc.
  * Author: Brian Swetland <swetland@google.com>
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
  * may be copied, distributed, and modified under those terms.
diff --git a/arch/arm/mach-msm/qdsp6/dal_acdb.h b/arch/arm/mach-msm/qdsp6/dal_acdb.h
index dfb1fef..511879c 100644
--- a/arch/arm/mach-msm/qdsp6/dal_acdb.h
+++ b/arch/arm/mach-msm/qdsp6/dal_acdb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/dal_adie.h b/arch/arm/mach-msm/qdsp6/dal_adie.h
index 6abc60c..78db05f 100644
--- a/arch/arm/mach-msm/qdsp6/dal_adie.h
+++ b/arch/arm/mach-msm/qdsp6/dal_adie.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/dal_audio.h b/arch/arm/mach-msm/qdsp6/dal_audio.h
index 25d1e4f..6c353db 100644
--- a/arch/arm/mach-msm/qdsp6/dal_audio.h
+++ b/arch/arm/mach-msm/qdsp6/dal_audio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/dal_audio_format.h b/arch/arm/mach-msm/qdsp6/dal_audio_format.h
index 6382693..4223974 100644
--- a/arch/arm/mach-msm/qdsp6/dal_audio_format.h
+++ b/arch/arm/mach-msm/qdsp6/dal_audio_format.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/dtmf.c b/arch/arm/mach-msm/qdsp6/dtmf.c
index cf27488..30978df 100644
--- a/arch/arm/mach-msm/qdsp6/dtmf.c
+++ b/arch/arm/mach-msm/qdsp6/dtmf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/evrc_in.c b/arch/arm/mach-msm/qdsp6/evrc_in.c
index 9fc412b..e059efa 100644
--- a/arch/arm/mach-msm/qdsp6/evrc_in.c
+++ b/arch/arm/mach-msm/qdsp6/evrc_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6/msm_q6vdec.c b/arch/arm/mach-msm/qdsp6/msm_q6vdec.c
index f285536..24d2117 100644
--- a/arch/arm/mach-msm/qdsp6/msm_q6vdec.c
+++ b/arch/arm/mach-msm/qdsp6/msm_q6vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/msm_q6venc.c b/arch/arm/mach-msm/qdsp6/msm_q6venc.c
index 0917c70..4704ae7 100644
--- a/arch/arm/mach-msm/qdsp6/msm_q6venc.c
+++ b/arch/arm/mach-msm/qdsp6/msm_q6venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6/q6audio.c b/arch/arm/mach-msm/qdsp6/q6audio.c
index 2d015fc..f660bdc 100644
--- a/arch/arm/mach-msm/qdsp6/q6audio.c
+++ b/arch/arm/mach-msm/qdsp6/q6audio.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp6/qcelp_in.c b/arch/arm/mach-msm/qdsp6/qcelp_in.c
index ca0ab1a..4289612 100644
--- a/arch/arm/mach-msm/qdsp6/qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp6/qcelp_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * Author: Brian Swetland <swetland@google.com>
  *
diff --git a/arch/arm/mach-msm/qdsp6v2/aac_in.c b/arch/arm/mach-msm/qdsp6v2/aac_in.c
index 6e79a75..5e959b5 100644
--- a/arch/arm/mach-msm/qdsp6v2/aac_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/aac_in.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/adsp-loader.c b/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
index 9924b52..e6f9512 100644
--- a/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
+++ b/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/amrnb_in.c b/arch/arm/mach-msm/qdsp6v2/amrnb_in.c
index 63a0774..91c588c 100644
--- a/arch/arm/mach-msm/qdsp6v2/amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/amrnb_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/amrwb_in.c b/arch/arm/mach-msm/qdsp6v2/amrwb_in.c
index d0462e0..ea3fe5b 100644
--- a/arch/arm/mach-msm/qdsp6v2/amrwb_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/amrwb_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/apr.c b/arch/arm/mach-msm/qdsp6v2/apr.c
index 8ac1fea..a25267f 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/apr_tal.c b/arch/arm/mach-msm/qdsp6v2/apr_tal.c
index 03f0513..98ec582 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr_tal.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr_tal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/apr_v1.c b/arch/arm/mach-msm/qdsp6v2/apr_v1.c
index 9535968..341df863 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr_v1.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr_v1.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/apr_v2.c b/arch/arm/mach-msm/qdsp6v2/apr_v2.c
index 1ef189f..b2e5392 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr_v2.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr_v2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
index 485234f..2bdd25d 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_aac.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -129,10 +129,9 @@
 		} else {
 			uint16_t sce_left = 1, sce_right = 2;
 			aac_config = audio->codec_cfg;
-			if ((aac_config->dual_mono_mode <
-				AUDIO_AAC_DUAL_MONO_PL_PR) ||
-				(aac_config->dual_mono_mode >
-				AUDIO_AAC_DUAL_MONO_PL_SR)) {
+			/* PL_PR is 0 only need to check PL_SR */
+			if (aac_config->dual_mono_mode >
+			    AUDIO_AAC_DUAL_MONO_PL_SR) {
 				pr_err("%s:AUDIO_SET_AAC_CONFIG: Invalid"
 					"dual_mono mode =%d\n", __func__,
 					aac_config->dual_mono_mode);
@@ -252,6 +251,10 @@
 		goto fail;
 	}
 	rc = audio_aio_open(audio, file);
+	if (rc < 0) {
+		pr_err("audio_aio_open rc=%d\n", rc);
+		goto fail;
+	}
 
 #ifdef CONFIG_DEBUG_FS
 	snprintf(name, sizeof name, "msm_aac_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index 7272f97..8efd808 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c b/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c
index f4316d0..fc023c1 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_amrnb.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -120,6 +120,10 @@
 		goto fail;
 	}
 	rc = audio_aio_open(audio, file);
+	if (rc < 0) {
+		pr_err("audio_aio_open rc=%d\n", rc);
+		goto fail;
+	}
 
 #ifdef CONFIG_DEBUG_FS
 	snprintf(name, sizeof name, "msm_amrnb_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c b/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c
index 28c1732..256da4d 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_amrwb.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -122,6 +122,10 @@
 		goto fail;
 	}
 	rc = audio_aio_open(audio, file);
+	if (rc < 0) {
+		pr_err("audio_aio_open rc=%d\n", rc);
+		goto fail;
+	}
 
 #ifdef CONFIG_DEBUG_FS
 	snprintf(name, sizeof name, "msm_amrwb_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_amrwbplus.c b/arch/arm/mach-msm/qdsp6v2/audio_amrwbplus.c
index 13f5e78..902e06d 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_amrwbplus.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_amrwbplus.c
@@ -199,6 +199,10 @@
 		goto fail;
 	}
 	rc = audio_aio_open(audio, file);
+	if (rc < 0) {
+		pr_err("audio_aio_open rc=%d\n", rc);
+		goto fail;
+	}
 
 	config_debug_fs(audio);
 	pr_debug("%s: AMRWBPLUS dec success mode[%d]session[%d]\n", __func__,
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c b/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
index aaae776..8aacb56 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_dev_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_evrc.c b/arch/arm/mach-msm/qdsp6v2/audio_evrc.c
index ec5162d..3498e69 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_evrc.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -128,6 +128,10 @@
 		goto fail;
 	}
 	rc = audio_aio_open(audio, file);
+	if (rc < 0) {
+		pr_err("audio_aio_open rc=%d\n", rc);
+		goto fail;
+	}
 
 #ifdef CONFIG_DEBUG_FS
 	snprintf(name, sizeof name, "msm_evrc_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
index 0640752..f6dd9fab 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -744,8 +744,8 @@
 
 		pr_debug("%s: AUDIO_GET_STATS cmd\n", __func__);
 		memset(&stats, 0, sizeof(stats));
-		timestamp = q6asm_get_session_time(audio->ac);
-		if (timestamp < 0) {
+		rc = q6asm_get_session_time(audio->ac, &timestamp);
+		if (rc < 0) {
 			pr_err("%s: Get Session Time return value =%lld\n",
 				__func__, timestamp);
 			return -EAGAIN;
@@ -1126,7 +1126,6 @@
 	if (audio->out_enabled)
 		audlpa_async_flush(audio);
 	audio->wflush = 0;
-	audlpa_unmap_ion_region(audio);
 	audio_disable(audio);
 	audlpa_unmap_ion_region(audio);
 	msm_clear_session_id(audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
index 93588b3..c305967 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_mp3.c b/arch/arm/mach-msm/qdsp6v2/audio_mp3.c
index 93a8739..a83c2d0 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_mp3.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -123,6 +123,10 @@
 		goto fail;
 	}
 	rc = audio_aio_open(audio, file);
+	if (rc < 0) {
+		pr_err("audio_aio_open rc=%d\n", rc);
+		goto fail;
+	}
 
 #ifdef CONFIG_DEBUG_FS
 	snprintf(name, sizeof name, "msm_mp3_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
index fbd94c5..9c8525f 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_multi_aac.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -142,10 +142,8 @@
 		} else {
 			uint16_t sce_left = 1, sce_right = 2;
 			aac_config = audio->codec_cfg;
-			if ((aac_config->dual_mono_mode <
-				AUDIO_AAC_DUAL_MONO_PL_PR) ||
-				(aac_config->dual_mono_mode >
-				AUDIO_AAC_DUAL_MONO_PL_SR)) {
+			if (aac_config->dual_mono_mode >
+			    AUDIO_AAC_DUAL_MONO_PL_SR) {
 				pr_err("%s:AUDIO_SET_AAC_CONFIG: Invalid dual_mono mode =%d\n",
 					 __func__, aac_config->dual_mono_mode);
 			} else {
@@ -182,6 +180,25 @@
 		}
 		break;
 	}
+	case AUDIO_SET_AAC_MIX_CONFIG:	{
+		pr_debug("%s, AUDIO_SET_AAC_MIX_CONFIG", __func__);
+		if (copy_from_user(audio->codec_cfg, (void *)arg,
+			sizeof(unsigned long))) {
+			rc = -EFAULT;
+			break;
+		} else {
+			unsigned long *mix_coeff =
+				 (unsigned long *)audio->codec_cfg;
+			pr_debug("%s, value of coeff = %lu",
+				 __func__, *mix_coeff);
+			rc = q6asm_cfg_aac_sel_mix_coef(audio->ac, *mix_coeff);
+			if (rc < 0)
+				pr_err("%s asm aac_sel_mix_coef failed rc=%d\n",
+								__func__, rc);
+			break;
+		}
+		break;
+	}
 	default:
 		pr_debug("Calling utils ioctl\n");
 		rc = audio->codec_ioctl(file, cmd, arg);
@@ -260,6 +277,10 @@
 		goto fail;
 	}
 	rc = audio_aio_open(audio, file);
+	if (rc < 0) {
+		pr_err("audio_aio_open rc=%d\n", rc);
+		goto fail;
+	}
 
 #ifdef CONFIG_DEBUG_FS
 	snprintf(name, sizeof name, "msm_multi_aac_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
index d748304..f64e5ea 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c b/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c
index 37f6e6b..4993226 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_qcelp.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -133,6 +133,10 @@
 		goto fail;
 	}
 	rc = audio_aio_open(audio, file);
+	if (rc < 0) {
+		pr_err("audio_aio_open rc=%d\n", rc);
+		goto fail;
+	}
 
 #ifdef CONFIG_DEBUG_FS
 	snprintf(name, sizeof name, "msm_qcelp_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.c b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
index 6a23e37..1f8fe5b 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.h b/arch/arm/mach-msm/qdsp6v2/audio_utils.h
index df963f9..b213c3f 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index e6f2041..af7a1fd 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1,6 +1,6 @@
 /* Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -468,7 +468,6 @@
 	audio->wflush = 0;
 	audio->drv_ops.out_flush(audio);
 	audio->drv_ops.in_flush(audio);
-	audio_aio_unmap_ion_region(audio);
 	audio_aio_disable(audio);
 	audio_aio_unmap_ion_region(audio);
 	audio_aio_reset_ion_region(audio);
@@ -803,6 +802,11 @@
 	struct audio_client *ac;
 	struct audio_aio_write_param param;
 
+        if (!audio || !buf_node) {
+                pr_err("%s: NULL pointer audio=[0x%p], buf_node=[0x%p]\n",
+                        __func__, audio, buf_node);
+                return;
+        }
 	pr_debug("%s[%p]: Send write buff %p phy %lx len %d meta_enable = %d\n",
 		__func__, audio, buf_node, buf_node->paddr,
 		buf_node->buf.data_len,
@@ -829,8 +833,7 @@
 	else
 		param.flags = 0xFF00;
 
-	if ((buf_node != NULL) &&
-		(buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOF_SET))
+	if (buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOF_SET)
 		param.flags |= AUDIO_DEC_EOF_SET;
 
 	param.uid = param.paddr;
@@ -993,7 +996,7 @@
 	return 0;
 }
 
-static void audio_aio_ioport_reset(struct q6audio_aio *audio)
+void audio_aio_ioport_reset(struct q6audio_aio *audio)
 {
 	if (audio->drv_status & ADRV_STATUS_AIO_INTF) {
 		/* If fsync is in progress, make sure
@@ -1078,9 +1081,6 @@
 	pr_debug("Ion client create in audio_aio_open %p", audio->client);
 	return 0;
 fail:
-	q6asm_audio_client_free(audio->ac);
-	kfree(audio->codec_cfg);
-	kfree(audio);
 	return rc;
 }
 
@@ -1154,15 +1154,15 @@
 				audio, audio->ac->session);
 		mutex_lock(&audio->lock);
 		audio->stopped = 1;
-		audio_aio_flush(audio);
-		audio->enabled = 0;
-		audio->drv_status &= ~ADRV_STATUS_PAUSE;
+		rc = audio_aio_flush(audio);
 		if (rc < 0) {
 			pr_err("%s[%p]:Audio Stop procedure failed rc=%d\n",
 				__func__, audio, rc);
 			mutex_unlock(&audio->lock);
 			break;
 		}
+		audio->enabled = 0;
+		audio->drv_status &= ~ADRV_STATUS_PAUSE;
 		mutex_unlock(&audio->lock);
 		break;
 	}
@@ -1201,8 +1201,6 @@
 		audio->wflush = 1;
 		/* Flush DSP */
 		rc = audio_aio_flush(audio);
-		/* Flush input / Output buffer in software*/
-		audio_aio_ioport_reset(audio);
 		if (rc < 0) {
 			pr_err("%s[%p]:AUDIO_FLUSH interrupted\n",
 				__func__, audio);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
index dedf991..7190740 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
@@ -1,6 +1,6 @@
 /* Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -211,6 +211,7 @@
 int audio_aio_fsync(struct file *file, loff_t start, loff_t end, int datasync);
 void audio_aio_async_out_flush(struct q6audio_aio *audio);
 void audio_aio_async_in_flush(struct q6audio_aio *audio);
+void audio_aio_ioport_reset(struct q6audio_aio *audio);
 #ifdef CONFIG_DEBUG_FS
 ssize_t audio_aio_debug_open(struct inode *inode, struct file *file);
 ssize_t audio_aio_debug_read(struct file *file, char __user *buf,
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_wma.c b/arch/arm/mach-msm/qdsp6v2/audio_wma.c
index 021d58b..5e3de86 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_wma.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -167,6 +167,10 @@
 		goto fail;
 	}
 	rc = audio_aio_open(audio, file);
+	if (rc < 0) {
+		pr_err("audio_aio_open rc=%d\n", rc);
+		goto fail;
+	}
 
 #ifdef CONFIG_DEBUG_FS
 	snprintf(name, sizeof name, "msm_wma_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c b/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
index 4fcdcc1..ce49cac 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -227,6 +227,10 @@
 		goto fail;
 	}
 	rc = audio_aio_open(audio, file);
+	if (rc < 0) {
+		pr_err("audio_aio_open rc=%d\n", rc);
+		goto fail;
+	}
 
 #ifdef CONFIG_DEBUG_FS
 	snprintf(name, sizeof name, "msm_wmapro_%04x", audio->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
index 0181cb5..0f35d1d 100644
--- a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
+++ b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/evrc_in.c b/arch/arm/mach-msm/qdsp6v2/evrc_in.c
index b95d659..0ee3421 100644
--- a/arch/arm/mach-msm/qdsp6v2/evrc_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/evrc_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/fm.c b/arch/arm/mach-msm/qdsp6v2/fm.c
index 9cf2723..3d72b97 100644
--- a/arch/arm/mach-msm/qdsp6v2/fm.c
+++ b/arch/arm/mach-msm/qdsp6v2/fm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
diff --git a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
index c19fd85..71ab566 100644
--- a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
+++ b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_in.c b/arch/arm/mach-msm/qdsp6v2/pcm_in.c
index 620c1ee..0db4894 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_in.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) 2009 HTC Corporation
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_out.c b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
index 733d5e3..4097b72 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_out.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_common.h b/arch/arm/mach-msm/qdsp6v2/q6audio_common.h
index e4291e7..137e70b 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_common.h
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v1.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v1.c
index f49d6e0..c36d5a9 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v1.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v1.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
index 078eea8..c0d61da 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013 The Linux Foundation. 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 and
@@ -39,6 +39,9 @@
 	case ASM_DATA_EVENT_ENC_SR_CM_NOTIFY:
 		audio_aio_cb(opcode, token, payload, audio);
 		break;
+	case APR_BASIC_RSP_RESULT:
+		audio_aio_cb(opcode, token, payload, audio);
+		break;
 	default:
 		pr_debug("%s:Unhandled event = 0x%8x\n", __func__, opcode);
 		break;
@@ -106,6 +109,26 @@
 		e_payload.stream_info.sample_rate = audio->pcm_cfg.sample_rate;
 		audio_aio_post_event(audio, AUDIO_EVENT_STREAM_INFO, e_payload);
 		break;
+	case APR_BASIC_RSP_RESULT:
+		switch (payload[0]) {
+		case ASM_STREAM_CMD_FLUSH:
+			if (payload[1] == ADSP_EOK) {
+				pr_debug("%s: FLUSH CMD success\n", __func__);
+				audio_aio_ioport_reset(audio);
+				audio->wflush = 0;
+				audio->rflush = 0;
+			} else {
+				pr_err("%s: FLUSH CMD failed with status:%d\n",
+					__func__, payload[1]);
+				audio_aio_ioport_reset(audio);
+				audio->wflush = 0;
+				audio->rflush = 0;
+			}
+			break;
+		default:
+			pr_debug("%s: cmd%x cmd_status:%d\n",
+				__func__, payload[0], payload[1]);
+		}
 	default:
 		break;
 	}
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c
index 0db1ef4..d2268c3 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c
index ad4fc6f..0e30403 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/q6core.c b/arch/arm/mach-msm/qdsp6v2/q6core.c
index d7de50e..8014254 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6core.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -249,8 +249,6 @@
 	int len;
 	static int t_len;
 
-	if (count < 0)
-		return 0;
 	len = count > 63 ? 63 : count;
 	if (copy_from_user(l_buf + 20 , buf, len)) {
 		pr_info("Unable to copy data from user space\n");
diff --git a/arch/arm/mach-msm/qdsp6v2/q6core.h b/arch/arm/mach-msm/qdsp6v2/q6core.h
index cb25d6b..1bd21c7 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6core.h
+++ b/arch/arm/mach-msm/qdsp6v2/q6core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index 12a02c5..8569068 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/qcelp_in.c b/arch/arm/mach-msm/qdsp6v2/qcelp_in.c
index a48df39..27700a3 100644
--- a/arch/arm/mach-msm/qdsp6v2/qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/qcelp_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/rtac.c b/arch/arm/mach-msm/qdsp6v2/rtac.c
index cae0f3a..1881607 100644
--- a/arch/arm/mach-msm/qdsp6v2/rtac.c
+++ b/arch/arm/mach-msm/qdsp6v2/rtac.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/rtac_v2.c b/arch/arm/mach-msm/qdsp6v2/rtac_v2.c
index 2d0607c..b09b4fc 100644
--- a/arch/arm/mach-msm/qdsp6v2/rtac_v2.c
+++ b/arch/arm/mach-msm/qdsp6v2/rtac_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.c b/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.c
index 0b38ec2..804fa14 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.h b/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.h
index b102de0..6eb6751 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.h
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_ecodec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c b/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c
index 9b8346d..f6af0ee 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.h b/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.h
index cc69033..672bfa6 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.h
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c b/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c
index e266d7a..38bb65a 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_icodec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_icodec.h b/arch/arm/mach-msm/qdsp6v2/snddev_icodec.h
index 8d5613f..3efa84b 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_icodec.h
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_icodec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.c b/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.c
index 4cf18b3..f5b073a 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.h b/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.h
index d369c96..8ae45cd 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.h
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_mi2s.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_virtual.c b/arch/arm/mach-msm/qdsp6v2/snddev_virtual.c
index f48aa0e..5ad49fe 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_virtual.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_virtual.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_virtual.h b/arch/arm/mach-msm/qdsp6v2/snddev_virtual.h
index dec4d07..e6da25f 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_virtual.h
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_virtual.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
index f02e0a0..3410994 100644
--- a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
+++ b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c
index 5400ccc..87dd3ce 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
index 1338e86..7e6a46b 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
index a973b92..d876dac 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
index f566e82..319be37 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h
index 042b293..03b62c5 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ramdump.c b/arch/arm/mach-msm/ramdump.c
index a7adc47..05b12bf 100644
--- a/arch/arm/mach-msm/ramdump.c
+++ b/arch/arm/mach-msm/ramdump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/ramdump.h b/arch/arm/mach-msm/ramdump.h
index 9006010..522978b 100644
--- a/arch/arm/mach-msm/ramdump.h
+++ b/arch/arm/mach-msm/ramdump.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/remote_spinlock.c b/arch/arm/mach-msm/remote_spinlock.c
index 2480433..28cede2 100644
--- a/arch/arm/mach-msm/remote_spinlock.c
+++ b/arch/arm/mach-msm/remote_spinlock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/reset_modem.c b/arch/arm/mach-msm/reset_modem.c
index 8e92456..7003eb5 100644
--- a/arch/arm/mach-msm/reset_modem.c
+++ b/arch/arm/mach-msm/reset_modem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/restart-fsm9xxx.c b/arch/arm/mach-msm/restart-fsm9xxx.c
index 4c5892f..d2fd051 100644
--- a/arch/arm/mach-msm/restart-fsm9xxx.c
+++ b/arch/arm/mach-msm/restart-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 0337751..7daf77d 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/restart_7k.c b/arch/arm/mach-msm/restart_7k.c
index dc9edf4..2ca0094 100644
--- a/arch/arm/mach-msm/restart_7k.c
+++ b/arch/arm/mach-msm/restart_7k.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rfic-fsm9xxx.c b/arch/arm/mach-msm/rfic-fsm9xxx.c
index 32b654b..ef13631 100644
--- a/arch/arm/mach-msm/rfic-fsm9xxx.c
+++ b/arch/arm/mach-msm/rfic-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rmt_storage_client.c b/arch/arm/mach-msm/rmt_storage_client.c
index 4bec55d..071383f 100644
--- a/arch/arm/mach-msm/rmt_storage_client.c
+++ b/arch/arm/mach-msm/rmt_storage_client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpc_dog_keepalive.c b/arch/arm/mach-msm/rpc_dog_keepalive.c
index 609b125..0f5b217 100644
--- a/arch/arm/mach-msm/rpc_dog_keepalive.c
+++ b/arch/arm/mach-msm/rpc_dog_keepalive.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpc_fsusb.c b/arch/arm/mach-msm/rpc_fsusb.c
index 4692d94..39ccdc2 100644
--- a/arch/arm/mach-msm/rpc_fsusb.c
+++ b/arch/arm/mach-msm/rpc_fsusb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpc_hsusb.c b/arch/arm/mach-msm/rpc_hsusb.c
index cd5f612..78666d7 100644
--- a/arch/arm/mach-msm/rpc_hsusb.c
+++ b/arch/arm/mach-msm/rpc_hsusb.c
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-msm/rpc_hsusb.c
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/arch/arm/mach-msm/rpc_pmapp.c b/arch/arm/mach-msm/rpc_pmapp.c
index 0828bb4..0205da2 100644
--- a/arch/arm/mach-msm/rpc_pmapp.c
+++ b/arch/arm/mach-msm/rpc_pmapp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpc_server_dog_keepalive.c b/arch/arm/mach-msm/rpc_server_dog_keepalive.c
index 5e0f46d..24b3b33 100644
--- a/arch/arm/mach-msm/rpc_server_dog_keepalive.c
+++ b/arch/arm/mach-msm/rpc_server_dog_keepalive.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/rpc_server_dog_keepalive.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/rpc_server_handset.c b/arch/arm/mach-msm/rpc_server_handset.c
index 6d173fb..73eadf5 100644
--- a/arch/arm/mach-msm/rpc_server_handset.c
+++ b/arch/arm/mach-msm/rpc_server_handset.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/rpc_server_handset.c
  *
- * Copyright (c) 2008-2010,2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010,2012 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpc_server_time_remote.c b/arch/arm/mach-msm/rpc_server_time_remote.c
index a7e6854..df2af6f 100644
--- a/arch/arm/mach-msm/rpc_server_time_remote.c
+++ b/arch/arm/mach-msm/rpc_server_time_remote.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/rpc_server_time_remote.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011 The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/rpc_server_time_remote.h b/arch/arm/mach-msm/rpc_server_time_remote.h
index 056666f..ee97de7 100644
--- a/arch/arm/mach-msm/rpc_server_time_remote.h
+++ b/arch/arm/mach-msm/rpc_server_time_remote.h
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/rpc_server_time_remote.h
  *
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/rpcrouter_sdio_xprt.c b/arch/arm/mach-msm/rpcrouter_sdio_xprt.c
index 94a2d26..e9818e5 100644
--- a/arch/arm/mach-msm/rpcrouter_sdio_xprt.c
+++ b/arch/arm/mach-msm/rpcrouter_sdio_xprt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpcrouter_smd_xprt.c b/arch/arm/mach-msm/rpcrouter_smd_xprt.c
index e974eb5..cf51d17 100644
--- a/arch/arm/mach-msm/rpcrouter_smd_xprt.c
+++ b/arch/arm/mach-msm/rpcrouter_smd_xprt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm-notifier.h b/arch/arm/mach-msm/rpm-notifier.h
index 33086c6..b54e167 100644
--- a/arch/arm/mach-msm/rpm-notifier.h
+++ b/arch/arm/mach-msm/rpm-notifier.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm-regulator-8660.c b/arch/arm/mach-msm/rpm-regulator-8660.c
index be590e1..5ba6ee6 100644
--- a/arch/arm/mach-msm/rpm-regulator-8660.c
+++ b/arch/arm/mach-msm/rpm-regulator-8660.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm-regulator-8930.c b/arch/arm/mach-msm/rpm-regulator-8930.c
index 9133856..d7ba67b 100644
--- a/arch/arm/mach-msm/rpm-regulator-8930.c
+++ b/arch/arm/mach-msm/rpm-regulator-8930.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm-regulator-8960.c b/arch/arm/mach-msm/rpm-regulator-8960.c
index c5c01c2..745cfe7 100644
--- a/arch/arm/mach-msm/rpm-regulator-8960.c
+++ b/arch/arm/mach-msm/rpm-regulator-8960.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm-regulator-9615.c b/arch/arm/mach-msm/rpm-regulator-9615.c
index 4abdc52..1c2e817 100644
--- a/arch/arm/mach-msm/rpm-regulator-9615.c
+++ b/arch/arm/mach-msm/rpm-regulator-9615.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm-regulator-private.h b/arch/arm/mach-msm/rpm-regulator-private.h
index 703335f..9836907 100644
--- a/arch/arm/mach-msm/rpm-regulator-private.h
+++ b/arch/arm/mach-msm/rpm-regulator-private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm-regulator-smd.c b/arch/arm/mach-msm/rpm-regulator-smd.c
index a8af9e7..c4c9566 100644
--- a/arch/arm/mach-msm/rpm-regulator-smd.c
+++ b/arch/arm/mach-msm/rpm-regulator-smd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm-regulator.c b/arch/arm/mach-msm/rpm-regulator.c
index 4e5281d..12b1392 100644
--- a/arch/arm/mach-msm/rpm-regulator.c
+++ b/arch/arm/mach-msm/rpm-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm-smd.c b/arch/arm/mach-msm/rpm-smd.c
index a190342..29c9fe8 100644
--- a/arch/arm/mach-msm/rpm-smd.c
+++ b/arch/arm/mach-msm/rpm-smd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm.c b/arch/arm/mach-msm/rpm.c
index 5ab484e2..5128b44 100644
--- a/arch/arm/mach-msm/rpm.c
+++ b/arch/arm/mach-msm/rpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm_log.c b/arch/arm/mach-msm/rpm_log.c
index 4835cef..76eb1d0 100644
--- a/arch/arm/mach-msm/rpm_log.c
+++ b/arch/arm/mach-msm/rpm_log.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm_log.h b/arch/arm/mach-msm/rpm_log.h
index 37349b6..95639cb 100644
--- a/arch/arm/mach-msm/rpm_log.h
+++ b/arch/arm/mach-msm/rpm_log.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm_rbcpr_stats.c b/arch/arm/mach-msm/rpm_rbcpr_stats.c
index 7f27efc..14f77a3 100644
--- a/arch/arm/mach-msm/rpm_rbcpr_stats.c
+++ b/arch/arm/mach-msm/rpm_rbcpr_stats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm_rbcpr_stats.h b/arch/arm/mach-msm/rpm_rbcpr_stats.h
index 55644d0..2ceb4a0 100644
--- a/arch/arm/mach-msm/rpm_rbcpr_stats.h
+++ b/arch/arm/mach-msm/rpm_rbcpr_stats.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm_resources.c b/arch/arm/mach-msm/rpm_resources.c
index 43073d3..b531968 100644
--- a/arch/arm/mach-msm/rpm_resources.c
+++ b/arch/arm/mach-msm/rpm_resources.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm_resources.h b/arch/arm/mach-msm/rpm_resources.h
index 46d6d94..060f86a 100644
--- a/arch/arm/mach-msm/rpm_resources.h
+++ b/arch/arm/mach-msm/rpm_resources.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm_stats.c b/arch/arm/mach-msm/rpm_stats.c
index a831bd5..752fa20 100644
--- a/arch/arm/mach-msm/rpm_stats.c
+++ b/arch/arm/mach-msm/rpm_stats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/rpm_stats.h b/arch/arm/mach-msm/rpm_stats.h
index a3beaa4..c60d40b 100644
--- a/arch/arm/mach-msm/rpm_stats.h
+++ b/arch/arm/mach-msm/rpm_stats.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/saw-regulator.c b/arch/arm/mach-msm/saw-regulator.c
index 6762648..231504c 100644
--- a/arch/arm/mach-msm/saw-regulator.c
+++ b/arch/arm/mach-msm/saw-regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/scm-boot.c b/arch/arm/mach-msm/scm-boot.c
index 01d0853..ae5bd04 100644
--- a/arch/arm/mach-msm/scm-boot.c
+++ b/arch/arm/mach-msm/scm-boot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
index 0d0e6aa..660cd05 100644
--- a/arch/arm/mach-msm/scm-boot.h
+++ b/arch/arm/mach-msm/scm-boot.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/scm-io.c b/arch/arm/mach-msm/scm-io.c
index 28614d3..a21ec36 100644
--- a/arch/arm/mach-msm/scm-io.c
+++ b/arch/arm/mach-msm/scm-io.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/scm-pas.c b/arch/arm/mach-msm/scm-pas.c
index 55ae2f8..9eb04e0 100644
--- a/arch/arm/mach-msm/scm-pas.c
+++ b/arch/arm/mach-msm/scm-pas.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/scm-pas.h b/arch/arm/mach-msm/scm-pas.h
index dd24e20..86b5b30 100644
--- a/arch/arm/mach-msm/scm-pas.h
+++ b/arch/arm/mach-msm/scm-pas.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
index 6052918..468939b 100644
--- a/arch/arm/mach-msm/scm.c
+++ b/arch/arm/mach-msm/scm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/sdio_al.c b/arch/arm/mach-msm/sdio_al.c
index 356ce90..bcfc556 100644
--- a/arch/arm/mach-msm/sdio_al.c
+++ b/arch/arm/mach-msm/sdio_al.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/sdio_al_dloader.c b/arch/arm/mach-msm/sdio_al_dloader.c
index f48c32b..167c163 100644
--- a/arch/arm/mach-msm/sdio_al_dloader.c
+++ b/arch/arm/mach-msm/sdio_al_dloader.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/sdio_al_private.h b/arch/arm/mach-msm/sdio_al_private.h
index 36d9ec1..3a5ab79 100644
--- a/arch/arm/mach-msm/sdio_al_private.h
+++ b/arch/arm/mach-msm/sdio_al_private.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/sdio_al_test.c b/arch/arm/mach-msm/sdio_al_test.c
index c97588f..2c9f675 100644
--- a/arch/arm/mach-msm/sdio_al_test.c
+++ b/arch/arm/mach-msm/sdio_al_test.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/sdio_cmux.c b/arch/arm/mach-msm/sdio_cmux.c
index d04a0b0..70935b2 100644
--- a/arch/arm/mach-msm/sdio_cmux.c
+++ b/arch/arm/mach-msm/sdio_cmux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/sdio_ctl.c b/arch/arm/mach-msm/sdio_ctl.c
index ac16e77..cacdce9 100644
--- a/arch/arm/mach-msm/sdio_ctl.c
+++ b/arch/arm/mach-msm/sdio_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/sdio_dmux.c b/arch/arm/mach-msm/sdio_dmux.c
index 71b4e9b..c6d665d 100644
--- a/arch/arm/mach-msm/sdio_dmux.c
+++ b/arch/arm/mach-msm/sdio_dmux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/sdio_smem.c b/arch/arm/mach-msm/sdio_smem.c
index 4416a79..edc0d23 100644
--- a/arch/arm/mach-msm/sdio_smem.c
+++ b/arch/arm/mach-msm/sdio_smem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/sdio_tty.c b/arch/arm/mach-msm/sdio_tty.c
index 41bc270..c4b7673 100644
--- a/arch/arm/mach-msm/sdio_tty.c
+++ b/arch/arm/mach-msm/sdio_tty.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/sirc-fsm9xxx.c b/arch/arm/mach-msm/sirc-fsm9xxx.c
index 71fa60a..2bd347a 100644
--- a/arch/arm/mach-msm/sirc-fsm9xxx.c
+++ b/arch/arm/mach-msm/sirc-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c
index 04124c5..6008619 100644
--- a/arch/arm/mach-msm/sirc.c
+++ b/arch/arm/mach-msm/sirc.c
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-msm/irq.c
  *
- * Copyright (c) 2009-2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011 The Linux Foundation. All rights reserved.
  * Copyright (C) 2009 Google, Inc.
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/sirc.h b/arch/arm/mach-msm/sirc.h
index f719969..8f5f83f 100644
--- a/arch/arm/mach-msm/sirc.h
+++ b/arch/arm/mach-msm/sirc.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/sirc.h
  *
  * Copyright (C) 2009 Google, Inc.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 166c496..796b5f9 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
index cc82a01..9206016 100644
--- a/arch/arm/mach-msm/smd_debug.c
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd_debug.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/smd_nmea.c b/arch/arm/mach-msm/smd_nmea.c
index 1aedbf5..d1b2b2d 100644
--- a/arch/arm/mach-msm/smd_nmea.c
+++ b/arch/arm/mach-msm/smd_nmea.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 19be521..d175b39 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/smd_private.c b/arch/arm/mach-msm/smd_private.c
index 5a78b6f..411cd81 100644
--- a/arch/arm/mach-msm/smd_private.c
+++ b/arch/arm/mach-msm/smd_private.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
index 7f39a24..af6a5a9 100644
--- a/arch/arm/mach-msm/smd_private.h
+++ b/arch/arm/mach-msm/smd_private.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd_private.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/arch/arm/mach-msm/smd_rpc_sym.h b/arch/arm/mach-msm/smd_rpc_sym.h
index e9a8b47..f476f49 100644
--- a/arch/arm/mach-msm/smd_rpc_sym.h
+++ b/arch/arm/mach-msm/smd_rpc_sym.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -9,7 +9,7 @@
  *       copyright notice, this list of conditions and the following
  *       disclaimer in the documentation and/or other materials provided
  *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     * Neither the name of The Linux Foundation nor the names of its
  *       contributors may be used to endorse or promote products derived
  *       from this software without specific prior written permission.
  *
diff --git a/arch/arm/mach-msm/smd_rpcrouter.c b/arch/arm/mach-msm/smd_rpcrouter.c
index 983d0c1..eb209e0 100644
--- a/arch/arm/mach-msm/smd_rpcrouter.c
+++ b/arch/arm/mach-msm/smd_rpcrouter.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd_rpcrouter.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2011, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/smd_rpcrouter.h b/arch/arm/mach-msm/smd_rpcrouter.h
index 1da7579..732e77b 100644
--- a/arch/arm/mach-msm/smd_rpcrouter.h
+++ b/arch/arm/mach-msm/smd_rpcrouter.h
@@ -1,7 +1,7 @@
 /** arch/arm/mach-msm/smd_rpcrouter.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2011, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/smd_rpcrouter_clients.c b/arch/arm/mach-msm/smd_rpcrouter_clients.c
index d94125e..6537846 100644
--- a/arch/arm/mach-msm/smd_rpcrouter_clients.c
+++ b/arch/arm/mach-msm/smd_rpcrouter_clients.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/smd_rpcrouter_device.c b/arch/arm/mach-msm/smd_rpcrouter_device.c
index e84d213..83616e0 100644
--- a/arch/arm/mach-msm/smd_rpcrouter_device.c
+++ b/arch/arm/mach-msm/smd_rpcrouter_device.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd_rpcrouter_device.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2011, The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/smd_rpcrouter_servers.c b/arch/arm/mach-msm/smd_rpcrouter_servers.c
index 3561c21..478eb1f 100644
--- a/arch/arm/mach-msm/smd_rpcrouter_servers.c
+++ b/arch/arm/mach-msm/smd_rpcrouter_servers.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/rpc_servers.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
  * Author: Iliyan Malchev <ibm@android.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/smd_rpcrouter_xdr.c b/arch/arm/mach-msm/smd_rpcrouter_xdr.c
index 1793516..107271c 100644
--- a/arch/arm/mach-msm/smd_rpcrouter_xdr.c
+++ b/arch/arm/mach-msm/smd_rpcrouter_xdr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
index 965a034..c7962af 100644
--- a/arch/arm/mach-msm/smd_tty.c
+++ b/arch/arm/mach-msm/smd_tty.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/smd_tty.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/smem_log.c b/arch/arm/mach-msm/smem_log.c
index fd8144a..169df1e 100644
--- a/arch/arm/mach-msm/smem_log.c
+++ b/arch/arm/mach-msm/smem_log.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 4d0e060..79a8499 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2013, The Linux Foundation. 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 and
@@ -35,6 +35,7 @@
 	HW_PLATFORM_LIQUID  = 9,
 	/* Dragonboard platform id is assigned as 10 in CDT */
 	HW_PLATFORM_DRAGON	= 10,
+	HW_PLATFORM_QRD	= 11,
 	HW_PLATFORM_INVALID
 };
 
@@ -234,6 +235,7 @@
 	[117] = MSM_CPU_8930,
 	[118] = MSM_CPU_8930,
 	[119] = MSM_CPU_8930,
+	[179] = MSM_CPU_8930,
 
 	/* 8627 IDs */
 	[120] = MSM_CPU_8627,
@@ -279,6 +281,7 @@
 	[143] = MSM_CPU_8930AA,
 	[144] = MSM_CPU_8930AA,
 	[160] = MSM_CPU_8930AA,
+	[180] = MSM_CPU_8930AA,
 
 	/* 8226 IDs */
 	[145] = MSM_CPU_8226,
@@ -294,6 +297,7 @@
 	[155] = MSM_CPU_8930AB,
 	[156] = MSM_CPU_8930AB,
 	[157] = MSM_CPU_8930AB,
+	[181] = MSM_CPU_8930AB,
 
 	/* 8064AA IDs */
 	[172] = MSM_CPU_8064AA,
diff --git a/arch/arm/mach-msm/spm-v2.c b/arch/arm/mach-msm/spm-v2.c
index 5684082..15ed78b 100644
--- a/arch/arm/mach-msm/spm-v2.c
+++ b/arch/arm/mach-msm/spm-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/spm.c b/arch/arm/mach-msm/spm.c
index 3d90678..f6dc2fa 100644
--- a/arch/arm/mach-msm/spm.c
+++ b/arch/arm/mach-msm/spm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/spm.h b/arch/arm/mach-msm/spm.h
index 09ee26a..2f63e24 100644
--- a/arch/arm/mach-msm/spm.h
+++ b/arch/arm/mach-msm/spm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 6fb693f..3391dfd 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -36,6 +36,7 @@
 	struct msm_spm_driver_data reg_data;
 	struct msm_spm_power_modes *modes;
 	uint32_t num_modes;
+	uint32_t cpu_vdd;
 };
 
 struct msm_spm_vdd_info {
@@ -54,6 +55,7 @@
 	struct msm_spm_vdd_info *info = (struct msm_spm_vdd_info *)data;
 
 	dev = &per_cpu(msm_cpu_spm_device, info->cpu);
+	dev->cpu_vdd = info->vlevel;
 	info->err = msm_spm_drv_set_vdd(&dev->reg_data, info->vlevel);
 }
 
@@ -96,7 +98,7 @@
 	struct msm_spm_device *dev;
 
 	dev = &per_cpu(msm_cpu_spm_device, cpu);
-	return msm_spm_drv_get_sts_curr_pmic_data(&dev->reg_data);
+	return dev->cpu_vdd;
 }
 EXPORT_SYMBOL(msm_spm_get_vdd);
 
diff --git a/arch/arm/mach-msm/spm_driver.h b/arch/arm/mach-msm/spm_driver.h
index 4cdfd33..87dd4b0 100644
--- a/arch/arm/mach-msm/spm_driver.h
+++ b/arch/arm/mach-msm/spm_driver.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/subsystem_map.c b/arch/arm/mach-msm/subsystem_map.c
index 5f5a02b..3e4a649 100644
--- a/arch/arm/mach-msm/subsystem_map.c
+++ b/arch/arm/mach-msm/subsystem_map.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -256,6 +256,8 @@
 
 	subsys_domain = msm_get_iommu_domain(msm_subsystem_get_domain_no
 								(subsys_id));
+	if (!subsys_domain)
+		return -EINVAL;
 
 	return iommu_iova_to_phys(subsys_domain, iova);
 }
@@ -429,15 +431,18 @@
 	return buf;
 
 outiova:
-	if (flags & MSM_SUBSYSTEM_MAP_IOVA)
-		iommu_unmap(d, temp_va, SZ_4K);
+	if (flags & MSM_SUBSYSTEM_MAP_IOVA) {
+		if (d)
+			iommu_unmap(d, temp_va, SZ_4K);
+	}
 outdomain:
 	if (flags & MSM_SUBSYSTEM_MAP_IOVA) {
 		/* Unmap the rest of the current domain, i */
-		for (j -= SZ_4K, temp_va -= SZ_4K;
-			j > 0; temp_va -= SZ_4K, j -= SZ_4K)
-			iommu_unmap(d, temp_va, SZ_4K);
-
+		if (d) {
+			for (j -= SZ_4K, temp_va -= SZ_4K;
+				j > 0; temp_va -= SZ_4K, j -= SZ_4K)
+				iommu_unmap(d, temp_va, SZ_4K);
+		}
 		/* Unmap all the other domains */
 		for (i--; i >= 0; i--) {
 			unsigned int domain_no, partition_no;
@@ -447,10 +452,14 @@
 			partition_no = msm_subsystem_get_partition_no(
 								subsys_ids[i]);
 
-			temp_va = buf->iova[i];
-			for (j = length; j > 0; j -= SZ_4K,
-						temp_va += SZ_4K)
-				iommu_unmap(d, temp_va, SZ_4K);
+			d = msm_get_iommu_domain(domain_no);
+
+			if (d) {
+				temp_va = buf->iova[i];
+				for (j = length; j > 0; j -= SZ_4K,
+							temp_va += SZ_4K)
+					iommu_unmap(d, temp_va, SZ_4K);
+			}
 			msm_free_iova_address(buf->iova[i], domain_no,
 					partition_no, length);
 		}
@@ -506,6 +515,9 @@
 						msm_subsystem_get_domain_no(
 						node->subsystems[i]));
 
+				if (!subsys_domain)
+					continue;
+
 				domain_no = msm_subsystem_get_domain_no(
 							node->subsystems[i]);
 				partition_no = msm_subsystem_get_partition_no(
diff --git a/arch/arm/mach-msm/subsystem_notif.c b/arch/arm/mach-msm/subsystem_notif.c
index f7db54c..afa7b48 100644
--- a/arch/arm/mach-msm/subsystem_notif.c
+++ b/arch/arm/mach-msm/subsystem_notif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index d1681f5..f2e969a 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -115,6 +115,20 @@
 	&restart_orders_8960_fusion_sglte,
 	};
 
+/* SGLTE2 restart ordering info*/
+static const char * const order_8064_sglte2[] = {"external_modem",
+						"external_modem_mdm"};
+
+static struct subsys_soc_restart_order restart_orders_8064_fusion_sglte2 = {
+	.subsystem_list = order_8064_sglte2,
+	.count = ARRAY_SIZE(order_8064_sglte2),
+	.subsys_ptrs = {[ARRAY_SIZE(order_8064_sglte2)] = NULL}
+	};
+
+static struct subsys_soc_restart_order *restart_orders_8064_sglte2[] = {
+	&restart_orders_8064_fusion_sglte2,
+	};
+
 /* These will be assigned to one of the sets above after
  * runtime SoC identification.
  */
@@ -133,6 +147,7 @@
 {
 	int ret;
 	int old_val = restart_level;
+	int subtype;
 
 	if (cpu_is_msm9615()) {
 		pr_err("Only Phase 1 subsystem restart is supported\n");
@@ -145,7 +160,9 @@
 
 	switch (restart_level) {
 	case RESET_SUBSYS_INDEPENDENT:
-		if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE) {
+		subtype = socinfo_get_platform_subtype();
+		if ((subtype == PLATFORM_SUBTYPE_SGLTE) ||
+			(subtype == PLATFORM_SUBTYPE_SGLTE2)) {
 			pr_info("Phase 3 is currently unsupported. Using phase 2 instead.\n");
 			restart_level = RESET_SUBSYS_COUPLED;
 		}
@@ -565,6 +582,11 @@
 		n_restart_orders = ARRAY_SIZE(restart_orders_8960_sglte);
 	}
 
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE2) {
+		restart_orders = restart_orders_8064_sglte2;
+		n_restart_orders = ARRAY_SIZE(restart_orders_8064_sglte2);
+	}
+
 	for (i = 0; i < n_restart_orders; i++) {
 		mutex_init(&restart_orders[i]->powerup_lock);
 		mutex_init(&restart_orders[i]->shutdown_lock);
diff --git a/arch/arm/mach-msm/sysmon.c b/arch/arm/mach-msm/sysmon.c
index fc5c3a9..610a3bf 100644
--- a/arch/arm/mach-msm/sysmon.c
+++ b/arch/arm/mach-msm/sysmon.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -45,15 +45,17 @@
 	char			rx_buf[RX_BUF_SIZE];
 	enum transports		transport;
 	struct device		*dev;
+	enum hsic_sysmon_device_id hsic_id;
 };
 
 static struct sysmon_subsys subsys[SYSMON_NUM_SS] = {
-	[SYSMON_SS_MODEM].transport     = TRANSPORT_SMD,
-	[SYSMON_SS_LPASS].transport     = TRANSPORT_SMD,
-	[SYSMON_SS_WCNSS].transport     = TRANSPORT_SMD,
-	[SYSMON_SS_DSPS].transport      = TRANSPORT_SMD,
-	[SYSMON_SS_Q6FW].transport      = TRANSPORT_SMD,
-	[SYSMON_SS_EXT_MODEM].transport = TRANSPORT_HSIC,
+	[SYSMON_SS_MODEM].transport      = TRANSPORT_SMD,
+	[SYSMON_SS_LPASS].transport      = TRANSPORT_SMD,
+	[SYSMON_SS_WCNSS].transport      = TRANSPORT_SMD,
+	[SYSMON_SS_DSPS].transport       = TRANSPORT_SMD,
+	[SYSMON_SS_Q6FW].transport       = TRANSPORT_SMD,
+	[SYSMON_SS_EXT_MODEM].transport  = TRANSPORT_HSIC,
+	[SYSMON_SS_EXT_MODEM2].transport = TRANSPORT_HSIC,
 };
 
 static const char *notif_name[SUBSYS_NOTIF_TYPE_COUNT] = {
@@ -89,11 +91,10 @@
 	size_t actual_len;
 
 	pr_debug("Sending HSIC message: %s\n", tx_buf);
-	ret = hsic_sysmon_write(HSIC_SYSMON_DEV_EXT_MODEM,
-				tx_buf, len, TIMEOUT_MS);
+	ret = hsic_sysmon_write(ss->hsic_id, tx_buf, len, TIMEOUT_MS);
 	if (ret)
 		return ret;
-	ret = hsic_sysmon_read(HSIC_SYSMON_DEV_EXT_MODEM, ss->rx_buf,
+	ret = hsic_sysmon_read(ss->hsic_id, ss->rx_buf,
 			       ARRAY_SIZE(ss->rx_buf), &actual_len, TIMEOUT_MS);
 	return ret;
 }
@@ -302,7 +303,9 @@
 		if (pdev->id < SMD_NUM_TYPE)
 			return -EINVAL;
 
-		ret = hsic_sysmon_open(HSIC_SYSMON_DEV_EXT_MODEM);
+		ss->hsic_id = HSIC_SYSMON_DEV_EXT_MODEM +
+				(pdev->id - SYSMON_SS_EXT_MODEM);
+		ret = hsic_sysmon_open(ss->hsic_id);
 		if (ret) {
 			pr_err("HSIC open failed\n");
 			return ret;
@@ -328,7 +331,7 @@
 		smd_close(ss->chan);
 		break;
 	case TRANSPORT_HSIC:
-		hsic_sysmon_close(HSIC_SYSMON_DEV_EXT_MODEM);
+		hsic_sysmon_close(ss->hsic_id);
 		break;
 	}
 	mutex_unlock(&ss->lock);
diff --git a/arch/arm/mach-msm/sysmon.h b/arch/arm/mach-msm/sysmon.h
index 8c2f6ea..59caf0e 100644
--- a/arch/arm/mach-msm/sysmon.h
+++ b/arch/arm/mach-msm/sysmon.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -31,6 +31,7 @@
 
 	/* Non-SMD subsystems */
 	SYSMON_SS_EXT_MODEM = SMD_NUM_TYPE,
+	SYSMON_SS_EXT_MODEM2,
 	SYSMON_NUM_SS
 };
 
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index b61604a..795e1d6 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -290,8 +290,6 @@
 
 	clock = clockevent_to_clock(evt);
 	clock_state = &__get_cpu_var(msm_clocks_percpu)[clock->index];
-	if (clock_state->stopped)
-		return 0;
 	now = msm_read_timer_count(clock, LOCAL_TIMER);
 	alarm = now + (cycles << clock->shift);
 	if (clock->flags & MSM_CLOCK_FLAGS_ODD_MATCH_WRITE)
@@ -1068,9 +1066,11 @@
 		__raw_writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
 		gpt->status_mask = BIT(10);
 		dgt->status_mask = BIT(2);
-		gpt->freq = 32765;
-		gpt_hz = 32765;
-		sclk_hz = 32765;
+		if (!soc_class_is_apq8064()) {
+			gpt->freq = 32765;
+			gpt_hz = 32765;
+			sclk_hz = 32765;
+		}
 		if (!soc_class_is_msm8930() && !cpu_is_msm8960ab()) {
 			gpt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT;
 			dgt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT;
diff --git a/arch/arm/mach-msm/timer.h b/arch/arm/mach-msm/timer.h
index ebe1819..9a213e5 100644
--- a/arch/arm/mach-msm/timer.h
+++ b/arch/arm/mach-msm/timer.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2011-2012 The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/tz_log.c b/arch/arm/mach-msm/tz_log.c
index db797cd..add64cf 100644
--- a/arch/arm/mach-msm/tz_log.c
+++ b/arch/arm/mach-msm/tz_log.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c
index 271da86..c3298b4 100644
--- a/arch/arm/mach-msm/vreg.c
+++ b/arch/arm/mach-msm/vreg.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/vreg.c
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012 The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index e7569af..b302866 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -237,7 +237,7 @@
 		goto out;
 	}
 	ret = request_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ,
-			riva_wdog_bite_irq_hdlr, IRQF_TRIGGER_HIGH,
+			riva_wdog_bite_irq_hdlr, IRQF_TRIGGER_RISING,
 				"riva_wdog", NULL);
 
 	if (ret < 0) {
diff --git a/arch/arm/mach-msm/xo-fsm9xxx.c b/arch/arm/mach-msm/xo-fsm9xxx.c
index cbf3b7a..34c9688 100644
--- a/arch/arm/mach-msm/xo-fsm9xxx.c
+++ b/arch/arm/mach-msm/xo-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index cb9fc76..0321122 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -2,7 +2,7 @@
  * arch/arm/mm/cache-l2x0.c - L210/L220 cache controller support
  *
  * Copyright (C) 2007 ARM Limited
- * Copyright (c) 2009, 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011-2012, The Linux Foundation. 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
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index afaa39d..8d08abc 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -165,16 +165,29 @@
 
 static void __dma_clear_buffer(struct page *page, size_t size)
 {
-	void *ptr;
 	/*
 	 * Ensure that the allocated pages are zeroed, and that any data
 	 * lurking in the kernel direct-mapped region is invalidated.
 	 */
-	ptr = page_address(page);
-	if (ptr) {
-		memset(ptr, 0, size);
-		dmac_flush_range(ptr, ptr + size);
-		outer_flush_range(__pa(ptr), __pa(ptr) + size);
+	if (!PageHighMem(page)) {
+		void *ptr = page_address(page);
+		if (ptr) {
+			memset(ptr, 0, size);
+			dmac_flush_range(ptr, ptr + size);
+			outer_flush_range(__pa(ptr), __pa(ptr) + size);
+		}
+	} else {
+		phys_addr_t base = __pfn_to_phys(page_to_pfn(page));
+		phys_addr_t end = base + size;
+		while (size > 0) {
+			void *ptr = kmap_atomic(page);
+			memset(ptr, 0, PAGE_SIZE);
+			dmac_flush_range(ptr, ptr + PAGE_SIZE);
+			kunmap_atomic(ptr);
+			page++;
+			size -= PAGE_SIZE;
+		}
+		outer_flush_range(base, end);
 	}
 }
 
@@ -315,7 +328,7 @@
 
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
 				     pgprot_t prot, struct page **ret_page,
-				     bool no_kernel_mapping);
+				     bool no_kernel_mapping, const void *caller);
 
 static struct arm_vmregion_head coherent_head = {
 	.vm_lock	= __SPIN_LOCK_UNLOCKED(&coherent_head.vm_lock),
@@ -344,7 +357,8 @@
 	if (!IS_ENABLED(CONFIG_CMA))
 		return 0;
 
-	ptr = __alloc_from_contiguous(NULL, size, prot, &page, false);
+	ptr = __alloc_from_contiguous(NULL, size, prot, &page, false,
+						coherent_init);
 	if (ptr) {
 		coherent_head.vm_start = (unsigned long) ptr;
 		coherent_head.vm_end = (unsigned long) ptr + size;
@@ -389,7 +403,7 @@
 		if (end > arm_lowmem_limit)
 			end = arm_lowmem_limit;
 		if (start >= end)
-			return;
+			continue;
 
 		map.pfn = __phys_to_pfn(start);
 		map.virtual = __phys_to_virt(start);
@@ -465,7 +479,7 @@
 	return NULL;
 }
 
-static void __dma_free_remap(void *cpu_addr, size_t size)
+static void __dma_free_remap(void *cpu_addr, size_t size, bool no_warn)
 {
 	struct arm_vmregion *c;
 	unsigned long addr;
@@ -475,9 +489,11 @@
 
 	c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
 	if (!c) {
-		pr_err("%s: trying to free invalid coherent area: %p\n",
-		       __func__, cpu_addr);
-		dump_stack();
+		if (!no_warn) {
+			pr_err("%s: trying to free invalid coherent area: %p\n",
+			       __func__, cpu_addr);
+			dump_stack();
+		}
 		return;
 	}
 
@@ -619,29 +635,54 @@
 	return 1;
 }
 
+#define NO_KERNEL_MAPPING_DUMMY	0x2222
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
 				     pgprot_t prot, struct page **ret_page,
-				     bool no_kernel_mapping)
+				     bool no_kernel_mapping,
+				     const void *caller)
 {
 	unsigned long order = get_order(size);
 	size_t count = size >> PAGE_SHIFT;
 	struct page *page;
+	void *ptr;
 
 	page = dma_alloc_from_contiguous(dev, count, order);
 	if (!page)
 		return NULL;
 
 	__dma_clear_buffer(page, size);
-	__dma_remap(page, size, prot, no_kernel_mapping);
 
+	if (!PageHighMem(page)) {
+		__dma_remap(page, size, prot, no_kernel_mapping);
+		ptr = page_address(page);
+	} else {
+		if (no_kernel_mapping) {
+			/*
+			 * Something non-NULL needs to be returned here. Give
+			 * back a dummy address that is unmapped to catch
+			 * clients trying to use the address incorrectly
+			 */
+			ptr = (void *)NO_KERNEL_MAPPING_DUMMY;
+		} else {
+			ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot,
+						caller);
+			if (!ptr) {
+				dma_release_from_contiguous(dev, page, count);
+				return NULL;
+			}
+		}
+	}
 	*ret_page = page;
-	return page_address(page);
+	return ptr;
 }
 
 static void __free_from_contiguous(struct device *dev, struct page *page,
-				   size_t size)
+				   void *cpu_addr, size_t size)
 {
-	__dma_remap(page, size, pgprot_kernel, false);
+	if (!PageHighMem(page))
+		__dma_remap(page, size, pgprot_kernel, false);
+	else
+		__dma_free_remap(cpu_addr, size, true);
 	dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
 }
 
@@ -731,7 +772,7 @@
 		addr = __alloc_from_pool(dev, size, &page, caller);
 	else
 		addr = __alloc_from_contiguous(dev, size, prot, &page,
-						no_kernel_mapping);
+						no_kernel_mapping, caller);
 
 	if (addr)
 		*handle = pfn_to_dma(dev, page_to_pfn(page));
@@ -798,7 +839,7 @@
 	if (arch_is_coherent() || nommu()) {
 		__dma_free_buffer(page, size);
 	} else if (!IS_ENABLED(CONFIG_CMA)) {
-		__dma_free_remap(cpu_addr, size);
+		__dma_free_remap(cpu_addr, size, false);
 		__dma_free_buffer(page, size);
 	} else {
 		if (__free_from_pool(cpu_addr, size))
@@ -807,7 +848,7 @@
 		 * Non-atomic allocations cannot be freed with IRQs disabled
 		 */
 		WARN_ON(irqs_disabled());
-		__free_from_contiguous(dev, page, size);
+		__free_from_contiguous(dev, page, cpu_addr, size);
 	}
 }
 
@@ -1332,7 +1373,7 @@
 	c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
 	if (c) {
 		struct page **pages = c->priv;
-		__dma_free_remap(cpu_addr, size);
+		__dma_free_remap(cpu_addr, size, false);
 		__iommu_remove_mapping(dev, handle, size);
 		__iommu_free_buffer(dev, pages, size);
 	}
diff --git a/arch/arm/mm/emulate_domain_manager-v7.c b/arch/arm/mm/emulate_domain_manager-v7.c
index 3797e21..86b5278 100644
--- a/arch/arm/mm/emulate_domain_manager-v7.c
+++ b/arch/arm/mm/emulate_domain_manager-v7.c
@@ -4,7 +4,7 @@
  *
  * Requires hooks to be alerted to any runtime changes of dacr or MMU context.
  *
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 57f41ca..56c37b7 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -689,9 +689,6 @@
 	extern u32 dtcm_end;
 	extern u32 itcm_end;
 #endif
-#ifdef CONFIG_FIX_MOVABLE_ZONE
-	struct zone *zone;
-#endif
 
 	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
 
@@ -737,14 +734,6 @@
 #endif
 	}
 
-#ifdef CONFIG_FIX_MOVABLE_ZONE
-	for_each_zone(zone) {
-		if (zone_idx(zone) == ZONE_MOVABLE)
-			total_unmovable_pages = totalram_pages -
-							zone->spanned_pages;
-	}
-#endif
-
 	/*
 	 * Since our memory may not be contiguous, calculate the
 	 * real number of pages we have in this system
@@ -858,39 +847,9 @@
 					    __phys_to_pfn(__pa(__init_end)),
 					    "init");
 		totalram_pages += reclaimed_initmem;
-#ifdef CONFIG_FIX_MOVABLE_ZONE
-		total_unmovable_pages += reclaimed_initmem;
-#endif
 	}
 }
 
-#ifdef CONFIG_MEMORY_HOTPLUG
-int arch_add_memory(int nid, u64 start, u64 size)
-{
-	struct pglist_data *pgdata = NODE_DATA(nid);
-	struct zone *zone = pgdata->node_zones + ZONE_MOVABLE;
-	unsigned long start_pfn = start >> PAGE_SHIFT;
-	unsigned long nr_pages = size >> PAGE_SHIFT;
-
-	return __add_pages(nid, zone, start_pfn, nr_pages);
-}
-
-int arch_physical_active_memory(u64 start, u64 size)
-{
-	return platform_physical_active_pages(start, size);
-}
-
-int arch_physical_remove_memory(u64 start, u64 size)
-{
-	return platform_physical_remove_pages(start, size);
-}
-
-int arch_physical_low_power_memory(u64 start, u64 size)
-{
-	return platform_physical_low_power_pages(start, size);
-}
-#endif
-
 #ifdef CONFIG_BLK_DEV_INITRD
 
 static int keep_initrd;
@@ -905,9 +864,6 @@
 						 __phys_to_pfn(__pa(end)),
 						 "initrd");
 		totalram_pages += reclaimed_initrd_mem;
-#ifdef CONFIG_FIX_MOVABLE_ZONE
-		total_unmovable_pages += reclaimed_initrd_mem;
-#endif
 	}
 }
 
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index da33be0..a6827fb 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -953,10 +953,6 @@
 	find_membank0_hole();
 #endif
 
-#if (defined CONFIG_HIGHMEM) && (defined CONFIG_FIX_MOVABLE_ZONE)
-	if (movable_reserved_size && __pa(vmalloc_min) > movable_reserved_start)
-		vmalloc_min = __va(movable_reserved_start);
-#endif
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
 		*bank = meminfo.bank[i];
diff --git a/arch/arm/mm/vcm.c b/arch/arm/mm/vcm.c
index f2d9457..c4dc1db 100644
--- a/arch/arm/mm/vcm.c
+++ b/arch/arm/mm/vcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mm/vcm_alloc.c b/arch/arm/mm/vcm_alloc.c
index 5f3c024..2106ebb 100644
--- a/arch/arm/mm/vcm_alloc.c
+++ b/arch/arm/mm/vcm_alloc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/mm/vcm_mm.c b/arch/arm/mm/vcm_mm.c
index dee51fa..2642390 100644
--- a/arch/arm/mm/vcm_mm.c
+++ b/arch/arm/mm/vcm_mm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/perfmon/cp15_registers.h b/arch/arm/perfmon/cp15_registers.h
index 3de4d8b..f5ba84e 100644
--- a/arch/arm/perfmon/cp15_registers.h
+++ b/arch/arm/perfmon/cp15_registers.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/perfmon/l2_cp15_registers.h b/arch/arm/perfmon/l2_cp15_registers.h
index 796dc8b..0cf1acd 100644
--- a/arch/arm/perfmon/l2_cp15_registers.h
+++ b/arch/arm/perfmon/l2_cp15_registers.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/perfmon/mcrmrc.h b/arch/arm/perfmon/mcrmrc.h
index 29f9ac0..875c564 100644
--- a/arch/arm/perfmon/mcrmrc.h
+++ b/arch/arm/perfmon/mcrmrc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/perfmon/per-axi.c b/arch/arm/perfmon/per-axi.c
index 48309be..e8bf3e6 100644
--- a/arch/arm/perfmon/per-axi.c
+++ b/arch/arm/perfmon/per-axi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/perfmon/per-axi.h b/arch/arm/perfmon/per-axi.h
index 89f67fc..080079c 100644
--- a/arch/arm/perfmon/per-axi.h
+++ b/arch/arm/perfmon/per-axi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/perfmon/per-process-perf.c b/arch/arm/perfmon/per-process-perf.c
index c8bebd8..57450d9 100644
--- a/arch/arm/perfmon/per-process-perf.c
+++ b/arch/arm/perfmon/per-process-perf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/perfmon/per.c b/arch/arm/perfmon/per.c
index 4222844..11cdbce 100644
--- a/arch/arm/perfmon/per.c
+++ b/arch/arm/perfmon/per.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/perfmon/perf-function-hooks.c b/arch/arm/perfmon/perf-function-hooks.c
index aacc353..bfe504a 100644
--- a/arch/arm/perfmon/perf-function-hooks.c
+++ b/arch/arm/perfmon/perf-function-hooks.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/perfmon/perf-smp.c b/arch/arm/perfmon/perf-smp.c
index 5417fc7..849658a 100644
--- a/arch/arm/perfmon/perf-smp.c
+++ b/arch/arm/perfmon/perf-smp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/perfmon/perf-v7.c b/arch/arm/perfmon/perf-v7.c
index 614eedc..5810ba7 100644
--- a/arch/arm/perfmon/perf-v7.c
+++ b/arch/arm/perfmon/perf-v7.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/perfmon/perf.h b/arch/arm/perfmon/perf.h
index 1a9bb8b..f02405e 100644
--- a/arch/arm/perfmon/perf.h
+++ b/arch/arm/perfmon/perf.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index a11842a..aa50e16 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1197,3 +1197,4 @@
 msm8625_ffa		MACH_MSM8625_FFA	MSM8625_FFA		4166
 msm8625_evt		MACH_MSM8625_EVT	MSM8625_EVT		4193
 apq8064_mako		MACH_APQ8064_MAKO	APQ8064_MAKO		7800
+msm8930_evt		MACH_MSM8930_EVT	MSM8930_EVT		4558
diff --git a/arch/hexagon/include/asm/atomic.h b/arch/hexagon/include/asm/atomic.h
index 3e25804..468fbb0 100644
--- a/arch/hexagon/include/asm/atomic.h
+++ b/arch/hexagon/include/asm/atomic.h
@@ -1,7 +1,7 @@
 /*
  * Atomic operations for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/include/asm/barrier.h b/arch/hexagon/include/asm/barrier.h
index a4ed6e2..1041a8e 100644
--- a/arch/hexagon/include/asm/barrier.h
+++ b/arch/hexagon/include/asm/barrier.h
@@ -1,7 +1,7 @@
 /*
  * Memory barrier definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/bitops.h b/arch/hexagon/include/asm/bitops.h
index 4caa649..9b1e4af 100644
--- a/arch/hexagon/include/asm/bitops.h
+++ b/arch/hexagon/include/asm/bitops.h
@@ -1,7 +1,7 @@
 /*
  * Bit operations for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/include/asm/bitsperlong.h b/arch/hexagon/include/asm/bitsperlong.h
index 2701cae..4a65815 100644
--- a/arch/hexagon/include/asm/bitsperlong.h
+++ b/arch/hexagon/include/asm/bitsperlong.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/byteorder.h b/arch/hexagon/include/asm/byteorder.h
index 0e19b9f..e31f3f7 100644
--- a/arch/hexagon/include/asm/byteorder.h
+++ b/arch/hexagon/include/asm/byteorder.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/cache.h b/arch/hexagon/include/asm/cache.h
index 0f01de2..f4ca594 100644
--- a/arch/hexagon/include/asm/cache.h
+++ b/arch/hexagon/include/asm/cache.h
@@ -1,7 +1,7 @@
 /*
  * Cache definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/cacheflush.h b/arch/hexagon/include/asm/cacheflush.h
index 6865c1b..49e0896 100644
--- a/arch/hexagon/include/asm/cacheflush.h
+++ b/arch/hexagon/include/asm/cacheflush.h
@@ -1,7 +1,7 @@
 /*
  * Cache flush operations for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/checksum.h b/arch/hexagon/include/asm/checksum.h
index 3ce4ecd..46ec8a7 100644
--- a/arch/hexagon/include/asm/checksum.h
+++ b/arch/hexagon/include/asm/checksum.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/cmpxchg.h b/arch/hexagon/include/asm/cmpxchg.h
index c5f9527..9e78029 100644
--- a/arch/hexagon/include/asm/cmpxchg.h
+++ b/arch/hexagon/include/asm/cmpxchg.h
@@ -1,7 +1,7 @@
 /*
  * xchg/cmpxchg operations for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/include/asm/delay.h b/arch/hexagon/include/asm/delay.h
index 9ab12e9..5307971 100644
--- a/arch/hexagon/include/asm/delay.h
+++ b/arch/hexagon/include/asm/delay.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/dma-mapping.h b/arch/hexagon/include/asm/dma-mapping.h
index 233ed3d..85e9935 100644
--- a/arch/hexagon/include/asm/dma-mapping.h
+++ b/arch/hexagon/include/asm/dma-mapping.h
@@ -1,7 +1,7 @@
 /*
  * DMA operations for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/dma.h b/arch/hexagon/include/asm/dma.h
index da6d2f6..9e34ff4 100644
--- a/arch/hexagon/include/asm/dma.h
+++ b/arch/hexagon/include/asm/dma.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h
index 37976a0..6ed2364 100644
--- a/arch/hexagon/include/asm/elf.h
+++ b/arch/hexagon/include/asm/elf.h
@@ -1,7 +1,7 @@
 /*
  * ELF definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/exec.h b/arch/hexagon/include/asm/exec.h
index 350e6d4..c32b213 100644
--- a/arch/hexagon/include/asm/exec.h
+++ b/arch/hexagon/include/asm/exec.h
@@ -1,7 +1,7 @@
 /*
  * Process execution related definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/fixmap.h b/arch/hexagon/include/asm/fixmap.h
index b27f494..b75b6bf 100644
--- a/arch/hexagon/include/asm/fixmap.h
+++ b/arch/hexagon/include/asm/fixmap.h
@@ -1,7 +1,7 @@
 /*
  * Fixmap support for Hexagon - enough to support highmem features
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/hexagon_vm.h b/arch/hexagon/include/asm/hexagon_vm.h
index 182cb9d..c144bee 100644
--- a/arch/hexagon/include/asm/hexagon_vm.h
+++ b/arch/hexagon/include/asm/hexagon_vm.h
@@ -1,7 +1,7 @@
 /*
  * Declarations for to Hexagon Virtal Machine.
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/intrinsics.h b/arch/hexagon/include/asm/intrinsics.h
index 1c02186..ca58773 100644
--- a/arch/hexagon/include/asm/intrinsics.h
+++ b/arch/hexagon/include/asm/intrinsics.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h
index b3acc2c..e527cfe 100644
--- a/arch/hexagon/include/asm/io.h
+++ b/arch/hexagon/include/asm/io.h
@@ -1,7 +1,7 @@
 /*
  * IO definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/irq.h b/arch/hexagon/include/asm/irq.h
index ded8c15..51661db 100644
--- a/arch/hexagon/include/asm/irq.h
+++ b/arch/hexagon/include/asm/irq.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/irqflags.h b/arch/hexagon/include/asm/irqflags.h
index ec15236..e5fd949 100644
--- a/arch/hexagon/include/asm/irqflags.h
+++ b/arch/hexagon/include/asm/irqflags.h
@@ -1,7 +1,7 @@
 /*
  * IRQ support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/kgdb.h b/arch/hexagon/include/asm/kgdb.h
index 9e87797..32a6fb6 100644
--- a/arch/hexagon/include/asm/kgdb.h
+++ b/arch/hexagon/include/asm/kgdb.h
@@ -1,7 +1,7 @@
 /*
  * arch/hexagon/include/asm/kgdb.h - Hexagon KGDB Support
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/linkage.h b/arch/hexagon/include/asm/linkage.h
index a00b85f..31b4cbe 100644
--- a/arch/hexagon/include/asm/linkage.h
+++ b/arch/hexagon/include/asm/linkage.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/mem-layout.h b/arch/hexagon/include/asm/mem-layout.h
index 72e5dcd..af16e97 100644
--- a/arch/hexagon/include/asm/mem-layout.h
+++ b/arch/hexagon/include/asm/mem-layout.h
@@ -1,7 +1,7 @@
 /*
  * Memory layout definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/mmu.h b/arch/hexagon/include/asm/mmu.h
index 30a5d8d..2288b19 100644
--- a/arch/hexagon/include/asm/mmu.h
+++ b/arch/hexagon/include/asm/mmu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/mmu_context.h b/arch/hexagon/include/asm/mmu_context.h
index b4fe5a5..d423d2e 100644
--- a/arch/hexagon/include/asm/mmu_context.h
+++ b/arch/hexagon/include/asm/mmu_context.h
@@ -1,7 +1,7 @@
 /*
  * MM context support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/module.h b/arch/hexagon/include/asm/module.h
index 72ba494..6b4323a 100644
--- a/arch/hexagon/include/asm/module.h
+++ b/arch/hexagon/include/asm/module.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h
index edd9762..692adc213 100644
--- a/arch/hexagon/include/asm/page.h
+++ b/arch/hexagon/include/asm/page.h
@@ -1,7 +1,7 @@
 /*
  * Page management definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/param.h b/arch/hexagon/include/asm/param.h
index 285344b..5cec8c0 100644
--- a/arch/hexagon/include/asm/param.h
+++ b/arch/hexagon/include/asm/param.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/perf_event.h b/arch/hexagon/include/asm/perf_event.h
index 8b8526b..430978b 100644
--- a/arch/hexagon/include/asm/perf_event.h
+++ b/arch/hexagon/include/asm/perf_event.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/pgalloc.h b/arch/hexagon/include/asm/pgalloc.h
index 13443c7..679bf6d 100644
--- a/arch/hexagon/include/asm/pgalloc.h
+++ b/arch/hexagon/include/asm/pgalloc.h
@@ -1,7 +1,7 @@
 /*
  * Page table support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/pgtable.h b/arch/hexagon/include/asm/pgtable.h
index ca619bf..20d55f6 100644
--- a/arch/hexagon/include/asm/pgtable.h
+++ b/arch/hexagon/include/asm/pgtable.h
@@ -1,7 +1,7 @@
 /*
  * Page table support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/processor.h b/arch/hexagon/include/asm/processor.h
index 20c5dda..9b3aea9 100644
--- a/arch/hexagon/include/asm/processor.h
+++ b/arch/hexagon/include/asm/processor.h
@@ -1,7 +1,7 @@
 /*
  * Process/processor support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/ptrace.h b/arch/hexagon/include/asm/ptrace.h
index 3d2f607..8ef7840 100644
--- a/arch/hexagon/include/asm/ptrace.h
+++ b/arch/hexagon/include/asm/ptrace.h
@@ -1,7 +1,7 @@
 /*
  * Ptrace definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/registers.h b/arch/hexagon/include/asm/registers.h
index 4dd741b..2bfd64d 100644
--- a/arch/hexagon/include/asm/registers.h
+++ b/arch/hexagon/include/asm/registers.h
@@ -1,7 +1,7 @@
 /*
  * Register definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/setup.h b/arch/hexagon/include/asm/setup.h
index 3b754c5..e48285e 100644
--- a/arch/hexagon/include/asm/setup.h
+++ b/arch/hexagon/include/asm/setup.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/sigcontext.h b/arch/hexagon/include/asm/sigcontext.h
index ce6dcd9..b6ba536 100644
--- a/arch/hexagon/include/asm/sigcontext.h
+++ b/arch/hexagon/include/asm/sigcontext.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/signal.h b/arch/hexagon/include/asm/signal.h
index 471c056..9395568 100644
--- a/arch/hexagon/include/asm/signal.h
+++ b/arch/hexagon/include/asm/signal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/smp.h b/arch/hexagon/include/asm/smp.h
index 87c869a..2b9b974 100644
--- a/arch/hexagon/include/asm/smp.h
+++ b/arch/hexagon/include/asm/smp.h
@@ -1,7 +1,7 @@
 /*
  * SMP definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/spinlock.h b/arch/hexagon/include/asm/spinlock.h
index 168a920..12ca4eb 100644
--- a/arch/hexagon/include/asm/spinlock.h
+++ b/arch/hexagon/include/asm/spinlock.h
@@ -1,7 +1,7 @@
 /*
  * Spinlock support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/include/asm/spinlock_types.h b/arch/hexagon/include/asm/spinlock_types.h
index 5e937af..2ae9ecc 100644
--- a/arch/hexagon/include/asm/spinlock_types.h
+++ b/arch/hexagon/include/asm/spinlock_types.h
@@ -1,7 +1,7 @@
 /*
  * Spinlock support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/string.h b/arch/hexagon/include/asm/string.h
index f4489c1..7d37f47 100644
--- a/arch/hexagon/include/asm/string.h
+++ b/arch/hexagon/include/asm/string.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/suspend.h b/arch/hexagon/include/asm/suspend.h
index 089dd82..18b44b5 100644
--- a/arch/hexagon/include/asm/suspend.h
+++ b/arch/hexagon/include/asm/suspend.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/swab.h b/arch/hexagon/include/asm/swab.h
index 99cf0be..9069e92 100644
--- a/arch/hexagon/include/asm/swab.h
+++ b/arch/hexagon/include/asm/swab.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/switch_to.h b/arch/hexagon/include/asm/switch_to.h
index 28ca0df..96745e7 100644
--- a/arch/hexagon/include/asm/switch_to.h
+++ b/arch/hexagon/include/asm/switch_to.h
@@ -1,7 +1,7 @@
 /*
  * Task switching definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/syscall.h b/arch/hexagon/include/asm/syscall.h
index 3e7d61d..fb0e9d4 100644
--- a/arch/hexagon/include/asm/syscall.h
+++ b/arch/hexagon/include/asm/syscall.h
@@ -1,7 +1,7 @@
 /*
  * Syscall support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/thread_info.h b/arch/hexagon/include/asm/thread_info.h
index 9c2934f..e369c1d 100644
--- a/arch/hexagon/include/asm/thread_info.h
+++ b/arch/hexagon/include/asm/thread_info.h
@@ -1,7 +1,7 @@
 /*
  * Thread support for the Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/time.h b/arch/hexagon/include/asm/time.h
index 081b82c..deda170 100644
--- a/arch/hexagon/include/asm/time.h
+++ b/arch/hexagon/include/asm/time.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/timer-regs.h b/arch/hexagon/include/asm/timer-regs.h
index d80db23..79912b8 100644
--- a/arch/hexagon/include/asm/timer-regs.h
+++ b/arch/hexagon/include/asm/timer-regs.h
@@ -1,7 +1,7 @@
 /*
  * Timer support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/timex.h b/arch/hexagon/include/asm/timex.h
index b11c62b..f63fe13 100644
--- a/arch/hexagon/include/asm/timex.h
+++ b/arch/hexagon/include/asm/timex.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/tlb.h b/arch/hexagon/include/asm/tlb.h
index 473abde..2f00772 100644
--- a/arch/hexagon/include/asm/tlb.h
+++ b/arch/hexagon/include/asm/tlb.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/tlbflush.h b/arch/hexagon/include/asm/tlbflush.h
index b89a902..62d95a9 100644
--- a/arch/hexagon/include/asm/tlbflush.h
+++ b/arch/hexagon/include/asm/tlbflush.h
@@ -1,7 +1,7 @@
 /*
  * TLB flush support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/traps.h b/arch/hexagon/include/asm/traps.h
index 6a407f6..ec11285 100644
--- a/arch/hexagon/include/asm/traps.h
+++ b/arch/hexagon/include/asm/traps.h
@@ -1,7 +1,7 @@
 /*
  * Trap support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/uaccess.h b/arch/hexagon/include/asm/uaccess.h
index 7e706ea..e4127e4 100644
--- a/arch/hexagon/include/asm/uaccess.h
+++ b/arch/hexagon/include/asm/uaccess.h
@@ -1,7 +1,7 @@
 /*
  * User memory access support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/unistd.h b/arch/hexagon/include/asm/unistd.h
index 4d0ecde..7ac1ef4 100644
--- a/arch/hexagon/include/asm/unistd.h
+++ b/arch/hexagon/include/asm/unistd.h
@@ -1,7 +1,7 @@
 /*
  * Syscall support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/user.h b/arch/hexagon/include/asm/user.h
index 3a55078..6cbcdf7 100644
--- a/arch/hexagon/include/asm/user.h
+++ b/arch/hexagon/include/asm/user.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/vdso.h b/arch/hexagon/include/asm/vdso.h
index 2d95cbb..ed08e6c 100644
--- a/arch/hexagon/include/asm/vdso.h
+++ b/arch/hexagon/include/asm/vdso.h
@@ -1,7 +1,7 @@
 /*
  * vDSO implementation for Hexagon
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/vm_fault.h b/arch/hexagon/include/asm/vm_fault.h
index cacda36..9b0e9c5 100644
--- a/arch/hexagon/include/asm/vm_fault.h
+++ b/arch/hexagon/include/asm/vm_fault.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/include/asm/vm_mmu.h b/arch/hexagon/include/asm/vm_mmu.h
index 580462d..9a94de7 100644
--- a/arch/hexagon/include/asm/vm_mmu.h
+++ b/arch/hexagon/include/asm/vm_mmu.h
@@ -1,7 +1,7 @@
 /*
  * Hexagon VM page table entry definitions
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/asm-offsets.c b/arch/hexagon/kernel/asm-offsets.c
index 89ffa51..2d5e84d 100644
--- a/arch/hexagon/kernel/asm-offsets.c
+++ b/arch/hexagon/kernel/asm-offsets.c
@@ -5,7 +5,7 @@
  * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000 MIPS Technologies, Inc.
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c
index 0f2367c..9c3712e 100644
--- a/arch/hexagon/kernel/dma.c
+++ b/arch/hexagon/kernel/dma.c
@@ -1,7 +1,7 @@
 /*
  * DMA implementation for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/head.S b/arch/hexagon/kernel/head.S
index 8e6b819..d859402 100644
--- a/arch/hexagon/kernel/head.S
+++ b/arch/hexagon/kernel/head.S
@@ -1,7 +1,7 @@
 /*
  * Early kernel startup code for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/kernel/hexagon_ksyms.c b/arch/hexagon/kernel/hexagon_ksyms.c
index 7f18924..32b1379 100644
--- a/arch/hexagon/kernel/hexagon_ksyms.c
+++ b/arch/hexagon/kernel/hexagon_ksyms.c
@@ -1,7 +1,7 @@
 /*
  * Export of symbols defined in assembly files and/or libgcc.
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/init_task.c b/arch/hexagon/kernel/init_task.c
index 73283d3..b4068e3 100644
--- a/arch/hexagon/kernel/init_task.c
+++ b/arch/hexagon/kernel/init_task.c
@@ -1,7 +1,7 @@
 /*
  * Init task definition
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/irq_cpu.c b/arch/hexagon/kernel/irq_cpu.c
index d4416a1..4de9943 100644
--- a/arch/hexagon/kernel/irq_cpu.c
+++ b/arch/hexagon/kernel/irq_cpu.c
@@ -1,7 +1,7 @@
 /*
  * First-level interrupt controller model for Hexagon.
  *
- * Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011 The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/kgdb.c b/arch/hexagon/kernel/kgdb.c
index fe4aa1b..3446453 100644
--- a/arch/hexagon/kernel/kgdb.c
+++ b/arch/hexagon/kernel/kgdb.c
@@ -1,7 +1,7 @@
 /*
  * arch/hexagon/kernel/kgdb.c - Hexagon KGDB Support
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/module.c b/arch/hexagon/kernel/module.c
index 61a76ba..477d07a 100644
--- a/arch/hexagon/kernel/module.c
+++ b/arch/hexagon/kernel/module.c
@@ -1,7 +1,7 @@
 /*
  * Kernel module loader for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c
index ff02821..2bc16a5 100644
--- a/arch/hexagon/kernel/process.c
+++ b/arch/hexagon/kernel/process.c
@@ -1,7 +1,7 @@
 /*
  * Process creation support for Hexagon
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c
index 96c3b2c..670b1b0 100644
--- a/arch/hexagon/kernel/ptrace.c
+++ b/arch/hexagon/kernel/ptrace.c
@@ -1,7 +1,7 @@
 /*
  * Ptrace support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/reset.c b/arch/hexagon/kernel/reset.c
index 4d72fc5..6aeabc9 100644
--- a/arch/hexagon/kernel/reset.c
+++ b/arch/hexagon/kernel/reset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c
index 1202f78..94a3878 100644
--- a/arch/hexagon/kernel/setup.c
+++ b/arch/hexagon/kernel/setup.c
@@ -1,7 +1,7 @@
 /*
  * Arch related setup for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c
index ecbab34..3d1017d 100644
--- a/arch/hexagon/kernel/signal.c
+++ b/arch/hexagon/kernel/signal.c
@@ -1,7 +1,7 @@
 /*
  * Signal support for Hexagon processor
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c
index 1298141..6fa1dc2 100644
--- a/arch/hexagon/kernel/smp.c
+++ b/arch/hexagon/kernel/smp.c
@@ -1,7 +1,7 @@
 /*
  * SMP support for Hexagon
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/stacktrace.c b/arch/hexagon/kernel/stacktrace.c
index 11c597b..f94918b 100644
--- a/arch/hexagon/kernel/stacktrace.c
+++ b/arch/hexagon/kernel/stacktrace.c
@@ -1,7 +1,7 @@
 /*
  * Stacktrace support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/syscall.c b/arch/hexagon/kernel/syscall.c
index 620dd18..2fd0764 100644
--- a/arch/hexagon/kernel/syscall.c
+++ b/arch/hexagon/kernel/syscall.c
@@ -1,7 +1,7 @@
 /*
  * Hexagon system calls
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/syscalltab.c b/arch/hexagon/kernel/syscalltab.c
index c550f41..7024b1d 100644
--- a/arch/hexagon/kernel/syscalltab.c
+++ b/arch/hexagon/kernel/syscalltab.c
@@ -1,7 +1,7 @@
 /*
  * System call table for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/time.c b/arch/hexagon/kernel/time.c
index 5d9b33b..6f80a4f 100644
--- a/arch/hexagon/kernel/time.c
+++ b/arch/hexagon/kernel/time.c
@@ -1,7 +1,7 @@
 /*
  * Time related functions for Hexagon architecture
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/topology.c b/arch/hexagon/kernel/topology.c
index ba44751..352f27e 100644
--- a/arch/hexagon/kernel/topology.c
+++ b/arch/hexagon/kernel/topology.c
@@ -1,7 +1,7 @@
 /*
  * CPU topology for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/trampoline.S b/arch/hexagon/kernel/trampoline.S
index 06c36c0..18110a9 100644
--- a/arch/hexagon/kernel/trampoline.S
+++ b/arch/hexagon/kernel/trampoline.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c
index f08857d..a41eeb8 100644
--- a/arch/hexagon/kernel/traps.c
+++ b/arch/hexagon/kernel/traps.c
@@ -1,7 +1,7 @@
 /*
  * Kernel traps/events for Hexagon processor
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/vdso.c b/arch/hexagon/kernel/vdso.c
index 5d39f42..0bf5a87 100644
--- a/arch/hexagon/kernel/vdso.c
+++ b/arch/hexagon/kernel/vdso.c
@@ -1,7 +1,7 @@
 /*
  * vDSO implementation for Hexagon
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S
index 5b99066..cd71673 100644
--- a/arch/hexagon/kernel/vm_entry.S
+++ b/arch/hexagon/kernel/vm_entry.S
@@ -1,7 +1,7 @@
 /*
  * Event entry/exit for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/vm_events.c b/arch/hexagon/kernel/vm_events.c
index 591fc1b..9b5a4a2 100644
--- a/arch/hexagon/kernel/vm_events.c
+++ b/arch/hexagon/kernel/vm_events.c
@@ -1,7 +1,7 @@
 /*
  * Mostly IRQ support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/vm_init_segtable.S b/arch/hexagon/kernel/vm_init_segtable.S
index aebb35b..80967f2 100644
--- a/arch/hexagon/kernel/vm_init_segtable.S
+++ b/arch/hexagon/kernel/vm_init_segtable.S
@@ -1,7 +1,7 @@
 /*
  * Initial page table for Linux kernel under Hexagon VM,
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/vm_ops.S b/arch/hexagon/kernel/vm_ops.S
index 24d7fca..9fb77b3 100644
--- a/arch/hexagon/kernel/vm_ops.S
+++ b/arch/hexagon/kernel/vm_ops.S
@@ -1,7 +1,7 @@
 /*
  * Hexagon VM instruction support
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/vm_switch.S b/arch/hexagon/kernel/vm_switch.S
index 0decf2f..62c6df9 100644
--- a/arch/hexagon/kernel/vm_switch.S
+++ b/arch/hexagon/kernel/vm_switch.S
@@ -1,7 +1,7 @@
 /*
  * Context switch support for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/vm_vectors.S b/arch/hexagon/kernel/vm_vectors.S
index 97a4b50..620f42c 100644
--- a/arch/hexagon/kernel/vm_vectors.S
+++ b/arch/hexagon/kernel/vm_vectors.S
@@ -1,7 +1,7 @@
 /*
  * Event jump tables
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S
index 071d3c3..14e793f 100644
--- a/arch/hexagon/kernel/vmlinux.lds.S
+++ b/arch/hexagon/kernel/vmlinux.lds.S
@@ -1,7 +1,7 @@
 /*
  * Linker script for Hexagon kernel
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/lib/checksum.c b/arch/hexagon/lib/checksum.c
index 9300552..8169f78 100644
--- a/arch/hexagon/lib/checksum.c
+++ b/arch/hexagon/lib/checksum.c
@@ -1,7 +1,7 @@
 /*
  * Checksum functions for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/lib/io.c b/arch/hexagon/lib/io.c
index 8ae47ba..885c962 100644
--- a/arch/hexagon/lib/io.c
+++ b/arch/hexagon/lib/io.c
@@ -1,7 +1,7 @@
 /*
  * I/O access functions for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/lib/memcpy.S b/arch/hexagon/lib/memcpy.S
index 2101c33..81c561c 100644
--- a/arch/hexagon/lib/memcpy.S
+++ b/arch/hexagon/lib/memcpy.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/arch/hexagon/lib/memset.S b/arch/hexagon/lib/memset.S
index 26d9614..1da2712 100644
--- a/arch/hexagon/lib/memset.S
+++ b/arch/hexagon/lib/memset.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011 The Linux Foundation. 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 and
diff --git a/arch/hexagon/mm/cache.c b/arch/hexagon/mm/cache.c
index c5cf6ee..fe14ccf 100644
--- a/arch/hexagon/mm/cache.c
+++ b/arch/hexagon/mm/cache.c
@@ -1,7 +1,7 @@
 /*
  * Cache management functions for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/mm/copy_from_user.S b/arch/hexagon/mm/copy_from_user.S
index 8eb1d4d..7fc94f3 100644
--- a/arch/hexagon/mm/copy_from_user.S
+++ b/arch/hexagon/mm/copy_from_user.S
@@ -1,7 +1,7 @@
 /*
  * User memory copy functions for kernel
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/mm/copy_to_user.S b/arch/hexagon/mm/copy_to_user.S
index cb9740e..0cfbcc0 100644
--- a/arch/hexagon/mm/copy_to_user.S
+++ b/arch/hexagon/mm/copy_to_user.S
@@ -1,7 +1,7 @@
 /*
  * User memory copying routines for the Hexagon Kernel
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/mm/copy_user_template.S b/arch/hexagon/mm/copy_user_template.S
index 08d7d7b..254d8cc 100644
--- a/arch/hexagon/mm/copy_user_template.S
+++ b/arch/hexagon/mm/copy_user_template.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/mm/init.c b/arch/hexagon/mm/init.c
index b57d741..69ffcfd 100644
--- a/arch/hexagon/mm/init.c
+++ b/arch/hexagon/mm/init.c
@@ -1,7 +1,7 @@
 /*
  * Memory subsystem initialization for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/mm/ioremap.c b/arch/hexagon/mm/ioremap.c
index 3a37bc3..5905fd5 100644
--- a/arch/hexagon/mm/ioremap.c
+++ b/arch/hexagon/mm/ioremap.c
@@ -1,7 +1,7 @@
 /*
  * I/O remap functions for Hexagon
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/mm/pgalloc.c b/arch/hexagon/mm/pgalloc.c
index b175e2d..19760a4 100644
--- a/arch/hexagon/mm/pgalloc.c
+++ b/arch/hexagon/mm/pgalloc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/mm/strnlen_user.S b/arch/hexagon/mm/strnlen_user.S
index 5c6a16c..0eecb7a 100644
--- a/arch/hexagon/mm/strnlen_user.S
+++ b/arch/hexagon/mm/strnlen_user.S
@@ -1,7 +1,7 @@
 /*
  * User string length functions for kernel
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/mm/uaccess.c b/arch/hexagon/mm/uaccess.c
index e748108..3412726 100644
--- a/arch/hexagon/mm/uaccess.c
+++ b/arch/hexagon/mm/uaccess.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c
index c10b76f..ed8bf67 100644
--- a/arch/hexagon/mm/vm_fault.c
+++ b/arch/hexagon/mm/vm_fault.c
@@ -1,7 +1,7 @@
 /*
  * Memory fault handling for Hexagon
  *
- * Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011 The Linux Foundation. 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 and
diff --git a/arch/hexagon/mm/vm_tlb.c b/arch/hexagon/mm/vm_tlb.c
index c6ff415..9647d00 100644
--- a/arch/hexagon/mm/vm_tlb.c
+++ b/arch/hexagon/mm/vm_tlb.c
@@ -1,7 +1,7 @@
 /*
  * Hexagon Virtual Machine TLB functions
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/block/blk-core.c b/block/blk-core.c
index 68d7158..fcb2a1b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -29,6 +29,7 @@
 #include <linux/fault-inject.h>
 #include <linux/list_sort.h>
 #include <linux/delay.h>
+#include <linux/ratelimit.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/block.h>
@@ -2141,9 +2142,11 @@
 			error_type = "I/O";
 			break;
 		}
-		printk(KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
-		       error_type, req->rq_disk ? req->rq_disk->disk_name : "?",
-		       (unsigned long long)blk_rq_pos(req));
+		printk_ratelimited(
+			KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
+			error_type,
+			req->rq_disk ? req->rq_disk->disk_name : "?",
+			(unsigned long long)blk_rq_pos(req));
 	}
 
 	blk_account_io_completion(req, nr_bytes);
diff --git a/block/test-iosched.c b/block/test-iosched.c
index 0a033dc..a7e5a24 100644
--- a/block/test-iosched.c
+++ b/block/test-iosched.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/base/genlock.c b/drivers/base/genlock.c
index f54d820..8b7259a 100644
--- a/drivers/base/genlock.c
+++ b/drivers/base/genlock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/base/sync.c b/drivers/base/sync.c
index 809d02b..a97a503 100644
--- a/drivers/base/sync.c
+++ b/drivers/base/sync.c
@@ -324,7 +324,6 @@
 
 		new_pt->fence = dst;
 		list_add(&new_pt->pt_list, &dst->pt_list_head);
-		sync_pt_activate(new_pt);
 	}
 
 	return 0;
@@ -356,7 +355,6 @@
 					new_pt->fence = dst;
 					list_replace(&dst_pt->pt_list,
 						     &new_pt->pt_list);
-					sync_pt_activate(new_pt);
 					sync_pt_free(dst_pt);
 				}
 				collapsed = true;
@@ -372,7 +370,6 @@
 
 			new_pt->fence = dst;
 			list_add(&new_pt->pt_list, &dst->pt_list_head);
-			sync_pt_activate(new_pt);
 		}
 	}
 
@@ -453,6 +450,7 @@
 				    struct sync_fence *a, struct sync_fence *b)
 {
 	struct sync_fence *fence;
+	struct list_head *pos;
 	int err;
 
 	fence = sync_fence_alloc(name);
@@ -467,6 +465,12 @@
 	if (err < 0)
 		goto err;
 
+	list_for_each(pos, &fence->pt_list_head) {
+		struct sync_pt *pt =
+			container_of(pos, struct sync_pt, pt_list);
+		sync_pt_activate(pt);
+	}
+
 	/*
 	 * signal the fence in case one of it's pts were activated before
 	 * they were activated
diff --git a/drivers/bluetooth/bluesleep.c b/drivers/bluetooth/bluesleep.c
index 0d11141..6dc9862 100644
--- a/drivers/bluetooth/bluesleep.c
+++ b/drivers/bluetooth/bluesleep.c
@@ -15,7 +15,7 @@
 
 
    Copyright (C) 2006-2007 - Motorola
-   Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
 
    Date         Author           Comment
    -----------  --------------   --------------------------------
diff --git a/drivers/bluetooth/bluetooth-power.c b/drivers/bluetooth/bluetooth-power.c
index 3bf49d1..718df02 100644
--- a/drivers/bluetooth/bluetooth-power.c
+++ b/drivers/bluetooth/bluetooth-power.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
index 50b3362..63c3dae 100644
--- a/drivers/bluetooth/hci_ath.c
+++ b/drivers/bluetooth/hci_ath.c
@@ -5,7 +5,7 @@
  *  power management protocol extension to H4 to support AR300x Bluetooth Chip.
  *
  *  Copyright (c) 2009-2010 Atheros Communications Inc.
- *  Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  *  Acknowledgements:
  *  This file is based on hci_h4.c, which was written
diff --git a/drivers/bluetooth/hci_ibs.c b/drivers/bluetooth/hci_ibs.c
index 6253605..e6fdc1f 100644
--- a/drivers/bluetooth/hci_ibs.c
+++ b/drivers/bluetooth/hci_ibs.c
@@ -5,7 +5,7 @@
  *  protocol extension to H4.
  *
  *  Copyright (C) 2007 Texas Instruments, Inc.
- *  Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2010, 2012 The Linux Foundation. All rights reserved.
  *
  *  Acknowledgements:
  *  This file is based on hci_ll.c, which was...
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 5c04693..81f5d32 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -4,7 +4,7 @@
  *
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (c) 2000-2001, 2010-2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2000-2001, 2010-2012, The Linux Foundation. All rights reserved.
  *
  *
  *  This program is free software; you can redistribute it and/or modify
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 9b60bda..90e7263 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -2,7 +2,7 @@
  *  HCI_SMD (HCI Shared Memory Driver) is Qualcomm's Shared memory driver
  *  for the BT HCI protocol.
  *
- *  Copyright (c) 2000-2001, 2011-2012 Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2000-2001, 2011-2012 The Linux Foundation. All rights reserved.
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
  *
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index 123fc24..b9efe30 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -4,7 +4,7 @@
  *
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (c) 2000-2001, 2010, 2012 Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2000-2001, 2010, 2012 The Linux Foundation. All rights reserved.
  *
  *
  *  This program is free software; you can redistribute it and/or modify
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 822da91..8e68acd 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -11,8 +11,110 @@
  * GNU General Public License for more details.
  *
  */
+#include "adsprpc_shared.h"
+
+#ifdef __KERNEL__
+
+#include <linux/slab.h>
+#include <linux/completion.h>
+#include <linux/pagemap.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/hash.h>
+#include <linux/msm_ion.h>
+#include <mach/msm_smd.h>
+#include <mach/ion.h>
 #include <linux/scatterlist.h>
-#include "adsprpc.h"
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/device.h>
+
+#ifndef ION_ADSPRPC_HEAP_ID
+#define ION_ADSPRPC_HEAP_ID ION_AUDIO_HEAP_ID
+#endif /*ION_ADSPRPC_HEAP_ID*/
+
+#define RPC_TIMEOUT	(5 * HZ)
+#define RPC_HASH_BITS	5
+#define RPC_HASH_SZ	(1 << RPC_HASH_BITS)
+#define BALIGN		32
+
+#define LOCK_MMAP(kernel)\
+		do {\
+			if (!kernel)\
+				down_read(&current->mm->mmap_sem);\
+		} while (0)
+
+#define UNLOCK_MMAP(kernel)\
+		do {\
+			if (!kernel)\
+				up_read(&current->mm->mmap_sem);\
+		} while (0)
+
+
+static inline uint32_t buf_page_start(void *buf)
+{
+	uint32_t start = (uint32_t) buf & PAGE_MASK;
+	return start;
+}
+
+static inline uint32_t buf_page_offset(void *buf)
+{
+	uint32_t offset = (uint32_t) buf & (PAGE_SIZE - 1);
+	return offset;
+}
+
+static inline int buf_num_pages(void *buf, int len)
+{
+	uint32_t start = buf_page_start(buf) >> PAGE_SHIFT;
+	uint32_t end = (((uint32_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
+	int nPages = end - start + 1;
+	return nPages;
+}
+
+static inline uint32_t buf_page_size(uint32_t size)
+{
+	uint32_t sz = (size + (PAGE_SIZE - 1)) & PAGE_MASK;
+	return sz > PAGE_SIZE ? sz : PAGE_SIZE;
+}
+
+static inline int buf_get_pages(void *addr, int sz, int nr_pages, int access,
+				  struct smq_phy_page *pages, int nr_elems)
+{
+	struct vm_area_struct *vma;
+	uint32_t start = buf_page_start(addr);
+	uint32_t len = nr_pages << PAGE_SHIFT;
+	unsigned long pfn;
+	int n = -1, err = 0;
+
+	VERIFY(err, 0 != access_ok(access ? VERIFY_WRITE : VERIFY_READ,
+			      (void __user *)start, len));
+	if (err)
+		goto bail;
+	VERIFY(err, 0 != (vma = find_vma(current->mm, start)));
+	if (err)
+		goto bail;
+	VERIFY(err, ((uint32_t)addr + sz) <= vma->vm_end);
+	if (err)
+		goto bail;
+	n = 0;
+	VERIFY(err, 0 == follow_pfn(vma, start, &pfn));
+	if (err)
+		goto bail;
+	VERIFY(err, nr_elems > 0);
+	if (err)
+		goto bail;
+	pages->addr = __pfn_to_phys(pfn);
+	pages->size = len;
+	n++;
+ bail:
+	return n;
+}
+
+#endif /*__KERNEL__*/
 
 struct smq_invoke_ctx {
 	struct completion work;
@@ -32,6 +134,8 @@
 	struct completion work;
 	struct ion_client *iclient;
 	struct cdev cdev;
+	struct class *class;
+	struct device *dev;
 	dev_t dev_no;
 	spinlock_t wrlock;
 	spinlock_t hlock;
@@ -485,9 +589,9 @@
 static void free_dev(struct fastrpc_device *dev)
 {
 	if (dev) {
-		module_put(THIS_MODULE);
 		free_mem(&dev->buf);
 		kfree(dev);
+		module_put(THIS_MODULE);
 	}
 }
 
@@ -609,8 +713,10 @@
 		wait_for_completion(&ctx->work);
 	}
 	context_free(ctx);
+
 	for (i = 0, b = abufs; i < nbufs; ++i, ++b)
 		free_mem(b);
+
 	kfree(abufs);
 	if (dev) {
 		add_dev(me, dev);
@@ -746,12 +852,16 @@
 	return err;
 }
 
+#ifdef __KERNEL__
+
 static const struct file_operations fops = {
 	.open = fastrpc_device_open,
 	.release = fastrpc_device_release,
 	.unlocked_ioctl = fastrpc_device_ioctl,
 };
 
+#endif /*__KERNEL__*/
+
 static int __init fastrpc_device_init(void)
 {
 	struct fastrpc_apps *me = &gfa;
@@ -768,11 +878,24 @@
 	VERIFY(err, 0 == cdev_add(&me->cdev, MKDEV(MAJOR(me->dev_no), 0), 1));
 	if (err)
 		goto bail;
-	pr_info("'mknod /dev/%s c %d 0'\n", DEVICE_NAME, MAJOR(me->dev_no));
+	me->class = class_create(THIS_MODULE, "chardrv");
+	VERIFY(err, !IS_ERR(me->class));
+	if (err)
+		goto bail;
+	me->dev = device_create(me->class, NULL, MKDEV(MAJOR(me->dev_no), 0),
+				NULL, DEVICE_NAME);
+	VERIFY(err, !IS_ERR(me->dev));
+	if (err)
+		goto bail;
+	pr_info("'created /dev/%s c %d 0'\n", DEVICE_NAME, MAJOR(me->dev_no));
  bail:
 	if (err) {
 		if (me->dev_no)
 			unregister_chrdev_region(me->dev_no, 1);
+		if (me->class)
+			class_destroy(me->class);
+		if (me->cdev.owner)
+			cdev_del(&me->cdev);
 		fastrpc_deinit();
 	}
 	return err;
@@ -783,6 +906,8 @@
 	struct fastrpc_apps *me = &gfa;
 
 	fastrpc_deinit();
+	device_destroy(me->class, MKDEV(MAJOR(me->dev_no), 0));
+	class_destroy(me->class);
 	cdev_del(&me->cdev);
 	unregister_chrdev_region(me->dev_no, 1);
 }
diff --git a/drivers/char/adsprpc.h b/drivers/char/adsprpc.h
deleted file mode 100644
index 3f1b4a7..0000000
--- a/drivers/char/adsprpc.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2012, The Linux Foundation. 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 and
- * only 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.
- *
- */
-#ifndef ADSPRPC_H
-#define ADSPRPC_H
-
-#include <linux/slab.h>
-#include <linux/completion.h>
-#include <linux/pagemap.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/cdev.h>
-#include <linux/list.h>
-#include <linux/hash.h>
-#include <linux/msm_ion.h>
-#include <mach/msm_smd.h>
-#include <mach/ion.h>
-#include "adsprpc_shared.h"
-
-#ifndef ION_ADSPRPC_HEAP_ID
-#define ION_ADSPRPC_HEAP_ID ION_AUDIO_HEAP_ID
-#endif
-
-#define RPC_TIMEOUT	(5 * HZ)
-#define RPC_HASH_BITS	5
-#define RPC_HASH_SZ	(1 << RPC_HASH_BITS)
-#define BALIGN		32
-
-#define LOCK_MMAP(kernel)\
-		do {\
-			if (!kernel)\
-				down_read(&current->mm->mmap_sem);\
-		} while (0)
-
-#define UNLOCK_MMAP(kernel)\
-		do {\
-			if (!kernel)\
-				up_read(&current->mm->mmap_sem);\
-		} while (0)
-
-
-static inline uint32_t buf_page_start(void *buf)
-{
-	uint32_t start = (uint32_t) buf & PAGE_MASK;
-	return start;
-}
-
-static inline uint32_t buf_page_offset(void *buf)
-{
-	uint32_t offset = (uint32_t) buf & (PAGE_SIZE - 1);
-	return offset;
-}
-
-static inline int buf_num_pages(void *buf, int len)
-{
-	uint32_t start = buf_page_start(buf) >> PAGE_SHIFT;
-	uint32_t end = (((uint32_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
-	int nPages = end - start + 1;
-	return nPages;
-}
-
-static inline uint32_t buf_page_size(uint32_t size)
-{
-	uint32_t sz = (size + (PAGE_SIZE - 1)) & PAGE_MASK;
-	return sz > PAGE_SIZE ? sz : PAGE_SIZE;
-}
-
-static inline int buf_get_pages(void *addr, int sz, int nr_pages, int access,
-				  struct smq_phy_page *pages, int nr_elems)
-{
-	struct vm_area_struct *vma;
-	uint32_t start = buf_page_start(addr);
-	uint32_t len = nr_pages << PAGE_SHIFT;
-	unsigned long pfn;
-	int n = -1, err = 0;
-
-	VERIFY(err, 0 != access_ok(access ? VERIFY_WRITE : VERIFY_READ,
-			      (void __user *)start, len));
-	if (err)
-		goto bail;
-	VERIFY(err, 0 != (vma = find_vma(current->mm, start)));
-	if (err)
-		goto bail;
-	VERIFY(err, ((uint32_t)addr + sz) <= vma->vm_end);
-	if (err)
-		goto bail;
-	n = 0;
-	VERIFY(err, 0 == follow_pfn(vma, start, &pfn));
-	if (err)
-		goto bail;
-	VERIFY(err, nr_elems > 0);
-	if (err)
-		goto bail;
-	pages->addr = __pfn_to_phys(pfn);
-	pages->size = len;
-	n++;
- bail:
-	return n;
-}
-
-#endif
diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h
index dc6ab6f..0354563 100644
--- a/drivers/char/adsprpc_shared.h
+++ b/drivers/char/adsprpc_shared.h
@@ -14,6 +14,12 @@
 #ifndef ADSPRPC_SHARED_H
 #define ADSPRPC_SHARED_H
 
+#ifdef __KERNEL__
+#include <linux/types.h>
+#endif /*__KERNEL__*/
+
+
+
 #define FASTRPC_IOCTL_INVOKE _IOWR('R', 1, struct fastrpc_ioctl_invoke)
 #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
 #define DEVICE_NAME      "adsprpc-smd"
diff --git a/drivers/char/csdio.c b/drivers/char/csdio.c
index ca7e986..85306d3 100644
--- a/drivers/char/csdio.c
+++ b/drivers/char/csdio.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. 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 and
@@ -1068,7 +1068,7 @@
 module_init(csdio_init);
 module_exit(csdio_exit);
 
-MODULE_AUTHOR("Code Aurora Forum");
+MODULE_AUTHOR("The Linux Foundation");
 MODULE_DESCRIPTION("CSDIO device driver version " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index d4b1856..6d28042 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -37,6 +37,7 @@
 unsigned char dci_cumulative_event_mask[DCI_EVENT_MASK_SIZE];
 struct mutex dci_log_mask_mutex;
 struct mutex dci_event_mask_mutex;
+struct mutex dci_health_mutex;
 
 #define DCI_CHK_CAPACITY(entry, new_data_len)				\
 ((entry->data_len + new_data_len > entry->total_capacity) ? 1 : 0)	\
@@ -107,91 +108,102 @@
 			break;
 		}
 	}
-	if (index == -1)
+	if (index == -1) {
 		pr_alert("diag: No matching PID for DCI data\n");
+		return;
+	}
 	/* Using PID of client process, find client buffer */
-	for (i = 0; i < MAX_DCI_CLIENTS; i++) {
-		if (driver->dci_client_tbl[i].client != NULL) {
-			if (curr_client_pid ==
-				driver->dci_client_tbl[i].client->tgid) {
-				/* copy pkt rsp in client buf */
-				entry = &(driver->dci_client_tbl[i]);
-				if (DCI_CHK_CAPACITY(entry, 8+write_len)) {
-					pr_alert("diag: create capacity for pkt rsp\n");
-					entry->total_capacity += 8+write_len;
-					temp_buf = krealloc(entry->dci_data,
-					entry->total_capacity, GFP_KERNEL);
-					if (!temp_buf) {
-						pr_err("diag: DCI realloc failed\n");
-						break;
-					} else {
-						entry->dci_data = temp_buf;
-					}
-				}
-				*(int *)(entry->dci_data+entry->data_len) =
-							DCI_PKT_RSP_TYPE;
-				entry->data_len += 4;
-				*(int *)(entry->dci_data+entry->data_len)
-								= write_len;
-				entry->data_len += 4;
-				memcpy(entry->dci_data+entry->data_len,
-					buf+4+cmd_code_len, write_len);
-				entry->data_len += write_len;
-				/* delete immediate response entry */
-				if (driver->smd_dci[MODEM_DATA].
-					buf_in_1[8+cmd_code_len] != 0x80)
-					driver->req_tracking_tbl[index].pid = 0;
-				break;
+	i = diag_dci_find_client_index(curr_client_pid);
+	if (i != DCI_CLIENT_INDEX_INVALID) {
+		/* copy pkt rsp in client buf */
+		entry = &(driver->dci_client_tbl[i]);
+		if (DCI_CHK_CAPACITY(entry, 8+write_len)) {
+			pr_alert("diag: create capacity for pkt rsp\n");
+			entry->total_capacity += 8+write_len;
+			temp_buf = krealloc(entry->dci_data,
+			entry->total_capacity, GFP_KERNEL);
+			if (!temp_buf) {
+				pr_err("diag: DCI realloc failed\n");
+				return;
+			} else {
+				entry->dci_data = temp_buf;
 			}
 		}
+		*(int *)(entry->dci_data+entry->data_len) =
+					DCI_PKT_RSP_TYPE;
+		entry->data_len += 4;
+		*(int *)(entry->dci_data+entry->data_len)
+						= write_len;
+		entry->data_len += 4;
+		memcpy(entry->dci_data+entry->data_len,
+			buf+4+cmd_code_len, write_len);
+		entry->data_len += write_len;
+		/* delete immediate response entry */
+		if (driver->smd_dci[MODEM_DATA].
+			buf_in_1[8+cmd_code_len] != 0x80)
+			driver->req_tracking_tbl[index].pid = 0;
 	}
 }
 
 void extract_dci_events(unsigned char *buf)
 {
-	uint16_t event_id, event_id_packet;
-	uint8_t *event_mask_ptr, byte_mask, payload_len;
-	uint8_t event_data[MAX_EVENT_SIZE], timestamp[8];
-	int i, byte_index, bit_index, length, temp_len;
-	int total_event_len, payload_len_field, timestamp_len;
+	uint16_t event_id, event_id_packet, length, temp_len;
+	uint8_t *event_mask_ptr, byte_mask, payload_len, payload_len_field;
+	uint8_t timestamp[8], bit_index, timestamp_len;
+	uint8_t event_data[MAX_EVENT_SIZE];
+	unsigned int byte_index, total_event_len, i;
 	struct diag_dci_client_tbl *entry;
 
-	length =  *(uint16_t *)(buf+1); /* total length of event series */
+	length =  *(uint16_t *)(buf + 1); /* total length of event series */
+	if (length == 0) {
+		pr_err("diag: Incoming dci event length is invalid\n");
+		return;
+	}
 	temp_len = 0;
 	buf = buf + 3; /* start of event series */
-	while (temp_len < length-1) {
-		*event_data = EVENT_CMD_CODE;
-		event_id_packet = *(uint16_t *)(buf+temp_len);
+	while (temp_len < (length - 1)) {
+		event_id_packet = *(uint16_t *)(buf + temp_len);
 		event_id = event_id_packet & 0x0FFF; /* extract 12 bits */
 		if (event_id_packet & 0x8000) {
 			timestamp_len = 2;
+			memset(timestamp, 0, 8);
 		} else {
 			timestamp_len = 8;
-			memcpy(timestamp, buf+temp_len+2, 8);
+			memcpy(timestamp, buf + temp_len + 2, timestamp_len);
 		}
+		/* 13th and 14th bit represent the payload length */
 		if (((event_id_packet & 0x6000) >> 13) == 3) {
 			payload_len_field = 1;
 			payload_len = *(uint8_t *)
-					(buf+temp_len+2+timestamp_len);
-			memcpy(event_data+13, buf+temp_len+2+timestamp_len, 1);
-			memcpy(event_data+14, buf+temp_len+2+timestamp_len+1,
-								 payload_len);
+					(buf + temp_len + 2 + timestamp_len);
+			if (payload_len < (MAX_EVENT_SIZE - 13)) {
+				/* copy the payload length and the payload */
+				memcpy(event_data + 12, buf + temp_len + 2 +
+							timestamp_len, 1);
+				memcpy(event_data + 13, buf + temp_len + 2 +
+					timestamp_len + 1, payload_len);
+			} else {
+				pr_err("diag: event > %d, payload_len = %d\n",
+					(MAX_EVENT_SIZE - 13), payload_len);
+				return;
+			}
 		} else {
 			payload_len_field = 0;
 			payload_len = (event_id_packet & 0x6000) >> 13;
-			if (payload_len < MAX_EVENT_SIZE)
-				memcpy(event_data+13,
-				 buf+temp_len+2+timestamp_len, payload_len);
-			else
-				pr_alert("diag: event > %d\n", MAX_EVENT_SIZE);
+			/* copy the payload */
+			memcpy(event_data + 12, buf + temp_len + 2 +
+						timestamp_len, payload_len);
 		}
 		/* 2 bytes for the event id & timestamp len is hard coded to 8,
 		   as individual events have full timestamp */
-		*(uint16_t *)(event_data+1) = 10+payload_len_field+payload_len;
-		*(uint16_t *)(event_data+3) = event_id_packet & 0x7FFF;
-		memcpy(event_data+5, timestamp, 8);
-		total_event_len = 3 + 10 + payload_len_field + payload_len;
-		byte_index = event_id/8;
+		*(uint16_t *)(event_data) = 10 +
+					payload_len_field + payload_len;
+		*(uint16_t *)(event_data + 2) = event_id_packet & 0x7FFF;
+		memcpy(event_data + 4, timestamp, 8);
+		/* 2 bytes for the event length field which is added to
+		   the event data */
+		total_event_len = 2 + 10 + payload_len_field + payload_len;
+		byte_index = event_id / 8;
 		bit_index = event_id % 8;
 		byte_mask = 0x1 << bit_index;
 		/* parse through event mask tbl of each client and check mask */
@@ -200,23 +212,29 @@
 				entry = &(driver->dci_client_tbl[i]);
 				event_mask_ptr = entry->dci_event_mask +
 								 byte_index;
+				mutex_lock(&dci_health_mutex);
 				if (*event_mask_ptr & byte_mask) {
 					/* copy to client buffer */
 					if (DCI_CHK_CAPACITY(entry,
 							 4 + total_event_len)) {
-						pr_err("diag:DCI event drop\n");
+						pr_err("diag: DCI event drop\n");
 						driver->dci_client_tbl[i].
 							dropped_events++;
-						return;
+						mutex_unlock(
+							&dci_health_mutex);
+						break;
 					}
 					driver->dci_client_tbl[i].
 							received_events++;
 					*(int *)(entry->dci_data+
 					entry->data_len) = DCI_EVENT_TYPE;
-					memcpy(entry->dci_data+
-				entry->data_len+4, event_data, total_event_len);
+					/* 4 bytes for DCI_EVENT_TYPE */
+					memcpy(entry->dci_data +
+						entry->data_len + 4, event_data
+						, total_event_len);
 					entry->data_len += 4 + total_event_len;
 				}
+				mutex_unlock(&dci_health_mutex);
 			}
 		}
 		temp_len += 2 + timestamp_len + payload_len_field + payload_len;
@@ -227,54 +245,52 @@
 {
 	uint16_t log_code, item_num;
 	uint8_t equip_id, *log_mask_ptr, byte_mask;
-	int i, byte_index, found = 0;
+	unsigned int i, byte_index, byte_offset = 0;
 	struct diag_dci_client_tbl *entry;
 
-	log_code = *(uint16_t *)(buf+6);
+	log_code = *(uint16_t *)(buf + 6);
 	equip_id = LOG_GET_EQUIP_ID(log_code);
 	item_num = LOG_GET_ITEM_NUM(log_code);
 	byte_index = item_num/8 + 2;
 	byte_mask = 0x01 << (item_num % 8);
 
+	byte_offset = (equip_id * 514) + byte_index;
+	if (byte_offset >=  DCI_LOG_MASK_SIZE) {
+		pr_err("diag: Invalid byte_offset %d in dci log\n",
+							byte_offset);
+		return;
+	}
+
 	/* parse through log mask table of each client and check mask */
 	for (i = 0; i < MAX_DCI_CLIENTS; i++) {
 		if (driver->dci_client_tbl[i].client) {
 			entry = &(driver->dci_client_tbl[i]);
 			log_mask_ptr = entry->dci_log_mask;
-			found = 0;
-			while (log_mask_ptr) {
-				if (*log_mask_ptr == equip_id) {
-					found = 1;
-					pr_debug("diag: find equip id = %x at %p\n",
-					equip_id, log_mask_ptr);
-					break;
-				} else {
-					pr_debug("diag: did not find equip id = %x at %p\n",
-						 equip_id, log_mask_ptr);
-					log_mask_ptr += 514;
-				}
-			}
-			if (!found)
-				pr_err("diag: dci equip id not found\n");
-			log_mask_ptr = log_mask_ptr + byte_index;
+			if (!log_mask_ptr)
+				return;
+			log_mask_ptr = log_mask_ptr + byte_offset;
+			mutex_lock(&dci_health_mutex);
 			if (*log_mask_ptr & byte_mask) {
 				pr_debug("\t log code %x needed by client %d",
 					 log_code, entry->client->tgid);
 				/* copy to client buffer */
 				if (DCI_CHK_CAPACITY(entry,
-						 4 + *(uint16_t *)(buf+2))) {
-						pr_err("diag:DCI log drop\n");
+						 4 + *(uint16_t *)(buf + 2))) {
+						pr_err("diag: DCI log drop\n");
 						driver->dci_client_tbl[i].
 								dropped_logs++;
+						mutex_unlock(
+							&dci_health_mutex);
 						return;
 				}
 				driver->dci_client_tbl[i].received_logs++;
 				*(int *)(entry->dci_data+entry->data_len) =
 								DCI_LOG_TYPE;
-				memcpy(entry->dci_data+entry->data_len+4, buf+4,
-						 *(uint16_t *)(buf+2));
-				entry->data_len += 4 + *(uint16_t *)(buf+2);
+				memcpy(entry->dci_data + entry->data_len + 4,
+					    buf + 4, *(uint16_t *)(buf + 2));
+				entry->data_len += 4 + *(uint16_t *)(buf + 2);
 			}
+			mutex_unlock(&dci_health_mutex);
 		}
 	}
 }
@@ -352,7 +368,6 @@
 			if (stat)
 				pr_err("diag: Err sending dci signal to client, signal data: 0x%x, stat: %d\n",
 				info.si_int, stat);
-			break;
 		}
 	} /* end of loop for all DCI clients */
 }
@@ -385,6 +400,10 @@
 
 	/* remove UID from user space pkt before sending to peripheral */
 	buf = buf + 4;
+	if (len > APPS_BUF_SIZE - 10) {
+		pr_err("diag: dci: buffer overwrite possible since payload bigger than buf size\n");
+		return -EIO;
+	}
 	len = len - 4;
 	mutex_lock(&driver->dci_mutex);
 	/* prepare DCI packet */
@@ -396,7 +415,6 @@
 		driver->req_tracking_tbl[index].tag;
 	for (i = 0; i < len; i++)
 		driver->apps_dci_buf[i+9] = *(buf+i);
-
 	driver->apps_dci_buf[9+len] = CONTROL_CHAR; /* end */
 
 	for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++) {
@@ -448,12 +466,12 @@
 {
 	unsigned char *temp = buf;
 	uint16_t subsys_cmd_code, log_code, item_num;
-	int subsys_id, cmd_code, i, ret = -1, index = -1, found = 0;
+	int subsys_id, cmd_code, ret = -1, index = -1, found = 0, read_len = 0;
 	struct diag_master_table entry;
-	int count, set_mask, num_codes, byte_index, bit_index, event_id;
+	int count, set_mask, num_codes, bit_index, event_id, offset = 0, i;
+	unsigned int byte_index;
 	uint8_t equip_id, *log_mask_ptr, *head_log_mask_ptr, byte_mask;
 	uint8_t *event_mask_ptr;
-	int offset = 0;
 
 	if (!driver->smd_dci[MODEM_DATA].ch) {
 		pr_err("diag: DCI smd channel for peripheral %d not valid for dci updates\n",
@@ -514,34 +532,37 @@
 		}
 	} else if (*(int *)temp == DCI_LOG_TYPE) {
 		/* find client id and table */
-		for (i = 0; i < MAX_DCI_CLIENTS; i++) {
-			if (driver->dci_client_tbl[i].client != NULL) {
-				if (driver->dci_client_tbl[i].client->tgid ==
-							current->tgid) {
-					found = 1;
-					break;
-				}
-			}
-		}
-		if (!found) {
+		i = diag_dci_find_client_index(current->tgid);
+		if (i == DCI_CLIENT_INDEX_INVALID) {
 			pr_err("diag: dci client not registered/found\n");
 			return ret;
 		}
 		/* Extract each log code and put in client table */
 		temp += 4;
+		read_len += 4;
 		set_mask = *(int *)temp;
 		temp += 4;
+		read_len += 4;
 		num_codes = *(int *)temp;
 		temp += 4;
+		read_len += 4;
 
 		head_log_mask_ptr = driver->dci_client_tbl[i].dci_log_mask;
 		pr_debug("diag: head of dci log mask %p\n", head_log_mask_ptr);
 		count = 0; /* iterator for extracting log codes */
 		while (count < num_codes) {
+			if (read_len >= USER_SPACE_DATA) {
+				pr_err("diag: dci: Log type, possible buffer overflow\n");
+				return -EIO;
+			}
 			log_code = *(uint16_t *)temp;
 			equip_id = LOG_GET_EQUIP_ID(log_code);
 			item_num = LOG_GET_ITEM_NUM(log_code);
 			byte_index = item_num/8 + 2;
+			if (byte_index >= (DCI_MAX_ITEMS_PER_LOG_CODE+2)) {
+				pr_err("diag: dci: Log type, invalid byte index\n");
+				return ret;
+			}
 			byte_mask = 0x01 << (item_num % 8);
 			/*
 			 * Parse through log mask table and find
@@ -550,7 +571,7 @@
 			log_mask_ptr = head_log_mask_ptr;
 			found = 0;
 			offset = 0;
-			while (log_mask_ptr) {
+			while (log_mask_ptr && (offset < DCI_LOG_MASK_SIZE)) {
 				if (*log_mask_ptr == equip_id) {
 					found = 1;
 					pr_debug("diag: find equip id = %x at %p\n",
@@ -578,6 +599,7 @@
 				offset, byte_index,
 				byte_mask);
 			temp += 2;
+			read_len += 2;
 			count++;
 			ret = DIAG_DCI_NO_ERROR;
 		}
@@ -585,32 +607,35 @@
 		ret = diag_send_dci_log_mask(driver->smd_cntl[MODEM_DATA].ch);
 	} else if (*(int *)temp == DCI_EVENT_TYPE) {
 		/* find client id and table */
-		for (i = 0; i < MAX_DCI_CLIENTS; i++) {
-			if (driver->dci_client_tbl[i].client != NULL) {
-				if (driver->dci_client_tbl[i].client->tgid ==
-							current->tgid) {
-					found = 1;
-					break;
-				}
-			}
-		}
-		if (!found) {
+		i = diag_dci_find_client_index(current->tgid);
+		if (i == DCI_CLIENT_INDEX_INVALID) {
 			pr_err("diag: dci client not registered/found\n");
 			return ret;
 		}
 		/* Extract each log code and put in client table */
 		temp += 4;
+		read_len += 4;
 		set_mask = *(int *)temp;
 		temp += 4;
+		read_len += 4;
 		num_codes = *(int *)temp;
 		temp += 4;
+		read_len += 4;
 
 		event_mask_ptr = driver->dci_client_tbl[i].dci_event_mask;
 		pr_debug("diag: head of dci event mask %p\n", event_mask_ptr);
 		count = 0; /* iterator for extracting log codes */
 		while (count < num_codes) {
+			if (read_len >= USER_SPACE_DATA) {
+				pr_err("diag: dci: Event type, possible buffer overflow\n");
+				return -EIO;
+			}
 			event_id = *(int *)temp;
 			byte_index = event_id/8;
+			if (byte_index >= DCI_EVENT_MASK_SIZE) {
+				pr_err("diag: dci: Event type, invalid byte index\n");
+				return ret;
+			}
 			bit_index = event_id % 8;
 			byte_mask = 0x1 << bit_index;
 			/*
@@ -624,6 +649,7 @@
 			/* add to cumulative mask */
 			update_dci_cumulative_event_mask(byte_index, byte_mask);
 			temp += sizeof(int);
+			read_len += sizeof(int);
 			count++;
 			ret = DIAG_DCI_NO_ERROR;
 		}
@@ -635,6 +661,22 @@
 	return ret;
 }
 
+int diag_dci_find_client_index(int client_id)
+{
+	int i, ret = DCI_CLIENT_INDEX_INVALID;
+
+	for (i = 0; i < MAX_DCI_CLIENTS; i++) {
+		if (driver->dci_client_tbl[i].client != NULL) {
+			if (driver->dci_client_tbl[i].client->tgid ==
+					client_id) {
+				ret = i;
+				break;
+			}
+		}
+	}
+	return ret;
+}
+
 void update_dci_cumulative_event_mask(int offset, uint8_t byte_mask)
 {
 	int i;
@@ -661,6 +703,69 @@
 	mutex_unlock(&dci_event_mask_mutex);
 }
 
+void clear_client_dci_cumulative_event_mask(int client_index)
+{
+	int i, j;
+	uint8_t *update_ptr = dci_cumulative_event_mask;
+	uint8_t *event_mask_ptr, *client_event_mask_ptr, byte_mask = 0;
+	bool is_set = false;
+
+	event_mask_ptr =
+		(driver->dci_client_tbl[client_index].dci_event_mask);
+
+	mutex_lock(&dci_event_mask_mutex);
+	for (i = 0; i < DCI_EVENT_MASK_SIZE; i++) {
+		is_set = false;
+		/* Already cleared event masks need not to be considered */
+		if (*event_mask_ptr != 0) {
+			byte_mask = *event_mask_ptr;
+		} else {
+			update_ptr++;
+			event_mask_ptr++;
+			continue;
+		}
+		for (j = 0; j < MAX_DCI_CLIENTS; j++) {
+			/* continue searching for valid client */
+			if (driver->dci_client_tbl[j].client == NULL ||
+				client_index == j)
+				continue;
+			client_event_mask_ptr =
+				(driver->dci_client_tbl[j].dci_event_mask);
+			client_event_mask_ptr += i;
+			if (*client_event_mask_ptr & byte_mask) {
+				/*
+				* Break if another client has same
+				* event mask set
+				*/
+				if ((*client_event_mask_ptr &
+					byte_mask) == byte_mask) {
+					is_set = true;
+					break;
+				} else {
+					byte_mask =
+					(~(*client_event_mask_ptr) &
+					byte_mask);
+					is_set = false;
+				}
+			}
+		}
+		/*
+		* Clear only if this client has event mask set else
+		* don't update cumulative event mask ptr
+		*/
+		if (is_set == false)
+			*update_ptr &= ~byte_mask;
+
+		update_ptr++;
+		event_mask_ptr++;
+	}
+	event_mask_ptr =
+		(driver->dci_client_tbl[client_index].dci_event_mask);
+	memset(event_mask_ptr, 0, DCI_EVENT_MASK_SIZE);
+	mutex_unlock(&dci_event_mask_mutex);
+}
+
+
 int diag_send_dci_event_mask(smd_channel_t *ch)
 {
 	void *buf = driver->buf_event_mask_update;
@@ -704,7 +809,7 @@
 	return ret;
 }
 
-void update_dci_cumulative_log_mask(int offset, int byte_index,
+void update_dci_cumulative_log_mask(int offset, unsigned int byte_index,
 						uint8_t byte_mask)
 {
 	int i;
@@ -740,6 +845,87 @@
 	mutex_unlock(&dci_log_mask_mutex);
 }
 
+void clear_client_dci_cumulative_log_mask(int client_index)
+{
+	int i, j, k;
+	uint8_t *update_ptr = dci_cumulative_log_mask;
+	uint8_t *log_mask_ptr, *client_log_mask_ptr, byte_mask = 0;
+	bool is_set = false;
+
+	log_mask_ptr = driver->dci_client_tbl[client_index].dci_log_mask;
+
+	mutex_lock(&dci_log_mask_mutex);
+	*update_ptr = 0;
+	/* set the equipment IDs */
+	for (i = 0; i < 16; i++)
+		*(update_ptr + (i*514)) = i;
+
+	/* update cumulative log mask ptr*/
+	update_ptr += 2;
+	log_mask_ptr += 2;
+	for (i = 0; i < 16; i++) {
+		for (j = 0; j < 512; j++) {
+			is_set = false;
+			/*
+			* Already cleared log masks need
+			* not to be considered
+			*/
+			if (*log_mask_ptr != 0) {
+				byte_mask = *log_mask_ptr;
+			} else {
+				update_ptr++;
+				log_mask_ptr++;
+				continue;
+			}
+			for (k = 0; k < MAX_DCI_CLIENTS; k++) {
+				/* continue searching for valid client */
+				if (driver->dci_client_tbl[k].client == NULL ||
+					client_index == k)
+					continue;
+				client_log_mask_ptr =
+				 (driver->dci_client_tbl[k].dci_log_mask);
+				client_log_mask_ptr += (i*514) + 2 + j;
+				if (*client_log_mask_ptr & byte_mask) {
+					/*
+					* Break if another client has same
+					* log mask set
+					*/
+					if ((*client_log_mask_ptr &
+						byte_mask) == byte_mask) {
+						is_set = true;
+						break;
+					} else {
+						byte_mask =
+						 (~(*client_log_mask_ptr) &
+						 byte_mask);
+						is_set = false;
+					}
+				}
+			}
+			/*
+			* Clear only if this client has log mask set else
+			* don't update cumulative log mask ptr
+			*/
+			if (is_set == false) {
+				/*
+				* Update the dirty bit for the equipment
+				* whose mask is changing
+				*/
+				dci_cumulative_log_mask[1+(i*514)] = 1;
+				*update_ptr &= ~byte_mask;
+			}
+
+			update_ptr++;
+			log_mask_ptr++;
+		}
+		update_ptr += 2;
+		log_mask_ptr += 2;
+	}
+	log_mask_ptr = driver->dci_client_tbl[client_index].dci_log_mask;
+	memset(log_mask_ptr, 0, DCI_LOG_MASK_SIZE);
+	mutex_unlock(&dci_log_mask_mutex);
+}
+
 int diag_send_dci_log_mask(smd_channel_t *ch)
 {
 	void *buf = driver->buf_log_mask_update;
@@ -755,6 +941,7 @@
 
 	mutex_lock(&driver->diag_cntl_mutex);
 	for (i = 0; i < 16; i++) {
+		retry_count = 0;
 		driver->log_mask->cmd_type = DIAG_CTRL_MSG_LOG_MASK;
 		driver->log_mask->num_items = 512;
 		driver->log_mask->data_len  = 11 + 512;
@@ -776,8 +963,9 @@
 					break;
 			}
 			if (wr_size != header_size + 512) {
-				pr_err("diag: dci log mask update failed %d, tried %d",
-					 wr_size, header_size + 512);
+				pr_err("diag: dci log mask update failed %d, tried %d for equip_id %d\n",
+					wr_size, header_size + 512,
+					driver->log_mask->equip_id);
 				ret = DIAG_DCI_SEND_DATA_FAIL;
 
 			} else {
@@ -849,10 +1037,14 @@
 	mutex_init(&driver->dci_mutex);
 	mutex_init(&dci_log_mask_mutex);
 	mutex_init(&dci_event_mask_mutex);
-	success = diag_smd_constructor(&driver->smd_dci[MODEM_DATA],
-					MODEM_DATA, SMD_DCI_TYPE);
-	if (!success)
-		goto err;
+	mutex_init(&dci_health_mutex);
+
+	for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++) {
+		success = diag_smd_constructor(&driver->smd_dci[i],
+					i, SMD_DCI_TYPE);
+		if (!success)
+			goto err;
+	}
 
 	if (driver->req_tracking_tbl == NULL) {
 		driver->req_tracking_tbl = kzalloc(dci_max_reg *
@@ -901,5 +1093,118 @@
 	kfree(driver->req_tracking_tbl);
 	kfree(driver->dci_client_tbl);
 	kfree(driver->apps_dci_buf);
+	mutex_destroy(&driver->dci_mutex);
+	mutex_destroy(&dci_log_mask_mutex);
+	mutex_destroy(&dci_event_mask_mutex);
+	mutex_destroy(&dci_health_mutex);
 	destroy_workqueue(driver->diag_dci_wq);
 }
+
+int diag_dci_clear_log_mask()
+{
+	int i, j, k, err = DIAG_DCI_NO_ERROR;
+	uint8_t *log_mask_ptr, *update_ptr;
+
+	i = diag_dci_find_client_index(current->tgid);
+	if (i == DCI_CLIENT_INDEX_INVALID)
+		return DIAG_DCI_TABLE_ERR;
+
+	mutex_lock(&dci_log_mask_mutex);
+	create_dci_log_mask_tbl(
+			driver->dci_client_tbl[i].dci_log_mask);
+	memset(dci_cumulative_log_mask,
+				0x0, DCI_LOG_MASK_SIZE);
+	for (i = 0; i < MAX_DCI_CLIENTS; i++) {
+		update_ptr = dci_cumulative_log_mask;
+		if (driver->dci_client_tbl[i].client) {
+			log_mask_ptr =
+				driver->dci_client_tbl[i].dci_log_mask;
+			for (j = 0; j < 16; j++) {
+				*update_ptr = j;
+				*(update_ptr + 1) = 1;
+				update_ptr += 2;
+				log_mask_ptr += 2;
+				for (k = 0; k < 513; k++) {
+					*update_ptr |= *log_mask_ptr;
+					update_ptr++;
+					log_mask_ptr++;
+				}
+			}
+		}
+	}
+	mutex_unlock(&dci_log_mask_mutex);
+	err = diag_send_dci_log_mask(driver->smd_cntl[MODEM_DATA].ch);
+	return err;
+}
+
+int diag_dci_clear_event_mask()
+{
+	int i, j, err = DIAG_DCI_NO_ERROR;
+	uint8_t *event_mask_ptr, *update_ptr;
+
+	i = diag_dci_find_client_index(current->tgid);
+	if (i == DCI_CLIENT_INDEX_INVALID)
+		return DIAG_DCI_TABLE_ERR;
+
+	mutex_lock(&dci_event_mask_mutex);
+	memset(driver->dci_client_tbl[i].dci_event_mask,
+			0x0, DCI_EVENT_MASK_SIZE);
+	memset(dci_cumulative_event_mask,
+			0x0, DCI_EVENT_MASK_SIZE);
+	update_ptr = dci_cumulative_event_mask;
+	for (i = 0; i < MAX_DCI_CLIENTS; i++) {
+		event_mask_ptr =
+			driver->dci_client_tbl[i].dci_event_mask;
+		for (j = 0; j < DCI_EVENT_MASK_SIZE; j++)
+			*(update_ptr + j) |= *(event_mask_ptr + j);
+	}
+	mutex_unlock(&dci_event_mask_mutex);
+	err = diag_send_dci_event_mask(driver->smd_cntl[MODEM_DATA].ch);
+	return err;
+}
+
+int diag_dci_query_log_mask(uint16_t log_code)
+{
+	uint16_t item_num;
+	uint8_t equip_id, *log_mask_ptr, byte_mask;
+	int i, byte_index, offset;
+
+	equip_id = LOG_GET_EQUIP_ID(log_code);
+	item_num = LOG_GET_ITEM_NUM(log_code);
+	byte_index = item_num/8 + 2;
+	byte_mask = 0x01 << (item_num % 8);
+	offset = equip_id * 514;
+
+	i = diag_dci_find_client_index(current->tgid);
+	if (i != DCI_CLIENT_INDEX_INVALID) {
+		log_mask_ptr = driver->dci_client_tbl[i].dci_log_mask;
+		log_mask_ptr = log_mask_ptr + offset + byte_index;
+		return ((*log_mask_ptr & byte_mask) == byte_mask) ?
+								1 : 0;
+	}
+	return 0;
+}
+
+
+int diag_dci_query_event_mask(uint16_t event_id)
+{
+	uint8_t *event_mask_ptr, byte_mask;
+	int i, byte_index, bit_index;
+	byte_index = event_id/8;
+	bit_index = event_id % 8;
+	byte_mask = 0x1 << bit_index;
+
+	i = diag_dci_find_client_index(current->tgid);
+	if (i != DCI_CLIENT_INDEX_INVALID) {
+		event_mask_ptr =
+		driver->dci_client_tbl[i].dci_event_mask;
+		event_mask_ptr = event_mask_ptr + byte_index;
+		if ((*event_mask_ptr & byte_mask) == byte_mask)
+			return 1;
+		else
+			return 0;
+	}
+	return 0;
+}
+
+
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index af89ac8..260cdf3 100644
--- a/drivers/char/diag/diag_dci.h
+++ b/drivers/char/diag/diag_dci.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -22,7 +22,9 @@
 #define DCI_EVENT_TYPE		-2
 #define SET_LOG_MASK		1
 #define DISABLE_LOG_MASK	0
-#define MAX_EVENT_SIZE		100
+#define MAX_EVENT_SIZE		512
+#define DCI_CLIENT_INDEX_INVALID -1
+
 
 /* 16 log code categories, each has:
  * 1 bytes equip id + 1 dirty byte + 512 byte max log mask
@@ -35,6 +37,7 @@
 
 extern unsigned int dci_max_reg;
 extern unsigned int dci_max_clients;
+extern struct mutex dci_health_mutex;
 
 struct dci_pkt_req_tracking_tbl {
 	int pid;
@@ -66,6 +69,13 @@
 	int reset_status;
 };
 
+/* This is used for querying DCI Log
+   or Event Mask */
+struct diag_log_event_stats {
+	uint16_t code;
+	int is_set;
+};
+
 enum {
 	DIAG_DCI_NO_ERROR = 1001,	/* No error */
 	DIAG_DCI_NO_REG,		/* Could not register */
@@ -86,15 +96,22 @@
 int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf,
 							 int len, int index);
 void extract_dci_pkt_rsp(unsigned char *buf);
+int diag_dci_find_client_index(int client_id);
 /* DCI Log streaming functions */
 void create_dci_log_mask_tbl(unsigned char *tbl_buf);
-void update_dci_cumulative_log_mask(int offset, int byte_index,
+void update_dci_cumulative_log_mask(int offset, unsigned int byte_index,
 						uint8_t byte_mask);
+void clear_client_dci_cumulative_log_mask(int client_index);
 int diag_send_dci_log_mask(smd_channel_t *ch);
 void extract_dci_log(unsigned char *buf);
+int diag_dci_clear_log_mask(void);
+int diag_dci_query_log_mask(uint16_t log_code);
 /* DCI event streaming functions */
 void update_dci_cumulative_event_mask(int offset, uint8_t byte_mask);
+void clear_client_dci_cumulative_event_mask(int client_index);
 int diag_send_dci_event_mask(smd_channel_t *ch);
 void extract_dci_events(unsigned char *buf);
 void create_dci_event_mask_tbl(unsigned char *tbl_buf);
+int diag_dci_clear_event_mask(void);
+int diag_dci_query_event_mask(uint16_t event_id);
 #endif
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index e179d4d..76490c8 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -22,6 +22,7 @@
 #define DEBUG_BUF_SIZE	4096
 static struct dentry *diag_dbgfs_dent;
 static int diag_dbgfs_table_index;
+static int diag_dbgfs_finished;
 
 static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
 				      size_t count, loff_t *ppos)
@@ -234,61 +235,115 @@
 {
 	char *buf;
 	int ret;
+	int i;
+	int bytes_remaining;
+	int bytes_in_buffer = 0;
+	int bytes_written;
+	int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+	int bytes_hsic_inited = 45;
+	int bytes_hsic_not_inited = 410;
 
-	buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
+	if (diag_dbgfs_finished) {
+		diag_dbgfs_finished = 0;
+		return 0;
+	}
+
+	buf = kzalloc(sizeof(char) * buf_size, GFP_KERNEL);
 	if (!buf) {
 		pr_err("diag: %s, Error allocating memory\n", __func__);
 		return -ENOMEM;
 	}
 
-	ret = scnprintf(buf, DEBUG_BUF_SIZE,
-		"hsic ch: %d\n"
-		"hsic_inited: %d\n"
-		"hsic enabled: %d\n"
-		"hsic_opened: %d\n"
-		"hsic_suspend: %d\n"
-		"in_busy_hsic_read_on_device: %d\n"
-		"in_busy_hsic_write: %d\n"
-		"count_hsic_pool: %d\n"
-		"count_hsic_write_pool: %d\n"
-		"diag_hsic_pool: %x\n"
-		"diag_hsic_write_pool: %x\n"
-		"HSIC write_len: %d\n"
-		"num_hsic_buf_tbl_entries: %d\n"
-		"HSIC usb_connected: %d\n"
-		"HSIC diag_read_work: %d\n"
-		"diag_read_hsic_work: %d\n"
-		"diag_disconnect_work: %d\n"
-		"diag_usb_read_complete_work: %d\n"
+	bytes_remaining = buf_size;
+
+	/* Only one smux for now */
+	bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
+		"Values for SMUX instance: 0\n"
 		"smux ch: %d\n"
 		"smux enabled %d\n"
 		"smux in busy %d\n"
-		"smux connected %d\n",
-		diag_hsic[HSIC].hsic_ch,
-		diag_hsic[HSIC].hsic_inited,
-		diag_hsic[HSIC].hsic_device_enabled,
-		diag_hsic[HSIC].hsic_device_opened,
-		diag_hsic[HSIC].hsic_suspend,
-		diag_hsic[HSIC].in_busy_hsic_read_on_device,
-		diag_hsic[HSIC].in_busy_hsic_write,
-		diag_hsic[HSIC].count_hsic_pool,
-		diag_hsic[HSIC].count_hsic_write_pool,
-		(unsigned int)diag_hsic[HSIC].diag_hsic_pool,
-		(unsigned int)diag_hsic[HSIC].diag_hsic_write_pool,
-			diag_bridge[HSIC].write_len,
-		diag_hsic[HSIC].num_hsic_buf_tbl_entries,
-			diag_bridge[HSIC].usb_connected,
-			work_pending(&(diag_bridge[HSIC].diag_read_work)),
-		work_pending(&(diag_hsic[HSIC].diag_read_hsic_work)),
-		work_pending(&(driver->diag_disconnect_work)),
-		work_pending(&(diag_bridge[HSIC].usb_read_complete_work)),
+		"smux connected %d\n\n",
 		driver->lcid,
 		driver->diag_smux_enabled,
 		driver->in_busy_smux,
 		driver->smux_connected);
 
-	ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
+	bytes_in_buffer += bytes_written;
+	bytes_remaining = buf_size - bytes_in_buffer;
 
+	bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
+		"HSIC diag_disconnect_work: %d\n",
+		work_pending(&(driver->diag_disconnect_work)));
+
+	bytes_in_buffer += bytes_written;
+	bytes_remaining = buf_size - bytes_in_buffer;
+
+	for (i = 0; i < MAX_HSIC_CH; i++) {
+		if (diag_hsic[i].hsic_inited) {
+			/* Check if there is room to add another HSIC entry */
+			if (bytes_remaining < bytes_hsic_inited)
+				break;
+			bytes_written = scnprintf(buf+bytes_in_buffer,
+							bytes_remaining,
+			"Values for HSIC Instance: %d\n"
+			"hsic ch: %d\n"
+			"hsic_inited: %d\n"
+			"hsic enabled: %d\n"
+			"hsic_opened: %d\n"
+			"hsic_suspend: %d\n"
+			"in_busy_hsic_read_on_device: %d\n"
+			"in_busy_hsic_write: %d\n"
+			"count_hsic_pool: %d\n"
+			"count_hsic_write_pool: %d\n"
+			"diag_hsic_pool: %x\n"
+			"diag_hsic_write_pool: %x\n"
+			"HSIC write_len: %d\n"
+			"num_hsic_buf_tbl_entries: %d\n"
+			"HSIC usb_connected: %d\n"
+			"HSIC diag_read_work: %d\n"
+			"diag_read_hsic_work: %d\n"
+			"diag_usb_read_complete_work: %d\n\n",
+			i,
+			diag_hsic[i].hsic_ch,
+			diag_hsic[i].hsic_inited,
+			diag_hsic[i].hsic_device_enabled,
+			diag_hsic[i].hsic_device_opened,
+			diag_hsic[i].hsic_suspend,
+			diag_hsic[i].in_busy_hsic_read_on_device,
+			diag_hsic[i].in_busy_hsic_write,
+			diag_hsic[i].count_hsic_pool,
+			diag_hsic[i].count_hsic_write_pool,
+			(unsigned int)diag_hsic[i].diag_hsic_pool,
+			(unsigned int)diag_hsic[i].diag_hsic_write_pool,
+			diag_bridge[i].write_len,
+			diag_hsic[i].num_hsic_buf_tbl_entries,
+			diag_bridge[i].usb_connected,
+			work_pending(&(diag_bridge[i].diag_read_work)),
+			work_pending(&(diag_hsic[i].diag_read_hsic_work)),
+			work_pending(&(diag_bridge[i].usb_read_complete_work)));
+			if (bytes_written > bytes_hsic_inited)
+				bytes_hsic_inited = bytes_written;
+		} else {
+			/* Check if there is room to add another HSIC entry */
+			if (bytes_remaining < bytes_hsic_not_inited)
+				break;
+			bytes_written = scnprintf(buf+bytes_in_buffer,
+				bytes_remaining,
+				"HSIC Instance: %d has not been initialized\n\n",
+				i);
+			if (bytes_written > bytes_hsic_not_inited)
+				bytes_hsic_not_inited = bytes_written;
+		}
+
+		bytes_in_buffer += bytes_written;
+
+		bytes_remaining = buf_size - bytes_in_buffer;
+	}
+
+	*ppos = 0;
+	ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
+
+	diag_dbgfs_finished = 1;
 	kfree(buf);
 	return ret;
 }
@@ -331,6 +386,7 @@
 #endif
 
 	diag_dbgfs_table_index = 0;
+	diag_dbgfs_finished = 0;
 }
 
 void diag_debugfs_cleanup(void)
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index e8567db..9e36e1e 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. 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 and
@@ -314,6 +314,9 @@
 	diag_send_event_mask_update(smd_info->ch, diag_event_num_bytes);
 	diag_send_feature_mask_update(smd_info->ch, smd_info->peripheral);
 
+	if (smd_info->notify_context == SMD_EVENT_OPEN)
+		diag_send_diag_mode_update_by_smd(smd_info, MODE_REALTIME);
+
 	smd_info->notify_context = 0;
 }
 
@@ -525,6 +528,10 @@
 			*(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
 			*(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
 			payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
+			if (payload_length > APPS_BUF_SIZE - 12) {
+				pr_err("diag: log masks: buffer overflow\n");
+				return -EIO;
+			}
 			for (i = 0; i < payload_length; i++)
 				*(int *)(driver->apps_rsp_buf+12+i) = *(buf+i);
 
@@ -608,6 +615,10 @@
 					rt_last_ssid) {
 					rt_mask_size = 4 * (rt_last_ssid -
 						rt_first_ssid + 1);
+					if (rt_mask_size > APPS_BUF_SIZE - 8) {
+						pr_err("diag: rt masks: buffer overflow\n");
+						return -EIO;
+					}
 					memcpy(driver->apps_rsp_buf+8,
 						rt_mask_ptr, rt_mask_size);
 					encode_rsp_and_send(8+rt_mask_size-1);
@@ -621,7 +632,17 @@
 	else if ((*buf == 0x7d) && (*(buf+1) == 0x4)) {
 		ssid_first = *(uint16_t *)(buf + 2);
 		ssid_last = *(uint16_t *)(buf + 4);
+		if (ssid_last < ssid_first) {
+			pr_err("diag: Invalid msg mask ssid values, first: %d, last: %d\n",
+				ssid_first, ssid_last);
+			return -EIO;
+		}
 		ssid_range = 4 * (ssid_last - ssid_first + 1);
+		if (ssid_range > APPS_BUF_SIZE - 8) {
+			pr_err("diag: Not enough space for message mask, ssid_range: %d\n",
+				ssid_range);
+			return -EIO;
+		}
 		pr_debug("diag: received mask update for ssid_first = %d, ssid_last = %d",
 			ssid_first, ssid_last);
 		diag_update_msg_mask(ssid_first, ssid_last , buf + 8);
@@ -716,8 +737,8 @@
 					(driver->log_on_demand_support)) {
 			driver->apps_rsp_buf[0] = 0x78;
 			/* Copy log code received */
-			*(uint16_t *)(driver->apps_rsp_buf+1) =
-							 *(uint16_t *)buf;
+			*(uint16_t *)(driver->apps_rsp_buf + 1) =
+							*(uint16_t *)(buf + 1);
 			driver->apps_rsp_buf[3] = 0x1;/* Unknown */
 			encode_rsp_and_send(3);
 		}
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index cab4020..6f37608 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -20,6 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 #include <linux/sched.h>
+#include <linux/wakelock.h>
 #include <mach/msm_smd.h>
 #include <asm/atomic.h>
 #include <asm/mach-types.h>
@@ -30,7 +31,6 @@
 #define IN_BUF_SIZE		16384
 #define MAX_IN_BUF_SIZE	32768
 #define MAX_SYNC_OBJ_NAME_SIZE	32
-#define UINT32_MAX	UINT_MAX
 /* Size of the buffer used for deframing a packet
   reveived from the PC tool*/
 #define HDLC_MAX 4096
@@ -77,6 +77,9 @@
 #define DIAG_STATUS_OPEN (0x00010000)	/* DCI channel open status mask   */
 #define DIAG_STATUS_CLOSED (0x00020000)	/* DCI channel closed status mask */
 
+#define MODE_REALTIME 1
+#define MODE_NONREALTIME 0
+
 #define NUM_SMD_DATA_CHANNELS 3
 #define NUM_SMD_CONTROL_CHANNELS 3
 #define NUM_SMD_DCI_CHANNELS 1
@@ -86,8 +89,8 @@
 #define SMD_DCI_TYPE 2
 
 /* Maximum number of pkt reg supported at initialization*/
-extern unsigned int diag_max_reg;
-extern unsigned int diag_threshold_reg;
+extern int diag_max_reg;
+extern int diag_threshold_reg;
 
 #define APPEND_DEBUG(ch) \
 do {							\
@@ -99,7 +102,10 @@
 /* List of remote processor supported */
 enum remote_procs {
 	MDM = 1,
-	QSC = 2,
+	MDM2 = 2,
+	MDM3 = 3,
+	MDM4 = 4,
+	QSC = 5,
 };
 
 struct diag_master_table {
@@ -141,6 +147,14 @@
 	int pid;
 };
 
+struct diag_nrt_wake_lock {
+	int enabled;
+	int ref_count;
+	int copy_count;
+	struct wake_lock read_lock;
+	spinlock_t read_spinlock;
+};
+
 /* This structure is defined in USB header file */
 #ifndef CONFIG_DIAG_OVER_USB
 struct diag_request {
@@ -160,6 +174,8 @@
 	smd_channel_t *ch;
 	smd_channel_t *ch_save;
 
+	struct mutex smd_ch_mutex;
+
 	int in_busy_1;
 	int in_busy_2;
 
@@ -169,6 +185,8 @@
 	struct diag_request *write_ptr_1;
 	struct diag_request *write_ptr_2;
 
+	struct diag_nrt_wake_lock nrt_lock;
+
 	struct work_struct diag_read_smd_work;
 	struct work_struct diag_notify_update_smd_work;
 	int notify_context;
@@ -235,6 +253,7 @@
 	struct diag_ctrl_msg_mask *msg_mask;
 	struct diag_ctrl_feature_mask *feature_mask;
 	/* State for diag forwarding */
+	int real_time_mode;
 	struct diag_smd_info smd_data[NUM_SMD_DATA_CHANNELS];
 	struct diag_smd_info smd_cntl[NUM_SMD_CONTROL_CHANNELS];
 	struct diag_smd_info smd_dci[NUM_SMD_DCI_CHANNELS];
@@ -247,9 +266,11 @@
 	unsigned char *buf_event_mask_update;
 	unsigned char *buf_feature_mask_update;
 	int read_len_legacy;
+	struct mutex diag_hdlc_mutex;
 	unsigned char *hdlc_buf;
 	unsigned hdlc_count;
 	unsigned hdlc_escape;
+	int in_busy_pktdata;
 #ifdef CONFIG_DIAG_OVER_USB
 	int usb_connected;
 	struct usb_diag_ch *legacy_ch;
@@ -289,6 +310,7 @@
 	struct diag_request *write_ptr_mdm;
 #endif
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
+	spinlock_t hsic_ready_spinlock;
 	/* common for all bridges */
 	struct work_struct diag_disconnect_work;
 	/* SGLTE variables */
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index fa69f0b..a0c32f5 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -20,6 +20,7 @@
 #include <linux/diagchar.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
+#include <linux/ratelimit.h>
 #ifdef CONFIG_DIAG_OVER_USB
 #include <mach/usbdiag.h>
 #endif
@@ -66,8 +67,8 @@
 static unsigned int max_clients = 15;
 static unsigned int threshold_client_limit = 30;
 /* This is the maximum number of pkt registrations supported at initialization*/
-unsigned int diag_max_reg = 600;
-unsigned int diag_threshold_reg = 750;
+int diag_max_reg = 600;
+int diag_threshold_reg = 750;
 
 /* Timer variables */
 static struct timer_list drain_timer;
@@ -153,7 +154,7 @@
 					/* Return the buffer to the pool */
 					diagmem_free(driver, (unsigned char *)
 						(diag_hsic[j].hsic_buf_tbl[i].
-						 buf), POOL_TYPE_HSIC);
+						 buf), j+POOL_TYPE_HSIC);
 					diag_hsic[j].hsic_buf_tbl[i].buf = 0;
 				}
 				diag_hsic[j].hsic_buf_tbl[i].length = 0;
@@ -245,7 +246,7 @@
 
 static int diagchar_close(struct inode *inode, struct file *file)
 {
-	int i = 0;
+	int i = -1;
 	struct diagchar_priv *diagpriv_data = file->private_data;
 
 	pr_debug("diag: process exit %s\n", current->comm);
@@ -261,14 +262,9 @@
 	* This will specially help in case of ungraceful exit of any DCI client
 	* This call will remove any pending registrations of such client
 	*/
-	for (i = 0; i < MAX_DCI_CLIENTS; i++) {
-		if (driver->dci_client_tbl[i].client &&
-			driver->dci_client_tbl[i].client->tgid ==
-							 current->tgid) {
-			diagchar_ioctl(NULL, DIAG_IOCTL_DCI_DEINIT, 0);
-			break;
-		}
-	}
+	if (diag_dci_find_client_index(current->tgid) !=
+		 DCI_CLIENT_INDEX_INVALID)
+		diagchar_ioctl(NULL, DIAG_IOCTL_DCI_DEINIT, 0);
 	/* If the exiting process is the socket process */
 	if (driver->socket_process &&
 		(driver->socket_process->tgid == current->tgid)) {
@@ -283,10 +279,11 @@
 	/* If the SD logging process exits, change logging to USB mode */
 	if (driver->logging_process_id == current->tgid) {
 		driver->logging_mode = USB_MODE;
+		diag_send_diag_mode_update(MODE_REALTIME);
 		diagfwd_connect();
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
 		diag_clear_hsic_tbl();
-		diagfwd_cancel_hsic();
+		diagfwd_cancel_hsic(REOPEN_HSIC);
 		diagfwd_connect_bridge(0);
 #endif
 	}
@@ -382,25 +379,6 @@
 	(*count_entries)++;
 }
 
-#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-uint16_t diag_get_remote_device_mask(void)
-{
-	uint16_t remote_dev = 0;
-
-	/* Check for MDM processor */
-	if (diag_hsic[HSIC].hsic_inited)
-		remote_dev |= 1 << 0;
-
-	/* Check for QSC processor */
-	if (driver->diag_smux_enabled)
-		remote_dev |= 1 << 1;
-
-	return remote_dev;
-}
-#else
-inline uint16_t diag_get_remote_device_mask(void) { return 0; }
-#endif
-
 static int diag_get_remote(int remote_info)
 {
 	int val = (remote_info < 0) ? -remote_info : remote_info;
@@ -408,6 +386,9 @@
 
 	switch (val) {
 	case MDM:
+	case MDM2:
+	case MDM3:
+	case MDM4:
 	case QSC:
 		remote_val = -remote_info;
 		break;
@@ -419,143 +400,518 @@
 	return remote_val;
 }
 
-long diagchar_ioctl(struct file *filp,
-			   unsigned int iocmd, unsigned long ioarg)
+#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
+uint16_t diag_get_remote_device_mask(void)
 {
-	int i, j, temp, success = -1, status;
-	unsigned int count_entries = 0, interim_count = 0;
-	void *temp_buf;
-	uint16_t support_list = 0;
-	struct diag_dci_client_tbl *dci_params;
-	struct diag_dci_health_stats stats;
+	uint16_t remote_dev = 0;
+	int i;
 
-	if (iocmd == DIAG_IOCTL_COMMAND_REG) {
-		struct bindpkt_params_per_process pkt_params;
-		struct bindpkt_params *params;
-		struct bindpkt_params *head_params;
-		if (copy_from_user(&pkt_params, (void *)ioarg,
-			   sizeof(struct bindpkt_params_per_process))) {
-			return -EFAULT;
-		}
-		if ((UINT32_MAX/sizeof(struct bindpkt_params)) <
-							 pkt_params.count) {
-			pr_warning("diag: integer overflow while multiply\n");
-			return -EFAULT;
-		}
-		params = kzalloc(pkt_params.count*sizeof(
-			struct bindpkt_params), GFP_KERNEL);
-		if (!params) {
-			pr_err("diag: unable to alloc memory\n");
-			return -ENOMEM;
-		} else
-			head_params = params;
+	/* Check for MDM processor */
+	for (i = 0; i < MAX_HSIC_CH; i++)
+		if (diag_hsic[i].hsic_inited)
+			remote_dev |= 1 << i;
 
-		if (copy_from_user(params, pkt_params.params,
-			   pkt_params.count*sizeof(struct bindpkt_params))) {
-			kfree(head_params);
-			return -EFAULT;
+	/* Check for QSC processor */
+	if (driver->diag_smux_enabled)
+		remote_dev |= 1 << SMUX;
+
+	return remote_dev;
+}
+
+int diag_copy_remote(char __user *buf, size_t count, int *pret, int *pnum_data)
+{
+	int i;
+	int index;
+	int exit_stat = 1;
+	int ret = *pret;
+	int num_data = *pnum_data;
+	int remote_token;
+	unsigned long spin_lock_flags;
+	struct diag_write_device hsic_buf_tbl[NUM_HSIC_BUF_TBL_ENTRIES];
+
+	remote_token = diag_get_remote(MDM);
+	for (index = 0; index < MAX_HSIC_CH; index++) {
+		if (!diag_hsic[index].hsic_inited) {
+			remote_token--;
+			continue;
 		}
-		mutex_lock(&driver->diagchar_mutex);
-		for (i = 0; i < diag_max_reg; i++) {
-			if (driver->table[i].process_id == 0) {
-				diag_add_reg(i, params, &success,
-							 &count_entries);
-				if (pkt_params.count > count_entries) {
-					params++;
-				} else {
-					mutex_unlock(&driver->diagchar_mutex);
-					kfree(head_params);
-					return success;
+
+		spin_lock_irqsave(&diag_hsic[index].hsic_spinlock,
+			spin_lock_flags);
+		for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) {
+			hsic_buf_tbl[i].buf =
+				diag_hsic[index].hsic_buf_tbl[i].buf;
+			diag_hsic[index].hsic_buf_tbl[i].buf = 0;
+			hsic_buf_tbl[i].length =
+				diag_hsic[index].hsic_buf_tbl[i].length;
+			diag_hsic[index].hsic_buf_tbl[i].length = 0;
+		}
+		diag_hsic[index].num_hsic_buf_tbl_entries = 0;
+		spin_unlock_irqrestore(&diag_hsic[index].hsic_spinlock,
+			spin_lock_flags);
+
+		for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) {
+			if (hsic_buf_tbl[i].length > 0) {
+				pr_debug("diag: HSIC copy to user, i: %d, buf: %x, len: %d\n",
+					i, (unsigned int)hsic_buf_tbl[i].buf,
+					hsic_buf_tbl[i].length);
+				num_data++;
+
+				/* Copy the negative token */
+				if (copy_to_user(buf+ret,
+					&remote_token, 4)) {
+						num_data--;
+						goto drop_hsic;
 				}
+				ret += 4;
+
+				/* Copy the length of data being passed */
+				if (copy_to_user(buf+ret,
+					(void *)&(hsic_buf_tbl[i].length),
+					4)) {
+						num_data--;
+						goto drop_hsic;
+				}
+				ret += 4;
+
+				/* Copy the actual data being passed */
+				if (copy_to_user(buf+ret,
+					(void *)hsic_buf_tbl[i].buf,
+					hsic_buf_tbl[i].length)) {
+						ret -= 4;
+						num_data--;
+						goto drop_hsic;
+				}
+				ret += hsic_buf_tbl[i].length;
+drop_hsic:
+				/* Return the buffer to the pool */
+				diagmem_free(driver,
+					(unsigned char *)(hsic_buf_tbl[i].buf),
+					index+POOL_TYPE_HSIC);
+
+				/* Call the write complete function */
+				diagfwd_write_complete_hsic(NULL, index);
 			}
 		}
-		if (i < diag_threshold_reg) {
-			/* Increase table size by amount required */
+		remote_token--;
+	}
+	if (driver->in_busy_smux == 1) {
+		remote_token = diag_get_remote(QSC);
+		num_data++;
+
+		/* Copy the negative  token of data being passed */
+		COPY_USER_SPACE_OR_EXIT(buf+ret,
+			remote_token, 4);
+		/* Copy the length of data being passed */
+		COPY_USER_SPACE_OR_EXIT(buf+ret,
+			(driver->write_ptr_mdm->length), 4);
+		/* Copy the actual data being passed */
+		COPY_USER_SPACE_OR_EXIT(buf+ret,
+			*(driver->buf_in_smux),
+			driver->write_ptr_mdm->length);
+		pr_debug("diag: SMUX  data copied\n");
+		driver->in_busy_smux = 0;
+	}
+	exit_stat = 0;
+exit:
+	*pret = ret;
+	*pnum_data = num_data;
+	return exit_stat;
+}
+
+static void diag_update_data_ready(int index)
+{
+	int clear_bit = 1;
+	unsigned long hsic_lock_flags;
+	unsigned long ready_lock_flags;
+	int i;
+
+	/*
+	 * Determine whether the data_ready USER_SPACE_DATA_TYPE bit
+	 * should be updated/cleared or not. There is a race condition that
+	 * can occur when in MEMORY_DEVICE_MODE with the hsic data.
+	 * When new hsic data arrives we prepare the data so it can
+	 * later be copied to userspace.  We set the USER_SPACE_DATA_TYPE
+	 * bit in data ready at that time. We later copy the hsic data
+	 * to userspace and clear the USER_SPACE_DATA_TYPE bit in
+	 * data ready. The race condition occurs if new data arrives (bit set)
+	 * while we are processing the current data and sending
+	 * it to userspace (bit clear).  The clearing of the bit can
+	 * overwrite the setting of the bit.
+	 */
+
+	spin_lock_irqsave(&driver->hsic_ready_spinlock, ready_lock_flags);
+	for (i = 0; i < MAX_HSIC_CH; i++) {
+		if (diag_hsic[i].hsic_inited) {
+			spin_lock_irqsave(&diag_hsic[i].hsic_spinlock,
+							hsic_lock_flags);
+			if ((diag_hsic[i].num_hsic_buf_tbl_entries > 0) &&
+				diag_hsic[i].hsic_device_enabled &&
+				diag_hsic[i].hsic_ch) {
+				/* New data do not clear the bit */
+				clear_bit = 0;
+			}
+			spin_unlock_irqrestore(&diag_hsic[i].hsic_spinlock,
+							hsic_lock_flags);
+			if (!clear_bit)
+				break;
+		}
+	}
+
+	if (clear_bit)
+		driver->data_ready[index] ^= USER_SPACE_DATA_TYPE;
+
+	spin_unlock_irqrestore(&driver->hsic_ready_spinlock, ready_lock_flags);
+}
+#else
+inline uint16_t diag_get_remote_device_mask(void) { return 0; }
+inline int diag_copy_remote(char __user *buf, size_t count, int *pret,
+			    int *pnum_data) { return 0; }
+static void diag_update_data_ready(int index)
+{
+	driver->data_ready[index] ^= USER_SPACE_DATA_TYPE;
+}
+#endif
+
+int diag_command_reg(unsigned long ioarg)
+{
+	int i = 0, success = -EINVAL, j;
+	void *temp_buf;
+	unsigned int count_entries = 0, interim_count = 0;
+	struct bindpkt_params_per_process pkt_params;
+	struct bindpkt_params *params;
+	struct bindpkt_params *head_params;
+	if (copy_from_user(&pkt_params, (void *)ioarg,
+		   sizeof(struct bindpkt_params_per_process))) {
+		return -EFAULT;
+	}
+	if ((UINT_MAX/sizeof(struct bindpkt_params)) <
+						 pkt_params.count) {
+		pr_warn("diag: integer overflow while multiply\n");
+		return -EFAULT;
+	}
+	head_params = kzalloc(pkt_params.count*sizeof(
+		struct bindpkt_params), GFP_KERNEL);
+	if (!head_params) {
+		pr_err("diag: unable to alloc memory\n");
+		return -ENOMEM;
+	} else
+		params = head_params;
+	if (copy_from_user(params, pkt_params.params,
+		   pkt_params.count*sizeof(struct bindpkt_params))) {
+		kfree(head_params);
+		return -EFAULT;
+	}
+	mutex_lock(&driver->diagchar_mutex);
+	for (i = 0; i < diag_max_reg; i++) {
+		if (driver->table[i].process_id == 0) {
+			diag_add_reg(i, params, &success,
+						 &count_entries);
+			if (pkt_params.count > count_entries) {
+				params++;
+			} else {
+				kfree(head_params);
+				mutex_unlock(&driver->diagchar_mutex);
+				return success;
+			}
+		}
+	}
+	if (i < diag_threshold_reg) {
+		/* Increase table size by amount required */
+		if (pkt_params.count >= count_entries) {
+			interim_count = pkt_params.count -
+						 count_entries;
+		} else {
+			pr_warn("diag: error in params count\n");
+			kfree(head_params);
+			mutex_unlock(&driver->diagchar_mutex);
+			return -EFAULT;
+		}
+		if (UINT_MAX - diag_max_reg >=
+						interim_count) {
+			diag_max_reg += interim_count;
+		} else {
+			pr_warn("diag: Integer overflow\n");
+			kfree(head_params);
+			mutex_unlock(&driver->diagchar_mutex);
+			return -EFAULT;
+		}
+		/* Make sure size doesnt go beyond threshold */
+		if (diag_max_reg > diag_threshold_reg) {
+			diag_max_reg = diag_threshold_reg;
+			pr_err("diag: best case memory allocation\n");
+		}
+		if (UINT_MAX/sizeof(struct diag_master_table) <
+							 diag_max_reg) {
+			pr_warn("diag: integer overflow\n");
+			kfree(head_params);
+			mutex_unlock(&driver->diagchar_mutex);
+			return -EFAULT;
+		}
+		temp_buf = krealloc(driver->table,
+				 diag_max_reg*sizeof(struct
+				 diag_master_table), GFP_KERNEL);
+		if (!temp_buf) {
+			pr_err("diag: Insufficient memory for reg.\n");
+
 			if (pkt_params.count >= count_entries) {
 				interim_count = pkt_params.count -
 							 count_entries;
 			} else {
-				pr_warning("diag: error in params count\n");
+				pr_warn("diag: params count error\n");
 				kfree(head_params);
 				mutex_unlock(&driver->diagchar_mutex);
 				return -EFAULT;
 			}
-			if (UINT32_MAX - diag_max_reg >=
-							interim_count) {
-				diag_max_reg += interim_count;
+			if (diag_max_reg >= interim_count) {
+				diag_max_reg -= interim_count;
 			} else {
-				pr_warning("diag: Integer overflow\n");
+				pr_warn("diag: Integer underflow\n");
 				kfree(head_params);
 				mutex_unlock(&driver->diagchar_mutex);
 				return -EFAULT;
 			}
-			/* Make sure size doesnt go beyond threshold */
-			if (diag_max_reg > diag_threshold_reg) {
-				diag_max_reg = diag_threshold_reg;
-				pr_info("diag: best case memory allocation\n");
-			}
-			if (UINT32_MAX/sizeof(struct diag_master_table) <
-								 diag_max_reg) {
-				pr_warning("diag: integer overflow\n");
-				kfree(head_params);
-				mutex_unlock(&driver->diagchar_mutex);
-				return -EFAULT;
-			}
-			temp_buf = krealloc(driver->table,
-					 diag_max_reg*sizeof(struct
-					 diag_master_table), GFP_KERNEL);
-			if (!temp_buf) {
-				pr_alert("diag: Insufficient memory for reg.\n");
-				mutex_unlock(&driver->diagchar_mutex);
-
-				if (pkt_params.count >= count_entries) {
-					interim_count = pkt_params.count -
-								 count_entries;
-				} else {
-					pr_warning("diag: params count error\n");
-					mutex_unlock(&driver->diagchar_mutex);
-					kfree(head_params);
-					return -EFAULT;
-				}
-				if (diag_max_reg >= interim_count) {
-					diag_max_reg -= interim_count;
-				} else {
-					pr_warning("diag: Integer underflow\n");
-					mutex_unlock(&driver->diagchar_mutex);
-					kfree(head_params);
-					return -EFAULT;
-				}
-				kfree(head_params);
-				return 0;
-			} else {
-				driver->table = temp_buf;
-			}
-			for (j = i; j < diag_max_reg; j++) {
-				diag_add_reg(j, params, &success,
-							 &count_entries);
-				if (pkt_params.count > count_entries) {
-					params++;
-				} else {
-					mutex_unlock(&driver->diagchar_mutex);
-					kfree(head_params);
-					return success;
-				}
-			}
 			kfree(head_params);
 			mutex_unlock(&driver->diagchar_mutex);
+			return 0;
 		} else {
-			mutex_unlock(&driver->diagchar_mutex);
-			kfree(head_params);
-			pr_err("Max size reached, Pkt Registration failed for"
-						" Process %d", current->tgid);
+			driver->table = temp_buf;
 		}
-		success = 0;
-	} else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) {
-		struct diagpkt_delay_params delay_params;
-		uint16_t interim_rsp_id;
-		int interim_size;
+		for (j = i; j < diag_max_reg; j++) {
+			diag_add_reg(j, params, &success,
+						 &count_entries);
+			if (pkt_params.count > count_entries) {
+				params++;
+			} else {
+				kfree(head_params);
+				mutex_unlock(&driver->diagchar_mutex);
+				return success;
+			}
+		}
+		kfree(head_params);
+		mutex_unlock(&driver->diagchar_mutex);
+	} else {
+		kfree(head_params);
+		mutex_unlock(&driver->diagchar_mutex);
+		pr_err("Max size reached, Pkt Registration failed for Process %d",
+					current->tgid);
+	}
+	success = 0;
+	return success;
+}
+
+#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
+void diag_cmp_logging_modes_diagfwd_bridge(int old_mode, int new_mode)
+{
+	if (old_mode == MEMORY_DEVICE_MODE && new_mode
+					== NO_LOGGING_MODE) {
+		diagfwd_disconnect_bridge(0);
+		diag_clear_hsic_tbl();
+	} else if (old_mode == NO_LOGGING_MODE && new_mode
+					== MEMORY_DEVICE_MODE) {
+		int i;
+		for (i = 0; i < MAX_HSIC_CH; i++)
+			if (diag_hsic[i].hsic_inited)
+				diag_hsic[i].hsic_data_requested =
+					driver->real_time_mode ? 1 : 0;
+		diagfwd_connect_bridge(0);
+	} else if (old_mode == USB_MODE && new_mode
+					 == NO_LOGGING_MODE) {
+		diagfwd_disconnect_bridge(0);
+	} else if (old_mode == NO_LOGGING_MODE && new_mode
+					== USB_MODE) {
+		diagfwd_connect_bridge(0);
+	} else if (old_mode == USB_MODE && new_mode
+					== MEMORY_DEVICE_MODE) {
+		if (driver->real_time_mode)
+			diagfwd_cancel_hsic(REOPEN_HSIC);
+		else
+			diagfwd_cancel_hsic(DONT_REOPEN_HSIC);
+		diagfwd_connect_bridge(0);
+	} else if (old_mode == MEMORY_DEVICE_MODE && new_mode
+					== USB_MODE) {
+		diag_clear_hsic_tbl();
+		diagfwd_cancel_hsic(REOPEN_HSIC);
+		diagfwd_connect_bridge(0);
+	}
+}
+#else
+void diag_cmp_logging_modes_diagfwd_bridge(int old_mode, int new_mode)
+{
+
+}
+#endif
+
+#ifdef CONFIG_DIAG_SDIO_PIPE
+void diag_cmp_logging_modes_sdio_pipe(int old_mode, int new_mode)
+{
+	if (old_mode == MEMORY_DEVICE_MODE && new_mode
+					== NO_LOGGING_MODE) {
+		mutex_lock(&driver->diagchar_mutex);
+		driver->in_busy_sdio = 1;
+		mutex_unlock(&driver->diagchar_mutex);
+	} else if (old_mode == NO_LOGGING_MODE && new_mode
+					== MEMORY_DEVICE_MODE) {
+		mutex_lock(&driver->diagchar_mutex);
+		driver->in_busy_sdio = 0;
+		mutex_unlock(&driver->diagchar_mutex);
+		/* Poll SDIO channel to check for data */
+		if (driver->sdio_ch)
+			queue_work(driver->diag_sdio_wq,
+				&(driver->diag_read_sdio_work));
+	} else if (old_mode == USB_MODE && new_mode
+					== MEMORY_DEVICE_MODE) {
+		mutex_lock(&driver->diagchar_mutex);
+		driver->in_busy_sdio = 0;
+		mutex_unlock(&driver->diagchar_mutex);
+		/* Poll SDIO channel to check for data */
+		if (driver->sdio_ch)
+			queue_work(driver->diag_sdio_wq,
+				&(driver->diag_read_sdio_work));
+	}
+}
+#else
+void diag_cmp_logging_modes_sdio_pipe(int old_mode, int new_mode)
+{
+
+}
+#endif
+
+int diag_switch_logging(unsigned long ioarg)
+{
+	int i, temp, success = -EINVAL, status;
+	int temp_realtime_mode = driver->real_time_mode;
+
+	mutex_lock(&driver->diagchar_mutex);
+	temp = driver->logging_mode;
+	driver->logging_mode = (int)ioarg;
+
+	if (driver->logging_mode == MEMORY_DEVICE_MODE_NRT) {
+		diag_send_diag_mode_update(MODE_NONREALTIME);
+		driver->logging_mode = MEMORY_DEVICE_MODE;
+	} else {
+		diag_send_diag_mode_update(MODE_REALTIME);
+	}
+
+	if (temp == driver->logging_mode) {
+		mutex_unlock(&driver->diagchar_mutex);
+		if (driver->logging_mode != MEMORY_DEVICE_MODE ||
+			temp_realtime_mode)
+			pr_info_ratelimited("diag: Already in logging mode change requested, mode: %d\n",
+					driver->logging_mode);
+		return 0;
+	}
+
+	if (driver->logging_mode == MEMORY_DEVICE_MODE) {
+		diag_clear_hsic_tbl();
+		driver->mask_check = 1;
+		if (driver->socket_process) {
+			/*
+			 * Notify the socket logging process that we
+			 * are switching to MEMORY_DEVICE_MODE
+			 */
+			status = send_sig(SIGCONT,
+				 driver->socket_process, 0);
+			if (status) {
+				pr_err("diag: %s, Error notifying ",
+					__func__);
+				pr_err("socket process, status: %d\n",
+					status);
+			}
+		}
+	} else if (driver->logging_mode == SOCKET_MODE) {
+		driver->socket_process = current;
+	} else if (driver->logging_mode == CALLBACK_MODE) {
+		driver->callback_process = current;
+	}
+
+	if (driver->logging_mode == UART_MODE ||
+				driver->logging_mode == SOCKET_MODE ||
+				driver->logging_mode == CALLBACK_MODE) {
+		diag_clear_hsic_tbl();
+		driver->mask_check = 0;
+		driver->logging_mode = MEMORY_DEVICE_MODE;
+	}
+
+	driver->logging_process_id = current->tgid;
+	mutex_unlock(&driver->diagchar_mutex);
+
+	if (temp == MEMORY_DEVICE_MODE && driver->logging_mode
+						== NO_LOGGING_MODE) {
+		for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) {
+			driver->smd_data[i].in_busy_1 = 0;
+			driver->smd_data[i].in_busy_2 = 0;
+		}
+		diag_cmp_logging_modes_sdio_pipe(temp, driver->logging_mode);
+		diag_cmp_logging_modes_diagfwd_bridge(temp,
+							driver->logging_mode);
+	} else if (temp == NO_LOGGING_MODE && driver->logging_mode
+						== MEMORY_DEVICE_MODE) {
+		for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) {
+			driver->smd_data[i].in_busy_1 = 0;
+			driver->smd_data[i].in_busy_2 = 0;
+			/* Poll SMD channels to check for data*/
+			if (driver->smd_data[i].ch)
+				queue_work(driver->diag_wq,
+					&(driver->smd_data[i].
+						diag_read_smd_work));
+		}
+		diag_cmp_logging_modes_sdio_pipe(temp,
+						driver->logging_mode);
+		diag_cmp_logging_modes_diagfwd_bridge(temp,
+						driver->logging_mode);
+	} else if (temp == USB_MODE && driver->logging_mode
+						 == NO_LOGGING_MODE) {
+		diagfwd_disconnect();
+		diag_cmp_logging_modes_diagfwd_bridge(temp,
+						driver->logging_mode);
+	} else if (temp == NO_LOGGING_MODE && driver->logging_mode
+							== USB_MODE) {
+		diagfwd_connect();
+		diag_cmp_logging_modes_diagfwd_bridge(temp,
+						driver->logging_mode);
+	} else if (temp == USB_MODE && driver->logging_mode
+						== MEMORY_DEVICE_MODE) {
+		diagfwd_disconnect();
+		for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) {
+			driver->smd_data[i].in_busy_1 = 0;
+			driver->smd_data[i].in_busy_2 = 0;
+			/* Poll SMD channels to check for data*/
+			if (driver->smd_data[i].ch)
+				queue_work(driver->diag_wq,
+					&(driver->smd_data[i].
+						diag_read_smd_work));
+		}
+		diag_cmp_logging_modes_sdio_pipe(temp, driver->logging_mode);
+		diag_cmp_logging_modes_diagfwd_bridge(temp,
+						driver->logging_mode);
+	} else if (temp == MEMORY_DEVICE_MODE &&
+			 driver->logging_mode == USB_MODE) {
+		diagfwd_connect();
+		diag_cmp_logging_modes_diagfwd_bridge(temp,
+						driver->logging_mode);
+	}
+	success = 1;
+	return success;
+}
+
+long diagchar_ioctl(struct file *filp,
+			   unsigned int iocmd, unsigned long ioarg)
+{
+	int i, result = -EINVAL, interim_size = 0, client_id = 0;
+	uint16_t support_list = 0, interim_rsp_id, remote_dev;
+	struct diag_dci_client_tbl *dci_params;
+	struct diag_dci_health_stats stats;
+	struct diag_log_event_stats le_stats;
+	struct diagpkt_delay_params delay_params;
+
+	switch (iocmd) {
+	case DIAG_IOCTL_COMMAND_REG:
+		result = diag_command_reg(ioarg);
+		break;
+	case DIAG_IOCTL_GET_DELAYED_RSP_ID:
 		if (copy_from_user(&delay_params, (void *)ioarg,
-					   sizeof(struct diagpkt_delay_params)))
+					sizeof(struct diagpkt_delay_params)))
 			return -EFAULT;
 		if ((delay_params.rsp_ptr) &&
 		 (delay_params.size == sizeof(delayed_rsp_id)) &&
@@ -569,9 +925,10 @@
 			if (copy_to_user((void *)delay_params.num_bytes_ptr,
 						 &interim_size, sizeof(int)))
 				return -EFAULT;
-			success = 0;
+			result = 0;
 		}
-	} else if (iocmd == DIAG_IOCTL_DCI_REG) {
+		break;
+	case DIAG_IOCTL_DCI_REG:
 		if (driver->dci_state == DIAG_DCI_NO_REG)
 			return DIAG_DCI_NO_REG;
 		if (driver->num_dci_client >= MAX_DCI_CLIENTS)
@@ -583,8 +940,10 @@
 			return -ENOMEM;
 		}
 		if (copy_from_user(dci_params, (void *)ioarg,
-				 sizeof(struct diag_dci_client_tbl)))
+				 sizeof(struct diag_dci_client_tbl))) {
+			kfree(dci_params);
 			return -EFAULT;
+		}
 		mutex_lock(&driver->dci_mutex);
 		if (!(driver->num_dci_client))
 			for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++)
@@ -616,30 +975,49 @@
 				break;
 			}
 		}
-		mutex_unlock(&driver->dci_mutex);
 		kfree(dci_params);
-		return driver->dci_client_id;
-	} else if (iocmd == DIAG_IOCTL_DCI_DEINIT) {
-		success = -1;
+		mutex_unlock(&driver->dci_mutex);
+		result = driver->dci_client_id;
+		break;
+	case DIAG_IOCTL_DCI_DEINIT:
+		result = -EIO;
 		/* Delete this process from DCI table */
 		mutex_lock(&driver->dci_mutex);
-		for (i = 0; i < dci_max_reg; i++)
-			if (driver->req_tracking_tbl[i].pid == current->tgid)
-				driver->req_tracking_tbl[i].pid = 0;
-		for (i = 0; i < MAX_DCI_CLIENTS; i++) {
-			if (driver->dci_client_tbl[i].client &&
-			driver->dci_client_tbl[i].client->tgid ==
-							 current->tgid) {
-				driver->dci_client_tbl[i].client = NULL;
-				success = i;
-				break;
+		i = diag_dci_find_client_index(current->tgid);
+		if (i == DCI_CLIENT_INDEX_INVALID) {
+			result = DIAG_DCI_NOT_SUPPORTED;
+		} else {
+			/* clear respective cumulative log masks */
+			clear_client_dci_cumulative_log_mask(i);
+			/* send updated log mask to peripherals */
+			result =
+			diag_send_dci_log_mask(driver->smd_cntl[MODEM_DATA].ch);
+			if (result != DIAG_DCI_NO_ERROR) {
+				mutex_unlock(&driver->dci_mutex);
+				return result;
 			}
-		}
-		if (success >= 0)
+			/* clear respective cumulative event masks */
+			clear_client_dci_cumulative_event_mask(i);
+			/* send updated event mask to peripherals */
+			result =
+			diag_send_dci_event_mask(
+				driver->smd_cntl[MODEM_DATA].ch);
+			if (result != DIAG_DCI_NO_ERROR) {
+				mutex_unlock(&driver->dci_mutex);
+				return result;
+			}
+			result = i;
+			/* Delete this process from DCI table */
+			for (i = 0; i < dci_max_reg; i++)
+				if (driver->req_tracking_tbl[i].pid ==
+					 current->tgid)
+					driver->req_tracking_tbl[i].pid = 0;
+			driver->dci_client_tbl[result].client = NULL;
 			driver->num_dci_client--;
+		}
 		mutex_unlock(&driver->dci_mutex);
-		return success;
-	} else if (iocmd == DIAG_IOCTL_DCI_SUPPORT) {
+		break;
+	case DIAG_IOCTL_DCI_SUPPORT:
 		for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++) {
 			if (driver->smd_dci[i].ch)
 				support_list |=
@@ -648,35 +1026,69 @@
 		if (copy_to_user((void *)ioarg, &support_list,
 							 sizeof(uint16_t)))
 			return -EFAULT;
-		return DIAG_DCI_NO_ERROR;
-	} else if (iocmd == DIAG_IOCTL_DCI_HEALTH_STATS) {
+		result = DIAG_DCI_NO_ERROR;
+		break;
+	case DIAG_IOCTL_DCI_HEALTH_STATS:
 		if (copy_from_user(&stats, (void *)ioarg,
 				 sizeof(struct diag_dci_health_stats)))
 			return -EFAULT;
-		for (i = 0; i < MAX_DCI_CLIENTS; i++) {
+		mutex_lock(&dci_health_mutex);
+		i = diag_dci_find_client_index(current->tgid);
+		if (i != DCI_CLIENT_INDEX_INVALID) {
 			dci_params = &(driver->dci_client_tbl[i]);
-			if (dci_params->client &&
-				dci_params->client->tgid == current->tgid) {
-				stats.dropped_logs = dci_params->dropped_logs;
-				stats.dropped_events =
-						 dci_params->dropped_events;
-				stats.received_logs = dci_params->received_logs;
-				stats.received_events =
-						 dci_params->received_events;
-				if (stats.reset_status) {
-					dci_params->dropped_logs = 0;
-					dci_params->dropped_events = 0;
-					dci_params->received_logs = 0;
-					dci_params->received_events = 0;
-				}
-				break;
+			stats.dropped_logs = dci_params->dropped_logs;
+			stats.dropped_events =
+					dci_params->dropped_events;
+			stats.received_logs =
+					dci_params->received_logs;
+			stats.received_events =
+					dci_params->received_events;
+			if (stats.reset_status) {
+				dci_params->dropped_logs = 0;
+				dci_params->dropped_events = 0;
+				dci_params->received_logs = 0;
+				dci_params->received_events = 0;
 			}
 		}
+		mutex_unlock(&dci_health_mutex);
 		if (copy_to_user((void *)ioarg, &stats,
 				   sizeof(struct diag_dci_health_stats)))
 			return -EFAULT;
-		return DIAG_DCI_NO_ERROR;
-	} else if (iocmd == DIAG_IOCTL_LSM_DEINIT) {
+		result = DIAG_DCI_NO_ERROR;
+		break;
+	case DIAG_IOCTL_DCI_LOG_STATUS:
+		if (copy_from_user(&le_stats, (void *)ioarg,
+				sizeof(struct diag_log_event_stats)))
+			return -EFAULT;
+		le_stats.is_set = diag_dci_query_log_mask(le_stats.code);
+		if (copy_to_user((void *)ioarg, &le_stats,
+				sizeof(struct diag_log_event_stats)))
+			return -EFAULT;
+		result = DIAG_DCI_NO_ERROR;
+		break;
+	case DIAG_IOCTL_DCI_EVENT_STATUS:
+		if (copy_from_user(&le_stats, (void *)ioarg,
+					sizeof(struct diag_log_event_stats)))
+			return -EFAULT;
+		le_stats.is_set = diag_dci_query_event_mask(le_stats.code);
+		if (copy_to_user((void *)ioarg, &le_stats,
+				sizeof(struct diag_log_event_stats)))
+			return -EFAULT;
+		result = DIAG_DCI_NO_ERROR;
+		break;
+	case DIAG_IOCTL_DCI_CLEAR_LOGS:
+		if (copy_from_user((void *)&client_id, (void *)ioarg,
+				sizeof(int)))
+			return -EFAULT;
+		result = diag_dci_clear_log_mask();
+		break;
+	case DIAG_IOCTL_DCI_CLEAR_EVENTS:
+		if (copy_from_user(&client_id, (void *)ioarg,
+				sizeof(int)))
+			return -EFAULT;
+		result = diag_dci_clear_event_mask();
+		break;
+	case DIAG_IOCTL_LSM_DEINIT:
 		for (i = 0; i < driver->num_clients; i++)
 			if (driver->client_map[i].pid == current->tgid)
 				break;
@@ -684,138 +1096,20 @@
 			return -EINVAL;
 		driver->data_ready[i] |= DEINIT_TYPE;
 		wake_up_interruptible(&driver->wait_q);
-		success = 1;
-	} else if (iocmd == DIAG_IOCTL_SWITCH_LOGGING) {
-		mutex_lock(&driver->diagchar_mutex);
-		temp = driver->logging_mode;
-		driver->logging_mode = (int)ioarg;
-		if (temp == driver->logging_mode) {
-			mutex_unlock(&driver->diagchar_mutex);
-			pr_alert("diag: forbidden logging change requested\n");
-			return 0;
-		}
-		if (driver->logging_mode == MEMORY_DEVICE_MODE) {
-			diag_clear_hsic_tbl();
-			driver->mask_check = 1;
-			if (driver->socket_process) {
-				/*
-				 * Notify the socket logging process that we
-				 * are switching to MEMORY_DEVICE_MODE
-				 */
-				status = send_sig(SIGCONT,
-					 driver->socket_process, 0);
-				if (status) {
-					pr_err("diag: %s, Error notifying ",
-						__func__);
-					pr_err("socket process, status: %d\n",
-						status);
-				}
-			}
-		}
-		if (driver->logging_mode == SOCKET_MODE)
-			driver->socket_process = current;
-		if (driver->logging_mode == CALLBACK_MODE)
-			driver->callback_process = current;
-		if (driver->logging_mode == UART_MODE ||
-			driver->logging_mode == SOCKET_MODE ||
-			driver->logging_mode == CALLBACK_MODE) {
-			diag_clear_hsic_tbl();
-			driver->mask_check = 0;
-			driver->logging_mode = MEMORY_DEVICE_MODE;
-		}
-		driver->logging_process_id = current->tgid;
-		mutex_unlock(&driver->diagchar_mutex);
-		if (temp == MEMORY_DEVICE_MODE && driver->logging_mode
-							== NO_LOGGING_MODE) {
-			for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) {
-				driver->smd_data[i].in_busy_1 = 0;
-				driver->smd_data[i].in_busy_2 = 0;
-			}
-#ifdef CONFIG_DIAG_SDIO_PIPE
-			driver->in_busy_sdio = 1;
-#endif
-#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-			diagfwd_disconnect_bridge(0);
-			diag_clear_hsic_tbl();
-#endif
-		} else if (temp == NO_LOGGING_MODE && driver->logging_mode
-							== MEMORY_DEVICE_MODE) {
-			for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) {
-				driver->smd_data[i].in_busy_1 = 0;
-				driver->smd_data[i].in_busy_2 = 0;
-				/* Poll SMD channels to check for data*/
-				if (driver->smd_data[i].ch)
-					queue_work(driver->diag_wq,
-						&(driver->smd_data[i].
-							diag_read_smd_work));
-			}
-#ifdef CONFIG_DIAG_SDIO_PIPE
-			driver->in_busy_sdio = 0;
-			/* Poll SDIO channel to check for data */
-			if (driver->sdio_ch)
-				queue_work(driver->diag_sdio_wq,
-					&(driver->diag_read_sdio_work));
-#endif
-#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-			diagfwd_connect_bridge(0);
-#endif
-		}
-#ifdef CONFIG_DIAG_OVER_USB
-		else if (temp == USB_MODE && driver->logging_mode
-							 == NO_LOGGING_MODE) {
-			diagfwd_disconnect();
-#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-			diagfwd_disconnect_bridge(0);
-#endif
-		} else if (temp == NO_LOGGING_MODE && driver->logging_mode
-								== USB_MODE) {
-			diagfwd_connect();
-#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-			diagfwd_connect_bridge(0);
-#endif
-		} else if (temp == USB_MODE && driver->logging_mode
-							== MEMORY_DEVICE_MODE) {
-			diagfwd_disconnect();
-			for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) {
-				driver->smd_data[i].in_busy_1 = 0;
-				driver->smd_data[i].in_busy_2 = 0;
-				/* Poll SMD channels to check for data*/
-				if (driver->smd_data[i].ch)
-					queue_work(driver->diag_wq,
-						&(driver->smd_data[i].
-							diag_read_smd_work));
-			}
-#ifdef CONFIG_DIAG_SDIO_PIPE
-			driver->in_busy_sdio = 0;
-			/* Poll SDIO channel to check for data */
-			if (driver->sdio_ch)
-				queue_work(driver->diag_sdio_wq,
-					&(driver->diag_read_sdio_work));
-#endif
-#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-			diagfwd_cancel_hsic();
-			diagfwd_connect_bridge(0);
-#endif
-		} else if (temp == MEMORY_DEVICE_MODE &&
-				 driver->logging_mode == USB_MODE) {
-			diagfwd_connect();
-#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-			diag_clear_hsic_tbl();
-			diagfwd_cancel_hsic();
-			diagfwd_connect_bridge(0);
-#endif
-		}
-#endif /* DIAG over USB */
-		success = 1;
-	} else if (iocmd == DIAG_IOCTL_REMOTE_DEV) {
-		uint16_t remote_dev = diag_get_remote_device_mask();
+		result = 1;
+		break;
+	case DIAG_IOCTL_SWITCH_LOGGING:
+		result = diag_switch_logging(ioarg);
+		break;
+	case DIAG_IOCTL_REMOTE_DEV:
+		remote_dev = diag_get_remote_device_mask();
 		if (copy_to_user((void *)ioarg, &remote_dev, sizeof(uint16_t)))
-			success = -EFAULT;
+			result = -EFAULT;
 		else
-			success = 1;
+			result = 1;
+		break;
 	}
-
-	return success;
+	return result;
 }
 
 static int diagchar_read(struct file *file, char __user *buf, size_t count,
@@ -825,6 +1119,8 @@
 	int index = -1, i = 0, ret = 0;
 	int num_data = 0, data_type;
 	int remote_token;
+	int exit_stat;
+	int clear_read_wakelock;
 
 	for (i = 0; i < driver->num_clients; i++)
 		if (driver->client_map[i].pid == current->tgid)
@@ -839,12 +1135,9 @@
 				  driver->data_ready[index]);
 	mutex_lock(&driver->diagchar_mutex);
 
+	clear_read_wakelock = 0;
 	if ((driver->data_ready[index] & USER_SPACE_DATA_TYPE) && (driver->
 					logging_mode == MEMORY_DEVICE_MODE)) {
-#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-		unsigned long spin_lock_flags;
-		struct diag_write_device hsic_buf_tbl[NUM_HSIC_BUF_TBL_ENTRIES];
-#endif
 		remote_token = 0;
 		pr_debug("diag: process woken up\n");
 		/*Copy the type of data being passed*/
@@ -904,6 +1197,10 @@
 				COPY_USER_SPACE_OR_EXIT(buf+ret,
 					*(data->buf_in_1),
 					data->write_ptr_1->length);
+				if (!driver->real_time_mode) {
+					process_lock_on_copy(&data->nrt_lock);
+					clear_read_wakelock++;
+				}
 				data->in_busy_1 = 0;
 			}
 			if (data->in_busy_2 == 1) {
@@ -915,6 +1212,10 @@
 				COPY_USER_SPACE_OR_EXIT(buf+ret,
 					*(data->buf_in_2),
 					data->write_ptr_2->length);
+				if (!driver->real_time_mode) {
+					process_lock_on_copy(&data->nrt_lock);
+					clear_read_wakelock++;
+				}
 				data->in_busy_2 = 0;
 			}
 		}
@@ -937,87 +1238,15 @@
 			driver->in_busy_sdio = 0;
 		}
 #endif
-#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
-		spin_lock_irqsave(&diag_hsic[HSIC].hsic_spinlock,
-							spin_lock_flags);
-		for (i = 0; i < diag_hsic[HSIC].poolsize_hsic_write; i++) {
-			hsic_buf_tbl[i].buf =
-					diag_hsic[HSIC].hsic_buf_tbl[i].buf;
-			diag_hsic[HSIC].hsic_buf_tbl[i].buf = 0;
-			hsic_buf_tbl[i].length =
-					diag_hsic[HSIC].hsic_buf_tbl[i].length;
-			diag_hsic[HSIC].hsic_buf_tbl[i].length = 0;
-		}
-		diag_hsic[HSIC].num_hsic_buf_tbl_entries = 0;
-		spin_unlock_irqrestore(&diag_hsic[HSIC].hsic_spinlock,
-					spin_lock_flags);
+		/* Copy date from remote processors */
+		exit_stat = diag_copy_remote(buf, count, &ret, &num_data);
+		if (exit_stat == 1)
+			goto exit;
 
-		remote_token = diag_get_remote(MDM);
-		for (i = 0; i < diag_hsic[HSIC].poolsize_hsic_write; i++) {
-			if (hsic_buf_tbl[i].length > 0) {
-				pr_debug("diag: HSIC copy to user, i: %d, buf: %x, len: %d\n",
-					 i, (unsigned int)hsic_buf_tbl[i].buf,
-					hsic_buf_tbl[i].length);
-				num_data++;
-
-				/* Copy the negative token */
-				if (copy_to_user(buf+ret,
-						&remote_token, 4)) {
-					num_data--;
-					goto drop_hsic;
-				}
-				ret += 4;
-
-				/* Copy the length of data being passed */
-				if (copy_to_user(buf+ret,
-					(void *)&(hsic_buf_tbl[i].length),
-					4)) {
-					num_data--;
-					goto drop_hsic;
-				}
-				ret += 4;
-
-				/* Copy the actual data being passed */
-				if (copy_to_user(buf+ret,
-						(void *)hsic_buf_tbl[i].buf,
-						hsic_buf_tbl[i].length)) {
-					ret -= 4;
-					num_data--;
-					goto drop_hsic;
-				}
-				ret += hsic_buf_tbl[i].length;
-drop_hsic:
-				/* Return the buffer to the pool */
-				diagmem_free(driver,
-					(unsigned char *)(hsic_buf_tbl[i].buf),
-					POOL_TYPE_HSIC);
-
-				/* Call the write complete function */
-				diagfwd_write_complete_hsic(NULL);
-			}
-		}
-		if (driver->in_busy_smux == 1) {
-			remote_token = diag_get_remote(QSC);
-			num_data++;
-
-			/* Copy the negative  token of data being passed */
-			COPY_USER_SPACE_OR_EXIT(buf+ret,
-						remote_token, 4);
-			/* Copy the length of data being passed */
-			COPY_USER_SPACE_OR_EXIT(buf+ret,
-					(driver->write_ptr_mdm->length), 4);
-			/* Copy the actual data being passed */
-			COPY_USER_SPACE_OR_EXIT(buf+ret,
-					*(driver->buf_in_smux),
-					driver->write_ptr_mdm->length);
-			pr_debug("diag: SMUX  data copied\n");
-			driver->in_busy_smux = 0;
-		}
-#endif
 		/* copy number of data fields */
 		COPY_USER_SPACE_OR_EXIT(buf+4, num_data, 4);
 		ret -= 4;
-		driver->data_ready[index] ^= USER_SPACE_DATA_TYPE;
+		diag_update_data_ready(index);
 		for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) {
 			if (driver->smd_data[i].ch)
 				queue_work(driver->diag_wq,
@@ -1081,6 +1310,7 @@
 		COPY_USER_SPACE_OR_EXIT(buf+4, *(driver->pkt_buf),
 							 driver->pkt_length);
 		driver->data_ready[index] ^= PKT_TYPE;
+		driver->in_busy_pktdata = 0;
 		goto exit;
 	}
 
@@ -1112,6 +1342,11 @@
 		goto exit;
 	}
 exit:
+	if (clear_read_wakelock) {
+		for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++)
+			process_lock_on_copy_complete(
+				&driver->smd_data[i].nrt_lock);
+	}
 	mutex_unlock(&driver->diagchar_mutex);
 	return ret;
 }
@@ -1128,13 +1363,7 @@
 	struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
 	void *buf_copy = NULL;
 	unsigned int payload_size;
-#ifdef CONFIG_DIAG_OVER_USB
-	if (((driver->logging_mode == USB_MODE) && (!driver->usb_connected)) ||
-				(driver->logging_mode == NO_LOGGING_MODE)) {
-		/*Drop the diag payload */
-		return -EIO;
-	}
-#endif /* DIAG over USB */
+
 	index = 0;
 	/* Get the packet type F3/log/event/Pkt response */
 	err = copy_from_user((&pkt_type), buf, 4);
@@ -1150,6 +1379,14 @@
 		driver->dropped_count++;
 		return -EBADMSG;
 	}
+#ifdef CONFIG_DIAG_OVER_USB
+	if (((pkt_type != DCI_DATA_TYPE) && (driver->logging_mode == USB_MODE)
+				&& (!driver->usb_connected)) ||
+				(driver->logging_mode == NO_LOGGING_MODE)) {
+		/*Drop the diag payload */
+		return -EIO;
+	}
+#endif /* DIAG over USB */
 	if (pkt_type == DCI_DATA_TYPE) {
 		err = copy_from_user(driver->user_space_data, buf + 4,
 							 payload_size);
@@ -1161,9 +1398,124 @@
 							payload_size);
 		return err;
 	}
+	if (pkt_type == CALLBACK_DATA_TYPE) {
+		err = copy_from_user(driver->user_space_data, buf + 4,
+							 payload_size);
+		 if (err) {
+			pr_err("diag: copy failed for user space data\n");
+			return -EIO;
+		}
+		/* Check for proc_type */
+		remote_proc = diag_get_remote(*(int *)driver->user_space_data);
+
+		if (!remote_proc) {
+			wait_event_interruptible(driver->wait_q,
+				 (driver->in_busy_pktdata == 0));
+			return diag_process_apps_pkt(driver->user_space_data,
+							payload_size);
+		}
+		/* The packet is for the remote processor */
+		token_offset = 4;
+		payload_size -= 4;
+		buf += 4;
+		/* Perform HDLC encoding on incoming data */
+		send.state = DIAG_STATE_START;
+		send.pkt = (void *)(driver->user_space_data + token_offset);
+		send.last = (void *)(driver->user_space_data + token_offset -
+							1 + payload_size);
+		send.terminate = 1;
+
+		mutex_lock(&driver->diagchar_mutex);
+		if (!buf_hdlc)
+			buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE,
+							POOL_TYPE_HDLC);
+		if (!buf_hdlc) {
+			ret = -ENOMEM;
+			goto fail_free_hdlc;
+		}
+		if (HDLC_OUT_BUF_SIZE < (2 * payload_size) + 3) {
+			pr_err("diag: Dropping packet, HDLC encoded packet payload size crosses buffer limit. Current payload size %d\n",
+					((2*payload_size) + 3));
+			driver->dropped_count++;
+			ret = -EBADMSG;
+			diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC);
+			goto fail_free_hdlc;
+		}
+		enc.dest = buf_hdlc + driver->used;
+		enc.dest_last = (void *)(buf_hdlc + driver->used +
+					(2 * payload_size) + token_offset - 1);
+		diag_hdlc_encode(&send, &enc);
+
+#ifdef CONFIG_DIAG_SDIO_PIPE
+		/* send masks to 9k too */
+		if (driver->sdio_ch && (remote_proc == MDM)) {
+			wait_event_interruptible(driver->wait_q,
+				 (sdio_write_avail(driver->sdio_ch) >=
+					 payload_size));
+			if (driver->sdio_ch && (payload_size > 0)) {
+				sdio_write(driver->sdio_ch, (void *)
+				   (char *)buf_hdlc, payload_size + 3);
+			}
+		}
+#endif
+#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
+		/* send masks to All 9k */
+		if ((remote_proc >= MDM) && (remote_proc <= MDM4)) {
+			index = remote_proc - MDM;
+			if (diag_hsic[index].hsic_ch && (payload_size > 0)) {
+				/* wait sending mask updates
+				 * if HSIC ch not ready */
+				if (diag_hsic[index].in_busy_hsic_write)
+					wait_event_interruptible(driver->wait_q,
+						(diag_hsic[index].
+						 in_busy_hsic_write != 1));
+				diag_hsic[index].in_busy_hsic_write = 1;
+				diag_hsic[index].in_busy_hsic_read_on_device =
+									0;
+				err = diag_bridge_write(index,
+					(char *)buf_hdlc, payload_size + 3);
+				if (err) {
+					pr_err("diag: err sending mask to MDM: %d\n",
+					       err);
+					/*
+					* If the error is recoverable, then
+					* clear the write flag, so we will
+					* resubmit a write on the next frame.
+					* Otherwise, don't resubmit a write
+					* on the next frame.
+					*/
+					if ((-ESHUTDOWN) != err)
+						diag_hsic[index].
+							in_busy_hsic_write = 0;
+				 }
+			 }
+		}
+		if (driver->diag_smux_enabled && (remote_proc == QSC)
+						&& driver->lcid) {
+			if (payload_size > 0) {
+				err = msm_smux_write(driver->lcid, NULL,
+					(char *)buf_hdlc, payload_size + 3);
+				if (err) {
+					pr_err("diag:send mask to MDM err %d",
+							err);
+					ret = err;
+				}
+			}
+		}
+#endif
+		diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC);
+		buf_hdlc = NULL;
+		driver->used = 0;
+		mutex_unlock(&driver->diagchar_mutex);
+		return ret;
+	}
 	if (pkt_type == USER_SPACE_DATA_TYPE) {
 		err = copy_from_user(driver->user_space_data, buf + 4,
 							 payload_size);
+		if (err) {
+			pr_err("diag: copy failed for user space data\n");
+			return -EIO;
+		}
 		/* Check for proc_type */
 		remote_proc = diag_get_remote(*(int *)driver->user_space_data);
 
@@ -1203,9 +1555,19 @@
 #endif
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
 		/* send masks to All 9k */
-		for (index = 0; index < MAX_HSIC_CH; index++) {
-			if (diag_hsic[index].hsic_ch && (payload_size > 0) &&
-							 (remote_proc == MDM)) {
+		if ((remote_proc >= MDM) && (remote_proc <= MDM4) &&
+							(payload_size > 0)) {
+			index = remote_proc - MDM;
+			/*
+			 * If hsic data is being requested for this remote
+			 * processor and its hsic in not open
+			 */
+			if (!diag_hsic[index].hsic_device_opened) {
+				diag_hsic[index].hsic_data_requested = 1;
+				connect_bridge(0, index);
+			}
+
+			if (diag_hsic[index].hsic_ch) {
 				/* wait sending mask updates
 				 * if HSIC ch not ready */
 				if (diag_hsic[index].in_busy_hsic_write)
@@ -1589,6 +1951,7 @@
 		driver->socket_process = NULL;
 		driver->callback_process = NULL;
 		driver->mask_check = 0;
+		driver->in_busy_pktdata = 0;
 		mutex_init(&driver->diagchar_mutex);
 		init_waitqueue_head(&driver->wait_q);
 		init_waitqueue_head(&driver->smd_wait_q);
@@ -1597,6 +1960,7 @@
 		diag_masks_init();
 		diagfwd_init();
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
+		spin_lock_init(&driver->hsic_ready_spinlock);
 		diagfwd_bridge_init(HSIC);
 		diagfwd_bridge_init(HSIC_2);
 		/* register HSIC device */
diff --git a/drivers/char/diag/diagchar_hdlc.c b/drivers/char/diag/diagchar_hdlc.c
index 74dcb6b..2369c4d 100644
--- a/drivers/char/diag/diagchar_hdlc.c
+++ b/drivers/char/diag/diagchar_hdlc.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2008-2009, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2012-2013, The Linux Foundation.
+ * 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 and
@@ -172,11 +173,14 @@
 	uint8_t src_byte;
 
 	int pkt_bnd = 0;
+	int msg_start;
 
 	if (hdlc && hdlc->src_ptr && hdlc->dest_ptr &&
 	    (hdlc->src_size - hdlc->src_idx > 0) &&
 	    (hdlc->dest_size - hdlc->dest_idx > 0)) {
 
+		msg_start = (hdlc->src_idx == 0) ? 1 : 0;
+
 		src_ptr = hdlc->src_ptr;
 		src_ptr = &src_ptr[hdlc->src_idx];
 		src_length = hdlc->src_size - hdlc->src_idx;
@@ -203,8 +207,16 @@
 				}
 			} else if (src_byte == CONTROL_CHAR) {
 				dest_ptr[len++] = src_byte;
-				pkt_bnd = 1;
+				/*
+				 * If this is the first byte in the message,
+				 * then it is part of the command. Otherwise,
+				 * consider it as the last byte of the
+				 * message.
+				 */
+				if (msg_start && i == 0 && src_length > 1)
+					continue;
 				i++;
+				pkt_bnd = 1;
 				break;
 			} else {
 				dest_ptr[len++] = src_byte;
diff --git a/drivers/char/diag/diagchar_hdlc.h b/drivers/char/diag/diagchar_hdlc.h
index 116c980..e3378ac 100644
--- a/drivers/char/diag/diagchar_hdlc.h
+++ b/drivers/char/diag/diagchar_hdlc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2012, The Linux Foundation. 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 and
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 21ad9ec..a4003ff 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -98,7 +98,7 @@
 
 int chk_config_get_id(void)
 {
-	/* For all Fusion targets, Modem will always be present */
+	/* For all Fusion targets,  Modem will always be present */
 	if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
 		return 0;
 
@@ -227,6 +227,93 @@
 	}
 }
 
+void process_lock_enabling(struct diag_nrt_wake_lock *lock, int real_time)
+{
+	unsigned long read_lock_flags;
+
+	spin_lock_irqsave(&lock->read_spinlock, read_lock_flags);
+	if (real_time)
+		lock->enabled = 0;
+	else
+		lock->enabled = 1;
+	lock->ref_count = 0;
+	lock->copy_count = 0;
+	wake_unlock(&lock->read_lock);
+	spin_unlock_irqrestore(&lock->read_spinlock, read_lock_flags);
+}
+
+void process_lock_on_notify(struct diag_nrt_wake_lock *lock)
+{
+	unsigned long read_lock_flags;
+
+	spin_lock_irqsave(&lock->read_spinlock, read_lock_flags);
+	/*
+	 * Do not work with ref_count here in case
+	 * of spurious interrupt
+	 */
+	if (lock->enabled)
+		wake_lock(&lock->read_lock);
+	spin_unlock_irqrestore(&lock->read_spinlock, read_lock_flags);
+}
+
+void process_lock_on_read(struct diag_nrt_wake_lock *lock, int pkt_len)
+{
+	unsigned long read_lock_flags;
+
+	spin_lock_irqsave(&lock->read_spinlock, read_lock_flags);
+	if (lock->enabled) {
+		if (pkt_len > 0) {
+			/*
+			 * We have an data that is read that
+			 * needs to be processed, make sure the
+			 * processor does not go to sleep
+			 */
+			lock->ref_count++;
+			if (!wake_lock_active(&lock->read_lock))
+				wake_lock(&lock->read_lock);
+		} else {
+			/*
+			 * There was no data associated with the
+			 * read from the smd, unlock the wake lock
+			 * if it is not needed.
+			 */
+			if (lock->ref_count < 1) {
+				if (wake_lock_active(&lock->read_lock))
+					wake_unlock(&lock->read_lock);
+				lock->ref_count = 0;
+				lock->copy_count = 0;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&lock->read_spinlock, read_lock_flags);
+}
+
+void process_lock_on_copy(struct diag_nrt_wake_lock *lock)
+{
+	unsigned long read_lock_flags;
+
+	spin_lock_irqsave(&lock->read_spinlock, read_lock_flags);
+	if (lock->enabled)
+		lock->copy_count++;
+	spin_unlock_irqrestore(&lock->read_spinlock, read_lock_flags);
+}
+
+void process_lock_on_copy_complete(struct diag_nrt_wake_lock *lock)
+{
+	unsigned long read_lock_flags;
+
+	spin_lock_irqsave(&lock->read_spinlock, read_lock_flags);
+	if (lock->enabled) {
+		lock->ref_count -= lock->copy_count;
+		if (lock->ref_count < 1) {
+			wake_unlock(&lock->read_lock);
+			lock->ref_count = 0;
+		}
+		lock->copy_count = 0;
+	}
+	spin_unlock_irqrestore(&lock->read_spinlock, read_lock_flags);
+}
+
 /* Process the data read from the smd data channel */
 int diag_process_smd_read_data(struct diag_smd_info *smd_info, void *buf,
 								int total_recd)
@@ -324,6 +411,8 @@
 			smd_read(smd_info->ch, temp_buf, r);
 			temp_buf += r;
 		}
+		if (!driver->real_time_mode && smd_info->type == SMD_DATA_TYPE)
+			process_lock_on_read(&smd_info->nrt_lock, pkt_len);
 
 		if (total_recd > 0) {
 			if (!buf) {
@@ -351,12 +440,32 @@
 	diag_smd_send_req(smd_info);
 }
 
+#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
+static void diag_mem_dev_mode_ready_update(int index, int hsic_updated)
+{
+	if (hsic_updated) {
+		unsigned long flags;
+		spin_lock_irqsave(&driver->hsic_ready_spinlock, flags);
+		driver->data_ready[index] |= USER_SPACE_DATA_TYPE;
+		spin_unlock_irqrestore(&driver->hsic_ready_spinlock, flags);
+	} else {
+		driver->data_ready[index] |= USER_SPACE_DATA_TYPE;
+	}
+}
+#else
+static void diag_mem_dev_mode_ready_update(int index, int hsic_updated)
+{
+	(void) hsic_updated;
+	driver->data_ready[index] |= USER_SPACE_DATA_TYPE;
+}
+#endif
 int diag_device_write(void *buf, int data_type, struct diag_request *write_ptr)
 {
 	int i, err = 0, index;
 	index = 0;
 
 	if (driver->logging_mode == MEMORY_DEVICE_MODE) {
+		int hsic_updated = 0;
 		if (data_type == APPS_DATA) {
 			for (i = 0; i < driver->poolsize_write_struct; i++)
 				if (driver->buf_tbl[i].length == 0) {
@@ -377,6 +486,7 @@
 		else if (data_type == HSIC_DATA || data_type == HSIC_2_DATA) {
 			unsigned long flags;
 			int foundIndex = -1;
+			hsic_updated = 1;
 			index = data_type - HSIC_DATA;
 			spin_lock_irqsave(&diag_hsic[index].hsic_spinlock,
 									flags);
@@ -409,7 +519,7 @@
 						 driver->logging_process_id)
 				break;
 		if (i < driver->num_clients) {
-			driver->data_ready[i] |= USER_SPACE_DATA_TYPE;
+			diag_mem_dev_mode_ready_update(i, hsic_updated);
 			pr_debug("diag: wake up logging process\n");
 			wake_up_interruptible(&driver->wait_q);
 		} else
@@ -531,9 +641,10 @@
 	unsigned char *temp = buf;
 
 	mutex_lock(&driver->diagchar_mutex);
-	if (CHK_OVERFLOW(ptr, ptr, ptr + PKT_SIZE, driver->pkt_length))
+	if (CHK_OVERFLOW(ptr, ptr, ptr + PKT_SIZE, driver->pkt_length)) {
 		memcpy(ptr, temp , driver->pkt_length);
-	else
+		driver->in_busy_pktdata = 1;
+	} else
 		printk(KERN_CRIT " Not enough buffer space for PKT_RESP\n");
 	mutex_unlock(&driver->diagchar_mutex);
 }
@@ -582,16 +693,19 @@
 		diag_update_sleeping_process(entry.process_id, PKT_TYPE);
 	} else {
 		if (len > 0) {
-			if ((entry.client_id >= 0) &&
-				(entry.client_id < NUM_SMD_DATA_CHANNELS)) {
+			if (entry.client_id < NUM_SMD_DATA_CHANNELS) {
 				int index = entry.client_id;
 				if (driver->smd_data[index].ch) {
 					if ((index == MODEM_DATA) &&
 						diag_check_mode_reset(buf)) {
 						return;
 					}
+					mutex_lock(&driver->smd_data[index].
+								smd_ch_mutex);
 					smd_write(driver->smd_data[index].ch,
 							buf, len);
+					mutex_unlock(&driver->smd_data[index].
+								smd_ch_mutex);
 				} else {
 					pr_err("diag: In %s, smd channel %d not open\n",
 						__func__, index);
@@ -604,20 +718,22 @@
 	}
 }
 
-static int diag_process_apps_pkt(unsigned char *buf, int len)
+int diag_process_apps_pkt(unsigned char *buf, int len)
 {
 	uint16_t subsys_cmd_code;
 	int subsys_id, ssid_first, ssid_last, ssid_range;
 	int packet_type = 1, i, cmd_code;
 	unsigned char *temp = buf;
 	int data_type;
+	int mask_ret;
 #if defined(CONFIG_DIAG_OVER_USB)
 	unsigned char *ptr;
 #endif
 
 	/* Check if the command is a supported mask command */
-	if (diag_process_apps_masks(buf, len) == 0)
-		return 0;
+	mask_ret = diag_process_apps_masks(buf, len);
+	if (mask_ret <= 0)
+		return mask_ret;
 
 	/* Check for registered clients and forward packet to apropriate proc */
 	cmd_code = (int)(*(char *)buf);
@@ -790,94 +906,186 @@
 		/* bld time masks */
 		switch (ssid_first) {
 		case MSG_SSID_0:
+			if (ssid_range > sizeof(msg_bld_masks_0)) {
+				pr_warning("diag: truncating ssid range for ssid 0");
+				ssid_range = sizeof(msg_bld_masks_0);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_0[i/4];
 			break;
 		case MSG_SSID_1:
+			if (ssid_range > sizeof(msg_bld_masks_1)) {
+				pr_warning("diag: truncating ssid range for ssid 1");
+				ssid_range = sizeof(msg_bld_masks_1);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_1[i/4];
 			break;
 		case MSG_SSID_2:
+			if (ssid_range > sizeof(msg_bld_masks_2)) {
+				pr_warning("diag: truncating ssid range for ssid 2");
+				ssid_range = sizeof(msg_bld_masks_2);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_2[i/4];
 			break;
 		case MSG_SSID_3:
+			if (ssid_range > sizeof(msg_bld_masks_3)) {
+				pr_warning("diag: truncating ssid range for ssid 3");
+				ssid_range = sizeof(msg_bld_masks_3);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_3[i/4];
 			break;
 		case MSG_SSID_4:
+			if (ssid_range > sizeof(msg_bld_masks_4)) {
+				pr_warning("diag: truncating ssid range for ssid 4");
+				ssid_range = sizeof(msg_bld_masks_4);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_4[i/4];
 			break;
 		case MSG_SSID_5:
+			if (ssid_range > sizeof(msg_bld_masks_5)) {
+				pr_warning("diag: truncating ssid range for ssid 5");
+				ssid_range = sizeof(msg_bld_masks_5);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_5[i/4];
 			break;
 		case MSG_SSID_6:
+			if (ssid_range > sizeof(msg_bld_masks_6)) {
+				pr_warning("diag: truncating ssid range for ssid 6");
+				ssid_range = sizeof(msg_bld_masks_6);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_6[i/4];
 			break;
 		case MSG_SSID_7:
+			if (ssid_range > sizeof(msg_bld_masks_7)) {
+				pr_warning("diag: truncating ssid range for ssid 7");
+				ssid_range = sizeof(msg_bld_masks_7);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_7[i/4];
 			break;
 		case MSG_SSID_8:
+			if (ssid_range > sizeof(msg_bld_masks_8)) {
+				pr_warning("diag: truncating ssid range for ssid 8");
+				ssid_range = sizeof(msg_bld_masks_8);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_8[i/4];
 			break;
 		case MSG_SSID_9:
+			if (ssid_range > sizeof(msg_bld_masks_9)) {
+				pr_warning("diag: truncating ssid range for ssid 9");
+				ssid_range = sizeof(msg_bld_masks_9);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_9[i/4];
 			break;
 		case MSG_SSID_10:
+			if (ssid_range > sizeof(msg_bld_masks_10)) {
+				pr_warning("diag: truncating ssid range for ssid 10");
+				ssid_range = sizeof(msg_bld_masks_10);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_10[i/4];
 			break;
 		case MSG_SSID_11:
+			if (ssid_range > sizeof(msg_bld_masks_11)) {
+				pr_warning("diag: truncating ssid range for ssid 11");
+				ssid_range = sizeof(msg_bld_masks_11);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_11[i/4];
 			break;
 		case MSG_SSID_12:
+			if (ssid_range > sizeof(msg_bld_masks_12)) {
+				pr_warning("diag: truncating ssid range for ssid 12");
+				ssid_range = sizeof(msg_bld_masks_12);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_12[i/4];
 			break;
 		case MSG_SSID_13:
+			if (ssid_range > sizeof(msg_bld_masks_13)) {
+				pr_warning("diag: truncating ssid range for ssid 13");
+				ssid_range = sizeof(msg_bld_masks_13);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_13[i/4];
 			break;
 		case MSG_SSID_14:
+			if (ssid_range > sizeof(msg_bld_masks_14)) {
+				pr_warning("diag: truncating ssid range for ssid 14");
+				ssid_range = sizeof(msg_bld_masks_14);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_14[i/4];
 			break;
 		case MSG_SSID_15:
+			if (ssid_range > sizeof(msg_bld_masks_15)) {
+				pr_warning("diag: truncating ssid range for ssid 15");
+				ssid_range = sizeof(msg_bld_masks_15);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_15[i/4];
 			break;
 		case MSG_SSID_16:
+			if (ssid_range > sizeof(msg_bld_masks_16)) {
+				pr_warning("diag: truncating ssid range for ssid 16");
+				ssid_range = sizeof(msg_bld_masks_16);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_16[i/4];
 			break;
 		case MSG_SSID_17:
+			if (ssid_range > sizeof(msg_bld_masks_17)) {
+				pr_warning("diag: truncating ssid range for ssid 17");
+				ssid_range = sizeof(msg_bld_masks_17);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_17[i/4];
 			break;
 		case MSG_SSID_18:
+			if (ssid_range > sizeof(msg_bld_masks_18)) {
+				pr_warning("diag: truncating ssid range for ssid 18");
+				ssid_range = sizeof(msg_bld_masks_18);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_18[i/4];
 			break;
 		case MSG_SSID_19:
+			if (ssid_range > sizeof(msg_bld_masks_19)) {
+				pr_warning("diag: truncating ssid range for ssid 19");
+				ssid_range = sizeof(msg_bld_masks_19);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_19[i/4];
 			break;
 		case MSG_SSID_20:
+			if (ssid_range > sizeof(msg_bld_masks_20)) {
+				pr_warning("diag: truncating ssid range for ssid 20");
+				ssid_range = sizeof(msg_bld_masks_20);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_20[i/4];
 			break;
 		case MSG_SSID_21:
+			if (ssid_range > sizeof(msg_bld_masks_21)) {
+				pr_warning("diag: truncating ssid range for ssid 21");
+				ssid_range = sizeof(msg_bld_masks_21);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_21[i/4];
 			break;
 		case MSG_SSID_22:
+			if (ssid_range > sizeof(msg_bld_masks_22)) {
+				pr_warning("diag: truncating ssid range for ssid 22");
+				ssid_range = sizeof(msg_bld_masks_22);
+			}
 			for (i = 0; i < ssid_range; i += 4)
 				*(int *)(ptr + i) = msg_bld_masks_22[i/4];
 			break;
@@ -980,6 +1188,9 @@
 {
 	struct diag_hdlc_decode_type hdlc;
 	int ret, type = 0;
+
+	mutex_lock(&driver->diag_hdlc_mutex);
+
 	pr_debug("diag: HDLC decode fn, len of data  %d\n", len);
 	hdlc.dest_ptr = driver->hdlc_buf;
 	hdlc.dest_size = USB_MAX_OUT_BUF;
@@ -991,10 +1202,27 @@
 
 	ret = diag_hdlc_decode(&hdlc);
 
-	if (ret)
+	/*
+	 * If the message is 3 bytes or less in length then the message is
+	 * too short. A message will need 4 bytes minimum, since there are
+	 * 2 bytes for the CRC and 1 byte for the ending 0x7e for the hdlc
+	 * encoding
+	 */
+	if (hdlc.dest_idx < 4) {
+		pr_err_ratelimited("diag: In %s, message is too short, len: %d, dest len: %d\n",
+			__func__, len, hdlc.dest_idx);
+		mutex_unlock(&driver->diag_hdlc_mutex);
+		return;
+	}
+
+	if (ret) {
 		type = diag_process_apps_pkt(driver->hdlc_buf,
 							  hdlc.dest_idx - 3);
-	else if (driver->debug_flag) {
+		if (type < 0) {
+			mutex_unlock(&driver->diag_hdlc_mutex);
+			return;
+		}
+	} else if (driver->debug_flag) {
 		printk(KERN_ERR "Packet dropped due to bad HDLC coding/CRC"
 				" errors or partial packet received, packet"
 				" length = %d\n", len);
@@ -1012,10 +1240,15 @@
 		if (chk_apps_only()) {
 			diag_send_error_rsp(hdlc.dest_idx);
 		} else { /* APQ 8060, Let Q6 respond */
-			if (driver->smd_data[LPASS_DATA].ch)
+			if (driver->smd_data[LPASS_DATA].ch) {
+				mutex_lock(&driver->smd_data[LPASS_DATA].
+								smd_ch_mutex);
 				smd_write(driver->smd_data[LPASS_DATA].ch,
 						driver->hdlc_buf,
 						hdlc.dest_idx - 3);
+				mutex_unlock(&driver->smd_data[LPASS_DATA].
+								smd_ch_mutex);
+			}
 		}
 		type = 0;
 	}
@@ -1030,8 +1263,10 @@
 	if ((driver->smd_data[MODEM_DATA].ch) && (ret) && (type) &&
 						(hdlc.dest_idx > 3)) {
 		APPEND_DEBUG('g');
+		mutex_lock(&driver->smd_data[MODEM_DATA].smd_ch_mutex);
 		smd_write(driver->smd_data[MODEM_DATA].ch,
 					driver->hdlc_buf, hdlc.dest_idx - 3);
+		mutex_unlock(&driver->smd_data[MODEM_DATA].smd_ch_mutex);
 		APPEND_DEBUG('h');
 #ifdef DIAG_DEBUG
 		printk(KERN_INFO "writing data to SMD, pkt length %d\n", len);
@@ -1039,6 +1274,7 @@
 			       1, DUMP_PREFIX_ADDRESS, data, len, 1);
 #endif /* DIAG DEBUG */
 	}
+	mutex_unlock(&driver->diag_hdlc_mutex);
 }
 
 #ifdef CONFIG_DIAG_OVER_USB
@@ -1266,6 +1502,9 @@
 			diag_dci_notify_client(smd_info->peripheral_mask,
 							DIAG_STATUS_OPEN);
 		}
+	} else if (event == SMD_EVENT_DATA && !driver->real_time_mode &&
+					smd_info->type == SMD_DATA_TYPE) {
+		process_lock_on_notify(&smd_info->nrt_lock);
 	}
 
 	wake_up(&driver->smd_wait_q);
@@ -1358,6 +1597,9 @@
 
 void diag_smd_destructor(struct diag_smd_info *smd_info)
 {
+	if (smd_info->type == SMD_DATA_TYPE)
+		wake_lock_destroy(&smd_info->nrt_lock.read_lock);
+
 	if (smd_info->ch)
 		smd_close(smd_info->ch);
 
@@ -1374,6 +1616,7 @@
 {
 	smd_info->peripheral = peripheral;
 	smd_info->type = type;
+	mutex_init(&smd_info->smd_ch_mutex);
 
 	switch (peripheral) {
 	case MODEM_DATA:
@@ -1468,6 +1711,30 @@
 		goto err;
 	}
 
+	smd_info->nrt_lock.enabled = 0;
+	smd_info->nrt_lock.ref_count = 0;
+	smd_info->nrt_lock.copy_count = 0;
+	if (type == SMD_DATA_TYPE) {
+		spin_lock_init(&smd_info->nrt_lock.read_spinlock);
+
+		switch (peripheral) {
+		case MODEM_DATA:
+			wake_lock_init(&smd_info->nrt_lock.read_lock,
+				WAKE_LOCK_SUSPEND, "diag_nrt_modem_read");
+			break;
+		case LPASS_DATA:
+			wake_lock_init(&smd_info->nrt_lock.read_lock,
+				WAKE_LOCK_SUSPEND, "diag_nrt_lpass_read");
+			break;
+		case WCNSS_DATA:
+			wake_lock_init(&smd_info->nrt_lock.read_lock,
+				WAKE_LOCK_SUSPEND, "diag_nrt_wcnss_read");
+			break;
+		default:
+			break;
+		}
+	}
+
 	return 1;
 err:
 	kfree(smd_info->buf_in_1);
@@ -1488,6 +1755,8 @@
 	diag_debug_buf_idx = 0;
 	driver->read_len_legacy = 0;
 	driver->use_device_tree = has_device_tree();
+	driver->real_time_mode = 1;
+	mutex_init(&driver->diag_hdlc_mutex);
 	mutex_init(&driver->diag_cntl_mutex);
 
 	success = diag_smd_constructor(&driver->smd_data[MODEM_DATA],
diff --git a/drivers/char/diag/diagfwd.h b/drivers/char/diag/diagfwd.h
index 14e2dd5..09f2f5e 100644
--- a/drivers/char/diag/diagfwd.h
+++ b/drivers/char/diag/diagfwd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. 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 and
@@ -23,6 +23,11 @@
 void diagfwd_exit(void);
 void diag_process_hdlc(void *data, unsigned len);
 void diag_smd_send_req(struct diag_smd_info *smd_info);
+void process_lock_enabling(struct diag_nrt_wake_lock *lock, int real_time);
+void process_lock_on_notify(struct diag_nrt_wake_lock *lock);
+void process_lock_on_read(struct diag_nrt_wake_lock *lock, int pkt_len);
+void process_lock_on_copy(struct diag_nrt_wake_lock *lock);
+void process_lock_on_copy_complete(struct diag_nrt_wake_lock *lock);
 void diag_usb_legacy_notifier(void *, unsigned, struct diag_request *);
 long diagchar_ioctl(struct file *, unsigned int, unsigned long);
 int diag_device_write(void *, int, struct diag_request *);
@@ -39,6 +44,11 @@
 int diag_smd_constructor(struct diag_smd_info *smd_info, int peripheral,
 			 int type);
 void diag_smd_destructor(struct diag_smd_info *smd_info);
+int diag_switch_logging(unsigned long);
+int diag_command_reg(unsigned long);
+void diag_cmp_logging_modes_sdio_pipe(int old_mode, int new_mode);
+void diag_cmp_logging_modes_diagfwd_bridge(int old_mode, int new_mode);
+int diag_process_apps_pkt(unsigned char *buf, int len);
 /* State for diag forwarding */
 #ifdef CONFIG_DIAG_OVER_USB
 int diagfwd_connect(void);
diff --git a/drivers/char/diag/diagfwd_bridge.c b/drivers/char/diag/diagfwd_bridge.c
index 61afa31..475f5ba 100644
--- a/drivers/char/diag/diagfwd_bridge.c
+++ b/drivers/char/diag/diagfwd_bridge.c
@@ -65,7 +65,9 @@
 		driver->in_busy_smux = 0;
 		diagfwd_connect_smux();
 	} else {
-		if (diag_hsic[index].hsic_device_enabled) {
+		if (diag_hsic[index].hsic_device_enabled &&
+			(driver->logging_mode != MEMORY_DEVICE_MODE ||
+			diag_hsic[index].hsic_data_requested)) {
 			diag_hsic[index].in_busy_hsic_read_on_device = 0;
 			diag_hsic[index].in_busy_hsic_write = 0;
 			/* If the HSIC (diag_bridge) platform
@@ -126,20 +128,24 @@
 				usb_diag_free_req(diag_bridge[i].ch);
 			}
 
-			if (i == SMUX && driver->diag_smux_enabled &&
+			if (i == SMUX) {
+				if (driver->diag_smux_enabled &&
 					driver->logging_mode == USB_MODE) {
-				driver->in_busy_smux = 1;
-				driver->lcid = LCID_INVALID;
-				driver->smux_connected = 0;
-				/* Turn off communication over usb and smux */
-				msm_smux_close(LCID_VALID);
+					driver->in_busy_smux = 1;
+					driver->lcid = LCID_INVALID;
+					driver->smux_connected = 0;
+					/*
+					 * Turn off communication over usb
+					 * and smux
+					 */
+					msm_smux_close(LCID_VALID);
+				}
 			}  else {
 				if (diag_hsic[i].hsic_device_enabled &&
-				     driver->logging_mode !=
-							MEMORY_DEVICE_MODE) {
+				     (driver->logging_mode != MEMORY_DEVICE_MODE
+				     || !diag_hsic[i].hsic_data_requested)) {
 					diag_hsic[i].
-						in_busy_hsic_read_on_device
-						= 1;
+						in_busy_hsic_read_on_device = 1;
 					diag_hsic[i].in_busy_hsic_write = 1;
 					/* Turn off communication over usb
 					 * and HSIC */
@@ -243,7 +249,7 @@
 		if (index == SMUX && driver->diag_smux_enabled)
 			diagfwd_write_complete_smux();
 		else if (diag_hsic[index].hsic_device_enabled)
-			diagfwd_write_complete_hsic(d_req);
+			diagfwd_write_complete_hsic(d_req, index);
 		break;
 	default:
 		pr_err("diag: in %s: Unknown event from USB diag:%u\n",
@@ -264,7 +270,7 @@
 	} else if (index == SMUX) {
 		strlcpy(name, "smux", sizeof(name));
 	} else {
-		pr_err("diag: incorrect bridge init\n");
+		pr_err("diag: incorrect bridge init, instance: %d\n", index);
 		return;
 	}
 
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index acac2fb..c3ff7dc 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -14,6 +14,7 @@
 #include <linux/diagchar.h>
 #include <linux/platform_device.h>
 #include <linux/kmemleak.h>
+#include <linux/delay.h>
 #include "diagchar.h"
 #include "diagfwd.h"
 #include "diagfwd_cntl.h"
@@ -85,14 +86,15 @@
 			range = buf+HDR_SIZ+
 					sizeof(struct diag_ctrl_msg);
 			pkt_params->count = msg->count_entries;
-			temp = kzalloc(pkt_params->count * sizeof(struct
-					 bindpkt_params), GFP_KERNEL);
-			if (temp == NULL) {
+			pkt_params->params = kzalloc(pkt_params->count *
+				sizeof(struct bindpkt_params), GFP_KERNEL);
+			if (pkt_params->params == NULL) {
 				pr_alert("diag: In %s, Memory alloc fail\n",
 					__func__);
 				kfree(pkt_params);
 				return flag;
 			}
+			temp = pkt_params->params;
 			for (j = 0; j < pkt_params->count; j++) {
 				temp->cmd_code = msg->cmd_code;
 				temp->subsys_id = msg->subsysid;
@@ -103,8 +105,6 @@
 				range++;
 				temp++;
 			}
-			temp -= pkt_params->count;
-			pkt_params->params = temp;
 			flag = 1;
 			/* peripheral undergoing SSR should not
 			 * record new registration
@@ -115,7 +115,7 @@
 			else
 				pr_err("diag: drop reg proc %d\n",
 						smd_info->peripheral);
-			kfree(temp);
+			kfree(pkt_params->params);
 		} else if ((type == DIAG_CTRL_MSG_FEATURE) &&
 				(smd_info->peripheral == MODEM_DATA)) {
 			feature_mask_len = *(int *)(buf + 8);
@@ -131,6 +131,83 @@
 	return flag;
 }
 
+void diag_send_diag_mode_update(int real_time)
+{
+	int i;
+
+	for (i = 0; i < NUM_SMD_CONTROL_CHANNELS; i++)
+		diag_send_diag_mode_update_by_smd(&driver->smd_cntl[i],
+							real_time);
+}
+
+void diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info,
+							int real_time)
+{
+	struct diag_ctrl_msg_diagmode diagmode;
+	char buf[sizeof(struct diag_ctrl_msg_diagmode)];
+	int msg_size = sizeof(struct diag_ctrl_msg_diagmode);
+	int wr_size = -ENOMEM, retry_count = 0, timer;
+
+	/* For now only allow the modem to receive the message */
+	if (!smd_info || smd_info->type != SMD_CNTL_TYPE ||
+		(smd_info->peripheral != MODEM_DATA))
+		return;
+
+	mutex_lock(&driver->diag_cntl_mutex);
+	diagmode.ctrl_pkt_id = DIAG_CTRL_MSG_DIAGMODE;
+	diagmode.ctrl_pkt_data_len = 36;
+	diagmode.version = 1;
+	diagmode.sleep_vote = real_time ? 1 : 0;
+	/*
+	 * 0 - Disables real-time logging (to prevent
+	 *     frequent APPS wake-ups, etc.).
+	 * 1 - Enable real-time logging
+	 */
+	diagmode.real_time = real_time;
+	diagmode.use_nrt_values = 0;
+	diagmode.commit_threshold = 0;
+	diagmode.sleep_threshold = 0;
+	diagmode.sleep_time = 0;
+	diagmode.drain_timer_val = 0;
+	diagmode.event_stale_timer_val = 0;
+
+	memcpy(buf, &diagmode, msg_size);
+
+	if (smd_info->ch) {
+		while (retry_count < 3) {
+			wr_size = smd_write(smd_info->ch, buf, msg_size);
+			if (wr_size == -ENOMEM) {
+				/*
+				 * The smd channel is full. Delay while
+				 * smd processes existing data and smd
+				 * has memory become available. The delay
+				 * of 2000 was determined empirically as
+				 * best value to use.
+				 */
+				retry_count++;
+				for (timer = 0; timer < 5; timer++)
+					udelay(2000);
+			} else {
+				struct diag_smd_info *data =
+				&driver->smd_data[smd_info->peripheral];
+				driver->real_time_mode = real_time;
+				process_lock_enabling(&data->nrt_lock,
+								real_time);
+				break;
+			}
+		}
+		if (wr_size != msg_size)
+			pr_err("diag: proc %d fail feature update %d, tried %d",
+				smd_info->peripheral,
+				wr_size, msg_size);
+	} else {
+		pr_err("diag: ch invalid, feature update on proc %d\n",
+				smd_info->peripheral);
+	}
+
+	mutex_unlock(&driver->diag_cntl_mutex);
+}
+
 static int diag_smd_cntl_probe(struct platform_device *pdev)
 {
 	int r = 0;
diff --git a/drivers/char/diag/diagfwd_cntl.h b/drivers/char/diag/diagfwd_cntl.h
index 8d262c4..7cd1866 100644
--- a/drivers/char/diag/diagfwd_cntl.h
+++ b/drivers/char/diag/diagfwd_cntl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -84,11 +84,28 @@
 	/* Copy feature mask here */
 } __packed;
 
+struct diag_ctrl_msg_diagmode {
+	uint32_t ctrl_pkt_id;
+	uint32_t ctrl_pkt_data_len;
+	uint32_t version;
+	uint32_t sleep_vote;
+	uint32_t real_time;
+	uint32_t use_nrt_values;
+	uint32_t commit_threshold;
+	uint32_t sleep_threshold;
+	uint32_t sleep_time;
+	uint32_t drain_timer_val;
+	uint32_t event_stale_timer_val;
+} __packed;
+
 void diagfwd_cntl_init(void);
 void diagfwd_cntl_exit(void);
 void diag_read_smd_cntl_work_fn(struct work_struct *);
 void diag_clean_reg_fn(struct work_struct *work);
 int diag_process_smd_cntl_read_data(struct diag_smd_info *smd_info, void *buf,
 								int total_recd);
+void diag_send_diag_mode_update(int real_time);
+void diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info,
+							int real_time);
 
 #endif
diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c
index e004fc6..fa46aab 100644
--- a/drivers/char/diag/diagfwd_hsic.c
+++ b/drivers/char/diag/diagfwd_hsic.c
@@ -45,6 +45,7 @@
 	struct diag_hsic_dev *hsic_struct = container_of(work,
 				struct diag_hsic_dev, diag_read_hsic_work);
 	int index = hsic_struct->id;
+	static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
 
 	if (!diag_hsic[index].hsic_ch) {
 		pr_err("DIAG in %s: diag_hsic[index].hsic_ch == 0\n", __func__);
@@ -103,7 +104,8 @@
 				diagmem_free(driver, buf_in_hsic,
 						index+POOL_TYPE_HSIC);
 
-				pr_err_ratelimited("diag: Error initiating HSIC read, err: %d\n",
+				if (__ratelimit(&rl))
+					pr_err("diag: Error initiating HSIC read, err: %d\n",
 					err);
 				/*
 				 * An error occurred, discontinue queuing
@@ -132,6 +134,7 @@
 {
 	int err = -2;
 	int index = (int)ctxt;
+	static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
 
 	if (!diag_hsic[index].hsic_ch) {
 		/*
@@ -164,7 +167,8 @@
 			if (err) {
 				diagmem_free(driver, buf, index +
 							POOL_TYPE_HSIC);
-				pr_err_ratelimited("diag: In %s, error calling diag_device_write, err: %d\n",
+				if (__ratelimit(&rl))
+					pr_err("diag: In %s, error calling diag_device_write, err: %d\n",
 					__func__, err);
 			}
 		}
@@ -223,8 +227,12 @@
 	if (diag_hsic[index].in_busy_hsic_write)
 		return -EBUSY;
 
-	/* Don't allow suspend if in MEMORY_DEVICE_MODE */
-	if (driver->logging_mode == MEMORY_DEVICE_MODE)
+	/*
+	 * Don't allow suspend if in MEMORY_DEVICE_MODE and if there
+	 * has been hsic data requested
+	 */
+	if (driver->logging_mode == MEMORY_DEVICE_MODE &&
+				diag_hsic[index].hsic_ch)
 		return -EBUSY;
 
 	diag_hsic[index].hsic_suspend = 1;
@@ -284,28 +292,38 @@
 }
 
 /* diagfwd_cancel_hsic is called to cancel outstanding read/writes */
-int diagfwd_cancel_hsic(void)
+int diagfwd_cancel_hsic(int reopen)
 {
 	int err, i;
 
 	/* Cancel it for all active HSIC bridges */
 	for (i = 0; i < MAX_HSIC_CH; i++) {
+		if (!diag_bridge[i].enabled)
+			continue;
 		mutex_lock(&diag_bridge[i].bridge_mutex);
 		if (diag_hsic[i].hsic_device_enabled) {
 			if (diag_hsic[i].hsic_device_opened) {
 				diag_hsic[i].hsic_ch = 0;
 				diag_hsic[i].hsic_device_opened = 0;
 				diag_bridge_close(i);
-				hsic_diag_bridge_ops[i].ctxt = (void *)(i);
-				err = diag_bridge_open(i,
-						   &hsic_diag_bridge_ops[i]);
-				if (err) {
-					pr_err("diag: HSIC channel open error: %d\n",
-						 err);
+				if (reopen) {
+					hsic_diag_bridge_ops[i].ctxt =
+								(void *)(i);
+					err = diag_bridge_open(i,
+						&hsic_diag_bridge_ops[i]);
+					if (err) {
+						pr_err("diag: HSIC %d channel open error: %d\n",
+							 i, err);
+					} else {
+						pr_debug("diag: opened HSIC channel: %d\n",
+							i);
+						diag_hsic[i].
+							hsic_device_opened = 1;
+						diag_hsic[i].hsic_ch = 1;
+					}
+					diag_hsic[i].hsic_data_requested = 1;
 				} else {
-					pr_debug("diag: opened HSIC channel\n");
-					diag_hsic[i].hsic_device_opened = 1;
-					diag_hsic[i].hsic_ch = 1;
+					diag_hsic[i].hsic_data_requested = 0;
 				}
 			}
 		}
@@ -318,10 +336,9 @@
  * diagfwd_write_complete_hsic is called after the asynchronous
  * usb_diag_write() on mdm channel is complete
  */
-int diagfwd_write_complete_hsic(struct diag_request *diag_write_ptr)
+int diagfwd_write_complete_hsic(struct diag_request *diag_write_ptr, int index)
 {
 	unsigned char *buf = (diag_write_ptr) ? diag_write_ptr->buf : NULL;
-	int index = (int)(diag_write_ptr->context);
 
 	if (buf) {
 		/* Return buffers to their pools */
@@ -422,15 +439,20 @@
 		diagmem_hsic_init(pdev->id);
 		INIT_WORK(&(diag_hsic[pdev->id].diag_read_hsic_work),
 			    diag_read_hsic_work_fn);
+		diag_hsic[pdev->id].hsic_data_requested =
+			(driver->logging_mode == MEMORY_DEVICE_MODE) ? 0 : 1;
 		diag_hsic[pdev->id].hsic_inited = 1;
 	}
 	/*
 	 * The probe function was called after the usb was connected
-	 * on the legacy channel OR ODL is turned on. Communication over usb
-	 * mdm and HSIC needs to be turned on.
+	 * on the legacy channel OR ODL is turned on and hsic data is
+	 * requested. Communication over usb mdm and HSIC needs to be
+	 * turned on.
 	 */
-	if (diag_bridge[pdev->id].usb_connected || (driver->logging_mode ==
-						   MEMORY_DEVICE_MODE)) {
+	if ((diag_bridge[pdev->id].usb_connected &&
+		(driver->logging_mode != MEMORY_DEVICE_MODE)) ||
+		((driver->logging_mode == MEMORY_DEVICE_MODE) &&
+		diag_hsic[pdev->id].hsic_data_requested)) {
 		if (diag_hsic[pdev->id].hsic_device_opened) {
 			/* should not happen. close it before re-opening */
 			pr_warn("diag: HSIC channel already opened in probe\n");
diff --git a/drivers/char/diag/diagfwd_hsic.h b/drivers/char/diag/diagfwd_hsic.h
index 5d00da3..64556f2 100644
--- a/drivers/char/diag/diagfwd_hsic.h
+++ b/drivers/char/diag/diagfwd_hsic.h
@@ -19,8 +19,10 @@
 #define N_MDM_READ	1
 #define NUM_HSIC_BUF_TBL_ENTRIES N_MDM_WRITE
 #define MAX_HSIC_CH	4
-int diagfwd_write_complete_hsic(struct diag_request *);
-int diagfwd_cancel_hsic(void);
+#define REOPEN_HSIC 1
+#define DONT_REOPEN_HSIC 0
+int diagfwd_write_complete_hsic(struct diag_request *, int index);
+int diagfwd_cancel_hsic(int reopen);
 void diag_read_usb_hsic_work_fn(struct work_struct *work);
 void diag_usb_read_complete_hsic_fn(struct work_struct *w);
 extern struct diag_bridge_ops hsic_diag_bridge_ops[MAX_HSIC_CH];
@@ -37,6 +39,7 @@
 	int hsic_device_enabled;
 	int hsic_device_opened;
 	int hsic_suspend;
+	int hsic_data_requested;
 	int in_busy_hsic_read_on_device;
 	int in_busy_hsic_write;
 	struct work_struct diag_read_hsic_work;
diff --git a/drivers/char/diag/diagfwd_sdio.c b/drivers/char/diag/diagfwd_sdio.c
index a145c06..7d4e0d5 100644
--- a/drivers/char/diag/diagfwd_sdio.c
+++ b/drivers/char/diag/diagfwd_sdio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
@@ -105,8 +105,8 @@
 {
 	int err;
 
-	err = usb_diag_alloc_req(driver->mdm_ch, N_MDM_WRITE,
-							 N_MDM_READ);
+	err = usb_diag_alloc_req(driver->mdm_ch, N_MDM_SDIO_WRITE,
+							 N_MDM_SDIO_READ);
 	if (err)
 		pr_err("diag: unable to alloc USB req on mdm ch\n");
 
diff --git a/drivers/char/diag/diagfwd_sdio.h b/drivers/char/diag/diagfwd_sdio.h
index 40982c3..bde4776 100644
--- a/drivers/char/diag/diagfwd_sdio.h
+++ b/drivers/char/diag/diagfwd_sdio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
@@ -14,8 +14,8 @@
 #define DIAGFWD_SDIO_H
 
 #include <mach/sdio_al.h>
-#define N_MDM_WRITE	1 /* Upgrade to 2 with ping pong buffer */
-#define N_MDM_READ	1
+#define N_MDM_SDIO_WRITE	1 /* Upgrade to 2 with ping pong buffer */
+#define N_MDM_SDIO_READ	1
 
 void diagfwd_sdio_init(void);
 void diagfwd_sdio_exit(void);
diff --git a/drivers/char/diag/diagfwd_smux.c b/drivers/char/diag/diagfwd_smux.c
index 0a97baf..a775983 100644
--- a/drivers/char/diag/diagfwd_smux.c
+++ b/drivers/char/diag/diagfwd_smux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/char/diag/diagfwd_smux.h b/drivers/char/diag/diagfwd_smux.h
index b45fd5d..fcf19d2 100644
--- a/drivers/char/diag/diagfwd_smux.h
+++ b/drivers/char/diag/diagfwd_smux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/char/diag/diagmem.c b/drivers/char/diag/diagmem.c
index cac6476..0cd8267 100644
--- a/drivers/char/diag/diagmem.c
+++ b/drivers/char/diag/diagmem.c
@@ -135,7 +135,7 @@
 		}
 
 		if (diag_hsic[index].diag_hsic_write_pool &&
-					(diag_hsic[HSIC].hsic_inited == 0)) {
+					(diag_hsic[index].hsic_inited == 0)) {
 			/*
 			 * Free up struct pool ONLY if there are no outstanding
 			 * transactions(aggregation buffer) with USB
diff --git a/drivers/char/hw_random/msm_rng.c b/drivers/char/hw_random/msm_rng.c
index 60ca44f..dd89e9b 100644
--- a/drivers/char/hw_random/msm_rng.c
+++ b/drivers/char/hw_random/msm_rng.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
@@ -261,6 +261,6 @@
 
 module_exit(msm_rng_exit);
 
-MODULE_AUTHOR("Code Aurora Forum");
+MODULE_AUTHOR("The Linux Foundation");
 MODULE_DESCRIPTION("Qualcomm MSM Random Number Driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index aebdf55..20e716e 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -29,6 +29,9 @@
 #include <linux/major.h>
 #include <linux/regulator/consumer.h>
 #include <linux/msm_ion.h>
+#include <linux/sync.h>
+#include <linux/sw_sync.h>
+
 #ifdef CONFIG_MSM_BUS_SCALING
 #include <mach/msm_bus.h>
 #include <mach/msm_bus_board.h>
@@ -90,11 +93,20 @@
 #define INVALID_SESSION -1
 #define VERSION_KEY_MASK 0xFFFFFF00
 #define MAX_DOWNSCALE_RATIO 3
+#define MAX_COMMIT_QUEUE 4
+#define WAIT_ROT_TIMEOUT 1000
+
+#define MAX_TIMELINE_NAME_LEN 16
+#define WAIT_FENCE_FIRST_TIMEOUT MSEC_PER_SEC
+#define WAIT_FENCE_FINAL_TIMEOUT (10 * MSEC_PER_SEC)
 
 #define ROTATOR_REVISION_V0		0
 #define ROTATOR_REVISION_V1		1
 #define ROTATOR_REVISION_V2		2
 #define ROTATOR_REVISION_NONE	0xffffffff
+#define	BASE_ADDR(height, y_stride) ((height % 64) * y_stride)
+#define	HW_BASE_ADDR(height, y_stride) (((dstp0_ystride >> 5) << 11) - \
+					((dst_height & 0x3f) * dstp0_ystride))
 
 uint32_t rotator_hw_revision;
 static char rot_iommu_split_domain;
@@ -128,12 +140,52 @@
 	struct list_head list;
 };
 
+struct rot_sync_info {
+	u32 initialized;
+	struct sync_fence *acq_fen;
+	struct sync_fence *rel_fen;
+	int rel_fen_fd;
+	struct sw_sync_timeline *timeline;
+	int timeline_value;
+	struct mutex sync_mutex;
+	atomic_t queue_buf_cnt;
+};
+
+struct msm_rotator_session {
+	struct msm_rotator_img_info img_info;
+	struct msm_rotator_fd_info fd_info;
+	int fast_yuv_enable;
+};
+
+struct msm_rotator_commit_info {
+	struct msm_rotator_data_info data_info;
+	struct msm_rotator_img_info img_info;
+	unsigned int format;
+	unsigned int in_paddr;
+	unsigned int out_paddr;
+	unsigned int in_chroma_paddr;
+	unsigned int out_chroma_paddr;
+	unsigned int in_chroma2_paddr;
+	unsigned int out_chroma2_paddr;
+	struct file *srcp0_file;
+	struct file *srcp1_file;
+	struct file *dstp0_file;
+	struct file *dstp1_file;
+	struct ion_handle *srcp0_ihdl;
+	struct ion_handle *srcp1_ihdl;
+	struct ion_handle *dstp0_ihdl;
+	struct ion_handle *dstp1_ihdl;
+	int ps0_need;
+	int session_index;
+	struct sync_fence *acq_fen;
+	int fast_yuv_en;
+};
+
 struct msm_rotator_dev {
 	void __iomem *io_base;
 	int irq;
-	struct msm_rotator_img_info *img_info[MAX_SESSIONS];
 	struct clk *core_clk;
-	struct msm_rotator_fd_info *fd_info[MAX_SESSIONS];
+	struct msm_rotator_session *rot_session[MAX_SESSIONS];
 	struct list_head fd_list;
 	struct clk *pclk;
 	int rot_clk_state;
@@ -159,6 +211,17 @@
 	#endif
 	u32 sec_mapped;
 	u32 mmu_clk_on;
+	struct rot_sync_info sync_info[MAX_SESSIONS];
+	/* non blocking */
+	struct mutex commit_mutex;
+	struct mutex commit_wq_mutex;
+	struct completion commit_comp;
+	u32 commit_running;
+	struct work_struct commit_work;
+	struct msm_rotator_commit_info commit_info[MAX_COMMIT_QUEUE];
+	atomic_t commit_q_r;
+	atomic_t commit_q_w;
+	atomic_t commit_q_cnt;
 };
 
 #define COMPONENT_5BITS 1
@@ -166,6 +229,8 @@
 #define COMPONENT_8BITS 3
 
 static struct msm_rotator_dev *msm_rotator_dev;
+#define mrd msm_rotator_dev
+static void rot_wait_for_commit_queue(u32 is_all);
 
 enum {
 	CLK_EN,
@@ -340,6 +405,175 @@
 	return IRQ_HANDLED;
 }
 
+static void msm_rotator_signal_timeline(u32 session_index)
+{
+	struct rot_sync_info *sync_info;
+	sync_info = &msm_rotator_dev->sync_info[session_index];
+
+	if ((!sync_info->timeline) || (!sync_info->initialized))
+		return;
+
+	mutex_lock(&sync_info->sync_mutex);
+	sw_sync_timeline_inc(sync_info->timeline, 1);
+	sync_info->timeline_value++;
+	mutex_unlock(&sync_info->sync_mutex);
+}
+
+static void msm_rotator_signal_timeline_done(u32 session_index)
+{
+	struct rot_sync_info *sync_info;
+	sync_info = &msm_rotator_dev->sync_info[session_index];
+
+	if ((sync_info->timeline == NULL) ||
+		(sync_info->initialized == false))
+			return;
+	mutex_lock(&sync_info->sync_mutex);
+	sw_sync_timeline_inc(sync_info->timeline, 1);
+	sync_info->timeline_value++;
+	if (atomic_read(&sync_info->queue_buf_cnt) <= 0)
+		pr_err("%s queue_buf_cnt=%d", __func__,
+			atomic_read(&sync_info->queue_buf_cnt));
+	else
+		atomic_dec(&sync_info->queue_buf_cnt);
+	mutex_unlock(&sync_info->sync_mutex);
+}
+
+static void msm_rotator_release_acq_fence(u32 session_index)
+{
+	struct rot_sync_info *sync_info;
+	sync_info = &msm_rotator_dev->sync_info[session_index];
+
+	if ((!sync_info->timeline) || (!sync_info->initialized))
+		return;
+	mutex_lock(&sync_info->sync_mutex);
+	sync_info->acq_fen = NULL;
+	mutex_unlock(&sync_info->sync_mutex);
+}
+
+static void msm_rotator_release_all_timeline(void)
+{
+	int i;
+	struct rot_sync_info *sync_info;
+	for (i = 0; i < MAX_SESSIONS; i++) {
+		sync_info = &msm_rotator_dev->sync_info[i];
+		if (sync_info->initialized) {
+			msm_rotator_signal_timeline(i);
+			msm_rotator_release_acq_fence(i);
+		}
+	}
+}
+
+static void msm_rotator_wait_for_fence(struct sync_fence *acq_fen)
+{
+	int ret;
+	if (acq_fen) {
+		ret = sync_fence_wait(acq_fen,
+				WAIT_FENCE_FIRST_TIMEOUT);
+		if (ret == -ETIME) {
+			pr_warn("%s: timeout, wait %ld more ms\n",
+				__func__, WAIT_FENCE_FINAL_TIMEOUT);
+			ret = sync_fence_wait(acq_fen,
+				WAIT_FENCE_FINAL_TIMEOUT);
+		}
+		if (ret < 0) {
+			pr_err("%s: sync_fence_wait failed! ret = %x\n",
+				__func__, ret);
+		}
+		sync_fence_put(acq_fen);
+	}
+}
+
+static int  msm_rotator_buf_sync(unsigned long arg)
+{
+	struct msm_rotator_buf_sync buf_sync;
+	int ret = 0;
+	struct sync_fence *fence = NULL;
+	struct rot_sync_info *sync_info;
+	struct sync_pt *rel_sync_pt;
+	struct sync_fence *rel_fence;
+	int rel_fen_fd;
+	u32 s;
+
+	if (copy_from_user(&buf_sync, (void __user *)arg, sizeof(buf_sync)))
+		return -EFAULT;
+
+	rot_wait_for_commit_queue(false);
+	for (s = 0; s < MAX_SESSIONS; s++)
+		if ((msm_rotator_dev->rot_session[s] != NULL) &&
+			(buf_sync.session_id ==
+			(unsigned int)msm_rotator_dev->rot_session[s]
+			))
+			break;
+
+	if (s == MAX_SESSIONS)  {
+		pr_err("%s invalid session id %d", __func__,
+			buf_sync.session_id);
+		return -EINVAL;
+	}
+
+	sync_info = &msm_rotator_dev->sync_info[s];
+
+	if (sync_info->acq_fen)
+		pr_err("%s previous acq_fen will be overwritten", __func__);
+
+	if ((sync_info->timeline == NULL) ||
+		(sync_info->initialized == false))
+		return -EINVAL;
+
+	mutex_lock(&sync_info->sync_mutex);
+	if (buf_sync.acq_fen_fd >= 0)
+		fence = sync_fence_fdget(buf_sync.acq_fen_fd);
+
+	sync_info->acq_fen = fence;
+
+	if (sync_info->acq_fen &&
+		(buf_sync.flags & MDP_BUF_SYNC_FLAG_WAIT)) {
+		msm_rotator_wait_for_fence(sync_info->acq_fen);
+		sync_info->acq_fen = NULL;
+	}
+
+	rel_sync_pt = sw_sync_pt_create(sync_info->timeline,
+			sync_info->timeline_value +
+			atomic_read(&sync_info->queue_buf_cnt) + 1);
+	if (rel_sync_pt == NULL) {
+		pr_err("%s: cannot create sync point", __func__);
+		ret = -ENOMEM;
+		goto buf_sync_err_1;
+	}
+	/* create fence */
+	rel_fence = sync_fence_create("msm_rotator-fence",
+			rel_sync_pt);
+	if (rel_fence == NULL) {
+		sync_pt_free(rel_sync_pt);
+		pr_err("%s: cannot create fence", __func__);
+		ret = -ENOMEM;
+		goto buf_sync_err_1;
+	}
+	/* create fd */
+	rel_fen_fd = get_unused_fd_flags(0);
+	if (rel_fen_fd < 0) {
+		pr_err("%s: get_unused_fd_flags failed", __func__);
+		ret  = -EIO;
+		goto buf_sync_err_2;
+	}
+	sync_fence_install(rel_fence, rel_fen_fd);
+	buf_sync.rel_fen_fd = rel_fen_fd;
+	sync_info->rel_fen = rel_fence;
+	sync_info->rel_fen_fd = rel_fen_fd;
+
+	ret = copy_to_user((void __user *)arg, &buf_sync, sizeof(buf_sync));
+	mutex_unlock(&sync_info->sync_mutex);
+	return ret;
+buf_sync_err_2:
+	sync_fence_put(rel_fence);
+buf_sync_err_1:
+	if (sync_info->acq_fen)
+		sync_fence_put(sync_info->acq_fen);
+	sync_info->acq_fen = NULL;
+	mutex_unlock(&sync_info->sync_mutex);
+	return ret;
+}
+
 static unsigned int tile_size(unsigned int src_width,
 		unsigned int src_height,
 		const struct tile_parm *tp)
@@ -472,6 +706,110 @@
 	return 0;
 }
 
+/* Checking invalid destination image size on FAST YUV for YUV420PP(NV12) with
+ * HW issue  for rotation 90 + U/D filp + with/without flip operation
+ * (rotation 90 + U/D + L/R flip is rotation 270 degree option) and pix_rot
+ * block issue with tile line size is 4.
+ *
+ * Rotator structure is:
+ * if Fetch input image: W x H,
+ * Downscale: W` x H` = W/ScaleHor(2, 4 or 8) x H/ScaleVert(2, 4 or 8)
+ * Rotated output : W`` x H`` = (W` x H`) or (H` x W`) depends on "Rotation 90
+ * degree option"
+ *
+ * Pack: W`` x H``
+ *
+ * Rotator source ROI image width restriction is applied to W x H (case a,
+ * image resolution before downscaling)
+ *
+ * Packer source Image width/ height restriction are applied to  W`` x H``
+ * (case c, image resolution after rotation)
+ *
+ * Supertile (64 x 8) and YUV (2 x 2)  alignment restriction should be
+ * applied to the W x H (case a). Input image should be at least (2 x 2).
+ *
+ * "Support If packer source image height <= 256, multiple of 8", this
+ * restriction should be applied to the rotated image (W`` x H``)
+ */
+
+uint32_t fast_yuv_invalid_size_checker(unsigned char rot_mode,
+						uint32_t src_width,
+						uint32_t dst_width,
+						uint32_t dst_height,
+						uint32_t dstp0_ystride,
+						uint32_t is_planar420)
+{
+	uint32_t hw_limit;
+
+	hw_limit  = is_planar420 ? 512 : 256;
+
+	/* checking image constaints for missing EOT event from pix_rot block */
+	if ((src_width > hw_limit) && ((src_width % (hw_limit / 2)) == 8))
+		return -EINVAL;
+
+	if (rot_mode & MDP_ROT_90) {
+
+		/* if rotation 90 degree on fast yuv
+		 * rotator image input width has to be multiple of 8
+		 * rotator image input height has to be multiple of 8
+		 */
+		if (((dst_width % 8) != 0) || ((dst_height % 8) != 0))
+			return -EINVAL;
+
+		if ((rot_mode & MDP_FLIP_UD) ||
+			(rot_mode & (MDP_FLIP_UD | MDP_FLIP_LR))) {
+
+			/* image constraint checking for wrong address
+			 * generation HW issue for Y plane checking
+			 */
+			if (((dst_height % 64) != 0) &&
+				((dst_height / 64) >= 4)) {
+
+				/* compare golden logic for second
+				 * tile base address generation in row
+				 * with actual HW implementation
+				*/
+				if (BASE_ADDR(dst_height, dstp0_ystride) !=
+					HW_BASE_ADDR(dst_height, dstp0_ystride))
+						return -EINVAL;
+			}
+
+			if (is_planar420) {
+				dst_width = dst_width / 2;
+				dstp0_ystride = dstp0_ystride / 2;
+			}
+
+			dst_height = dst_height / 2;
+
+			/* image constraint checking for wrong
+			 * address generation HW issue. for
+			 * U/V (P) or UV (PP) plane checking
+			 */
+			if (((dst_height % 64) != 0) && ((dst_height / 64) >=
+				(hw_limit / 128))) {
+
+				/* compare golden logic for
+				 * second tile base address
+				 * generation in row with
+				 * actual HW implementation
+				*/
+				if (BASE_ADDR(dst_height, dstp0_ystride) !=
+					HW_BASE_ADDR(dst_height, dstp0_ystride))
+						return -EINVAL;
+			}
+		}
+	} else {
+		/* if NOT applying rotation 90 degree on fast yuv,
+		 * rotator image input width has to be multiple of 8
+		 * rotator image input height has to be multiple of 2
+		*/
+		if (((dst_width % 8) != 0) || ((dst_height % 2) != 0))
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int msm_rotator_ycxcx_h2v1(struct msm_rotator_img_info *info,
 				  unsigned int in_paddr,
 				  unsigned int out_paddr,
@@ -552,7 +890,9 @@
 				  int new_session,
 				  unsigned int in_chroma_paddr,
 				  unsigned int out_chroma_paddr,
-				  unsigned int in_chroma2_paddr)
+				  unsigned int in_chroma2_paddr,
+				  unsigned int out_chroma2_paddr,
+				  int fast_yuv_en)
 {
 	uint32_t dst_format;
 	int is_tile = 0;
@@ -560,14 +900,26 @@
 	switch (info->src.format) {
 	case MDP_Y_CRCB_H2V2_TILE:
 		is_tile = 1;
+		dst_format = MDP_Y_CRCB_H2V2;
+		break;
 	case MDP_Y_CR_CB_H2V2:
 	case MDP_Y_CR_CB_GH2V2:
+		if (fast_yuv_en) {
+			dst_format = info->src.format;
+			break;
+		}
 	case MDP_Y_CRCB_H2V2:
 		dst_format = MDP_Y_CRCB_H2V2;
 		break;
+	case MDP_Y_CB_CR_H2V2:
+		if (fast_yuv_en) {
+			dst_format = info->src.format;
+			break;
+		}
+		dst_format = MDP_Y_CBCR_H2V2;
+		break;
 	case MDP_Y_CBCR_H2V2_TILE:
 		is_tile = 1;
-	case MDP_Y_CB_CR_H2V2:
 	case MDP_Y_CBCR_H2V2:
 		dst_format = MDP_Y_CBCR_H2V2;
 		break;
@@ -591,8 +943,12 @@
 			((info->dst_y * info->dst.width) + info->dst_x),
 		  MSM_ROTATOR_OUTP0_ADDR);
 	iowrite32(out_chroma_paddr +
-			((info->dst_y * info->dst.width)/2 + info->dst_x),
+			(((info->dst_y * info->dst.width)/2) + info->dst_x),
 		  MSM_ROTATOR_OUTP1_ADDR);
+	if (out_chroma2_paddr)
+		iowrite32(out_chroma2_paddr +
+			(((info->dst_y * info->dst.width)/2) + info->dst_x),
+			  MSM_ROTATOR_OUTP2_ADDR);
 
 	if (new_session) {
 		if (in_chroma2_paddr) {
@@ -614,11 +970,28 @@
 					info->src.width << 16,
 					MSM_ROTATOR_SRC_YSTRIDE1);
 		}
-		iowrite32(info->dst.width |
-				info->dst.width << 16,
-				MSM_ROTATOR_OUT_YSTRIDE1);
+		if (out_chroma2_paddr) {
+			if (info->dst.format == MDP_Y_CR_CB_GH2V2) {
+				iowrite32(ALIGN(info->dst.width, 16) |
+					ALIGN((info->dst.width / 2), 16) << 16,
+					MSM_ROTATOR_OUT_YSTRIDE1);
+				iowrite32(ALIGN((info->dst.width / 2), 16),
+					MSM_ROTATOR_OUT_YSTRIDE2);
+			} else {
+				iowrite32(info->dst.width |
+						info->dst.width/2 << 16,
+						MSM_ROTATOR_OUT_YSTRIDE1);
+				iowrite32(info->dst.width/2,
+						MSM_ROTATOR_OUT_YSTRIDE2);
+			}
+		} else {
+			iowrite32(info->dst.width |
+					info->dst.width << 16,
+					MSM_ROTATOR_OUT_YSTRIDE1);
+		}
 
-		if (dst_format == MDP_Y_CBCR_H2V2) {
+		if (dst_format == MDP_Y_CBCR_H2V2 ||
+			dst_format == MDP_Y_CB_CR_H2V2) {
 			iowrite32(GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8),
 				  MSM_ROTATOR_SRC_UNPACK_PATTERN1);
 			iowrite32(GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8),
@@ -629,9 +1002,11 @@
 			iowrite32(GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8),
 				  MSM_ROTATOR_OUT_PACK_PATTERN1);
 		}
+
 		iowrite32((3  << 18) | 		/* chroma sampling 3=4:2:0 */
 			  (ROTATIONS_TO_BITMASK(info->rotations) << 9) |
 			  1 << 8 |			/* ROT_EN */
+			  fast_yuv_en << 4 |		/*fast YUV*/
 			  info->downscale_ratio << 2 |	/* downscale v ratio */
 			  info->downscale_ratio,	/* downscale h ratio */
 			  MSM_ROTATOR_SUB_BLOCK_CFG);
@@ -921,31 +1296,33 @@
 	}
 #endif
 }
-static int msm_rotator_do_rotate(unsigned long arg)
+
+static int msm_rotator_rotate_prepare(
+	struct msm_rotator_data_info *data_info,
+	struct msm_rotator_commit_info *commit_info)
 {
-	unsigned int status, format;
+	unsigned int format;
 	struct msm_rotator_data_info info;
 	unsigned int in_paddr, out_paddr;
 	unsigned long src_len, dst_len;
-	int use_imem = 0, rc = 0, s;
+	int rc = 0, s;
 	struct file *srcp0_file = NULL, *dstp0_file = NULL;
 	struct file *srcp1_file = NULL, *dstp1_file = NULL;
 	struct ion_handle *srcp0_ihdl = NULL, *dstp0_ihdl = NULL;
 	struct ion_handle *srcp1_ihdl = NULL, *dstp1_ihdl = NULL;
 	int ps0_need, p_need;
 	unsigned int in_chroma_paddr = 0, out_chroma_paddr = 0;
-	unsigned int in_chroma2_paddr = 0;
+	unsigned int in_chroma2_paddr = 0, out_chroma2_paddr = 0;
 	struct msm_rotator_img_info *img_info;
 	struct msm_rotator_mem_planes src_planes, dst_planes;
 
-	if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
-		return -EFAULT;
-
 	mutex_lock(&msm_rotator_dev->rotator_lock);
+	info = *data_info;
+
 	for (s = 0; s < MAX_SESSIONS; s++)
-		if ((msm_rotator_dev->img_info[s] != NULL) &&
+		if ((msm_rotator_dev->rot_session[s] != NULL) &&
 			(info.session_id ==
-			(unsigned int)msm_rotator_dev->img_info[s]
+			(unsigned int)msm_rotator_dev->rot_session[s]
 			))
 			break;
 
@@ -953,25 +1330,27 @@
 		pr_err("%s() : Attempt to use invalid session_id %d\n",
 			__func__, s);
 		rc = -EINVAL;
-		goto do_rotate_unlock_mutex;
+		mutex_unlock(&msm_rotator_dev->rotator_lock);
+		return rc;
 	}
 
-	if (msm_rotator_dev->img_info[s]->enable == 0) {
+	img_info = &(msm_rotator_dev->rot_session[s]->img_info);
+	if (img_info->enable == 0) {
 		dev_dbg(msm_rotator_dev->device,
-			"%s() : Session_id %d not enabled \n",
-			__func__, s);
+			"%s() : Session_id %d not enabled\n", __func__, s);
 		rc = -EINVAL;
-		goto do_rotate_unlock_mutex;
+		mutex_unlock(&msm_rotator_dev->rotator_lock);
+		return rc;
 	}
 
-	img_info = msm_rotator_dev->img_info[s];
 	if (msm_rotator_get_plane_sizes(img_info->src.format,
 					img_info->src.width,
 					img_info->src.height,
 					&src_planes)) {
 		pr_err("%s: invalid src format\n", __func__);
 		rc = -EINVAL;
-		goto do_rotate_unlock_mutex;
+		mutex_unlock(&msm_rotator_dev->rotator_lock);
+		return rc;
 	}
 	if (msm_rotator_get_plane_sizes(img_info->dst.format,
 					img_info->dst.width,
@@ -979,7 +1358,8 @@
 					&dst_planes)) {
 		pr_err("%s: invalid dst format\n", __func__);
 		rc = -EINVAL;
-		goto do_rotate_unlock_mutex;
+		mutex_unlock(&msm_rotator_dev->rotator_lock);
+		return rc;
 	}
 
 	rc = get_img(&info.src, ROTATOR_SRC_DOMAIN, (unsigned long *)&in_paddr,
@@ -988,7 +1368,7 @@
 	if (rc) {
 		pr_err("%s: in get_img() failed id=0x%08x\n",
 			DRIVER_NAME, info.src.memory_id);
-		goto do_rotate_unlock_mutex;
+		goto rotate_prepare_error;
 	}
 
 	rc = get_img(&info.dst, ROTATOR_DST_DOMAIN, (unsigned long *)&out_paddr,
@@ -997,10 +1377,10 @@
 	if (rc) {
 		pr_err("%s: out get_img() failed id=0x%08x\n",
 		       DRIVER_NAME, info.dst.memory_id);
-		goto do_rotate_unlock_mutex;
+		goto rotate_prepare_error;
 	}
 
-	format = msm_rotator_dev->img_info[s]->src.format;
+	format = img_info->src.format;
 	if (((info.version_key & VERSION_KEY_MASK) == 0xA5B4C300) &&
 			((info.version_key & ~VERSION_KEY_MASK) > 0) &&
 			(src_planes.num_planes == 2)) {
@@ -1010,7 +1390,7 @@
 			pr_err("%s: invalid src buffer (len=%lu offset=%x)\n",
 			       __func__, src_len, info.src.offset);
 			rc = -ERANGE;
-			goto do_rotate_unlock_mutex;
+			goto rotate_prepare_error;
 		}
 		if (checkoffset(info.dst.offset,
 				dst_planes.plane_size[0],
@@ -1018,7 +1398,7 @@
 			pr_err("%s: invalid dst buffer (len=%lu offset=%x)\n",
 			       __func__, dst_len, info.dst.offset);
 			rc = -ERANGE;
-			goto do_rotate_unlock_mutex;
+			goto rotate_prepare_error;
 		}
 
 		rc = get_img(&info.src_chroma, ROTATOR_SRC_DOMAIN,
@@ -1028,7 +1408,7 @@
 		if (rc) {
 			pr_err("%s: in chroma get_img() failed id=0x%08x\n",
 				DRIVER_NAME, info.src_chroma.memory_id);
-			goto do_rotate_unlock_mutex;
+			goto rotate_prepare_error;
 		}
 
 		rc = get_img(&info.dst_chroma, ROTATOR_DST_DOMAIN,
@@ -1038,7 +1418,7 @@
 		if (rc) {
 			pr_err("%s: out chroma get_img() failed id=0x%08x\n",
 				DRIVER_NAME, info.dst_chroma.memory_id);
-			goto do_rotate_unlock_mutex;
+			goto rotate_prepare_error;
 		}
 
 		if (checkoffset(info.src_chroma.offset,
@@ -1047,7 +1427,7 @@
 			pr_err("%s: invalid chr src buf len=%lu offset=%x\n",
 			       __func__, src_len, info.src_chroma.offset);
 			rc = -ERANGE;
-			goto do_rotate_unlock_mutex;
+			goto rotate_prepare_error;
 		}
 
 		if (checkoffset(info.dst_chroma.offset,
@@ -1056,7 +1436,7 @@
 			pr_err("%s: invalid chr dst buf len=%lu offset=%x\n",
 			       __func__, dst_len, info.dst_chroma.offset);
 			rc = -ERANGE;
-			goto do_rotate_unlock_mutex;
+			goto rotate_prepare_error;
 		}
 
 		in_chroma_paddr += info.src_chroma.offset;
@@ -1068,7 +1448,7 @@
 			pr_err("%s: invalid src buffer (len=%lu offset=%x)\n",
 			       __func__, src_len, info.src.offset);
 			rc = -ERANGE;
-			goto do_rotate_unlock_mutex;
+			goto rotate_prepare_error;
 		}
 		if (checkoffset(info.dst.offset,
 				dst_planes.total_size,
@@ -1076,7 +1456,7 @@
 			pr_err("%s: invalid dst buffer (len=%lu offset=%x)\n",
 			       __func__, dst_len, info.dst.offset);
 			rc = -ERANGE;
-			goto do_rotate_unlock_mutex;
+			goto rotate_prepare_error;
 		}
 	}
 
@@ -1089,6 +1469,91 @@
 		out_chroma_paddr = out_paddr + dst_planes.plane_size[0];
 	if (src_planes.num_planes >= 3)
 		in_chroma2_paddr = in_chroma_paddr + src_planes.plane_size[1];
+	if (dst_planes.num_planes >= 3)
+		out_chroma2_paddr = out_chroma_paddr + dst_planes.plane_size[1];
+
+	commit_info->data_info = info;
+	commit_info->img_info = *img_info;
+	commit_info->format = format;
+	commit_info->in_paddr = in_paddr;
+	commit_info->out_paddr = out_paddr;
+	commit_info->in_chroma_paddr = in_chroma_paddr;
+	commit_info->out_chroma_paddr = out_chroma_paddr;
+	commit_info->in_chroma2_paddr = in_chroma2_paddr;
+	commit_info->out_chroma2_paddr = out_chroma2_paddr;
+	commit_info->srcp0_file = srcp0_file;
+	commit_info->srcp1_file = srcp1_file;
+	commit_info->srcp0_ihdl = srcp0_ihdl;
+	commit_info->srcp1_ihdl = srcp1_ihdl;
+	commit_info->dstp0_file = dstp0_file;
+	commit_info->dstp0_ihdl = dstp0_ihdl;
+	commit_info->dstp1_file = dstp1_file;
+	commit_info->dstp1_ihdl = dstp1_ihdl;
+	commit_info->ps0_need = ps0_need;
+	commit_info->session_index = s;
+	commit_info->acq_fen = msm_rotator_dev->sync_info[s].acq_fen;
+	commit_info->fast_yuv_en = mrd->rot_session[s]->fast_yuv_enable;
+	mutex_unlock(&msm_rotator_dev->rotator_lock);
+	return 0;
+
+rotate_prepare_error:
+	put_img(dstp1_file, dstp1_ihdl, ROTATOR_DST_DOMAIN,
+		msm_rotator_dev->rot_session[s]->img_info.secure);
+	put_img(srcp1_file, srcp1_ihdl, ROTATOR_SRC_DOMAIN, 0);
+	put_img(dstp0_file, dstp0_ihdl, ROTATOR_DST_DOMAIN,
+		msm_rotator_dev->rot_session[s]->img_info.secure);
+
+	/* only source may use frame buffer */
+	if (info.src.flags & MDP_MEMORY_ID_TYPE_FB)
+		fput_light(srcp0_file, ps0_need);
+	else
+		put_img(srcp0_file, srcp0_ihdl, ROTATOR_SRC_DOMAIN, 0);
+	dev_dbg(msm_rotator_dev->device, "%s() returning rc = %d\n",
+		__func__, rc);
+	mutex_unlock(&msm_rotator_dev->rotator_lock);
+	return rc;
+}
+
+static int msm_rotator_do_rotate_sub(
+	struct msm_rotator_commit_info *commit_info)
+{
+	unsigned int status, format;
+	struct msm_rotator_data_info info;
+	unsigned int in_paddr, out_paddr;
+	int use_imem = 0, rc = 0;
+	struct file *srcp0_file, *dstp0_file;
+	struct file *srcp1_file, *dstp1_file;
+	struct ion_handle *srcp0_ihdl, *dstp0_ihdl;
+	struct ion_handle *srcp1_ihdl, *dstp1_ihdl;
+	int s, ps0_need;
+	unsigned int in_chroma_paddr, out_chroma_paddr;
+	unsigned int in_chroma2_paddr, out_chroma2_paddr;
+	struct msm_rotator_img_info *img_info;
+
+	mutex_lock(&msm_rotator_dev->rotator_lock);
+
+	info = commit_info->data_info;
+	img_info = &commit_info->img_info;
+	format = commit_info->format;
+	in_paddr = commit_info->in_paddr;
+	out_paddr = commit_info->out_paddr;
+	in_chroma_paddr = commit_info->in_chroma_paddr;
+	out_chroma_paddr = commit_info->out_chroma_paddr;
+	in_chroma2_paddr = commit_info->in_chroma2_paddr;
+	out_chroma2_paddr = commit_info->out_chroma2_paddr;
+	srcp0_file = commit_info->srcp0_file;
+	srcp1_file = commit_info->srcp1_file;
+	srcp0_ihdl = commit_info->srcp0_ihdl;
+	srcp1_ihdl = commit_info->srcp1_ihdl;
+	dstp0_file = commit_info->dstp0_file;
+	dstp0_ihdl = commit_info->dstp0_ihdl;
+	dstp1_file = commit_info->dstp1_file;
+	dstp1_ihdl = commit_info->dstp1_ihdl;
+	ps0_need = commit_info->ps0_need;
+	s = commit_info->session_index;
+
+	msm_rotator_wait_for_fence(commit_info->acq_fen);
+	commit_info->acq_fen = NULL;
 
 	cancel_delayed_work(&msm_rotator_dev->rot_clk_work);
 	if (msm_rotator_dev->rot_clk_state != CLK_EN) {
@@ -1110,17 +1575,17 @@
 	if (use_imem)
 		iowrite32(0x42, MSM_ROTATOR_MAX_BURST_SIZE);
 
-	iowrite32(((msm_rotator_dev->img_info[s]->src_rect.h & 0x1fff)
+	iowrite32(((img_info->src_rect.h & 0x1fff)
 				<< 16) |
-		  (msm_rotator_dev->img_info[s]->src_rect.w & 0x1fff),
+		  (img_info->src_rect.w & 0x1fff),
 		  MSM_ROTATOR_SRC_SIZE);
-	iowrite32(((msm_rotator_dev->img_info[s]->src_rect.y & 0x1fff)
+	iowrite32(((img_info->src_rect.y & 0x1fff)
 				<< 16) |
-		  (msm_rotator_dev->img_info[s]->src_rect.x & 0x1fff),
+		  (img_info->src_rect.x & 0x1fff),
 		  MSM_ROTATOR_SRC_XY);
-	iowrite32(((msm_rotator_dev->img_info[s]->src.height & 0x1fff)
+	iowrite32(((img_info->src.height & 0x1fff)
 				<< 16) |
-		  (msm_rotator_dev->img_info[s]->src.width & 0x1fff),
+		  (img_info->src.width & 0x1fff),
 		  MSM_ROTATOR_SRC_IMAGE_SIZE);
 
 	switch (format) {
@@ -1134,7 +1599,7 @@
 	case MDP_RGBX_8888:
 	case MDP_YCBCR_H1V1:
 	case MDP_YCRCB_H1V1:
-		rc = msm_rotator_rgb_types(msm_rotator_dev->img_info[s],
+		rc = msm_rotator_rgb_types(img_info,
 					   in_paddr, out_paddr,
 					   use_imem,
 					   msm_rotator_dev->last_session_idx
@@ -1147,17 +1612,19 @@
 	case MDP_Y_CR_CB_GH2V2:
 	case MDP_Y_CRCB_H2V2_TILE:
 	case MDP_Y_CBCR_H2V2_TILE:
-		rc = msm_rotator_ycxcx_h2v2(msm_rotator_dev->img_info[s],
+		rc = msm_rotator_ycxcx_h2v2(img_info,
 					    in_paddr, out_paddr, use_imem,
 					    msm_rotator_dev->last_session_idx
 								!= s,
 					    in_chroma_paddr,
 					    out_chroma_paddr,
-					    in_chroma2_paddr);
+					    in_chroma2_paddr,
+					    out_chroma2_paddr,
+					    commit_info->fast_yuv_en);
 		break;
 	case MDP_Y_CBCR_H2V1:
 	case MDP_Y_CRCB_H2V1:
-		rc = msm_rotator_ycxcx_h2v1(msm_rotator_dev->img_info[s],
+		rc = msm_rotator_ycxcx_h2v1(img_info,
 					    in_paddr, out_paddr, use_imem,
 					    msm_rotator_dev->last_session_idx
 								!= s,
@@ -1165,7 +1632,7 @@
 					    out_chroma_paddr);
 		break;
 	case MDP_YCRYCB_H2V1:
-		rc = msm_rotator_ycrycb(msm_rotator_dev->img_info[s],
+		rc = msm_rotator_ycrycb(img_info,
 				in_paddr, out_paddr, use_imem,
 				msm_rotator_dev->last_session_idx != s,
 				out_chroma_paddr);
@@ -1186,9 +1653,10 @@
 
 	msm_rotator_dev->processing = 1;
 	iowrite32(0x1, MSM_ROTATOR_START);
-
+	mutex_unlock(&msm_rotator_dev->rotator_lock);
 	wait_event(msm_rotator_dev->wq,
 		   (msm_rotator_dev->processing == 0));
+	mutex_lock(&msm_rotator_dev->rotator_lock);
 	status = (unsigned char)ioread32(MSM_ROTATOR_INTR_STATUS);
 	if ((status & 0x03) != 0x01) {
 		pr_err("%s(): AXI Bus Error, issuing SW_RESET\n", __func__);
@@ -1204,24 +1672,132 @@
 	msm_rotator_imem_free(ROTATOR_REQUEST);
 #endif
 	schedule_delayed_work(&msm_rotator_dev->rot_clk_work, HZ);
-do_rotate_unlock_mutex:
 	put_img(dstp1_file, dstp1_ihdl, ROTATOR_DST_DOMAIN,
-		msm_rotator_dev->img_info[s]->secure);
+		img_info->secure);
 	put_img(srcp1_file, srcp1_ihdl, ROTATOR_SRC_DOMAIN, 0);
 	put_img(dstp0_file, dstp0_ihdl, ROTATOR_DST_DOMAIN,
-		msm_rotator_dev->img_info[s]->secure);
+		img_info->secure);
 
 	/* only source may use frame buffer */
 	if (info.src.flags & MDP_MEMORY_ID_TYPE_FB)
 		fput_light(srcp0_file, ps0_need);
 	else
 		put_img(srcp0_file, srcp0_ihdl, ROTATOR_SRC_DOMAIN, 0);
+	msm_rotator_signal_timeline_done(s);
 	mutex_unlock(&msm_rotator_dev->rotator_lock);
 	dev_dbg(msm_rotator_dev->device, "%s() returning rc = %d\n",
 		__func__, rc);
+
 	return rc;
 }
 
+static void rot_wait_for_commit_queue(u32 is_all)
+{
+	int ret = 0;
+	u32 loop_cnt = 0;
+
+	while (1) {
+		mutex_lock(&mrd->commit_mutex);
+		if (is_all && (atomic_read(&mrd->commit_q_cnt) == 0))
+			break;
+		if ((!is_all) &&
+			(atomic_read(&mrd->commit_q_cnt) < MAX_COMMIT_QUEUE))
+			break;
+		INIT_COMPLETION(mrd->commit_comp);
+		mutex_unlock(&mrd->commit_mutex);
+		ret = wait_for_completion_interruptible_timeout(
+				&mrd->commit_comp,
+			msecs_to_jiffies(WAIT_ROT_TIMEOUT));
+		if ((ret <= 0) ||
+			(atomic_read(&mrd->commit_q_cnt) >= MAX_COMMIT_QUEUE) ||
+				(loop_cnt > MAX_COMMIT_QUEUE)) {
+			pr_err("%s wait for commit queue failed ret=%d pointers:%d %d",
+				__func__, ret, atomic_read(&mrd->commit_q_r),
+				atomic_read(&mrd->commit_q_w));
+			mutex_lock(&mrd->commit_mutex);
+			ret = -ETIME;
+			break;
+		} else {
+			ret = 0;
+		}
+		loop_cnt++;
+	};
+	if (is_all || ret) {
+		atomic_set(&mrd->commit_q_r, 0);
+		atomic_set(&mrd->commit_q_cnt, 0);
+		atomic_set(&mrd->commit_q_w, 0);
+	}
+	mutex_unlock(&mrd->commit_mutex);
+}
+
+static int msm_rotator_do_rotate(unsigned long arg)
+{
+	struct msm_rotator_data_info info;
+	struct rot_sync_info *sync_info;
+	int session_index, ret;
+	int commit_q_w;
+
+	if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
+		return -EFAULT;
+
+	rot_wait_for_commit_queue(false);
+	mutex_lock(&mrd->commit_mutex);
+	commit_q_w = atomic_read(&mrd->commit_q_w);
+	ret = msm_rotator_rotate_prepare(&info,
+			&mrd->commit_info[commit_q_w]);
+	if (ret) {
+		mutex_unlock(&mrd->commit_mutex);
+		return ret;
+	}
+
+	session_index = mrd->commit_info[commit_q_w].session_index;
+	sync_info = &msm_rotator_dev->sync_info[session_index];
+	mutex_lock(&sync_info->sync_mutex);
+	atomic_inc(&sync_info->queue_buf_cnt);
+	sync_info->acq_fen = NULL;
+	mutex_unlock(&sync_info->sync_mutex);
+
+	if (atomic_inc_return(&mrd->commit_q_w) >= MAX_COMMIT_QUEUE)
+		atomic_set(&mrd->commit_q_w, 0);
+	atomic_inc(&mrd->commit_q_cnt);
+
+	schedule_work(&mrd->commit_work);
+	mutex_unlock(&mrd->commit_mutex);
+
+	if (info.wait_for_finish)
+		rot_wait_for_commit_queue(true);
+
+	return 0;
+}
+
+static void rot_commit_wq_handler(struct work_struct *work)
+{
+	mutex_lock(&mrd->commit_wq_mutex);
+	mutex_lock(&mrd->commit_mutex);
+	while (atomic_read(&mrd->commit_q_cnt) > 0) {
+		mrd->commit_running = true;
+		mutex_unlock(&mrd->commit_mutex);
+		msm_rotator_do_rotate_sub(
+			&mrd->commit_info[atomic_read(&mrd->commit_q_r)]);
+		mutex_lock(&mrd->commit_mutex);
+		if (atomic_read(&mrd->commit_q_cnt) > 0) {
+			atomic_dec(&mrd->commit_q_cnt);
+			if (atomic_inc_return(&mrd->commit_q_r) >=
+					MAX_COMMIT_QUEUE)
+				atomic_set(&mrd->commit_q_r, 0);
+		}
+		complete_all(&mrd->commit_comp);
+	}
+	mrd->commit_running = false;
+	if (atomic_read(&mrd->commit_q_r) != atomic_read(&mrd->commit_q_w))
+		pr_err("%s invalid state: r=%d w=%d cnt=%d", __func__,
+			atomic_read(&mrd->commit_q_r),
+			atomic_read(&mrd->commit_q_w),
+			atomic_read(&mrd->commit_q_cnt));
+	mutex_unlock(&mrd->commit_mutex);
+	mutex_unlock(&mrd->commit_wq_mutex);
+}
+
 static void msm_rotator_set_perf_level(u32 wh, u32 is_rgb)
 {
 	u32 perf_level;
@@ -1327,10 +1903,14 @@
 			     struct msm_rotator_fd_info *fd_info)
 {
 	struct msm_rotator_img_info info;
+	struct msm_rotator_session *rot_session = NULL;
 	int rc = 0;
 	int s, is_rgb = 0;
-	int first_free_index = INVALID_SESSION;
+	int first_free_idx = INVALID_SESSION;
 	unsigned int dst_w, dst_h;
+	unsigned int is_planar420 = 0;
+	int fast_yuv_en = 0;
+	struct rot_sync_info *sync_info;
 
 	if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
 		return -EFAULT;
@@ -1362,6 +1942,30 @@
 	}
 
 	switch (info.src.format) {
+	case MDP_Y_CB_CR_H2V2:
+	case MDP_Y_CR_CB_H2V2:
+	case MDP_Y_CR_CB_GH2V2:
+		is_planar420 = 1;
+	case MDP_Y_CBCR_H2V2:
+	case MDP_Y_CRCB_H2V2:
+	case MDP_Y_CRCB_H2V2_TILE:
+	case MDP_Y_CBCR_H2V2_TILE:
+		if (rotator_hw_revision >= ROTATOR_REVISION_V2 &&
+			!(info.downscale_ratio &&
+			(info.rotations & MDP_ROT_90)))
+			fast_yuv_en = !fast_yuv_invalid_size_checker(
+						info.rotations,
+						info.src.width,
+						dst_w,
+						dst_h,
+						dst_w,
+						is_planar420);
+	break;
+	default:
+		fast_yuv_en = 0;
+	}
+
+	switch (info.src.format) {
 	case MDP_RGB_565:
 	case MDP_BGR_565:
 	case MDP_RGB_888:
@@ -1388,11 +1992,19 @@
 			info.dst.format = MDP_Y_CRCB_H2V1;
 		break;
 	case MDP_Y_CB_CR_H2V2:
+		if (fast_yuv_en) {
+			info.dst.format = info.src.format;
+			break;
+		}
 	case MDP_Y_CBCR_H2V2_TILE:
 		info.dst.format = MDP_Y_CBCR_H2V2;
 		break;
 	case MDP_Y_CR_CB_H2V2:
 	case MDP_Y_CR_CB_GH2V2:
+		if (fast_yuv_en) {
+			info.dst.format = info.src.format;
+			break;
+		}
 	case MDP_Y_CRCB_H2V2_TILE:
 		info.dst.format = MDP_Y_CRCB_H2V2;
 		break;
@@ -1405,12 +2017,14 @@
 	msm_rotator_set_perf_level((info.src.width*info.src.height), is_rgb);
 
 	for (s = 0; s < MAX_SESSIONS; s++) {
-		if ((msm_rotator_dev->img_info[s] != NULL) &&
+		if ((msm_rotator_dev->rot_session[s] != NULL) &&
 			(info.session_id ==
-			(unsigned int)msm_rotator_dev->img_info[s]
+			(unsigned int)msm_rotator_dev->rot_session[s]
 			)) {
-			*(msm_rotator_dev->img_info[s]) = info;
-			msm_rotator_dev->fd_info[s] = fd_info;
+			rot_session = msm_rotator_dev->rot_session[s];
+			rot_session->img_info =	info;
+			rot_session->fd_info =	*fd_info;
+			rot_session->fast_yuv_enable = fast_yuv_en;
 
 			if (msm_rotator_dev->last_session_idx == s)
 				msm_rotator_dev->last_session_idx =
@@ -1418,27 +2032,30 @@
 			break;
 		}
 
-		if ((msm_rotator_dev->img_info[s] == NULL) &&
-			(first_free_index ==
-			INVALID_SESSION))
-			first_free_index = s;
+		if ((msm_rotator_dev->rot_session[s] == NULL) &&
+			(first_free_idx == INVALID_SESSION))
+				first_free_idx = s;
 	}
 
-	if ((s == MAX_SESSIONS) && (first_free_index != INVALID_SESSION)) {
+	if ((s == MAX_SESSIONS) && (first_free_idx != INVALID_SESSION)) {
 		/* allocate a session id */
-		msm_rotator_dev->img_info[first_free_index] =
-			kzalloc(sizeof(struct msm_rotator_img_info),
+		msm_rotator_dev->rot_session[first_free_idx] =
+			kzalloc(sizeof(struct msm_rotator_session),
 					GFP_KERNEL);
-		if (!msm_rotator_dev->img_info[first_free_index]) {
+		if (!msm_rotator_dev->rot_session[first_free_idx]) {
 			printk(KERN_ERR "%s : unable to alloc mem\n",
 					__func__);
 			rc = -ENOMEM;
 			goto rotator_start_exit;
 		}
 		info.session_id = (unsigned int)
-			msm_rotator_dev->img_info[first_free_index];
-		*(msm_rotator_dev->img_info[first_free_index]) = info;
-		msm_rotator_dev->fd_info[first_free_index] = fd_info;
+			msm_rotator_dev->rot_session[first_free_idx];
+		rot_session = msm_rotator_dev->rot_session[first_free_idx];
+
+		rot_session->img_info =	info;
+		rot_session->fd_info =	*fd_info;
+		rot_session->fast_yuv_enable = fast_yuv_en;
+		s = first_free_idx;
 	} else if (s == MAX_SESSIONS) {
 		dev_dbg(msm_rotator_dev->device, "%s: all sessions in use\n",
 			__func__);
@@ -1449,6 +2066,25 @@
 		rc = -EFAULT;
 	if ((rc == 0) && (info.secure))
 		map_sec_resource(msm_rotator_dev);
+
+	sync_info = &msm_rotator_dev->sync_info[s];
+	if ((rc == 0) && (sync_info->initialized == false)) {
+		char timeline_name[MAX_TIMELINE_NAME_LEN];
+		if (sync_info->timeline == NULL) {
+			snprintf(timeline_name, sizeof(timeline_name),
+				"msm_rot_%d", first_free_idx);
+			sync_info->timeline =
+				sw_sync_timeline_create(timeline_name);
+			if (sync_info->timeline == NULL)
+				pr_err("%s: cannot create %s time line",
+					__func__, timeline_name);
+			sync_info->timeline_value = 0;
+		}
+		mutex_init(&sync_info->sync_mutex);
+		sync_info->initialized = true;
+	}
+	sync_info->acq_fen = NULL;
+	atomic_set(&sync_info->queue_buf_cnt, 0);
 rotator_start_exit:
 	mutex_unlock(&msm_rotator_dev->rotator_lock);
 
@@ -1466,15 +2102,16 @@
 
 	mutex_lock(&msm_rotator_dev->rotator_lock);
 	for (s = 0; s < MAX_SESSIONS; s++) {
-		if ((msm_rotator_dev->img_info[s] != NULL) &&
+		if ((msm_rotator_dev->rot_session[s] != NULL) &&
 			(session_id ==
-			(unsigned int)msm_rotator_dev->img_info[s])) {
+			(unsigned int)msm_rotator_dev->rot_session[s])) {
 			if (msm_rotator_dev->last_session_idx == s)
 				msm_rotator_dev->last_session_idx =
 					INVALID_SESSION;
-			kfree(msm_rotator_dev->img_info[s]);
-			msm_rotator_dev->img_info[s] = NULL;
-			msm_rotator_dev->fd_info[s] = NULL;
+			msm_rotator_signal_timeline(s);
+			msm_rotator_release_acq_fence(s);
+			kfree(msm_rotator_dev->rot_session[s]);
+			msm_rotator_dev->rot_session[s] = NULL;
 			break;
 		}
 	}
@@ -1502,7 +2139,7 @@
 
 	mutex_lock(&msm_rotator_dev->rotator_lock);
 	for (i = 0; i < MAX_SESSIONS; i++) {
-		if (msm_rotator_dev->fd_info[i] == NULL)
+		if (msm_rotator_dev->rot_session[i] == NULL)
 			break;
 	}
 
@@ -1552,14 +2189,15 @@
 	}
 
 	for (s = 0; s < MAX_SESSIONS; s++) {
-		if (msm_rotator_dev->img_info[s] != NULL &&
-			msm_rotator_dev->fd_info[s] == fd_info) {
+		if (msm_rotator_dev->rot_session[s] != NULL &&
+		&(msm_rotator_dev->rot_session[s]->fd_info) == fd_info) {
 			pr_debug("%s: freeing rotator session %p (pid %d)\n",
-				 __func__, msm_rotator_dev->img_info[s],
+				 __func__, msm_rotator_dev->rot_session[s],
 				 fd_info->pid);
-			kfree(msm_rotator_dev->img_info[s]);
-			msm_rotator_dev->img_info[s] = NULL;
-			msm_rotator_dev->fd_info[s] = NULL;
+			rot_wait_for_commit_queue(true);
+			msm_rotator_signal_timeline(s);
+			kfree(msm_rotator_dev->rot_session[s]);
+			msm_rotator_dev->rot_session[s] = NULL;
 			if (msm_rotator_dev->last_session_idx == s)
 				msm_rotator_dev->last_session_idx =
 					INVALID_SESSION;
@@ -1589,6 +2227,8 @@
 		return msm_rotator_do_rotate(arg);
 	case MSM_ROTATOR_IOCTL_FINISH:
 		return msm_rotator_finish(arg);
+	case MSM_ROTATOR_IOCTL_BUFFER_SYNC:
+		return msm_rotator_buf_sync(arg);
 
 	default:
 		dev_dbg(msm_rotator_dev->device,
@@ -1619,7 +2259,7 @@
 		return -ENOMEM;
 	}
 	for (i = 0; i < MAX_SESSIONS; i++)
-		msm_rotator_dev->img_info[i] = NULL;
+		msm_rotator_dev->rot_session[i] = NULL;
 	msm_rotator_dev->last_session_idx = INVALID_SESSION;
 
 	pdata = pdev->dev.platform_data;
@@ -1802,6 +2442,13 @@
 	}
 
 	init_waitqueue_head(&msm_rotator_dev->wq);
+	INIT_WORK(&msm_rotator_dev->commit_work, rot_commit_wq_handler);
+	init_completion(&msm_rotator_dev->commit_comp);
+	mutex_init(&msm_rotator_dev->commit_mutex);
+	mutex_init(&msm_rotator_dev->commit_wq_mutex);
+	atomic_set(&msm_rotator_dev->commit_q_w, 0);
+	atomic_set(&msm_rotator_dev->commit_q_r, 0);
+	atomic_set(&msm_rotator_dev->commit_q_cnt, 0);
 
 	dev_dbg(msm_rotator_dev->device, "probe successful\n");
 	return rc;
@@ -1834,6 +2481,7 @@
 {
 	int i;
 
+	rot_wait_for_commit_queue(true);
 #ifdef CONFIG_MSM_BUS_SCALING
 	if (msm_rotator_dev->bus_client_handle) {
 		msm_bus_scale_unregister_client
@@ -1864,8 +2512,8 @@
 	msm_rotator_dev->pclk = NULL;
 	mutex_destroy(&msm_rotator_dev->imem_lock);
 	for (i = 0; i < MAX_SESSIONS; i++)
-		if (msm_rotator_dev->img_info[i] != NULL)
-			kfree(msm_rotator_dev->img_info[i]);
+		if (msm_rotator_dev->rot_session[i] != NULL)
+			kfree(msm_rotator_dev->rot_session[i]);
 	kfree(msm_rotator_dev);
 	return 0;
 }
@@ -1873,6 +2521,7 @@
 #ifdef CONFIG_PM
 static int msm_rotator_suspend(struct platform_device *dev, pm_message_t state)
 {
+	rot_wait_for_commit_queue(true);
 	mutex_lock(&msm_rotator_dev->imem_lock);
 	if (msm_rotator_dev->imem_clk_state == CLK_EN
 		&& msm_rotator_dev->imem_clk) {
@@ -1885,6 +2534,7 @@
 		disable_rot_clks();
 		msm_rotator_dev->rot_clk_state = CLK_SUSPEND;
 	}
+	msm_rotator_release_all_timeline();
 	mutex_unlock(&msm_rotator_dev->rotator_lock);
 	return 0;
 }
diff --git a/drivers/char/msm_smd_pkt.c b/drivers/char/msm_smd_pkt.c
index adb2926..cc85fa1 100644
--- a/drivers/char/msm_smd_pkt.c
+++ b/drivers/char/msm_smd_pkt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. 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 and
diff --git a/drivers/char/tpm/tpm_st_i2c.c b/drivers/char/tpm/tpm_st_i2c.c
index 3a6e8c4f..333548e 100644
--- a/drivers/char/tpm/tpm_st_i2c.c
+++ b/drivers/char/tpm/tpm_st_i2c.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/coresight/coresight-etb.c b/drivers/coresight/coresight-etb.c
index bd5bf8e..d52ab28 100644
--- a/drivers/coresight/coresight-etb.c
+++ b/drivers/coresight/coresight-etb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/coresight/coresight-funnel.c b/drivers/coresight/coresight-funnel.c
index 3d5c0c2..7f39a3e 100644
--- a/drivers/coresight/coresight-funnel.c
+++ b/drivers/coresight/coresight-funnel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/coresight/coresight-replicator.c b/drivers/coresight/coresight-replicator.c
index fec76c5..fe37e5e 100644
--- a/drivers/coresight/coresight-replicator.c
+++ b/drivers/coresight/coresight-replicator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/coresight/coresight-stm.c b/drivers/coresight/coresight-stm.c
index b5238ea..bc72e02 100644
--- a/drivers/coresight/coresight-stm.c
+++ b/drivers/coresight/coresight-stm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/coresight/coresight-tpiu.c b/drivers/coresight/coresight-tpiu.c
index 290ae7f..3726a0d 100644
--- a/drivers/coresight/coresight-tpiu.c
+++ b/drivers/coresight/coresight-tpiu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/coresight/of_coresight.c b/drivers/coresight/of_coresight.c
index 5c2c525..a9d0182 100644
--- a/drivers/coresight/of_coresight.c
+++ b/drivers/coresight/of_coresight.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/crypto/msm/ota_crypto.c b/drivers/crypto/msm/ota_crypto.c
index b129c05..af53543 100644
--- a/drivers/crypto/msm/ota_crypto.c
+++ b/drivers/crypto/msm/ota_crypto.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/crypto/msm/qce.c b/drivers/crypto/msm/qce.c
index 4a9729c..b556701 100644
--- a/drivers/crypto/msm/qce.c
+++ b/drivers/crypto/msm/qce.c
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto Engine driver.
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/crypto/msm/qce.h b/drivers/crypto/msm/qce.h
index 037861c..8a31003 100644
--- a/drivers/crypto/msm/qce.h
+++ b/drivers/crypto/msm/qce.h
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto Engine driver API
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/crypto/msm/qce40.c b/drivers/crypto/msm/qce40.c
index de060cc..97f7a55 100644
--- a/drivers/crypto/msm/qce40.c
+++ b/drivers/crypto/msm/qce40.c
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto Engine driver.
  *
- * Copyright (c) 2011 - 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011 - 2012, The Linux Foundation. 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 and
diff --git a/drivers/crypto/msm/qce40.h b/drivers/crypto/msm/qce40.h
index 809ba7f..0d19106 100644
--- a/drivers/crypto/msm/qce40.h
+++ b/drivers/crypto/msm/qce40.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 4ccd89d..b4e68a7 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto Engine driver.
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
@@ -1432,6 +1432,9 @@
 		}
 	break;
 	default:
+		pr_err("Unknown mode of operation %d received, exiting now\n",
+			mode);
+		return -EINVAL;
 	break;
 	}
 
@@ -1585,6 +1588,8 @@
 		}
 	break;
 	default:
+		pr_err("Unknown algorithms %d received, exiting now\n", alg);
+		return -EINVAL;
 	break;
 	}
 
@@ -1806,6 +1811,8 @@
 								0, NULL);
 	break;
 	default:
+		pr_err("Unknown algorithms %d received, exiting now\n", alg);
+		return -EINVAL;
 	break;
 	}
 
@@ -2150,6 +2157,12 @@
 
 	if (q_req->mode != QCE_MODE_CCM)
 		ivsize = crypto_aead_ivsize(aead);
+		auth_cmdlistinfo = &pce_dev->ce_sps.cmdlistptr.aead_sha1_hmac;
+		if (auth_cmdlistinfo == NULL) {
+			pr_err("Received NULL cmdlist, exiting now\n");
+			return -EINVAL;
+		}
+	}
 
 	ce_burst_size = pce_dev->ce_sps.ce_burst_size;
 	if (q_req->dir == QCE_ENCRYPT) {
diff --git a/drivers/crypto/msm/qce50.h b/drivers/crypto/msm/qce50.h
index c9eba82..adf4c50 100644
--- a/drivers/crypto/msm/qce50.h
+++ b/drivers/crypto/msm/qce50.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/crypto/msm/qce_ota.h b/drivers/crypto/msm/qce_ota.h
index 72af585..8778ca5 100644
--- a/drivers/crypto/msm/qce_ota.h
+++ b/drivers/crypto/msm/qce_ota.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index 63f7fd9..723308e 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1,6 +1,6 @@
 /* Qualcomm CE device driver.
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. 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 and
@@ -595,6 +595,9 @@
 		sreq.authklen = qcedev_areq->sha_op_req.authklen;
 		break;
 	default:
+		pr_err("Algorithm %d not supported, exiting\n",
+			qcedev_areq->sha_op_req.alg);
+		return -EINVAL;
 		break;
 	};
 
@@ -2038,18 +2041,6 @@
 	podev->pdev = pdev;
 	platform_set_drvdata(pdev, podev);
 
-	if (podev->platform_support.bus_scale_table != NULL) {
-		podev->bus_scale_handle =
-			msm_bus_scale_register_client(
-				(struct msm_bus_scale_pdata *)
-				podev->platform_support.bus_scale_table);
-		if (!podev->bus_scale_handle) {
-			printk(KERN_ERR "%s not able to get bus scale\n",
-								__func__);
-			rc =  -ENOMEM;
-			goto err;
-		}
-	}
 	rc = misc_register(&podev->miscdevice);
 	qce_hw_support(podev->qce, &podev->ce_support);
 	if (podev->ce_support.bam) {
@@ -2070,6 +2061,18 @@
 				platform_support->bus_scale_table;
 		podev->platform_support.sha_hmac = platform_support->sha_hmac;
 	}
+	if (podev->platform_support.bus_scale_table != NULL) {
+		podev->bus_scale_handle =
+			msm_bus_scale_register_client(
+				(struct msm_bus_scale_pdata *)
+				podev->platform_support.bus_scale_table);
+		if (!podev->bus_scale_handle) {
+			pr_err("%s not able to get bus scale\n",
+				__func__);
+			rc =  -ENOMEM;
+			goto err;
+		}
+	}
 	if (rc >= 0)
 		return 0;
 	else
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 7fc5cab..63da4bb 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto driver
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. 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 and
@@ -1151,6 +1151,8 @@
 		sreq.authklen = SHA_HMAC_KEY_SIZE;
 		break;
 	default:
+		pr_err("Algorithm %d not supported, exiting", sha_ctx->alg);
+		ret = -1;
 		break;
 	};
 	ret =  qce_process_sha_req(cp->qce, &sreq);
@@ -1213,6 +1215,12 @@
 			rctx->orig_dst = req->dst;
 			rctx->data = kzalloc((req->cryptlen + qreq.assoclen +
 					qreq.authsize + 64*2), GFP_KERNEL);
+			if (rctx->data == NULL) {
+				pr_err("Mem Alloc fail rctx->data, err %ld\n",
+							PTR_ERR(rctx->data));
+				kzfree(qreq.assoc);
+				return -ENOMEM;
+			}
 
 			memcpy((char *)rctx->data, qreq.assoc, qreq.assoclen);
 
diff --git a/drivers/crypto/msm/qcryptohw_30.h b/drivers/crypto/msm/qcryptohw_30.h
index edbee71..3c18ed2 100644
--- a/drivers/crypto/msm/qcryptohw_30.h
+++ b/drivers/crypto/msm/qcryptohw_30.h
@@ -1,4 +1,4 @@
-/* Copyright (c)2009- 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c)2009- 2011, The Linux Foundation. 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 and
diff --git a/drivers/crypto/msm/qcryptohw_40.h b/drivers/crypto/msm/qcryptohw_40.h
index 367bdaa..f2102c6 100644
--- a/drivers/crypto/msm/qcryptohw_40.h
+++ b/drivers/crypto/msm/qcryptohw_40.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/crypto/msm/qcryptohw_50.h b/drivers/crypto/msm/qcryptohw_50.h
index 898109e..26b833c 100644
--- a/drivers/crypto/msm/qcryptohw_50.h
+++ b/drivers/crypto/msm/qcryptohw_50.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/gpio/gpio-fsm9xxx.c b/drivers/gpio/gpio-fsm9xxx.c
index ad7e1fd..496e97e 100644
--- a/drivers/gpio/gpio-fsm9xxx.c
+++ b/drivers/gpio/gpio-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpio/gpio-msm-common.c b/drivers/gpio/gpio-msm-common.c
index 800c376..41301e3 100644
--- a/drivers/gpio/gpio-msm-common.c
+++ b/drivers/gpio/gpio-msm-common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -343,8 +343,10 @@
 	mb();
 	spin_unlock_irqrestore(&tlmm_lock, irq_flags);
 
-	if (msm_gpio_irq_extn.irq_set_type)
-		msm_gpio_irq_extn.irq_set_type(d, flow_type);
+	if ((flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH) {
+		if (msm_gpio_irq_extn.irq_set_type)
+			msm_gpio_irq_extn.irq_set_type(d, flow_type);
+	}
 
 	return 0;
 }
diff --git a/drivers/gpio/gpio-msm-common.h b/drivers/gpio/gpio-msm-common.h
index b1590ef..67c9569 100644
--- a/drivers/gpio/gpio-msm-common.h
+++ b/drivers/gpio/gpio-msm-common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/gpio/gpio-msm-v1.c b/drivers/gpio/gpio-msm-v1.c
index 8718c9a..f28ebb4 100644
--- a/drivers/gpio/gpio-msm-v1.c
+++ b/drivers/gpio/gpio-msm-v1.c
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-msm/gpio.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c
index 592391e..8c42bd6 100644
--- a/drivers/gpio/gpio-msm-v2.c
+++ b/drivers/gpio/gpio-msm-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpio/gpio-msm-v3.c b/drivers/gpio/gpio-msm-v3.c
index 1da276f..b395a4c 100644
--- a/drivers/gpio/gpio-msm-v3.c
+++ b/drivers/gpio/gpio-msm-v3.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/gpio/gpio-pm8xxx-rpc.c b/drivers/gpio/gpio-pm8xxx-rpc.c
index 1acc741..5cbbe26 100644
--- a/drivers/gpio/gpio-pm8xxx-rpc.c
+++ b/drivers/gpio/gpio-pm8xxx-rpc.c
@@ -1,7 +1,7 @@
 /*
  * Qualcomm PMIC8XXX GPIO driver based on RPC
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c
index 93b94bd..d24bd8f 100644
--- a/drivers/gpio/gpio-sx150x.c
+++ b/drivers/gpio/gpio-sx150x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/gpio/pm8xxx-mpp.c b/drivers/gpio/pm8xxx-mpp.c
index affe980..9b2ac74 100644
--- a/drivers/gpio/pm8xxx-mpp.c
+++ b/drivers/gpio/pm8xxx-mpp.c
@@ -1,7 +1,7 @@
 /*
  * Qualcomm PM8XXX Multi-Purpose Pin (MPP) driver
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpio/qpnp-pin.c b/drivers/gpio/qpnp-pin.c
index 67a2e6b..ab9a6da 100644
--- a/drivers/gpio/qpnp-pin.c
+++ b/drivers/gpio/qpnp-pin.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c
index 82431dc..fa67ca2 100644
--- a/drivers/gpu/drm/drm_platform.c
+++ b/drivers/gpu/drm/drm_platform.c
@@ -3,7 +3,7 @@
  *
  * Copyright 2003 José Fonseca.
  * Copyright 2003 Leif Delgass.
- * Copyright (c) 2009, Code Aurora Forum.
+ * Copyright (c) 2009, The Linux Foundation.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index f789ac8..d005605 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index b889368..256de07 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_carveout_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -240,25 +240,78 @@
 			void *vaddr, unsigned int offset, unsigned int length,
 			unsigned int cmd)
 {
-	void (*outer_cache_op)(phys_addr_t, phys_addr_t);
+	void (*outer_cache_op)(phys_addr_t, phys_addr_t) = NULL;
 	struct ion_carveout_heap *carveout_heap =
 	     container_of(heap, struct  ion_carveout_heap, heap);
+	unsigned int size_to_vmap, total_size;
+	int i, j;
+	void *ptr = NULL;
+	ion_phys_addr_t buff_phys = buffer->priv_phys;
 
-	switch (cmd) {
-	case ION_IOC_CLEAN_CACHES:
-		dmac_clean_range(vaddr, vaddr + length);
-		outer_cache_op = outer_clean_range;
-		break;
-	case ION_IOC_INV_CACHES:
-		dmac_inv_range(vaddr, vaddr + length);
-		outer_cache_op = outer_inv_range;
-		break;
-	case ION_IOC_CLEAN_INV_CACHES:
-		dmac_flush_range(vaddr, vaddr + length);
-		outer_cache_op = outer_flush_range;
-		break;
-	default:
-		return -EINVAL;
+	if (!vaddr) {
+		/*
+		 * Split the vmalloc space into smaller regions in
+		 * order to clean and/or invalidate the cache.
+		 */
+		size_to_vmap = ((VMALLOC_END - VMALLOC_START)/8);
+		total_size = buffer->size;
+
+		for (i = 0; i < total_size; i += size_to_vmap) {
+			size_to_vmap = min(size_to_vmap, total_size - i);
+			for (j = 0; j < 10 && size_to_vmap; ++j) {
+				ptr = ioremap(buff_phys, size_to_vmap);
+				if (ptr) {
+					switch (cmd) {
+					case ION_IOC_CLEAN_CACHES:
+						dmac_clean_range(ptr,
+							ptr + size_to_vmap);
+						outer_cache_op =
+							outer_clean_range;
+						break;
+					case ION_IOC_INV_CACHES:
+						dmac_inv_range(ptr,
+							ptr + size_to_vmap);
+						outer_cache_op =
+							outer_inv_range;
+						break;
+					case ION_IOC_CLEAN_INV_CACHES:
+						dmac_flush_range(ptr,
+							ptr + size_to_vmap);
+						outer_cache_op =
+							outer_flush_range;
+						break;
+					default:
+						return -EINVAL;
+					}
+					buff_phys += size_to_vmap;
+					break;
+				} else {
+					size_to_vmap >>= 1;
+				}
+			}
+			if (!ptr) {
+				pr_err("Couldn't io-remap the memory\n");
+				return -EINVAL;
+			}
+			iounmap(ptr);
+		}
+	} else {
+		switch (cmd) {
+		case ION_IOC_CLEAN_CACHES:
+			dmac_clean_range(vaddr, vaddr + length);
+			outer_cache_op = outer_clean_range;
+			break;
+		case ION_IOC_INV_CACHES:
+			dmac_inv_range(vaddr, vaddr + length);
+			outer_cache_op = outer_inv_range;
+			break;
+		case ION_IOC_CLEAN_INV_CACHES:
+			dmac_flush_range(vaddr, vaddr + length);
+			outer_cache_op = outer_flush_range;
+			break;
+		default:
+			return -EINVAL;
+		}
 	}
 
 	if (carveout_heap->has_outer_cache) {
diff --git a/drivers/gpu/ion/ion_cma_heap.c b/drivers/gpu/ion/ion_cma_heap.c
index bef6b6f..8b50185 100644
--- a/drivers/gpu/ion/ion_cma_heap.c
+++ b/drivers/gpu/ion/ion_cma_heap.c
@@ -280,15 +280,30 @@
 
 	switch (cmd) {
 	case ION_IOC_CLEAN_CACHES:
-		dmac_clean_range(vaddr, vaddr + length);
+		if (!vaddr)
+			dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_TO_DEVICE);
+		else
+			dmac_clean_range(vaddr, vaddr + length);
 		outer_cache_op = outer_clean_range;
 		break;
 	case ION_IOC_INV_CACHES:
-		dmac_inv_range(vaddr, vaddr + length);
+		if (!vaddr)
+			dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_FROM_DEVICE);
+		else
+			dmac_inv_range(vaddr, vaddr + length);
 		outer_cache_op = outer_inv_range;
 		break;
 	case ION_IOC_CLEAN_INV_CACHES:
-		dmac_flush_range(vaddr, vaddr + length);
+		if (!vaddr) {
+			dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_TO_DEVICE);
+			dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_FROM_DEVICE);
+		} else {
+			dmac_flush_range(vaddr, vaddr + length);
+		}
 		outer_cache_op = outer_flush_range;
 		break;
 	default:
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index 017b756..ea0ec41 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -243,9 +243,13 @@
 
 	if (atomic_inc_return(&cp_heap->protect_cnt) == 1) {
 		/* Make sure we are in C state when the heap is protected. */
-		if (!cp_heap->allocated_bytes)
-			if (ion_on_first_alloc(heap))
+		if (!cp_heap->allocated_bytes) {
+			ret_value = ion_on_first_alloc(heap);
+			if (ret_value) {
+				atomic_dec(&cp_heap->protect_cnt);
 				goto out;
+			}
+		}
 
 		ret_value = ion_cp_protect_mem(cp_heap->secure_base,
 				cp_heap->secure_size, cp_heap->permission_type,
@@ -578,6 +582,11 @@
 			int i;
 			pgprot_t pgprot;
 
+			if (!pages) {
+				mutex_unlock(&cp_heap->lock);
+				return ERR_PTR(-ENOMEM);
+			}
+
 			if (ION_IS_CACHED(buffer->flags))
 				pgprot = PAGE_KERNEL;
 			else
@@ -685,25 +694,77 @@
 			void *vaddr, unsigned int offset, unsigned int length,
 			unsigned int cmd)
 {
-	void (*outer_cache_op)(phys_addr_t, phys_addr_t);
+	void (*outer_cache_op)(phys_addr_t, phys_addr_t) = NULL;
 	struct ion_cp_heap *cp_heap =
-	     container_of(heap, struct  ion_cp_heap, heap);
+		container_of(heap, struct  ion_cp_heap, heap);
+	unsigned int size_to_vmap, total_size;
+	int i, j;
+	void *ptr = NULL;
+	ion_phys_addr_t buff_phys = buffer->priv_phys;
 
-	switch (cmd) {
-	case ION_IOC_CLEAN_CACHES:
-		dmac_clean_range(vaddr, vaddr + length);
-		outer_cache_op = outer_clean_range;
-		break;
-	case ION_IOC_INV_CACHES:
-		dmac_inv_range(vaddr, vaddr + length);
-		outer_cache_op = outer_inv_range;
-		break;
-	case ION_IOC_CLEAN_INV_CACHES:
-		dmac_flush_range(vaddr, vaddr + length);
-		outer_cache_op = outer_flush_range;
-		break;
-	default:
-		return -EINVAL;
+	if (!vaddr) {
+		/*
+		 * Split the vmalloc space into smaller regions in
+		 * order to clean and/or invalidate the cache.
+		 */
+		size_to_vmap = (VMALLOC_END - VMALLOC_START)/8;
+		total_size = buffer->size;
+		for (i = 0; i < total_size; i += size_to_vmap) {
+			size_to_vmap = min(size_to_vmap, total_size - i);
+			for (j = 0; j < 10 && size_to_vmap; ++j) {
+				ptr = ioremap(buff_phys, size_to_vmap);
+				if (ptr) {
+					switch (cmd) {
+					case ION_IOC_CLEAN_CACHES:
+						dmac_clean_range(ptr,
+							ptr + size_to_vmap);
+						outer_cache_op =
+							outer_clean_range;
+						break;
+					case ION_IOC_INV_CACHES:
+						dmac_inv_range(ptr,
+							ptr + size_to_vmap);
+						outer_cache_op =
+							outer_inv_range;
+						break;
+					case ION_IOC_CLEAN_INV_CACHES:
+						dmac_flush_range(ptr,
+							ptr + size_to_vmap);
+						outer_cache_op =
+							outer_flush_range;
+						break;
+					default:
+						return -EINVAL;
+					}
+					buff_phys += size_to_vmap;
+					break;
+				} else {
+					size_to_vmap >>= 1;
+				}
+			}
+			if (!ptr) {
+				pr_err("Couldn't io-remap the memory\n");
+				return -EINVAL;
+			}
+			iounmap(ptr);
+		}
+	} else {
+		switch (cmd) {
+		case ION_IOC_CLEAN_CACHES:
+			dmac_clean_range(vaddr, vaddr + length);
+			outer_cache_op = outer_clean_range;
+			break;
+		case ION_IOC_INV_CACHES:
+			dmac_inv_range(vaddr, vaddr + length);
+			outer_cache_op = outer_inv_range;
+			break;
+		case ION_IOC_CLEAN_INV_CACHES:
+			dmac_flush_range(vaddr, vaddr + length);
+			outer_cache_op = outer_flush_range;
+			break;
+		default:
+			return -EINVAL;
+		}
 	}
 
 	if (cp_heap->has_outer_cache) {
diff --git a/drivers/gpu/ion/ion_heap.c b/drivers/gpu/ion/ion_heap.c
index 0670468..98c1a8c 100644
--- a/drivers/gpu/ion/ion_heap.c
+++ b/drivers/gpu/ion/ion_heap.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index 0e47d54..a7004ed 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/msm_ion.h>
 #include <linux/mm.h>
+#include <linux/highmem.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
@@ -32,36 +33,113 @@
 	unsigned int has_outer_cache;
 };
 
+/*
+ * We will attempt to allocate high-order pages and store those in an
+ * sg_list. However, some APIs expect an array of struct page * where
+ * each page is of size PAGE_SIZE. We use this extra structure to
+ * carry around an array of such pages (derived from the high-order
+ * pages with nth_page).
+ */
 struct ion_iommu_priv_data {
 	struct page **pages;
 	int nrpages;
 	unsigned long size;
 };
 
+#define MAX_VMAP_RETRIES 10
+
+static const unsigned int orders[] = {8, 4, 0};
+static const int num_orders = ARRAY_SIZE(orders);
+
+struct page_info {
+	struct page *page;
+	unsigned int order;
+	struct list_head list;
+};
+
+static unsigned int order_to_size(int order)
+{
+	return PAGE_SIZE << order;
+}
+
+static struct page_info *alloc_largest_available(unsigned long size,
+						unsigned int max_order)
+{
+	struct page *page;
+	struct page_info *info;
+	int i;
+
+	for (i = 0; i < num_orders; i++) {
+		gfp_t gfp;
+		if (size < order_to_size(orders[i]))
+			continue;
+		if (max_order < orders[i])
+			continue;
+
+		gfp = __GFP_HIGHMEM;
+
+		if (orders[i]) {
+			gfp |= __GFP_COMP | __GFP_NORETRY |
+			       __GFP_NO_KSWAPD | __GFP_NOWARN;
+		} else {
+			gfp |= GFP_KERNEL;
+		}
+		page = alloc_pages(gfp, orders[i]);
+		if (!page)
+			continue;
+
+		info = kmalloc(sizeof(struct page_info), GFP_KERNEL);
+		info->page = page;
+		info->order = orders[i];
+		return info;
+	}
+	return NULL;
+}
+
 static int ion_iommu_heap_allocate(struct ion_heap *heap,
 				      struct ion_buffer *buffer,
 				      unsigned long size, unsigned long align,
 				      unsigned long flags)
 {
 	int ret, i;
+	struct list_head pages_list;
+	struct page_info *info, *tmp_info;
 	struct ion_iommu_priv_data *data = NULL;
 
 	if (msm_use_iommu()) {
 		struct scatterlist *sg;
 		struct sg_table *table;
-		unsigned int i;
+		int j;
+		void *ptr = NULL;
+		unsigned int npages_to_vmap, total_pages, num_large_pages = 0;
+		long size_remaining = PAGE_ALIGN(size);
+		unsigned int max_order = orders[0];
 
 		data = kmalloc(sizeof(*data), GFP_KERNEL);
 		if (!data)
 			return -ENOMEM;
 
+		INIT_LIST_HEAD(&pages_list);
+		while (size_remaining > 0) {
+			info = alloc_largest_available(size_remaining,
+						max_order);
+			if (!info) {
+				ret = -ENOMEM;
+				goto err_free_data;
+			}
+			list_add_tail(&info->list, &pages_list);
+			size_remaining -= order_to_size(info->order);
+			max_order = info->order;
+			num_large_pages++;
+		}
+
 		data->size = PFN_ALIGN(size);
 		data->nrpages = data->size >> PAGE_SHIFT;
 		data->pages = kzalloc(sizeof(struct page *)*data->nrpages,
 				GFP_KERNEL);
 		if (!data->pages) {
 			ret = -ENOMEM;
-			goto err1;
+			goto err_free_data;
 		}
 
 		table = buffer->sg_table =
@@ -71,18 +149,55 @@
 			ret = -ENOMEM;
 			goto err1;
 		}
-		ret = sg_alloc_table(table, data->nrpages, GFP_KERNEL);
+		ret = sg_alloc_table(table, num_large_pages, GFP_KERNEL);
 		if (ret)
 			goto err2;
 
-		for_each_sg(table->sgl, sg, table->nents, i) {
-			data->pages[i] = alloc_page(
-				GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
-			if (!data->pages[i])
-				goto err3;
-
-			sg_set_page(sg, data->pages[i], PAGE_SIZE, 0);
+		i = 0;
+		sg = table->sgl;
+		list_for_each_entry_safe(info, tmp_info, &pages_list, list) {
+			struct page *page = info->page;
+			sg_set_page(sg, page, order_to_size(info->order), 0);
 			sg_dma_address(sg) = sg_phys(sg);
+			sg = sg_next(sg);
+			for (j = 0; j < (1 << info->order); ++j)
+				data->pages[i++] = nth_page(page, j);
+			list_del(&info->list);
+			kfree(info);
+		}
+
+		/*
+		 * As an optimization, we omit __GFP_ZERO from
+		 * alloc_page above and manually zero out all of the
+		 * pages in one fell swoop here. To safeguard against
+		 * insufficient vmalloc space, we only vmap
+		 * `npages_to_vmap' at a time, starting with a
+		 * conservative estimate of 1/8 of the total number of
+		 * vmalloc pages available. Note that the `pages'
+		 * array is composed of all 4K pages, irrespective of
+		 * the size of the pages on the sg list.
+		 */
+		npages_to_vmap = ((VMALLOC_END - VMALLOC_START)/8)
+			>> PAGE_SHIFT;
+		total_pages = data->nrpages;
+		for (i = 0; i < total_pages; i += npages_to_vmap) {
+			npages_to_vmap = min(npages_to_vmap, total_pages - i);
+			for (j = 0; j < MAX_VMAP_RETRIES && npages_to_vmap;
+			     ++j) {
+				ptr = vmap(&data->pages[i], npages_to_vmap,
+					VM_IOREMAP, pgprot_kernel);
+				if (ptr)
+					break;
+				else
+					npages_to_vmap >>= 1;
+			}
+			if (!ptr) {
+				pr_err("Couldn't vmap the pages for zeroing\n");
+				ret = -ENOMEM;
+				goto err3;
+			}
+			memset(ptr, 0, npages_to_vmap * PAGE_SIZE);
+			vunmap(ptr);
 		}
 
 		if (!ION_IS_CACHED(flags))
@@ -102,28 +217,38 @@
 err2:
 	kfree(buffer->sg_table);
 	buffer->sg_table = 0;
-
-	for (i = 0; i < data->nrpages; i++) {
-		if (data->pages[i])
-			__free_page(data->pages[i]);
-	}
-	kfree(data->pages);
 err1:
+	kfree(data->pages);
+err_free_data:
 	kfree(data);
+
+	list_for_each_entry_safe(info, tmp_info, &pages_list, list) {
+		if (info->page)
+			__free_pages(info->page, info->order);
+		list_del(&info->list);
+		kfree(info);
+	}
 	return ret;
 }
 
 static void ion_iommu_heap_free(struct ion_buffer *buffer)
 {
-	struct ion_iommu_priv_data *data = buffer->priv_virt;
 	int i;
+	struct scatterlist *sg;
+	struct sg_table *table = buffer->sg_table;
+	struct ion_iommu_priv_data *data = buffer->priv_virt;
 
+	if (!table)
+		return;
 	if (!data)
 		return;
 
-	for (i = 0; i < data->nrpages; i++)
-		__free_page(data->pages[i]);
+	for_each_sg(table->sgl, sg, table->nents, i)
+		__free_pages(sg_page(sg), get_order(sg_dma_len(sg)));
 
+	sg_free_table(table);
+	kfree(table);
+	table = 0;
 	kfree(data->pages);
 	kfree(data);
 }
@@ -158,25 +283,34 @@
 int ion_iommu_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
 			       struct vm_area_struct *vma)
 {
-	struct ion_iommu_priv_data *data = buffer->priv_virt;
+	struct sg_table *table = buffer->sg_table;
+	unsigned long addr = vma->vm_start;
+	unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
+	struct scatterlist *sg;
 	int i;
-	unsigned long curr_addr;
-	if (!data)
-		return -EINVAL;
 
 	if (!ION_IS_CACHED(buffer->flags))
 		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 
-	curr_addr = vma->vm_start;
-	for (i = 0; i < data->nrpages && curr_addr < vma->vm_end; i++) {
-		if (vm_insert_page(vma, curr_addr, data->pages[i])) {
-			/*
-			 * This will fail the mmap which will
-			 * clean up the vma space properly.
-			 */
-			return -EINVAL;
+	for_each_sg(table->sgl, sg, table->nents, i) {
+		struct page *page = sg_page(sg);
+		unsigned long remainder = vma->vm_end - addr;
+		unsigned long len = sg_dma_len(sg);
+
+		if (offset >= sg_dma_len(sg)) {
+			offset -= sg_dma_len(sg);
+			continue;
+		} else if (offset) {
+			page += offset / PAGE_SIZE;
+			len = sg_dma_len(sg) - offset;
+			offset = 0;
 		}
-		curr_addr += PAGE_SIZE;
+		len = min(len, remainder);
+		remap_pfn_range(vma, addr, page_to_pfn(page), len,
+				vma->vm_page_prot);
+		addr += len;
+		if (addr >= vma->vm_end)
+			return 0;
 	}
 	return 0;
 }
@@ -200,6 +334,14 @@
 	data->mapped_size = iova_length;
 	extra = iova_length - buffer->size;
 
+	/* Use the biggest alignment to allow bigger IOMMU mappings.
+	 * Use the first entry since the first entry will always be the
+	 * biggest entry. To take advantage of bigger mapping sizes both the
+	 * VA and PA addresses have to be aligned to the biggest size.
+	 */
+	if (buffer->sg_table->sgl->length > align)
+		align = buffer->sg_table->sgl->length;
+
 	ret = msm_allocate_iova_address(domain_num, partition_num,
 						data->mapped_size, align,
 						&data->iova_addr);
@@ -278,15 +420,30 @@
 
 	switch (cmd) {
 	case ION_IOC_CLEAN_CACHES:
-		dmac_clean_range(vaddr, vaddr + length);
+		if (!vaddr)
+			dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_TO_DEVICE);
+		else
+			dmac_clean_range(vaddr, vaddr + length);
 		outer_cache_op = outer_clean_range;
 		break;
 	case ION_IOC_INV_CACHES:
-		dmac_inv_range(vaddr, vaddr + length);
+		if (!vaddr)
+			dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_FROM_DEVICE);
+		else
+			dmac_inv_range(vaddr, vaddr + length);
 		outer_cache_op = outer_inv_range;
 		break;
 	case ION_IOC_CLEAN_INV_CACHES:
-		dmac_flush_range(vaddr, vaddr + length);
+		if (!vaddr) {
+			dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_TO_DEVICE);
+			dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_FROM_DEVICE);
+		} else {
+			dmac_flush_range(vaddr, vaddr + length);
+		}
 		outer_cache_op = outer_flush_range;
 		break;
 	default:
@@ -317,10 +474,6 @@
 static void ion_iommu_heap_unmap_dma(struct ion_heap *heap,
 				 struct ion_buffer *buffer)
 {
-	if (buffer->sg_table)
-		sg_free_table(buffer->sg_table);
-	kfree(buffer->sg_table);
-	buffer->sg_table = 0;
 }
 
 static struct ion_heap_ops iommu_heap_ops = {
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index bfd5ebd..d494f7a 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_priv.h
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index 132545b..e94a585 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_system_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -28,6 +28,7 @@
 #include <mach/memory.h>
 #include <asm/cacheflush.h>
 #include <linux/msm_ion.h>
+#include <linux/dma-mapping.h>
 
 static atomic_t system_heap_allocated;
 static atomic_t system_contig_heap_allocated;
@@ -184,15 +185,30 @@
 
 	switch (cmd) {
 	case ION_IOC_CLEAN_CACHES:
-		dmac_clean_range(vaddr, vaddr + length);
+		if (!vaddr)
+			dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_TO_DEVICE);
+		else
+			dmac_clean_range(vaddr, vaddr + length);
 		outer_cache_op = outer_clean_range;
 		break;
 	case ION_IOC_INV_CACHES:
-		dmac_inv_range(vaddr, vaddr + length);
+		if (!vaddr)
+			dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_FROM_DEVICE);
+		else
+			dmac_inv_range(vaddr, vaddr + length);
 		outer_cache_op = outer_inv_range;
 		break;
 	case ION_IOC_CLEAN_INV_CACHES:
-		dmac_flush_range(vaddr, vaddr + length);
+		if (!vaddr) {
+			dma_sync_sg_for_device(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_TO_DEVICE);
+			dma_sync_sg_for_cpu(NULL, buffer->sg_table->sgl,
+				buffer->sg_table->nents, DMA_FROM_DEVICE);
+		} else {
+			dmac_flush_range(vaddr, vaddr + length);
+		}
 		outer_cache_op = outer_flush_range;
 		break;
 	default:
@@ -255,6 +271,14 @@
 	data->mapped_size = iova_length;
 	extra = iova_length - buffer->size;
 
+	/* Use the biggest alignment to allow bigger IOMMU mappings.
+	 * Use the first entry since the first entry will always be the
+	 * biggest entry. To take advantage of bigger mapping sizes both the
+	 * VA and PA addresses have to be aligned to the biggest size.
+	 */
+	if (table->sgl->length > align)
+		align = table->sgl->length;
+
 	ret = msm_allocate_iova_address(domain_num, partition_num,
 						data->mapped_size, align,
 						&data->iova_addr);
diff --git a/drivers/gpu/ion/msm/ion_cp_common.c b/drivers/gpu/ion/msm/ion_cp_common.c
index b274ba2..41e0a04 100644
--- a/drivers/gpu/ion/msm/ion_cp_common.c
+++ b/drivers/gpu/ion/msm/ion_cp_common.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2011 Google, Inc
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/ion/msm/ion_cp_common.h b/drivers/gpu/ion/msm/ion_cp_common.h
index 634473f..eec66e6 100644
--- a/drivers/gpu/ion/msm/ion_cp_common.h
+++ b/drivers/gpu/ion/msm/ion_cp_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index deff514..68bab69 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -607,7 +607,7 @@
 		start = (unsigned long) data.vaddr;
 		end = (unsigned long) data.vaddr + data.length;
 
-		if (check_vaddr_bounds(start, end)) {
+		if (start && check_vaddr_bounds(start, end)) {
 			pr_err("%s: virtual address %p is out of bounds\n",
 				__func__, data.vaddr);
 			return -EINVAL;
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index aacd355..fec5363 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -9,7 +9,8 @@
 	kgsl_mmu.o \
 	kgsl_gpummu.o \
 	kgsl_iommu.o \
-	kgsl_snapshot.o
+	kgsl_snapshot.o \
+	kgsl_events.o
 
 msm_kgsl_core-$(CONFIG_DEBUG_FS) += kgsl_debugfs.o
 msm_kgsl_core-$(CONFIG_MSM_KGSL_CFF_DUMP) += kgsl_cffdump.o
diff --git a/drivers/gpu/msm/a2xx_reg.h b/drivers/gpu/msm/a2xx_reg.h
index 41cb601..c70c4eb 100644
--- a/drivers/gpu/msm/a2xx_reg.h
+++ b/drivers/gpu/msm/a2xx_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 93db37d..b49261c 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -17,6 +17,8 @@
 #include <linux/sched.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/msm_kgsl.h>
+#include <linux/delay.h>
 
 #include <mach/socinfo.h>
 #include <mach/msm_bus_board.h>
@@ -119,14 +121,21 @@
  * If the values of these registers are same after
  * KGSL_TIMEOUT_PART time, GPU hang is reported in
  * kernel log.
+ * *****ALERT******ALERT********ALERT*************
+ * Order of registers below is important, registers
+ * from LONG_IB_DETECT_REG_INDEX_START to
+ * LONG_IB_DETECT_REG_INDEX_END are used in long ib detection.
  */
-unsigned int hang_detect_regs[] = {
+#define LONG_IB_DETECT_REG_INDEX_START 1
+#define LONG_IB_DETECT_REG_INDEX_END 5
+
+unsigned int ft_detect_regs[] = {
 	A3XX_RBBM_STATUS,
-	REG_CP_RB_RPTR,
+	REG_CP_RB_RPTR,   /* LONG_IB_DETECT_REG_INDEX_START */
 	REG_CP_IB1_BASE,
 	REG_CP_IB1_BUFSZ,
 	REG_CP_IB2_BASE,
-	REG_CP_IB2_BUFSZ,
+	REG_CP_IB2_BUFSZ, /* LONG_IB_DETECT_REG_INDEX_END */
 	0,
 	0,
 	0,
@@ -135,7 +144,7 @@
 	0
 };
 
-const unsigned int hang_detect_regs_count = ARRAY_SIZE(hang_detect_regs);
+const unsigned int ft_detect_regs_count = ARRAY_SIZE(ft_detect_regs);
 
 /*
  * This is the master list of all GPU cores that are supported by this
@@ -1199,7 +1208,7 @@
 	int status = -EINVAL;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 
-	if (KGSL_STATE_DUMP_AND_RECOVER != device->state)
+	if (KGSL_STATE_DUMP_AND_FT != device->state)
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
 
 	/* Power up the device */
@@ -1254,16 +1263,16 @@
 
 	/* Assign correct RBBM status register to hang detect regs
 	 */
-	hang_detect_regs[0] = adreno_dev->gpudev->reg_rbbm_status;
+	ft_detect_regs[0] = adreno_dev->gpudev->reg_rbbm_status;
 
 	/* Add A3XX specific registers for hang detection */
 	if (adreno_is_a3xx(adreno_dev)) {
-		hang_detect_regs[6] = A3XX_RBBM_PERFCTR_SP_7_LO;
-		hang_detect_regs[7] = A3XX_RBBM_PERFCTR_SP_7_HI;
-		hang_detect_regs[8] = A3XX_RBBM_PERFCTR_SP_6_LO;
-		hang_detect_regs[9] = A3XX_RBBM_PERFCTR_SP_6_HI;
-		hang_detect_regs[10] = A3XX_RBBM_PERFCTR_SP_5_LO;
-		hang_detect_regs[11] = A3XX_RBBM_PERFCTR_SP_5_HI;
+		ft_detect_regs[6] = A3XX_RBBM_PERFCTR_SP_7_LO;
+		ft_detect_regs[7] = A3XX_RBBM_PERFCTR_SP_7_HI;
+		ft_detect_regs[8] = A3XX_RBBM_PERFCTR_SP_6_LO;
+		ft_detect_regs[9] = A3XX_RBBM_PERFCTR_SP_6_HI;
+		ft_detect_regs[10] = A3XX_RBBM_PERFCTR_SP_5_LO;
+		ft_detect_regs[11] = A3XX_RBBM_PERFCTR_SP_5_HI;
 	}
 
 	status = kgsl_mmu_start(device);
@@ -1284,9 +1293,9 @@
 
 	status = adreno_ringbuffer_start(&adreno_dev->ringbuffer, init_ram);
 	if (status == 0) {
-		/* While recovery is on we do not want timer to
+		/* While fault tolerance is on we do not want timer to
 		 * fire and attempt to change any device state */
-		if (KGSL_STATE_DUMP_AND_RECOVER != device->state)
+		if (KGSL_STATE_DUMP_AND_FT != device->state)
 			mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
 		return 0;
 	}
@@ -1325,26 +1334,26 @@
 }
 
 static void adreno_mark_context_status(struct kgsl_device *device,
-					int recovery_status)
+					int ft_status)
 {
 	struct kgsl_context *context;
 	int next = 0;
 	/*
 	 * Set the reset status of all contexts to
 	 * INNOCENT_CONTEXT_RESET_EXT except for the bad context
-	 * since thats the guilty party, if recovery failed then
+	 * since thats the guilty party, if fault tolerance failed then
 	 * mark all as guilty
 	 */
 	while ((context = idr_get_next(&device->context_idr, &next))) {
 		struct adreno_context *adreno_context = context->devctxt;
-		if (recovery_status) {
+		if (ft_status) {
 			context->reset_status =
 					KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT;
 			adreno_context->flags |= CTXT_FLAGS_GPU_HANG;
 		} else if (KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT !=
 			context->reset_status) {
 			if (adreno_context->flags & (CTXT_FLAGS_GPU_HANG |
-				CTXT_FLAGS_GPU_HANG_RECOVERED))
+				CTXT_FLAGS_GPU_HANG_FT))
 				context->reset_status =
 				KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT;
 			else
@@ -1379,103 +1388,316 @@
 	}
 }
 
-static void adreno_destroy_recovery_data(struct adreno_recovery_data *rec_data)
+static void adreno_destroy_ft_data(struct adreno_ft_data *ft_data)
 {
-	vfree(rec_data->rb_buffer);
-	vfree(rec_data->bad_rb_buffer);
+	vfree(ft_data->rb_buffer);
+	vfree(ft_data->bad_rb_buffer);
+	vfree(ft_data->good_rb_buffer);
 }
 
-static int adreno_setup_recovery_data(struct kgsl_device *device,
-					struct adreno_recovery_data *rec_data)
+static int _find_start_of_cmd_seq(struct adreno_ringbuffer *rb,
+					unsigned int *ptr,
+					bool inc)
+{
+	int status = -EINVAL;
+	unsigned int val1;
+	unsigned int size = rb->buffer_desc.size;
+	unsigned int start_ptr = *ptr;
+
+	while ((start_ptr / sizeof(unsigned int)) != rb->wptr) {
+		if (inc)
+			start_ptr = adreno_ringbuffer_inc_wrapped(start_ptr,
+									size);
+		else
+			start_ptr = adreno_ringbuffer_dec_wrapped(start_ptr,
+									size);
+		kgsl_sharedmem_readl(&rb->buffer_desc, &val1, start_ptr);
+		/* Ensure above read is finished before next read */
+		rmb();
+		if (KGSL_CMD_IDENTIFIER == val1) {
+			if ((start_ptr / sizeof(unsigned int)) != rb->wptr)
+				start_ptr = adreno_ringbuffer_dec_wrapped(
+							start_ptr, size);
+				*ptr = start_ptr;
+				status = 0;
+				break;
+		}
+	}
+	return status;
+}
+
+static int _find_cmd_seq_after_eop_ts(struct adreno_ringbuffer *rb,
+					unsigned int *rb_rptr,
+					unsigned int global_eop,
+					bool inc)
+{
+	int status = -EINVAL;
+	unsigned int temp_rb_rptr = *rb_rptr;
+	unsigned int size = rb->buffer_desc.size;
+	unsigned int val[3];
+	int i = 0;
+	bool check = false;
+
+	if (inc && temp_rb_rptr / sizeof(unsigned int) != rb->wptr)
+		return status;
+
+	do {
+		/*
+		 * when decrementing we need to decrement first and
+		 * then read make sure we cover all the data
+		 */
+		if (!inc)
+			temp_rb_rptr = adreno_ringbuffer_dec_wrapped(
+					temp_rb_rptr, size);
+		kgsl_sharedmem_readl(&rb->buffer_desc, &val[i],
+					temp_rb_rptr);
+		/* Ensure above read is finished before next read */
+		rmb();
+
+		if (check && ((inc && val[i] == global_eop) ||
+			(!inc && (val[i] ==
+			cp_type3_packet(CP_MEM_WRITE, 2) ||
+			val[i] == CACHE_FLUSH_TS)))) {
+			/* decrement i, i.e i = (i - 1 + 3) % 3 if
+			 * we are going forward, else increment i */
+			i = (i + 2) % 3;
+			if (val[i] == rb->device->memstore.gpuaddr +
+				KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
+						eoptimestamp)) {
+				int j = ((i + 2) % 3);
+				if ((inc && (val[j] == CACHE_FLUSH_TS ||
+						val[j] == cp_type3_packet(
+							CP_MEM_WRITE, 2))) ||
+					(!inc && val[j] == global_eop)) {
+						/* Found the global eop */
+						status = 0;
+						break;
+				}
+			}
+			/* if no match found then increment i again
+			 * since we decremented before matching */
+			i = (i + 1) % 3;
+		}
+		if (inc)
+			temp_rb_rptr = adreno_ringbuffer_inc_wrapped(
+						temp_rb_rptr, size);
+
+		i = (i + 1) % 3;
+		if (2 == i)
+			check = true;
+	} while (temp_rb_rptr / sizeof(unsigned int) != rb->wptr);
+	/* temp_rb_rptr points to the command stream after global eop,
+	 * move backward till the start of command sequence */
+	if (!status) {
+		status = _find_start_of_cmd_seq(rb, &temp_rb_rptr, false);
+		if (!status) {
+			*rb_rptr = temp_rb_rptr;
+			KGSL_FT_INFO(rb->device,
+			"Offset of cmd sequence after eop timestamp: 0x%x\n",
+			temp_rb_rptr / sizeof(unsigned int));
+		}
+	}
+	if (status)
+		KGSL_FT_ERR(rb->device,
+		"Failed to find the command sequence after eop timestamp\n");
+	return status;
+}
+
+static int _find_hanging_ib_sequence(struct adreno_ringbuffer *rb,
+				unsigned int *rb_rptr,
+				unsigned int ib1)
+{
+	int status = -EINVAL;
+	unsigned int temp_rb_rptr = *rb_rptr;
+	unsigned int size = rb->buffer_desc.size;
+	unsigned int val[2];
+	int i = 0;
+	bool check = false;
+	bool ctx_switch = false;
+
+	while (temp_rb_rptr / sizeof(unsigned int) != rb->wptr) {
+		kgsl_sharedmem_readl(&rb->buffer_desc, &val[i], temp_rb_rptr);
+		/* Ensure above read is finished before next read */
+		rmb();
+
+		if (check && val[i] == ib1) {
+			/* decrement i, i.e i = (i - 1 + 2) % 2 */
+			i = (i + 1) % 2;
+			if (adreno_cmd_is_ib(val[i])) {
+				/* go till start of command sequence */
+				status = _find_start_of_cmd_seq(rb,
+						&temp_rb_rptr, false);
+
+				KGSL_FT_INFO(rb->device,
+				"Found the hanging IB at offset 0x%x\n",
+				temp_rb_rptr / sizeof(unsigned int));
+				break;
+			}
+			/* if no match the increment i since we decremented
+			 * before checking */
+			i = (i + 1) % 2;
+		}
+		/* Make sure you do not encounter a context switch twice, we can
+		 * encounter it once for the bad context as the start of search
+		 * can point to the context switch */
+		if (val[i] == KGSL_CONTEXT_TO_MEM_IDENTIFIER) {
+			if (ctx_switch) {
+				KGSL_FT_ERR(rb->device,
+				"Context switch encountered before bad "
+				"IB found\n");
+				break;
+			}
+			ctx_switch = true;
+		}
+		i = (i + 1) % 2;
+		if (1 == i)
+			check = true;
+		temp_rb_rptr = adreno_ringbuffer_inc_wrapped(temp_rb_rptr,
+								size);
+	}
+	if  (!status)
+		*rb_rptr = temp_rb_rptr;
+	return status;
+}
+
+static void adreno_setup_ft_data(struct kgsl_device *device,
+					struct adreno_ft_data *ft_data)
 {
 	int ret = 0;
-	unsigned int ib1_sz, ib2_sz;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
+	struct kgsl_context *context;
+	struct adreno_context *adreno_context;
+	unsigned int rb_rptr = rb->wptr * sizeof(unsigned int);
 
-	memset(rec_data, 0, sizeof(*rec_data));
+	memset(ft_data, 0, sizeof(*ft_data));
+	ft_data->start_of_replay_cmds = 0xFFFFFFFF;
+	ft_data->replay_for_snapshot = 0xFFFFFFFF;
 
-	adreno_regread(device, REG_CP_IB1_BUFSZ, &ib1_sz);
-	adreno_regread(device, REG_CP_IB2_BUFSZ, &ib2_sz);
-	if (ib1_sz || ib2_sz)
-		adreno_regread(device, REG_CP_IB1_BASE, &rec_data->ib1);
+	adreno_regread(device, REG_CP_IB1_BASE, &ft_data->ib1);
 
-	kgsl_sharedmem_readl(&device->memstore, &rec_data->context_id,
+	kgsl_sharedmem_readl(&device->memstore, &ft_data->context_id,
 			KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
 			current_context));
 
 	kgsl_sharedmem_readl(&device->memstore,
-				&rec_data->global_eop,
-				KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
-				eoptimestamp));
+			&ft_data->global_eop,
+			KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
+			eoptimestamp));
 
-	rec_data->rb_buffer = vmalloc(rb->buffer_desc.size);
-	if (!rec_data->rb_buffer) {
+	/* Ensure context id and global eop ts read complete */
+	rmb();
+
+	ft_data->rb_buffer = vmalloc(rb->buffer_desc.size);
+	if (!ft_data->rb_buffer) {
 		KGSL_MEM_ERR(device, "vmalloc(%d) failed\n",
 				rb->buffer_desc.size);
-		return -ENOMEM;
+		return;
 	}
 
-	rec_data->bad_rb_buffer = vmalloc(rb->buffer_desc.size);
-	if (!rec_data->bad_rb_buffer) {
+	ft_data->bad_rb_buffer = vmalloc(rb->buffer_desc.size);
+	if (!ft_data->bad_rb_buffer) {
 		KGSL_MEM_ERR(device, "vmalloc(%d) failed\n",
 				rb->buffer_desc.size);
-		ret = -ENOMEM;
-		goto done;
+		return;
 	}
-	rec_data->fault = device->mmu.fault;
 
-done:
+	ft_data->good_rb_buffer = vmalloc(rb->buffer_desc.size);
+	if (!ft_data->good_rb_buffer) {
+		KGSL_MEM_ERR(device, "vmalloc(%d) failed\n",
+				rb->buffer_desc.size);
+		return;
+	}
+
+	ft_data->status = 0;
+
+	/* find the start of bad command sequence in rb */
+	context = idr_find(&device->context_idr, ft_data->context_id);
+	/* Look for the command stream that is right after the global eop */
+
+	if (!context) {
+		/*
+		 * If there is no context then fault tolerance does not need to
+		 * replay anything, just reset GPU and thats it
+		 */
+		return;
+	}
+
+	ft_data->ft_policy = adreno_dev->ft_policy;
+
+	if (!adreno_dev->ft_policy)
+		adreno_dev->ft_policy = KGSL_FT_DEFAULT_POLICY;
+
+	ret = _find_cmd_seq_after_eop_ts(rb, &rb_rptr,
+					ft_data->global_eop + 1, false);
 	if (ret) {
-		vfree(rec_data->rb_buffer);
-		vfree(rec_data->bad_rb_buffer);
+		ft_data->ft_policy |= KGSL_FT_TEMP_DISABLE;
+		return;
+	} else
+		ft_data->ft_policy &= ~KGSL_FT_TEMP_DISABLE;
+
+	ft_data->start_of_replay_cmds = rb_rptr;
+
+	adreno_context = context->devctxt;
+	if (adreno_context->flags & CTXT_FLAGS_PREAMBLE) {
+		if (ft_data->ib1) {
+			ret = _find_hanging_ib_sequence(rb,
+					&rb_rptr, ft_data->ib1);
+			if (ret) {
+				KGSL_FT_ERR(device,
+				"Start not found for replay IB sequence\n");
+				return;
+			}
+			ft_data->start_of_replay_cmds = rb_rptr;
+			ft_data->replay_for_snapshot = rb_rptr;
+		}
 	}
-	return ret;
 }
 
 static int
-_adreno_recover_hang(struct kgsl_device *device,
-			struct adreno_recovery_data *rec_data,
-			bool try_bad_commands)
+_adreno_check_long_ib(struct kgsl_device *device)
 {
-	int ret;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
-	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
-	struct kgsl_context *context;
-	struct adreno_context *adreno_context = NULL;
-	struct adreno_context *last_active_ctx = adreno_dev->drawctxt_active;
+	unsigned int curr_global_ts = 0;
 
-	context = idr_find(&device->context_idr, rec_data->context_id);
-	if (context == NULL) {
-		KGSL_DRV_ERR(device, "Last context unknown id:%d\n",
-			rec_data->context_id);
+	/* check if the global ts is still the same */
+	kgsl_sharedmem_readl(&device->memstore,
+			&curr_global_ts,
+			KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
+			eoptimestamp));
+	/* Ensure above read is finished before long ib check */
+	rmb();
+
+	/* Mark long ib as handled */
+	adreno_dev->long_ib = 0;
+
+	if (curr_global_ts == adreno_dev->long_ib_ts) {
+		KGSL_FT_ERR(device,
+			"IB ran too long, invalidate ctxt\n");
+		return 1;
 	} else {
-		adreno_context = context->devctxt;
-		adreno_context->flags |= CTXT_FLAGS_GPU_HANG;
-		/*
-		 * set the invalid ts flag to 0 for this context since we have
-		 * detected a hang for it
-		 */
-		context->wait_on_invalid_ts = false;
+		/* Do nothing GPU has gone ahead */
+		KGSL_FT_INFO(device, "false long ib detection return\n");
+		return 0;
 	}
+}
 
-	/* Extract valid contents from rb which can still be executed after
-	 * hang */
-	ret = adreno_ringbuffer_extract(rb, rec_data);
-	if (ret)
-		goto done;
+static int
+_adreno_ft_restart_device(struct kgsl_device *device,
+		   struct kgsl_context *context)
+{
+
+	struct adreno_context *adreno_context = context->devctxt;
 
 	/* restart device */
-	ret = adreno_stop(device);
-	if (ret) {
-		KGSL_DRV_ERR(device, "Device stop failed in recovery\n");
-		goto done;
+	if (adreno_stop(device)) {
+		KGSL_FT_ERR(device, "Device stop failed\n");
+		return 1;
 	}
 
-	ret = adreno_start(device, true);
-	if (ret) {
-		KGSL_DRV_ERR(device, "Device start failed in recovery\n");
-		goto done;
+	if (adreno_start(device, true)) {
+		KGSL_FT_ERR(device, "Device start failed\n");
+		return 1;
 	}
 
 	if (context)
@@ -1485,83 +1707,286 @@
 	/* If iommu is used then we need to make sure that the iommu clocks
 	 * are on since there could be commands in pipeline that touch iommu */
 	if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype()) {
-		ret = kgsl_mmu_enable_clk(&device->mmu,
-			KGSL_IOMMU_CONTEXT_USER);
-		if (ret)
-			goto done;
+		if (kgsl_mmu_enable_clk(&device->mmu,
+				KGSL_IOMMU_CONTEXT_USER))
+			return 1;
 	}
 
-	/* Do not try the bad commands if recovery has failed bad commands
-	 * once already or if hang is due to a fault */
-	if (!try_bad_commands || rec_data->fault)
-		rec_data->bad_rb_size = 0;
+	return 0;
+}
 
-	if (rec_data->bad_rb_size) {
-		int idle_ret;
-		/* submit the bad and good context commands and wait for
-		 * them to pass */
-		adreno_ringbuffer_restore(rb, rec_data->bad_rb_buffer,
-					rec_data->bad_rb_size);
-		idle_ret = adreno_idle(device);
-		if (idle_ret) {
-			ret = adreno_stop(device);
-			if (ret) {
-				KGSL_DRV_ERR(device,
-				"Device stop failed in recovery\n");
-				goto done;
-			}
-			ret = adreno_start(device, true);
-			if (ret) {
-				KGSL_DRV_ERR(device,
-				"Device start failed in recovery\n");
-				goto done;
-			}
-			if (context)
-				kgsl_mmu_setstate(&device->mmu,
-						adreno_context->pagetable,
-						KGSL_MEMSTORE_GLOBAL);
+static inline void
+_adreno_debug_ft_info(struct kgsl_device *device,
+			struct adreno_ft_data *ft_data)
+{
 
-			if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype()) {
-				ret = kgsl_mmu_enable_clk(&device->mmu,
-						KGSL_IOMMU_CONTEXT_USER);
-				if (ret)
-					goto done;
-			}
+	/*
+	 * Dumping rb is a very useful tool to debug FT.
+	 * It will tell us if we are extracting the rb correctly
+	 * NOP'ing the right IB, skipping the EOF correctly etc.
+	 */
+	if (device->ft_log >= 7)  {
 
-			ret = idle_ret;
-			KGSL_DRV_ERR(device,
-			"Bad context commands hung in recovery\n");
-		} else {
-			KGSL_DRV_ERR(device,
-			"Bad context commands succeeded in recovery\n");
-			if (adreno_context)
-				adreno_context->flags = (adreno_context->flags &
-					~CTXT_FLAGS_GPU_HANG) |
-					CTXT_FLAGS_GPU_HANG_RECOVERED;
-			adreno_dev->drawctxt_active = last_active_ctx;
-		}
+		/* Print fault tolerance data here */
+		KGSL_FT_INFO(device, "Temp RB buffer size 0x%X\n",
+			ft_data->rb_size);
+		adreno_dump_rb(device, ft_data->rb_buffer,
+			ft_data->rb_size<<2, 0, ft_data->rb_size);
+
+		KGSL_FT_INFO(device, "Bad RB buffer size 0x%X\n",
+			ft_data->bad_rb_size);
+		adreno_dump_rb(device, ft_data->bad_rb_buffer,
+			ft_data->bad_rb_size<<2, 0, ft_data->bad_rb_size);
+
+		KGSL_FT_INFO(device, "Good RB buffer size 0x%X\n",
+			ft_data->good_rb_size);
+		adreno_dump_rb(device, ft_data->good_rb_buffer,
+			ft_data->good_rb_size<<2, 0, ft_data->good_rb_size);
+
 	}
-	/* If either the bad command sequence failed or we did not play it */
-	if (ret || !rec_data->bad_rb_size) {
-		adreno_ringbuffer_restore(rb, rec_data->rb_buffer,
-				rec_data->rb_size);
+}
+
+static int
+_adreno_ft_resubmit_rb(struct kgsl_device *device,
+			struct adreno_ringbuffer *rb,
+			struct kgsl_context *context,
+			struct adreno_ft_data *ft_data,
+			unsigned int *buff, unsigned int size)
+{
+	unsigned int ret = 0;
+	unsigned int retry_num = 0;
+
+	_adreno_debug_ft_info(device, ft_data);
+
+	do {
+		ret = _adreno_ft_restart_device(device, context);
+		if (ret == 0)
+			break;
+		/*
+		 * If device restart fails sleep for 20ms before
+		 * attempting restart. This allows GPU HW to settle
+		 * and improve the chances of next restart to be
+		 * successful.
+		 */
+		msleep(20);
+		KGSL_FT_ERR(device, "Retry device restart %d\n", retry_num);
+		retry_num++;
+	} while (retry_num < 4);
+
+	if (ret) {
+		KGSL_FT_ERR(device, "Device restart failed\n");
+		BUG_ON(1);
+		goto done;
+	}
+
+	if (size) {
+
+		/* submit commands and wait for them to pass */
+		adreno_ringbuffer_restore(rb, buff, size);
+
 		ret = adreno_idle(device);
-		if (ret) {
-			/* If we fail here we can try to invalidate another
-			 * context and try recovering again */
-			ret = -EAGAIN;
-			goto done;
+	}
+
+done:
+	return ret;
+}
+
+static int
+_adreno_ft(struct kgsl_device *device,
+			struct adreno_ft_data *ft_data)
+{
+	int ret = 0, i;
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
+	struct kgsl_context *context;
+	struct adreno_context *adreno_context = NULL;
+	struct adreno_context *last_active_ctx = adreno_dev->drawctxt_active;
+	unsigned int long_ib = 0;
+
+	context = idr_find(&device->context_idr, ft_data->context_id);
+	if (context == NULL) {
+		KGSL_FT_ERR(device, "Last context unknown id:%d\n",
+			ft_data->context_id);
+		goto play_good_cmds;
+	} else {
+		adreno_context = context->devctxt;
+		adreno_context->flags |= CTXT_FLAGS_GPU_HANG;
+		/*
+		 * set the invalid ts flag to 0 for this context since we have
+		 * detected a hang for it
+		 */
+		context->wait_on_invalid_ts = false;
+
+		if (!(adreno_context->flags & CTXT_FLAGS_PER_CONTEXT_TS)) {
+			ft_data->status = 1;
+			KGSL_FT_ERR(device, "Fault tolerance not supported\n");
+			goto play_good_cmds;
 		}
-		/* ringbuffer now has data from the last valid context id,
-		 * so restore the active_ctx to the last valid context */
-		if (rec_data->last_valid_ctx_id) {
-			struct kgsl_context *last_ctx =
-					idr_find(&device->context_idr,
-					rec_data->last_valid_ctx_id);
-			if (last_ctx)
-				adreno_dev->drawctxt_active = last_ctx->devctxt;
+
+		/*
+		 *  This flag will be set by userspace for contexts
+		 *  that do not want to be fault tolerant (ex: OPENCL)
+		 */
+		if (adreno_context->flags & CTXT_FLAGS_NO_FAULT_TOLERANCE) {
+			ft_data->status = 1;
+			KGSL_FT_ERR(device,
+			"No FT set for this context play good cmds\n");
+			goto play_good_cmds;
+		}
+
+	}
+
+	/* Check if we detected a long running IB,
+	 * if true do not attempt replay of bad cmds */
+	if (adreno_dev->long_ib) {
+		long_ib = _adreno_check_long_ib(device);
+		if (!long_ib) {
+			adreno_context->flags &= ~CTXT_FLAGS_GPU_HANG;
+			return 0;
 		}
 	}
+
+	/*
+	 * Extract valid contents from rb which can still be executed after
+	 * hang
+	 */
+	adreno_ringbuffer_extract(rb, ft_data);
+
+	/* If long IB detected do not attempt replay of bad cmds */
+	if (long_ib) {
+		ft_data->status = 1;
+		_adreno_debug_ft_info(device, ft_data);
+		goto play_good_cmds;
+	}
+
+	if ((ft_data->ft_policy & KGSL_FT_DISABLE) ||
+		(ft_data->ft_policy & KGSL_FT_TEMP_DISABLE)) {
+		KGSL_FT_ERR(device, "NO FT policy play only good cmds\n");
+		ft_data->status = 1;
+		goto play_good_cmds;
+	}
+
+	/* Do not try the reply if hang is due to a pagefault */
+	if (adreno_context->pagefault) {
+		if ((ft_data->context_id == adreno_context->id) &&
+			(ft_data->global_eop == adreno_context->pagefault_ts)) {
+			ft_data->ft_policy &= ~KGSL_FT_REPLAY;
+			KGSL_FT_ERR(device, "MMU fault skipping replay\n");
+		}
+
+		adreno_context->pagefault = 0;
+	}
+
+	if (ft_data->ft_policy & KGSL_FT_REPLAY) {
+		ret = _adreno_ft_resubmit_rb(device, rb, context, ft_data,
+				ft_data->bad_rb_buffer, ft_data->bad_rb_size);
+
+		if (ret) {
+			KGSL_FT_ERR(device, "Replay status: 1\n");
+			ft_data->status = 1;
+		} else
+			goto play_good_cmds;
+	}
+
+	if (ft_data->ft_policy & KGSL_FT_SKIPIB) {
+		for (i = 0; i < ft_data->bad_rb_size; i++) {
+			if ((ft_data->bad_rb_buffer[i] ==
+					CP_HDR_INDIRECT_BUFFER_PFD) &&
+				(ft_data->bad_rb_buffer[i+1] == ft_data->ib1)) {
+
+				ft_data->bad_rb_buffer[i] = cp_nop_packet(2);
+				ft_data->bad_rb_buffer[i+1] =
+							KGSL_NOP_IB_IDENTIFIER;
+				ft_data->bad_rb_buffer[i+2] =
+							KGSL_NOP_IB_IDENTIFIER;
+				break;
+			}
+		}
+
+		if ((i == (ft_data->bad_rb_size)) || (!ft_data->ib1)) {
+			KGSL_FT_ERR(device, "Bad IB to NOP not found\n");
+			ft_data->status = 1;
+			goto play_good_cmds;
+		}
+
+		ret = _adreno_ft_resubmit_rb(device, rb, context, ft_data,
+				ft_data->bad_rb_buffer, ft_data->bad_rb_size);
+
+		if (ret) {
+			KGSL_FT_ERR(device, "NOP faulty IB status: 1\n");
+			ft_data->status = 1;
+		} else {
+			ft_data->status = 0;
+			goto play_good_cmds;
+		}
+	}
+
+	if (ft_data->ft_policy & KGSL_FT_SKIPFRAME) {
+		for (i = 0; i < ft_data->bad_rb_size; i++) {
+			if (ft_data->bad_rb_buffer[i] ==
+					KGSL_END_OF_FRAME_IDENTIFIER) {
+				ft_data->bad_rb_buffer[0] = cp_nop_packet(i);
+				break;
+			}
+		}
+
+		/* EOF not found in RB, discard till EOF in
+		   next IB submission */
+		if (i == ft_data->bad_rb_size) {
+			adreno_context->flags |= CTXT_FLAGS_SKIP_EOF;
+			KGSL_FT_INFO(device,
+			"EOF not found in RB, skip next issueib till EOF\n");
+			ft_data->bad_rb_buffer[0] = cp_nop_packet(i);
+		}
+
+		ret = _adreno_ft_resubmit_rb(device, rb, context, ft_data,
+				ft_data->bad_rb_buffer, ft_data->bad_rb_size);
+
+		if (ret) {
+			KGSL_FT_ERR(device, "Skip EOF status: 1\n");
+			ft_data->status = 1;
+		} else {
+			ft_data->status = 0;
+			goto play_good_cmds;
+		}
+	}
+
+play_good_cmds:
+
+	if (ft_data->status)
+		KGSL_FT_ERR(device, "Bad context commands failed\n");
+	else {
+		KGSL_FT_INFO(device, "Bad context commands success\n");
+
+		if (adreno_context) {
+			adreno_context->flags = (adreno_context->flags &
+				~CTXT_FLAGS_GPU_HANG) | CTXT_FLAGS_GPU_HANG_FT;
+		}
+		adreno_dev->drawctxt_active = last_active_ctx;
+	}
+
+	ret = _adreno_ft_resubmit_rb(device, rb, context, ft_data,
+			ft_data->good_rb_buffer, ft_data->good_rb_size);
+
+	if (ret) {
+		/* If we fail here we can try to invalidate another
+		 * context and try fault tolerance again */
+		ret = -EAGAIN;
+		KGSL_FT_ERR(device, "Playing good commands unsuccessful\n");
+		goto done;
+	} else
+		KGSL_FT_INFO(device, "Playing good commands successful\n");
+
+	/* ringbuffer now has data from the last valid context id,
+	 * so restore the active_ctx to the last valid context */
+	if (ft_data->last_valid_ctx_id) {
+		struct kgsl_context *last_ctx =
+				idr_find(&device->context_idr,
+				ft_data->last_valid_ctx_id);
+		if (last_ctx)
+			adreno_dev->drawctxt_active = last_ctx->devctxt;
+	}
+
 done:
 	/* Turn off iommu clocks */
 	if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype())
@@ -1570,40 +1995,38 @@
 }
 
 static int
-adreno_recover_hang(struct kgsl_device *device,
-			struct adreno_recovery_data *rec_data)
+adreno_ft(struct kgsl_device *device,
+			struct adreno_ft_data *ft_data)
 {
 	int ret = 0;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
 	unsigned int timestamp;
 
-	KGSL_DRV_ERR(device,
-	"Starting recovery from 3D GPU hang. Recovery parameters: IB1: 0x%X, "
+	KGSL_FT_INFO(device,
+	"Start Parameters: IB1: 0x%X, "
 	"Bad context_id: %u, global_eop: 0x%x\n",
-	rec_data->ib1, rec_data->context_id, rec_data->global_eop);
+	ft_data->ib1, ft_data->context_id, ft_data->global_eop);
 
 	timestamp = rb->timestamp[KGSL_MEMSTORE_GLOBAL];
-	KGSL_DRV_ERR(device, "Last issued global timestamp: %x\n", timestamp);
+	KGSL_FT_INFO(device, "Last issued global timestamp: %x\n", timestamp);
 
 	/* We may need to replay commands multiple times based on whether
 	 * multiple contexts hang the GPU */
 	while (true) {
-		if (!ret)
-			ret = _adreno_recover_hang(device, rec_data, true);
-		else
-			ret = _adreno_recover_hang(device, rec_data, false);
+
+		ret = _adreno_ft(device, ft_data);
 
 		if (-EAGAIN == ret) {
-			/* setup new recovery parameters and retry, this
+			/* setup new fault tolerance parameters and retry, this
 			 * means more than 1 contexts are causing hang */
-			adreno_destroy_recovery_data(rec_data);
-			adreno_setup_recovery_data(device, rec_data);
-			KGSL_DRV_ERR(device,
-			"Retry recovery from 3D GPU hang. Recovery parameters: "
+			adreno_destroy_ft_data(ft_data);
+			adreno_setup_ft_data(device, ft_data);
+			KGSL_FT_INFO(device,
+			"Retry. Parameters: "
 			"IB1: 0x%X, Bad context_id: %u, global_eop: 0x%x\n",
-			rec_data->ib1, rec_data->context_id,
-			rec_data->global_eop);
+			ft_data->ib1, ft_data->context_id,
+			ft_data->global_eop);
 		} else {
 			break;
 		}
@@ -1612,7 +2035,7 @@
 	if (ret)
 		goto done;
 
-	/* Restore correct states after recovery */
+	/* Restore correct states after fault tolerance */
 	if (adreno_dev->drawctxt_active)
 		device->mmu.hwpagetable =
 			adreno_dev->drawctxt_active->pagetable;
@@ -1631,60 +2054,78 @@
 done:
 	adreno_set_max_ts_for_bad_ctxs(device);
 	adreno_mark_context_status(device, ret);
-	if (!ret)
-		KGSL_DRV_ERR(device, "Recovery succeeded\n");
-	else
-		KGSL_DRV_ERR(device, "Recovery failed\n");
+	KGSL_FT_ERR(device, "policy 0x%X status 0x%x\n",
+			ft_data->ft_policy, ret);
 	return ret;
 }
 
 int
-adreno_dump_and_recover(struct kgsl_device *device)
+adreno_dump_and_exec_ft(struct kgsl_device *device)
 {
 	int result = -ETIMEDOUT;
-	struct adreno_recovery_data rec_data;
+	struct adreno_ft_data ft_data;
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+	unsigned int curr_pwrlevel;
 
 	if (device->state == KGSL_STATE_HUNG)
 		goto done;
-	if (device->state == KGSL_STATE_DUMP_AND_RECOVER) {
+	if (device->state == KGSL_STATE_DUMP_AND_FT) {
 		mutex_unlock(&device->mutex);
-		wait_for_completion(&device->recovery_gate);
+		wait_for_completion(&device->ft_gate);
 		mutex_lock(&device->mutex);
 		if (device->state != KGSL_STATE_HUNG)
 			result = 0;
 	} else {
-		kgsl_pwrctrl_set_state(device, KGSL_STATE_DUMP_AND_RECOVER);
-		INIT_COMPLETION(device->recovery_gate);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_DUMP_AND_FT);
+		INIT_COMPLETION(device->ft_gate);
 		/* Detected a hang */
 
-		/* Get the recovery data as soon as hang is detected */
-		result = adreno_setup_recovery_data(device, &rec_data);
-		/*
-		 * Trigger an automatic dump of the state to
-		 * the console
-		 */
-		kgsl_postmortem_dump(device, 0);
+		/* Run fault tolerance at max power level */
+		curr_pwrlevel = pwr->active_pwrlevel;
+		kgsl_pwrctrl_pwrlevel_change(device, pwr->max_pwrlevel);
+
+		/* Get the fault tolerance data as soon as hang is detected */
+		adreno_setup_ft_data(device, &ft_data);
 
 		/*
-		 * Make a GPU snapshot.  For now, do it after the PM dump so we
-		 * can at least be sure the PM dump will work as it always has
+		 * If long ib is detected, do not attempt postmortem or
+		 * snapshot, if GPU is still executing commands
+		 * we will get errors
 		 */
-		kgsl_device_snapshot(device, 1);
+		if (!adreno_dev->long_ib) {
+			/*
+			 * Trigger an automatic dump of the state to
+			 * the console
+			 */
+			kgsl_postmortem_dump(device, 0);
 
-		result = adreno_recover_hang(device, &rec_data);
-		adreno_destroy_recovery_data(&rec_data);
+			/*
+			* Make a GPU snapshot.  For now, do it after the
+			* PM dump so we can at least be sure the PM dump
+			* will work as it always has
+			*/
+			kgsl_device_snapshot(device, 1);
+		}
+
+		result = adreno_ft(device, &ft_data);
+		adreno_destroy_ft_data(&ft_data);
+
+		/* restore power level */
+		kgsl_pwrctrl_pwrlevel_change(device, curr_pwrlevel);
+
 		if (result) {
 			kgsl_pwrctrl_set_state(device, KGSL_STATE_HUNG);
 		} else {
 			kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
 			mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
 		}
-		complete_all(&device->recovery_gate);
+		complete_all(&device->ft_gate);
 	}
 done:
 	return result;
 }
-EXPORT_SYMBOL(adreno_dump_and_recover);
+EXPORT_SYMBOL(adreno_dump_and_exec_ft);
 
 static int adreno_getproperty(struct kgsl_device *device,
 				enum kgsl_property_type type,
@@ -1851,7 +2292,7 @@
 	do {
 		if (time_after(jiffies, wait)) {
 			/* Check to see if the core is hung */
-			if (adreno_hang_detect(device, regs))
+			if (adreno_ft_detect(device, regs))
 				return -ETIMEDOUT;
 
 			wait = jiffies + msecs_to_jiffies(KGSL_TIMEOUT_PART);
@@ -1875,7 +2316,7 @@
 	unsigned int rbbm_status;
 	unsigned long wait_time;
 	unsigned long wait_time_part;
-	unsigned int prev_reg_val[hang_detect_regs_count];
+	unsigned int prev_reg_val[ft_detect_regs_count];
 
 	memset(prev_reg_val, 0, sizeof(prev_reg_val));
 
@@ -1908,7 +2349,7 @@
 		if (time_after(jiffies, wait_time_part)) {
 				wait_time_part = jiffies +
 					msecs_to_jiffies(KGSL_TIMEOUT_PART);
-				if ((adreno_hang_detect(device, prev_reg_val)))
+				if ((adreno_ft_detect(device, prev_reg_val)))
 					goto err;
 		}
 
@@ -1916,9 +2357,9 @@
 
 err:
 	KGSL_DRV_ERR(device, "spun too long waiting for RB to idle\n");
-	if (KGSL_STATE_DUMP_AND_RECOVER != device->state &&
-		!adreno_dump_and_recover(device)) {
-		wait_time = jiffies + msecs_to_jiffies(ADRENO_IDLE_TIMEOUT);
+	if (KGSL_STATE_DUMP_AND_FT != device->state &&
+		!adreno_dump_and_exec_ft(device)) {
+		wait_time = jiffies + ADRENO_IDLE_TIMEOUT;
 		goto retry;
 	}
 	return -ETIMEDOUT;
@@ -1965,8 +2406,17 @@
 		/* Is the ring buffer is empty? */
 		GSL_RB_GET_READPTR(rb, &rb->rptr);
 		if (!device->active_cnt && (rb->rptr == rb->wptr)) {
-			/* Is the core idle? */
-			status = is_adreno_rbbm_status_idle(device);
+			/*
+			 * Are there interrupts pending? If so then pretend we
+			 * are not idle - this avoids the possiblity that we go
+			 * to a lower power state without handling interrupts
+			 * first.
+			 */
+
+			if (!adreno_dev->gpudev->irq_pending(adreno_dev)) {
+				/* Is the core idle? */
+				status = is_adreno_rbbm_status_idle(device);
+			}
 		}
 	} else {
 		status = true;
@@ -2112,125 +2562,88 @@
 	return context_id;
 }
 
-static void adreno_next_event(struct kgsl_device *device,
-		struct kgsl_event *event)
-{
-	int status;
-	unsigned int ref_ts, enableflag;
-	unsigned int context_id = _get_context_id(event->context);
-	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
-
-	status = kgsl_check_timestamp(device, event->context, event->timestamp);
-	if (!status) {
-		kgsl_sharedmem_readl(&device->memstore, &enableflag,
-			KGSL_MEMSTORE_OFFSET(context_id, ts_cmp_enable));
-		/*
-		 * Barrier is needed here to make sure the read from memstore
-		 * has posted
-		 */
-
-		mb();
-
-		if (enableflag) {
-			kgsl_sharedmem_readl(&device->memstore, &ref_ts,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					ref_wait_ts));
-
-			/* Make sure the memstore read has posted */
-			mb();
-			if (timestamp_cmp(ref_ts, event->timestamp) >= 0) {
-				kgsl_sharedmem_writel(&device->memstore,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					ref_wait_ts), event->timestamp);
-				/* Make sure the memstore write is posted */
-				wmb();
-			}
-		} else {
-			unsigned int cmds[2];
-			kgsl_sharedmem_writel(&device->memstore,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					ref_wait_ts), event->timestamp);
-			enableflag = 1;
-			kgsl_sharedmem_writel(&device->memstore,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					ts_cmp_enable), enableflag);
-
-			/* Make sure the memstore write gets posted */
-			wmb();
-
-			/*
-			 * submit a dummy packet so that even if all
-			 * commands upto timestamp get executed we will still
-			 * get an interrupt
-			 */
-			cmds[0] = cp_type3_packet(CP_NOP, 1);
-			cmds[1] = 0;
-
-			if (adreno_dev->drawctxt_active)
-				adreno_ringbuffer_issuecmds_intr(device,
-						event->context, &cmds[0], 2);
-		}
-	}
-}
-
-static int kgsl_check_interrupt_timestamp(struct kgsl_device *device,
+static unsigned int adreno_check_hw_ts(struct kgsl_device *device,
 		struct kgsl_context *context, unsigned int timestamp)
 {
-	int status;
+	int status = 0;
 	unsigned int ref_ts, enableflag;
-	unsigned int context_id;
+	unsigned int context_id = _get_context_id(context);
 
-	mutex_lock(&device->mutex);
-	context_id = _get_context_id(context);
 	/*
 	 * If the context ID is invalid, we are in a race with
 	 * the context being destroyed by userspace so bail.
 	 */
 	if (context_id == KGSL_CONTEXT_INVALID) {
 		KGSL_DRV_WARN(device, "context was detached");
-		status = -EINVAL;
-		goto unlock;
+		return -EINVAL;
 	}
 
 	status = kgsl_check_timestamp(device, context, timestamp);
-	if (!status) {
-		kgsl_sharedmem_readl(&device->memstore, &enableflag,
-			KGSL_MEMSTORE_OFFSET(context_id, ts_cmp_enable));
-		mb();
+	if (status)
+		return status;
 
-		if (enableflag) {
-			kgsl_sharedmem_readl(&device->memstore, &ref_ts,
+	kgsl_sharedmem_readl(&device->memstore, &enableflag,
+			KGSL_MEMSTORE_OFFSET(context_id, ts_cmp_enable));
+	/*
+	 * Barrier is needed here to make sure the read from memstore
+	 * has posted
+	 */
+
+	mb();
+
+	if (enableflag) {
+		kgsl_sharedmem_readl(&device->memstore, &ref_ts,
 				KGSL_MEMSTORE_OFFSET(context_id,
 					ref_wait_ts));
-			mb();
-			if (timestamp_cmp(ref_ts, timestamp) >= 0) {
-				kgsl_sharedmem_writel(&device->memstore,
+
+		/* Make sure the memstore read has posted */
+		mb();
+		if (timestamp_cmp(ref_ts, timestamp) >= 0) {
+			kgsl_sharedmem_writel(&device->memstore,
+					KGSL_MEMSTORE_OFFSET(context_id,
+						ref_wait_ts), timestamp);
+			/* Make sure the memstore write is posted */
+			wmb();
+		}
+	} else {
+		kgsl_sharedmem_writel(&device->memstore,
 				KGSL_MEMSTORE_OFFSET(context_id,
 					ref_wait_ts), timestamp);
-				wmb();
-			}
-		} else {
-			unsigned int cmds[2];
-			kgsl_sharedmem_writel(&device->memstore,
-				KGSL_MEMSTORE_OFFSET(context_id,
-					ref_wait_ts), timestamp);
-			enableflag = 1;
-			kgsl_sharedmem_writel(&device->memstore,
+		enableflag = 1;
+		kgsl_sharedmem_writel(&device->memstore,
 				KGSL_MEMSTORE_OFFSET(context_id,
 					ts_cmp_enable), enableflag);
-			wmb();
-			/* submit a dummy packet so that even if all
-			* commands upto timestamp get executed we will still
-			* get an interrupt */
-			cmds[0] = cp_type3_packet(CP_NOP, 1);
-			cmds[1] = 0;
+		/* Make sure the memstore write gets posted */
+		wmb();
 
-			if (context && device->state != KGSL_STATE_SLUMBER)
-				adreno_ringbuffer_issuecmds_intr(device,
-						context, &cmds[0], 2);
-		}
+		/*
+		 * submit a dummy packet so that even if all
+		 * commands upto timestamp get executed we will still
+		 * get an interrupt
+		 */
+
+		if (context && device->state != KGSL_STATE_SLUMBER)
+			adreno_ringbuffer_issuecmds(device, context->devctxt,
+					KGSL_CMD_FLAGS_NONE, NULL, 0);
 	}
-unlock:
+
+	return 0;
+}
+
+/* Return 1 if the event timestmp has already passed, 0 if it was marked */
+static int adreno_next_event(struct kgsl_device *device,
+		struct kgsl_event *event)
+{
+	return adreno_check_hw_ts(device, event->context, event->timestamp);
+}
+
+static int adreno_check_interrupt_timestamp(struct kgsl_device *device,
+		struct kgsl_context *context, unsigned int timestamp)
+{
+	int status;
+
+	mutex_lock(&device->mutex);
+	status = adreno_check_hw_ts(device, context, timestamp);
 	mutex_unlock(&device->mutex);
 
 	return status;
@@ -2254,16 +2667,26 @@
 
 
 
-unsigned int adreno_hang_detect(struct kgsl_device *device,
+unsigned int adreno_ft_detect(struct kgsl_device *device,
 						unsigned int *prev_reg_val)
 {
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
-	unsigned int curr_reg_val[hang_detect_regs_count];
-	unsigned int hang_detected = 1;
+	unsigned int curr_reg_val[ft_detect_regs_count];
+	unsigned int fast_hang_detected = 1;
+	unsigned int long_ib_detected = 1;
 	unsigned int i;
+	static unsigned long next_hang_detect_time;
+	static unsigned int prev_global_ts;
+	unsigned int curr_global_ts = 0;
+	unsigned int curr_context_id = 0;
+	static struct adreno_context *curr_context;
+	static struct kgsl_context *context;
 
 	if (!adreno_dev->fast_hang_detect)
-		return 0;
+		fast_hang_detected = 0;
+
+	if (!adreno_dev->long_ib_detect)
+		long_ib_detected = 0;
 
 	if (is_adreno_rbbm_status_idle(device)) {
 
@@ -2284,20 +2707,137 @@
 		return 0;
 	}
 
-	for (i = 0; i < hang_detect_regs_count; i++) {
+	/*
+	 * Time interval between hang detection should be KGSL_TIMEOUT_PART
+	 * or more, if next hang detection is requested < KGSL_TIMEOUT_PART
+	 * from the last time do nothing.
+	 */
+	if ((next_hang_detect_time) &&
+		(time_before(jiffies, next_hang_detect_time)))
+			return 0;
+	else
+		next_hang_detect_time = (jiffies +
+			msecs_to_jiffies(KGSL_TIMEOUT_PART-1));
 
-		if (hang_detect_regs[i] == 0)
+	/* Read the current Hang detect reg values here */
+	for (i = 0; i < ft_detect_regs_count; i++) {
+		if (ft_detect_regs[i] == 0)
 			continue;
-
-		adreno_regread(device, hang_detect_regs[i],
-					   &curr_reg_val[i]);
-		if (curr_reg_val[i] != prev_reg_val[i]) {
-			prev_reg_val[i] = curr_reg_val[i];
-			hang_detected = 0;
-		}
+		adreno_regread(device, ft_detect_regs[i],
+			&curr_reg_val[i]);
 	}
 
-	return hang_detected;
+	/* Read the current global timestamp here */
+	kgsl_sharedmem_readl(&device->memstore,
+			&curr_global_ts,
+			KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
+			eoptimestamp));
+
+	mb();
+
+	if (curr_global_ts == prev_global_ts) {
+
+		/* Get the current context here */
+		if (context == NULL) {
+			kgsl_sharedmem_readl(&device->memstore,
+				&curr_context_id,
+				KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
+				current_context));
+			context = idr_find(&device->context_idr,
+				curr_context_id);
+			if (context != NULL) {
+				curr_context = context->devctxt;
+				curr_context->ib_gpu_time_used = 0;
+			} else {
+				KGSL_DRV_ERR(device,
+					"Fault tolerance no context found\n");
+			}
+		}
+
+		mb();
+
+		if (curr_context != NULL) {
+
+			curr_context->ib_gpu_time_used += KGSL_TIMEOUT_PART;
+			KGSL_FT_INFO(device,
+			"Proc %s used GPU Time %d ms on timestamp 0x%X\n",
+			curr_context->pid_name, curr_context->ib_gpu_time_used,
+			curr_global_ts+1);
+
+			for (i = 0; i < ft_detect_regs_count; i++) {
+				if (curr_reg_val[i] != prev_reg_val[i]) {
+					fast_hang_detected = 0;
+
+					/* Check for long IB here */
+					if ((i >=
+						LONG_IB_DETECT_REG_INDEX_START)
+						&&
+						(i <=
+						LONG_IB_DETECT_REG_INDEX_END))
+						long_ib_detected = 0;
+				}
+			}
+
+			if (fast_hang_detected) {
+				KGSL_FT_ERR(device,
+					"Proc %s, ctxt_id %d ts %d triggered fault tolerance"
+					" on global ts %d\n",
+					curr_context->pid_name, curr_context->id
+					, (kgsl_readtimestamp(device, context,
+					KGSL_TIMESTAMP_RETIRED)+1),
+					curr_global_ts+1);
+				return 1;
+			}
+
+			if ((long_ib_detected) &&
+				(!(curr_context->flags &
+				 CTXT_FLAGS_NO_FAULT_TOLERANCE))) {
+				curr_context->ib_gpu_time_used +=
+					KGSL_TIMEOUT_PART;
+				if (curr_context->ib_gpu_time_used >
+					KGSL_TIMEOUT_LONG_IB_DETECTION) {
+					if (adreno_dev->long_ib_ts !=
+						curr_global_ts) {
+						KGSL_FT_ERR(device,
+						"Proc %s, ctxt_id %d ts %d"
+						"used GPU for %d ms long ib "
+						"detected on global ts %d\n",
+						curr_context->pid_name,
+						curr_context->id,
+						(kgsl_readtimestamp(device,
+						context,
+						KGSL_TIMESTAMP_RETIRED)+1),
+						curr_context->ib_gpu_time_used,
+						curr_global_ts+1);
+						adreno_dev->long_ib = 1;
+						adreno_dev->long_ib_ts =
+								curr_global_ts;
+						curr_context->ib_gpu_time_used =
+								0;
+						return 1;
+					}
+				}
+			}
+		} else {
+			KGSL_FT_ERR(device,
+				"Last context unknown id:%d\n",
+				curr_context_id);
+		}
+	} else {
+		/* GPU is moving forward */
+		prev_global_ts = curr_global_ts;
+		context = NULL;
+		curr_context = NULL;
+		adreno_dev->long_ib = 0;
+		adreno_dev->long_ib_ts = 0;
+	}
+
+
+	/* If hangs are not detected copy the current reg values
+	 * to previous values and return no hang */
+	for (i = 0; i < ft_detect_regs_count; i++)
+			prev_reg_val[i] = curr_reg_val[i];
+	return 0;
 }
 
 /**
@@ -2306,7 +2846,8 @@
  * @context - pointer to the active KGSL context
  * @timestamp - the timestamp that the process was waiting for
  *
- * Process a possible GPU hang and try to recover from it cleanly
+ * Process a possible GPU hang and try fault tolerance from it
+ * cleanly
  */
 static int adreno_handle_hang(struct kgsl_device *device,
 	struct kgsl_context *context, unsigned int timestamp)
@@ -2314,6 +2855,7 @@
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	unsigned int context_id = _get_context_id(context);
 	unsigned int ts_issued;
+	unsigned int rptr;
 
 	/* Do one last check to see if we somehow made it through */
 	if (kgsl_check_timestamp(device, context, timestamp))
@@ -2321,15 +2863,20 @@
 
 	ts_issued = adreno_dev->ringbuffer.timestamp[context_id];
 
-	KGSL_DRV_ERR(device,
+	adreno_regread(device, REG_CP_RB_RPTR, &rptr);
+	mb();
+
+	KGSL_DRV_WARN(device,
 		     "Device hang detected while waiting for timestamp: "
 		     "<%d:0x%x>, last submitted timestamp: <%d:0x%x>, "
-		     "wptr: 0x%x\n",
-		      context_id, timestamp, context_id, ts_issued,
-		      adreno_dev->ringbuffer.wptr);
+		     "retired timestamp: <%d:0x%x>, wptr: 0x%x, rptr: 0x%x\n",
+		      context_id, timestamp, context_id, ts_issued, context_id,
+			kgsl_readtimestamp(device, context,
+			KGSL_TIMESTAMP_RETIRED),
+		      adreno_dev->ringbuffer.wptr, rptr);
 
-	/* Return 0 after a successful recovery */
-	if (!adreno_dump_and_recover(device))
+	/* Return 0 after a successful fault tolerance */
+	if (!adreno_dump_and_exec_ft(device))
 		return 0;
 
 	return -ETIMEDOUT;
@@ -2383,7 +2930,7 @@
 	struct adreno_context *adreno_ctx = context ? context->devctxt : NULL;
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
 	unsigned int context_id = _get_context_id(context);
-	unsigned int prev_reg_val[hang_detect_regs_count];
+	unsigned int prev_reg_val[ft_detect_regs_count];
 	unsigned int time_elapsed = 0;
 	unsigned int wait;
 	int ts_compare = 1;
@@ -2442,7 +2989,7 @@
 		}
 
 		/* Check to see if the GPU is hung */
-		if (adreno_hang_detect(device, prev_reg_val)) {
+		if (adreno_ft_detect(device, prev_reg_val)) {
 			ret = adreno_handle_hang(device, context, timestamp);
 			break;
 		}
@@ -2464,7 +3011,7 @@
 		/* Wait for a timestamp event */
 		status = kgsl_wait_event_interruptible_timeout(
 			device->wait_queue,
-			kgsl_check_interrupt_timestamp(device, context,
+			adreno_check_interrupt_timestamp(device, context,
 				timestamp), msecs_to_jiffies(wait), io);
 
 		mutex_lock(&device->mutex);
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 95d995d..8d16bfa 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
@@ -34,12 +34,15 @@
 #define KGSL_CMD_FLAGS_NONE             0x00000000
 #define KGSL_CMD_FLAGS_PMODE		0x00000001
 #define KGSL_CMD_FLAGS_INTERNAL_ISSUE	0x00000002
+#define KGSL_CMD_FLAGS_EOF	        0x00000100
 
 /* Command identifiers */
 #define KGSL_CONTEXT_TO_MEM_IDENTIFIER	0x2EADBEEF
 #define KGSL_CMD_IDENTIFIER		0x2EEDFACE
 #define KGSL_START_OF_IB_IDENTIFIER	0x2EADEABE
 #define KGSL_END_OF_IB_IDENTIFIER	0x2ABEDEAD
+#define KGSL_END_OF_FRAME_IDENTIFIER	0x2E0F2E0F
+#define KGSL_NOP_IB_IDENTIFIER	        0x20F20F20
 
 #ifdef CONFIG_MSM_SCM
 #define ADRENO_DEFAULT_PWRSCALE_POLICY  (&kgsl_pwrscale_policy_tz)
@@ -99,6 +102,12 @@
 	unsigned int instruction_size;
 	unsigned int ib_check_level;
 	unsigned int fast_hang_detect;
+	unsigned int ft_policy;
+	unsigned int ft_user_control;
+	unsigned int long_ib_detect;
+	unsigned int long_ib;
+	unsigned int long_ib_ts;
+	unsigned int ft_pf_policy;
 	unsigned int gpulist_index;
 	struct ocmem_buf *ocmem_hdl;
 	unsigned int ocmem_base;
@@ -123,6 +132,7 @@
 					struct adreno_context *);
 	irqreturn_t (*irq_handler)(struct adreno_device *);
 	void (*irq_control)(struct adreno_device *, int);
+	unsigned int (*irq_pending)(struct adreno_device *);
 	void * (*snapshot)(struct adreno_device *, void *, int *, int);
 	void (*rb_init)(struct adreno_device *, struct adreno_ringbuffer *);
 	void (*start)(struct adreno_device *);
@@ -130,8 +140,8 @@
 };
 
 /*
- * struct adreno_recovery_data - Structure that contains all information to
- * perform gpu recovery from hangs
+ * struct adreno_ft_data - Structure that contains all information to
+ * perform gpu fault tolerance
  * @ib1 - IB1 that the GPU was executing when hang happened
  * @context_id - Context which caused the hang
  * @global_eop - eoptimestamp at time of hang
@@ -139,11 +149,19 @@
  * @rb_size - Number of valid dwords in rb_buffer
  * @bad_rb_buffer - Buffer that holds commands from the hanging context
  * bad_rb_size - Number of valid dwords in bad_rb_buffer
+ * @good_rb_buffer - Buffer that holds commands from good contexts
+ * good_rb_size - Number of valid dwords in good_rb_buffer
  * @last_valid_ctx_id - The last context from which commands were placed in
  * ringbuffer before the GPU hung
+ * @step - Current fault tolerance step being executed
+ * @err_code - Fault tolerance error code
  * @fault - Indicates whether the hang was caused due to a pagefault
+ * @start_of_replay_cmds - Offset in ringbuffer from where commands can be
+ * replayed during fault tolerance
+ * @replay_for_snapshot - Offset in ringbuffer where IB's can be saved for
+ * replaying with snapshot
  */
-struct adreno_recovery_data {
+struct adreno_ft_data {
 	unsigned int ib1;
 	unsigned int context_id;
 	unsigned int global_eop;
@@ -151,10 +169,32 @@
 	unsigned int rb_size;
 	unsigned int *bad_rb_buffer;
 	unsigned int bad_rb_size;
+	unsigned int *good_rb_buffer;
+	unsigned int good_rb_size;
 	unsigned int last_valid_ctx_id;
-	int fault;
+	unsigned int status;
+	unsigned int ft_policy;
+	unsigned int err_code;
+	unsigned int start_of_replay_cmds;
+	unsigned int replay_for_snapshot;
 };
 
+/* Fault Tolerance policy flags */
+#define  KGSL_FT_DISABLE                  BIT(0)
+#define  KGSL_FT_REPLAY                   BIT(1)
+#define  KGSL_FT_SKIPIB                   BIT(2)
+#define  KGSL_FT_SKIPFRAME                BIT(3)
+#define  KGSL_FT_TEMP_DISABLE             BIT(4)
+#define  KGSL_FT_DEFAULT_POLICY           (KGSL_FT_REPLAY + KGSL_FT_SKIPIB)
+
+/* Pagefault policy flags */
+#define KGSL_FT_PAGEFAULT_INT_ENABLE         0x00000001
+#define KGSL_FT_PAGEFAULT_GPUHALT_ENABLE     0x00000002
+#define KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE   0x00000004
+#define KGSL_FT_PAGEFAULT_LOG_ONE_PER_INT    0x00000008
+#define KGSL_FT_PAGEFAULT_DEFAULT_POLICY     (KGSL_FT_PAGEFAULT_INT_ENABLE + \
+					KGSL_FT_PAGEFAULT_GPUHALT_ENABLE)
+
 extern struct adreno_gpudev adreno_a2xx_gpudev;
 extern struct adreno_gpudev adreno_a3xx_gpudev;
 
@@ -176,8 +216,8 @@
 extern const unsigned int a330_registers[];
 extern const unsigned int a330_registers_count;
 
-extern unsigned int hang_detect_regs[];
-extern const unsigned int hang_detect_regs_count;
+extern unsigned int ft_detect_regs[];
+extern const unsigned int ft_detect_regs_count;
 
 
 int adreno_idle(struct kgsl_device *device);
@@ -202,9 +242,12 @@
 void *adreno_snapshot(struct kgsl_device *device, void *snapshot, int *remain,
 		int hang);
 
-int adreno_dump_and_recover(struct kgsl_device *device);
+int adreno_dump_and_exec_ft(struct kgsl_device *device);
 
-unsigned int adreno_hang_detect(struct kgsl_device *device,
+void adreno_dump_rb(struct kgsl_device *device, const void *buf,
+			 size_t len, int start, int size);
+
+unsigned int adreno_ft_detect(struct kgsl_device *device,
 						unsigned int *prev_reg_val);
 
 static inline int adreno_is_a200(struct adreno_device *adreno_dev)
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index cfa1557..aa14330 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2013, The Linux Foundation. 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 and
@@ -1708,28 +1708,6 @@
 		return;
 	}
 
-	if (status & CP_INT_CNTL__RB_INT_MASK) {
-		/* signal intr completion event */
-		unsigned int context_id;
-		kgsl_sharedmem_readl(&device->memstore,
-				&context_id,
-				KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
-					current_context));
-		if (context_id < KGSL_MEMSTORE_MAX) {
-			/* reset per context ts_cmp_enable */
-			kgsl_sharedmem_writel(&device->memstore,
-					KGSL_MEMSTORE_OFFSET(context_id,
-						ts_cmp_enable), 0);
-			/* Always reset global timestamp ts_cmp_enable */
-			kgsl_sharedmem_writel(&device->memstore,
-					KGSL_MEMSTORE_OFFSET(
-						KGSL_MEMSTORE_GLOBAL,
-						ts_cmp_enable), 0);
-			wmb();
-		}
-		KGSL_CMD_WARN(rb->device, "ringbuffer rb interrupt\n");
-	}
-
 	for (i = 0; i < ARRAY_SIZE(kgsl_cp_error_irqs); i++) {
 		if (status & kgsl_cp_error_irqs[i].mask) {
 			KGSL_CMD_CRIT(rb->device, "%s\n",
@@ -1840,6 +1818,19 @@
 	wmb();
 }
 
+static unsigned int a2xx_irq_pending(struct adreno_device *adreno_dev)
+{
+	struct kgsl_device *device = &adreno_dev->dev;
+	unsigned int status;
+
+	adreno_regread(device, REG_MASTER_INT_SIGNAL, &status);
+
+	return (status &
+		(MASTER_INT_SIGNAL__MH_INT_STAT |
+		 MASTER_INT_SIGNAL__CP_INT_STAT |
+		 MASTER_INT_SIGNAL__RBBM_INT_STAT)) ? 1 : 0;
+}
+
 static void a2xx_rb_init(struct adreno_device *adreno_dev,
 			struct adreno_ringbuffer *rb)
 {
@@ -2035,6 +2026,7 @@
 	.ctxt_draw_workaround = a2xx_drawctxt_draw_workaround,
 	.irq_handler = a2xx_irq_handler,
 	.irq_control = a2xx_irq_control,
+	.irq_pending = a2xx_irq_pending,
 	.snapshot = a2xx_snapshot,
 	.rb_init = a2xx_rb_init,
 	.busy_cycles = a2xx_busy_cycles,
diff --git a/drivers/gpu/msm/adreno_a2xx_snapshot.c b/drivers/gpu/msm/adreno_a2xx_snapshot.c
index 282440c..75795b1 100644
--- a/drivers/gpu/msm/adreno_a2xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a2xx_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/adreno_a2xx_trace.c b/drivers/gpu/msm/adreno_a2xx_trace.c
index c91d1a0..87c930b 100644
--- a/drivers/gpu/msm/adreno_a2xx_trace.c
+++ b/drivers/gpu/msm/adreno_a2xx_trace.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/adreno_a2xx_trace.h b/drivers/gpu/msm/adreno_a2xx_trace.h
index 2528e15..af355d6 100644
--- a/drivers/gpu/msm/adreno_a2xx_trace.h
+++ b/drivers/gpu/msm/adreno_a2xx_trace.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 6276a59..3d9ec6d 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -70,7 +70,7 @@
 const unsigned int a3xx_registers_count = ARRAY_SIZE(a3xx_registers) / 2;
 
 /* Removed the following HLSQ register ranges from being read during
- * recovery since reading the registers may cause the device to hang:
+ * fault tolerance since reading the registers may cause the device to hang:
  */
 const unsigned int a3xx_hlsq_registers[] = {
 	0x0e00, 0x0e05, 0x0e0c, 0x0e0c, 0x0e22, 0x0e23,
@@ -2576,26 +2576,7 @@
 {
 	struct kgsl_device *device = &adreno_dev->dev;
 
-	if (irq == A3XX_INT_CP_RB_INT) {
-		unsigned int context_id;
-		kgsl_sharedmem_readl(&device->memstore, &context_id,
-				KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
-					current_context));
-		if (context_id < KGSL_MEMSTORE_MAX) {
-			/* reset per context ts_cmp_enable */
-			kgsl_sharedmem_writel(&device->memstore,
-					KGSL_MEMSTORE_OFFSET(context_id,
-						ts_cmp_enable), 0);
-			/* Always reset global timestamp ts_cmp_enable */
-			kgsl_sharedmem_writel(&device->memstore,
-					KGSL_MEMSTORE_OFFSET(
-						KGSL_MEMSTORE_GLOBAL,
-						ts_cmp_enable), 0);
-			wmb();
-		}
-		KGSL_CMD_WARN(device, "ringbuffer rb interrupt\n");
-	}
-
+	/* Wake up everybody waiting for the interrupt */
 	wake_up_interruptible_all(&device->wait_queue);
 
 	/* Schedule work to free mem and issue ibs */
@@ -2694,6 +2675,15 @@
 		adreno_regwrite(device, A3XX_RBBM_INT_0_MASK, 0);
 }
 
+static unsigned int a3xx_irq_pending(struct adreno_device *adreno_dev)
+{
+	unsigned int status;
+
+	adreno_regread(&adreno_dev->dev, A3XX_RBBM_INT_0_STATUS, &status);
+
+	return (status & A3XX_INT_MASK) ? 1 : 0;
+}
+
 static unsigned int a3xx_busy_cycles(struct adreno_device *adreno_dev)
 {
 	struct kgsl_device *device = &adreno_dev->dev;
@@ -2888,6 +2878,7 @@
 	.rb_init = a3xx_rb_init,
 	.irq_control = a3xx_irq_control,
 	.irq_handler = a3xx_irq_handler,
+	.irq_pending = a3xx_irq_pending,
 	.busy_cycles = a3xx_busy_cycles,
 	.start = a3xx_start,
 	.snapshot = a3xx_snapshot,
diff --git a/drivers/gpu/msm/adreno_a3xx_snapshot.c b/drivers/gpu/msm/adreno_a3xx_snapshot.c
index 0d9453c..d9d5ec8 100644
--- a/drivers/gpu/msm/adreno_a3xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a3xx_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/adreno_a3xx_trace.c b/drivers/gpu/msm/adreno_a3xx_trace.c
index 8b4a80d..325b068 100644
--- a/drivers/gpu/msm/adreno_a3xx_trace.c
+++ b/drivers/gpu/msm/adreno_a3xx_trace.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/adreno_a3xx_trace.h b/drivers/gpu/msm/adreno_a3xx_trace.h
index 44483a8..d48faf4 100644
--- a/drivers/gpu/msm/adreno_a3xx_trace.h
+++ b/drivers/gpu/msm/adreno_a3xx_trace.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index bb3da40..890c8a1 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-2012, The Linux Foundation. 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 and
@@ -65,4 +65,38 @@
 	debugfs_create_u32("fast_hang_detect", 0644, device->d_debugfs,
 			   &adreno_dev->fast_hang_detect);
 
+	/* Top level switch to enable/disable userspace FT control */
+	adreno_dev->ft_user_control = 0;
+	debugfs_create_u32("ft_user_control", 0644, device->d_debugfs,
+			   &adreno_dev->ft_user_control);
+	/*
+	 * FT policy can be set to any of the options below.
+	 * KGSL_FT_DISABLE -> BIT(0) Set to disable FT
+	 * KGSL_FT_REPLAY  -> BIT(1) Set to enable replay
+	 * KGSL_FT_SKIPIB  -> BIT(2) Set to skip IB
+	 * KGSL_FT_SKIPFRAME -> BIT(3) Set to skip frame
+	 * by default set FT policy to KGSL_FT_DEFAULT_POLICY
+	 */
+	adreno_dev->ft_policy = KGSL_FT_DEFAULT_POLICY;
+	debugfs_create_u32("ft_policy", 0644, device->d_debugfs,
+			   &adreno_dev->ft_policy);
+
+	/* By default enable long IB detection */
+	adreno_dev->long_ib_detect = 1;
+	debugfs_create_u32("long_ib_detect", 0644, device->d_debugfs,
+			   &adreno_dev->long_ib_detect);
+
+	/*
+	 * FT pagefault policy can be set to any of the options below.
+	 * KGSL_FT_PAGEFAULT_INT_ENABLE -> BIT(0) set to enable pagefault INT
+	 * KGSL_FT_PAGEFAULT_GPUHALT_ENABLE  -> BIT(1) Set to enable GPU HALT on
+	 * pagefaults. This stalls the GPU on a pagefault on IOMMU v1 HW.
+	 * KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE  -> BIT(2) Set to log only one
+	 * pagefault per page.
+	 * KGSL_FT_PAGEFAULT_LOG_ONE_PER_INT -> BIT(3) Set to log only one
+	 * pagefault per INT.
+	 */
+	adreno_dev->ft_pf_policy = KGSL_FT_PAGEFAULT_DEFAULT_POLICY;
+	debugfs_create_u32("ft_pagefault_policy", 0644, device->d_debugfs,
+			   &adreno_dev->ft_pf_policy);
 }
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index 4dda7ba..6fbcdee 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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 and
@@ -155,6 +155,8 @@
 	if (drawctxt == NULL)
 		return -ENOMEM;
 
+	drawctxt->pid = task_pid_nr(current);
+	strlcpy(drawctxt->pid_name, current->comm, TASK_COMM_LEN);
 	drawctxt->pagetable = pagetable;
 	drawctxt->bin_base_offset = 0;
 	drawctxt->id = context->id;
@@ -177,6 +179,9 @@
 		drawctxt->flags |= CTXT_FLAGS_USER_GENERATED_TS;
 	}
 
+	if (flags & KGSL_CONTEXT_NO_FAULT_TOLERANCE)
+		drawctxt->flags |= CTXT_FLAGS_NO_FAULT_TOLERANCE;
+
 	ret = adreno_dev->gpudev->ctxt_create(adreno_dev, drawctxt);
 	if (ret)
 		goto err;
diff --git a/drivers/gpu/msm/adreno_drawctxt.h b/drivers/gpu/msm/adreno_drawctxt.h
index 58e4791..c91bfc0 100644
--- a/drivers/gpu/msm/adreno_drawctxt.h
+++ b/drivers/gpu/msm/adreno_drawctxt.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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 and
@@ -13,6 +13,8 @@
 #ifndef __ADRENO_DRAWCTXT_H
 #define __ADRENO_DRAWCTXT_H
 
+#include <linux/sched.h>
+
 #include "adreno_pm4types.h"
 #include "a2xx_reg.h"
 
@@ -44,12 +46,16 @@
 #define CTXT_FLAGS_TRASHSTATE		BIT(10)
 /* per context timestamps enabled */
 #define CTXT_FLAGS_PER_CONTEXT_TS	BIT(11)
-/* Context has caused a GPU hang and recovered properly */
-#define CTXT_FLAGS_GPU_HANG_RECOVERED	BIT(12)
+/* Context has caused a GPU hang and fault tolerance successful */
+#define CTXT_FLAGS_GPU_HANG_FT	BIT(12)
 /* Context is being destroyed so dont save it */
 #define CTXT_FLAGS_BEING_DESTROYED	BIT(13)
 /* User mode generated timestamps enabled */
 #define CTXT_FLAGS_USER_GENERATED_TS    BIT(14)
+/* Context skip till EOF */
+#define CTXT_FLAGS_SKIP_EOF             BIT(15)
+/* Context no fault tolerance */
+#define CTXT_FLAGS_NO_FAULT_TOLERANCE  BIT(16)
 
 struct kgsl_device;
 struct adreno_device;
@@ -82,8 +88,13 @@
 };
 
 struct adreno_context {
+	pid_t pid;
+	char pid_name[TASK_COMM_LEN];
 	unsigned int id;
+	unsigned int ib_gpu_time_used;
 	uint32_t flags;
+	uint32_t pagefault;
+	unsigned long pagefault_ts;
 	struct kgsl_pagetable *pagetable;
 	struct kgsl_memdesc gpustate;
 	unsigned int reg_restore[3];
diff --git a/drivers/gpu/msm/adreno_pm4types.h b/drivers/gpu/msm/adreno_pm4types.h
index c8b49fb..a3fa312 100644
--- a/drivers/gpu/msm/adreno_pm4types.h
+++ b/drivers/gpu/msm/adreno_pm4types.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 620b82c..5fdcf19 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
@@ -268,7 +268,7 @@
 #endif
 }
 
-static void adreno_dump_rb(struct kgsl_device *device, const void *buf,
+void adreno_dump_rb(struct kgsl_device *device, const void *buf,
 			 size_t len, int start, int size)
 {
 	const uint32_t *ptr = buf;
@@ -692,6 +692,7 @@
 	unsigned int ts_processed = 0xdeaddead;
 	struct kgsl_context *context;
 	unsigned int context_id;
+	unsigned int rbbm_status;
 
 	static struct ib_list ib_list;
 
@@ -701,10 +702,14 @@
 
 	mb();
 
-	if (adreno_is_a2xx(adreno_dev))
-		adreno_dump_a2xx(device);
-	else if (adreno_is_a3xx(adreno_dev))
-		adreno_dump_a3xx(device);
+	if (device->pm_dump_enable) {
+		if (adreno_is_a2xx(adreno_dev))
+			adreno_dump_a2xx(device);
+		else if (adreno_is_a3xx(adreno_dev))
+			adreno_dump_a3xx(device);
+	}
+
+	kgsl_regread(device, adreno_dev->gpudev->reg_rbbm_status, &rbbm_status);
 
 	pt_base = kgsl_mmu_get_current_ptbase(&device->mmu);
 	cur_pt_base = pt_base;
@@ -719,6 +724,18 @@
 	kgsl_regread(device, REG_CP_IB2_BASE, &cp_ib2_base);
 	kgsl_regread(device, REG_CP_IB2_BUFSZ, &cp_ib2_bufsz);
 
+	/* If postmortem dump is not enabled, dump minimal set and return */
+	if (!device->pm_dump_enable) {
+
+		KGSL_LOG_DUMP(device,
+			"STATUS %08X | IB1:%08X/%08X | IB2: %08X/%08X"
+			" | RPTR: %04X | WPTR: %04X\n",
+			rbbm_status,  cp_ib1_base, cp_ib1_bufsz, cp_ib2_base,
+			cp_ib2_bufsz, cp_rb_rptr, cp_rb_wptr);
+
+		return 0;
+	}
+
 	kgsl_sharedmem_readl(&device->memstore,
 			(unsigned int *) &context_id,
 			KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
@@ -727,7 +744,7 @@
 	if (context) {
 		ts_processed = kgsl_readtimestamp(device, context,
 						  KGSL_TIMESTAMP_RETIRED);
-		KGSL_LOG_DUMP(device, "CTXT: %d  TIMESTM RTRD: %08X\n",
+		KGSL_LOG_DUMP(device, "FT CTXT: %d  TIMESTM RTRD: %08X\n",
 				context->id, ts_processed);
 	} else
 		KGSL_LOG_DUMP(device, "BAD CTXT: %d\n", context_id);
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 3558b8f..48367fa 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2013, The Linux Foundation. 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 and
@@ -64,7 +64,7 @@
 	unsigned long wait_time;
 	unsigned long wait_timeout = msecs_to_jiffies(ADRENO_IDLE_TIMEOUT);
 	unsigned long wait_time_part;
-	unsigned int prev_reg_val[hang_detect_regs_count];
+	unsigned int prev_reg_val[ft_detect_regs_count];
 
 	memset(prev_reg_val, 0, sizeof(prev_reg_val));
 
@@ -109,7 +109,7 @@
 		if (time_after(jiffies, wait_time_part)) {
 			wait_time_part = jiffies +
 				msecs_to_jiffies(KGSL_TIMEOUT_PART);
-			if ((adreno_hang_detect(rb->device,
+			if ((adreno_ft_detect(rb->device,
 						prev_reg_val))){
 				KGSL_DRV_ERR(rb->device,
 				"Hang detected while waiting for freespace in"
@@ -129,7 +129,7 @@
 		continue;
 
 err:
-		if (!adreno_dump_and_recover(rb->device)) {
+		if (!adreno_dump_and_exec_ft(rb->device)) {
 			if (context && context->flags & CTXT_FLAGS_GPU_HANG) {
 				KGSL_CTXT_WARN(rb->device,
 				"Context %p caused a gpu hang. Will not accept commands for context %d\n",
@@ -138,7 +138,7 @@
 			}
 			wait_time = jiffies + wait_timeout;
 		} else {
-			/* GPU is hung and we cannot recover */
+			/* GPU is hung and fault tolerance failed */
 			BUG();
 		}
 	}
@@ -564,15 +564,17 @@
 	total_sizedwords += flags & KGSL_CMD_FLAGS_PMODE ? 4 : 0;
 	/* 2 dwords to store the start of command sequence */
 	total_sizedwords += 2;
-	/*
-	 * Add CP_COND_EXEC commands to generate CP_INTERRUPT only
-	 */
-	total_sizedwords += context ? 7 : 0;
+
+	/* Add CP_COND_EXEC commands to generate CP_INTERRUPT */
+	total_sizedwords += context ? 13 : 0;
 
 	if (adreno_is_a3xx(adreno_dev))
 		total_sizedwords += 7;
 
-	total_sizedwords += 2; /* scratchpad ts for recovery */
+	if (adreno_is_a2xx(adreno_dev))
+		total_sizedwords += 2; /* CP_WAIT_FOR_IDLE */
+
+	total_sizedwords += 2; /* scratchpad ts for fault tolerance */
 	if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS &&
 			!(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
 		total_sizedwords += 3; /* sop timestamp */
@@ -580,9 +582,12 @@
 		total_sizedwords += 3; /* global timestamp without cache
 					* flush for non-zero context */
 	} else {
-		total_sizedwords += 4; /* global timestamp for recovery*/
+		total_sizedwords += 4; /* global timestamp for fault tolerance*/
 	}
 
+	if (flags & KGSL_CMD_FLAGS_EOF)
+		total_sizedwords += 2;
+
 	ringcmds = adreno_ringbuffer_allocspace(rb, context, total_sizedwords);
 	if (!ringcmds) {
 		/*
@@ -632,7 +637,17 @@
 	}
 	timestamp = rb->timestamp[context_id];
 
-	/* scratchpad ts for recovery */
+	/* HW Workaround for MMU Page fault
+	* due to memory getting free early before
+	* GPU completes it.
+	*/
+	if (adreno_is_a2xx(adreno_dev)) {
+		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+			cp_type3_packet(CP_WAIT_FOR_IDLE, 1));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x00);
+	}
+
+	/* scratchpad ts for fault tolerance */
 	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type0_packet(REG_CP_TIMESTAMP, 1));
 	GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
 
@@ -696,7 +711,25 @@
 				context_id, ref_wait_ts)) >> 2);
 		GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
 		/* # of conditional command DWORDs */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, 2);
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, 8);
+
+		/* Clear the ts_cmp_enable for the context */
+		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+			cp_type3_packet(CP_MEM_WRITE, 2));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, gpuaddr +
+			KGSL_MEMSTORE_OFFSET(
+				context_id, ts_cmp_enable));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x0);
+
+		/* Clear the ts_cmp_enable for the global timestamp */
+		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+			cp_type3_packet(CP_MEM_WRITE, 2));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, gpuaddr +
+			KGSL_MEMSTORE_OFFSET(
+				KGSL_MEMSTORE_GLOBAL, ts_cmp_enable));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x0);
+
+		/* Trigger the interrupt */
 		GSL_RB_WRITE(ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_INTERRUPT, 1));
 		GSL_RB_WRITE(ringcmds, rcmd_gpu, CP_INT_CNTL__RB_INT_MASK);
@@ -711,35 +744,16 @@
 		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0);
 	}
 
+	if (flags & KGSL_CMD_FLAGS_EOF) {
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_nop_packet(1));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, KGSL_END_OF_FRAME_IDENTIFIER);
+	}
+
 	adreno_ringbuffer_submit(rb);
 
 	return timestamp;
 }
 
-void
-adreno_ringbuffer_issuecmds_intr(struct kgsl_device *device,
-						struct kgsl_context *k_ctxt,
-						unsigned int *cmds,
-						int sizedwords)
-{
-	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
-	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
-	struct adreno_context *a_ctxt = NULL;
-
-	if (!k_ctxt)
-		return;
-
-	a_ctxt = k_ctxt->devctxt;
-
-	if (k_ctxt->id == KGSL_CONTEXT_INVALID ||
-		a_ctxt == NULL ||
-		device->state & KGSL_STATE_HUNG)
-		return;
-
-	adreno_ringbuffer_addcmds(rb, a_ctxt, KGSL_CMD_FLAGS_INTERNAL_ISSUE,
-					cmds, sizedwords, 0);
-}
-
 unsigned int
 adreno_ringbuffer_issuecmds(struct kgsl_device *device,
 						struct adreno_context *drawctxt,
@@ -977,12 +991,22 @@
 	drawctxt = context->devctxt;
 
 	if (drawctxt->flags & CTXT_FLAGS_GPU_HANG) {
-		KGSL_CTXT_WARN(device, "Context %p caused a gpu hang.."
+		KGSL_CTXT_ERR(device, "proc %s failed fault tolerance"
 			" will not accept commands for context %d\n",
-			drawctxt, drawctxt->id);
+			drawctxt->pid_name, drawctxt->id);
 		return -EDEADLK;
 	}
 
+	if (drawctxt->flags & CTXT_FLAGS_SKIP_EOF) {
+		KGSL_CTXT_ERR(device,
+			"proc %s triggered fault tolerance"
+			" skipping commands for context till EOF %d\n",
+			drawctxt->pid_name, drawctxt->id);
+		if (flags & KGSL_CMD_FLAGS_EOF)
+			drawctxt->flags &= ~CTXT_FLAGS_SKIP_EOF;
+		numibs = 0;
+	}
+
 	cmds = link = kzalloc(sizeof(unsigned int) * (numibs * 3 + 4),
 				GFP_KERNEL);
 	if (!link) {
@@ -1032,7 +1056,7 @@
 
 	*timestamp = adreno_ringbuffer_addcmds(&adreno_dev->ringbuffer,
 					drawctxt,
-					0,
+					(flags & KGSL_CMD_FLAGS_EOF),
 					&link[0], (cmds - link), *timestamp);
 
 	KGSL_CMD_INFO(device, "ctxt %d g %08x numibs %d ts %d\n",
@@ -1048,169 +1072,16 @@
 	 */
 	adreno_idle(device);
 #endif
-	/* If context hung and recovered then return error so that the
-	 * application may handle it */
-	if (drawctxt->flags & CTXT_FLAGS_GPU_HANG_RECOVERED)
-		return -EDEADLK;
-	else
+
+	/*
+	 * If context hung and recovered then return error so that the
+	 * application may handle it
+	 */
+	if (drawctxt->flags & CTXT_FLAGS_GPU_HANG_FT) {
+		drawctxt->flags &= ~CTXT_FLAGS_GPU_HANG_FT;
+		return -EPROTO;
+	} else
 		return 0;
-
-}
-
-static int _find_start_of_cmd_seq(struct adreno_ringbuffer *rb,
-					unsigned int *ptr,
-					bool inc)
-{
-	int status = -EINVAL;
-	unsigned int val1;
-	unsigned int size = rb->buffer_desc.size;
-	unsigned int start_ptr = *ptr;
-
-	while ((start_ptr / sizeof(unsigned int)) != rb->wptr) {
-		if (inc)
-			start_ptr = adreno_ringbuffer_inc_wrapped(start_ptr,
-									size);
-		else
-			start_ptr = adreno_ringbuffer_dec_wrapped(start_ptr,
-									size);
-		kgsl_sharedmem_readl(&rb->buffer_desc, &val1, start_ptr);
-		if (KGSL_CMD_IDENTIFIER == val1) {
-			if ((start_ptr / sizeof(unsigned int)) != rb->wptr)
-				start_ptr = adreno_ringbuffer_dec_wrapped(
-							start_ptr, size);
-				*ptr = start_ptr;
-				status = 0;
-				break;
-		}
-	}
-	return status;
-}
-
-static int _find_cmd_seq_after_eop_ts(struct adreno_ringbuffer *rb,
-					unsigned int *rb_rptr,
-					unsigned int global_eop,
-					bool inc)
-{
-	int status = -EINVAL;
-	unsigned int temp_rb_rptr = *rb_rptr;
-	unsigned int size = rb->buffer_desc.size;
-	unsigned int val[3];
-	int i = 0;
-	bool check = false;
-
-	if (inc && temp_rb_rptr / sizeof(unsigned int) != rb->wptr)
-		return status;
-
-	do {
-		/* when decrementing we need to decrement first and
-		 * then read make sure we cover all the data */
-		if (!inc)
-			temp_rb_rptr = adreno_ringbuffer_dec_wrapped(
-					temp_rb_rptr, size);
-		kgsl_sharedmem_readl(&rb->buffer_desc, &val[i],
-					temp_rb_rptr);
-
-		if (check && ((inc && val[i] == global_eop) ||
-			(!inc && (val[i] ==
-			cp_type3_packet(CP_MEM_WRITE, 2) ||
-			val[i] == CACHE_FLUSH_TS)))) {
-			/* decrement i, i.e i = (i - 1 + 3) % 3 if
-			 * we are going forward, else increment i */
-			i = (i + 2) % 3;
-			if (val[i] == rb->device->memstore.gpuaddr +
-				KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
-						eoptimestamp)) {
-				int j = ((i + 2) % 3);
-				if ((inc && (val[j] == CACHE_FLUSH_TS ||
-						val[j] == cp_type3_packet(
-							CP_MEM_WRITE, 2))) ||
-					(!inc && val[j] == global_eop)) {
-						/* Found the global eop */
-						status = 0;
-						break;
-				}
-			}
-			/* if no match found then increment i again
-			 * since we decremented before matching */
-			i = (i + 1) % 3;
-		}
-		if (inc)
-			temp_rb_rptr = adreno_ringbuffer_inc_wrapped(
-						temp_rb_rptr, size);
-
-		i = (i + 1) % 3;
-		if (2 == i)
-			check = true;
-	} while (temp_rb_rptr / sizeof(unsigned int) != rb->wptr);
-	/* temp_rb_rptr points to the command stream after global eop,
-	 * move backward till the start of command sequence */
-	if (!status) {
-		status = _find_start_of_cmd_seq(rb, &temp_rb_rptr, false);
-		if (!status) {
-			*rb_rptr = temp_rb_rptr;
-			KGSL_DRV_ERR(rb->device,
-			"Offset of cmd sequence after eop timestamp: 0x%x\n",
-			temp_rb_rptr / sizeof(unsigned int));
-		}
-	}
-	if (status)
-		KGSL_DRV_ERR(rb->device,
-		"Failed to find the command sequence after eop timestamp\n");
-	return status;
-}
-
-static int _find_hanging_ib_sequence(struct adreno_ringbuffer *rb,
-				unsigned int *rb_rptr,
-				unsigned int ib1)
-{
-	int status = -EINVAL;
-	unsigned int temp_rb_rptr = *rb_rptr;
-	unsigned int size = rb->buffer_desc.size;
-	unsigned int val[2];
-	int i = 0;
-	bool check = false;
-	bool ctx_switch = false;
-
-	while (temp_rb_rptr / sizeof(unsigned int) != rb->wptr) {
-		kgsl_sharedmem_readl(&rb->buffer_desc, &val[i], temp_rb_rptr);
-
-		if (check && val[i] == ib1) {
-			/* decrement i, i.e i = (i - 1 + 2) % 2 */
-			i = (i + 1) % 2;
-			if (adreno_cmd_is_ib(val[i])) {
-				/* go till start of command sequence */
-				status = _find_start_of_cmd_seq(rb,
-						&temp_rb_rptr, false);
-				KGSL_DRV_ERR(rb->device,
-				"Found the hanging IB at offset 0x%x\n",
-				temp_rb_rptr / sizeof(unsigned int));
-				break;
-			}
-			/* if no match the increment i since we decremented
-			 * before checking */
-			i = (i + 1) % 2;
-		}
-		/* Make sure you do not encounter a context switch twice, we can
-		 * encounter it once for the bad context as the start of search
-		 * can point to the context switch */
-		if (val[i] == KGSL_CONTEXT_TO_MEM_IDENTIFIER) {
-			if (ctx_switch) {
-				KGSL_DRV_ERR(rb->device,
-				"Context switch encountered before bad "
-				"IB found\n");
-				break;
-			}
-			ctx_switch = true;
-		}
-		i = (i + 1) % 2;
-		if (1 == i)
-			check = true;
-		temp_rb_rptr = adreno_ringbuffer_inc_wrapped(temp_rb_rptr,
-								size);
-	}
-	if  (!status)
-		*rb_rptr = temp_rb_rptr;
-	return status;
 }
 
 static void _turn_preamble_on_for_ib_seq(struct adreno_ringbuffer *rb,
@@ -1235,7 +1106,7 @@
 				kgsl_sharedmem_writel(&rb->buffer_desc,
 					temp_rb_rptr, cp_nop_packet(1));
 			}
-			KGSL_DRV_ERR(rb->device,
+			KGSL_FT_INFO(rb->device,
 			"Turned preamble on at offset 0x%x\n",
 			temp_rb_rptr / 4);
 			break;
@@ -1257,21 +1128,41 @@
 	}
 }
 
-static void _copy_valid_rb_content(struct adreno_ringbuffer *rb,
-		unsigned int rb_rptr, unsigned int *temp_rb_buffer,
-		int *rb_size, unsigned int *bad_rb_buffer,
-		int *bad_rb_size,
-		int *last_valid_ctx_id)
+void adreno_ringbuffer_extract(struct adreno_ringbuffer *rb,
+				struct adreno_ft_data *ft_data)
 {
-	unsigned int good_rb_idx = 0, cmd_start_idx = 0;
+	struct kgsl_device *device = rb->device;
+	unsigned int rb_rptr = ft_data->start_of_replay_cmds;
+	unsigned int good_rb_idx = 0, bad_rb_idx = 0, temp_rb_idx = 0;
+	unsigned int last_good_cmd_end_idx = 0, last_bad_cmd_end_idx = 0;
+	unsigned int cmd_start_idx = 0;
 	unsigned int val1 = 0;
-	struct kgsl_context *k_ctxt;
-	struct adreno_context *a_ctxt;
-	unsigned int bad_rb_idx = 0;
 	int copy_rb_contents = 0;
 	unsigned int temp_rb_rptr;
+	struct kgsl_context *k_ctxt;
+	struct adreno_context *a_ctxt;
 	unsigned int size = rb->buffer_desc.size;
-	unsigned int good_cmd_start_idx = 0;
+	unsigned int *temp_rb_buffer = ft_data->rb_buffer;
+	int *rb_size = &ft_data->rb_size;
+	unsigned int *bad_rb_buffer = ft_data->bad_rb_buffer;
+	int *bad_rb_size = &ft_data->bad_rb_size;
+	unsigned int *good_rb_buffer = ft_data->good_rb_buffer;
+	int *good_rb_size = &ft_data->good_rb_size;
+
+	/*
+	 * If the start index from where commands need to be copied is invalid
+	 * then no need to save off any commands
+	 */
+	if (0xFFFFFFFF == ft_data->start_of_replay_cmds)
+		return;
+
+	k_ctxt = idr_find(&device->context_idr, ft_data->context_id);
+	if (k_ctxt) {
+		a_ctxt = k_ctxt->devctxt;
+		if (a_ctxt->flags & CTXT_FLAGS_PREAMBLE)
+			_turn_preamble_on_for_ib_seq(rb, rb_rptr);
+	}
+	k_ctxt = NULL;
 
 	/* Walk the rb from the context switch. Omit any commands
 	 * for an invalid context. */
@@ -1281,9 +1172,11 @@
 		if (KGSL_CMD_IDENTIFIER == val1) {
 			/* Start is the NOP dword that comes before
 			 * KGSL_CMD_IDENTIFIER */
-			cmd_start_idx = bad_rb_idx - 1;
-			if (copy_rb_contents)
-				good_cmd_start_idx = good_rb_idx - 1;
+			cmd_start_idx = temp_rb_idx - 1;
+			if ((copy_rb_contents) && (good_rb_idx))
+				last_good_cmd_end_idx = good_rb_idx - 1;
+			if ((!copy_rb_contents) && (bad_rb_idx))
+				last_bad_cmd_end_idx = bad_rb_idx - 1;
 		}
 
 		/* check for context switch indicator */
@@ -1309,86 +1202,48 @@
 				!(a_ctxt->flags & CTXT_FLAGS_GPU_HANG)) ||
 				!k_ctxt)) {
 				for (temp_idx = cmd_start_idx;
-					temp_idx < bad_rb_idx;
+					temp_idx < temp_rb_idx;
 					temp_idx++)
-					temp_rb_buffer[good_rb_idx++] =
-						bad_rb_buffer[temp_idx];
-				*last_valid_ctx_id = val2;
+					good_rb_buffer[good_rb_idx++] =
+						temp_rb_buffer[temp_idx];
+				ft_data->last_valid_ctx_id = val2;
 				copy_rb_contents = 1;
+				/* remove the good commands from bad buffer */
+				bad_rb_idx = last_bad_cmd_end_idx;
 			} else if (copy_rb_contents && k_ctxt &&
 				(a_ctxt->flags & CTXT_FLAGS_GPU_HANG)) {
-				/* If we are changing to bad context then remove
-				 * the dwords we copied for this sequence from
-				 * the good buffer */
-				good_rb_idx = good_cmd_start_idx;
+
+				/* If we are changing back to a bad context
+				 * from good ctxt and were not copying commands
+				 * to bad ctxt then copy over commands to
+				 * the bad context */
+				for (temp_idx = cmd_start_idx;
+					temp_idx < temp_rb_idx;
+					temp_idx++)
+					bad_rb_buffer[bad_rb_idx++] =
+						temp_rb_buffer[temp_idx];
+				/* If we are changing to bad context then
+				 * remove the dwords we copied for this
+				 * sequence from the good buffer */
+				good_rb_idx = last_good_cmd_end_idx;
 				copy_rb_contents = 0;
 			}
 			}
 		}
 
 		if (copy_rb_contents)
-			temp_rb_buffer[good_rb_idx++] = val1;
-		/* Copy both good and bad commands for replay to the bad
-		 * buffer */
-		bad_rb_buffer[bad_rb_idx++] = val1;
+			good_rb_buffer[good_rb_idx++] = val1;
+		else
+			bad_rb_buffer[bad_rb_idx++] = val1;
+
+		/* Copy both good and bad commands to temp buffer */
+		temp_rb_buffer[temp_rb_idx++] = val1;
 
 		rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr, size);
 	}
-	*rb_size = good_rb_idx;
+	*good_rb_size = good_rb_idx;
 	*bad_rb_size = bad_rb_idx;
-}
-
-int adreno_ringbuffer_extract(struct adreno_ringbuffer *rb,
-				struct adreno_recovery_data *rec_data)
-{
-	int status;
-	struct kgsl_device *device = rb->device;
-	unsigned int rb_rptr = rb->wptr * sizeof(unsigned int);
-	struct kgsl_context *context;
-	struct adreno_context *adreno_context;
-
-	context = idr_find(&device->context_idr, rec_data->context_id);
-
-	/* Look for the command stream that is right after the global eop */
-	status = _find_cmd_seq_after_eop_ts(rb, &rb_rptr,
-				rec_data->global_eop + 1, false);
-	if (status)
-		goto done;
-
-	if (context) {
-		adreno_context = context->devctxt;
-
-		if (adreno_context->flags & CTXT_FLAGS_PREAMBLE) {
-			if (rec_data->ib1) {
-				status = _find_hanging_ib_sequence(rb, &rb_rptr,
-								rec_data->ib1);
-				if (status)
-					goto copy_rb_contents;
-			}
-			_turn_preamble_on_for_ib_seq(rb, rb_rptr);
-		} else {
-			status = -EINVAL;
-		}
-	}
-
-copy_rb_contents:
-	_copy_valid_rb_content(rb, rb_rptr, rec_data->rb_buffer,
-				&rec_data->rb_size,
-				rec_data->bad_rb_buffer,
-				&rec_data->bad_rb_size,
-				&rec_data->last_valid_ctx_id);
-	/* If we failed to get the hanging IB sequence then we cannot execute
-	 * commands from the bad context or preambles not supported */
-	if (status) {
-		rec_data->bad_rb_size = 0;
-		status = 0;
-	}
-	/* If there is no context then that means there are no commands for
-	 * good case */
-	if (!context)
-		rec_data->rb_size = 0;
-done:
-	return status;
+	*rb_size = temp_rb_idx;
 }
 
 void
diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h
index 50d9c25..fa03c05 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.h
+++ b/drivers/gpu/msm/adreno_ringbuffer.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2013, The Linux Foundation. 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 and
@@ -27,7 +27,7 @@
 
 struct kgsl_device;
 struct kgsl_device_private;
-struct adreno_recovery_data;
+struct adreno_ft_data;
 
 #define GSL_RB_MEMPTRS_SCRATCH_COUNT	 8
 struct kgsl_rbmemptrs {
@@ -110,17 +110,12 @@
 					unsigned int *cmdaddr,
 					int sizedwords);
 
-void adreno_ringbuffer_issuecmds_intr(struct kgsl_device *device,
-					struct kgsl_context *k_ctxt,
-					unsigned int *cmdaddr,
-					int sizedwords);
-
 void adreno_ringbuffer_submit(struct adreno_ringbuffer *rb);
 
 void kgsl_cp_intrcallback(struct kgsl_device *device);
 
-int adreno_ringbuffer_extract(struct adreno_ringbuffer *rb,
-				struct adreno_recovery_data *rec_data);
+void adreno_ringbuffer_extract(struct adreno_ringbuffer *rb,
+				struct adreno_ft_data *ft_data);
 
 void
 adreno_ringbuffer_restore(struct adreno_ringbuffer *rb, unsigned int *rb_buff,
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index 08a01b0..f23586e 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -177,10 +177,11 @@
 	{ 8, 2 },
 };
 
-static void ib_parse_load_state(struct kgsl_device *device, unsigned int *pkt,
+static int ib_parse_load_state(struct kgsl_device *device, unsigned int *pkt,
 	unsigned int ptbase)
 {
 	unsigned int block, source, type;
+	int ret = 0;
 
 	/*
 	 * The object here is to find indirect shaders i.e - shaders loaded from
@@ -192,7 +193,7 @@
 	 */
 
 	if (type3_pkt_size(pkt[0]) < 2)
-		return;
+		return 0;
 
 	/*
 	 * pkt[1] 18:16 - source
@@ -220,8 +221,14 @@
 				pkt[2] & 0xFFFFFFFC,
 				(((pkt[1] >> 22) & 0x03FF) * unitsize) << 2,
 				SNAPSHOT_GPU_OBJECT_SHADER);
+
+		if (ret < 0)
+			return -EINVAL;
+
 		snapshot_frozen_objsize += ret;
 	}
+
+	return ret;
 }
 
 /*
@@ -229,23 +236,31 @@
  * visiblity stream size buffer.
  */
 
-static void ib_parse_set_bin_data(struct kgsl_device *device, unsigned int *pkt,
+static int ib_parse_set_bin_data(struct kgsl_device *device, unsigned int *pkt,
 	unsigned int ptbase)
 {
 	int ret;
 
 	if (type3_pkt_size(pkt[0]) < 2)
-		return;
+		return 0;
 
 	/* Visiblity stream buffer */
 	ret = kgsl_snapshot_get_object(device, ptbase, pkt[1], 0,
 			SNAPSHOT_GPU_OBJECT_GENERIC);
+
+	if (ret < 0)
+		return -EINVAL;
+
 	snapshot_frozen_objsize += ret;
 
 	/* visiblity stream size buffer (fixed size 8 dwords) */
 	ret = kgsl_snapshot_get_object(device, ptbase, pkt[2], 32,
 			SNAPSHOT_GPU_OBJECT_GENERIC);
-	snapshot_frozen_objsize += ret;
+
+	if (ret >= 0)
+		snapshot_frozen_objsize += ret;
+
+	return ret;
 }
 
 /*
@@ -254,13 +269,13 @@
  * buffers that are written to as frozen
  */
 
-static void ib_parse_mem_write(struct kgsl_device *device, unsigned int *pkt,
+static int ib_parse_mem_write(struct kgsl_device *device, unsigned int *pkt,
 	unsigned int ptbase)
 {
 	int ret;
 
 	if (type3_pkt_size(pkt[0]) < 1)
-		return;
+		return 0;
 
 	/*
 	 * The address is where the data in the rest of this packet is written
@@ -272,7 +287,10 @@
 	ret = kgsl_snapshot_get_object(device, ptbase, pkt[1] & 0xFFFFFFFC, 0,
 		SNAPSHOT_GPU_OBJECT_GENERIC);
 
-	snapshot_frozen_objsize += ret;
+	if (ret >= 0)
+		snapshot_frozen_objsize += ret;
+
+	return ret;
 }
 
 /*
@@ -282,19 +300,22 @@
  * frozen with the others
  */
 
-static void ib_parse_draw_indx(struct kgsl_device *device, unsigned int *pkt,
+static int ib_parse_draw_indx(struct kgsl_device *device, unsigned int *pkt,
 	unsigned int ptbase)
 {
-	int ret, i;
+	int ret = 0, i;
 
 	if (type3_pkt_size(pkt[0]) < 3)
-		return;
+		return 0;
 
 	/*  DRAW_IDX may have a index buffer pointer */
 
 	if (type3_pkt_size(pkt[0]) > 3) {
 		ret = kgsl_snapshot_get_object(device, ptbase, pkt[4], pkt[5],
 			SNAPSHOT_GPU_OBJECT_GENERIC);
+		if (ret < 0)
+			return -EINVAL;
+
 		snapshot_frozen_objsize += ret;
 	}
 
@@ -310,6 +331,9 @@
 			ret = kgsl_snapshot_get_object(device, ptbase,
 				vsc_pipe[i].base, vsc_pipe[i].size,
 				SNAPSHOT_GPU_OBJECT_GENERIC);
+			if (ret < 0)
+				return -EINVAL;
+
 			snapshot_frozen_objsize += ret;
 		}
 	}
@@ -320,6 +344,9 @@
 		ret = kgsl_snapshot_get_object(device, ptbase,
 				vsc_size_address, 32,
 				SNAPSHOT_GPU_OBJECT_GENERIC);
+		if (ret < 0)
+			return -EINVAL;
+
 		snapshot_frozen_objsize += ret;
 	}
 
@@ -328,15 +355,22 @@
 		ret = kgsl_snapshot_get_object(device, ptbase,
 				sp_vs_pvt_mem_addr, 8192,
 				SNAPSHOT_GPU_OBJECT_GENERIC);
+		if (ret < 0)
+			return -EINVAL;
 
 		snapshot_frozen_objsize += ret;
+		sp_vs_pvt_mem_addr = 0;
 	}
 
 	if (sp_fs_pvt_mem_addr) {
 		ret = kgsl_snapshot_get_object(device, ptbase,
 				sp_fs_pvt_mem_addr, 8192,
 				SNAPSHOT_GPU_OBJECT_GENERIC);
+		if (ret < 0)
+			return -EINVAL;
+
 		snapshot_frozen_objsize += ret;
+		sp_fs_pvt_mem_addr = 0;
 	}
 
 	/* Finally: VBOs */
@@ -357,9 +391,20 @@
 			ret = kgsl_snapshot_get_object(device, ptbase,
 				vbo[i].base,
 				0, SNAPSHOT_GPU_OBJECT_GENERIC);
+			if (ret < 0)
+				return -EINVAL;
+
 			snapshot_frozen_objsize += ret;
 		}
+
+		vbo[i].base = 0;
+		vbo[i].stride = 0;
 	}
+
+	vfd_control_0 = 0;
+	vfd_index_max = 0;
+
+	return ret;
 }
 
 /*
@@ -367,23 +412,21 @@
  * such as additional GPU buffers to grab or a draw initator
  */
 
-static void ib_parse_type3(struct kgsl_device *device, unsigned int *ptr,
+static int ib_parse_type3(struct kgsl_device *device, unsigned int *ptr,
 	unsigned int ptbase)
 {
-	switch (cp_type3_opcode(*ptr)) {
-	case CP_LOAD_STATE:
-		ib_parse_load_state(device, ptr, ptbase);
-		break;
-	case CP_SET_BIN_DATA:
-		ib_parse_set_bin_data(device, ptr, ptbase);
-		break;
-	case CP_MEM_WRITE:
-		ib_parse_mem_write(device, ptr, ptbase);
-		break;
-	case CP_DRAW_INDX:
-		ib_parse_draw_indx(device, ptr, ptbase);
-		break;
-	}
+	int opcode = cp_type3_opcode(*ptr);
+
+	if (opcode == CP_LOAD_STATE)
+		return ib_parse_load_state(device, ptr, ptbase);
+	else if (opcode == CP_SET_BIN_DATA)
+		return ib_parse_set_bin_data(device, ptr, ptbase);
+	else if (opcode == CP_MEM_WRITE)
+		return ib_parse_mem_write(device, ptr, ptbase);
+	else if (opcode == CP_DRAW_INDX)
+		return ib_parse_draw_indx(device, ptr, ptbase);
+
+	return 0;
 }
 
 /*
@@ -469,33 +512,80 @@
 
 /* Add an IB as a GPU object, but first, parse it to find more goodies within */
 
-static void ib_add_gpu_object(struct kgsl_device *device, unsigned int ptbase,
+static int ib_add_gpu_object(struct kgsl_device *device, unsigned int ptbase,
 		unsigned int gpuaddr, unsigned int dwords)
 {
 	int i, ret, rem = dwords;
-	unsigned int *src = (unsigned int *) adreno_convertaddr(device, ptbase,
-		gpuaddr, dwords << 2);
+	unsigned int *src;
+
+	/*
+	 * If the object is already in the list, we don't need to parse it again
+	 */
+
+	if (kgsl_snapshot_have_object(device, ptbase, gpuaddr, dwords << 2))
+		return 0;
+
+	src = (unsigned int *) adreno_convertaddr(device, ptbase, gpuaddr,
+		dwords << 2);
 
 	if (src == NULL)
-		return;
+		return -EINVAL;
 
-	for (i = 0; rem != 0; rem--, i++) {
+	for (i = 0; rem > 0; rem--, i++) {
 		int pktsize;
 
+		/* If the packet isn't a type 1 or a type 3, then don't bother
+		 * parsing it - it is likely corrupted */
+
 		if (!pkt_is_type0(src[i]) && !pkt_is_type3(src[i]))
-			continue;
+			break;
 
 		pktsize = type3_pkt_size(src[i]);
 
-		if ((pktsize + 1) > rem)
+		if (!pktsize || (pktsize + 1) > rem)
 			break;
 
 		if (pkt_is_type3(src[i])) {
-			if (adreno_cmd_is_ib(src[i]))
-				ib_add_gpu_object(device, ptbase,
-					src[i + 1], src[i + 2]);
-			else
-				ib_parse_type3(device, &src[i], ptbase);
+			if (adreno_cmd_is_ib(src[i])) {
+				unsigned int gpuaddr = src[i + 1];
+				unsigned int size = src[i + 2];
+				unsigned int ibbase;
+
+				/* Address of the last processed IB2 */
+				kgsl_regread(device, REG_CP_IB2_BASE, &ibbase);
+
+				/*
+				 * If this is the last IB2 that was executed,
+				 * then push it to make sure it goes into the
+				 * static space
+				 */
+
+				if (ibbase == gpuaddr)
+					push_object(device,
+						SNAPSHOT_OBJ_TYPE_IB, ptbase,
+						gpuaddr, size);
+				else {
+					ret = ib_add_gpu_object(device,
+						ptbase, gpuaddr, size);
+
+					/*
+					 * If adding the IB failed then stop
+					 * parsing
+					 */
+					if (ret < 0)
+						goto done;
+				}
+			} else {
+				ret = ib_parse_type3(device, &src[i], ptbase);
+				/*
+				 * If the parse function failed (probably
+				 * because of a bad decode) then bail out and
+				 * just capture the binary IB data
+				 */
+
+				if (ret < 0)
+					goto done;
+			}
 		} else if (pkt_is_type0(src[i])) {
 			ib_parse_type0(device, &src[i], ptbase);
 		}
@@ -504,10 +594,14 @@
 		rem -= pktsize;
 	}
 
+done:
 	ret = kgsl_snapshot_get_object(device, ptbase, gpuaddr, dwords << 2,
 		SNAPSHOT_GPU_OBJECT_IB);
 
-	snapshot_frozen_objsize += ret;
+	if (ret >= 0)
+		snapshot_frozen_objsize += ret;
+
+	return ret;
 }
 
 /* Snapshot the istore memory */
@@ -650,27 +744,11 @@
 		*data = rbptr[index];
 
 		/*
-		 * Sometimes the rptr is located in the middle of a packet.
-		 * try to adust for that by modifying the rptr to match a
-		 * packet boundary. Unfortunately for us, it is hard to tell
-		 * which dwords are legitimate type0 header and which are just
-		 * random data so only do the adjustments for type3 packets
-		 */
-
-		if (pkt_is_type3(rbptr[index])) {
-			unsigned int pktsize =
-				type3_pkt_size(rbptr[index]);
-			if (index +  pktsize > rptr)
-				rptr = (index + pktsize) %
-					rb->sizedwords;
-		}
-
-		/*
 		 * Only parse IBs between the start and the rptr or the next
 		 * context switch, whichever comes first
 		 */
 
-		if (index == ib_parse_start)
+		if (parse_ibs == 0 && index == ib_parse_start)
 			parse_ibs = 1;
 		else if (index == rptr || adreno_rb_ctxtswitch(&rbptr[index]))
 			parse_ibs = 0;
@@ -729,7 +807,7 @@
 	struct kgsl_snapshot_obj *obj = priv;
 	unsigned int *src = obj->ptr;
 	unsigned int *dst = snapshot + sizeof(*header);
-	int i;
+	int i, ret;
 
 	if (remain < (obj->dwords << 2) + sizeof(*header)) {
 		KGSL_DRV_ERR(device,
@@ -753,8 +831,13 @@
 			if (adreno_cmd_is_ib(*src))
 				push_object(device, SNAPSHOT_OBJ_TYPE_IB,
 					obj->ptbase, src[1], src[2]);
-			else
-				ib_parse_type3(device, src, obj->ptbase);
+			else {
+				ret = ib_parse_type3(device, src, obj->ptbase);
+
+				/* Stop parsing if the type3 decode fails */
+				if (ret < 0)
+					break;
+			}
 		}
 	}
 
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 460cf01..324dc5c 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
@@ -52,155 +52,6 @@
 
 static struct ion_client *kgsl_ion_client;
 
-/**
- * kgsl_add_event - Add a new timstamp event for the KGSL device
- * @device - KGSL device for the new event
- * @ts - the timestamp to trigger the event on
- * @cb - callback function to call when the timestamp expires
- * @priv - private data for the specific event type
- * @owner - driver instance that owns this event
- *
- * @returns - 0 on success or error code on failure
- */
-
-int kgsl_add_event(struct kgsl_device *device, u32 id, u32 ts,
-	void (*cb)(struct kgsl_device *, void *, u32, u32), void *priv,
-	void *owner)
-{
-	struct kgsl_event *event;
-	struct list_head *n;
-	unsigned int cur_ts;
-	struct kgsl_context *context = NULL;
-
-	if (cb == NULL)
-		return -EINVAL;
-
-	if (id != KGSL_MEMSTORE_GLOBAL) {
-		context = idr_find(&device->context_idr, id);
-		if (context == NULL)
-			return -EINVAL;
-	}
-	cur_ts = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
-
-	/* Check to see if the requested timestamp has already fired */
-
-	if (timestamp_cmp(cur_ts, ts) >= 0) {
-		cb(device, priv, id, cur_ts);
-		return 0;
-	}
-
-	event = kzalloc(sizeof(*event), GFP_KERNEL);
-	if (event == NULL)
-		return -ENOMEM;
-
-	event->context = context;
-	event->timestamp = ts;
-	event->priv = priv;
-	event->func = cb;
-	event->owner = owner;
-
-	/* inc refcount to avoid race conditions in cleanup */
-	if (context)
-		kgsl_context_get(context);
-
-	/*
-	 * Add the event in order to the list.  Order is by context id
-	 * first and then by timestamp for that context.
-	 */
-
-	for (n = device->events.next ; n != &device->events; n = n->next) {
-		struct kgsl_event *e =
-			list_entry(n, struct kgsl_event, list);
-
-		if (e->context != context)
-			continue;
-
-		if (timestamp_cmp(e->timestamp, ts) > 0) {
-			list_add(&event->list, n->prev);
-			break;
-		}
-	}
-
-	if (n == &device->events)
-		list_add_tail(&event->list, &device->events);
-
-	queue_work(device->work_queue, &device->ts_expired_ws);
-	return 0;
-}
-EXPORT_SYMBOL(kgsl_add_event);
-
-/**
- * kgsl_cancel_events_ctxt - Cancel all events for a context
- * @device - KGSL device for the events to cancel
- * @ctxt - context whose events we want to cancel
- *
- */
-static void kgsl_cancel_events_ctxt(struct kgsl_device *device,
-	struct kgsl_context *context)
-{
-	struct kgsl_event *event, *event_tmp;
-	unsigned int id, cur;
-
-	cur = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
-	id = context->id;
-
-	list_for_each_entry_safe(event, event_tmp, &device->events, list) {
-		if (event->context != context)
-			continue;
-
-		/*
-		 * "cancel" the events by calling their callback.
-		 * Currently, events are used for lock and memory
-		 * management, so if the process is dying the right
-		 * thing to do is release or free.
-		 */
-		if (event->func)
-			event->func(device, event->priv, id, cur);
-
-		kgsl_context_put(context);
-		list_del(&event->list);
-		kfree(event);
-	}
-}
-
-/**
- * kgsl_cancel_events - Cancel all events for a process
- * @device - KGSL device for the events to cancel
- * @owner - driver instance that owns the events to cancel
- *
- */
-void kgsl_cancel_events(struct kgsl_device *device,
-	void *owner)
-{
-	struct kgsl_event *event, *event_tmp;
-	unsigned int id, cur;
-
-	list_for_each_entry_safe(event, event_tmp, &device->events, list) {
-		if (event->owner != owner)
-			continue;
-
-		cur = kgsl_readtimestamp(device, event->context,
-					 KGSL_TIMESTAMP_RETIRED);
-
-		id = event->context ? event->context->id : KGSL_MEMSTORE_GLOBAL;
-		/*
-		 * "cancel" the events by calling their callback.
-		 * Currently, events are used for lock and memory
-		 * management, so if the process is dying the right
-		 * thing to do is release or free.
-		 */
-		if (event->func)
-			event->func(device, event->priv, id, cur);
-
-		if (event->context)
-			kgsl_context_put(event->context);
-
-		list_del(&event->list);
-		kfree(event);
-	}
-}
-EXPORT_SYMBOL(kgsl_cancel_events);
-
 /* kgsl_get_mem_entry - get the mem_entry structure for the specified object
  * @device - Pointer to the device structure
  * @ptbase - the pagetable base of the object
@@ -379,6 +230,25 @@
 
 	if (kgsl_sync_timeline_create(context)) {
 		idr_remove(&dev_priv->device->context_idr, id);
+		goto func_end;
+	}
+
+	/* Initialize the pending event list */
+	INIT_LIST_HEAD(&context->events);
+
+	/*
+	 * Initialize the node that is used to maintain the master list of
+	 * contexts with pending events in the device structure. Normally we
+	 * wouldn't take the time to initalize a node but at event add time we
+	 * call list_empty() on the node as a quick way of determining if the
+	 * context is already in the master list so it needs to always be either
+	 * active or in an unused but initialized state
+	 */
+
+	INIT_LIST_HEAD(&context->events_list);
+
+func_end:
+	if (ret) {
 		kfree(context);
 		return NULL;
 	}
@@ -431,55 +301,6 @@
 	kfree(context);
 }
 
-void kgsl_timestamp_expired(struct work_struct *work)
-{
-	struct kgsl_device *device = container_of(work, struct kgsl_device,
-		ts_expired_ws);
-	struct kgsl_event *event, *event_tmp;
-	uint32_t ts_processed;
-	unsigned int id;
-
-	mutex_lock(&device->mutex);
-
-	/* Process expired events */
-	list_for_each_entry_safe(event, event_tmp, &device->events, list) {
-		ts_processed = kgsl_readtimestamp(device, event->context,
-						  KGSL_TIMESTAMP_RETIRED);
-		if (timestamp_cmp(ts_processed, event->timestamp) < 0)
-			continue;
-
-		id = event->context ? event->context->id : KGSL_MEMSTORE_GLOBAL;
-
-		if (event->func)
-			event->func(device, event->priv, id, ts_processed);
-
-		if (event->context)
-			kgsl_context_put(event->context);
-
-		list_del(&event->list);
-		kfree(event);
-	}
-
-	/* Send the next pending event for each context to the device */
-	if (device->ftbl->next_event) {
-		unsigned int id = KGSL_MEMSTORE_GLOBAL;
-
-		list_for_each_entry(event, &device->events, list) {
-
-			if (!event->context)
-				continue;
-
-			if (event->context->id != id) {
-				device->ftbl->next_event(device, event);
-				id = event->context->id;
-			}
-		}
-	}
-
-	mutex_unlock(&device->mutex);
-}
-EXPORT_SYMBOL(kgsl_timestamp_expired);
-
 static void kgsl_check_idle_locked(struct kgsl_device *device)
 {
 	if (device->pwrctrl.nap_allowed == true &&
@@ -1082,10 +903,7 @@
 				      result);
 
 	/* Fire off any pending suspend operations that are in flight */
-
-	INIT_COMPLETION(dev_priv->device->suspend_gate);
-	dev_priv->device->active_cnt--;
-	complete(&dev_priv->device->suspend_gate);
+	kgsl_active_count_put(dev_priv->device);
 
 	return result;
 }
@@ -1109,11 +927,8 @@
 	int result;
 
 	context = kgsl_find_context(dev_priv, param->context_id);
-	if (context == NULL) {
-		KGSL_DRV_ERR(dev_priv->device, "invalid context_id %d\n",
-			param->context_id);
+	if (context == NULL)
 		return -EINVAL;
-	}
 	/*
 	 * A reference count is needed here, because waittimestamp may
 	 * block with the device mutex unlocked and userspace could
@@ -1137,9 +952,6 @@
 	context = kgsl_find_context(dev_priv, param->drawctxt_id);
 	if (context == NULL) {
 		result = -EINVAL;
-		KGSL_DRV_ERR(dev_priv->device,
-			"invalid context_id %d\n",
-			param->drawctxt_id);
 		goto done;
 	}
 
@@ -1250,11 +1062,9 @@
 	struct kgsl_context *context;
 
 	context = kgsl_find_context(dev_priv, param->context_id);
-	if (context == NULL) {
-		KGSL_DRV_ERR(dev_priv->device, "invalid context_id %d\n",
-			param->context_id);
+	if (context == NULL)
 		return -EINVAL;
-	}
+
 
 	return _cmdstream_readtimestamp(dev_priv, context,
 			param->type, &param->timestamp);
@@ -2592,18 +2402,17 @@
 			kgsl_idle(device);
 
 	}
-	KGSL_LOG_DUMP(device, "|%s| Dump Started\n", device->name);
-	KGSL_LOG_DUMP(device, "POWER: FLAGS = %08lX | ACTIVE POWERLEVEL = %08X",
-			pwr->power_flags, pwr->active_pwrlevel);
 
-	KGSL_LOG_DUMP(device, "POWER: INTERVAL TIMEOUT = %08X ",
-		pwr->interval_timeout);
+	if (device->pm_dump_enable) {
 
-	KGSL_LOG_DUMP(device, "GRP_CLK = %lu ",
-				  kgsl_get_clkrate(pwr->grp_clks[0]));
+		KGSL_LOG_DUMP(device,
+				"POWER: FLAGS = %08lX | ACTIVE POWERLEVEL = %08X",
+				pwr->power_flags, pwr->active_pwrlevel);
 
-	KGSL_LOG_DUMP(device, "BUS CLK = %lu ",
-		kgsl_get_clkrate(pwr->ebi1_clk));
+		KGSL_LOG_DUMP(device, "POWER: INTERVAL TIMEOUT = %08X ",
+				pwr->interval_timeout);
+
+	}
 
 	/* Disable the idle timer so we don't get interrupted */
 	del_timer_sync(&device->idle_timer);
@@ -2631,7 +2440,7 @@
 	/* On a manual trigger, turn on the interrupts and put
 	   the clocks to sleep.  They will recover themselves
 	   on the next event.  For a hang, leave things as they
-	   are until recovery kicks in. */
+	   are until fault tolerance kicks in. */
 
 	if (manual) {
 		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
@@ -2641,8 +2450,6 @@
 		kgsl_pwrctrl_sleep(device);
 	}
 
-	KGSL_LOG_DUMP(device, "|%s| Dump Finished\n", device->name);
-
 	return 0;
 }
 EXPORT_SYMBOL(kgsl_postmortem_dump);
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 72a251a..3935164 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. 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 and
@@ -72,6 +72,7 @@
 	do { _stat += (_size); if (_stat > _max) _max = _stat; } while (0)
 
 struct kgsl_device;
+struct kgsl_context;
 
 struct kgsl_driver {
 	struct cdev cdev;
@@ -195,6 +196,9 @@
 void kgsl_cancel_events(struct kgsl_device *device,
 	void *owner);
 
+void kgsl_cancel_events_ctxt(struct kgsl_device *device,
+	struct kgsl_context *context);
+
 extern const struct dev_pm_ops kgsl_pm_ops;
 
 struct early_suspend;
diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c
index 4e354d0..e06c94d 100644
--- a/drivers/gpu/msm/kgsl_cffdump.c
+++ b/drivers/gpu/msm/kgsl_cffdump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_cffdump.h b/drivers/gpu/msm/kgsl_cffdump.h
index 140e486..2733cc3 100644
--- a/drivers/gpu/msm/kgsl_cffdump.h
+++ b/drivers/gpu/msm/kgsl_cffdump.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c
index 52097dc..b41bd6b 100644
--- a/drivers/gpu/msm/kgsl_debugfs.c
+++ b/drivers/gpu/msm/kgsl_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-2012, The Linux Foundation. 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 and
@@ -70,6 +70,20 @@
 	return 0;
 }
 
+static int pm_enabled_set(void *data, u64 val)
+{
+	struct kgsl_device *device = data;
+	device->pm_dump_enable = val;
+	return 0;
+}
+
+static int pm_enabled_get(void *data, u64 *val)
+{
+	struct kgsl_device *device = data;
+	*val = device->pm_dump_enable;
+	return 0;
+}
+
 
 DEFINE_SIMPLE_ATTRIBUTE(pm_regs_enabled_fops,
 			pm_regs_enabled_get,
@@ -79,6 +93,10 @@
 			pm_ib_enabled_get,
 			pm_ib_enabled_set, "%llu\n");
 
+DEFINE_SIMPLE_ATTRIBUTE(pm_enabled_fops,
+			pm_enabled_get,
+			pm_enabled_set, "%llu\n");
+
 static inline int kgsl_log_set(unsigned int *log_val, void *data, u64 val)
 {
 	*log_val = min((unsigned int)val, (unsigned int)KGSL_LOG_LEVEL_MAX);
@@ -105,6 +123,7 @@
 KGSL_DEBUGFS_LOG(ctxt_log);
 KGSL_DEBUGFS_LOG(mem_log);
 KGSL_DEBUGFS_LOG(pwr_log);
+KGSL_DEBUGFS_LOG(ft_log);
 
 void kgsl_device_debugfs_init(struct kgsl_device *device)
 {
@@ -120,6 +139,7 @@
 	device->drv_log = KGSL_LOG_LEVEL_DEFAULT;
 	device->mem_log = KGSL_LOG_LEVEL_DEFAULT;
 	device->pwr_log = KGSL_LOG_LEVEL_DEFAULT;
+	device->ft_log = KGSL_LOG_LEVEL_DEFAULT;
 
 	debugfs_create_file("log_level_cmd", 0644, device->d_debugfs, device,
 			    &cmd_log_fops);
@@ -131,6 +151,8 @@
 				&mem_log_fops);
 	debugfs_create_file("log_level_pwr", 0644, device->d_debugfs, device,
 				&pwr_log_fops);
+	debugfs_create_file("log_level_ft", 0644, device->d_debugfs, device,
+				&ft_log_fops);
 
 	/* Create postmortem dump control files */
 
@@ -145,6 +167,9 @@
 			    &pm_regs_enabled_fops);
 	debugfs_create_file("ib_enabled", 0644, pm_d_debugfs, device,
 				    &pm_ib_enabled_fops);
+	device->pm_dump_enable = 0;
+	debugfs_create_file("enable", 0644, pm_d_debugfs, device,
+				    &pm_enabled_fops);
 
 }
 
diff --git a/drivers/gpu/msm/kgsl_debugfs.h b/drivers/gpu/msm/kgsl_debugfs.h
index 898c4e9..ae5601f 100644
--- a/drivers/gpu/msm/kgsl_debugfs.h
+++ b/drivers/gpu/msm/kgsl_debugfs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-2011, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 97345fe..b215d8c 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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 and
@@ -24,9 +24,10 @@
 #include "kgsl_pwrscale.h"
 #include <linux/sync.h>
 
-#define KGSL_TIMEOUT_NONE       0
-#define KGSL_TIMEOUT_DEFAULT    0xFFFFFFFF
-#define KGSL_TIMEOUT_PART       50 /* 50 msec */
+#define KGSL_TIMEOUT_NONE           0
+#define KGSL_TIMEOUT_DEFAULT        0xFFFFFFFF
+#define KGSL_TIMEOUT_PART           50 /* 50 msec */
+#define KGSL_TIMEOUT_LONG_IB_DETECTION  2000 /* 2 sec*/
 
 #define FIRST_TIMEOUT (HZ / 2)
 
@@ -46,7 +47,7 @@
 #define KGSL_STATE_SLEEP	0x00000008
 #define KGSL_STATE_SUSPEND	0x00000010
 #define KGSL_STATE_HUNG		0x00000020
-#define KGSL_STATE_DUMP_AND_RECOVER	0x00000040
+#define KGSL_STATE_DUMP_AND_FT	0x00000040
 #define KGSL_STATE_SLUMBER	0x00000080
 
 #define KGSL_GRAPHICS_MEMORY_LOW_WATERMARK  0x1000000
@@ -113,7 +114,7 @@
 		enum kgsl_property_type type, void *value,
 		unsigned int sizebytes);
 	int (*postmortem_dump) (struct kgsl_device *device, int manual);
-	void (*next_event)(struct kgsl_device *device,
+	int (*next_event)(struct kgsl_device *device,
 		struct kgsl_event *event);
 };
 
@@ -133,6 +134,7 @@
 	void *priv;
 	struct list_head list;
 	void *owner;
+	unsigned int created;
 };
 
 
@@ -169,7 +171,7 @@
 	wait_queue_head_t wait_queue;
 	struct workqueue_struct *work_queue;
 	struct device *parentdev;
-	struct completion recovery_gate;
+	struct completion ft_gate;
 	struct dentry *d_debugfs;
 	struct idr context_idr;
 	struct early_suspend display_off;
@@ -195,11 +197,14 @@
 	int drv_log;
 	int mem_log;
 	int pwr_log;
+	int ft_log;
+	int pm_dump_enable;
 	struct kgsl_pwrscale pwrscale;
 	struct kobject pwrscale_kobj;
 	struct pm_qos_request pm_qos_req_dma;
 	struct work_struct ts_expired_ws;
 	struct list_head events;
+	struct list_head events_pending_list;
 	s64 on_time;
 
 	/* Postmortem Control switches */
@@ -207,46 +212,53 @@
 	int pm_ib_enabled;
 };
 
-void kgsl_timestamp_expired(struct work_struct *work);
+void kgsl_process_events(struct work_struct *work);
+void kgsl_check_fences(struct work_struct *work);
 
 #define KGSL_DEVICE_COMMON_INIT(_dev) \
 	.hwaccess_gate = COMPLETION_INITIALIZER((_dev).hwaccess_gate),\
 	.suspend_gate = COMPLETION_INITIALIZER((_dev).suspend_gate),\
-	.recovery_gate = COMPLETION_INITIALIZER((_dev).recovery_gate),\
+	.ft_gate = COMPLETION_INITIALIZER((_dev).ft_gate),\
 	.ts_notifier_list = ATOMIC_NOTIFIER_INIT((_dev).ts_notifier_list),\
 	.idle_check_ws = __WORK_INITIALIZER((_dev).idle_check_ws,\
 			kgsl_idle_check),\
 	.ts_expired_ws  = __WORK_INITIALIZER((_dev).ts_expired_ws,\
-			kgsl_timestamp_expired),\
+			kgsl_process_events),\
 	.context_idr = IDR_INIT((_dev).context_idr),\
 	.events = LIST_HEAD_INIT((_dev).events),\
+	.events_pending_list = LIST_HEAD_INIT((_dev).events_pending_list), \
 	.wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).wait_queue),\
 	.mutex = __MUTEX_INITIALIZER((_dev).mutex),\
 	.state = KGSL_STATE_INIT,\
 	.ver_major = DRIVER_VERSION_MAJOR,\
 	.ver_minor = DRIVER_VERSION_MINOR
 
+
+/**
+ * struct kgsl_context - Master structure for a KGSL context object
+ * @refcount - kref object for reference counting the context
+ * @id - integer identifier for the context
+ * @dev_priv - pointer to the owning device instance
+ * @devctxt - pointer to the device specific context information
+ * @reset_status - status indication whether a gpu reset occured and whether
+ * this context was responsible for causing it
+ * @wait_on_invalid_ts - flag indicating if this context has tried to wait on a
+ * bad timestamp
+ * @timeline - sync timeline used to create fences that can be signaled when a
+ * sync_pt timestamp expires
+ * @events - list head of pending events for this context
+ * @events_list - list node for the list of all contexts that have pending events
+ */
 struct kgsl_context {
 	struct kref refcount;
 	uint32_t id;
-
-	/* Pointer to the owning device instance */
 	struct kgsl_device_private *dev_priv;
-
-	/* Pointer to the device specific context information */
 	void *devctxt;
-	/*
-	 * Status indicating whether a gpu reset occurred and whether this
-	 * context was responsible for causing it
-	 */
 	unsigned int reset_status;
-	/* Flag indicating if we tried to wait for bad timestamp for this ctx */
 	bool wait_on_invalid_ts;
-	/*
-	 * Timeline used to create fences that can be signaled when a
-	 * sync_pt timestamp expires.
-	 */
 	struct sync_timeline *timeline;
+	struct list_head events;
+	struct list_head events_list;
 };
 
 struct kgsl_process_private {
@@ -432,4 +444,23 @@
 	kref_put(&context->refcount, kgsl_context_destroy);
 }
 
+/**
+ * kgsl_active_count_put - Decrease the device active count
+ * @device: Pointer to a KGSL device
+ *
+ * Decrease the active count for the KGSL device and trigger the suspend_gate
+ * completion if it hits zero
+ */
+static inline void
+kgsl_active_count_put(struct kgsl_device *device)
+{
+	if (device->active_cnt == 1)
+		INIT_COMPLETION(device->suspend_gate);
+
+	device->active_cnt--;
+
+	if (device->active_cnt == 0)
+		complete(&device->suspend_gate);
+}
+
 #endif  /* __KGSL_DEVICE_H */
diff --git a/drivers/gpu/msm/kgsl_drm.c b/drivers/gpu/msm/kgsl_drm.c
index 2003098..2a5a5fa 100644
--- a/drivers/gpu/msm/kgsl_drm.c
+++ b/drivers/gpu/msm/kgsl_drm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_events.c b/drivers/gpu/msm/kgsl_events.c
new file mode 100644
index 0000000..9e9c0da
--- /dev/null
+++ b/drivers/gpu/msm/kgsl_events.c
@@ -0,0 +1,322 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
+ * only 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.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <kgsl_device.h>
+
+#include "kgsl_trace.h"
+
+static void _add_event_to_list(struct list_head *head, struct kgsl_event *event)
+{
+	struct list_head *n;
+
+	for (n = head->next; n != head; n = n->next) {
+		struct kgsl_event *e =
+			list_entry(n, struct kgsl_event, list);
+
+		if (timestamp_cmp(e->timestamp, event->timestamp) > 0) {
+			list_add(&event->list, n->prev);
+			break;
+		}
+	}
+
+	if (n == head)
+		list_add_tail(&event->list, head);
+}
+
+/**
+ * kgsl_add_event - Add a new timstamp event for the KGSL device
+ * @device - KGSL device for the new event
+ * @id - the context ID that the event should be added to
+ * @ts - the timestamp to trigger the event on
+ * @cb - callback function to call when the timestamp expires
+ * @priv - private data for the specific event type
+ * @owner - driver instance that owns this event
+ *
+ * @returns - 0 on success or error code on failure
+ */
+int kgsl_add_event(struct kgsl_device *device, u32 id, u32 ts,
+	void (*cb)(struct kgsl_device *, void *, u32, u32), void *priv,
+	void *owner)
+{
+	struct kgsl_event *event;
+	unsigned int cur_ts;
+	struct kgsl_context *context = NULL;
+
+	if (cb == NULL)
+		return -EINVAL;
+
+	if (id != KGSL_MEMSTORE_GLOBAL) {
+		context = idr_find(&device->context_idr, id);
+		if (context == NULL)
+			return -EINVAL;
+	}
+	cur_ts = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
+
+	/*
+	 * Check to see if the requested timestamp has already fired.  If it
+	 * did do the callback right away.  Make sure to send the timestamp that
+	 * the event expected instead of the current timestamp because sometimes
+	 * the event handlers can get confused.
+	 */
+
+	if (timestamp_cmp(cur_ts, ts) >= 0) {
+		trace_kgsl_fire_event(id, ts, 0);
+		cb(device, priv, id, ts);
+		return 0;
+	}
+
+	event = kzalloc(sizeof(*event), GFP_KERNEL);
+	if (event == NULL)
+		return -ENOMEM;
+
+	event->context = context;
+	event->timestamp = ts;
+	event->priv = priv;
+	event->func = cb;
+	event->owner = owner;
+	event->created = jiffies;
+
+	trace_kgsl_register_event(id, ts);
+
+	/* inc refcount to avoid race conditions in cleanup */
+	if (context)
+		kgsl_context_get(context);
+
+	/* Add the event to either the owning context or the global list */
+
+	if (context) {
+		_add_event_to_list(&context->events, event);
+
+		/*
+		 * Add it to the master list of contexts with pending events if
+		 * it isn't already there
+		 */
+
+		if (list_empty(&context->events_list))
+			list_add_tail(&context->events_list,
+				&device->events_pending_list);
+
+	} else
+		_add_event_to_list(&device->events, event);
+
+	/*
+	 * Increase the active count on the device to avoid going into power
+	 * saving modes while events are pending
+	 */
+
+	device->active_cnt++;
+
+	queue_work(device->work_queue, &device->ts_expired_ws);
+	return 0;
+}
+EXPORT_SYMBOL(kgsl_add_event);
+
+/**
+ * kgsl_cancel_events_ctxt - Cancel all events for a context
+ * @device - KGSL device for the events to cancel
+ * @context - context whose events we want to cancel
+ *
+ */
+void kgsl_cancel_events_ctxt(struct kgsl_device *device,
+	struct kgsl_context *context)
+{
+	struct kgsl_event *event, *event_tmp;
+	unsigned int id, cur;
+
+	cur = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
+	id = context->id;
+
+	list_for_each_entry_safe(event, event_tmp, &context->events, list) {
+		/*
+		 * "cancel" the events by calling their callback.
+		 * Currently, events are used for lock and memory
+		 * management, so if the process is dying the right
+		 * thing to do is release or free.
+		 *
+		 * Send the current timestamp so the event knows how far the
+		 * system got before the event was canceled
+		 */
+		list_del(&event->list);
+
+		trace_kgsl_fire_event(id, cur, jiffies - event->created);
+
+		if (event->func)
+			event->func(device, event->priv, id, cur);
+
+		kgsl_context_put(context);
+		kfree(event);
+
+		kgsl_active_count_put(device);
+	}
+
+	/* Remove ourselves from the master pending list */
+	list_del_init(&context->events_list);
+}
+
+/**
+ * kgsl_cancel_events - Cancel all generic events for a process
+ * @device - KGSL device for the events to cancel
+ * @owner - driver instance that owns the events to cancel
+ *
+ */
+void kgsl_cancel_events(struct kgsl_device *device,
+	void *owner)
+{
+	struct kgsl_event *event, *event_tmp;
+	unsigned int cur;
+
+	cur = kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED);
+
+	list_for_each_entry_safe(event, event_tmp, &device->events, list) {
+		if (event->owner != owner)
+			continue;
+
+		/*
+		 * "cancel" the events by calling their callback.
+		 * Currently, events are used for lock and memory
+		 * management, so if the process is dying the right
+		 * thing to do is release or free. Send the current timestamp so
+		 * the callback knows how far the GPU made it before things went
+		 * explosion
+		 */
+		list_del(&event->list);
+
+		trace_kgsl_fire_event(KGSL_MEMSTORE_GLOBAL, cur,
+			jiffies - event->created);
+
+		if (event->func)
+			event->func(device, event->priv, KGSL_MEMSTORE_GLOBAL,
+				cur);
+
+		if (event->context)
+			kgsl_context_put(event->context);
+		kfree(event);
+
+		kgsl_active_count_put(device);
+	}
+}
+EXPORT_SYMBOL(kgsl_cancel_events);
+
+static void _process_event_list(struct kgsl_device *device,
+		struct list_head *head, unsigned int timestamp)
+{
+	struct kgsl_event *event, *tmp;
+	unsigned int id;
+
+	list_for_each_entry_safe(event, tmp, head, list) {
+		if (timestamp_cmp(timestamp, event->timestamp) < 0)
+			break;
+
+		id = event->context ? event->context->id : KGSL_MEMSTORE_GLOBAL;
+
+		/*
+		 * Send the timestamp of the expired event, not the current
+		 * timestamp.  This prevents the event handlers from getting
+		 * confused if they don't bother comparing the current timetamp
+		 * to the timestamp they wanted
+		 */
+		list_del(&event->list);
+
+		trace_kgsl_fire_event(id, event->timestamp,
+			jiffies - event->created);
+
+		if (event->func)
+			event->func(device, event->priv, id, event->timestamp);
+
+		if (event->context)
+			kgsl_context_put(event->context);
+		kfree(event);
+
+		kgsl_active_count_put(device);
+	}
+}
+
+static inline int _mark_next_event(struct kgsl_device *device,
+		struct list_head *head)
+{
+	struct kgsl_event *event;
+
+	if (!list_empty(head)) {
+		event = list_first_entry(head, struct kgsl_event, list);
+
+		/*
+		 * Next event will return 0 if the event was marked or 1 if the
+		 * timestamp on the event has passed - return that up a layer
+		 */
+
+		return device->ftbl->next_event(device, event);
+	}
+
+	return 0;
+}
+
+static int kgsl_process_context_events(struct kgsl_device *device,
+		struct kgsl_context *context)
+{
+	while (1) {
+		unsigned int timestamp = kgsl_readtimestamp(device, context,
+			KGSL_TIMESTAMP_RETIRED);
+
+		_process_event_list(device, &context->events, timestamp);
+
+		/*
+		 * _mark_next event will return 1 as long as the next event
+		 * timestamp has expired - this is to cope with an unavoidable
+		 * race condition with the GPU that is still processing events.
+		 */
+
+		if (!_mark_next_event(device, &context->events))
+			break;
+	}
+
+	/*
+	 * Return 0 if the list is empty so the calling function can remove the
+	 * context from the pending list
+	 */
+
+	return list_empty(&context->events) ? 0 : 1;
+}
+
+void kgsl_process_events(struct work_struct *work)
+{
+	struct kgsl_device *device = container_of(work, struct kgsl_device,
+		ts_expired_ws);
+	struct kgsl_context *context, *tmp;
+	uint32_t timestamp;
+
+	mutex_lock(&device->mutex);
+
+	/* Process expired global events */
+	timestamp = kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED);
+	_process_event_list(device, &device->events, timestamp);
+	_mark_next_event(device, &device->events);
+
+	/* Now process all of the pending contexts */
+	list_for_each_entry_safe(context, tmp, &device->events_pending_list,
+		events_list) {
+
+		/*
+		 * If kgsl_timestamp_expired_context returns 0 then it no longer
+		 * has any pending events and can be removed from the list
+		 */
+
+		if (kgsl_process_context_events(device, context) == 0)
+			list_del_init(&context->events_list);
+	}
+
+	mutex_unlock(&device->mutex);
+}
+EXPORT_SYMBOL(kgsl_process_events);
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index 326e79d..8f28505 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_gpummu.h b/drivers/gpu/msm/kgsl_gpummu.h
index caa5df1..99e7d5f 100644
--- a/drivers/gpu/msm/kgsl_gpummu.h
+++ b/drivers/gpu/msm/kgsl_gpummu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index bf40c04..57ccb8f 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -109,6 +109,13 @@
 	struct kgsl_iommu_unit *iommu_unit;
 	struct kgsl_iommu_device *iommu_dev;
 	unsigned int ptbase, fsr;
+	struct kgsl_device *device;
+	struct adreno_device *adreno_dev;
+	unsigned int no_page_fault_log = 0;
+	unsigned int curr_context_id = 0;
+	unsigned int curr_global_ts = 0;
+	static struct adreno_context *curr_context;
+	static struct kgsl_context *context;
 
 	ret = get_iommu_unit(dev, &mmu, &iommu_unit);
 	if (ret)
@@ -120,6 +127,8 @@
 		goto done;
 	}
 	iommu = mmu->priv;
+	device = mmu->device;
+	adreno_dev = ADRENO_DEVICE(device);
 
 	ptbase = KGSL_IOMMU_GET_CTX_REG(iommu, iommu_unit,
 					iommu_dev->ctx_id, TTBR0);
@@ -127,15 +136,36 @@
 	fsr = KGSL_IOMMU_GET_CTX_REG(iommu, iommu_unit,
 		iommu_dev->ctx_id, FSR);
 
-	KGSL_MEM_CRIT(iommu_dev->kgsldev,
-		"GPU PAGE FAULT: addr = %lX pid = %d\n",
-		addr, kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase));
-	KGSL_MEM_CRIT(iommu_dev->kgsldev, "context = %d FSR = %X\n",
-		iommu_dev->ctx_id, fsr);
+	if (adreno_dev->ft_pf_policy & KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE)
+		no_page_fault_log = kgsl_mmu_log_fault_addr(mmu, ptbase, addr);
+
+	if (!no_page_fault_log) {
+		KGSL_MEM_CRIT(iommu_dev->kgsldev,
+			"GPU PAGE FAULT: addr = %lX pid = %d\n",
+			addr, kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase));
+		KGSL_MEM_CRIT(iommu_dev->kgsldev, "context = %d FSR = %X\n",
+			iommu_dev->ctx_id, fsr);
+	}
 
 	mmu->fault = 1;
 	iommu_dev->fault = 1;
 
+	kgsl_sharedmem_readl(&device->memstore, &curr_context_id,
+		KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context));
+	context = idr_find(&device->context_idr, curr_context_id);
+	if (context != NULL)
+			curr_context = context->devctxt;
+
+	kgsl_sharedmem_readl(&device->memstore, &curr_global_ts,
+		KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, eoptimestamp));
+
+	/*
+	 * Store pagefault's timestamp and ib1 addr in context,
+	 * this information is used in GFT
+	 */
+	curr_context->pagefault = 1;
+	curr_context->pagefault_ts = curr_global_ts;
+
 	trace_kgsl_mmu_pagefault(iommu_dev->kgsldev, addr,
 			kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase), 0);
 
@@ -145,7 +175,8 @@
 	 * the GPU and trigger a snapshot. To stall the transaction return
 	 * EBUSY error.
 	 */
-	ret = -EBUSY;
+	if (adreno_dev->ft_pf_policy & KGSL_FT_PAGEFAULT_GPUHALT_ENABLE)
+		ret = -EBUSY;
 done:
 	return ret;
 }
diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h
index 6e04996..4507700 100644
--- a/drivers/gpu/msm/kgsl_iommu.h
+++ b/drivers/gpu/msm/kgsl_iommu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_log.h b/drivers/gpu/msm/kgsl_log.h
index 6fd28ab..83d14f7 100644
--- a/drivers/gpu/msm/kgsl_log.h
+++ b/drivers/gpu/msm/kgsl_log.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-2011, The Linux Foundation. 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 and
@@ -103,6 +103,15 @@
 #define KGSL_PWR_CRIT(_dev, fmt, args...) \
 KGSL_LOG_CRIT(_dev->dev, _dev->pwr_log, fmt, ##args)
 
+#define KGSL_FT_INFO(_dev, fmt, args...) \
+KGSL_LOG_INFO(_dev->dev, _dev->ft_log, fmt, ##args)
+#define KGSL_FT_WARN(_dev, fmt, args...) \
+KGSL_LOG_WARN(_dev->dev, _dev->ft_log, fmt, ##args)
+#define KGSL_FT_ERR(_dev, fmt, args...) \
+KGSL_LOG_ERR(_dev->dev, _dev->ft_log, fmt, ##args)
+#define KGSL_FT_CRIT(_dev, fmt, args...) \
+KGSL_LOG_CRIT(_dev->dev, _dev->ft_log, fmt, ##args)
+
 /* Core error messages - these are for core KGSL functions that have
    no device associated with them (such as memory) */
 
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 087d279..f11511f 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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 and
@@ -347,6 +347,35 @@
 }
 EXPORT_SYMBOL(kgsl_mmu_get_ptname_from_ptbase);
 
+unsigned int
+kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu, unsigned int pt_base,
+					unsigned int addr)
+{
+	struct kgsl_pagetable *pt;
+	unsigned int ret = 0;
+
+	if (!mmu->mmu_ops || !mmu->mmu_ops->mmu_pt_equal)
+		return KGSL_MMU_GLOBAL_PT;
+	spin_lock(&kgsl_driver.ptlock);
+	list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) {
+		if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) {
+			if ((addr & ~(PAGE_SIZE-1)) == pt->fault_addr) {
+				ret = 1;
+				break;
+			} else {
+				pt->fault_addr = (addr & ~(PAGE_SIZE-1));
+				ret = 0;
+				break;
+			}
+
+		}
+	}
+	spin_unlock(&kgsl_driver.ptlock);
+
+	return ret;
+}
+EXPORT_SYMBOL(kgsl_mmu_log_fault_addr);
+
 int kgsl_mmu_init(struct kgsl_device *device)
 {
 	int status = 0;
@@ -452,6 +481,7 @@
 
 	pagetable->name = name;
 	pagetable->max_entries = KGSL_PAGETABLE_ENTRIES(ptsize);
+	pagetable->fault_addr = 0xFFFFFFFF;
 
 	/*
 	 * create a separate kgsl pool for IOMMU, global mappings can be mapped
@@ -695,6 +725,8 @@
 {
 	struct gen_pool *pool;
 	int size;
+	unsigned int start_addr = 0;
+	unsigned int end_addr = 0;
 
 	if (memdesc->size == 0 || memdesc->gpuaddr == 0)
 		return 0;
@@ -706,10 +738,19 @@
 
 	size = kgsl_sg_size(memdesc->sg, memdesc->sglen);
 
+	start_addr = memdesc->gpuaddr;
+	end_addr = (memdesc->gpuaddr + size);
+
 	if (KGSL_MMU_TYPE_IOMMU != kgsl_mmu_get_mmutype())
 		spin_lock(&pagetable->lock);
 	pagetable->pt_ops->mmu_unmap(pagetable->priv, memdesc,
 					&pagetable->tlb_flags);
+
+	/* If buffer is unmapped 0 fault addr */
+	if ((pagetable->fault_addr >= start_addr) &&
+		(pagetable->fault_addr < end_addr))
+		pagetable->fault_addr = 0;
+
 	if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype())
 		spin_lock(&pagetable->lock);
 	/* Remove the statistics */
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 0865978..377f342 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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 and
@@ -114,6 +114,7 @@
 	} stats;
 	const struct kgsl_mmu_pt_ops *pt_ops;
 	unsigned int tlb_flags;
+	unsigned int fault_addr;
 	void *priv;
 };
 
@@ -210,6 +211,8 @@
 			uint32_t flags);
 int kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu,
 					unsigned int pt_base);
+unsigned int kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu,
+			unsigned int pt_base, unsigned int addr);
 int kgsl_mmu_pt_get_flags(struct kgsl_pagetable *pt,
 			enum kgsl_deviceid id);
 void kgsl_mmu_ptpool_destroy(void *ptpool);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 1eb12a0..d489119 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
@@ -1024,7 +1024,7 @@
 			}
 		}
 	} else if (device->state & (KGSL_STATE_HUNG |
-					KGSL_STATE_DUMP_AND_RECOVER)) {
+					KGSL_STATE_DUMP_AND_FT)) {
 		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
 	}
 
@@ -1063,7 +1063,7 @@
 		break;
 	case KGSL_STATE_INIT:
 	case KGSL_STATE_HUNG:
-	case KGSL_STATE_DUMP_AND_RECOVER:
+	case KGSL_STATE_DUMP_AND_FT:
 		if (test_bit(KGSL_PWRFLAGS_CLK_ON,
 					 &device->pwrctrl.power_flags))
 			break;
@@ -1087,9 +1087,9 @@
 		mutex_unlock(&device->mutex);
 		wait_for_completion(&device->hwaccess_gate);
 		mutex_lock(&device->mutex);
-	} else if (device->state == KGSL_STATE_DUMP_AND_RECOVER) {
+	} else if (device->state == KGSL_STATE_DUMP_AND_FT) {
 		mutex_unlock(&device->mutex);
-		wait_for_completion(&device->recovery_gate);
+		wait_for_completion(&device->ft_gate);
 		mutex_lock(&device->mutex);
 	} else if (device->state == KGSL_STATE_SLUMBER)
 		kgsl_pwrctrl_wake(device);
@@ -1312,7 +1312,7 @@
 		return "SUSPEND";
 	case KGSL_STATE_HUNG:
 		return "HUNG";
-	case KGSL_STATE_DUMP_AND_RECOVER:
+	case KGSL_STATE_DUMP_AND_FT:
 		return "DNR";
 	case KGSL_STATE_SLUMBER:
 		return "SLUMBER";
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index e51ec54..8d66505 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index d46f552..02ada38 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
@@ -237,16 +237,14 @@
 void kgsl_pwrscale_busy(struct kgsl_device *device)
 {
 	if (PWRSCALE_ACTIVE(device) && device->pwrscale.policy->busy)
-		if (device->requested_state != KGSL_STATE_SLUMBER)
-			device->pwrscale.policy->busy(device,
-					&device->pwrscale);
+		device->pwrscale.policy->busy(device,
+				&device->pwrscale);
 }
 
 void kgsl_pwrscale_idle(struct kgsl_device *device)
 {
 	if (PWRSCALE_ACTIVE(device) && device->pwrscale.policy->idle)
-		if (device->requested_state != KGSL_STATE_SLUMBER &&
-			device->requested_state != KGSL_STATE_SLEEP)
+		if (device->state == KGSL_STATE_ACTIVE)
 			device->pwrscale.policy->idle(device,
 					&device->pwrscale);
 }
diff --git a/drivers/gpu/msm/kgsl_pwrscale.h b/drivers/gpu/msm/kgsl_pwrscale.h
index 85d5b82..f17b394 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.h
+++ b/drivers/gpu/msm/kgsl_pwrscale.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_pwrscale_idlestats.c b/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
index cd432c6..c3188a5 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
index 3e81e56..a647361 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
@@ -38,6 +38,10 @@
  * per frame for 60fps content.
  */
 #define FLOOR			5000
+/* CEILING is 50msec, larger than any standard
+ * frame length, but less than the idle timer.
+ */
+#define CEILING			50000
 #define SWITCH_OFF		200
 #define SWITCH_OFF_RESET_TH	40
 #define SKIP_COUNTER		500
@@ -163,11 +167,18 @@
 		priv->no_switch_cnt = 0;
 	}
 
-	idle = priv->bin.total_time - priv->bin.busy_time;
+	/* If there is an extended block of busy processing,
+	 * increase frequency.  Otherwise run the normal algorithm.
+	 */
+	if (priv->bin.busy_time > CEILING) {
+		val = -1;
+	} else {
+		idle = priv->bin.total_time - priv->bin.busy_time;
+		idle = (idle > 0) ? idle : 0;
+		val = __secure_tz_entry(TZ_UPDATE_ID, idle, device->id);
+	}
 	priv->bin.total_time = 0;
 	priv->bin.busy_time = 0;
-	idle = (idle > 0) ? idle : 0;
-	val = __secure_tz_entry(TZ_UPDATE_ID, idle, device->id);
 	if (val)
 		kgsl_pwrctrl_pwrlevel_change(device,
 					     pwr->active_pwrlevel + val);
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 755e347..099f4cc 100755
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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 and
@@ -571,11 +571,10 @@
 	memdesc->pagetable = pagetable;
 	memdesc->ops = &kgsl_page_alloc_ops;
 
-	memdesc->sg = kgsl_sg_alloc(sglen_alloc);
+	memdesc->sglen_alloc = sglen_alloc;
+	memdesc->sg = kgsl_sg_alloc(memdesc->sglen_alloc);
 
 	if (memdesc->sg == NULL) {
-		KGSL_CORE_ERR("vmalloc(%d) failed\n",
-			sglen_alloc * sizeof(struct scatterlist));
 		ret = -ENOMEM;
 		goto done;
 	}
@@ -587,26 +586,24 @@
 	 * two pages; well within the acceptable limits for using kmalloc.
 	 */
 
-	pages = kmalloc(sglen_alloc * sizeof(struct page *), GFP_KERNEL);
+	pages = kmalloc(memdesc->sglen_alloc * sizeof(struct page *),
+		GFP_KERNEL);
 
 	if (pages == NULL) {
-		KGSL_CORE_ERR("kmalloc (%d) failed\n",
-			sglen_alloc * sizeof(struct page *));
 		ret = -ENOMEM;
 		goto done;
 	}
 
 	kmemleak_not_leak(memdesc->sg);
 
-	memdesc->sglen_alloc = sglen_alloc;
-	sg_init_table(memdesc->sg, sglen_alloc);
+	sg_init_table(memdesc->sg, memdesc->sglen_alloc);
 
 	len = size;
 
 	while (len > 0) {
 		struct page *page;
 		unsigned int gfp_mask = GFP_KERNEL | __GFP_HIGHMEM |
-			__GFP_NOWARN | __GFP_NORETRY;
+			__GFP_NOWARN;
 		int j;
 
 		/* don't waste space at the end of the allocation*/
diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h
index ffd80fa..a895a75 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.h
+++ b/drivers/gpu/msm/kgsl_sharedmem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index a2ab5b1..a5aa42f 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -289,6 +289,32 @@
 	kfree(obj);
 }
 
+/* ksgl_snapshot_have_object - Return 1 if the object has been processed
+ *@device - the device that is being snapshotted
+ * @ptbase - the pagetable base of the object to freeze
+ * @gpuaddr - The gpu address of the object to freeze
+ * @size - the size of the object (may not always be the size of the region)
+ *
+ * Return 1 if the object is already in the list - this can save us from
+ * having to parse the sme thing over again.
+*/
+int kgsl_snapshot_have_object(struct kgsl_device *device, unsigned int ptbase,
+	unsigned int gpuaddr, unsigned int size)
+{
+	struct kgsl_snapshot_object *obj;
+
+	list_for_each_entry(obj, &device->snapshot_obj_list, node) {
+		if (obj->ptbase != ptbase)
+			continue;
+
+		if ((gpuaddr >= obj->gpuaddr) &&
+			((gpuaddr + size) <= (obj->gpuaddr + obj->size)))
+			return 1;
+	}
+
+	return 0;
+}
+
 /* kgsl_snapshot_get_object - Mark a GPU buffer to be frozen
  * @device - the device that is being snapshotted
  * @ptbase - the pagetable base of the object to freeze
@@ -313,14 +339,14 @@
 	if (entry == NULL) {
 		KGSL_DRV_ERR(device, "Unable to find GPU buffer %8.8X\n",
 				gpuaddr);
-		return 0;
+		return -EINVAL;
 	}
 
 	/* We can't freeze external memory, because we don't own it */
 	if (entry->memtype != KGSL_MEM_ENTRY_KERNEL) {
 		KGSL_DRV_ERR(device,
 			"Only internal GPU buffers can be frozen\n");
-		return 0;
+		return -EINVAL;
 	}
 
 	/*
@@ -343,7 +369,7 @@
 	if (size + offset > entry->memdesc.size) {
 		KGSL_DRV_ERR(device, "Invalid size for GPU buffer %8.8X\n",
 				gpuaddr);
-		return 0;
+		return -EINVAL;
 	}
 
 	/* If the buffer is already on the list, skip it */
@@ -360,14 +386,14 @@
 	if (kgsl_memdesc_map(&entry->memdesc) == NULL) {
 		KGSL_DRV_ERR(device, "Unable to map GPU buffer %X\n",
 				gpuaddr);
-		return 0;
+		return -EINVAL;
 	}
 
 	obj = kzalloc(sizeof(*obj), GFP_KERNEL);
 
 	if (obj == NULL) {
 		KGSL_DRV_ERR(device, "Unable to allocate memory\n");
-		return 0;
+		return -EINVAL;
 	}
 
 	/* Ref count the mem entry */
@@ -492,6 +518,7 @@
 	struct kgsl_snapshot_header *header = device->snapshot;
 	int remain = device->snapshot_maxsize - sizeof(*header);
 	void *snapshot;
+	struct timespec boot;
 
 	/*
 	 * The first hang is always the one we are interested in. To
@@ -533,16 +560,21 @@
 		snapshot = device->ftbl->snapshot(device, snapshot, &remain,
 			hang);
 
-	device->snapshot_timestamp = get_seconds();
+	/*
+	 * The timestamp is the seconds since boot so it is easier to match to
+	 * the kernel log
+	 */
+
+	getboottime(&boot);
+	device->snapshot_timestamp = get_seconds() - boot.tv_sec;
 	device->snapshot_size = (int) (snapshot - device->snapshot);
 
 	/* Freeze the snapshot on a hang until it gets read */
 	device->snapshot_frozen = (hang) ? 1 : 0;
 
-	/* log buffer info to aid in ramdump recovery */
-	KGSL_DRV_ERR(device, "snapshot created at va %p pa %lx size %d\n",
-			device->snapshot, __pa(device->snapshot),
-			device->snapshot_size);
+	/* log buffer info to aid in ramdump fault tolerance */
+	KGSL_DRV_ERR(device, "snapshot created at pa %lx size %d\n",
+			__pa(device->snapshot),	device->snapshot_size);
 	if (hang)
 		sysfs_notify(&device->snapshot_kobj, NULL, "timestamp");
 	return 0;
@@ -629,7 +661,7 @@
 /* Show the timestamp of the last collected snapshot */
 static ssize_t timestamp_show(struct kgsl_device *device, char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%x\n", device->snapshot_timestamp);
+	return snprintf(buf, PAGE_SIZE, "%d\n", device->snapshot_timestamp);
 }
 
 /* manually trigger a new snapshot to be collected */
diff --git a/drivers/gpu/msm/kgsl_snapshot.h b/drivers/gpu/msm/kgsl_snapshot.h
index 6d81bcf..327d18a 100644
--- a/drivers/gpu/msm/kgsl_snapshot.h
+++ b/drivers/gpu/msm/kgsl_snapshot.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -311,5 +311,8 @@
 int kgsl_snapshot_get_object(struct kgsl_device *device, unsigned int ptbase,
 	unsigned int gpuaddr, unsigned int size, unsigned int type);
 
+int kgsl_snapshot_have_object(struct kgsl_device *device, unsigned int ptbase,
+	unsigned int gpuaddr, unsigned int size);
+
 #endif
 #endif
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index a2dfe3b..813305a 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -69,6 +69,7 @@
 
 struct kgsl_fence_event_priv {
 	struct kgsl_context *context;
+	unsigned int timestamp;
 };
 
 /**
@@ -85,7 +86,7 @@
 	void *priv, u32 context_id, u32 timestamp)
 {
 	struct kgsl_fence_event_priv *ev = priv;
-	kgsl_sync_timeline_signal(ev->context->timeline, timestamp);
+	kgsl_sync_timeline_signal(ev->context->timeline, ev->timestamp);
 	kgsl_context_put(ev->context);
 	kfree(ev);
 }
@@ -125,6 +126,7 @@
 	if (event == NULL)
 		return -ENOMEM;
 	event->context = context;
+	event->timestamp = timestamp;
 	kgsl_context_get(context);
 
 	pt = kgsl_sync_pt_create(context->timeline, timestamp);
@@ -179,6 +181,7 @@
 }
 
 static const struct sync_timeline_ops kgsl_sync_timeline_ops = {
+	.driver_name = "kgsl-timeline",
 	.dup = kgsl_sync_pt_dup,
 	.has_signaled = kgsl_sync_pt_has_signaled,
 	.compare = kgsl_sync_pt_compare,
@@ -204,7 +207,9 @@
 {
 	struct kgsl_sync_timeline *ktimeline =
 		(struct kgsl_sync_timeline *) timeline;
-	ktimeline->last_timestamp = timestamp;
+
+	if (timestamp_cmp(timestamp, ktimeline->last_timestamp) > 0)
+		ktimeline->last_timestamp = timestamp;
 	sync_timeline_signal(timeline);
 }
 
diff --git a/drivers/gpu/msm/kgsl_trace.c b/drivers/gpu/msm/kgsl_trace.c
index 2bcca15..e432729 100644
--- a/drivers/gpu/msm/kgsl_trace.c
+++ b/drivers/gpu/msm/kgsl_trace.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index e12013d..c54445c 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -535,6 +535,41 @@
 	)
 );
 
+TRACE_EVENT(kgsl_register_event,
+		TP_PROTO(unsigned int id, unsigned int timestamp),
+		TP_ARGS(id, timestamp),
+		TP_STRUCT__entry(
+			__field(unsigned int, id)
+			__field(unsigned int, timestamp)
+		),
+		TP_fast_assign(
+			__entry->id = id;
+			__entry->timestamp = timestamp;
+		),
+		TP_printk(
+			"ctx=%d ts=%d",
+			__entry->id, __entry->timestamp)
+);
+
+TRACE_EVENT(kgsl_fire_event,
+		TP_PROTO(unsigned int id, unsigned int ts,
+			unsigned int age),
+		TP_ARGS(id, ts, age),
+		TP_STRUCT__entry(
+			__field(unsigned int, id)
+			__field(unsigned int, ts)
+			__field(unsigned int, age)
+		),
+		TP_fast_assign(
+			__entry->id = id;
+			__entry->ts = ts;
+			__entry->age = age;
+		),
+		TP_printk(
+			"ctx=%d ts=%d age=%u",
+			__entry->id, __entry->ts, __entry->age)
+);
+
 #endif /* _KGSL_TRACE_H */
 
 /* This part must be outside protection */
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 8ddc991..484630d 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/z180.h b/drivers/gpu/msm/z180.h
index a8973d2..268aac3 100644
--- a/drivers/gpu/msm/z180.h
+++ b/drivers/gpu/msm/z180.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/z180_postmortem.c b/drivers/gpu/msm/z180_postmortem.c
index 7cf3799..c1e5f07 100644
--- a/drivers/gpu/msm/z180_postmortem.c
+++ b/drivers/gpu/msm/z180_postmortem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/z180_reg.h b/drivers/gpu/msm/z180_reg.h
index 07d60b9..81f1fdc 100644
--- a/drivers/gpu/msm/z180_reg.h
+++ b/drivers/gpu/msm/z180_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/z180_trace.c b/drivers/gpu/msm/z180_trace.c
index 29b519c..9d971ee 100644
--- a/drivers/gpu/msm/z180_trace.c
+++ b/drivers/gpu/msm/z180_trace.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/gpu/msm/z180_trace.h b/drivers/gpu/msm/z180_trace.h
index fbe1fe5..4f65b9b 100644
--- a/drivers/gpu/msm/z180_trace.h
+++ b/drivers/gpu/msm/z180_trace.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/gud/Kconfig b/drivers/gud/Kconfig
index 3a241b7..929ba01d 100644
--- a/drivers/gud/Kconfig
+++ b/drivers/gud/Kconfig
@@ -3,7 +3,6 @@
 #
 config MOBICORE_SUPPORT
 	tristate "Linux MobiCore Support"
-	#depends on ARM_TRUSTZONE
 	---help---
 	  Enable Linux Kernel MobiCore Support
 
@@ -12,14 +11,14 @@
     depends on MOBICORE_SUPPORT
     ---help---
       Enable Debug mode in the MobiCore Driver.
-      It enables printing information about mobicore operations
+      It enables printing information about MobiCore operations
 
 config MOBICORE_VERBOSE
     bool "MobiCore Module verbose debug mode"
     depends on MOBICORE_DEBUG
     ---help---
       Enable Verbose Debug mode in the MobiCore Driver.
-      It enables printing extra information about mobicore operations
+      It enables printing extra information about MobiCore operations
       Beware: this is only useful for debuging deep in the driver because
       it prints too much logs
 
@@ -29,4 +28,3 @@
     depends on MOBICORE_SUPPORT
     ---help---
       Enable Linux Kernel MobiCore API
-
diff --git a/drivers/gud/Makefile b/drivers/gud/Makefile
index ea212c5..3a16bb7 100644
--- a/drivers/gud/Makefile
+++ b/drivers/gud/Makefile
@@ -6,7 +6,11 @@
 obj-$(CONFIG_MOBICORE_API) += mckernelapi.o
 obj-$(CONFIG_MOBICORE_SUPPORT) += mcdrvmodule.o
 
-mcdrvmodule-objs := mobicore_driver/logging.o mobicore_driver/main.o
+mcdrvmodule-objs := mobicore_driver/logging.o \
+		mobicore_driver/ops.o \
+		mobicore_driver/mem.o \
+		mobicore_driver/api.o \
+		mobicore_driver/main.o
 
 mckernelapi-objs := mobicore_kernelapi/main.o \
 		mobicore_kernelapi/clientlib.o \
@@ -15,7 +19,7 @@
 		mobicore_kernelapi/connection.o
 
 # Release mode by default
-ccflags-y := -DNDEBUG
+ccflags-y := -DNDEBUG -include $(PWD)/$(GUD_ROOT_FOLDER)/mobicore_driver/build_tag.h
 ccflags-y += -Wno-declaration-after-statement
 
 ccflags-$(CONFIG_MOBICORE_DEBUG) += -DDEBUG
diff --git a/drivers/gud/mobicore_driver/api.c b/drivers/gud/mobicore_driver/api.c
new file mode 100644
index 0000000..871f6cc
--- /dev/null
+++ b/drivers/gud/mobicore_driver/api.c
@@ -0,0 +1,115 @@
+/* MobiCore driver module.(interface to the secure world SWD)
+ * MobiCore Driver Kernel Module.
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+
+#include "main.h"
+#include "mem.h"
+#include "debug.h"
+
+
+/*
+ * Map a virtual memory buffer structure to Mobicore
+ * @param instance
+ * @param addr		address of the buffer(NB it must be kernel virtual!)
+ * @param len		buffer length
+ * @param handle	pointer to handle
+ * @param phys_wsm_l2_table	pointer to physical L2 table(?)
+ *
+ * @return 0 if no error
+ *
+ */
+int mobicore_map_vmem(struct mc_instance *instance, void *addr,
+	uint32_t len, uint32_t *handle, uint32_t *phys)
+{
+	return mc_register_wsm_l2(instance, (uint32_t)addr, len,
+		handle, phys);
+}
+EXPORT_SYMBOL(mobicore_map_vmem);
+
+/*
+ * Unmap a virtual memory buffer from mobicore
+ * @param instance
+ * @param handle
+ *
+ * @return 0 if no error
+ *
+ */
+int mobicore_unmap_vmem(struct mc_instance *instance, uint32_t handle)
+{
+	return mc_unregister_wsm_l2(instance, handle);
+}
+EXPORT_SYMBOL(mobicore_unmap_vmem);
+
+/*
+ * Free a WSM buffer allocated with mobicore_allocate_wsm
+ * @param instance
+ * @param handle		handle of the buffer
+ *
+ * @return 0 if no error
+ *
+ */
+int mobicore_free_wsm(struct mc_instance *instance, uint32_t handle)
+{
+	return mc_free_buffer(instance, handle);
+}
+EXPORT_SYMBOL(mobicore_free_wsm);
+
+
+/*
+ * Allocate WSM for given instance
+ *
+ * @param instance		instance
+ * @param requested_size		size of the WSM
+ * @param handle		pointer where the handle will be saved
+ * @param virt_kernel_addr	pointer for the kernel virtual address
+ * @param phys_addr		pointer for the physical address
+ *
+ * @return error code or 0 for success
+ */
+int mobicore_allocate_wsm(struct mc_instance *instance,
+	unsigned long requested_size, uint32_t *handle, void **virt_kernel_addr,
+	void **phys_addr)
+{
+	struct mc_buffer *buffer = NULL;
+
+	/* Setup the WSM buffer structure! */
+	if (mc_get_buffer(instance, &buffer, requested_size))
+		return -EFAULT;
+
+	*handle = buffer->handle;
+	*phys_addr = buffer->phys;
+	*virt_kernel_addr = buffer->addr;
+	return 0;
+}
+EXPORT_SYMBOL(mobicore_allocate_wsm);
+
+/*
+ * Initialize a new mobicore API instance object
+ *
+ * @return Instance or NULL if no allocation was possible.
+ */
+struct mc_instance *mobicore_open(void)
+{
+	return mc_alloc_instance();
+}
+EXPORT_SYMBOL(mobicore_open);
+
+/*
+ * Release a mobicore instance object and all objects related to it
+ * @param instance instance
+ * @return 0 if Ok or -E ERROR
+ */
+int mobicore_release(struct mc_instance *instance)
+{
+	return mc_release_instance(instance);
+}
+EXPORT_SYMBOL(mobicore_release);
+
diff --git a/drivers/gud/mobicore_driver/arm.h b/drivers/gud/mobicore_driver/arm.h
new file mode 100644
index 0000000..439feed
--- /dev/null
+++ b/drivers/gud/mobicore_driver/arm.h
@@ -0,0 +1,73 @@
+/*
+ * MobiCore driver module.(interface to the secure world SWD)
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * 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 _MC_ARM_H_
+#define _MC_ARM_H_
+
+#include "debug.h"
+
+/*
+ * ARM Trustzone specific masks and modes
+ * Vanilla Linux is unaware of TrustZone extension.
+ * I.e. arch/arm/include/asm/ptrace.h does not define monitor mode.
+ * Also TZ bits in cpuid are not defined, ARM port uses magic numbers,
+ * see arch/arm/kernel/setup.c
+ */
+#define ARM_MONITOR_MODE		(0b10110)
+#define ARM_SECURITY_EXTENSION_MASK	(0x30)
+
+/* check if CPU supports the ARM TrustZone Security Extensions */
+inline bool has_security_extensions(void)
+{
+	u32 fea = 0;
+	asm volatile(
+		"mrc p15, 0, %[fea], cr0, cr1, 0" :
+		[fea]"=r" (fea));
+
+	MCDRV_DBG_VERBOSE(mcd, "CPU Features: 0x%X", fea);
+
+	/*
+	 * If the CPU features ID has 0 for security features then the CPU
+	 * doesn't support TrustZone at all!
+	 */
+	if ((fea & ARM_SECURITY_EXTENSION_MASK) == 0)
+		return false;
+
+	return true;
+}
+
+/* check if running in secure mode */
+inline bool is_secure_mode(void)
+{
+	u32 cpsr = 0;
+	u32 nsacr = 0;
+
+	asm volatile(
+		"mrc	p15, 0, %[nsacr], cr1, cr1, 2\n"
+		"mrs %[cpsr], cpsr\n" :
+		[nsacr]"=r" (nsacr),
+		[cpsr]"=r"(cpsr));
+
+	MCDRV_DBG_VERBOSE(mcd, "CPRS.M = set to 0x%X\n", cpsr & MODE_MASK);
+	MCDRV_DBG_VERBOSE(mcd, "SCR.NS = set to 0x%X\n", nsacr);
+
+	/*
+	 * If the NSACR contains the reset value(=0) then most likely we are
+	 * running in Secure MODE.
+	 * If the cpsr mode is set to monitor mode then we cannot load!
+	 */
+	if (nsacr == 0 || ((cpsr & MODE_MASK) == ARM_MONITOR_MODE))
+		return true;
+
+	return false;
+}
+
+#endif /* _MC_ARM_H_ */
diff --git a/drivers/gud/mobicore_driver/build_tag.h b/drivers/gud/mobicore_driver/build_tag.h
index 43541bb..4abd003 100644
--- a/drivers/gud/mobicore_driver/build_tag.h
+++ b/drivers/gud/mobicore_driver/build_tag.h
@@ -1,6 +1,5 @@
-/**
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2012-2012 -->
+/*
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,4 +25,5 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#define MOBICORE_COMPONENT_BUILD_TAG "*** GC_MSM8960_Release_V010 ###"
+#define MOBICORE_COMPONENT_BUILD_TAG \
+		"*** GC_MSM8960_Release_V016 ###"
diff --git a/drivers/gud/mobicore_driver/debug.h b/drivers/gud/mobicore_driver/debug.h
new file mode 100644
index 0000000..1f9a632
--- /dev/null
+++ b/drivers/gud/mobicore_driver/debug.h
@@ -0,0 +1,62 @@
+/*
+ * MobiCore driver module.(interface to the secure world SWD)
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * 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 _MC_DEBUG_H_
+#define _MC_DEBUG_H_
+/* Found in main.c */
+extern struct device *mcd;
+
+#define MCDRV_DBG_ERROR(dev, txt, ...) \
+	dev_err(dev, "MobiCore %s() ### ERROR: " txt, \
+		__func__, \
+		##__VA_ARGS__)
+
+/* dummy function helper macro. */
+#define DUMMY_FUNCTION()	do {} while (0)
+
+#if defined(DEBUG)
+
+/* #define DEBUG_VERBOSE */
+#if defined(DEBUG_VERBOSE)
+#define MCDRV_DBG_VERBOSE	MCDRV_DBG
+#else
+#define MCDRV_DBG_VERBOSE(...)	DUMMY_FUNCTION()
+#endif
+
+#define MCDRV_DBG(dev, txt, ...) \
+	dev_info(dev, "MobiCore %s(): " txt, \
+		 __func__, \
+		 ##__VA_ARGS__)
+
+#define MCDRV_DBG_WARN(dev, txt, ...) \
+	dev_warn(dev, "MobiCore %s() WARNING: " txt, \
+		 __func__, \
+		 ##__VA_ARGS__)
+
+#define MCDRV_ASSERT(cond) \
+	do { \
+		if (unlikely(!(cond))) { \
+			panic("Assertion failed: %s:%d\n", \
+			      __FILE__, __LINE__); \
+		} \
+	} while (0)
+
+#else
+
+#define MCDRV_DBG_VERBOSE(...)	DUMMY_FUNCTION()
+#define MCDRV_DBG(...)		DUMMY_FUNCTION()
+#define MCDRV_DBG_WARN(...)	DUMMY_FUNCTION()
+
+#define MCDRV_ASSERT(...)	DUMMY_FUNCTION()
+
+#endif /* [not] defined(DEBUG) */
+
+#endif /* _MC_DEBUG_H_ */
diff --git a/drivers/gud/mobicore_driver/fastcall.h b/drivers/gud/mobicore_driver/fastcall.h
new file mode 100644
index 0000000..1c90520
--- /dev/null
+++ b/drivers/gud/mobicore_driver/fastcall.h
@@ -0,0 +1,169 @@
+/*
+ * Header file of MobiCore Driver Kernel Module.
+ *
+ * MobiCore Fast Call interface
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * 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 _MC_FASTCALL_H_
+#define _MC_FASTCALL_H_
+
+#include "debug.h"
+
+/* Use the arch_extension sec pseudo op before switching to secure world */
+#if defined(__GNUC__) && \
+	defined(__GNUC_MINOR__) && \
+	defined(__GNUC_PATCHLEVEL__) && \
+	((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)) \
+	>= 40502
+#define MC_ARCH_EXTENSION_SEC
+#endif
+
+/*
+ * MobiCore SMCs
+ */
+#define MC_SMC_N_YIELD		0x3 /* Yield to switch from NWd to SWd. */
+#define MC_SMC_N_SIQ		0x4  /* SIQ to switch from NWd to SWd. */
+
+/*
+ * MobiCore fast calls. See MCI documentation
+ */
+#define MC_FC_INIT		-1
+#define MC_FC_INFO		-2
+#define MC_FC_POWER		-3
+#define MC_FC_DUMP		-4
+#define MC_FC_NWD_TRACE		-31 /* Mem trace setup fastcall */
+
+
+/*
+ * return code for fast calls
+ */
+#define MC_FC_RET_OK				0
+#define MC_FC_RET_ERR_INVALID			1
+#define MC_FC_RET_ERR_ALREADY_INITIALIZED	5
+
+
+/* structure wrappers for specific fastcalls */
+
+/* generic fast call parameters */
+union fc_generic {
+	struct {
+		uint32_t cmd;
+		uint32_t param[3];
+	} as_in;
+	struct {
+		uint32_t resp;
+		uint32_t ret;
+		uint32_t param[2];
+	} as_out;
+};
+
+/* fast call init */
+union mc_fc_init {
+	union fc_generic as_generic;
+	struct {
+		uint32_t cmd;
+		uint32_t base;
+		uint32_t nq_info;
+		uint32_t mcp_info;
+	} as_in;
+	struct {
+		uint32_t resp;
+		uint32_t ret;
+		uint32_t rfu[2];
+	} as_out;
+};
+
+/* fast call info parameters */
+union mc_fc_info {
+	union fc_generic as_generic;
+	struct {
+		uint32_t cmd;
+		uint32_t ext_info_id;
+		uint32_t rfu[2];
+	} as_in;
+	struct {
+		uint32_t resp;
+		uint32_t ret;
+		uint32_t state;
+		uint32_t ext_info;
+	} as_out;
+};
+
+/*
+ * _smc() - fast call to MobiCore
+ *
+ * @data: pointer to fast call data
+ */
+static inline long _smc(void *data)
+{
+	int ret = 0;
+	union fc_generic fc_generic;
+
+	if (data == NULL)
+		return -EPERM;
+
+#ifdef MC_SMC_FASTCALL
+	{
+		ret = smc_fastcall(data, sizeof(fc_generic));
+	}
+#else
+	memcpy(&fc_generic, data, sizeof(union fc_generic));
+	{
+		/* SVC expect values in r0-r3 */
+		register u32 reg0 __asm__("r0") = fc_generic.as_in.cmd;
+		register u32 reg1 __asm__("r1") = fc_generic.as_in.param[0];
+		register u32 reg2 __asm__("r2") = fc_generic.as_in.param[1];
+		register u32 reg3 __asm__("r3") = fc_generic.as_in.param[2];
+
+		__asm__ volatile (
+#ifdef MC_ARCH_EXTENSION_SEC
+			/* This pseudo op is supported and required from
+			 * binutils 2.21 on */
+			".arch_extension sec\n"
+#endif
+			"smc 0\n"
+			: "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
+		);
+
+		/* set response */
+		fc_generic.as_out.resp     = reg0;
+		fc_generic.as_out.ret      = reg1;
+		fc_generic.as_out.param[0] = reg2;
+		fc_generic.as_out.param[1] = reg3;
+		memcpy(data, &fc_generic, sizeof(union fc_generic));
+	}
+#endif
+	return ret;
+}
+
+/*
+ * convert fast call return code to linux driver module error code
+ */
+static inline int convert_fc_ret(uint32_t sret)
+{
+	int ret = -EFAULT;
+
+	switch (sret) {
+	case MC_FC_RET_OK:
+		ret = 0;
+		break;
+	case MC_FC_RET_ERR_INVALID:
+		ret = -EINVAL;
+		break;
+	case MC_FC_RET_ERR_ALREADY_INITIALIZED:
+		ret = -EBUSY;
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+#endif /* _MC_FASTCALL_H_ */
diff --git a/drivers/gud/mobicore_driver/logging.c b/drivers/gud/mobicore_driver/logging.c
index eb44c8a..1f599f9 100644
--- a/drivers/gud/mobicore_driver/logging.c
+++ b/drivers/gud/mobicore_driver/logging.c
@@ -1,247 +1,231 @@
-/** MobiCore driver module.(interface to the secure world SWD)
- * @addtogroup MCD_MCDIMPL_KMOD_LOGGING MobiCore Driver Logging Subsystem.
- * @ingroup  MCD_MCDIMPL_KMOD
- * @{
- * @file
+/*
  * MobiCore Driver Logging Subsystem.
- * The logging subsytem provides the interface between the Mobicore trace
+ *
+ * The logging subsystem provides the interface between the Mobicore trace
  * buffer and the Linux log
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * 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 "mc_drv_module.h"
-#include "mc_drv_module_linux_api.h"
-#include "mc_drv_module_fastcalls.h"
+#include <linux/miscdevice.h>
+#include <linux/moduleparam.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/device.h>
 
-/* Default len of the log ring buffer 256KB*/
-#define LOG_BUF_SIZE	(64 * PAGE_SIZE)
+#include "main.h"
+#include "debug.h"
+#include "ops.h"
+#include "logging.h"
+
+/* Default length of the log ring buffer 256KB*/
+#define LOG_BUF_SIZE			(64 * PAGE_SIZE)
 
 /* Max Len of a log line for printing */
-#define LOG_LINE_SIZE	256
+#define LOG_LINE_SIZE			256
 
 static uint32_t log_size = LOG_BUF_SIZE;
-module_param(log_size, uint, 0);
-MODULE_PARM_DESC(log_size, " Size of the MobiCore log ringbuffer "
-						"(or 256KB default).");
 
-/*----------------------------------------------------------------------------*/
+module_param(log_size, uint, 0);
+MODULE_PARM_DESC(log_size, "Size of the MobiCore log ringbuffer(256KB def)");
+
 /* Definitions for log version 2 */
-#define LOG_TYPE_MASK				(0x0007)
-#define LOG_TYPE_CHAR				0
-#define LOG_TYPE_INTEGER			1
+#define LOG_TYPE_MASK			(0x0007)
+#define LOG_TYPE_CHAR			0
+#define LOG_TYPE_INTEGER		1
 /* Field length */
-#define LOG_LENGTH_MASK				(0x00F8)
-#define LOG_LENGTH_SHIFT			3
+#define LOG_LENGTH_MASK			(0x00F8)
+#define LOG_LENGTH_SHIFT		3
 /* Extra attributes */
-#define LOG_EOL					(0x0100)
-#define LOG_INTEGER_DECIMAL			(0x0200)
-#define LOG_INTEGER_SIGNED			(0x0400)
+#define LOG_EOL				(0x0100)
+#define LOG_INTEGER_DECIMAL		(0x0200)
+#define LOG_INTEGER_SIGNED		(0x0400)
 
 struct logmsg_struct {
-	/* Type and format of data */
-	uint16_t ctrl;
-	/* Unique value for each event source */
-	uint16_t source;
-	/* Value, if any */
-	uint32_t log_data;
+	uint16_t ctrl;			/* Type and format of data */
+	uint16_t source;		/* Unique value for each event source */
+	uint32_t log_data;		/* Value, if any */
 };
 
-/** MobiCore log previous position */
-static uint32_t log_pos;
-/** MobiCore log buffer structure */
-static struct mc_trace_buf *log_buf;
-/** Log Thread task structure */
-struct task_struct *log_thread;
-/** Log Line buffer */
-static char *log_line;
+static bool prev_eol;			/* Previous char was a EOL */
+static uint16_t prev_source;		/* Previous Log source */
+static uint32_t log_pos;		/* MobiCore log previous position */
+static struct mc_trace_buf *log_buf;	/* MobiCore log buffer structure */
+struct task_struct *log_thread;		/* Log Thread task structure */
+static char *log_line;			/* Log Line buffer */
+static uint32_t log_line_len;		/* Log Line buffer current length */
+static int thread_err;
 
-static void log_msg(struct logmsg_struct *msg);
-
-/*----------------------------------------------------------------------------*/
-static void log_eol(void)
+static void log_eol(uint16_t source)
 {
 	if (!strnlen(log_line, LOG_LINE_SIZE))
 		return;
-	printk(KERN_INFO "%s\n", log_line);
+	prev_eol = true;
+	/* MobiCore Userspace */
+	if (prev_source)
+		dev_info(mcd, "%03x|%s\n", prev_source, log_line);
+	/* MobiCore kernel */
+	else
+		dev_info(mcd, "%s\n", log_line);
+
+	log_line_len = 0;
 	log_line[0] = 0;
 }
-/*----------------------------------------------------------------------------*/
-/**
- * Put a char to the log line if there is enough space if not then also
- * output the line. Assume nobody else is updating the line! */
-static void log_char(char ch)
+
+/*
+ * Collect chars in log_line buffer and output the buffer when it is full.
+ * No locking needed because only "mobicore_log" thread updates this buffer.
+ */
+static void log_char(char ch, uint16_t source)
 {
-	uint32_t len;
 	if (ch == '\n' || ch == '\r') {
-		log_eol();
+		log_eol(source);
 		return;
 	}
 
-	if (strnlen(log_line, LOG_LINE_SIZE) >= LOG_LINE_SIZE - 1) {
-		printk(KERN_INFO "%s\n", log_line);
-		log_line[0] = 0;
-	}
+	if (log_line_len >= LOG_LINE_SIZE - 1 || source != prev_source)
+		log_eol(source);
 
-	len = strnlen(log_line, LOG_LINE_SIZE);
-	log_line[len] = ch;
-	log_line[len + 1] = 0;
+
+	log_line[log_line_len] = ch;
+	log_line[log_line_len + 1] = 0;
+	log_line_len++;
+	prev_eol = false;
+	prev_source = source;
 }
 
-/*----------------------------------------------------------------------------*/
-/**
- * Put a string to the log line if there is enough space if not then also
- * output the line. Assume nobody else is updating the line! */
-static void log_str(const char *s)
-{
-	int i;
-	for (i = 0; i < strnlen(s, LOG_LINE_SIZE); i++)
-		log_char(s[i]);
-}
+static const uint8_t HEX2ASCII[16] = {
+	'0', '1', '2', '3', '4', '5', '6', '7',
+	'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
 
-/*----------------------------------------------------------------------------*/
-static uint32_t process_v1log(void)
-{
-	char *last_char = log_buf->buff + log_buf->write_pos;
-	char *buff = log_buf->buff + log_pos;
-	while (buff != last_char) {
-		log_char(*(buff++));
-		/* Wrap around */
-		if (buff - (char *)log_buf >= log_size)
-			buff = log_buf->buff;
-	}
-	return buff - log_buf->buff;
-}
-
-/*----------------------------------------------------------------------------*/
-static uint32_t process_v2log(void)
-{
-	char *last_msg = log_buf->buff + log_buf->write_pos;
-	char *buff = log_buf->buff + log_pos;
-	while (buff != last_msg) {
-		log_msg((struct logmsg_struct *)buff);
-		buff += sizeof(struct logmsg_struct);
-		/* Wrap around */
-		if (buff + sizeof(struct logmsg_struct) >
-			(char *)log_buf + log_size)
-			buff = log_buf->buff;
-	}
-	return buff - log_buf->buff;
-}
-
-static const uint8_t HEX2ASCII[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
-				'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-
-/*----------------------------------------------------------------------------*/
-static void dbg_raw_nro(uint32_t format, uint32_t value)
+static void dbg_raw_nro(uint32_t format, uint32_t value, uint16_t source)
 {
 	int digits = 1;
 	uint32_t base = (format & LOG_INTEGER_DECIMAL) ? 10 : 16;
 	int width = (format & LOG_LENGTH_MASK) >> LOG_LENGTH_SHIFT;
-	int negative = FALSE;
+	int negative = 0;
 	uint32_t digit_base = 1;
 
 	if ((format & LOG_INTEGER_SIGNED) != 0 && ((signed int)value) < 0) {
-			negative = TRUE;
-			value = (uint32_t)(-(signed int)value);
-			width--;
+		negative = 1;
+		value = (uint32_t)(-(signed int)value);
+		width--;
 	}
 
 	/* Find length and divider to get largest digit */
 	while (value / digit_base >= base) {
-			digit_base *= base;
-			digits++;
+		digit_base *= base;
+		digits++;
 	}
 
 	if (width > digits) {
 		char ch = (base == 10) ? ' ' : '0';
 		while (width > digits) {
-			log_char(ch);
+			log_char(ch, source);
 			width--;
 		}
 	}
 
 	if (negative)
-		log_char('-');
+		log_char('-', source);
 
 	while (digits-- > 0) {
 		uint32_t d = value / digit_base;
-		log_char(HEX2ASCII[d]);
+		log_char(HEX2ASCII[d], source);
 		value = value - d * digit_base;
 		digit_base /= base;
 	}
 }
 
-/*----------------------------------------------------------------------------*/
 static void log_msg(struct logmsg_struct *msg)
 {
-	unsigned char msgtxt[5];
-	int mpos = 0;
 	switch (msg->ctrl & LOG_TYPE_MASK) {
 	case LOG_TYPE_CHAR: {
 		uint32_t ch;
 		ch = msg->log_data;
 		while (ch != 0) {
-			msgtxt[mpos++] = ch&0xFF;
+			log_char(ch & 0xFF, msg->source);
 			ch >>= 8;
 		}
-		msgtxt[mpos] = 0;
-		log_str(msgtxt);
 		break;
 	}
 	case LOG_TYPE_INTEGER: {
-		dbg_raw_nro(msg->ctrl, msg->log_data);
+		dbg_raw_nro(msg->ctrl, msg->log_data, msg->source);
 		break;
 	}
 	default:
 		break;
 	}
 	if (msg->ctrl & LOG_EOL)
-		log_eol();
+		log_eol(msg->source);
 }
 
-/*----------------------------------------------------------------------------*/
+static uint32_t process_log(void)
+{
+	char *last_msg = log_buf->buff + log_buf->write_pos;
+	char *buff = log_buf->buff + log_pos;
+
+	while (buff != last_msg) {
+		log_msg((struct logmsg_struct *)buff);
+		buff += sizeof(struct logmsg_struct);
+		/* Wrap around */
+		if ((buff + sizeof(struct logmsg_struct)) >
+		    ((char *)log_buf + log_size))
+			buff = log_buf->buff;
+	}
+	return buff - log_buf->buff;
+}
+
+/* log_worker() - Worker thread processing the log_buf buffer. */
 static int log_worker(void *p)
 {
-	if (log_buf == NULL)
-		return -EFAULT;
-
-	/* The thread should have never started */
-	if (log_buf == NULL)
-		return -EFAULT;
+	int ret = 0;
+	if (log_buf == NULL) {
+		ret = -EFAULT;
+		goto err_kthread;
+	}
 
 	while (!kthread_should_stop()) {
 		if (log_buf->write_pos == log_pos)
 			schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
 
 		switch (log_buf->version) {
-		case 1:
-			log_pos = process_v1log();
-			break;
 		case 2:
-			log_pos = process_v2log();
+			log_pos = process_log();
 			break;
 		default:
-			MCDRV_DBG_ERROR("Unknown Mobicore log data "
-				"version %d logging disabled.",
-				log_buf->version);
+			MCDRV_DBG_ERROR(mcd, "Unknown Mobicore log data");
 			log_pos = log_buf->write_pos;
-			/* Stop the thread as we have no idea what
-			 * happens next */
-			return -EFAULT;
+			/*
+			 * Stop the thread as we have no idea what
+			 * happens next
+			 */
+			ret = -EFAULT;
+			goto err_kthread;
 		}
 	}
-	MCDRV_DBG("Logging thread stopped!");
-	return 0;
+err_kthread:
+	MCDRV_DBG(mcd, "Logging thread stopped!");
+	thread_err = ret;
+	/* Wait until the next kthread_stop() is called, if it was already
+	 * called we just slip through, if there is an error signal it and
+	 * wait to get the signal */
+	set_current_state(TASK_INTERRUPTIBLE);
+	while (!kthread_should_stop()) {
+		schedule();
+		set_current_state(TASK_INTERRUPTIBLE);
+	}
+	set_current_state(TASK_RUNNING);
+	return ret;
 }
 
-
-/*----------------------------------------------------------------------------*/
-/**
- * Wakeup the log reader thread
+/*
+ * Wake up the log reader thread
  * This should be called from the places where calls into MobiCore have
  * generated some logs(eg, yield, SIQ...)
  */
@@ -250,78 +234,105 @@
 	if (log_thread == NULL || IS_ERR(log_thread))
 		return;
 
+	/* The thread itself is in some error condition so just get
+	 * rid of it */
+	if (thread_err != 0) {
+		kthread_stop(log_thread);
+		log_thread = NULL;
+		return;
+	}
+
 	wake_up_process(log_thread);
 }
 
-/*----------------------------------------------------------------------------*/
-/**
- * Setup mobicore kernel log. It assumes it's running on CORE 0!
+/*
+ * Setup MobiCore kernel log. It assumes it's running on CORE 0!
  * The fastcall will complain is that is not the case!
  */
-long mobicore_log_setup(void *data)
+long mobicore_log_setup(void)
 {
 	unsigned long phys_log_buf;
 	union fc_generic fc_log;
+	struct sched_param param = { .sched_priority = 1 };
 
+	long ret;
 	log_pos = 0;
 	log_buf = NULL;
 	log_thread = NULL;
 	log_line = NULL;
+	log_line_len = 0;
+	prev_eol = false;
+	prev_source = 0;
+	thread_err = 0;
 
 	/* Sanity check for the log size */
 	if (log_size < PAGE_SIZE)
 		return -EFAULT;
 	else
-		log_size =
-			get_nr_of_pages_for_buffer(NULL, log_size) * PAGE_SIZE;
+		log_size = PAGE_ALIGN(log_size);
 
 	log_line = kzalloc(LOG_LINE_SIZE, GFP_KERNEL);
 	if (IS_ERR(log_line)) {
-		MCDRV_DBG_ERROR("failed to allocate log line!");
+		MCDRV_DBG_ERROR(mcd, "failed to allocate log line!");
 		return -ENOMEM;
 	}
 
-	log_thread = kthread_create(log_worker, NULL, "mobicore_log");
+	log_thread = kthread_create(log_worker, NULL, "mc_log");
 	if (IS_ERR(log_thread)) {
-		MCDRV_DBG_ERROR("mobicore log thread creation failed!");
-		return -EFAULT;
+		MCDRV_DBG_ERROR(mcd, "MobiCore log thread creation failed!");
+		ret = -EFAULT;
+		goto err_free_line;
 	}
 
-	log_pos = 0;
+	sched_setscheduler(log_thread, SCHED_IDLE, &param);
+	/*
+	 * We are going to map this buffer into virtual address space in SWd.
+	 * To reduce complexity there, we use a contiguous buffer.
+	 */
 	log_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
-					size_to_order(log_size));
+					   get_order(log_size));
 	if (!log_buf) {
-		MCDRV_DBG_ERROR("Failed to get page for logger!");
-		return -ENOMEM;
+		MCDRV_DBG_ERROR(mcd, "Failed to get page for logger!");
+		ret = -ENOMEM;
+		goto err_stop_kthread;
 	}
 	phys_log_buf = virt_to_phys(log_buf);
 
 	memset(&fc_log, 0, sizeof(fc_log));
-	fc_log.as_in.cmd      = MC_FC_NWD_TRACE;
+	fc_log.as_in.cmd = MC_FC_NWD_TRACE;
 	fc_log.as_in.param[0] = phys_log_buf;
 	fc_log.as_in.param[1] = log_size;
 
-	MCDRV_DBG("fc_log virt=%p phys=%p ", log_buf, (void *)phys_log_buf);
+	MCDRV_DBG(mcd, "fc_log virt=%p phys=%p ",
+		  log_buf, (void *)phys_log_buf);
 	mc_fastcall(&fc_log);
-	MCDRV_DBG("fc_log out ret=0x%08x", fc_log.as_out.ret);
+	MCDRV_DBG(mcd, "fc_log out ret=0x%08x", fc_log.as_out.ret);
+
 	/* If the setup failed we must free the memory allocated */
 	if (fc_log.as_out.ret) {
-		MCDRV_DBG_ERROR("MobiCore shared traces setup failed!");
-		kthread_stop(log_thread);
-		free_pages((unsigned long)log_buf, size_to_order(log_size));
-
+		MCDRV_DBG_ERROR(mcd, "MobiCore shared traces setup failed!");
+		free_pages((unsigned long)log_buf, get_order(log_size));
 		log_buf = NULL;
-		log_thread = NULL;
-		return -EIO;
+		ret = -EIO;
+		goto err_stop_kthread;
 	}
 
-	MCDRV_DBG("fc_log Logger version %u\n", log_buf->version);
+	set_task_state(log_thread, TASK_INTERRUPTIBLE);
+
+	MCDRV_DBG(mcd, "fc_log Logger version %u\n", log_buf->version);
 	return 0;
+
+err_stop_kthread:
+	kthread_stop(log_thread);
+	log_thread = NULL;
+err_free_line:
+	kfree(log_line);
+	log_line = NULL;
+	return ret;
 }
 
-/*----------------------------------------------------------------------------*/
-/**
- * Free kernel log componenets.
+/*
+ * Free kernel log components.
  * ATTN: We can't free the log buffer because it's also in use by MobiCore and
  * even if the module is unloaded MobiCore is still running.
  */
diff --git a/drivers/gud/mobicore_driver/logging.h b/drivers/gud/mobicore_driver/logging.h
new file mode 100644
index 0000000..ddb60fb
--- /dev/null
+++ b/drivers/gud/mobicore_driver/logging.h
@@ -0,0 +1,28 @@
+/*
+ * MobiCore driver module.(interface to the secure world SWD)
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * 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 _MC_LOGGING_H_
+#define _MC_LOGGING_H_
+
+/* MobiCore internal trace buffer structure. */
+struct mc_trace_buf {
+	uint32_t version; /* version of trace buffer */
+	uint32_t length; /* length of allocated buffer(includes header) */
+	uint32_t write_pos; /* last write position */
+	char  buff[1]; /* start of the log buffer */
+};
+
+/* MobiCore internal trace log setup. */
+void mobicore_log_read(void);
+long mobicore_log_setup(void);
+void mobicore_log_free(void);
+
+#endif /* _MC_LOGGING_H_ */
diff --git a/drivers/gud/mobicore_driver/main.c b/drivers/gud/mobicore_driver/main.c
index 8a8ea1e..a2b3ad7 100644
--- a/drivers/gud/mobicore_driver/main.c
+++ b/drivers/gud/mobicore_driver/main.c
@@ -1,1969 +1,810 @@
-/** MobiCore driver module.(interface to the secure world SWD)
- * @addtogroup MCD_MCDIMPL_KMOD_IMPL
- * @{
- * @file
+/*
  * MobiCore Driver Kernel Module.
- * This module is written as a Linux device driver.
+ *
  * This driver represents the command proxy on the lowest layer, from the
  * secure world to the non secure world, and vice versa.
- * This driver is located in the non secure world (Linux).
+
  * This driver offers IOCTL commands, for access to the secure world, and has
  * the interface from the secure world to the normal world.
  * The access to the driver is possible with a file descriptor,
- * which has to be created by the fd = open(/dev/mobicore) command.
+ * which has to be created by the fd = open(/dev/mobicore) command or
+ * fd = open(/dev/mobicore-user)
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * 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/miscdevice.h>
+#include <linux/interrupt.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/device.h>
 #include <linux/module.h>
-#include "mc_drv_module.h"
-#include "mc_drv_module_linux_api.h"
-#include "mc_drv_module_android.h"
-#include "mc_drv_module_fastcalls.h"
-#include "public/mc_kernel_api.h"
+#include <linux/ioctl.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/completion.h>
+#include <linux/fdtable.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
+#include <net/tcp_states.h>
+#include <net/af_unix.h>
 
-/* Initial value for the daemon sempahore signaling */
-#define DAEMON_SEM_VAL 0
+#include "main.h"
+#include "fastcall.h"
 
-/** MobiCore interrupt context data */
-static struct mc_drv_kmod_ctx	mc_drv_kmod_ctx;
+#include "arm.h"
+#include "mem.h"
+#include "ops.h"
+#include "pm.h"
+#include "debug.h"
+#include "logging.h"
 
-/** MobiCore MCI information */
-static uint32_t mci_base;
-/*
-#############################################################################
-##
-## Convenience functions for Linux API functions
-##
-#############################################################################*/
-static int goto_cpu0(void);
-static int goto_all_cpu(void) __attribute__ ((unused));
+/* Define a MobiCore device structure for use with dev_debug() etc */
+struct device_driver mcd_debug_name = {
+	.name = "mcdrvkmod"
+};
 
+struct device mcd_debug_subname = {
+	.init_name = "", /* Set to 'mcd' at mc_init() time */
+	.driver = &mcd_debug_name
+};
 
-/*----------------------------------------------------------------------------*/
-static void init_and_add_to_list(
-	struct list_head *item,
-	struct list_head *list_head
-)
+struct device *mcd = &mcd_debug_subname;
+
+#ifndef FMODE_PATH
+ #define FMODE_PATH 0x0
+#endif
+
+static struct sock *__get_socket(struct file *filp)
 {
-	INIT_LIST_HEAD(item);
+	struct sock *u_sock = NULL;
+	struct inode *inode = filp->f_path.dentry->d_inode;
 
-	list_add(item, list_head);
+	/*
+	 *	Socket ?
+	 */
+	if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) {
+		struct socket *sock = SOCKET_I(inode);
+		struct sock *s = sock->sk;
+
+		/*
+		 *	PF_UNIX ?
+		 */
+		if (s && sock->ops && sock->ops->family == PF_UNIX)
+			u_sock = s;
+	}
+	return u_sock;
 }
 
-/*----------------------------------------------------------------------------*/
-/** check if CPU supports the ARM TrustZone Security Extensions
- *	@return int TRUE or FALSE */
-static int has_security_extensions(
-	void
-)
+
+/* MobiCore interrupt context data */
+struct mc_context ctx;
+
+/* Get process context from file pointer */
+static struct mc_instance *get_instance(struct file *file)
 {
-	u32 fea = 0;
-	asm volatile(
-		"mrc p15, 0, %[fea], cr0, cr1, 0" :
-		[fea]"=r" (fea));
+	return (struct mc_instance *)(file->private_data);
+}
 
-	MCDRV_DBG_VERBOSE("CPU Features: 0x%X", fea);
+/* Get a unique ID */
+unsigned int get_unique_id(void)
+{
+	return (unsigned int)atomic_inc_return(&ctx.unique_counter);
+}
 
-	/* If the CPU features ID has 0 for security features then the CPU
-	 * doesn't support TrustZone at all!
-	 */
-	if ((fea & ARM_SECURITY_EXTENSION_MASK) == 0)
+/* Clears the reserved bit of each page and frees the pages */
+static inline void free_continguous_pages(void *addr, unsigned int order)
+{
+	int i;
+	struct page *page = virt_to_page(addr);
+	for (i = 0; i < (1<<order); i++) {
+		MCDRV_DBG_VERBOSE(mcd, "free page at 0x%p\n", page);
+		ClearPageReserved(page);
+		page++;
+	}
+
+	MCDRV_DBG_VERBOSE(mcd, "freeing addr:%p, order:%x\n", addr, order);
+	free_pages((unsigned long)addr, order);
+}
+
+/* Frees the memory associated with a buffer */
+static int free_buffer(struct mc_buffer *buffer, bool unlock)
+{
+	if (buffer->handle == 0)
+		return -EINVAL;
+
+	if (buffer->addr == 0)
+		return -EINVAL;
+
+	MCDRV_DBG_VERBOSE(mcd,
+			  "handle=%u phys_addr=0x%p, virt_addr=0x%p len=%u\n",
+		  buffer->handle, buffer->phys, buffer->addr, buffer->len);
+
+	if (!atomic_dec_and_test(&buffer->usage)) {
+		MCDRV_DBG_VERBOSE(mcd, "Could not free %u", buffer->handle);
+		return 0;
+	}
+
+	list_del(&buffer->list);
+
+	free_continguous_pages(buffer->addr, buffer->order);
+	kfree(buffer);
+	return 0;
+}
+
+static uint32_t mc_find_cont_wsm_addr(struct mc_instance *instance, void *uaddr,
+	uint32_t *addr, uint32_t len)
+{
+	int ret = 0;
+	struct mc_buffer *buffer;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	mutex_lock(&instance->lock);
+
+	mutex_lock(&ctx.bufs_lock);
+
+	/* search for the given handle in the buffers list */
+	list_for_each_entry(buffer, &ctx.cont_bufs, list) {
+		if (buffer->uaddr == uaddr && buffer->len == len) {
+			*addr = (uint32_t)buffer->addr;
+			goto found;
+		}
+	}
+
+	/* Coundn't find the buffer */
+	ret = -EINVAL;
+
+found:
+	mutex_unlock(&ctx.bufs_lock);
+	mutex_unlock(&instance->lock);
+
+	return ret;
+}
+
+bool mc_check_owner_fd(struct mc_instance *instance, int32_t fd)
+{
+#ifndef __ARM_VE_A9X4_STD__
+	struct file *fp;
+	struct sock *s;
+	struct files_struct *files;
+	struct task_struct *peer = NULL;
+	bool ret = false;
+
+	MCDRV_DBG(mcd, "Finding wsm for fd = %d\n", fd);
+	if (!instance)
+		return false;
+
+	if (is_daemon(instance))
+		return true;
+
+	fp = fcheck_files(current->files, fd);
+	s = __get_socket(fp);
+	if (s) {
+		peer = get_pid_task(s->sk_peer_pid, PIDTYPE_PID);
+		MCDRV_DBG(mcd, "Found pid for fd %d\n", peer->pid);
+	}
+	if (peer) {
+		task_lock(peer);
+		files = peer->files;
+		if (!files)
+			goto out;
+		for (fd = 0; fd < files_fdtable(files)->max_fds; fd++) {
+			fp = fcheck_files(files, fd);
+			if (!fp)
+				continue;
+			if (fp->private_data == instance) {
+				MCDRV_DBG(mcd, "Found owner!");
+				ret = true;
+				goto out;
+			}
+
+		}
+	} else {
+		MCDRV_DBG(mcd, "Owner not found!");
+		return false;
+	}
+out:
+	if (peer)
+		task_unlock(peer);
+	if (!ret)
+		MCDRV_DBG(mcd, "Owner not found!");
+	return ret;
+#else
+	return true;
+#endif
+}
+static uint32_t mc_find_cont_wsm(struct mc_instance *instance, uint32_t handle,
+	int32_t fd, uint32_t *phys, uint32_t *len)
+{
+	int ret = 0;
+	struct mc_buffer *buffer;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	if (WARN_ON(!is_daemon(instance))) {
+		MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon\n");
+		return -EPERM;
+	}
+
+	mutex_lock(&instance->lock);
+
+	mutex_lock(&ctx.bufs_lock);
+
+	/* search for the given handle in the buffers list */
+	list_for_each_entry(buffer, &ctx.cont_bufs, list) {
+		if (buffer->handle == handle) {
+			if (mc_check_owner_fd(buffer->instance, fd)) {
+				*phys = (uint32_t)buffer->phys;
+				*len = buffer->len;
+				goto found;
+			} else {
+				break;
+			}
+		}
+	}
+
+	/* Couldn't find the buffer */
+	ret = -EINVAL;
+
+found:
+	mutex_unlock(&ctx.bufs_lock);
+	mutex_unlock(&instance->lock);
+
+	return ret;
+}
+
+/*
+ * __free_buffer - Free a WSM buffer allocated with mobicore_allocate_wsm
+ *
+ * @instance
+ * @handle		handle of the buffer
+ *
+ * Returns 0 if no error
+ *
+ */
+static int __free_buffer(struct mc_instance *instance, uint32_t handle,
+		bool unlock)
+{
+	int ret = 0;
+	struct mc_buffer *buffer;
+	void *uaddr = NULL;
+	size_t len = 0;
+#ifndef MC_VM_UNMAP
+	struct mm_struct *mm = current->mm;
+#endif
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	mutex_lock(&ctx.bufs_lock);
+	/* search for the given handle in the buffers list */
+	list_for_each_entry(buffer, &ctx.cont_bufs, list) {
+		if (buffer->handle == handle) {
+			uaddr = buffer->uaddr;
+			len = buffer->len;
+			goto found_buffer;
+		}
+	}
+	ret = -EINVAL;
+	goto err;
+found_buffer:
+	if (!is_daemon(instance) && buffer->instance != instance) {
+		ret = -EPERM;
+		goto err;
+	}
+	mutex_unlock(&ctx.bufs_lock);
+	/* Only unmap if the request is comming from the user space and
+	 * it hasn't already been unmapped */
+	if (unlock == false && uaddr != NULL) {
+#ifndef MC_VM_UNMAP
+		/* do_munmap must be done with mm->mmap_sem taken */
+		down_write(&mm->mmap_sem);
+		ret = do_munmap(mm, (long unsigned int)uaddr, len);
+		up_write(&mm->mmap_sem);
+
+#else
+		ret = vm_munmap((long unsigned int)uaddr, len);
+#endif
+		if (ret < 0) {
+			/* Something is not right if we end up here, better not
+			 * clean the buffer so we just leak memory instead of
+			 * creating security issues */
+			MCDRV_DBG_ERROR(mcd, "Memory can't be unmapped\n");
+			return -EINVAL;
+		}
+	}
+
+	mutex_lock(&ctx.bufs_lock);
+	/* search for the given handle in the buffers list */
+	list_for_each_entry(buffer, &ctx.cont_bufs, list) {
+		if (buffer->handle == handle)
+			goto del_buffer;
+	}
+	ret = -EINVAL;
+	goto err;
+
+del_buffer:
+	if (is_daemon(instance) || buffer->instance == instance)
+		ret = free_buffer(buffer, unlock);
+	else
+		ret = -EPERM;
+err:
+	mutex_unlock(&ctx.bufs_lock);
+	return ret;
+}
+
+int mc_free_buffer(struct mc_instance *instance, uint32_t handle)
+{
+	int ret = 0;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	mutex_lock(&instance->lock);
+
+	ret = __free_buffer(instance, handle, false);
+	mutex_unlock(&instance->lock);
+	return ret;
+}
+
+
+int mc_get_buffer(struct mc_instance *instance,
+	struct mc_buffer **buffer, unsigned long len)
+{
+	struct mc_buffer *cbuffer = NULL;
+	void *addr = 0;
+	void *phys = 0;
+	unsigned int order;
+	unsigned long allocated_size;
+	int ret = 0;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	if (len == 0) {
+		MCDRV_DBG_WARN(mcd, "cannot allocate size 0\n");
+		return -ENOMEM;
+	}
+
+	order = get_order(len);
+	if (order > MAX_ORDER) {
+		MCDRV_DBG_WARN(mcd, "Buffer size too large\n");
+		return -ENOMEM;
+	}
+	allocated_size = (1 << order) * PAGE_SIZE;
+
+	if (mutex_lock_interruptible(&instance->lock))
+		return -ERESTARTSYS;
+
+	/* allocate a new buffer. */
+	cbuffer = kzalloc(sizeof(struct mc_buffer), GFP_KERNEL);
+
+	if (cbuffer == NULL) {
+		MCDRV_DBG_WARN(mcd,
+			       "MMAP_WSM request: could not allocate buffer\n");
+		ret = -ENOMEM;
+		goto unlock_instance;
+	}
+	mutex_lock(&ctx.bufs_lock);
+
+	MCDRV_DBG_VERBOSE(mcd, "size %ld -> order %d --> %ld (2^n pages)\n",
+			  len, order, allocated_size);
+
+	addr = (void *)__get_free_pages(GFP_USER | __GFP_ZERO, order);
+
+	if (addr == NULL) {
+		MCDRV_DBG_WARN(mcd, "get_free_pages failed\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+	phys = (void *)virt_to_phys(addr);
+	cbuffer->handle = get_unique_id();
+	cbuffer->phys = phys;
+	cbuffer->addr = addr;
+	cbuffer->order = order;
+	cbuffer->len = len;
+	cbuffer->instance = instance;
+	cbuffer->uaddr = 0;
+	/* Refcount +1 because the TLC is requesting it */
+	atomic_set(&cbuffer->usage, 1);
+
+	INIT_LIST_HEAD(&cbuffer->list);
+	list_add(&cbuffer->list, &ctx.cont_bufs);
+
+	MCDRV_DBG_VERBOSE(mcd,
+			  "allocated phys=0x%p - 0x%p, size=%ld, kvirt=0x%p, h=%d\n",
+		  phys, (void *)((unsigned int)phys+allocated_size),
+		  allocated_size, addr, cbuffer->handle);
+	*buffer = cbuffer;
+	goto unlock;
+
+err:
+	kfree(cbuffer);
+unlock:
+	mutex_unlock(&ctx.bufs_lock);
+unlock_instance:
+	mutex_unlock(&instance->lock);
+	return ret;
+}
+
+/*
+ * __lock_buffer() - Locks a contiguous buffer - +1 refcount.
+ * Assumes the instance lock is already taken!
+ */
+static int __lock_buffer(struct mc_instance *instance, uint32_t handle)
+{
+	int ret = 0;
+	struct mc_buffer *buffer;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	if (WARN_ON(!is_daemon(instance))) {
+		MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon\n");
+		return -EPERM;
+	}
+
+	mutex_lock(&ctx.bufs_lock);
+	/* search for the given handle in the buffers list */
+	list_for_each_entry(buffer, &ctx.cont_bufs, list) {
+		if (buffer->handle == handle) {
+			atomic_inc(&buffer->usage);
+			goto unlock;
+		}
+	}
+	ret = -EINVAL;
+
+unlock:
+	mutex_unlock(&ctx.bufs_lock);
+	return ret;
+}
+
+void *get_mci_base_phys(unsigned int len)
+{
+	if (ctx.mci_base.phys) {
+		return ctx.mci_base.phys;
+	} else {
+		unsigned int order = get_order(len);
+		ctx.mcp = NULL;
+		ctx.mci_base.order = order;
+		ctx.mci_base.addr =
+			(void *)__get_free_pages(GFP_USER | __GFP_ZERO, order);
+		if (ctx.mci_base.addr == NULL) {
+			MCDRV_DBG_WARN(mcd, "get_free_pages failed\n");
+			memset(&ctx.mci_base, 0, sizeof(ctx.mci_base));
+			return NULL;
+		}
+		ctx.mci_base.phys = (void *)virt_to_phys(ctx.mci_base.addr);
+		return ctx.mci_base.phys;
+	}
+}
+
+/*
+ * Create a l2 table from a virtual memory buffer which can be vmalloc
+ * or user space virtual memory
+ */
+int mc_register_wsm_l2(struct mc_instance *instance,
+	uint32_t buffer, uint32_t len,
+	uint32_t *handle, uint32_t *phys)
+{
+	int ret = 0;
+	struct mc_l2_table *table = NULL;
+	struct task_struct *task = current;
+	uint32_t kbuff = 0x0;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	if (len == 0) {
+		MCDRV_DBG_ERROR(mcd, "len=0 is not supported!\n");
+		return -EINVAL;
+	}
+
+	MCDRV_DBG_VERBOSE(mcd, "buffer: %p, len=%08x\n", (void *)buffer, len);
+
+	if (!mc_find_cont_wsm_addr(instance, (void *)buffer, &kbuff, len))
+		table = mc_alloc_l2_table(instance, NULL, (void *)kbuff, len);
+	else
+		table = mc_alloc_l2_table(instance, task, (void *)buffer, len);
+
+	if (IS_ERR(table)) {
+		MCDRV_DBG_ERROR(mcd, "new_used_l2_table() failed\n");
+		return -EINVAL;
+	}
+
+	/* set response */
+	*handle = table->handle;
+	/* WARNING: daemon shouldn't know this either, but live with it */
+	if (is_daemon(instance))
+		*phys = (uint32_t)table->phys;
+	else
+		*phys = 0;
+
+	MCDRV_DBG_VERBOSE(mcd, "handle: %d, phys=%p\n",
+			  *handle, (void *)*phys);
+
+	MCDRV_DBG_VERBOSE(mcd, "exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+int mc_unregister_wsm_l2(struct mc_instance *instance, uint32_t handle)
+{
+	int ret = 0;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	/* free table (if no further locks exist) */
+	mc_free_l2_table(instance, handle);
+
+	return ret;
+}
+/* Lock the object from handle, it could be a WSM l2 table or a cont buffer! */
+static int mc_lock_handle(struct mc_instance *instance, uint32_t handle)
+{
+	int ret = 0;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	if (WARN_ON(!is_daemon(instance))) {
+		MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon\n");
+		return -EPERM;
+	}
+
+	mutex_lock(&instance->lock);
+	ret = mc_lock_l2_table(instance, handle);
+
+	/* Handle was not a l2 table but a cont buffer */
+	if (ret == -EINVAL) {
+		/* Call the non locking variant! */
+		ret = __lock_buffer(instance, handle);
+	}
+
+	mutex_unlock(&instance->lock);
+
+	return ret;
+}
+
+static int mc_unlock_handle(struct mc_instance *instance, uint32_t handle)
+{
+	int ret = 0;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	if (WARN_ON(!is_daemon(instance))) {
+		MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon\n");
+		return -EPERM;
+	}
+
+	mutex_lock(&instance->lock);
+	ret = mc_free_l2_table(instance, handle);
+
+	/* Not a l2 table, then it must be a buffer */
+	if (ret == -EINVAL) {
+		/* Call the non locking variant! */
+		ret = __free_buffer(instance, handle, true);
+	}
+	mutex_unlock(&instance->lock);
+
+	return ret;
+}
+
+static uint32_t mc_find_wsm_l2(struct mc_instance *instance,
+	uint32_t handle, int32_t fd)
+{
+	uint32_t ret = 0;
+
+	if (WARN(!instance, "No instance data available"))
 		return 0;
 
-	return 1;
+	if (WARN_ON(!is_daemon(instance))) {
+		MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon\n");
+		return 0;
+	}
+
+	ret = mc_find_l2_table(handle, fd);
+
+	return ret;
 }
 
-/*----------------------------------------------------------------------------*/
-/** check if running in secure mode
- *	@return int TRUE or FALSE */
-static int is_secure_mode(
-	void
-)
+static int mc_clean_wsm_l2(struct mc_instance *instance)
 {
-	u32 cpsr = 0, nsacr = 0;
-	asm volatile(
-		"mrc	p15, 0, %[nsacr], cr1, cr1, 2\n"
-		"mrs %[cpsr], cpsr\n" :
-		[nsacr]"=r" (nsacr),
-		[cpsr]"=r"(cpsr));
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
 
-	MCDRV_DBG_VERBOSE("CPRS.M = set to 0x%X\n", cpsr & ARM_CPSR_MASK);
-	MCDRV_DBG_VERBOSE("SCR.NS = set to 0x%X\n", nsacr);
+	if (WARN_ON(!is_daemon(instance))) {
+		MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon\n");
+		return -EPERM;
+	}
 
-	/* If the NSACR contains the reset value(=0) then most likely we are
-	 * running in Secure MODE.
-	 * If the cpsr mode is set to monitor mode then we cannot load!
-	 */
-	if (nsacr == 0 || ((cpsr & ARM_CPSR_MASK) == ARM_MONITOR_MODE))
-		return 1;
+	mc_clean_l2_tables();
 
 	return 0;
 }
 
-/*----------------------------------------------------------------------------*/
-/** check if userland caller is privileged (aka has "root" access rights).
-	@return int TRUE or FALSE */
-static int is_userland_caller_privileged(
-	void
-) {
-	/* For some platforms we cannot run the Daemon as root - for Android
-	 * compliance tests it is not allowed, thus we assume the daemon is ran
-	 * as the system user.
-	 * In Android the system user for daemons has no particular capabilities
-	 * other than a fixed UID: AID_SYSTEM 1000
-	 * The actual number is guaranteed to be the same in all Android systems
-	 * so we will take it for granted: see android_filesystem_config.h in
-	 * the Android source tree for all UIDs and their meaning:
-	 * http://android-dls.com/wiki/index.php?title=Android_UIDs_and_GIDs
-	 */
-#ifdef MC_ANDROID_UID_CHECK
-	return current_euid() <= AID_SYSTEM;
-#else
-	/* capable should cover all possibilities, root or sudo, uid checking
-	 * was not very reliable */
-	return capable(CAP_SYS_ADMIN);
-#endif
-}
-
-
-
-/*----------------------------------------------------------------------------*/
-static void unlock_page_from_used_l2_table(
-	struct page *page
-){
-	/* REV axh: check if we should do this. */
-	SetPageDirty(page);
-
-	/* release page, old api was page_cache_release() */
-	ClearPageReserved(page);
-	put_page(page);
-}
-
-/*----------------------------------------------------------------------------*/
-/* convert L2 PTE to page pointer */
-static struct page *l2_pte_to_page(
-	pte_t pte
-) {
-	void *phys_page_addr	= (void *)((unsigned int)pte & PAGE_MASK);
-	unsigned int pfn	= addr_to_pfn(phys_page_addr);
-	struct page *page	= pfn_to_page(pfn);
-	return page;
-}
-
-/*----------------------------------------------------------------------------*/
-/* convert page pointer to L2 PTE */
-static pte_t page_to_l2_pte(
-	struct page *page
-)
+static int mc_fd_mmap(struct file *file, struct vm_area_struct *vmarea)
 {
-	unsigned int pfn	= page_to_pfn(page);
-	void *phys_addr		= pfn_to_addr(pfn);
-	pte_t pte		= (pte_t)((unsigned int)phys_addr & PAGE_MASK);
-	return pte;
-}
-
-
-/*----------------------------------------------------------------------------*/
-static inline int lock_user_pages(
-	struct task_struct	*task,
-	void			*virt_start_page_addr,
-	int			nr_of_pages,
-	struct page		**pages
-)
-{
-	int		ret = 0;
-	int		locked_pages = 0;
-	unsigned int	i;
-
-	do {
-
-		/* lock user pages, must hold the mmap_sem to do this. */
-		down_read(&(task->mm->mmap_sem));
-		locked_pages = get_user_pages(
-					  task,
-					  task->mm,
-					  (unsigned long)virt_start_page_addr,
-					  nr_of_pages,
-					  1, /* write access */
-					  0, /* they say drivers should always
-						pass 0 here..... */
-					  pages,
-					  NULL); /* we don't need the VMAs */
-		up_read(&(task->mm->mmap_sem));
-
-		/* could as lock all pages? */
-		if (locked_pages != nr_of_pages) {
-			MCDRV_DBG_ERROR(
-				"get_user_pages() failed, "
-				"locked_pages=%d\n",
-				locked_pages);
-			ret = -ENOMEM;
-			/* check if an error has been returned. */
-			if (locked_pages < 0) {
-				ret = locked_pages;
-				locked_pages = 0;
-			}
-			break;
-		}
-
-		/* do cache maintenance on locked pages. */
-		for (i = 0; i < nr_of_pages; i++)
-			flush_dcache_page(pages[i]);
-
-	} while (FALSE);
-
-
-	if (ret != 0) {
-		/* release all locked pages. */
-		MCDRV_ASSERT(locked_pages >= 0);
-		for (i = 0; i < locked_pages; i++)
-			put_page(pages[i]);
-	}
-
-	return ret;
-
-}
-
-/*
-#############################################################################
-##
-## Driver implementation functions
-##
-#############################################################################*/
-/*----------------------------------------------------------------------------*/
-/* check if caller is MobiCore Daemon */
-static unsigned int is_caller_mc_daemon(
-	struct mc_instance *instance
-)
-{
-	return ((instance != NULL)
-		&& (mc_drv_kmod_ctx.daemon_inst == instance));
-}
-
-
-/*----------------------------------------------------------------------------*/
-/* Get process context from file pointer */
-static struct mc_instance *get_instance(
-	struct file *file
-) {
-	MCDRV_ASSERT(file != NULL);
-
-	return (struct mc_instance *)(file->private_data);
-}
-
-
-/*----------------------------------------------------------------------------*/
-/* Get a unique ID */
-static unsigned int get_mc_kmod_unique_id(
-	void
-)
-{
-	return (unsigned int)atomic_inc_return(
-			   &(mc_drv_kmod_ctx.unique_counter));
-}
-
-
-/*----------------------------------------------------------------------------*/
-/* Get kernel pointer to shared L2 table given a per-process reference */
-static struct l2table *get_l2_table_kernel_virt(
-	struct mc_used_l2_table	*used_l2table
-)
-{
-	MCDRV_ASSERT(used_l2table != NULL);
-	MCDRV_ASSERT(used_l2table->set != NULL);
-	MCDRV_ASSERT(used_l2table->set->kernel_virt != NULL);
-	return &(used_l2table->set->kernel_virt->table[used_l2table->idx]);
-}
-
-/*----------------------------------------------------------------------------*/
-/* Get physical address of a shared L2 table given a per-process reference */
-static struct l2table *get_l2_table_phys(
-	struct mc_used_l2_table  *used_l2table
-)
-{
-	MCDRV_ASSERT(used_l2table != NULL);
-	MCDRV_ASSERT(used_l2table->set != NULL);
-	MCDRV_ASSERT(used_l2table->set->phys != NULL);
-	return &(used_l2table->set->phys->table[used_l2table->idx]);
-}
-
-/*----------------------------------------------------------------------------*/
-static unsigned int is_in_use_used_l2_table(
-	struct mc_used_l2_table	*used_l2table
-)
-{
-	return ((used_l2table->flags &
-			  (MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP
-			   | MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC)) != 0);
-}
-
-
-
-/*----------------------------------------------------------------------------*/
-static struct mc_used_l2_table *find_used_l2_table_by_handle(
-	unsigned int	handle
-) {
-	struct mc_used_l2_table  *used_l2table;
-	struct mc_used_l2_table  *used_l2table_with_handle = NULL;
-
-	list_for_each_entry(
-		used_l2table,
-		&(mc_drv_kmod_ctx.mc_used_l2_tables),
-		list
-	) {
-		if (handle == used_l2table->handle) {
-			used_l2table_with_handle = used_l2table;
-			break;
-		}
-	}
-
-	return used_l2table_with_handle;
-}
-
-/*
-#############################################################################
-##
-## L2 Table Pool
-##
-#############################################################################*/
-
-/*----------------------------------------------------------------------------*/
-static struct mc_used_l2_table *allocate_used_l2_table(
-	struct mc_instance	*instance
-) {
-	int				ret = 0;
-	struct mc_l2_table_store	*l2table_store = NULL;
-	struct mc_l2_tables_set		*l2table_set = NULL;
-	struct mc_used_l2_table		*used_l2table = NULL;
-	struct page			*page;
-	unsigned int			i = 0;
-
-	do {
-		/* allocate a WSM L2 descriptor */
-		used_l2table  = kmalloc(sizeof(*used_l2table), GFP_KERNEL);
-		if (used_l2table == NULL) {
-			ret = -ENOMEM;
-			MCDRV_DBG_ERROR("out of memory\n");
-			break;
-		}
-		/* clean */
-		memset(used_l2table, 0, sizeof(*used_l2table));
-		used_l2table->handle = get_mc_kmod_unique_id();
-		used_l2table->owner = instance;
-
-		/* add to global list. */
-		init_and_add_to_list(
-			&(used_l2table->list),
-			&(mc_drv_kmod_ctx.mc_used_l2_tables));
-
-		/* walk though list to find free set. */
-		list_for_each_entry(
-			l2table_set,
-			&(mc_drv_kmod_ctx.mc_l2_tables_sets),
-			list
-		) {
-			for (i = 0; i < MC_DRV_KMOD_L2_TABLE_PER_PAGES; i++) {
-				if ((l2table_set->usage_bitmap & (1U << i))
-					== 0) {
-					/* found a set,
-						l2table_set and i are set. */
-					l2table_store =
-						l2table_set->kernel_virt;
-					break;
-				}
-			}
-			if (l2table_store != NULL)
-				break;
-		} /* end while */
-
-		if (l2table_store == NULL) {
-			l2table_store = (struct mc_l2_table_store *)
-						get_zeroed_page(GFP_KERNEL);
-			if (l2table_store == NULL) {
-				ret = -ENOMEM;
-				break;
-			}
-
-			/* Actually, locking is not necessary, because kernel
-				memory is not supposed to get swapped out. But
-				we play safe.... */
-			page = virt_to_page(l2table_store);
-			SetPageReserved(page);
-
-			/* allocate a descriptor */
-			l2table_set = kmalloc(sizeof(*l2table_set), GFP_KERNEL);
-			if (l2table_set == NULL) {
-				kfree(l2table_store);
-				ret = -ENOMEM;
-				break;
-			}
-			/* initialize */
-			memset(l2table_set, 0, sizeof(*l2table_set));
-
-			l2table_set->kernel_virt = l2table_store;
-			l2table_set->page = page;
-			l2table_set->phys = (void *)virt_to_phys(l2table_store);
-
-			/* init add to list. */
-			init_and_add_to_list(
-				&(l2table_set->list),
-				&(mc_drv_kmod_ctx.mc_l2_tables_sets));
-
-			/* use first table */
-			i = 0;
-		}
-
-		/* set set usage */
-		l2table_set->usage_bitmap |= (1U << i);
-
-		/* set set reference */
-		used_l2table->set = l2table_set;
-		used_l2table->idx = i;
-
-		MCDRV_DBG_VERBOSE(
-			"chunkPhys=%p,idx=%d\n",
-			l2table_set->phys, i);
-
-	} while (FALSE);
-
-	if (ret != 0) {
-		if (used_l2table != NULL) {
-			/* remove from list */
-			list_del(&(l2table_set->list));
-			/* free memory */
-			kfree(used_l2table);
-			used_l2table = NULL;
-		}
-	}
-
-	return used_l2table;
-}
-
-/*----------------------------------------------------------------------------*/
-static void free_used_l2_table(
-	struct mc_used_l2_table *used_l2table
-)
-{
-	struct mc_l2_tables_set	*l2table_set;
-	unsigned int		idx;
-
-	MCDRV_ASSERT(used_l2table != NULL);
-
-	l2table_set = used_l2table->set;
-	MCDRV_ASSERT(l2table_set != NULL);
-
-	/* clean usage flag */
-	idx = used_l2table->idx;
-	MCDRV_ASSERT(idx < MC_DRV_KMOD_L2_TABLE_PER_PAGES);
-	l2table_set->usage_bitmap &= ~(1U << idx);
-
-	/* if nobody uses this set, we can release it. */
-	if (l2table_set->usage_bitmap == 0) {
-		MCDRV_ASSERT(l2table_set->page != NULL);
-		ClearPageReserved(l2table_set->page);
-
-		MCDRV_ASSERT(l2table_set->kernel_virt != NULL);
-		free_page((unsigned long)l2table_set->kernel_virt);
-
-		/* remove from list */
-		list_del(&(l2table_set->list));
-
-		/* free memory */
-		kfree(l2table_set);
-	}
-
-	return;
-}
-
-
-
-/*----------------------------------------------------------------------------*/
-/**
- * Create a L2 table in a WSM container that has been allocates previously.
- *
- * @param task		pointer to task owning WSM
- * @param wsm_buffer	user space WSM start
- * @param wsm_len	WSM length
- * @param used_l2table	Pointer to L2 table details
- */
-static int map_buffer_into_used_l2_table(
-	struct task_struct	*task,
-	void			*wsm_buffer,
-	unsigned int		wsm_len,
-	struct mc_used_l2_table	*used_l2table
-)
-{
-	int		ret = 0;
-	unsigned int	i, nr_of_pages;
-	void		*virt_addr_page;
-	struct page	*page;
-	struct l2table	*l2table;
-	struct page	**l2table_as_array_of_pointers_to_page;
-
-	/* task can be null when called from kernel space */
-	MCDRV_ASSERT(wsm_buffer != NULL);
-	MCDRV_ASSERT(wsm_len != 0);
-	MCDRV_ASSERT(used_l2table != NULL);
-
-	MCDRV_DBG_VERBOSE("WSM addr=0x%p, len=0x%08x\n", wsm_buffer, wsm_len);
-
-	/* Check if called from kernel space wsm_buffer is actually
-	 * vmalloced or not */
-	if (task == NULL && !is_vmalloc_addr(wsm_buffer)) {
-		MCDRV_DBG_ERROR("WSM addr is not a vmalloc address");
-		return -EINVAL;
-	}
-
-	l2table = get_l2_table_kernel_virt(used_l2table);
-	/* We use the memory for the L2 table to hold the pointer
-	and convert them later. This works, as everything comes
-	down to a 32 bit value. */
-	l2table_as_array_of_pointers_to_page = (struct page **)l2table;
-
-	do {
-
-		/* no size > 1Mib supported */
-		if (wsm_len > SZ_1M) {
-			MCDRV_DBG_ERROR("size > 1 MiB\n");
-			ret = -EINVAL;
-			break;
-		}
-
-		/* calculate page usage */
-		virt_addr_page = get_page_start(wsm_buffer);
-		nr_of_pages  = get_nr_of_pages_for_buffer(wsm_buffer, wsm_len);
-
-
-		MCDRV_DBG_VERBOSE("virt addr pageStart=0x%p,pages=%d\n",
-				  virt_addr_page,
-				  nr_of_pages);
-
-		/* L2 table can hold max 1MiB in 256 pages. */
-		if ((nr_of_pages*PAGE_SIZE) > SZ_1M) {
-			MCDRV_DBG_ERROR("WSM paged exceed 1 MiB\n");
-			ret = -EINVAL;
-			break;
-		}
-
-		/* Request comes from user space */
-		if (task != NULL) {
-			/* lock user page in memory, so they do not get swapped
-			* out.
-			* REV axh:
-			* Kernel 2.6.27 added a new get_user_pages_fast()
-			* function, maybe it is called fast_gup() in some
-			* versions.
-			* handle user process doing a fork().
-			* Child should not get things.
-			* http://osdir.com/ml/linux-media/2009-07/msg00813.html
-			* http://lwn.net/Articles/275808/ */
-
-			ret = lock_user_pages(
-					  task,
-					  virt_addr_page,
-					  nr_of_pages,
-					  l2table_as_array_of_pointers_to_page);
-			if (ret != 0) {
-				MCDRV_DBG_ERROR("lock_user_pages() failed\n");
-				break;
-			}
-		}
-		/* Request comes from kernel space(vmalloc buffer) */
-		else {
-			void *uaddr = wsm_buffer;
-			for (i = 0; i < nr_of_pages; i++) {
-				page = vmalloc_to_page(uaddr);
-				if (!page) {
-					MCDRV_DBG_ERROR(
-						"vmalloc_to_Page()"
-						" failed to map address\n");
-					ret = -EINVAL;
-					break;
-				}
-				get_page(page);
-				/* Lock the page in memory, it can't be swapped
-				 * out */
-				SetPageReserved(page);
-				l2table_as_array_of_pointers_to_page[i] = page;
-				uaddr += PAGE_SIZE;
-			}
-		}
-
-		used_l2table->nr_of_pages = nr_of_pages;
-		used_l2table->flags |= MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP;
-
-		/* create L2 Table entries. used_l2table->table contains a list
-		of page pointers here. For a proper cleanup we have to ensure
-		that the following code either works and used_l2table contains
-		a valid L2 table - or fails and used_l2table->table contains the
-		list of page pointers. Any mixed contents will make cleanup
-		difficult.*/
-
-		for (i = 0; i < nr_of_pages; i++) {
-			pte_t pte;
-			page = l2table_as_array_of_pointers_to_page[i];
-
-			/* create L2 table entry, see ARM MMU docu for details
-			about flags stored in the lowest 12 bits. As a side
-			reference, the Article "ARM's multiply-mapped memory
-			mess" found in the collection at at
-			http://lwn.net/Articles/409032/ is also worth reading.*/
-			pte = page_to_l2_pte(page)
-					| L2_FLAG_AP1 | L2_FLAG_AP0
-					| L2_FLAG_C | L2_FLAG_B
-					| L2_FLAG_SMALL | L2_FLAG_SMALL_XN
-			/* Linux uses different mappings for SMP systems(the
-			 * sharing flag is set for the pte. In order not to
-			 * confuse things too much in Mobicore make sure the
-			 * shared buffers have the same flags.
-			 * This should also be done in SWD side
-			 */
-#ifdef CONFIG_SMP
-					| L2_FLAG_S | L2_FLAG_SMALL_TEX0
-#endif
-				  ;
-
-			l2table->table_entries[i] = pte;
-			MCDRV_DBG_VERBOSE("L2 entry %d:  0x%08x\n", i,
-					  (unsigned int)(pte));
-		}
-
-		/* ensure rest of table is empty */
-		while (i < 255)
-			l2table->table_entries[i++] = (pte_t)0;
-
-	} while (FALSE);
-
-	return ret;
-}
-
-
-/*----------------------------------------------------------------------------*/
-/**
- * Remove a L2 table in a WSM container. Afterwards the container may be
- * released.
- *
- * @param used_l2table	Pointer to L2 table details
- */
-
-static void unmap_buffers_from_used_l2_table(
-	struct mc_used_l2_table	*used_l2table
-)
-{
-	unsigned int	i;
-	struct l2table	*l2table;
-
-	MCDRV_ASSERT(used_l2table != NULL);
-	/* this should not happen, as we have no empty tables. */
-	MCDRV_ASSERT(!is_in_use_used_l2_table(used_l2table));
-
-	/* found the table, now release the resources. */
-	MCDRV_DBG_VERBOSE("clear L2 table, phys_base=%p, nr_of_pages=%d\n",
-			  get_l2_table_phys(used_l2table),
-			  used_l2table->nr_of_pages);
-
-	l2table = get_l2_table_kernel_virt(used_l2table);
-
-	/* release all locked user space pages */
-	for (i = 0; i < used_l2table->nr_of_pages; i++) {
-		/* convert physical entries from L2 table to page pointers */
-		pte_t pte = get_l2_table_kernel_virt(used_l2table)->
-							table_entries[i];
-		struct page *page = l2_pte_to_page(pte);
-		unlock_page_from_used_l2_table(page);
-	}
-
-	/* remember that all pages have been freed */
-	used_l2table->nr_of_pages = 0;
-
-	return;
-}
-
-
-/*
-#############################################################################
-##
-## Helper functions
-##
-#############################################################################*/
-/*----------------------------------------------------------------------------*/
-#define FREE_FROM_SWD	TRUE
-#define FREE_FROM_NWD	FALSE
-/** Delete a used l2 table. */
-static void delete_used_l2_table(
-	struct mc_used_l2_table	*used_l2table,
-	unsigned int		is_swd
-)
-{
-	if (is_swd) {
-		used_l2table->flags &=
-			~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
-	} else {
-		used_l2table->flags &=
-			~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP;
-		used_l2table->owner = NULL;
-	}
-
-	/* release if Nwd and Swd/MC do no longer use it. */
-	if (is_in_use_used_l2_table(used_l2table)) {
-		MCDRV_DBG_WARN(
-			"WSM L2 table still in use: physBase=%p, "
-			"nr_of_pages=%d\n",
-			get_l2_table_phys(used_l2table),
-			used_l2table->nr_of_pages);
-	} else {
-		unmap_buffers_from_used_l2_table(used_l2table);
-		free_used_l2_table(used_l2table);
-
-		list_del(&(used_l2table->list));
-
-		kfree(used_l2table);
-	}
-	return;
-}
-
-/*----------------------------------------------------------------------------*/
-/** Allocate L2 table and map buffer into it. That is, create respective table
-	entries. Must hold Semaphore mc_drv_kmod_ctx.wsm_l2_sem */
-static struct mc_used_l2_table *new_used_l2_table(
-	struct mc_instance	*instance,
-	struct task_struct	*task,
-	void			*wsm_buffer,
-	unsigned int		wsm_len
-) {
-	int			ret = 0;
-	struct mc_used_l2_table	*used_l2table;
-
-	do {
-		used_l2table = allocate_used_l2_table(instance);
-		if (used_l2table == NULL) {
-			MCDRV_DBG_ERROR(
-				"allocate_used_l2_table() failed\n");
-			break;
-		}
-
-		/* create the L2 page for the WSM */
-		ret = map_buffer_into_used_l2_table(
-				  task,
-				  wsm_buffer,
-				  wsm_len,
-				  used_l2table);
-		if (ret != 0) {
-			MCDRV_DBG_ERROR(
-				"map_buffer_into_used_l2_table() failed\n");
-			delete_used_l2_table(used_l2table, FREE_FROM_NWD);
-			used_l2table = NULL;
-			break;
-		}
-
-	} while (FALSE);
-
-
-	return used_l2table;
-}
-
-/*
-#############################################################################
-##
-## IoCtl handler
-##
-#############################################################################*/
-
-/**
- * Map a virtual memory buffer structure to Mobicore
- * @param instance
- * @param addr		address of the buffer(NB it must be kernel virtual!)
- * @param len		buffer length
- * @param handle	pointer to handle
- * @param phys_wsm_l2_table	pointer to physical L2 table(?)
- *
- * @return 0 if no error
- *
- */
-/*----------------------------------------------------------------------------*/
-int mobicore_map_vmem(
-	struct mc_instance	*instance,
-	void			*addr,
-	uint32_t		len,
-	uint32_t		*handle,
-	void			**phys_wsm_l2_table
-)
-{
-	int ret = 0;
-	struct mc_used_l2_table *used_l2table = NULL;
-	MCDRV_ASSERT(instance != NULL);
-
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		if (len == 0) {
-			MCDRV_DBG_ERROR("len=0 is not supported!\n");
-			ret = -EINVAL;
-			break;
-		}
-
-		/* try to get the semaphore */
-		ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem));
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("down_interruptible() failed with %d\n",
-					ret);
-			ret = -ERESTARTSYS;
-			break;
-		}
-
-		do {
-			used_l2table = new_used_l2_table(
-						   instance,
-						   NULL,
-						   addr,
-						   len);
-
-			if (used_l2table == NULL) {
-				MCDRV_DBG_ERROR("new_used_l2_table() failed\n");
-				ret = -EINVAL;
-				break;
-			}
-
-			/* set response */
-			*handle = used_l2table->handle;
-			*phys_wsm_l2_table =
-				(void *)get_l2_table_phys(used_l2table);
-			MCDRV_DBG_VERBOSE("handle: %d, phys=%p\n",
-					  *handle,
-					  (void *)(*phys_wsm_l2_table));
-
-		} while (FALSE);
-
-		/* release semaphore */
-		up(&(mc_drv_kmod_ctx.wsm_l2_sem));
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-EXPORT_SYMBOL(mobicore_map_vmem);
-/*----------------------------------------------------------------------------*/
-/**
- *
- * @param instance
- * @param arg
- *
- * @return 0 if no error
- *
- */
-static int handle_ioctl_app_register_wsm_l2(
-	struct mc_instance			*instance,
-	union mc_ioctl_app_reg_wsm_l2_params	*user_params
-)
-{
-	int					ret = 0;
-	union mc_ioctl_app_reg_wsm_l2_params	params;
-	struct mc_used_l2_table			*used_l2table = NULL;
-	struct pid				*pid_struct = NULL;
-	struct task_struct			*task = current;
-
-	MCDRV_ASSERT(instance != NULL);
-
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		/* get use parameters */
-		ret = copy_from_user(
-				  &(params.in),
-				  &(user_params->in),
-				  sizeof(params.in));
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("copy_from_user() failed\n");
-			break;
-		}
-
-		/* daemon can do this for another task. */
-		if (params.in.pid != 0) {
-			MCDRV_DBG_ERROR("pid != 0 unsupported\n");
-			ret = -EINVAL;
-			break;
-		}
-		if (params.in.len == 0) {
-			MCDRV_DBG_ERROR("len=0 is not supported!\n");
-			ret = -EINVAL;
-			break;
-		}
-
-		/* try to get the semaphore */
-		ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem));
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("down_interruptible() failed with %d\n",
-					ret);
-			ret = -ERESTARTSYS;
-			break;
-		}
-
-		do {
-			used_l2table = new_used_l2_table(
-						   instance,
-						   task,
-						   (void *)(params.in.buffer),
-						   params.in.len);
-
-			if (used_l2table == NULL) {
-				MCDRV_DBG_ERROR("new_used_l2_table() failed\n");
-				ret = -EINVAL;
-				break;
-			}
-
-			/* if the daemon does this, we set the MC lock */
-			if (is_caller_mc_daemon(instance))
-				used_l2table->flags |=
-					MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
-
-			/* set response */
-			memset(&params.out, 0, sizeof(params.out));
-			params.out.handle = used_l2table->handle;
-			/* TODO: return the physical address for daemon only,
-				otherwise set NULL */
-			params.out.phys_wsm_l2_table =
-				(uint32_t)get_l2_table_phys(used_l2table);
-
-			MCDRV_DBG_VERBOSE("handle: %d, phys=%p\n",
-					params.out.handle,
-					(void *)(params.out.phys_wsm_l2_table));
-
-
-			/* copy L2Table to user space */
-			ret = copy_to_user(
-					  &(user_params->out),
-					  &(params.out),
-					  sizeof(params.out));
-			if (ret != 0) {
-				MCDRV_DBG_ERROR("copy_to_user() failed\n");
-
-				/* free the table again, as app does not know
-					about anything. */
-				if (is_caller_mc_daemon(instance)) {
-					used_l2table->flags &=
-					~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
-				}
-				delete_used_l2_table(used_l2table,
-						FREE_FROM_NWD);
-				used_l2table = NULL;
-				break;
-			}
-
-		} while (FALSE);
-
-		/* release semaphore */
-		up(&(mc_drv_kmod_ctx.wsm_l2_sem));
-
-	} while (FALSE);
-
-
-
-	/* release PID struct reference */
-	if (pid_struct != NULL)
-		put_pid(pid_struct);
-
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-
-
-/*----------------------------------------------------------------------------*/
-/**
- * Unmap a virtual memory buffer from mobicore
- * @param instance
- * @param handle
- *
- * @return 0 if no error
- *
- */
-int mobicore_unmap_vmem(
-	struct mc_instance	*instance,
-	uint32_t		handle
-)
-{
-	int ret = 0;
-	struct mc_used_l2_table *used_l2table = NULL;
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		/* try to get the semaphore */
-		ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem));
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("processOpenSession() failed with %d\n",
-					ret);
-			ret = -ERESTARTSYS;
-			break;
-		}
-
-		do {
-			used_l2table = find_used_l2_table_by_handle(handle);
-			if (used_l2table == NULL) {
-				ret = -EINVAL;
-				MCDRV_DBG_ERROR("entry not found\n");
-				break;
-			}
-
-			if (instance != used_l2table->owner) {
-				ret = -EINVAL;
-				MCDRV_DBG_ERROR("instance does no own it\n");
-				break;
-			}
-
-			/* free table (if no further locks exist) */
-			delete_used_l2_table(used_l2table, FREE_FROM_NWD);
-			used_l2table = NULL;
-			/* there are no out parameters */
-		} while (FALSE);
-		/* release semaphore */
-		up(&(mc_drv_kmod_ctx.wsm_l2_sem));
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-EXPORT_SYMBOL(mobicore_unmap_vmem);
-/*----------------------------------------------------------------------------*/
-/**
- *
- * @param instance
- * @param arg
- *
- * @return 0 if no error
- *
- */
-static int handle_ioctl_app_unregister_wsm_l2(
-	struct mc_instance			*instance,
-	struct mc_ioctl_app_unreg_wsm_l2_params	*user_params
-)
-{
-	int					ret = 0;
-	struct mc_ioctl_app_unreg_wsm_l2_params	params;
-	struct mc_used_l2_table			*used_l2table = NULL;
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		ret = copy_from_user(
-				  &(params.in),
-				  &(user_params->in),
-				  sizeof(params.in));
-
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("copy_from_user\n");
-			break;
-		}
-
-		/* try to get the semaphore */
-		ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem));
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("down_interruptible() failed with %d\n",
-					ret);
-			ret = -ERESTARTSYS;
-			break;
-		}
-
-		do {
-			/* daemon can do this for another task. */
-			if (params.in.pid != 0) {
-				MCDRV_DBG_ERROR("pid != 0 unsupported\n");
-				ret = -EINVAL;
-				break;
-			}
-
-			used_l2table =
-				find_used_l2_table_by_handle(params.in.handle);
-			if (used_l2table == NULL) {
-				ret = -EINVAL;
-				MCDRV_DBG_ERROR("entry not found\n");
-				break;
-			}
-
-			if (is_caller_mc_daemon(instance)) {
-				/* if daemon does this, we have to release the
-					MobiCore lock. */
-				used_l2table->flags &=
-					~MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
-			} else if (instance != used_l2table->owner) {
-				ret = -EINVAL;
-				MCDRV_DBG_ERROR("instance does no own it\n");
-				break;
-			}
-
-			/* free table (if no further locks exist) */
-			delete_used_l2_table(used_l2table, FREE_FROM_NWD);
-			used_l2table = NULL;
-
-			/* there are no out parameters */
-
-		} while (FALSE);
-
-		/* release semaphore */
-		up(&(mc_drv_kmod_ctx.wsm_l2_sem));
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-
-
-/*----------------------------------------------------------------------------*/
-static int handle_ioctl_daemon_lock_wsm_l2(
-	struct mc_instance				*instance,
-	struct mc_ioctl_daemon_lock_wsm_l2_params	*user_params
-)
-{
-	int						ret = 0;
-	struct mc_ioctl_daemon_lock_wsm_l2_params	params;
-	struct mc_used_l2_table				*used_l2table = NULL;
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		if (!is_caller_mc_daemon(instance)) {
-			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
-			ret = -EFAULT;
-			break;
-		}
-
-		ret = copy_from_user(
-				  &(params.in),
-				  &(user_params->in),
-				  sizeof(params.in));
-
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("copy_from_user\n");
-			break;
-		}
-		/* try to get the semaphore */
-		ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem));
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("down_interruptible() failed with %d\n",
-					ret);
-			ret = -ERESTARTSYS;
-			break;
-		}
-
-		do {
-			used_l2table =
-				find_used_l2_table_by_handle(params.in.handle);
-			if (used_l2table == NULL) {
-				ret = -EINVAL;
-				MCDRV_DBG_ERROR("entry not found\n");
-				break;
-			}
-			if (instance != used_l2table->owner) {
-				ret = -EINVAL;
-				MCDRV_DBG_ERROR("instance does no own it\n");
-				break;
-			}
-
-			/* lock entry */
-			if ((used_l2table->flags &
-				  MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC) != 0) {
-				MCDRV_DBG_WARN("entry already locked\n");
-			}
-			used_l2table->flags |=
-				MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
-
-			/* prepare response */
-			memset(&(params.out), 0, sizeof(params.out));
-			params.out.phys_wsm_l2_table =
-				(uint32_t)get_l2_table_phys(used_l2table);
-
-			/* copy to user space */
-			ret = copy_to_user(
-					  &(user_params->out),
-					  &(params.out),
-					  sizeof(params.out));
-			if (ret != 0) {
-				MCDRV_DBG_ERROR("copy_to_user() failed\n");
-
-				/* undo, as userspace did not get it. */
-				used_l2table->flags |=
-					MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC;
-				break;
-			}
-
-		} while (FALSE);
-
-		/* release semaphore */
-		up(&(mc_drv_kmod_ctx.wsm_l2_sem));
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-
-
-/*----------------------------------------------------------------------------*/
-static int handle_ioctl_daemon_unlock_wsm_l2(
-	struct mc_instance				*instance,
-	struct mc_ioctl_daemon_unlock_wsm_l2_params	*user_params
-)
-{
-	int						ret = 0;
-	struct mc_ioctl_daemon_unlock_wsm_l2_params	params;
-	struct mc_used_l2_table				*used_l2table = NULL;
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		if (!is_caller_mc_daemon(instance)) {
-			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
-			ret = -EFAULT;
-			break;
-		}
-
-		ret = copy_from_user(
-				  &(params.in),
-				  &(user_params->in),
-				  sizeof(params.in));
-
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("copy_from_user\n");
-			break;
-		}
-		/* try to get the semaphore */
-		ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem));
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("down_interruptible() failed with %d\n",
-						ret);
-			ret = -ERESTARTSYS;
-			break;
-		}
-
-		do {
-			used_l2table =
-				find_used_l2_table_by_handle(params.in.handle);
-			if (used_l2table == NULL) {
-				ret = -EINVAL;
-				MCDRV_DBG_ERROR("entry not found\n");
-				break;
-			}
-			if (instance != used_l2table->owner) {
-				ret = -EINVAL;
-				MCDRV_DBG_ERROR("instance does no own it\n");
-				break;
-			}
-
-			/* lock entry */
-			if ((used_l2table->flags &
-				  MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC) == 0) {
-				MCDRV_DBG_WARN("entry is not locked locked\n");
-			}
-
-			/* free table (if no further locks exist) */
-			delete_used_l2_table(used_l2table, FREE_FROM_SWD);
-			used_l2table = NULL;
-
-			/* there are no out parameters */
-
-		} while (FALSE);
-
-	} while (FALSE);
-
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-/** Clears the reserved bit of each page and frees the pages */
-static inline void free_continguous_pages(
-	void		*addr,
-	unsigned int	size
-)
-{
-	struct page *page = virt_to_page(addr);
-	int i;
-	for (i = 0; i < size; i++) {
-		MCDRV_DBG_VERBOSE("free page at 0x%p\n", page);
-		ClearPageReserved(page);
-		page++;
-	}
-	/* REV luh: see man kmalloc */
-	free_pages((unsigned long)addr, size_to_order(size));
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- * Free a WSM buffer allocated with mobicore_allocate_wsm
- * @param instance
- * @param handle		handle of the buffer
- *
- * @return 0 if no error
- *
- */
-int mobicore_free(
-	struct mc_instance	*instance,
-	uint32_t		handle
-)
-{
-	int ret = 0;
-	unsigned int i;
-	struct mc_contg_buffer	*contg_buffer;
-
-	do {
-		/* search for the given address in the contg_buffers list */
-		for (i = 0; i < MC_DRV_KMOD_CONTG_BUFFER_MAX; i++) {
-			contg_buffer = &(instance->contg_buffers[i]);
-			if (contg_buffer->handle == handle)
-				break;
-		}
-		if (i == MC_DRV_KMOD_CONTG_BUFFER_MAX) {
-			MCDRV_DBG_ERROR("contigous buffer not found\n");
-			ret = -EFAULT;
-			break;
-		}
-
-		MCDRV_DBG_VERBOSE("phys_addr=0x%p, virt_addr=0x%p\n",
-				contg_buffer->phys_addr,
-				contg_buffer->virt_kernel_addr);
-
-		free_continguous_pages(contg_buffer->virt_kernel_addr,
-					contg_buffer->num_pages);
-
-		memset(contg_buffer, 0, sizeof(*contg_buffer));
-
-		/* there are no out parameters */
-
-	} while (FALSE);
-
-
-	return ret;
-}
-EXPORT_SYMBOL(mobicore_free);
-/*----------------------------------------------------------------------------*/
-
-/**
- *
- * @param instance
- * @param arg
- *
- * @return 0 if no error
- *
- */
-static int handle_ioctl_free(
-	struct mc_instance		*instance,
-	union mc_ioctl_free_params	*user_params
-)
-{
-	int				ret = 0;
-	union mc_ioctl_free_params	params;
-
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		ret = copy_from_user(
-				  &(params.in),
-				  &(user_params->in),
-				  sizeof(params.in));
-
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("copy_from_user\n");
-			break;
-		}
-
-		/* daemon can do this for another task. */
-		if (params.in.pid != 0) {
-			MCDRV_DBG_ERROR("pid != 0 unsupported\n");
-			ret = -EINVAL;
-			break;
-		}
-
-		ret = mobicore_free(instance, params.in.handle);
-
-		/* there are no out parameters */
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-
-}
-
-
-/*----------------------------------------------------------------------------*/
-/**
- *
- * @param instance
- * @param arg
- *
- * @return 0 if no error
- *
- */
-static int handle_ioctl_info(
-	struct mc_instance	*instance,
-	union mc_ioctl_info_params	*user_params
-)
-{
-	int			ret = 0;
-	union mc_ioctl_info_params	params;
-	union mc_fc_info		fc_info;
-
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		/* only the MobiCore Daemon is allowed to call this function */
-		if (!is_caller_mc_daemon(instance)) {
-			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
-			ret = -EFAULT;
-			break;
-		}
-
-		ret = copy_from_user(
-				  &(params.in),
-				  &(user_params->in),
-				  sizeof(params.in));
-
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("copy_from_user\n");
-			break;
-		}
-
-
-		memset(&fc_info, 0, sizeof(fc_info));
-		fc_info.as_in.cmd	   = MC_FC_INFO;
-		fc_info.as_in.ext_info_id = params.in.ext_info_id;
-
-		MCDRV_DBG(
-			"fc_info in cmd=0x%08x, ext_info_id=0x%08x "
-			"rfu=(0x%08x, 0x%08x)\n",
-			fc_info.as_in.cmd,
-			fc_info.as_in.ext_info_id,
-			fc_info.as_in.rfu[0],
-			fc_info.as_in.rfu[1]);
-
-		mc_fastcall(&(fc_info.as_generic));
-
-		MCDRV_DBG(
-			"fc_info out resp=0x%08x, ret=0x%08x "
-			"state=0x%08x, ext_info=0x%08x\n",
-			fc_info.as_out.resp,
-			fc_info.as_out.ret,
-			fc_info.as_out.state,
-			fc_info.as_out.ext_info);
-
-		ret = convert_fc_ret(fc_info.as_out.ret);
-		if (ret != 0)
-			break;
-
-		memset(&(params.out), 0, sizeof(params.out));
-		params.out.state  = fc_info.as_out.state;
-		params.out.ext_info = fc_info.as_out.ext_info;
-
-		ret = copy_to_user(
-				  &(user_params->out),
-				  &(params.out),
-				  sizeof(params.out));
-
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("copy_to_user\n");
-			break;
-		}
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- *
- * @param instance
- * @param arg
- *
- * @return 0 if no error
- *
- */
-static int handle_ioctl_yield(
-	struct mc_instance	*instance
-)
-{
-	int			ret = 0;
-	union mc_fc_s_yield	fc_s_yield;
-
-	MCDRV_ASSERT(instance != NULL);
-
-	/* avoid putting debug output here, as we do this very often */
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		/* only the MobiCore Daemon is allowed to call this function */
-		if (!is_caller_mc_daemon(instance)) {
-			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
-			ret = -EFAULT;
-			break;
-		}
-
-		memset(&fc_s_yield, 0, sizeof(fc_s_yield));
-		fc_s_yield.as_in.cmd = MC_SMC_N_YIELD;
-		mc_fastcall(&(fc_s_yield.as_generic));
-		ret = convert_fc_ret(fc_s_yield.as_out.ret);
-		if (ret != 0)
-			break;
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- * handle ioctl and call common notify
- *
- * @param instance
- * @param arg
- *
- * @return 0 if no error
- *
- */
-static int handle_ioctl_nsiq(
-	struct mc_instance	*instance,
-	unsigned long		arg
-)
-{
-	int		ret = 0;
-
-	MCDRV_ASSERT(instance != NULL);
-
-	/* avoid putting debug output here, as we do this very often */
-	MCDRV_DBG_VERBOSE("enter\n");
-	/* only the MobiCore Daemon is allowed to call this function */
-	if (!is_caller_mc_daemon(instance)) {
-		MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
-		return -EFAULT;
-	}
-
-	do {
-		union mc_fc_nsiq fc_nsiq;
-		memset(&fc_nsiq, 0, sizeof(fc_nsiq));
-		fc_nsiq.as_in.cmd = MC_SMC_N_SIQ;
-		mc_fastcall(&(fc_nsiq.as_generic));
-		ret = convert_fc_ret(fc_nsiq.as_out.ret);
-		if (ret != 0)
-			break;
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- *
- * @param instance
- * @param arg
- *
- * @return 0 if no error
- *
- */
-static int handle_ioctl_dump_status(
-	struct mc_instance	*instance,
-	unsigned long		arg
-)
-{
-	int		ret = 0;
-	int		i = 0;
-	union mc_fc_info	fc_info;
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		/* anybody with root access can do this. */
-		if (!is_userland_caller_privileged()) {
-			MCDRV_DBG_ERROR("caller must have root privileges\n");
-			ret = -EFAULT;
-			break;
-		}
-
-		/* loop ext_info */
-		while (TRUE) {
-			memset(&fc_info, 0, sizeof(fc_info));
-			fc_info.as_in.cmd	   = MC_FC_INFO;
-			fc_info.as_in.ext_info_id = i;
-
-			MCDRV_DBG(
-				"fc_info in cmd=0x%08x, ext_info_id=0x%08x "
-				"rfu=(0x%08x, 0x%08x)\n",
-				fc_info.as_in.cmd,
-				fc_info.as_in.ext_info_id,
-				fc_info.as_in.rfu[0],
-				fc_info.as_in.rfu[1]);
-
-			mc_fastcall(&(fc_info.as_generic));
-
-			MCDRV_DBG(
-				"fc_info out resp=0x%08x, ret=0x%08x "
-				"state=0x%08x, ext_info=0x%08x\n",
-				fc_info.as_out.resp,
-				fc_info.as_out.ret,
-				fc_info.as_out.state,
-				fc_info.as_out.ext_info);
-
-			ret = convert_fc_ret(fc_info.as_out.ret);
-			if (ret != 0)
-				break;
-
-			MCDRV_DBG("state=%08X, idx=%02d: ext_info=%08X\n",
-				fc_info.as_out.state,
-				i,
-				fc_info.as_out.ext_info);
-			i++;
-		};
-
-		if (ret != 0)
-			break;
-
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- *
- * @param instance
- * @param arg
- *
- * @return 0 if no error
- *
- */
-static int handle_ioctl_init(
-	struct mc_instance	*instance,
-	union mc_ioctl_init_params	*user_params
-)
-{
-	int			ret = 0;
-	union mc_ioctl_init_params	params;
-	union mc_fc_init		fc_init;
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		/* only the MobiCore Daemon is allowed to call this function */
-		if (!is_caller_mc_daemon(instance)) {
-			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
-			ret = -EFAULT;
-			break;
-		}
-
-		ret = copy_from_user(
-				  &(params.in),
-				  &(user_params->in),
-				  sizeof(params.in));
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("copy_from_user failed\n");
-			break;
-		}
-
-		memset(&fc_init, 0, sizeof(fc_init));
-
-		fc_init.as_in.cmd	= MC_FC_INIT;
-		/* base address of mci buffer 4KB aligned */
-		fc_init.as_in.base   = (uint32_t)params.in.base;
-		/* notification buffer start/length [16:16] [start, length] */
-		fc_init.as_in.nq_info  = (params.in.nq_offset << 16)
-					  | (params.in.nq_length & 0xFFFF);
-		/* mcp buffer start/length [16:16] [start, length] */
-		fc_init.as_in.mcp_info = (params.in.mcp_offset << 16)
-					  | (params.in.mcp_length & 0xFFFF);
-
-		/* Set KMOD notification queue to start of MCI
-			mciInfo was already set up in mmap */
-		if (!mci_base) {
-			MCDRV_DBG_ERROR("No MCI set yet.\n");
-			return -EFAULT;
-		}
-		MCDRV_DBG("in cmd=0x%08x, base=0x%08x, "
-			  "nq_info=0x%08x, mcp_info=0x%08x\n",
-			  fc_init.as_in.cmd,
-			  fc_init.as_in.base,
-			  fc_init.as_in.nq_info,
-			  fc_init.as_in.mcp_info);
-
-		mc_fastcall(&(fc_init.as_generic));
-
-		MCDRV_DBG("out cmd=0x%08x, ret=0x%08x rfu=(0x%08x, 0x%08x)\n",
-			  fc_init.as_out.resp,
-			  fc_init.as_out.ret,
-			  fc_init.as_out.rfu[0],
-			  fc_init.as_out.rfu[1]);
-
-		ret = convert_fc_ret(fc_init.as_out.ret);
-		if (ret != 0)
-			break;
-
-		/* no ioctl response parameters */
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- *
- * @param instance
- * @param arg
- *
- * @return 0 if no error
- *
- */
-static int handle_ioctl_fc_execute(
-	struct mc_instance		*instance,
-	union mc_ioctl_fc_execute_params	*user_params
-)
-{
-	int				ret = 0;
-	union mc_ioctl_fc_execute_params	params;
-	union fc_generic			fc_params;
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		/* only the MobiCore Daemon is allowed to call this function */
-		if (!is_caller_mc_daemon(instance)) {
-			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
-			ret = -EFAULT;
-			break;
-		}
-
-		ret = copy_from_user(
-				  &(params.in),
-				  &(user_params->in),
-				  sizeof(params.in));
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("copy_from_user failed\n");
-			break;
-		}
-
-		fc_params.as_in.cmd = -4;/*FC_EXECUTE */
-		fc_params.as_in.param[0] = params.in.phys_start_addr;
-		fc_params.as_in.param[1] = params.in.length;
-		fc_params.as_in.param[2] = 0;
-
-		MCDRV_DBG("in cmd=0x%08x, startAddr=0x%08x, length=0x%08x\n",
-			  fc_params.as_in.cmd,
-			  fc_params.as_in.param[0],
-			  fc_params.as_in.param[1]);
-
-		mc_fastcall(&fc_params);
-
-		MCDRV_DBG("out cmd=0x%08x, ret=0x%08x rfu=(0x%08x, 0x%08x)\n",
-			  fc_params.as_out.resp,
-			  fc_params.as_out.ret,
-			  fc_params.as_out.param[0],
-			  fc_params.as_out.param[1]);
-
-		ret = convert_fc_ret(fc_params.as_out.ret);
-		if (ret != 0)
-			break;
-
-		/* no ioctl response parameters */
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-#define MC_MAKE_VERSION(major, minor) \
-		(((major & 0x0000ffff) << 16) | (minor & 0x0000ffff))
-/**
- *
- * @param instance
- * @param arg
- *
- * @return 0 if no error
- *
- */
-static int handle_ioctl_get_version(
-	struct mc_instance			*instance,
-	struct mc_ioctl_get_version_params	*user_params
-)
-{
-	int ret = 0;
-	struct mc_ioctl_get_version_params params = {
-		{
-			MC_MAKE_VERSION(MCDRVMODULEAPI_VERSION_MAJOR,
-					MCDRVMODULEAPI_VERSION_MINOR)
-		}
-	};
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		MCDRV_DBG("mcDrvModuleApi version is %i.%i\n",
-				MCDRVMODULEAPI_VERSION_MAJOR,
-				MCDRVMODULEAPI_VERSION_MINOR);
-
-		/* no ioctl response parameters */
-		ret = copy_to_user(
-					&(user_params->out),
-					&(params.out),
-					sizeof(params.out));
-		if (ret != 0)
-			MCDRV_DBG_ERROR("copy_to_user() failed\n");
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- * This function will be called from user space as ioctl(...).
- * @param file	pointer to file
- * @param cmd	command
- * @param arg	arguments
- *
- * @return int 0 for OK and an errno in case of error
- */
-static long mc_kernel_module_ioctl(
-	struct file	*file,
-	unsigned int	cmd,
-	unsigned long	arg
-)
-{
-	int ret;
 	struct mc_instance *instance = get_instance(file);
+	unsigned long len = vmarea->vm_end - vmarea->vm_start;
+	void *paddr = (void *)(vmarea->vm_pgoff << PAGE_SHIFT);
+	unsigned int pfn;
+	struct mc_buffer *buffer = 0;
+	int ret = 0;
 
-	MCDRV_ASSERT(instance != NULL);
+	MCDRV_DBG_VERBOSE(mcd, "enter (vma start=0x%p, size=%ld, mci=%p)\n",
+			  (void *)vmarea->vm_start, len, ctx.mci_base.phys);
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	if (len == 0) {
+		MCDRV_DBG_ERROR(mcd, "cannot allocate size 0\n");
+		return -ENOMEM;
+	}
+	if (paddr) {
+		mutex_lock(&ctx.bufs_lock);
+
+		/* search for the buffer list. */
+		list_for_each_entry(buffer, &ctx.cont_bufs, list) {
+			/* Only allow mapping if the client owns it!*/
+			if (buffer->phys == paddr &&
+			    buffer->instance == instance) {
+				/* We shouldn't do remap with larger size */
+				if (buffer->len > len)
+					break;
+				/* We can't allow mapping the buffer twice */
+				if (!buffer->uaddr)
+					goto found;
+				else
+					break;
+			}
+		}
+		/* Nothing found return */
+		mutex_unlock(&ctx.bufs_lock);
+		return -EINVAL;
+
+found:
+		buffer->uaddr = (void *)vmarea->vm_start;
+		vmarea->vm_flags |= VM_IO;
+		/*
+		 * Convert kernel address to user address. Kernel address begins
+		 * at PAGE_OFFSET, user address range is below PAGE_OFFSET.
+		 * Remapping the area is always done, so multiple mappings
+		 * of one region are possible. Now remap kernel address
+		 * space into user space
+		 */
+		pfn = (unsigned int)paddr >> PAGE_SHIFT;
+		ret = (int)remap_pfn_range(vmarea, vmarea->vm_start, pfn,
+			buffer->len, vmarea->vm_page_prot);
+		/* If the remap failed then don't mark this buffer as marked
+		 * since the unmaping will also fail */
+		if (ret)
+			buffer->uaddr = NULL;
+		mutex_unlock(&ctx.bufs_lock);
+	} else {
+		if (!is_daemon(instance))
+			return -EPERM;
+
+		paddr = get_mci_base_phys(len);
+		if (!paddr)
+			return -EFAULT;
+
+		vmarea->vm_flags |= VM_IO;
+		/*
+		 * Convert kernel address to user address. Kernel address begins
+		 * at PAGE_OFFSET, user address range is below PAGE_OFFSET.
+		 * Remapping the area is always done, so multiple mappings
+		 * of one region are possible. Now remap kernel address
+		 * space into user space
+		 */
+		pfn = (unsigned int)paddr >> PAGE_SHIFT;
+		ret = (int)remap_pfn_range(vmarea, vmarea->vm_start, pfn, len,
+			vmarea->vm_page_prot);
+	}
+
+	MCDRV_DBG_VERBOSE(mcd, "exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+static inline int ioctl_check_pointer(unsigned int cmd, int __user *uarg)
+{
+	int err = 0;
+	if (_IOC_DIR(cmd) & _IOC_READ)
+		err = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd));
+	else if (_IOC_DIR(cmd) & _IOC_WRITE)
+		err = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd));
+	if (err)
+		return -EFAULT;
+
+	return 0;
+}
+
+/*
+ * mc_fd_user_ioctl() - Will be called from user space as ioctl(..)
+ * @file	pointer to file
+ * @cmd		command
+ * @arg		arguments
+ *
+ * Returns 0 for OK and an errno in case of error
+ */
+static long mc_fd_user_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	struct mc_instance *instance = get_instance(file);
+	int __user *uarg = (int __user *)arg;
+	int ret = -EINVAL;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	if (ioctl_check_pointer(cmd, uarg))
+		return -EFAULT;
 
 	switch (cmd) {
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_DUMP_STATUS:
-		ret = handle_ioctl_dump_status(
-				instance,
-				arg);
+	case MC_IO_FREE:
+		ret = mc_free_buffer(instance, (uint32_t)arg);
 		break;
 
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_FC_INIT:
-		ret = handle_ioctl_init(
-				instance,
-				(union mc_ioctl_init_params *)arg);
+	case MC_IO_REG_WSM:{
+		struct mc_ioctl_reg_wsm reg;
+		if (copy_from_user(&reg, uarg, sizeof(reg)))
+			return -EFAULT;
+
+		ret = mc_register_wsm_l2(instance, reg.buffer,
+			reg.len, &reg.handle, &reg.table_phys);
+		if (!ret) {
+			if (copy_to_user(uarg, &reg, sizeof(reg))) {
+				ret = -EFAULT;
+				mc_unregister_wsm_l2(instance, reg.handle);
+			}
+		}
 		break;
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_FC_INFO:
-		ret = handle_ioctl_info(
-				instance,
-				(union mc_ioctl_info_params *)arg);
+	}
+	case MC_IO_UNREG_WSM:
+		ret = mc_unregister_wsm_l2(instance, (uint32_t)arg);
 		break;
 
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_FC_YIELD:
-		ret = handle_ioctl_yield(
-				instance);
+	case MC_IO_VERSION:
+		ret = put_user(mc_get_version(), uarg);
+		if (ret)
+			MCDRV_DBG_ERROR(mcd,
+					"IOCTL_GET_VERSION failed to put data");
 		break;
 
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_FC_NSIQ:
-		ret = handle_ioctl_nsiq(
-				instance,
-				arg);
-		break;
+	case MC_IO_MAP_WSM:{
+		struct mc_ioctl_map map;
+		struct mc_buffer *buffer = 0;
+		if (copy_from_user(&map, uarg, sizeof(map)))
+			return -EFAULT;
 
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2:
-		ret = handle_ioctl_daemon_lock_wsm_l2(
-			instance,
-			(struct mc_ioctl_daemon_lock_wsm_l2_params *)arg);
-		break;
+		/* Setup the WSM buffer structure! */
+		if (mc_get_buffer(instance, &buffer, map.len))
+			return -EFAULT;
 
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2:
-		ret = handle_ioctl_daemon_unlock_wsm_l2(
-			instance,
-			(struct mc_ioctl_daemon_unlock_wsm_l2_params *)arg);
+		map.handle = buffer->handle;
+		map.phys_addr = (unsigned long)buffer->phys;
+		map.reused = 0;
+		if (copy_to_user(uarg, &map, sizeof(map)))
+			ret = -EFAULT;
+		else
+			ret = 0;
 		break;
-
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_FREE:
-		/* called by ClientLib */
-		ret = handle_ioctl_free(
-				instance,
-				(union mc_ioctl_free_params *)arg);
-		break;
-
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2:
-		/* called by ClientLib */
-		ret = handle_ioctl_app_register_wsm_l2(
-				instance,
-				(union mc_ioctl_app_reg_wsm_l2_params *)arg);
-		break;
-
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2:
-		/* called by ClientLib */
-		ret = handle_ioctl_app_unregister_wsm_l2(
-				instance,
-				(struct mc_ioctl_app_unreg_wsm_l2_params *)arg);
-		break;
-
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_FC_EXECUTE:
-		ret = handle_ioctl_fc_execute(
-				instance,
-				(union mc_ioctl_fc_execute_params *)arg);
-		break;
-
-	/*--------------------------------------------------------------------*/
-	case MC_DRV_KMOD_IOCTL_GET_VERSION:
-		ret = handle_ioctl_get_version(
-				instance,
-				(struct mc_ioctl_get_version_params *)arg);
-		break;
-
-	/*--------------------------------------------------------------------*/
+	}
 	default:
-		MCDRV_DBG_ERROR("unsupported cmd=%d\n", cmd);
-		ret = -EFAULT;
+		MCDRV_DBG_ERROR(mcd, "unsupported cmd=%d\n", cmd);
+		ret = -ENOIOCTLCMD;
 		break;
 
 	} /* end switch(cmd) */
@@ -1975,895 +816,546 @@
 	return (int)ret;
 }
 
-
-/*----------------------------------------------------------------------------*/
-/**
- * This function will be called from user space as read(...).
- * The read function is blocking until a interrupt occurs. In that case the
- * event counter is copied into user space and the function is finished.
- * @param *file
- * @param *buffer  buffer where to copy to(userspace)
- * @param buffer_len	 number of requested data
- * @param *pos	 not used
- * @return ssize_t  ok case: number of copied data
- *				error case: return errno
- */
-static ssize_t mc_kernel_module_read(
-	struct file	*file,
-	char		*buffer,
-	size_t		buffer_len,
-	loff_t		*pos
-)
+static long mc_fd_admin_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
 {
-	int ret = 0, ssiq_counter;
-	size_t retLen = 0;
 	struct mc_instance *instance = get_instance(file);
+	int __user *uarg = (int __user *)arg;
+	int ret = -EINVAL;
 
-	MCDRV_ASSERT(instance != NULL);
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
 
-	/* avoid debug output on non-error, because this is call quite often */
-	MCDRV_DBG_VERBOSE("enter\n");
-
-	do {
-		/* only the MobiCore Daemon is allowed to call this function */
-		if (!is_caller_mc_daemon(instance)) {
-			MCDRV_DBG_ERROR("caller not MobiCore Daemon\n");
-			ret = -EFAULT;
-			break;
-		}
-
-		if (buffer_len < sizeof(unsigned int)) {
-			MCDRV_DBG_ERROR("invalid length\n");
-			ret = (ssize_t)(-EINVAL);
-			break;
-		}
-
-		for (;;) {
-			if (down_interruptible(
-					&mc_drv_kmod_ctx.daemon_ctx.sem)) {
-				MCDRV_DBG_VERBOSE("read interrupted\n");
-				ret = (ssize_t)-ERESTARTSYS;
-				break;
-			}
-
-			ssiq_counter = atomic_read(
-					&(mc_drv_kmod_ctx.ssiq_ctx.counter));
-			MCDRV_DBG_VERBOSE("ssiq_counter=%i, ctx.counter=%i\n",
-				ssiq_counter,
-				mc_drv_kmod_ctx.daemon_ctx.ssiq_counter);
-
-			if (ssiq_counter !=
-				mc_drv_kmod_ctx.daemon_ctx.ssiq_counter) {
-				/* read data and exit loop without
-					error */
-				mc_drv_kmod_ctx.daemon_ctx.ssiq_counter =
-					ssiq_counter;
-				ret = 0;
-				break;
-			}
-
-			/* end loop if non-blocking */
-			if ((file->f_flags & O_NONBLOCK) != 0) {
-				MCDRV_DBG_ERROR("non-blocking read\n");
-				ret = (ssize_t)(-EAGAIN);
-				break;
-			}
-
-			if (signal_pending(current) != 0) {
-				MCDRV_DBG_VERBOSE("received signal.\n");
-				ret = (ssize_t)(-ERESTARTSYS);
-				break;
-			}
-
-		}
-
-		/* we are here if an event occurred or we had an
-			error.*/
-		if (ret != 0)
-			break;
-
-		/* read data and exit loop */
-		ret = copy_to_user(
-				  buffer,
-				  &(mc_drv_kmod_ctx.daemon_ctx.ssiq_counter),
-				  sizeof(unsigned int));
-
-
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("copy_to_user failed\n");
-			ret = (ssize_t)(-EFAULT);
-			break;
-		}
-
-		retLen = sizeof(s32);
-
-	} while (FALSE);
-
-	/* avoid debug on non-error. */
-	if (ret == 0)
-		ret = (size_t)retLen;
-	else
-		MCDRV_DBG("exit with %d/0x%08X\n", ret, ret);
-
-	return (ssize_t)ret;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- * Allocate WSM for given instance
- *
- * @param instance		instance
- * @param requested_size		size of the WSM
- * @param handle		pointer where the handle will be saved
- * @param virt_kernel_addr	pointer for the kernel virtual address
- * @param phys_addr		pointer for the physical address
- *
- * @return error code or 0 for success
- */
-int mobicore_allocate_wsm(
-	struct mc_instance	*instance,
-	unsigned long		requested_size,
-	uint32_t		*handle,
-	void			**virt_kernel_addr,
-	void			**phys_addr
-)
-{
-	unsigned int	i;
-	unsigned int	order;
-	unsigned long	allocated_size;
-	int		ret = 0;
-	struct mc_contg_buffer	*contg_buffer = 0;
-	void		*virt_kernel_addr_stack;
-	void		*phys_addr_stack;
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG("%s (size=%ld)\n", __func__, requested_size);
-
-	order = size_to_order(requested_size);
-	if (order == INVALID_ORDER) {
-		MCDRV_DBG_ERROR(
-			"size to order converting failed for size %ld\n",
-			requested_size);
-		return INVALID_ORDER;
+	if (WARN_ON(!is_daemon(instance))) {
+		MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon\n");
+		return -EPERM;
 	}
 
-	allocated_size = (1<<order)*PAGE_SIZE;
+	if (ioctl_check_pointer(cmd, uarg))
+		return -EFAULT;
 
-	MCDRV_DBG("size %ld -> order %d --> %ld (2^n pages)\n",
-		  requested_size, order, allocated_size);
-
-	do {
-		/* Usual Wsm request, allocate contigous buffer. */
-		/* search for a free entry in the wsm buffer list
-		 * REV axh: serialize this over multiple instances. */
-		for (i = 0; i < MC_DRV_KMOD_CONTG_BUFFER_MAX; i++) {
-			contg_buffer = &(instance->contg_buffers[i]);
-			if (contg_buffer->handle == 0) {
-				contg_buffer->handle = get_mc_kmod_unique_id();
-				break;
-			}
+	switch (cmd) {
+	case MC_IO_INIT: {
+		struct mc_ioctl_init init;
+		ctx.mcp = NULL;
+		if (!ctx.mci_base.phys) {
+			MCDRV_DBG_ERROR(mcd,
+					"Cannot init MobiCore without MCI!");
+			return -EINVAL;
 		}
-		if (i == MC_DRV_KMOD_CONTG_BUFFER_MAX) {
-			MCDRV_DBG_ERROR("no free contigous buffer\n");
+		if (copy_from_user(&init, uarg, sizeof(init)))
+			return -EFAULT;
+
+		ctx.mcp = ctx.mci_base.addr + init.mcp_offset;
+		ret = mc_init((uint32_t)ctx.mci_base.phys, init.nq_offset,
+			init.nq_length, init.mcp_offset, init.mcp_length);
+		break;
+	}
+	case MC_IO_INFO: {
+		struct mc_ioctl_info info;
+		if (copy_from_user(&info, uarg, sizeof(info)))
+			return -EFAULT;
+
+		ret = mc_info(info.ext_info_id, &info.state,
+			&info.ext_info);
+
+		if (!ret) {
+			if (copy_to_user(uarg, &info, sizeof(info)))
+				ret = -EFAULT;
+		}
+		break;
+	}
+	case MC_IO_YIELD:
+		ret = mc_yield();
+		break;
+
+	case MC_IO_NSIQ:
+		ret = mc_nsiq();
+		break;
+
+	case MC_IO_LOCK_WSM: {
+		ret = mc_lock_handle(instance, (uint32_t)arg);
+		break;
+	}
+	case MC_IO_UNLOCK_WSM:
+		ret = mc_unlock_handle(instance, (uint32_t)arg);
+		break;
+	case MC_IO_CLEAN_WSM:
+		ret = mc_clean_wsm_l2(instance);
+		break;
+	case MC_IO_RESOLVE_WSM: {
+		uint32_t phys;
+		struct mc_ioctl_resolv_wsm wsm;
+		if (copy_from_user(&wsm, uarg, sizeof(wsm)))
+			return -EFAULT;
+		phys = mc_find_wsm_l2(instance, wsm.handle, wsm.fd);
+		if (!phys)
+			return -EINVAL;
+
+		wsm.phys = phys;
+		if (copy_to_user(uarg, &wsm, sizeof(wsm)))
+			return -EFAULT;
+		ret = 0;
+		break;
+	}
+	case MC_IO_RESOLVE_CONT_WSM: {
+		struct mc_ioctl_resolv_cont_wsm cont_wsm;
+		uint32_t phys = 0, len = 0;
+		if (copy_from_user(&cont_wsm, uarg, sizeof(cont_wsm)))
+			return -EFAULT;
+		ret = mc_find_cont_wsm(instance, cont_wsm.handle, cont_wsm.fd,
+					&phys, &len);
+		if (!ret) {
+			cont_wsm.phys = phys;
+			cont_wsm.length = len;
+			if (copy_to_user(uarg, &cont_wsm, sizeof(cont_wsm)))
+				ret = -EFAULT;
+		}
+		break;
+	}
+	case MC_IO_MAP_MCI:{
+		struct mc_ioctl_map map;
+		if (copy_from_user(&map, uarg, sizeof(map)))
+			return -EFAULT;
+
+		map.reused = (ctx.mci_base.phys != 0);
+		map.phys_addr = (unsigned long)get_mci_base_phys(map.len);
+		if (!map.phys_addr) {
+			MCDRV_DBG_ERROR(mcd, "Failed to setup MCI buffer!");
+			return -EFAULT;
+		}
+
+		if (copy_to_user(uarg, &map, sizeof(map)))
 			ret = -EFAULT;
-			break;
-		}
-
-		/* Common code for all allocation paths */
-		virt_kernel_addr_stack = (void *)__get_free_pages(
-							GFP_USER | __GFP_COMP,
-							order);
-		if (virt_kernel_addr_stack == NULL) {
-			MCDRV_DBG_ERROR("get_free_pages failed\n");
-			ret = -ENOMEM;
-			break;
-		}
-
-		/* Get physical address to instance data */
-		phys_addr_stack = (void *)virt_to_phys(virt_kernel_addr_stack);
-		/* TODO: check for INVALID_ADDRESS? */
-
-		MCDRV_DBG(
-			"allocated phys=0x%p - 0x%p, "
-			"size=%ld, kernel_virt=0x%p, handle=%d\n",
-			phys_addr_stack,
-			(void *)((unsigned int)phys_addr_stack+allocated_size),
-			allocated_size,
-			virt_kernel_addr_stack,
-			contg_buffer->handle);
-
-		/* Usual Wsm request, allocate contg_buffer.
-		 *		Also, we never free a persistent Tci */
-		contg_buffer->phys_addr	 = phys_addr_stack;
-		contg_buffer->virt_kernel_addr = virt_kernel_addr_stack;
-		contg_buffer->virt_user_addr   = virt_kernel_addr_stack;
-		contg_buffer->num_pages	 = (1U << order);
-		*handle = contg_buffer->handle;
-		*virt_kernel_addr = virt_kernel_addr_stack;
-		*phys_addr = phys_addr_stack;
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("%s: exit with 0x%08X\n", __func__, ret);
-
-	return ret;
-}
-EXPORT_SYMBOL(mobicore_allocate_wsm);
-
-
-/*----------------------------------------------------------------------------*/
-/**
- * This function will be called from user space as address = mmap(...).
- *
- * @param file
- * @param vmarea
- * vmarea.pg_offset != 0 is mapping of MCI is requested
- *
- * @return 0 if OK or -ENOMEM in case of error.
- */
-static int mc_kernel_module_mmap(
-	struct file		*file,
-	struct vm_area_struct	*vmarea
-)
-{
-	unsigned int		i;
-	unsigned int		order;
-	void			*virt_kernel_addr_stack = 0;
-	void			*phys_addr = 0;
-	unsigned long		requested_size =
-					vmarea->vm_end - vmarea->vm_start;
-	unsigned long		allocated_size;
-	int			ret = 0;
-	struct mc_contg_buffer	*contg_buffer = 0;
-	unsigned int		handle = 0;
-	struct mc_instance	*instance = get_instance(file);
-	unsigned int		request = vmarea->vm_pgoff * 4096;
-#if defined(DEBUG)
-	bool release = false;
-#else
-	bool release = true;
-#endif
-
-	MCDRV_ASSERT(instance != NULL);
-	MCDRV_DBG("enter (vmaStart=0x%p, size=%ld, request=0x%x, mci=0x%x)\n",
-		  (void *)vmarea->vm_start,
-		  requested_size,
-		  request,
-		  mci_base);
-
-	order = size_to_order(requested_size);
-	if (order == INVALID_ORDER) {
-		MCDRV_DBG_ERROR(
-			"size to order converting failed for size %ld\n",
-			requested_size);
-		return -ENOMEM;
+		ret = 0;
+		break;
+	}
+	case MC_IO_MAP_PWSM:{
+		break;
 	}
 
-	allocated_size = (1<<order)*PAGE_SIZE;
-
-	MCDRV_DBG("size %ld -> order %d --> %ld (2^n pages)\n",
-		  requested_size, order, allocated_size);
-
-	do {
-		/* Daemon tries to get an existing MCI */
-		if ((request == MC_DRV_KMOD_MMAP_MCI) && (mci_base != 0)) {
-			MCDRV_DBG("Request MCI, it is at (%x)\n", mci_base);
-
-			if (!is_caller_mc_daemon(instance)) {
-				ret = -EPERM;
-				break;
-			}
-			virt_kernel_addr_stack = (void *)mci_base;
-			phys_addr =
-				(void *)virt_to_phys(virt_kernel_addr_stack);
-		} else {
-			/* Usual Wsm request, allocate buffer. */
-			if (request == MC_DRV_KMOD_MMAP_WSM) {
-				/* search for a free entry in the buffer list
-				REV axh: serialize this over multiple instances.
-				*/
-				for (i = 0; i < MC_DRV_KMOD_CONTG_BUFFER_MAX;
-					i++) {
-					contg_buffer =
-						&(instance->contg_buffers[i]);
-					if (contg_buffer->handle == 0) {
-						contg_buffer->handle =
-							get_mc_kmod_unique_id();
-						break;
-					}
-				}
-				if (i == MC_DRV_KMOD_CONTG_BUFFER_MAX) {
-					MCDRV_DBG_ERROR(
-						"no free contigous buffer\n");
-					ret = -EFAULT;
-					break;
-				}
-			} else {
-				if (request <= MC_DRV_KMOD_MMAP_PERSISTENTWSM
-					|| release) {
-					/* Special Wsm request
-						--> only Daemon is allowed */
-					if (!is_caller_mc_daemon(instance)) {
-						ret = -EPERM;
-						break;
-					}
-				}
-			}
-			if (request <= MC_DRV_KMOD_MMAP_PERSISTENTWSM) {
-				/* Common code for all allocation paths
-					*  get physical address, */
-				virt_kernel_addr_stack =
-					(void *)__get_free_pages(
-							GFP_USER | __GFP_COMP,
-							order);
-				if (virt_kernel_addr_stack == NULL) {
-					MCDRV_DBG_ERROR(
-						"get_free_pages failed\n");
-					ret = -ENOMEM;
-					break;
-				}
-				if (request == MC_DRV_KMOD_MMAP_WSM)
-					handle = contg_buffer->handle;
-				/* Get physical address to instance data */
-				/* TODO: check for INVALID_ADDRESS? */
-				phys_addr = (void *)virt_to_phys(
-							virt_kernel_addr_stack);
-			} else {
-#if defined(DEBUG)
-				phys_addr = (void *)request;
-				virt_kernel_addr_stack = phys_to_virt(request);
+	case MC_IO_LOG_SETUP: {
+#ifdef MC_MEM_TRACES
+		ret = mobicore_log_setup();
 #endif
-			}
-		}
-		/* Common code for all mmap calls:
-		 * map page to user
-		 * store data in page */
+		break;
+	}
 
-		MCDRV_DBG("allocated phys=0x%p - 0x%p, "
-			"size=%ld, kernel_virt=0x%p, handle=%d\n",
-			phys_addr,
-			(void *)((unsigned int)phys_addr+allocated_size),
-			allocated_size, virt_kernel_addr_stack, handle);
+	/* The rest is handled commonly by user IOCTL */
+	default:
+		ret = mc_fd_user_ioctl(file, cmd, arg);
+	} /* end switch(cmd) */
 
-		vmarea->vm_flags |= VM_RESERVED;
-		/* convert Kernel address to User Address. Kernel address begins
-			at PAGE_OFFSET, user Address range is below PAGE_OFFSET.
-			Remapping the area is always done, so multiple mappings
-			of one region are possible. Now remap kernel address
-			space into user space */
-		ret = (int)remap_pfn_range(
-				vmarea,
-				(vmarea->vm_start),
-				addr_to_pfn(phys_addr),
-				requested_size,
-				vmarea->vm_page_prot);
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("remapPfnRange failed\n");
-
-			/* free allocated pages when mmap fails, however, do not
-				do it, when daemon tried to get an MCI that
-				existed */
-			if (!((request == MC_DRV_KMOD_MMAP_MCI) &&
-				  (mci_base != 0)))
-				free_continguous_pages(virt_kernel_addr_stack,
-							(1U << order));
-			break;
-		}
-
-		/* Usual Wsm request, allocate contg_buffer.
-			When requesting Mci, we do not associate the page with
-			the process.
-			Note: we also never free the Mci
-			Also, we never free a persistent Tci */
-		if (request == MC_DRV_KMOD_MMAP_WSM) {
-			contg_buffer->phys_addr = phys_addr;
-			contg_buffer->virt_kernel_addr = virt_kernel_addr_stack;
-			contg_buffer->virt_user_addr =
-						(void *)(vmarea->vm_start);
-			contg_buffer->num_pages = (1U << order);
-		}
-
-		/* set response in allocated buffer */
-		{
-			struct mc_mmap_resp *mmap_resp =
-				(struct mc_mmap_resp *)virt_kernel_addr_stack;
-			/* TODO: do this for daemon only, otherwise set NULL */
-			mmap_resp->phys_addr = (uint32_t)phys_addr;
-			mmap_resp->handle = handle;
-			if ((request == MC_DRV_KMOD_MMAP_MCI) &&
-				(mci_base != 0)) {
-				mmap_resp->is_reused = 1;
-			} else
-				mmap_resp->is_reused = 0;
-		}
-
-		/* store MCI pointer */
-		if ((request == MC_DRV_KMOD_MMAP_MCI) && (mci_base == 0)) {
-			mci_base = (uint32_t)virt_kernel_addr_stack;
-			MCDRV_DBG("MCI base set to 0x%x\n", mci_base);
-		}
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+#ifdef MC_MEM_TRACES
+	mobicore_log_read();
+#endif
 
 	return (int)ret;
 }
 
-#ifdef CONFIG_SMP
-/*----------------------------------------------------------------------------*/
-/**
- * Force migration of current task to CPU0(where the monitor resides)
+/*
+ * mc_fd_read() - This will be called from user space as read(...)
+ * @file:	file pointer
+ * @buffer:	buffer where to copy to(userspace)
+ * @buffer_len:	number of requested data
+ * @pos:	not used
  *
- * @return Error code or 0 for success
- */
-static int goto_cpu0(
-	void
-)
-{
-	int		ret = 0;
-	struct cpumask	mask =  CPU_MASK_CPU0;
-
-	MCDRV_DBG_VERBOSE("System has %d CPU's, we are on CPU #%d\n"
-		  "\tBinding this process to CPU #0.\n"
-		  "\tactive mask is %lx, setting it to mask=%lx\n",
-		  nr_cpu_ids,
-		  raw_smp_processor_id(),
-		  cpu_active_mask->bits[0],
-		  mask.bits[0]);
-	ret = set_cpus_allowed_ptr(current, &mask);
-	if (ret != 0)
-		MCDRV_DBG_ERROR("set_cpus_allowed_ptr=%d.\n", ret);
-	MCDRV_DBG_VERBOSE("And now we are on CPU #%d\n",
-				raw_smp_processor_id());
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- * Restore CPU mask for current to ALL Cpus(reverse of goto_cpu0)
+ * The read function is blocking until a interrupt occurs. In that case the
+ * event counter is copied into user space and the function is finished.
  *
- * @return Error code or 0 for success
+ * If OK this function returns the number of copied data otherwise it returns
+ * errno
  */
-static int goto_all_cpu(
-	void
-)
+static ssize_t mc_fd_read(struct file *file, char *buffer, size_t buffer_len,
+			  loff_t *pos)
 {
-	int		ret = 0;
+	int ret = 0, ssiq_counter;
+	struct mc_instance *instance = get_instance(file);
 
-	struct cpumask	mask =  CPU_MASK_ALL;
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
 
-	MCDRV_DBG_VERBOSE("System has %d CPU's, we are on CPU #%d\n"
-		  "\tBinding this process to CPU #0.\n"
-		  "\tactive mask is %lx, setting it to mask=%lx\n",
-		  nr_cpu_ids,
-		  raw_smp_processor_id(),
-		  cpu_active_mask->bits[0],
-		  mask.bits[0]);
-	ret = set_cpus_allowed_ptr(current, &mask);
-	if (ret != 0)
-		MCDRV_DBG_ERROR("set_cpus_allowed_ptr=%d.\n", ret);
-	MCDRV_DBG_VERBOSE("And now we are on CPU #%d\n",
-				raw_smp_processor_id());
+	/* avoid debug output on non-error, because this is call quite often */
+	MCDRV_DBG_VERBOSE(mcd, "enter\n");
 
-	return ret;
+	/* only the MobiCore Daemon is allowed to call this function */
+	if (WARN_ON(!is_daemon(instance))) {
+		MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon\n");
+		return -EPERM;
+	}
+
+	if (buffer_len < sizeof(unsigned int)) {
+		MCDRV_DBG_ERROR(mcd, "invalid length\n");
+		return -EINVAL;
+	}
+
+	for (;;) {
+		if (wait_for_completion_interruptible(&ctx.isr_comp)) {
+			MCDRV_DBG_VERBOSE(mcd, "read interrupted\n");
+			return -ERESTARTSYS;
+		}
+
+		ssiq_counter = atomic_read(&ctx.isr_counter);
+		MCDRV_DBG_VERBOSE(mcd, "ssiq_counter=%i, ctx.counter=%i\n",
+				  ssiq_counter, ctx.evt_counter);
+
+		if (ssiq_counter != ctx.evt_counter) {
+			/* read data and exit loop without error */
+			ctx.evt_counter = ssiq_counter;
+			ret = 0;
+			break;
+		}
+
+		/* end loop if non-blocking */
+		if (file->f_flags & O_NONBLOCK) {
+			MCDRV_DBG_ERROR(mcd, "non-blocking read\n");
+			return -EAGAIN;
+		}
+
+		if (signal_pending(current)) {
+			MCDRV_DBG_VERBOSE(mcd, "received signal.\n");
+			return -ERESTARTSYS;
+		}
+	}
+
+	/* read data and exit loop */
+	ret = copy_to_user(buffer, &ctx.evt_counter, sizeof(unsigned int));
+
+	if (ret != 0) {
+		MCDRV_DBG_ERROR(mcd, "copy_to_user failed\n");
+		return -EFAULT;
+	}
+
+	ret = sizeof(unsigned int);
+
+	return (ssize_t)ret;
 }
 
-#else
-static int goto_cpu0(void)
-{
-	return 0;
-}
-
-static int goto_all_cpu(void)
-{
-	return 0;
-}
-#endif
-
-/*----------------------------------------------------------------------------*/
-/**
+/*
  * Initialize a new mobicore API instance object
  *
  * @return Instance or NULL if no allocation was possible.
  */
-struct mc_instance *mobicore_open(
-	void
-) {
-	struct mc_instance	*instance;
-	pid_t			pid_vnr;
+struct mc_instance *mc_alloc_instance(void)
+{
+	struct mc_instance *instance;
 
 	instance = kzalloc(sizeof(*instance), GFP_KERNEL);
 	if (instance == NULL)
 		return NULL;
 
 	/* get a unique ID for this instance (PIDs are not unique) */
-	instance->handle = get_mc_kmod_unique_id();
+	instance->handle = get_unique_id();
 
-	/* get the PID of the calling process. We avoid using
-	 *	current->pid directly, as 2.6.24 introduced PID
-	 *	namespaces. See also http://lwn.net/Articles/259217 */
-	pid_vnr = task_pid_vnr(current);
-	instance->pid_vnr = pid_vnr;
+	mutex_init(&instance->lock);
 
 	return instance;
 }
-EXPORT_SYMBOL(mobicore_open);
 
-/*----------------------------------------------------------------------------*/
-/**
- * This function will be called from user space as fd = open(...).
+/*
+ * Release a mobicore instance object and all objects related to it
+ * @instance:	instance
+ * Returns 0 if Ok or -E ERROR
+ */
+int mc_release_instance(struct mc_instance *instance)
+{
+	struct mc_buffer *buffer, *tmp;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	mutex_lock(&instance->lock);
+	mc_clear_l2_tables(instance);
+
+	mutex_lock(&ctx.bufs_lock);
+	/* release all mapped data */
+
+	/* Check if some buffers are orphaned. */
+	list_for_each_entry_safe(buffer, tmp, &ctx.cont_bufs, list) {
+		/* It's safe here to only call free_buffer() without unmapping
+		 * because mmap() takes a refcount to the file's fd so only
+		 * time we end up here is when everything has been unmaped or
+		 * the process called exit() */
+		if (buffer->instance == instance) {
+			buffer->instance = NULL;
+			free_buffer(buffer, false);
+		}
+	}
+	mutex_unlock(&ctx.bufs_lock);
+
+	mutex_unlock(&instance->lock);
+
+	/* release instance context */
+	kfree(instance);
+
+	return 0;
+}
+
+/*
+ * mc_fd_user_open() - Will be called from user space as fd = open(...)
  * A set of internal instance data are created and initialized.
  *
- * @param inode
- * @param file
- * @return 0 if OK or -ENOMEM if no allocation was possible.
+ * @inode
+ * @file
+ * Returns 0 if OK or -ENOMEM if no allocation was possible.
  */
-static int mc_kernel_module_open(
-	struct inode	*inode,
-	struct file	*file
-)
+static int mc_fd_user_open(struct inode *inode, struct file *file)
 {
-	struct mc_instance	*instance;
-	int			ret = 0;
+	struct mc_instance *instance;
 
-	MCDRV_DBG_VERBOSE("enter\n");
+	MCDRV_DBG_VERBOSE(mcd, "enter\n");
 
-	do {
-		instance = mobicore_open();
-		if (instance == NULL)
-			return -ENOMEM;
+	instance = mc_alloc_instance();
+	if (instance == NULL)
+		return -ENOMEM;
 
-		/* check if Daemon. We simply assume that the first to open us
-			with root privileges must be the daemon. */
-		if ((is_userland_caller_privileged())
-			&& (mc_drv_kmod_ctx.daemon_inst == NULL)) {
-			MCDRV_DBG("accept this as MobiCore Daemon\n");
+	/* store instance data reference */
+	file->private_data = instance;
 
-			/* Set the caller's CPU mask to CPU0*/
-			ret = goto_cpu0();
-			if (ret != 0) {
-				mobicore_release(instance);
-				file->private_data = NULL;
-				MCDRV_DBG("changing core failed!\n");
-				break;
-			}
-
-			mc_drv_kmod_ctx.daemon_inst = instance;
-			sema_init(&mc_drv_kmod_ctx.daemon_ctx.sem,
-					DAEMON_SEM_VAL);
-			/* init ssiq event counter */
-			mc_drv_kmod_ctx.daemon_ctx.ssiq_counter =
-				atomic_read(
-					&(mc_drv_kmod_ctx.ssiq_ctx.counter));
-
-#ifdef MC_MEM_TRACES
-			/* The traces have to be setup on CPU-0 since we must
-			 * do a fastcall to MobiCore. */
-			if (!mci_base)
-				/* Do the work only if MCI base is not
-				 * initialized properly */
-				work_on_cpu(0, mobicore_log_setup, NULL);
-#endif
-		}
-
-		/* store instance data reference */
-		file->private_data = instance;
-
-		/* TODO axh: link all instances to allow clean up? */
-
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
-
-	return (int)ret;
-
+	return 0;
 }
 
-/*----------------------------------------------------------------------------*/
-/**
- * Release a mobicore instance object and all objects related to it
- * @param instance instance
- * @return 0 if Ok or -E ERROR
- */
-int mobicore_release(
-	struct mc_instance	*instance
-)
+static int mc_fd_admin_open(struct inode *inode, struct file *file)
 {
-	int ret = 0;
-	int i;
-	struct mc_used_l2_table	*used_l2table, *used_l2table_temp;
+	struct mc_instance *instance;
 
-	do {
-		/* try to get the semaphore */
-		ret = down_interruptible(&(mc_drv_kmod_ctx.wsm_l2_sem));
-		if (ret != 0) {
-			MCDRV_DBG_ERROR(
-				"down_interruptible() failed with %d\n", ret);
-			/* TODO: can be block here? */
-			ret = -ERESTARTSYS;
-		} else {
-			/* Check if some WSM is still in use. */
-			list_for_each_entry_safe(
-				used_l2table,
-				used_l2table_temp,
-				&(mc_drv_kmod_ctx.mc_used_l2_tables),
-				list
-			) {
-				if (used_l2table->owner == instance) {
-					MCDRV_DBG_WARN(
-						"trying to release WSM L2: "
-						"physBase=%p ,nr_of_pages=%d\n",
-						get_l2_table_phys(used_l2table),
-						used_l2table->nr_of_pages);
+	/*
+	 * The daemon is already set so we can't allow anybody else to open
+	 * the admin interface.
+	 */
+	if (ctx.daemon_inst) {
+		MCDRV_DBG_ERROR(mcd, "Daemon is already connected");
+		return -EPERM;
+	}
+	/* Setup the usual variables */
+	if (mc_fd_user_open(inode, file))
+		return -ENOMEM;
+	instance = get_instance(file);
 
-					/* unlock app usage and free if MobiCore
-					does not use it */
-					delete_used_l2_table(used_l2table,
-							FREE_FROM_NWD);
-				}
-			} /* end while */
+	MCDRV_DBG(mcd, "accept this as MobiCore Daemon\n");
 
-			/* release semaphore */
-			up(&(mc_drv_kmod_ctx.wsm_l2_sem));
-		}
+	ctx.daemon_inst = instance;
+	ctx.daemon = current;
+	instance->admin = true;
+	init_completion(&ctx.isr_comp);
+	/* init ssiq event counter */
+	ctx.evt_counter = atomic_read(&(ctx.isr_counter));
 
-
-		/* release all mapped data */
-		for (i = 0; i < MC_DRV_KMOD_CONTG_BUFFER_MAX; i++) {
-			struct mc_contg_buffer *contg_buffer =
-					&(instance->contg_buffers[i]);
-
-			if (contg_buffer->virt_user_addr != 0) {
-				free_continguous_pages(
-					contg_buffer->virt_kernel_addr,
-					contg_buffer->num_pages);
-			}
-		}
-
-		/* release instance context */
-		kfree(instance);
-	} while (FALSE);
-
-	return ret;
+	return 0;
 }
-EXPORT_SYMBOL(mobicore_release);
 
-/*----------------------------------------------------------------------------*/
-/**
- * This function will be called from user space as close(...).
+/*
+ * mc_fd_release() - This function will be called from user space as close(...)
  * The instance data are freed and the associated memory pages are unreserved.
  *
- * @param inode
- * @param file
+ * @inode
+ * @file
  *
- * @return 0
+ * Returns 0
  */
-static int mc_kernel_module_release(
-	struct inode	*inode,
-	struct file	*file
-)
+static int mc_fd_release(struct inode *inode, struct file *file)
 {
-	int			ret = 0;
-	struct mc_instance	*instance = get_instance(file);
+	int ret = 0;
+	struct mc_instance *instance = get_instance(file);
 
-	MCDRV_DBG_VERBOSE("enter\n");
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
 
-	do {
-		/* check if daemon closes us. */
-		if (is_caller_mc_daemon(instance)) {
-			/* TODO: cleanup?
-				* mc_drv_kmod_ctx.mc_used_l2_tables remains */
-			MCDRV_DBG_WARN("WARNING: MobiCore Daemon died\n");
-			mc_drv_kmod_ctx.daemon_inst = NULL;
-		}
+	/* check if daemon closes us. */
+	if (is_daemon(instance)) {
+		MCDRV_DBG_WARN(mcd, "WARNING: MobiCore Daemon died\n");
+		ctx.daemon_inst = NULL;
+		ctx.daemon = NULL;
+	}
 
-		ret = mobicore_release(instance);
+	ret = mc_release_instance(instance);
 
-	} while (FALSE);
-
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+	/*
+	 * ret is quite irrelevant here as most apps don't care about the
+	 * return value from close() and it's quite difficult to recover
+	 */
+	MCDRV_DBG_VERBOSE(mcd, "exit with %d/0x%08X\n", ret, ret);
 
 	return (int)ret;
 }
 
-
-/*----------------------------------------------------------------------------*/
-/**
+/*
  * This function represents the interrupt function of the mcDrvModule.
  * It signals by incrementing of an event counter and the start of the read
  * waiting queue, the read function a interrupt has occurred.
- *
- * @param   intr
- * @param   *context  pointer to registered device data
- *
- * @return  IRQ_HANDLED
  */
-static irqreturn_t mc_kernel_module_intr_ssiq(
-	int	intr,
-	void	*context
-)
+static irqreturn_t mc_ssiq_isr(int intr, void *context)
 {
-	irqreturn_t	ret = IRQ_NONE;
+	/* increment interrupt event counter */
+	atomic_inc(&(ctx.isr_counter));
 
-	/* we know the context. */
-	MCDRV_ASSERT(&mc_drv_kmod_ctx == context);
+	/* signal the daemon */
+	complete(&ctx.isr_comp);
 
-	do {
-		if (intr != MC_INTR_SSIQ) {
-			/* this should not happen, as we did no register for any
-				other interrupt. For debugging, we print a
-				message, but continue */
-			MCDRV_DBG_WARN(
-				"unknown interrupt %d, expecting only %d\n",
-				intr, MC_INTR_SSIQ);
-		}
-		MCDRV_DBG_VERBOSE("received interrupt %d\n",
-				  intr);
-
-		/* increment interrupt event counter */
-		atomic_inc(&(mc_drv_kmod_ctx.ssiq_ctx.counter));
-
-		/* signal the daemon */
-		up(&mc_drv_kmod_ctx.daemon_ctx.sem);
-
-
-		ret = IRQ_HANDLED;
-
-	} while (FALSE);
-
-	return ret;
+	return IRQ_HANDLED;
 }
 
-/*----------------------------------------------------------------------------*/
-/** function table structure of this device driver. */
-static const struct file_operations mc_kernel_module_file_operations = {
-	.owner		= THIS_MODULE, /**< driver owner */
-	.open		= mc_kernel_module_open, /**< driver open function */
-	.release	= mc_kernel_module_release, /**< driver release function*/
-	.unlocked_ioctl	= mc_kernel_module_ioctl, /**< driver ioctl function */
-	.mmap		= mc_kernel_module_mmap, /**< driver mmap function */
-	.read		= mc_kernel_module_read, /**< driver read function */
+/* function table structure of this device driver. */
+static const struct file_operations mc_admin_fops = {
+	.owner		= THIS_MODULE,
+	.open		= mc_fd_admin_open,
+	.release	= mc_fd_release,
+	.unlocked_ioctl	= mc_fd_admin_ioctl,
+	.mmap		= mc_fd_mmap,
+	.read		= mc_fd_read,
 };
 
-/*----------------------------------------------------------------------------*/
-/** registration structure as miscdevice. */
-static struct miscdevice mc_kernel_module_device = {
-	.name	= MC_DRV_MOD_DEVNODE, /**< device name */
-	.minor	= MISC_DYNAMIC_MINOR, /**< device minor number */
-	/** device interface function structure */
-	.fops	= &mc_kernel_module_file_operations,
+static struct miscdevice mc_admin_device = {
+	.name	= MC_ADMIN_DEVNODE,
+	.mode	= (S_IRWXU),
+	.minor	= 253,
+	.fops	= &mc_admin_fops,
 };
 
+/* function table structure of this device driver. */
+static const struct file_operations mc_user_fops = {
+	.owner		= THIS_MODULE,
+	.open		= mc_fd_user_open,
+	.release	= mc_fd_release,
+	.unlocked_ioctl	= mc_fd_user_ioctl,
+	.mmap		= mc_fd_mmap,
+};
 
-/*----------------------------------------------------------------------------*/
-/**
+static struct miscdevice mc_user_device = {
+	.name	= MC_USER_DEVNODE,
+	.mode	= (S_IRWXU | S_IRWXG | S_IRWXO),
+	.minor	= 254,
+	.fops	= &mc_user_fops,
+};
+
+/*
  * This function is called the kernel during startup or by a insmod command.
  * This device is installed and registered as miscdevice, then interrupt and
  * queue handling is set up
- *
- * @return 0 for no error or -EIO if registration fails
  */
-static int __init mc_kernel_module_init(
-	void
-)
+static int __init mobicore_init(void)
 {
 	int ret = 0;
 
-	MCDRV_DBG("enter (Build " __TIMESTAMP__ ")\n");
-	MCDRV_DBG("mcDrvModuleApi version is %i.%i\n",
-			MCDRVMODULEAPI_VERSION_MAJOR,
-			MCDRVMODULEAPI_VERSION_MINOR);
+	dev_set_name(mcd, "mcd");
+
+	MCDRV_DBG(mcd, "enter (Build " __TIMESTAMP__ ")\n");
+	MCDRV_DBG(mcd, "mcDrvModuleApi version is %i.%i\n",
+		  MCDRVMODULEAPI_VERSION_MAJOR,
+		  MCDRVMODULEAPI_VERSION_MINOR);
 #ifdef MOBICORE_COMPONENT_BUILD_TAG
-	MCDRV_DBG("%s\n", MOBICORE_COMPONENT_BUILD_TAG);
+	MCDRV_DBG(mcd, "%s\n", MOBICORE_COMPONENT_BUILD_TAG);
 #endif
-	do {
-		/* Hardware does not support ARM TrustZone
-			-> Cannot continue! */
-		if (!has_security_extensions()) {
-			MCDRV_DBG_ERROR(
-				"Hardware does't support ARM TrustZone!\n");
-			ret = -ENODEV;
-			break;
-		}
+	/* Hardware does not support ARM TrustZone -> Cannot continue! */
+	if (!has_security_extensions()) {
+		MCDRV_DBG_ERROR(mcd,
+				"Hardware doesn't support ARM TrustZone!\n");
+		return -ENODEV;
+	}
 
-		/* Running in secure mode -> Cannot load the driver! */
-		if (is_secure_mode()) {
-			MCDRV_DBG_ERROR("Running in secure MODE!\n");
-			ret = -ENODEV;
-			break;
-		}
+	/* Running in secure mode -> Cannot load the driver! */
+	if (is_secure_mode()) {
+		MCDRV_DBG_ERROR(mcd, "Running in secure MODE!\n");
+		return -ENODEV;
+	}
 
-		sema_init(&mc_drv_kmod_ctx.daemon_ctx.sem, DAEMON_SEM_VAL);
-		/* set up S-SIQ interrupt handler */
-		ret = request_irq(
-				  MC_INTR_SSIQ,
-				  mc_kernel_module_intr_ssiq,
-				  IRQF_TRIGGER_RISING,
-				  MC_DRV_MOD_DEVNODE,
-				  &mc_drv_kmod_ctx);
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("interrupt request failed\n");
-			break;
-		}
+	ret = mc_fastcall_init(&ctx);
+	if (ret)
+		goto error;
 
-		ret = misc_register(&mc_kernel_module_device);
-		if (ret != 0) {
-			MCDRV_DBG_ERROR("device register failed\n");
-			break;
-		}
+	init_completion(&ctx.isr_comp);
+	/* set up S-SIQ interrupt handler */
+	ret = request_irq(MC_INTR_SSIQ, mc_ssiq_isr, IRQF_TRIGGER_RISING,
+			MC_ADMIN_DEVNODE, &ctx);
+	if (ret != 0) {
+		MCDRV_DBG_ERROR(mcd, "interrupt request failed\n");
+		goto err_req_irq;
+	}
 
-		/* initialize event counter for signaling of an IRQ to zero */
-		atomic_set(&(mc_drv_kmod_ctx.ssiq_ctx.counter), 0);
+#ifdef MC_PM_RUNTIME
+	ret = mc_pm_initialize(&ctx);
+	if (ret != 0) {
+		MCDRV_DBG_ERROR(mcd, "Power Management init failed!\n");
+		goto free_isr;
+	}
+#endif
 
-		/* init list for WSM L2 chunks. */
-		INIT_LIST_HEAD(&(mc_drv_kmod_ctx.mc_l2_tables_sets));
+	ret = misc_register(&mc_admin_device);
+	if (ret != 0) {
+		MCDRV_DBG_ERROR(mcd, "admin device register failed\n");
+		goto free_isr;
+	}
 
-		/* L2 table descriptor list. */
-		INIT_LIST_HEAD(&(mc_drv_kmod_ctx.mc_used_l2_tables));
+	ret = misc_register(&mc_user_device);
+	if (ret != 0) {
+		MCDRV_DBG_ERROR(mcd, "user device register failed\n");
+		goto free_admin;
+	}
 
-		sema_init(&(mc_drv_kmod_ctx.wsm_l2_sem), 1);
+	/* initialize event counter for signaling of an IRQ to zero */
+	atomic_set(&ctx.isr_counter, 0);
 
-		/* initialize unique number counter which we can use for
-			handles. It is limited to 2^32, but this should be
-			enough to be roll-over safe for us. We start with 1
-			instead of 0. */
-		atomic_set(&(mc_drv_kmod_ctx.unique_counter), 1);
+	ret = mc_init_l2_tables();
 
-		mci_base = 0;
-		MCDRV_DBG("initialized\n");
+	/*
+	 * initialize unique number counter which we can use for
+	 * handles. It is limited to 2^32, but this should be
+	 * enough to be roll-over safe for us. We start with 1
+	 * instead of 0.
+	 */
+	atomic_set(&ctx.unique_counter, 1);
 
-		ret = 0;
+	/* init list for contiguous buffers  */
+	INIT_LIST_HEAD(&ctx.cont_bufs);
 
-	} while (FALSE);
+	/* init lock for the buffers list */
+	mutex_init(&ctx.bufs_lock);
 
-	MCDRV_DBG_VERBOSE("exit with %d/0x%08X\n", ret, ret);
+	memset(&ctx.mci_base, 0, sizeof(ctx.mci_base));
+	MCDRV_DBG(mcd, "initialized\n");
+	return 0;
 
-	return (int)ret;
+free_admin:
+	misc_deregister(&mc_admin_device);
+free_isr:
+	free_irq(MC_INTR_SSIQ, &ctx);
+err_req_irq:
+	mc_fastcall_destroy();
+error:
+	return ret;
 }
 
-
-
-/*----------------------------------------------------------------------------*/
-/**
+/*
  * This function removes this device driver from the Linux device manager .
  */
-static void __exit mc_kernel_module_exit(
-	void
-)
+static void __exit mobicore_exit(void)
 {
-	struct mc_used_l2_table	*used_l2table;
-
-	MCDRV_DBG_VERBOSE("enter\n");
-
+	MCDRV_DBG_VERBOSE(mcd, "enter\n");
+#ifdef MC_MEM_TRACES
 	mobicore_log_free();
+#endif
 
-	/* Check if some WSM is still in use. */
-	list_for_each_entry(
-		used_l2table,
-		&(mc_drv_kmod_ctx.mc_used_l2_tables),
-		list
-	) {
-		MCDRV_DBG_WARN(
-			"WSM L2 still in use: physBase=%p ,nr_of_pages=%d\n",
-			get_l2_table_phys(used_l2table),
-			used_l2table->nr_of_pages);
-	} /* end while */
+	mc_release_l2_tables();
 
-	free_irq(MC_INTR_SSIQ, &mc_drv_kmod_ctx);
+#ifdef MC_PM_RUNTIME
+	mc_pm_free();
+#endif
 
-	misc_deregister(&mc_kernel_module_device);
-	MCDRV_DBG_VERBOSE("exit");
+	free_irq(MC_INTR_SSIQ, &ctx);
+
+	misc_deregister(&mc_admin_device);
+	misc_deregister(&mc_user_device);
+
+	mc_fastcall_destroy();
+
+	MCDRV_DBG_VERBOSE(mcd, "exit");
 }
 
-
-/*----------------------------------------------------------------------------*/
 /* Linux Driver Module Macros */
-module_init(mc_kernel_module_init);
-module_exit(mc_kernel_module_exit);
+module_init(mobicore_init);
+module_exit(mobicore_exit);
 MODULE_AUTHOR("Giesecke & Devrient GmbH");
+MODULE_AUTHOR("Trustonic Limited");
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("MobiCore driver");
 
-/** @} */
-
diff --git a/drivers/gud/mobicore_driver/main.h b/drivers/gud/mobicore_driver/main.h
new file mode 100644
index 0000000..871191e
--- /dev/null
+++ b/drivers/gud/mobicore_driver/main.h
@@ -0,0 +1,150 @@
+/*
+ * Header file of MobiCore Driver Kernel Module.
+ *
+ * Internal structures of the McDrvModule
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * 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 _MC_MAIN_H_
+#define _MC_MAIN_H_
+
+#include <asm/pgtable.h>
+#include <linux/semaphore.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+
+#include "public/mc_linux.h"
+/* Platform specific settings */
+#include "platform.h"
+
+#define MC_VERSION(major, minor) \
+		(((major & 0x0000ffff) << 16) | (minor & 0x0000ffff))
+
+/* Instance data for MobiCore Daemon and TLCs. */
+struct mc_instance {
+	/* lock for the instance */
+	struct mutex lock;
+	/* unique handle */
+	unsigned int handle;
+	bool admin;
+};
+
+/*
+ * Contiguous buffer allocated to TLCs.
+ * These buffers are uses as world shared memory (wsm) and shared with
+ * secure world.
+ * The virtual kernel address is added for a simpler search algorithm.
+ */
+struct mc_buffer {
+	struct list_head	list;
+	/* unique handle */
+	unsigned int		handle;
+	/* Number of references kept to this buffer */
+	atomic_t		usage;
+	/* virtual Kernel start address */
+	void			*addr;
+	/* virtual Userspace start address */
+	void			*uaddr;
+	/* physical start address */
+	void			*phys;
+	/* order of number of pages */
+	unsigned int		order;
+	uint32_t		len;
+	struct mc_instance	*instance;
+};
+
+/* MobiCore Driver Kernel Module context data. */
+struct mc_context {
+	/* MobiCore MCI information */
+	struct mc_buffer	mci_base;
+	/* MobiCore MCP buffer */
+	struct mc_mcp_buffer	*mcp;
+	/* event completion */
+	struct completion	isr_comp;
+	/* isr event counter */
+	unsigned int		evt_counter;
+	atomic_t		isr_counter;
+	/* ever incrementing counter */
+	atomic_t		unique_counter;
+	/* pointer to instance of daemon */
+	struct mc_instance	*daemon_inst;
+	/* pointer to instance of daemon */
+	struct task_struct	*daemon;
+	/* General list of contiguous buffers allocated by the kernel */
+	struct list_head	cont_bufs;
+	/* Lock for the list of contiguous buffers */
+	struct mutex		bufs_lock;
+};
+
+struct mc_sleep_mode {
+	uint16_t	SleepReq;
+	uint16_t	ReadyToSleep;
+};
+
+/* MobiCore is idle. No scheduling required. */
+#define SCHEDULE_IDLE		0
+/* MobiCore is non idle, scheduling is required. */
+#define SCHEDULE_NON_IDLE	1
+
+/* MobiCore status flags */
+struct mc_flags {
+	/*
+	 * Scheduling hint: if <> SCHEDULE_IDLE, MobiCore should
+	 * be scheduled by the NWd
+	 */
+	uint32_t		schedule;
+	/* State of sleep protocol */
+	struct mc_sleep_mode	sleep_mode;
+	/* Reserved for future use: Must not be interpreted */
+	uint32_t		rfu[2];
+};
+
+/* MCP buffer structure */
+struct mc_mcp_buffer {
+	/* MobiCore Flags */
+	struct mc_flags	flags;
+	uint32_t	rfu; /* MCP message buffer - ignore */
+};
+
+unsigned int get_unique_id(void);
+
+/* check if caller is MobiCore Daemon */
+static inline bool is_daemon(struct mc_instance *instance)
+{
+	if (!instance)
+		return false;
+	return instance->admin;
+}
+
+
+/* Initialize a new mobicore API instance object */
+struct mc_instance *mc_alloc_instance(void);
+/* Release a mobicore instance object and all objects related to it */
+int mc_release_instance(struct mc_instance *instance);
+
+/*
+ * mc_register_wsm_l2() - Create a L2 table from a virtual memory buffer which
+ * can be vmalloc or user space virtual memory
+ */
+int mc_register_wsm_l2(struct mc_instance *instance,
+	uint32_t buffer, uint32_t len,
+	uint32_t *handle, uint32_t *phys);
+/* Unregister the buffer mapped above */
+int mc_unregister_wsm_l2(struct mc_instance *instance, uint32_t handle);
+
+/* Allocate one mc_buffer of contiguous space */
+int mc_get_buffer(struct mc_instance *instance,
+	struct mc_buffer **buffer, unsigned long len);
+/* Free the buffer allocated above */
+int mc_free_buffer(struct mc_instance *instance, uint32_t handle);
+
+/* Check if the other end of the fd owns instance */
+bool mc_check_owner_fd(struct mc_instance *instance, int32_t fd);
+
+#endif /* _MC_MAIN_H_ */
diff --git a/drivers/gud/mobicore_driver/mc_drv_module.h b/drivers/gud/mobicore_driver/mc_drv_module.h
deleted file mode 100644
index 8b402d6..0000000
--- a/drivers/gud/mobicore_driver/mc_drv_module.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- * Header file of MobiCore Driver Kernel Module.
- *
- * @addtogroup MCD_MCDIMPL_KMOD_IMPL
- * @{
- * Internal structures of the McDrvModule
- * @file
- *
- * Header file the MobiCore Driver Kernel Module,
- * its internal structures and defines.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
- *
- * 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 _MC_DRV_KMOD_H_
-#define _MC_DRV_KMOD_H_
-
-#include "mc_drv_module_linux_api.h"
-#include "public/mc_drv_module_api.h"
-/** Platform specific settings */
-#include "platform.h"
-
-/** ARM Specific masks and modes */
-#define ARM_CPSR_MASK 0x1F
-#define ARM_MONITOR_MODE 0b10110
-#define ARM_SECURITY_EXTENSION_MASK 0x30
-
-/**
- * Number of page table entries in one L2 table. This is ARM specific, an
- *  L2 table covers 1 MiB by using 256 entry referring to 4KiB pages each.
- */
-#define MC_ARM_L2_TABLE_ENTRIES		256
-
-/** Maximum number of contiguous buffer allocations for one driver instance. */
-#define MC_DRV_KMOD_CONTG_BUFFER_MAX	16
-
-/** Number of pages for L2 tables. There are 4 table in each page. */
-#define MC_DRV_KMOD_L2_TABLE_PER_PAGES	4
-
-/** ARM level 2 (L2) table with 256 entries. Size: 1k */
-struct l2table {
-	pte_t	table_entries[MC_ARM_L2_TABLE_ENTRIES];
-};
-
-#define INVALID_ADDRESS     ((void *)(-1))
-
-/** ARM L2 PTE bits */
-#define L2_FLAG_SMALL_XN    (1U <<  0)
-#define L2_FLAG_SMALL       (1U <<  1)
-#define L2_FLAG_B           (1U <<  2)
-#define L2_FLAG_C           (1U <<  3)
-#define L2_FLAG_AP0         (1U <<  4)
-#define L2_FLAG_AP1         (1U <<  5)
-#define L2_FLAG_SMALL_TEX0  (1U <<  6)
-#define L2_FLAG_SMALL_TEX1  (1U <<  7)
-#define L2_FLAG_SMALL_TEX2  (1U <<  8)
-#define L2_FLAG_APX         (1U <<  9)
-#define L2_FLAG_S           (1U << 10)
-#define L2_FLAG_NG          (1U << 11)
-
-/**
- * Contiguous buffer allocated to TLCs.
- * These buffers are uses as world shared memory (wsm) and shared with
- * secure world.
- * The virtual kernel address is added for a simpler search algorithm.
- */
-struct mc_contg_buffer {
-	unsigned int	handle; /* unique handle */
-	void		*virt_user_addr; /**< virtual User start address */
-	void		*virt_kernel_addr; /**< virtual Kernel start address */
-	void		*phys_addr; /**< physical start address */
-	unsigned int	num_pages; /**< number of pages */
-};
-
-/** Instance data for MobiCore Daemon and TLCs. */
-struct mc_instance {
-	/** unique handle */
-	unsigned int	handle;
-	/** process that opened this instance */
-	pid_t		pid_vnr;
-	/** buffer list for mmap generated address space and
-		its virtual client address */
-	struct mc_contg_buffer	contg_buffers[MC_DRV_KMOD_CONTG_BUFFER_MAX];
-};
-
-/** Store for four L2 tables in one 4kb page*/
-struct mc_l2_table_store {
-	struct l2table table[MC_DRV_KMOD_L2_TABLE_PER_PAGES];
-};
-
-/** Usage and maintenance information about mc_l2_table_store */
-struct mc_l2_tables_set {
-	struct list_head		list;
-	unsigned int			usage_bitmap;	/**< usage bitmap */
-	struct mc_l2_table_store	*kernel_virt;	/**< kernel virtual address */
-	struct mc_l2_table_store	*phys;		/**< physical address */
-	struct page			*page;		/**< pointer to page struct */
-};
-
-/**
- * L2 table allocated to the Daemon or a TLC describing a world shared buffer.
- * When users map a malloc()ed area into SWd, a L2 table is allocated.
- * In addition, the area of maximum 1MB virtual address space is mapped into
- * the L2 table and a handle for this table is returned to the user.
- */
-struct mc_used_l2_table {
-	struct list_head	list;
-
-	/** handle as communicated to user mode */
-	unsigned int		handle;
-	unsigned int		flags;
-
-	/** owner of this L2 table */
-	struct mc_instance	*owner;
-
-	/** set describing where our L2 table is stored */
-	struct mc_l2_tables_set	*set;
-
-	/** index into L2 table set */
-	unsigned int		idx;
-
-	/** size of buffer */
-	unsigned int		nr_of_pages;
-};
-
-#define MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP   (1U << 0)
-#define MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC    (1U << 1)
-
-
-/** MobiCore S-SIQ interrupt context data. */
-struct mc_ssiq_ctx {
-	/** S-SIQ interrupt counter */
-	atomic_t	counter;
-};
-
-/** MobiCore Daemon context data. */
-struct mc_daemon_ctx {
-	/** event semaphore */
-	struct semaphore	sem;
-	struct fasync_struct	*async_queue;
-	/** event counter */
-	unsigned int		ssiq_counter;
-};
-
-/** MobiCore Driver Kernel Module context data. */
-struct mc_drv_kmod_ctx {
-
-	/** ever incrementing counter */
-	atomic_t		unique_counter;
-
-	/** S-SIQ interrupt context */
-	struct mc_ssiq_ctx	ssiq_ctx;
-
-	/** MobiCore Daemon context */
-	struct mc_daemon_ctx	daemon_ctx;
-
-	/** pointer to instance of daemon */
-	struct mc_instance	*daemon_inst;
-
-	/** Backing store for L2 tables */
-	struct list_head	mc_l2_tables_sets;
-
-	/** Bookkeeping for used L2 tables */
-	struct list_head	mc_used_l2_tables;
-
-	/** semaphore to synchronize access to above lists */
-	struct semaphore	wsm_l2_sem;
-};
-
-/** MobiCore internal trace buffer structure. */
-struct mc_trace_buf {
-	uint32_t version; /**< version of trace buffer */
-	uint32_t length; /**< length of allocated buffer(includes header) */
-	uint32_t write_pos; /**< last write position */
-	char  buff[1]; /**< start of the log buffer */
-};
-
-/*** MobiCore internal trace log setup. */
-void mobicore_log_read(void);
-long mobicore_log_setup(void *);
-void mobicore_log_free(void);
-
-#define MCDRV_DBG_ERROR(txt, ...) \
-	printk(KERN_ERR "mcDrvKMod [%d] %s() ### ERROR: " txt, \
-		task_pid_vnr(current), \
-		__func__, \
-		##__VA_ARGS__)
-
-/* dummy function helper macro. */
-#define DUMMY_FUNCTION()    do {} while (0)
-
-#if defined(DEBUG)
-
-/* #define DEBUG_VERBOSE */
-#if defined(DEBUG_VERBOSE)
-#define MCDRV_DBG_VERBOSE          MCDRV_DBG
-#else
-#define MCDRV_DBG_VERBOSE(...)     DUMMY_FUNCTION()
-#endif
-
-#define MCDRV_DBG(txt, ...) \
-	printk(KERN_INFO "mcDrvKMod [%d on CPU%d] %s(): " txt, \
-		task_pid_vnr(current), \
-		raw_smp_processor_id(), \
-		__func__, \
-		##__VA_ARGS__)
-
-#define MCDRV_DBG_WARN(txt, ...) \
-	printk(KERN_WARNING "mcDrvKMod [%d] %s() WARNING: " txt, \
-		task_pid_vnr(current), \
-		__func__, \
-		##__VA_ARGS__)
-
-#define MCDRV_ASSERT(cond) \
-	do { \
-		if (unlikely(!(cond))) { \
-			panic("mcDrvKMod Assertion failed: %s:%d\n", \
-				__FILE__, __LINE__); \
-		} \
-	} while (0)
-
-#else
-
-#define MCDRV_DBG_VERBOSE(...)	DUMMY_FUNCTION()
-#define MCDRV_DBG(...)		DUMMY_FUNCTION()
-#define MCDRV_DBG_WARN(...)	DUMMY_FUNCTION()
-
-#define MCDRV_ASSERT(...)	DUMMY_FUNCTION()
-
-#endif /* [not] defined(DEBUG) */
-
-
-#endif /* _MC_DRV_KMOD_H_ */
-/** @} */
diff --git a/drivers/gud/mobicore_driver/mc_drv_module_android.h b/drivers/gud/mobicore_driver/mc_drv_module_android.h
deleted file mode 100644
index 319509f..0000000
--- a/drivers/gud/mobicore_driver/mc_drv_module_android.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Header file of MobiCore Driver Kernel Module.
- *
- * @addtogroup MobiCore_Driver_Kernel_Module
- * @{
- * Android specific defines
- * @file
- *
- * Android specific defines
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
- *
- * 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 _MC_DRV_MODULE_ANDROID_H_
-#define _MC_DRV_MODULE_ANDROID_H_
-
-/* Defines needed to identify the Daemon in Android systems
- * For the full list see:
- * platform_system_core/include/private/android_filesystem_config.h in the
- * Android source tree
- */
-/* traditional unix root user */
-#define AID_ROOT	0
-/* system server */
-#define AID_SYSTEM	1000
-/* access to misc storage */
-#define AID_MISC	9998
-#define AID_NOBODY	9999
-/* first app user */
-#define AID_APP		10000
-
-#endif /* _MC_DRV_MODULE_ANDROID_H_ */
-/** @} */
diff --git a/drivers/gud/mobicore_driver/mc_drv_module_fastcalls.h b/drivers/gud/mobicore_driver/mc_drv_module_fastcalls.h
deleted file mode 100644
index d058043..0000000
--- a/drivers/gud/mobicore_driver/mc_drv_module_fastcalls.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/**
- * Header file of MobiCore Driver Kernel Module.
- *
- * @addtogroup MobiCore_Driver_Kernel_Module
- * @{
- * Internal structures of the McDrvModule
- * @file
- *
- * MobiCore Fast Call interface
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
- *
- * 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 _MC_DRV_MODULE_FC_H_
-#define _MC_DRV_MODULE_FC_H_
-
-#include "mc_drv_module.h"
-
-/**
- * MobiCore SMCs
- */
-enum mc_smc_codes {
-	MC_SMC_N_YIELD  = 0x3, /**< Yield to switch from NWd to SWd. */
-	MC_SMC_N_SIQ    = 0x4  /**< SIQ to switch from NWd to SWd. */
-};
-
-/**
- * MobiCore fast calls. See MCI documentation
- */
-enum mc_fast_call_codes {
-	MC_FC_INIT      = -1,
-	MC_FC_INFO      = -2,
-	MC_FC_POWER     = -3,
-	MC_FC_DUMP      = -4,
-	MC_FC_NWD_TRACE = -31 /**< Mem trace setup fastcall */
-};
-
-/**
- * return code for fast calls
- */
-enum mc_fast_calls_result {
-	MC_FC_RET_OK                       = 0,
-	MC_FC_RET_ERR_INVALID              = 1,
-	MC_FC_RET_ERR_ALREADY_INITIALIZED  = 5
-};
-
-
-
-/*------------------------------------------------------------------------------
-	structure wrappers for specific fastcalls
-------------------------------------------------------------------------------*/
-
-/** generic fast call parameters */
-union fc_generic {
-	struct {
-		uint32_t cmd;
-		uint32_t param[3];
-	} as_in;
-	struct {
-		uint32_t resp;
-		uint32_t ret;
-		uint32_t param[2];
-	} as_out;
-};
-
-
-/** fast call init */
-union mc_fc_init {
-	union fc_generic as_generic;
-	struct {
-		uint32_t cmd;
-		uint32_t base;
-		uint32_t nq_info;
-		uint32_t mcp_info;
-	} as_in;
-	struct {
-		uint32_t resp;
-		uint32_t ret;
-		uint32_t rfu[2];
-	} as_out;
-};
-
-
-/** fast call info parameters */
-union mc_fc_info {
-	union fc_generic as_generic;
-	struct {
-		uint32_t cmd;
-		uint32_t ext_info_id;
-		uint32_t rfu[2];
-	} as_in;
-	struct {
-		uint32_t resp;
-		uint32_t ret;
-		uint32_t state;
-		uint32_t ext_info;
-	} as_out;
-};
-
-
-/** fast call S-Yield parameters */
-union mc_fc_s_yield {
-	union fc_generic as_generic;
-	struct {
-		uint32_t cmd;
-		uint32_t rfu[3];
-	} as_in;
-	struct {
-		uint32_t resp;
-		uint32_t ret;
-		uint32_t rfu[2];
-	} as_out;
-};
-
-
-/** fast call N-SIQ parameters */
-union mc_fc_nsiq {
-	union fc_generic as_generic;
-	struct {
-		uint32_t cmd;
-		uint32_t rfu[3];
-	} as_in;
-	struct {
-		uint32_t resp;
-		uint32_t ret;
-		uint32_t rfu[2];
-	} as_out;
-};
-
-
-/*----------------------------------------------------------------------------*/
-/**
- * fast call to MobiCore
- *
- * @param fc_generic pointer to fast call data
- */
-static inline void mc_fastcall(
-	union fc_generic *fc_generic
-)
-{
-	MCDRV_ASSERT(fc_generic != NULL);
-	/* We only expect to make smc calls on CPU0 otherwise something wrong
-	 * will happen */
-	MCDRV_ASSERT(raw_smp_processor_id() == 0);
-	mb();
-#ifdef MC_SMC_FASTCALL
-	{
-		int ret = 0;
-		MCDRV_DBG("Going into SCM()");
-		ret = smc_fastcall((void *)fc_generic, sizeof(*fc_generic));
-		MCDRV_DBG("Coming from SCM, scm_call=%i, resp=%d/0x%x\n",
-			ret,
-			fc_generic->as_out.resp, fc_generic->as_out.resp);
-	}
-#else
-	{
-		/* SVC expect values in r0-r3 */
-		register u32 reg0 __asm__("r0") = fc_generic->as_in.cmd;
-		register u32 reg1 __asm__("r1") = fc_generic->as_in.param[0];
-		register u32 reg2 __asm__("r2") = fc_generic->as_in.param[1];
-		register u32 reg3 __asm__("r3") = fc_generic->as_in.param[2];
-
-		/* one of the famous preprocessor hacks to stingitize things.*/
-#define __STR2(x)   #x
-#define __STR(x)    __STR2(x)
-
-		/* compiler does not support certain instructions
-		"SMC": secure monitor call.*/
-#define ASM_ARM_SMC         0xE1600070
-		/*   "BPKT": debugging breakpoint. We keep this, as is comes
-				quite handy for debugging. */
-#define ASM_ARM_BPKT        0xE1200070
-#define ASM_THUMB_BPKT      0xBE00
-
-
-		__asm__ volatile (
-			".word " __STR(ASM_ARM_SMC) "\n"
-			: "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
-		);
-
-		/* set response */
-		fc_generic->as_out.resp     = reg0;
-		fc_generic->as_out.ret      = reg1;
-		fc_generic->as_out.param[0] = reg2;
-		fc_generic->as_out.param[1] = reg3;
-	}
-#endif
-}
-
-
-/*----------------------------------------------------------------------------*/
-/**
- * convert fast call return code to linux driver module error code
- *
- */
-static inline int convert_fc_ret(
-	uint32_t sret
-)
-{
-	int         ret = -EFAULT;
-
-	switch (sret) {
-
-	case MC_FC_RET_OK:
-		ret = 0;
-		break;
-
-	case MC_FC_RET_ERR_INVALID:
-		ret = -EINVAL;
-		break;
-
-	case MC_FC_RET_ERR_ALREADY_INITIALIZED:
-		ret = -EBUSY;
-		break;
-
-	default:
-		break;
-	} /* end switch( sret ) */
-	return ret;
-}
-
-#endif /* _MC_DRV_MODULE_FC_H_ */
-/** @} */
diff --git a/drivers/gud/mobicore_driver/mc_drv_module_linux_api.h b/drivers/gud/mobicore_driver/mc_drv_module_linux_api.h
deleted file mode 100644
index b2a99f1..0000000
--- a/drivers/gud/mobicore_driver/mc_drv_module_linux_api.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/**
- * Header file of MobiCore Driver Kernel Module.
- *
- * @addtogroup MobiCore_Driver_Kernel_Module
- * @{
- * Wrapper for Linux API
- * @file
- *
- * Some convenient wrappers for memory functions
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
- *
- * 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 _MC_DRV_MODULE_LINUX_API_H_
-#define _MC_DRV_MODULE_LINUX_API_H_
-
-#include <linux/version.h>
-#include <linux/miscdevice.h>
-#include <linux/interrupt.h>
-#include <linux/highmem.h>
-#include <linux/kthread.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <asm/sizes.h>
-#include <asm/pgtable.h>
-#include <linux/semaphore.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-
-
-/* make some nice types */
-#if !defined(TRUE)
-#define TRUE (1 == 1)
-#endif
-
-#if !defined(FALSE)
-#define FALSE (1 != 1)
-#endif
-
-
-/* Linux GCC modifiers */
-#if !defined(__init)
-#warning "missing definition: __init"
-/* define a dummy */
-#define __init
-#endif
-
-
-#if !defined(__exit)
-#warning "missing definition: __exit"
-/* define a dummy */
-#define __exit
-#endif
-
-
-#if !defined(__must_check)
-#warning "missing definition: __must_check"
-/* define a dummy */
-#define __must_check
-#endif
-
-
-#if !defined(__user)
-#warning "missing definition: __user"
-/* define a dummy */
-#define __user
-#endif
-
-#define INVALID_ORDER       ((unsigned int)(-1))
-
-/*----------------------------------------------------------------------------*/
-/* get start address of the 4 KiB page where the given addres is located in. */
-static inline void *get_page_start(
-	void *addr
-)
-{
-	return (void *)(((unsigned long)(addr)) & PAGE_MASK);
-}
-
-/*----------------------------------------------------------------------------*/
-/* get offset into the 4 KiB page where the given addres is located in. */
-static inline unsigned int get_offset_in_page(
-	void *addr
-)
-{
-	return (unsigned int)(((unsigned long)(addr)) & (~PAGE_MASK));
-}
-
-/*----------------------------------------------------------------------------*/
-/* get number of pages for a given buffer. */
-static inline unsigned int get_nr_of_pages_for_buffer(
-	void		*addr_start, /* may be null */
-	unsigned int	len
-)
-{
-	/* calculate used number of pages. Example:
-	offset+size    newSize+PAGE_SIZE-1    nr_of_pages
-	   0              4095                   0
-	   1              4096                   1
-	  4095            8190                   1
-	  4096            8191                   1
-	  4097            8192                   2 */
-
-	return (get_offset_in_page(addr_start) + len + PAGE_SIZE-1) / PAGE_SIZE;
-}
-
-
-/*----------------------------------------------------------------------------*/
-/**
- * convert a given size to page order, which is equivalent to finding log_2(x).
- * The maximum for order was 5 in Linux 2.0 corresponding to 32 pages.
- * Later versions allow 9 corresponding to 512 pages, which is 2 MB on
- * most platforms). Anyway, the bigger order is, the more likely it is
- * that the allocation will fail.
- * Size       0           1  4097  8193  12289  24577  28673   40961   61441
- * Pages      -           1     2     3      4      7      8      15      16
- * Order  INVALID_ORDER   0     1     1      2      2      3       3       4
- *
- * @param  size
- * @return order
- */
-static inline unsigned int size_to_order(
-	unsigned int size
-)
-{
-	unsigned int order = INVALID_ORDER;
-
-	if (size != 0) {
-		/* ARMv5 as a CLZ instruction which count the leading zeros of
-		the binary representation of a value. It return a value
-		between 0 and 32.
-		Value   0   1   2   3   4   5   6   7   8   9  10 ...
-		CLZ    32  31  30  30  29  29  29  29  28  28  28 ...
-
-		We have excluded Size==0 before, so this is safe. */
-		order = __builtin_clz(
-				get_nr_of_pages_for_buffer(NULL, size));
-
-		/* there is a size overflow in get_nr_of_pages_for_buffer when
-		 * the size is too large */
-		if (unlikely(order > 31))
-			return INVALID_ORDER;
-		order = 31 - order;
-
-		/* above algorithm rounds down: clz(5)=2 instead of 3 */
-		/* quick correction to fix it: */
-		if (((1<<order)*PAGE_SIZE) < size)
-			order++;
-	}
-	return order;
-}
-
-/* magic linux macro */
-#if !defined(list_for_each_entry)
-/* stop compiler */
-#error "missing macro: list_for_each_entry()"
-/* define a dummy */
-#define list_for_each_entry(a, b, c)    if (0)
-#endif
-
-/*----------------------------------------------------------------------------*/
-/* return the page frame number of an address */
-static inline unsigned int addr_to_pfn(
-	void *addr
-)
-{
-	/* there is no real API for this */
-	return ((unsigned int)(addr)) >> PAGE_SHIFT;
-}
-
-
-/*----------------------------------------------------------------------------*/
-/* return the address of a page frame number */
-static inline void *pfn_to_addr(
-	unsigned int pfn
-)
-{
-	/* there is no real API for this */
-	return (void *)(pfn << PAGE_SHIFT);
-}
-
-#endif /* _MC_DRV_MODULE_LINUX_API_H_ */
-/** @} */
diff --git a/drivers/gud/mobicore_driver/mem.c b/drivers/gud/mobicore_driver/mem.c
new file mode 100644
index 0000000..33c51b6
--- /dev/null
+++ b/drivers/gud/mobicore_driver/mem.c
@@ -0,0 +1,708 @@
+/*
+ * MobiCore Driver Kernel Module.
+ *
+ * This module is written as a Linux device driver.
+ * This driver represents the command proxy on the lowest layer, from the
+ * secure world to the non secure world, and vice versa.
+ * This driver is located in the non secure world (Linux).
+ * This driver offers IOCTL commands, for access to the secure world, and has
+ * the interface from the secure world to the normal world.
+ * The access to the driver is possible with a file descriptor,
+ * which has to be created by the fd = open(/dev/mobicore) command.
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * 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 "main.h"
+#include "debug.h"
+#include "mem.h"
+
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/pagemap.h>
+#include <linux/device.h>
+
+
+/* MobiCore memory context data */
+struct mc_mem_context mem_ctx;
+
+/* convert L2 PTE to page pointer */
+static inline struct page *l2_pte_to_page(pte_t pte)
+{
+	unsigned long phys_page_addr = ((unsigned long)pte & PAGE_MASK);
+	unsigned int pfn = phys_page_addr >> PAGE_SHIFT;
+	struct page *page = pfn_to_page(pfn);
+	return page;
+}
+
+/* convert page pointer to L2 PTE */
+static inline pte_t page_to_l2_pte(struct page *page)
+{
+	unsigned long pfn = page_to_pfn(page);
+	unsigned long phys_addr = (pfn << PAGE_SHIFT);
+	pte_t pte = (pte_t)(phys_addr & PAGE_MASK);
+	return pte;
+}
+
+static inline void release_page(struct page *page)
+{
+	SetPageDirty(page);
+
+	page_cache_release(page);
+}
+
+static int lock_pages(struct task_struct *task, void *virt_start_page_addr,
+	int pages_no, struct page **pages)
+{
+	int locked_pages;
+
+	/* lock user pages, must hold the mmap_sem to do this. */
+	down_read(&(task->mm->mmap_sem));
+	locked_pages = get_user_pages(
+				task,
+				task->mm,
+				(unsigned long)virt_start_page_addr,
+				pages_no,
+				1, /* write access */
+				0,
+				pages,
+				NULL);
+	up_read(&(task->mm->mmap_sem));
+
+	/* check if we could lock all pages. */
+	if (locked_pages != pages_no) {
+		MCDRV_DBG_ERROR(mcd, "get_user_pages() failed, locked_pages=%d",
+				locked_pages);
+		if (locked_pages > 0) {
+			/* release all locked pages. */
+			release_pages(pages, locked_pages, 0);
+		}
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/* Get kernel pointer to shared L2 table given a per-process reference */
+struct l2table *get_l2_table_kernel_virt(struct mc_l2_table *table)
+{
+	if (WARN(!table, "Invalid L2 table"))
+		return NULL;
+
+	if (WARN(!table->set, "Invalid L2 table set"))
+		return NULL;
+
+	if (WARN(!table->set->kernel_virt, "Invalid L2 pointer"))
+		return NULL;
+
+	return &(table->set->kernel_virt->table[table->idx]);
+}
+
+/* Get physical address of a shared L2 table given a per-process reference */
+struct l2table *get_l2_table_phys(struct mc_l2_table *table)
+{
+	if (WARN(!table, "Invalid L2 table"))
+		return NULL;
+	if (WARN(!table->set, "Invalid L2 table set"))
+		return NULL;
+	if (WARN(!table->set->kernel_virt, "Invalid L2 phys pointer"))
+		return NULL;
+
+	return &(table->set->phys->table[table->idx]);
+}
+
+static inline int in_use(struct mc_l2_table *table)
+{
+	return atomic_read(&table->usage) > 0;
+}
+
+/*
+ * Search the list of used l2 tables and return the one with the handle.
+ * Assumes the table_lock is taken.
+ */
+struct mc_l2_table *find_l2_table(unsigned int handle)
+{
+	struct mc_l2_table *table;
+
+	list_for_each_entry(table, &mem_ctx.l2_tables, list) {
+		if (table->handle == handle)
+			return table;
+	}
+	return NULL;
+}
+
+/*
+ * Allocate a new l2 table store plus L2_TABLES_PER_PAGE in the l2 free tables
+ * list. Assumes the table_lock is already taken by the caller above.
+ */
+static int alloc_table_store(void)
+{
+	unsigned long store;
+	struct mc_l2_tables_set *l2table_set;
+	struct mc_l2_table *l2table, *l2table2;
+	struct page *page;
+	int ret = 0, i;
+	/* temp list for holding the l2 tables */
+	LIST_HEAD(temp);
+
+	store = get_zeroed_page(GFP_KERNEL);
+	if (!store)
+		return -ENOMEM;
+
+	/*
+	 * Actually, locking is not necessary, because kernel
+	 * memory is not supposed to get swapped out. But we
+	 * play safe....
+	 */
+	page = virt_to_page(store);
+	SetPageReserved(page);
+
+	/* add all the descriptors to the free descriptors list */
+	l2table_set = kmalloc(sizeof(*l2table_set), GFP_KERNEL | __GFP_ZERO);
+	if (l2table_set == NULL) {
+		ret = -ENOMEM;
+		goto free_store;
+	}
+	/* initialize */
+	l2table_set->kernel_virt = (void *)store;
+	l2table_set->page = page;
+	l2table_set->phys = (void *)virt_to_phys((void *)store);
+	/* the set is not yet used */
+	atomic_set(&l2table_set->used_tables, 0);
+
+	/* init add to list. */
+	INIT_LIST_HEAD(&(l2table_set->list));
+	list_add(&l2table_set->list, &mem_ctx.l2_tables_sets);
+
+	for (i = 0; i < L2_TABLES_PER_PAGE; i++) {
+		/* allocate a WSM L2 descriptor */
+		l2table  = kmalloc(sizeof(*l2table), GFP_KERNEL | __GFP_ZERO);
+		if (l2table == NULL) {
+			ret = -ENOMEM;
+			MCDRV_DBG_ERROR(mcd, "out of memory\n");
+			/* Free the full temp list and the store in this case */
+			goto free_temp_list;
+		}
+
+		/* set set reference */
+		l2table->set = l2table_set;
+		l2table->idx = i;
+		l2table->virt = get_l2_table_kernel_virt(l2table);
+		l2table->phys = (unsigned long)get_l2_table_phys(l2table);
+		atomic_set(&l2table->usage, 0);
+
+		/* add to temp list. */
+		INIT_LIST_HEAD(&l2table->list);
+		list_add_tail(&l2table->list, &temp);
+	}
+
+	/*
+	 * If everything went ok then merge the temp list with the global
+	 * free list
+	 */
+	list_splice_tail(&temp, &mem_ctx.free_l2_tables);
+	return 0;
+free_temp_list:
+	list_for_each_entry_safe(l2table, l2table2, &temp, list) {
+		kfree(l2table);
+	}
+
+	list_del(&l2table_set->list);
+
+free_store:
+	free_page(store);
+	return ret;
+
+}
+/*
+ * Get a l2 table from the free tables list or allocate a new one and
+ * initialize it. Assumes the table_lock is already taken.
+ */
+static struct mc_l2_table *alloc_l2_table(struct mc_instance *instance)
+{
+	int ret = 0;
+	struct mc_l2_table *table = NULL;
+
+	if (list_empty(&mem_ctx.free_l2_tables)) {
+		ret = alloc_table_store();
+		if (ret) {
+			MCDRV_DBG_ERROR(mcd, "Failed to allocate new store!");
+			return ERR_PTR(-ENOMEM);
+		}
+		/* if it's still empty something wrong has happened */
+		if (list_empty(&mem_ctx.free_l2_tables)) {
+			MCDRV_DBG_ERROR(mcd,
+					"Free list not updated correctly!");
+			return ERR_PTR(-EFAULT);
+		}
+	}
+
+	/* get a WSM L2 descriptor */
+	table  = list_first_entry(&mem_ctx.free_l2_tables,
+		struct mc_l2_table, list);
+	if (table == NULL) {
+		MCDRV_DBG_ERROR(mcd, "out of memory\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	/* Move it to the used l2 tables list */
+	list_move_tail(&table->list, &mem_ctx.l2_tables);
+
+	table->handle = get_unique_id();
+	table->owner = instance;
+
+	atomic_inc(&table->set->used_tables);
+	atomic_inc(&table->usage);
+
+	MCDRV_DBG_VERBOSE(mcd,
+			  "chunkPhys=%p,idx=%d", table->set->phys, table->idx);
+
+	return table;
+}
+
+/*
+ * Frees the object associated with a l2 table. Initially the object is moved
+ * to the free tables list, but if all the 4 lists of the store are free
+ * then the store is also released.
+ * Assumes the table_lock is already taken.
+ */
+static void free_l2_table(struct mc_l2_table *table)
+{
+	struct mc_l2_tables_set *l2table_set;
+
+	if (WARN(!table, "Invalid table"))
+		return;
+
+	l2table_set = table->set;
+	if (WARN(!l2table_set, "Invalid table set"))
+		return;
+
+	list_move_tail(&table->list, &mem_ctx.free_l2_tables);
+
+	/* if nobody uses this set, we can release it. */
+	if (atomic_dec_and_test(&l2table_set->used_tables)) {
+		struct mc_l2_table *tmp;
+
+		/* remove from list */
+		list_del(&l2table_set->list);
+		/*
+		 * All the l2 tables are in the free list for this set
+		 * so we can just remove them from there
+		 */
+		list_for_each_entry_safe(table, tmp, &mem_ctx.free_l2_tables,
+					 list) {
+			if (table->set == l2table_set) {
+				list_del(&table->list);
+				kfree(table);
+			}
+		} /* end while */
+
+		/*
+		 * We shouldn't recover from this since it was some data
+		 * corruption before
+		 */
+		BUG_ON(!l2table_set->page);
+		ClearPageReserved(l2table_set->page);
+
+		BUG_ON(!l2table_set->kernel_virt);
+		free_page((unsigned long)l2table_set->kernel_virt);
+
+		kfree(l2table_set);
+	}
+}
+
+/*
+ * Create a L2 table in a WSM container that has been allocates previously.
+ * Assumes the table lock is already taken or there is no need to take like
+ * when first creating the l2 table the full list is locked.
+ *
+ * @task	pointer to task owning WSM
+ * @wsm_buffer	user space WSM start
+ * @wsm_len	WSM length
+ * @table	Pointer to L2 table details
+ */
+static int map_buffer(struct task_struct *task, void *wsm_buffer,
+		      unsigned int wsm_len, struct mc_l2_table *table)
+{
+	int		ret = 0;
+	unsigned int	i, nr_of_pages;
+	/* start address of the 4 KiB page of wsm_buffer */
+	void		*virt_addr_page;
+	struct page	*page;
+	struct l2table	*l2table;
+	struct page	**l2table_as_array_of_pointers_to_page;
+	/* page offset in wsm buffer */
+	unsigned int offset;
+
+	if (WARN(!wsm_buffer, "Invalid WSM buffer pointer"))
+		return -EINVAL;
+
+	if (WARN(wsm_len == 0, "Invalid WSM buffer length"))
+		return -EINVAL;
+
+	if (WARN(!table, "Invalid mapping table for WSM"))
+		return -EINVAL;
+
+	/* no size > 1Mib supported */
+	if (wsm_len > SZ_1M) {
+		MCDRV_DBG_ERROR(mcd, "size > 1 MiB\n");
+		return -EINVAL;
+	}
+
+	MCDRV_DBG_VERBOSE(mcd, "WSM addr=0x%p, len=0x%08x\n", wsm_buffer,
+			  wsm_len);
+
+
+	/* calculate page usage */
+	virt_addr_page = (void *)(((unsigned long)(wsm_buffer)) & PAGE_MASK);
+	offset = (unsigned int)	(((unsigned long)(wsm_buffer)) & (~PAGE_MASK));
+	nr_of_pages  = PAGE_ALIGN(offset + wsm_len) / PAGE_SIZE;
+
+	MCDRV_DBG_VERBOSE(mcd, "virt addr page start=0x%p, pages=%d\n",
+			  virt_addr_page, nr_of_pages);
+
+	/* L2 table can hold max 1MiB in 256 pages. */
+	if ((nr_of_pages * PAGE_SIZE) > SZ_1M) {
+		MCDRV_DBG_ERROR(mcd, "WSM paged exceed 1 MiB\n");
+		return -EINVAL;
+	}
+
+	l2table = table->virt;
+	/*
+	 * We use the memory for the L2 table to hold the pointer
+	 * and convert them later. This works, as everything comes
+	 * down to a 32 bit value.
+	 */
+	l2table_as_array_of_pointers_to_page = (struct page **)l2table;
+
+	/* Request comes from user space */
+	if (task != NULL && !is_vmalloc_addr(wsm_buffer)) {
+		/*
+		 * lock user page in memory, so they do not get swapped
+		 * out.
+		 * REV axh: Kernel 2.6.27 added a new get_user_pages_fast()
+		 * function, maybe it is called fast_gup() in some versions.
+		 * handle user process doing a fork().
+		 * Child should not get things.
+		 * http://osdir.com/ml/linux-media/2009-07/msg00813.html
+		 * http://lwn.net/Articles/275808/
+		 */
+		ret = lock_pages(task, virt_addr_page, nr_of_pages,
+				 l2table_as_array_of_pointers_to_page);
+		if (ret != 0) {
+			MCDRV_DBG_ERROR(mcd, "lock_user_pages() failed\n");
+			return ret;
+		}
+	}
+	/* Request comes from kernel space(cont buffer) */
+	else if (task == NULL && !is_vmalloc_addr(wsm_buffer)) {
+		void *uaddr = wsm_buffer;
+		for (i = 0; i < nr_of_pages; i++) {
+			page = virt_to_page(uaddr);
+			if (!page) {
+				MCDRV_DBG_ERROR(mcd, "failed to map address");
+				return -EINVAL;
+			}
+			get_page(page);
+			l2table_as_array_of_pointers_to_page[i] = page;
+			uaddr += PAGE_SIZE;
+		}
+	}
+	/* Request comes from kernel space(vmalloc buffer) */
+	else {
+		void *uaddr = wsm_buffer;
+		for (i = 0; i < nr_of_pages; i++) {
+			page = vmalloc_to_page(uaddr);
+			if (!page) {
+				MCDRV_DBG_ERROR(mcd, "failed to map address");
+				return -EINVAL;
+			}
+			get_page(page);
+			l2table_as_array_of_pointers_to_page[i] = page;
+			uaddr += PAGE_SIZE;
+		}
+	}
+
+	table->pages = nr_of_pages;
+
+	/*
+	 * create L2 Table entries.
+	 * used_l2table->table contains a list of page pointers here.
+	 * For a proper cleanup we have to ensure that the following
+	 * code either works and used_l2table contains a valid L2 table
+	 * - or fails and used_l2table->table contains the list of page
+	 * pointers.
+	 * Any mixed contents will make cleanup difficult.
+	 */
+	for (i = 0; i < nr_of_pages; i++) {
+		pte_t pte;
+		page = l2table_as_array_of_pointers_to_page[i];
+
+		/*
+		 * create L2 table entry, see ARM MMU docu for details
+		 * about flags stored in the lowest 12 bits.
+		 * As a side reference, the Article
+		 * "ARM's multiply-mapped memory mess"
+		 * found in the collection at
+		 * http://lwn.net/Articles/409032/
+		 * is also worth reading.
+		 */
+		pte = page_to_l2_pte(page)
+				| PTE_EXT_AP1 | PTE_EXT_AP0
+				| PTE_CACHEABLE | PTE_BUFFERABLE
+				| PTE_TYPE_SMALL | PTE_TYPE_EXT | PTE_EXT_NG;
+		/*
+		 * Linux uses different mappings for SMP systems(the
+		 * sharing flag is set for the pte. In order not to
+		 * confuse things too much in Mobicore make sure the
+		 * shared buffers have the same flags.
+		 * This should also be done in SWD side
+		 */
+#ifdef CONFIG_SMP
+		pte |= PTE_EXT_SHARED | PTE_EXT_TEX(1);
+#endif
+
+		l2table->table_entries[i] = pte;
+		MCDRV_DBG_VERBOSE(mcd, "L2 entry %d:  0x%08x\n", i,
+				  (unsigned int)(pte));
+	}
+
+	/* ensure rest of table is empty */
+	while (i < 255)
+		l2table->table_entries[i++] = (pte_t)0;
+
+
+	return ret;
+}
+
+/*
+ * Remove a L2 table in a WSM container. Afterwards the container may be
+ * released. Assumes the table_lock and the lock is taken.
+ */
+static void unmap_buffers(struct mc_l2_table *table)
+{
+	struct l2table *l2table;
+	int i;
+
+	if (WARN_ON(!table))
+		return;
+
+	/* found the table, now release the resources. */
+	MCDRV_DBG_VERBOSE(mcd, "clear L2 table, phys_base=%p, nr_of_pages=%d\n",
+			  (void *)table->phys, table->pages);
+
+	l2table = table->virt;
+
+	/* release all locked user space pages */
+	for (i = 0; i < table->pages; i++) {
+		/* convert physical entries from L2 table to page pointers */
+		pte_t pte = l2table->table_entries[i];
+		struct page *page = l2_pte_to_page(pte);
+		release_page(page);
+	}
+
+	/* remember that all pages have been freed */
+	table->pages = 0;
+}
+
+/* Delete a used l2 table. Assumes the table_lock and the lock is taken */
+static void unmap_l2_table(struct mc_l2_table *table)
+{
+	/* Check if it's not locked by other processes too! */
+	if (!atomic_dec_and_test(&table->usage))
+		return;
+
+	/* release if Nwd and Swd/MC do no longer use it. */
+	unmap_buffers(table);
+	free_l2_table(table);
+}
+
+int mc_free_l2_table(struct mc_instance *instance, uint32_t handle)
+{
+	struct mc_l2_table *table;
+	int ret = 0;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	mutex_lock(&mem_ctx.table_lock);
+	table = find_l2_table(handle);
+
+	if (table == NULL) {
+		MCDRV_DBG_VERBOSE(mcd, "entry not found");
+		ret = -EINVAL;
+		goto err_unlock;
+	}
+	if (instance != table->owner && !is_daemon(instance)) {
+		MCDRV_DBG_ERROR(mcd, "instance does no own it");
+		ret = -EPERM;
+		goto err_unlock;
+	}
+	/* free table (if no further locks exist) */
+	unmap_l2_table(table);
+err_unlock:
+	mutex_unlock(&mem_ctx.table_lock);
+
+	return ret;
+}
+
+int mc_lock_l2_table(struct mc_instance *instance, uint32_t handle)
+{
+	int ret = 0;
+	struct mc_l2_table *table = NULL;
+
+	if (WARN(!instance, "No instance data available"))
+		return -EFAULT;
+
+	mutex_lock(&mem_ctx.table_lock);
+	table = find_l2_table(handle);
+
+	if (table == NULL) {
+		MCDRV_DBG_VERBOSE(mcd, "entry not found %u\n", handle);
+		ret = -EINVAL;
+		goto table_err;
+	}
+	if (instance != table->owner && !is_daemon(instance)) {
+		MCDRV_DBG_ERROR(mcd, "instance does no own it\n");
+		ret = -EPERM;
+		goto table_err;
+	}
+
+	/* lock entry */
+	atomic_inc(&table->usage);
+table_err:
+	mutex_unlock(&mem_ctx.table_lock);
+	return ret;
+}
+/*
+ * Allocate L2 table and map buffer into it.
+ * That is, create respective table entries.
+ * Must hold Semaphore mem_ctx.wsm_l2_sem
+ */
+struct mc_l2_table *mc_alloc_l2_table(struct mc_instance *instance,
+	struct task_struct *task, void *wsm_buffer, unsigned int wsm_len)
+{
+	int ret = 0;
+	struct mc_l2_table *table;
+
+	if (WARN(!instance, "No instance data available"))
+		return ERR_PTR(-EFAULT);
+
+	mutex_lock(&mem_ctx.table_lock);
+	table = alloc_l2_table(instance);
+	if (IS_ERR(table)) {
+		MCDRV_DBG_ERROR(mcd, "allocate_used_l2_table() failed\n");
+		ret = -ENOMEM;
+		goto err_no_mem;
+	}
+
+	/* create the L2 page for the WSM */
+	ret = map_buffer(task, wsm_buffer, wsm_len, table);
+
+	if (ret != 0) {
+		MCDRV_DBG_ERROR(mcd, "map_buffer() failed\n");
+		unmap_l2_table(table);
+		goto err_no_mem;
+	}
+	MCDRV_DBG(mcd, "mapped buffer %p to table with handle %d @ %lx",
+		  wsm_buffer, table->handle, table->phys);
+
+	mutex_unlock(&mem_ctx.table_lock);
+	return table;
+err_no_mem:
+	mutex_unlock(&mem_ctx.table_lock);
+	return ERR_PTR(ret);
+}
+
+uint32_t mc_find_l2_table(uint32_t handle, int32_t fd)
+{
+	uint32_t ret = 0;
+	struct mc_l2_table *table = NULL;
+
+	mutex_lock(&mem_ctx.table_lock);
+	table = find_l2_table(handle);
+
+	if (table == NULL) {
+		MCDRV_DBG_ERROR(mcd, "entry not found %u\n", handle);
+		ret = 0;
+		goto table_err;
+	}
+
+	/* It's safe here not to lock the instance since the owner of
+	 * the table will be cleared only with the table lock taken */
+	if (!mc_check_owner_fd(table->owner, fd)) {
+		MCDRV_DBG_ERROR(mcd, "not valid owner%u\n", handle);
+		ret = 0;
+		goto table_err;
+	}
+
+	ret = table->phys;
+table_err:
+	mutex_unlock(&mem_ctx.table_lock);
+	return ret;
+}
+
+void mc_clean_l2_tables(void)
+{
+	struct mc_l2_table *table, *tmp;
+
+	mutex_lock(&mem_ctx.table_lock);
+	/* Check if some WSM is orphaned. */
+	list_for_each_entry_safe(table, tmp, &mem_ctx.l2_tables, list) {
+		if (table->owner == NULL) {
+			MCDRV_DBG(mcd,
+				  "clearing orphaned WSM L2: p=%lx pages=%d\n",
+				  table->phys, table->pages);
+			unmap_l2_table(table);
+		}
+	}
+	mutex_unlock(&mem_ctx.table_lock);
+}
+
+void mc_clear_l2_tables(struct mc_instance *instance)
+{
+	struct mc_l2_table *table, *tmp;
+
+	mutex_lock(&mem_ctx.table_lock);
+	/* Check if some WSM is still in use. */
+	list_for_each_entry_safe(table, tmp, &mem_ctx.l2_tables, list) {
+		if (table->owner == instance) {
+			MCDRV_DBG(mcd, "release WSM L2: p=%lx pages=%d\n",
+				  table->phys, table->pages);
+			/* unlock app usage and free or mark it as orphan */
+			table->owner = NULL;
+			unmap_l2_table(table);
+		}
+	}
+	mutex_unlock(&mem_ctx.table_lock);
+}
+
+int mc_init_l2_tables(void)
+{
+	/* init list for WSM L2 chunks. */
+	INIT_LIST_HEAD(&mem_ctx.l2_tables_sets);
+
+	/* L2 table descriptor list. */
+	INIT_LIST_HEAD(&mem_ctx.l2_tables);
+
+	/* L2 table descriptor list. */
+	INIT_LIST_HEAD(&mem_ctx.free_l2_tables);
+
+	mutex_init(&mem_ctx.table_lock);
+
+	return 0;
+}
+
+void mc_release_l2_tables()
+{
+	struct mc_l2_table *table;
+	/* Check if some WSM is still in use. */
+	list_for_each_entry(table, &mem_ctx.l2_tables, list) {
+		WARN(1, "WSM L2 still in use: phys=%lx ,nr_of_pages=%d\n",
+		     table->phys, table->pages);
+	}
+}
diff --git a/drivers/gud/mobicore_driver/mem.h b/drivers/gud/mobicore_driver/mem.h
new file mode 100644
index 0000000..397a6cc
--- /dev/null
+++ b/drivers/gud/mobicore_driver/mem.h
@@ -0,0 +1,128 @@
+/*
+ * MobiCore driver module.(interface to the secure world SWD)
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * 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 _MC_MEM_H_
+#define _MC_MEM_H_
+
+#define FREE_FROM_SWD	1
+#define FREE_FROM_NWD	0
+
+#define LOCKED_BY_APP	(1U << 0)
+#define LOCKED_BY_MC	(1U << 1)
+
+/*
+ * MobiCore specific page tables for world shared memory.
+ * Linux uses shadow page tables, see arch/arm/include/asm/pgtable-2level.
+ * MobiCore uses the default ARM format.
+ *
+ * Number of page table entries in one L2 table. This is ARM specific, an
+ * L2 table covers 1 MiB by using 256 entry referring to 4KiB pages each.
+ */
+#define MC_ARM_L2_TABLE_ENTRIES		256
+
+/* ARM level 2 (L2) table with 256 entries. Size: 1k */
+struct l2table {
+	pte_t	table_entries[MC_ARM_L2_TABLE_ENTRIES];
+};
+
+/* Number of pages for L2 tables. There are 4 table in each page. */
+#define L2_TABLES_PER_PAGE		4
+
+/* Store for four L2 tables in one 4kb page*/
+struct mc_l2_table_store {
+	struct l2table table[L2_TABLES_PER_PAGE];
+};
+
+/* Usage and maintenance information about mc_l2_table_store */
+struct mc_l2_tables_set {
+	struct list_head		list;
+	/* kernel virtual address */
+	struct mc_l2_table_store	*kernel_virt;
+	/* physical address */
+	struct mc_l2_table_store	*phys;
+	/* pointer to page struct */
+	struct page			*page;
+	/* How many pages from this set are used */
+	atomic_t			used_tables;
+};
+
+/*
+ * L2 table allocated to the Daemon or a TLC describing a world shared buffer.
+ * When users map a malloc()ed area into SWd, a L2 table is allocated.
+ * In addition, the area of maximum 1MB virtual address space is mapped into
+ * the L2 table and a handle for this table is returned to the user.
+ */
+struct mc_l2_table {
+	struct list_head	list;
+	/* Table lock */
+	struct mutex		lock;
+	/* handle as communicated to user mode */
+	unsigned int		handle;
+	/* Number of references kept to this l2 table */
+	atomic_t		usage;
+	/* owner of this L2 table */
+	struct mc_instance	*owner;
+	/* set describing where our L2 table is stored */
+	struct mc_l2_tables_set	*set;
+	/* index into L2 table set */
+	unsigned int		idx;
+	/* size of buffer */
+	unsigned int		pages;
+	/* virtual address*/
+	void			*virt;
+	unsigned long		phys;
+};
+
+/* MobiCore Driver Memory context data. */
+struct mc_mem_context {
+	struct mc_instance	*daemon_inst;
+	/* Backing store for L2 tables */
+	struct list_head	l2_tables_sets;
+	/* Bookkeeping for used L2 tables */
+	struct list_head	l2_tables;
+	/* Bookkeeping for free L2 tables */
+	struct list_head	free_l2_tables;
+	/* semaphore to synchronize access to above lists */
+	struct mutex		table_lock;
+};
+
+/*
+ * Allocate L2 table and map buffer into it.
+ * That is, create respective table entries.
+ */
+struct mc_l2_table *mc_alloc_l2_table(struct mc_instance *instance,
+	struct task_struct *task, void *wsm_buffer, unsigned int wsm_len);
+
+/* Delete all the l2 tables associated with an instance */
+void mc_clear_l2_tables(struct mc_instance *instance);
+
+/* Release all orphaned L2 tables */
+void mc_clean_l2_tables(void);
+
+/* Delete a used l2 table. */
+int mc_free_l2_table(struct mc_instance *instance, uint32_t handle);
+
+/*
+ * Lock a l2 table - the daemon adds +1 to refcount of the L2 table
+ * marking it in use by SWD so it doesn't get released when the TLC dies.
+ */
+int mc_lock_l2_table(struct mc_instance *instance, uint32_t handle);
+/* Unlock l2 table. */
+int mc_unlock_l2_table(struct mc_instance *instance, uint32_t handle);
+/* Return the phys address of l2 table. */
+uint32_t mc_find_l2_table(uint32_t handle, int32_t fd);
+/* Release all used l2 tables to Linux memory space */
+void mc_release_l2_tables(void);
+
+/* Initialize all l2 tables structure */
+int mc_init_l2_tables(void);
+
+#endif /* _MC_MEM_H_ */
diff --git a/drivers/gud/mobicore_driver/ops.c b/drivers/gud/mobicore_driver/ops.c
new file mode 100644
index 0000000..05c80b7
--- /dev/null
+++ b/drivers/gud/mobicore_driver/ops.c
@@ -0,0 +1,268 @@
+/*
+ * MobiCore Driver Kernel Module.
+ *
+ * This module is written as a Linux device driver.
+ * This driver represents the command proxy on the lowest layer, from the
+ * secure world to the non secure world, and vice versa.
+ * This driver is located in the non secure world (Linux).
+ * This driver offers IOCTL commands, for access to the secure world, and has
+ * the interface from the secure world to the normal world.
+ * The access to the driver is possible with a file descriptor,
+ * which has to be created by the fd = open(/dev/mobicore) command.
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * 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/kthread.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/cpu.h>
+
+#include "main.h"
+#include "fastcall.h"
+#include "ops.h"
+#include "mem.h"
+#include "pm.h"
+#include "debug.h"
+
+/* MobiCore context data */
+static struct mc_context *ctx;
+
+static inline long smc(union fc_generic *fc)
+{
+	/* If we request sleep yields must be filtered out as they
+	 * make no sense */
+	if (ctx->mcp)
+		if (ctx->mcp->flags.sleep_mode.SleepReq) {
+			if (fc->as_in.cmd == MC_SMC_N_YIELD)
+				return MC_FC_RET_ERR_INVALID;
+		}
+	return _smc(fc);
+}
+
+#ifdef MC_FASTCALL_WORKER_THREAD
+
+static struct task_struct *fastcall_thread;
+static DEFINE_KTHREAD_WORKER(fastcall_worker);
+
+struct fastcall_work {
+	struct kthread_work work;
+	void *data;
+};
+
+static void fastcall_work_func(struct kthread_work *work)
+{
+	struct fastcall_work *fc_work =
+		container_of(work, struct fastcall_work, work);
+	smc(fc_work->data);
+}
+
+void mc_fastcall(void *data)
+{
+	struct fastcall_work fc_work = {
+		KTHREAD_WORK_INIT(fc_work.work, fastcall_work_func),
+		.data = data,
+	};
+
+	queue_kthread_work(&fastcall_worker, &fc_work.work);
+	flush_kthread_work(&fc_work.work);
+}
+
+int mc_fastcall_init(struct mc_context *context)
+{
+	int ret = 0;
+
+	ctx = context;
+
+	fastcall_thread = kthread_create(kthread_worker_fn, &fastcall_worker,
+					 "mc_fastcall");
+	if (IS_ERR(fastcall_thread)) {
+		ret = PTR_ERR(fastcall_thread);
+		fastcall_thread = NULL;
+		MCDRV_DBG_ERROR(mcd, "cannot create fastcall wq (%d)\n", ret);
+		return ret;
+	}
+
+	/* this thread MUST run on CPU 0 */
+	kthread_bind(fastcall_thread, 0);
+	wake_up_process(fastcall_thread);
+
+	return 0;
+}
+
+void mc_fastcall_destroy(void)
+{
+	if (!IS_ERR_OR_NULL(fastcall_thread)) {
+		kthread_stop(fastcall_thread);
+		fastcall_thread = NULL;
+	}
+}
+#else
+
+struct fastcall_work_struct {
+	struct work_struct work;
+	void *data;
+};
+
+static void fastcall_work_func(struct work_struct *work)
+{
+	struct fastcall_work_struct *fc_work =
+		container_of(work, struct fastcall_work_struct, work);
+	smc(fc_work->data);
+}
+
+void mc_fastcall(void *data)
+{
+	struct fastcall_work_struct work = {
+		.data = data,
+	};
+	INIT_WORK(&work.work, fastcall_work_func);
+	schedule_work_on(0, &work.work);
+
+	flush_work(&work.work);
+}
+
+int mc_fastcall_init(struct mc_context *context)
+{
+	ctx = context;
+	return 0;
+};
+
+void mc_fastcall_destroy(void) {};
+#endif
+
+int mc_info(uint32_t ext_info_id, uint32_t *state, uint32_t *ext_info)
+{
+	int ret = 0;
+	union mc_fc_info fc_info;
+
+	MCDRV_DBG_VERBOSE(mcd, "enter\n");
+
+	memset(&fc_info, 0, sizeof(fc_info));
+	fc_info.as_in.cmd = MC_FC_INFO;
+	fc_info.as_in.ext_info_id = ext_info_id;
+
+	MCDRV_DBG(mcd, "fc_info <- cmd=0x%08x, ext_info_id=0x%08x\n",
+		  fc_info.as_in.cmd, fc_info.as_in.ext_info_id);
+
+	mc_fastcall(&(fc_info.as_generic));
+
+	MCDRV_DBG(mcd,
+		  "fc_info -> r=0x%08x ret=0x%08x state=0x%08x ext_info=0x%08x",
+		  fc_info.as_out.resp,
+		  fc_info.as_out.ret,
+		  fc_info.as_out.state,
+		  fc_info.as_out.ext_info);
+
+	ret = convert_fc_ret(fc_info.as_out.ret);
+
+	*state  = fc_info.as_out.state;
+	*ext_info = fc_info.as_out.ext_info;
+
+	MCDRV_DBG_VERBOSE(mcd, "exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+/* Yield to MobiCore */
+int mc_yield(void)
+{
+	int ret = 0;
+	union fc_generic yield;
+
+	MCDRV_DBG_VERBOSE(mcd, "enter\n");
+
+	memset(&yield, 0, sizeof(yield));
+	yield.as_in.cmd = MC_SMC_N_YIELD;
+	mc_fastcall(&yield);
+	ret = convert_fc_ret(yield.as_out.ret);
+
+	return ret;
+}
+
+/* call common notify */
+int mc_nsiq(void)
+{
+	int ret = 0;
+	union fc_generic nsiq;
+	MCDRV_DBG_VERBOSE(mcd, "enter\n");
+
+	memset(&nsiq, 0, sizeof(nsiq));
+	nsiq.as_in.cmd = MC_SMC_N_SIQ;
+	mc_fastcall(&nsiq);
+	ret = convert_fc_ret(nsiq.as_out.ret);
+
+	return ret;
+}
+
+/* call common notify */
+int _nsiq(void)
+{
+	int ret = 0;
+	union fc_generic nsiq;
+	MCDRV_DBG_VERBOSE(mcd, "enter\n");
+
+	memset(&nsiq, 0, sizeof(nsiq));
+	nsiq.as_in.cmd = MC_SMC_N_SIQ;
+	_smc(&nsiq);
+	ret = convert_fc_ret(nsiq.as_out.ret);
+
+	return ret;
+}
+
+/* Call the INIT fastcall to setup MobiCore initialization */
+int mc_init(uint32_t base, uint32_t nq_offset, uint32_t nq_length,
+	uint32_t mcp_offset, uint32_t mcp_length)
+{
+	int ret = 0;
+	union mc_fc_init fc_init;
+
+	MCDRV_DBG_VERBOSE(mcd, "enter\n");
+
+	memset(&fc_init, 0, sizeof(fc_init));
+
+	fc_init.as_in.cmd = MC_FC_INIT;
+	/* base address of mci buffer 4KB aligned */
+	fc_init.as_in.base = base;
+	/* notification buffer start/length [16:16] [start, length] */
+	fc_init.as_in.nq_info = (nq_offset << 16) | (nq_length & 0xFFFF);
+	/* mcp buffer start/length [16:16] [start, length] */
+	fc_init.as_in.mcp_info = (mcp_offset << 16) | (mcp_length & 0xFFFF);
+
+	/*
+	 * Set KMOD notification queue to start of MCI
+	 * mciInfo was already set up in mmap
+	 */
+	MCDRV_DBG(mcd,
+		  "cmd=0x%08x, base=0x%08x,nq_info=0x%08x, mcp_info=0x%08x\n",
+		  fc_init.as_in.cmd, fc_init.as_in.base, fc_init.as_in.nq_info,
+		  fc_init.as_in.mcp_info);
+
+	mc_fastcall(&fc_init.as_generic);
+
+	MCDRV_DBG(mcd, "out cmd=0x%08x, ret=0x%08x\n", fc_init.as_out.resp,
+		  fc_init.as_out.ret);
+
+	ret = convert_fc_ret(fc_init.as_out.ret);
+
+	MCDRV_DBG_VERBOSE(mcd, "exit with %d/0x%08X\n", ret, ret);
+
+	return ret;
+}
+
+/* Return MobiCore driver version */
+uint32_t mc_get_version(void)
+{
+	MCDRV_DBG(mcd, "MobiCore driver version is %i.%i\n",
+		  MCDRVMODULEAPI_VERSION_MAJOR,
+		  MCDRVMODULEAPI_VERSION_MINOR);
+
+	return MC_VERSION(MCDRVMODULEAPI_VERSION_MAJOR,
+					MCDRVMODULEAPI_VERSION_MINOR);
+}
diff --git a/drivers/gud/mobicore_driver/ops.h b/drivers/gud/mobicore_driver/ops.h
new file mode 100644
index 0000000..910c1f4
--- /dev/null
+++ b/drivers/gud/mobicore_driver/ops.h
@@ -0,0 +1,32 @@
+/*
+ * MobiCore driver module.(interface to the secure world SWD)
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * 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 _MC_OPS_H_
+#define _MC_OPS_H_
+
+#include <linux/workqueue.h>
+#include "fastcall.h"
+
+int mc_yield(void);
+int mc_nsiq(void);
+int _nsiq(void);
+uint32_t mc_get_version(void);
+
+int mc_info(uint32_t ext_info_id, uint32_t *state, uint32_t *ext_info);
+int mc_init(uint32_t base, uint32_t  nq_offset, uint32_t  nq_length,
+	    uint32_t mcp_offset, uint32_t  mcp_length);
+
+void mc_fastcall(void *data);
+
+int mc_fastcall_init(struct mc_context *context);
+void mc_fastcall_destroy(void);
+
+#endif /* _MC_OPS_H_ */
diff --git a/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h b/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h
index 070222e..7febcb6 100644
--- a/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h
+++ b/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h
@@ -1,32 +1,24 @@
-/**
- * Header file of MobiCore Driver Kernel Module Platform
- * specific structures
- *
- * @addtogroup MobiCore_Driver_Kernel_Module
- * @{
- * Internal structures of the McDrvModule
- * @file
- *
- * Header file the MobiCore Driver Kernel Module,
+/*
+ * Header file for the MobiCore Driver Kernel Module,
  * its internal structures and defines.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * 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 _MC_DRV_PLATFORM_H_
-#define _MC_DRV_PLATFORM_H_
+#ifndef _MC_PLATFORM_H_
+#define _MC_PLATFORM_H_
 
-/** MobiCore Interrupt for Qualcomm */
+/* MobiCore Interrupt for Qualcomm */
 #define MC_INTR_SSIQ						280
 
-/** Use SMC for fastcalls */
+/* Use SMC for fastcalls */
 #define MC_SMC_FASTCALL
 
-
 /*--------------- Implementation -------------- */
 #include <mach/scm.h>
 /* from following file */
@@ -34,17 +26,21 @@
 #define SCM_CMD_MOBICORE		1
 
 extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
-			void *resp_buf, size_t resp_len);
+		    void *resp_buf, size_t resp_len);
 
 static inline int smc_fastcall(void *fc_generic, size_t size)
 {
 	return scm_call(SCM_SVC_MOBICORE, SCM_CMD_MOBICORE,
-			   fc_generic, size,
-			   fc_generic, size);
+			fc_generic, size,
+			fc_generic, size);
 }
 
-/** Enable mobicore mem traces */
-#define MC_MEM_TRACES
+/* Enable mobicore mem traces */
+/* #define MC_MEM_TRACES */
 
-#endif /* _MC_DRV_PLATFORM_H_ */
-/** @} */
+/* Enable the use of vm_unamp instead of the deprecated do_munmap
+ * and other 3.7 features
+ */
+#define MC_VM_UNMAP
+
+#endif /* _MC_PLATFORM_H_ */
diff --git a/drivers/gud/mobicore_driver/pm.h b/drivers/gud/mobicore_driver/pm.h
new file mode 100644
index 0000000..3e73b8b
--- /dev/null
+++ b/drivers/gud/mobicore_driver/pm.h
@@ -0,0 +1,35 @@
+/*
+ * Header file of MobiCore Driver Kernel Module.
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * 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 _MC_PM_H_
+#define _MC_PM_H_
+
+#include "main.h"
+#ifdef MC_BL_NOTIFIER
+#include <asm/bL_switcher.h>
+#endif
+
+
+#define NO_SLEEP_REQ	0
+#define REQ_TO_SLEEP	1
+
+#define NORMAL_EXECUTION	0
+#define READY_TO_SLEEP		1
+
+/* How much time after resume the daemon should backoff */
+#define DAEMON_BACKOFF_TIME	500
+
+/* Initialize Power Management */
+int mc_pm_initialize(struct mc_context *context);
+/* Free all Power Management resources*/
+int mc_pm_free(void);
+
+#endif /* _MC_PM_H_ */
diff --git a/drivers/gud/mobicore_driver/public/mc_drv_module_api.h b/drivers/gud/mobicore_driver/public/mc_drv_module_api.h
deleted file mode 100644
index 59366f3..0000000
--- a/drivers/gud/mobicore_driver/public/mc_drv_module_api.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/** @addtogroup MCD_MCDIMPL_KMOD_API Mobicore Driver Module API
- * @ingroup  MCD_MCDIMPL_KMOD
- * @{
- * Interface to Mobicore Driver Kernel Module.
- * @file
- *
- * <h2>Introduction</h2>
- * The MobiCore Driver Kernel Module is a Linux device driver, which represents
- * the command proxy on the lowest layer to the secure world (Swd). Additional
- * services like memory allocation via mmap and generation of a L2 tables for
- * given virtual memory are also supported. IRQ functionallity receives
- * information from the SWd in the non secure world (NWd).
- * As customary the driver is handled as linux device driver with "open",
- * "close" and "ioctl" commands. Access to the driver is possible after the
- * device "/dev/mobicore" has been opened.
- * The MobiCore Driver Kernel Module must be installed via
- * "insmod mcDrvModule.ko".
- *
- *
- * <h2>Version history</h2>
- * <table class="customtab">
- * <tr><td width="100px"><b>Date</b></td><td width="80px"><b>Version</b></td>
- * <td><b>Changes</b></td></tr>
- * <tr><td>2010-05-25</td><td>0.1</td><td>Initial Release</td></tr>
- * </table>
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *	notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *	notice, this list of conditions and the following disclaimer in the
- *	documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *	products derived from this software without specific prior
- *	written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MC_DRV_MODULEAPI_H_
-#define _MC_DRV_MODULEAPI_H_
-
-#include "version.h"
-
-#define MC_DRV_MOD_DEVNODE		   "mobicore"
-#define MC_DRV_MOD_DEVNODE_FULLPATH  "/dev/" MC_DRV_MOD_DEVNODE
-
-/**
- * Data exchange structure of the MC_DRV_MODULE_INIT ioctl command.
- * INIT request data to SWD
- */
-union mc_ioctl_init_params {
-	struct {
-		/** base address of mci buffer 4KB align */
-		uint32_t  base;
-		/** notification buffer start/length [16:16] [start, length] */
-		uint32_t  nq_offset;
-		/** length of notification queue */
-		uint32_t  nq_length;
-		/** mcp buffer start/length [16:16] [start, length] */
-		uint32_t  mcp_offset;
-		/** length of mcp buffer */
-		uint32_t  mcp_length;
-	} in;
-	struct {
-		/* nothing */
-	} out;
-};
-
-
-/**
- * Data exchange structure of the MC_DRV_MODULE_INFO ioctl command.
- * INFO request data to the SWD
- */
-union mc_ioctl_info_params {
-	struct {
-		uint32_t  ext_info_id; /**< extended info ID */
-	} in;
-	struct {
-		uint32_t  state; /**< state */
-		uint32_t  ext_info; /**< extended info */
-	} out;
-};
-
-/**
- * Mmap allocates and maps contiguous memory into a process.
- * We use the third parameter, void *offset, to distinguish between some cases
- * offset = MC_DRV_KMOD_MMAP_WSM	usual operation, pages are registered in
-					device structure and freed later.
- * offset = MC_DRV_KMOD_MMAP_MCI	get Instance of MCI, allocates or mmaps
-					the MCI to daemon
- * offset = MC_DRV_KMOD_MMAP_PERSISTENTWSM	special operation, without
-						registration of pages
- *
- * In mmap(), the offset specifies which of several device I/O pages is
- *  requested. Linux only transfers the page number, i.e. the upper 20 bits to
- *  kernel module. Therefore we define our special offsets as multiples of page
- *  size.
- */
-enum mc_mmap_memtype {
-	MC_DRV_KMOD_MMAP_WSM		= 0,
-	MC_DRV_KMOD_MMAP_MCI		= 4096,
-	MC_DRV_KMOD_MMAP_PERSISTENTWSM	= 8192
-};
-
-struct mc_mmap_resp {
-	uint32_t  handle; /**< WSN handle */
-	uint32_t  phys_addr; /**< physical address of WSM (or NULL) */
-	bool	  is_reused; /**< if WSM memory was reused, or new allocated */
-};
-
-/**
- * Data exchange structure of the MC_DRV_KMOD_IOCTL_FREE ioctl command.
- */
-union mc_ioctl_free_params {
-	struct {
-		uint32_t  handle; /**< driver handle */
-		uint32_t  pid; /**< process id */
-	} in;
-	struct {
-		/* nothing */
-	} out;
-};
-
-
-/**
- * Data exchange structure of the MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2 command.
- *
- * Allocates a physical L2 table and maps the buffer into this page.
- * Returns the physical address of the L2 table.
- * The page alignment will be created and the appropriated pSize and pOffsetL2
- * will be modified to the used values.
- */
-union mc_ioctl_app_reg_wsm_l2_params {
-	struct {
-		uint32_t  buffer; /**< base address of the virtual address  */
-		uint32_t  len; /**< size of the virtual address space */
-		uint32_t  pid; /**< process id */
-	} in;
-	struct {
-		uint32_t  handle; /**< driver handle for locked memory */
-		uint32_t  phys_wsm_l2_table; /* physical address of the L2 table */
-	} out;
-};
-
-
-/**
- * Data exchange structure of the MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2
- * command.
- */
-struct mc_ioctl_app_unreg_wsm_l2_params {
-	struct {
-		uint32_t  handle; /**< driver handle for locked memory */
-		uint32_t  pid; /**< process id */
-	} in;
-	struct {
-		/* nothing */
-	} out;
-};
-
-
-/**
- * Data exchange structure of the MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2 command.
- */
-struct mc_ioctl_daemon_lock_wsm_l2_params {
-	struct {
-		uint32_t  handle; /**< driver handle for locked memory */
-	} in;
-	struct {
-		uint32_t phys_wsm_l2_table;
-	} out;
-};
-
-
-/**
- * Data exchange structure of the MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2
- * command.
- */
-struct mc_ioctl_daemon_unlock_wsm_l2_params {
-	struct {
-		uint32_t  handle; /**< driver handle for locked memory */
-	} in;
-	struct {
-		/* nothing */
-	} out;
-};
-
-/**
- * Data exchange structure of the MC_DRV_MODULE_FC_EXECUTE ioctl command.
- */
-union mc_ioctl_fc_execute_params {
-	struct {
-		/**< base address of mobicore binary */
-		uint32_t  phys_start_addr;
-		/**< length of DDR area */
-		uint32_t  length;
-	} in;
-	struct {
-		/* nothing */
-	} out;
-};
-
-/**
- * Data exchange structure of the MC_DRV_MODULE_GET_VERSION ioctl command.
- */
-struct mc_ioctl_get_version_params {
-	struct {
-		uint32_t	kernel_module_version;
-	} out;
-};
-
-/* @defgroup Mobicore_Driver_Kernel_Module_Interface IOCTL */
-
-
-
-
-/* TODO: use IOCTL macros like _IOWR. See Documentation/ioctl/ioctl-number.txt,
-	Documentation/ioctl/ioctl-decoding.txt */
-/**
- * defines for the ioctl mobicore driver module function call from user space.
- */
-enum mc_kmod_ioctl {
-
-	/*
-	 * get detailed MobiCore Status
-	 */
-	MC_DRV_KMOD_IOCTL_DUMP_STATUS  = 200,
-
-	/*
-	 * initialize MobiCore
-	 */
-	MC_DRV_KMOD_IOCTL_FC_INIT  = 201,
-
-	/*
-	 * get MobiCore status
-	 */
-	MC_DRV_KMOD_IOCTL_FC_INFO  = 202,
-
-	/**
-	 * ioctl parameter to send the YIELD command to the SWD.
-	 * Only possible in Privileged Mode.
-	 * ioctl(fd, MC_DRV_MODULE_YIELD)
-	 */
-	MC_DRV_KMOD_IOCTL_FC_YIELD =  203,
-	/**
-	 * ioctl parameter to send the NSIQ signal to the SWD.
-	 * Only possible in Privileged Mode
-	 * ioctl(fd, MC_DRV_MODULE_NSIQ)
-	 */
-	MC_DRV_KMOD_IOCTL_FC_NSIQ   =  204,
-	/**
-	 * ioctl parameter to tzbsp to start Mobicore binary from DDR.
-	 * Only possible in Privileged Mode
-	 * ioctl(fd, MC_DRV_KMOD_IOCTL_FC_EXECUTE)
-	 */
-	MC_DRV_KMOD_IOCTL_FC_EXECUTE =  205,
-
-	/**
-	 * Free's memory which is formerly allocated by the driver's mmap
-	 * command. The parameter must be this mmaped address.
-	 * The internal instance data regarding to this address are deleted as
-	 * well as each according memory page and its appropriated reserved bit
-	 * is cleared (ClearPageReserved).
-	 * Usage: ioctl(fd, MC_DRV_MODULE_FREE, &address) with address beeing of
-	 * type long address
-	 */
-	MC_DRV_KMOD_IOCTL_FREE = 218,
-
-	/**
-	 * Creates a L2 Table of the given base address and the size of the
-	 * data.
-	 * Parameter: mc_ioctl_app_reg_wsm_l2_params
-	 */
-	MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2 = 220,
-
-	/**
-	 * Frees the L2 table created by a MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2
-	 * ioctl.
-	 * Parameter: mc_ioctl_app_unreg_wsm_l2_params
-	 */
-	MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2 = 221,
-
-
-	/* TODO: comment this. */
-	MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2 = 222,
-	MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2 = 223,
-
-	/**
-	 * Return kernel driver version.
-	 * Parameter: mc_ioctl_get_version_params
-	 */
-	MC_DRV_KMOD_IOCTL_GET_VERSION = 224,
-};
-
-
-#endif /* _MC_DRV_MODULEAPI_H_ */
-/** @} */
diff --git a/drivers/gud/mobicore_driver/public/mc_kernel_api.h b/drivers/gud/mobicore_driver/public/mc_kernel_api.h
index fdfc618..cca0636 100644
--- a/drivers/gud/mobicore_driver/public/mc_kernel_api.h
+++ b/drivers/gud/mobicore_driver/public/mc_kernel_api.h
@@ -1,100 +1,77 @@
-/** @addtogroup MCD_MCDIMPL_KMOD_KAPI Mobicore Driver Module API inside Kernel.
- * @ingroup  MCD_MCDIMPL_KMOD
- * @{
- * Interface to Mobicore Driver Kernel Module inside Kernel.
- * @file
- *
+/*
  * Interface to be used by module MobiCoreKernelAPI.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * 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 _MOBICORE_KERNELMODULE_API_H_
-#define _MOBICORE_KERNELMODULE_API_H_
+#ifndef _MC_KERNEL_API_H_
+#define _MC_KERNEL_API_H_
 
 struct mc_instance;
 
-/**
- * Initialize a new mobicore API instance object
+/*
+ * mobicore_open() - Initialize a new MobiCore API instance object
  *
- * @return Instance or NULL if no allocation was possible.
+ * Returns a MobiCore Instance or NULL if no allocation was possible.
  */
-struct mc_instance *mobicore_open(
-	void
-);
+struct mc_instance *mobicore_open(void);
 
-/**
- * Release a mobicore instance object and all objects related to it
- * @param instance instance
- * @return 0 if Ok or -E ERROR
+/*
+ * mobicore_release() - Release a MobiCore instance object
+ * @instance:		MobiCore instance
+ *
+ * Returns 0 if Ok or -E ERROR
  */
-int mobicore_release(
-	struct mc_instance	*instance
-);
+int mobicore_release(struct mc_instance *instance);
 
-/**
- * Free a WSM buffer allocated with mobicore_allocate_wsm
- * @param instance
- * @param handle		handle of the buffer
+/*
+ * mobicore_allocate_wsm() - Allocate MobiCore WSM
+ * @instance:		instance data for MobiCore Daemon and TLCs
+ * @requested_size:	memory size requested in bytes
+ * @handle:		pointer to handle
+ * @kernel_virt_addr:	virtual user start address
+ * @phys_addr:		physical start address
  *
- * @return 0 if no error
- *
+ * Returns 0 if OK
  */
-int mobicore_allocate_wsm(
-	struct mc_instance	*instance,
-	unsigned long		requested_size,
-	uint32_t		*handle,
-	void			**kernel_virt_addr,
-	void			**phys_addr
-);
+int mobicore_allocate_wsm(struct mc_instance *instance,
+			  unsigned long requested_size, uint32_t *handle,
+			  void **virt_kernel_addr, void **phys_addr);
 
-/**
- * Free a WSM buffer allocated with mobicore_allocate_wsm
- * @param instance
- * @param handle		handle of the buffer
+/*
+ * mobicore_free() - Free a WSM buffer allocated with mobicore_allocate_wsm
+ * @instance:		instance data for MobiCore Daemon and TLCs
+ * @handle:		handle of the buffer
  *
- * @return 0 if no error
- *
+ * Returns 0 if OK
  */
-int mobicore_free(
-	struct mc_instance	*instance,
-	uint32_t		handle
-);
+int mobicore_free_wsm(struct mc_instance *instance, uint32_t handle);
 
-/**
- * Map a virtual memory buffer structure to Mobicore
- * @param instance
- * @param addr		address of the buffer(NB it must be kernel virtual!)
- * @param len		buffer length
- * @param handle	pointer to handle
- * @param phys_wsm_l2_table	pointer to physical L2 table(?)
+/*
+ * mobicore_map_vmem() - Map a virtual memory buffer structure to Mobicore
+ * @instance:		instance data for MobiCore Daemon and TLCs
+ * @addr:		address of the buffer (NB it must be kernel virtual!)
+ * @len:		buffer length (in bytes)
+ * @handle:		unique handle
+ * @phys:		pointer for physical address of L2 table
  *
- * @return 0 if no error
- *
+ * Returns 0 if no error
  */
-int mobicore_map_vmem(
-	struct mc_instance	*instance,
-	void			*addr,
-	uint32_t		len,
-	uint32_t		*handle,
-	void			**phys_wsm_l2_table
-);
+int mobicore_map_vmem(struct mc_instance *instance, void *addr,
+		      uint32_t len, uint32_t *handle, uint32_t *phys);
 
-/**
- * Unmap a virtual memory buffer from mobicore
- * @param instance
- * @param handle
+/*
+ * mobicore_unmap_vmem() - Unmap a virtual memory buffer from MobiCore
+ * @instance:		instance data for MobiCore Daemon and TLCs
+ * @handle:		unique handle
  *
- * @return 0 if no error
- *
+ * Returns 0 if no error
  */
-int mobicore_unmap_vmem(
-	struct mc_instance	*instance,
-	uint32_t		handle
-);
-#endif /* _MOBICORE_KERNELMODULE_API_H_ */
-/** @} */
+int mobicore_unmap_vmem(struct mc_instance *instance, uint32_t handle);
+
+#endif /* _MC_KERNEL_API_H_ */
diff --git a/drivers/gud/mobicore_driver/public/mc_linux.h b/drivers/gud/mobicore_driver/public/mc_linux.h
new file mode 100644
index 0000000..9c49aef
--- /dev/null
+++ b/drivers/gud/mobicore_driver/public/mc_linux.h
@@ -0,0 +1,231 @@
+/*
+ * The MobiCore Driver Kernel Module is a Linux device driver, which represents
+ * the command proxy on the lowest layer to the secure world (Swd). Additional
+ * services like memory allocation via mmap and generation of a L2 tables for
+ * given virtual memory are also supported. IRQ functionality receives
+ * information from the SWd in the non secure world (NWd).
+ * As customary the driver is handled as linux device driver with "open",
+ * "close" and "ioctl" commands. Access to the driver is possible after the
+ * device "/dev/mobicore" has been opened.
+ * The MobiCore Driver Kernel Module must be installed via
+ * "insmod mcDrvModule.ko".
+ *
+ * <-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	notice, this list of conditions and the following disclaimer in the
+ *	documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *	products derived from this software without specific prior
+ *	written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MC_LINUX_H_
+#define _MC_LINUX_H_
+
+#include "version.h"
+
+#define MC_ADMIN_DEVNODE	"mobicore"
+#define MC_USER_DEVNODE		"mobicore-user"
+
+/*
+ * Data exchange structure of the MC_DRV_MODULE_INIT ioctl command.
+ * INIT request data to SWD
+ */
+struct mc_ioctl_init {
+	/* notification buffer start/length [16:16] [start, length] */
+	uint32_t  nq_offset;
+	/* length of notification queue */
+	uint32_t  nq_length;
+	/* mcp buffer start/length [16:16] [start, length] */
+	uint32_t  mcp_offset;
+	/* length of mcp buffer */
+	uint32_t  mcp_length;
+};
+
+/*
+ * Data exchange structure of the MC_DRV_MODULE_INFO ioctl command.
+ * INFO request data to the SWD
+ */
+struct mc_ioctl_info {
+	uint32_t  ext_info_id;	/* extended info ID */
+	uint32_t  state;	/* state */
+	uint32_t  ext_info;	/* extended info */
+};
+
+/*
+ * Data exchange structure of the MC_IO_MAP_WSM, MC_IO_MAP_MCI, and
+ *				  MC_IO_MAP_PWSM commands.
+ *
+ * Allocate a contiguous memory buffer for a process.
+ * The physical address can be used as for later calls to mmap.
+ * The handle can be used to communicate about this buffer to the Daemon.
+ * For MC_IO_MAP_MCI command, the reused field indicates that MCI was set up
+ * already. I.e. Daemon was restarted.
+ */
+struct mc_ioctl_map {
+	size_t	      len;	/* Buffer length */
+	uint32_t      handle;	/* WSM handle */
+	unsigned long addr;	/* Virtual address */
+	unsigned long phys_addr;/* physical address of WSM (or NULL) */
+	bool	      reused;	/* if WSM memory was reused, or new allocated */
+};
+
+/*
+ * Data exchange structure of the MC_IO_REG_WSM command.
+ *
+ * Allocates a physical L2 table and maps the buffer into this page.
+ * Returns the physical address of the L2 table.
+ * The page alignment will be created and the appropriated pSize and pOffsetL2
+ * will be modified to the used values.
+ */
+struct mc_ioctl_reg_wsm {
+	uint32_t buffer;	/* base address of the virtual address  */
+	uint32_t len;		/* size of the virtual address space */
+	uint32_t pid;		/* process id */
+	uint32_t handle;	/* driver handle for locked memory */
+	uint32_t table_phys;	/* physical address of the L2 table */
+};
+
+
+/*
+ * Data exchange structure of the MC_DRV_MODULE_FC_EXECUTE ioctl command.
+ * internal, unsupported
+ */
+struct mc_ioctl_execute {
+	/* base address of mobicore binary */
+	uint32_t phys_start_addr;
+	/* length of DDR area */
+	uint32_t length;
+};
+
+/*
+ * Data exchange structure of the MC_IO_RESOLVE_CONT_WSM ioctl command.
+ */
+struct mc_ioctl_resolv_cont_wsm {
+	/* driver handle for buffer */
+	uint32_t handle;
+	/* base address of memory */
+	uint32_t phys;
+	/* length memory */
+	uint32_t length;
+	/* fd to owner of the buffer */
+	int32_t fd;
+};
+
+/*
+ * Data exchange structure of the MC_IO_RESOLVE_WSM ioctl command.
+ */
+struct mc_ioctl_resolv_wsm {
+	/* driver handle for buffer */
+	uint32_t handle;
+	/* fd to owner of the buffer */
+	int32_t fd;
+	/* base address of memory */
+	uint32_t phys;
+};
+
+
+/*
+ * defines for the ioctl mobicore driver module function call from user space.
+ */
+/* MobiCore IOCTL magic number */
+#define MC_IOC_MAGIC	'M'
+
+#define MC_IO_INIT		_IOWR(MC_IOC_MAGIC, 0, struct mc_ioctl_init)
+#define MC_IO_INFO		_IOWR(MC_IOC_MAGIC, 1, struct mc_ioctl_info)
+#define MC_IO_VERSION		_IOR(MC_IOC_MAGIC, 2, uint32_t)
+/*
+ * ioctl parameter to send the YIELD command to the SWD.
+ * Only possible in Privileged Mode.
+ * ioctl(fd, MC_DRV_MODULE_YIELD)
+ */
+#define MC_IO_YIELD		_IO(MC_IOC_MAGIC, 3)
+/*
+ * ioctl parameter to send the NSIQ signal to the SWD.
+ * Only possible in Privileged Mode
+ * ioctl(fd, MC_DRV_MODULE_NSIQ)
+ */
+#define MC_IO_NSIQ		_IO(MC_IOC_MAGIC, 4)
+/*
+ * Free's memory which is formerly allocated by the driver's mmap
+ * command. The parameter must be this mmaped address.
+ * The internal instance data regarding to this address are deleted as
+ * well as each according memory page and its appropriated reserved bit
+ * is cleared (ClearPageReserved).
+ * Usage: ioctl(fd, MC_DRV_MODULE_FREE, &address) with address being of
+ * type long address
+ */
+#define MC_IO_FREE		_IO(MC_IOC_MAGIC, 5)
+/*
+ * Creates a L2 Table of the given base address and the size of the
+ * data.
+ * Parameter: mc_ioctl_app_reg_wsm_l2_params
+ */
+#define MC_IO_REG_WSM		_IOWR(MC_IOC_MAGIC, 6, struct mc_ioctl_reg_wsm)
+#define MC_IO_UNREG_WSM		_IO(MC_IOC_MAGIC, 7)
+#define MC_IO_LOCK_WSM		_IO(MC_IOC_MAGIC, 8)
+#define MC_IO_UNLOCK_WSM	_IO(MC_IOC_MAGIC, 9)
+#define MC_IO_EXECUTE		_IOWR(MC_IOC_MAGIC, 10, struct mc_ioctl_execute)
+
+/*
+ * Allocate contiguous memory for a process for later mapping with mmap.
+ * MC_DRV_KMOD_MMAP_WSM	usual operation, pages are registered in
+ *					device structure and freed later.
+ * MC_DRV_KMOD_MMAP_MCI	get Instance of MCI, allocates or mmaps
+ *					the MCI to daemon
+ * MC_DRV_KMOD_MMAP_PERSISTENTWSM	special operation, without
+ *						registration of pages
+ */
+#define MC_IO_MAP_WSM		_IOWR(MC_IOC_MAGIC, 11, struct mc_ioctl_map)
+#define MC_IO_MAP_MCI		_IOWR(MC_IOC_MAGIC, 12, struct mc_ioctl_map)
+#define MC_IO_MAP_PWSM		_IOWR(MC_IOC_MAGIC, 13, struct mc_ioctl_map)
+
+/*
+ * Clean orphaned WSM buffers. Only available to the daemon and should
+ * only be carried out if the TLC crashes or otherwise calls exit() in
+ * an unexpected manner.
+ * The clean is needed together with the lock/unlock mechanism so the daemon
+ * has clear control of the mapped buffers so it can close a Trustlet before
+ * release all the WSM buffers, otherwise the Trustlet would be able to write
+ * to possibly kernel memory areas
+ */
+#define MC_IO_CLEAN_WSM		_IO(MC_IOC_MAGIC, 14)
+
+/*
+ * Get L2 phys address of a buffer handle allocated to the user.
+ * Only available to the daemon.
+ */
+#define MC_IO_RESOLVE_WSM	_IOWR(MC_IOC_MAGIC, 15, \
+					struct mc_ioctl_resolv_wsm)
+
+/*
+ * Get the phys address & length of a allocated contiguous buffer.
+ * Only available to the daemon */
+#define MC_IO_RESOLVE_CONT_WSM	_IOWR(MC_IOC_MAGIC, 16, \
+					struct mc_ioctl_resolv_cont_wsm)
+
+/*
+ * Setup the mem traces when called.
+ * Only available to the daemon */
+#define MC_IO_LOG_SETUP		_IO(MC_IOC_MAGIC, 17)
+
+#endif /* _MC_LINUX_H_ */
diff --git a/drivers/gud/mobicore_driver/public/version.h b/drivers/gud/mobicore_driver/public/version.h
index 9b2dbca..591ca3d 100644
--- a/drivers/gud/mobicore_driver/public/version.h
+++ b/drivers/gud/mobicore_driver/public/version.h
@@ -1,6 +1,6 @@
-/** @addtogroup MCD_MCDIMPL_KMOD
- * @{
- * <!-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+/*
+ * <-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
 #ifndef _MC_DRV_VERSION_H_
 #define _MC_DRV_VERSION_H_
 
-#define MCDRVMODULEAPI_VERSION_MAJOR 0
+#define MCDRVMODULEAPI_VERSION_MAJOR 1
 #define MCDRVMODULEAPI_VERSION_MINOR 1
 
 #endif /* _MC_DRV_VERSION_H_ */
diff --git a/drivers/gud/mobicore_kernelapi/clientlib.c b/drivers/gud/mobicore_kernelapi/clientlib.c
index 13826f2..7038e02 100644
--- a/drivers/gud/mobicore_kernelapi/clientlib.c
+++ b/drivers/gud/mobicore_kernelapi/clientlib.c
@@ -1,7 +1,7 @@
-/**
+/*
  * MobiCore KernelApi module
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
  *
  * 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
@@ -19,16 +19,15 @@
 
 #include "public/mobicore_driver_api.h"
 #include "public/mobicore_driver_cmd.h"
+#include "include/mcinq.h"
 #include "device.h"
 #include "session.h"
 
 /* device list */
 LIST_HEAD(devices);
 
-/*----------------------------------------------------------------------------*/
-static struct mcore_device_t *resolve_device_id(
-	uint32_t device_id
-) {
+static struct mcore_device_t *resolve_device_id(uint32_t device_id)
+{
 	struct mcore_device_t *tmp;
 	struct list_head *pos;
 
@@ -41,19 +40,13 @@
 	return NULL;
 }
 
-
-/*----------------------------------------------------------------------------*/
-static void add_device(
-	struct mcore_device_t *device
-) {
+static void add_device(struct mcore_device_t *device)
+{
 	list_add_tail(&(device->list), &devices);
 }
 
-
-/*----------------------------------------------------------------------------*/
-static bool remove_device(
-	uint32_t device_id
-) {
+static bool remove_device(uint32_t device_id)
+{
 	struct mcore_device_t *tmp;
 	struct list_head *pos, *q;
 
@@ -68,22 +61,18 @@
 	return false;
 }
 
-
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_open_device(
-	uint32_t device_id
-) {
+enum mc_result mc_open_device(uint32_t device_id)
+{
 	enum mc_result mc_result = MC_DRV_OK;
 	struct connection *dev_con = NULL;
 
-	MCDRV_DBG_VERBOSE("===%s()===", __func__);
-
-	/* Enter critical section */
+	MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
 
 	do {
 		struct mcore_device_t *device = resolve_device_id(device_id);
 		if (device != NULL) {
-			MCDRV_DBG_ERROR("Device %d already opened", device_id);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"Device %d already opened", device_id);
 			mc_result = MC_DRV_ERR_INVALID_OPERATION;
 			break;
 		}
@@ -92,6 +81,7 @@
 		dev_con = connection_new();
 		if (!connection_connect(dev_con, MC_DAEMON_PID)) {
 			MCDRV_DBG_ERROR(
+				mc_kapi,
 				"Could not setup netlink connection to PID %u",
 				MC_DAEMON_PID);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
@@ -100,12 +90,11 @@
 
 		/* Forward device open to the daemon and read result */
 		struct mc_drv_cmd_open_device_t mc_drv_cmd_open_device = {
-			/* C++ does not support C99 designated initializers */
-			/* .header = */ {
-			/* .command_id = */ MC_DRV_CMD_OPEN_DEVICE
+			{
+				MC_DRV_CMD_OPEN_DEVICE
 			},
-		/* .payload = */ {
-		/* .device_id = */ device_id
+			{
+				device_id
 			}
 		};
 
@@ -114,8 +103,9 @@
 				&mc_drv_cmd_open_device,
 				sizeof(struct mc_drv_cmd_open_device_t));
 		if (len < 0) {
-			MCDRV_DBG_ERROR("CMD_OPEN_DEVICE writeCmd failed "
-				"ret=%d", len);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_OPEN_DEVICE writeCmd failed %d",
+					len);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
@@ -126,14 +116,16 @@
 					&rsp_header,
 					sizeof(rsp_header));
 		if (len != sizeof(rsp_header)) {
-			MCDRV_DBG_ERROR("CMD_OPEN_DEVICE readRsp failed "
-				"ret=%d", len);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_OPEN_DEVICE readRsp failed %d",
+					len);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
 		if (rsp_header.response_id != MC_DRV_RSP_OK) {
-			MCDRV_DBG_ERROR("CMD_OPEN_DEVICE failed, respId=%d",
-							rsp_header.response_id);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_OPEN_DEVICE failed, respId=%d",
+					rsp_header.response_id);
 			switch (rsp_header.response_id) {
 			case MC_DRV_RSP_PAYLOAD_LENGTH_ERROR:
 				mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
@@ -154,8 +146,9 @@
 		device = mcore_device_create(device_id, dev_con);
 		if (!mcore_device_open(device, MC_DRV_MOD_DEVNODE_FULLPATH)) {
 			mcore_device_cleanup(device);
-			MCDRV_DBG_ERROR("could not open device file: %s",
-				MC_DRV_MOD_DEVNODE_FULLPATH);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"could not open device file: %s",
+					MC_DRV_MOD_DEVNODE_FULLPATH);
 			mc_result = MC_DRV_ERR_INVALID_DEVICE_FILE;
 			break;
 		}
@@ -167,25 +160,20 @@
 	if (mc_result != MC_DRV_OK)
 		connection_cleanup(dev_con);
 
-	/* Exit critical section */
-
 	return mc_result;
 }
 EXPORT_SYMBOL(mc_open_device);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_close_device(
-	uint32_t device_id
-) {
+enum mc_result mc_close_device(uint32_t device_id)
+{
 	enum mc_result mc_result = MC_DRV_OK;
 
-	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+	MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
 
-	/* Enter critical section */
 	do {
 		struct mcore_device_t *device = resolve_device_id(device_id);
 		if (device == NULL) {
-			MCDRV_DBG_ERROR("Device not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Device not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
 			break;
 		}
@@ -193,15 +181,15 @@
 
 		/* Return if not all sessions have been closed */
 		if (mcore_device_has_sessions(device)) {
-			MCDRV_DBG_ERROR("cannot close with sessions pending");
+			MCDRV_DBG_ERROR(mc_kapi,
+					"cannot close with sessions pending");
 			mc_result = MC_DRV_ERR_SESSION_PENDING;
 			break;
 		}
 
 		struct mc_drv_cmd_close_device_t mc_drv_cmd_close_device = {
-			/* C++ does not support C99 designated initializers */
-			/* .header = */ {
-				/* .command_id = */ MC_DRV_CMD_CLOSE_DEVICE
+			{
+				MC_DRV_CMD_CLOSE_DEVICE
 			}
 		};
 		int len = connection_write_data(
@@ -210,8 +198,9 @@
 				sizeof(struct mc_drv_cmd_close_device_t));
 		/* ignore error, but log details */
 		if (len < 0) {
-			MCDRV_DBG_ERROR("CMD_CLOSE_DEVICE writeCmd failed "
-				"ret=%d", len);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_CLOSE_DEVICE writeCmd failed %d",
+					len);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 		}
 
@@ -221,15 +210,17 @@
 					&rsp_header,
 					sizeof(rsp_header));
 		if (len != sizeof(rsp_header)) {
-			MCDRV_DBG_ERROR("CMD_CLOSE_DEVICE readResp failed "
-				" ret=%d", len);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_CLOSE_DEVICE readResp failed %d",
+					len);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
 
 		if (rsp_header.response_id != MC_DRV_RSP_OK) {
-			MCDRV_DBG_ERROR("CMD_CLOSE_DEVICE failed, respId=%d",
-							rsp_header.response_id);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_CLOSE_DEVICE failed, respId=%d",
+					rsp_header.response_id);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
@@ -238,44 +229,37 @@
 
 	} while (false);
 
-	/* Exit critical section */
-
 	return mc_result;
 }
 EXPORT_SYMBOL(mc_close_device);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_open_session(
-	struct mc_session_handle *session,
-	const struct mc_uuid_t	*uuid,
-	uint8_t			*tci,
-	uint32_t		len
-) {
+enum mc_result mc_open_session(struct mc_session_handle *session,
+			       const struct mc_uuid_t *uuid,
+			       uint8_t *tci, uint32_t len)
+{
 	enum mc_result mc_result = MC_DRV_OK;
 
-	MCDRV_DBG_VERBOSE("===%s()===", __func__);
-
-	/* Enter critical section */
+	MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
 
 	do {
 		if (session == NULL) {
-			MCDRV_DBG_ERROR("Session is null");
+			MCDRV_DBG_ERROR(mc_kapi, "Session is null");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 		if (uuid == NULL) {
-			MCDRV_DBG_ERROR("UUID is null");
+			MCDRV_DBG_ERROR(mc_kapi, "UUID is null");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 		if (tci == NULL) {
-			MCDRV_DBG_ERROR("TCI is null");
+			MCDRV_DBG_ERROR(mc_kapi, "TCI is null");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 		if (len > MC_MAX_TCI_LEN) {
-			MCDRV_DBG_ERROR("TCI length is longer than %d",
-				MC_MAX_TCI_LEN);
+			MCDRV_DBG_ERROR(mc_kapi, "TCI length is longer than %d",
+					MC_MAX_TCI_LEN);
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
@@ -284,7 +268,7 @@
 		struct mcore_device_t *device =
 				resolve_device_id(session->device_id);
 		if (device == NULL) {
-			MCDRV_DBG_ERROR("Device not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Device not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
 			break;
 		}
@@ -294,40 +278,40 @@
 		struct wsm *wsm =
 			mcore_device_find_contiguous_wsm(device, tci);
 		if (wsm == NULL) {
-			MCDRV_DBG_ERROR("Could not resolve TCI phy address ");
+			MCDRV_DBG_ERROR(mc_kapi,
+					"Could not resolve TCI phy address ");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 
 		if (wsm->len < len) {
-			MCDRV_DBG_ERROR("length is more than allocated TCI");
+			MCDRV_DBG_ERROR(mc_kapi,
+					"length is more than allocated TCI");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 
 		/* Prepare open session command */
 		struct mc_drv_cmd_open_session_t cmdOpenSession = {
-			/* C++ does not support C99 designated initializers */
-			/* .header = */ {
-				/* .command_id = */ MC_DRV_CMD_OPEN_SESSION
+			{
+				MC_DRV_CMD_OPEN_SESSION
 			},
-			/* .payload = */ {
-				/* .device_id = */ session->device_id,
-				/* .uuid = */ *uuid,
-				/* .tci = */ (uint32_t)wsm->phys_addr,
-				/* .len = */ len
+			{
+				session->device_id,
+				*uuid,
+				(uint32_t)wsm->phys_addr,
+				len
 			}
 		};
 
 		/* Transmit command data */
-
-		int len = connection_write_data(
-						dev_con,
+		int len = connection_write_data(dev_con,
 						&cmdOpenSession,
 						sizeof(cmdOpenSession));
 		if (len != sizeof(cmdOpenSession)) {
-			MCDRV_DBG_ERROR("CMD_OPEN_SESSION writeData failed "
-				"ret=%d", len);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_OPEN_SESSION writeData failed %d",
+					len);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
@@ -336,20 +320,21 @@
 
 		/* read header first */
 		struct mc_drv_response_header_t rsp_header;
-		len = connection_read_datablock(
-					dev_con,
-					&rsp_header,
-					sizeof(rsp_header));
+		len = connection_read_datablock(dev_con,
+						&rsp_header,
+						sizeof(rsp_header));
 		if (len != sizeof(rsp_header)) {
-			MCDRV_DBG_ERROR("CMD_OPEN_SESSION readResp failed "
-				" ret=%d", len);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_OPEN_SESSION readResp failed %d",
+					len);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
 
 		if (rsp_header.response_id != MC_DRV_RSP_OK) {
-			MCDRV_DBG_ERROR("CMD_OPEN_SESSION failed, respId=%d",
-							rsp_header.response_id);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_OPEN_SESSION failed, respId=%d",
+					rsp_header.response_id);
 			switch (rsp_header.response_id) {
 			case MC_DRV_RSP_TRUSTLET_NOT_FOUND:
 				mc_result = MC_DRV_ERR_INVALID_DEVICE_FILE;
@@ -366,14 +351,15 @@
 
 		/* read payload */
 		struct mc_drv_rsp_open_session_payload_t
-						rsp_open_session_payload;
+					rsp_open_session_payload;
 		len = connection_read_datablock(
 					dev_con,
 					&rsp_open_session_payload,
 					sizeof(rsp_open_session_payload));
 		if (len != sizeof(rsp_open_session_payload)) {
-			MCDRV_DBG_ERROR("CMD_OPEN_SESSION readPayload failed "
-				"ret=%d", len);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_OPEN_SESSION readPayload fail %d",
+					len);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
@@ -383,9 +369,10 @@
 
 		/* Set up second channel for notifications */
 		struct connection *session_connection = connection_new();
-		/*TODO: no real need to connect here? */
+
 		if (!connection_connect(session_connection, MC_DAEMON_PID)) {
 			MCDRV_DBG_ERROR(
+				mc_kapi,
 				"Could not setup netlink connection to PID %u",
 				MC_DAEMON_PID);
 			connection_cleanup(session_connection);
@@ -393,42 +380,38 @@
 			break;
 		}
 
-		/*TODO CONTINOUE HERE !!!! FIX RW RETURN HANDLING!!!! */
-
 		/* Write command to use channel for notifications */
 		struct mc_drv_cmd_nqconnect_t cmd_nqconnect = {
-			/* C++ does not support C99 designated initializers */
-			/* .header = */ {
-				/* .command_id = */ MC_DRV_CMD_NQ_CONNECT
+			{
+				MC_DRV_CMD_NQ_CONNECT
 			},
-			/* .payload = */ {
-				/* .device_id =  */ session->device_id,
-				/* .session_id = */ session->session_id,
-				/* .device_session_id = */
+			{
+				session->device_id,
+				session->session_id,
 				rsp_open_session_payload.device_session_id,
-				/* .session_magic = */
-					rsp_open_session_payload.session_magic
+				rsp_open_session_payload.session_magic
 			}
 		};
 		connection_write_data(session_connection,
-			&cmd_nqconnect,
-			sizeof(cmd_nqconnect));
+				      &cmd_nqconnect,
+				      sizeof(cmd_nqconnect));
 
 		/* Read command response, header first */
-		len = connection_read_datablock(
-					session_connection,
-					&rsp_header,
-					sizeof(rsp_header));
+		len = connection_read_datablock(session_connection,
+						&rsp_header,
+						sizeof(rsp_header));
 		if (len != sizeof(rsp_header)) {
-			MCDRV_DBG_ERROR("CMD_NQ_CONNECT readRsp failed "
-				"ret=%d", len);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_NQ_CONNECT readRsp failed %d",
+					len);
 			connection_cleanup(session_connection);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
 
 		if (rsp_header.response_id != MC_DRV_RSP_OK) {
-			MCDRV_DBG_ERROR("CMD_NQ_CONNECT failed, respId=%d",
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_NQ_CONNECT failed, respId=%d",
 					rsp_header.response_id);
 			connection_cleanup(session_connection);
 			mc_result = MC_DRV_ERR_NQ_FAILED;
@@ -438,84 +421,78 @@
 		/* there is no payload. */
 
 		/* Session established, new session object must be created */
-		mcore_device_create_new_session(
-			device,
-			session->session_id,
-			session_connection);
+		mcore_device_create_new_session(device,
+						session->session_id,
+						session_connection);
 
 	} while (false);
 
-	/* Exit critical section */
-
 	return mc_result;
 }
 EXPORT_SYMBOL(mc_open_session);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_close_session(
-	struct mc_session_handle *session
-) {
+enum mc_result mc_close_session(struct mc_session_handle *session)
+{
 	enum mc_result mc_result = MC_DRV_OK;
 
-	MCDRV_DBG_VERBOSE("===%s()===", __func__);
-
-	/* Enter critical section */
+	MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
 
 	do {
 		if (session == NULL) {
-			MCDRV_DBG_ERROR("Session is null");
+			MCDRV_DBG_ERROR(mc_kapi, "Session is null");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 
-		struct mcore_device_t  *device =
+		struct mcore_device_t *device =
 					resolve_device_id(session->device_id);
 		if (device == NULL) {
-			MCDRV_DBG_ERROR("Device not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Device not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
 			break;
 		}
-		struct connection  *dev_con = device->connection;
+		struct connection *dev_con = device->connection;
 
-		struct session  *nq_session =
-		 mcore_device_resolve_session_id(device, session->session_id);
+		struct session *nq_session =
+			mcore_device_resolve_session_id(device,
+							session->session_id);
+
 		if (nq_session == NULL) {
-			MCDRV_DBG_ERROR("Session not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Session not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
 			break;
 		}
 
 		/* Write close session command */
 		struct mc_drv_cmd_close_session_t cmd_close_session = {
-			/* C++ does not support C99 designated initializers */
-			/* .header = */ {
-				/* .command_id = */ MC_DRV_CMD_CLOSE_SESSION
+			{
+				MC_DRV_CMD_CLOSE_SESSION
 			},
-			/* .payload = */ {
-				/* .session_id = */ session->session_id,
+			{
+				session->session_id,
 			}
 		};
-		connection_write_data(
-			dev_con,
-			&cmd_close_session,
-			sizeof(cmd_close_session));
+		connection_write_data(dev_con,
+				      &cmd_close_session,
+				      sizeof(cmd_close_session));
 
 		/* Read command response */
 		struct mc_drv_response_header_t rsp_header;
-		int len = connection_read_datablock(
-						dev_con,
-						&rsp_header,
-						sizeof(rsp_header));
+		int len = connection_read_datablock(dev_con,
+						    &rsp_header,
+						    sizeof(rsp_header));
 		if (len != sizeof(rsp_header)) {
-			MCDRV_DBG_ERROR("CMD_CLOSE_SESSION readRsp failed "
-				"ret=%d", len);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_CLOSE_SESSION readRsp failed %d",
+					len);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
 
 		if (rsp_header.response_id != MC_DRV_RSP_OK) {
-			MCDRV_DBG_ERROR("CMD_CLOSE_SESSION failed, respId=%d",
-							rsp_header.response_id);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_CLOSE_SESSION failed, respId=%d",
+					rsp_header.response_id);
 			mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
 			break;
 		}
@@ -525,23 +502,19 @@
 
 	} while (false);
 
-	/* Exit critical section */
-
 	return mc_result;
 }
 EXPORT_SYMBOL(mc_close_session);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_notify(
-	struct mc_session_handle   *session
-) {
+enum mc_result mc_notify(struct mc_session_handle *session)
+{
 	enum mc_result mc_result = MC_DRV_OK;
 
-	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+	MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
 
 	do {
 		if (session == NULL) {
-			MCDRV_DBG_ERROR("Session is null");
+			MCDRV_DBG_ERROR(mc_kapi, "Session is null");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
@@ -549,7 +522,7 @@
 		struct mcore_device_t *device =
 					resolve_device_id(session->device_id);
 		if (device == NULL) {
-			MCDRV_DBG_ERROR("Device not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Device not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
 			break;
 		}
@@ -558,25 +531,23 @@
 		struct session  *nqsession =
 		 mcore_device_resolve_session_id(device, session->session_id);
 		if (nqsession == NULL) {
-			MCDRV_DBG_ERROR("Session not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Session not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
 			break;
 		}
 
 		struct mc_drv_cmd_notify_t cmd_notify = {
-			/* C++ does not support C99 designated initializers */
-			/* .header = */ {
-				/* .command_id = */ MC_DRV_CMD_NOTIFY
+			{
+				MC_DRV_CMD_NOTIFY
 			},
-			/* .payload = */ {
-				/* .session_id = */ session->session_id,
+			{
+				session->session_id
 			}
 		};
 
-		connection_write_data(
-			dev_con,
-			&cmd_notify,
-			sizeof(cmd_notify));
+		connection_write_data(dev_con,
+				      &cmd_notify,
+				      sizeof(cmd_notify));
 
 		/* Daemon will not return a response */
 
@@ -586,14 +557,12 @@
 }
 EXPORT_SYMBOL(mc_notify);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_wait_notification(
-	struct mc_session_handle  *session,
-	int32_t			timeout
-) {
+enum mc_result mc_wait_notification(struct mc_session_handle *session,
+				    int32_t timeout)
+{
 	enum mc_result mc_result = MC_DRV_OK;
 
-	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+	MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
 
 	do {
 		if (session == NULL) {
@@ -601,18 +570,19 @@
 			break;
 		}
 
-		struct mcore_device_t  *device =
+		struct mcore_device_t *device =
 					resolve_device_id(session->device_id);
 		if (device == NULL) {
-			MCDRV_DBG_ERROR("Device not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Device not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
 			break;
 		}
 
-		struct session  *nq_session =
-		 mcore_device_resolve_session_id(device, session->session_id);
+		struct session *nq_session =
+			mcore_device_resolve_session_id(device,
+							session->session_id);
 		if (nq_session == NULL) {
-			MCDRV_DBG_ERROR("Session not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Session not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
 			break;
 		}
@@ -624,22 +594,26 @@
 		/* Read notification queue till it's empty */
 		for (;;) {
 			struct notification notification;
-			ssize_t num_read = connection_read_data(
-				nqconnection,
-				&notification,
-				sizeof(notification),
-				timeout);
-			/* Exit on timeout in first run. Later runs have
+			ssize_t num_read =
+				connection_read_data(nqconnection,
+						     &notification,
+						     sizeof(notification),
+						     timeout);
+			/*
+			 * Exit on timeout in first run. Later runs have
 			 * timeout set to 0.
-			 * -2 means, there is no more data. */
+			 * -2 means, there is no more data.
+			 */
 			if (count == 0 && num_read == -2) {
-				MCDRV_DBG_ERROR("read timeout");
+				MCDRV_DBG_ERROR(mc_kapi, "read timeout");
 				mc_result = MC_DRV_ERR_TIMEOUT;
 				break;
 			}
-			/* After first notification the queue will be
+			/*
+			 * After first notification the queue will be
 			 * drained, Thus we set no timeout for the
-			 * following reads */
+			 * following reads
+			 */
 			timeout = 0;
 
 			if (num_read != sizeof(struct notification)) {
@@ -647,28 +621,33 @@
 					/* failure in first read, notify it */
 					mc_result = MC_DRV_ERR_NOTIFICATION;
 					MCDRV_DBG_ERROR(
+					mc_kapi,
 					"read notification failed, "
 					"%i bytes received", (int)num_read);
 					break;
 				} else {
-					/* Read of the n-th notification
-					   failed/timeout. We don't tell the
-					   caller, as we got valid notifications
-					   before. */
+					/*
+					 * Read of the n-th notification
+					 * failed/timeout. We don't tell the
+					 * caller, as we got valid notifications
+					 * before.
+					 */
 					mc_result = MC_DRV_OK;
 					break;
 				}
 			}
 
 			count++;
-			MCDRV_DBG_VERBOSE("readNq count=%d, SessionID=%d, "
-				"Payload=%d", count,
-				notification.session_id, notification.payload);
+			MCDRV_DBG_VERBOSE(mc_kapi,
+					  "count=%d, SessionID=%d, Payload=%d",
+					  count,
+					  notification.session_id,
+					  notification.payload);
 
 			if (notification.payload != 0) {
 				/* Session end point died -> store exit code */
 				session_set_error_info(nq_session,
-					notification.payload);
+						       notification.payload);
 
 				mc_result = MC_DRV_INFO_NOTIFICATION;
 				break;
@@ -681,24 +660,17 @@
 }
 EXPORT_SYMBOL(mc_wait_notification);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_malloc_wsm(
-	uint32_t	device_id,
-	uint32_t	align,
-	uint32_t	len,
-	uint8_t		**wsm,
-	uint32_t	wsm_flags
-) {
+enum mc_result mc_malloc_wsm(uint32_t device_id, uint32_t align, uint32_t len,
+			     uint8_t **wsm, uint32_t wsm_flags)
+{
 	enum mc_result mc_result = MC_DRV_ERR_UNKNOWN;
 
-	MCDRV_DBG_VERBOSE("===%s()===", __func__);
-
-	/* Enter critical section */
+	MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
 
 	do {
 		struct mcore_device_t *device = resolve_device_id(device_id);
 		if (device == NULL) {
-			MCDRV_DBG_ERROR("Device not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Device not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
 			break;
 		}
@@ -710,7 +682,7 @@
 		struct wsm *wsm_stack =
 			mcore_device_allocate_contiguous_wsm(device, len);
 		if (wsm_stack == NULL) {
-			MCDRV_DBG_ERROR("Allocation of WSM failed");
+			MCDRV_DBG_ERROR(mc_kapi, "Allocation of WSM failed");
 			mc_result = MC_DRV_ERR_NO_FREE_MEMORY;
 			break;
 		}
@@ -720,31 +692,24 @@
 
 	} while (false);
 
-	/* Exit critical section */
-
 	return mc_result;
 }
 EXPORT_SYMBOL(mc_malloc_wsm);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_free_wsm(
-	uint32_t	device_id,
-	uint8_t		*wsm
-) {
+enum mc_result mc_free_wsm(uint32_t device_id, uint8_t *wsm)
+{
 	enum mc_result mc_result = MC_DRV_ERR_UNKNOWN;
 	struct mcore_device_t *device;
 
 
-	MCDRV_DBG_VERBOSE("===%s()===", __func__);
-
-	/* Enter critical section */
+	MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
 
 	do {
 
 		/* Get the device associated wit the given session */
 		device = resolve_device_id(device_id);
 		if (device == NULL) {
-			MCDRV_DBG_ERROR("Device not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Device not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
 			break;
 		}
@@ -753,14 +718,15 @@
 		struct wsm *wsm_stack =
 			mcore_device_find_contiguous_wsm(device, wsm);
 		if (wsm_stack == NULL) {
-			MCDRV_DBG_ERROR("unknown address");
+			MCDRV_DBG_ERROR(mc_kapi, "unknown address");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 
 		/* Free the given virtual address */
 		if (!mcore_device_free_contiguous_wsm(device, wsm_stack)) {
-			MCDRV_DBG_ERROR("Free of virtual address failed");
+			MCDRV_DBG_ERROR(mc_kapi,
+					"Free of virtual address failed");
 			mc_result = MC_DRV_ERR_FREE_MEMORY_FAILED;
 			break;
 		}
@@ -768,130 +734,124 @@
 
 	} while (false);
 
-	/* Exit critical section */
-
 	return mc_result;
 }
 EXPORT_SYMBOL(mc_free_wsm);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_map(
-	struct mc_session_handle	*session_handle,
-	void				*buf,
-	uint32_t			buf_len,
-	struct mc_bulk_map		*map_info
-) {
+enum mc_result mc_map(struct mc_session_handle *session_handle, void *buf,
+		      uint32_t buf_len, struct mc_bulk_map *map_info)
+{
 	enum mc_result mc_result = MC_DRV_ERR_UNKNOWN;
 
-	MCDRV_DBG_VERBOSE("===%s()===", __func__);
-
-	/* Enter critical section */
+	MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
 
 	do {
 		if (session_handle == NULL) {
-			MCDRV_DBG_ERROR("session_handle is null");
+			MCDRV_DBG_ERROR(mc_kapi, "session_handle is null");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 		if (map_info == NULL) {
-			MCDRV_DBG_ERROR("map_info is null");
+			MCDRV_DBG_ERROR(mc_kapi, "map_info is null");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 		if (buf == NULL) {
-			MCDRV_DBG_ERROR("buf is null");
+			MCDRV_DBG_ERROR(mc_kapi, "buf is null");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 
 		/* Determine device the session belongs to */
-		struct mcore_device_t  *device = resolve_device_id(
-						session_handle->device_id);
+		struct mcore_device_t *device =
+				resolve_device_id(session_handle->device_id);
+
 		if (device == NULL) {
-			MCDRV_DBG_ERROR("Device not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Device not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
 			break;
 		}
 		struct connection *dev_con = device->connection;
 
 		/* Get session */
-		struct session  *session =
-		mcore_device_resolve_session_id(device,
-						session_handle->session_id);
+		uint32_t session_id = session_handle->session_id;
+		struct session *session =
+				mcore_device_resolve_session_id(device,
+								session_id);
 		if (session == NULL) {
-			MCDRV_DBG_ERROR("Session not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Session not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
 			break;
 		}
 
-		/* Register mapped bulk buffer to Kernel Module and keep mapped
-		   bulk buffer in mind */
-		struct bulk_buffer_descriptor *bulk_buf = session_add_bulk_buf(
-			session, buf, buf_len);
+		/*
+		 * Register mapped bulk buffer to Kernel Module and keep mapped
+		 * bulk buffer in mind
+		 */
+		struct bulk_buffer_descriptor *bulk_buf =
+				session_add_bulk_buf(session, buf, buf_len);
 		if (bulk_buf == NULL) {
-			MCDRV_DBG_ERROR("Error mapping bulk buffer");
+			MCDRV_DBG_ERROR(mc_kapi, "Error mapping bulk buffer");
 			mc_result = MC_DRV_ERR_BULK_MAPPING;
 			break;
 		}
 
 		/* Prepare map command */
 		struct mc_drv_cmd_map_bulk_mem_t mc_drv_cmd_map_bulk_mem = {
-			/* C++ does not support C99 designated initializers */
-			/* .header = */ {
-				/* .command_id = */ MC_DRV_CMD_MAP_BULK_BUF
+			{
+				MC_DRV_CMD_MAP_BULK_BUF
 			},
-			/* .payload = */ {
-				/* .session_id = */ session->session_id,
-				/* .phys_addr_l2; = */
-					(uint32_t)bulk_buf->phys_addr_wsm_l2,
-				/* .offset_payload = */
-					(uint32_t)(bulk_buf->virt_addr) & 0xFFF,
-				/* .len_bulk_mem = */ bulk_buf->len
+			{
+				session->session_id,
+				bulk_buf->handle,
+				(uint32_t)bulk_buf->phys_addr_wsm_l2,
+				(uint32_t)(bulk_buf->virt_addr) & 0xFFF,
+				bulk_buf->len
 			}
 		};
 
 		/* Transmit map command to MobiCore device */
-		connection_write_data(
-			dev_con,
-			&mc_drv_cmd_map_bulk_mem,
-			sizeof(mc_drv_cmd_map_bulk_mem));
+		connection_write_data(dev_con,
+				      &mc_drv_cmd_map_bulk_mem,
+				      sizeof(mc_drv_cmd_map_bulk_mem));
 
 		/* Read command response */
 		struct mc_drv_response_header_t rsp_header;
-		int len = connection_read_datablock(
-						dev_con,
-						&rsp_header,
-						sizeof(rsp_header));
+		int len = connection_read_datablock(dev_con,
+						    &rsp_header,
+						    sizeof(rsp_header));
 		if (len != sizeof(rsp_header)) {
-			MCDRV_DBG_ERROR("CMD_MAP_BULK_BUF readRsp failed, "
-				"ret=%d", len);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_MAP_BULK_BUF readRsp failed %d",
+					len);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
 
 		if (rsp_header.response_id != MC_DRV_RSP_OK) {
-			MCDRV_DBG_ERROR("CMD_MAP_BULK_BUF failed, respId=%d",
-							rsp_header.response_id);
-			/* REV We ignore Daemon Error code because client cannot
-			   handle it anyhow. */
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_MAP_BULK_BUF failed, respId=%d",
+					rsp_header.response_id);
+
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 
-			/* Unregister mapped bulk buffer from Kernel Module and
-			   remove mapped bulk buffer from session maintenance */
+			/*
+			 * Unregister mapped bulk buffer from Kernel Module and
+			 * remove mapped bulk buffer from session maintenance
+			 */
 			if (!session_remove_bulk_buf(session, buf)) {
 				/* Removing of bulk buffer not possible */
-				MCDRV_DBG_ERROR("Unregistering of bulk memory"
-					"from Kernel Module failed");
+				MCDRV_DBG_ERROR(mc_kapi,
+						"Unreg of bulk memory failed");
 			}
 			break;
 		}
 
 		struct mc_drv_rsp_map_bulk_mem_payload_t
 						rsp_map_bulk_mem_payload;
-		connection_read_datablock(
-			dev_con,
-			&rsp_map_bulk_mem_payload,
-			sizeof(rsp_map_bulk_mem_payload));
+		connection_read_datablock(dev_con,
+					  &rsp_map_bulk_mem_payload,
+					  sizeof(rsp_map_bulk_mem_payload));
 
 		/* Set mapping info for Trustlet */
 		map_info->secure_virt_addr =
@@ -901,37 +861,30 @@
 
 	} while (false);
 
-	/* Exit critical section */
-
 	return mc_result;
 }
 EXPORT_SYMBOL(mc_map);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_unmap(
-	struct mc_session_handle	*session_handle,
-	void				*buf,
-	struct mc_bulk_map		*map_info
-) {
+enum mc_result mc_unmap(struct mc_session_handle *session_handle, void *buf,
+			struct mc_bulk_map *map_info)
+{
 	enum mc_result mc_result = MC_DRV_ERR_UNKNOWN;
 
-	MCDRV_DBG_VERBOSE("===%s()===", __func__);
-
-	/* Enter critical section */
+	MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
 
 	do {
 		if (session_handle == NULL) {
-			MCDRV_DBG_ERROR("session_handle is null");
+			MCDRV_DBG_ERROR(mc_kapi, "session_handle is null");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 		if (map_info == NULL) {
-			MCDRV_DBG_ERROR("map_info is null");
+			MCDRV_DBG_ERROR(mc_kapi, "map_info is null");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
 		if (buf == NULL) {
-			MCDRV_DBG_ERROR("buf is null");
+			MCDRV_DBG_ERROR(mc_kapi, "buf is null");
 			mc_result = MC_DRV_ERR_INVALID_PARAMETER;
 			break;
 		}
@@ -940,79 +893,83 @@
 		struct mcore_device_t  *device =
 			resolve_device_id(session_handle->device_id);
 		if (device == NULL) {
-			MCDRV_DBG_ERROR("Device not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Device not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
 			break;
 		}
-		struct connection  *dev_con = device->connection;
+		struct connection *dev_con = device->connection;
 
 		/* Get session */
+		uint32_t session_id = session_handle->session_id;
 		struct session  *session =
 			mcore_device_resolve_session_id(device,
-						session_handle->session_id);
+							session_id);
 		if (session == NULL) {
-			MCDRV_DBG_ERROR("Session not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Session not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
 			break;
 		}
 
+		uint32_t handle = session_find_bulk_buf(session, buf);
+		if (handle == 0) {
+			MCDRV_DBG_ERROR(mc_kapi, "Buffer not found");
+			mc_result = MC_DRV_ERR_BULK_UNMAPPING;
+			break;
+		}
+
+
 		/* Prepare unmap command */
 		struct mc_drv_cmd_unmap_bulk_mem_t cmd_unmap_bulk_mem = {
-				/* .header = */ {
-					/* .command_id = */
-						MC_DRV_CMD_UNMAP_BULK_BUF
+				{
+					MC_DRV_CMD_UNMAP_BULK_BUF
 				},
-				/* .payload = */ {
-					/* .session_id = */ session->session_id,
-					/* .secure_virtual_adr = */
-					(uint32_t)(map_info->secure_virt_addr),
-					/* .len_bulk_mem =
-						map_info->secure_virt_len*/
+				{
+					session->session_id,
+					handle,
+					(uint32_t)(map_info->secure_virt_addr)
 				}
 			};
 
-		connection_write_data(
-			dev_con,
-			&cmd_unmap_bulk_mem,
-			sizeof(cmd_unmap_bulk_mem));
+		connection_write_data(dev_con,
+				      &cmd_unmap_bulk_mem,
+				      sizeof(cmd_unmap_bulk_mem));
 
 		/* Read command response */
 		struct mc_drv_response_header_t rsp_header;
-		int len = connection_read_datablock(
-						dev_con,
-						&rsp_header,
-						sizeof(rsp_header));
+		int len = connection_read_datablock(dev_con,
+						    &rsp_header,
+						    sizeof(rsp_header));
 		if (len != sizeof(rsp_header)) {
-			MCDRV_DBG_ERROR("CMD_UNMAP_BULK_BUF readRsp failed, "
-				"ret=%d", len);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_UNMAP_BULK_BUF readRsp failed %d",
+					len);
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
 
 		if (rsp_header.response_id != MC_DRV_RSP_OK) {
-			MCDRV_DBG_ERROR("CMD_UNMAP_BULK_BUF failed, respId=%d",
-							rsp_header.response_id);
-			/* REV We ignore Daemon Error code because client
-			   cannot handle it anyhow. */
+			MCDRV_DBG_ERROR(mc_kapi,
+					"CMD_UNMAP_BULK_BUF failed, respId=%d",
+					rsp_header.response_id);
+
 			mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
 			break;
 		}
 
 		struct mc_drv_rsp_unmap_bulk_mem_payload_t
 						rsp_unmap_bulk_mem_payload;
-		connection_read_datablock(
-			dev_con,
-			&rsp_unmap_bulk_mem_payload,
-			sizeof(rsp_unmap_bulk_mem_payload));
+		connection_read_datablock(dev_con,
+					  &rsp_unmap_bulk_mem_payload,
+					  sizeof(rsp_unmap_bulk_mem_payload));
 
-		/* REV axh: what about check the payload? */
-
-		/* Unregister mapped bulk buffer from Kernel Module and
-		 * remove mapped bulk buffer from session maintenance */
+		/*
+		 * Unregister mapped bulk buffer from Kernel Module and
+		 * remove mapped bulk buffer from session maintenance
+		 */
 		if (!session_remove_bulk_buf(session, buf)) {
 			/* Removing of bulk buffer not possible */
-			MCDRV_DBG_ERROR("Unregistering of bulk memory from "
-							"Kernel Module failed");
+			MCDRV_DBG_ERROR(mc_kapi,
+					"Unregistering of bulk memory failed");
 			mc_result = MC_DRV_ERR_BULK_UNMAPPING;
 			break;
 		}
@@ -1021,20 +978,16 @@
 
 	} while (false);
 
-	/* Exit critical section */
-
 	return mc_result;
 }
 EXPORT_SYMBOL(mc_unmap);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_get_session_error_code(
-	struct mc_session_handle   *session,
-	int32_t			 *last_error
-) {
+enum mc_result mc_get_session_error_code(struct mc_session_handle *session,
+					 int32_t *last_error)
+{
 	enum mc_result mc_result = MC_DRV_OK;
 
-	MCDRV_DBG_VERBOSE("===%s()===", __func__);
+	MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
 
 	do {
 		if (session == NULL || last_error == NULL) {
@@ -1044,23 +997,24 @@
 
 		/* Get device */
 		struct mcore_device_t *device =
-					resolve_device_id(session->device_id);
+				resolve_device_id(session->device_id);
 		if (device == NULL) {
-			MCDRV_DBG_ERROR("Device not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Device not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
 			break;
 		}
 
 		/* Get session */
+		uint32_t session_id = session->session_id;
 		struct session *nqsession =
-		 mcore_device_resolve_session_id(device, session->session_id);
+				mcore_device_resolve_session_id(device,
+								session_id);
 		if (nqsession == NULL) {
-			MCDRV_DBG_ERROR("Session not found");
+			MCDRV_DBG_ERROR(mc_kapi, "Session not found");
 			mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
 			break;
 		}
 
-		/* get session error code from session */
 		*last_error = session_get_last_err(nqsession);
 
 	} while (false);
@@ -1069,24 +1023,17 @@
 }
 EXPORT_SYMBOL(mc_get_session_error_code);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_driver_ctrl(
-	enum mc_driver_ctrl  param,
-	uint8_t		 *data,
-	uint32_t		len
-) {
-	MCDRV_DBG_WARN("not implemented");
+enum mc_result mc_driver_ctrl(enum mc_driver_ctrl param, uint8_t *data,
+			      uint32_t len)
+{
+	MCDRV_DBG_WARN(mc_kapi, "not implemented");
 	return MC_DRV_ERR_NOT_IMPLEMENTED;
 }
 EXPORT_SYMBOL(mc_driver_ctrl);
 
-/*----------------------------------------------------------------------------*/
-enum mc_result mc_manage(
-	uint32_t  device_id,
-	uint8_t   *data,
-	uint32_t  len
-) {
-	MCDRV_DBG_WARN("not implemented");
+enum mc_result mc_manage(uint32_t device_id, uint8_t *data, uint32_t len)
+{
+	MCDRV_DBG_WARN(mc_kapi, "not implemented");
 	return MC_DRV_ERR_NOT_IMPLEMENTED;
 }
 EXPORT_SYMBOL(mc_manage);
diff --git a/drivers/gud/mobicore_kernelapi/common.h b/drivers/gud/mobicore_kernelapi/common.h
index 2a73474..a15b1d7 100644
--- a/drivers/gud/mobicore_kernelapi/common.h
+++ b/drivers/gud/mobicore_kernelapi/common.h
@@ -1,97 +1,73 @@
-/**
+/*
+ * Common data types for use by the MobiCore Kernel API Driver
  *
- * Common data types
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * 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 COMMON_H
-#define COMMON_H
+#ifndef _MC_KAPI_COMMON_H
+#define _MC_KAPI_COMMON_H
 
 #include "connection.h"
 #include "mcinq.h"
 
-void mcapi_insert_connection(
-	struct connection *connection
-);
+void mcapi_insert_connection(struct connection *connection);
+void mcapi_remove_connection(uint32_t seq);
+unsigned int mcapi_unique_id(void);
 
-void mcapi_remove_connection(
-	uint32_t seq
-);
+#define MC_DAEMON_PID			0xFFFFFFFF
+#define MC_DRV_MOD_DEVNODE_FULLPATH	"/dev/mobicore"
 
-unsigned int mcapi_unique_id(
-	void
-);
+/* dummy function helper macro */
+#define DUMMY_FUNCTION()		do {} while (0)
 
+/* Found in main.c */
+extern struct device *mc_kapi;
 
-#define MC_DAEMON_PID 0xFFFFFFFF
-#define MC_DRV_MOD_DEVNODE_FULLPATH "/dev/mobicore"
-
-/* dummy function helper macro. */
-#define DUMMY_FUNCTION()	do {} while (0)
-
-#define MCDRV_ERROR(txt, ...) \
-	printk(KERN_ERR "mcKernelApi %s() ### ERROR: " txt, \
-		__func__, \
-		##__VA_ARGS__)
+#define MCDRV_ERROR(dev, txt, ...) \
+	dev_err(dev, "%s() ### ERROR: " txt, __func__, ##__VA_ARGS__)
 
 #if defined(DEBUG)
 
 /* #define DEBUG_VERBOSE */
 #if defined(DEBUG_VERBOSE)
-#define MCDRV_DBG_VERBOSE		  MCDRV_DBG
+#define MCDRV_DBG_VERBOSE		MCDRV_DBG
 #else
-#define MCDRV_DBG_VERBOSE(...)	 DUMMY_FUNCTION()
+#define MCDRV_DBG_VERBOSE(...)		DUMMY_FUNCTION()
 #endif
 
-#define MCDRV_DBG(txt, ...) \
-	printk(KERN_INFO "mcKernelApi %s(): " txt, \
-		__func__, \
-		##__VA_ARGS__)
+#define MCDRV_DBG(dev, txt, ...) \
+	dev_info(dev, "%s(): " txt, __func__, ##__VA_ARGS__)
 
-#define MCDRV_DBG_WARN(txt, ...) \
-	printk(KERN_WARNING "mcKernelApi %s() WARNING: " txt, \
-		__func__, \
-		##__VA_ARGS__)
+#define MCDRV_DBG_WARN(dev, txt, ...) \
+	dev_warn(dev, "%s() WARNING: " txt, __func__, ##__VA_ARGS__)
 
-#define MCDRV_DBG_ERROR(txt, ...) \
-	printk(KERN_ERR "mcKernelApi %s() ### ERROR: " txt, \
-		__func__, \
-		##__VA_ARGS__)
-
+#define MCDRV_DBG_ERROR(dev, txt, ...) \
+	dev_err(dev, "%s() ### ERROR: " txt, __func__, ##__VA_ARGS__)
 
 #define MCDRV_ASSERT(cond) \
 	do { \
 		if (unlikely(!(cond))) { \
-			panic("mcKernelApi Assertion failed: %s:%d\n", \
-				__FILE__, __LINE__); \
+			panic("mc_kernelapi Assertion failed: %s:%d\n", \
+			      __FILE__, __LINE__); \
 		} \
 	} while (0)
 
 #elif defined(NDEBUG)
 
-#define MCDRV_DBG_VERBOSE(...)	DUMMY_FUNCTION()
-#define MCDRV_DBG(...)		DUMMY_FUNCTION()
-#define MCDRV_DBG_WARN(...)	DUMMY_FUNCTION()
-#define MCDRV_DBG_ERROR(...)	DUMMY_FUNCTION()
+#define MCDRV_DBG_VERBOSE(...)		DUMMY_FUNCTION()
+#define MCDRV_DBG(...)			DUMMY_FUNCTION()
+#define MCDRV_DBG_WARN(...)		DUMMY_FUNCTION()
+#define MCDRV_DBG_ERROR(...)		DUMMY_FUNCTION()
 
-#define MCDRV_ASSERT(...)	DUMMY_FUNCTION()
+#define MCDRV_ASSERT(...)		DUMMY_FUNCTION()
 
 #else
 #error "Define DEBUG or NDEBUG"
 #endif /* [not] defined(DEBUG_MCMODULE) */
 
+#define assert(expr)			MCDRV_ASSERT(expr)
 
-#define LOG_I MCDRV_DBG_VERBOSE
-#define LOG_W MCDRV_DBG_WARN
-#define LOG_E MCDRV_DBG_ERROR
-
-
-#define assert(expr) MCDRV_ASSERT(expr)
-
-#endif /* COMMON_H */
-
-/** @} */
+#endif /* _MC_KAPI_COMMON_H */
diff --git a/drivers/gud/mobicore_kernelapi/connection.c b/drivers/gud/mobicore_kernelapi/connection.c
index 9048ae8..03288a0 100644
--- a/drivers/gud/mobicore_kernelapi/connection.c
+++ b/drivers/gud/mobicore_kernelapi/connection.c
@@ -1,10 +1,7 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
- * @{
- * @file
- *
+/*
  * Connection data.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * 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
@@ -26,37 +23,29 @@
 /* Define the initial state of the Data Available Semaphore */
 #define SEM_NO_DATA_AVAILABLE 0
 
-/*----------------------------------------------------------------------------*/
-struct connection *connection_new(
-	void
-) {
-	struct connection *conn = kzalloc(sizeof(struct connection),
-					GFP_KERNEL);
+struct connection *connection_new(void)
+{
+	struct connection *conn;
+
+	conn = kzalloc(sizeof(*conn), GFP_KERNEL);
 	conn->sequence_magic = mcapi_unique_id();
 	mutex_init(&conn->data_lock);
-	/* No data available */
 	sema_init(&conn->data_available_sem, SEM_NO_DATA_AVAILABLE);
 
 	mcapi_insert_connection(conn);
 	return conn;
 }
 
-/*----------------------------------------------------------------------------*/
-struct connection *connection_create(
-	int	 socket_descriptor,
-	pid_t   dest
-) {
+struct connection *connection_create(int socket_descriptor, pid_t dest)
+{
 	struct connection *conn = connection_new();
 
 	conn->peer_pid = dest;
 	return conn;
 }
 
-
-/*----------------------------------------------------------------------------*/
-void connection_cleanup(
-	struct connection *conn
-) {
+void connection_cleanup(struct connection *conn)
+{
 	if (!conn)
 		return;
 
@@ -66,26 +55,20 @@
 	kfree(conn);
 }
 
-
-/*----------------------------------------------------------------------------*/
-bool connection_connect(
-	struct connection *conn,
-	pid_t		dest
-) {
+bool connection_connect(struct connection *conn, pid_t dest)
+{
 	/* Nothing to connect */
 	conn->peer_pid = dest;
 	return true;
 }
 
-/*----------------------------------------------------------------------------*/
-size_t connection_readDataMsg(
-	struct connection *conn,
-	void *buffer,
-	uint32_t len
-) {
+size_t connection_read_data_msg(struct connection *conn, void *buffer,
+				uint32_t len)
+{
 	size_t ret = -1;
-	MCDRV_DBG_VERBOSE("reading connection data %u, connection data left %u",
-			len, conn->data_len);
+	MCDRV_DBG_VERBOSE(mc_kapi,
+			  "reading connection data %u, connection data left %u",
+			  len, conn->data_len);
 	/* trying to read more than the left data */
 	if (len > conn->data_len) {
 		ret = conn->data_len;
@@ -98,80 +81,75 @@
 		conn->data_start += len;
 	}
 
-	if (conn->data_len == 0)	{
+	if (conn->data_len == 0) {
 		conn->data_start = NULL;
 		kfree_skb(conn->skb);
 		conn->skb = NULL;
 	}
-	MCDRV_DBG_VERBOSE("read %u",  ret);
+	MCDRV_DBG_VERBOSE(mc_kapi, "read %u",  ret);
 	return ret;
 }
 
-/*----------------------------------------------------------------------------*/
-size_t connection_read_datablock(
-	struct connection *conn,
-	void		 *buffer,
-	uint32_t	 len
-) {
+size_t connection_read_datablock(struct connection *conn, void *buffer,
+				 uint32_t len)
+{
 	return connection_read_data(conn, buffer, len, -1);
 }
 
-
-/*----------------------------------------------------------------------------*/
-size_t connection_read_data(
-	struct connection *conn,
-	void		*buffer,
-	uint32_t	len,
-	int32_t		timeout
-) {
+size_t connection_read_data(struct connection *conn, void *buffer, uint32_t len,
+			    int32_t timeout)
+{
 	size_t ret = 0;
 
 	MCDRV_ASSERT(buffer != NULL);
 	MCDRV_ASSERT(conn->socket_descriptor != NULL);
 
-	MCDRV_DBG_VERBOSE("read data len = %u for PID = %u",
-						len, conn->sequence_magic);
+	MCDRV_DBG_VERBOSE(mc_kapi, "read data len = %u for PID = %u",
+			  len, conn->sequence_magic);
 	do {
-		/* Wait until data is available or timeout
-		   msecs_to_jiffies(-1) -> wait forever for the sem */
+		/*
+		 * Wait until data is available or timeout
+		 * msecs_to_jiffies(-1) -> wait forever for the sem
+		 */
 		if (down_timeout(&(conn->data_available_sem),
-				  msecs_to_jiffies(timeout))) {
-			MCDRV_DBG_VERBOSE("Timeout reading the data sem");
+				 msecs_to_jiffies(timeout))) {
+			MCDRV_DBG_VERBOSE(mc_kapi,
+					  "Timeout reading the data sem");
 			ret = -2;
 			break;
 		}
 
 		if (mutex_lock_interruptible(&(conn->data_lock))) {
-			MCDRV_DBG_ERROR("interrupted reading the data sem");
+			MCDRV_DBG_ERROR(mc_kapi,
+					"interrupted reading the data sem");
 			ret = -1;
 			break;
 		}
+
 		/* Have data, use it */
 		if (conn->data_len > 0)
-			ret = connection_readDataMsg(conn, buffer, len);
+			ret = connection_read_data_msg(conn, buffer, len);
 
-			mutex_unlock(&(conn->data_lock));
+		mutex_unlock(&(conn->data_lock));
 
 		/* There is still some data left */
 		if (conn->data_len > 0)
 			up(&conn->data_available_sem);
+
 	} while (0);
 
 	return ret;
 }
 
-/*----------------------------------------------------------------------------*/
-size_t connection_write_data(
-	struct connection *conn,
-	void		 *buffer,
-	uint32_t	 len
-) {
+size_t connection_write_data(struct connection *conn, void *buffer,
+			     uint32_t len)
+{
 	struct sk_buff *skb = NULL;
 	struct nlmsghdr *nlh;
 	int ret = 0;
 
-	MCDRV_DBG_VERBOSE("buffer length %u from pid %u\n",
-		  len,  conn->sequence_magic);
+	MCDRV_DBG_VERBOSE(mc_kapi, "buffer length %u from pid %u\n",
+			  len,  conn->sequence_magic);
 	do {
 		skb = nlmsg_new(NLMSG_SPACE(len), GFP_KERNEL);
 		if (!skb) {
@@ -180,7 +158,7 @@
 		}
 
 		nlh = nlmsg_put(skb, 0, conn->sequence_magic, 2,
-					  NLMSG_LENGTH(len), NLM_F_REQUEST);
+				NLMSG_LENGTH(len), NLM_F_REQUEST);
 		if (!nlh) {
 			ret = -1;
 			break;
@@ -188,7 +166,7 @@
 		memcpy(NLMSG_DATA(nlh), buffer, len);
 
 		netlink_unicast(conn->socket_descriptor, skb,
-						conn->peer_pid, MSG_DONTWAIT);
+				conn->peer_pid, MSG_DONTWAIT);
 		ret = len;
 	} while (0);
 
@@ -198,22 +176,20 @@
 	return ret;
 }
 
-int connection_process(
-	struct connection *conn,
-	struct sk_buff *skb
-)
+int connection_process(struct connection *conn, struct sk_buff *skb)
 {
 	int ret = 0;
 	do {
 		if (mutex_lock_interruptible(&(conn->data_lock))) {
-			MCDRV_DBG_ERROR("Interrupted getting data semaphore!");
+			MCDRV_DBG_ERROR(mc_kapi,
+					"Interrupted getting data semaphore!");
 			ret = -1;
 			break;
 		}
 
 		kfree_skb(conn->skb);
 
-		/* Get a reference to the incomming skb */
+		/* Get a reference to the incoming skb */
 		conn->skb = skb_get(skb);
 		if (conn->skb) {
 			conn->data_msg = nlmsg_hdr(conn->skb);
@@ -226,4 +202,3 @@
 	} while (0);
 	return ret;
 }
-/** @} */
diff --git a/drivers/gud/mobicore_kernelapi/connection.h b/drivers/gud/mobicore_kernelapi/connection.h
index 0b468e6..6c3ff00 100644
--- a/drivers/gud/mobicore_kernelapi/connection.h
+++ b/drivers/gud/mobicore_kernelapi/connection.h
@@ -1,122 +1,58 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
- * @{
- * @file
- *
+/*
  * Connection data.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * 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 CONNECTION_H_
-#define CONNECTION_H_
+#ifndef _MC_KAPI_CONNECTION_H_
+#define _MC_KAPI_CONNECTION_H_
 
 #include <linux/semaphore.h>
+#include <linux/mutex.h>
 
 #include <stddef.h>
 #include <stdbool.h>
 
-#define MAX_PAYLOAD_SIZE 128
-
 struct connection {
-	struct sock *socket_descriptor; /**< Netlink socket */
-	uint32_t sequence_magic; /**< Random? magic to match requests/answers */
+	/* Netlink socket */
+	struct sock		*socket_descriptor;
+	/* Random? magic to match requests/answers */
+	uint32_t		sequence_magic;
 
-	struct nlmsghdr *data_msg;
-	uint32_t data_len; /**< How much connection data is left */
-	void *data_start; /**< Start pointer of remaining data */
-	struct sk_buff *skb;
+	struct nlmsghdr		*data_msg;
+	/* How much connection data is left */
+	uint32_t		data_len;
+	/* Start pointer of remaining data */
+	void			*data_start;
+	struct sk_buff		*skb;
 
-	struct mutex data_lock; /**< Data protection lock */
-	struct semaphore data_available_sem; /**< Data protection semaphore */
+	/* Data protection lock */
+	struct mutex		data_lock;
+	/* Data protection semaphore */
+	struct semaphore	data_available_sem;
 
-	pid_t self_pid; /**< PID address used for local connection */
-	pid_t peer_pid; /**< Remote PID for connection */
+	/* PID address used for local connection */
+	pid_t			self_pid;
+	/* Remote PID for connection */
+	pid_t			peer_pid;
 
-	struct list_head list; /**< The list param for using the kernel lists*/
+	/* The list param for using the kernel lists */
+	struct list_head	list;
 };
 
-struct connection *connection_new(
-	void
-);
+struct connection *connection_new(void);
+struct connection *connection_create(int socket_descriptor, pid_t dest);
+void connection_cleanup(struct connection *conn);
+bool connection_connect(struct connection *conn, pid_t dest);
+size_t connection_read_datablock(struct connection *conn, void *buffer,
+					uint32_t len);
+size_t connection_read_data(struct connection *conn, void *buffer,
+				   uint32_t len, int32_t timeout);
+size_t connection_write_data(struct connection *conn, void *buffer,
+				    uint32_t len);
+int connection_process(struct connection *conn, struct sk_buff *skb);
 
-struct connection *connection_create(
-	int		  socket_descriptor,
-	pid_t		dest
-);
-
-void connection_cleanup(
-	struct connection *conn
-);
-
-/**
-  * Connect to destination.
-  *
-  * @param Destination pointer.
-  * @return true on success.
-  */
-bool connection_connect(
-	struct connection *conn,
-	pid_t		dest
-);
-
-
-/**
-  * Read bytes from the connection.
-  *
-  * @param buffer	Pointer to destination buffer.
-  * @param len	   Number of bytes to read.
-  * @return Number of bytes read.
-  */
-size_t connection_read_datablock(
-	struct connection *conn,
-	void		 *buffer,
-	uint32_t	 len
-);
-/**
-  * Read bytes from the connection.
-  *
-  * @param buffer	Pointer to destination buffer.
-  * @param len	   Number of bytes to read.
-  * @param timeout   Timeout in milliseconds
-  * @return Number of bytes read.
-  * @return -1 if select() failed (returned -1)
-  * @return -2 if no data available, i.e. timeout
-  */
-size_t connection_read_data(
-	struct connection *conn,
-	void		 *buffer,
-	uint32_t	 len,
-	int32_t	  timeout
-);
-
-/**
-  * Write bytes to the connection.
-  *
-  * @param buffer	Pointer to source buffer.
-  * @param len		Number of bytes to read.
-  * @return Number of bytes written.
-  */
-size_t connection_write_data(
-	struct connection *conn,
-	void		 *buffer,
-	uint32_t	  len
-);
-
-/**
- * Write bytes to the connection.
- *
- * @param buffer	Pointer to source buffer.
- * @param len		Number of bytes to read.
- * @return Number of bytes written.
- */
-int connection_process(
-	struct connection *conn,
-	struct sk_buff *skb
-);
-
-#endif /* CONNECTION_H_ */
-
-/** @} */
+#endif /* _MC_KAPI_CONNECTION_H_ */
diff --git a/drivers/gud/mobicore_kernelapi/device.c b/drivers/gud/mobicore_kernelapi/device.c
index dbeee6a..a176322 100644
--- a/drivers/gud/mobicore_kernelapi/device.c
+++ b/drivers/gud/mobicore_kernelapi/device.c
@@ -1,12 +1,9 @@
-/** @addtogroup MCD_IMPL_LIB
- * @{
- * @file
+/*
+ * MobiCore client library device management.
  *
- * Client library device management.
+ * Device and Trustlet Session management Functions.
  *
- * Device and Trustlet Session management Funtions.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * 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
@@ -14,21 +11,19 @@
  */
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <linux/device.h>
 #include "mc_kernel_api.h"
 #include "public/mobicore_driver_api.h"
 
 #include "device.h"
 #include "common.h"
 
-/*----------------------------------------------------------------------------*/
-struct wsm *wsm_create(
-	void	*virt_addr,
-	uint32_t  len,
-	uint32_t  handle,
-	void	*phys_addr /*= NULL this may be unknown, so is can be omitted.*/
-	)
+struct wsm *wsm_create(void *virt_addr, uint32_t len, uint32_t handle,
+		       void *phys_addr)
 {
-	struct wsm *wsm = kzalloc(sizeof(struct wsm), GFP_KERNEL);
+	struct wsm *wsm;
+
+	wsm = kzalloc(sizeof(*wsm), GFP_KERNEL);
 	wsm->virt_addr = virt_addr;
 	wsm->len = len;
 	wsm->handle = handle;
@@ -36,14 +31,12 @@
 	return wsm;
 }
 
+struct mcore_device_t *mcore_device_create(uint32_t device_id,
+					   struct connection *connection)
+{
+	struct mcore_device_t *dev;
 
-/*----------------------------------------------------------------------------*/
-struct mcore_device_t *mcore_device_create(
-	uint32_t  device_id,
-	struct connection  *connection
-) {
-	struct mcore_device_t *dev =
-			kzalloc(sizeof(struct mcore_device_t), GFP_KERNEL);
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	dev->device_id = device_id;
 	dev->connection = connection;
 
@@ -53,17 +46,16 @@
 	return dev;
 }
 
-
-/*----------------------------------------------------------------------------*/
-void mcore_device_cleanup(
-	struct mcore_device_t *dev
-) {
+void mcore_device_cleanup(struct mcore_device_t *dev)
+{
 	struct session *tmp;
 	struct wsm *wsm;
 	struct list_head *pos, *q;
 
-	/* Delete all session objects. Usually this should not be needed
-	 * as closeDevice()requires that all sessions have been closed before.*/
+	/*
+	 * Delete all session objects. Usually this should not be needed
+	 * as close_device() requires that all sessions have been closed before.
+	 */
 	list_for_each_safe(pos, q, &dev->session_vector) {
 		tmp = list_entry(pos, struct session, list);
 		list_del(pos);
@@ -73,7 +65,6 @@
 	/* Free all allocated WSM descriptors */
 	list_for_each_safe(pos, q, &dev->wsm_l2_vector) {
 		wsm = list_entry(pos, struct wsm, list);
-		/* mcKMod_free(dev->instance, wsm->handle); */
 		list_del(pos);
 		kfree(wsm);
 	}
@@ -83,56 +74,41 @@
 	kfree(dev);
 }
 
-
-/*----------------------------------------------------------------------------*/
-bool mcore_device_open(
-	struct mcore_device_t   *dev,
-	const char *deviceName
-) {
+bool mcore_device_open(struct mcore_device_t *dev, const char *deviceName)
+{
 	dev->instance = mobicore_open();
 	return (dev->instance != NULL);
 }
 
-
-/*----------------------------------------------------------------------------*/
-void mcore_device_close(
-	struct mcore_device_t *dev
-) {
+void mcore_device_close(struct mcore_device_t *dev)
+{
 	mobicore_release(dev->instance);
 }
 
-
-/*----------------------------------------------------------------------------*/
-bool mcore_device_has_sessions(
-	struct mcore_device_t *dev
-) {
+bool mcore_device_has_sessions(struct mcore_device_t *dev)
+{
 	return !list_empty(&dev->session_vector);
 }
 
-
-/*----------------------------------------------------------------------------*/
-bool mcore_device_create_new_session(
-	struct mcore_device_t	*dev,
-	uint32_t		session_id,
-	struct connection	*connection
-) {
+bool mcore_device_create_new_session(struct mcore_device_t *dev,
+				     uint32_t session_id,
+				     struct connection *connection)
+{
 	/* Check if session_id already exists */
 	if (mcore_device_resolve_session_id(dev, session_id)) {
-		MCDRV_DBG_ERROR(" session %u already exists", session_id);
+		MCDRV_DBG_ERROR(mc_kapi,
+				" session %u already exists", session_id);
 		return false;
 	}
-	struct session *session = session_create(session_id, dev->instance,
-						connection);
+	struct session *session =
+			session_create(session_id, dev->instance, connection);
 	list_add_tail(&(session->list), &(dev->session_vector));
 	return true;
 }
 
-
-/*----------------------------------------------------------------------------*/
-bool mcore_device_remove_session(
-	struct mcore_device_t *dev,
-	uint32_t session_id
-) {
+bool mcore_device_remove_session(struct mcore_device_t *dev,
+				 uint32_t session_id)
+{
 	bool ret = false;
 	struct session *tmp;
 	struct list_head *pos, *q;
@@ -149,17 +125,13 @@
 	return ret;
 }
 
-
-/*----------------------------------------------------------------------------*/
-struct session *mcore_device_resolve_session_id(
-	struct mcore_device_t *dev,
-	uint32_t session_id
-) {
-	struct session  *ret = NULL;
+struct session *mcore_device_resolve_session_id(struct mcore_device_t *dev,
+						uint32_t session_id)
+{
+	struct session *ret = NULL;
 	struct session *tmp;
 	struct list_head *pos;
 
-
 	/* Get session for session_id */
 	list_for_each(pos, &dev->session_vector) {
 		tmp = list_entry(pos, struct session, list);
@@ -171,26 +143,20 @@
 	return ret;
 }
 
-
-/*----------------------------------------------------------------------------*/
-struct wsm *mcore_device_allocate_contiguous_wsm(
-	struct mcore_device_t *dev,
-	uint32_t len
-) {
+struct wsm *mcore_device_allocate_contiguous_wsm(struct mcore_device_t *dev,
+						 uint32_t len)
+{
 	struct wsm *wsm = NULL;
 	do {
 		if (len == 0)
 			break;
 
 		/* Allocate shared memory */
-		void	*virt_addr;
-		uint32_t  handle;
-		void	*phys_addr;
-		int ret = mobicore_allocate_wsm(dev->instance,
-						len,
-						&handle,
-						&virt_addr,
-						&phys_addr);
+		void *virt_addr;
+		uint32_t handle;
+		void *phys_addr;
+		int ret = mobicore_allocate_wsm(dev->instance, len, &handle,
+						&virt_addr, &phys_addr);
 		if (ret != 0)
 			break;
 
@@ -201,16 +167,12 @@
 
 	} while (0);
 
-	/* Return pointer to the allocated memory */
 	return wsm;
 }
 
-
-/*----------------------------------------------------------------------------*/
-bool mcore_device_free_contiguous_wsm(
-	struct mcore_device_t  *dev,
-	struct wsm   *wsm
-) {
+bool mcore_device_free_contiguous_wsm(struct mcore_device_t *dev,
+				      struct wsm *wsm)
+{
 	bool ret = false;
 	struct wsm *tmp;
 	struct list_head *pos;
@@ -224,11 +186,12 @@
 	}
 
 	if (ret) {
-		MCDRV_DBG_VERBOSE("freeWsm virt_addr=0x%p, handle=%d",
-				wsm->virt_addr, wsm->handle);
+		MCDRV_DBG_VERBOSE(mc_kapi,
+				  "freeWsm virt_addr=0x%p, handle=%d",
+				  wsm->virt_addr, wsm->handle);
 
 		/* ignore return code */
-		mobicore_free(dev->instance, wsm->handle);
+		mobicore_free_wsm(dev->instance, wsm->handle);
 
 		list_del(pos);
 		kfree(wsm);
@@ -236,12 +199,9 @@
 	return ret;
 }
 
-
-/*----------------------------------------------------------------------------*/
-struct wsm *mcore_device_find_contiguous_wsm(
-	struct mcore_device_t *dev,
-	void   *virt_addr
-) {
+struct wsm *mcore_device_find_contiguous_wsm(struct mcore_device_t *dev,
+					     void *virt_addr)
+{
 	struct wsm *wsm;
 	struct list_head *pos;
 
@@ -253,5 +213,3 @@
 
 	return NULL;
 }
-
-/** @} */
diff --git a/drivers/gud/mobicore_kernelapi/device.h b/drivers/gud/mobicore_kernelapi/device.h
index f40d993..16626bd 100644
--- a/drivers/gud/mobicore_kernelapi/device.h
+++ b/drivers/gud/mobicore_kernelapi/device.h
@@ -1,19 +1,16 @@
-/** @addtogroup MCD_IMPL_LIB
- * @{
- * @file
- *
- * Client library device management.
+/*
+ * MobiCore client library device management.
  *
  * Device and Trustlet Session management Functions.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * 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 DEVICE_H_
-#define DEVICE_H_
+#ifndef _MC_KAPI_DEVICE_H_
+#define _MC_KAPI_DEVICE_H_
 
 #include <linux/list.h>
 
@@ -21,119 +18,39 @@
 #include "session.h"
 #include "wsm.h"
 
-
 struct mcore_device_t {
-	struct list_head session_vector; /**< MobiCore Trustlet session
-				associated with the device */
-	struct list_head	 wsm_l2_vector; /**< WSM L2 Table  */
+	/* MobiCore Trustlet session associated with the device */
+	struct list_head	session_vector;
+	struct list_head	 wsm_l2_vector; /* WSM L2 Table  */
 
-	uint32_t		device_id; /**< Device identifier */
-	struct connection	*connection; /**< The device connection */
-	struct mc_instance  *instance; /**< MobiCore Driver instance */
+	uint32_t		device_id;	/* Device identifier */
+	struct connection	*connection;	/* The device connection */
+	struct mc_instance	*instance;	/* MobiCore Driver instance */
 
-	struct list_head list; /**< The list param for using the kernel lists*/
+	/* The list param for using the kernel lists */
+	struct list_head	list;
 };
 
 struct mcore_device_t *mcore_device_create(
-	uint32_t	  device_id,
-	struct connection  *connection
-);
+		uint32_t device_id, struct connection *connection);
+void mcore_device_cleanup(struct mcore_device_t *dev);
 
-void mcore_device_cleanup(
-	struct mcore_device_t *dev
-);
 
-/**
-  * Open the device.
-  * @param deviceName Name of the kernel modules device file.
-  * @return true if the device has been opened successfully
-  */
-bool mcore_device_open(
-	struct mcore_device_t   *dev,
-	const char *deviceName
-);
-
-/**
-  * Closes the device.
-  */
-void mcore_device_close(
-	struct mcore_device_t *dev
-);
-
-/**
-  * Check if the device has open sessions.
-  * @return true if the device has one or more open sessions.
-  */
-bool mcore_device_has_sessions(
-	struct mcore_device_t *dev
-);
-
-/**
-  * Add a session to the device.
-  * @param session_id session ID
-  * @param connection session connection
-  */
+bool mcore_device_open(struct mcore_device_t *dev, const char *deviceName);
+void mcore_device_close(struct mcore_device_t *dev);
+bool mcore_device_has_sessions(struct mcore_device_t *dev);
 bool mcore_device_create_new_session(
-	struct mcore_device_t	  *dev,
-	uint32_t	session_id,
-	struct connection  *connection
-);
-
-/**
-  * Remove the specified session from the device.
-  * The session object will be destroyed and all resources associated with it
-  * will be freed.
-  *
-  * @param session_id Session of the session to remove.
-  * @return true if a session has been found and removed.
-  */
+		struct mcore_device_t *dev, uint32_t session_id,
+		struct connection *connection);
 bool mcore_device_remove_session(
-	struct mcore_device_t *dev,
-	uint32_t session_id
-);
-
-/**
-  * Get as session object for a given session ID.
-  * @param session_id Identified of a previously opened session.
-  * @return Session object if available or NULL if no session has been found.
-  */
+		struct mcore_device_t *dev, uint32_t session_id);
 struct session *mcore_device_resolve_session_id(
-	struct mcore_device_t *dev,
-	uint32_t session_id
-);
-
-/**
-  * Allocate a block of contiguous WSM.
-  * @param len The virtual address to be registered.
-  * @return The virtual address of the allocated memory or NULL if no memory
-  * is available.
-  */
+		struct mcore_device_t *dev, uint32_t session_id);
 struct wsm *mcore_device_allocate_contiguous_wsm(
-	struct mcore_device_t *dev,
-	uint32_t len
-);
-
-/**
-  * Unregister a vaddr from a device.
-  * @param vaddr The virtual address to be registered.
-  * @param paddr The physical address to be registered.
-  */
+		struct mcore_device_t *dev, uint32_t len);
 bool mcore_device_free_contiguous_wsm(
-	struct mcore_device_t  *dev,
-	struct wsm *wsm
-);
-
-/**
-  * Get a WSM object for a given virtual address.
-  * @param vaddr The virtual address which has been allocate with mc_malloc_wsm()
-  * in advance.
-  * @return the WSM object or NULL if no address has been found.
-  */
+		struct mcore_device_t *dev, struct wsm *wsm);
 struct wsm *mcore_device_find_contiguous_wsm(
-	struct mcore_device_t *dev,
-	void   *virt_addr
-);
+		struct mcore_device_t *dev, void *virt_addr);
 
-#endif /* DEVICE_H_ */
-
-/** @} */
+#endif /* _MC_KAPI_DEVICE_H_ */
diff --git a/drivers/gud/mobicore_kernelapi/include/mcinq.h b/drivers/gud/mobicore_kernelapi/include/mcinq.h
index 3cb82be..34216a7 100644
--- a/drivers/gud/mobicore_kernelapi/include/mcinq.h
+++ b/drivers/gud/mobicore_kernelapi/include/mcinq.h
@@ -1,8 +1,8 @@
-/** @addtogroup NQ
- * @{
+/*
  * Notifications inform the MobiCore runtime environment that information is
  * pending in a WSM buffer.
- * The Trustlet Connector (TLC) and the corresponding trustlet also utilize
+ *
+ * The Trustlet Connector (TLC) and the corresponding Trustlet also utilize
  * this buffer to notify each other about new data within the
  * Trustlet Connector Interface (TCI).
  *
@@ -13,13 +13,12 @@
  *
  * Notifications hold the session ID, which is used to reference the
  * communication partner in the other world.
- * So if, e.g., the TLC in the normal world wants to notify his trustlet
+ * So if, e.g., the TLC in the normal world wants to notify his Trustlet
  * about new data in the TLC buffer
  *
- * @file
  * Notification queue declarations.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,81 +44,74 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#ifndef NQ_H_
-#define NQ_H_
+#ifndef _MCINQ_H_
+#define _MCINQ_H_
 
-/** \name NQ Size Defines
- * Minimum and maximum count of elements in the notification queue.
- * @{ */
-#define MIN_NQ_ELEM 1   /**< Minimum notification queue elements. */
-#define MAX_NQ_ELEM 64 /**< Maximum notification queue elements. */
-/** @} */
+/* Minimum and maximum count of elements in the notification queue */
+#define MIN_NQ_ELEM	1	/* Minimum notification queue elements. */
+#define MAX_NQ_ELEM	64	/* Maximum notification queue elements. */
 
-/** \name NQ Length Defines
- * Minimum and maximum notification queue length.
- * @{ */
-/**< Minimum notification length (in bytes). */
-#define MIN_NQ_LEN (MIN_NQ_ELEM * sizeof(notification))
-/**< Maximum notification length (in bytes). */
-#define MAX_NQ_LEN (MAX_NQ_ELEM * sizeof(notification))
-/** @} */
+/* Minimum notification length (in bytes). */
+#define MIN_NQ_LEN	(MIN_NQ_ELEM * sizeof(notification))
 
-/** \name Session ID Defines
- * Standard Session IDs.
- * @{ */
-/**< MCP session ID is used when directly communicating with the MobiCore
- * (e.g. for starting and stopping of trustlets). */
-#define SID_MCP	   0
-/**< Invalid session id is returned in case of an error. */
-#define SID_INVALID   0xffffffff
-/** @} */
+/* Maximum notification length (in bytes). */
+#define MAX_NQ_LEN	(MAX_NQ_ELEM * sizeof(notification))
 
-/** Notification data structure. */
+/*
+ * MCP session ID is used when directly communicating with the MobiCore
+ * (e.g. for starting and stopping of Trustlets).
+ */
+#define SID_MCP		0
+/* Invalid session id is returned in case of an error. */
+#define SID_INVALID	0xffffffff
+
+/* Notification data structure. */
 struct notification {
-	uint32_t session_id; /**< Session ID. */
-	int32_t payload;	/**< Additional notification information. */
+	uint32_t	session_id;	/* Session ID. */
+	int32_t		payload;	/* Additional notification info */
 };
 
-/** Notification payload codes.
+/*
+ * Notification payload codes.
  * 0 indicated a plain simple notification,
  * a positive value is a termination reason from the task,
  * a negative value is a termination reason from MobiCore.
  * Possible negative values are given below.
  */
 enum notification_payload {
-	/**< task terminated, but exit code is invalid */
-	ERR_INVALID_EXIT_CODE   = -1,
-	/**< task terminated due to session end, no exit code available */
-	ERR_SESSION_CLOSE	   = -2,
-	/**< task terminated due to invalid operation */
-	ERR_INVALID_OPERATION   = -3,
-	/**< session ID is unknown */
-	ERR_INVALID_SID		 = -4,
-	/**<  session is not active */
-	ERR_SID_NOT_ACTIVE	  = -5
+	/* task terminated, but exit code is invalid */
+	ERR_INVALID_EXIT_CODE	= -1,
+	/* task terminated due to session end, no exit code available */
+	ERR_SESSION_CLOSE	= -2,
+	/* task terminated due to invalid operation */
+	ERR_INVALID_OPERATION	= -3,
+	/* session ID is unknown */
+	ERR_INVALID_SID		= -4,
+	/*  session is not active */
+	ERR_SID_NOT_ACTIVE	= -5
 };
 
-/** Declaration of the notification queue header.
- * layout as specified in the data structure specification.
+/*
+ * Declaration of the notification queue header.
+ * Layout as specified in the data structure specification.
  */
 struct notification_queue_header {
-	uint32_t write_cnt;  /**< Write counter. */
-	uint32_t read_cnt;   /**< Read counter. */
-	uint32_t queue_size; /**< Queue size. */
+	uint32_t	write_cnt;	/* Write counter. */
+	uint32_t	read_cnt;	/* Read counter. */
+	uint32_t	queue_size;	/* Queue size. */
 };
 
-/** Queue struct which defines a queue object.
+/*
+ * Queue struct which defines a queue object.
  * The queue struct is accessed by the queue<operation> type of
  * function. elementCnt must be a power of two and the power needs
  * to be smaller than power of uint32_t (obviously 32).
  */
 struct notification_queue {
-	/**< Queue header. */
+	/* Queue header. */
 	struct notification_queue_header hdr;
-	/**< Notification elements. */
+	/* Notification elements. */
 	struct notification notification[MIN_NQ_ELEM];
-} ;
+};
 
-#endif /** NQ_H_ */
-
-/** @} */
+#endif /* _MCINQ_H_ */
diff --git a/drivers/gud/mobicore_kernelapi/include/mcuuid.h b/drivers/gud/mobicore_kernelapi/include/mcuuid.h
index b72acb8..6da9437 100644
--- a/drivers/gud/mobicore_kernelapi/include/mcuuid.h
+++ b/drivers/gud/mobicore_kernelapi/include/mcuuid.h
@@ -1,7 +1,5 @@
-/**
- * @addtogroup MC_UUID mcUuid - Universally Unique Identifier.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2011-2012 -->
+/*
+ * <-- Copyright Giesecke & Devrient GmbH 2011-2012 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,21 +25,19 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * @ingroup  MC_DATA_TYPES
- * @{
  */
 
-#ifndef MC_UUID_H_
-#define MC_UUID_H_
+#ifndef _MCUUID_H_
+#define _MCUUID_H_
 
 #define UUID_TYPE
 
-/** Universally Unique Identifier (UUID) according to ISO/IEC 11578. */
+/* Universally Unique Identifier (UUID) according to ISO/IEC 11578. */
 struct mc_uuid_t {
-	uint8_t value[16]; /**< Value of the UUID. */
+	uint8_t		value[16];	/* Value of the UUID. */
 };
 
-/** UUID value used as free marker in service provider containers. */
+/* UUID value used as free marker in service provider containers. */
 #define MC_UUID_FREE_DEFINE \
 	{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
 	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
@@ -50,7 +46,7 @@
 	MC_UUID_FREE_DEFINE
 };
 
-/** Reserved UUID. */
+/* Reserved UUID. */
 #define MC_UUID_RESERVED_DEFINE \
 	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
 	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
@@ -59,7 +55,7 @@
 	MC_UUID_RESERVED_DEFINE
 };
 
-/** UUID for system applications. */
+/* UUID for system applications. */
 #define MC_UUID_SYSTEM_DEFINE \
 	{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
 	  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE }
@@ -68,7 +64,4 @@
 	MC_UUID_SYSTEM_DEFINE
 };
 
-#endif /* MC_UUID_H_ */
-
-/** @} */
-
+#endif /* _MCUUID_H_ */
diff --git a/drivers/gud/mobicore_kernelapi/main.c b/drivers/gud/mobicore_kernelapi/main.c
index 62997f7..8943c26 100644
--- a/drivers/gud/mobicore_kernelapi/main.c
+++ b/drivers/gud/mobicore_kernelapi/main.c
@@ -1,7 +1,7 @@
-/**
+/*
  * MobiCore KernelApi module
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
  *
  * 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
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/netlink.h>
 #include <linux/kthread.h>
+#include <linux/device.h>
 #include <net/sock.h>
 
 #include <linux/list.h>
@@ -29,23 +30,27 @@
 	atomic_t counter;
 };
 
-struct mc_kernelapi_ctx *mod_ctx; /* = NULL; */
+struct mc_kernelapi_ctx *mod_ctx;
 
-/*----------------------------------------------------------------------------*/
+/* Define a MobiCore Kernel API device structure for use with dev_debug() etc */
+struct device_driver mc_kernel_api_name = {
+	.name = "mckernelapi"
+};
+
+struct device mc_kernel_api_subname = {
+	.init_name = "", /* Set to 'mcapi' at mcapi_init() time */
+	.driver = &mc_kernel_api_name
+};
+
+struct device *mc_kapi = &mc_kernel_api_subname;
+
 /* get a unique ID */
-unsigned int mcapi_unique_id(
-	void
-)
+unsigned int mcapi_unique_id(void)
 {
-	return (unsigned int)atomic_inc_return(
-		&(mod_ctx->counter));
+	return (unsigned int)atomic_inc_return(&(mod_ctx->counter));
 }
 
-
-/*----------------------------------------------------------------------------*/
-static struct connection *mcapi_find_connection(
-	uint32_t seq
-)
+static struct connection *mcapi_find_connection(uint32_t seq)
 {
 	struct connection *tmp;
 	struct list_head *pos;
@@ -60,24 +65,21 @@
 	return NULL;
 }
 
-/*----------------------------------------------------------------------------*/
-void mcapi_insert_connection(
-	struct connection *connection
-)
+void mcapi_insert_connection(struct connection *connection)
 {
 	list_add_tail(&(connection->list), &(mod_ctx->peers));
 	connection->socket_descriptor = mod_ctx->sk;
 }
 
-void mcapi_remove_connection(
-	uint32_t seq
-)
+void mcapi_remove_connection(uint32_t seq)
 {
 	struct connection *tmp;
 	struct list_head *pos, *q;
 
-	/* Delete all session objects. Usually this should not be needed as
-	   closeDevice() requires that all sessions have been closed before.*/
+	/*
+	 * Delete all session objects. Usually this should not be needed as
+	 * closeDevice() requires that all sessions have been closed before.
+	 */
 	list_for_each_safe(pos, q, &mod_ctx->peers) {
 		tmp = list_entry(pos, struct connection, list);
 		if (tmp->sequence_magic == seq) {
@@ -87,11 +89,7 @@
 	}
 }
 
-/*----------------------------------------------------------------------------*/
-static int mcapi_process(
-	struct sk_buff *skb,
-	struct nlmsghdr *nlh
-)
+static int mcapi_process(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
 	struct connection *c;
 	int length;
@@ -102,13 +100,14 @@
 	pid = nlh->nlmsg_pid;
 	length = nlh->nlmsg_len;
 	seq = nlh->nlmsg_seq;
-	MCDRV_DBG_VERBOSE("nlmsg len %d type %d pid 0x%X seq %d\n",
-		   length, nlh->nlmsg_type, pid, seq);
+	MCDRV_DBG_VERBOSE(mc_kapi, "nlmsg len %d type %d pid 0x%X seq %d\n",
+			  length, nlh->nlmsg_type, pid, seq);
 	do {
 		c = mcapi_find_connection(seq);
 		if (!c) {
-			MCDRV_ERROR("Invalid incomming connection - seq=%u!",
-				seq);
+			MCDRV_ERROR(mc_kapi,
+				    "Invalid incoming connection - seq=%u!",
+				    seq);
 			ret = -1;
 			break;
 		}
@@ -121,10 +120,7 @@
 	return ret;
 }
 
-/*----------------------------------------------------------------------------*/
-static void mcapi_callback(
-	struct sk_buff *skb
-)
+static void mcapi_callback(struct sk_buff *skb)
 {
 	struct nlmsghdr *nlh = nlmsg_hdr(skb);
 	int len = skb->len;
@@ -141,19 +137,33 @@
 	}
 }
 
-/*----------------------------------------------------------------------------*/
 static int __init mcapi_init(void)
 {
-	printk(KERN_INFO "Mobicore API module initialized!\n");
+#if defined MC_NETLINK_COMPAT || defined MC_NETLINK_COMPAT_V37
+	struct netlink_kernel_cfg cfg = {
+		.input  = mcapi_callback,
+	};
+#endif
+
+	dev_set_name(mc_kapi, "mcapi");
+
+	dev_info(mc_kapi, "Mobicore API module initialized!\n");
 
 	mod_ctx = kzalloc(sizeof(struct mc_kernelapi_ctx), GFP_KERNEL);
-
+#ifdef MC_NETLINK_COMPAT_V37
+	mod_ctx->sk = netlink_kernel_create(&init_net, MC_DAEMON_NETLINK,
+					    &cfg);
+#elif defined MC_NETLINK_COMPAT
+	mod_ctx->sk = netlink_kernel_create(&init_net, MC_DAEMON_NETLINK,
+					    THIS_MODULE, &cfg);
+#else
 	/* start kernel thread */
 	mod_ctx->sk = netlink_kernel_create(&init_net, MC_DAEMON_NETLINK, 0,
-					mcapi_callback, NULL, THIS_MODULE);
+					    mcapi_callback, NULL, THIS_MODULE);
+#endif
 
 	if (!mod_ctx->sk) {
-		MCDRV_ERROR("register of recieve handler failed");
+		MCDRV_ERROR(mc_kapi, "register of receive handler failed");
 		return -EFAULT;
 	}
 
@@ -163,7 +173,7 @@
 
 static void __exit mcapi_exit(void)
 {
-	printk(KERN_INFO "Unloading Mobicore API module.\n");
+	dev_info(mc_kapi, "Unloading Mobicore API module.\n");
 
 	if (mod_ctx->sk != NULL) {
 		netlink_kernel_release(mod_ctx->sk);
diff --git a/drivers/gud/mobicore_kernelapi/public/mobicore_driver_api.h b/drivers/gud/mobicore_kernelapi/public/mobicore_driver_api.h
index ccfb2e5..07a3ae3 100644
--- a/drivers/gud/mobicore_kernelapi/public/mobicore_driver_api.h
+++ b/drivers/gud/mobicore_kernelapi/public/mobicore_driver_api.h
@@ -1,21 +1,10 @@
-/**
- * @defgroup MCD_API					MobiCore Driver API
- * @addtogroup MCD_API
- * @{
- *
- * @if DOXYGEN_MCDRV_API
- *   @mainpage MobiCore Driver API.
- * @endif
- *
+/*
  * MobiCore Driver API.
  *
  * The MobiCore (MC) Driver API provides access functions to the MobiCore
  * runtime environment and the contained Trustlets.
  *
- * @image html DoxyOverviewDrvApi500x.png
- * @image latex DoxyOverviewDrvApi500x.png "MobiCore Overview" width=12cm
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -41,278 +30,272 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#ifndef MCDRIVER_H_
-#define MCDRIVER_H_
+#ifndef _MOBICORE_DRIVER_API_H_
+#define _MOBICORE_DRIVER_API_H_
 
 #define __MC_CLIENT_LIB_API
 
 #include "mcuuid.h"
 
-/**
+/*
  * Return values of MobiCore driver functions.
  */
 enum mc_result {
-	/**< Function call succeeded. */
-	MC_DRV_OK		= 0,
-	/**< No notification available. */
-	MC_DRV_NO_NOTIFICATION	= 1,
-	/**< Error during notification on communication level. */
-	MC_DRV_ERR_NOTIFICATION	= 2,
-	/**< Function not implemented. */
-	MC_DRV_ERR_NOT_IMPLEMENTED = 3,
-	/**< No more resources available. */
-	MC_DRV_ERR_OUT_OF_RESOURCES = 4,
-	/**< Driver initialization failed. */
-	MC_DRV_ERR_INIT = 5,
-	/**< Unknown error. */
-	MC_DRV_ERR_UNKNOWN	= 6,
-	/**< The specified device is unknown. */
-	MC_DRV_ERR_UNKNOWN_DEVICE = 7,
-	/**< The specified session is unknown.*/
-	MC_DRV_ERR_UNKNOWN_SESSION = 8,
-	/**< The specified operation is not allowed. */
-	MC_DRV_ERR_INVALID_OPERATION = 9,
-	/**< The response header from the MC is invalid. */
-	MC_DRV_ERR_INVALID_RESPONSE = 10,
-	/**< Function call timed out. */
-	MC_DRV_ERR_TIMEOUT = 11,
-	/**< Can not allocate additional memory. */
-	MC_DRV_ERR_NO_FREE_MEMORY = 12,
-	/**< Free memory failed. */
-	MC_DRV_ERR_FREE_MEMORY_FAILED = 13,
-	/**< Still some open sessions pending. */
-	MC_DRV_ERR_SESSION_PENDING = 14,
-	/**< MC daemon not reachable */
-	MC_DRV_ERR_DAEMON_UNREACHABLE = 15,
-	/**< The device file of the kernel module could not be opened. */
-	MC_DRV_ERR_INVALID_DEVICE_FILE = 16,
-	/**< Invalid parameter. */
+	/* Function call succeeded. */
+	MC_DRV_OK			= 0,
+	/* No notification available. */
+	MC_DRV_NO_NOTIFICATION		= 1,
+	/* Error during notification on communication level. */
+	MC_DRV_ERR_NOTIFICATION		= 2,
+	/* Function not implemented. */
+	MC_DRV_ERR_NOT_IMPLEMENTED	= 3,
+	/* No more resources available. */
+	MC_DRV_ERR_OUT_OF_RESOURCES	= 4,
+	/* Driver initialization failed. */
+	MC_DRV_ERR_INIT			= 5,
+	/* Unknown error. */
+	MC_DRV_ERR_UNKNOWN		= 6,
+	/* The specified device is unknown. */
+	MC_DRV_ERR_UNKNOWN_DEVICE	= 7,
+	/* The specified session is unknown.*/
+	MC_DRV_ERR_UNKNOWN_SESSION	= 8,
+	/* The specified operation is not allowed. */
+	MC_DRV_ERR_INVALID_OPERATION	= 9,
+	/* The response header from the MC is invalid. */
+	MC_DRV_ERR_INVALID_RESPONSE	= 10,
+	/* Function call timed out. */
+	MC_DRV_ERR_TIMEOUT		= 11,
+	/* Can not allocate additional memory. */
+	MC_DRV_ERR_NO_FREE_MEMORY	= 12,
+	/* Free memory failed. */
+	MC_DRV_ERR_FREE_MEMORY_FAILED	= 13,
+	/* Still some open sessions pending. */
+	MC_DRV_ERR_SESSION_PENDING	= 14,
+	/* MC daemon not reachable */
+	MC_DRV_ERR_DAEMON_UNREACHABLE	= 15,
+	/* The device file of the kernel module could not be opened. */
+	MC_DRV_ERR_INVALID_DEVICE_FILE	= 16,
+	/* Invalid parameter. */
 	MC_DRV_ERR_INVALID_PARAMETER	= 17,
-	/**< Unspecified error from Kernel Module*/
-	MC_DRV_ERR_KERNEL_MODULE = 18,
-	/**< Error during mapping of additional bulk memory to session. */
-	MC_DRV_ERR_BULK_MAPPING = 19,
-	/**< Error during unmapping of additional bulk memory to session. */
-	MC_DRV_ERR_BULK_UNMAPPING = 20,
-	/**< Notification received, exit code available. */
-	MC_DRV_INFO_NOTIFICATION = 21,
-	/**< Set up of NWd connection failed. */
-	MC_DRV_ERR_NQ_FAILED = 22
+	/* Unspecified error from Kernel Module*/
+	MC_DRV_ERR_KERNEL_MODULE	= 18,
+	/* Error during mapping of additional bulk memory to session. */
+	MC_DRV_ERR_BULK_MAPPING		= 19,
+	/* Error during unmapping of additional bulk memory to session. */
+	MC_DRV_ERR_BULK_UNMAPPING	= 20,
+	/* Notification received, exit code available. */
+	MC_DRV_INFO_NOTIFICATION	= 21,
+	/* Set up of NWd connection failed. */
+	MC_DRV_ERR_NQ_FAILED		= 22
 };
 
-
-/**
+/*
  * Driver control command.
  */
 enum mc_driver_ctrl {
-	MC_CTRL_GET_VERSION = 1 /**< Return the driver version */
+	/* Return the driver version */
+	MC_CTRL_GET_VERSION		= 1
 };
 
-
-/** Structure of Session Handle, includes the Session ID and the Device ID the
+/*
+ * Structure of Session Handle, includes the Session ID and the Device ID the
  * Session belongs to.
  * The session handle will be used for session-based MobiCore communication.
  * It will be passed to calls which address a communication end point in the
  * MobiCore environment.
  */
 struct mc_session_handle {
-	uint32_t session_id; /**< MobiCore session ID */
-	uint32_t device_id; /**< Device ID the session belongs to */
+	uint32_t session_id;		/* MobiCore session ID */
+	uint32_t device_id;		/* Device ID the session belongs to */
 };
 
-/** Information structure about additional mapped Bulk buffer between the
- * Trustlet Connector (Nwd) and the Trustlet (Swd). This structure is
+/*
+ * Information structure about additional mapped Bulk buffer between the
+ * Trustlet Connector (NWd) and the Trustlet (SWd). This structure is
  * initialized from a Trustlet Connector by calling mc_map().
  * In order to use the memory within a Trustlet the Trustlet Connector has to
  * inform the Trustlet with the content of this structure via the TCI.
  */
 struct mc_bulk_map {
-	/**< The virtual address of the Bulk buffer regarding the address space
+	/* The virtual address of the Bulk buffer regarding the address space
 	 * of the Trustlet, already includes a possible offset! */
 	void *secure_virt_addr;
-	uint32_t secure_virt_len; /**< Length of the mapped Bulk buffer */
+	uint32_t secure_virt_len;	/* Length of the mapped Bulk buffer */
 };
 
-
-/**< The default device ID */
+/* The default device ID */
 #define MC_DEVICE_ID_DEFAULT	0
-/**< Wait infinite for a response of the MC. */
+/* Wait infinite for a response of the MC. */
 #define MC_INFINITE_TIMEOUT	((int32_t)(-1))
-/**< Do not wait for a response of the MC. */
+/* Do not wait for a response of the MC. */
 #define MC_NO_TIMEOUT		0
-/**< TCI/DCI must not exceed 1MiB */
+/* TCI/DCI must not exceed 1MiB */
 #define MC_MAX_TCI_LEN		0x100000
 
-
-
-/** Open a new connection to a MobiCore device.
+/**
+ * mc_open_device() - Open a new connection to a MobiCore device.
+ * @device_id:		Identifier for the MobiCore device to be used.
+ *			MC_DEVICE_ID_DEFAULT refers to the default device.
  *
- * mc_open_device() initializes all device specific resources required to
- * communicate with an MobiCore instance located on the specified device in the
- * system. If the device does not exist the function will return
- * MC_DRV_ERR_UNKNOWN_DEVICE.
+ * Initializes all device specific resources required to communicate with a
+ * MobiCore instance located on the specified device in the system. If the
+ * device does not exist the function will return MC_DRV_ERR_UNKNOWN_DEVICE.
  *
- * @param [in] device_id Identifier for the MobiCore device to be used.
- * MC_DEVICE_ID_DEFAULT refers to the default device.
- *
- * @return MC_DRV_OK if operation has been successfully completed.
- * @return MC_DRV_ERR_INVALID_OPERATION if device already opened.
- * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when device_id is unknown.
- * @return MC_DRV_ERR_INVALID_DEVICE_FILE if kernel module under
- * /dev/mobicore cannot be opened
- *
- * Uses a Mutex.
+ * Return codes:
+ *	MC_DRV_OK:			operation completed successfully
+ *	MC_DRV_ERR_INVALID_OPERATION:	device already opened
+ *	MC_DRV_ERR_DAEMON_UNREACHABLE:	problems with daemon
+ *	MC_DRV_ERR_UNKNOWN_DEVICE:	device_id unknown
+ *	MC_DRV_ERR_INVALID_DEVICE_FILE:	kernel module under /dev/mobicore
+ *					cannot be opened
  */
-__MC_CLIENT_LIB_API enum mc_result mc_open_device(
-	uint32_t device_id
-);
+__MC_CLIENT_LIB_API enum mc_result mc_open_device(uint32_t device_id);
 
-/** Close the connection to a MobiCore device.
+/**
+ * mc_close_device() - Close the connection to a MobiCore device.
+ * @device_id:		Identifier for the MobiCore device.
+ *
  * When closing a device, active sessions have to be closed beforehand.
  * Resources associated with the device will be released.
  * The device may be opened again after it has been closed.
  *
- * @param [in] device_id Identifier for the MobiCore device.
  * MC_DEVICE_ID_DEFAULT refers to the default device.
  *
- * @return MC_DRV_OK if operation has been successfully completed.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
- * @return MC_DRV_ERR_SESSION_PENDING when a session is still open.
- * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
- *
- * Uses a Mutex.
+ * Return codes:
+ *	MC_DRV_OK:			operation completed successfully
+ *	MC_DRV_ERR_UNKNOWN_DEVICE:	device id is invalid
+ *	MC_DRV_ERR_SESSION_PENDING:	a session is still open
+ *	MC_DRV_ERR_DAEMON_UNREACHABLE:	problems with daemon occur
  */
-__MC_CLIENT_LIB_API enum mc_result mc_close_device(
-	uint32_t device_id
-);
+__MC_CLIENT_LIB_API enum mc_result mc_close_device(uint32_t device_id);
 
-/** Open a new session to a Trustlet. The trustlet with the given UUID has
- * to be available in the flash filesystem.
+/**
+ * mc_open_session() - Open a new session to a Trustlet.
+ * @session:		On success, the session data will be returned
+ * @uuid:		UUID of the Trustlet to be opened
+ * @tci:		TCI buffer for communicating with the Trustlet
+ * @tci_len:		Length of the TCI buffer. Maximum allowed value
+ *			is MC_MAX_TCI_LEN
+ *
+ * The Trustlet with the given UUID has to be available in the flash filesystem.
  *
  * Write MCP open message to buffer and notify MobiCore about the availability
  * of a new command.
+ *
  * Waits till the MobiCore responses with the new session ID (stored in the MCP
  * buffer).
  *
- * @param [in,out] session On success, the session data will be returned.
  * Note that session.device_id has to be the device id of an opened device.
- * @param [in] uuid UUID of the Trustlet to be opened.
- * @param [in] tci TCI buffer for communicating with the trustlet.
- * @param [in] tci_len Length of the TCI buffer. Maximum allowed value
- * is MC_MAX_TCI_LEN.
  *
- * @return MC_DRV_OK if operation has been successfully completed.
- * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
- * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon socket occur.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when daemon returns an error.
- *
- * Uses a Mutex.
+ * Return codes:
+ *	MC_DRV_OK:			operation completed successfully
+ *	MC_DRV_INVALID_PARAMETER:	session parameter is invalid
+ *	MC_DRV_ERR_UNKNOWN_DEVICE:	device id is invalid
+ *	MC_DRV_ERR_DAEMON_UNREACHABLE:	problems with daemon socket occur
+ *	MC_DRV_ERR_NQ_FAILED:		daemon returns an error
  */
 __MC_CLIENT_LIB_API enum mc_result mc_open_session(
-	struct mc_session_handle  *session,
-	const struct mc_uuid_t *uuid,
-	uint8_t *tci,
-	uint32_t tci_len
-);
+	struct mc_session_handle *session, const struct mc_uuid_t *uuid,
+	uint8_t *tci, uint32_t tci_len);
 
-/** Close a Trustlet session.
+/**
+ * mc_close_session() - Close a Trustlet session.
+ * @session:		Session to be closed.
  *
  * Closes the specified MobiCore session. The call will block until the
  * session has been closed.
  *
- * @pre Device device_id has to be opened in advance.
+ * Device device_id has to be opened in advance.
  *
- * @param [in] session Session to be closed.
- *
- * @return MC_DRV_OK if operation has been successfully completed.
- * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.
- * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
- * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
- * @return MC_DRV_ERR_INVALID_DEVICE_FILE when daemon cannot open trustlet file.
- *
- * Uses a Mutex.
+ * Return codes:
+ *	MC_DRV_OK:			operation completed successfully
+ *	MC_DRV_INVALID_PARAMETER:	session parameter is invalid
+ *	MC_DRV_ERR_UNKNOWN_SESSION:	session id is invalid
+ *	MC_DRV_ERR_UNKNOWN_DEVICE:	device id of session is invalid
+ *	MC_DRV_ERR_DAEMON_UNREACHABLE:	problems with daemon occur
+ *	MC_DRV_ERR_INVALID_DEVICE_FILE:	daemon cannot open Trustlet file
  */
 __MC_CLIENT_LIB_API enum mc_result mc_close_session(
-	struct mc_session_handle *session
-);
+	struct mc_session_handle *session);
 
-/** Notify a session.
+/**
+ * mc_notify() - Notify a session.
+ * @session:		The session to be notified.
+ *
  * Notifies the session end point about available message data.
  * If the session parameter is correct, notify will always succeed.
  * Corresponding errors can only be received by mc_wait_notification().
- * @pre A session has to be opened in advance.
  *
- * @param session The session to be notified.
+ * A session has to be opened in advance.
  *
- * @return MC_DRV_OK if operation has been successfully completed.
- * @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.
- * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
+ * Return codes:
+ *	MC_DRV_OK:			operation completed successfully
+ *	MC_DRV_INVALID_PARAMETER:	session parameter is invalid
+ *	MC_DRV_ERR_UNKNOWN_SESSION:	session id is invalid
+ *	MC_DRV_ERR_UNKNOWN_DEVICE:	device id of session is invalid
  */
-__MC_CLIENT_LIB_API enum mc_result mc_notify(
-	struct mc_session_handle *session
-);
+__MC_CLIENT_LIB_API enum mc_result mc_notify(struct mc_session_handle *session);
 
-/** Wait for a notification.
+/**
+ * mc_wait_notification() - Wait for a notification.
+ * @session:		The session the notification should correspond to.
+ * @timeout:		Time in milliseconds to wait
+ *			(MC_NO_TIMEOUT : direct return, > 0 : milliseconds,
+ *			 MC_INFINITE_TIMEOUT : wait infinitely)
  *
  * Wait for a notification issued by the MobiCore for a specific session.
  * The timeout parameter specifies the number of milliseconds the call will wait
  * for a notification.
+ *
  * If the caller passes 0 as timeout value the call will immediately return.
  * If timeout value is below 0 the call will block until a notification for the
- session has been received.
+ * session has been received.
  *
- * @attention if timeout is below 0, call will block:
+ * If timeout is below 0, call will block.
+ *
  * Caller has to trust the other side to send a notification to wake him up
  * again.
  *
- * @param [in] session The session the notification should correspond to.
- * @param [in] timeout Time in milliseconds to wait
- * (MC_NO_TIMEOUT : direct return, > 0 : milliseconds,
- * MC_INFINITE_TIMEOUT : wait infinitely)
- *
- * @return MC_DRV_OK if notification is available.
- * @return MC_DRV_ERR_TIMEOUT if no notification arrived in time.
- * @return MC_DRV_INFO_NOTIFICATION if a problem with the session was
- * encountered. Get more details with mc_get_session_error_code().
- * @return MC_DRV_ERR_NOTIFICATION if a problem with the socket occurred.
- * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
- * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
+ * Return codes:
+ *	MC_DRV_OK:			operation completed successfully
+ *	MC_DRV_ERR_TIMEOUT:		no notification arrived in time
+ *	MC_DRV_INFO_NOTIFICATION:	a problem with the session was
+ *					encountered. Get more details with
+ *					mc_get_session_error_code()
+ *	MC_DRV_ERR_NOTIFICATION:	a problem with the socket occurred
+ *	MC_DRV_INVALID_PARAMETER:	a parameter is invalid
+ *	MC_DRV_ERR_UNKNOWN_SESSION:	session id is invalid
+ *	MC_DRV_ERR_UNKNOWN_DEVICE:	device id of session is invalid
  */
 __MC_CLIENT_LIB_API enum mc_result mc_wait_notification(
-	struct mc_session_handle  *session,
-	int32_t			timeout
-);
+	struct mc_session_handle *session, int32_t timeout);
 
 /**
- * Allocate a block of world shared memory (WSM).
+ * mc_malloc_wsm() - Allocate a block of world shared memory (WSM).
+ * @device_id:		The ID of an opened device to retrieve the WSM from.
+ * @align:		The alignment (number of pages) of the memory block
+ *			(e.g. 0x00000001 for 4kb).
+ * @len:		Length of the block in bytes.
+ * @wsm:		Virtual address of the world shared memory block.
+ * @wsm_flags:		Platform specific flags describing the memory to
+ *			be allocated.
+ *
  * The MC driver allocates a contiguous block of memory which can be used as
  * WSM.
  * This implicates that the allocated memory is aligned according to the
  * alignment parameter.
+ *
  * Always returns a buffer of size WSM_SIZE aligned to 4K.
  *
- * @param [in]  device_id The ID of an opened device to retrieve the WSM from.
- * @param [in]  align The alignment (number of pages) of the memory block
- * (e.g. 0x00000001 for 4kb).
- * @param [in]  len	Length of the block in bytes.
- * @param [out] wsm Virtual address of the world shared memory block.
- * @param [in]  wsm_flags Platform specific flags describing the memory to
- * be allocated.
+ * Align and wsm_flags are currently ignored
  *
- * @attention: align and wsm_flags are currently ignored
- *
- * @return MC_DRV_OK if operation has been successfully completed.
- * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
- * @return MC_DRV_ERR_NO_FREE_MEMORY if no more contiguous memory is available
- * in this size or for this process.
- *
- * Uses a Mutex.
+ * Return codes:
+ *	MC_DRV_OK:			operation completed successfully
+ *	MC_DRV_INVALID_PARAMETER:	a parameter is invalid
+ *	MC_DRV_ERR_UNKNOWN_DEVICE:	device id is invalid
+ *	MC_DRV_ERR_NO_FREE_MEMORY:	no more contiguous memory is
+ *					available in this size or for this
+ *					process
  */
 __MC_CLIENT_LIB_API enum mc_result mc_malloc_wsm(
 	uint32_t  device_id,
@@ -323,161 +306,140 @@
 );
 
 /**
- * Free a block of world shared memory (WSM).
+ * mc_free_wsm() - Free a block of world shared memory (WSM).
+ * @device_id:		The ID to which the given address belongs
+ * @wsm:		Address of WSM block to be freed
+ *
  * The MC driver will free a block of world shared memory (WSM) previously
  * allocated with mc_malloc_wsm(). The caller has to assure that the address
  * handed over to the driver is a valid WSM address.
  *
- * @param [in] device_id The ID to which the given address belongs.
- * @param [in] wsm Address of WSM block to be freed.
- *
- * @return MC_DRV_OK if operation has been successfully completed.
- * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
- * @return MC_DRV_ERR_FREE_MEMORY_FAILED on failures.
- *
- * Uses a Mutex.
+ * Return codes:
+ *	MC_DRV_OK:			operation completed successfully
+ *	MC_DRV_INVALID_PARAMETER:	a parameter is invalid
+ *	MC_DRV_ERR_UNKNOWN_DEVICE:	when device id is invalid
+ *	MC_DRV_ERR_FREE_MEMORY_FAILED:	on failure
  */
-__MC_CLIENT_LIB_API enum mc_result mc_free_wsm(
-	uint32_t  device_id,
-	uint8_t   *wsm
-);
+__MC_CLIENT_LIB_API enum mc_result mc_free_wsm(uint32_t device_id,
+					       uint8_t *wsm);
 
 /**
- * Map additional bulk buffer between a Trustlet Connector (TLC) and
- * the Trustlet (TL) for a session.
+ *mc_map() -	Map additional bulk buffer between a Trustlet Connector (TLC)
+ *		and the Trustlet (TL) for a session
+ * @session:		Session handle with information of the device_id and
+ *			the session_id. The given buffer is mapped to the
+ *			session specified in the sessionHandle
+ * @buf:		Virtual address of a memory portion (relative to TLC)
+ *			to be shared with the Trustlet, already includes a
+ *			possible offset!
+ * @len:		length of buffer block in bytes.
+ * @map_info:		Information structure about the mapped Bulk buffer
+ *			between the TLC (NWd) and the TL (SWd).
+ *
  * Memory allocated in user space of the TLC can be mapped as additional
  * communication channel (besides TCI) to the Trustlet. Limitation of the
  * Trustlet memory structure apply: only 6 chunks can be mapped with a maximum
  * chunk size of 1 MiB each.
  *
- * @attention It is up to the application layer (TLC) to inform the Trustlet
+ * It is up to the application layer (TLC) to inform the Trustlet
  * about the additional mapped bulk memory.
  *
- * @param [in] session Session handle with information of the device_id and
- * the session_id. The
- * given buffer is mapped to the session specified in the sessionHandle.
- * @param [in] buf Virtual address of a memory portion (relative to TLC)
- * to be shared with the Trustlet, already includes a possible offset!
- * @param [in] len length of buffer block in bytes.
- * @param [out] map_info Information structure about the mapped Bulk buffer
- * between the TLC (Nwd) and
- * the TL (Swd).
- *
- * @return MC_DRV_OK if operation has been successfully completed.
- * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
- * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
- * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
- * @return MC_DRV_ERR_BULK_MAPPING when buf is already uses as bulk buffer or
- * when registering the buffer failed.
- *
- * Uses a Mutex.
+ * Return codes:
+ *	MC_DRV_OK:			operation completed successfully
+ *	MC_DRV_INVALID_PARAMETER:	a parameter is invalid
+ *	MC_DRV_ERR_UNKNOWN_SESSION:	session id is invalid
+ *	MC_DRV_ERR_UNKNOWN_DEVICE:	device id of session is invalid
+ *	MC_DRV_ERR_DAEMON_UNREACHABLE:	problems with daemon occur
+ *	MC_DRV_ERR_BULK_MAPPING:	buf is already uses as bulk buffer or
+ *					when registering the buffer failed
  */
 __MC_CLIENT_LIB_API enum mc_result mc_map(
-	struct mc_session_handle	*session,
-	void				*buf,
-	uint32_t			len,
-	struct mc_bulk_map		*map_info
-);
+	struct mc_session_handle *session, void	*buf, uint32_t len,
+	struct mc_bulk_map *map_info);
 
 /**
- * Remove additional mapped bulk buffer between Trustlet Connector (TLC)
- * and the Trustlet (TL) for a session.
+ * mc_unmap() -	Remove additional mapped bulk buffer between Trustlet Connector
+ *		(TLC) and the Trustlet (TL) for a session
+ * @session:		Session handle with information of the device_id and
+ *			the session_id. The given buffer is unmapped from the
+ *			session specified in the sessionHandle.
+ * @buf:		Virtual address of a memory portion (relative to TLC)
+ *			shared with the TL, already includes a possible offset!
+ * @map_info:		Information structure about the mapped Bulk buffer
+ *			between the TLC (NWd) and the TL (SWd)
  *
- * @attention The bulk buffer will immediately be unmapped from the session
- * context.
- * @attention The application layer (TLC) must inform the TL about unmapping
- * of the additional bulk memory before calling mc_unmap!
+ * The bulk buffer will immediately be unmapped from the session context.
  *
- * @param [in] session Session handle with information of the device_id and
- * the session_id. The given buffer is unmapped from the session specified
- * in the sessionHandle.
- * @param [in] buf Virtual address of a memory portion (relative to TLC)
- * shared with the TL, already includes a possible offset!
- * @param [in] map_info Information structure about the mapped Bulk buffer
- * between the TLC (Nwd) and
- * the TL (Swd).
- * @attention The clientlib currently ignores the len field in map_info.
+ * The application layer (TLC) must inform the TL about unmapping of the
+ * additional bulk memory before calling mc_unmap!
  *
- * @return MC_DRV_OK if operation has been successfully completed.
- * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
- * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
- * @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
- * @return MC_DRV_ERR_BULK_UNMAPPING when buf was not registered earlier
- * or when unregistering failed.
+ * The clientlib currently ignores the len field in map_info.
  *
- * Uses a Mutex.
+ * Return codes:
+ *	MC_DRV_OK:			operation completed successfully
+ *	MC_DRV_INVALID_PARAMETER:	a parameter is invalid
+ *	MC_DRV_ERR_UNKNOWN_SESSION:	session id is invalid
+ *	MC_DRV_ERR_UNKNOWN_DEVICE:	device id of session is invalid
+ *	MC_DRV_ERR_DAEMON_UNREACHABLE:	problems with daemon occur
+ *	MC_DRV_ERR_BULK_UNMAPPING:	buf was not registered earlier
+ *					or when unregistering failed
  */
 __MC_CLIENT_LIB_API enum mc_result mc_unmap(
-	struct mc_session_handle	*session,
-	void				*buf,
-	struct mc_bulk_map		*map_info
-);
-
+	struct mc_session_handle *session, void *buf,
+	struct mc_bulk_map *map_info);
 
 /**
- * @attention: Not implemented.
- * Execute driver specific command.
- * mc_driver_ctrl() can be used to execute driver specific commands.
- * Besides the control command MC_CTRL_GET_VERSION commands are implementation
- * specific.
+ * mc_driver_ctrl() - Execute driver specific command.
+ * @param:		Command ID of the command to be executed
+ * @data:		Command data and response depending on command
+ * @len:		Length of the data block
+ *
+ * Can be used to execute driver specific commands. Besides the control command
+ * MC_CTRL_GET_VERSION commands are implementation specific.
+ *
  * Please refer to the corresponding specification of the driver manufacturer.
  *
- * @param [in] param Command ID of the command to be executed.
- * @param [in, out] data  Command data and response depending on command.
- * @param [in] len Length of the data block.
- *
- * @return MC_DRV_ERR_NOT_IMPLEMENTED.
+ * Return codes:
+ *	MC_DRV_ERR_NOT_IMPLEMENTED.
  */
 __MC_CLIENT_LIB_API enum mc_result mc_driver_ctrl(
-	enum mc_driver_ctrl  param,
-	uint8_t		 *data,
-	uint32_t	len
-);
+	enum mc_driver_ctrl param, uint8_t *data, uint32_t len);
 
 /**
- * @attention: Not implemented.
- * Execute application management command.
- * mc_manage() shall be used to exchange application management commands with
- * the MobiCore.
+ * mc_manage() - Execute application management command.
+ * @device_id:		Identifier for the MobiCore device to be used.
+ *			NULL refers to the default device.
+ * @data:		Command data/response data depending on command
+ * @len:		Length of the data block
+ *
+ * Shall be used to exchange application management commands with the MobiCore.
  * The MobiCore Application Management Protocol is described in [MCAMP].
  *
- * @param [in] device_id Identifier for the MobiCore device to be used.
- * NULL refers to the default device.
- * @param [in, out] data  Command data/response data depending on command.
- * @param [in] len Length of the data block.
- *
- * @return MC_DRV_ERR_NOT_IMPLEMENTED.
+ * Return codes:
+ *	MC_DRV_ERR_NOT_IMPLEMENTED.
  */
 __MC_CLIENT_LIB_API enum mc_result mc_manage(
-	uint32_t  device_id,
-	uint8_t   *data,
-	uint32_t  len
-);
+	uint32_t device_id, uint8_t *data, uint32_t len);
 
 /**
- * Get additional error information of the last error that occured on a session.
+ * mc_get_session_error_code() - Get additional error information of the last
+ *				 error that occurred on a session.
+ * @session:		Session handle with information of the device_id and
+ *			the session_id
+ * @last_error:		>0 Trustlet has terminated itself with this value,
+ *			<0 Trustlet is dead because of an error within the
+ *			MobiCore (e.g. Kernel exception). See also MCI
+ *			definition.
+ *
  * After the request the stored error code will be deleted.
  *
- * @param [in] session Session handle with information of the device_id and
- * the session_id.
- * @param [out] last_error >0 Trustlet has terminated itself with this value,
- * <0 Trustlet is dead because of an error within the MobiCore
- * (e.g. Kernel exception).
- * See also MCI definition.
- *
- * @return MC_DRV_OK if operation has been successfully completed.
- * @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
- * @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
- * @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
+ * Return codes:
+ *	MC_DRV_OK:			operation completed successfully
+ *	MC_DRV_INVALID_PARAMETER:	a parameter is invalid
+ *	MC_DRV_ERR_UNKNOWN_SESSION:	session id is invalid
+ *	MC_DRV_ERR_UNKNOWN_DEVICE:	device id of session is invalid
  */
 __MC_CLIENT_LIB_API enum mc_result mc_get_session_error_code(
-	struct mc_session_handle  *session,
-	int32_t			*last_error
-);
+	struct mc_session_handle *session, int32_t *last_error);
 
-#endif /** MCDRIVER_H_ */
-
-/** @} */
+#endif /* _MOBICORE_DRIVER_API_H_ */
diff --git a/drivers/gud/mobicore_kernelapi/public/mobicore_driver_cmd.h b/drivers/gud/mobicore_kernelapi/public/mobicore_driver_cmd.h
index 9ff7989..3b8eb4b 100644
--- a/drivers/gud/mobicore_kernelapi/public/mobicore_driver_cmd.h
+++ b/drivers/gud/mobicore_kernelapi/public/mobicore_driver_cmd.h
@@ -1,8 +1,5 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON
- * @{
- * @file
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+/*
+ * <-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,11 +25,8 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#ifndef MCDAEMON_H_
-#define MCDAEMON_H_
-
-
-
+#ifndef _MOBICORE_DRIVER_CMD_H_
+#define _MOBICORE_DRIVER_CMD_H_
 
 #include "mcuuid.h"
 
@@ -64,19 +58,17 @@
 
 
 struct mc_drv_command_header_t {
-	uint32_t  command_id;
+	uint32_t command_id;
 };
 
 struct mc_drv_response_header_t {
-	uint32_t  response_id;
+	uint32_t response_id;
 };
 
-#define MC_DEVICE_ID_DEFAULT	0 /**< The default device ID */
+#define MC_DEVICE_ID_DEFAULT	0		/* The default device ID */
 
-
-/*****************************************************************************/
 struct mc_drv_cmd_open_device_payload_t {
-	uint32_t  device_id;
+	uint32_t device_id;
 };
 
 struct mc_drv_cmd_open_device_t {
@@ -94,13 +86,13 @@
 	struct mc_drv_rsp_open_device_payload_t payload;
 };
 
-
-/*****************************************************************************/
 struct mc_drv_cmd_close_device_t {
 	struct mc_drv_command_header_t header;
-	/* no payload here because close has none.
-	   If we use an empty struct, C++ will count it as 4 bytes.
-	   This will write too much into the socket at write(cmd,sizeof(cmd)) */
+	/*
+	 * no payload here because close has none.
+	 * If we use an empty struct, C++ will count it as 4 bytes.
+	 * This will write too much into the socket at write(cmd,sizeof(cmd))
+	 */
 };
 
 
@@ -113,8 +105,6 @@
 	struct mc_drv_rsp_close_device_payload_t payload;
 };
 
-
-/*****************************************************************************/
 struct mc_drv_cmd_open_session_payload_t {
 	uint32_t device_id;
 	struct mc_uuid_t uuid;
@@ -141,8 +131,6 @@
 	struct mc_drv_rsp_open_session_payload_t  payload;
 };
 
-
-/*****************************************************************************/
 struct mc_drv_cmd_close_session_payload_t {
 	uint32_t  session_id;
 };
@@ -162,8 +150,6 @@
 	struct mc_drv_rsp_close_session_payload_t payload;
 };
 
-
-/*****************************************************************************/
 struct mc_drv_cmd_notify_payload_t {
 	uint32_t session_id;
 };
@@ -183,10 +169,9 @@
 	struct mc_drv_rsp_notify_payload_t  payload;
 };
 
-
-/*****************************************************************************/
 struct mc_drv_cmd_map_bulk_mem_payload_t {
 	uint32_t session_id;
+	uint32_t handle;
 	uint32_t phys_addr_l2;
 	uint32_t offset_payload;
 	uint32_t len_bulk_mem;
@@ -209,10 +194,9 @@
 	struct mc_drv_rsp_map_bulk_mem_payload_t  payload;
 };
 
-
-/*****************************************************************************/
 struct mc_drv_cmd_unmap_bulk_mem_payload_t {
 	uint32_t session_id;
+	uint32_t handle;
 	uint32_t secure_virtual_adr;
 	uint32_t len_bulk_mem;
 };
@@ -234,8 +218,6 @@
 	struct mc_drv_rsp_unmap_bulk_mem_payload_t payload;
 };
 
-
-/*****************************************************************************/
 struct mc_drv_cmd_nqconnect_payload_t {
 	uint32_t device_id;
 	uint32_t session_id;
@@ -258,8 +240,6 @@
 	struct mc_drv_rsp_nqconnect_payload_t payload;
 };
 
-
-/*****************************************************************************/
 union mc_drv_command_t {
 	struct mc_drv_command_header_t		header;
 	struct mc_drv_cmd_open_device_t		mc_drv_cmd_open_device;
@@ -284,6 +264,4 @@
 	struct mc_drv_rsp_unmap_bulk_mem_t	mc_drv_rsp_unmap_bulk_mem;
 };
 
-#endif /* MCDAEMON_H_ */
-
-/** @} */
+#endif /* _MOBICORE_DRIVER_CMD_H_ */
diff --git a/drivers/gud/mobicore_kernelapi/session.c b/drivers/gud/mobicore_kernelapi/session.c
index e62b4b3..dae2c00 100644
--- a/drivers/gud/mobicore_kernelapi/session.c
+++ b/drivers/gud/mobicore_kernelapi/session.c
@@ -1,7 +1,5 @@
-/** @addtogroup MCD_IMPL_LIB
- * @{
- * @file
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+/*
+ * <-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -9,39 +7,35 @@
  */
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/device.h>
 #include "mc_kernel_api.h"
 #include "public/mobicore_driver_api.h"
 
 #include "session.h"
 
-/*****************************************************************************/
 struct bulk_buffer_descriptor *bulk_buffer_descriptor_create(
-	void		*virt_addr,
-	uint32_t	len,
-	uint32_t	handle,
-	void		*phys_addr_wsm_l2
-) {
-	struct bulk_buffer_descriptor *desc =
-		kzalloc(sizeof(struct bulk_buffer_descriptor), GFP_KERNEL);
+	void *virt_addr, uint32_t len, uint32_t handle, void *phys_addr_wsm_l2)
+{
+	struct bulk_buffer_descriptor *desc;
+
+	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
 	desc->virt_addr = virt_addr;
 	desc->len = len;
 	desc->handle = handle;
 	desc->phys_addr_wsm_l2 = phys_addr_wsm_l2;
+
 	return desc;
 }
 
-/*****************************************************************************/
 struct session *session_create(
-	uint32_t	session_id,
-	void		*instance,
-	struct connection *connection
-) {
-	struct session *session =
-			kzalloc(sizeof(struct session), GFP_KERNEL);
+	uint32_t session_id, void *instance, struct connection *connection)
+{
+	struct session *session;
+
+	session = kzalloc(sizeof(*session), GFP_KERNEL);
 	session->session_id = session_id;
 	session->instance = instance;
 	session->notification_connection = connection;
-
 	session->session_info.last_error = SESSION_ERR_NO;
 	session->session_info.state = SESSION_STATE_INITIAL;
 
@@ -49,29 +43,31 @@
 	return session;
 }
 
-
-/*****************************************************************************/
-void session_cleanup(
-	struct session *session
-) {
-	struct bulk_buffer_descriptor  *bulk_buf_descr;
+void session_cleanup(struct session *session)
+{
+	struct bulk_buffer_descriptor *bulk_buf_descr;
 	struct list_head *pos, *q;
+	unsigned int phys_addr_wsm_l2;
 
 	/* Unmap still mapped buffers */
 	list_for_each_safe(pos, q, &session->bulk_buffer_descriptors) {
 		bulk_buf_descr =
 			list_entry(pos, struct bulk_buffer_descriptor, list);
 
-		MCDRV_DBG_VERBOSE("Physical Address of L2 Table = 0x%X, "
-				"handle= %d",
-				(unsigned int)bulk_buf_descr->phys_addr_wsm_l2,
-				bulk_buf_descr->handle);
+		phys_addr_wsm_l2 =
+			(unsigned int)bulk_buf_descr->phys_addr_wsm_l2;
+
+		MCDRV_DBG_VERBOSE(mc_kapi,
+				  "Phys Addr of L2 Table = 0x%X, handle= %d",
+				  phys_addr_wsm_l2,
+				  bulk_buf_descr->handle);
 
 		/* ignore any error, as we cannot do anything in this case. */
 		int ret = mobicore_unmap_vmem(session->instance,
-						bulk_buf_descr->handle);
+					      bulk_buf_descr->handle);
 		if (ret != 0)
-			MCDRV_DBG_ERROR("mobicore_unmap_vmem failed: %d", ret);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"mobicore_unmap_vmem failed: %d", ret);
 
 		list_del(pos);
 		kfree(bulk_buf_descr);
@@ -82,36 +78,27 @@
 	kfree(session);
 }
 
-
-/*****************************************************************************/
-void session_set_error_info(
-	struct session *session,
-	int32_t   err
-) {
+void session_set_error_info(struct session *session, int32_t err)
+{
 	session->session_info.last_error = err;
 }
 
-
-/*****************************************************************************/
-int32_t session_get_last_err(
-	struct session *session
-) {
+int32_t session_get_last_err(struct session *session)
+{
 	return session->session_info.last_error;
 }
 
-
-/*****************************************************************************/
-struct bulk_buffer_descriptor *session_add_bulk_buf(
-	struct session	*session,
-	void		*buf,
-	uint32_t	len
-) {
+struct bulk_buffer_descriptor *session_add_bulk_buf(struct session *session,
+						    void *buf, uint32_t len)
+{
 	struct bulk_buffer_descriptor *bulk_buf_descr = NULL;
-	struct bulk_buffer_descriptor  *tmp;
+	struct bulk_buffer_descriptor *tmp;
 	struct list_head *pos;
 
-	/* Search bulk buffer descriptors for existing vAddr
-	   At the moment a virtual address can only be added one time */
+	/*
+	 * Search bulk buffer descriptors for existing vAddr
+	 * At the moment a virtual address can only be added one time
+	 */
 	list_for_each(pos, &session->bulk_buffer_descriptors) {
 		tmp = list_entry(pos, struct bulk_buffer_descriptor, list);
 		if (tmp->virt_addr == buf)
@@ -119,84 +106,96 @@
 	}
 
 	do {
-		/* Prepare the interface structure for memory registration in
-		   Kernel Module */
-		void	*l2_table_phys;
-		uint32_t  handle;
+		/*
+		 * Prepare the interface structure for memory registration in
+		 * Kernel Module
+		 */
+		uint32_t l2_table_phys;
+		uint32_t handle;
 
-		int ret = mobicore_map_vmem(session->instance,
-					buf,
-					len,
-					&handle,
-					&l2_table_phys);
+		int ret = mobicore_map_vmem(session->instance, buf, len,
+					    &handle, &l2_table_phys);
 
 		if (ret != 0) {
-			MCDRV_DBG_ERROR("mobicore_map_vmem failed, ret=%d",
+			MCDRV_DBG_ERROR(mc_kapi,
+					"mobicore_map_vmem failed, ret=%d",
 					ret);
 			break;
 		}
 
-		MCDRV_DBG_VERBOSE("Physical Address of L2 Table = 0x%X, "
-				"handle=%d",
-				(unsigned int)l2_table_phys,
-				handle);
+		MCDRV_DBG_VERBOSE(mc_kapi,
+				  "Phys Addr of L2 Table = 0x%X, handle=%d",
+				  (unsigned int)l2_table_phys, handle);
 
 		/* Create new descriptor */
-		bulk_buf_descr = bulk_buffer_descriptor_create(
-							buf,
-							len,
-							handle,
-							l2_table_phys);
+		bulk_buf_descr =
+			bulk_buffer_descriptor_create(buf, len,
+						      handle,
+						      (void *)l2_table_phys);
 
 		/* Add to vector of descriptors */
 		list_add_tail(&(bulk_buf_descr->list),
-			&(session->bulk_buffer_descriptors));
+			      &(session->bulk_buffer_descriptors));
 	} while (0);
 
 	return bulk_buf_descr;
 }
 
-
-/*****************************************************************************/
-bool session_remove_bulk_buf(
-	struct session *session,
-	void	*virt_addr
-) {
+bool session_remove_bulk_buf(struct session *session, void *virt_addr)
+{
 	bool ret = true;
-	struct bulk_buffer_descriptor  *bulk_buf_descr = NULL;
-	struct bulk_buffer_descriptor  *tmp;
+	struct bulk_buffer_descriptor *bulk_buf = NULL;
+	struct bulk_buffer_descriptor *tmp;
 	struct list_head *pos, *q;
 
-	MCDRV_DBG_VERBOSE("Virtual Address = 0x%X", (unsigned int) virt_addr);
+	MCDRV_DBG_VERBOSE(mc_kapi, "Virtual Address = 0x%X",
+			  (unsigned int) virt_addr);
 
 	/* Search and remove bulk buffer descriptor */
 	list_for_each_safe(pos, q, &session->bulk_buffer_descriptors) {
 		tmp = list_entry(pos, struct bulk_buffer_descriptor, list);
 		if (tmp->virt_addr == virt_addr) {
-			bulk_buf_descr = tmp;
+			bulk_buf = tmp;
 			list_del(pos);
 			break;
 		}
 	}
 
-	if (bulk_buf_descr == NULL) {
-		MCDRV_DBG_ERROR("Virtual Address not found");
+	if (bulk_buf == NULL) {
+		MCDRV_DBG_ERROR(mc_kapi, "Virtual Address not found");
 		ret = false;
 	} else {
-		MCDRV_DBG_VERBOSE("WsmL2 phys=0x%X, handle=%d",
-			(unsigned int)bulk_buf_descr->phys_addr_wsm_l2,
-			bulk_buf_descr->handle);
+		MCDRV_DBG_VERBOSE(mc_kapi, "WsmL2 phys=0x%X, handle=%d",
+				  (unsigned int)bulk_buf->phys_addr_wsm_l2,
+				  bulk_buf->handle);
 
 		/* ignore any error, as we cannot do anything */
 		int ret = mobicore_unmap_vmem(session->instance,
-						bulk_buf_descr->handle);
+					      bulk_buf->handle);
 		if (ret != 0)
-			MCDRV_DBG_ERROR("mobicore_unmap_vmem failed: %d", ret);
+			MCDRV_DBG_ERROR(mc_kapi,
+					"mobicore_unmap_vmem failed: %d", ret);
 
-		kfree(bulk_buf_descr);
+		kfree(bulk_buf);
 	}
 
 	return ret;
 }
 
-/** @} */
+uint32_t session_find_bulk_buf(struct session *session, void *virt_addr)
+{
+	struct bulk_buffer_descriptor *tmp;
+	struct list_head *pos, *q;
+
+	MCDRV_DBG_VERBOSE(mc_kapi, "Virtual Address = 0x%X",
+			  (unsigned int) virt_addr);
+
+	/* Search and return buffer descriptor handle */
+	list_for_each_safe(pos, q, &session->bulk_buffer_descriptors) {
+		tmp = list_entry(pos, struct bulk_buffer_descriptor, list);
+		if (tmp->virt_addr == virt_addr)
+			return tmp->handle;
+	}
+
+	return 0;
+}
diff --git a/drivers/gud/mobicore_kernelapi/session.h b/drivers/gud/mobicore_kernelapi/session.h
index 9a53740..4a834e5 100644
--- a/drivers/gud/mobicore_kernelapi/session.h
+++ b/drivers/gud/mobicore_kernelapi/session.h
@@ -1,14 +1,12 @@
-/** @addtogroup MCD_IMPL_LIB
- * @{
- * @file
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+/*
+ * <-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * 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 SESSION_H_
-#define SESSION_H_
+#ifndef _MC_KAPI_SESSION_H_
+#define _MC_KAPI_SESSION_H_
 
 #include "common.h"
 
@@ -17,23 +15,27 @@
 
 
 struct bulk_buffer_descriptor {
-	void		*virt_addr;/**< The virtual address of the Bulk buffer*/
-	uint32_t	len;	  /**< Length of the Bulk buffer*/
+	void		*virt_addr;	/* The VA of the Bulk buffer */
+	uint32_t	len;		/* Length of the Bulk buffer */
 	uint32_t	handle;
-	void		*phys_addr_wsm_l2; /**< The physical address of the
-				L2 table of the Bulk buffer*/
-	struct list_head list; /**< The list param for using the kernel lists*/
+
+	/* The physical address of the L2 table of the Bulk buffer*/
+	void		*phys_addr_wsm_l2;
+
+	/* The list param for using the kernel lists*/
+	struct list_head list;
 };
 
 struct bulk_buffer_descriptor *bulk_buffer_descriptor_create(
-	void	*virt_addr,
-	uint32_t  len,
-	uint32_t  handle,
-	void	*phys_addr_wsm_l2
+	void		*virt_addr,
+	uint32_t	len,
+	uint32_t	handle,
+	void		*phys_addr_wsm_l2
 );
 
-/** Session states.
- * At the moment not used !!.
+/*
+ * Session states.
+ * At the moment not used !!
  */
 enum session_state {
 	SESSION_STATE_INITIAL,
@@ -41,96 +43,102 @@
 	SESSION_STATE_TRUSTLET_DEAD
 };
 
-#define SESSION_ERR_NO	  0 /**< No session error */
+#define SESSION_ERR_NO	0		/* No session error */
 
-/** Session information structure.
+/*
+ * Session information structure.
  * The information structure is used to hold the state of the session, which
  * will limit further actions for the session.
  * Also the last error code will be stored till it's read.
  */
 struct session_information {
-	enum session_state state;	   /**< Session state */
-	int32_t		last_error;	 /**< Last error of session */
+	enum session_state state;	/* Session state */
+	int32_t		last_error;	/* Last error of session */
 };
 
 
 struct session {
 	struct mc_instance		*instance;
-	/**< Descriptors of additional bulk buffer of a session */
-	struct list_head	bulk_buffer_descriptors;
-	/**< Informations about session */
-	struct session_information	 session_info;
 
-	uint32_t		 session_id;
-	struct connection	 *notification_connection;
+	/* Descriptors of additional bulk buffer of a session */
+	struct list_head		bulk_buffer_descriptors;
 
-	/**< The list param for using the kernel lists*/
-	struct list_head list;
+	/* Information about session */
+	struct session_information	session_info;
+
+	uint32_t			session_id;
+	struct connection		*notification_connection;
+
+	/* The list param for using the kernel lists */
+	struct list_head		list;
 };
 
 struct session *session_create(
-	uint32_t	 session_id,
-	void		 *instance,
-	struct connection *connection
+	uint32_t		session_id,
+	void			*instance,
+	struct connection	*connection
 );
 
-void session_cleanup(
-	struct session *session
-);
+void session_cleanup(struct session *session);
 
-/**
-  * Add address information of additional bulk buffer memory to session and
-  * register virtual memory in kernel module.
-  *
-  * @attention The virtual address can only be added one time. If the virtual
-  * address already exist, NULL is returned.
-  *
-  * @param buf The virtual address of bulk buffer.
-  * @param len Length of bulk buffer.
-  *
-  * @return On success the actual Bulk buffer descriptor with all address
-  * information is retured, NULL if an error occurs.
-  */
+/*
+ * session_add_bulk_buf() -	Add address information of additional bulk
+ *				buffer memory to session and register virtual
+ *				memory in kernel module
+ * @session:		Session information structure
+ * @buf:		The virtual address of bulk buffer.
+ * @len:		Length of bulk buffer.
+ *
+ * The virtual address can only be added one time. If the virtual
+ * address already exist, NULL is returned.
+ *
+ * On success the actual Bulk buffer descriptor with all address information
+ * is returned, NULL if an error occurs.
+ */
 struct bulk_buffer_descriptor *session_add_bulk_buf(
-	struct session *session,
-	void	*buf,
-	uint32_t  len
-);
+	struct session *session, void *buf, uint32_t len);
 
-/**
-  * Remove address information of additional bulk buffer memory from session and
-  * unregister virtual memory in kernel module
-  *
-  * @param buf The virtual address of the bulk buffer.
-  *
-  * @return true on success.
-  */
-bool session_remove_bulk_buf(
-	struct session *session,
-	void  *buf
-);
+/*
+ * session_remove_bulk_buf() -	Remove address information of additional bulk
+ *				buffer memory from session and unregister
+ *				virtual memory in kernel module
+ * @session:		Session information structure
+ * @buf:		The virtual address of the bulk buffer
+ *
+ * Returns true on success
+ */
+bool session_remove_bulk_buf(struct session *session, void *buf);
 
-/**
-  * Set additional error information of the last error that occured.
-  *
-  * @param errorCode The actual error.
-  */
-void session_set_error_info(
-	struct session *session,
-	int32_t err
-);
 
-/**
-  * Get additional error information of the last error that occured.
-  *
-  * @attention After request the information is set to SESSION_ERR_NO.
-  *
-  * @return Last stored error code or SESSION_ERR_NO.
-  */
-int32_t session_get_last_err(
-	struct session *session
-);
+/*
+ * session_find_bulk_buf() - Find the handle of the bulk buffer for this
+ *			session
+ *
+ * @session:		Session information structure
+ * @buf:		The virtual address of bulk buffer.
+ *
+ * On success the actual Bulk buffer handle is returned, 0
+ * if an error occurs.
+ */
+uint32_t session_find_bulk_buf(struct session *session, void *virt_addr);
 
-#endif /* SESSION_H_ */
+/*
+ * session_set_error_info() -	Set additional error information of the last
+ *				error that occurred.
+ * @session:		Session information structure
+ * @err:		The actual error
+ */
+void session_set_error_info(struct session *session, int32_t err);
 
-/** @} */
+/*
+ * session_get_last_err() -	Get additional error information of the last
+ *				error that occurred.
+ * @session:		Session information structure
+ *
+ * After request the information is set to SESSION_ERR_NO.
+ *
+ * Returns the last stored error code or SESSION_ERR_NO
+ */
+int32_t session_get_last_err(struct session *session);
+
+#endif /* _MC_KAPI_SESSION_H_ */
diff --git a/drivers/gud/mobicore_kernelapi/wsm.h b/drivers/gud/mobicore_kernelapi/wsm.h
index 6877c53..f8a107c 100644
--- a/drivers/gud/mobicore_kernelapi/wsm.h
+++ b/drivers/gud/mobicore_kernelapi/wsm.h
@@ -1,35 +1,33 @@
-/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
- * @{
- * @file
- *
+/*
  * World shared memory definitions.
  *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * 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 WSM_H_
-#define WSM_H_
+#ifndef _MC_KAPI_WSM_H_
+#define _MC_KAPI_WSM_H_
 
 #include "common.h"
 #include <linux/list.h>
 
 struct wsm {
-	void *virt_addr;
-	uint32_t len;
-	uint32_t handle;
-	void *phys_addr;
-	struct list_head list;
+	void			*virt_addr;
+	uint32_t		len;
+	uint32_t		handle;
+	void			*phys_addr;
+	struct list_head	list;
 };
 
 struct wsm *wsm_create(
-	void	*virt_addr,
-	uint32_t  len,
-	uint32_t  handle,
-	void	*phys_addr /*= NULL this may be unknown, so is can be omitted.*/
-);
-#endif /* WSM_H_ */
+	void			*virt_addr,
+	uint32_t		len,
+	uint32_t		handle,
 
-/** @} */
+	/* NULL this may be unknown, so is can be omitted */
+	void			*phys_addr
+);
+
+#endif /* _MC_KAPI_WSM_H_ */
diff --git a/drivers/hwmon/epm_adc.c b/drivers/hwmon/epm_adc.c
index 56b8841..1b63625 100644
--- a/drivers/hwmon/epm_adc.c
+++ b/drivers/hwmon/epm_adc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/hwmon/m_adcproc.c b/drivers/hwmon/m_adcproc.c
index 70e505e..fe12492 100644
--- a/drivers/hwmon/m_adcproc.c
+++ b/drivers/hwmon/m_adcproc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/hwmon/msm_adc.c b/drivers/hwmon/msm_adc.c
index 018ce79..ca6fae7 100644
--- a/drivers/hwmon/msm_adc.c
+++ b/drivers/hwmon/msm_adc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/hwmon/pm8xxx-adc-scale.c b/drivers/hwmon/pm8xxx-adc-scale.c
index 4a1f58c..9d66425 100644
--- a/drivers/hwmon/pm8xxx-adc-scale.c
+++ b/drivers/hwmon/pm8xxx-adc-scale.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/hwmon/pm8xxx-adc.c b/drivers/hwmon/pm8xxx-adc.c
index 8e35252..3633332 100644
--- a/drivers/hwmon/pm8xxx-adc.c
+++ b/drivers/hwmon/pm8xxx-adc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -31,6 +31,7 @@
 #include <linux/mfd/pm8xxx/core.h>
 #include <linux/regulator/consumer.h>
 #include <linux/mfd/pm8xxx/pm8xxx-adc.h>
+#include <mach/msm_xo.h>
 
 /* User Bank register set */
 #define PM8XXX_ADC_ARB_USRP_CNTRL1			0x197
@@ -141,6 +142,7 @@
 	struct work_struct			cool_work;
 	uint32_t				mpp_base;
 	struct device				*hwmon;
+	struct msm_xo_voter			*adc_voter;
 	int					msm_suspend_check;
 	struct pm8xxx_adc_amux_properties	*conv;
 	struct pm8xxx_adc_arb_btm_param		batt;
@@ -290,14 +292,34 @@
 	return rc;
 }
 
+static int32_t pm8xxx_adc_xo_vote(bool on)
+{
+	struct pm8xxx_adc *adc_pmic = pmic_adc;
+
+	if (on)
+		msm_xo_mode_vote(adc_pmic->adc_voter, MSM_XO_MODE_ON);
+	else
+		msm_xo_mode_vote(adc_pmic->adc_voter, MSM_XO_MODE_OFF);
+
+	return 0;
+}
+
 static int32_t pm8xxx_adc_channel_power_enable(uint32_t channel,
 							bool power_cntrl)
 {
 	int rc = 0;
 
-	switch (channel)
+	switch (channel) {
 	case ADC_MPP_1_AMUX8:
 		rc = pm8xxx_adc_patherm_power(power_cntrl);
+		break;
+	case CHANNEL_DIE_TEMP:
+	case CHANNEL_MUXOFF:
+		rc = pm8xxx_adc_xo_vote(power_cntrl);
+		break;
+	default:
+		break;
+	}
 
 	return rc;
 }
@@ -1147,6 +1169,7 @@
 	struct pm8xxx_adc *adc_pmic = pmic_adc;
 	int i;
 
+	msm_xo_put(adc_pmic->adc_voter);
 	platform_set_drvdata(pdev, NULL);
 	pmic_adc = NULL;
 	if (!pa_therm) {
@@ -1265,6 +1288,14 @@
 	}
 	adc_pmic->hwmon = hwmon_device_register(adc_pmic->dev);
 
+	if (adc_pmic->adc_voter == NULL) {
+		adc_pmic->adc_voter = msm_xo_get(MSM_XO_TCXO_D0, "pmic_xoadc");
+		if (IS_ERR(adc_pmic->adc_voter)) {
+			dev_err(&pdev->dev, "Failed to get XO vote\n");
+			return PTR_ERR(adc_pmic->adc_voter);
+		}
+	}
+
 	pa_therm = regulator_get(adc_pmic->dev, "pa_therm");
 	if (IS_ERR(pa_therm)) {
 		rc = PTR_ERR(pa_therm);
diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
index f908181..c94aaae 100644
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index aa375d7..292f391 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c
index a0e7ab9..03b760f 100644
--- a/drivers/hwmon/qpnp-adc-voltage.c
+++ b/drivers/hwmon/qpnp-adc-voltage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/i2c/busses/i2c-msm.c b/drivers/i2c/busses/i2c-msm.c
index 4b48a69..bceec78 100644
--- a/drivers/i2c/busses/i2c-msm.c
+++ b/drivers/i2c/busses/i2c-msm.c
@@ -1,7 +1,7 @@
 /* drivers/i2c/busses/i2c-msm.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index b562350..69a54bf 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -128,6 +128,9 @@
 };
 
 #define QUP_MAX_CLK_STATE_RETRIES	300
+#define DEFAULT_CLK_RATE		(19200000)
+#define I2C_STATUS_CLK_STATE		13
+#define QUP_OUT_FIFO_NOT_EMPTY		0x10
 
 static char const * const i2c_rsrcs[] = {"i2c_clk", "i2c_sda"};
 
@@ -191,14 +194,18 @@
 qup_i2c_interrupt(int irq, void *devid)
 {
 	struct qup_i2c_dev *dev = devid;
-	uint32_t status = readl_relaxed(dev->base + QUP_I2C_STATUS);
-	uint32_t status1 = readl_relaxed(dev->base + QUP_ERROR_FLAGS);
-	uint32_t op_flgs = readl_relaxed(dev->base + QUP_OPERATIONAL);
+	uint32_t status = 0;
+	uint32_t status1 = 0;
+	uint32_t op_flgs = 0;
 	int err = 0;
 
 	if (pm_runtime_suspended(dev->dev))
 		return IRQ_NONE;
 
+	status = readl_relaxed(dev->base + QUP_I2C_STATUS);
+	status1 = readl_relaxed(dev->base + QUP_ERROR_FLAGS);
+	op_flgs = readl_relaxed(dev->base + QUP_OPERATIONAL);
+
 	if (!dev->msg || !dev->complete) {
 		/* Clear Error interrupt if it's a level triggered interrupt*/
 		if (dev->num_irqs == 1) {
@@ -375,6 +382,7 @@
 static int qup_i2c_poll_clock_ready(struct qup_i2c_dev *dev)
 {
 	uint32_t retries = 0;
+	uint32_t op_flgs = -1, clk_state = -1;
 
 	/*
 	 * Wait for the clock state to transition to either IDLE or FORCED
@@ -383,16 +391,32 @@
 
 	while (retries++ < QUP_MAX_CLK_STATE_RETRIES) {
 		uint32_t status = readl_relaxed(dev->base + QUP_I2C_STATUS);
-		uint32_t clk_state = (status >> 13) & 0x7;
+		clk_state = (status >> I2C_STATUS_CLK_STATE) & 0x7;
+		/* Read the operational register */
+		op_flgs = readl_relaxed(dev->base +
+			QUP_OPERATIONAL) & QUP_OUT_FIFO_NOT_EMPTY;
 
-		if (clk_state == I2C_CLK_RESET_BUSIDLE_STATE ||
-				clk_state == I2C_CLK_FORCED_LOW_STATE)
+		/*
+		 * In very corner case when slave do clock stretching and
+		 * output fifo will have 1 block of data space empty at
+		 * the same time.  So i2c qup will get output service
+		 * interrupt and as it doesn't have more data to be written.
+		 * This can lead to issue where output fifo is not empty.
+		*/
+		if (op_flgs == 0 &&
+			(clk_state == I2C_CLK_RESET_BUSIDLE_STATE ||
+			clk_state == I2C_CLK_FORCED_LOW_STATE)){
+			dev_dbg(dev->dev, "clk_state 0x%x op_flgs [%x]\n",
+				clk_state, op_flgs);
 			return 0;
+		}
+
 		/* 1-bit delay before we check again */
 		udelay(dev->one_bit_t);
 	}
 
-	dev_err(dev->dev, "Error waiting for clk ready\n");
+	dev_err(dev->dev, "Error waiting for clk ready clk_state: 0x%x op_flgs: 0x%x\n",
+		clk_state, op_flgs);
 	return -ETIMEDOUT;
 }
 
@@ -670,7 +694,7 @@
 	int gpio_dat;
 	bool gpio_clk_status = false;
 	uint32_t status = readl_relaxed(dev->base + QUP_I2C_STATUS);
-	struct gpiomux_setting old_gpio_setting;
+	struct gpiomux_setting old_gpio_setting[ARRAY_SIZE(i2c_rsrcs)];
 
 	if (dev->pdata->msm_i2c_config_gpio)
 		return;
@@ -690,7 +714,7 @@
 	disable_irq(dev->err_irq);
 	for (i = 0; i < ARRAY_SIZE(i2c_rsrcs); ++i) {
 		if (msm_gpiomux_write(dev->i2c_gpios[i], GPIOMUX_ACTIVE,
-				&recovery_config, &old_gpio_setting)) {
+				&recovery_config, &old_gpio_setting[i])) {
 			dev_err(dev->dev, "GPIO pins have no active setting\n");
 			goto recovery_end;
 		}
@@ -720,7 +744,7 @@
 	/* Configure ALT funciton to QUP I2C*/
 	for (i = 0; i < ARRAY_SIZE(i2c_rsrcs); ++i) {
 		msm_gpiomux_write(dev->i2c_gpios[i], GPIOMUX_ACTIVE,
-				&old_gpio_setting, NULL);
+				&old_gpio_setting[i], NULL);
 	}
 
 	udelay(10);
diff --git a/drivers/i2c/busses/i2c-ssbi.c b/drivers/i2c/busses/i2c-ssbi.c
index c803402..3022a80 100644
--- a/drivers/i2c/busses/i2c-ssbi.c
+++ b/drivers/i2c/busses/i2c-ssbi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/drivers/input/joystick/tdisc_vtd518_shinetsu.c b/drivers/input/joystick/tdisc_vtd518_shinetsu.c
index efbe974..5faaf72 100644
--- a/drivers/input/joystick/tdisc_vtd518_shinetsu.c
+++ b/drivers/input/joystick/tdisc_vtd518_shinetsu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index dd05cca..f7b5558 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -2,7 +2,7 @@
  *  GPIO driven matrix keyboard driver
  *
  *  Copyright (c) 2008 Marek Vasut <marek.vasut@gmail.com>
- *  Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  *  Based on corgikbd.c
  *
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c
index d529ea4..26e26e2 100644
--- a/drivers/input/keyboard/pmic8xxx-keypad.c
+++ b/drivers/input/keyboard/pmic8xxx-keypad.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/drivers/input/keyboard/qci_kbd.c b/drivers/input/keyboard/qci_kbd.c
index d735012..d43e81c 100644
--- a/drivers/input/keyboard/qci_kbd.c
+++ b/drivers/input/keyboard/qci_kbd.c
@@ -1,7 +1,7 @@
 /* Quanta I2C Keyboard Driver
  *
  * Copyright (C) 2009 Quanta Computer Inc.
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  * Author: Hsin Wu <hsin.wu@quantatw.com>
  * Author: Austin Lai <austin.lai@quantatw.com>
  *
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 1464dab..f6c647c 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -654,4 +654,24 @@
           If you say yes here you get support for STMicroelectronics's
           acceleration sensors LIS3DH.
 
+config BMP18X
+       tristate "BMP18X digital pressure sensor"
+       depends on (I2C ) && SYSFS
+       help
+         If you say yes here you get support for Bosch Sensortec
+	 digital pressure sensors BMP085, BMP180.
+
+         To compile this driver as a module, choose M here: the
+         module will be called bmp18x-core.
+
+config BMP18X_I2C
+       tristate "support I2C bus connection"
+       depends on BMP18X && I2C
+       help
+         Say Y here if you want to support Bosch Sensortec digital pressure
+         sensor hooked to an I2C bus.
+
+         To compile this driver as a module, choose M here: the
+         module will be called bmp18x-i2c.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 96c9288..97d9782 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -61,3 +61,5 @@
 obj-$(CONFIG_INPUT_PMIC8058_VIBRA_MEMLESS) += pmic8058-vib-memless.o
 obj-$(CONFIG_BOSCH_BMA150)              += bma150.o
 obj-$(CONFIG_STM_LIS3DH)		+= lis3dh_acc.o
+obj-$(CONFIG_BMP18X)			+= bmp18x-core.o
+obj-$(CONFIG_BMP18X_I2C)		+= bmp18x-i2c.o
diff --git a/drivers/input/misc/bmp18x-core.c b/drivers/input/misc/bmp18x-core.c
new file mode 100644
index 0000000..9d15816
--- /dev/null
+++ b/drivers/input/misc/bmp18x-core.c
@@ -0,0 +1,710 @@
+/*  Copyright (c) 2011  Bosch Sensortec GmbH
+    Copyright (c) 2011  Unixphere
+
+    Based on:
+    BMP085 driver, bmp085.c
+    Copyright (c) 2010  Christoph Mair <christoph.mair@gmail.com>
+
+    This driver supports the bmp18x digital barometric pressure
+    and temperature sensors from Bosch Sensortec.
+
+    A pressure measurement is issued by reading from pressure0_input.
+    The return value ranges from 30000 to 110000 pascal with a resulution
+    of 1 pascal (0.01 millibar) which enables measurements from 9000m above
+    to 500m below sea level.
+
+    The temperature can be read from temp0_input. Values range from
+    -400 to 850 representing the ambient temperature in degree celsius
+    multiplied by 10.The resolution is 0.1 celsius.
+
+    Because ambient pressure is temperature dependent, a temperature
+    measurement will be executed automatically even if the user is reading
+    from pressure0_input. This happens if the last temperature measurement
+    has been executed more then one second ago.
+
+    To decrease RMS noise from pressure measurements, the bmp18x can
+    autonomously calculate the average of up to eight samples. This is
+    set up by writing to the oversampling sysfs file. Accepted values
+    are 0, 1, 2 and 3. 2^x when x is the value written to this file
+    specifies the number of samples used to calculate the ambient pressure.
+    RMS noise is specified with six pascal (without averaging) and decreases
+    down to 3 pascal when using an oversampling setting of 3.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include "bmp18x.h"
+
+#define BMP18X_CHIP_ID			0x55
+
+#define BMP18X_CALIBRATION_DATA_START	0xAA
+#define BMP18X_CALIBRATION_DATA_LENGTH	11	/* 16 bit values */
+#define BMP18X_CHIP_ID_REG		0xD0
+#define BMP18X_CTRL_REG			0xF4
+#define BMP18X_TEMP_MEASUREMENT		0x2E
+#define BMP18X_PRESSURE_MEASUREMENT	0x34
+#define BMP18X_CONVERSION_REGISTER_MSB	0xF6
+#define BMP18X_CONVERSION_REGISTER_LSB	0xF7
+#define BMP18X_CONVERSION_REGISTER_XLSB	0xF8
+#define BMP18X_TEMP_CONVERSION_TIME	5
+
+#define ABS_MIN_PRESSURE	30000
+#define ABS_MAX_PRESSURE	120000
+#define BMP_DELAY_DEFAULT	200
+#define BMP_DELAY_MIN		20
+#define BMP_DELAY_MAX		2000
+
+struct bmp18x_calibration_data {
+	s16 AC1, AC2, AC3;
+	u16 AC4, AC5, AC6;
+	s16 B1, B2;
+	s16 MB, MC, MD;
+};
+
+/* Each client has this additional data */
+struct bmp18x_data {
+	struct	bmp18x_data_bus data_bus;
+	struct	device *dev;
+	struct	mutex lock;
+	struct	bmp18x_calibration_data calibration;
+	u8	oversampling_setting;
+	u8	sw_oversampling_setting;
+	u32	raw_temperature;
+	u32	raw_pressure;
+	u32	temp_measurement_period;
+	u32	last_temp_measurement;
+	s32	b6; /* calculated temperature correction coefficient */
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	struct early_suspend early_suspend;
+#endif
+	struct input_dev	*input;
+	struct delayed_work work;
+	u32					delay;
+	u32					enable;
+};
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void bmp18x_early_suspend(struct early_suspend *h);
+static void bmp18x_late_resume(struct early_suspend *h);
+#endif
+
+static s32 bmp18x_read_calibration_data(struct bmp18x_data *data)
+{
+	u16 tmp[BMP18X_CALIBRATION_DATA_LENGTH];
+	struct bmp18x_calibration_data *cali = &(data->calibration);
+	s32 status = data->data_bus.bops->read_block(data->data_bus.client,
+				BMP18X_CALIBRATION_DATA_START,
+				BMP18X_CALIBRATION_DATA_LENGTH*sizeof(u16),
+				(u8 *)tmp);
+	if (status < 0)
+		return status;
+
+	if (status != BMP18X_CALIBRATION_DATA_LENGTH*sizeof(u16))
+		return -EIO;
+
+	cali->AC1 =  be16_to_cpu(tmp[0]);
+	cali->AC2 =  be16_to_cpu(tmp[1]);
+	cali->AC3 =  be16_to_cpu(tmp[2]);
+	cali->AC4 =  be16_to_cpu(tmp[3]);
+	cali->AC5 =  be16_to_cpu(tmp[4]);
+	cali->AC6 = be16_to_cpu(tmp[5]);
+	cali->B1 = be16_to_cpu(tmp[6]);
+	cali->B2 = be16_to_cpu(tmp[7]);
+	cali->MB = be16_to_cpu(tmp[8]);
+	cali->MC = be16_to_cpu(tmp[9]);
+	cali->MD = be16_to_cpu(tmp[10]);
+	return 0;
+}
+
+
+static s32 bmp18x_update_raw_temperature(struct bmp18x_data *data)
+{
+	u16 tmp;
+	s32 status;
+
+	mutex_lock(&data->lock);
+	status = data->data_bus.bops->write_byte(data->data_bus.client,
+				BMP18X_CTRL_REG, BMP18X_TEMP_MEASUREMENT);
+	if (status != 0) {
+		dev_err(data->dev,
+			"Error while requesting temperature measurement.\n");
+		goto exit;
+	}
+	msleep(BMP18X_TEMP_CONVERSION_TIME);
+
+	status = data->data_bus.bops->read_block(data->data_bus.client,
+		BMP18X_CONVERSION_REGISTER_MSB, sizeof(tmp), (u8 *)&tmp);
+	if (status < 0)
+		goto exit;
+	if (status != sizeof(tmp)) {
+		dev_err(data->dev,
+			"Error while reading temperature measurement result\n");
+		status = -EIO;
+		goto exit;
+	}
+	data->raw_temperature = be16_to_cpu(tmp);
+	data->last_temp_measurement = jiffies;
+	status = 0;	/* everything ok, return 0 */
+
+exit:
+	mutex_unlock(&data->lock);
+	return status;
+}
+
+static s32 bmp18x_update_raw_pressure(struct bmp18x_data *data)
+{
+	u32 tmp = 0;
+	s32 status;
+
+	mutex_lock(&data->lock);
+	status = data->data_bus.bops->write_byte(data->data_bus.client,
+		BMP18X_CTRL_REG, BMP18X_PRESSURE_MEASUREMENT +
+		(data->oversampling_setting<<6));
+	if (status != 0) {
+		dev_err(data->dev,
+			"Error while requesting pressure measurement.\n");
+		goto exit;
+	}
+
+	/* wait for the end of conversion */
+	msleep(2+(3 << data->oversampling_setting));
+
+	/* copy data into a u32 (4 bytes), but skip the first byte. */
+	status = data->data_bus.bops->read_block(data->data_bus.client,
+			BMP18X_CONVERSION_REGISTER_MSB, 3, ((u8 *)&tmp)+1);
+	if (status < 0)
+		goto exit;
+	if (status != 3) {
+		dev_err(data->dev,
+			"Error while reading pressure measurement results\n");
+		status = -EIO;
+		goto exit;
+	}
+	data->raw_pressure = be32_to_cpu((tmp));
+	data->raw_pressure >>= (8-data->oversampling_setting);
+	status = 0;	/* everything ok, return 0 */
+
+exit:
+	mutex_unlock(&data->lock);
+	return status;
+}
+
+
+/*
+ * This function starts the temperature measurement and returns the value
+ * in tenth of a degree celsius.
+ */
+static s32 bmp18x_get_temperature(struct bmp18x_data *data, int *temperature)
+{
+	struct bmp18x_calibration_data *cali = &data->calibration;
+	long x1, x2;
+	int status;
+
+	status = bmp18x_update_raw_temperature(data);
+	if (status != 0)
+		goto exit;
+
+	x1 = ((data->raw_temperature - cali->AC6) * cali->AC5) >> 15;
+	x2 = (cali->MC << 11) / (x1 + cali->MD);
+	data->b6 = x1 + x2 - 4000;
+	/* if NULL just update b6. Used for pressure only measurements */
+	if (temperature != NULL)
+		*temperature = (x1+x2+8) >> 4;
+
+exit:
+	return status;
+}
+
+/*
+ * This function starts the pressure measurement and returns the value
+ * in millibar. Since the pressure depends on the ambient temperature,
+ * a temperature measurement is executed according to the given temperature
+ * measurememt period (default is 1 sec boundary). This period could vary
+ * and needs to be adjusted accoring to the sensor environment, i.e. if big
+ * temperature variations then the temperature needs to be read out often.
+ */
+static s32 bmp18x_get_pressure(struct bmp18x_data *data, int *pressure)
+{
+	struct bmp18x_calibration_data *cali = &data->calibration;
+	s32 x1, x2, x3, b3;
+	u32 b4, b7;
+	s32 p;
+	int status;
+	int i_loop, i;
+	u32 p_tmp;
+
+	/* update the ambient temperature according to the given meas. period */
+	if (data->last_temp_measurement +
+			data->temp_measurement_period < jiffies) {
+		status = bmp18x_get_temperature(data, NULL);
+		if (status != 0)
+			goto exit;
+	}
+
+	if ((data->oversampling_setting == 3)
+		&& (data->sw_oversampling_setting == 1)) {
+		i_loop = 3;
+	} else {
+		i_loop = 1;
+	}
+
+	p_tmp = 0;
+	for (i = 0; i < i_loop; i++) {
+		status = bmp18x_update_raw_pressure(data);
+		if (status != 0)
+			goto exit;
+		p_tmp += data->raw_pressure;
+	}
+
+	data->raw_pressure = (p_tmp + (i_loop >> 1)) / i_loop;
+
+	x1 = (data->b6 * data->b6) >> 12;
+	x1 *= cali->B2;
+	x1 >>= 11;
+
+	x2 = cali->AC2 * data->b6;
+	x2 >>= 11;
+
+	x3 = x1 + x2;
+
+	b3 = (((((s32)cali->AC1) * 4 + x3) << data->oversampling_setting) + 2);
+	b3 >>= 2;
+
+	x1 = (cali->AC3 * data->b6) >> 13;
+	x2 = (cali->B1 * ((data->b6 * data->b6) >> 12)) >> 16;
+	x3 = (x1 + x2 + 2) >> 2;
+	b4 = (cali->AC4 * (u32)(x3 + 32768)) >> 15;
+
+	b7 = ((u32)data->raw_pressure - b3) *
+					(50000 >> data->oversampling_setting);
+	p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
+
+	x1 = p >> 8;
+	x1 *= x1;
+	x1 = (x1 * 3038) >> 16;
+	x2 = (-7357 * p) >> 16;
+	p += (x1 + x2 + 3791) >> 4;
+
+	*pressure = p;
+
+exit:
+	return status;
+}
+
+/*
+ * This function sets the chip-internal oversampling. Valid values are 0..3.
+ * The chip will use 2^oversampling samples for internal averaging.
+ * This influences the measurement time and the accuracy; larger values
+ * increase both. The datasheet gives on overview on how measurement time,
+ * accuracy and noise correlate.
+ */
+static void bmp18x_set_oversampling(struct bmp18x_data *data,
+						unsigned char oversampling)
+{
+	if (oversampling > 3)
+		oversampling = 3;
+	data->oversampling_setting = oversampling;
+}
+
+/*
+ * Returns the currently selected oversampling. Range: 0..3
+ */
+static unsigned char bmp18x_get_oversampling(struct bmp18x_data *data)
+{
+	return data->oversampling_setting;
+}
+
+/* sysfs callbacks */
+static ssize_t set_oversampling(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	unsigned long oversampling;
+	int success = strict_strtoul(buf, 10, &oversampling);
+	if (success == 0) {
+		mutex_lock(&data->lock);
+		bmp18x_set_oversampling(data, oversampling);
+		if (oversampling != 3)
+			data->sw_oversampling_setting = 0;
+		mutex_unlock(&data->lock);
+		return count;
+	}
+	return success;
+}
+
+static ssize_t show_oversampling(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	return sprintf(buf, "%u\n", bmp18x_get_oversampling(data));
+}
+static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
+					show_oversampling, set_oversampling);
+
+static ssize_t set_sw_oversampling(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	unsigned long sw_oversampling;
+	int success = strict_strtoul(buf, 10, &sw_oversampling);
+	if (success == 0) {
+		mutex_lock(&data->lock);
+		data->sw_oversampling_setting = sw_oversampling ? 1 : 0;
+		mutex_unlock(&data->lock);
+	}
+	return success;
+}
+
+static ssize_t show_sw_oversampling(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	return sprintf(buf, "%u\n", data->sw_oversampling_setting);
+}
+static DEVICE_ATTR(sw_oversampling, S_IWUSR | S_IRUGO,
+				show_sw_oversampling, set_sw_oversampling);
+
+static ssize_t show_delay(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	return sprintf(buf, "%u\n", data->delay);
+}
+
+static ssize_t set_delay(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	unsigned long delay;
+	int success = strict_strtoul(buf, 10, &delay);
+	if (success == 0) {
+		if ((delay >= BMP_DELAY_MIN) &&
+			(delay <= BMP_DELAY_MAX)) {
+			mutex_lock(&data->lock);
+			data->delay = delay;
+			mutex_unlock(&data->lock);
+		}
+		return count;
+	}
+	return success;
+}
+static DEVICE_ATTR(pollrate_ms, S_IWUSR | S_IRUGO,
+				show_delay, set_delay);
+
+static ssize_t show_enable(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	return sprintf(buf, "%u\n", data->enable);
+}
+
+static ssize_t set_enable(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+	unsigned long enable;
+	int success = strict_strtoul(buf, 10, &enable);
+	if (success == 0) {
+		mutex_lock(&data->lock);
+		data->enable = enable ? 1 : 0;
+
+		if (data->enable) {
+			bmp18x_enable(dev);
+			schedule_delayed_work(&data->work,
+						msecs_to_jiffies(data->delay));
+		} else {
+			cancel_delayed_work_sync(&data->work);
+			bmp18x_disable(dev);
+		}
+		mutex_unlock(&data->lock);
+		return count;
+	}
+	return success;
+}
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
+				show_enable, set_enable);
+
+static ssize_t show_temperature(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	int temperature;
+	int status;
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+
+	status = bmp18x_get_temperature(data, &temperature);
+	if (status != 0)
+		return status;
+	else
+		return sprintf(buf, "%d\n", temperature);
+}
+static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL);
+
+
+static ssize_t show_pressure(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	int pressure;
+	int status;
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+
+	status = bmp18x_get_pressure(data, &pressure);
+	if (status != 0)
+		return status;
+	else
+		return sprintf(buf, "%d\n", pressure);
+}
+static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL);
+
+
+static struct attribute *bmp18x_attributes[] = {
+	&dev_attr_temp0_input.attr,
+	&dev_attr_pressure0_input.attr,
+	&dev_attr_oversampling.attr,
+	&dev_attr_sw_oversampling.attr,
+	&dev_attr_pollrate_ms.attr,
+	&dev_attr_enable.attr,
+	NULL
+};
+
+static const struct attribute_group bmp18x_attr_group = {
+	.attrs = bmp18x_attributes,
+};
+
+static void bmp18x_work_func(struct work_struct *work)
+{
+	struct bmp18x_data *client_data =
+		container_of((struct delayed_work *)work,
+		struct bmp18x_data, work);
+	unsigned long delay = msecs_to_jiffies(client_data->delay);
+	unsigned long j1 = jiffies;
+	int pressure;
+	int status;
+
+	status = bmp18x_get_pressure(client_data, &pressure);
+
+	if (status == 0) {
+		input_report_abs(client_data->input, ABS_PRESSURE, pressure);
+		input_sync(client_data->input);
+	}
+
+	schedule_delayed_work(&client_data->work, delay-(jiffies-j1));
+}
+
+static int bmp18x_input_init(struct bmp18x_data *data, struct device *parent)
+{
+	struct input_dev *dev;
+	int err;
+
+	dev = input_allocate_device();
+	if (!dev)
+		return -ENOMEM;
+	dev->name = BMP18X_NAME;
+	dev->id.bustype = BUS_I2C;
+	dev->dev.parent = parent;
+
+	input_set_capability(dev, EV_ABS, ABS_MISC);
+	input_set_abs_params(dev, ABS_PRESSURE,
+		ABS_MIN_PRESSURE, ABS_MAX_PRESSURE, 0, 0);
+	input_set_drvdata(dev, data);
+
+	err = input_register_device(dev);
+	if (err < 0) {
+		input_free_device(dev);
+		return err;
+	}
+	data->input = dev;
+
+	return 0;
+}
+
+static void bmp18x_input_delete(struct bmp18x_data *data)
+{
+	struct input_dev *dev = data->input;
+
+	input_unregister_device(dev);
+	input_free_device(dev);
+}
+
+static int bmp18x_init_client(struct bmp18x_data *data,
+			      struct bmp18x_platform_data *pdata)
+{
+	int status = bmp18x_read_calibration_data(data);
+	if (status != 0)
+		goto exit;
+	data->last_temp_measurement = 0;
+	data->temp_measurement_period =
+		pdata ? (pdata->temp_measurement_period/1000)*HZ : 1*HZ;
+	data->oversampling_setting = pdata ? pdata->default_oversampling : 3;
+	if (data->oversampling_setting == 3)
+		data->sw_oversampling_setting
+			= pdata ? pdata->default_sw_oversampling : 0;
+	mutex_init(&data->lock);
+exit:
+	return status;
+}
+
+__devinit int bmp18x_probe(struct device *dev, struct bmp18x_data_bus *data_bus)
+{
+	struct bmp18x_data *data;
+	struct bmp18x_platform_data *pdata = dev->platform_data;
+	u8 chip_id = pdata && pdata->chip_id ? pdata->chip_id : BMP18X_CHIP_ID;
+	int err = 0;
+
+	if (pdata && pdata->init_hw) {
+		err = pdata->init_hw();
+		if (err) {
+			printk(KERN_ERR "%s: init_hw failed!\n",
+				BMP18X_NAME);
+			goto exit;
+		}
+	}
+
+	if (data_bus->bops->read_byte(data_bus->client,
+			BMP18X_CHIP_ID_REG) != chip_id) {
+		printk(KERN_ERR "%s: chip_id failed!\n", BMP18X_NAME);
+		err = -ENODEV;
+		goto exit;
+	}
+
+	data = kzalloc(sizeof(struct bmp18x_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	dev_set_drvdata(dev, data);
+	data->data_bus = *data_bus;
+	data->dev = dev;
+
+	/* Initialize the BMP18X chip */
+	err = bmp18x_init_client(data, pdata);
+	if (err != 0)
+		goto exit_free;
+
+	/* Initialize the BMP18X input device */
+	err = bmp18x_input_init(data, dev);
+	if (err != 0)
+		goto exit_free;
+
+
+	/* Register sysfs hooks */
+	err = sysfs_create_group(&dev->kobj, &bmp18x_attr_group);
+	if (err)
+		goto error_sysfs;
+	/* workqueue init */
+	INIT_DELAYED_WORK(&data->work, bmp18x_work_func);
+	data->delay  = BMP_DELAY_DEFAULT;
+	data->enable = 0;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+	data->early_suspend.suspend = bmp18x_early_suspend;
+	data->early_suspend.resume = bmp18x_late_resume;
+	register_early_suspend(&data->early_suspend);
+#endif
+
+	dev_info(dev, "Succesfully initialized bmp18x!\n");
+	return 0;
+
+error_sysfs:
+	bmp18x_input_delete(data);
+exit_free:
+	kfree(data);
+exit:
+	if (pdata && pdata->deinit_hw)
+		pdata->deinit_hw();
+	return err;
+}
+EXPORT_SYMBOL(bmp18x_probe);
+
+int bmp18x_remove(struct device *dev)
+{
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	unregister_early_suspend(&data->early_suspend);
+#endif
+	sysfs_remove_group(&dev->kobj, &bmp18x_attr_group);
+	kfree(data);
+
+	return 0;
+}
+EXPORT_SYMBOL(bmp18x_remove);
+
+#ifdef CONFIG_PM
+int bmp18x_disable(struct device *dev)
+{
+	struct bmp18x_platform_data *pdata = dev->platform_data;
+
+	if (pdata && pdata->deinit_hw)
+		pdata->deinit_hw();
+
+	return 0;
+}
+EXPORT_SYMBOL(bmp18x_disable);
+
+int bmp18x_enable(struct device *dev)
+{
+	struct bmp18x_platform_data *pdata = dev->platform_data;
+
+	if (pdata && pdata->init_hw)
+		return pdata->init_hw();
+
+	return 0;
+}
+EXPORT_SYMBOL(bmp18x_enable);
+#endif
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void bmp18x_early_suspend(struct early_suspend *h)
+{
+	struct bmp18x_data *data =
+		container_of(h, struct bmp18x_data, early_suspend);
+	if (data->enable) {
+		cancel_delayed_work_sync(&data->work);
+		(void) bmp18x_disable(data->dev);
+	}
+}
+
+static void bmp18x_late_resume(struct early_suspend *h)
+{
+	struct bmp18x_data *data =
+		container_of(h, struct bmp18x_data, early_suspend);
+
+	if (data->enable) {
+		(void) bmp18x_enable(data->dev);
+		schedule_delayed_work(&data->work,
+					msecs_to_jiffies(data->delay));
+	}
+
+}
+#endif
+
+MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>");
+MODULE_DESCRIPTION("BMP18X driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/bmp18x-i2c.c b/drivers/input/misc/bmp18x-i2c.c
new file mode 100644
index 0000000..6c01ad3
--- /dev/null
+++ b/drivers/input/misc/bmp18x-i2c.c
@@ -0,0 +1,122 @@
+/*  Copyright (c) 2011  Bosch Sensortec GmbH
+    Copyright (c) 2011  Unixphere
+
+    Based on:
+    BMP085 driver, bmp085.c
+    Copyright (c) 2010  Christoph Mair <christoph.mair@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.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include "bmp18x.h"
+
+static int bmp18x_i2c_read_block(void *client, u8 reg, int len, char *buf)
+{
+	return i2c_smbus_read_i2c_block_data(client, reg, len, buf);
+}
+
+static int bmp18x_i2c_read_byte(void *client, u8 reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int bmp18x_i2c_write_byte(void *client, u8 reg, u8 value)
+{
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static const struct bmp18x_bus_ops bmp18x_i2c_bus_ops = {
+	.read_block	= bmp18x_i2c_read_block,
+	.read_byte	= bmp18x_i2c_read_byte,
+	.write_byte	= bmp18x_i2c_write_byte
+};
+
+static int __devinit bmp18x_i2c_probe(struct i2c_client *client,
+				      const struct i2c_device_id *id)
+{
+	struct bmp18x_data_bus data_bus = {
+		.bops = &bmp18x_i2c_bus_ops,
+		.client = client
+	};
+
+	return bmp18x_probe(&client->dev, &data_bus);
+}
+
+static void bmp18x_i2c_shutdown(struct i2c_client *client)
+{
+	bmp18x_disable(&client->dev);
+}
+
+static int bmp18x_i2c_remove(struct i2c_client *client)
+{
+	return bmp18x_remove(&client->dev);
+}
+
+#ifdef CONFIG_PM
+static int bmp18x_i2c_suspend(struct device *dev)
+{
+	return bmp18x_disable(dev);
+}
+
+static int bmp18x_i2c_resume(struct device *dev)
+{
+	return bmp18x_enable(dev);
+}
+
+static const struct dev_pm_ops bmp18x_i2c_pm_ops = {
+	.suspend	= bmp18x_i2c_suspend,
+	.resume		= bmp18x_i2c_resume
+};
+#endif
+
+static const struct i2c_device_id bmp18x_id[] = {
+	{ BMP18X_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, bmp18x_id);
+
+static struct i2c_driver bmp18x_i2c_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= BMP18X_NAME,
+#ifdef CONFIG_PM
+		.pm	= &bmp18x_i2c_pm_ops,
+#endif
+	},
+	.id_table	= bmp18x_id,
+	.probe		= bmp18x_i2c_probe,
+	.shutdown	= bmp18x_i2c_shutdown,
+	.remove		= __devexit_p(bmp18x_i2c_remove)
+};
+
+static int __init bmp18x_i2c_init(void)
+{
+	return i2c_add_driver(&bmp18x_i2c_driver);
+}
+
+static void __exit bmp18x_i2c_exit(void)
+{
+	i2c_del_driver(&bmp18x_i2c_driver);
+}
+
+
+MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>");
+MODULE_DESCRIPTION("BMP18X I2C bus driver");
+MODULE_LICENSE("GPL");
+
+module_init(bmp18x_i2c_init);
+module_exit(bmp18x_i2c_exit);
diff --git a/drivers/input/misc/bmp18x.h b/drivers/input/misc/bmp18x.h
new file mode 100644
index 0000000..f9d55ec
--- /dev/null
+++ b/drivers/input/misc/bmp18x.h
@@ -0,0 +1,64 @@
+/*  Copyright (c) 2010  Christoph Mair <christoph.mair@gmail.com>
+    Copyright (c) 2011  Bosch Sensortec GmbH
+    Copyright (c) 2011  Unixphere AB
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _BMP18X_H
+#define _BMP18X_H
+
+#define BMP18X_NAME "bmp18x"
+
+/**
+ * struct bmp18x_platform_data - represents platform data for the bmp18x driver
+ * @chip_id: Configurable chip id for non-default chip revisions
+ * @default_oversampling: Default oversampling value to be used at startup,
+ * value range is 0-3 with rising sensitivity.
+ * @default_sw_oversampling: Default software oversampling value to be used
+ * at startup,value range is 0(Disabled) or 1(Enabled). Only take effect
+ * when default_oversampling is 3.
+ * @temp_measurement_period: Temperature measurement period (milliseconds), set
+ * to zero if unsure.
+ * @init_hw: Callback for hw specific startup
+ * @deinit_hw: Callback for hw specific shutdown
+ */
+struct bmp18x_platform_data {
+	u8	chip_id;
+	u8	default_oversampling;
+	u8	default_sw_oversampling;
+	u32	temp_measurement_period;
+	int	(*init_hw)(void);
+	void	(*deinit_hw)(void);
+};
+
+struct bmp18x_bus_ops {
+	int	(*read_block)(void *client, u8 reg, int len, char *buf);
+	int	(*read_byte)(void *client, u8 reg);
+	int	(*write_byte)(void *client, u8 reg, u8 value);
+};
+
+struct bmp18x_data_bus {
+	const struct bmp18x_bus_ops	*bops;
+	void	*client;
+};
+
+int bmp18x_probe(struct device *dev, struct bmp18x_data_bus *data_bus);
+int bmp18x_remove(struct device *dev);
+#ifdef CONFIG_PM
+int bmp18x_enable(struct device *dev);
+int bmp18x_disable(struct device *dev);
+#endif
+
+#endif
diff --git a/drivers/input/misc/isa1200-ff-memless.c b/drivers/input/misc/isa1200-ff-memless.c
index f4e2c35..61f07d0 100644
--- a/drivers/input/misc/isa1200-ff-memless.c
+++ b/drivers/input/misc/isa1200-ff-memless.c
@@ -2,7 +2,7 @@
  * Copyright (C) 2009 Samsung Electronics
  * Kyungmin Park <kyungmin.park@samsung.com>
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c
index dfbfb46..14d2fdd 100644
--- a/drivers/input/misc/pm8xxx-vibrator.c
+++ b/drivers/input/misc/pm8xxx-vibrator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/input/misc/pmic8058-othc.c b/drivers/input/misc/pmic8058-othc.c
index cac748a..d50dbc3 100644
--- a/drivers/input/misc/pmic8058-othc.c
+++ b/drivers/input/misc/pmic8058-othc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/input/misc/pmic8058-vib-memless.c b/drivers/input/misc/pmic8058-vib-memless.c
index ba05400..455b289 100644
--- a/drivers/input/misc/pmic8058-vib-memless.c
+++ b/drivers/input/misc/pmic8058-vib-memless.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index bc51a2a..bc987a6 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -965,5 +965,47 @@
 	default y
 	help
 	  Synaptics Register map TM2000.
-endif
 
+config TOUCHSCREEN_SYNAPTICS_I2C_RMI4
+	tristate "Synaptics DSX I2C touchscreen"
+	depends on I2C
+	help
+	  Say Y here if you have a Synaptics DSX I2C touchscreen
+	  connected to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called synaptics_i2c_rmi4.
+
+config TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV
+	tristate "Synaptics I2C touchscreen rmi device"
+	depends on TOUCHSCREEN_SYNAPTICS_I2C_RMI4
+	help
+	  This enables support for character device channel for Synaptics
+	  RMI4 touchscreens.
+
+	  Say Y here if you have a Synaptics DSX I2C touchscreen
+	  connected to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called synaptics_dsx_rmi4_dev.
+
+config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE
+	tristate "Synaptics I2C touchscreen firmware update"
+	depends on TOUCHSCREEN_SYNAPTICS_I2C_RMI4
+	help
+	  This enables support for firmware update for Synaptics RMI4
+	  touchscreens.
+
+	  Say Y here if you have a Synaptics DSX I2C touchscreen
+	  connected to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called synaptics_dsx_fw_update.
+
+endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index abb9aa2..6d5b4f1 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -82,3 +82,7 @@
 obj-$(CONFIG_TOUCHSCREEN_LGE_COMMON)	+= lge_touch_core.o
 obj-$(CONFIG_TOUCHSCREEN_LGE_SYNAPTICS) += touch_synaptics.o
 obj-$(CONFIG_TOUCHSCREEN_LGE_SYNAPTICS) += touch_synaptics_ds4_fw_upgrade.o
+obj-$(CONFIG_TOUCHSCREEN_FT5X06)	+= ft5x06_ts.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4)		+= synaptics_i2c_rmi4.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV)	+= synaptics_rmi_dev.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE) 	+= synaptics_fw_update.o
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index e696973..ae8ad80 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2010 Samsung Electronics Co.Ltd
  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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
diff --git a/drivers/input/touchscreen/cy8c_ts.c b/drivers/input/touchscreen/cy8c_ts.c
index 88f7d1b..2ee4797 100644
--- a/drivers/input/touchscreen/cy8c_ts.c
+++ b/drivers/input/touchscreen/cy8c_ts.c
@@ -3,7 +3,7 @@
  * drivers/input/touchscreen/cy8c_ts.c
  *
  * Copyright (C) 2009, 2010 Cypress Semiconductor, Inc.
- * Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012 The Linux Foundation. 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
diff --git a/drivers/input/touchscreen/cyttsp-i2c-qc.c b/drivers/input/touchscreen/cyttsp-i2c-qc.c
index f96348e..6604268 100644
--- a/drivers/input/touchscreen/cyttsp-i2c-qc.c
+++ b/drivers/input/touchscreen/cyttsp-i2c-qc.c
@@ -2879,17 +2879,17 @@
 
 	cyttsp_debug("Wake Up\n");
 
-	if (ts->is_suspended == false) {
-		pr_err("%s: in wakeup state\n", __func__);
-		return 0;
-	}
-
 	if (device_may_wakeup(dev)) {
 		if (ts->client->irq)
 			disable_irq_wake(ts->client->irq);
 		return 0;
 	}
 
+	if (ts->is_suspended == false) {
+		pr_err("%s: in wakeup state\n", __func__);
+		return 0;
+	}
+
 	/* re-enable the interrupt prior to wake device */
 	if (ts->client->irq)
 		enable_irq(ts->client->irq);
@@ -2950,6 +2950,12 @@
 
 	cyttsp_debug("Enter Sleep\n");
 
+	if (device_may_wakeup(dev)) {
+		if (ts->client->irq)
+			enable_irq_wake(ts->client->irq);
+		return 0;
+	}
+
 	if (ts->is_suspended == true) {
 		pr_err("%s: in sleep state\n", __func__);
 		return 0;
@@ -2964,11 +2970,6 @@
 	}
 	mutex_unlock(&ts->mutex);
 
-	if (device_may_wakeup(dev)) {
-		if (ts->client->irq)
-			enable_irq_wake(ts->client->irq);
-		return 0;
-	}
 
 	if (ts->client->irq == 0)
 		del_timer(&ts->timer);
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
index ffeb8fe..f74f2d5 100644
--- a/drivers/input/touchscreen/ft5x06_ts.c
+++ b/drivers/input/touchscreen/ft5x06_ts.c
@@ -3,7 +3,7 @@
  * FocalTech ft5x06 TouchScreen driver.
  *
  * Copyright (c) 2010  Focal tech Ltd.
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/input/touchscreen/msm_touch.c b/drivers/input/touchscreen/msm_touch.c
index 7ba896a..16cda8d 100644
--- a/drivers/input/touchscreen/msm_touch.c
+++ b/drivers/input/touchscreen/msm_touch.c
@@ -1,6 +1,6 @@
 /* drivers/input/touchscreen/msm_touch.c
  *
- * Copyright (c) 2008-2009, 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/input/touchscreen/msm_ts.c b/drivers/input/touchscreen/msm_ts.c
index e66120e..5d6f90d 100644
--- a/drivers/input/touchscreen/msm_ts.c
+++ b/drivers/input/touchscreen/msm_ts.c
@@ -1,7 +1,7 @@
 /* drivers/input/touchscreen/msm_ts.c
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
new file mode 100644
index 0000000..7f94716
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -0,0 +1,1717 @@
+/*
+ * Synaptics RMI4 touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.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/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/firmware.h>
+#include <linux/input/synaptics_dsx.h>
+#include "synaptics_i2c_rmi4.h"
+
+#define DEBUG_FW_UPDATE
+#define SHOW_PROGRESS
+#define FW_IMAGE_NAME "PR1063486-s7301_00000000.img"
+#define MAX_FIRMWARE_ID_LEN 10
+#define FORCE_UPDATE false
+#define INSIDE_FIRMWARE_UPDATE
+
+#define CHECKSUM_OFFSET 0x00
+#define BOOTLOADER_VERSION_OFFSET 0x07
+#define IMAGE_SIZE_OFFSET 0x08
+#define CONFIG_SIZE_OFFSET 0x0C
+#define PRODUCT_ID_OFFSET 0x10
+#define PRODUCT_INFO_OFFSET 0x1E
+#define FW_IMAGE_OFFSET 0x100
+#define PRODUCT_ID_SIZE 10
+
+#define BOOTLOADER_ID_OFFSET 0
+#define FLASH_PROPERTIES_OFFSET 2
+#define BLOCK_SIZE_OFFSET 3
+#define FW_BLOCK_COUNT_OFFSET 5
+
+#define REG_MAP (1 << 0)
+#define UNLOCKED (1 << 1)
+#define HAS_CONFIG_ID (1 << 2)
+#define HAS_PERM_CONFIG (1 << 3)
+#define HAS_BL_CONFIG (1 << 4)
+#define HAS_DISP_CONFIG (1 << 5)
+#define HAS_CTRL1 (1 << 6)
+
+#define BLOCK_NUMBER_OFFSET 0
+#define BLOCK_DATA_OFFSET 2
+
+#define UI_CONFIG_AREA 0x00
+#define PERM_CONFIG_AREA 0x01
+#define BL_CONFIG_AREA 0x02
+#define DISP_CONFIG_AREA 0x03
+
+enum flash_command {
+	CMD_WRITE_FW_BLOCK		= 0x2,
+	CMD_ERASE_ALL			= 0x3,
+	CMD_READ_CONFIG_BLOCK	= 0x5,
+	CMD_WRITE_CONFIG_BLOCK	= 0x6,
+	CMD_ERASE_CONFIG		= 0x7,
+	CMD_ERASE_BL_CONFIG		= 0x9,
+	CMD_ERASE_DISP_CONFIG	= 0xA,
+	CMD_ENABLE_FLASH_PROG	= 0xF,
+};
+
+enum flash_area {
+	NONE,
+	UI_FIRMWARE,
+	CONFIG_AREA
+};
+
+#define SLEEP_MODE_NORMAL (0x00)
+#define SLEEP_MODE_SENSOR_SLEEP (0x01)
+#define SLEEP_MODE_RESERVED0 (0x02)
+#define SLEEP_MODE_RESERVED1 (0x03)
+
+#define ENABLE_WAIT_MS (1 * 1000)
+#define WRITE_WAIT_MS (3 * 1000)
+#define ERASE_WAIT_MS (5 * 1000)
+#define RESET_WAIT_MS (500)
+
+#define SLEEP_TIME_US 50
+
+static ssize_t fwu_sysfs_show_image(struct file *data_file,
+		struct kobject *kobj, struct bin_attribute *attributes,
+		char *buf, loff_t pos, size_t count);
+
+static ssize_t fwu_sysfs_store_image(struct file *data_file,
+		struct kobject *kobj, struct bin_attribute *attributes,
+		char *buf, loff_t pos, size_t count);
+
+static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t fwu_sysfs_write_config_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t fwu_sysfs_read_config_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t fwu_sysfs_config_area_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t fwu_sysfs_image_size_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t fwu_sysfs_block_size_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t fwu_sysfs_config_id_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static int fwu_wait_for_idle(int timeout_ms);
+
+struct image_header {
+	unsigned int checksum;
+	unsigned int image_size;
+	unsigned int config_size;
+	unsigned char options;
+	unsigned char bootloader_version;
+	unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
+	unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE];
+};
+
+struct pdt_properties {
+	union {
+		struct {
+			unsigned char reserved_1:6;
+			unsigned char has_bsr:1;
+			unsigned char reserved_2:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct f01_device_status {
+	union {
+		struct {
+			unsigned char status_code:4;
+			unsigned char reserved:2;
+			unsigned char flash_prog:1;
+			unsigned char unconfigured:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct f01_device_control {
+	union {
+		struct {
+			unsigned char sleep_mode:2;
+			unsigned char nosleep:1;
+			unsigned char reserved:2;
+			unsigned char charger_connected:1;
+			unsigned char report_rate:1;
+			unsigned char configured:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct f34_flash_control {
+	union {
+		struct {
+			unsigned char command:4;
+			unsigned char status:3;
+			unsigned char program_enabled:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct f34_flash_properties {
+	union {
+		struct {
+			unsigned char regmap:1;
+			unsigned char unlocked:1;
+			unsigned char has_configid:1;
+			unsigned char has_perm_config:1;
+			unsigned char has_bl_config:1;
+			unsigned char has_display_config:1;
+			unsigned char has_blob_config:1;
+			unsigned char reserved:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct synaptics_rmi4_fwu_handle {
+	bool initialized;
+	bool force_update;
+	char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
+	unsigned int image_size;
+	unsigned int data_pos;
+	unsigned char intr_mask;
+	unsigned char bootloader_id[2];
+	unsigned char productinfo1;
+	unsigned char productinfo2;
+	unsigned char *ext_data_source;
+	unsigned char *read_config_buf;
+	const unsigned char *firmware_data;
+	const unsigned char *config_data;
+	unsigned short block_size;
+	unsigned short fw_block_count;
+	unsigned short config_block_count;
+	unsigned short perm_config_block_count;
+	unsigned short bl_config_block_count;
+	unsigned short disp_config_block_count;
+	unsigned short config_size;
+	unsigned short config_area;
+	unsigned short addr_f34_flash_control;
+	unsigned short addr_f01_interrupt_register;
+	struct synaptics_rmi4_fn_desc f01_fd;
+	struct synaptics_rmi4_fn_desc f34_fd;
+	struct synaptics_rmi4_exp_fn_ptr *fn_ptr;
+	struct synaptics_rmi4_data *rmi4_data;
+	struct f34_flash_control flash_control;
+	struct f34_flash_properties flash_properties;
+	struct workqueue_struct *fwu_workqueue;
+	struct delayed_work fwu_work;
+};
+
+static struct bin_attribute dev_attr_data = {
+	.attr = {
+		.name = "data",
+		.mode = (S_IRUGO | S_IWUGO),
+	},
+	.size = 0,
+	.read = fwu_sysfs_show_image,
+	.write = fwu_sysfs_store_image,
+};
+
+static struct device_attribute attrs[] = {
+	__ATTR(doreflash, S_IWUGO,
+			synaptics_rmi4_show_error,
+			fwu_sysfs_do_reflash_store),
+	__ATTR(writeconfig, S_IWUGO,
+			synaptics_rmi4_show_error,
+			fwu_sysfs_write_config_store),
+	__ATTR(readconfig, S_IWUGO,
+			synaptics_rmi4_show_error,
+			fwu_sysfs_read_config_store),
+	__ATTR(configarea, S_IWUGO,
+			synaptics_rmi4_show_error,
+			fwu_sysfs_config_area_store),
+	__ATTR(imagesize, S_IWUGO,
+			synaptics_rmi4_show_error,
+			fwu_sysfs_image_size_store),
+	__ATTR(blocksize, S_IRUGO,
+			fwu_sysfs_block_size_show,
+			synaptics_rmi4_store_error),
+	__ATTR(fwblockcount, S_IRUGO,
+			fwu_sysfs_firmware_block_count_show,
+			synaptics_rmi4_store_error),
+	__ATTR(configblockcount, S_IRUGO,
+			fwu_sysfs_configuration_block_count_show,
+			synaptics_rmi4_store_error),
+	__ATTR(permconfigblockcount, S_IRUGO,
+			fwu_sysfs_perm_config_block_count_show,
+			synaptics_rmi4_store_error),
+	__ATTR(blconfigblockcount, S_IRUGO,
+			fwu_sysfs_bl_config_block_count_show,
+			synaptics_rmi4_store_error),
+	__ATTR(dispconfigblockcount, S_IRUGO,
+			fwu_sysfs_disp_config_block_count_show,
+			synaptics_rmi4_store_error),
+	__ATTR(config_id, S_IRUGO,
+			fwu_sysfs_config_id_show,
+			synaptics_rmi4_store_error),
+};
+
+static struct synaptics_rmi4_fwu_handle *fwu;
+
+static struct completion remove_complete;
+
+static unsigned int extract_uint(const unsigned char *ptr)
+{
+	return (unsigned int)ptr[0] +
+			(unsigned int)ptr[1] * 0x100 +
+			(unsigned int)ptr[2] * 0x10000 +
+			(unsigned int)ptr[3] * 0x1000000;
+}
+
+static void parse_header(struct image_header *header,
+		const unsigned char *fw_image)
+{
+	header->checksum = extract_uint(&fw_image[CHECKSUM_OFFSET]);
+	header->bootloader_version = fw_image[BOOTLOADER_VERSION_OFFSET];
+	header->image_size = extract_uint(&fw_image[IMAGE_SIZE_OFFSET]);
+	header->config_size = extract_uint(&fw_image[CONFIG_SIZE_OFFSET]);
+	memcpy(header->product_id, &fw_image[PRODUCT_ID_OFFSET],
+			SYNAPTICS_RMI4_PRODUCT_ID_SIZE);
+	header->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0;
+	memcpy(header->product_info, &fw_image[PRODUCT_INFO_OFFSET],
+			SYNAPTICS_RMI4_PRODUCT_INFO_SIZE);
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&fwu->rmi4_data->i2c_client->dev,
+		"Firwmare size %d, config size %d\n",
+		header->image_size,
+		header->config_size);
+#endif
+	return;
+}
+
+static int fwu_read_f01_device_status(struct f01_device_status *status)
+{
+	int retval;
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f01_fd.data_base_addr,
+			status->data,
+			sizeof(status->data));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to read F01 device status\n",
+				__func__);
+		return retval;
+	}
+
+	return 0;
+}
+
+static int fwu_read_f34_queries(void)
+{
+	int retval;
+	unsigned char count = 4;
+	unsigned char buf[10];
+	struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f34_fd.query_base_addr + BOOTLOADER_ID_OFFSET,
+			fwu->bootloader_id,
+			sizeof(fwu->bootloader_id));
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+				"%s: Failed to read bootloader ID\n",
+				__func__);
+		return retval;
+	}
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f34_fd.query_base_addr + FLASH_PROPERTIES_OFFSET,
+			fwu->flash_properties.data,
+			sizeof(fwu->flash_properties.data));
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+				"%s: Failed to read flash properties\n",
+				__func__);
+		return retval;
+	}
+
+	dev_info(&i2c_client->dev, "%s perm:%d, bl:%d, display:%d\n",
+				__func__,
+				fwu->flash_properties.has_perm_config,
+				fwu->flash_properties.has_bl_config,
+				fwu->flash_properties.has_display_config);
+
+	if (fwu->flash_properties.has_perm_config)
+		count += 2;
+
+	if (fwu->flash_properties.has_bl_config)
+		count += 2;
+
+	if (fwu->flash_properties.has_display_config)
+		count += 2;
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f34_fd.query_base_addr + BLOCK_SIZE_OFFSET,
+			buf,
+			2);
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+				"%s: Failed to read block size info\n",
+				__func__);
+		return retval;
+	}
+
+	batohs(&fwu->block_size, &(buf[0]));
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f34_fd.query_base_addr + FW_BLOCK_COUNT_OFFSET,
+			buf,
+			count);
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+				"%s: Failed to read block count info\n",
+				__func__);
+		return retval;
+	}
+
+	batohs(&fwu->fw_block_count, &(buf[0]));
+	batohs(&fwu->config_block_count, &(buf[2]));
+
+	count = 4;
+
+	if (fwu->flash_properties.has_perm_config) {
+		batohs(&fwu->perm_config_block_count, &(buf[count]));
+		count += 2;
+	}
+
+	if (fwu->flash_properties.has_bl_config) {
+		batohs(&fwu->bl_config_block_count, &(buf[count]));
+		count += 2;
+	}
+
+	if (fwu->flash_properties.has_display_config)
+		batohs(&fwu->disp_config_block_count, &(buf[count]));
+
+	fwu->addr_f34_flash_control = fwu->f34_fd.data_base_addr +
+					BLOCK_DATA_OFFSET +
+					fwu->block_size;
+	return 0;
+}
+
+static int fwu_read_interrupt_status(void)
+{
+	int retval;
+	unsigned char interrupt_status;
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->addr_f01_interrupt_register,
+			&interrupt_status,
+			sizeof(interrupt_status));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to read flash status\n",
+				__func__);
+		return retval;
+	}
+	return interrupt_status;
+}
+
+static int fwu_read_f34_flash_status(void)
+{
+	int retval;
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->addr_f34_flash_control,
+			fwu->flash_control.data,
+			sizeof(fwu->flash_control.data));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to read flash status\n",
+				__func__);
+		return retval;
+	}
+	return 0;
+}
+
+static int fwu_reset_device(void)
+{
+	int retval;
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Reset device\n",
+			__func__);
+#endif
+
+	retval = fwu->rmi4_data->reset_device(fwu->rmi4_data);
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to reset core driver after reflash\n",
+				__func__);
+		return retval;
+	}
+	return 0;
+}
+
+static int fwu_write_f34_command(unsigned char cmd)
+{
+	int retval;
+
+	fwu->flash_control.data[0] = cmd;
+	retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->addr_f34_flash_control,
+			fwu->flash_control.data,
+			sizeof(fwu->flash_control.data));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to write command 0x%02x\n",
+				__func__, fwu->flash_control.data[0]);
+		return retval;
+	}
+	return 0;
+}
+
+static int fwu_wait_for_idle(int timeout_ms)
+{
+	int count = 0;
+	int timeout_count = ((timeout_ms * 1000) / SLEEP_TIME_US) + 1;
+	do {
+		if (fwu->flash_control.command == 0x00)
+			return 0;
+
+		usleep_range(SLEEP_TIME_US, SLEEP_TIME_US + 100);
+	} while (count++ < timeout_count);
+
+	fwu_read_f34_flash_status();
+	if (fwu->flash_control.command == 0x00)
+		return 0;
+
+	dev_err(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Timed out waiting for idle status\n",
+			__func__);
+
+	return -ETIMEDOUT;
+}
+
+static enum flash_area fwu_go_nogo(void)
+{
+	int retval = 0;
+	int index = 0;
+	int deviceFirmwareID;
+	int imageConfigID;
+	int deviceConfigID;
+	unsigned long imageFirmwareID;
+	unsigned char firmware_id[4];
+	unsigned char config_id[4];
+	char *strptr;
+	char *imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
+	enum flash_area flash_area = NONE;
+	struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
+	struct f01_device_status f01_device_status;
+
+	if (fwu->force_update) {
+		flash_area = UI_FIRMWARE;
+		goto exit;
+	}
+
+	retval = fwu_read_f01_device_status(&f01_device_status);
+	if (retval < 0) {
+		flash_area = NONE;
+		goto exit;
+	}
+
+	imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
+
+	/* Force update firmware when device is in bootloader mode */
+	if (f01_device_status.flash_prog) {
+		dev_info(&i2c_client->dev,
+			"%s: In flash prog mode\n",
+			__func__);
+		flash_area = UI_FIRMWARE;
+		goto exit;
+	}
+
+
+	/* device firmware id */
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+				fwu->f01_fd.query_base_addr + 18,
+				firmware_id,
+				sizeof(firmware_id));
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+			"Failed to read firmware ID (code %d).\n", retval);
+		goto exit;
+	}
+	firmware_id[3] = 0;
+	deviceFirmwareID = extract_uint(firmware_id);
+
+	/* .img firmware id */
+	strptr = strstr(FW_IMAGE_NAME, "PR");
+	if (!strptr) {
+		dev_err(&i2c_client->dev,
+			"No valid PR number (PRxxxxxxx)" \
+			"found in image file name...\n");
+		goto exit;
+	}
+
+	strptr += 2;
+	while (strptr[index] >= '0' && strptr[index] <= '9') {
+		imagePR[index] = strptr[index];
+		index++;
+	}
+	imagePR[index] = 0;
+
+	retval = sstrtoul(imagePR, 10, &imageFirmwareID);
+	if (retval ==  -EINVAL) {
+		dev_err(&i2c_client->dev,
+			"invalid image firmware id...\n");
+		goto exit;
+	}
+
+	dev_info(&i2c_client->dev,
+			"Device firmware id %d, .img firmware id %d\n",
+			deviceFirmwareID,
+			(unsigned int)imageFirmwareID);
+	if (imageFirmwareID > deviceFirmwareID) {
+		flash_area = UI_FIRMWARE;
+		goto exit;
+	}
+
+	/* device config id */
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+				fwu->f34_fd.ctrl_base_addr,
+				config_id,
+				sizeof(config_id));
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+			"Failed to read config ID (code %d).\n", retval);
+		flash_area = NONE;
+		goto exit;
+	}
+	deviceConfigID =  extract_uint(config_id);
+
+	dev_info(&i2c_client->dev,
+		"Device config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
+		config_id[0], config_id[1], config_id[2], config_id[3]);
+
+	/* .img config id */
+	dev_info(&i2c_client->dev,
+			".img config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
+			fwu->config_data[0],
+			fwu->config_data[1],
+			fwu->config_data[2],
+			fwu->config_data[3]);
+	imageConfigID =  extract_uint(fwu->config_data);
+
+	if (imageConfigID > deviceConfigID) {
+		flash_area = CONFIG_AREA;
+		goto exit;
+	}
+
+exit:
+	kfree(imagePR);
+	if (flash_area == NONE)
+		dev_info(&i2c_client->dev,
+			"Nothing needs to be updated\n");
+	else
+		dev_info(&i2c_client->dev,
+			"Update %s block\n",
+			flash_area == UI_FIRMWARE ? "UI FW" : "CONFIG");
+	return flash_area;
+}
+
+static int fwu_scan_pdt(void)
+{
+	int retval;
+	unsigned char ii;
+	unsigned char intr_count = 0;
+	unsigned char intr_off;
+	unsigned char intr_src;
+	unsigned short addr;
+	bool f01found = false;
+	bool f34found = false;
+	struct synaptics_rmi4_fn_desc rmi_fd;
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&fwu->rmi4_data->i2c_client->dev, "Scan PDT\n");
+#endif
+
+	for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) {
+		retval = fwu->fn_ptr->read(fwu->rmi4_data,
+					addr,
+					(unsigned char *)&rmi_fd,
+					sizeof(rmi_fd));
+		if (retval < 0)
+			return retval;
+
+		if (rmi_fd.fn_number) {
+			dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+					"%s: Found F%02x\n",
+					__func__, rmi_fd.fn_number);
+			switch (rmi_fd.fn_number) {
+			case SYNAPTICS_RMI4_F01:
+				f01found = true;
+				fwu->f01_fd = rmi_fd;
+				fwu->addr_f01_interrupt_register =
+					fwu->f01_fd.data_base_addr + 1;
+				break;
+			case SYNAPTICS_RMI4_F34:
+				f34found = true;
+				fwu->f34_fd = rmi_fd;
+				fwu->intr_mask = 0;
+				intr_src = rmi_fd.intr_src_count;
+				intr_off = intr_count % 8;
+				for (ii = intr_off;
+						ii < ((intr_src & MASK_3BIT) +
+						intr_off);
+						ii++)
+					fwu->intr_mask |= 1 << ii;
+				break;
+			}
+		} else
+		break;
+
+		intr_count += (rmi_fd.intr_src_count & MASK_3BIT);
+	}
+
+	if (!f01found || !f34found) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to find both F01 and F34\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	fwu_read_interrupt_status();
+	return 0;
+}
+
+static int fwu_write_blocks(unsigned char *block_ptr, unsigned short block_cnt,
+		unsigned char command)
+{
+	int retval;
+	unsigned char block_offset[] = {0, 0};
+	unsigned short block_num;
+	struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client;
+#ifdef SHOW_PROGRESS
+	unsigned int progress = (command == CMD_WRITE_CONFIG_BLOCK) ?
+				10 : 100;
+#endif
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&i2c_client->dev,
+			"%s: Start to update %s blocks\n",
+			__func__,
+			command == CMD_WRITE_CONFIG_BLOCK ?
+			"config" : "firmware");
+#endif
+	retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
+			block_offset,
+			sizeof(block_offset));
+	if (retval < 0) {
+		dev_err(&i2c_client->dev,
+				"%s: Failed to write to block number registers\n",
+				__func__);
+		return retval;
+	}
+
+	for (block_num = 0; block_num < block_cnt; block_num++) {
+#ifdef SHOW_PROGRESS
+		if (block_num % progress == 0)
+			dev_info(&i2c_client->dev,
+					"%s: update %s %3d / %3d\n",
+					__func__,
+					command == CMD_WRITE_CONFIG_BLOCK ?
+					"config" : "firmware",
+					block_num, block_cnt);
+#endif
+		retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
+			block_ptr,
+			fwu->block_size);
+		if (retval < 0) {
+			dev_err(&i2c_client->dev,
+				"%s: Failed to write block data (block %d)\n",
+				__func__, block_num);
+			return retval;
+		}
+
+		retval = fwu_write_f34_command(command);
+		if (retval < 0) {
+			dev_err(&i2c_client->dev,
+					"%s: Failed to write command for block %d\n",
+					__func__, block_num);
+			return retval;
+		}
+
+		retval = fwu_wait_for_idle(WRITE_WAIT_MS);
+		if (retval < 0) {
+			dev_err(&i2c_client->dev,
+					"%s: Failed to wait for idle status (block %d)\n",
+					__func__, block_num);
+			return retval;
+		}
+
+		if (fwu->flash_control.status != 0x00) {
+			dev_err(&i2c_client->dev,
+					"%s: Flash block %d failed, status 0x%02X\n",
+					__func__, block_num, retval);
+			return retval;
+		}
+
+		block_ptr += fwu->block_size;
+	}
+#ifdef SHOW_PROGRESS
+	dev_info(&i2c_client->dev,
+			"%s: update %s %3d / %3d\n",
+			__func__,
+			command == CMD_WRITE_CONFIG_BLOCK ?
+			"config" : "firmware",
+			block_cnt, block_cnt);
+#endif
+	return 0;
+}
+
+static int fwu_write_firmware(void)
+{
+	return fwu_write_blocks((unsigned char *)fwu->firmware_data,
+		fwu->fw_block_count, CMD_WRITE_FW_BLOCK);
+}
+
+static int fwu_write_configuration(void)
+{
+	return fwu_write_blocks((unsigned char *)fwu->config_data,
+		fwu->config_block_count, CMD_WRITE_CONFIG_BLOCK);
+}
+
+static int fwu_write_bootloader_id(void)
+{
+	int retval;
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&fwu->rmi4_data->i2c_client->dev,
+			"Write bootloader ID 0x%02X 0x%02X\n",
+			fwu->bootloader_id[0],
+			fwu->bootloader_id[1]);
+#endif
+	retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
+			fwu->bootloader_id,
+			sizeof(fwu->bootloader_id));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to write bootloader ID\n",
+				__func__);
+		return retval;
+	}
+
+	return 0;
+}
+
+static int fwu_enter_flash_prog(void)
+{
+	int retval;
+	struct f01_device_status f01_device_status;
+	struct f01_device_control f01_device_control;
+
+#ifdef DEBUG_FW_UPDATE
+	dev_info(&fwu->rmi4_data->i2c_client->dev, "Enter bootloader mode\n");
+#endif
+	retval = fwu_read_f01_device_status(&f01_device_status);
+	if (retval < 0)
+		return retval;
+
+	if (f01_device_status.flash_prog) {
+		dev_info(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Already in flash prog mode\n",
+				__func__);
+		return 0;
+	}
+
+	retval = fwu_write_bootloader_id();
+	if (retval < 0)
+		return retval;
+
+	retval = fwu_write_f34_command(CMD_ENABLE_FLASH_PROG);
+	if (retval < 0)
+		return retval;
+
+	retval = fwu_wait_for_idle(ENABLE_WAIT_MS);
+	if (retval < 0)
+		return retval;
+
+	retval = fwu_scan_pdt();
+	if (retval < 0)
+		return retval;
+
+	retval = fwu_read_f01_device_status(&f01_device_status);
+	if (retval < 0)
+		return retval;
+
+	if (!f01_device_status.flash_prog) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Not in flash prog mode\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	retval = fwu_read_f34_queries();
+	if (retval < 0)
+		return retval;
+
+	retval = fwu->fn_ptr->read(fwu->rmi4_data,
+			fwu->f01_fd.ctrl_base_addr,
+			f01_device_control.data,
+			sizeof(f01_device_control.data));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to read F01 device control\n",
+				__func__);
+		return retval;
+	}
+
+	f01_device_control.nosleep = true;
+	f01_device_control.sleep_mode = SLEEP_MODE_NORMAL;
+
+	retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->f01_fd.ctrl_base_addr,
+			f01_device_control.data,
+			sizeof(f01_device_control.data));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to write F01 device control\n",
+				__func__);
+		return retval;
+	}
+
+	return retval;
+}
+
+static int fwu_do_reflash(void)
+{
+	int retval;
+
+	retval = fwu_enter_flash_prog();
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Entered flash prog mode\n",
+			__func__);
+
+	retval = fwu_write_bootloader_id();
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Bootloader ID written\n",
+			__func__);
+
+	retval = fwu_write_f34_command(CMD_ERASE_ALL);
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Erase all command written\n",
+			__func__);
+
+	retval = fwu_wait_for_idle(ERASE_WAIT_MS);
+	if (retval < 0)
+		return retval;
+
+	if (fwu->flash_control.status != 0x00) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Erase all command failed, status 0x%02X\n",
+				__func__, retval);
+		return -1;
+	}
+
+	if (fwu->firmware_data) {
+		retval = fwu_write_firmware();
+		if (retval < 0)
+			return retval;
+		pr_notice("%s: Firmware programmed\n", __func__);
+	}
+
+	if (fwu->config_data) {
+		retval = fwu_write_configuration();
+		if (retval < 0)
+			return retval;
+		pr_notice("%s: Configuration programmed\n", __func__);
+	}
+
+	return retval;
+}
+
+static int fwu_do_write_config(void)
+{
+	int retval;
+
+	retval = fwu_enter_flash_prog();
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Entered flash prog mode\n",
+			__func__);
+
+	if (fwu->config_area == PERM_CONFIG_AREA) {
+		fwu->config_block_count = fwu->perm_config_block_count;
+		goto write_config;
+	}
+
+	retval = fwu_write_bootloader_id();
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Bootloader ID written\n",
+			__func__);
+
+	switch (fwu->config_area) {
+	case UI_CONFIG_AREA:
+		retval = fwu_write_f34_command(CMD_ERASE_CONFIG);
+		break;
+	case BL_CONFIG_AREA:
+		retval = fwu_write_f34_command(CMD_ERASE_BL_CONFIG);
+		fwu->config_block_count = fwu->bl_config_block_count;
+		break;
+	case DISP_CONFIG_AREA:
+		retval = fwu_write_f34_command(CMD_ERASE_DISP_CONFIG);
+		fwu->config_block_count = fwu->disp_config_block_count;
+		break;
+	}
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Erase command written\n",
+			__func__);
+
+	retval = fwu_wait_for_idle(ERASE_WAIT_MS);
+	if (retval < 0)
+		return retval;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Idle status detected\n",
+			__func__);
+
+write_config:
+	retval = fwu_write_configuration();
+	if (retval < 0)
+		return retval;
+
+	pr_notice("%s: Config written\n", __func__);
+
+	return retval;
+}
+
+static int fwu_start_write_config(void)
+{
+	int retval;
+	struct image_header header;
+
+	switch (fwu->config_area) {
+	case UI_CONFIG_AREA:
+		break;
+	case PERM_CONFIG_AREA:
+		if (!fwu->flash_properties.has_perm_config)
+			return -EINVAL;
+		break;
+	case BL_CONFIG_AREA:
+		if (!fwu->flash_properties.has_bl_config)
+			return -EINVAL;
+		break;
+	case DISP_CONFIG_AREA:
+		if (!fwu->flash_properties.has_display_config)
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (fwu->ext_data_source)
+		fwu->config_data = fwu->ext_data_source;
+	else
+		return -EINVAL;
+
+	if (fwu->config_area == UI_CONFIG_AREA) {
+		parse_header(&header, fwu->ext_data_source);
+
+		if (header.config_size) {
+			fwu->config_data = fwu->ext_data_source +
+					FW_IMAGE_OFFSET +
+					header.image_size;
+		} else {
+			return -EINVAL;
+		}
+	}
+
+	pr_notice("%s: Start of write config process\n", __func__);
+
+	retval = fwu_do_write_config();
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to write config\n",
+				__func__);
+	}
+
+	fwu->rmi4_data->reset_device(fwu->rmi4_data);
+
+	pr_notice("%s: End of write config process\n", __func__);
+
+	return retval;
+}
+
+static int fwu_do_read_config(void)
+{
+	int retval;
+	unsigned char block_offset[] = {0, 0};
+	unsigned short block_num;
+	unsigned short block_count;
+	unsigned short index = 0;
+
+	retval = fwu_enter_flash_prog();
+	if (retval < 0)
+		goto exit;
+
+	dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+			"%s: Entered flash prog mode\n",
+			__func__);
+
+	switch (fwu->config_area) {
+	case UI_CONFIG_AREA:
+		block_count = fwu->config_block_count;
+		break;
+	case PERM_CONFIG_AREA:
+		if (!fwu->flash_properties.has_perm_config) {
+			retval = -EINVAL;
+			goto exit;
+		}
+		block_count = fwu->perm_config_block_count;
+		break;
+	case BL_CONFIG_AREA:
+		if (!fwu->flash_properties.has_bl_config) {
+			retval = -EINVAL;
+			goto exit;
+		}
+		block_count = fwu->bl_config_block_count;
+		break;
+	case DISP_CONFIG_AREA:
+		if (!fwu->flash_properties.has_display_config) {
+			retval = -EINVAL;
+			goto exit;
+		}
+		block_count = fwu->disp_config_block_count;
+		break;
+	default:
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	fwu->config_size = fwu->block_size * block_count;
+
+	kfree(fwu->read_config_buf);
+	fwu->read_config_buf = kzalloc(fwu->config_size, GFP_KERNEL);
+
+	block_offset[1] |= (fwu->config_area << 5);
+
+	retval = fwu->fn_ptr->write(fwu->rmi4_data,
+			fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET,
+			block_offset,
+			sizeof(block_offset));
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to write to block number registers\n",
+				__func__);
+		goto exit;
+	}
+
+	for (block_num = 0; block_num < block_count; block_num++) {
+		retval = fwu_write_f34_command(CMD_READ_CONFIG_BLOCK);
+		if (retval < 0) {
+			dev_err(&fwu->rmi4_data->i2c_client->dev,
+					"%s: Failed to write read config command\n",
+					__func__);
+			goto exit;
+		}
+
+		retval = fwu_wait_for_idle(WRITE_WAIT_MS);
+		if (retval < 0) {
+			dev_err(&fwu->rmi4_data->i2c_client->dev,
+					"%s: Failed to wait for idle status\n",
+					__func__);
+			goto exit;
+		}
+
+		retval = fwu->fn_ptr->read(fwu->rmi4_data,
+				fwu->f34_fd.data_base_addr + BLOCK_DATA_OFFSET,
+				&fwu->read_config_buf[index],
+				fwu->block_size);
+		if (retval < 0) {
+			dev_err(&fwu->rmi4_data->i2c_client->dev,
+					"%s: Failed to read block data (block %d)\n",
+					__func__, block_num);
+			goto exit;
+		}
+
+		index += fwu->block_size;
+	}
+
+exit:
+	fwu->rmi4_data->reset_device(fwu->rmi4_data);
+
+	return retval;
+}
+
+static int fwu_start_reflash(void)
+{
+	int retval;
+	struct image_header header;
+	const unsigned char *fw_image;
+	const struct firmware *fw_entry = NULL;
+	struct f01_device_status f01_device_status;
+	enum flash_area flash_area;
+
+	pr_notice("%s: Start of reflash process\n", __func__);
+
+	if (fwu->ext_data_source)
+		fw_image = fwu->ext_data_source;
+	else {
+		dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Requesting firmware image %s\n",
+				__func__, FW_IMAGE_NAME);
+
+		retval = request_firmware(&fw_entry, FW_IMAGE_NAME,
+				&fwu->rmi4_data->i2c_client->dev);
+		if (retval != 0) {
+			dev_err(&fwu->rmi4_data->i2c_client->dev,
+					"%s: Firmware image %s not available\n",
+					__func__, FW_IMAGE_NAME);
+			retval = -EINVAL;
+			goto exit;
+		}
+
+		dev_dbg(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Firmware image size = %d\n",
+				__func__, fw_entry->size);
+
+		fw_image = fw_entry->data;
+	}
+
+	parse_header(&header, fw_image);
+
+	if (header.image_size)
+		fwu->firmware_data = fw_image + FW_IMAGE_OFFSET;
+	if (header.config_size) {
+		fwu->config_data = fw_image + FW_IMAGE_OFFSET +
+				header.image_size;
+	}
+
+	if (fwu->ext_data_source)
+		flash_area = UI_FIRMWARE;
+	else
+		flash_area = fwu_go_nogo();
+
+	switch (flash_area) {
+	case NONE:
+		dev_info(&fwu->rmi4_data->i2c_client->dev,
+		"%s: No need to do reflash.\n",
+		__func__);
+		goto exit;
+	case UI_FIRMWARE:
+		retval = fwu_do_reflash();
+		break;
+	case CONFIG_AREA:
+		retval = fwu_do_write_config();
+		break;
+	default:
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Unknown flash area\n",
+				__func__);
+		goto exit;
+	}
+
+	if (retval < 0) {
+		dev_err(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Failed to do reflash\n",
+				__func__);
+	}
+
+	/* reset device */
+	fwu_reset_device();
+
+	/* check device status */
+	retval = fwu_read_f01_device_status(&f01_device_status);
+	if (retval < 0)
+		goto exit;
+
+	dev_info(&fwu->rmi4_data->i2c_client->dev, "Device is in %s mode\n",
+		f01_device_status.flash_prog == 1 ? "bootloader" : "UI");
+	if (f01_device_status.flash_prog)
+		dev_info(&fwu->rmi4_data->i2c_client->dev, "Flash status %d\n",
+				f01_device_status.status_code);
+
+	if (f01_device_status.flash_prog) {
+		dev_info(&fwu->rmi4_data->i2c_client->dev,
+				"%s: Device is in flash prog mode 0x%02X\n",
+				__func__, f01_device_status.status_code);
+		retval = 0;
+		goto exit;
+	}
+
+	if (fw_entry)
+		release_firmware(fw_entry);
+
+	pr_notice("%s: End of reflash process\n", __func__);
+exit:
+	return retval;
+}
+
+int synaptics_fw_updater(unsigned char *fw_data)
+{
+	int retval;
+
+	if (!fwu)
+		return -ENODEV;
+
+	if (!fwu->initialized)
+		return -ENODEV;
+
+	fwu->ext_data_source = fw_data;
+	fwu->config_area = UI_CONFIG_AREA;
+
+	retval = fwu_start_reflash();
+
+	return retval;
+}
+EXPORT_SYMBOL(synaptics_fw_updater);
+
+static ssize_t fwu_sysfs_show_image(struct file *data_file,
+		struct kobject *kobj, struct bin_attribute *attributes,
+		char *buf, loff_t pos, size_t count)
+{
+	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+
+	if (count < fwu->config_size) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Not enough space (%d bytes) in buffer\n",
+				__func__, count);
+		return -EINVAL;
+	}
+
+	memcpy(buf, fwu->read_config_buf, fwu->config_size);
+
+	return fwu->config_size;
+}
+
+static ssize_t fwu_sysfs_store_image(struct file *data_file,
+		struct kobject *kobj, struct bin_attribute *attributes,
+		char *buf, loff_t pos, size_t count)
+{
+	memcpy((void *)(&fwu->ext_data_source[fwu->data_pos]),
+			(const void *)buf,
+			count);
+
+	fwu->data_pos += count;
+
+	return count;
+}
+
+static ssize_t fwu_sysfs_do_reflash_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int input;
+	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+
+	if (sscanf(buf, "%u", &input) != 1) {
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	if (input != 1) {
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	retval = synaptics_fw_updater(fwu->ext_data_source);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to do reflash\n",
+				__func__);
+		goto exit;
+	}
+
+	retval = count;
+
+exit:
+	kfree(fwu->ext_data_source);
+	fwu->ext_data_source = NULL;
+	return retval;
+}
+
+static ssize_t fwu_sysfs_write_config_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int input;
+	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+
+	if (sscanf(buf, "%u", &input) != 1) {
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	if (input != 1) {
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	retval = fwu_start_write_config();
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to write config\n",
+				__func__);
+		goto exit;
+	}
+
+	retval = count;
+
+exit:
+	kfree(fwu->ext_data_source);
+	fwu->ext_data_source = NULL;
+	return retval;
+}
+
+static ssize_t fwu_sysfs_read_config_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int input;
+	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+
+	if (sscanf(buf, "%u", &input) != 1)
+		return -EINVAL;
+
+	if (input != 1)
+		return -EINVAL;
+
+	retval = fwu_do_read_config();
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to read config\n",
+				__func__);
+		return retval;
+	}
+
+	return count;
+}
+
+static ssize_t fwu_sysfs_config_area_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned long config_area;
+
+	retval = kstrtoul(buf, 10, &config_area);
+	if (retval)
+		return retval;
+
+	fwu->config_area = config_area;
+
+	return count;
+}
+
+static ssize_t fwu_sysfs_image_size_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned long size;
+	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+
+	retval = kstrtoul(buf, 10, &size);
+	if (retval)
+		return retval;
+
+	fwu->image_size = size;
+	fwu->data_pos = 0;
+
+	kfree(fwu->ext_data_source);
+	fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL);
+	if (!fwu->ext_data_source) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for image data\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	return count;
+}
+
+static ssize_t fwu_sysfs_block_size_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->block_size);
+}
+
+static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->fw_block_count);
+}
+
+static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->config_block_count);
+}
+
+static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->perm_config_block_count);
+}
+
+static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->bl_config_block_count);
+}
+
+static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fwu->disp_config_block_count);
+}
+
+static ssize_t fwu_sysfs_config_id_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	unsigned char config_id[8];
+	/* device config id */
+	fwu->fn_ptr->read(fwu->rmi4_data,
+				fwu->f34_fd.ctrl_base_addr,
+				config_id,
+				sizeof(config_id));
+
+	return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
+		config_id[0], config_id[1], config_id[2], config_id[3]);
+}
+
+static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
+		unsigned char intr_mask)
+{
+	if (fwu->intr_mask & intr_mask)
+		fwu_read_f34_flash_status();
+
+	return;
+}
+
+static void synaptics_rmi4_fwu_work(struct work_struct *work)
+{
+	fwu_start_reflash();
+}
+
+static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char attr_count;
+	struct pdt_properties pdt_props;
+
+	fwu = kzalloc(sizeof(*fwu), GFP_KERNEL);
+	if (!fwu) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for fwu\n",
+				__func__);
+		goto exit;
+	}
+
+	fwu->fn_ptr = kzalloc(sizeof(*(fwu->fn_ptr)), GFP_KERNEL);
+	if (!fwu->fn_ptr) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for fn_ptr\n",
+				__func__);
+		retval = -ENOMEM;
+		goto exit_free_fwu;
+	}
+
+	fwu->rmi4_data = rmi4_data;
+	fwu->fn_ptr->read = rmi4_data->i2c_read;
+	fwu->fn_ptr->write = rmi4_data->i2c_write;
+	fwu->fn_ptr->enable = rmi4_data->irq_enable;
+
+	retval = fwu->fn_ptr->read(rmi4_data,
+			PDT_PROPS,
+			pdt_props.data,
+			sizeof(pdt_props.data));
+	if (retval < 0) {
+		dev_dbg(&rmi4_data->i2c_client->dev,
+				"%s: Failed to read PDT properties, assuming 0x00\n",
+				__func__);
+	} else if (pdt_props.has_bsr) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Reflash for LTS not currently supported\n",
+				__func__);
+		goto exit_free_mem;
+	}
+
+	retval = fwu_scan_pdt();
+	if (retval < 0)
+		goto exit_free_mem;
+
+	fwu->productinfo1 = rmi4_data->rmi4_mod_info.product_info[0];
+	fwu->productinfo2 = rmi4_data->rmi4_mod_info.product_info[1];
+
+	memcpy(fwu->product_id, rmi4_data->rmi4_mod_info.product_id_string,
+			SYNAPTICS_RMI4_PRODUCT_ID_SIZE);
+	fwu->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0;
+
+	dev_dbg(&rmi4_data->i2c_client->dev,
+			"%s: F01 product info: 0x%04x 0x%04x\n",
+			__func__, fwu->productinfo1, fwu->productinfo2);
+	dev_dbg(&rmi4_data->i2c_client->dev,
+			"%s: F01 product ID: %s\n",
+			__func__, fwu->product_id);
+
+	retval = fwu_read_f34_queries();
+	if (retval < 0)
+		goto exit_free_mem;
+
+	fwu->initialized = true;
+	fwu->force_update = FORCE_UPDATE;
+
+	retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj,
+			&dev_attr_data);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to create sysfs bin file\n",
+				__func__);
+		goto exit_free_mem;
+	}
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+		retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+		if (retval < 0) {
+			dev_err(&rmi4_data->i2c_client->dev,
+					"%s: Failed to create sysfs attributes\n",
+					__func__);
+			retval = -ENODEV;
+			goto exit_remove_attrs;
+		}
+	}
+
+#ifdef INSIDE_FIRMWARE_UPDATE
+	fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue");
+	INIT_DELAYED_WORK(&fwu->fwu_work, synaptics_rmi4_fwu_work);
+	queue_delayed_work(fwu->fwu_workqueue,
+			&fwu->fwu_work,
+			msecs_to_jiffies(1000));
+#endif
+	return 0;
+
+exit_remove_attrs:
+for (attr_count--; attr_count >= 0; attr_count--) {
+	sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+			&attrs[attr_count].attr);
+}
+
+sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
+
+exit_free_mem:
+	kfree(fwu->fn_ptr);
+
+exit_free_fwu:
+	kfree(fwu);
+
+exit:
+	return 0;
+}
+
+static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data)
+{
+	unsigned char attr_count;
+
+	sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data);
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+		sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+	}
+
+	kfree(fwu->fn_ptr);
+	kfree(fwu);
+
+	complete(&remove_complete);
+
+	return;
+}
+
+static int __init rmi4_fw_update_module_init(void)
+{
+	synaptics_rmi4_new_function(RMI_FW_UPDATER, true,
+			synaptics_rmi4_fwu_init,
+			synaptics_rmi4_fwu_remove,
+			synaptics_rmi4_fwu_attn);
+	return 0;
+}
+
+static void __exit rmi4_fw_update_module_exit(void)
+{
+	init_completion(&remove_complete);
+	synaptics_rmi4_new_function(RMI_FW_UPDATER, false,
+			synaptics_rmi4_fwu_init,
+			synaptics_rmi4_fwu_remove,
+			synaptics_rmi4_fwu_attn);
+	wait_for_completion(&remove_complete);
+	return;
+}
+
+module_init(rmi4_fw_update_module_init);
+module_exit(rmi4_fw_update_module_exit);
+
+MODULE_AUTHOR("Synaptics, Inc.");
+MODULE_DESCRIPTION("RMI4 FW Update Module");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
new file mode 100644
index 0000000..775d62a
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -0,0 +1,2453 @@
+/*
+ * Synaptics RMI4 touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
+ * Copyright (c) 2013, The Linux Foundation. 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/input/synaptics_dsx.h>
+#include <linux/of_gpio.h>
+#include "synaptics_i2c_rmi4.h"
+#include <linux/input/mt.h>
+
+#define DRIVER_NAME "synaptics_rmi4_i2c"
+#define INPUT_PHYS_NAME "synaptics_rmi4_i2c/input0"
+#define TYPE_B_PROTOCOL
+
+#define NO_0D_WHILE_2D
+/*
+#define REPORT_2D_Z
+*/
+#define REPORT_2D_W
+
+#define RPT_TYPE (1 << 0)
+#define RPT_X_LSB (1 << 1)
+#define RPT_X_MSB (1 << 2)
+#define RPT_Y_LSB (1 << 3)
+#define RPT_Y_MSB (1 << 4)
+#define RPT_Z (1 << 5)
+#define RPT_WX (1 << 6)
+#define RPT_WY (1 << 7)
+#define RPT_DEFAULT (RPT_TYPE | RPT_X_LSB | RPT_X_MSB | RPT_Y_LSB | RPT_Y_MSB)
+
+#define EXP_FN_DET_INTERVAL 1000 /* ms */
+#define POLLING_PERIOD 1 /* ms */
+#define SYN_I2C_RETRY_TIMES 10
+#define MAX_ABS_MT_TOUCH_MAJOR 15
+
+#define F01_STD_QUERY_LEN 21
+#define F01_BUID_ID_OFFSET 18
+#define F11_STD_QUERY_LEN 9
+#define F11_STD_CTRL_LEN 10
+#define F11_STD_DATA_LEN 12
+
+#define NORMAL_OPERATION (0 << 0)
+#define SENSOR_SLEEP (1 << 0)
+#define NO_SLEEP_OFF (0 << 3)
+#define NO_SLEEP_ON (1 << 3)
+
+#define RMI4_VTG_MIN_UV		2700000
+#define RMI4_VTG_MAX_UV		3300000
+#define RMI4_ACTIVE_LOAD_UA	15000
+#define RMI4_LPM_LOAD_UA	10
+
+#define RMI4_I2C_VTG_MIN_UV	1800000
+#define RMI4_I2C_VTG_MAX_UV	1800000
+#define RMI4_I2C_LOAD_UA	10000
+#define RMI4_I2C_LPM_LOAD_UA	10
+
+#define RMI4_GPIO_SLEEP_LOW_US 10000
+#define RMI4_GPIO_WAIT_HIGH_MS 25
+
+static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data,
+		unsigned short addr, unsigned char *data,
+		unsigned short length);
+
+static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data,
+		unsigned short addr, unsigned char *data,
+		unsigned short length);
+
+static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static void synaptics_rmi4_early_suspend(struct early_suspend *h);
+
+static void synaptics_rmi4_late_resume(struct early_suspend *h);
+
+static int synaptics_rmi4_suspend(struct device *dev);
+
+static int synaptics_rmi4_resume(struct device *dev);
+#endif
+
+static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+struct synaptics_rmi4_f01_device_status {
+	union {
+		struct {
+			unsigned char status_code:4;
+			unsigned char reserved:2;
+			unsigned char flash_prog:1;
+			unsigned char unconfigured:1;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct synaptics_rmi4_f1a_query {
+	union {
+		struct {
+			unsigned char max_button_count:3;
+			unsigned char reserved:5;
+			unsigned char has_general_control:1;
+			unsigned char has_interrupt_enable:1;
+			unsigned char has_multibutton_select:1;
+			unsigned char has_tx_rx_map:1;
+			unsigned char has_perbutton_threshold:1;
+			unsigned char has_release_threshold:1;
+			unsigned char has_strongestbtn_hysteresis:1;
+			unsigned char has_filter_strength:1;
+		} __packed;
+		unsigned char data[2];
+	};
+};
+
+struct synaptics_rmi4_f1a_control_0 {
+	union {
+		struct {
+			unsigned char multibutton_report:2;
+			unsigned char filter_mode:2;
+			unsigned char reserved:4;
+		} __packed;
+		unsigned char data[1];
+	};
+};
+
+struct synaptics_rmi4_f1a_control_3_4 {
+	unsigned char transmitterbutton;
+	unsigned char receiverbutton;
+};
+
+struct synaptics_rmi4_f1a_control {
+	struct synaptics_rmi4_f1a_control_0 general_control;
+	unsigned char *button_int_enable;
+	unsigned char *multi_button;
+	struct synaptics_rmi4_f1a_control_3_4 *electrode_map;
+	unsigned char *button_threshold;
+	unsigned char button_release_threshold;
+	unsigned char strongest_button_hysteresis;
+	unsigned char filter_strength;
+};
+
+struct synaptics_rmi4_f1a_handle {
+	int button_bitmask_size;
+	unsigned char button_count;
+	unsigned char valid_button_count;
+	unsigned char *button_data_buffer;
+	unsigned char *button_map;
+	struct synaptics_rmi4_f1a_query button_query;
+	struct synaptics_rmi4_f1a_control button_control;
+};
+
+struct synaptics_rmi4_exp_fn {
+	enum exp_fn fn_type;
+	bool inserted;
+	int (*func_init)(struct synaptics_rmi4_data *rmi4_data);
+	void (*func_remove)(struct synaptics_rmi4_data *rmi4_data);
+	void (*func_attn)(struct synaptics_rmi4_data *rmi4_data,
+			unsigned char intr_mask);
+	struct list_head link;
+};
+
+static struct device_attribute attrs[] = {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	__ATTR(full_pm_cycle, (S_IRUGO | S_IWUGO),
+			synaptics_rmi4_full_pm_cycle_show,
+			synaptics_rmi4_full_pm_cycle_store),
+#endif
+	__ATTR(reset, S_IWUGO,
+			synaptics_rmi4_show_error,
+			synaptics_rmi4_f01_reset_store),
+	__ATTR(productinfo, S_IRUGO,
+			synaptics_rmi4_f01_productinfo_show,
+			synaptics_rmi4_store_error),
+	__ATTR(buildid, S_IRUGO,
+			synaptics_rmi4_f01_buildid_show,
+			synaptics_rmi4_store_error),
+	__ATTR(flashprog, S_IRUGO,
+			synaptics_rmi4_f01_flashprog_show,
+			synaptics_rmi4_store_error),
+	__ATTR(0dbutton, (S_IRUGO | S_IWUGO),
+			synaptics_rmi4_0dbutton_show,
+			synaptics_rmi4_0dbutton_store),
+};
+
+static bool exp_fn_inited;
+static struct mutex exp_fn_list_mutex;
+static struct list_head exp_fn_list;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			rmi4_data->full_pm_cycle);
+}
+
+static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	if (sscanf(buf, "%u", &input) != 1)
+		return -EINVAL;
+
+	rmi4_data->full_pm_cycle = input > 0 ? 1 : 0;
+
+	return count;
+}
+#endif
+
+static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int reset;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	if (sscanf(buf, "%u", &reset) != 1)
+		return -EINVAL;
+
+	if (reset != 1)
+		return -EINVAL;
+
+	retval = synaptics_rmi4_reset_device(rmi4_data);
+	if (retval < 0) {
+		dev_err(dev,
+				"%s: Failed to issue reset command, error = %d\n",
+				__func__, retval);
+		return retval;
+	}
+
+	return count;
+}
+
+static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "0x%02x 0x%02x\n",
+			(rmi4_data->rmi4_mod_info.product_info[0]),
+			(rmi4_data->rmi4_mod_info.product_info[1]));
+}
+
+static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	unsigned int build_id;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	build_id = (unsigned int)rmi->build_id[0] +
+			(unsigned int)rmi->build_id[1] * 0x100 +
+			(unsigned int)rmi->build_id[2] * 0x10000;
+
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			build_id);
+}
+
+static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int retval;
+	struct synaptics_rmi4_f01_device_status device_status;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_data_base_addr,
+			device_status.data,
+			sizeof(device_status.data));
+	if (retval < 0) {
+		dev_err(dev,
+				"%s: Failed to read device status, error = %d\n",
+				__func__, retval);
+		return retval;
+	}
+
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			device_status.flash_prog);
+}
+
+static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			rmi4_data->button_0d_enabled);
+}
+
+static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int input;
+	unsigned char ii;
+	unsigned char intr_enable;
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	if (sscanf(buf, "%u", &input) != 1)
+		return -EINVAL;
+
+	input = input > 0 ? 1 : 0;
+
+	if (rmi4_data->button_0d_enabled == input)
+		return count;
+
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) {
+				ii = fhandler->intr_reg_num;
+
+				retval = synaptics_rmi4_i2c_read(rmi4_data,
+						rmi4_data->f01_ctrl_base_addr +
+						1 + ii,
+						&intr_enable,
+						sizeof(intr_enable));
+				if (retval < 0)
+					return retval;
+
+				if (input == 1)
+					intr_enable |= fhandler->intr_mask;
+				else
+					intr_enable &= ~fhandler->intr_mask;
+
+				retval = synaptics_rmi4_i2c_write(rmi4_data,
+						rmi4_data->f01_ctrl_base_addr +
+						1 + ii,
+						&intr_enable,
+						sizeof(intr_enable));
+				if (retval < 0)
+					return retval;
+			}
+		}
+	}
+
+	rmi4_data->button_0d_enabled = input;
+
+	return count;
+}
+
+ /**
+ * synaptics_rmi4_set_page()
+ *
+ * Called by synaptics_rmi4_i2c_read() and synaptics_rmi4_i2c_write().
+ *
+ * This function writes to the page select register to switch to the
+ * assigned page.
+ */
+static int synaptics_rmi4_set_page(struct synaptics_rmi4_data *rmi4_data,
+		unsigned int address)
+{
+	int retval = 0;
+	unsigned char retry;
+	unsigned char buf[PAGE_SELECT_LEN];
+	unsigned char page;
+	struct i2c_client *i2c = rmi4_data->i2c_client;
+
+	page = ((address >> 8) & MASK_8BIT);
+	if (page != rmi4_data->current_page) {
+		buf[0] = MASK_8BIT;
+		buf[1] = page;
+		for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
+			retval = i2c_master_send(i2c, buf, PAGE_SELECT_LEN);
+			if (retval != PAGE_SELECT_LEN) {
+				dev_err(&i2c->dev,
+						"%s: I2C retry %d\n",
+						__func__, retry + 1);
+				msleep(20);
+			} else {
+				rmi4_data->current_page = page;
+				break;
+			}
+		}
+	} else
+		return PAGE_SELECT_LEN;
+	return (retval == PAGE_SELECT_LEN) ? retval : -EIO;
+}
+
+ /**
+ * synaptics_rmi4_i2c_read()
+ *
+ * Called by various functions in this driver, and also exported to
+ * other expansion Function modules such as rmi_dev.
+ *
+ * This function reads data of an arbitrary length from the sensor,
+ * starting from an assigned register address of the sensor, via I2C
+ * with a retry mechanism.
+ */
+static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data,
+		unsigned short addr, unsigned char *data, unsigned short length)
+{
+	int retval;
+	unsigned char retry;
+	unsigned char buf;
+	struct i2c_msg msg[] = {
+		{
+			.addr = rmi4_data->i2c_client->addr,
+			.flags = 0,
+			.len = 1,
+			.buf = &buf,
+		},
+		{
+			.addr = rmi4_data->i2c_client->addr,
+			.flags = I2C_M_RD,
+			.len = length,
+			.buf = data,
+		},
+	};
+
+	buf = addr & MASK_8BIT;
+
+	mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+	retval = synaptics_rmi4_set_page(rmi4_data, addr);
+	if (retval != PAGE_SELECT_LEN)
+		goto exit;
+
+	for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
+		if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 2) == 2) {
+			retval = length;
+			break;
+		}
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: I2C retry %d\n",
+				__func__, retry + 1);
+		msleep(20);
+	}
+
+	if (retry == SYN_I2C_RETRY_TIMES) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: I2C read over retry limit\n",
+				__func__);
+		retval = -EIO;
+	}
+
+exit:
+	mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+	return retval;
+}
+
+ /**
+ * synaptics_rmi4_i2c_write()
+ *
+ * Called by various functions in this driver, and also exported to
+ * other expansion Function modules such as rmi_dev.
+ *
+ * This function writes data of an arbitrary length to the sensor,
+ * starting from an assigned register address of the sensor, via I2C with
+ * a retry mechanism.
+ */
+static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data,
+		unsigned short addr, unsigned char *data, unsigned short length)
+{
+	int retval;
+	unsigned char retry;
+	unsigned char buf[length + 1];
+	struct i2c_msg msg[] = {
+		{
+			.addr = rmi4_data->i2c_client->addr,
+			.flags = 0,
+			.len = length + 1,
+			.buf = buf,
+		}
+	};
+
+	mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+	retval = synaptics_rmi4_set_page(rmi4_data, addr);
+	if (retval != PAGE_SELECT_LEN)
+		goto exit;
+
+	buf[0] = addr & MASK_8BIT;
+	memcpy(&buf[1], &data[0], length);
+
+	for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) {
+		if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 1) == 1) {
+			retval = length;
+			break;
+		}
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: I2C retry %d\n",
+				__func__, retry + 1);
+		msleep(20);
+	}
+
+	if (retry == SYN_I2C_RETRY_TIMES) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: I2C write over retry limit\n",
+				__func__);
+		retval = -EIO;
+	}
+
+exit:
+	mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+	return retval;
+}
+
+ /**
+ * synaptics_rmi4_f11_abs_report()
+ *
+ * Called by synaptics_rmi4_report_touch() when valid Function $11
+ * finger data has been detected.
+ *
+ * This function reads the Function $11 data registers, determines the
+ * status of each finger supported by the Function, processes any
+ * necessary coordinate manipulation, reports the finger data to
+ * the input subsystem, and returns the number of fingers detected.
+ */
+static int synaptics_rmi4_f11_abs_report(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler)
+{
+	int retval;
+	unsigned char touch_count = 0; /* number of touch points */
+	unsigned char reg_index;
+	unsigned char finger;
+	unsigned char fingers_supported;
+	unsigned char num_of_finger_status_regs;
+	unsigned char finger_shift;
+	unsigned char finger_status;
+	unsigned char data_reg_blk_size;
+	unsigned char finger_status_reg[3];
+	unsigned char data[F11_STD_DATA_LEN];
+	unsigned short data_addr;
+	unsigned short data_offset;
+	int x;
+	int y;
+	int wx;
+	int wy;
+
+	/*
+	 * The number of finger status registers is determined by the
+	 * maximum number of fingers supported - 2 bits per finger. So
+	 * the number of finger status registers to read is:
+	 * register_count = ceil(max_num_of_fingers / 4)
+	 */
+	fingers_supported = fhandler->num_of_data_points;
+	num_of_finger_status_regs = (fingers_supported + 3) / 4;
+	data_addr = fhandler->full_addr.data_base;
+	data_reg_blk_size = fhandler->size_of_data_register_block;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			data_addr,
+			finger_status_reg,
+			num_of_finger_status_regs);
+	if (retval < 0)
+		return 0;
+
+	for (finger = 0; finger < fingers_supported; finger++) {
+		reg_index = finger / 4;
+		finger_shift = (finger % 4) * 2;
+		finger_status = (finger_status_reg[reg_index] >> finger_shift)
+				& MASK_2BIT;
+
+		/*
+		 * Each 2-bit finger status field represents the following:
+		 * 00 = finger not present
+		 * 01 = finger present and data accurate
+		 * 10 = finger present but data may be inaccurate
+		 * 11 = reserved
+		 */
+#ifdef TYPE_B_PROTOCOL
+		input_mt_slot(rmi4_data->input_dev, finger);
+		input_mt_report_slot_state(rmi4_data->input_dev,
+				MT_TOOL_FINGER, finger_status != 0);
+#endif
+
+		if (finger_status) {
+			data_offset = data_addr +
+					num_of_finger_status_regs +
+					(finger * data_reg_blk_size);
+			retval = synaptics_rmi4_i2c_read(rmi4_data,
+					data_offset,
+					data,
+					data_reg_blk_size);
+			if (retval < 0)
+				return 0;
+
+			x = (data[0] << 4) | (data[2] & MASK_4BIT);
+			y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT);
+			wx = (data[3] & MASK_4BIT);
+			wy = (data[3] >> 4) & MASK_4BIT;
+
+			if (rmi4_data->board->x_flip)
+				x = rmi4_data->sensor_max_x - x;
+			if (rmi4_data->board->y_flip)
+				y = rmi4_data->sensor_max_y - y;
+
+			dev_dbg(&rmi4_data->i2c_client->dev,
+					"%s: Finger %d:\n"
+					"status = 0x%02x\n"
+					"x = %d\n"
+					"y = %d\n"
+					"wx = %d\n"
+					"wy = %d\n",
+					__func__, finger,
+					finger_status,
+					x, y, wx, wy);
+
+			input_report_abs(rmi4_data->input_dev,
+					ABS_MT_POSITION_X, x);
+			input_report_abs(rmi4_data->input_dev,
+					ABS_MT_POSITION_Y, y);
+
+#ifdef REPORT_2D_W
+			input_report_abs(rmi4_data->input_dev,
+					ABS_MT_TOUCH_MAJOR, max(wx, wy));
+			input_report_abs(rmi4_data->input_dev,
+					ABS_MT_TOUCH_MINOR, min(wx, wy));
+#endif
+#ifndef TYPE_B_PROTOCOL
+			input_mt_sync(rmi4_data->input_dev);
+#endif
+			touch_count++;
+		}
+	}
+
+	input_report_key(rmi4_data->input_dev, BTN_TOUCH, touch_count > 0);
+	input_report_key(rmi4_data->input_dev,
+			BTN_TOOL_FINGER, touch_count > 0);
+
+#ifndef TYPE_B_PROTOCOL
+	if (!touch_count)
+		input_mt_sync(rmi4_data->input_dev);
+#else
+	/* sync after groups of events */
+	#ifdef KERNEL_ABOVE_3_7
+	input_mt_sync_frame(rmi4_data->input_dev);
+	#endif
+#endif
+
+	input_sync(rmi4_data->input_dev);
+
+	return touch_count;
+}
+
+static void synaptics_rmi4_f1a_report(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler)
+{
+	int retval;
+	unsigned char button;
+	unsigned char index;
+	unsigned char shift;
+	unsigned char status;
+	unsigned char *data;
+	unsigned short data_addr = fhandler->full_addr.data_base;
+	struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
+	static unsigned char do_once = 1;
+	static bool current_status[MAX_NUMBER_OF_BUTTONS];
+#ifdef NO_0D_WHILE_2D
+	static bool before_2d_status[MAX_NUMBER_OF_BUTTONS];
+	static bool while_2d_status[MAX_NUMBER_OF_BUTTONS];
+#endif
+
+	if (do_once) {
+		memset(current_status, 0, sizeof(current_status));
+#ifdef NO_0D_WHILE_2D
+		memset(before_2d_status, 0, sizeof(before_2d_status));
+		memset(while_2d_status, 0, sizeof(while_2d_status));
+#endif
+		do_once = 0;
+	}
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			data_addr,
+			f1a->button_data_buffer,
+			f1a->button_bitmask_size);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to read button data registers\n",
+				__func__);
+		return;
+	}
+
+	data = f1a->button_data_buffer;
+
+	for (button = 0; button < f1a->valid_button_count; button++) {
+		index = button / 8;
+		shift = button % 8;
+		status = ((data[index] >> shift) & MASK_1BIT);
+
+		if (current_status[button] == status)
+			continue;
+		else
+			current_status[button] = status;
+
+		dev_dbg(&rmi4_data->i2c_client->dev,
+				"%s: Button %d (code %d) ->%d\n",
+				__func__, button,
+				f1a->button_map[button],
+				status);
+#ifdef NO_0D_WHILE_2D
+		if (rmi4_data->fingers_on_2d == false) {
+			if (status == 1) {
+				before_2d_status[button] = 1;
+			} else {
+				if (while_2d_status[button] == 1) {
+					while_2d_status[button] = 0;
+					continue;
+				} else {
+					before_2d_status[button] = 0;
+				}
+			}
+			input_report_key(rmi4_data->input_dev,
+					f1a->button_map[button],
+					status);
+		} else {
+			if (before_2d_status[button] == 1) {
+				before_2d_status[button] = 0;
+				input_report_key(rmi4_data->input_dev,
+						f1a->button_map[button],
+						status);
+			} else {
+				if (status == 1)
+					while_2d_status[button] = 1;
+				else
+					while_2d_status[button] = 0;
+			}
+		}
+#else
+		input_report_key(rmi4_data->input_dev,
+				f1a->button_map[button],
+				status);
+#endif
+	}
+
+	input_sync(rmi4_data->input_dev);
+
+	return;
+}
+
+ /**
+ * synaptics_rmi4_report_touch()
+ *
+ * Called by synaptics_rmi4_sensor_report().
+ *
+ * This function calls the appropriate finger data reporting function
+ * based on the function handler it receives and returns the number of
+ * fingers detected.
+ */
+static void synaptics_rmi4_report_touch(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler,
+		unsigned char *touch_count)
+{
+	unsigned char touch_count_2d;
+
+	dev_dbg(&rmi4_data->i2c_client->dev,
+			"%s: Function %02x reporting\n",
+			__func__, fhandler->fn_number);
+
+	switch (fhandler->fn_number) {
+	case SYNAPTICS_RMI4_F11:
+		touch_count_2d = synaptics_rmi4_f11_abs_report(rmi4_data,
+				fhandler);
+
+		*touch_count += touch_count_2d;
+
+		if (touch_count_2d)
+			rmi4_data->fingers_on_2d = true;
+		else
+			rmi4_data->fingers_on_2d = false;
+		break;
+
+	case SYNAPTICS_RMI4_F1A:
+		synaptics_rmi4_f1a_report(rmi4_data, fhandler);
+		break;
+
+	default:
+		break;
+	}
+
+	return;
+}
+
+ /**
+ * synaptics_rmi4_sensor_report()
+ *
+ * Called by synaptics_rmi4_irq().
+ *
+ * This function determines the interrupt source(s) from the sensor
+ * and calls synaptics_rmi4_report_touch() with the appropriate
+ * function handler for each function with valid data inputs.
+ */
+static int synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char touch_count = 0;
+	unsigned char intr[MAX_INTR_REGISTERS];
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_exp_fn *exp_fhandler;
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	/*
+	 * Get interrupt status information from F01 Data1 register to
+	 * determine the source(s) that are flagging the interrupt.
+	 */
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_data_base_addr + 1,
+			intr,
+			rmi4_data->num_of_intr_regs);
+	if (retval < 0)
+		return retval;
+
+	/*
+	 * Traverse the function handler list and service the source(s)
+	 * of the interrupt accordingly.
+	 */
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->num_of_data_sources) {
+				if (fhandler->intr_mask &
+						intr[fhandler->intr_reg_num]) {
+					synaptics_rmi4_report_touch(rmi4_data,
+							fhandler, &touch_count);
+				}
+			}
+		}
+	}
+
+	mutex_lock(&exp_fn_list_mutex);
+	if (!list_empty(&exp_fn_list)) {
+		list_for_each_entry(exp_fhandler, &exp_fn_list, link) {
+			if (exp_fhandler->inserted &&
+					(exp_fhandler->func_attn != NULL))
+				exp_fhandler->func_attn(rmi4_data, intr[0]);
+		}
+	}
+	mutex_unlock(&exp_fn_list_mutex);
+
+	return touch_count;
+}
+
+ /**
+ * synaptics_rmi4_irq()
+ *
+ * Called by the kernel when an interrupt occurs (when the sensor
+ * asserts the attention irq).
+ *
+ * This function is the ISR thread and handles the acquisition
+ * and the reporting of finger data when the presence of fingers
+ * is detected.
+ */
+static irqreturn_t synaptics_rmi4_irq(int irq, void *data)
+{
+	struct synaptics_rmi4_data *rmi4_data = data;
+
+	synaptics_rmi4_sensor_report(rmi4_data);
+
+	return IRQ_HANDLED;
+}
+
+static int synaptics_rmi4_parse_dt(struct device *dev,
+				struct synaptics_rmi4_platform_data *rmi4_pdata)
+{
+	struct device_node *np = dev->of_node;
+	struct property *prop;
+	u32 temp_val, num_buttons;
+	u32 button_map[MAX_NUMBER_OF_BUTTONS];
+	int rc, i;
+
+	rmi4_pdata->i2c_pull_up = of_property_read_bool(np,
+			"synaptics,i2c-pull-up");
+	rmi4_pdata->regulator_en = of_property_read_bool(np,
+			"synaptics,reg-en");
+	rmi4_pdata->x_flip = of_property_read_bool(np, "synaptics,x-flip");
+	rmi4_pdata->y_flip = of_property_read_bool(np, "synaptics,y-flip");
+
+	rc = of_property_read_u32(np, "synaptics,panel-x", &temp_val);
+	if (rc && (rc != -EINVAL)) {
+		dev_err(dev, "Unable to read panel X dimension\n");
+		return rc;
+	} else {
+		rmi4_pdata->panel_x = temp_val;
+	}
+
+	rc = of_property_read_u32(np, "synaptics,panel-y", &temp_val);
+	if (rc && (rc != -EINVAL)) {
+		dev_err(dev, "Unable to read panel Y dimension\n");
+		return rc;
+	} else {
+		rmi4_pdata->panel_y = temp_val;
+	}
+
+	/* reset, irq gpio info */
+	rmi4_pdata->reset_gpio = of_get_named_gpio_flags(np,
+			"synaptics,reset-gpio", 0, &rmi4_pdata->reset_flags);
+	rmi4_pdata->irq_gpio = of_get_named_gpio_flags(np,
+			"synaptics,irq-gpio", 0, &rmi4_pdata->irq_flags);
+
+	prop = of_find_property(np, "synaptics,button-map", NULL);
+	if (prop) {
+		num_buttons = prop->length / sizeof(temp_val);
+
+		rmi4_pdata->capacitance_button_map = devm_kzalloc(dev,
+			sizeof(*rmi4_pdata->capacitance_button_map),
+			GFP_KERNEL);
+		if (!rmi4_pdata->capacitance_button_map)
+			return -ENOMEM;
+
+		rmi4_pdata->capacitance_button_map->map = devm_kzalloc(dev,
+			sizeof(*rmi4_pdata->capacitance_button_map->map) *
+			MAX_NUMBER_OF_BUTTONS, GFP_KERNEL);
+		if (!rmi4_pdata->capacitance_button_map->map)
+			return -ENOMEM;
+
+		if (num_buttons <= MAX_NUMBER_OF_BUTTONS) {
+			rc = of_property_read_u32_array(np,
+				"synaptics,button-map", button_map,
+				num_buttons);
+			if (rc) {
+				dev_err(dev, "Unable to read key codes\n");
+				return rc;
+			}
+			for (i = 0; i < num_buttons; i++)
+				rmi4_pdata->capacitance_button_map->map[i] =
+					button_map[i];
+			rmi4_pdata->capacitance_button_map->nbuttons =
+				num_buttons;
+		} else {
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+ /**
+ * synaptics_rmi4_irq_enable()
+ *
+ * Called by synaptics_rmi4_probe() and the power management functions
+ * in this driver and also exported to other expansion Function modules
+ * such as rmi_dev.
+ *
+ * This function handles the enabling and disabling of the attention
+ * irq including the setting up of the ISR thread.
+ */
+static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data,
+		bool enable)
+{
+	int retval = 0;
+	unsigned char intr_status;
+
+	if (enable) {
+		if (rmi4_data->irq_enabled)
+			return retval;
+
+		/* Clear interrupts first */
+		retval = synaptics_rmi4_i2c_read(rmi4_data,
+				rmi4_data->f01_data_base_addr + 1,
+				&intr_status,
+				rmi4_data->num_of_intr_regs);
+		if (retval < 0)
+			return retval;
+
+		retval = request_threaded_irq(rmi4_data->irq, NULL,
+				synaptics_rmi4_irq,
+				rmi4_data->board->irq_flags,
+				DRIVER_NAME, rmi4_data);
+		if (retval < 0) {
+			dev_err(&rmi4_data->i2c_client->dev,
+					"%s: Failed to create irq thread\n",
+					__func__);
+			return retval;
+		}
+
+		rmi4_data->irq_enabled = true;
+	} else {
+		if (rmi4_data->irq_enabled) {
+			disable_irq(rmi4_data->irq);
+			free_irq(rmi4_data->irq, rmi4_data);
+			rmi4_data->irq_enabled = false;
+		}
+	}
+
+	return retval;
+}
+
+ /**
+ * synaptics_rmi4_f11_init()
+ *
+ * Called by synaptics_rmi4_query_device().
+ *
+ * This funtion parses information from the Function 11 registers
+ * and determines the number of fingers supported, x and y data ranges,
+ * offset to the associated interrupt status register, interrupt bit
+ * mask, and gathers finger data acquisition capabilities from the query
+ * registers.
+ */
+static int synaptics_rmi4_f11_init(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler,
+		struct synaptics_rmi4_fn_desc *fd,
+		unsigned int intr_count)
+{
+	int retval;
+	unsigned char ii;
+	unsigned char intr_offset;
+	unsigned char abs_data_size;
+	unsigned char abs_data_blk_size;
+	unsigned char query[F11_STD_QUERY_LEN];
+	unsigned char control[F11_STD_CTRL_LEN];
+
+	fhandler->fn_number = fd->fn_number;
+	fhandler->num_of_data_sources = fd->intr_src_count;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			fhandler->full_addr.query_base,
+			query,
+			sizeof(query));
+	if (retval < 0)
+		return retval;
+
+	/* Maximum number of fingers supported */
+	if ((query[1] & MASK_3BIT) <= 4)
+		fhandler->num_of_data_points = (query[1] & MASK_3BIT) + 1;
+	else if ((query[1] & MASK_3BIT) == 5)
+		fhandler->num_of_data_points = 10;
+
+	rmi4_data->num_of_fingers = fhandler->num_of_data_points;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			fhandler->full_addr.ctrl_base,
+			control,
+			sizeof(control));
+	if (retval < 0)
+		return retval;
+
+	/* Maximum x and y */
+	rmi4_data->sensor_max_x = ((control[6] & MASK_8BIT) << 0) |
+			((control[7] & MASK_4BIT) << 8);
+	rmi4_data->sensor_max_y = ((control[8] & MASK_8BIT) << 0) |
+			((control[9] & MASK_4BIT) << 8);
+	dev_dbg(&rmi4_data->i2c_client->dev,
+			"%s: Function %02x max x = %d max y = %d\n",
+			__func__, fhandler->fn_number,
+			rmi4_data->sensor_max_x,
+			rmi4_data->sensor_max_y);
+
+	fhandler->intr_reg_num = (intr_count + 7) / 8;
+	if (fhandler->intr_reg_num != 0)
+		fhandler->intr_reg_num -= 1;
+
+	/* Set an enable bit for each data source */
+	intr_offset = intr_count % 8;
+	fhandler->intr_mask = 0;
+	for (ii = intr_offset;
+			ii < ((fd->intr_src_count & MASK_3BIT) +
+			intr_offset);
+			ii++)
+		fhandler->intr_mask |= 1 << ii;
+
+	abs_data_size = query[5] & MASK_2BIT;
+	abs_data_blk_size = 3 + (2 * (abs_data_size == 0 ? 1 : 0));
+	fhandler->size_of_data_register_block = abs_data_blk_size;
+
+	return retval;
+}
+
+static int synaptics_rmi4_f1a_alloc_mem(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler)
+{
+	int retval;
+	struct synaptics_rmi4_f1a_handle *f1a;
+
+	f1a = kzalloc(sizeof(*f1a), GFP_KERNEL);
+	if (!f1a) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for function handle\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	fhandler->data = (void *)f1a;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			fhandler->full_addr.query_base,
+			f1a->button_query.data,
+			sizeof(f1a->button_query.data));
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to read query registers\n",
+				__func__);
+		return retval;
+	}
+
+	f1a->button_count = f1a->button_query.max_button_count + 1;
+	f1a->button_bitmask_size = (f1a->button_count + 7) / 8;
+
+	f1a->button_data_buffer = kcalloc(f1a->button_bitmask_size,
+			sizeof(*(f1a->button_data_buffer)), GFP_KERNEL);
+	if (!f1a->button_data_buffer) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for data buffer\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	f1a->button_map = kcalloc(f1a->button_count,
+			sizeof(*(f1a->button_map)), GFP_KERNEL);
+	if (!f1a->button_map) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for button map\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int synaptics_rmi4_capacitance_button_map(
+				struct synaptics_rmi4_data *rmi4_data,
+				struct synaptics_rmi4_fn *fhandler)
+{
+	unsigned char ii;
+	struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
+	const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board;
+
+	if (!pdata->capacitance_button_map) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: capacitance_button_map is" \
+				"NULL in board file\n",
+				__func__);
+		return -ENODEV;
+	} else if (!pdata->capacitance_button_map->map) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Button map is missing in board file\n",
+				__func__);
+		return -ENODEV;
+	} else {
+		if (pdata->capacitance_button_map->nbuttons !=
+			f1a->button_count) {
+			f1a->valid_button_count = min(f1a->button_count,
+				pdata->capacitance_button_map->nbuttons);
+		} else {
+			f1a->valid_button_count = f1a->button_count;
+		}
+
+		for (ii = 0; ii < f1a->valid_button_count; ii++)
+			f1a->button_map[ii] =
+					pdata->capacitance_button_map->map[ii];
+	}
+
+	return 0;
+}
+
+static void synaptics_rmi4_f1a_kfree(struct synaptics_rmi4_fn *fhandler)
+{
+	struct synaptics_rmi4_f1a_handle *f1a = fhandler->data;
+
+	if (f1a) {
+		kfree(f1a->button_data_buffer);
+		kfree(f1a->button_map);
+		kfree(f1a);
+		fhandler->data = NULL;
+	}
+
+	return;
+}
+
+static int synaptics_rmi4_f1a_init(struct synaptics_rmi4_data *rmi4_data,
+		struct synaptics_rmi4_fn *fhandler,
+		struct synaptics_rmi4_fn_desc *fd,
+		unsigned int intr_count)
+{
+	int retval;
+	unsigned char ii;
+	unsigned short intr_offset;
+
+	fhandler->fn_number = fd->fn_number;
+	fhandler->num_of_data_sources = fd->intr_src_count;
+
+	fhandler->intr_reg_num = (intr_count + 7) / 8;
+	if (fhandler->intr_reg_num != 0)
+		fhandler->intr_reg_num -= 1;
+
+	/* Set an enable bit for each data source */
+	intr_offset = intr_count % 8;
+	fhandler->intr_mask = 0;
+	for (ii = intr_offset;
+			ii < ((fd->intr_src_count & MASK_3BIT) +
+			intr_offset);
+			ii++)
+		fhandler->intr_mask |= 1 << ii;
+
+	retval = synaptics_rmi4_f1a_alloc_mem(rmi4_data, fhandler);
+	if (retval < 0)
+		goto error_exit;
+
+	retval = synaptics_rmi4_capacitance_button_map(rmi4_data, fhandler);
+	if (retval < 0)
+		goto error_exit;
+
+	rmi4_data->button_0d_enabled = 1;
+
+	return 0;
+
+error_exit:
+	synaptics_rmi4_f1a_kfree(fhandler);
+
+	return retval;
+}
+
+static int synaptics_rmi4_alloc_fh(struct synaptics_rmi4_fn **fhandler,
+		struct synaptics_rmi4_fn_desc *rmi_fd, int page_number)
+{
+	*fhandler = kmalloc(sizeof(**fhandler), GFP_KERNEL);
+	if (!(*fhandler))
+		return -ENOMEM;
+
+	(*fhandler)->full_addr.data_base =
+			(rmi_fd->data_base_addr |
+			(page_number << 8));
+	(*fhandler)->full_addr.ctrl_base =
+			(rmi_fd->ctrl_base_addr |
+			(page_number << 8));
+	(*fhandler)->full_addr.cmd_base =
+			(rmi_fd->cmd_base_addr |
+			(page_number << 8));
+	(*fhandler)->full_addr.query_base =
+			(rmi_fd->query_base_addr |
+			(page_number << 8));
+
+	return 0;
+}
+
+
+ /**
+ * synaptics_rmi4_query_device_info()
+ *
+ * Called by synaptics_rmi4_query_device().
+ *
+ */
+static int synaptics_rmi4_query_device_info(
+					struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char f01_query[F01_STD_QUERY_LEN];
+	struct synaptics_rmi4_device_info *rmi = &(rmi4_data->rmi4_mod_info);
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_query_base_addr,
+			f01_query,
+			sizeof(f01_query));
+	if (retval < 0)
+		return retval;
+
+	/* RMI Version 4.0 currently supported */
+	rmi->version_major = 4;
+	rmi->version_minor = 0;
+
+	rmi->manufacturer_id = f01_query[0];
+	rmi->product_props = f01_query[1];
+	rmi->product_info[0] = f01_query[2] & MASK_7BIT;
+	rmi->product_info[1] = f01_query[3] & MASK_7BIT;
+	rmi->date_code[0] = f01_query[4] & MASK_5BIT;
+	rmi->date_code[1] = f01_query[5] & MASK_4BIT;
+	rmi->date_code[2] = f01_query[6] & MASK_5BIT;
+	rmi->tester_id = ((f01_query[7] & MASK_7BIT) << 8) |
+			(f01_query[8] & MASK_7BIT);
+	rmi->serial_number = ((f01_query[9] & MASK_7BIT) << 8) |
+			(f01_query[10] & MASK_7BIT);
+	memcpy(rmi->product_id_string, &f01_query[11], 10);
+
+	if (rmi->manufacturer_id != 1) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Non-Synaptics device found, manufacturer ID = %d\n",
+				__func__, rmi->manufacturer_id);
+	}
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_query_base_addr + F01_BUID_ID_OFFSET,
+			rmi->build_id,
+			sizeof(rmi->build_id));
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to read firmware build id (code %d)\n",
+				__func__, retval);
+		return retval;
+	}
+	return retval;
+}
+
+ /**
+ * synaptics_rmi4_query_device()
+ *
+ * Called by synaptics_rmi4_probe().
+ *
+ * This funtion scans the page description table, records the offsets
+ * to the register types of Function $01, sets up the function handlers
+ * for Function $11 and Function $12, determines the number of interrupt
+ * sources from the sensor, adds valid Functions with data inputs to the
+ * Function linked list, parses information from the query registers of
+ * Function $01, and enables the interrupt sources from the valid Functions
+ * with data inputs.
+ */
+static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char ii;
+	unsigned char page_number;
+	unsigned char intr_count = 0;
+	unsigned char data_sources = 0;
+	unsigned short pdt_entry_addr;
+	unsigned short intr_addr;
+	struct synaptics_rmi4_f01_device_status status;
+	struct synaptics_rmi4_fn_desc rmi_fd;
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	INIT_LIST_HEAD(&rmi->support_fn_list);
+
+	/* Scan the page description tables of the pages to service */
+	for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) {
+		for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END;
+				pdt_entry_addr -= PDT_ENTRY_SIZE) {
+			pdt_entry_addr |= (page_number << 8);
+
+			retval = synaptics_rmi4_i2c_read(rmi4_data,
+					pdt_entry_addr,
+					(unsigned char *)&rmi_fd,
+					sizeof(rmi_fd));
+			if (retval < 0)
+				return retval;
+
+			fhandler = NULL;
+
+			if (rmi_fd.fn_number == 0) {
+				dev_dbg(&rmi4_data->i2c_client->dev,
+						"%s: Reached end of PDT\n",
+						__func__);
+				break;
+			}
+
+			dev_dbg(&rmi4_data->i2c_client->dev,
+					"%s: F%02x found (page %d)\n",
+					__func__, rmi_fd.fn_number,
+					page_number);
+
+			switch (rmi_fd.fn_number) {
+			case SYNAPTICS_RMI4_F01:
+				rmi4_data->f01_query_base_addr =
+						rmi_fd.query_base_addr;
+				rmi4_data->f01_ctrl_base_addr =
+						rmi_fd.ctrl_base_addr;
+				rmi4_data->f01_data_base_addr =
+						rmi_fd.data_base_addr;
+				rmi4_data->f01_cmd_base_addr =
+						rmi_fd.cmd_base_addr;
+
+				retval =
+				synaptics_rmi4_query_device_info(rmi4_data);
+				if (retval < 0)
+					return retval;
+
+				retval = synaptics_rmi4_i2c_read(rmi4_data,
+						rmi4_data->f01_data_base_addr,
+						status.data,
+						sizeof(status.data));
+				if (retval < 0)
+					return retval;
+
+				if (status.flash_prog == 1) {
+					pr_notice("%s: In flash prog mode, status = 0x%02x\n",
+							__func__,
+							status.status_code);
+					goto flash_prog_mode;
+				}
+				break;
+
+			case SYNAPTICS_RMI4_F34:
+				retval = synaptics_rmi4_i2c_read(rmi4_data,
+						rmi_fd.ctrl_base_addr,
+						rmi->config_id,
+						sizeof(rmi->config_id));
+				if (retval < 0)
+					return retval;
+				break;
+
+			case SYNAPTICS_RMI4_F11:
+				if (rmi_fd.intr_src_count == 0)
+					break;
+
+				retval = synaptics_rmi4_alloc_fh(&fhandler,
+						&rmi_fd, page_number);
+				if (retval < 0) {
+					dev_err(&rmi4_data->i2c_client->dev,
+							"%s: Failed to alloc for F%d\n",
+							__func__,
+							rmi_fd.fn_number);
+					return retval;
+				}
+
+				retval = synaptics_rmi4_f11_init(rmi4_data,
+						fhandler, &rmi_fd, intr_count);
+				if (retval < 0)
+					return retval;
+				break;
+
+			case SYNAPTICS_RMI4_F1A:
+				if (rmi_fd.intr_src_count == 0)
+					break;
+
+				retval = synaptics_rmi4_alloc_fh(&fhandler,
+						&rmi_fd, page_number);
+				if (retval < 0) {
+					dev_err(&rmi4_data->i2c_client->dev,
+							"%s: Failed to alloc for F%d\n",
+							__func__,
+							rmi_fd.fn_number);
+					return retval;
+				}
+
+				retval = synaptics_rmi4_f1a_init(rmi4_data,
+						fhandler, &rmi_fd, intr_count);
+				if (retval < 0)
+					return retval;
+				break;
+			}
+
+			/* Accumulate the interrupt count */
+			intr_count += (rmi_fd.intr_src_count & MASK_3BIT);
+
+			if (fhandler && rmi_fd.intr_src_count) {
+				list_add_tail(&fhandler->link,
+						&rmi->support_fn_list);
+			}
+		}
+	}
+
+flash_prog_mode:
+	rmi4_data->num_of_intr_regs = (intr_count + 7) / 8;
+	dev_dbg(&rmi4_data->i2c_client->dev,
+			"%s: Number of interrupt registers = %d\n",
+			__func__, rmi4_data->num_of_intr_regs);
+
+	memset(rmi4_data->intr_mask, 0x00, sizeof(rmi4_data->intr_mask));
+
+	/*
+	 * Map out the interrupt bit masks for the interrupt sources
+	 * from the registered function handlers.
+	 */
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link)
+			data_sources += fhandler->num_of_data_sources;
+	}
+	if (data_sources) {
+		if (!list_empty(&rmi->support_fn_list)) {
+			list_for_each_entry(fhandler,
+						&rmi->support_fn_list, link) {
+				if (fhandler->num_of_data_sources) {
+					rmi4_data->intr_mask[fhandler->intr_reg_num] |=
+							fhandler->intr_mask;
+				}
+			}
+		}
+	}
+
+	/* Enable the interrupt sources */
+	for (ii = 0; ii < rmi4_data->num_of_intr_regs; ii++) {
+		if (rmi4_data->intr_mask[ii] != 0x00) {
+			dev_dbg(&rmi4_data->i2c_client->dev,
+					"%s: Interrupt enable mask %d = 0x%02x\n",
+					__func__, ii, rmi4_data->intr_mask[ii]);
+			intr_addr = rmi4_data->f01_ctrl_base_addr + 1 + ii;
+			retval = synaptics_rmi4_i2c_write(rmi4_data,
+					intr_addr,
+					&(rmi4_data->intr_mask[ii]),
+					sizeof(rmi4_data->intr_mask[ii]));
+			if (retval < 0)
+				return retval;
+		}
+	}
+
+	return 0;
+}
+
+static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char command = 0x01;
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	retval = synaptics_rmi4_i2c_write(rmi4_data,
+			rmi4_data->f01_cmd_base_addr,
+			&command,
+			sizeof(command));
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to issue reset command, error = %d\n",
+				__func__, retval);
+		return retval;
+	}
+
+	msleep(100);
+
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+				synaptics_rmi4_f1a_kfree(fhandler);
+			else
+				kfree(fhandler->data);
+			kfree(fhandler);
+		}
+	}
+
+	retval = synaptics_rmi4_query_device(rmi4_data);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to query device\n",
+				__func__);
+		return retval;
+	}
+
+	return 0;
+}
+
+/**
+* synaptics_rmi4_detection_work()
+*
+* Called by the kernel at the scheduled time.
+*
+* This function is a self-rearming work thread that checks for the
+* insertion and removal of other expansion Function modules such as
+* rmi_dev and calls their initialization and removal callback functions
+* accordingly.
+*/
+static void synaptics_rmi4_detection_work(struct work_struct *work)
+{
+	struct synaptics_rmi4_exp_fn *exp_fhandler, *next_list_entry;
+	struct synaptics_rmi4_data *rmi4_data =
+			container_of(work, struct synaptics_rmi4_data,
+			det_work.work);
+
+	mutex_lock(&exp_fn_list_mutex);
+	if (!list_empty(&exp_fn_list)) {
+		list_for_each_entry_safe(exp_fhandler,
+				next_list_entry,
+				&exp_fn_list,
+				link) {
+			if ((exp_fhandler->func_init != NULL) &&
+					(exp_fhandler->inserted == false)) {
+				exp_fhandler->func_init(rmi4_data);
+				exp_fhandler->inserted = true;
+			} else if ((exp_fhandler->func_init == NULL) &&
+					(exp_fhandler->inserted == true)) {
+				exp_fhandler->func_remove(rmi4_data);
+				list_del(&exp_fhandler->link);
+				kfree(exp_fhandler);
+			}
+		}
+	}
+	mutex_unlock(&exp_fn_list_mutex);
+
+	return;
+}
+
+/**
+* synaptics_rmi4_new_function()
+*
+* Called by other expansion Function modules in their module init and
+* module exit functions.
+*
+* This function is used by other expansion Function modules such as
+* rmi_dev to register themselves with the driver by providing their
+* initialization and removal callback function pointers so that they
+* can be inserted or removed dynamically at module init and exit times,
+* respectively.
+*/
+void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert,
+		int (*func_init)(struct synaptics_rmi4_data *rmi4_data),
+		void (*func_remove)(struct synaptics_rmi4_data *rmi4_data),
+		void (*func_attn)(struct synaptics_rmi4_data *rmi4_data,
+		unsigned char intr_mask))
+{
+	struct synaptics_rmi4_exp_fn *exp_fhandler;
+
+	if (!exp_fn_inited) {
+		mutex_init(&exp_fn_list_mutex);
+		INIT_LIST_HEAD(&exp_fn_list);
+		exp_fn_inited = 1;
+	}
+
+	mutex_lock(&exp_fn_list_mutex);
+	if (insert) {
+		exp_fhandler = kzalloc(sizeof(*exp_fhandler), GFP_KERNEL);
+		if (!exp_fhandler) {
+			pr_err("%s: Failed to alloc mem for expansion function\n",
+					__func__);
+			goto exit;
+		}
+		exp_fhandler->fn_type = fn_type;
+		exp_fhandler->func_init = func_init;
+		exp_fhandler->func_attn = func_attn;
+		exp_fhandler->func_remove = func_remove;
+		exp_fhandler->inserted = false;
+		list_add_tail(&exp_fhandler->link, &exp_fn_list);
+	} else {
+		if (!list_empty(&exp_fn_list)) {
+			list_for_each_entry(exp_fhandler, &exp_fn_list, link) {
+				if (exp_fhandler->func_init == func_init) {
+					exp_fhandler->inserted = false;
+					exp_fhandler->func_init = NULL;
+					exp_fhandler->func_attn = NULL;
+					goto exit;
+				}
+			}
+		}
+	}
+
+exit:
+	mutex_unlock(&exp_fn_list_mutex);
+
+	return;
+}
+EXPORT_SYMBOL(synaptics_rmi4_new_function);
+
+
+static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA)
+{
+	return (regulator_count_voltages(reg) > 0) ?
+		regulator_set_optimum_mode(reg, load_uA) : 0;
+}
+
+static int synaptics_rmi4_regulator_configure(struct synaptics_rmi4_data
+						*rmi4_data, bool on)
+{
+	int retval;
+
+	if (on == false)
+		goto hw_shutdown;
+
+	if (rmi4_data->board->regulator_en) {
+		rmi4_data->vdd = regulator_get(&rmi4_data->i2c_client->dev,
+						"vdd");
+		if (IS_ERR(rmi4_data->vdd)) {
+			dev_err(&rmi4_data->i2c_client->dev,
+					"%s: Failed to get vdd regulator\n",
+					__func__);
+			return PTR_ERR(rmi4_data->vdd);
+		}
+
+		if (regulator_count_voltages(rmi4_data->vdd) > 0) {
+			retval = regulator_set_voltage(rmi4_data->vdd,
+				RMI4_VTG_MIN_UV, RMI4_VTG_MAX_UV);
+			if (retval) {
+				dev_err(&rmi4_data->i2c_client->dev,
+					"regulator set_vtg failed retval=%d\n",
+					retval);
+				goto err_set_vtg_vdd;
+			}
+		}
+	}
+
+	if (rmi4_data->board->i2c_pull_up) {
+		rmi4_data->vcc_i2c = regulator_get(&rmi4_data->i2c_client->dev,
+						"vcc_i2c");
+		if (IS_ERR(rmi4_data->vcc_i2c)) {
+			dev_err(&rmi4_data->i2c_client->dev,
+					"%s: Failed to get i2c regulator\n",
+					__func__);
+			retval = PTR_ERR(rmi4_data->vcc_i2c);
+			goto err_get_vtg_i2c;
+		}
+
+		if (regulator_count_voltages(rmi4_data->vcc_i2c) > 0) {
+			retval = regulator_set_voltage(rmi4_data->vcc_i2c,
+				RMI4_I2C_VTG_MIN_UV, RMI4_I2C_VTG_MAX_UV);
+			if (retval) {
+				dev_err(&rmi4_data->i2c_client->dev,
+					"reg set i2c vtg failed retval=%d\n",
+					retval);
+			goto err_set_vtg_i2c;
+			}
+		}
+	}
+	return 0;
+
+err_set_vtg_i2c:
+	if (rmi4_data->board->i2c_pull_up)
+		regulator_put(rmi4_data->vcc_i2c);
+err_get_vtg_i2c:
+	if (rmi4_data->board->regulator_en)
+		if (regulator_count_voltages(rmi4_data->vdd) > 0)
+			regulator_set_voltage(rmi4_data->vdd, 0,
+				RMI4_VTG_MAX_UV);
+err_set_vtg_vdd:
+	if (rmi4_data->board->regulator_en)
+		regulator_put(rmi4_data->vdd);
+	return retval;
+
+hw_shutdown:
+	if (rmi4_data->board->regulator_en) {
+		if (regulator_count_voltages(rmi4_data->vdd) > 0)
+			regulator_set_voltage(rmi4_data->vdd, 0,
+				RMI4_VTG_MAX_UV);
+		regulator_put(rmi4_data->vdd);
+	}
+	if (rmi4_data->board->i2c_pull_up) {
+		if (regulator_count_voltages(rmi4_data->vcc_i2c) > 0)
+			regulator_set_voltage(rmi4_data->vcc_i2c, 0,
+					RMI4_I2C_VTG_MAX_UV);
+		regulator_put(rmi4_data->vcc_i2c);
+	}
+	return 0;
+};
+
+static int synaptics_rmi4_power_on(struct synaptics_rmi4_data *rmi4_data,
+					bool on) {
+	int retval;
+
+	if (on == false)
+		goto power_off;
+
+	if (rmi4_data->board->regulator_en) {
+		retval = reg_set_optimum_mode_check(rmi4_data->vdd,
+			RMI4_ACTIVE_LOAD_UA);
+		if (retval < 0) {
+			dev_err(&rmi4_data->i2c_client->dev,
+				"Regulator vdd set_opt failed rc=%d\n",
+				retval);
+			return retval;
+		}
+
+		retval = regulator_enable(rmi4_data->vdd);
+		if (retval) {
+			dev_err(&rmi4_data->i2c_client->dev,
+				"Regulator vdd enable failed rc=%d\n",
+				retval);
+			goto error_reg_en_vdd;
+		}
+	}
+
+	if (rmi4_data->board->i2c_pull_up) {
+		retval = reg_set_optimum_mode_check(rmi4_data->vcc_i2c,
+			RMI4_I2C_LOAD_UA);
+		if (retval < 0) {
+			dev_err(&rmi4_data->i2c_client->dev,
+				"Regulator vcc_i2c set_opt failed rc=%d\n",
+				retval);
+			goto error_reg_opt_i2c;
+		}
+
+		retval = regulator_enable(rmi4_data->vcc_i2c);
+		if (retval) {
+			dev_err(&rmi4_data->i2c_client->dev,
+				"Regulator vcc_i2c enable failed rc=%d\n",
+				retval);
+			goto error_reg_en_vcc_i2c;
+		}
+	}
+	return 0;
+
+error_reg_en_vcc_i2c:
+	if (rmi4_data->board->i2c_pull_up)
+		reg_set_optimum_mode_check(rmi4_data->vdd, 0);
+error_reg_opt_i2c:
+	if (rmi4_data->board->regulator_en)
+		regulator_disable(rmi4_data->vdd);
+error_reg_en_vdd:
+	if (rmi4_data->board->regulator_en)
+		reg_set_optimum_mode_check(rmi4_data->vdd, 0);
+	return retval;
+
+power_off:
+	if (rmi4_data->board->regulator_en) {
+		reg_set_optimum_mode_check(rmi4_data->vdd, 0);
+		regulator_disable(rmi4_data->vdd);
+	}
+	if (rmi4_data->board->i2c_pull_up) {
+		reg_set_optimum_mode_check(rmi4_data->vcc_i2c, 0);
+		regulator_disable(rmi4_data->vcc_i2c);
+	}
+	return 0;
+}
+
+ /**
+ * synaptics_rmi4_probe()
+ *
+ * Called by the kernel when an association with an I2C device of the
+ * same name is made (after doing i2c_add_driver).
+ *
+ * This funtion allocates and initializes the resources for the driver
+ * as an input driver, turns on the power to the sensor, queries the
+ * sensor for its supported Functions and characteristics, registers
+ * the driver to the input subsystem, sets up the interrupt, handles
+ * the registration of the early_suspend and late_resume functions,
+ * and creates a work queue for detection of other expansion Function
+ * modules.
+ */
+static int __devinit synaptics_rmi4_probe(struct i2c_client *client,
+		const struct i2c_device_id *dev_id)
+{
+	int retval = 0;
+	unsigned char ii;
+	unsigned char attr_count;
+	struct synaptics_rmi4_f1a_handle *f1a;
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_data *rmi4_data;
+	struct synaptics_rmi4_device_info *rmi;
+	struct synaptics_rmi4_platform_data *platform_data =
+			client->dev.platform_data;
+
+	if (!i2c_check_functionality(client->adapter,
+			I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev,
+				"%s: SMBus byte data not supported\n",
+				__func__);
+		return -EIO;
+	}
+
+	if (client->dev.of_node) {
+		platform_data = devm_kzalloc(&client->dev,
+			sizeof(*platform_data),
+			GFP_KERNEL);
+		if (!platform_data) {
+			dev_err(&client->dev, "Failed to allocate memory\n");
+			return -ENOMEM;
+		}
+
+		retval = synaptics_rmi4_parse_dt(&client->dev, platform_data);
+		if (retval)
+			return retval;
+	} else {
+		platform_data = client->dev.platform_data;
+	}
+
+	if (!platform_data) {
+		dev_err(&client->dev,
+				"%s: No platform data found\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	rmi4_data = kzalloc(sizeof(*rmi4_data) * 2, GFP_KERNEL);
+	if (!rmi4_data) {
+		dev_err(&client->dev,
+				"%s: Failed to alloc mem for rmi4_data\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	rmi4_data->input_dev = input_allocate_device();
+	if (rmi4_data->input_dev == NULL) {
+		dev_err(&client->dev,
+				"%s: Failed to allocate input device\n",
+				__func__);
+		retval = -ENOMEM;
+		goto err_input_device;
+	}
+
+	rmi4_data->i2c_client = client;
+	rmi4_data->current_page = MASK_8BIT;
+	rmi4_data->board = platform_data;
+	rmi4_data->touch_stopped = false;
+	rmi4_data->sensor_sleep = false;
+	rmi4_data->irq_enabled = false;
+
+	rmi4_data->i2c_read = synaptics_rmi4_i2c_read;
+	rmi4_data->i2c_write = synaptics_rmi4_i2c_write;
+	rmi4_data->irq_enable = synaptics_rmi4_irq_enable;
+	rmi4_data->reset_device = synaptics_rmi4_reset_device;
+
+	rmi4_data->input_dev->name = DRIVER_NAME;
+	rmi4_data->input_dev->phys = INPUT_PHYS_NAME;
+	rmi4_data->input_dev->id.bustype = BUS_I2C;
+	rmi4_data->input_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT;
+	rmi4_data->input_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION;
+	rmi4_data->input_dev->dev.parent = &client->dev;
+	input_set_drvdata(rmi4_data->input_dev, rmi4_data);
+
+	set_bit(EV_SYN, rmi4_data->input_dev->evbit);
+	set_bit(EV_KEY, rmi4_data->input_dev->evbit);
+	set_bit(EV_ABS, rmi4_data->input_dev->evbit);
+	set_bit(BTN_TOUCH, rmi4_data->input_dev->keybit);
+	set_bit(BTN_TOOL_FINGER, rmi4_data->input_dev->keybit);
+
+#ifdef INPUT_PROP_DIRECT
+	set_bit(INPUT_PROP_DIRECT, rmi4_data->input_dev->propbit);
+#endif
+
+	retval = synaptics_rmi4_regulator_configure(rmi4_data, true);
+	if (retval < 0) {
+		dev_err(&client->dev, "Failed to configure regulators\n");
+		goto err_reg_configure;
+	}
+
+	retval = synaptics_rmi4_power_on(rmi4_data, true);
+	if (retval < 0) {
+		dev_err(&client->dev, "Failed to power on\n");
+		goto err_power_device;
+	}
+
+	if (gpio_is_valid(platform_data->irq_gpio)) {
+		/* configure touchscreen irq gpio */
+		retval = gpio_request(platform_data->irq_gpio, "rmi4_irq_gpio");
+		if (retval) {
+			dev_err(&client->dev, "unable to request gpio [%d]\n",
+						platform_data->irq_gpio);
+			goto err_irq_gpio_req;
+		}
+		retval = gpio_direction_input(platform_data->irq_gpio);
+		if (retval) {
+			dev_err(&client->dev,
+				"unable to set direction for gpio [%d]\n",
+				platform_data->irq_gpio);
+			goto err_irq_gpio_dir;
+		}
+	} else {
+		dev_err(&client->dev, "irq gpio not provided\n");
+		goto err_irq_gpio_req;
+	}
+
+	if (gpio_is_valid(platform_data->reset_gpio)) {
+		/* configure touchscreen reset out gpio */
+		retval = gpio_request(platform_data->reset_gpio,
+				"rmi4_reset_gpio");
+		if (retval) {
+			dev_err(&client->dev, "unable to request gpio [%d]\n",
+						platform_data->reset_gpio);
+			goto err_irq_gpio_dir;
+		}
+
+		retval = gpio_direction_output(platform_data->reset_gpio, 1);
+		if (retval) {
+			dev_err(&client->dev,
+				"unable to set direction for gpio [%d]\n",
+				platform_data->reset_gpio);
+			goto err_reset_gpio_dir;
+		}
+
+		gpio_set_value(platform_data->reset_gpio, 0);
+		usleep(RMI4_GPIO_SLEEP_LOW_US);
+		gpio_set_value(platform_data->reset_gpio, 1);
+		msleep(RMI4_GPIO_WAIT_HIGH_MS);
+	}
+
+
+	init_waitqueue_head(&rmi4_data->wait);
+	mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex));
+
+	retval = synaptics_rmi4_query_device(rmi4_data);
+	if (retval < 0) {
+		dev_err(&client->dev,
+				"%s: Failed to query device\n",
+				__func__);
+		goto err_reset_gpio_dir;
+	}
+
+	input_set_abs_params(rmi4_data->input_dev,
+			ABS_MT_POSITION_X, 0,
+			rmi4_data->sensor_max_x, 0, 0);
+	input_set_abs_params(rmi4_data->input_dev,
+			ABS_MT_POSITION_Y, 0,
+			rmi4_data->sensor_max_y, 0, 0);
+#ifdef REPORT_2D_W
+	input_set_abs_params(rmi4_data->input_dev,
+			ABS_MT_TOUCH_MAJOR, 0,
+			MAX_ABS_MT_TOUCH_MAJOR, 0, 0);
+#endif
+
+#ifdef TYPE_B_PROTOCOL
+	input_mt_init_slots(rmi4_data->input_dev,
+			rmi4_data->num_of_fingers);
+#endif
+
+	i2c_set_clientdata(client, rmi4_data);
+
+	f1a = NULL;
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+				f1a = fhandler->data;
+		}
+	}
+
+	if (f1a) {
+		for (ii = 0; ii < f1a->valid_button_count; ii++) {
+			set_bit(f1a->button_map[ii],
+					rmi4_data->input_dev->keybit);
+			input_set_capability(rmi4_data->input_dev,
+					EV_KEY, f1a->button_map[ii]);
+		}
+	}
+
+	retval = input_register_device(rmi4_data->input_dev);
+	if (retval) {
+		dev_err(&client->dev,
+				"%s: Failed to register input device\n",
+				__func__);
+		goto err_register_input;
+	}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	rmi4_data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+	rmi4_data->early_suspend.suspend = synaptics_rmi4_early_suspend;
+	rmi4_data->early_suspend.resume = synaptics_rmi4_late_resume;
+	register_early_suspend(&rmi4_data->early_suspend);
+#endif
+
+	if (!exp_fn_inited) {
+		mutex_init(&exp_fn_list_mutex);
+		INIT_LIST_HEAD(&exp_fn_list);
+		exp_fn_inited = 1;
+	}
+
+	rmi4_data->det_workqueue =
+			create_singlethread_workqueue("rmi_det_workqueue");
+	INIT_DELAYED_WORK(&rmi4_data->det_work,
+			synaptics_rmi4_detection_work);
+	queue_delayed_work(rmi4_data->det_workqueue,
+			&rmi4_data->det_work,
+			msecs_to_jiffies(EXP_FN_DET_INTERVAL));
+
+	rmi4_data->irq = gpio_to_irq(platform_data->irq_gpio);
+
+	retval = synaptics_rmi4_irq_enable(rmi4_data, true);
+	if (retval < 0) {
+		dev_err(&client->dev,
+				"%s: Failed to enable attention interrupt\n",
+				__func__);
+		goto err_enable_irq;
+	}
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+		retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+		if (retval < 0) {
+			dev_err(&client->dev,
+					"%s: Failed to create sysfs attributes\n",
+					__func__);
+			goto err_sysfs;
+		}
+	}
+
+	return retval;
+
+err_sysfs:
+	for (attr_count--; attr_count >= 0; attr_count--) {
+		sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+	}
+
+err_enable_irq:
+	cancel_delayed_work_sync(&rmi4_data->det_work);
+	flush_workqueue(rmi4_data->det_workqueue);
+	destroy_workqueue(rmi4_data->det_workqueue);
+	input_unregister_device(rmi4_data->input_dev);
+
+err_register_input:
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+				synaptics_rmi4_f1a_kfree(fhandler);
+			else
+				kfree(fhandler->data);
+			kfree(fhandler);
+		}
+	}
+err_reset_gpio_dir:
+	if (gpio_is_valid(platform_data->reset_gpio))
+		gpio_free(platform_data->reset_gpio);
+err_irq_gpio_dir:
+	if (gpio_is_valid(platform_data->irq_gpio))
+		gpio_free(platform_data->irq_gpio);
+err_irq_gpio_req:
+	synaptics_rmi4_power_on(rmi4_data, false);
+err_power_device:
+	synaptics_rmi4_regulator_configure(rmi4_data, false);
+err_reg_configure:
+	input_free_device(rmi4_data->input_dev);
+	rmi4_data->input_dev = NULL;
+err_input_device:
+	kfree(rmi4_data);
+
+	return retval;
+}
+
+ /**
+ * synaptics_rmi4_remove()
+ *
+ * Called by the kernel when the association with an I2C device of the
+ * same name is broken (when the driver is unloaded).
+ *
+ * This funtion terminates the work queue, stops sensor data acquisition,
+ * frees the interrupt, unregisters the driver from the input subsystem,
+ * turns off the power to the sensor, and frees other allocated resources.
+ */
+static int __devexit synaptics_rmi4_remove(struct i2c_client *client)
+{
+	unsigned char attr_count;
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client);
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	cancel_delayed_work_sync(&rmi4_data->det_work);
+	flush_workqueue(rmi4_data->det_workqueue);
+	destroy_workqueue(rmi4_data->det_workqueue);
+
+	rmi4_data->touch_stopped = true;
+	wake_up(&rmi4_data->wait);
+
+	synaptics_rmi4_irq_enable(rmi4_data, false);
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+		sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+	}
+
+	input_unregister_device(rmi4_data->input_dev);
+
+	if (!list_empty(&rmi->support_fn_list)) {
+		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
+			if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
+				synaptics_rmi4_f1a_kfree(fhandler);
+			else
+				kfree(fhandler->data);
+			kfree(fhandler);
+		}
+	}
+
+	if (gpio_is_valid(rmi4_data->board->reset_gpio))
+		gpio_free(rmi4_data->board->reset_gpio);
+	if (gpio_is_valid(rmi4_data->board->irq_gpio))
+		gpio_free(rmi4_data->board->irq_gpio);
+
+	synaptics_rmi4_power_on(rmi4_data, false);
+	synaptics_rmi4_regulator_configure(rmi4_data, false);
+
+	kfree(rmi4_data);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+ /**
+ * synaptics_rmi4_sensor_sleep()
+ *
+ * Called by synaptics_rmi4_early_suspend() and synaptics_rmi4_suspend().
+ *
+ * This function stops finger data acquisition and puts the sensor to sleep.
+ */
+static void synaptics_rmi4_sensor_sleep(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char device_ctrl;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_ctrl_base_addr,
+			&device_ctrl,
+			sizeof(device_ctrl));
+	if (retval < 0) {
+		dev_err(&(rmi4_data->input_dev->dev),
+				"%s: Failed to enter sleep mode\n",
+				__func__);
+		rmi4_data->sensor_sleep = false;
+		return;
+	}
+
+	device_ctrl = (device_ctrl & ~MASK_3BIT);
+	device_ctrl = (device_ctrl | NO_SLEEP_OFF | SENSOR_SLEEP);
+
+	retval = synaptics_rmi4_i2c_write(rmi4_data,
+			rmi4_data->f01_ctrl_base_addr,
+			&device_ctrl,
+			sizeof(device_ctrl));
+	if (retval < 0) {
+		dev_err(&(rmi4_data->input_dev->dev),
+				"%s: Failed to enter sleep mode\n",
+				__func__);
+		rmi4_data->sensor_sleep = false;
+		return;
+	} else {
+		rmi4_data->sensor_sleep = true;
+	}
+
+	return;
+}
+
+ /**
+ * synaptics_rmi4_sensor_wake()
+ *
+ * Called by synaptics_rmi4_resume() and synaptics_rmi4_late_resume().
+ *
+ * This function wakes the sensor from sleep.
+ */
+static void synaptics_rmi4_sensor_wake(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	unsigned char device_ctrl;
+
+	retval = synaptics_rmi4_i2c_read(rmi4_data,
+			rmi4_data->f01_ctrl_base_addr,
+			&device_ctrl,
+			sizeof(device_ctrl));
+	if (retval < 0) {
+		dev_err(&(rmi4_data->input_dev->dev),
+				"%s: Failed to wake from sleep mode\n",
+				__func__);
+		rmi4_data->sensor_sleep = true;
+		return;
+	}
+
+	device_ctrl = (device_ctrl & ~MASK_3BIT);
+	device_ctrl = (device_ctrl | NO_SLEEP_OFF | NORMAL_OPERATION);
+
+	retval = synaptics_rmi4_i2c_write(rmi4_data,
+			rmi4_data->f01_ctrl_base_addr,
+			&device_ctrl,
+			sizeof(device_ctrl));
+	if (retval < 0) {
+		dev_err(&(rmi4_data->input_dev->dev),
+				"%s: Failed to wake from sleep mode\n",
+				__func__);
+		rmi4_data->sensor_sleep = true;
+		return;
+	} else {
+		rmi4_data->sensor_sleep = false;
+	}
+
+	return;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ /**
+ * synaptics_rmi4_early_suspend()
+ *
+ * Called by the kernel during the early suspend phase when the system
+ * enters suspend.
+ *
+ * This function calls synaptics_rmi4_sensor_sleep() to stop finger
+ * data acquisition and put the sensor to sleep.
+ */
+static void synaptics_rmi4_early_suspend(struct early_suspend *h)
+{
+	struct synaptics_rmi4_data *rmi4_data =
+			container_of(h, struct synaptics_rmi4_data,
+			early_suspend);
+
+	rmi4_data->touch_stopped = true;
+	wake_up(&rmi4_data->wait);
+	synaptics_rmi4_irq_enable(rmi4_data, false);
+	synaptics_rmi4_sensor_sleep(rmi4_data);
+
+	if (rmi4_data->full_pm_cycle)
+		synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev));
+
+	return;
+}
+
+ /**
+ * synaptics_rmi4_late_resume()
+ *
+ * Called by the kernel during the late resume phase when the system
+ * wakes up from suspend.
+ *
+ * This function goes through the sensor wake process if the system wakes
+ * up from early suspend (without going into suspend).
+ */
+static void synaptics_rmi4_late_resume(struct early_suspend *h)
+{
+	struct synaptics_rmi4_data *rmi4_data =
+			container_of(h, struct synaptics_rmi4_data,
+			early_suspend);
+
+	if (rmi4_data->full_pm_cycle)
+		synaptics_rmi4_resume(&(rmi4_data->input_dev->dev));
+
+	if (rmi4_data->sensor_sleep == true) {
+		synaptics_rmi4_sensor_wake(rmi4_data);
+		rmi4_data->touch_stopped = false;
+		synaptics_rmi4_irq_enable(rmi4_data, true);
+	}
+
+	return;
+}
+#endif
+
+ /**
+ * synaptics_rmi4_suspend()
+ *
+ * Called by the kernel during the suspend phase when the system
+ * enters suspend.
+ *
+ * This function stops finger data acquisition and puts the sensor to
+ * sleep (if not already done so during the early suspend phase),
+ * disables the interrupt, and turns off the power to the sensor.
+ */
+static int synaptics_rmi4_suspend(struct device *dev)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	if (!rmi4_data->sensor_sleep) {
+		rmi4_data->touch_stopped = true;
+		wake_up(&rmi4_data->wait);
+		synaptics_rmi4_irq_enable(rmi4_data, false);
+		synaptics_rmi4_sensor_sleep(rmi4_data);
+	}
+
+	return 0;
+}
+
+ /**
+ * synaptics_rmi4_resume()
+ *
+ * Called by the kernel during the resume phase when the system
+ * wakes up from suspend.
+ *
+ * This function turns on the power to the sensor, wakes the sensor
+ * from sleep, enables the interrupt, and starts finger data
+ * acquisition.
+ */
+static int synaptics_rmi4_resume(struct device *dev)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	synaptics_rmi4_sensor_wake(rmi4_data);
+	rmi4_data->touch_stopped = false;
+	synaptics_rmi4_irq_enable(rmi4_data, true);
+
+	return 0;
+}
+
+static const struct dev_pm_ops synaptics_rmi4_dev_pm_ops = {
+	.suspend = synaptics_rmi4_suspend,
+	.resume  = synaptics_rmi4_resume,
+};
+#endif
+
+static const struct i2c_device_id synaptics_rmi4_id_table[] = {
+	{DRIVER_NAME, 0},
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, synaptics_rmi4_id_table);
+
+#ifdef CONFIG_OF
+static struct of_device_id rmi4_match_table[] = {
+	{ .compatible = "synaptics,rmi4",},
+	{ },
+};
+#else
+#define rmi4_match_table NULL
+#endif
+
+static struct i2c_driver synaptics_rmi4_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = rmi4_match_table,
+#ifdef CONFIG_PM
+		.pm = &synaptics_rmi4_dev_pm_ops,
+#endif
+	},
+	.probe = synaptics_rmi4_probe,
+	.remove = __devexit_p(synaptics_rmi4_remove),
+	.id_table = synaptics_rmi4_id_table,
+};
+
+ /**
+ * synaptics_rmi4_init()
+ *
+ * Called by the kernel during do_initcalls (if built-in)
+ * or when the driver is loaded (if a module).
+ *
+ * This function registers the driver to the I2C subsystem.
+ *
+ */
+static int __init synaptics_rmi4_init(void)
+{
+	return i2c_add_driver(&synaptics_rmi4_driver);
+}
+
+ /**
+ * synaptics_rmi4_exit()
+ *
+ * Called by the kernel when the driver is unloaded.
+ *
+ * This funtion unregisters the driver from the I2C subsystem.
+ *
+ */
+static void __exit synaptics_rmi4_exit(void)
+{
+	i2c_del_driver(&synaptics_rmi4_driver);
+}
+
+module_init(synaptics_rmi4_init);
+module_exit(synaptics_rmi4_exit);
+
+MODULE_AUTHOR("Synaptics, Inc.");
+MODULE_DESCRIPTION("Synaptics RMI4 I2C Touch Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.h b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
new file mode 100644
index 0000000..d13f172
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
@@ -0,0 +1,274 @@
+/*
+ * Synaptics RMI4 touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
+ * Copyright (c) 2013, The Linux Foundation. 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.
+ */
+
+#ifndef _SYNAPTICS_DSX_RMI4_H_
+#define _SYNAPTICS_DSX_RMI4_H_
+
+#define SYNAPTICS_DS4 (1 << 0)
+#define SYNAPTICS_DS5 (1 << 1)
+#define SYNAPTICS_DSX_DRIVER_PRODUCT SYNAPTICS_DS4
+#define SYNAPTICS_DSX_DRIVER_VERSION 0x1002
+
+#include <linux/version.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#define PDT_PROPS (0x00EF)
+#define PDT_START (0x00E9)
+#define PDT_END (0x000A)
+#define PDT_ENTRY_SIZE (0x0006)
+#define PAGES_TO_SERVICE (10)
+#define PAGE_SELECT_LEN (2)
+
+#define SYNAPTICS_RMI4_F01 (0x01)
+#define SYNAPTICS_RMI4_F11 (0x11)
+#define SYNAPTICS_RMI4_F1A (0x1a)
+#define SYNAPTICS_RMI4_F34 (0x34)
+#define SYNAPTICS_RMI4_F54 (0x54)
+#define SYNAPTICS_RMI4_F55 (0x55)
+
+#define SYNAPTICS_RMI4_PRODUCT_INFO_SIZE 2
+#define SYNAPTICS_RMI4_DATE_CODE_SIZE 3
+#define SYNAPTICS_RMI4_PRODUCT_ID_SIZE 10
+#define SYNAPTICS_RMI4_BUILD_ID_SIZE 3
+
+#define MAX_NUMBER_OF_FINGERS 10
+#define MAX_NUMBER_OF_BUTTONS 4
+#define MAX_INTR_REGISTERS 4
+
+#define MASK_16BIT 0xFFFF
+#define MASK_8BIT 0xFF
+#define MASK_7BIT 0x7F
+#define MASK_6BIT 0x3F
+#define MASK_5BIT 0x1F
+#define MASK_4BIT 0x0F
+#define MASK_3BIT 0x07
+#define MASK_2BIT 0x03
+#define MASK_1BIT 0x01
+
+/*
+ * struct synaptics_rmi4_fn_desc - function descriptor fields in PDT
+ * @query_base_addr: base address for query registers
+ * @cmd_base_addr: base address for command registers
+ * @ctrl_base_addr: base address for control registers
+ * @data_base_addr: base address for data registers
+ * @intr_src_count: number of interrupt sources
+ * @fn_number: function number
+ */
+struct synaptics_rmi4_fn_desc {
+	unsigned char query_base_addr;
+	unsigned char cmd_base_addr;
+	unsigned char ctrl_base_addr;
+	unsigned char data_base_addr;
+	unsigned char intr_src_count;
+	unsigned char fn_number;
+};
+
+/*
+ * synaptics_rmi4_fn_full_addr - full 16-bit base addresses
+ * @query_base: 16-bit base address for query registers
+ * @cmd_base: 16-bit base address for data registers
+ * @ctrl_base: 16-bit base address for command registers
+ * @data_base: 16-bit base address for control registers
+ */
+struct synaptics_rmi4_fn_full_addr {
+	unsigned short query_base;
+	unsigned short cmd_base;
+	unsigned short ctrl_base;
+	unsigned short data_base;
+};
+
+/*
+ * struct synaptics_rmi4_fn - function handler data structure
+ * @fn_number: function number
+ * @num_of_data_sources: number of data sources
+ * @num_of_data_points: maximum number of fingers supported
+ * @size_of_data_register_block: data register block size
+ * @data1_offset: offset to data1 register from data base address
+ * @intr_reg_num: index to associated interrupt register
+ * @intr_mask: interrupt mask
+ * @full_addr: full 16-bit base addresses of function registers
+ * @link: linked list for function handlers
+ * @data_size: size of private data
+ * @data: pointer to private data
+ */
+struct synaptics_rmi4_fn {
+	unsigned char fn_number;
+	unsigned char num_of_data_sources;
+	unsigned char num_of_data_points;
+	unsigned char size_of_data_register_block;
+	unsigned char data1_offset;
+	unsigned char intr_reg_num;
+	unsigned char intr_mask;
+	struct synaptics_rmi4_fn_full_addr full_addr;
+	struct list_head link;
+	int data_size;
+	void *data;
+};
+
+/*
+ * struct synaptics_rmi4_device_info - device information
+ * @version_major: rmi protocol major version number
+ * @version_minor: rmi protocol minor version number
+ * @manufacturer_id: manufacturer id
+ * @product_props: product properties information
+ * @product_info: product info array
+ * @date_code: device manufacture date
+ * @tester_id: tester id array
+ * @serial_number: device serial number
+ * @product_id_string: device product id
+ * @support_fn_list: linked list for function handlers
+ */
+struct synaptics_rmi4_device_info {
+	unsigned int version_major;
+	unsigned int version_minor;
+	unsigned char manufacturer_id;
+	unsigned char product_props;
+	unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE];
+	unsigned char date_code[SYNAPTICS_RMI4_DATE_CODE_SIZE];
+	unsigned short tester_id;
+	unsigned short serial_number;
+	unsigned char product_id_string[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
+	unsigned char build_id[SYNAPTICS_RMI4_BUILD_ID_SIZE];
+	unsigned char config_id[3];
+	struct list_head support_fn_list;
+};
+
+/*
+ * struct synaptics_rmi4_data - rmi4 device instance data
+ * @i2c_client: pointer to associated i2c client
+ * @input_dev: pointer to associated input device
+ * @board: constant pointer to platform data
+ * @rmi4_mod_info: device information
+ * @regulator: pointer to associated regulator
+ * @rmi4_io_ctrl_mutex: mutex for i2c i/o control
+ * @det_work: work thread instance for expansion function detection
+ * @det_workqueue: pointer to work queue for work thread instance
+ * @early_suspend: instance to support early suspend power management
+ * @current_page: current page in sensor to acess
+ * @button_0d_enabled: flag for 0d button support
+ * @full_pm_cycle: flag for full power management cycle in early suspend stage
+ * @num_of_intr_regs: number of interrupt registers
+ * @f01_query_base_addr: query base address for f01
+ * @f01_cmd_base_addr: command base address for f01
+ * @f01_ctrl_base_addr: control base address for f01
+ * @f01_data_base_addr: data base address for f01
+ * @irq: attention interrupt
+ * @sensor_max_x: sensor maximum x value
+ * @sensor_max_y: sensor maximum y value
+ * @irq_enabled: flag for indicating interrupt enable status
+ * @touch_stopped: flag to stop interrupt thread processing
+ * @fingers_on_2d: flag to indicate presence of fingers in 2d area
+ * @sensor_sleep: flag to indicate sleep state of sensor
+ * @wait: wait queue for touch data polling in interrupt thread
+ * @i2c_read: pointer to i2c read function
+ * @i2c_write: pointer to i2c write function
+ * @irq_enable: pointer to irq enable function
+ */
+struct synaptics_rmi4_data {
+	struct i2c_client *i2c_client;
+	struct input_dev *input_dev;
+	const struct synaptics_rmi4_platform_data *board;
+	struct synaptics_rmi4_device_info rmi4_mod_info;
+	struct regulator *vdd;
+	struct regulator *vcc_i2c;
+	struct mutex rmi4_io_ctrl_mutex;
+	struct delayed_work det_work;
+	struct workqueue_struct *det_workqueue;
+	struct early_suspend early_suspend;
+	unsigned char current_page;
+	unsigned char button_0d_enabled;
+	unsigned char full_pm_cycle;
+	unsigned char num_of_rx;
+	unsigned char num_of_tx;
+	unsigned char num_of_fingers;
+	unsigned char intr_mask[MAX_INTR_REGISTERS];
+	unsigned short num_of_intr_regs;
+	unsigned short f01_query_base_addr;
+	unsigned short f01_cmd_base_addr;
+	unsigned short f01_ctrl_base_addr;
+	unsigned short f01_data_base_addr;
+	int irq;
+	int sensor_max_x;
+	int sensor_max_y;
+	bool irq_enabled;
+	bool touch_stopped;
+	bool fingers_on_2d;
+	bool sensor_sleep;
+	wait_queue_head_t wait;
+	int (*i2c_read)(struct synaptics_rmi4_data *pdata, unsigned short addr,
+			unsigned char *data, unsigned short length);
+	int (*i2c_write)(struct synaptics_rmi4_data *pdata, unsigned short addr,
+			unsigned char *data, unsigned short length);
+	int (*irq_enable)(struct synaptics_rmi4_data *rmi4_data, bool enable);
+	int (*reset_device)(struct synaptics_rmi4_data *rmi4_data);
+};
+
+enum exp_fn {
+	RMI_DEV = 0,
+	RMI_F34,
+	RMI_F54,
+	RMI_FW_UPDATER,
+	RMI_LAST,
+};
+
+struct synaptics_rmi4_exp_fn_ptr {
+	int (*read)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr,
+			unsigned char *data, unsigned short length);
+	int (*write)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr,
+			unsigned char *data, unsigned short length);
+	int (*enable)(struct synaptics_rmi4_data *rmi4_data, bool enable);
+};
+
+void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert,
+		int (*func_init)(struct synaptics_rmi4_data *rmi4_data),
+		void (*func_remove)(struct synaptics_rmi4_data *rmi4_data),
+		void (*func_attn)(struct synaptics_rmi4_data *rmi4_data,
+				unsigned char intr_mask));
+
+static inline ssize_t synaptics_rmi4_show_error(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	dev_warn(dev, "%s Attempted to read from write-only attribute %s\n",
+			__func__, attr->attr.name);
+	return -EPERM;
+}
+
+static inline ssize_t synaptics_rmi4_store_error(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	dev_warn(dev, "%s Attempted to write to read-only attribute %s\n",
+			__func__, attr->attr.name);
+	return -EPERM;
+}
+
+static inline void batohs(unsigned short *dest, unsigned char *src)
+{
+	*dest = src[1] * 0x100 + src[0];
+}
+
+static inline void hstoba(unsigned char *dest, unsigned short src)
+{
+	dest[0] = src % 0x100;
+	dest[1] = src / 0x100;
+}
+
+#endif
diff --git a/drivers/input/touchscreen/synaptics_rmi_dev.c b/drivers/input/touchscreen/synaptics_rmi_dev.c
new file mode 100644
index 0000000..7f1aac5
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_rmi_dev.c
@@ -0,0 +1,709 @@
+/*
+ * Synaptics RMI4 touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.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/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/uaccess.h>
+#include <linux/cdev.h>
+#include <linux/input/synaptics_dsx.h>
+#include "synaptics_i2c_rmi4.h"
+
+#define CHAR_DEVICE_NAME "rmi"
+#define DEVICE_CLASS_NAME "rmidev"
+#define DEV_NUMBER 1
+#define REG_ADDR_LIMIT 0xFFFF
+
+static ssize_t rmidev_sysfs_open_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t rmidev_sysfs_release_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t rmidev_sysfs_address_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t rmidev_sysfs_length_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t rmidev_sysfs_data_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t rmidev_sysfs_data_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+struct rmidev_handle {
+	dev_t dev_no;
+	unsigned short address;
+	unsigned int length;
+	struct device dev;
+	struct synaptics_rmi4_data *rmi4_data;
+	struct synaptics_rmi4_exp_fn_ptr *fn_ptr;
+	struct kobject *sysfs_dir;
+	void *data;
+};
+
+struct rmidev_data {
+	int ref_count;
+	struct cdev main_dev;
+	struct class *device_class;
+	struct mutex file_mutex;
+	struct rmidev_handle *rmi_dev;
+};
+
+static struct device_attribute attrs[] = {
+	__ATTR(open, S_IWUGO,
+			synaptics_rmi4_show_error,
+			rmidev_sysfs_open_store),
+	__ATTR(release, S_IWUGO,
+			synaptics_rmi4_show_error,
+			rmidev_sysfs_release_store),
+	__ATTR(address, S_IWUGO,
+			synaptics_rmi4_show_error,
+			rmidev_sysfs_address_store),
+	__ATTR(length, S_IWUGO,
+			synaptics_rmi4_show_error,
+			rmidev_sysfs_length_store),
+	__ATTR(data, (S_IRUGO | S_IWUGO),
+			rmidev_sysfs_data_show,
+			rmidev_sysfs_data_store),
+};
+
+static int rmidev_major_num;
+
+static struct class *rmidev_device_class;
+
+static struct rmidev_handle *rmidev;
+
+static struct completion remove_complete;
+
+static ssize_t rmidev_sysfs_open_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+
+	if (sscanf(buf, "%u", &input) != 1)
+			return -EINVAL;
+
+	if (input != 1)
+		return -EINVAL;
+
+	rmidev->fn_ptr->enable(rmidev->rmi4_data, false);
+	dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
+			"%s: Attention interrupt disabled\n",
+			__func__);
+
+	return count;
+}
+
+static ssize_t rmidev_sysfs_release_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+
+	if (sscanf(buf, "%u", &input) != 1)
+			return -EINVAL;
+
+	if (input != 1)
+		return -EINVAL;
+
+	rmidev->fn_ptr->enable(rmidev->rmi4_data, true);
+	dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
+			"%s: Attention interrupt enabled\n",
+			__func__);
+
+	return count;
+}
+
+static ssize_t rmidev_sysfs_address_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+
+	if (sscanf(buf, "%u", &input) != 1)
+			return -EINVAL;
+
+	if (input > REG_ADDR_LIMIT)
+		return -EINVAL;
+
+	rmidev->address = (unsigned short)input;
+
+	return count;
+}
+
+static ssize_t rmidev_sysfs_length_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+
+	if (sscanf(buf, "%u", &input) != 1)
+			return -EINVAL;
+
+	if (input > REG_ADDR_LIMIT)
+		return -EINVAL;
+
+	rmidev->length = input;
+
+	return count;
+}
+
+static ssize_t rmidev_sysfs_data_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int retval;
+	unsigned int data_length = rmidev->length;
+
+	if (data_length > (REG_ADDR_LIMIT - rmidev->address))
+		data_length = REG_ADDR_LIMIT - rmidev->address;
+
+	if (data_length) {
+		retval = rmidev->fn_ptr->read(rmidev->rmi4_data,
+				rmidev->address,
+				(unsigned char *)buf,
+				data_length);
+		if (retval < 0) {
+			dev_err(&rmidev->rmi4_data->i2c_client->dev,
+					"%s: Failed to read data\n",
+					__func__);
+			return retval;
+		}
+	} else {
+		return -EINVAL;
+	}
+
+	return data_length;
+}
+
+static ssize_t rmidev_sysfs_data_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	int retval;
+	unsigned int data_length = rmidev->length;
+
+	if (data_length > (REG_ADDR_LIMIT - rmidev->address))
+		data_length = REG_ADDR_LIMIT - rmidev->address;
+
+	if (data_length) {
+		retval = rmidev->fn_ptr->write(rmidev->rmi4_data,
+				rmidev->address,
+				(unsigned char *)buf,
+				data_length);
+		if (retval < 0) {
+			dev_err(&rmidev->rmi4_data->i2c_client->dev,
+					"%s: Failed to write data\n",
+					__func__);
+			return retval;
+		}
+	} else {
+		return -EINVAL;
+	}
+
+	return data_length;
+}
+
+/*
+ * rmidev_llseek - used to set up register address
+ *
+ * @filp: file structure for seek
+ * @off: offset
+ *   if whence == SEEK_SET,
+ *     high 16 bits: page address
+ *     low 16 bits: register address
+ *   if whence == SEEK_CUR,
+ *     offset from current position
+ *   if whence == SEEK_END,
+ *     offset from end position (0xFFFF)
+ * @whence: SEEK_SET, SEEK_CUR, or SEEK_END
+ */
+static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence)
+{
+	loff_t newpos;
+	struct rmidev_data *dev_data = filp->private_data;
+
+	if (IS_ERR(dev_data)) {
+		pr_err("%s: Pointer of char device data is invalid", __func__);
+		return -EBADF;
+	}
+
+	mutex_lock(&(dev_data->file_mutex));
+
+	switch (whence) {
+	case SEEK_SET:
+		newpos = off;
+		break;
+	case SEEK_CUR:
+		newpos = filp->f_pos + off;
+		break;
+	case SEEK_END:
+		newpos = REG_ADDR_LIMIT + off;
+		break;
+	default:
+		newpos = -EINVAL;
+		goto clean_up;
+	}
+
+	if (newpos < 0 || newpos > REG_ADDR_LIMIT) {
+		dev_err(&rmidev->rmi4_data->i2c_client->dev,
+				"%s: New position 0x%04x is invalid\n",
+				__func__, (unsigned int)newpos);
+		newpos = -EINVAL;
+		goto clean_up;
+	}
+
+	filp->f_pos = newpos;
+
+clean_up:
+	mutex_unlock(&(dev_data->file_mutex));
+
+	return newpos;
+}
+
+/*
+ * rmidev_read: - use to read data from rmi device
+ *
+ * @filp: file structure for read
+ * @buf: user space buffer pointer
+ * @count: number of bytes to read
+ * @f_pos: offset (starting register address)
+ */
+static ssize_t rmidev_read(struct file *filp, char __user *buf,
+		size_t count, loff_t *f_pos)
+{
+	ssize_t retval;
+	unsigned char tmpbuf[count + 1];
+	struct rmidev_data *dev_data = filp->private_data;
+
+	if (IS_ERR(dev_data)) {
+		pr_err("%s: Pointer of char device data is invalid", __func__);
+		return -EBADF;
+	}
+
+	if (count == 0)
+		return 0;
+
+	if (count > (REG_ADDR_LIMIT - *f_pos))
+		count = REG_ADDR_LIMIT - *f_pos;
+
+	mutex_lock(&(dev_data->file_mutex));
+
+	retval = rmidev->fn_ptr->read(rmidev->rmi4_data,
+			*f_pos,
+			tmpbuf,
+			count);
+	if (retval < 0)
+		goto clean_up;
+
+	if (copy_to_user(buf, tmpbuf, count))
+		retval = -EFAULT;
+	else
+		*f_pos += retval;
+
+clean_up:
+	mutex_unlock(&(dev_data->file_mutex));
+
+	return retval;
+}
+
+/*
+ * rmidev_write: - used to write data to rmi device
+ *
+ * @filep: file structure for write
+ * @buf: user space buffer pointer
+ * @count: number of bytes to write
+ * @f_pos: offset (starting register address)
+ */
+static ssize_t rmidev_write(struct file *filp, const char __user *buf,
+		size_t count, loff_t *f_pos)
+{
+	ssize_t retval;
+	unsigned char tmpbuf[count + 1];
+	struct rmidev_data *dev_data = filp->private_data;
+
+	if (IS_ERR(dev_data)) {
+		pr_err("%s: Pointer of char device data is invalid", __func__);
+		return -EBADF;
+	}
+
+	if (count == 0)
+		return 0;
+
+	if (count > (REG_ADDR_LIMIT - *f_pos))
+		count = REG_ADDR_LIMIT - *f_pos;
+
+	if (copy_from_user(tmpbuf, buf, count))
+		return -EFAULT;
+
+	mutex_lock(&(dev_data->file_mutex));
+
+	retval = rmidev->fn_ptr->write(rmidev->rmi4_data,
+			*f_pos,
+			tmpbuf,
+			count);
+	if (retval >= 0)
+		*f_pos += retval;
+
+	mutex_unlock(&(dev_data->file_mutex));
+
+	return retval;
+}
+
+/*
+ * rmidev_open: enable access to rmi device
+ * @inp: inode struture
+ * @filp: file structure
+ */
+static int rmidev_open(struct inode *inp, struct file *filp)
+{
+	int retval = 0;
+	struct rmidev_data *dev_data =
+			container_of(inp->i_cdev, struct rmidev_data, main_dev);
+
+	if (!dev_data)
+		return -EACCES;
+
+	filp->private_data = dev_data;
+
+	mutex_lock(&(dev_data->file_mutex));
+
+	rmidev->fn_ptr->enable(rmidev->rmi4_data, false);
+	dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
+			"%s: Attention interrupt disabled\n",
+			__func__);
+
+	if (dev_data->ref_count < 1)
+		dev_data->ref_count++;
+	else
+		retval = -EACCES;
+
+	mutex_unlock(&(dev_data->file_mutex));
+
+	return retval;
+}
+
+/*
+ * rmidev_release: - release access to rmi device
+ * @inp: inode structure
+ * @filp: file structure
+ */
+static int rmidev_release(struct inode *inp, struct file *filp)
+{
+	struct rmidev_data *dev_data =
+			container_of(inp->i_cdev, struct rmidev_data, main_dev);
+
+	if (!dev_data)
+		return -EACCES;
+
+	mutex_lock(&(dev_data->file_mutex));
+
+	dev_data->ref_count--;
+	if (dev_data->ref_count < 0)
+		dev_data->ref_count = 0;
+
+	rmidev->fn_ptr->enable(rmidev->rmi4_data, true);
+	dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
+			"%s: Attention interrupt enabled\n",
+			__func__);
+
+	mutex_unlock(&(dev_data->file_mutex));
+
+	return 0;
+}
+
+static const struct file_operations rmidev_fops = {
+	.owner = THIS_MODULE,
+	.llseek = rmidev_llseek,
+	.read = rmidev_read,
+	.write = rmidev_write,
+	.open = rmidev_open,
+	.release = rmidev_release,
+};
+
+static void rmidev_device_cleanup(struct rmidev_data *dev_data)
+{
+	dev_t devno;
+
+	if (dev_data) {
+		devno = dev_data->main_dev.dev;
+
+		if (dev_data->device_class)
+			device_destroy(dev_data->device_class, devno);
+
+		cdev_del(&dev_data->main_dev);
+
+		unregister_chrdev_region(devno, 1);
+
+		dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
+				"%s: rmidev device removed\n",
+				__func__);
+	}
+
+	return;
+}
+
+static char *rmi_char_devnode(struct device *dev, mode_t *mode)
+{
+	if (!mode)
+		return NULL;
+
+	*mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+
+	return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev));
+}
+
+static int rmidev_create_device_class(void)
+{
+	rmidev_device_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME);
+
+	if (IS_ERR(rmidev_device_class)) {
+		pr_err("%s: Failed to create /dev/%s\n",
+				__func__, CHAR_DEVICE_NAME);
+		return -ENODEV;
+	}
+
+	rmidev_device_class->devnode = rmi_char_devnode;
+
+	return 0;
+}
+
+static int rmidev_init_device(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	dev_t dev_no;
+	unsigned char attr_count;
+	struct rmidev_data *dev_data;
+	struct device *device_ptr;
+
+	rmidev = kzalloc(sizeof(*rmidev), GFP_KERNEL);
+	if (!rmidev) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for rmidev\n",
+				__func__);
+		retval = -ENOMEM;
+		goto err_rmidev;
+	}
+
+	rmidev->fn_ptr =  kzalloc(sizeof(*(rmidev->fn_ptr)), GFP_KERNEL);
+	if (!rmidev) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for fn_ptr\n",
+				__func__);
+		retval = -ENOMEM;
+		goto err_fn_ptr;
+	}
+
+	rmidev->fn_ptr->read = rmi4_data->i2c_read;
+	rmidev->fn_ptr->write = rmi4_data->i2c_write;
+	rmidev->fn_ptr->enable = rmi4_data->irq_enable;
+	rmidev->rmi4_data = rmi4_data;
+
+	retval = rmidev_create_device_class();
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to create device class\n",
+				__func__);
+		goto err_device_class;
+	}
+
+	if (rmidev_major_num) {
+		dev_no = MKDEV(rmidev_major_num, DEV_NUMBER);
+		retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME);
+	} else {
+		retval = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME);
+		if (retval < 0) {
+			dev_err(&rmi4_data->i2c_client->dev,
+					"%s: Failed to allocate char device region\n",
+					__func__);
+			goto err_device_region;
+		}
+
+		rmidev_major_num = MAJOR(dev_no);
+		dev_dbg(&rmi4_data->i2c_client->dev,
+				"%s: Major number of rmidev = %d\n",
+				__func__, rmidev_major_num);
+	}
+
+	dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL);
+	if (!dev_data) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to alloc mem for dev_data\n",
+				__func__);
+		retval = -ENOMEM;
+		goto err_dev_data;
+	}
+
+	mutex_init(&dev_data->file_mutex);
+	dev_data->rmi_dev = rmidev;
+	rmidev->data = dev_data;
+
+	cdev_init(&dev_data->main_dev, &rmidev_fops);
+
+	retval = cdev_add(&dev_data->main_dev, dev_no, 1);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to add rmi char device\n",
+				__func__);
+		goto err_char_device;
+	}
+
+	dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no));
+	dev_data->device_class = rmidev_device_class;
+
+	device_ptr = device_create(dev_data->device_class, NULL, dev_no,
+			NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no));
+	if (IS_ERR(device_ptr)) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to create rmi char device\n",
+				__func__);
+		retval = -ENODEV;
+		goto err_char_device;
+	}
+
+	retval = gpio_export(rmi4_data->board->irq_gpio, false);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to export attention gpio\n",
+				__func__);
+	} else {
+		retval = gpio_export_link(&(rmi4_data->input_dev->dev),
+				"attn", rmi4_data->board->irq_gpio);
+		if (retval < 0) {
+			dev_err(&rmi4_data->input_dev->dev,
+					"%s Failed to create gpio symlink\n",
+					__func__);
+		} else {
+			dev_dbg(&rmi4_data->input_dev->dev,
+					"%s: Exported attention gpio %d\n",
+					__func__, rmi4_data->board->irq_gpio);
+		}
+	}
+
+	rmidev->sysfs_dir = kobject_create_and_add("rmidev",
+			&rmi4_data->input_dev->dev.kobj);
+	if (!rmidev->sysfs_dir) {
+		dev_err(&rmi4_data->i2c_client->dev,
+				"%s: Failed to create sysfs directory\n",
+				__func__);
+		goto err_sysfs_dir;
+	}
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+		retval = sysfs_create_file(rmidev->sysfs_dir,
+				&attrs[attr_count].attr);
+		if (retval < 0) {
+			dev_err(&rmi4_data->input_dev->dev,
+					"%s: Failed to create sysfs attributes\n",
+					__func__);
+			retval = -ENODEV;
+			goto err_sysfs_attrs;
+		}
+	}
+
+	return 0;
+
+err_sysfs_attrs:
+	for (attr_count--; attr_count >= 0; attr_count--) {
+		sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
+				&attrs[attr_count].attr);
+	}
+
+	kobject_put(rmidev->sysfs_dir);
+
+err_sysfs_dir:
+err_char_device:
+	rmidev_device_cleanup(dev_data);
+	kfree(dev_data);
+
+err_dev_data:
+	unregister_chrdev_region(dev_no, 1);
+
+err_device_region:
+	class_destroy(rmidev_device_class);
+
+err_device_class:
+	kfree(rmidev->fn_ptr);
+
+err_fn_ptr:
+	kfree(rmidev);
+
+err_rmidev:
+	return retval;
+}
+
+static void rmidev_remove_device(struct synaptics_rmi4_data *rmi4_data)
+{
+	unsigned char attr_count;
+	struct rmidev_data *dev_data;
+
+	if (!rmidev)
+		return;
+
+	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++)
+		sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr);
+
+	kobject_put(rmidev->sysfs_dir);
+
+	dev_data = rmidev->data;
+	if (dev_data) {
+		rmidev_device_cleanup(dev_data);
+		kfree(dev_data);
+	}
+
+	unregister_chrdev_region(rmidev->dev_no, 1);
+
+	class_destroy(rmidev_device_class);
+
+	kfree(rmidev->fn_ptr);
+	kfree(rmidev);
+
+	complete(&remove_complete);
+
+	return;
+}
+
+static int __init rmidev_module_init(void)
+{
+	synaptics_rmi4_new_function(RMI_DEV, true,
+			rmidev_init_device,
+			rmidev_remove_device,
+			NULL);
+	return 0;
+}
+
+static void __exit rmidev_module_exit(void)
+{
+	init_completion(&remove_complete);
+	synaptics_rmi4_new_function(RMI_DEV, false,
+			rmidev_init_device,
+			rmidev_remove_device,
+			NULL);
+	wait_for_completion(&remove_complete);
+	return;
+}
+
+module_init(rmidev_module_init);
+module_exit(rmidev_module_exit);
+
+MODULE_AUTHOR("Synaptics, Inc.");
+MODULE_DESCRIPTION("RMI4 RMI_Dev Module");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/msm_iommu-v2.c b/drivers/iommu/msm_iommu-v2.c
index de31859..15de300 100644
--- a/drivers/iommu/msm_iommu-v2.c
+++ b/drivers/iommu/msm_iommu-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. 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 and
diff --git a/drivers/iommu/msm_iommu_dev-v2.c b/drivers/iommu/msm_iommu_dev-v2.c
index 8c26f95..4c69c8c 100644
--- a/drivers/iommu/msm_iommu_dev-v2.c
+++ b/drivers/iommu/msm_iommu_dev-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. 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 and
diff --git a/drivers/iommu/msm_iommu_dev.c b/drivers/iommu/msm_iommu_dev.c
index 967283d..fca102a 100644
--- a/drivers/iommu/msm_iommu_dev.c
+++ b/drivers/iommu/msm_iommu_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/iommu/msm_iommu_pagetable.c b/drivers/iommu/msm_iommu_pagetable.c
index b93860e..2ee9ba6 100644
--- a/drivers/iommu/msm_iommu_pagetable.c
+++ b/drivers/iommu/msm_iommu_pagetable.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. 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 and
diff --git a/drivers/iommu/msm_iommu_pagetable.h b/drivers/iommu/msm_iommu_pagetable.h
index b943084..3266681 100644
--- a/drivers/iommu/msm_iommu_pagetable.h
+++ b/drivers/iommu/msm_iommu_pagetable.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. 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 and
diff --git a/drivers/leds/leds-msm-pdm.c b/drivers/leds/leds-msm-pdm.c
index 467026b..9660cd2 100644
--- a/drivers/leds/leds-msm-pdm.c
+++ b/drivers/leds/leds-msm-pdm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/leds/leds-msm-pmic.c b/drivers/leds/leds-msm-pmic.c
index b9c6a53..35be94e 100644
--- a/drivers/leds/leds-msm-pmic.c
+++ b/drivers/leds/leds-msm-pmic.c
@@ -1,7 +1,7 @@
 /*
  * leds-msm-pmic.c - MSM PMIC LEDs driver.
  *
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/leds/leds-msm-tricolor.c b/drivers/leds/leds-msm-tricolor.c
index d0715ce..60ceb26 100644
--- a/drivers/leds/leds-msm-tricolor.c
+++ b/drivers/leds/leds-msm-tricolor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/leds/leds-pm8xxx.c b/drivers/leds/leds-pm8xxx.c
index 48ac039..965c955 100644
--- a/drivers/leds/leds-pm8xxx.c
+++ b/drivers/leds/leds-pm8xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/leds/leds-pmic-mpp.c b/drivers/leds/leds-pmic-mpp.c
index a3762be..62ea96b 100644
--- a/drivers/leds/leds-pmic-mpp.c
+++ b/drivers/leds/leds-pmic-mpp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/leds/leds-pmic8058.c b/drivers/leds/leds-pmic8058.c
index 0ba3f58..0af3ba2 100644
--- a/drivers/leds/leds-pmic8058.c
+++ b/drivers/leds/leds-pmic8058.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2011, The Linux Foundation. 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 and
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index f42fb5e..4c4405e 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -1,5 +1,5 @@
 
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 52b7994..1e109fb 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -2073,8 +2073,18 @@
 		return 0;
 	}
 
-	if ((dmxdevfilter->params.pes.output == DMX_OUT_DECODER) ||
-		(buffer->error)) {
+	if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
+		if (DMX_OVERRUN_ERROR == dmx_data_ready->status) {
+			dprintk("dmxdev: buffer overflow\n");
+			event.type = DMX_EVENT_BUFFER_OVERFLOW;
+			dvb_dmxdev_add_event(&dmxdevfilter->events, &event);
+		}
+		spin_unlock(&dmxdevfilter->dev->lock);
+		wake_up_all(&buffer->queue);
+		return 0;
+	}
+
+	if (buffer->error) {
 		spin_unlock(&dmxdevfilter->dev->lock);
 		wake_up_all(&buffer->queue);
 		return 0;
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index dfb8d58..84286cc 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -376,6 +376,10 @@
 	else
 		ccok = ((feed->cc + 1) & 0x0f) == cc;
 
+	/* discard TS packets holding sections with TEI bit set */
+	if (buf[1] & 0x80)
+		return -EINVAL;
+
 	feed->first_cc = 0;
 	feed->cc = cc;
 
@@ -514,6 +518,10 @@
 			((feed->pid != pid) && (feed->pid != 0x2000)))
 			continue;
 
+		if (feed->secure_mode.is_secured &&
+			!dvb_dmx_is_rec_feed(feed))
+			return 0;
+
 		if (feed->type == DMX_TYPE_TS) {
 			desired_space = 192; /* upper bound */
 			ts = &feed->feed.ts;
@@ -593,19 +601,23 @@
 		if (!feed->feed.ts.is_filtering)
 			break;
 		if (feed->ts_type & TS_PACKET) {
-			if (feed->ts_type & TS_PAYLOAD_ONLY)
-				dvb_dmx_swfilter_payload(feed, buf);
-			else
+			if (feed->ts_type & TS_PAYLOAD_ONLY) {
+				if (!feed->secure_mode.is_secured)
+					dvb_dmx_swfilter_payload(feed, buf);
+			} else {
 				dvb_dmx_swfilter_output_packet(feed,
 						buf, timestamp);
+			}
 		}
-		if (feed->ts_type & TS_DECODER)
+		if ((feed->ts_type & TS_DECODER) &&
+			!feed->secure_mode.is_secured)
 			if (feed->demux->write_to_decoder)
 				feed->demux->write_to_decoder(feed, buf, 188);
 		break;
 
 	case DMX_TYPE_SEC:
-		if (!feed->feed.sec.is_filtering)
+		if (!feed->feed.sec.is_filtering ||
+			feed->secure_mode.is_secured)
 			break;
 		if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
 			feed->feed.sec.seclen = feed->feed.sec.secbufp = 0;
@@ -621,7 +633,7 @@
 	((f)->feed.ts.is_filtering) &&					\
 	(((f)->ts_type & (TS_PACKET | TS_DEMUX)) == TS_PACKET))
 
-void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf,
+static void dvb_dmx_swfilter_one_packet(struct dvb_demux *demux, const u8 *buf,
 				const u8 timestamp[TIMESTAMP_LEN])
 {
 	struct dvb_demux_feed *feed;
@@ -701,6 +713,14 @@
 			dvb_dmx_swfilter_output_packet(feed, buf, timestamp);
 	}
 }
+
+void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf,
+				const u8 timestamp[TIMESTAMP_LEN])
+{
+	spin_lock(&demux->lock);
+	dvb_dmx_swfilter_one_packet(demux, buf, timestamp);
+	spin_unlock(&demux->lock);
+}
 EXPORT_SYMBOL(dvb_dmx_swfilter_packet);
 
 void dvb_dmx_swfilter_section_packets(struct dvb_demux *demux, const u8 *buf,
@@ -765,7 +785,7 @@
 
 	while (count--) {
 		if (buf[0] == 0x47)
-			dvb_dmx_swfilter_packet(demux, buf, timestamp);
+			dvb_dmx_swfilter_one_packet(demux, buf, timestamp);
 		buf += 188;
 	}
 
@@ -845,10 +865,11 @@
 		if (pktsize == 192 &&
 			leadingbytes &&
 			demux->tsbuf[leadingbytes] == 0x47)  /* double check */
-			dvb_dmx_swfilter_packet(demux,
+			dvb_dmx_swfilter_one_packet(demux,
 				demux->tsbuf + TIMESTAMP_LEN, timestamp);
 		else if (demux->tsbuf[0] == 0x47) /* double check */
-			dvb_dmx_swfilter_packet(demux, demux->tsbuf, timestamp);
+			dvb_dmx_swfilter_one_packet(demux,
+					demux->tsbuf, timestamp);
 		demux->tsbufp = 0;
 		p += j;
 	}
@@ -877,13 +898,13 @@
 				q = &buf[p+leadingbytes];
 				memcpy(timestamp, &buf[p], TIMESTAMP_LEN);
 			} else {
-				memcpy(timestamp, &buf[188], TIMESTAMP_LEN);
+				memcpy(timestamp, &buf[p+188], TIMESTAMP_LEN);
 			}
 		} else {
 			memset(timestamp, 0, TIMESTAMP_LEN);
 		}
 
-		dvb_dmx_swfilter_packet(demux, q, timestamp);
+		dvb_dmx_swfilter_one_packet(demux, q, timestamp);
 		p += pktsize;
 	}
 
@@ -1212,17 +1233,22 @@
 {
 	struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
 	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+	int ret = 0;
 
 	mutex_lock(&dvbdmx->mutex);
 
-	dvbdmxfeed->secure_mode = *secure_mode;
-
 	if ((dvbdmxfeed->state == DMX_STATE_GO) &&
-		dvbdmxfeed->demux->set_secure_mode)
-		dvbdmxfeed->demux->set_secure_mode(dvbdmxfeed, secure_mode);
+		dvbdmxfeed->demux->set_secure_mode) {
+		ret = dvbdmxfeed->demux->set_secure_mode(dvbdmxfeed,
+			secure_mode);
+		if (!ret)
+			dvbdmxfeed->secure_mode = *secure_mode;
+	} else {
+		dvbdmxfeed->secure_mode = *secure_mode;
+	}
 
 	mutex_unlock(&dvbdmx->mutex);
-	return 0;
+	return ret;
 }
 
 static int dmx_ts_set_indexing_params(
@@ -1863,13 +1889,13 @@
 	if (dvbdemux->dmx.debugfs_demux_dir != NULL) {
 		debugfs_create_u32(
 			"total_processing_time",
-			S_IRUGO|S_IWUGO,
+			S_IRUGO | S_IWUSR | S_IWGRP,
 			dvbdemux->dmx.debugfs_demux_dir,
 			&dvbdemux->total_process_time);
 
 		debugfs_create_u32(
 			"total_crc_time",
-			S_IRUGO|S_IWUGO,
+			S_IRUGO | S_IWUSR | S_IWGRP,
 			dvbdemux->dmx.debugfs_demux_dir,
 			&dvbdemux->total_crc_time);
 	}
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index f5f6039..f3dc4b8 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -203,5 +203,85 @@
 void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf,
 				const u8 timestamp[TIMESTAMP_LEN]);
 
+/**
+ * dvb_dmx_is_video_feed - Returns whether the PES feed
+ * is video one.
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return     1 if feed is video feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_video_feed(struct dvb_demux_feed *feed)
+{
+	if (feed->type != DMX_TYPE_TS)
+		return 0;
+
+	if (feed->ts_type & (~TS_DECODER))
+		return 0;
+
+	if ((feed->pes_type == DMX_TS_PES_VIDEO0) ||
+		(feed->pes_type == DMX_TS_PES_VIDEO1) ||
+		(feed->pes_type == DMX_TS_PES_VIDEO2) ||
+		(feed->pes_type == DMX_TS_PES_VIDEO3))
+		return 1;
+
+	return 0;
+}
+
+/**
+ * dvb_dmx_is_pcr_feed - Returns whether the PES feed
+ * is PCR one.
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return     1 if feed is PCR feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_pcr_feed(struct dvb_demux_feed *feed)
+{
+	if (feed->type != DMX_TYPE_TS)
+		return 0;
+
+	if (feed->ts_type & (~TS_DECODER))
+		return 0;
+
+	if ((feed->pes_type == DMX_TS_PES_PCR0) ||
+		(feed->pes_type == DMX_TS_PES_PCR1) ||
+		(feed->pes_type == DMX_TS_PES_PCR2) ||
+		(feed->pes_type == DMX_TS_PES_PCR3))
+		return 1;
+
+	return 0;
+}
+
+/**
+ * dvb_dmx_is_sec_feed - Returns whether this is a section feed
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is a section feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_sec_feed(struct dvb_demux_feed *feed)
+{
+	return (feed->type == DMX_TYPE_SEC);
+}
+
+/**
+ * dvb_dmx_is_rec_feed - Returns whether this is a recording feed
+ *
+ * @feed: The feed to be checked.
+ *
+ * Return 1 if feed is recording feed, 0 otherwise.
+ */
+static inline int dvb_dmx_is_rec_feed(struct dvb_demux_feed *feed)
+{
+	if (feed->type != DMX_TYPE_TS)
+		return 0;
+
+	if (feed->ts_type & (TS_DECODER | TS_PAYLOAD_ONLY))
+		return 0;
+
+	return 1;
+}
+
 
 #endif /* _DVB_DEMUX_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
index 36cc475..e8480f7 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003 Oliver Endriss
  * Copyright (C) 2004 Andrew de Quincey
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * based on code originally found in av7110.c & dvb_ci.c:
  * Copyright (C) 1999-2003 Ralph  Metzler
@@ -334,7 +334,10 @@
 		idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
 	}
 
-	consumed = (idx - rbuf->pread) % rbuf->size;
+	if (idx >= rbuf->pread)
+		consumed = idx - rbuf->pread;
+	else
+		consumed = rbuf->size - (rbuf->pread - idx);
 
 	while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) {
 
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
index 4093fa5..10de856 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
@@ -5,7 +5,7 @@
  * Copyright (C) 2003 Oliver Endriss
  * Copyright (C) 2004 Andrew de Quincey
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * based on code originally found in av7110.c & dvb_ci.c:
  * Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler
diff --git a/drivers/media/dvb/mpq/adapter/mpq_adapter.c b/drivers/media/dvb/mpq/adapter/mpq_adapter.c
index 9664f04..c48b7ed 100644
--- a/drivers/media/dvb/mpq/adapter/mpq_adapter.c
+++ b/drivers/media/dvb/mpq/adapter/mpq_adapter.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
index c7c617f..20db2fe 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
@@ -18,6 +18,8 @@
 #include "mpq_dmx_plugin_common.h"
 #include "mpq_sdmx.h"
 
+#define SDMX_MAJOR_VERSION_MATCH	(3)
+
 #define TS_PACKET_HEADER_LENGTH (4)
 
 /* Length of mandatory fields that must exist in header of video PES */
@@ -25,6 +27,8 @@
 
 #define MAX_PES_LENGTH	(SZ_64K)
 
+#define MAX_TS_PACKETS_FOR_SDMX_PROCESS	(500)
+
 /*
  * PES header length field is 8 bits so PES header length after this field
  * can be up to 256 bytes.
@@ -87,6 +91,15 @@
 static int mpq_bypass_sdmx = 1;
 module_param(mpq_bypass_sdmx, int, S_IRUGO | S_IWUSR);
 
+/* Max number of TS packets allowed as input for a single sdmx process */
+static int mpq_sdmx_proc_limit = MAX_TS_PACKETS_FOR_SDMX_PROCESS;
+module_param(mpq_sdmx_proc_limit, int, S_IRUGO | S_IWUSR);
+
+/* Debug flag for secure demux process */
+static int mpq_sdmx_debug;
+module_param(mpq_sdmx_debug, int, S_IRUGO | S_IWUSR);
+
+
 /**
  * Maximum allowed framing pattern size
  */
@@ -613,8 +626,77 @@
 		mpq_demux->sdmx_process_time_max = process_time;
 }
 
-/* Extend dvb-demux debugfs with HW statistics */
-void mpq_dmx_init_hw_statistics(struct mpq_demux *mpq_demux)
+static int mpq_sdmx_log_level_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t mpq_sdmx_log_level_read(struct file *fp,
+	char __user *user_buffer, size_t count, loff_t *position)
+{
+	char user_str[16];
+	struct mpq_demux *mpq_demux = fp->private_data;
+	int ret;
+
+	ret = scnprintf(user_str, 16, "%d", mpq_demux->sdmx_log_level);
+	ret = simple_read_from_buffer(user_buffer, count, position,
+		user_str, ret+1);
+
+	return ret;
+}
+
+static ssize_t mpq_sdmx_log_level_write(struct file *fp,
+	const char __user *user_buffer, size_t count, loff_t *position)
+{
+	char user_str[16];
+	int ret;
+	int ret_count;
+	int level;
+	struct mpq_demux *mpq_demux = fp->private_data;
+
+	if (count >= 16)
+		return -EINVAL;
+
+	ret_count = simple_write_to_buffer(user_str, 16, position, user_buffer,
+		count);
+	if (ret_count < 0)
+		return ret_count;
+
+	ret = sscanf(user_str, "%d", &level);
+	if (ret != 1)
+		return -EINVAL;
+
+	if (level < SDMX_LOG_NO_PRINT || level > SDMX_LOG_VERBOSE)
+		return -EINVAL;
+
+	mutex_lock(&mpq_demux->mutex);
+	mpq_demux->sdmx_log_level = level;
+	if (mpq_demux->sdmx_session_handle != SDMX_INVALID_SESSION_HANDLE) {
+		ret = sdmx_set_log_level(mpq_demux->sdmx_session_handle,
+			mpq_demux->sdmx_log_level);
+		if (ret) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: Could not set sdmx log level. ret = %d\n",
+				__func__, ret);
+			mutex_unlock(&mpq_demux->mutex);
+			return -EINVAL;
+		}
+	}
+
+	mutex_unlock(&mpq_demux->mutex);
+	return ret_count;
+}
+
+static const struct file_operations sdmx_debug_fops = {
+	.open = mpq_sdmx_log_level_open,
+	.read = mpq_sdmx_log_level_read,
+	.write = mpq_sdmx_log_level_write,
+	.owner = THIS_MODULE,
+};
+
+/* Extend dvb-demux debugfs with common plug-in entries */
+void mpq_dmx_init_debugfs_entries(struct mpq_demux *mpq_demux)
 {
 	/*
 	 * Extend dvb-demux debugfs with HW statistics.
@@ -631,113 +713,119 @@
 
 	debugfs_create_u32(
 		"hw_notification_interval",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->hw_notification_interval);
 
 	debugfs_create_u32(
 		"hw_notification_min_interval",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->hw_notification_min_interval);
 
 	debugfs_create_u32(
 		"hw_notification_count",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->hw_notification_count);
 
 	debugfs_create_u32(
 		"hw_notification_size",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->hw_notification_size);
 
 	debugfs_create_u32(
 		"hw_notification_min_size",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->hw_notification_min_size);
 
 	debugfs_create_u32(
 		"decoder_drop_count",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->decoder_drop_count);
 
 	debugfs_create_u32(
 		"decoder_out_count",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->decoder_out_count);
 
 	debugfs_create_u32(
 		"decoder_out_interval_sum",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->decoder_out_interval_sum);
 
 	debugfs_create_u32(
 		"decoder_out_interval_average",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->decoder_out_interval_average);
 
 	debugfs_create_u32(
 		"decoder_out_interval_max",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->decoder_out_interval_max);
 
 	debugfs_create_u32(
 		"decoder_ts_errors",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->decoder_ts_errors);
 
 	debugfs_create_u32(
 		"sdmx_process_count",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->sdmx_process_count);
 
 	debugfs_create_u32(
 		"sdmx_process_time_sum",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->sdmx_process_time_sum);
 
 	debugfs_create_u32(
 		"sdmx_process_time_average",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->sdmx_process_time_average);
 
 	debugfs_create_u32(
 		"sdmx_process_time_max",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->sdmx_process_time_max);
 
 	debugfs_create_u32(
 		"sdmx_process_packets_sum",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->sdmx_process_packets_sum);
 
 	debugfs_create_u32(
 		"sdmx_process_packets_average",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->sdmx_process_packets_average);
 
 	debugfs_create_u32(
 		"sdmx_process_packets_min",
-		S_IRUGO|S_IWUGO,
+		S_IRUGO | S_IWUSR | S_IWGRP,
 		mpq_demux->demux.dmx.debugfs_demux_dir,
 		&mpq_demux->sdmx_process_packets_min);
+
+	debugfs_create_file("sdmx_log_level",
+		S_IRUGO | S_IWUSR | S_IWGRP,
+		mpq_demux->demux.dmx.debugfs_demux_dir,
+		mpq_demux,
+		&sdmx_debug_fops);
 }
-EXPORT_SYMBOL(mpq_dmx_init_hw_statistics);
+EXPORT_SYMBOL(mpq_dmx_init_debugfs_entries);
 
 /* Update dvb-demux debugfs with HW notification statistics */
 void mpq_dmx_update_hw_statistics(struct mpq_demux *mpq_demux)
@@ -769,6 +857,7 @@
 static void mpq_sdmx_check_app_loaded(void)
 {
 	int session;
+	u32 version;
 	int ret;
 
 	ret = sdmx_open_session(&session);
@@ -780,6 +869,24 @@
 		return;
 	}
 
+	/* Check proper sdmx major version */
+	ret = sdmx_get_version(session, &version);
+	if (ret != SDMX_SUCCESS) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: Could not get sdmx version. ret = %d\n",
+			__func__, ret);
+	} else {
+		if ((version >> 8) != SDMX_MAJOR_VERSION_MATCH)
+			MPQ_DVB_ERR_PRINT(
+				"%s: sdmx major version does not match. expected=%d, actual=%d\n",
+				__func__, SDMX_MAJOR_VERSION_MATCH,
+				(version >> 8));
+		else
+			MPQ_DVB_DBG_PRINT(
+				"%s: sdmx major version is ok = %d\n",
+				__func__, SDMX_MAJOR_VERSION_MATCH);
+	}
+
 	mpq_dmx_info.secure_demux_app_loaded = 1;
 	sdmx_close_session(session);
 }
@@ -819,7 +926,7 @@
 	mpq_dmx_info.devices = NULL;
 	mpq_dmx_info.ion_client = NULL;
 
-	mpq_sdmx_check_app_loaded();
+	mpq_dmx_info.secure_demux_app_loaded = 0;
 
 	/*
 	 * TODO: the following should be set based on the decoder:
@@ -875,8 +982,11 @@
 
 		mutex_init(&mpq_demux->mutex);
 
+		mpq_demux->num_secure_feeds = 0;
+		mpq_demux->num_active_feeds = 0;
 		mpq_demux->sdmx_filter_count = 0;
 		mpq_demux->sdmx_session_handle = SDMX_INVALID_SESSION_HANDLE;
+		mpq_demux->sdmx_log_level = SDMX_LOG_NO_PRINT;
 
 		if (mpq_demux->demux.feednum > MPQ_MAX_DMX_FILES) {
 			MPQ_DVB_ERR_PRINT(
@@ -1197,12 +1307,14 @@
 		return -EPERM;
 	}
 
+	MPQ_DVB_DBG_PRINT("%s: cookie=%d\n", __func__, cookie);
+
 	if (cookie < 0) {
 		MPQ_DVB_ERR_PRINT("%s: invalid cookie parameter\n", __func__);
 		return -EINVAL;
 	}
 
-	if (mpq_dmx_is_video_feed(feed)) {
+	if (dvb_dmx_is_video_feed(feed)) {
 		struct mpq_video_feed_info *feed_data;
 		struct mpq_feed *mpq_feed;
 		struct mpq_streambuffer *stream_buffer;
@@ -1929,9 +2041,10 @@
 		}
 
 		mpq_sdmx_close_session(mpq_demux);
+		mpq_demux->num_secure_feeds--;
 	}
 
-	if (mpq_dmx_is_video_feed(feed)) {
+	if (dvb_dmx_is_video_feed(feed)) {
 		ret = mpq_dmx_terminate_video_feed(mpq_feed);
 		if (ret)
 			MPQ_DVB_ERR_PRINT(
@@ -1945,6 +2058,7 @@
 	}
 
 	mpq_sdmx_terminate_metadata_buffer(mpq_feed);
+	mpq_demux->num_active_feeds--;
 
 	mutex_unlock(&mpq_demux->mutex);
 
@@ -1954,7 +2068,7 @@
 
 int mpq_dmx_decoder_fullness_init(struct dvb_demux_feed *feed)
 {
-	if (mpq_dmx_is_video_feed(feed)) {
+	if (dvb_dmx_is_video_feed(feed)) {
 		struct mpq_feed *mpq_feed;
 		struct mpq_video_feed_info *feed_data;
 
@@ -2028,7 +2142,7 @@
 	struct mpq_feed *mpq_feed;
 	int ret = 0;
 
-	if (!mpq_dmx_is_video_feed(feed)) {
+	if (!dvb_dmx_is_video_feed(feed)) {
 		MPQ_DVB_DBG_PRINT("%s: Invalid feed type %d\n",
 			__func__,
 			feed->pes_type);
@@ -2111,7 +2225,7 @@
 
 int mpq_dmx_decoder_fullness_abort(struct dvb_demux_feed *feed)
 {
-	if (mpq_dmx_is_video_feed(feed)) {
+	if (dvb_dmx_is_video_feed(feed)) {
 		struct mpq_feed *mpq_feed;
 		struct mpq_video_feed_info *feed_data;
 		struct dvb_ringbuffer *video_buff;
@@ -2415,9 +2529,15 @@
 
 	data->data_length = 0;
 	data->buf.handle = packet->raw_data_handle;
+
 	/* this has to succeed when called here, after packet was written */
 	data->buf.cookie = mpq_streambuffer_pkt_next(stream_buffer,
 				feed_data->last_pkt_index, &len);
+	if (data->buf.cookie < 0)
+		MPQ_DVB_DBG_PRINT(
+			"%s: received invalid packet index %d\n",
+			__func__, data->buf.cookie);
+
 	data->buf.offset = packet->raw_data_offset;
 	data->buf.len = packet->raw_data_len;
 	data->buf.pts_exists = pts_dts->pts_exist;
@@ -2433,6 +2553,8 @@
 	/* save for next time: */
 	feed_data->last_pkt_index = data->buf.cookie;
 
+	MPQ_DVB_DBG_PRINT("%s: cookie=%d\n", __func__, data->buf.cookie);
+
 	/* reset counters */
 	feed_data->ts_packets_num = 0;
 	feed_data->ts_dropped_bytes = 0;
@@ -3059,7 +3181,7 @@
 	struct mpq_streambuffer *video_buff;
 	struct mpq_feed *mpq_feed;
 
-	if (!mpq_dmx_is_video_feed(feed)) {
+	if (!dvb_dmx_is_video_feed(feed)) {
 		MPQ_DVB_ERR_PRINT(
 			"%s: Invalid feed type %d\n",
 			__func__,
@@ -3202,67 +3324,6 @@
 }
 EXPORT_SYMBOL(mpq_dmx_process_pcr_packet);
 
-int mpq_dmx_set_secure_mode(struct dvb_demux_feed *feed,
-	struct dmx_secure_mode *sec_mode)
-{
-	struct mpq_feed *mpq_feed;
-	struct mpq_demux *mpq_demux;
-	int ret;
-
-	if (!feed || !feed->priv || !sec_mode) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: invalid parameters\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	MPQ_DVB_DBG_PRINT("%s(%d, %d, %d)\n",
-		__func__, sec_mode->pid,
-		sec_mode->is_secured,
-		sec_mode->key_ladder_id);
-
-	mpq_feed = feed->priv;
-	mpq_demux = mpq_feed->mpq_demux;
-
-	mutex_lock(&mpq_demux->mutex);
-
-	/*
-	 * If secure demux is active, set the KL now,
-	 * otherwise it will be set when secure-demux is started
-	 * (when filtering starts).
-	 */
-	if (mpq_demux->sdmx_session_handle !=
-		SDMX_INVALID_SESSION_HANDLE) {
-		if (sec_mode->is_secured) {
-			MPQ_DVB_DBG_PRINT(
-				"%s: set key-ladder %d to PID %d\n",
-				__func__,
-				sec_mode->key_ladder_id,
-				sec_mode->pid);
-			ret = sdmx_set_kl_ind(mpq_demux->sdmx_session_handle,
-				sec_mode->pid, sec_mode->key_ladder_id);
-			if (ret) {
-				MPQ_DVB_ERR_PRINT(
-					"%s: FAILED to set keyladder, ret=%d\n",
-					__func__, ret);
-				ret = -EINVAL;
-			}
-		} else {
-			MPQ_DVB_DBG_PRINT("%s: setting non-secure mode\n",
-				__func__);
-			ret = 0;
-		}
-	} else {
-		MPQ_DVB_DBG_PRINT("%s: SDMX not started yet\n", __func__);
-		ret = 0;
-	}
-
-	mutex_unlock(&mpq_demux->mutex);
-
-	return ret;
-}
-EXPORT_SYMBOL(mpq_dmx_set_secure_mode);
-
 int mpq_sdmx_open_session(struct mpq_demux *mpq_demux)
 {
 	enum sdmx_status ret = SDMX_SUCCESS;
@@ -3325,6 +3386,15 @@
 		return -EINVAL;
 	}
 
+	ret = sdmx_set_log_level(mpq_demux->sdmx_session_handle,
+		mpq_demux->sdmx_log_level);
+	if (ret != SDMX_SUCCESS) {
+		MPQ_DVB_ERR_PRINT("%s: Could not set log level. ret=%d\n",
+				__func__, ret);
+		/* Don't fail open session if just log level setting failed */
+		ret = 0;
+	}
+
 	mpq_demux->sdmx_process_count = 0;
 	mpq_demux->sdmx_process_time_sum = 0;
 	mpq_demux->sdmx_process_time_average = 0;
@@ -3381,7 +3451,7 @@
 
 	*buf_mode = SDMX_RING_BUF;
 
-	if (mpq_dmx_is_video_feed(feed->dvb_demux_feed)) {
+	if (dvb_dmx_is_video_feed(feed->dvb_demux_feed)) {
 		if (feed_data->buffer_desc.decoder_buffers_num > 1)
 			*buf_mode = SDMX_LINEAR_GROUP_BUF;
 		*num_buffers = feed_data->buffer_desc.decoder_buffers_num;
@@ -3401,8 +3471,8 @@
 		}
 	} else {
 		*num_buffers = 1;
-		if (mpq_dmx_is_sec_feed(dvbdmx_feed) ||
-			mpq_dmx_is_pcr_feed(dvbdmx_feed)) {
+		if (dvb_dmx_is_sec_feed(dvbdmx_feed) ||
+			dvb_dmx_is_pcr_feed(dvbdmx_feed)) {
 			buffer = &feed->sdmx_buf;
 			sdmx_buff = feed->sdmx_buf_handle;
 		} else {
@@ -3448,20 +3518,40 @@
 	struct sdmx_buff_descr data_buff_desc[DMX_MAX_DECODER_BUFFER_NUM];
 	u32 data_buf_num = DMX_MAX_DECODER_BUFFER_NUM;
 	enum sdmx_buf_mode buf_mode;
+	enum sdmx_raw_out_format ts_out_format = SDMX_188_OUTPUT;
+	u32 filter_flags = 0;
 
 	feed = dvbdmx_feed->priv;
 
-	if (mpq_dmx_is_sec_feed(dvbdmx_feed)) {
+	if (dvb_dmx_is_sec_feed(dvbdmx_feed)) {
 		feed->filter_type = SDMX_SECTION_FILTER;
+		if (dvbdmx_feed->feed.sec.check_crc)
+			filter_flags |= SDMX_FILTER_FLAG_VERIFY_SECTION_CRC;
 		MPQ_DVB_DBG_PRINT("%s: SDMX_SECTION_FILTER\n", __func__);
-	} else if (mpq_dmx_is_pcr_feed(dvbdmx_feed)) {
+	} else if (dvb_dmx_is_pcr_feed(dvbdmx_feed)) {
 		feed->filter_type = SDMX_PCR_FILTER;
 		MPQ_DVB_DBG_PRINT("%s: SDMX_PCR_FILTER\n", __func__);
-	} else if (mpq_dmx_is_video_feed(dvbdmx_feed)) {
+	} else if (dvb_dmx_is_video_feed(dvbdmx_feed)) {
 		feed->filter_type = SDMX_SEPARATED_PES_FILTER;
 		MPQ_DVB_DBG_PRINT("%s: SDMX_SEPARATED_PES_FILTER\n", __func__);
-	} else if (mpq_dmx_is_rec_feed(dvbdmx_feed)) {
+	} else if (dvb_dmx_is_rec_feed(dvbdmx_feed)) {
 		feed->filter_type = SDMX_RAW_FILTER;
+		switch (dvbdmx_feed->tsp_out_format) {
+		case (DMX_TSP_FORMAT_188):
+			ts_out_format = SDMX_188_OUTPUT;
+			break;
+		case (DMX_TSP_FORMAT_192_HEAD):
+			ts_out_format = SDMX_192_HEAD_OUTPUT;
+			break;
+		case (DMX_TSP_FORMAT_192_TAIL):
+			ts_out_format = SDMX_192_TAIL_OUTPUT;
+			break;
+		default:
+			MPQ_DVB_ERR_PRINT(
+				"%s: Unsupported TS output format %d\n",
+				__func__, dvbdmx_feed->tsp_out_format);
+			return -EINVAL;
+		}
 		MPQ_DVB_DBG_PRINT("%s: SDMX_RAW_FILTER\n", __func__);
 	} else {
 		feed->filter_type = SDMX_PES_FILTER;
@@ -3491,13 +3581,14 @@
 		feed->secondary_feed = 0;
 
 		MPQ_DVB_DBG_PRINT(
-			"%s: Adding new sdmx filter, pid %d\n",
-			__func__, dvbdmx_feed->pid);
+			"%s: Adding new sdmx filter, pid %d, flags=0x%X, ts_out_format=%d\n",
+			__func__, dvbdmx_feed->pid, filter_flags,
+			ts_out_format);
 
 		/* Meta-data initialization,
 		 * Recording filters do no need meta-data buffers.
 		 */
-		if (mpq_dmx_is_rec_feed(dvbdmx_feed)) {
+		if (dvb_dmx_is_rec_feed(dvbdmx_feed)) {
 			metadata_buff_desc.base_addr = 0;
 			metadata_buff_desc.size = 0;
 		} else {
@@ -3527,7 +3618,9 @@
 			buf_mode,
 			data_buf_num,
 			data_buff_desc,
-			&feed->sdmx_filter_handle);
+			&feed->sdmx_filter_handle,
+			ts_out_format,
+			filter_flags);
 		if (ret) {
 			MPQ_DVB_ERR_PRINT(
 				"%s: SDMX_add_filter failed. ret = %d\n",
@@ -3589,6 +3682,63 @@
 	return ret;
 }
 
+/**
+ * mpq_sdmx_init_feed - initialize secure demux related elements of mpq feed
+ *
+ * @mpq_demux: mpq_demux object
+ * @mpq_feed: mpq_feed object
+ *
+ * Note: the function assumes mpq_demux->mutex locking is done by caller.
+ */
+static int mpq_sdmx_init_feed(struct mpq_demux *mpq_demux,
+	struct mpq_feed *mpq_feed)
+{
+	int ret;
+
+	ret = mpq_sdmx_open_session(mpq_demux);
+	if (ret) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_sdmx_open_session failed, ret=%d\n",
+			__func__, ret);
+
+		ret = -ENODEV;
+		goto init_sdmx_feed_failed;
+	}
+
+	/* PCR and sections have internal buffer for SDMX */
+	if (dvb_dmx_is_pcr_feed(mpq_feed->dvb_demux_feed))
+		ret = mpq_sdmx_alloc_data_buf(mpq_feed, SDMX_PCR_BUFFER_SIZE);
+	else if (dvb_dmx_is_sec_feed(mpq_feed->dvb_demux_feed))
+		ret = mpq_sdmx_alloc_data_buf(mpq_feed,
+			SDMX_SECTION_BUFFER_SIZE);
+	else
+		ret = 0;
+
+	if (ret) {
+		MPQ_DVB_ERR_PRINT("%s: init buffer failed, ret=%d\n",
+			__func__, ret);
+		goto init_sdmx_feed_failed_free_sdmx;
+	}
+
+	ret = mpq_sdmx_filter_setup(mpq_demux, mpq_feed->dvb_demux_feed);
+	if (ret) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: mpq_sdmx_filter_setup failed, ret=%d\n",
+			__func__, ret);
+		goto init_sdmx_feed_failed_free_data_buff;
+	}
+
+	mpq_demux->num_secure_feeds++;
+	return 0;
+
+init_sdmx_feed_failed_free_data_buff:
+	mpq_sdmx_free_data_buf(mpq_feed);
+init_sdmx_feed_failed_free_sdmx:
+	mpq_sdmx_close_session(mpq_demux);
+init_sdmx_feed_failed:
+	return ret;
+}
+
 int mpq_dmx_init_mpq_feed(struct dvb_demux_feed *feed)
 {
 	int ret = 0;
@@ -3597,80 +3747,113 @@
 
 	mutex_lock(&mpq_demux->mutex);
 
-	if (mpq_dmx_is_video_feed(feed)) {
-		ret = mpq_dmx_init_video_feed(mpq_feed);
-
-		if (ret) {
-			MPQ_DVB_ERR_PRINT(
-				"%s: mpq_dmx_init_video_feed failed, ret=%d\n",
-				__func__, ret);
-			goto init_mpq_feed_failed;
-		}
-	}
-
 	mpq_feed->sdmx_buf_handle = NULL;
 	mpq_feed->metadata_buf_handle = NULL;
 	mpq_feed->sdmx_filter_handle = SDMX_INVALID_FILTER_HANDLE;
 
-	if (!mpq_sdmx_is_loaded()) {
-		/* nothing more to do */
-		mpq_demux->sdmx_session_handle = SDMX_INVALID_SESSION_HANDLE;
-		mutex_unlock(&mpq_demux->mutex);
-		return ret;
+	if (dvb_dmx_is_video_feed(feed)) {
+		ret = mpq_dmx_init_video_feed(mpq_feed);
+		if (ret) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_dmx_init_video_feed failed, ret=%d\n",
+				__func__, ret);
+			goto init_mpq_feed_end;
+		}
 	}
 
-	/* Further initializations for secure demux */
-	ret = mpq_sdmx_open_session(mpq_demux);
+	/*
+	 * sdmx is not relevant for recording filters, which always use
+	 * regular filters (non-sdmx)
+	 */
+	if (!mpq_sdmx_is_loaded() || !feed->secure_mode.is_secured ||
+		dvb_dmx_is_rec_feed(feed)) {
+		if (!mpq_sdmx_is_loaded())
+			mpq_demux->sdmx_session_handle =
+				SDMX_INVALID_SESSION_HANDLE;
+		goto init_mpq_feed_end;
+	}
+
+	 /* Initialization of secure demux filters (PES/PCR/Video/Section) */
+	ret = mpq_sdmx_init_feed(mpq_demux, mpq_feed);
 	if (ret) {
 		MPQ_DVB_ERR_PRINT(
-			"%s: mpq_sdmx_open_session failed, ret=%d\n",
+			"%s: mpq_sdmx_init_feed failed, ret=%d\n",
 			__func__, ret);
-
-		ret = -ENODEV;
-		goto init_mpq_feed_failed_free_video;
+		if (dvb_dmx_is_video_feed(feed))
+			mpq_dmx_terminate_video_feed(mpq_feed);
 	}
 
-	/* PCR and sections have internal buffer for SDMX */
-	if (mpq_dmx_is_pcr_feed(feed))
-		ret = mpq_sdmx_alloc_data_buf(mpq_feed,
-			SDMX_PCR_BUFFER_SIZE);
-	else if (mpq_dmx_is_sec_feed(feed))
-		ret = mpq_sdmx_alloc_data_buf(mpq_feed,
-			SDMX_SECTION_BUFFER_SIZE);
-	else
-		ret = 0;
-
-	if (ret) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: init buffer failed, ret=%d\n",
-			__func__, ret);
-		goto init_mpq_feed_failed_free_sdmx;
-	}
-
-	ret = mpq_sdmx_filter_setup(mpq_demux, feed);
-	if (ret) {
-		MPQ_DVB_ERR_PRINT(
-			"%s: mpq_sdmx_filter_setup failed, ret=%d\n",
-			__func__, ret);
-		goto init_mpq_feed_failed_free_data_buff;
-	}
-
-	mutex_unlock(&mpq_demux->mutex);
-	return 0;
-
-init_mpq_feed_failed_free_data_buff:
-	mpq_sdmx_free_data_buf(mpq_feed);
-init_mpq_feed_failed_free_sdmx:
-	mpq_sdmx_close_session(mpq_demux);
-init_mpq_feed_failed_free_video:
-	if (mpq_dmx_is_video_feed(feed))
-		mpq_dmx_terminate_video_feed(mpq_feed);
-init_mpq_feed_failed:
+init_mpq_feed_end:
+	if (!ret)
+		mpq_demux->num_active_feeds++;
 	mutex_unlock(&mpq_demux->mutex);
 	return ret;
 }
 EXPORT_SYMBOL(mpq_dmx_init_mpq_feed);
 
+/**
+ * Note: Called only when filter is in "GO" state - after feed has been started.
+ */
+int mpq_dmx_set_secure_mode(struct dvb_demux_feed *feed,
+	struct dmx_secure_mode *sec_mode)
+{
+	struct mpq_feed *mpq_feed;
+	struct mpq_demux *mpq_demux;
+	int ret = 0;
+
+	if (!feed || !feed->priv || !sec_mode) {
+		MPQ_DVB_ERR_PRINT(
+			"%s: invalid parameters\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	MPQ_DVB_DBG_PRINT("%s(%d, %d, %d)\n",
+		__func__, sec_mode->pid,
+		sec_mode->is_secured,
+		sec_mode->key_ladder_id);
+
+	mpq_feed = feed->priv;
+	mpq_demux = mpq_feed->mpq_demux;
+
+	mutex_lock(&mpq_demux->mutex);
+
+	if (feed->secure_mode.is_secured != sec_mode->is_secured) {
+		/*
+		 * Switching between secure & non-secure mode is not allowed
+		 * while filter is running
+		 */
+		MPQ_DVB_ERR_PRINT(
+			"%s: Cannot switch between secure mode while filter is running\n",
+			__func__);
+		mutex_unlock(&mpq_demux->mutex);
+		return -EPERM;
+	}
+
+	/*
+	 * Feed is running in secure mode, this secure mode request is to
+	 * update the key ladder id
+	 */
+	if (feed->secure_mode.pid == sec_mode->pid && sec_mode->is_secured &&
+		feed->secure_mode.key_ladder_id != sec_mode->key_ladder_id &&
+		mpq_demux->sdmx_session_handle != SDMX_INVALID_SESSION_HANDLE) {
+		ret = sdmx_set_kl_ind(mpq_demux->sdmx_session_handle,
+			sec_mode->pid,
+			sec_mode->key_ladder_id);
+		if (ret) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: FAILED to set key ladder, ret=%d\n",
+				__func__, ret);
+			ret = -ENODEV;
+		}
+	}
+
+	mutex_unlock(&mpq_demux->mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(mpq_dmx_set_secure_mode);
+
 static void mpq_sdmx_prepare_filter_status(struct mpq_demux *mpq_demux,
 	struct sdmx_filter_status *filter_sts,
 	struct mpq_feed *mpq_feed)
@@ -3691,11 +3874,11 @@
 		__func__, filter_sts->metadata_fill_count,
 		filter_sts->metadata_write_offset);
 
-	if (!mpq_dmx_is_video_feed(feed)) {
+	if (!dvb_dmx_is_video_feed(feed)) {
 		struct dvb_ringbuffer *buffer;
 
-		if (mpq_dmx_is_sec_feed(feed) ||
-			mpq_dmx_is_pcr_feed(feed)) {
+		if (dvb_dmx_is_sec_feed(feed) ||
+			dvb_dmx_is_pcr_feed(feed)) {
 			buffer = (struct dvb_ringbuffer *)
 				&mpq_feed->sdmx_buf;
 		} else {
@@ -3862,6 +4045,7 @@
 {
 	int ret;
 	struct sdmx_metadata_header header;
+	struct sdmx_pes_counters counters;
 	struct dmx_data_ready data_event;
 	struct dmx_data_ready pes_event;
 	struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
@@ -3899,22 +4083,26 @@
 
 	while (sts->metadata_fill_count) {
 		if (dvb_ringbuffer_avail(&mpq_feed->metadata_buf) <
-			sizeof(header)) {
+			(sizeof(header) + sizeof(counters))) {
 			MPQ_DVB_ERR_PRINT(
 				"%s: metadata_fill_count is %d but actual buffer has less than %d bytes\n",
 				__func__,
 				sts->metadata_fill_count,
-				sizeof(header));
+				sizeof(header) + sizeof(counters));
 			break;
 		}
 
-		dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *) &header,
+		dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&header,
 			sizeof(header));
 		MPQ_DVB_DBG_PRINT(
 			"%s: metadata header: start=%u, length=%u\n",
 			__func__, header.payload_start, header.payload_length);
 		sts->metadata_fill_count -= sizeof(header);
 
+		dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&counters,
+			sizeof(counters));
+		sts->metadata_fill_count -= sizeof(counters);
+
 		/* Notify new data in buffer */
 		data_event.status = DMX_OK;
 		data_event.data_length = header.payload_length;
@@ -3940,11 +4128,13 @@
 			pes_event.pes_end.pes_length_mismatch = 1;
 		if (sts->error_indicators & SDMX_FILTER_ERR_CONT_CNT_INVALID)
 			pes_event.pes_end.disc_indicator_set = 0;
-		/* TODO: report these when SDMX returns them */
+
 		pes_event.pes_end.stc = 0;
-		pes_event.pes_end.tei_counter = 0;
-		pes_event.pes_end.cont_err_counter = 0;
-		pes_event.pes_end.ts_packets_num = 0;
+		pes_event.pes_end.tei_counter = counters.transport_err_count;
+		pes_event.pes_end.cont_err_counter =
+			counters.continuity_err_count;
+		pes_event.pes_end.ts_packets_num =
+			counters.pes_ts_count;
 
 		ret = mpq_sdmx_check_ts_stall(mpq_demux, mpq_feed, sts, 0, 1);
 		if (ret) {
@@ -4017,6 +4207,7 @@
 	struct sdmx_filter_status *sts)
 {
 	struct sdmx_metadata_header header;
+	struct sdmx_pes_counters counters;
 	int pes_header_offset;
 	struct ts_packet_header *ts_header;
 	struct ts_adaptation_field *ts_adapt;
@@ -4053,7 +4244,7 @@
 		struct mpq_adapter_video_meta_data meta_data;
 
 		pes_cnt++;
-		/* Read header & metadata */
+		/* Read metadata header */
 		dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&header,
 			sizeof(header));
 		sts->metadata_fill_count -= sizeof(header);
@@ -4062,17 +4253,23 @@
 			__func__, header.payload_start, header.payload_length,
 			header.metadata_length);
 
-		/* Read actual metadata */
+		/* Read metadata - PES counters */
+		dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&counters,
+					sizeof(counters));
+		sts->metadata_fill_count -= sizeof(counters);
+
+		/* Read metadata - TS & PES headers */
 		if (header.metadata_length < MAX_SDMX_METADATA_LENGTH)
 			dvb_ringbuffer_read(&mpq_feed->metadata_buf,
 				metadata_buf,
-				header.metadata_length);
+				header.metadata_length - sizeof(counters));
 		else
 			MPQ_DVB_ERR_PRINT(
 				"%s: meta-data size=%d is too big for meta-data buffer=%d\n",
 				__func__, header.metadata_length,
 				MAX_SDMX_METADATA_LENGTH);
-		sts->metadata_fill_count -= header.metadata_length;
+		sts->metadata_fill_count -=
+			(header.metadata_length - sizeof(counters));
 
 		ts_header = (struct ts_packet_header *)&metadata_buf[0];
 		if (1 == ts_header->adaptation_field_control) {
@@ -4112,6 +4309,16 @@
 		}
 
 		spin_lock(&mpq_feed->video_info.video_buffer_lock);
+
+		mpq_feed->video_info.tei_errs =
+			counters.transport_err_count;
+		mpq_feed->video_info.continuity_errs =
+			counters.continuity_err_count;
+		mpq_feed->video_info.ts_packets_num =
+			counters.pes_ts_count;
+		mpq_feed->video_info.ts_dropped_bytes =
+			counters.drop_count * mpq_demux->demux.ts_packet_size;
+
 		sbuf = mpq_feed->video_info.video_buffer;
 		if (sbuf == NULL) {
 			MPQ_DVB_ERR_PRINT(
@@ -4135,7 +4342,12 @@
 				__func__, ret);
 		}
 		mpq_dmx_update_decoder_stat(mpq_demux);
-		mpq_streambuffer_pkt_write(sbuf, &packet, (u8 *)&meta_data);
+		if (mpq_streambuffer_pkt_write(sbuf,
+				&packet,
+				(u8 *)&meta_data) < 0)
+			MPQ_DVB_ERR_PRINT(
+				"%s: Couldn't write packet. Should never happen\n",
+				__func__);
 
 		if (generate_es_events) {
 			struct dmx_data_ready data;
@@ -4339,14 +4551,15 @@
 	}
 }
 
-int mpq_sdmx_process(struct mpq_demux *mpq_demux,
+static int mpq_sdmx_process_buffer(struct mpq_demux *mpq_demux,
 	struct sdmx_buff_descr *input,
 	u32 fill_count,
 	u32 read_offset)
 {
 	struct sdmx_filter_status *sts;
 	struct mpq_feed *mpq_feed;
-	u8 flags = 0;	/* MPQ_TODO: EOS handling */
+	/* MPQ_TODO: EOS handling */
+	u8 flags = mpq_sdmx_debug ? SDMX_INPUT_FLAG_DBG_ENABLE : 0;
 	u32 errors;
 	u32 status;
 	u32 prev_read_offset;
@@ -4435,6 +4648,41 @@
 
 	return bytes_read;
 }
+
+int mpq_sdmx_process(struct mpq_demux *mpq_demux,
+	struct sdmx_buff_descr *input,
+	u32 fill_count,
+	u32 read_offset)
+{
+	int ret;
+	int todo;
+	int total_bytes_read = 0;
+	int limit = mpq_sdmx_proc_limit * mpq_demux->demux.ts_packet_size;
+
+	while (fill_count >= mpq_demux->demux.ts_packet_size) {
+		todo = fill_count > limit ? limit : fill_count;
+		ret = mpq_sdmx_process_buffer(mpq_demux, input, todo,
+			read_offset);
+		if (ret > 0) {
+			total_bytes_read += ret;
+			fill_count -= ret;
+			read_offset += ret;
+			if (read_offset >= input->size)
+				read_offset -= input->size;
+		} else if (ret == 0) {
+			/* Not enough data to read (less than 1 TS packet) */
+			break;
+		} else {
+			/* Some error occurred */
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_sdmx_process_buffer failed, returned %d\n",
+				__func__, ret);
+			break;
+		}
+	}
+
+	return total_bytes_read;
+}
 EXPORT_SYMBOL(mpq_sdmx_process);
 
 static int mpq_sdmx_write(struct mpq_demux *mpq_demux,
@@ -4474,6 +4722,7 @@
 {
 	struct dvb_demux *dvb_demux;
 	struct mpq_demux *mpq_demux;
+	int ret = count;
 
 	if (demux == NULL)
 		return -EINVAL;
@@ -4481,25 +4730,50 @@
 	dvb_demux = demux->priv;
 	mpq_demux = dvb_demux->priv;
 
-	if (mpq_sdmx_is_loaded()) {
-		/* route through secure demux */
-		return mpq_sdmx_write(mpq_demux,
+	/* Route through secure demux - process secure feeds if any exist */
+	if (mpq_sdmx_is_loaded() && mpq_demux->sdmx_filter_count) {
+		ret = mpq_sdmx_write(mpq_demux,
 			demux->dvr_input.priv_handle,
 			buf,
 			count);
-	} else {
-		/* route through sw filter */
-		dvb_dmx_swfilter_format(dvb_demux, buf, count,
-			dvb_demux->tsp_format);
-		if (signal_pending(current))
-			return -EINTR;
-		return count;
+		if (ret < 0) {
+			MPQ_DVB_ERR_PRINT(
+				"%s: mpq_sdmx_write failed. ret = %d\n",
+				__func__, ret);
+			ret = count;
+		}
 	}
+
+	/*
+	 * Route through sw filter - process non-secure feeds if any exist.
+	 * For sw filter, should process the same amount of bytes the sdmx
+	 * process managed to consume, unless some sdmx error occurred, for
+	 * which should process the whole buffer
+	 */
+	if (mpq_demux->num_active_feeds > mpq_demux->num_secure_feeds) {
+		dvb_dmx_swfilter_format(dvb_demux, buf, ret,
+			dvb_demux->tsp_format);
+	}
+
+	if (signal_pending(current))
+		return -EINTR;
+
+	return ret;
 }
 EXPORT_SYMBOL(mpq_dmx_write);
 
 int mpq_sdmx_is_loaded(void)
 {
-	return mpq_bypass_sdmx ? 0 : mpq_dmx_info.secure_demux_app_loaded;
+	static int sdmx_load_checked;
+
+	if (mpq_bypass_sdmx)
+		return 0;
+
+	if (!sdmx_load_checked) {
+		mpq_sdmx_check_app_loaded();
+		sdmx_load_checked = 1;
+	}
+
+	return mpq_dmx_info.secure_demux_app_loaded;
 }
 EXPORT_SYMBOL(mpq_sdmx_is_loaded);
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
index 2c2420b..8d2010b 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
@@ -362,6 +362,9 @@
  * @ion_client: ION demux client used to allocate memory from ION.
  * @mutex: Lock used to protect against private feed data
  * @feeds: mpq common feed object pool
+ * @num_active_feeds: Number of active mpq feeds
+ * @num_secure_feeds: Number of secure feeds (have a sdmx filter associated)
+ * currently allocated.
  * @filters_status: Array holding buffers status for each secure demux filter.
  * Used before each call to sdmx_process() to build up to date state.
  * @sdmx_session_handle: Secure demux open session handle
@@ -406,6 +409,8 @@
 	struct ion_client *ion_client;
 	struct mutex mutex;
 	struct mpq_feed feeds[MPQ_MAX_DMX_FILES];
+	u32 num_active_feeds;
+	u32 num_secure_feeds;
 	struct sdmx_filter_status filters_status[MPQ_MAX_DMX_FILES];
 	int sdmx_session_handle;
 	int sdmx_session_ref_count;
@@ -431,6 +436,7 @@
 	u32 sdmx_process_packets_sum;
 	u32 sdmx_process_packets_average;
 	u32 sdmx_process_packets_min;
+	enum sdmx_log_level sdmx_log_level;
 
 	struct timespec decoder_out_last_time;
 	struct timespec last_notification_time;
@@ -615,92 +621,13 @@
 int mpq_dmx_process_pcr_packet(struct dvb_demux_feed *feed, const u8 *buf);
 
 /**
- * mpq_dmx_is_video_feed - Returns whether the PES feed
- * is video one.
- *
- * @feed: The feed to be checked.
- *
- * Return     1 if feed is video feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_video_feed(struct dvb_demux_feed *feed)
-{
-	if (feed->type != DMX_TYPE_TS)
-		return 0;
-
-	if (feed->ts_type & (~TS_DECODER))
-		return 0;
-
-	if ((feed->pes_type == DMX_TS_PES_VIDEO0) ||
-		(feed->pes_type == DMX_TS_PES_VIDEO1) ||
-		(feed->pes_type == DMX_TS_PES_VIDEO2) ||
-		(feed->pes_type == DMX_TS_PES_VIDEO3))
-		return 1;
-
-	return 0;
-}
-
-/**
- * mpq_dmx_is_pcr_feed - Returns whether the PES feed
- * is PCR one.
- *
- * @feed: The feed to be checked.
- *
- * Return     1 if feed is PCR feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_pcr_feed(struct dvb_demux_feed *feed)
-{
-	if (feed->type != DMX_TYPE_TS)
-		return 0;
-
-	if (feed->ts_type & (~TS_DECODER))
-		return 0;
-
-	if ((feed->pes_type == DMX_TS_PES_PCR0) ||
-		(feed->pes_type == DMX_TS_PES_PCR1) ||
-		(feed->pes_type == DMX_TS_PES_PCR2) ||
-		(feed->pes_type == DMX_TS_PES_PCR3))
-		return 1;
-
-	return 0;
-}
-
-/**
- * mpq_dmx_is_sec_feed - Returns whether this is a section feed
- *
- * @feed: The feed to be checked.
- *
- * Return 1 if feed is a section feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_sec_feed(struct dvb_demux_feed *feed)
-{
-	return (feed->type == DMX_TYPE_SEC);
-}
-
-/**
- * mpq_dmx_is_rec_feed - Returns whether this is a recording feed
- *
- * @feed: The feed to be checked.
- *
- * Return 1 if feed is recording feed, 0 otherwise.
- */
-static inline int mpq_dmx_is_rec_feed(struct dvb_demux_feed *feed)
-{
-	if (feed->type != DMX_TYPE_TS)
-		return 0;
-
-	if (feed->ts_type & (TS_DECODER | TS_PAYLOAD_ONLY))
-		return 0;
-
-	return 1;
-}
-
-/**
- * mpq_dmx_init_hw_statistics -
- * Extend dvb-demux debugfs with HW statistics.
+ * mpq_dmx_init_debugfs_entries -
+ * Extend dvb-demux debugfs with mpq related entries (HW statistics and secure
+ * demux log level).
  *
  * @mpq_demux: The mpq_demux device to initialize.
  */
-void mpq_dmx_init_hw_statistics(struct mpq_demux *mpq_demux);
+void mpq_dmx_init_debugfs_entries(struct mpq_demux *mpq_demux);
 
 /**
  * mpq_dmx_update_hw_statistics -
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
index b29759c..d48ecee 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
@@ -518,10 +518,10 @@
 				"%s: warnning - len larger than one packet\n",
 				__func__);
 
-	if (mpq_dmx_is_video_feed(feed))
+	if (dvb_dmx_is_video_feed(feed))
 		return mpq_dmx_process_video_packet(feed, buf);
 
-	if (mpq_dmx_is_pcr_feed(feed))
+	if (dvb_dmx_is_pcr_feed(feed))
 		return mpq_dmx_process_pcr_packet(feed, buf);
 
 	return 0;
@@ -718,7 +718,7 @@
 	}
 
 	/* Extend dvb-demux debugfs with TSIF statistics. */
-	mpq_dmx_init_hw_statistics(mpq_demux);
+	mpq_dmx_init_debugfs_entries(mpq_demux);
 
 	return 0;
 
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
index 49f87ba..8ff3a85 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
@@ -306,6 +306,30 @@
 }
 
 /**
+ * mpq_dmx_tspp_swfilter_desc - helper function
+ *
+ * Takes a tspp buffer descriptor and send it to the SW filter for demuxing,
+ * one TS packet at a time.
+ *
+ * @mpq_demux - mpq demux object
+ * @tspp_data_desc - tspp buffer descriptor
+ */
+static inline void mpq_dmx_tspp_swfilter_desc(struct mpq_demux *mpq_demux,
+	const struct tspp_data_descriptor *tspp_data_desc)
+{
+	u32 notif_size;
+	int i;
+
+	notif_size = tspp_data_desc->size / TSPP_RAW_TTS_SIZE;
+	for (i = 0; i < notif_size; i++)
+		dvb_dmx_swfilter_packet(&mpq_demux->demux,
+			((u8 *)tspp_data_desc->virt_base) +
+			i * TSPP_RAW_TTS_SIZE,
+			((u8 *)tspp_data_desc->virt_base) +
+			i * TSPP_RAW_TTS_SIZE + TSPP_RAW_SIZE);
+}
+
+/**
  * Demux TS packets from TSPP by secure-demux.
  * The fucntion assumes the buffer is physically contiguous
  * and that TSPP descriptors are continuous in memory.
@@ -320,37 +344,46 @@
 	struct sdmx_buff_descr input;
 	size_t aggregate_len = 0;
 	size_t aggregate_count = 0;
-	phys_addr_t buff_start_addr;
-	phys_addr_t buff_current_addr = 0;
+	phys_addr_t buff_start_addr_phys;
+	phys_addr_t buff_current_addr_phys = 0;
+	u32 notif_size;
 	int i;
 
 	while ((tspp_data_desc = tspp_get_buffer(0, channel_id)) != NULL) {
 		if (0 == aggregate_count)
-			buff_current_addr = tspp_data_desc->phys_base;
+			buff_current_addr_phys = tspp_data_desc->phys_base;
+		notif_size = tspp_data_desc->size / TSPP_RAW_TTS_SIZE;
 		mpq_dmx_tspp_info.tsif[tsif].aggregate_ids[aggregate_count] =
 			tspp_data_desc->id;
 		aggregate_len += tspp_data_desc->size;
 		aggregate_count++;
-		mpq_demux->hw_notification_size +=
-			tspp_data_desc->size / TSPP_RAW_TTS_SIZE;
+		mpq_demux->hw_notification_size += notif_size;
+
+		/* Let SW filter process only if it might be relevant */
+		if (mpq_demux->num_active_feeds > mpq_demux->num_secure_feeds)
+			mpq_dmx_tspp_swfilter_desc(mpq_demux, tspp_data_desc);
+
 	}
 
 	if (!aggregate_count)
 		return;
 
-	buff_start_addr = mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_phys_base;
-	input.base_addr = (void *)buff_start_addr;
+	buff_start_addr_phys =
+		mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_phys_base;
+	input.base_addr = (void *)buff_start_addr_phys;
 	input.size = mpq_dmx_tspp_info.tsif[tsif].buffer_count *
 		TSPP_DESCRIPTOR_SIZE;
 
-	MPQ_DVB_DBG_PRINT(
-		"%s: Processing %d descriptors: %d bytes at start address 0x%x, read offset %d\n",
-		__func__, aggregate_count, aggregate_len,
-		(unsigned int)input.base_addr,
-		buff_current_addr - buff_start_addr);
+	if (mpq_sdmx_is_loaded() && mpq_demux->sdmx_filter_count) {
+		MPQ_DVB_DBG_PRINT(
+			"%s: SDMX Processing %d descriptors: %d bytes at start address 0x%x, read offset %d\n",
+			__func__, aggregate_count, aggregate_len,
+			(unsigned int)input.base_addr,
+			buff_current_addr_phys - buff_start_addr_phys);
 
-	mpq_sdmx_process(mpq_demux, &input, aggregate_len,
-		 buff_current_addr - buff_start_addr);
+		mpq_sdmx_process(mpq_demux, &input, aggregate_len,
+			buff_current_addr_phys - buff_start_addr_phys);
+	}
 
 	for (i = 0; i < aggregate_count; i++)
 		tspp_release_buffer(0, channel_id,
@@ -373,7 +406,6 @@
 	int channel_id;
 	int ref_count;
 	int ret;
-	int j;
 
 	do {
 		ret = wait_event_interruptible(
@@ -427,13 +459,8 @@
 					TSPP_RAW_TTS_SIZE;
 				mpq_demux->hw_notification_size += notif_size;
 
-				for (j = 0; j < notif_size; j++)
-					dvb_dmx_swfilter_packet(
-					 &mpq_demux->demux,
-					 ((u8 *)tspp_data_desc->virt_base) +
-					 j * TSPP_RAW_TTS_SIZE,
-					 ((u8 *)tspp_data_desc->virt_base) +
-					 j * TSPP_RAW_TTS_SIZE + TSPP_RAW_SIZE);
+				mpq_dmx_tspp_swfilter_desc(mpq_demux,
+					tspp_data_desc);
 				/*
 				 * Notify TSPP that the buffer
 				 * is no longer needed
@@ -1433,8 +1460,8 @@
 	if (*channel_ref_count == 0) {
 		/* channel is not used any more, release it */
 		tspp_unregister_notification(0, channel_id);
-		tspp_close_channel(0, channel_id);
 		tspp_close_stream(0, channel_id);
+		tspp_close_channel(0, channel_id);
 		atomic_set(data_cnt, 0);
 
 		if (allocation_mode == MPQ_DMX_TSPP_CONTIGUOUS_PHYS_ALLOC)
@@ -1554,10 +1581,10 @@
 				"%s: warnning - len larger than one packet\n",
 				__func__);
 
-	if (mpq_dmx_is_video_feed(feed))
+	if (dvb_dmx_is_video_feed(feed))
 		return mpq_dmx_process_video_packet(feed, buf);
 
-	if (mpq_dmx_is_pcr_feed(feed))
+	if (dvb_dmx_is_pcr_feed(feed))
 		return mpq_dmx_process_pcr_packet(feed, buf);
 
 	return 0;
@@ -1746,7 +1773,7 @@
 	}
 
 	/* Extend dvb-demux debugfs with TSPP statistics. */
-	mpq_dmx_init_hw_statistics(mpq_demux);
+	mpq_dmx_init_debugfs_entries(mpq_demux);
 
 	return 0;
 
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v2.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v2.c
index 21483ee..60ce9e5 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v2.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/dvb/mpq/demux/mpq_sdmx.c b/drivers/media/dvb/mpq/demux/mpq_sdmx.c
index 0f91930..14d3a39 100644
--- a/drivers/media/dvb/mpq/demux/mpq_sdmx.c
+++ b/drivers/media/dvb/mpq/demux/mpq_sdmx.c
@@ -38,7 +38,9 @@
 	SDMX_PROCESS_CMD,
 	SDMX_GET_DBG_COUNTERS_CMD,
 	SDMX_RESET_DBG_COUNTERS_CMD,
-	SDMX_GET_VERSION_CMD
+	SDMX_GET_VERSION_CMD,
+	SDMX_INVALIDATE_KL_CMD,
+	SDMX_SET_LOG_LEVEL_CMD
 };
 
 struct sdmx_proc_req {
@@ -110,6 +112,8 @@
 	enum sdmx_filter filter_type;
 	struct sdmx_buff_descr meta_data_buf;
 	enum sdmx_buf_mode buffer_mode;
+	enum sdmx_raw_out_format ts_out_format;
+	u32 flags;
 	u32 num_data_bufs;
 	struct sdmx_buff_descr data_bufs[];
 };
@@ -182,6 +186,15 @@
 	int32_t version;
 };
 
+struct sdmx_set_log_level_req {
+	enum sdmx_cmd_id cmd_id;
+	enum sdmx_log_level level;
+	u32 session_handle;
+};
+
+struct sdmx_set_log_level_rsp {
+	enum sdmx_status ret;
+};
 static void get_cmd_rsp_buffers(int handle_index,
 	void **cmd,
 	int *cmd_len,
@@ -453,6 +466,9 @@
  * @num_data_bufs: number of data buffers (use 1 for a ring buffer)
  * @data_bufs: data buffers descriptors array
  * @filter_handle: returned filter handle
+ * @ts_out_format: output format for raw filters
+ * @flags: optional flags for filter
+ *	   (currently only clear section CRC verification is supported)
  *
  * Return error code
  */
@@ -463,7 +479,9 @@
 	enum sdmx_buf_mode d_buf_mode,
 	u32 num_data_bufs,
 	struct sdmx_buff_descr *data_bufs,
-	int *filter_handle)
+	int *filter_handle,
+	enum sdmx_raw_out_format ts_out_format,
+	u32 flags)
 {
 	int res, cmd_len, rsp_len;
 	struct sdmx_add_filt_req *cmd;
@@ -493,6 +511,8 @@
 	cmd->session_handle = session_handle;
 	cmd->pid = (u32)pid;
 	cmd->filter_type = filterype;
+	cmd->ts_out_format = ts_out_format;
+	cmd->flags = flags;
 	if (meta_data_buf != NULL)
 		memcpy(&(cmd->meta_data_buf), meta_data_buf,
 			sizeof(struct sdmx_buff_descr));
@@ -926,3 +946,48 @@
 	return ret;
 }
 EXPORT_SYMBOL(sdmx_reset_dbg_counters);
+
+/*
+ * Set debug log verbosity level
+ *
+ * @session_handle: secure demux instance
+ * @level: requested log level
+ *
+ * Return error code
+ */
+int sdmx_set_log_level(int session_handle, enum sdmx_log_level level)
+{
+	int res, cmd_len, rsp_len;
+	struct sdmx_set_log_level_req *cmd;
+	struct sdmx_set_log_level_rsp *rsp;
+	enum sdmx_status ret;
+
+	cmd_len = sizeof(struct sdmx_set_log_level_req);
+	rsp_len = sizeof(struct sdmx_set_log_level_rsp);
+
+	/* Get command and response buffers */
+	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+
+	/* Lock shared memory */
+	mutex_lock(&sdmx_lock[session_handle]);
+
+	/* Populate command struct */
+	cmd->cmd_id = SDMX_SET_LOG_LEVEL_CMD;
+	cmd->session_handle = session_handle;
+	cmd->level = level;
+
+	/* Issue QSEECom command */
+	res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+		(void *)cmd, cmd_len, (void *)rsp, rsp_len);
+	if (res < 0) {
+		mutex_unlock(&sdmx_lock[session_handle]);
+		return SDMX_STATUS_GENERAL_FAILURE;
+	}
+	ret = rsp->ret;
+
+	/* Unlock */
+	mutex_unlock(&sdmx_lock[session_handle]);
+	return ret;
+}
+
diff --git a/drivers/media/dvb/mpq/demux/mpq_sdmx.h b/drivers/media/dvb/mpq/demux/mpq_sdmx.h
index ffb9046..6b669e4 100644
--- a/drivers/media/dvb/mpq/demux/mpq_sdmx.h
+++ b/drivers/media/dvb/mpq/demux/mpq_sdmx.h
@@ -27,29 +27,33 @@
 #define SDMX_FILTER_ERR_INVALID_SCRAMBLE_BITS     BIT(3)
 #define SDMX_FILTER_ERR_KL_IND_NOT_SET            BIT(4)
 #define SDMX_FILTER_ERR_CAS_DECRYPT_ERROR         BIT(5)
-#define SDMX_FILTER_ERR_SEC_VERIF_GENERAL_FAIL    BIT(6)
-#define SDMX_FILTER_ERR_SEC_VERIF_CRC32_FAIL      BIT(7)
-#define SDMX_FILTER_ERR_SEC_INTERNAL_MALLOC_FAIL  BIT(8)
-#define SDMX_FILTER_ERR_SEC_LEN_INVALID           BIT(9)
-#define SDMX_FILTER_ERR_SEC_PUSI_PTR_INVALID      BIT(10)
-#define SDMX_FILTER_ERR_TS_SYNC_BYTE_INVALID      BIT(11)
-#define SDMX_FILTER_ERR_TS_TRANSPORT_ERR          BIT(12)
-#define SDMX_FILTER_ERR_CONT_CNT_INVALID          BIT(13)
-#define SDMX_FILTER_ERR_CONT_CNT_DUPLICATE        BIT(14)
-#define SDMX_FILTER_ERR_INVALID_PES_HDR           BIT(15)
-#define SDMX_FILTER_ERR_INVALID_PES_LEN           BIT(16)
-#define SDMX_FILTER_ERR_INVALID_PES_ENCRYPTION    BIT(17)
-#define SDMX_FILTER_ERR_SECURITY_FAULT            BIT(18)
-#define SDMX_FILTER_ERR_IN_NS_BUFFER              BIT(19)
+#define SDMX_FILTER_ERR_SEC_VERIF_CRC32_FAIL      BIT(6)
+#define SDMX_FILTER_ERR_SEC_INTERNAL_MALLOC_FAIL  BIT(7)
+#define SDMX_FILTER_ERR_SEC_LEN_INVALID           BIT(8)
+#define SDMX_FILTER_ERR_SEC_PUSI_PTR_INVALID      BIT(9)
+#define SDMX_FILTER_ERR_TS_SYNC_BYTE_INVALID      BIT(10)
+#define SDMX_FILTER_ERR_TS_TRANSPORT_ERR          BIT(11)
+#define SDMX_FILTER_ERR_CONT_CNT_INVALID          BIT(12)
+#define SDMX_FILTER_ERR_CONT_CNT_DUPLICATE        BIT(13)
+#define SDMX_FILTER_ERR_INVALID_PES_HDR           BIT(14)
+#define SDMX_FILTER_ERR_INVALID_PES_LEN           BIT(15)
+#define SDMX_FILTER_ERR_INVALID_PES_ENCRYPTION    BIT(16)
+#define SDMX_FILTER_ERR_SECURITY_FAULT            BIT(17)
+#define SDMX_FILTER_ERR_IN_NS_BUFFER              BIT(18)
 
 /* Filter-level status indicators */
 #define SDMX_FILTER_STATUS_EOS                    BIT(0)
+#define SDMX_FILTER_STATUS_WR_PTR_CHANGED         BIT(1)
+
+/* Filter-level flags */
+#define SDMX_FILTER_FLAG_VERIFY_SECTION_CRC	BIT(0)
 
 #define SDMX_INVALID_SESSION_HANDLE		(-1)
 #define SDMX_INVALID_FILTER_HANDLE		(-1)
 
 /* Input flags */
-#define SDMX_INPUT_FLAG_EOS BIT(0)
+#define SDMX_INPUT_FLAG_EOS		BIT(0)
+#define SDMX_INPUT_FLAG_DBG_ENABLE	BIT(1)
 
 
 enum sdmx_buf_mode {
@@ -74,6 +78,13 @@
 	SDMX_195_BYTE_PKT = 195,
 };
 
+enum sdmx_log_level {
+	SDMX_LOG_NO_PRINT,
+	SDMX_LOG_MSG_ERROR,
+	SDMX_LOG_DEBUG,
+	SDMX_LOG_VERBOSE
+};
+
 enum sdmx_status {
 	SDMX_SUCCESS = 0,
 	SDMX_STATUS_GENERAL_FAILURE = -1,
@@ -89,10 +100,9 @@
 	SDMX_STATUS_SINGLE_PID_RAW_FILTER = -11,
 	SDMX_STATUS_INP_BUF_INVALID_PARAMS = -12,
 	SDMX_STATUS_INVALID_FILTER_CFG = -13,
-	SDMX_STATUS_ILLEGAL_WR_PTR_CHANGE = -14,
-	SDMX_STATUS_STALLED_IN_PULL_MODE = -15,
-	SDMX_STATUS_SECURITY_FAULT = -16,
-	SDMX_STATUS_NS_BUFFER_ERROR = -17,
+	SDMX_STATUS_STALLED_IN_PULL_MODE = -14,
+	SDMX_STATUS_SECURITY_FAULT = -15,
+	SDMX_STATUS_NS_BUFFER_ERROR = -16,
 };
 
 enum sdmx_filter {
@@ -103,6 +113,12 @@
 	SDMX_RAW_FILTER,		/* Recording */
 };
 
+enum sdmx_raw_out_format {
+	SDMX_188_OUTPUT,
+	SDMX_192_HEAD_OUTPUT,
+	SDMX_192_TAIL_OUTPUT
+};
+
 struct sdmx_session_dbg_counters {
 	/* Total number of TS-packets input to SDMX. */
 	u32 ts_pkt_in;
@@ -130,6 +146,20 @@
 	u32 ts_pkt_key_not_ready;
 };
 
+struct sdmx_pes_counters {
+	/* Number of TS packets with the TEI flag set */
+	u32 transport_err_count;
+
+	/* Number of TS packets with continuity counter errors */
+	u32 continuity_err_count;
+
+	/* Number of TS packets composing this PES frame */
+	u32 pes_ts_count;
+
+	/* Number of TS packets dropped due to full buffer */
+	u32 drop_count;
+};
+
 struct sdmx_buff_descr {
 	/* Physical address where buffer starts */
 	void *base_addr;
@@ -155,9 +185,7 @@
 	/* Payload length */
 	u32 payload_length;
 
-	/* Total metadata length (including this header, plus optional
-	 * additional metadata.
-	 */
+	/* Number of meta data bytes immediately following this header */
 	u32 metadata_length;
 };
 
@@ -204,7 +232,7 @@
 int sdmx_add_filter(int session_handle, u16 pid, enum sdmx_filter filter_type,
 	struct sdmx_buff_descr *meta_data_buf, enum sdmx_buf_mode data_buf_mode,
 	u32 num_data_bufs, struct sdmx_buff_descr *data_bufs,
-	int *filter_handle);
+	int *filter_handle, enum sdmx_raw_out_format ts_out_format, u32 flags);
 
 int sdmx_remove_filter(int session_handle, int filter_handle);
 
@@ -229,4 +257,6 @@
 
 int sdmx_reset_dbg_counters(int session_handle);
 
+int sdmx_set_log_level(int session_handle, enum sdmx_log_level level);
+
 #endif /* _MPQ_SDMX_H */
diff --git a/drivers/media/dvb/mpq/include/mpq_adapter.h b/drivers/media/dvb/mpq/include/mpq_adapter.h
index c9b2441..23121b2 100644
--- a/drivers/media/dvb/mpq/include/mpq_adapter.h
+++ b/drivers/media/dvb/mpq/include/mpq_adapter.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/dvb/mpq/include/mpq_dvb_debug.h b/drivers/media/dvb/mpq/include/mpq_dvb_debug.h
index 4890b85..0b00b71 100644
--- a/drivers/media/dvb/mpq/include/mpq_dvb_debug.h
+++ b/drivers/media/dvb/mpq/include/mpq_dvb_debug.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/dvb/mpq/include/mpq_stream_buffer.h b/drivers/media/dvb/mpq/include/mpq_stream_buffer.h
index e5ba635..3804fb2 100644
--- a/drivers/media/dvb/mpq/include/mpq_stream_buffer.h
+++ b/drivers/media/dvb/mpq/include/mpq_stream_buffer.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/radio/radio-iris-transport.c b/drivers/media/radio/radio-iris-transport.c
index ed6ab4d..9a9b385 100644
--- a/drivers/media/radio/radio-iris-transport.c
+++ b/drivers/media/radio/radio-iris-transport.c
@@ -4,7 +4,7 @@
  *  FM HCI_SMD ( FM HCI Shared Memory Driver) is Qualcomm's Shared memory driver
  *  for the HCI protocol. This file is based on drivers/bluetooth/hci_vhci.c
  *
- *  Copyright (c) 2000-2001, 2011-2012 Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2000-2001, 2011-2012 The Linux Foundation. All rights reserved.
  *
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index d380c46..2724d3f 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -49,6 +49,7 @@
 static char utf_8_flag;
 static char rt_ert_flag;
 static char formatting_dir;
+static DEFINE_MUTEX(iris_fm);
 
 module_param(rds_buf, uint, 0);
 MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
@@ -1167,6 +1168,7 @@
 
 	DECLARE_WAITQUEUE(wait, current);
 
+	mutex_lock(&iris_fm);
 	hdev->req_status = HCI_REQ_PEND;
 
 	add_wait_queue(&hdev->req_wait_q, &wait);
@@ -1178,8 +1180,10 @@
 
 	remove_wait_queue(&hdev->req_wait_q, &wait);
 
-	if (signal_pending(current))
+	if (signal_pending(current)) {
+		mutex_unlock(&iris_fm);
 		return -EINTR;
+	}
 
 	switch (hdev->req_status) {
 	case HCI_REQ_DONE:
@@ -1197,6 +1201,7 @@
 	}
 
 	hdev->req_status = hdev->req_result = 0;
+	mutex_unlock(&iris_fm);
 
 	return err;
 }
@@ -2535,7 +2540,6 @@
 		case SCAN_FOR_WEAK:
 			radio->srch_st_list.srch_list_dir = dir;
 			radio->srch_st_list.srch_list_mode = srch;
-			radio->srch_st_list.srch_list_max = 0;
 			retval = hci_fm_search_station_list(
 				&radio->srch_st_list, radio->fm_hdev);
 			break;
@@ -3280,6 +3284,7 @@
 		radio->srch_rds.srch_pi = ctrl->value;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
+		radio->srch_st_list.srch_list_max = ctrl->value;
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SPACING:
 		if (radio->mode == FM_RECV) {
@@ -3998,6 +4003,31 @@
 	return retval;
 }
 
+static int iris_fops_release(struct file *file)
+{
+	struct iris_device *radio = video_get_drvdata(video_devdata(file));
+	int retval = 0;
+
+	FMDBG("Enter %s ", __func__);
+	if (radio == NULL)
+		return -EINVAL;
+
+	if (radio->mode == FM_OFF)
+		return 0;
+
+	if (radio->mode == FM_RECV)
+		retval = hci_cmd(HCI_FM_DISABLE_RECV_CMD,
+						radio->fm_hdev);
+	else if (radio->mode == FM_TRANS)
+		retval = hci_cmd(HCI_FM_DISABLE_TRANS_CMD,
+					radio->fm_hdev);
+	if (retval < 0)
+		FMDERR("Err on disable FM %d\n", retval);
+
+	radio->mode = FM_OFF;
+	return retval;
+}
+
 static int iris_vidioc_dqbuf(struct file *file, void *priv,
 				struct v4l2_buffer *buffer)
 {
@@ -4092,6 +4122,7 @@
 static const struct v4l2_file_operations iris_fops = {
 	.owner = THIS_MODULE,
 	.unlocked_ioctl = video_ioctl2,
+	.release        = iris_fops_release,
 };
 
 static struct video_device iris_viddev_template = {
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index af4c2c9..b9f1625 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2013, The Linux Foundation. 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 and
@@ -744,7 +744,15 @@
 		return;
 	}
 	mutex_lock(&radio->lock);
-	tavarua_read_registers(radio, STATUS_REG1, STATUS_REG_NUM);
+	retval = tavarua_read_registers(radio, STATUS_REG1, STATUS_REG_NUM);
+	if (retval < 0) {
+		FMDERR("Fails to read status register and try once again");
+		msleep(TAVARUA_DELAY);
+		retval = tavarua_read_registers(radio, STATUS_REG1,
+							STATUS_REG_NUM);
+		if (retval < 0)
+			FMDERR("Fails to read status register");
+	}
 
 	FMDBG("INTSTAT1 <%x>\n", radio->registers[STATUS_REG1]);
 	FMDBG("INTSTAT2 <%x>\n", radio->registers[STATUS_REG2]);
@@ -1354,13 +1362,16 @@
 	/* Set channel spacing */
 	switch (region) {
 	case TAVARUA_REGION_US:
-		if (adie_type_bahma) {
+		if ((adie_type_bahma) && (bahama_version == 0x09)) {
 			FMDBG("Adie type : Bahama\n");
 			/*
 			Configuring all 200KHZ spaced regions as 100KHz due to
 			change in the new Bahma FM SoC search algorithm.
 			*/
 			value = FM_CH_SPACE_100KHZ;
+		} else if ((adie_type_bahma) && (bahama_version == 0x0a)) {
+			FMDBG("Adie type : Bahama B1\n");
+			value = FM_CH_SPACE_200KHZ;
 		} else {
 			FMDBG("Adie type : Marimba\n");
 			value = FM_CH_SPACE_200KHZ;
@@ -1368,7 +1379,7 @@
 		break;
 	case TAVARUA_REGION_JAPAN:
 	case TAVARUA_REGION_OTHER:
-		if (adie_type_bahma) {
+		if ((adie_type_bahma) && (bahama_version == 0x09)) {
 			FMDBG("Adie type : Bahama\n");
 			FMDBG("%s: Configuring the channel-spacing as 50KHz"
 				"for the Region : %d", __func__, region);
@@ -1377,6 +1388,9 @@
 			change in the new Bahma FM SoC search algorithm.
 			*/
 			value = FM_CH_SPACE_50KHZ;
+		} else if ((adie_type_bahma) && (bahama_version == 0x0a)) {
+			FMDBG("Adie type : Bahama B1\n");
+			value = FM_CH_SPACE_100KHZ;
 		} else {
 			FMDBG("Adie type : Marimba\n");
 			value = FM_CH_SPACE_100KHZ;
@@ -1940,7 +1954,7 @@
 		}
 
 		/* Check for Bahama V2 variant*/
-		if (bahama_version == 0x09)	{
+		if ((bahama_version == 0x09) || (bahama_version == 0x0a)) {
 
 			/* In case of Bahama v2, forcefully enable the
 			 * internal analog and digital voltage controllers
@@ -2179,7 +2193,8 @@
 	/* Set the index based on the bt status*/
 	index = bt_status ?  1 : 0;
 	/* Check for Bahama's existance and Bahama V2 variant*/
-	if (bahama_present && (bahama_version == 0x09))   {
+	if (bahama_present
+		&& (bahama_version == 0x09 || bahama_version == 0x0a))   {
 		radio->marimba->mod_id = SLAVE_ID_BAHAMA;
 		/* actual value itself used as mask*/
 		retval = marimba_write_bit_mask(radio->marimba,
@@ -4149,7 +4164,7 @@
 
 	/* use xfr for interrupt setup */
     if (radio->chipID == MARIMBA_2_1 || radio->chipID == BAHAMA_1_0
-		|| radio->chipID == BAHAMA_2_0) {
+		|| radio->chipID == BAHAMA_2_0 || radio->chipID == BAHAMA_2_1) {
 		FMDBG("Setting interrupts\n");
 		retval =  sync_write_xfr(radio, INT_CTRL, int_ctrl);
 	/* use register write to setup interrupts */
@@ -4175,7 +4190,8 @@
 	*  registers and it is not valid for MBA 2.1
 	*/
 	if ((radio->chipID != MARIMBA_2_1) && (radio->chipID != BAHAMA_1_0)
-		&& (radio->chipID != BAHAMA_2_0))
+		&& (radio->chipID != BAHAMA_2_0)
+		&& (radio->chipID != BAHAMA_2_1))
 		tavarua_handle_interrupts(radio);
 
 	return retval;
@@ -4208,7 +4224,7 @@
 	/* use xfr for interrupt setup */
 	wait_timeout = 100;
 	if (radio->chipID == MARIMBA_2_1 || radio->chipID == BAHAMA_1_0
-		|| radio->chipID == BAHAMA_2_0)
+		|| radio->chipID == BAHAMA_2_0 || radio->chipID == BAHAMA_2_1)
 		retval = sync_write_xfr(radio, INT_CTRL, lpm_buf);
 	/* use register write to setup interrupts */
 	else
@@ -4318,9 +4334,15 @@
 			retval = tavarua_setup_interrupts(radio,
 			(radio->registers[RDCTRL] & 0x03));
 			if (retval < 0) {
-				printk(KERN_INFO DRIVER_NAME "Error in \
-					tavarua_resume %d\n", retval);
-				return -EIO;
+				FMDERR("Fails to write RDCTRL");
+				msleep(TAVARUA_DELAY);
+				retval = tavarua_setup_interrupts(radio,
+				(radio->registers[RDCTRL] & 0x03));
+				if (retval < 0) {
+					FMDERR("Error in tavarua_resume %d\n",
+								retval);
+					return -EIO;
+				}
 			}
 		}
 	}
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index d7dc67d..d21196e 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/rc/keymaps/rc-philips.c b/drivers/media/rc/keymaps/rc-philips.c
index 9f63520..3bebcbf 100644
--- a/drivers/media/rc/keymaps/rc-philips.c
+++ b/drivers/media/rc/keymaps/rc-philips.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/rc/keymaps/rc-samsung-necx.c b/drivers/media/rc/keymaps/rc-samsung-necx.c
index 1a3d6be..3f490d9 100644
--- a/drivers/media/rc/keymaps/rc-samsung-necx.c
+++ b/drivers/media/rc/keymaps/rc-samsung-necx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/rc/keymaps/rc-ue-rf4ce.c b/drivers/media/rc/keymaps/rc-ue-rf4ce.c
index ea982a8..704d8b6 100644
--- a/drivers/media/rc/keymaps/rc-ue-rf4ce.c
+++ b/drivers/media/rc/keymaps/rc-ue-rf4ce.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/rc/user-rc-input.c b/drivers/media/rc/user-rc-input.c
index f1a9334..d02b32a 100644
--- a/drivers/media/rc/user-rc-input.c
+++ b/drivers/media/rc/user-rc-input.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index e9b4e2b..e08c673 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -208,6 +208,24 @@
 	  two mipi lanes, required for msm8625 platform.
 	  Say Y here if this is msm8625 variant platform.
 
+config IMX135
+	bool "Sensor imx135 (Sony 13MP)"
+	depends on MSM_CAMERA
+	---help---
+	  Support for IMX135 sensor driver.
+	  This is a Sony 13MP Bayer Sensor with autofocus and video HDR
+	  support.
+	  Say Y if the platform uses IMX135 sensor.
+
+config OV9724
+	bool "Sensor ov9724 (Omnivision 1.3M)"
+	depends on MSM_CAMERA
+	---help---
+	  Support for OV9724 sensor driver.
+	  It is a Bayer 1.3MP sensor with auto focus and it supports
+	  two mipi lanes, required for msm8625 platform.
+	  Say Y here if this is msm8625 variant platform.
+
 config VB6801
 	bool "Sensor vb6801"
 	depends on MSM_CAMERA && !ARCH_MSM8X60 && !MSM_CAMERA_V4L2
diff --git a/drivers/media/video/msm/actuators/msm_actuator.c b/drivers/media/video/msm/actuators/msm_actuator.c
index 538ee74..f666e20 100644
--- a/drivers/media/video/msm/actuators/msm_actuator.c
+++ b/drivers/media/video/msm/actuators/msm_actuator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/actuators/msm_actuator.h b/drivers/media/video/msm/actuators/msm_actuator.h
index 82157e8..19b71a6 100644
--- a/drivers/media/video/msm/actuators/msm_actuator.h
+++ b/drivers/media/video/msm/actuators/msm_actuator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/cci/msm_cam_cci_hwreg.h b/drivers/media/video/msm/cci/msm_cam_cci_hwreg.h
index 2d489b9..0262eb4 100644
--- a/drivers/media/video/msm/cci/msm_cam_cci_hwreg.h
+++ b/drivers/media/video/msm/cci/msm_cam_cci_hwreg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/cci/msm_cci.c b/drivers/media/video/msm/cci/msm_cci.c
index 09dfd7c..4da5897 100644
--- a/drivers/media/video/msm/cci/msm_cci.c
+++ b/drivers/media/video/msm/cci/msm_cci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/cci/msm_cci.h b/drivers/media/video/msm/cci/msm_cci.h
index 6955576..827916d 100644
--- a/drivers/media/video/msm/cci/msm_cci.h
+++ b/drivers/media/video/msm/cci/msm_cci.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/cpp/msm_cpp.c b/drivers/media/video/msm/cpp/msm_cpp.c
index e569388..cd932bd 100644
--- a/drivers/media/video/msm/cpp/msm_cpp.c
+++ b/drivers/media/video/msm/cpp/msm_cpp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/cpp/msm_cpp.h b/drivers/media/video/msm/cpp/msm_cpp.h
index 8c10cac..f585569 100644
--- a/drivers/media/video/msm/cpp/msm_cpp.h
+++ b/drivers/media/video/msm/cpp/msm_cpp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/include/csi2.0/msm_csid_hwreg.h b/drivers/media/video/msm/csi/include/csi2.0/msm_csid_hwreg.h
index 4682f8f..cc8a9cf 100644
--- a/drivers/media/video/msm/csi/include/csi2.0/msm_csid_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi2.0/msm_csid_hwreg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/include/csi2.0/msm_csiphy_hwreg.h b/drivers/media/video/msm/csi/include/csi2.0/msm_csiphy_hwreg.h
index 2e83101..9263483 100644
--- a/drivers/media/video/msm/csi/include/csi2.0/msm_csiphy_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi2.0/msm_csiphy_hwreg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h b/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
index d37d67e..1864d40 100644
--- a/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/include/csi3.0/msm_csid_hwreg.h b/drivers/media/video/msm/csi/include/csi3.0/msm_csid_hwreg.h
index 11a04d5..7f35c2c 100644
--- a/drivers/media/video/msm/csi/include/csi3.0/msm_csid_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi3.0/msm_csid_hwreg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/include/csi3.0/msm_csiphy_hwreg.h b/drivers/media/video/msm/csi/include/csi3.0/msm_csiphy_hwreg.h
index 4e640e3..c290731 100644
--- a/drivers/media/video/msm/csi/include/csi3.0/msm_csiphy_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi3.0/msm_csiphy_hwreg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h b/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
index 7c09c4f..4b69dda 100644
--- a/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/msm_csi2_register.c b/drivers/media/video/msm/csi/msm_csi2_register.c
index aa539ff..b10d820 100644
--- a/drivers/media/video/msm/csi/msm_csi2_register.c
+++ b/drivers/media/video/msm/csi/msm_csi2_register.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/msm_csi_register.h b/drivers/media/video/msm/csi/msm_csi_register.h
index ebb001c..a744e1a 100644
--- a/drivers/media/video/msm/csi/msm_csi_register.h
+++ b/drivers/media/video/msm/csi/msm_csi_register.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/msm_csic.c b/drivers/media/video/msm/csi/msm_csic.c
index c34d9f7..34489cb 100644
--- a/drivers/media/video/msm/csi/msm_csic.c
+++ b/drivers/media/video/msm/csi/msm_csic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/msm_csic.h b/drivers/media/video/msm/csi/msm_csic.h
index c8f1f99..f8aa92a 100644
--- a/drivers/media/video/msm/csi/msm_csic.h
+++ b/drivers/media/video/msm/csi/msm_csic.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/msm_csic_register.c b/drivers/media/video/msm/csi/msm_csic_register.c
index dc3641a..e3fe3d4 100644
--- a/drivers/media/video/msm/csi/msm_csic_register.c
+++ b/drivers/media/video/msm/csi/msm_csic_register.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
index 37aa54e..f3cb623 100644
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ b/drivers/media/video/msm/csi/msm_csid.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/msm_csid.h b/drivers/media/video/msm/csi/msm_csid.h
index 46e8117..252f5fd 100644
--- a/drivers/media/video/msm/csi/msm_csid.h
+++ b/drivers/media/video/msm/csi/msm_csid.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
index 6e4ba78..dbf674d 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/msm_csiphy.h b/drivers/media/video/msm/csi/msm_csiphy.h
index 2fb21d2..93c9758 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.h
+++ b/drivers/media/video/msm/csi/msm_csiphy.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
index 7fb2e8f..73140c8 100644
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ b/drivers/media/video/msm/csi/msm_ispif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -802,9 +802,14 @@
 static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
 								void *arg)
 {
+	struct ispif_device *ispif;
 	switch (cmd) {
 	case VIDIOC_MSM_ISPIF_CFG:
 		return msm_ispif_cmd(sd, arg);
+	case VIDIOC_MSM_ISPIF_REL:
+		ispif =	(struct ispif_device *)v4l2_get_subdevdata(sd);
+		msm_ispif_release(ispif);
+		return 0;
 	default:
 		return -ENOIOCTLCMD;
 	}
diff --git a/drivers/media/video/msm/csi/msm_ispif.h b/drivers/media/video/msm/csi/msm_ispif.h
index d4ca864..b8926f4 100644
--- a/drivers/media/video/msm/csi/msm_ispif.h
+++ b/drivers/media/video/msm/csi/msm_ispif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -59,4 +59,7 @@
 #define VIDIOC_MSM_ISPIF_CFG \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 18, struct ispif_cfg_data*)
 
+#define VIDIOC_MSM_ISPIF_REL \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 19, struct ispif_cfg_data*)
+
 #endif
diff --git a/drivers/media/video/msm/eeprom/imx074_eeprom.c b/drivers/media/video/msm/eeprom/imx074_eeprom.c
index a99b17e..eafa9a8 100644
--- a/drivers/media/video/msm/eeprom/imx074_eeprom.c
+++ b/drivers/media/video/msm/eeprom/imx074_eeprom.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/eeprom/imx091_eeprom.c b/drivers/media/video/msm/eeprom/imx091_eeprom.c
index c53eb20..20624ac 100644
--- a/drivers/media/video/msm/eeprom/imx091_eeprom.c
+++ b/drivers/media/video/msm/eeprom/imx091_eeprom.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/eeprom/msm_camera_eeprom.c b/drivers/media/video/msm/eeprom/msm_camera_eeprom.c
index effae8b..a1b809f 100644
--- a/drivers/media/video/msm/eeprom/msm_camera_eeprom.c
+++ b/drivers/media/video/msm/eeprom/msm_camera_eeprom.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/eeprom/msm_camera_eeprom.h b/drivers/media/video/msm/eeprom/msm_camera_eeprom.h
index 830e5d8..05b4533 100644
--- a/drivers/media/video/msm/eeprom/msm_camera_eeprom.h
+++ b/drivers/media/video/msm/eeprom/msm_camera_eeprom.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/flash.c b/drivers/media/video/msm/flash.c
index 78a96b9..d17ceb4 100644
--- a/drivers/media/video/msm/flash.c
+++ b/drivers/media/video/msm/flash.c
@@ -1,5 +1,5 @@
 
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
@@ -18,11 +18,21 @@
 #include <linux/pmic8058-pwm.h>
 #include <linux/hrtimer.h>
 #include <linux/export.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
 #include <mach/pmic.h>
 #include <mach/camera.h>
 #include <mach/gpio.h>
 #include "msm_camera_i2c.h"
 
+struct flash_work {
+	struct work_struct my_work;
+	int    x;
+};
+struct flash_work *work;
+static struct timer_list flash_timer;
+static int timer_state;
+static struct workqueue_struct *flash_wq;
 struct i2c_client *sx150x_client;
 struct timer_list timer_flash;
 static struct msm_camera_sensor_info *sensor_data;
@@ -277,6 +287,23 @@
 	return rc;
 }
 
+static void flash_wq_function(struct work_struct *work)
+{
+	if (tps61310_client) {
+		i2c_client.client = tps61310_client;
+		i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
+		msm_camera_i2c_write(&i2c_client, 0x01,
+				0x46, MSM_CAMERA_I2C_BYTE_DATA);
+	}
+	return;
+}
+
+void flash_timer_callback(unsigned long data)
+{
+	queue_work(flash_wq, (struct work_struct *)work );
+	mod_timer(&flash_timer, jiffies + msecs_to_jiffies(10000));
+}
+
 int msm_camera_flash_external(
 	struct msm_camera_sensor_flash_external *external,
 	unsigned led_state)
@@ -382,6 +409,11 @@
 				sc628a_client = NULL;
 			}
 			if (tps61310_client) {
+				if (timer_state) {
+					del_timer(&flash_timer);
+					kfree((void *)work);
+					timer_state = 0;
+				}
 				i2c_del_driver(&tps61310_i2c_driver);
 				tps61310_client = NULL;
 			}
@@ -407,6 +439,11 @@
 				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
 				rc = msm_camera_i2c_write(&i2c_client, 0x01,
 					0x00, MSM_CAMERA_I2C_BYTE_DATA);
+				if (timer_state) {
+					del_timer(&flash_timer);
+					kfree((void *)work);
+					timer_state = 0;
+				}
 			}
 			gpio_set_value_cansleep(external->led_en, 0);
 			gpio_set_value_cansleep(external->led_flash_en, 0);
@@ -428,7 +465,13 @@
 				i2c_client.client = tps61310_client;
 				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
 				rc = msm_camera_i2c_write(&i2c_client, 0x01,
-					0x86, MSM_CAMERA_I2C_BYTE_DATA);
+					0x46, MSM_CAMERA_I2C_BYTE_DATA);
+				flash_wq = create_workqueue("my_queue");
+				work = (struct flash_work *)kmalloc(sizeof(struct flash_work), GFP_KERNEL);
+				INIT_WORK( (struct work_struct *)work, flash_wq_function );
+				setup_timer(&flash_timer, flash_timer_callback, 0);
+				mod_timer(&flash_timer, jiffies + msecs_to_jiffies(10000));
+				timer_state = 1;
 			}
 		}
 		break;
diff --git a/drivers/media/video/msm/gemini/msm_gemini_common.h b/drivers/media/video/msm/gemini/msm_gemini_common.h
index 0ddedc5..95223d80 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_common.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/gemini/msm_gemini_core.c b/drivers/media/video/msm/gemini/msm_gemini_core.c
index 2a5495e..542696e 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_core.c
+++ b/drivers/media/video/msm/gemini/msm_gemini_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/gemini/msm_gemini_core.h b/drivers/media/video/msm/gemini/msm_gemini_core.h
index f240505..62dd473 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_core.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/gemini/msm_gemini_dev.c b/drivers/media/video/msm/gemini/msm_gemini_dev.c
index 01d45ed..770a28f 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_dev.c
+++ b/drivers/media/video/msm/gemini/msm_gemini_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/gemini/msm_gemini_hw.c b/drivers/media/video/msm/gemini/msm_gemini_hw.c
index 241cbbd..90dea85 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_hw.c
+++ b/drivers/media/video/msm/gemini/msm_gemini_hw.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/gemini/msm_gemini_hw.h b/drivers/media/video/msm/gemini/msm_gemini_hw.h
index c147f11..0abd4c4 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_hw.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_hw.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/gemini/msm_gemini_hw_reg.h b/drivers/media/video/msm/gemini/msm_gemini_hw_reg.h
index bd992d0..8f27892 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_hw_reg.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_hw_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/gemini/msm_gemini_platform.c b/drivers/media/video/msm/gemini/msm_gemini_platform.c
index 111402b..d5a8098 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_platform.c
+++ b/drivers/media/video/msm/gemini/msm_gemini_platform.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/gemini/msm_gemini_platform.h b/drivers/media/video/msm/gemini/msm_gemini_platform.h
index d7f81aa..f6291dc 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_platform.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_platform.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/gemini/msm_gemini_sync.c b/drivers/media/video/msm/gemini/msm_gemini_sync.c
index b89a468..ef727fd 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_sync.c
+++ b/drivers/media/video/msm/gemini/msm_gemini_sync.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/gemini/msm_gemini_sync.h b/drivers/media/video/msm/gemini/msm_gemini_sync.h
index 3f6f1bc..d4e8190 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_sync.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_sync.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/imx072.c b/drivers/media/video/msm/imx072.c
index 7e34178..29d2118 100644
--- a/drivers/media/video/msm/imx072.c
+++ b/drivers/media/video/msm/imx072.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/imx072.h b/drivers/media/video/msm/imx072.h
index e3d279f..95f688c 100644
--- a/drivers/media/video/msm/imx072.h
+++ b/drivers/media/video/msm/imx072.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/imx072_reg.c b/drivers/media/video/msm/imx072_reg.c
index ea75548..fc07e0f 100644
--- a/drivers/media/video/msm/imx072_reg.c
+++ b/drivers/media/video/msm/imx072_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/imx074.c b/drivers/media/video/msm/imx074.c
index 636b402..511c7db 100644
--- a/drivers/media/video/msm/imx074.c
+++ b/drivers/media/video/msm/imx074.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/imx074.h b/drivers/media/video/msm/imx074.h
index 8be0fb7..9468cb0 100644
--- a/drivers/media/video/msm/imx074.h
+++ b/drivers/media/video/msm/imx074.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/imx074_reg.c b/drivers/media/video/msm/imx074_reg.c
index ccc9b2f..a9d19f2 100644
--- a/drivers/media/video/msm/imx074_reg.c
+++ b/drivers/media/video/msm/imx074_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.c b/drivers/media/video/msm/io/msm_camera_i2c.c
index 27ebac5..ce1fafa 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.c
+++ b/drivers/media/video/msm/io/msm_camera_i2c.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.h b/drivers/media/video/msm/io/msm_camera_i2c.h
index 35b3bd4..ce42607 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.h
+++ b/drivers/media/video/msm/io/msm_camera_i2c.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_camera_i2c_mux.c b/drivers/media/video/msm/io/msm_camera_i2c_mux.c
index 1698da7..730cb78 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c_mux.c
+++ b/drivers/media/video/msm/io/msm_camera_i2c_mux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_camera_i2c_mux.h b/drivers/media/video/msm/io/msm_camera_i2c_mux.h
index 94394fc..30f908b 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c_mux.h
+++ b/drivers/media/video/msm/io/msm_camera_i2c_mux.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_camera_io_util.c b/drivers/media/video/msm/io/msm_camera_io_util.c
index 613850b..4d0f544 100644
--- a/drivers/media/video/msm/io/msm_camera_io_util.c
+++ b/drivers/media/video/msm/io/msm_camera_io_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_io7x.c b/drivers/media/video/msm/io/msm_io7x.c
index 8804106..ebdaeb1 100644
--- a/drivers/media/video/msm/io/msm_io7x.c
+++ b/drivers/media/video/msm/io/msm_io7x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_io8x.c b/drivers/media/video/msm/io/msm_io8x.c
index 5f1f34f..dba93a0 100644
--- a/drivers/media/video/msm/io/msm_io8x.c
+++ b/drivers/media/video/msm/io/msm_io8x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_io_7x27a.c b/drivers/media/video/msm/io/msm_io_7x27a.c
index 4d89c06..6e70d37 100644
--- a/drivers/media/video/msm/io/msm_io_7x27a.c
+++ b/drivers/media/video/msm/io/msm_io_7x27a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c b/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
index 9549dcc..483b4a6 100644
--- a/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
+++ b/drivers/media/video/msm/io/msm_io_7x27a_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_io_8960.c b/drivers/media/video/msm/io/msm_io_8960.c
index ab3ea5d..6ddd701 100644
--- a/drivers/media/video/msm/io/msm_io_8960.c
+++ b/drivers/media/video/msm/io/msm_io_8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_io_8x60.c b/drivers/media/video/msm/io/msm_io_8x60.c
index baa1245..6896538 100644
--- a/drivers/media/video/msm/io/msm_io_8x60.c
+++ b/drivers/media/video/msm/io/msm_io_8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_io_vfe31.c b/drivers/media/video/msm/io/msm_io_vfe31.c
index 8c733a0..1cd2782 100644
--- a/drivers/media/video/msm/io/msm_io_vfe31.c
+++ b/drivers/media/video/msm/io/msm_io_vfe31.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/io/msm_io_vfe31_v4l2.c b/drivers/media/video/msm/io/msm_io_vfe31_v4l2.c
index 88a9316..acf87e4 100644
--- a/drivers/media/video/msm/io/msm_io_vfe31_v4l2.c
+++ b/drivers/media/video/msm/io/msm_io_vfe31_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_common.h b/drivers/media/video/msm/mercury/msm_mercury_common.h
index f5939c1..8ce7f7e 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_common.h
+++ b/drivers/media/video/msm/mercury/msm_mercury_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_core.c b/drivers/media/video/msm/mercury/msm_mercury_core.c
index a91c257..b0630f0 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_core.c
+++ b/drivers/media/video/msm/mercury/msm_mercury_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_core.h b/drivers/media/video/msm/mercury/msm_mercury_core.h
index e374cee..7237e7b 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_core.h
+++ b/drivers/media/video/msm/mercury/msm_mercury_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_dev.c b/drivers/media/video/msm/mercury/msm_mercury_dev.c
index df32b26..b245bfd 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_dev.c
+++ b/drivers/media/video/msm/mercury/msm_mercury_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_hw.c b/drivers/media/video/msm/mercury/msm_mercury_hw.c
index 7bc4abe..244c038 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_hw.c
+++ b/drivers/media/video/msm/mercury/msm_mercury_hw.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_hw.h b/drivers/media/video/msm/mercury/msm_mercury_hw.h
index f6e3e49..54fc818 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_hw.h
+++ b/drivers/media/video/msm/mercury/msm_mercury_hw.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_hw_reg.h b/drivers/media/video/msm/mercury/msm_mercury_hw_reg.h
index 671bc66..015bf49 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_hw_reg.h
+++ b/drivers/media/video/msm/mercury/msm_mercury_hw_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_macros.h b/drivers/media/video/msm/mercury/msm_mercury_macros.h
index 33c4f9a..0ab07cd 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_macros.h
+++ b/drivers/media/video/msm/mercury/msm_mercury_macros.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_platform.c b/drivers/media/video/msm/mercury/msm_mercury_platform.c
index 3dc7f4b..e6392fe 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_platform.c
+++ b/drivers/media/video/msm/mercury/msm_mercury_platform.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_platform.h b/drivers/media/video/msm/mercury/msm_mercury_platform.h
index 9edbb30..dfdea3c 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_platform.h
+++ b/drivers/media/video/msm/mercury/msm_mercury_platform.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_sync.c b/drivers/media/video/msm/mercury/msm_mercury_sync.c
index 31fb8b4..9293aad 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_sync.c
+++ b/drivers/media/video/msm/mercury/msm_mercury_sync.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mercury/msm_mercury_sync.h b/drivers/media/video/msm/mercury/msm_mercury_sync.h
index f392907..a44092f 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_sync.h
+++ b/drivers/media/video/msm/mercury/msm_mercury_sync.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 00f099c..cad6930 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -957,8 +957,10 @@
 			goto msm_cam_server_begin_session_failed;
 		}
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-		pmctl->client = msm_ion_client_create(-1, "camera");
-		kref_init(&pmctl->refcount);
+		if (!pmctl->client) {
+			pmctl->client = msm_ion_client_create(-1, "camera");
+			kref_init(&pmctl->refcount);
+		}
 		ion_client_created = 1;
 #endif
 
@@ -984,6 +986,7 @@
 		msm_queue_init(&pcam->eventData_q, "eventData");
 	}
 	pcam_inst->vbqueue_initialized = 0;
+	pcam_inst->sequence = 0;
 	rc = 0;
 
 	f->private_data = &pcam_inst->eventHandle;
@@ -1104,6 +1107,7 @@
 		struct msm_cam_media_controller, refcount);
 	pr_err("%s Calling ion_client_destroy\n", __func__);
 	ion_client_destroy(mctl->client);
+	mctl->client = NULL;
 }
 
 static int msm_close(struct file *f)
@@ -1235,6 +1239,10 @@
 	v4l2_ev = evt_payload.evt;
 	v4l2_ev.id = 0;
 	pcam = mctl->pcam_ptr;
+	if(!pcam) {
+		pr_err("%s: pcam is NULL\n", __func__);
+		return -EINVAL;
+	}
 	ktime_get_ts(&v4l2_ev.timestamp);
 	if (evt_payload.payload_length > 0 && evt_payload.payload != NULL) {
 		mutex_lock(&pcam->event_lock);
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 42d7d6b..380fdd1 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -359,6 +359,7 @@
 	int vbqueue_initialized;
 	struct mutex inst_lock;
 	uint32_t inst_handle;
+	uint32_t sequence;
 };
 
 struct msm_cam_mctl_node {
diff --git a/drivers/media/video/msm/msm_axi_qos.c b/drivers/media/video/msm/msm_axi_qos.c
index eaceceb..ac484d3 100644
--- a/drivers/media/video/msm/msm_axi_qos.c
+++ b/drivers/media/video/msm/msm_axi_qos.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm_camera.c b/drivers/media/video/msm/msm_camera.c
index dce3630..fd9dfe9 100644
--- a/drivers/media/video/msm/msm_camera.c
+++ b/drivers/media/video/msm/msm_camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm_camirq_router.c b/drivers/media/video/msm/msm_camirq_router.c
index 25a561f..37dd6c2 100644
--- a/drivers/media/video/msm/msm_camirq_router.c
+++ b/drivers/media/video/msm/msm_camirq_router.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm_camirq_router.h b/drivers/media/video/msm/msm_camirq_router.h
index 2c9cb73..3ea3cec 100644
--- a/drivers/media/video/msm/msm_camirq_router.h
+++ b/drivers/media/video/msm/msm_camirq_router.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm_gesture.c b/drivers/media/video/msm/msm_gesture.c
index 5777cb5..3ab041e 100644
--- a/drivers/media/video/msm/msm_gesture.c
+++ b/drivers/media/video/msm/msm_gesture.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 9c0ab9a..25b5f52 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -389,18 +389,16 @@
 		struct msm_stats_buf *stats_buf = NULL;
 
 		isp_event->isp_data.isp_msg.msg_id = MSG_ID_STATS_COMPOSITE;
-		stats->aec.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->aec.buff, &(stats->aec.fd));
-		stats->awb.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->awb.buff, &(stats->awb.fd));
-		stats->af.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->af.buff, &(stats->af.fd));
-		stats->ihist.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->ihist.buff, &(stats->ihist.fd));
-		stats->rs.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->rs.buff, &(stats->rs.fd));
-		stats->cs.buff = msm_pmem_stats_ptov_lookup(pmctl,
-					stats->cs.buff, &(stats->cs.fd));
+		CDBG("%s: aec (%d, %x) awb (%d, %x) af (%d, %x) ", __func__,
+			stats->aec.fd, (uint32_t)stats->aec.buff,
+			stats->awb.fd, (uint32_t)stats->awb.buff,
+			stats->af.fd, (uint32_t)stats->af.buff);
+		CDBG("%s: rs (%d, %x) cs(%d, %x) ihist(%d, %x)", __func__,
+			stats->rs.fd, (uint32_t)stats->rs.buff,
+			stats->cs.fd, (uint32_t)stats->cs.buff,
+			stats->ihist.fd, (uint32_t)stats->ihist.buff);
+		CDBG("%s:bhist/skin(%d, %x) ", __func__,
+			stats->skin.fd, (uint32_t)stats->skin.buff);
 
 		stats_buf = kmalloc(sizeof(struct msm_stats_buf), GFP_ATOMIC);
 		if (!stats_buf) {
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 3d14de5..1ddb2d8 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -560,17 +560,18 @@
 				 const char *const apps_id)
 {
 	int rc = 0;
-	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(p_mctl->sensor_sdev);
-	struct msm_camera_sensor_info *sinfo =
-		(struct msm_camera_sensor_info *) s_ctrl->sensordata;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	struct msm_sensor_ctrl_t *s_ctrl;
+	struct msm_camera_sensor_info *sinfo;
+	struct msm_camera_device_platform_data *camdev;
 	uint8_t csid_core;
 	D("%s\n", __func__);
 	if (!p_mctl) {
 		pr_err("%s: param is NULL", __func__);
 		return -EINVAL;
 	}
-
+	s_ctrl = get_sctrl(p_mctl->sensor_sdev);
+	sinfo = (struct msm_camera_sensor_info *) s_ctrl->sensordata;
+	camdev = sinfo->pdata;
 	mutex_lock(&p_mctl->lock);
 	/* open sub devices - once only*/
 	if (!p_mctl->opencnt) {
@@ -678,6 +679,8 @@
 
 	v4l2_subdev_call(p_mctl->sensor_sdev, core, s_power, 0);
 
+	v4l2_subdev_call(p_mctl->ispif_sdev,
+			core, ioctl, VIDIOC_MSM_ISPIF_REL, NULL);
 	pm_qos_update_request(&p_mctl->pm_qos_req_list,
 				PM_QOS_DEFAULT_VALUE);
 	pm_qos_remove_request(&p_mctl->pm_qos_req_list);
@@ -789,8 +792,10 @@
 	v4l2_set_subdev_hostdata(pcam->sensor_sdev, pmctl);
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	pmctl->client = msm_ion_client_create(-1, "camera");
-	kref_init(&pmctl->refcount);
+	if (!pmctl->client) {
+		pmctl->client = msm_ion_client_create(-1, "camera");
+		kref_init(&pmctl->refcount);
+	}
 #endif
 
 	return 0;
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 93e55e9..d4277c3 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -264,7 +264,7 @@
 		spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
 	}
 	pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
-	if (pmctl == NULL) {
+	if (pmctl == NULL || pmctl->client == NULL) {
 		pr_err("%s No mctl found\n", __func__);
 		buf->state = MSM_BUFFER_STATE_UNUSED;
 		return;
@@ -453,6 +453,7 @@
 		buf->vidbuf.v4l2_buf.timestamp = cam_ts->timestamp;
 		buf->vidbuf.v4l2_buf.sequence  = cam_ts->frame_id;
 	}
+	pcam_inst->sequence = buf->vidbuf.v4l2_buf.sequence;
 	D("%s Notify user about buffer %d image_mode %d frame_id %d", __func__,
 		buf->vidbuf.v4l2_buf.index, pcam_inst->image_mode,
 		buf->vidbuf.v4l2_buf.sequence);
@@ -857,7 +858,7 @@
 	cam_ts.present = 1;
 	cam_ts.timestamp = ret_frame->timestamp;
 	cam_ts.frame_id   = ret_frame->frame_id;
-	if (ret_frame->dirty)
+	if (ret_frame->dirty || (ret_frame->frame_id < pcam_inst->sequence))
 		/* the frame is dirty, not going to disptach to app */
 		rc = msm_mctl_release_free_buf(pmctl, pcam_inst, frame);
 	else
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
old mode 100644
new mode 100755
index 29d0576..980bdd5
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -108,7 +108,8 @@
 			*pp_type = OUTPUT_TYPE_R;
 		break;
 	case MSM_V4L2_EXT_CAPTURE_MODE_RDI2:
-		*pp_divert_type = OUTPUT_TYPE_R2;
+		if (p_mctl->pp_info.pp_key & PP_RDI)
+			*pp_divert_type = OUTPUT_TYPE_R2;
 		break;
 	default:
 		break;
@@ -376,6 +377,12 @@
 		pp_frame->num_planes = pcam_inst->plane_info.num_planes;
 		for (i = 0; i < pp_frame->num_planes; i++) {
 			mem = vb2_plane_cookie(&vb->vidbuf, i);
+			if (mem == NULL) {
+				pr_err("%s frame id %d buffer %d plane %d, invalid plane cookie "
+					, __func__, pp_frame->frame_id,
+					 buf_idx, i);
+				return -EINVAL;
+			}
 			pp_frame->mp[i].addr_offset = mem->addr_offset;
 			pp_frame->mp[i].phy_addr =
 				videobuf2_to_pmem_contig(&vb->vidbuf, i);
@@ -577,6 +584,8 @@
 			__func__);
 		return -EINVAL;
 	}
+	memset(&p_mctl->pp_info.div_frame[image_mode],
+		   0, sizeof(struct msm_free_buf));
 
 	rc = msm_mctl_release_free_buf(p_mctl, pcam_inst, &free_buf);
 	D("%s: release free buf, rc = %d, phy = 0x%x",
@@ -631,7 +640,7 @@
 			msm_mctl_pp_path_to_img_mode(frame.path);
 		image_mode = buf_handle.image_mode;
 	}
-	if (image_mode < 0) {
+	if (image_mode < 0 || image_mode >= MSM_MAX_IMG_MODE) {
 		pr_err("%s Invalid image mode\n", __func__);
 		return image_mode;
 	}
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index 1875df2..a32704d 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm_v4l2_video.c b/drivers/media/video/msm/msm_v4l2_video.c
index c4e6c62..fb46cc1 100644
--- a/drivers/media/video/msm/msm_v4l2_video.c
+++ b/drivers/media/video/msm/msm_v4l2_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm_v4l2_video.h b/drivers/media/video/msm/msm_v4l2_video.h
index a7baa75..0c09a3f 100644
--- a/drivers/media/video/msm/msm_v4l2_video.h
+++ b/drivers/media/video/msm/msm_v4l2_video.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index 34fab82..41a4463 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm_vpe.h b/drivers/media/video/msm/msm_vpe.h
index aad2380..6b89bf0 100644
--- a/drivers/media/video/msm/msm_vpe.h
+++ b/drivers/media/video/msm/msm_vpe.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm_vpe1.c b/drivers/media/video/msm/msm_vpe1.c
index df3630a..948f7ac 100644
--- a/drivers/media/video/msm/msm_vpe1.c
+++ b/drivers/media/video/msm/msm_vpe1.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/msm_vpe1.h b/drivers/media/video/msm/msm_vpe1.h
index f4d328d..5fd7a4a 100644
--- a/drivers/media/video/msm/msm_vpe1.h
+++ b/drivers/media/video/msm/msm_vpe1.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9d112.c b/drivers/media/video/msm/mt9d112.c
index 4dd0285..9c19965 100644
--- a/drivers/media/video/msm/mt9d112.c
+++ b/drivers/media/video/msm/mt9d112.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9d112.h b/drivers/media/video/msm/mt9d112.h
index 309fcec..f07d732 100644
--- a/drivers/media/video/msm/mt9d112.h
+++ b/drivers/media/video/msm/mt9d112.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9d112_reg.c b/drivers/media/video/msm/mt9d112_reg.c
index 24edaf2..6c35cbc 100644
--- a/drivers/media/video/msm/mt9d112_reg.c
+++ b/drivers/media/video/msm/mt9d112_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9d113.c b/drivers/media/video/msm/mt9d113.c
index 8e81bda..a32c804 100644
--- a/drivers/media/video/msm/mt9d113.c
+++ b/drivers/media/video/msm/mt9d113.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9d113.h b/drivers/media/video/msm/mt9d113.h
index f22f16c..4aedc5e 100644
--- a/drivers/media/video/msm/mt9d113.h
+++ b/drivers/media/video/msm/mt9d113.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9d113_reg.c b/drivers/media/video/msm/mt9d113_reg.c
index cd5be0f..28ff518 100644
--- a/drivers/media/video/msm/mt9d113_reg.c
+++ b/drivers/media/video/msm/mt9d113_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9e013.c b/drivers/media/video/msm/mt9e013.c
index 94546f4..f91bec4 100644
--- a/drivers/media/video/msm/mt9e013.c
+++ b/drivers/media/video/msm/mt9e013.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9e013.h b/drivers/media/video/msm/mt9e013.h
index 9052a35..6f43ec4 100644
--- a/drivers/media/video/msm/mt9e013.h
+++ b/drivers/media/video/msm/mt9e013.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9e013_reg.c b/drivers/media/video/msm/mt9e013_reg.c
index 9a4bd7e..bdcf3f8 100644
--- a/drivers/media/video/msm/mt9e013_reg.c
+++ b/drivers/media/video/msm/mt9e013_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9p012.h b/drivers/media/video/msm/mt9p012.h
index 3df98b7..a30b2f1 100644
--- a/drivers/media/video/msm/mt9p012.h
+++ b/drivers/media/video/msm/mt9p012.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9p012_bam.c b/drivers/media/video/msm/mt9p012_bam.c
index 9197380..9363893 100644
--- a/drivers/media/video/msm/mt9p012_bam.c
+++ b/drivers/media/video/msm/mt9p012_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9p012_fox.c b/drivers/media/video/msm/mt9p012_fox.c
index a652c9f..a8d90c1 100644
--- a/drivers/media/video/msm/mt9p012_fox.c
+++ b/drivers/media/video/msm/mt9p012_fox.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2011 The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9p012_km.c b/drivers/media/video/msm/mt9p012_km.c
index 5ba0e62..959023b 100644
--- a/drivers/media/video/msm/mt9p012_km.c
+++ b/drivers/media/video/msm/mt9p012_km.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9p012_km.h b/drivers/media/video/msm/mt9p012_km.h
index 0feb331..d386474 100644
--- a/drivers/media/video/msm/mt9p012_km.h
+++ b/drivers/media/video/msm/mt9p012_km.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9p012_km_reg.c b/drivers/media/video/msm/mt9p012_km_reg.c
index 109930b..5c6318f 100644
--- a/drivers/media/video/msm/mt9p012_km_reg.c
+++ b/drivers/media/video/msm/mt9p012_km_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9p012_reg.c b/drivers/media/video/msm/mt9p012_reg.c
index 06fe419..b828852 100644
--- a/drivers/media/video/msm/mt9p012_reg.c
+++ b/drivers/media/video/msm/mt9p012_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9t013.c b/drivers/media/video/msm/mt9t013.c
index b4b5bdd..e107930 100644
--- a/drivers/media/video/msm/mt9t013.c
+++ b/drivers/media/video/msm/mt9t013.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9t013.h b/drivers/media/video/msm/mt9t013.h
index 6afcb2d..e2d0c23 100644
--- a/drivers/media/video/msm/mt9t013.h
+++ b/drivers/media/video/msm/mt9t013.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/mt9t013_reg.c b/drivers/media/video/msm/mt9t013_reg.c
index 9a9867e..9031441 100644
--- a/drivers/media/video/msm/mt9t013_reg.c
+++ b/drivers/media/video/msm/mt9t013_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/ov5640.c b/drivers/media/video/msm/ov5640.c
index 1380bcf..8441a46 100644
--- a/drivers/media/video/msm/ov5640.c
+++ b/drivers/media/video/msm/ov5640.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/ov5640.h b/drivers/media/video/msm/ov5640.h
index 0e65329..a428da6 100644
--- a/drivers/media/video/msm/ov5640.h
+++ b/drivers/media/video/msm/ov5640.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/ov5647.c b/drivers/media/video/msm/ov5647.c
index 2a6e7be..365faef 100644
--- a/drivers/media/video/msm/ov5647.c
+++ b/drivers/media/video/msm/ov5647.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/ov5647.h b/drivers/media/video/msm/ov5647.h
index b43f15c..0015d63 100644
--- a/drivers/media/video/msm/ov5647.h
+++ b/drivers/media/video/msm/ov5647.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/ov5647_reg.c b/drivers/media/video/msm/ov5647_reg.c
index 4a0fed4..c9709bf 100644
--- a/drivers/media/video/msm/ov5647_reg.c
+++ b/drivers/media/video/msm/ov5647_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/ov7692.c b/drivers/media/video/msm/ov7692.c
index 7696b44..252d42c 100644
--- a/drivers/media/video/msm/ov7692.c
+++ b/drivers/media/video/msm/ov7692.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/ov7692.h b/drivers/media/video/msm/ov7692.h
index fc9cf1c..da98284 100644
--- a/drivers/media/video/msm/ov7692.h
+++ b/drivers/media/video/msm/ov7692.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/ov7692_qrd.c b/drivers/media/video/msm/ov7692_qrd.c
index d83f28e..05a82ab 100644
--- a/drivers/media/video/msm/ov7692_qrd.c
+++ b/drivers/media/video/msm/ov7692_qrd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/ov9726.c b/drivers/media/video/msm/ov9726.c
index 9619baa..96a084c 100644
--- a/drivers/media/video/msm/ov9726.c
+++ b/drivers/media/video/msm/ov9726.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/ov9726.h b/drivers/media/video/msm/ov9726.h
index 56d3da6..40ba1a8 100644
--- a/drivers/media/video/msm/ov9726.h
+++ b/drivers/media/video/msm/ov9726.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/ov9726_reg.c b/drivers/media/video/msm/ov9726_reg.c
index 54afbe8..216ecca 100644
--- a/drivers/media/video/msm/ov9726_reg.c
+++ b/drivers/media/video/msm/ov9726_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/qs_s5k4e1.c b/drivers/media/video/msm/qs_s5k4e1.c
index 64db015..32d094d 100644
--- a/drivers/media/video/msm/qs_s5k4e1.c
+++ b/drivers/media/video/msm/qs_s5k4e1.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/qs_s5k4e1.h b/drivers/media/video/msm/qs_s5k4e1.h
index f9c4c3f..dca3d0a 100644
--- a/drivers/media/video/msm/qs_s5k4e1.h
+++ b/drivers/media/video/msm/qs_s5k4e1.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/qs_s5k4e1_reg.c b/drivers/media/video/msm/qs_s5k4e1_reg.c
index 39c3f29..b872343 100644
--- a/drivers/media/video/msm/qs_s5k4e1_reg.c
+++ b/drivers/media/video/msm/qs_s5k4e1_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/s5k3e2fx.c b/drivers/media/video/msm/s5k3e2fx.c
index 07a058e..f7591d9 100644
--- a/drivers/media/video/msm/s5k3e2fx.c
+++ b/drivers/media/video/msm/s5k3e2fx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/s5k3e2fx.h b/drivers/media/video/msm/s5k3e2fx.h
index cf3f881..3cf4f8e 100644
--- a/drivers/media/video/msm/s5k3e2fx.h
+++ b/drivers/media/video/msm/s5k3e2fx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/s5k4e1.c b/drivers/media/video/msm/s5k4e1.c
index 30572d8..c62103e 100644
--- a/drivers/media/video/msm/s5k4e1.c
+++ b/drivers/media/video/msm/s5k4e1.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/s5k4e1.h b/drivers/media/video/msm/s5k4e1.h
index 7f60332..d58b3f0 100644
--- a/drivers/media/video/msm/s5k4e1.h
+++ b/drivers/media/video/msm/s5k4e1.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/s5k4e1_reg.c b/drivers/media/video/msm/s5k4e1_reg.c
index 59bb1c8..679ef17 100644
--- a/drivers/media/video/msm/s5k4e1_reg.c
+++ b/drivers/media/video/msm/s5k4e1_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/Makefile b/drivers/media/video/msm/sensors/Makefile
index cd228a1..25b1374 100644
--- a/drivers/media/video/msm/sensors/Makefile
+++ b/drivers/media/video/msm/sensors/Makefile
@@ -8,6 +8,7 @@
 obj-$(CONFIG_OV8825) += ov8825_v4l2.o
 obj-$(CONFIG_IMX074) += imx074_v4l2.o
 obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
+obj-$(CONFIG_IMX135) += imx135_v4l2.o
 obj-$(CONFIG_OV2720) += ov2720.o
 obj-$(CONFIG_MT9M114) += mt9m114_v4l2.o
 obj-$(CONFIG_S5K4E1) += s5k4e1_v4l2.o
@@ -15,3 +16,4 @@
 obj-$(CONFIG_WEBCAM_OV9726) += ov9726_v4l2.o
 obj-$(CONFIG_OV7692) += ov7692_v4l2.o
 obj-$(CONFIG_VX6953) += vx6953.o
+obj-$(CONFIG_OV9724) += ov9724_v4l2.o
diff --git a/drivers/media/video/msm/sensors/imx074_v4l2.c b/drivers/media/video/msm/sensors/imx074_v4l2.c
index 91d4797..f0759a8 100644
--- a/drivers/media/video/msm/sensors/imx074_v4l2.c
+++ b/drivers/media/video/msm/sensors/imx074_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/imx091.c b/drivers/media/video/msm/sensors/imx091.c
index 6d708ed..428067b 100644
--- a/drivers/media/video/msm/sensors/imx091.c
+++ b/drivers/media/video/msm/sensors/imx091.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/imx091.h b/drivers/media/video/msm/sensors/imx091.h
index 3618b4c..d2a646e 100644
--- a/drivers/media/video/msm/sensors/imx091.h
+++ b/drivers/media/video/msm/sensors/imx091.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/imx111.c b/drivers/media/video/msm/sensors/imx111.c
index 5cdd25a..51391be 100644
--- a/drivers/media/video/msm/sensors/imx111.c
+++ b/drivers/media/video/msm/sensors/imx111.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/imx119_v4l2.c b/drivers/media/video/msm/sensors/imx119_v4l2.c
index 9cc508b..548df52 100644
--- a/drivers/media/video/msm/sensors/imx119_v4l2.c
+++ b/drivers/media/video/msm/sensors/imx119_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/imx135_v4l2.c b/drivers/media/video/msm/sensors/imx135_v4l2.c
new file mode 100755
index 0000000..b549842
--- /dev/null
+++ b/drivers/media/video/msm/sensors/imx135_v4l2.c
@@ -0,0 +1,1420 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 and
+ * only 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.
+ *
+ */
+
+#include "msm_sensor.h"
+#define SENSOR_NAME "imx135"
+#define PLATFORM_DRIVER_NAME "msm_camera_imx135"
+#define imx135_obj imx135_##obj
+
+DEFINE_MUTEX(imx135_mut);
+
+/* Register addresses for HDR control */
+#define SHORT_SHUTTER_WORD_ADDR		0x0230
+#define SHORT_GAIN_BYTE_ADDR		0x0233
+#define ABS_GAIN_R_WORD_ADDR		0x0714
+#define ABS_GAIN_B_WORD_ADDR		0x0716
+#define LSC_ENABLE_BYTE_ADDR		0x0700
+#define EN_LSC_BYTE_ADDR			0x4500
+#define RAM_SEL_TOGGLE_BYTE_ADDR	0x3A63
+#define LSC_TABLE_START_ADDR		0x4800
+#define TC_OUT_NOISE_WORD_ADDR		0x4452
+#define TC_OUT_MID_WORD_ADDR		0x4454
+#define TC_NOISE_BRATE_REGADDR		0x4458
+#define TC_MID_BRATE_REGADDR		0x4459
+#define TC_SWITCH_BYTE_ADDR			0x446C
+
+#define LSC_TABLE_LEN_BYTES			504
+
+/* Adaptive tone reduction parameters */
+#define INIT_ATR_OUT_NOISE	0xA0
+#define INIT_ATR_OUT_MID	0x800
+#define ATR_OFFSET			0x00
+#define THRESHOLD_DEAD_ZONE	10
+#define THRESHOLD_0			20
+#define THRESHOLD_1			50
+
+static struct msm_sensor_ctrl_t imx135_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf imx135_start_settings[] = {
+	{0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_stop_settings[] = {
+	{0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_groupon_settings[] = {
+	{0x104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_groupoff_settings[] = {
+	{0x104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_recommend_settings[] = {
+	/*Global Settings*/
+	{0x0101, 0x00},
+	{0x0105, 0x01},
+	{0x0110, 0x00},
+	{0x0220, 0x01},
+	{0x3302, 0x11},
+	{0x3833, 0x20},
+	{0x3893, 0x00},
+	{0x3906, 0x08},
+	{0x3907, 0x01},
+	{0x391B, 0x01},
+	{0x3C09, 0x01},
+	{0x600A, 0x00},
+	{0x3008, 0xB0},
+	{0x320A, 0x01},
+	{0x320D, 0x10},
+	{0x3216, 0x2E},
+	{0x322C, 0x02},
+	{0x3409, 0x0C},
+	{0x340C, 0x2D},
+	{0x3411, 0x39},
+	{0x3414, 0x1E},
+	{0x3427, 0x04},
+	{0x3480, 0x1E},
+	{0x3484, 0x1E},
+	{0x3488, 0x1E},
+	{0x348C, 0x1E},
+	{0x3490, 0x1E},
+	{0x3494, 0x1E},
+	{0x3511, 0x8F},
+	{0x364F, 0x2D},
+	/*Defect Correction Recommended Setting */
+	{0x380A, 0x00},
+	{0x380B, 0x00},
+	{0x4103, 0x00},
+	/*Color Artifact Recommended Setting */
+	{0x4243, 0x9A},
+	{0x4330, 0x01},
+	{0x4331, 0x90},
+	{0x4332, 0x02},
+	{0x4333, 0x58},
+	{0x4334, 0x03},
+	{0x4335, 0x20},
+	{0x4336, 0x03},
+	{0x4337, 0x84},
+	{0x433C, 0x01},
+	{0x4340, 0x02},
+	{0x4341, 0x58},
+	{0x4342, 0x03},
+	{0x4343, 0x52},
+	/*Moiré reduction Parameter Setting	*/
+	{0x4364, 0x0B},
+	{0x4368, 0x00},
+	{0x4369, 0x0F},
+	{0x436A, 0x03},
+	{0x436B, 0xA8},
+	{0x436C, 0x00},
+	{0x436D, 0x00},
+	{0x436E, 0x00},
+	{0x436F, 0x06},
+	/*CNR parameter setting	*/
+	{0x4281, 0x21},
+	{0x4282, 0x18},
+	{0x4283, 0x04},
+	{0x4284, 0x08},
+	{0x4287, 0x7F},
+	{0x4288, 0x08},
+	{0x428B, 0x7F},
+	{0x428C, 0x08},
+	{0x428F, 0x7F},
+	{0x4297, 0x00},
+	{0x4298, 0x7E},
+	{0x4299, 0x7E},
+	{0x429A, 0x7E},
+	{0x42A4, 0xFB},
+	{0x42A5, 0x7E},
+	{0x42A6, 0xDF},
+	{0x42A7, 0xB7},
+	{0x42AF, 0x03},
+	/*ARNR Parameter Setting*/
+	{0x4207, 0x03},
+	{0x4216, 0x08},
+	{0x4217, 0x08},
+	/*DLC Parameter Setting*/
+	{0x4218, 0x00},
+	{0x421B, 0x20},
+	{0x421F, 0x04},
+	{0x4222, 0x02},
+	{0x4223, 0x22},
+	{0x422E, 0x54},
+	{0x422F, 0xFB},
+	{0x4230, 0xFF},
+	{0x4231, 0xFE},
+	{0x4232, 0xFF},
+	{0x4235, 0x58},
+	{0x4236, 0xF7},
+	{0x4237, 0xFD},
+	{0x4239, 0x4E},
+	{0x423A, 0xFC},
+	{0x423B, 0xFD},
+	/*HDR Setting*/
+	{0x4300, 0x00},
+	{0x4316, 0x12},
+	{0x4317, 0x22},
+	{0x4318, 0x00},
+	{0x4319, 0x00},
+	{0x431A, 0x00},
+	{0x4324, 0x03},
+	{0x4325, 0x20},
+	{0x4326, 0x03},
+	{0x4327, 0x84},
+	{0x4328, 0x03},
+	{0x4329, 0x20},
+	{0x432A, 0x03},
+	{0x432B, 0x20},
+	{0x432C, 0x01},
+	{0x432D, 0x01},
+	{0x4338, 0x02},
+	{0x4339, 0x00},
+	{0x433A, 0x00},
+	{0x433B, 0x02},
+	{0x435A, 0x03},
+	{0x435B, 0x84},
+	{0x435E, 0x01},
+	{0x435F, 0xFF},
+	{0x4360, 0x01},
+	{0x4361, 0xF4},
+	{0x4362, 0x03},
+	{0x4363, 0x84},
+	{0x437B, 0x01},
+	{0x4401, 0x03}, /*0x3F*/
+	{0x4402, 0xFF},
+	{0x4404, 0x13},
+	{0x4405, 0x26},
+	{0x4406, 0x07},
+	{0x4408, 0x20},
+	{0x4409, 0xE5},
+	{0x440A, 0xFB},
+	{0x440C, 0xF6},
+	{0x440D, 0xEA},
+	{0x440E, 0x20},
+	{0x4410, 0x00},
+	{0x4411, 0x00},
+	{0x4412, 0x3F},
+	{0x4413, 0xFF},
+	{0x4414, 0x1F},
+	{0x4415, 0xFF},
+	{0x4416, 0x20},
+	{0x4417, 0x00},
+	{0x4418, 0x1F},
+	{0x4419, 0xFF},
+	{0x441A, 0x20},
+	{0x441B, 0x00},
+	{0x441D, 0x40},
+	{0x441E, 0x1E},
+	{0x441F, 0x38},
+	{0x4420, 0x01},
+	{0x4444, 0x00},
+	{0x4445, 0x00},
+	{0x4446, 0x1D},
+	{0x4447, 0xF9},
+	{0x4452, 0x00},
+	{0x4453, 0xA0},
+	{0x4454, 0x08},
+	{0x4455, 0x00},
+	{0x4456, 0x0F},
+	{0x4457, 0xFF},
+	{0x4458, 0x18},
+	{0x4459, 0x18},
+	{0x445A, 0x3F},
+	{0x445B, 0x3A},
+	{0x445C, 0x00},
+	{0x445D, 0x28},
+	{0x445E, 0x01},
+	{0x445F, 0x90},
+	{0x4460, 0x00},
+	{0x4461, 0x60},
+	{0x4462, 0x00},
+	{0x4463, 0x00},
+	{0x4464, 0x00},
+	{0x4465, 0x00},
+	{0x446C, 0x00},
+	{0x446D, 0x00},
+	{0x446E, 0x00},
+	/*LSC Setting*/
+	{0x452A, 0x02},
+	/*White Balance Setting */
+	{0x0712, 0x01},
+	{0x0713, 0x00},
+	{0x0714, 0x01},
+	{0x0715, 0x00},
+	{0x0716, 0x01},
+	{0x0717, 0x00},
+	{0x0718, 0x01},
+	{0x0719, 0x00},
+	/*Shading setting*/
+	{0x4500, 0x1F},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_prev_settings[] = {
+	/* Clock Setting */
+	{0x011E, 0x18},
+	{0x011F, 0x00},
+	{0x0301, 0x05},
+	{0x0303, 0x01},
+	{0x0305, 0x03},
+	{0x0309, 0x05},
+	{0x030B, 0x02},
+	{0x030C, 0x00},
+	{0x030D, 0x71},
+	{0x030E, 0x01},
+	{0x3A06, 0x12},
+	/* Mode setting */
+	{0x0108, 0x03},
+	{0x0112, 0x0A},
+	{0x0113, 0x0A},
+	{0x0381, 0x01},
+	{0x0383, 0x01},
+	{0x0385, 0x01},
+	{0x0387, 0x01},
+	{0x0390, 0x01},
+	{0x0391, 0x22},
+	{0x0392, 0x00},
+	{0x0401, 0x00},
+	{0x0404, 0x00},
+	{0x0405, 0x10},
+	{0x4082, 0x01},
+	{0x4083, 0x01},
+	{0x7006, 0x04},
+	/* OptionalFunction setting */
+	{0x0700, 0x00},
+	{0x3A63, 0x00},
+	{0x4100, 0xF8},
+	{0x4203, 0xFF},
+	{0x4344, 0x00},
+	{0x441C, 0x01},
+	/* Size setting	*/
+	{0x0340, 0x0A},
+	{0x0341, 0x40},
+	{0x0342, 0x11},
+	{0x0343, 0xDC},
+	{0x0344, 0x00},
+	{0x0345, 0x00},
+	{0x0346, 0x00},
+	{0x0347, 0x00},
+	{0x0348, 0x10},
+	{0x0349, 0x6F},
+	{0x034A, 0x0C},
+	{0x034B, 0x2F},
+	{0x034C, 0x08},
+	{0x034D, 0x38},
+	{0x034E, 0x06},
+	{0x034F, 0x18},
+	{0x0350, 0x00},
+	{0x0351, 0x00},
+	{0x0352, 0x00},
+	{0x0353, 0x00},
+	{0x0354, 0x08},
+	{0x0355, 0x38},
+	{0x0356, 0x06},
+	{0x0357, 0x18},
+	{0x301D, 0x30},
+	{0x3310, 0x08},
+	{0x3311, 0x38},
+	{0x3312, 0x06},
+	{0x3313, 0x18},
+	{0x331C, 0x00},
+	{0x331D, 0x52},
+	{0x4084, 0x00},
+	{0x4085, 0x00},
+	{0x4086, 0x00},
+	{0x4087, 0x00},
+	{0x4400, 0x00},
+	/* Global Timing Setting */
+	{0x0830, 0x67},
+	{0x0831, 0x27},
+	{0x0832, 0x47},
+	{0x0833, 0x27},
+	{0x0834, 0x27},
+	{0x0835, 0x1F},
+	{0x0836, 0x87},
+	{0x0837, 0x2F},
+	{0x0839, 0x1F},
+	{0x083A, 0x17},
+	{0x083B, 0x02},
+	/* Integration Time Setting */
+	{0x0202, 0x06},
+	{0x0203, 0x2A},
+	/* Gain Setting	*/
+	{0x0205, 0x00},
+	{0x020E, 0x01},
+	{0x020F, 0x00},
+	{0x0210, 0x01},
+	{0x0211, 0x00},
+	{0x0212, 0x01},
+	{0x0213, 0x00},
+	{0x0214, 0x01},
+	{0x0215, 0x00},
+	/* HDR Setting */
+	{0x0230, 0x00},
+	{0x0231, 0x00},
+	{0x0233, 0x00},
+	{0x0234, 0x00},
+	{0x0235, 0x40},
+	{0x0238, 0x00},
+	{0x0239, 0x04},
+	{0x023B, 0x00},
+	{0x023C, 0x01},
+	{0x33B0, 0x04},
+	{0x33B1, 0x00},
+	{0x33B3, 0x00},
+	{0x33B4, 0x00},
+	{0x3800, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_LSCTable_settings[] = {
+	{0x4800, 0x02},
+	{0x4801, 0x68},
+	{0x4802, 0x02},
+	{0x4803, 0x4f},
+	{0x4804, 0x02},
+	{0x4805, 0x10},
+	{0x4806, 0x01},
+	{0x4807, 0xf3},
+	{0x4808, 0x01},
+	{0x4809, 0xc3},
+	{0x480a, 0x01},
+	{0x480b, 0xb3},
+	{0x480c, 0x01},
+	{0x480d, 0x9a},
+	{0x480e, 0x01},
+	{0x480f, 0x8e},
+	{0x4810, 0x01},
+	{0x4811, 0x84},
+	{0x4812, 0x01},
+	{0x4813, 0x7f},
+	{0x4814, 0x01},
+	{0x4815, 0x94},
+	{0x4816, 0x01},
+	{0x4817, 0x8a},
+	{0x4818, 0x01},
+	{0x4819, 0xb7},
+	{0x481a, 0x01},
+	{0x481b, 0xa6},
+	{0x481c, 0x01},
+	{0x481d, 0xf9},
+	{0x481e, 0x01},
+	{0x481f, 0xe2},
+	{0x4820, 0x02},
+	{0x4821, 0x62},
+	{0x4822, 0x02},
+	{0x4823, 0x37},
+	{0x4824, 0x02},
+	{0x4825, 0x26},
+	{0x4826, 0x02},
+	{0x4827, 0x0c},
+	{0x4828, 0x01},
+	{0x4829, 0xbb},
+	{0x482a, 0x01},
+	{0x482b, 0xaf},
+	{0x482c, 0x01},
+	{0x482d, 0x7c},
+	{0x482e, 0x01},
+	{0x482f, 0x70},
+	{0x4830, 0x01},
+	{0x4831, 0x50},
+	{0x4832, 0x01},
+	{0x4833, 0x4b},
+	{0x4834, 0x01},
+	{0x4835, 0x3e},
+	{0x4836, 0x01},
+	{0x4837, 0x39},
+	{0x4838, 0x01},
+	{0x4839, 0x4c},
+	{0x483a, 0x01},
+	{0x483b, 0x45},
+	{0x483c, 0x01},
+	{0x483d, 0x74},
+	{0x483e, 0x01},
+	{0x483f, 0x63},
+	{0x4840, 0x01},
+	{0x4841, 0xae},
+	{0x4842, 0x01},
+	{0x4843, 0x97},
+	{0x4844, 0x02},
+	{0x4845, 0x07},
+	{0x4846, 0x01},
+	{0x4847, 0xeb},
+	{0x4848, 0x01},
+	{0x4849, 0xf6},
+	{0x484a, 0x01},
+	{0x484b, 0xdf},
+	{0x484c, 0x01},
+	{0x484d, 0x93},
+	{0x484e, 0x01},
+	{0x484f, 0x8d},
+	{0x4850, 0x01},
+	{0x4851, 0x50},
+	{0x4852, 0x01},
+	{0x4853, 0x4b},
+	{0x4854, 0x01},
+	{0x4855, 0x22},
+	{0x4856, 0x01},
+	{0x4857, 0x20},
+	{0x4858, 0x01},
+	{0x4859, 0x10},
+	{0x485a, 0x01},
+	{0x485b, 0x0e},
+	{0x485c, 0x01},
+	{0x485d, 0x1d},
+	{0x485e, 0x01},
+	{0x485f, 0x18},
+	{0x4860, 0x01},
+	{0x4861, 0x48},
+	{0x4862, 0x01},
+	{0x4863, 0x3f},
+	{0x4864, 0x01},
+	{0x4865, 0x85},
+	{0x4866, 0x01},
+	{0x4867, 0x7b},
+	{0x4868, 0x01},
+	{0x4869, 0xd9},
+	{0x486a, 0x01},
+	{0x486b, 0xc5},
+	{0x486c, 0x01},
+	{0x486d, 0xdf},
+	{0x486e, 0x01},
+	{0x486f, 0xcf},
+	{0x4870, 0x01},
+	{0x4871, 0x87},
+	{0x4872, 0x01},
+	{0x4873, 0x7f},
+	{0x4874, 0x01},
+	{0x4875, 0x3d},
+	{0x4876, 0x01},
+	{0x4877, 0x3a},
+	{0x4878, 0x01},
+	{0x4879, 0x10},
+	{0x487a, 0x01},
+	{0x487b, 0x0e},
+	{0x487c, 0x01},
+	{0x487d, 0x00},
+	{0x487e, 0x01},
+	{0x487f, 0x00},
+	{0x4880, 0x01},
+	{0x4881, 0x0a},
+	{0x4882, 0x01},
+	{0x4883, 0x07},
+	{0x4884, 0x01},
+	{0x4885, 0x34},
+	{0x4886, 0x01},
+	{0x4887, 0x2f},
+	{0x4888, 0x01},
+	{0x4889, 0x77},
+	{0x488a, 0x01},
+	{0x488b, 0x69},
+	{0x488c, 0x01},
+	{0x488d, 0xcc},
+	{0x488e, 0x01},
+	{0x488f, 0xb9},
+	{0x4890, 0x01},
+	{0x4891, 0xea},
+	{0x4892, 0x01},
+	{0x4893, 0xdf},
+	{0x4894, 0x01},
+	{0x4895, 0x93},
+	{0x4896, 0x01},
+	{0x4897, 0x86},
+	{0x4898, 0x01},
+	{0x4899, 0x4c},
+	{0x489a, 0x01},
+	{0x489b, 0x48},
+	{0x489c, 0x01},
+	{0x489d, 0x20},
+	{0x489e, 0x01},
+	{0x489f, 0x1c},
+	{0x48a0, 0x01},
+	{0x48a1, 0x0d},
+	{0x48a2, 0x01},
+	{0x48a3, 0x09},
+	{0x48a4, 0x01},
+	{0x48a5, 0x1a},
+	{0x48a6, 0x01},
+	{0x48a7, 0x15},
+	{0x48a8, 0x01},
+	{0x48a9, 0x43},
+	{0x48aa, 0x01},
+	{0x48ab, 0x3d},
+	{0x48ac, 0x01},
+	{0x48ad, 0x84},
+	{0x48ae, 0x01},
+	{0x48af, 0x75},
+	{0x48b0, 0x01},
+	{0x48b1, 0xd3},
+	{0x48b2, 0x01},
+	{0x48b3, 0xbf},
+	{0x48b4, 0x02},
+	{0x48b5, 0x23},
+	{0x48b6, 0x02},
+	{0x48b7, 0x07},
+	{0x48b8, 0x01},
+	{0x48b9, 0xbc},
+	{0x48ba, 0x01},
+	{0x48bb, 0xac},
+	{0x48bc, 0x01},
+	{0x48bd, 0x7a},
+	{0x48be, 0x01},
+	{0x48bf, 0x6f},
+	{0x48c0, 0x01},
+	{0x48c1, 0x4c},
+	{0x48c2, 0x01},
+	{0x48c3, 0x47},
+	{0x48c4, 0x01},
+	{0x48c5, 0x3d},
+	{0x48c6, 0x01},
+	{0x48c7, 0x37},
+	{0x48c8, 0x01},
+	{0x48c9, 0x48},
+	{0x48ca, 0x01},
+	{0x48cb, 0x40},
+	{0x48cc, 0x01},
+	{0x48cd, 0x70},
+	{0x48ce, 0x01},
+	{0x48cf, 0x61},
+	{0x48d0, 0x01},
+	{0x48d1, 0xab},
+	{0x48d2, 0x01},
+	{0x48d3, 0x9a},
+	{0x48d4, 0x02},
+	{0x48d5, 0x03},
+	{0x48d6, 0x01},
+	{0x48d7, 0xe6},
+	{0x48d8, 0x02},
+	{0x48d9, 0x71},
+	{0x48da, 0x02},
+	{0x48db, 0x4a},
+	{0x48dc, 0x02},
+	{0x48dd, 0x07},
+	{0x48de, 0x01},
+	{0x48df, 0xef},
+	{0x48e0, 0x01},
+	{0x48e1, 0xbf},
+	{0x48e2, 0x01},
+	{0x48e3, 0xae},
+	{0x48e4, 0x01},
+	{0x48e5, 0x97},
+	{0x48e6, 0x01},
+	{0x48e7, 0x89},
+	{0x48e8, 0x01},
+	{0x48e9, 0x82},
+	{0x48ea, 0x01},
+	{0x48eb, 0x7a},
+	{0x48ec, 0x01},
+	{0x48ed, 0x91},
+	{0x48ee, 0x01},
+	{0x48ef, 0x83},
+	{0x48f0, 0x01},
+	{0x48f1, 0xb7},
+	{0x48f2, 0x01},
+	{0x48f3, 0xa9},
+	{0x48f4, 0x01},
+	{0x48f5, 0xf0},
+	{0x48f6, 0x01},
+	{0x48f7, 0xd9},
+	{0x48f8, 0x02},
+	{0x48f9, 0x55},
+	{0x48fa, 0x02},
+	{0x48fb, 0x32},
+	{0x48fc, 0x02},
+	{0x48fd, 0x4b},
+	{0x48fe, 0x02},
+	{0x48ff, 0x4c},
+	{0x4900, 0x01},
+	{0x4901, 0xec},
+	{0x4902, 0x01},
+	{0x4903, 0xf2},
+	{0x4904, 0x01},
+	{0x4905, 0xb1},
+	{0x4906, 0x01},
+	{0x4907, 0xb7},
+	{0x4908, 0x01},
+	{0x4909, 0x8a},
+	{0x490a, 0x01},
+	{0x490b, 0x8c},
+	{0x490c, 0x01},
+	{0x490d, 0x7d},
+	{0x490e, 0x01},
+	{0x490f, 0x7d},
+	{0x4910, 0x01},
+	{0x4911, 0x87},
+	{0x4912, 0x01},
+	{0x4913, 0x87},
+	{0x4914, 0x01},
+	{0x4915, 0xa8},
+	{0x4916, 0x01},
+	{0x4917, 0xa8},
+	{0x4918, 0x01},
+	{0x4919, 0xe2},
+	{0x491a, 0x01},
+	{0x491b, 0xda},
+	{0x491c, 0x02},
+	{0x491d, 0x38},
+	{0x491e, 0x02},
+	{0x491f, 0x30},
+	{0x4920, 0x02},
+	{0x4921, 0x0a},
+	{0x4922, 0x02},
+	{0x4923, 0x0e},
+	{0x4924, 0x01},
+	{0x4925, 0xae},
+	{0x4926, 0x01},
+	{0x4927, 0xaf},
+	{0x4928, 0x01},
+	{0x4929, 0x71},
+	{0x492a, 0x01},
+	{0x492b, 0x74},
+	{0x492c, 0x01},
+	{0x492d, 0x4b},
+	{0x492e, 0x01},
+	{0x492f, 0x4a},
+	{0x4930, 0x01},
+	{0x4931, 0x3b},
+	{0x4932, 0x01},
+	{0x4933, 0x3c},
+	{0x4934, 0x01},
+	{0x4935, 0x46},
+	{0x4936, 0x01},
+	{0x4937, 0x47},
+	{0x4938, 0x01},
+	{0x4939, 0x68},
+	{0x493a, 0x01},
+	{0x493b, 0x68},
+	{0x493c, 0x01},
+	{0x493d, 0x9e},
+	{0x493e, 0x01},
+	{0x493f, 0xa0},
+	{0x4940, 0x01},
+	{0x4941, 0xf4},
+	{0x4942, 0x01},
+	{0x4943, 0xec},
+	{0x4944, 0x01},
+	{0x4945, 0xdc},
+	{0x4946, 0x01},
+	{0x4947, 0xe7},
+	{0x4948, 0x01},
+	{0x4949, 0x8a},
+	{0x494a, 0x01},
+	{0x494b, 0x8e},
+	{0x494c, 0x01},
+	{0x494d, 0x4b},
+	{0x494e, 0x01},
+	{0x494f, 0x4b},
+	{0x4950, 0x01},
+	{0x4951, 0x1e},
+	{0x4952, 0x01},
+	{0x4953, 0x1f},
+	{0x4954, 0x01},
+	{0x4955, 0x0c},
+	{0x4956, 0x01},
+	{0x4957, 0x0b},
+	{0x4958, 0x01},
+	{0x4959, 0x18},
+	{0x495a, 0x01},
+	{0x495b, 0x17},
+	{0x495c, 0x01},
+	{0x495d, 0x42},
+	{0x495e, 0x01},
+	{0x495f, 0x3f},
+	{0x4960, 0x01},
+	{0x4961, 0x7b},
+	{0x4962, 0x01},
+	{0x4963, 0x79},
+	{0x4964, 0x01},
+	{0x4965, 0xcb},
+	{0x4966, 0x01},
+	{0x4967, 0xc1},
+	{0x4968, 0x01},
+	{0x4969, 0xd4},
+	{0x496a, 0x01},
+	{0x496b, 0xd4},
+	{0x496c, 0x01},
+	{0x496d, 0x80},
+	{0x496e, 0x01},
+	{0x496f, 0x81},
+	{0x4970, 0x01},
+	{0x4971, 0x3e},
+	{0x4972, 0x01},
+	{0x4973, 0x3a},
+	{0x4974, 0x01},
+	{0x4975, 0x10},
+	{0x4976, 0x01},
+	{0x4977, 0x0d},
+	{0x4978, 0x01},
+	{0x4979, 0x00},
+	{0x497a, 0x01},
+	{0x497b, 0x00},
+	{0x497c, 0x01},
+	{0x497d, 0x07},
+	{0x497e, 0x01},
+	{0x497f, 0x08},
+	{0x4980, 0x01},
+	{0x4981, 0x34},
+	{0x4982, 0x01},
+	{0x4983, 0x32},
+	{0x4984, 0x01},
+	{0x4985, 0x72},
+	{0x4986, 0x01},
+	{0x4987, 0x6d},
+	{0x4988, 0x01},
+	{0x4989, 0xc1},
+	{0x498a, 0x01},
+	{0x498b, 0xb6},
+	{0x498c, 0x01},
+	{0x498d, 0xe1},
+	{0x498e, 0x01},
+	{0x498f, 0xe5},
+	{0x4990, 0x01},
+	{0x4991, 0x8d},
+	{0x4992, 0x01},
+	{0x4993, 0x8f},
+	{0x4994, 0x01},
+	{0x4995, 0x4c},
+	{0x4996, 0x01},
+	{0x4997, 0x4d},
+	{0x4998, 0x01},
+	{0x4999, 0x1d},
+	{0x499a, 0x01},
+	{0x499b, 0x1d},
+	{0x499c, 0x01},
+	{0x499d, 0x0b},
+	{0x499e, 0x01},
+	{0x499f, 0x0b},
+	{0x49a0, 0x01},
+	{0x49a1, 0x18},
+	{0x49a2, 0x01},
+	{0x49a3, 0x16},
+	{0x49a4, 0x01},
+	{0x49a5, 0x40},
+	{0x49a6, 0x01},
+	{0x49a7, 0x3f},
+	{0x49a8, 0x01},
+	{0x49a9, 0x7c},
+	{0x49aa, 0x01},
+	{0x49ab, 0x77},
+	{0x49ac, 0x01},
+	{0x49ad, 0xcb},
+	{0x49ae, 0x01},
+	{0x49af, 0xc8},
+	{0x49b0, 0x02},
+	{0x49b1, 0x0a},
+	{0x49b2, 0x02},
+	{0x49b3, 0x0f},
+	{0x49b4, 0x01},
+	{0x49b5, 0xad},
+	{0x49b6, 0x01},
+	{0x49b7, 0xaf},
+	{0x49b8, 0x01},
+	{0x49b9, 0x74},
+	{0x49ba, 0x01},
+	{0x49bb, 0x73},
+	{0x49bc, 0x01},
+	{0x49bd, 0x49},
+	{0x49be, 0x01},
+	{0x49bf, 0x48},
+	{0x49c0, 0x01},
+	{0x49c1, 0x37},
+	{0x49c2, 0x01},
+	{0x49c3, 0x37},
+	{0x49c4, 0x01},
+	{0x49c5, 0x44},
+	{0x49c6, 0x01},
+	{0x49c7, 0x3f},
+	{0x49c8, 0x01},
+	{0x49c9, 0x68},
+	{0x49ca, 0x01},
+	{0x49cb, 0x65},
+	{0x49cc, 0x01},
+	{0x49cd, 0xa2},
+	{0x49ce, 0x01},
+	{0x49cf, 0x9d},
+	{0x49d0, 0x01},
+	{0x49d1, 0xf0},
+	{0x49d2, 0x01},
+	{0x49d3, 0xe6},
+	{0x49d4, 0x02},
+	{0x49d5, 0x4f},
+	{0x49d6, 0x02},
+	{0x49d7, 0x4c},
+	{0x49d8, 0x01},
+	{0x49d9, 0xf4},
+	{0x49da, 0x01},
+	{0x49db, 0xf8},
+	{0x49dc, 0x01},
+	{0x49dd, 0xb6},
+	{0x49de, 0x01},
+	{0x49df, 0xb4},
+	{0x49e0, 0x01},
+	{0x49e1, 0x90},
+	{0x49e2, 0x01},
+	{0x49e3, 0x91},
+	{0x49e4, 0x01},
+	{0x49e5, 0x7f},
+	{0x49e6, 0x01},
+	{0x49e7, 0x81},
+	{0x49e8, 0x01},
+	{0x49e9, 0x8a},
+	{0x49ea, 0x01},
+	{0x49eb, 0x88},
+	{0x49ec, 0x01},
+	{0x49ed, 0xa8},
+	{0x49ee, 0x01},
+	{0x49ef, 0xa9},
+	{0x49f0, 0x01},
+	{0x49f1, 0xde},
+	{0x49f2, 0x01},
+	{0x49f3, 0xd9},
+	{0x49f4, 0x02},
+	{0x49f5, 0x3b},
+	{0x49f6, 0x02},
+	{0x49f7, 0x30},
+	{0x3A63, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_snap_settings[] = {
+	/* Clock Setting	*/
+	{0x011E, 0x18},
+	{0x011F, 0x00},
+	{0x0301, 0x05},
+	{0x0303, 0x01},
+	{0x0305, 0x03},
+	{0x0309, 0x05},
+	{0x030B, 0x01},
+	{0x030C, 0x00},
+	{0x030D, 0x60},/*0x64*/
+	{0x030E, 0x01},
+	{0x3A06, 0x11},
+	/* Mode setting */
+	{0x0108, 0x03},
+	{0x0112, 0x0A},
+	{0x0113, 0x0A},
+	{0x0381, 0x01},
+	{0x0383, 0x01},
+	{0x0385, 0x01},
+	{0x0387, 0x01},
+	{0x0390, 0x00},
+	{0x0391, 0x11},
+	{0x0392, 0x00},
+	{0x0401, 0x00},
+	{0x0404, 0x00},
+	{0x0405, 0x10},
+	{0x4082, 0x01},
+	{0x4083, 0x01},
+	{0x7006, 0x04},
+	/* OptionalFunction setting */
+	{0x0700, 0x00},
+	{0x3A63, 0x00},
+	{0x4100, 0xF8},
+	{0x4203, 0xFF},
+	{0x4344, 0x00},
+	{0x441C, 0x01},
+	/* Size setting	*/
+	{0x0340, 0x0C},
+	{0x0341, 0x46},
+	{0x0342, 0x11},
+	{0x0343, 0xDC},
+	{0x0344, 0x00},
+	{0x0345, 0x00},
+	{0x0346, 0x00},
+	{0x0347, 0x00},
+	{0x0348, 0x10},
+	{0x0349, 0x6F},
+	{0x034A, 0x0C},
+	{0x034B, 0x2F},
+	{0x034C, 0x10},
+	{0x034D, 0x70},
+	{0x034E, 0x0C},
+	{0x034F, 0x30},
+	{0x0350, 0x00},
+	{0x0351, 0x00},
+	{0x0352, 0x00},
+	{0x0353, 0x00},
+	{0x0354, 0x10},
+	{0x0355, 0x70},
+	{0x0356, 0x0C},
+	{0x0357, 0x30},
+	{0x301D, 0x30},
+	{0x3310, 0x10},
+	{0x3311, 0x70},
+	{0x3312, 0x0C},
+	{0x3313, 0x30},
+	{0x331C, 0x01},
+	{0x331D, 0x68},
+	{0x4084, 0x00},
+	{0x4085, 0x00},
+	{0x4086, 0x00},
+	{0x4087, 0x00},
+	{0x4400, 0x00},
+	/* Global Timing Setting */
+	{0x0830, 0x7F},
+	{0x0831, 0x37},
+	{0x0832, 0x5F},
+	{0x0833, 0x37},
+	{0x0834, 0x37},
+	{0x0835, 0x3F},
+	{0x0836, 0xC7},
+	{0x0837, 0x3F},
+	{0x0839, 0x1F},
+	{0x083A, 0x17},
+	{0x083B, 0x02},
+	/* Integration Time Setting */
+	{0x0202, 0x0C},
+	{0x0203, 0x42},
+	/* Gain Setting	*/
+	{0x0205, 0x00},
+	{0x020E, 0x01},
+	{0x020F, 0x00},
+	{0x0210, 0x01},
+	{0x0211, 0x00},
+	{0x0212, 0x01},
+	{0x0213, 0x00},
+	{0x0214, 0x01},
+	{0x0215, 0x00},
+	/* HDR Setting */
+	{0x0230, 0x00},
+	{0x0231, 0x00},
+	{0x0233, 0x00},
+	{0x0234, 0x00},
+	{0x0235, 0x40},
+	{0x0238, 0x00},
+	{0x0239, 0x04},
+	{0x023B, 0x00},
+	{0x023C, 0x01},
+	{0x33B0, 0x04},
+	{0x33B1, 0x00},
+	{0x33B3, 0x00},
+	{0x33B4, 0x00},
+	{0x3800, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf imx135_hdr_settings[] = {
+	/* Clock Setting */
+	{0x011E, 0x18},
+	{0x011F, 0x00},
+	{0x0301, 0x05},
+	{0x0303, 0x01},
+	{0x0305, 0x03},
+	{0x0309, 0x05},
+	{0x030B, 0x02},
+	{0x030C, 0x00},
+	{0x030D, 0x71},
+	{0x030E, 0x01},
+	{0x3A06, 0x12},
+	/* Mode setting	*/
+	{0x0108, 0x03},
+	{0x0112, 0x0E},
+	{0x0113, 0x0A},
+	{0x0381, 0x01},
+	{0x0383, 0x01},
+	{0x0385, 0x01},
+	{0x0387, 0x01},
+	{0x0390, 0x00},
+	{0x0391, 0x11},
+	{0x0392, 0x00},
+	{0x0401, 0x00},
+	{0x0404, 0x00},
+	{0x0405, 0x10},
+	{0x4082, 0x01},
+	{0x4083, 0x01},
+	{0x7006, 0x04},
+	/* OptionnalFunction setting */
+	{0x0700, 0x01},
+	{0x3A63, 0x00},
+	{0x4100, 0xF8},
+	{0x4203, 0xFF},
+	{0x4344, 0x00},
+	{0x441C, 0x01},
+	/* Size setting	*/
+	{0x0340, 0x0C},
+	{0x0341, 0x48},
+	{0x0342, 0x11},
+	{0x0343, 0xDC},
+	{0x0344, 0x00},
+	{0x0345, 0x08},
+	{0x0346, 0x00},
+	{0x0347, 0x00},
+	{0x0348, 0x10},
+	{0x0349, 0x67},
+	{0x034A, 0x0C},
+	{0x034B, 0x2F},
+	{0x034C, 0x08},
+	{0x034D, 0x30},
+	{0x034E, 0x06},
+	{0x034F, 0x18},
+	{0x0350, 0x00},
+	{0x0351, 0x00},
+	{0x0352, 0x00},
+	{0x0353, 0x00},
+	{0x0354, 0x08},
+	{0x0355, 0x30},
+	{0x0356, 0x06},
+	{0x0357, 0x18},
+	{0x301D, 0x30},
+	{0x3310, 0x08},
+	{0x3311, 0x30},
+	{0x3312, 0x06},
+	{0x3313, 0x18},
+	{0x331C, 0x00},
+	{0x331D, 0x10},
+	{0x4084, 0x00},
+	{0x4085, 0x00},
+	{0x4086, 0x00},
+	{0x4087, 0x00},
+	{0x4400, 0x00},
+	/*Global Timing Setting	*/
+	{0x0830, 0x67},
+	{0x0831, 0x27},
+	{0x0832, 0x47},
+	{0x0833, 0x27},
+	{0x0834, 0x27},
+	{0x0835, 0x1F},
+	{0x0836, 0x87},
+	{0x0837, 0x2F},
+	{0x0839, 0x1F},
+	{0x083A, 0x17},
+	{0x083B, 0x02},
+	/*Integration Time Setting*/
+	{0x0202, 0x0C},
+	{0x0203, 0x44},
+	/*Gain Setting */
+	{0x0205, 0x00},
+	{0x020E, 0x01},
+	{0x020F, 0x00},
+	{0x0210, 0x01},
+	{0x0211, 0x00},
+	{0x0212, 0x01},
+	{0x0213, 0x00},
+	{0x0214, 0x01},
+	{0x0215, 0x00},
+	/* HDR Setting */
+	{0x0230, 0x00},
+	{0x0231, 0x00},
+	{0x0233, 0x00},
+	{0x0234, 0x00},
+	{0x0235, 0x40},
+	{0x0238, 0x01}, /*Direct 1 / Auto 0*/
+	{0x0239, 0x04},
+	{0x023B, 0x03},
+	{0x023C, 0x01},
+	{0x33B0, 0x08},
+	{0x33B1, 0x30},
+	{0x33B3, 0x01},
+	{0x33B4, 0x00},
+	{0x3800, 0x00},
+};
+
+static struct v4l2_subdev_info imx135_subdev_info[] = {
+	{
+	.code		= V4L2_MBUS_FMT_SBGGR10_1X10,
+	.colorspace	= V4L2_COLORSPACE_JPEG,
+	.fmt		= 1,
+	.order		= 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array imx135_init_conf[] = {
+	{&imx135_recommend_settings[0],
+	ARRAY_SIZE(imx135_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&imx135_LSCTable_settings[0],
+	ARRAY_SIZE(imx135_LSCTable_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array imx135_confs[] = {
+	{&imx135_snap_settings[0],
+	ARRAY_SIZE(imx135_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&imx135_prev_settings[0],
+	ARRAY_SIZE(imx135_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&imx135_hdr_settings[0],
+	ARRAY_SIZE(imx135_hdr_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t imx135_dimensions[] = {
+	/* RES0 snapshot(FULL SIZE) */
+	{
+		.x_output = 4208,
+		.y_output = 3120,
+		.line_length_pclk = 4572,
+		.frame_length_lines = 3142,
+		.vt_pixel_clk = 360000000,
+		.op_pixel_clk = 319680000,
+		.binning_factor = 1,
+	},
+	/* RES1 4:3 preview(1/2HV QTR SIZE) */
+	{
+		.x_output = 2104,
+		.y_output = 1560,
+		.line_length_pclk = 4572,
+		.frame_length_lines = 2624,
+		.vt_pixel_clk = 360000000,
+		.op_pixel_clk = 180000000,
+		.binning_factor = 1,
+	},
+	/* RES2 4:3 HDR movie mode */
+	{
+		.x_output = 2096,
+		.y_output = 1560,
+		.line_length_pclk = 4572,
+		.frame_length_lines = 3290,
+		.vt_pixel_clk = 360000000,
+		.op_pixel_clk = 180000000,
+		.binning_factor = 1,
+	},
+};
+
+static struct msm_sensor_output_reg_addr_t imx135_reg_addr = {
+	.x_output = 0x34C,
+	.y_output = 0x34E,
+	.line_length_pclk = 0x342,
+	.frame_length_lines = 0x340,
+};
+
+static struct msm_sensor_id_info_t imx135_id_info = {
+	.sensor_id_reg_addr = 0x0000,
+	.sensor_id = 0x1210,
+};
+
+static struct msm_sensor_exp_gain_info_t imx135_exp_gain_info = {
+	.coarse_int_time_addr = 0x202,
+	.global_gain_addr = 0x205,
+	.vert_offset = 4,
+};
+
+static const struct i2c_device_id imx135_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&imx135_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver imx135_i2c_driver = {
+	.id_table = imx135_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client imx135_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	return i2c_add_driver(&imx135_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops imx135_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops imx135_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops imx135_subdev_ops = {
+	.core = &imx135_subdev_core_ops,
+	.video  = &imx135_subdev_video_ops,
+};
+
+int32_t imx135_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+	uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
+{
+	uint32_t fl_lines;
+	uint8_t offset;
+	uint16_t shortshutter_gain = 0;
+	uint32_t shortshutter = 0;
+	uint16_t shortshutter_expratio = 8;
+
+	uint16_t atr_out_noise = 0;
+	uint16_t atr_out_mid = 0;
+
+	fl_lines = s_ctrl->curr_frame_length_lines;
+	fl_lines = (fl_lines * s_ctrl->fps_divider) / Q10;
+	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+	if (line > (fl_lines - offset))
+		fl_lines = line + offset;
+	CDBG("%s luma_avg=%d\n", __func__, luma_avg);
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr, line,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
+		MSM_CAMERA_I2C_BYTE_DATA);
+
+	/* For video HDR mode */
+	if (s_ctrl->curr_res == MSM_SENSOR_RES_2) {
+		/* Short shutter update */
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			SHORT_GAIN_BYTE_ADDR, shortshutter_gain,
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+		shortshutter = (line * fgain) / (Q8 * shortshutter_expratio);
+		CDBG("longtshutter =%d, shortshutter=%d, longgain =%d\n",
+			line, shortshutter, gain);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			SHORT_SHUTTER_WORD_ADDR, shortshutter,
+			MSM_CAMERA_I2C_WORD_DATA);
+
+		/* Adaptive tone curve parameters update */
+		if (luma_avg < THRESHOLD_DEAD_ZONE) {
+			/* change to fixed tone curve */
+			msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+				TC_SWITCH_BYTE_ADDR, 0x01,
+				MSM_CAMERA_I2C_BYTE_DATA);
+		} else {
+			/* change to adaptive tone curve */
+			msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+					TC_SWITCH_BYTE_ADDR, 0x00,
+					MSM_CAMERA_I2C_BYTE_DATA);
+			if (luma_avg < THRESHOLD_0) {
+				atr_out_noise = 0;
+				atr_out_mid = 0;
+			} else if (luma_avg < THRESHOLD_1) {
+				atr_out_noise =
+					INIT_ATR_OUT_NOISE *
+					(luma_avg - THRESHOLD_0)/
+					(THRESHOLD_1 - THRESHOLD_0);
+				atr_out_mid = INIT_ATR_OUT_MID *
+					(luma_avg - THRESHOLD_0)/
+					(THRESHOLD_1 - THRESHOLD_0);
+			} else {
+				atr_out_noise = INIT_ATR_OUT_NOISE;
+				atr_out_mid = INIT_ATR_OUT_MID;
+			}
+			atr_out_noise += ATR_OFFSET;
+			atr_out_mid += ATR_OFFSET;
+			msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+				TC_OUT_NOISE_WORD_ADDR, atr_out_noise,
+				MSM_CAMERA_I2C_WORD_DATA);
+			msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+				TC_OUT_MID_WORD_ADDR, atr_out_mid,
+				MSM_CAMERA_I2C_WORD_DATA);
+		}
+	}
+
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	return 0;
+}
+
+int32_t imx135_hdr_update(struct msm_sensor_ctrl_t *s_ctrl,
+	struct sensor_hdr_update_parm_t *update_parm)
+{
+	int i;
+	switch (update_parm->type) {
+	case SENSOR_HDR_UPDATE_AWB:
+		CDBG("%s: SENSOR_HDR_UPDATE_AWB\n", __func__);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			ABS_GAIN_R_WORD_ADDR, update_parm->awb_gain_r,
+			MSM_CAMERA_I2C_WORD_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			ABS_GAIN_B_WORD_ADDR, update_parm->awb_gain_b,
+			MSM_CAMERA_I2C_WORD_DATA);
+		CDBG("%s: awb gains updated r=0x%x, b=0x%x\n", __func__,
+			 update_parm->awb_gain_r, update_parm->awb_gain_b);
+		break;
+	case SENSOR_HDR_UPDATE_LSC:
+		/* step1: write knot points to LSC table */
+		for (i = 0; i < LSC_TABLE_LEN_BYTES; i++) {
+			CDBG("lsc[%d] = %x\n", i, update_parm->lsc_table[i]);
+			msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+				LSC_TABLE_START_ADDR + i,
+				update_parm->lsc_table[i],
+				MSM_CAMERA_I2C_BYTE_DATA);
+		}
+		/* step2: LSC enable */
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			EN_LSC_BYTE_ADDR, 0x1F, MSM_CAMERA_I2C_BYTE_DATA);
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			LSC_ENABLE_BYTE_ADDR, 0x01, MSM_CAMERA_I2C_BYTE_DATA);
+		/* step3: RAM_SEL_TOGGLE */
+		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			RAM_SEL_TOGGLE_BYTE_ADDR, 0x01,
+			MSM_CAMERA_I2C_BYTE_DATA);
+
+		CDBG("%s: lsc table updated\n", __func__);
+		break;
+	default:
+		pr_err("%s: invalid HDR update type %d\n",
+			   __func__, update_parm->type);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct msm_sensor_fn_t imx135_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = msm_sensor_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_write_exp_gain = imx135_write_exp_gain,
+	.sensor_write_snapshot_exp_gain = imx135_write_exp_gain,
+	.sensor_setting = msm_sensor_setting,
+	.sensor_csi_setting = msm_sensor_setting1,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines1,
+	.sensor_get_csi_params = msm_sensor_get_csi_params,
+	.sensor_hdr_update = imx135_hdr_update,
+};
+
+static struct msm_sensor_reg_t imx135_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = imx135_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(imx135_start_settings),
+	.stop_stream_conf = imx135_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(imx135_stop_settings),
+	.group_hold_on_conf = imx135_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(imx135_groupon_settings),
+	.group_hold_off_conf = imx135_groupoff_settings,
+	.group_hold_off_conf_size =
+		ARRAY_SIZE(imx135_groupoff_settings),
+	.init_settings = &imx135_init_conf[0],
+	.init_size = ARRAY_SIZE(imx135_init_conf),
+	.mode_settings = &imx135_confs[0],
+	.output_settings = &imx135_dimensions[0],
+	.num_conf = ARRAY_SIZE(imx135_confs),
+};
+
+static struct msm_sensor_ctrl_t imx135_s_ctrl = {
+	.msm_sensor_reg = &imx135_regs,
+	.sensor_i2c_client = &imx135_sensor_i2c_client,
+	.sensor_i2c_addr = 0x20,
+	.sensor_output_reg_addr = &imx135_reg_addr,
+	.sensor_id_info = &imx135_id_info,
+	.sensor_exp_gain_info = &imx135_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &imx135_mut,
+	.sensor_i2c_driver = &imx135_i2c_driver,
+	.sensor_v4l2_subdev_info = imx135_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx135_subdev_info),
+	.sensor_v4l2_subdev_ops = &imx135_subdev_ops,
+	.func_tbl = &imx135_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Sony 13MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index dcefaac..c39b356 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -170,7 +170,7 @@
 		s_ctrl->msm_sensor_reg->start_stream_conf,
 		s_ctrl->msm_sensor_reg->start_stream_conf_size,
 		s_ctrl->msm_sensor_reg->default_data_type);
-	msm_sensor_delay_frames(s_ctrl);
+	msleep(20);
 }
 
 void msm_sensor_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
@@ -210,7 +210,7 @@
 }
 
 int32_t msm_sensor_write_exp_gain1(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
 {
 	uint32_t fl_lines;
 	uint8_t offset;
@@ -235,7 +235,7 @@
 }
 
 int32_t msm_sensor_write_exp_gain2(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
 {
 	uint32_t fl_lines, ll_pclk, ll_ratio;
 	uint8_t offset;
@@ -289,7 +289,6 @@
 			int update_type, int res)
 {
 	int32_t rc = 0;
-
 	if (update_type == MSM_SENSOR_REG_INIT) {
 		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
 		msm_sensor_write_init_settings(s_ctrl);
@@ -457,7 +456,9 @@
 				sensor_write_exp_gain(
 					s_ctrl,
 					cdata.cfg.exp_gain.gain,
-					cdata.cfg.exp_gain.line);
+					cdata.cfg.exp_gain.line,
+					cdata.cfg.exp_gain.luma_avg,
+					cdata.cfg.exp_gain.fgain);
 			break;
 
 		case CFG_SET_PICT_EXP_GAIN:
@@ -474,7 +475,9 @@
 				sensor_write_snapshot_exp_gain(
 					s_ctrl,
 					cdata.cfg.exp_gain.gain,
-					cdata.cfg.exp_gain.line);
+					cdata.cfg.exp_gain.line,
+					cdata.cfg.exp_gain.luma_avg,
+					cdata.cfg.exp_gain.fgain);
 			break;
 
 		case CFG_SET_MODE:
@@ -493,6 +496,18 @@
 		case CFG_SET_EFFECT:
 			break;
 
+		case CFG_HDR_UPDATE:
+			if (s_ctrl->func_tbl->
+			sensor_hdr_update == NULL) {
+				rc = -EFAULT;
+				break;
+			}
+			rc = s_ctrl->func_tbl->
+					sensor_hdr_update(
+					   s_ctrl,
+					   &(cdata.cfg.hdr_update_parm));
+			break;
+
 		case CFG_SENSOR_INIT:
 			if (s_ctrl->func_tbl->
 			sensor_mode_init == NULL) {
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index 7dd0602..40ca934 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -41,9 +41,9 @@
 int32_t msm_sensor_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
 			struct fps_cfg   *fps);
 int32_t msm_sensor_write_exp_gain1(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line);
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain);
 int32_t msm_sensor_write_exp_gain2(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line);
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain);
 int32_t msm_sensor_set_sensor_mode(struct msm_sensor_ctrl_t *s_ctrl,
 	int mode, int res);
 int32_t msm_sensor_mode_init(struct msm_sensor_ctrl_t *s_ctrl,
diff --git a/drivers/media/video/msm/sensors/msm_sensor_bayer.c b/drivers/media/video/msm/sensors/msm_sensor_bayer.c
index f4ee31f..60eca7a 100644
--- a/drivers/media/video/msm/sensors/msm_sensor_bayer.c
+++ b/drivers/media/video/msm/sensors/msm_sensor_bayer.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/msm_sensor_bayer.h b/drivers/media/video/msm/sensors/msm_sensor_bayer.h
index d12244b..1c1ccea 100644
--- a/drivers/media/video/msm/sensors/msm_sensor_bayer.h
+++ b/drivers/media/video/msm/sensors/msm_sensor_bayer.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/msm_sensor_common.c b/drivers/media/video/msm/sensors/msm_sensor_common.c
index 9dac632..a8d78b0 100644
--- a/drivers/media/video/msm/sensors/msm_sensor_common.c
+++ b/drivers/media/video/msm/sensors/msm_sensor_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/msm_sensor_common.h b/drivers/media/video/msm/sensors/msm_sensor_common.h
index e2ae18e..69e2e1a 100644
--- a/drivers/media/video/msm/sensors/msm_sensor_common.h
+++ b/drivers/media/video/msm/sensors/msm_sensor_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -135,9 +135,9 @@
 	int32_t (*sensor_set_fps) (struct msm_sensor_ctrl_t *,
 			struct fps_cfg *);
 	int32_t (*sensor_write_exp_gain) (struct msm_sensor_ctrl_t *,
-			uint16_t, uint32_t);
+			uint16_t, uint32_t, int32_t, uint16_t);
 	int32_t (*sensor_write_snapshot_exp_gain) (struct msm_sensor_ctrl_t *,
-			uint16_t, uint32_t);
+			uint16_t, uint32_t, int32_t, uint16_t);
 	int32_t (*sensor_setting) (struct msm_sensor_ctrl_t *,
 			int update_type, int rt);
 	int32_t (*sensor_csi_setting) (struct msm_sensor_ctrl_t *,
@@ -160,6 +160,9 @@
 			int32_t vision_mode_enable);
 	int (*sensor_set_vision_ae_control)(
 			struct msm_sensor_ctrl_t *s_ctrl, int ae_mode);
+	int32_t (*sensor_read_eeprom)(struct msm_sensor_ctrl_t *);
+	int32_t (*sensor_hdr_update)(struct msm_sensor_ctrl_t *,
+		 struct sensor_hdr_update_parm_t *);
 };
 
 struct msm_sensor_csi_info {
diff --git a/drivers/media/video/msm/sensors/msm_sensor_init.c b/drivers/media/video/msm/sensors/msm_sensor_init.c
index 41c00eb..d759cf1 100644
--- a/drivers/media/video/msm/sensors/msm_sensor_init.c
+++ b/drivers/media/video/msm/sensors/msm_sensor_init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/mt9e013_v4l2.c b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
index a38cb57..24373226 100644
--- a/drivers/media/video/msm/sensors/mt9e013_v4l2.c
+++ b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -344,7 +344,7 @@
 };
 
 static int32_t mt9e013_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
 {
 	uint32_t fl_lines;
 	fl_lines =
@@ -362,7 +362,7 @@
 }
 
 static int32_t mt9e013_write_exp_snapshot_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
 {
 	uint32_t fl_lines;
 	fl_lines =
diff --git a/drivers/media/video/msm/sensors/mt9m114_v4l2.c b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
index cba9538..6095fe1 100644
--- a/drivers/media/video/msm/sensors/mt9m114_v4l2.c
+++ b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
index d21e1fe..e25029a 100644
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ b/drivers/media/video/msm/sensors/ov2720.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -683,7 +683,7 @@
 };
 
 static int32_t ov2720_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
 {
 	uint32_t fl_lines, offset;
 	uint8_t int_time[3];
diff --git a/drivers/media/video/msm/sensors/ov2720.h b/drivers/media/video/msm/sensors/ov2720.h
index 7077a7d..6b47666 100644
--- a/drivers/media/video/msm/sensors/ov2720.h
+++ b/drivers/media/video/msm/sensors/ov2720.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index eb6a8b0..10fe453 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -429,7 +429,7 @@
 }
 
 static int32_t ov5647_write_pict_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
 {
 
 	static uint16_t max_line = 1964;
@@ -538,7 +538,10 @@
 
 
 static int32_t ov5647_write_prev_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-						uint16_t gain, uint32_t line)
+						uint16_t gain,
+						uint32_t line,
+						int32_t luma_avg,
+						uint16_t fgain)
 {
 	u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
 	uint8_t gain_lsb, gain_hsb;
diff --git a/drivers/media/video/msm/sensors/ov7692_v4l2.c b/drivers/media/video/msm/sensors/ov7692_v4l2.c
index e0d4b53f..efc78f8 100644
--- a/drivers/media/video/msm/sensors/ov7692_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov7692_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/ov8825_v4l2.c b/drivers/media/video/msm/sensors/ov8825_v4l2.c
old mode 100644
new mode 100755
index 092ee72..9cff6a0
--- a/drivers/media/video/msm/sensors/ov8825_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov8825_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -11,16 +11,37 @@
  *
  */
 
+#include <linux/module.h>
 #include "msm_sensor.h"
 #include "msm.h"
 #define SENSOR_NAME "ov8825"
 #define PLATFORM_DRIVER_NAME "msm_camera_ov8825"
 #define ov8825_obj ov8825_##obj
 
+#define OV8825_2LANES 1
+
+#ifdef CDBG
+#undef CDBG
+#endif
+#ifdef CDBG_HIGH
+#undef CDBG_HIGH
+#endif
+
+#define OV8825_DGB
+
+#ifdef OV8825_DGB
+#define CDBG printk
+#define CDBG_HIGH(fmt, args...) printk(fmt, ##args)
+#else
+#define CDBG printk
+#define CDBG_HIGH(fmt, args...) printk(fmt, ##args)
+#endif
+
+
 /* TO DO - Currently ov5647 typical values are used
  * Need to get the exact values */
-#define OV8825_RG_RATIO_TYPICAL_VALUE 64 /* R/G of typical camera module */
-#define OV8825_BG_RATIO_TYPICAL_VALUE 105 /* B/G of typical camera module */
+#define OV8825_RG_RATIO_TYPICAL_VALUE 0x51 /* R/G of typical camera module */
+#define OV8825_BG_RATIO_TYPICAL_VALUE 0x4e /* B/G of typical camera module */
 
 DEFINE_MUTEX(ov8825_mut);
 static struct msm_sensor_ctrl_t ov8825_s_ctrl;
@@ -34,6 +55,7 @@
 	uint8_t user_data[5];
 } st_ov8825_otp;
 
+
 static struct msm_camera_i2c_reg_conf ov8825_start_settings[] = {
 	{0x0100, 0x01},
 };
@@ -53,17 +75,24 @@
 
 static struct msm_camera_i2c_reg_conf ov8825_prev_settings[] = {
 	{0x3003, 0xce}, /*PLL_CTRL0*/
+#if OV8825_2LANES
 	{0x3004, 0xd4}, /*PLL_CTRL1*/
 	{0x3005, 0x00}, /*PLL_CTRL2*/
+#else
+	{0x3004, 0xce}, /*PLL_CTRL1*/
+	{0x3005, 0x10}, /*PLL_CTRL2*/
+#endif
 	{0x3006, 0x10}, /*PLL_CTRL3*/
 	{0x3007, 0x3b}, /*PLL_CTRL4*/
+#if OV8825_2LANES
 	{0x3011, 0x01}, /*MIPI_Lane_4_Lane*/
+#else
+	{0x3011, 0x02}, /*MIPI_Lane_4_Lane*/
+#endif
 	{0x3012, 0x80}, /*SC_PLL CTRL_S0*/
 	{0x3013, 0x39}, /*SC_PLL CTRL_S1*/
 	{0x3104, 0x20}, /*SCCB_PLL*/
 	{0x3106, 0x15}, /*SRB_CTRL*/
-	{0x3501, 0x4e}, /*AEC_HIGH*/
-	{0x3502, 0xa0}, /*AEC_LOW*/
 	{0x350b, 0x1f}, /*AGC*/
 	{0x3600, 0x06}, /*ANACTRL0*/
 	{0x3601, 0x34}, /*ANACTRL1*/
@@ -106,15 +135,21 @@
 	{0x3813, 0x04}, /*VOFF*/
 	{0x3814, 0x31}, /*X INC*/
 	{0x3815, 0x31}, /*Y INC*/
-	{0x3820, 0x81}, /*Timing Reg20:Vflip*/
-	{0x3821, 0x17}, /*Timing Reg21:Hmirror*/
+	{0x3820, 0x87}, /*Timing Reg20:Vflip*/
+	{0x3821, 0x11}, /*Timing Reg21:Hmirror*/
+	{0x4005, 0x18},
+	{0x404f, 0x8f},
 	{0x3f00, 0x00}, /*PSRAM Ctrl0*/
 	{0x3f01, 0xfc}, /*PSRAM Ctrl1*/
 	{0x3f05, 0x10}, /*PSRAM Ctrl5*/
 	{0x4600, 0x04}, /*VFIFO Ctrl0*/
 	{0x4601, 0x00}, /*VFIFO Read ST High*/
 	{0x4602, 0x30}, /*VFIFO Read ST Low*/
-	{0x4837, 0x28}, /*MIPI PCLK PERIOD*/
+#if OV8825_2LANES
+	{0x4837, 0x16}, /*MIPI PCLK PERIOD*/
+#else
+	{0x4837, 0x27}, /*MIPI PCLK PERIOD*/
+#endif
 	{0x5068, 0x00}, /*HSCALE_CTRL*/
 	{0x506a, 0x00}, /*VSCALE_CTRL*/
 	{0x5c00, 0x80}, /*PBLC CTRL00*/
@@ -128,18 +163,24 @@
 
 static struct msm_camera_i2c_reg_conf ov8825_snap_settings[] = {
 	{0x3003, 0xce}, /*PLL_CTRL0*/
+#if OV8825_2LANES
 	{0x3004, 0xd8}, /*PLL_CTRL1*/
 	{0x3005, 0x00}, /*PLL_CTRL2*/
+#else
+	{0x3004, 0xce}, /*PLL_CTRL1*/
+	{0x3005, 0x10}, /*PLL_CTRL2*/
+#endif
 	{0x3006, 0x10}, /*PLL_CTRL3*/
 	{0x3007, 0x3b}, /*PLL_CTRL4*/
+#if OV8825_2LANES
 	{0x3011, 0x01}, /*MIPI_Lane_4_Lane*/
+#else
+	{0x3011, 0x02}, /*MIPI_Lane_4_Lane*/
+#endif
 	{0x3012, 0x81}, /*SC_PLL CTRL_S0*/
 	{0x3013, 0x39}, /*SC_PLL CTRL_S1*/
 	{0x3104, 0x20}, /*SCCB_PLL*/
 	{0x3106, 0x11}, /*SRB_CTRL*/
-	{0x3501, 0x9a}, /*AEC_HIGH*/
-	{0x3502, 0xa0}, /*AEC_LOW*/
-	{0x350b, 0x1f}, /*AGC*/
 	{0x3600, 0x07}, /*ANACTRL0*/
 	{0x3601, 0x33}, /*ANACTRL1*/
 	{0x3700, 0x10}, /*SENCTROL0 Sensor control*/
@@ -181,15 +222,21 @@
 	{0x3813, 0x06}, /*VOFF*/
 	{0x3814, 0x11}, /*X INC*/
 	{0x3815, 0x11}, /*Y INC*/
-	{0x3820, 0x80}, /*Timing Reg20:Vflip*/
-	{0x3821, 0x16}, /*Timing Reg21:Hmirror*/
+	{0x3820, 0x86}, /*Timing Reg20:Vflip*/
+	{0x3821, 0x10}, /*Timing Reg21:Hmirror*/
+	{0x4005, 0x1a},
+	{0x404f, 0x7f},
 	{0x3f00, 0x02}, /*PSRAM Ctrl0*/
 	{0x3f01, 0xfc}, /*PSRAM Ctrl1*/
 	{0x3f05, 0x10}, /*PSRAM Ctrl5*/
 	{0x4600, 0x04}, /*VFIFO Ctrl0*/
 	{0x4601, 0x00}, /*VFIFO Read ST High*/
 	{0x4602, 0x78}, /*VFIFO Read ST Low*/
-	{0x4837, 0x28}, /*MIPI PCLK PERIOD*/
+#if OV8825_2LANES
+	{0x4837, 0x18}, /*MIPI PCLK PERIOD*/
+#else
+	{0x4837, 0x27}, /*MIPI PCLK PERIOD*/
+#endif
 	{0x5068, 0x00}, /*HSCALE_CTRL*/
 	{0x506a, 0x00}, /*VSCALE_CTRL*/
 	{0x5c00, 0x80}, /*PBLC CTRL00*/
@@ -202,10 +249,6 @@
 };
 
 
-static struct msm_camera_i2c_reg_conf ov8825_reset_settings[] = {
-	{0x0103, 0x01},
-};
-
 static struct msm_camera_i2c_reg_conf ov8825_recommend_settings[] = {
 	{0x3000, 0x16},
 	{0x3001, 0x00},
@@ -215,7 +258,6 @@
 	{0x3010, 0x00},
 	{0x3018, 0x00},
 	{0x3300, 0x00},
-	{0x3500, 0x00},
 	{0x3503, 0x07},
 	{0x3509, 0x00},
 	{0x3602, 0x42},
@@ -388,8 +430,8 @@
 	{0x5849, 0xd5},
 	{0x3503, 0x07},
 	{0x3500, 0x00},
-	{0x3501, 0x27},
-	{0x3502, 0x00},
+	{0x3501, 0x4e},
+	{0x3502, 0xa0},
 	{0x350b, 0xff},
 	{0x3400, 0x04},
 	{0x3401, 0x00},
@@ -463,6 +505,9 @@
 	{0x583b, 0x28},
 	{0x583c, 0x26},
 	{0x583d, 0x9d},
+	{0x4818, 0x00},
+	{0x4819, 0xe0},
+	{0x482a, 0x05},
 };
 
 static struct v4l2_subdev_info ov8825_subdev_info[] = {
@@ -476,8 +521,6 @@
 };
 
 static struct msm_camera_i2c_conf_array ov8825_init_conf[] = {
-	{&ov8825_reset_settings[0],
-	ARRAY_SIZE(ov8825_reset_settings), 50, MSM_CAMERA_I2C_BYTE_DATA},
 	{&ov8825_recommend_settings[0],
 	ARRAY_SIZE(ov8825_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
 };
@@ -495,17 +538,26 @@
 		.y_output = 0x990,
 		.line_length_pclk = 0xE00,
 		.frame_length_lines = 0x9B0,
+#if OV8825_2LANES
 		.vt_pixel_clk = 133400000,
+#else
+		.vt_pixel_clk = 133000000,
+#endif
 		.op_pixel_clk = 176000000,
 		.binning_factor = 1,
 	},
 	{
 		.x_output = 0x660,
 		.y_output = 0x4C8,
-		.line_length_pclk = 0x6DE,
-		.frame_length_lines = 0x505,
-		.vt_pixel_clk = 66700000,
-		.op_pixel_clk = 88000000,
+		.line_length_pclk = 0xdbc,
+		.frame_length_lines = 0x4f0,
+#if OV8825_2LANES
+		.vt_pixel_clk = 133400000,
+#else
+		.vt_pixel_clk = 133000000,
+#endif
+		.op_pixel_clk = 176000000,
+
 		.binning_factor = 2,
 	},
 };
@@ -523,7 +575,7 @@
 };
 
 static struct msm_sensor_exp_gain_info_t ov8825_exp_gain_info = {
-	.coarse_int_time_addr = 0x3501,
+	.coarse_int_time_addr = 0x3500,
 	.global_gain_addr = 0x350A,
 	.vert_offset = 6,
 };
@@ -763,7 +815,7 @@
 }
 
 static int32_t ov8825_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
 {
 	uint32_t fl_lines, offset;
 	uint8_t int_time[3];
@@ -782,7 +834,36 @@
 	int_time[1] = line >> 4;
 	int_time[2] = line << 4;
 	msm_camera_i2c_write_seq(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr-1,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+		&int_time[0], 3);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
+		MSM_CAMERA_I2C_WORD_DATA);
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	return 0;
+}
+
+static int32_t ov8825_write_pic_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
+{
+	uint32_t fl_lines, offset;
+	uint8_t int_time[3];
+
+	fl_lines =
+		(s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider) / Q10;
+	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+	if (line > (fl_lines - offset))
+		fl_lines = line + offset;
+	CDBG("ov8825_write_exp_gain: %d %d %d\n", fl_lines, gain, line);
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines, fl_lines,
+		MSM_CAMERA_I2C_WORD_DATA);
+	int_time[0] = line >> 12;
+	int_time[1] = line >> 4;
+	int_time[2] = line << 4;
+	msm_camera_i2c_write_seq(s_ctrl->sensor_i2c_client,
+		s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
 		&int_time[0], 3);
 	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
 		s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
@@ -796,28 +877,6 @@
 	{ }
 };
 
-int32_t ov8825_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	int32_t rc = 0;
-	struct msm_camera_sensor_info *info = NULL;
-
-	info = s_ctrl->sensordata;
-	gpio_direction_output(info->sensor_pwd, 0);
-	gpio_direction_output(info->sensor_reset, 0);
-	usleep_range(10000, 11000);
-	rc = msm_sensor_power_up(s_ctrl);
-	if (rc < 0) {
-		CDBG("%s: msm_sensor_power_up failed\n", __func__);
-		return rc;
-	}
-	/* turn on ldo and vreg */
-	gpio_direction_output(info->sensor_pwd, 1);
-	msleep(20);
-	gpio_direction_output(info->sensor_reset, 1);
-	msleep(40);
-	return rc;
-}
-
 static struct i2c_driver ov8825_i2c_driver = {
 	.id_table = ov8825_i2c_id,
 	.probe  = msm_sensor_i2c_probe,
@@ -830,8 +889,6 @@
 	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
 };
 
-
-
 static int __init msm_sensor_init_module(void)
 {
 	return i2c_add_driver(&ov8825_i2c_driver);
@@ -856,6 +913,8 @@
 {
 	int32_t rc = 0;
 
+	CDBG("function:%s,line:%d\n", __func__, __LINE__);
+
 	if (update_type == MSM_SENSOR_REG_INIT) {
 		CDBG("Register INIT\n");
 		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
@@ -863,21 +922,19 @@
 		msm_sensor_write_init_settings(s_ctrl);
 		CDBG("Update OTP\n");
 		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x100, 0x1,
-				MSM_CAMERA_I2C_BYTE_DATA);
+		MSM_CAMERA_I2C_BYTE_DATA);
 		msleep(66);
 		ov8825_update_otp(s_ctrl);
 		usleep_range(10000, 11000);
 		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x100, 0x0,
-		  MSM_CAMERA_I2C_BYTE_DATA);
+		MSM_CAMERA_I2C_BYTE_DATA);
 	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
 		CDBG("PERIODIC : %d\n", res);
-		msm_sensor_write_conf_array(
-			s_ctrl->sensor_i2c_client,
-			s_ctrl->msm_sensor_reg->mode_settings, res);
+		msm_sensor_write_res_settings(s_ctrl, res);
 		msleep(30);
 		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
-			NOTIFY_PCLK_CHANGE,
-			&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);
+			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
+			output_settings[res].op_pixel_clk);
 	}
 	return rc;
 }
@@ -889,14 +946,17 @@
 	.sensor_group_hold_off = msm_sensor_group_hold_off,
 	.sensor_set_fps = msm_sensor_set_fps,
 	.sensor_write_exp_gain = ov8825_write_exp_gain,
-	.sensor_write_snapshot_exp_gain = ov8825_write_exp_gain,
-	.sensor_csi_setting = ov8825_sensor_setting,
+	.sensor_write_snapshot_exp_gain = ov8825_write_pic_exp_gain,
+	.sensor_setting = ov8825_sensor_setting,    /*msm_sensor_setting,*/
+	.sensor_csi_setting = msm_sensor_setting,
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
 	.sensor_get_output_info = msm_sensor_get_output_info,
 	.sensor_config = msm_sensor_config,
-	.sensor_power_up = ov8825_sensor_power_up,
+	.sensor_power_up = msm_sensor_power_up,
 	.sensor_power_down = msm_sensor_power_down,
+	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines1,
+	.sensor_get_csi_params = msm_sensor_get_csi_params,
 };
 
 static struct msm_sensor_reg_t ov8825_regs = {
@@ -930,8 +990,9 @@
 	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov8825_subdev_info),
 	.sensor_v4l2_subdev_ops = &ov8825_subdev_ops,
 	.func_tbl = &ov8825_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
 };
 
 module_init(msm_sensor_init_module);
-MODULE_DESCRIPTION("Omnivison 8MP Bayer sensor driver");
+MODULE_DESCRIPTION("OV 8MP Bayer sensor driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/ov9724_v4l2.c b/drivers/media/video/msm/sensors/ov9724_v4l2.c
new file mode 100644
index 0000000..8988197
--- /dev/null
+++ b/drivers/media/video/msm/sensors/ov9724_v4l2.c
@@ -0,0 +1,257 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 and
+ * only 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.
+ *
+ */
+
+#include "msm_sensor.h"
+#define SENSOR_NAME "ov9724"
+#define PLATFORM_DRIVER_NAME "msm_camera_ov9724"
+#define ov9724_obj ov9724_##obj
+
+DEFINE_MUTEX(ov9724_mut);
+static struct msm_sensor_ctrl_t ov9724_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf ov9724_start_settings[] = {
+	{0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf ov9724_stop_settings[] = {
+	{0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf ov9724_groupon_settings[] = {
+	{0x0104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf ov9724_groupoff_settings[] = {
+	{0x0104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf ov9724_prev_settings[] = {
+};
+
+static struct msm_camera_i2c_reg_conf ov9724_recommend_settings[] = {
+	{0x0103, 0x01},
+	{0x3210, 0x43},
+	{0x3606, 0x75},
+	{0x3705, 0x67},
+	{0x3601, 0x33},
+	{0x3607, 0x94},
+	{0x3608, 0x38},
+	{0x3712, 0x60},
+	{0x370d, 0x00},
+	{0x4010, 0x00},
+	{0x0340, 0x02},
+	{0x0341, 0xf8},
+	{0x0342, 0x06},
+	{0x0343, 0x28},
+	{0x0344, 0x00},
+	{0x0345, 0x00},
+	{0x0346, 0x00},
+	{0x0347, 0x00},
+	{0x0348, 0x04},
+	{0x0349, 0xff},
+	{0x034a, 0x02},
+	{0x034b, 0xcf},
+	{0x034c, 0x05},
+	{0x034d, 0x00},
+	{0x034e, 0x02},
+	{0x034f, 0xd0},
+	{0x4908, 0x20},
+	{0x4909, 0x14},
+	{0x3811, 0x10},
+	{0x3813, 0x0a},
+	{0x0202, 0x02},
+	{0x0203, 0xf0},
+	{0x4800, 0x64},
+	{0x4801, 0x0f},
+	{0x4801, 0x8f},
+	{0x4814, 0x2b},
+	{0x4307, 0x3a},
+	{0x5000, 0x06},
+	{0x5001, 0x73},
+	{0x0205, 0x3f},
+	{0x0100, 0x01},
+};
+
+static struct v4l2_subdev_info ov9724_subdev_info[] = {
+	{
+		.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.fmt    = 1,
+		.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array ov9724_init_conf[] = {
+	{&ov9724_recommend_settings[0],
+		ARRAY_SIZE(ov9724_recommend_settings), 0,
+		MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array ov9724_confs[] = {
+	{&ov9724_prev_settings[0],
+		ARRAY_SIZE(ov9724_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t ov9724_dimensions[] = {
+	{
+		.x_output = 0x500, /* 1280 */
+		.y_output = 0x2d0, /* 720 */
+		.line_length_pclk = 0x628, /* 1576 */
+		.frame_length_lines = 0x2f8, /* 760 */
+		.vt_pixel_clk = 36000000,
+		.op_pixel_clk = 36000000,
+		.binning_factor = 1,
+	},
+};
+
+static struct msm_sensor_output_reg_addr_t ov9724_reg_addr = {
+	.x_output = 0x034c,
+	.y_output = 0x034e,
+	.line_length_pclk = 0x0342,
+	.frame_length_lines = 0x0340,
+};
+
+static struct msm_sensor_id_info_t ov9724_id_info = {
+	.sensor_id_reg_addr = 0x0000,
+	.sensor_id = 0x9724,
+};
+
+static struct msm_sensor_exp_gain_info_t ov9724_exp_gain_info = {
+	.coarse_int_time_addr = 0x0202,
+	.global_gain_addr = 0x0205,
+	.vert_offset = 6,
+};
+
+static const struct i2c_device_id ov9724_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&ov9724_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver ov9724_i2c_driver = {
+	.id_table = ov9724_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client ov9724_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	return i2c_add_driver(&ov9724_i2c_driver);
+}
+
+
+int32_t ov9724_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
+{
+	uint32_t fl_lines;
+	uint8_t offset;
+	fl_lines = s_ctrl->curr_frame_length_lines;
+	fl_lines = (fl_lines * s_ctrl->fps_divider) / Q10;
+	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
+	if (line > (fl_lines - offset))
+		fl_lines = line + offset;
+
+	s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
+
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines,
+			fl_lines, MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
+			line, MSM_CAMERA_I2C_WORD_DATA);
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
+			MSM_CAMERA_I2C_BYTE_DATA);
+	s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
+	return 0;
+}
+
+
+static struct v4l2_subdev_core_ops ov9724_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops ov9724_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops ov9724_subdev_ops = {
+	.core = &ov9724_subdev_core_ops,
+	.video  = &ov9724_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t ov9724_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = msm_sensor_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_write_exp_gain = ov9724_write_exp_gain,
+	.sensor_write_snapshot_exp_gain = ov9724_write_exp_gain,
+	.sensor_setting = msm_sensor_setting,
+	.sensor_csi_setting = msm_sensor_setting1,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+	.sensor_get_csi_params = msm_sensor_get_csi_params,
+};
+
+static struct msm_sensor_reg_t ov9724_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = ov9724_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(ov9724_start_settings),
+	.stop_stream_conf = ov9724_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(ov9724_stop_settings),
+	.group_hold_on_conf = ov9724_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(ov9724_groupon_settings),
+	.group_hold_off_conf = ov9724_groupoff_settings,
+	.group_hold_off_conf_size =
+		ARRAY_SIZE(ov9724_groupoff_settings),
+	.init_settings = &ov9724_init_conf[0],
+	.init_size = ARRAY_SIZE(ov9724_init_conf),
+	.mode_settings = &ov9724_confs[0],
+	.output_settings = &ov9724_dimensions[0],
+	.num_conf = ARRAY_SIZE(ov9724_confs),
+};
+
+static struct msm_sensor_ctrl_t ov9724_s_ctrl = {
+	.msm_sensor_reg = &ov9724_regs,
+	.sensor_i2c_client = &ov9724_sensor_i2c_client,
+	.sensor_i2c_addr = 0x20,
+	.sensor_output_reg_addr = &ov9724_reg_addr,
+	.sensor_id_info = &ov9724_id_info,
+	.sensor_exp_gain_info = &ov9724_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.msm_sensor_mutex = &ov9724_mut,
+	.sensor_i2c_driver = &ov9724_i2c_driver,
+	.sensor_v4l2_subdev_info = ov9724_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov9724_subdev_info),
+	.sensor_v4l2_subdev_ops = &ov9724_subdev_ops,
+	.func_tbl = &ov9724_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Omnivision WXGA Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/media/video/msm/sensors/ov9726_v4l2.c b/drivers/media/video/msm/sensors/ov9726_v4l2.c
index 50c13c6..debd959 100644
--- a/drivers/media/video/msm/sensors/ov9726_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov9726_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/s5k3l1yx.c b/drivers/media/video/msm/sensors/s5k3l1yx.c
index 6a2372e..9ee22f1 100644
--- a/drivers/media/video/msm/sensors/s5k3l1yx.c
+++ b/drivers/media/video/msm/sensors/s5k3l1yx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c b/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
index 8cdadd8..fdb1bdf 100644
--- a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
+++ b/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -235,7 +235,7 @@
 }
 
 static int32_t s5k4e1_write_prev_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-						uint16_t gain, uint32_t line)
+	uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
 {
 	uint16_t max_legal_gain = 0x0200;
 	int32_t rc = 0;
@@ -321,7 +321,7 @@
 }
 
 static int32_t s5k4e1_write_pict_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
-		uint16_t gain, uint32_t line)
+		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
 {
 	uint16_t max_legal_gain = 0x0200;
 	uint16_t min_ll_pck = 0x0AB2;
diff --git a/drivers/media/video/msm/sensors/vx6953.c b/drivers/media/video/msm/sensors/vx6953.c
index ddc6cee..9867468 100644
--- a/drivers/media/video/msm/sensors/vx6953.c
+++ b/drivers/media/video/msm/sensors/vx6953.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/vx6953.h b/drivers/media/video/msm/sensors/vx6953.h
index 0fcdb53..2fc2a19 100644
--- a/drivers/media/video/msm/sensors/vx6953.h
+++ b/drivers/media/video/msm/sensors/vx6953.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sensors/vx6953_reg.h b/drivers/media/video/msm/sensors/vx6953_reg.h
index b76aa93..fe99be5 100644
--- a/drivers/media/video/msm/sensors/vx6953_reg.h
+++ b/drivers/media/video/msm/sensors/vx6953_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index afc3b63..47cd7b0 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -445,7 +445,7 @@
 			break;
 		D("%s: wait_event interrupted by signal, remain_count = %d",
 			__func__, wait_count);
-	} while (wait_count > 0);
+	} while (1);
 	D("Waiting is over for config status\n");
 	if (list_empty_careful(&queue->list)) {
 		if (!rc)
@@ -1081,8 +1081,37 @@
 			struct v4l2_event_subscription *sub)
 {
 	int rc = 0;
+	struct v4l2_event ev;
 
 	D("%s: fh = 0x%x\n", __func__, (u32)fh);
+
+	/* Undequeue all pending events and free associated
+	 * msm_isp_event_ctrl  */
+	while (v4l2_event_pending(fh)) {
+		struct msm_isp_event_ctrl *isp_event;
+		rc = v4l2_event_dequeue(fh, &ev, O_NONBLOCK);
+		if (rc) {
+			pr_err("%s: v4l2_event_dequeue failed %d",
+						__func__, rc);
+			break;
+		}
+		isp_event = (struct msm_isp_event_ctrl *)
+			(*((uint32_t *)ev.u.data));
+		if (isp_event) {
+			if (ev.type == (V4L2_EVENT_PRIVATE_START +
+						MSM_CAM_RESP_STAT_EVT_MSG)) {
+				if (isp_event->isp_data.isp_msg.len != 0 &&
+				isp_event->isp_data.isp_msg.data != NULL) {
+					kfree(isp_event->isp_data.isp_msg.data);
+					isp_event->isp_data.isp_msg.len = 0;
+					isp_event->isp_data.isp_msg.data = NULL;
+				}
+				kfree(isp_event);
+				*((uint32_t *)ev.u.data) = 0;
+			}
+		}
+	}
+
 	rc = v4l2_event_unsubscribe(fh, sub);
 	D("%s: rc = %d\n", __func__, rc);
 	return rc;
@@ -1452,13 +1481,14 @@
 					/*so that it isn't closed again*/
 					pmctl->mctl_release = NULL;
 				}
-				msm_cam_server_send_error_evt(pmctl,
-					V4L2_EVENT_PRIVATE_START +
-					MSM_CAM_APP_NOTIFY_ERROR_EVENT);
+				if (pmctl)
+					msm_cam_server_send_error_evt(pmctl,
+						V4L2_EVENT_PRIVATE_START +
+						MSM_CAM_APP_NOTIFY_ERROR_EVENT);
 			}
 		}
 		sub.type = V4L2_EVENT_ALL;
-		msm_server_v4l2_unsubscribe_event(
+		v4l2_event_unsubscribe(
 			&g_server_dev.server_command_queue.eventHandle, &sub);
 		mutex_unlock(&g_server_dev.server_lock);
 	}
@@ -1651,6 +1681,7 @@
 
 static const struct v4l2_ioctl_ops msm_ioctl_ops_server = {
 	.vidioc_subscribe_event = msm_server_v4l2_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 	.vidioc_default = msm_ioctl_server,
 };
 
@@ -1763,7 +1794,11 @@
 	case NOTIFY_VFE_MSG_COMP_STATS:
 	case NOTIFY_VFE_BUF_EVT:
 		p_mctl = msm_cam_server_get_mctl(mctl_handle);
-		if (p_mctl->isp_notify && p_mctl->vfe_sdev)
+		if (p_mctl == NULL) {
+			pr_err("%s: Not find p_mctl instance!\n", __func__);
+			return;
+		}
+		if (p_mctl && p_mctl->isp_notify && p_mctl->vfe_sdev)
 			rc = p_mctl->isp_notify(p_mctl,
 				p_mctl->vfe_sdev, notification, arg);
 		break;
@@ -1782,18 +1817,20 @@
 		break;
 	case NOTIFY_AXI_RDI_SOF_COUNT:
 		p_mctl = msm_cam_server_get_mctl(mctl_handle);
-		if (p_mctl->axi_sdev)
+		if (p_mctl && p_mctl->axi_sdev)
 			rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
 				VIDIOC_MSM_AXI_RDI_COUNT_UPDATE, arg);
 		break;
 	case NOTIFY_PCLK_CHANGE:
 		p_mctl = v4l2_get_subdev_hostdata(sd);
-		if (p_mctl->axi_sdev)
-			rc = v4l2_subdev_call(p_mctl->axi_sdev, video,
-			s_crystal_freq, *(uint32_t *)arg, 0);
-		else
-			rc = v4l2_subdev_call(p_mctl->vfe_sdev, video,
-			s_crystal_freq, *(uint32_t *)arg, 0);
+		if (p_mctl) {
+			if (p_mctl->axi_sdev)
+				rc = v4l2_subdev_call(p_mctl->axi_sdev, video,
+				s_crystal_freq, *(uint32_t *)arg, 0);
+			else
+				rc = v4l2_subdev_call(p_mctl->vfe_sdev, video,
+				s_crystal_freq, *(uint32_t *)arg, 0);
+		}
 		break;
 	case NOTIFY_GESTURE_EVT:
 		rc = v4l2_subdev_call(g_server_dev.gesture_device,
@@ -1805,8 +1842,10 @@
 		break;
 	case NOTIFY_VFE_CAMIF_ERROR: {
 		p_mctl = msm_cam_server_get_mctl(mctl_handle);
-		msm_cam_server_send_error_evt(p_mctl, V4L2_EVENT_PRIVATE_START
-			+ MSM_CAM_APP_NOTIFY_ERROR_EVENT);
+		if (p_mctl)
+			msm_cam_server_send_error_evt(p_mctl,
+				V4L2_EVENT_PRIVATE_START +
+				MSM_CAM_APP_NOTIFY_ERROR_EVENT);
 		break;
 	}
 	default:
@@ -3012,6 +3051,8 @@
 						break;
 					}
 					kfree(k_msg_value);
+					k_isp_event->isp_data.isp_msg.len = 0;
+					k_isp_event->isp_data.isp_msg.data = 0;
 					k_msg_value = NULL;
 				}
 			}
@@ -3025,6 +3066,7 @@
 			break;
 		}
 		kfree(k_isp_event);
+		*((uint32_t *)ev.u.data) = 0;
 		k_isp_event = NULL;
 
 		/* Copy the v4l2_event structure back to the user*/
@@ -3089,9 +3131,7 @@
 
 static int msm_close_config(struct inode *node, struct file *f)
 {
-	struct v4l2_event ev;
 	struct v4l2_event_subscription sub;
-	struct msm_isp_event_ctrl *isp_event;
 	struct msm_cam_config_dev *config_cam = f->private_data;
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
@@ -3102,20 +3142,6 @@
 	msm_server_v4l2_unsubscribe_event(
 		&config_cam->config_stat_event_queue.eventHandle,
 		&sub);
-	while (v4l2_event_pending(
-		&config_cam->config_stat_event_queue.eventHandle)) {
-		v4l2_event_dequeue(
-			&config_cam->config_stat_event_queue.eventHandle,
-			&ev, O_NONBLOCK);
-		isp_event = (struct msm_isp_event_ctrl *)
-			(*((uint32_t *)ev.u.data));
-		if (isp_event) {
-			if (isp_event->isp_data.isp_msg.len != 0 &&
-				isp_event->isp_data.isp_msg.data != NULL)
-				kfree(isp_event->isp_data.isp_msg.data);
-			kfree(isp_event);
-		}
-	}
 	return 0;
 }
 
diff --git a/drivers/media/video/msm/server/msm_cam_server.h b/drivers/media/video/msm/server/msm_cam_server.h
index 582d23e..dc8eceb 100644
--- a/drivers/media/video/msm/server/msm_cam_server.h
+++ b/drivers/media/video/msm/server/msm_cam_server.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sn12m0pz.c b/drivers/media/video/msm/sn12m0pz.c
index c39e97f..1fcd732 100644
--- a/drivers/media/video/msm/sn12m0pz.c
+++ b/drivers/media/video/msm/sn12m0pz.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sn12m0pz.h b/drivers/media/video/msm/sn12m0pz.h
index f2abc47..c3d3346 100644
--- a/drivers/media/video/msm/sn12m0pz.h
+++ b/drivers/media/video/msm/sn12m0pz.h
@@ -1,5 +1,5 @@
 
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/sn12m0pz_reg.c b/drivers/media/video/msm/sn12m0pz_reg.c
index d21eac1..c406d98 100644
--- a/drivers/media/video/msm/sn12m0pz_reg.c
+++ b/drivers/media/video/msm/sn12m0pz_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vb6801.c b/drivers/media/video/msm/vb6801.c
index fa82570..f916a1c 100644
--- a/drivers/media/video/msm/vb6801.c
+++ b/drivers/media/video/msm/vb6801.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vb6801.h b/drivers/media/video/msm/vb6801.h
index 8248f8d..5a8842c 100644
--- a/drivers/media/video/msm/vb6801.h
+++ b/drivers/media/video/msm/vb6801.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe31.c b/drivers/media/video/msm/vfe/msm_vfe31.c
index 2929538..ab92085 100644
--- a/drivers/media/video/msm/vfe/msm_vfe31.c
+++ b/drivers/media/video/msm/vfe/msm_vfe31.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe31.h b/drivers/media/video/msm/vfe/msm_vfe31.h
index bec5f58..4e1a8d4 100644
--- a/drivers/media/video/msm/vfe/msm_vfe31.h
+++ b/drivers/media/video/msm/vfe/msm_vfe31.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.c b/drivers/media/video/msm/vfe/msm_vfe31_v4l2.c
index de32f1b..10ddd4b 100644
--- a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.c
+++ b/drivers/media/video/msm/vfe/msm_vfe31_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.h b/drivers/media/video/msm/vfe/msm_vfe31_v4l2.h
index 97ecd6e..eea8078 100644
--- a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.h
+++ b/drivers/media/video/msm/vfe/msm_vfe31_v4l2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.c b/drivers/media/video/msm/vfe/msm_vfe32.c
index 5167757..0ad496a 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.c
+++ b/drivers/media/video/msm/vfe/msm_vfe32.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -232,12 +232,12 @@
 		{VFE_CMD_STATS_UNREGBUF},
 		{VFE_CMD_STATS_BG_START, V32_STATS_BG_LEN, V32_STATS_BG_OFF},
 		{VFE_CMD_STATS_BG_STOP},
-		{VFE_CMD_STATS_BF_START, V32_STATS_BF_LEN, V32_STATS_BF_OFF},
-/*145*/ {VFE_CMD_STATS_BF_STOP},
+/*145*/	{VFE_CMD_STATS_BF_START, V32_STATS_BF_LEN, V32_STATS_BF_OFF},
+		{VFE_CMD_STATS_BF_STOP},
 		{VFE_CMD_STATS_BHIST_START, V32_STATS_BHIST_LEN,
 			V32_STATS_BHIST_OFF},
 		{VFE_CMD_STATS_BHIST_STOP},
-/*148*/	{VFE_CMD_SELECT_RDI},
+/*149*/	{VFE_CMD_SELECT_RDI},
 };
 
 uint32_t vfe32_AXI_WM_CFG[] = {
@@ -364,7 +364,7 @@
 	"DEMOSAICV3_DBCC_UPDATE", /* 110 */
 	"DEMOSAICV3_DBPC_UPDATE",
 	"XBAR_CFG",
-	"EZTUNE_CFG",
+	"MODULE_CFG",
 	"V32_ZSL",
 	"LINEARIZATION_UPDATE", /*115*/
 	"DEMOSAICV3_ABF_UPDATE",
@@ -380,16 +380,16 @@
 	"GET_RGB_G_TABLE",
 	"GET_LA_TABLE",
 	"DEMOSAICV3_UPDATE",
-	"DUMMY_11",
-	"DUMMY_12", /*130*/
-	"DUMMY_13",
-	"DUMMY_14",
-	"DUMMY_15",
-	"DUMMY_16",
-	"DUMMY_17", /*135*/
-	"DUMMY_18",
-	"DUMMY_19",
-	"DUMMY_20",
+	"VFE_CMD_ACTIVE_REGION_CFG",
+	"VFE_CMD_COLOR_PROCESSING_CONFIG", /*130*/
+	"VFE_CMD_STATS_WB_AEC_CONFIG",
+	"VFE_CMD_STATS_WB_AEC_UPDATE",
+	"VFE_CMD_Y_GAMMA_CONFIG",
+	"VFE_CMD_SCALE_OUTPUT1_CONFIG",
+	"VFE_CMD_SCALE_OUTPUT2_CONFIG", /*135*/
+	"VFE_CMD_CAPTURE_RAW",
+	"VFE_CMD_STOP_LIVESHOT",
+	"VFE_CMD_RECONFIG_VFE",
 	"STATS_REQBUF",
 	"STATS_ENQUEUEBUF", /*140*/
 	"STATS_FLUSH_BUFQ",
@@ -400,7 +400,6 @@
 	"STATS_BF_STOP",
 	"STATS_BHIST_START",
 	"STATS_BHIST_STOP",
-	"RESET_2",
 	"RDI_SEL" /*150*/
 };
 
@@ -1063,13 +1062,13 @@
 			vfe32_ctrl->share_ctrl->vfebase +
 				VFE_BUS_STATS_HIST_UB_CFG);
 	} else {
-		msm_camera_io_w(0x350001F,
+		msm_camera_io_w(0x316001F,
 			vfe32_ctrl->share_ctrl->vfebase +
 				VFE_BUS_STATS_HIST_UB_CFG);
-		msm_camera_io_w(0x370002F,
+		msm_camera_io_w(0x336005C,
 			vfe32_ctrl->share_ctrl->vfebase +
 				VFE_BUS_STATS_AEC_BG_UB_CFG);
-		msm_camera_io_w(0x3A0002F,
+		msm_camera_io_w(0x393003C,
 			vfe32_ctrl->share_ctrl->vfebase +
 				VFE_BUS_STATS_AF_BF_UB_CFG);
 		msm_camera_io_w(0x3D00007,
@@ -1550,8 +1549,10 @@
 	CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
 		vfe32_ctrl->share_ctrl->operation_mode,
 		vfe32_ctrl->share_ctrl->outpath.output_mode);
-		msm_camera_io_w_mb(1, vfe32_ctrl->share_ctrl->vfebase +
-			VFE_CAMIF_COMMAND);
+	msm_camera_io_w_mb(1, vfe32_ctrl->share_ctrl->vfebase +
+		VFE_CAMIF_COMMAND);
+	msm_camera_io_w_mb(VFE_AXI_CFG_MASK,
+		vfe32_ctrl->share_ctrl->vfebase + VFE_AXI_CFG);
 }
 
 static int vfe32_start_recording(
@@ -2949,6 +2950,67 @@
 	    cmdp -= 1;
 		break;
 
+	case VFE_CMD_RGB_ALL_CFG: {
+		cmdp = kmalloc((cmd->length), GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		msm_camera_io_memcpy(
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF,
+			cmdp, 4);
+		cmdp += 1;
+
+		vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0,
+			cmdp + VFE32_GAMMA_CH0_G_POS, vfe32_ctrl);
+		vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0,
+			cmdp + VFE32_GAMMA_CH1_B_POS, vfe32_ctrl);
+		vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0,
+			cmdp + VFE32_GAMMA_CH2_R_POS, vfe32_ctrl);
+		}
+	    cmdp -= 1;
+		break;
+
+	case VFE_CMD_RGB_ALL_UPDATE: {
+		cmdp = kmalloc((cmd->length), GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp, (void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		old_val = msm_camera_io_r(
+			vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
+			cmdp += 1;
+		if (old_val != 0x0) {
+			vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0,
+				cmdp + VFE32_GAMMA_CH0_G_POS, vfe32_ctrl);
+			vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK0,
+				cmdp + VFE32_GAMMA_CH1_B_POS, vfe32_ctrl);
+			vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK0,
+				cmdp + VFE32_GAMMA_CH2_R_POS, vfe32_ctrl);
+		} else {
+			vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK1,
+				cmdp + VFE32_GAMMA_CH0_G_POS, vfe32_ctrl);
+			vfe32_write_gamma_cfg(RGBLUT_RAM_CH1_BANK1,
+				cmdp + VFE32_GAMMA_CH1_B_POS, vfe32_ctrl);
+			vfe32_write_gamma_cfg(RGBLUT_RAM_CH2_BANK1,
+				cmdp + VFE32_GAMMA_CH2_R_POS, vfe32_ctrl);
+		}
+		}
+		vfe32_ctrl->update_gamma = TRUE;
+		cmdp -= 1;
+		break;
+
 	case VFE_CMD_RGB_G_UPDATE: {
 		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
 		if (!cmdp) {
@@ -4785,7 +4847,9 @@
 	struct vfe32_ctrl_type *vfe32_ctrl, uint32_t status_bits)
 {
 	struct msm_stats_buf msgStats;
-	uint32_t temp;
+	uint32_t stats_type;
+	int rc = 0;
+	void *vaddr = NULL;
 
 	msgStats.frame_id = vfe32_ctrl->share_ctrl->vfeFrameId;
 	if (vfe32_ctrl->simultaneous_sof_stat)
@@ -4793,21 +4857,116 @@
 
 	msgStats.status_bits = status_bits;
 
-	msgStats.aec.buff = vfe32_ctrl->aecbgStatsControl.bufToRender;
-	msgStats.awb.buff = vfe32_ctrl->awbStatsControl.bufToRender;
-	msgStats.af.buff = vfe32_ctrl->afbfStatsControl.bufToRender;
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AEC_BG) {
+		stats_type = (!vfe32_use_bayer_stats(vfe32_ctrl)) ?
+			MSM_STATS_TYPE_AEC : MSM_STATS_TYPE_BG;
+		rc = vfe32_ctrl->stats_ops.dispatch(
+			vfe32_ctrl->stats_ops.stats_ctrl, stats_type,
+			vfe32_ctrl->aecbgStatsControl.bufToRender,
+			&msgStats.buf_idx, &vaddr, &msgStats.aec.fd,
+			vfe32_ctrl->stats_ops.client);
+		if (rc == 0)
+			msgStats.aec.buff = (uint32_t)vaddr;
+		else
+			CDBG("%s: Could not dispatch AEC/BG stats buffer %d",
+				__func__, stats_type);
+	} else {
+		msgStats.aec.buff = 0;
+	}
 
-	msgStats.ihist.buff = vfe32_ctrl->ihistStatsControl.bufToRender;
-	msgStats.rs.buff = vfe32_ctrl->rsStatsControl.bufToRender;
-	msgStats.cs.buff = vfe32_ctrl->csStatsControl.bufToRender;
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
+		rc = vfe32_ctrl->stats_ops.dispatch(
+			vfe32_ctrl->stats_ops.stats_ctrl, MSM_STATS_TYPE_AWB,
+			vfe32_ctrl->awbStatsControl.bufToRender,
+			&msgStats.buf_idx, &vaddr, &msgStats.awb.fd,
+			vfe32_ctrl->stats_ops.client);
+		if (rc == 0)
+			msgStats.awb.buff = (uint32_t)vaddr;
+		else
+			CDBG("%s: Could not dispatch AWB stats buffer",
+				__func__);
+	} else {
+		msgStats.awb.buff = 0;
+	}
 
-	temp = msm_camera_io_r(
-		vfe32_ctrl->share_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
-	msgStats.awb_ymin = (0xFF00 & temp) >> 8;
+	if (status_bits & VFE_IRQ_STATUS0_STATS_AF_BF) {
+		stats_type = (!vfe32_use_bayer_stats(vfe32_ctrl)) ?
+			MSM_STATS_TYPE_AF : MSM_STATS_TYPE_BF;
+		rc = vfe32_ctrl->stats_ops.dispatch(
+			vfe32_ctrl->stats_ops.stats_ctrl, stats_type,
+			vfe32_ctrl->afbfStatsControl.bufToRender,
+			&msgStats.buf_idx, &vaddr, &msgStats.af.fd,
+			vfe32_ctrl->stats_ops.client);
+		if (rc == 0)
+			msgStats.af.buff = (uint32_t)vaddr;
+		else
+			CDBG("%s: Could not dispatch AF/BF stats buffer %d",
+				__func__, stats_type);
+	} else {
+		msgStats.af.buff = 0;
+	}
 
+	if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
+		rc = vfe32_ctrl->stats_ops.dispatch(
+			vfe32_ctrl->stats_ops.stats_ctrl, MSM_STATS_TYPE_IHIST,
+			vfe32_ctrl->ihistStatsControl.bufToRender,
+			&msgStats.buf_idx, &vaddr, &msgStats.ihist.fd,
+			vfe32_ctrl->stats_ops.client);
+		if (rc == 0)
+			msgStats.ihist.buff = (uint32_t)vaddr;
+		else
+			CDBG("%s: Could not dispatch IHIST stats buffer",
+				__func__);
+	} else {
+		msgStats.ihist.buff = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_RS) {
+		rc = vfe32_ctrl->stats_ops.dispatch(
+			vfe32_ctrl->stats_ops.stats_ctrl, MSM_STATS_TYPE_RS,
+			vfe32_ctrl->rsStatsControl.bufToRender,
+			&msgStats.buf_idx, &vaddr, &msgStats.rs.fd,
+			vfe32_ctrl->stats_ops.client);
+		if (rc == 0)
+			msgStats.rs.buff = (uint32_t)vaddr;
+		else
+			CDBG("%s: Could not dispatch RS stats buffer",
+				__func__);
+	} else {
+		msgStats.rs.buff = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
+		rc = vfe32_ctrl->stats_ops.dispatch(
+			vfe32_ctrl->stats_ops.stats_ctrl, MSM_STATS_TYPE_CS,
+			vfe32_ctrl->csStatsControl.bufToRender,
+			&msgStats.buf_idx, &vaddr, &msgStats.cs.fd,
+			vfe32_ctrl->stats_ops.client);
+		if (rc == 0)
+			msgStats.cs.buff = (uint32_t)vaddr;
+		else
+			CDBG("%s: Could not dispatch CS stats buffer",
+				__func__);
+	} else {
+		msgStats.cs.buff = 0;
+	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_SK_BHIST) {
+		rc = vfe32_ctrl->stats_ops.dispatch(
+			vfe32_ctrl->stats_ops.stats_ctrl, MSM_STATS_TYPE_BHIST,
+			vfe32_ctrl->bhistStatsControl.bufToRender,
+			&msgStats.buf_idx, &vaddr, &msgStats.skin.fd,
+			vfe32_ctrl->stats_ops.client);
+		if (rc == 0)
+			msgStats.skin.buff = (uint32_t)vaddr;
+		else
+			CDBG("%s: Could not dispatch BHIST stats buffer",
+				__func__);
+	} else {
+	  msgStats.skin.buff = 0;
+	}
 	v4l2_subdev_notify(&vfe32_ctrl->subdev,
-				NOTIFY_VFE_MSG_COMP_STATS,
-				&msgStats);
+		NOTIFY_VFE_MSG_COMP_STATS, &msgStats);
 }
 
 static void vfe32_process_stats_ae_bg_irq(struct vfe32_ctrl_type *vfe32_ctrl)
@@ -5085,6 +5244,24 @@
 	} else {
 		vfe32_ctrl->csStatsControl.bufToRender = 0;
 	}
+
+	if (status_bits & VFE_IRQ_STATUS0_STATS_SK_BHIST) {
+		addr = (uint32_t)vfe32_stats_dqbuf(vfe32_ctrl,
+				MSM_STATS_TYPE_BHIST);
+		if (addr) {
+			vfe32_ctrl->bhistStatsControl.bufToRender =
+				vfe32_process_stats_irq_common(
+				vfe32_ctrl,	statsSkinNum,
+				addr);
+			process_stats = true;
+		} else {
+			vfe32_ctrl->bhistStatsControl.droppedStatsFrameCount++;
+			vfe32_ctrl->bhistStatsControl.bufToRender = 0;
+		}
+	} else {
+		vfe32_ctrl->bhistStatsControl.bufToRender = 0;
+	}
+
 	spin_unlock_irqrestore(&vfe32_ctrl->stats_bufq_lock, flags);
 	if (process_stats)
 		vfe_send_comp_stats_msg(vfe32_ctrl, status_bits);
@@ -5096,6 +5273,7 @@
 	struct vfe32_ctrl_type *vfe32_ctrl, uint32_t irqstatus)
 {
 	uint32_t status_bits = VFE_COM_STATUS & irqstatus;
+
 	if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
 		(vfe32_ctrl->share_ctrl->vfeFrameId %
 		 vfe32_ctrl->hfr_mode != 0)) {
@@ -5551,10 +5729,20 @@
 	struct vfe_cmd_stats_ack *sack = NULL;
 
 	if (!vfe32_ctrl->share_ctrl->vfebase) {
-		pr_err("%s: base address unmapped\n", __func__);
-		return -EFAULT;
+		if (arg) {
+			vfe_params = (struct msm_camvfe_params *)arg;
+			cmd = vfe_params->vfe_cfg;
+			if (cmd->cmd_type != VFE_CMD_STATS_REQBUF &&
+				cmd->cmd_type != VFE_CMD_STATS_ENQUEUEBUF &&
+				cmd->cmd_type != VFE_CMD_STATS_FLUSH_BUFQ &&
+				cmd->cmd_type != VFE_CMD_STATS_UNREGBUF &&
+				subdev_cmd != VIDIOC_MSM_VFE_RELEASE) {
+				pr_err("%s: base address unmapped\n", __func__);
+				return -EFAULT;
+			}
+		} else
+			return -EFAULT;
 	}
-
 	CDBG("%s\n", __func__);
 	if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
 		CDBG("%s init\n", __func__);
@@ -6196,6 +6384,10 @@
 			msm_camio_bus_scale_cfg(
 				pmctl->sdata->pdata->cam_bus_scale_table,
 				S_PREVIEW);
+		else if(axi_ctrl->share_ctrl->dual_enabled)
+			msm_camio_bus_scale_cfg(
+				pmctl->sdata->pdata->cam_bus_scale_table,
+				S_DUAL);
 		break;
 	case AXI_CMD_CAPTURE:
 	case AXI_CMD_RAW_CAPTURE:
@@ -6217,6 +6409,10 @@
 			msm_camio_bus_scale_cfg(
 				pmctl->sdata->pdata->cam_bus_scale_table,
 				S_ZSL);
+		else if(axi_ctrl->share_ctrl->dual_enabled)
+			msm_camio_bus_scale_cfg(
+				pmctl->sdata->pdata->cam_bus_scale_table,
+				S_DUAL);
 		break;
 	case AXI_CMD_LIVESHOT:
 		if (!axi_ctrl->share_ctrl->dual_enabled)
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.h b/drivers/media/video/msm/vfe/msm_vfe32.h
index b8c967f..6525752 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.h
+++ b/drivers/media/video/msm/vfe/msm_vfe32.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -543,6 +543,12 @@
 
 #define VFE32_GAMMA_NUM_ENTRIES  64
 
+#define VFE32_GAMMA_CH0_G_POS    0
+
+#define VFE32_GAMMA_CH1_B_POS    32
+
+#define VFE32_GAMMA_CH2_R_POS    64
+
 #define VFE32_LA_TABLE_LENGTH    64
 
 #define VFE32_LINEARIZATON_TABLE_LENGTH    36
@@ -916,6 +922,7 @@
 #define VFE_DMI_ADDR                    0x0000059C
 #define VFE_DMI_DATA_HI                 0x000005A0
 #define VFE_DMI_DATA_LO                 0x000005A4
+#define VFE_AXI_CFG                     0x00000600
 #define VFE_BUS_IO_FORMAT_CFG           0x000006F8
 #define VFE_PIXEL_IF_CFG                0x000006FC
 #define VFE_RDI0_CFG                    0x00000734
@@ -925,6 +932,7 @@
 
 #define VFE33_DMI_DATA_HI               0x000005A0
 #define VFE33_DMI_DATA_LO               0x000005A4
+#define VFE_AXI_CFG_MASK                0xFFFFFFFF
 
 #define VFE32_OUTPUT_MODE_PT			BIT(0)
 #define VFE32_OUTPUT_MODE_S			BIT(1)
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.c b/drivers/media/video/msm/vfe/msm_vfe40.c
index e958241..767baae 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.c
+++ b/drivers/media/video/msm/vfe/msm_vfe40.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.h b/drivers/media/video/msm/vfe/msm_vfe40.h
index 8201d18..f2499bc 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.h
+++ b/drivers/media/video/msm/vfe/msm_vfe40.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe40_axi.c b/drivers/media/video/msm/vfe/msm_vfe40_axi.c
index 41d1cdd..88a219c 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40_axi.c
+++ b/drivers/media/video/msm/vfe/msm_vfe40_axi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x.c b/drivers/media/video/msm/vfe/msm_vfe7x.c
index 6a6eeb7..bbf9d1b 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x.c
+++ b/drivers/media/video/msm/vfe/msm_vfe7x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x.h b/drivers/media/video/msm/vfe/msm_vfe7x.h
index dd3571f..944bfea 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x.h
+++ b/drivers/media/video/msm/vfe/msm_vfe7x.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a.c b/drivers/media/video/msm/vfe/msm_vfe7x27a.c
index 825b7cb..0279c78 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a.c
+++ b/drivers/media/video/msm/vfe/msm_vfe7x27a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a.h b/drivers/media/video/msm/vfe/msm_vfe7x27a.h
index a488206..fbebb60 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a.h
+++ b/drivers/media/video/msm/vfe/msm_vfe7x27a.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
index 15c38af..cfb1574 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.h b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.h
index 7693235..78b1929 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.h
+++ b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe8x.c b/drivers/media/video/msm/vfe/msm_vfe8x.c
index 38011ba..953d634 100644
--- a/drivers/media/video/msm/vfe/msm_vfe8x.c
+++ b/drivers/media/video/msm/vfe/msm_vfe8x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe8x.h b/drivers/media/video/msm/vfe/msm_vfe8x.h
index 1b3148f..54e9c95 100644
--- a/drivers/media/video/msm/vfe/msm_vfe8x.h
+++ b/drivers/media/video/msm/vfe/msm_vfe8x.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe8x_proc.c b/drivers/media/video/msm/vfe/msm_vfe8x_proc.c
index 055b244..4ebb30d 100644
--- a/drivers/media/video/msm/vfe/msm_vfe8x_proc.c
+++ b/drivers/media/video/msm/vfe/msm_vfe8x_proc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe8x_proc.h b/drivers/media/video/msm/vfe/msm_vfe8x_proc.h
index da00e8f..4e18c7c 100644
--- a/drivers/media/video/msm/vfe/msm_vfe8x_proc.h
+++ b/drivers/media/video/msm/vfe/msm_vfe8x_proc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c
index 1d13e79..35cd1ea 100644
--- a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c
+++ b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -354,6 +354,8 @@
 	bufq = stats_ctrl->bufq[stats_type];
 
 	list_for_each_entry(stats_buf, &bufq->head, list) {
+		if(!stats_buf)
+			return -1;
 		if (stats_buf->state == MSM_STATS_BUFFER_STATE_QUEUED) {
 			/* found one buf */
 			list_del_init(&stats_buf->list);
diff --git a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.h b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.h
index bf3e70e..6a1c79d 100644
--- a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.h
+++ b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vx6953.c b/drivers/media/video/msm/vx6953.c
index f933a76..cc09a0d 100644
--- a/drivers/media/video/msm/vx6953.c
+++ b/drivers/media/video/msm/vx6953.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vx6953.h b/drivers/media/video/msm/vx6953.h
index 0e12063..175facc 100644
--- a/drivers/media/video/msm/vx6953.h
+++ b/drivers/media/video/msm/vx6953.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vx6953_reg.c b/drivers/media/video/msm/vx6953_reg.c
index 48fc71f..eee6904 100644
--- a/drivers/media/video/msm/vx6953_reg.c
+++ b/drivers/media/video/msm/vx6953_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vx6953_reg_v4l2.c b/drivers/media/video/msm/vx6953_reg_v4l2.c
index f16054b..8b1c1be 100644
--- a/drivers/media/video/msm/vx6953_reg_v4l2.c
+++ b/drivers/media/video/msm/vx6953_reg_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vx6953_v4l2.c b/drivers/media/video/msm/vx6953_v4l2.c
index 2e5e39b..7913752 100644
--- a/drivers/media/video/msm/vx6953_v4l2.c
+++ b/drivers/media/video/msm/vx6953_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm/vx6953_v4l2.h b/drivers/media/video/msm/vx6953_v4l2.h
index e5428e9..4c7e90f 100644
--- a/drivers/media/video/msm/vx6953_v4l2.h
+++ b/drivers/media/video/msm/vx6953_v4l2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/msm_smem.c b/drivers/media/video/msm_vidc/msm_smem.c
index c51ac7f..eb97eb4 100644
--- a/drivers/media/video/msm_vidc/msm_smem.c
+++ b/drivers/media/video/msm_vidc/msm_smem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/msm_smem.h b/drivers/media/video/msm_vidc/msm_smem.h
index f11e6cc..980f177 100644
--- a/drivers/media/video/msm_vidc/msm_smem.h
+++ b/drivers/media/video/msm_vidc/msm_smem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
index 12b4c76..e29238a 100644
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index a838a12..9ad7c83 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/msm_vdec.h b/drivers/media/video/msm_vidc/msm_vdec.h
index b8326d8..c4cec25 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.h
+++ b/drivers/media/video/msm_vidc/msm_vdec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 2e51daa..22ef5da 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/msm_venc.h b/drivers/media/video/msm_vidc/msm_venc.h
index 83610b3..3ee8533 100644
--- a/drivers/media/video/msm_vidc/msm_venc.h
+++ b/drivers/media/video/msm_vidc/msm_venc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
index 7c9b6db..b2f6dcb 100644
--- a/drivers/media/video/msm_vidc/msm_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 50f98da..af414bc 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.h b/drivers/media/video/msm_vidc/msm_vidc_common.h
index 9430d5f..289e3bb 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index 630f383..9a09880 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
index cf540d8..5eb2bbc 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ b/drivers/media/video/msm_vidc/vidc_hal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/vidc_hal.h b/drivers/media/video/msm_vidc/vidc_hal.h
index 8e7c3d3..d597844 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.h
+++ b/drivers/media/video/msm_vidc/vidc_hal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/vidc_hal_api.h b/drivers/media/video/msm_vidc/vidc_hal_api.h
index c77ae12..4c32c72 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_api.h
+++ b/drivers/media/video/msm_vidc/vidc_hal_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/vidc_hal_helper.h b/drivers/media/video/msm_vidc/vidc_hal_helper.h
index 43995eb..d560d3e 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_helper.h
+++ b/drivers/media/video/msm_vidc/vidc_hal_helper.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c b/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
index 364faa9..f986cc0 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
+++ b/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_vidc/vidc_hal_io.h b/drivers/media/video/msm_vidc/vidc_hal_io.h
index 05a4c60..a42305b 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_io.h
+++ b/drivers/media/video/msm_vidc/vidc_hal_io.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_wfd/enc-mfc-subdev.c b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
index 78678eb..9c91690 100644
--- a/drivers/media/video/msm_wfd/enc-mfc-subdev.c
+++ b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
@@ -2087,8 +2087,8 @@
 				rc = ion_map_iommu(client_ctx->user_ion_client,
 					client_ctx->recon_buffer_ion_handle[i],
 					VIDEO_DOMAIN, VIDEO_MAIN_POOL, SZ_4K,
-					0, &phy_addr, (unsigned long *)&len,
-					0, 0);
+					ctrl->buffer_size * 2, &phy_addr,
+					(unsigned long *)&len, 0, 0);
 				 if (rc || !phy_addr) {
 					WFD_MSG_ERR(
 						"ion map iommu failed, rc = %d, phy_addr = 0x%lx\n",
@@ -2096,6 +2096,12 @@
 					goto unmap_ion_alloc;
 				}
 
+				 msm_ion_do_cache_op(
+					 client_ctx->user_ion_client,
+					 client_ctx->recon_buffer_ion_handle[i],
+					 ctrl->kernel_virtual_addr,
+					 ctrl->buffer_size,
+					 ION_IOC_CLEAN_INV_CACHES);
 			}
 			ctrl->physical_addr =  (u8 *) phy_addr;
 			ctrl->dev_addr = ctrl->physical_addr;
diff --git a/drivers/media/video/msm_wfd/enc-subdev.h b/drivers/media/video/msm_wfd/enc-subdev.h
index 25373e4..93c0079 100644
--- a/drivers/media/video/msm_wfd/enc-subdev.h
+++ b/drivers/media/video/msm_wfd/enc-subdev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_wfd/mdp-4-subdev.c b/drivers/media/video/msm_wfd/mdp-4-subdev.c
index 3708c14..d1b39f6 100644
--- a/drivers/media/video/msm_wfd/mdp-4-subdev.c
+++ b/drivers/media/video/msm_wfd/mdp-4-subdev.c
@@ -202,9 +202,12 @@
 	if (inst->uses_iommu_split_domain) {
 		if (inst->secure)
 			use_iommu = false;
-		else
+		else {
+			use_iommu = true;
 			domain = DISPLAY_WRITE_DOMAIN;
+		}
 	} else {
+		use_iommu = true;
 		domain = DISPLAY_READ_DOMAIN;
 	}
 
@@ -227,7 +230,7 @@
 {
 	struct mem_region_map *mmap = arg;
 	struct mem_region *mregion;
-	bool use_iommu = false;
+	bool use_iommu = true;
 	int domain = -1;
 	struct mdp_instance *inst = NULL;
 
@@ -242,9 +245,12 @@
 	if (inst->uses_iommu_split_domain) {
 		if (inst->secure)
 			use_iommu = false;
-		else
+		else {
+			use_iommu = true;
 			domain = DISPLAY_WRITE_DOMAIN;
+		}
 	} else {
+		use_iommu = true;
 		domain = DISPLAY_READ_DOMAIN;
 	}
 
diff --git a/drivers/media/video/msm_wfd/mdp-subdev.h b/drivers/media/video/msm_wfd/mdp-subdev.h
index 5e81e3c..b04d448 100644
--- a/drivers/media/video/msm_wfd/mdp-subdev.h
+++ b/drivers/media/video/msm_wfd/mdp-subdev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_wfd/vsg-subdev.c b/drivers/media/video/msm_wfd/vsg-subdev.c
index 73b840b..bbe2b7b 100644
--- a/drivers/media/video/msm_wfd/vsg-subdev.c
+++ b/drivers/media/video/msm_wfd/vsg-subdev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_wfd/vsg-subdev.h b/drivers/media/video/msm_wfd/vsg-subdev.h
index dfc2e2e..f5e4f5d 100644
--- a/drivers/media/video/msm_wfd/vsg-subdev.h
+++ b/drivers/media/video/msm_wfd/vsg-subdev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/msm_wfd/wfd-ioctl.c b/drivers/media/video/msm_wfd/wfd-ioctl.c
index bb2e606..cf0a038 100644
--- a/drivers/media/video/msm_wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm_wfd/wfd-ioctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -266,11 +266,15 @@
 		mmap_context.ion_client = wfd_dev->ion_client;
 		rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
 				ENC_MMAP, &mmap_context);
-		if (rc || !enc_mregion->paddr) {
+		if (rc) {
 			WFD_MSG_ERR("Failed to map input memory\n");
 			goto alloc_fail;
+		} else if (!enc_mregion->paddr) {
+			WFD_MSG_ERR("ENC_MMAP returned success" \
+				"but failed to map input memory\n");
+			rc = -EINVAL;
+			goto alloc_fail;
 		}
-
 		WFD_MSG_DBG("NOTE: enc paddr = [%p->%p], kvaddr = %p\n",
 				enc_mregion->paddr, (int8_t *)
 				enc_mregion->paddr + enc_mregion->size,
@@ -298,7 +302,7 @@
 		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
 				MDP_MMAP, (void *)&mmap_context);
 
-		if (rc || !mdp_mregion->paddr) {
+		if (rc) {
 			WFD_MSG_ERR(
 				"Failed to map to mdp, rc = %d, paddr = 0x%p\n",
 				rc, mdp_mregion->paddr);
@@ -306,6 +310,14 @@
 			mdp_mregion->paddr = NULL;
 			mdp_mregion->ion_handle = NULL;
 			goto mdp_mmap_fail;
+		} else if (!mdp_mregion->paddr) {
+			WFD_MSG_ERR("MDP_MMAP returned success" \
+				"but failed to map to MDP\n");
+			rc = -EINVAL;
+			mdp_mregion->kvaddr = NULL;
+			mdp_mregion->paddr = NULL;
+			mdp_mregion->ion_handle = NULL;
+			goto mdp_mmap_fail;
 		}
 
 		mdp_buf.inst = inst->mdp_inst;
diff --git a/drivers/media/video/msm_wfd/wfd-util.c b/drivers/media/video/msm_wfd/wfd-util.c
index 5c00e5c..06b3f5b 100644
--- a/drivers/media/video/msm_wfd/wfd-util.c
+++ b/drivers/media/video/msm_wfd/wfd-util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -55,6 +55,7 @@
 
 	memset(stats, 0, sizeof(*stats));
 	INIT_LIST_HEAD(&stats->enc_queue);
+	mutex_init(&stats->mutex);
 
 	snprintf(device_str, sizeof(device_str), "%d", device);
 	stats->d_parent = debugfs_create_dir(device_str, wfd_debugfs_root);
@@ -128,6 +129,8 @@
 int wfd_stats_update(struct wfd_stats *stats, enum wfd_stats_event event)
 {
 	int rc = 0;
+
+	mutex_lock(&stats->mutex);
 	switch (event) {
 	case WFD_STAT_EVENT_CLIENT_QUEUE:
 		stats->v4l2_buf_count++;
@@ -193,6 +196,7 @@
 		rc = -ENOTSUPP;
 	}
 
+	mutex_unlock(&stats->mutex);
 	return rc;
 }
 
diff --git a/drivers/media/video/msm_wfd/wfd-util.h b/drivers/media/video/msm_wfd/wfd-util.h
index 2fe7360..0a2d50c 100644
--- a/drivers/media/video/msm_wfd/wfd-util.h
+++ b/drivers/media/video/msm_wfd/wfd-util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -14,6 +14,7 @@
 #include <linux/debugfs.h>
 #include <linux/list.h>
 #include <linux/ktime.h>
+#include <linux/mutex.h>
 
 #ifndef _WFD_UTIL_H_
 #define _WFD_UTIL_H_
@@ -34,6 +35,8 @@
 };
 
 struct wfd_stats {
+	struct mutex mutex;
+
 	/* Output Buffers */
 	uint32_t v4l2_buf_count;
 
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
index e8d9e04..8152a05 100644
--- a/drivers/media/video/vcap_v4l2.c
+++ b/drivers/media/video/vcap_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/vcap_vc.c b/drivers/media/video/vcap_vc.c
index 62cc306..8d4f7d0 100644
--- a/drivers/media/video/vcap_vc.c
+++ b/drivers/media/video/vcap_vc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/vcap_vc.h b/drivers/media/video/vcap_vc.h
index 792fb14..887fdc4 100644
--- a/drivers/media/video/vcap_vc.h
+++ b/drivers/media/video/vcap_vc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/vcap_vp.c b/drivers/media/video/vcap_vp.c
index d8d06dc..ae90424 100644
--- a/drivers/media/video/vcap_vp.c
+++ b/drivers/media/video/vcap_vp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/vcap_vp.h b/drivers/media/video/vcap_vp.h
index b2b00e9..4dc2cfb 100644
--- a/drivers/media/video/vcap_vp.h
+++ b/drivers/media/video/vcap_vp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/media/video/videobuf-msm-mem.c b/drivers/media/video/videobuf-msm-mem.c
index 5646f9f..9e2cc22 100644
--- a/drivers/media/video/videobuf-msm-mem.c
+++ b/drivers/media/video/videobuf-msm-mem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * Based on videobuf-dma-contig.c,
  * (c) 2008 Magnus Damm
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index 56d4bef..6794d75 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * Based on videobuf-dma-contig.c,
  * (c) 2008 Magnus Damm
diff --git a/drivers/mfd/marimba-codec.c b/drivers/mfd/marimba-codec.c
index 6416e0a..2ba251c 100644
--- a/drivers/mfd/marimba-codec.c
+++ b/drivers/mfd/marimba-codec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/mfd/marimba-core.c b/drivers/mfd/marimba-core.c
index 70ec2ec..1db7eaa 100644
--- a/drivers/mfd/marimba-core.c
+++ b/drivers/mfd/marimba-core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
@@ -76,12 +76,16 @@
 	rc = marimba_read_bit_mask(marimba, 0x00,  &bahama_version, 1, 0x1F);
 	if (rc < 0)
 		return rc;
+	pr_debug("%s: Bahama version: 0x%x\n", __func__, bahama_version);
 	switch (bahama_version) {
 	case 0x08: /* varient of bahama v1 */
 	case 0x10:
 	case 0x00:
 		return BAHAMA_VER_1_0;
 	case 0x09: /* variant of bahama v2 */
+	case 0x0a: /* variant of bahama v2.1 */
+	/* Falling through because initialization */
+	/* and configuration for 2.0 and 2.1 are same */
 		return BAHAMA_VER_2_0;
 	default:
 		return BAHAMA_VER_UNSUPPORTED;
diff --git a/drivers/mfd/marimba-tsadc.c b/drivers/mfd/marimba-tsadc.c
index 32b93e1..c933b48 100644
--- a/drivers/mfd/marimba-tsadc.c
+++ b/drivers/mfd/marimba-tsadc.c
@@ -1,7 +1,7 @@
 /*
  * Marimba TSADC driver.
  *
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/mfd/msm-adie-codec.c b/drivers/mfd/msm-adie-codec.c
index d9414ed..b9e317e 100644
--- a/drivers/mfd/msm-adie-codec.c
+++ b/drivers/mfd/msm-adie-codec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pm8018-core.c b/drivers/mfd/pm8018-core.c
index a91152f..ab45738 100644
--- a/drivers/mfd/pm8018-core.c
+++ b/drivers/mfd/pm8018-core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pm8038-core.c b/drivers/mfd/pm8038-core.c
index 479fc02..803920f 100644
--- a/drivers/mfd/pm8038-core.c
+++ b/drivers/mfd/pm8038-core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pm8821-core.c b/drivers/mfd/pm8821-core.c
index 1d3c927a..ae60bf9 100644
--- a/drivers/mfd/pm8821-core.c
+++ b/drivers/mfd/pm8821-core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -29,6 +29,9 @@
 #define REG_MPP_BASE		0x050
 #define REG_IRQ_BASE		0x100
 
+#define REG_TEMP_ALARM_CTRL	0x01B
+#define REG_TEMP_ALARM_PWM	0x09B
+
 #define PM8821_VERSION_MASK	0xFFF0
 #define PM8821_VERSION_VALUE	0x0BF0
 #define PM8821_REVISION_MASK	0x000F
@@ -142,6 +145,29 @@
 	.pdata_size	= sizeof("pm8821-dbg"),
 };
 
+static const struct resource thermal_alarm_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("pm8821_tempstat_irq", PM8821_TEMPSTAT_IRQ),
+	SINGLE_IRQ_RESOURCE("pm8821_overtemp_irq", PM8821_OVERTEMP_IRQ),
+};
+
+static struct pm8xxx_tm_core_data thermal_alarm_cdata = {
+	.adc_type			= PM8XXX_TM_ADC_NONE,
+	.reg_addr_temp_alarm_ctrl	= REG_TEMP_ALARM_CTRL,
+	.reg_addr_temp_alarm_pwm	= REG_TEMP_ALARM_PWM,
+	.tm_name			= "pm8821_tz",
+	.irq_name_temp_stat		= "pm8821_tempstat_irq",
+	.irq_name_over_temp		= "pm8821_overtemp_irq",
+	.default_no_adc_temp		= 37000,
+};
+
+static struct mfd_cell thermal_alarm_cell __devinitdata = {
+	.name		= PM8XXX_TM_DEV_NAME,
+	.id		= 1,
+	.resources	= thermal_alarm_cell_resources,
+	.num_resources	= ARRAY_SIZE(thermal_alarm_cell_resources),
+	.platform_data	= &thermal_alarm_cdata,
+	.pdata_size	= sizeof(struct pm8xxx_tm_core_data),
+};
 
 static int __devinit
 pm8821_add_subdevices(const struct pm8821_platform_data *pdata,
@@ -183,6 +209,14 @@
 		goto bail;
 	}
 
+	ret = mfd_add_devices(pmic->dev, 0, &thermal_alarm_cell, 1, NULL,
+				irq_base);
+	if (ret) {
+		pr_err("Failed to add thermal alarm subdevice ret=%d\n",
+			ret);
+		goto bail;
+	}
+
 	return 0;
 bail:
 	if (pmic->irq_chip) {
diff --git a/drivers/mfd/pm8821-irq.c b/drivers/mfd/pm8821-irq.c
index ff68c08..201fab7 100644
--- a/drivers/mfd/pm8821-irq.c
+++ b/drivers/mfd/pm8821-irq.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 685bb32..088c756 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pm8xxx-batt-alarm.c b/drivers/mfd/pm8xxx-batt-alarm.c
index 1d30db9..88aab98 100644
--- a/drivers/mfd/pm8xxx-batt-alarm.c
+++ b/drivers/mfd/pm8xxx-batt-alarm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pm8xxx-debug.c b/drivers/mfd/pm8xxx-debug.c
index d450db3..b58b6fe 100644
--- a/drivers/mfd/pm8xxx-debug.c
+++ b/drivers/mfd/pm8xxx-debug.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pm8xxx-irq.c b/drivers/mfd/pm8xxx-irq.c
index cc156b3..999b53f 100644
--- a/drivers/mfd/pm8xxx-irq.c
+++ b/drivers/mfd/pm8xxx-irq.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index 6bb1441..59b4dd9 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pm8xxx-pwm.c b/drivers/mfd/pm8xxx-pwm.c
index 022cfb6..6f6369b 100644
--- a/drivers/mfd/pm8xxx-pwm.c
+++ b/drivers/mfd/pm8xxx-pwm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pm8xxx-spk.c b/drivers/mfd/pm8xxx-spk.c
index a88c06c..27c8d3a 100644
--- a/drivers/mfd/pm8xxx-spk.c
+++ b/drivers/mfd/pm8xxx-spk.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pmic8058.c b/drivers/mfd/pmic8058.c
index 8f7ab2d..7ecd73e 100644
--- a/drivers/mfd/pmic8058.c
+++ b/drivers/mfd/pmic8058.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/drivers/mfd/pmic8901.c b/drivers/mfd/pmic8901.c
index 955258c..1ca5331 100644
--- a/drivers/mfd/pmic8901.c
+++ b/drivers/mfd/pmic8901.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/mfd/timpani-codec.c b/drivers/mfd/timpani-codec.c
index 1e0a839..164ffcc 100644
--- a/drivers/mfd/timpani-codec.c
+++ b/drivers/mfd/timpani-codec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/mfd/tps65023.c b/drivers/mfd/tps65023.c
index 318692f..546aded 100644
--- a/drivers/mfd/tps65023.c
+++ b/drivers/mfd/tps65023.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index e7e11d0..6152bc2 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/mfd/wcd9xxx-irq.c b/drivers/mfd/wcd9xxx-irq.c
index 68c4557..a5f9fad 100644
--- a/drivers/mfd/wcd9xxx-irq.c
+++ b/drivers/mfd/wcd9xxx-irq.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -151,21 +151,35 @@
 }
 EXPORT_SYMBOL_GPL(wcd9xxx_unlock_sleep);
 
+void wcd9xxx_nested_irq_lock(struct wcd9xxx *wcd9xxx)
+{
+	mutex_lock(&wcd9xxx->nested_irq_lock);
+}
+
+void wcd9xxx_nested_irq_unlock(struct wcd9xxx *wcd9xxx)
+{
+	mutex_unlock(&wcd9xxx->nested_irq_lock);
+}
+
 static void wcd9xxx_irq_dispatch(struct wcd9xxx *wcd9xxx, int irqbit)
 {
 	if ((irqbit <= TABLA_IRQ_MBHC_INSERTION) &&
 	    (irqbit >= TABLA_IRQ_MBHC_REMOVAL)) {
+                wcd9xxx_nested_irq_lock(wcd9xxx);
 		wcd9xxx_reg_write(wcd9xxx, TABLA_A_INTR_CLEAR0 +
 				  BIT_BYTE(irqbit), BYTE_BIT_MASK(irqbit));
 		if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
 			wcd9xxx_reg_write(wcd9xxx, TABLA_A_INTR_MODE, 0x02);
 		handle_nested_irq(wcd9xxx->irq_base + irqbit);
+		wcd9xxx_nested_irq_unlock(wcd9xxx);
 	} else {
+		wcd9xxx_nested_irq_lock(wcd9xxx);
 		handle_nested_irq(wcd9xxx->irq_base + irqbit);
 		wcd9xxx_reg_write(wcd9xxx, TABLA_A_INTR_CLEAR0 +
 				  BIT_BYTE(irqbit), BYTE_BIT_MASK(irqbit));
 		if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
 			wcd9xxx_reg_write(wcd9xxx, TABLA_A_INTR_MODE, 0x02);
+		wcd9xxx_nested_irq_unlock(wcd9xxx);
 	}
 }
 
@@ -223,6 +237,7 @@
 	unsigned int i, cur_irq;
 
 	mutex_init(&wcd9xxx->irq_lock);
+	mutex_init(&wcd9xxx->nested_irq_lock);
 
 	if (!wcd9xxx->irq) {
 		dev_warn(wcd9xxx->dev,
@@ -235,6 +250,9 @@
 		dev_err(wcd9xxx->dev,
 			"No interrupt base specified, no interrupts\n");
 		return 0;
+		mutex_destroy(&wcd9xxx->nested_irq_lock);
+		mutex_destroy(&wcd9xxx->irq_lock);
+		mutex_destroy(&wcd9xxx->nested_irq_lock);
 	}
 	/* Mask the individual interrupt sources */
 	for (i = 0, cur_irq = wcd9xxx->irq_base; i < TABLA_NUM_IRQS; i++,
@@ -294,8 +312,10 @@
 			free_irq(wcd9xxx->irq, wcd9xxx);
 	}
 
-	if (ret)
+	if (ret) {
 		mutex_destroy(&wcd9xxx->irq_lock);
+		mutex_destroy(&wcd9xxx->nested_irq_lock);
+	}
 
 	return ret;
 }
@@ -308,4 +328,5 @@
 		device_init_wakeup(wcd9xxx->dev, 0);
 	}
 	mutex_destroy(&wcd9xxx->irq_lock);
+	mutex_destroy(&wcd9xxx->nested_irq_lock);
 }
diff --git a/drivers/mfd/wcd9xxx-slimslave.c b/drivers/mfd/wcd9xxx-slimslave.c
index b4cf435..e001fae 100644
--- a/drivers/mfd/wcd9xxx-slimslave.c
+++ b/drivers/mfd/wcd9xxx-slimslave.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -299,7 +299,30 @@
 
 	/* Configure slave interface device */
 	pr_debug("%s: ch_cnt[%d] rate=%d\n", __func__, ch_cnt, rate);
-
+	/* Calculate the payload for shared channels */
+	for (i = 0; i < ch_cnt; i++) {
+		slave_port_id = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset);
+		if ((slave_port_id > sh_ch.num_rx_slave_port)) {
+			pr_err("Slimbus: invalid slave port id: %d",
+			       slave_port_id);
+			ret = -EINVAL;
+			goto err;
+		}
+		slave_port_id += sh_ch.rx_port_start_offset;
+		/* look for the valid port range and calculate the
+		 * payload accordingly
+		 */
+		if ((slave_port_id > sh_ch.pgd_tx_port_ch_1_end_port_id) &&
+		    (slave_port_id <= sh_ch.port_ch_0_end_port_id)) {
+			payload_rx = payload_rx |
+				(1 << (slave_port_id -
+				      sh_ch.port_ch_0_start_port_id));
+		} else {
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+	/* Set Payload and Watermark for channels */
 	for (i = 0; i < ch_cnt; i++) {
 		idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset);
 		ch_h[i] = rx[idx].ch_h;
@@ -315,26 +338,13 @@
 		}
 		slave_port_id += sh_ch.rx_port_start_offset;
 		pr_debug("%s: slave_port_id %d\n", __func__, slave_port_id);
-		/* look for the valid port range and chose the
-		 * payload accordingly
-		 */
-		if ((slave_port_id > sh_ch.pgd_tx_port_ch_1_end_port_id) &&
-		    (slave_port_id <= sh_ch.port_ch_0_end_port_id)) {
-			payload_rx = payload_rx |
-				(1 << (slave_port_id -
-				      sh_ch.port_ch_0_start_port_id));
-		} else {
-			ret = -EINVAL;
-			goto err;
-		}
 
 		multi_chan_cfg_reg_addr =
 		    SB_PGD_RX_PORT_MULTI_CHANNEL_0(sh_ch.rx_port_ch_reg_base,
 						   idx);
-		pr_debug("%s: multi_chan_cfg_reg_addr 0x%x\n", __func__,
-			 multi_chan_cfg_reg_addr);
-
-		/* write to interface device */
+		pr_debug("%s: multi_chan_cfg_reg_addr 0x%x\t payload 0x%x\n",
+			 __func__, multi_chan_cfg_reg_addr, payload_rx);
+		/* write payload to interface device */
 		ret = wcd9xxx_interface_reg_write(wcd9xxx,
 						  multi_chan_cfg_reg_addr,
 						  payload_rx);
@@ -418,21 +428,17 @@
 	struct slim_ch prop;
 
 	pr_debug("%s: ch_cnt[%d] rate[%d]\n", __func__, ch_cnt, rate);
+	/* Calculate the payload for shared channels */
 	for (i = 0; i < ch_cnt; i++) {
-		idx = (ch_num[i] - BASE_CH_NUM);
-		ch_h[i] = tx[idx].ch_h;
-		sph[i] = tx[idx].sph;
-		slave_port_id = idx;
-		pr_debug("%s: idx %d, ch_h %d, sph %d, slave_port_id %d\n",
-			 __func__, idx, ch_h[i], sph[i], slave_port_id);
+		slave_port_id = (ch_num[i] - BASE_CH_NUM);
 		if (slave_port_id > sh_ch.number_of_tx_slave_dev_ports) {
 			pr_err("SLIMbus: invalid slave port id: %d",
 			       slave_port_id);
 			ret = -EINVAL;
 			goto err;
 		}
-		/* look for the valid port range and chose the
-		 *  payload accordingly
+		/* look for the valid port range and calculate the
+		 * payload accordingly
 		 */
 		if (slave_port_id <=
 		    SB_PGD_TX_PORT_MULTI_CHANNEL_0_END_PORT_ID) {
@@ -448,11 +454,26 @@
 			ret = -EINVAL;
 			goto err;
 		}
+	}
+	/* Set Payload and Watermark for channels */
+	for (i = 0; i < ch_cnt; i++) {
+		idx = (ch_num[i] - BASE_CH_NUM);
+		ch_h[i] = tx[idx].ch_h;
+		sph[i] = tx[idx].sph;
+		slave_port_id = idx;
+		pr_debug("%s: idx %d, ch_h %d, sph %d, slave_port_id %d\n",
+			 __func__, idx, ch_h[i], sph[i], slave_port_id);
+		if (slave_port_id > sh_ch.number_of_tx_slave_dev_ports) {
+			pr_err("SLIMbus: invalid slave port id: %d",
+			       slave_port_id);
+			ret = -EINVAL;
+			goto err;
+		}
 		multi_chan_cfg_reg_addr =
 		    SB_PGD_TX_PORT_MULTI_CHANNEL_0(slave_port_id);
-		pr_debug("%s: multi_chan_cfg_reg_addr 0x%x\n", __func__,
-			 multi_chan_cfg_reg_addr);
-		/* write to interface device */
+		pr_debug("%s: multi_chan_cfg_reg_addr 0x%x\t payload 0x%x\n",
+			 __func__, multi_chan_cfg_reg_addr, payload_tx_0);
+		/* write payload to interface device */
 		ret = wcd9xxx_interface_reg_write(wcd9xxx,
 				multi_chan_cfg_reg_addr,
 				payload_tx_0);
@@ -464,6 +485,8 @@
 		}
 		multi_chan_cfg_reg_addr =
 		    SB_PGD_TX_PORT_MULTI_CHANNEL_1(slave_port_id);
+		pr_debug("%s: multi_chan_cfg_reg_addr 0x%x\t payload 0x%x\n",
+			 __func__, multi_chan_cfg_reg_addr, payload_tx_1);
 		/* ports 8,9 */
 		ret = wcd9xxx_interface_reg_write(wcd9xxx,
 						  multi_chan_cfg_reg_addr,
diff --git a/drivers/misc/isa1200.c b/drivers/misc/isa1200.c
index 6c3e787..c6d08d1 100644
--- a/drivers/misc/isa1200.c
+++ b/drivers/misc/isa1200.c
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2009 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
- *  Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2010-2013, The Linux Foundation. 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
@@ -23,6 +23,7 @@
 #include <linux/clk.h>
 #include <linux/i2c/isa1200.h>
 #include "../staging/android/timed_output.h"
+#include <linux/of_gpio.h>
 
 #define ISA1200_HCTRL0		0x30
 #define ISA1200_HCTRL1		0x31
@@ -42,7 +43,7 @@
 	struct hrtimer timer;
 	struct timed_output_dev dev;
 	struct work_struct work;
-	spinlock_t lock;
+	struct mutex lock;
 	unsigned int enable;
 	unsigned int period_ns;
 	bool is_len_gpio_valid;
@@ -121,7 +122,7 @@
 
 			/* vote for clock */
 			if (haptic->pdata->need_pwm_clk && !haptic->clk_on) {
-				rc = clk_enable(haptic->pwm_clk);
+				rc = clk_prepare_enable(haptic->pwm_clk);
 				if (rc < 0) {
 					pr_err("%s: clk enable failed\n",
 								__func__);
@@ -163,7 +164,7 @@
 
 			/* de-vote clock */
 			if (haptic->pdata->need_pwm_clk && haptic->clk_on) {
-				clk_disable(haptic->pwm_clk);
+				clk_disable_unprepare(haptic->pwm_clk);
 				haptic->clk_on = false;
 			}
 			/* check for board specific clk callback */
@@ -180,7 +181,7 @@
 
 dis_clk:
 	if (haptic->pdata->need_pwm_clk && haptic->clk_on) {
-		clk_disable(haptic->pwm_clk);
+		clk_disable_unprepare(haptic->pwm_clk);
 		haptic->clk_on = false;
 	}
 
@@ -216,9 +217,8 @@
 {
 	struct isa1200_chip *haptic = container_of(dev, struct isa1200_chip,
 					dev);
-	unsigned long flags;
 
-	spin_lock_irqsave(&haptic->lock, flags);
+	mutex_lock(&haptic->lock);
 	hrtimer_cancel(&haptic->timer);
 	if (value == 0)
 		haptic->enable = 0;
@@ -230,7 +230,7 @@
 			ktime_set(value / 1000, (value % 1000) * 1000000),
 			HRTIMER_MODE_REL);
 	}
-	spin_unlock_irqrestore(&haptic->lock, flags);
+	mutex_unlock(&haptic->lock);
 	schedule_work(&haptic->work);
 }
 
@@ -407,10 +407,10 @@
 
 	for (i = 0; i < num_reg; i++) {
 		haptic->regs[i] = regulator_get(&haptic->client->dev,
-							reg_info[i].name);
+						reg_info[i].name);
 		if (IS_ERR(haptic->regs[i])) {
 			rc = PTR_ERR(haptic->regs[i]);
-			pr_err("%s:regulator get failed(%d)\n",	__func__, rc);
+			pr_err("%s:regulator get failed(%d)\n", __func__, rc);
 			goto put_regs;
 		}
 
@@ -439,6 +439,138 @@
 	return rc;
 }
 
+#ifdef CONFIG_OF
+static int isa1200_parse_dt(struct device *dev,
+			struct isa1200_platform_data *pdata)
+{
+	struct device_node *temp, *np = dev->of_node;
+	struct isa1200_regulator *reg_info;
+	enum of_gpio_flags hap_en_flags = OF_GPIO_ACTIVE_LOW;
+	enum of_gpio_flags hap_len_flags = OF_GPIO_ACTIVE_LOW;
+	int rc = 0;
+	u32 temp_val;
+	const char *temp_string;
+
+	rc = of_property_read_string(np, "label", &pdata->name);
+	if (rc) {
+		dev_err(dev, "Unable to read device name\n");
+		return rc;
+	}
+
+	pdata->chip_en = of_property_read_bool(np, "imagis,chip-en");
+	pdata->ext_clk_en = of_property_read_bool(np, "imagis,ext-clk-en");
+	pdata->is_erm = of_property_read_bool(np, "imagis,is-erm");
+	pdata->overdrive_high =
+		of_property_read_bool(np, "imagis,overdrive-high");
+	pdata->overdrive_en = of_property_read_bool(np, "imagis,overdrive-en");
+	pdata->smart_en = of_property_read_bool(np, "imagis,smart-en");
+	pdata->need_pwm_clk = of_property_read_bool(np, "imagis,need-pwm-clk");
+
+	pdata->hap_en_gpio = of_get_named_gpio_flags(np,
+				"imagis,hap-en-gpio", 0, &hap_en_flags);
+	pdata->hap_len_gpio = of_get_named_gpio_flags(np,
+				"imagis,hap-len-gpio", 0, &hap_len_flags);
+
+	rc = of_property_read_u32(np, "imagis,max-timeout",
+				&pdata->max_timeout);
+	if (rc) {
+		dev_err(dev, "Unable to read max timeout\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "imagis,pwm-div", &pdata->pwm_fd.pwm_div);
+	if (rc && (rc != -EINVAL)) {
+		dev_err(dev, "Unable to read pwm division\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "imagis,pwm-freq",
+			&pdata->pwm_fd.pwm_freq);
+	if (rc && (rc != -EINVAL)) {
+		dev_err(dev, "Unable to read pwm frequency\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "imagis,pwm-ch-id", &pdata->pwm_ch_id);
+	if (rc && (rc != -EINVAL)) {
+		dev_err(dev, "Unable to read pwm channel id\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "imagis,mode-ctrl", &pdata->mode_ctrl);
+	if (rc) {
+		dev_err(dev, "Unable to read control mode\n");
+		return rc;
+	}
+
+	rc = of_property_read_u32(np, "imagis,duty", &pdata->duty);
+	if (rc && (rc != -EINVAL)) {
+		dev_err(dev, "Unable to read duty cycle\n");
+		return rc;
+	}
+
+	pdata->num_regulators = 0;
+	temp = NULL;
+	while ((temp = of_get_next_child(np, temp)))
+		pdata->num_regulators++;
+
+	if (!pdata->num_regulators)
+		return 0;
+
+	reg_info = devm_kzalloc(dev, pdata->num_regulators *
+				sizeof(struct isa1200_regulator), GFP_KERNEL);
+	if (!reg_info)
+		return -ENOMEM;
+
+	pdata->regulator_info = reg_info;
+
+	for_each_child_of_node(np, temp) {
+		rc = of_property_read_string(temp,
+			"regulator-name", &temp_string);
+		if (rc) {
+			dev_err(dev, "Unable to read regulator name\n");
+			return rc;
+		} else
+			reg_info->name = temp_string;
+
+		rc = of_property_read_u32(temp, "regulator-max-microvolt",
+			&temp_val);
+		if (rc) {
+			dev_err(dev, "Unable to read max uV\n");
+			return rc;
+		} else
+			reg_info->max_uV = temp_val;
+
+		rc = of_property_read_u32(temp, "regulator-min-microvolt",
+			&temp_val);
+		if (rc) {
+			dev_err(dev, "Unable to read min uV\n");
+			return rc;
+		} else
+			reg_info->min_uV = temp_val;
+
+		rc = of_property_read_u32(temp, "regulator-max-microamp",
+			&temp_val);
+		if (rc) {
+			dev_err(dev, "Unable to read load uA\n");
+			return rc;
+		} else
+			reg_info->load_uA = temp_val;
+
+		reg_info++;
+	}
+
+	return 0;
+}
+#else
+static int isa1200_parse_dt(struct device *dev,
+		struct isa1200_platform_data *pdata)
+{
+	return -ENODEV;
+}
+#endif
+
+
 static int __devinit isa1200_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -453,7 +585,22 @@
 		return -EIO;
 	}
 
-	pdata = client->dev.platform_data;
+	if (client->dev.of_node) {
+		pdata = devm_kzalloc(&client->dev,
+			sizeof(struct isa1200_platform_data), GFP_KERNEL);
+		if (!pdata) {
+			dev_err(&client->dev, "Failed to allocate memory\n");
+			return -ENOMEM;
+		}
+
+		ret = isa1200_parse_dt(&client->dev, pdata);
+		if (ret) {
+			dev_err(&client->dev, "Parsing DT failed(%d)", ret);
+			return ret;
+		}
+	} else
+		pdata = client->dev.platform_data;
+
 	if (!pdata) {
 		dev_err(&client->dev, "%s: no platform data\n", __func__);
 		return -EINVAL;
@@ -501,7 +648,7 @@
 		}
 	}
 
-	spin_lock_init(&haptic->lock);
+	mutex_init(&haptic->lock);
 	INIT_WORK(&haptic->work, isa1200_chip_work);
 	haptic->clk_on = false;
 
@@ -591,6 +738,7 @@
 hen_gpio_fail:
 	timed_output_dev_unregister(&haptic->dev);
 timed_reg_fail:
+	mutex_destroy(&haptic->lock);
 	if (pdata->power_on)
 		pdata->power_on(0);
 pwr_up_fail:
@@ -637,6 +785,9 @@
 				ISA1200_HCTRL1_RESET);
 
 
+	/* destroy mutex */
+	mutex_destroy(&haptic->lock);
+
 	/* power-off the chip */
 	if (haptic->pdata->regulator_info) {
 		isa1200_reg_power(haptic, false);
@@ -711,10 +862,19 @@
 	{ },
 };
 MODULE_DEVICE_TABLE(i2c, isa1200_id);
+#ifdef CONFIG_OF
+static struct of_device_id isa1200_match_table[] = {
+	{ .compatible = "imagis,isa1200",},
+	{ },
+};
+#else
+#define isa1200_match_table NULL
+#endif
 
 static struct i2c_driver isa1200_driver = {
 	.driver	= {
 		.name	= "isa1200",
+		.of_match_table = isa1200_match_table,
 	},
 	.probe		= isa1200_probe,
 	.remove		= __devexit_p(isa1200_remove),
diff --git a/drivers/misc/msm_migrate_pages.c b/drivers/misc/msm_migrate_pages.c
index 6dcdd02..c4aa1f8 100644
--- a/drivers/misc/msm_migrate_pages.c
+++ b/drivers/misc/msm_migrate_pages.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/misc/pm8xxx-nfc.c b/drivers/misc/pm8xxx-nfc.c
index 1aaa3e3..eeb3e2c 100644
--- a/drivers/misc/pm8xxx-nfc.c
+++ b/drivers/misc/pm8xxx-nfc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010,2011 The Linux Foundation. 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 and
diff --git a/drivers/misc/pm8xxx-upl.c b/drivers/misc/pm8xxx-upl.c
index d3d9746f..5a1b36f 100644
--- a/drivers/misc/pm8xxx-upl.c
+++ b/drivers/misc/pm8xxx-upl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010,2011 The Linux Foundation. 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 and
diff --git a/drivers/misc/pm8xxx-vibrator.c b/drivers/misc/pm8xxx-vibrator.c
index 62e7b45..bfe5b3c 100644
--- a/drivers/misc/pm8xxx-vibrator.c
+++ b/drivers/misc/pm8xxx-vibrator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/misc/pmem.c b/drivers/misc/pmem.c
index 0ab5b69..e91db7a 100644
--- a/drivers/misc/pmem.c
+++ b/drivers/misc/pmem.c
@@ -1,7 +1,7 @@
 /* drivers/android/pmem.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/misc/pmic8058-pwm.c b/drivers/misc/pmic8058-pwm.c
index 33407b7..996a81e 100644
--- a/drivers/misc/pmic8058-pwm.c
+++ b/drivers/misc/pmic8058-pwm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/misc/pmic8058-xoadc.c b/drivers/misc/pmic8058-xoadc.c
index 3452672..bdcaa4d 100644
--- a/drivers/misc/pmic8058-xoadc.c
+++ b/drivers/misc/pmic8058-xoadc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/misc/qfp_fuse.c b/drivers/misc/qfp_fuse.c
index 341e5b2..3a088dc 100644
--- a/drivers/misc/qfp_fuse.c
+++ b/drivers/misc/qfp_fuse.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 188457c..ac67c9d 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -2,7 +2,7 @@
 
 /*Qualcomm Secure Execution Environment Communicator (QSEECOM) driver
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
@@ -718,6 +718,9 @@
 			&resp, sizeof(resp));
 		if (ret) {
 			pr_err("scm_call to load app failed\n");
+			if (!IS_ERR_OR_NULL(ihandle))
+				ion_free(qseecom.ion_clnt, ihandle);
+			qsee_disable_clock_vote(CLK_SFPB);
 			return -EINVAL;
 		}
 
@@ -1474,6 +1477,7 @@
 
 		if (ret < 0) {
 			kfree(*handle);
+			kfree(data);
 			*handle = NULL;
 			return ret;
 		}
@@ -1483,6 +1487,9 @@
 		entry = kmalloc(sizeof(*entry), GFP_KERNEL);
 		if (!entry) {
 			pr_err("kmalloc failed\n");
+			kfree(data);
+			kfree(*handle);
+			*handle = NULL;
 			return -ENOMEM;
 		}
 		entry->app_id = ret;
@@ -1524,8 +1531,8 @@
 int qseecom_shutdown_app(struct qseecom_handle **handle)
 {
 	int ret = -EINVAL;
-	struct qseecom_dev_handle *data =
-			(struct qseecom_dev_handle *) ((*handle)->dev);
+	struct qseecom_dev_handle *data;
+
 	struct qseecom_registered_kclient_list *kclient = NULL;
 	unsigned long flags = 0;
 	bool found_handle = false;
@@ -1534,11 +1541,11 @@
 		pr_err("This functionality is UNSUPPORTED in version 1.3\n");
 		return -EINVAL;
 	}
-	if (*handle == NULL) {
+	if ((handle == NULL)  || (*handle == NULL)) {
 		pr_err("Handle is not initialized\n");
 		return -EINVAL;
 	}
-
+	data =	(struct qseecom_dev_handle *) ((*handle)->dev);
 	spin_lock_irqsave(&qseecom.registered_kclient_list_lock, flags);
 	list_for_each_entry(kclient, &qseecom.registered_kclient_list_head,
 				list) {
diff --git a/drivers/misc/qseecom_legacy.h b/drivers/misc/qseecom_legacy.h
index 66f87e9..35d6e06 100644
--- a/drivers/misc/qseecom_legacy.h
+++ b/drivers/misc/qseecom_legacy.h
@@ -1,6 +1,6 @@
 /* Qualcomm Secure Execution Environment Communicator (QSEECOM) driver
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/misc/smsc_hub.c b/drivers/misc/smsc_hub.c
index b11474a..0e5b86d 100644
--- a/drivers/misc/smsc_hub.c
+++ b/drivers/misc/smsc_hub.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/misc/tsif_chrdev.c b/drivers/misc/tsif_chrdev.c
index 122c7ed..a53bc9a 100644
--- a/drivers/misc/tsif_chrdev.c
+++ b/drivers/misc/tsif_chrdev.c
@@ -4,7 +4,7 @@
  * Character device that, being read
  * returns stream of TSIF packets.
  *
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights
+ * Copyright (c) 2009-2011, The Linux Foundation. All rights
  * reserved.
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index 0715d6d..eaf795b 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.c
@@ -41,11 +41,15 @@
 #include <mach/dma.h>
 #include <mach/msm_tspp.h>
 #include <linux/debugfs.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/string.h>
 
 /*
  * General defines
  */
 #define TSPP_TSIF_INSTANCES            2
+#define TSPP_GPIOS_PER_TSIF            4
 #define TSPP_FILTER_TABLES             3
 #define TSPP_MAX_DEVICES               1
 #define TSPP_NUM_CHANNELS              16
@@ -647,45 +651,26 @@
 }
 
 /*** GPIO functions ***/
-static void tspp_gpios_free(const struct msm_gpio *table, int size)
-{
-	int i;
-	const struct msm_gpio *g;
-	for (i = size-1; i >= 0; i--) {
-		g = table + i;
-		gpio_free(GPIO_PIN(g->gpio_cfg));
-	}
-}
-
-static int tspp_gpios_request(const struct msm_gpio *table, int size)
-{
-	int rc;
-	int i;
-	const struct msm_gpio *g;
-	for (i = 0; i < size; i++) {
-		g = table + i;
-		rc = gpio_request(GPIO_PIN(g->gpio_cfg), g->label);
-		if (rc) {
-			pr_err("tspp: gpio_request(%d) <%s> failed: %d\n",
-			       GPIO_PIN(g->gpio_cfg), g->label ?: "?", rc);
-			goto err;
-		}
-	}
-	return 0;
-err:
-	tspp_gpios_free(table, i);
-	return rc;
-}
-
-static int tspp_gpios_disable(const struct msm_gpio *table, int size)
+static int tspp_gpios_disable(const struct tspp_tsif_device *tsif_device,
+				const struct msm_gpio *table,
+				int size)
 {
 	int rc = 0;
 	int i;
 	const struct msm_gpio *g;
+
 	for (i = size-1; i >= 0; i--) {
 		int tmp;
 		g = table + i;
-		tmp = gpio_tlmm_config(g->gpio_cfg, GPIO_CFG_DISABLE);
+
+		/* don't use sync GPIO when not working in mode 2 */
+		if ((tsif_device->mode != TSPP_TSIF_MODE_2) &&
+			(strnstr(g->label, "sync", strlen(g->label)) != NULL))
+			continue;
+
+		tmp = gpio_tlmm_config(GPIO_CFG(GPIO_PIN(g->gpio_cfg),
+			0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+			GPIO_CFG_DISABLE);
 		if (tmp) {
 			pr_err("tspp_gpios_disable(0x%08x, GPIO_CFG_DISABLE) <%s> failed: %d\n",
 			       g->gpio_cfg, g->label ?: "?", rc);
@@ -701,13 +686,22 @@
 	return rc;
 }
 
-static int tspp_gpios_enable(const struct msm_gpio *table, int size)
+static int tspp_gpios_enable(const struct tspp_tsif_device *tsif_device,
+				const struct msm_gpio *table,
+				int size)
 {
 	int rc;
 	int i;
 	const struct msm_gpio *g;
+
 	for (i = 0; i < size; i++) {
 		g = table + i;
+
+		/* don't use sync GPIO when not working in mode 2 */
+		if ((tsif_device->mode != TSPP_TSIF_MODE_2) &&
+			(strnstr(g->label, "sync", strlen(g->label)) != NULL))
+			continue;
+
 		rc = gpio_tlmm_config(g->gpio_cfg, GPIO_CFG_ENABLE);
 		if (rc) {
 			pr_err("tspp: gpio_tlmm_config(0x%08x, GPIO_CFG_ENABLE) <%s> failed: %d\n",
@@ -721,44 +715,59 @@
 	}
 	return 0;
 err:
-	tspp_gpios_disable(table, i);
+	tspp_gpios_disable(tsif_device, table, i);
+
 	return rc;
 }
 
-static int tspp_gpios_request_enable(const struct msm_gpio *table, int size)
-{
-	int rc = tspp_gpios_request(table, size);
-	if (rc)
-		return rc;
-	rc = tspp_gpios_enable(table, size);
-	if (rc)
-		tspp_gpios_free(table, size);
-	return rc;
-}
 
-static void tspp_gpios_disable_free(const struct msm_gpio *table, int size)
+static int tspp_config_gpios(struct tspp_device *device,
+				enum tspp_source source,
+				int enable)
 {
-	tspp_gpios_disable(table, size);
-	tspp_gpios_free(table, size);
-}
+	const struct msm_gpio *table;
+	struct msm_tspp_platform_data *pdata = device->pdev->dev.platform_data;
+	int num_gpios = (pdata->num_gpios / TSPP_TSIF_INSTANCES);
+	int i = 0;
 
-static int tspp_start_gpios(struct tspp_device *device)
-{
-	struct msm_tspp_platform_data *pdata =
-		device->pdev->dev.platform_data;
-	return tspp_gpios_request_enable(pdata->gpios, pdata->num_gpios);
-}
+	if (num_gpios != TSPP_GPIOS_PER_TSIF) {
+		pr_err("tspp %s: unexpected number of GPIOs %d, expected %d\n",
+			__func__, num_gpios, TSPP_GPIOS_PER_TSIF);
+		return -EINVAL;
+	}
 
-static void tspp_stop_gpios(struct tspp_device *device)
-{
-	struct msm_tspp_platform_data *pdata =
-		device->pdev->dev.platform_data;
-	tspp_gpios_disable_free(pdata->gpios, pdata->num_gpios);
+	/*
+	 * Note: this code assumes that the GPIO definitions in the
+	 * pdata->gpios table are according to the TSIF instance number,
+	 * i.e., that TSIF0 GPIOs are defined first, then TSIF1 GPIOs etc.
+	 */
+	switch (source) {
+	case TSPP_SOURCE_TSIF0:
+		i = 0;
+		break;
+	case TSPP_SOURCE_TSIF1:
+		i = 1;
+		break;
+	default:
+		pr_err("tspp %s: invalid source\n", __func__);
+		return -EINVAL;
+	}
+
+	table = pdata->gpios + (i * num_gpios);
+	if (enable)
+		return tspp_gpios_enable(&device->tsif[i], table, num_gpios);
+	else
+		return tspp_gpios_disable(&device->tsif[i], table, num_gpios);
 }
 
 /*** Clock functions ***/
 static int tspp_clock_start(struct tspp_device *device)
 {
+	if (device == NULL) {
+		pr_err("tspp: Can't start clocks, invalid device\n");
+		return -EINVAL;
+	}
+
 	if (device->tsif_pclk && clk_prepare_enable(device->tsif_pclk) != 0) {
 		pr_err("tspp: Can't start pclk");
 		return -EBUSY;
@@ -776,11 +785,16 @@
 
 static void tspp_clock_stop(struct tspp_device *device)
 {
+	if (device == NULL) {
+		pr_err("tspp: Can't stop clocks, invalid device\n");
+		return;
+	}
+
 	if (device->tsif_pclk)
-		clk_disable(device->tsif_pclk);
+		clk_disable_unprepare(device->tsif_pclk);
 
 	if (device->tsif_ref_clk)
-		clk_disable(device->tsif_ref_clk);
+		clk_disable_unprepare(device->tsif_ref_clk);
 }
 
 /*** TSIF functions ***/
@@ -1306,26 +1320,38 @@
 
 	switch (source->source) {
 	case TSPP_SOURCE_TSIF0:
+		if (tspp_config_gpios(pdev, channel->src, 1) != 0) {
+			pr_err("tspp: error enabling tsif0 GPIOs\n");
+			return -EBUSY;
+		}
 		/* make sure TSIF0 is running & enabled */
 		if (tspp_start_tsif(&pdev->tsif[0]) != 0) {
 			pr_err("tspp: error starting tsif0");
 			return -EBUSY;
 		}
-		val = readl_relaxed(pdev->base + TSPP_CONTROL);
-		writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
-			pdev->base + TSPP_CONTROL);
-		wmb();
+		if (pdev->tsif[0].ref_count == 1) {
+			val = readl_relaxed(pdev->base + TSPP_CONTROL);
+			writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
+				pdev->base + TSPP_CONTROL);
+			wmb();
+		}
 		break;
 	case TSPP_SOURCE_TSIF1:
+		if (tspp_config_gpios(pdev, channel->src, 1) != 0) {
+			pr_err("tspp: error enabling tsif1 GPIOs\n");
+			return -EBUSY;
+		}
 		/* make sure TSIF1 is running & enabled */
 		if (tspp_start_tsif(&pdev->tsif[1]) != 0) {
 			pr_err("tspp: error starting tsif1");
 			return -EBUSY;
 		}
-		val = readl_relaxed(pdev->base + TSPP_CONTROL);
-		writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
-			pdev->base + TSPP_CONTROL);
-		wmb();
+		if (pdev->tsif[1].ref_count == 1) {
+			val = readl_relaxed(pdev->base + TSPP_CONTROL);
+			writel_relaxed(val & ~TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
+				pdev->base + TSPP_CONTROL);
+			wmb();
+		}
 		break;
 	case TSPP_SOURCE_MEM:
 		break;
@@ -1351,6 +1377,7 @@
 int tspp_close_stream(u32 dev, u32 channel_id)
 {
 	u32 val;
+	u32 prev_ref_count;
 	struct tspp_device *pdev;
 	struct tspp_channel *channel;
 
@@ -1367,17 +1394,30 @@
 
 	switch (channel->src) {
 	case TSPP_SOURCE_TSIF0:
+		prev_ref_count = pdev->tsif[0].ref_count;
 		tspp_stop_tsif(&pdev->tsif[0]);
-		val = readl_relaxed(pdev->base + TSPP_CONTROL);
-		writel_relaxed(val | TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
-			pdev->base + TSPP_CONTROL);
-		wmb();
+		if (tspp_config_gpios(pdev, channel->src, 0) != 0)
+			pr_err("tspp: error disabling tsif0 GPIOs\n");
+
+		if (prev_ref_count == 1) {
+			val = readl_relaxed(pdev->base + TSPP_CONTROL);
+			writel_relaxed(val | TSPP_CONTROL_TSP_TSIF0_SRC_DIS,
+				pdev->base + TSPP_CONTROL);
+			wmb();
+		}
 		break;
 	case TSPP_SOURCE_TSIF1:
+		prev_ref_count = pdev->tsif[1].ref_count;
 		tspp_stop_tsif(&pdev->tsif[1]);
-		val = readl_relaxed(pdev->base + TSPP_CONTROL);
-		writel_relaxed(val | TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
-			pdev->base + TSPP_CONTROL);
+		if (tspp_config_gpios(pdev, channel->src, 0) != 0)
+			pr_err("tspp: error disabling tsif0 GPIOs\n");
+
+		if (prev_ref_count == 1) {
+			val = readl_relaxed(pdev->base + TSPP_CONTROL);
+			writel_relaxed(val | TSPP_CONTROL_TSP_TSIF1_SRC_DIS,
+				pdev->base + TSPP_CONTROL);
+			wmb();
+		}
 		break;
 	case TSPP_SOURCE_MEM:
 		break;
@@ -1427,9 +1467,13 @@
 	event = &channel->event;
 
 	/* start the clocks if needed */
-	tspp_clock_start(pdev);
-	if (tspp_channels_in_use(pdev) == 0)
+	if (tspp_channels_in_use(pdev) == 0) {
+		rc = tspp_clock_start(pdev);
+		if (rc)
+			return rc;
+
 		wake_lock(&pdev->wake_lock);
+	}
 
 	/* mark it as used */
 	channel->used = 1;
@@ -1525,7 +1569,9 @@
 {
 	int i;
 	int id;
+	int table_idx;
 	u32 val;
+	unsigned long flags;
 
 	struct sps_connect *config;
 	struct tspp_device *pdev;
@@ -1546,6 +1592,15 @@
 	if (!channel->used)
 		return 0;
 
+	/*
+	 * Need to protect access to used and waiting fields, as they are
+	 * used by the tasklet which is invoked from interrupt context
+	 */
+	spin_lock_irqsave(&pdev->spinlock, flags);
+	channel->used = 0;
+	channel->waiting = NULL;
+	spin_unlock_irqrestore(&pdev->spinlock, flags);
+
 	if (channel->expiration_period_ms)
 		del_timer(&channel->expiration_timer);
 
@@ -1562,23 +1617,22 @@
 	wmb();
 
 	/* unregister all filters for this channel */
-	for (i = 0; i < TSPP_NUM_PRIORITIES; i++) {
-		struct tspp_pid_filter *tspp_filter =
-			&pdev->filters[channel->src]->filter[i];
-		id = FILTER_GET_PIPE_NUMBER0(tspp_filter);
-		if (id == channel->id) {
-			if (FILTER_HAS_ENCRYPTION(tspp_filter))
-				tspp_free_key_entry(
-					FILTER_GET_KEY_NUMBER(tspp_filter));
-			tspp_filter->config = 0;
-			tspp_filter->filter = 0;
+	for (table_idx = 0; table_idx < TSPP_FILTER_TABLES; table_idx++) {
+		for (i = 0; i < TSPP_NUM_PRIORITIES; i++) {
+			struct tspp_pid_filter *filter =
+				&pdev->filters[table_idx]->filter[i];
+			id = FILTER_GET_PIPE_NUMBER0(filter);
+			if (id == channel->id) {
+				if (FILTER_HAS_ENCRYPTION(filter))
+					tspp_free_key_entry(
+						FILTER_GET_KEY_NUMBER(filter));
+				filter->config = 0;
+				filter->filter = 0;
+			}
 		}
 	}
 	channel->filter_count = 0;
 
-	/* stop the stream */
-	tspp_close_stream(dev, channel->id);
-
 	/* disconnect the bam */
 	if (sps_disconnect(channel->pipe) != 0)
 		pr_warn("tspp: Error freeing sps endpoint (%i)", channel->id);
@@ -1600,13 +1654,14 @@
 	channel->buffer_count = 0;
 	channel->data = NULL;
 	channel->read = NULL;
-	channel->waiting = NULL;
 	channel->locked = NULL;
-	channel->used = 0;
 
-	if (tspp_channels_in_use(pdev) == 0)
+	if (tspp_channels_in_use(pdev) == 0) {
 		wake_unlock(&pdev->wake_lock);
-	tspp_clock_stop(pdev);
+		tspp_clock_stop(pdev);
+	}
+
+	pm_runtime_put(&pdev->pdev->dev);
 
 	return 0;
 }
@@ -2415,7 +2470,7 @@
 	channel = filp->private_data;
 	dev = channel->pdev->pdev->id;
 
-	if (!param1)
+	if ((param0 != TSPP_IOCTL_CLOSE_STREAM) && !param1)
 		return -EINVAL;
 
 	switch (param0) {
@@ -2482,6 +2537,9 @@
 			sizeof(struct tspp_buffer)) == 0)
 			rc = tspp_set_buffer_size(channel, &b);
 		break;
+	case TSPP_IOCTL_CLOSE_STREAM:
+		rc = tspp_close_stream(dev, channel->id);
+		break;
 	default:
 		pr_err("tspp: Unknown ioctl %i", param0);
 	}
@@ -2535,28 +2593,27 @@
 
 		debugfs_create_u32(
 			"stat_rx_chunks",
-			S_IRUGO|S_IWUGO,
+			S_IRUGO | S_IWUSR | S_IWGRP,
 			tsif_device->dent_tsif,
 			&tsif_device->stat_rx);
 
 		debugfs_create_u32(
 			"stat_overflow",
-			S_IRUGO|S_IWUGO,
+			S_IRUGO | S_IWUSR | S_IWGRP,
 			tsif_device->dent_tsif,
 			&tsif_device->stat_overflow);
 
 		debugfs_create_u32(
 			"stat_lost_sync",
-			S_IRUGO|S_IWUGO,
+			S_IRUGO | S_IWUSR | S_IWGRP,
 			tsif_device->dent_tsif,
 			&tsif_device->stat_lost_sync);
 
 		debugfs_create_u32(
 			"stat_timeout",
-			S_IRUGO|S_IWUGO,
+			S_IRUGO | S_IWUSR | S_IWGRP,
 			tsif_device->dent_tsif,
 			&tsif_device->stat_timeout);
-
 	}
 }
 
@@ -2603,6 +2660,137 @@
 	}
 }
 
+/* copy device-tree data to platfrom data struct */
+static __devinit struct msm_tspp_platform_data *
+msm_tspp_dt_to_pdata(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct msm_tspp_platform_data *data;
+	struct msm_gpio *gpios;
+	int i, rc;
+	int gpio;
+	u32 gpio_func;
+
+	/* Note: memory allocated by devm_kzalloc is freed automatically */
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		pr_err("tspp: Unable to allocate platform data\n");
+		return NULL;
+	}
+	rc = of_property_read_string(node, "qcom,tsif-pclk", &data->tsif_pclk);
+	if (rc) {
+		pr_err("tspp: Could not find tsif-pclk property, err = %d\n",
+			rc);
+		return NULL;
+	}
+	rc = of_property_read_string(node, "qcom,tsif-ref-clk",
+			&data->tsif_ref_clk);
+	if (rc) {
+		pr_err("tspp: Could not find tsif-ref-clk property, err = %d\n",
+			rc);
+		return NULL;
+	}
+
+	data->num_gpios = of_gpio_count(node);
+	if (data->num_gpios == 0) {
+		pr_err("tspp: Could not find GPIO definitions\n");
+		return NULL;
+	}
+	gpios = devm_kzalloc(&pdev->dev,
+			(data->num_gpios * sizeof(struct msm_gpio)),
+			GFP_KERNEL);
+	if (!gpios) {
+		pr_err("tspp: Unable to allocate memory for GPIOs table\n");
+		return NULL;
+	}
+	/* Assuming GPIO FUNC property is the same for all GPIOs */
+	if (of_property_read_u32(node, "qcom,gpios-func", &gpio_func)) {
+		pr_err("tspp: Could not find gpios-func property\n");
+		return NULL;
+	}
+	for (i = 0; i < data->num_gpios; i++) {
+		gpio = of_get_gpio(node, i);
+		gpios[i].gpio_cfg = GPIO_CFG(gpio, gpio_func,
+						GPIO_CFG_INPUT,
+						GPIO_CFG_PULL_DOWN,
+						GPIO_CFG_2MA);
+		rc = of_property_read_string_index(node, "qcom,gpio-names",
+						i, &gpios[i].label);
+		if (rc)
+			pr_warn("tspp: Could not find gpio-names property\n");
+	}
+
+	data->gpios = gpios;
+
+	return data;
+}
+
+static int msm_tspp_map_irqs(struct platform_device *pdev,
+				struct tspp_device *device)
+{
+	int rc;
+	int i;
+
+	/* get IRQ numbers from platform information */
+
+	/* map TSPP IRQ */
+	rc = platform_get_irq_byname(pdev, "TSIF_TSPP_IRQ");
+	if (rc > 0) {
+		device->tspp_irq = rc;
+		rc = request_irq(device->tspp_irq, tspp_isr, IRQF_SHARED,
+				 dev_name(&pdev->dev), device);
+		if (rc) {
+			dev_err(&pdev->dev,
+				"failed to request TSPP IRQ %d : %d",
+				device->tspp_irq, rc);
+			device->tspp_irq = 0;
+			return -EINVAL;
+		}
+	} else {
+		dev_err(&pdev->dev, "failed to get TSPP IRQ");
+		return -EINVAL;
+	}
+
+	/* map TSIF IRQs */
+	rc = platform_get_irq_byname(pdev, "TSIF0_IRQ");
+	if (rc > 0) {
+		device->tsif[0].tsif_irq = rc;
+	} else {
+		dev_err(&pdev->dev, "failed to get TSIF0 IRQ");
+		return -EINVAL;
+	}
+
+	rc = platform_get_irq_byname(pdev, "TSIF1_IRQ");
+	if (rc > 0) {
+		device->tsif[1].tsif_irq = rc;
+	} else {
+		dev_err(&pdev->dev, "failed to get TSIF1 IRQ");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
+		rc = request_irq(device->tsif[i].tsif_irq,
+				tsif_isr, IRQF_SHARED,
+				dev_name(&pdev->dev), &device->tsif[i]);
+		if (rc) {
+			dev_warn(&pdev->dev, "failed to request TSIF%d IRQ: %d",
+				i, rc);
+			device->tsif[i].tsif_irq = 0;
+		}
+	}
+
+	/* map BAM IRQ */
+	rc = platform_get_irq_byname(pdev, "TSIF_BAM_IRQ");
+	if (rc > 0) {
+		device->bam_irq = rc;
+	} else {
+		dev_err(&pdev->dev, "failed to get TSPP BAM IRQ");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int __devinit msm_tspp_probe(struct platform_device *pdev)
 {
 	int rc = -ENODEV;
@@ -2616,8 +2804,20 @@
 	struct resource *mem_bam;
 	struct tspp_channel *channel;
 
-	/* must have platform data */
-	data = pdev->dev.platform_data;
+	if (pdev->dev.of_node) {
+		/* get information from device tree */
+		data = msm_tspp_dt_to_pdata(pdev);
+		/* get device ID */
+		rc = of_property_read_u32(pdev->dev.of_node,
+					"cell-index", &pdev->id);
+		if (rc)
+			pdev->id = -1;
+
+		pdev->dev.platform_data = data;
+	} else {
+		/* must have platform data */
+		data = pdev->dev.platform_data;
+	}
 	if (!data) {
 		pr_err("tspp: Platform data not available");
 		rc = -EINVAL;
@@ -2666,7 +2866,8 @@
 	}
 
 	/* map I/O memory */
-	mem_tsif0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mem_tsif0 = platform_get_resource_byname(pdev,
+				IORESOURCE_MEM, "MSM_TSIF0_PHYS");
 	if (!mem_tsif0) {
 		pr_err("tspp: Missing tsif0 MEM resource");
 		rc = -ENXIO;
@@ -2679,7 +2880,8 @@
 		goto err_map_tsif0;
 	}
 
-	mem_tsif1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	mem_tsif1 = platform_get_resource_byname(pdev,
+				IORESOURCE_MEM, "MSM_TSIF1_PHYS");
 	if (!mem_tsif1) {
 		dev_err(&pdev->dev, "Missing tsif1 MEM resource");
 		rc = -ENXIO;
@@ -2692,7 +2894,8 @@
 		goto err_map_tsif1;
 	}
 
-	mem_tspp = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	mem_tspp = platform_get_resource_byname(pdev,
+				IORESOURCE_MEM, "MSM_TSPP_PHYS");
 	if (!mem_tspp) {
 		dev_err(&pdev->dev, "Missing MEM resource");
 		rc = -ENXIO;
@@ -2704,7 +2907,8 @@
 		goto err_map_dev;
 	}
 
-	mem_bam = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+	mem_bam = platform_get_resource_byname(pdev,
+				IORESOURCE_MEM, "MSM_TSPP_BAM_PHYS");
 	if (!mem_bam) {
 		pr_err("tspp: Missing bam MEM resource");
 		rc = -ENXIO;
@@ -2719,44 +2923,8 @@
 		goto err_map_bam;
 	}
 
-	/* map TSPP IRQ */
-	rc = platform_get_irq(pdev, 0);
-	if (rc > 0) {
-		device->tspp_irq = rc;
-		rc = request_irq(device->tspp_irq, tspp_isr, IRQF_SHARED,
-				 dev_name(&pdev->dev), device);
-		if (rc) {
-			dev_err(&pdev->dev, "failed to request IRQ %d : %d",
-				device->tspp_irq, rc);
-			goto err_irq;
-		}
-	} else {
-		dev_err(&pdev->dev, "failed to get tspp IRQ");
+	if (msm_tspp_map_irqs(pdev, device))
 		goto err_irq;
-	}
-
-	/* map TSIF IRQs */
-	device->tsif[0].tsif_irq = TSIF1_IRQ;
-	device->tsif[1].tsif_irq = TSIF2_IRQ;
-
-	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
-		rc = request_irq(device->tsif[i].tsif_irq,
-				tsif_isr, IRQF_SHARED,
-				dev_name(&pdev->dev), &device->tsif[i]);
-		if (rc) {
-			dev_warn(&pdev->dev, "failed to request TSIF%d IRQ: %d",
-				i, rc);
-			device->tsif[i].tsif_irq = 0;
-		}
-	}
-
-	/* BAM IRQ */
-	device->bam_irq = TSIF_BAM_IRQ;
-
-	/* GPIOs */
-	rc = tspp_start_gpios(device);
-	if (rc)
-		goto err_gpio;
 
 	/* power management */
 	pm_runtime_set_active(&pdev->dev);
@@ -2786,17 +2954,17 @@
 	device->bam_props.irq = device->bam_irq;
 	device->bam_props.manage = SPS_BAM_MGR_LOCAL;
 
+	if (tspp_clock_start(device) != 0) {
+		dev_err(&pdev->dev, "Can't start clocks");
+		goto err_clock;
+	}
+
 	if (sps_register_bam_device(&device->bam_props,
 		&device->bam_handle) != 0) {
 		pr_err("tspp: failed to register bam");
 		goto err_bam;
 	}
 
-	if (tspp_clock_start(device) != 0) {
-		dev_err(&pdev->dev, "Can't start clocks");
-		goto err_clock;
-	}
-
 	spin_lock_init(&device->spinlock);
 	tasklet_init(&device->tlet, tspp_sps_complete_tlet,
 			(unsigned long)device);
@@ -2805,7 +2973,11 @@
 	tspp_global_reset(device);
 
 	version = readl_relaxed(device->base + TSPP_VERSION);
-	if (version != 1)
+	/*
+	 * TSPP version can be bits [7:0] or alternatively,
+	 * TSPP major version is bits [31:28].
+	 */
+	if ((version != 0x1) && (((version >> 28) & 0xF) != 0x1))
 		pr_warn("tspp: unrecognized hw version=%i", version);
 
 	/* initialize the channels */
@@ -2825,21 +2997,27 @@
 	return 0;
 
 err_channel:
-	/* uninitialize channels */
+	/* un-initialize channels */
 	for (j = 0; j < i; j++) {
 		channel = &(device->channels[i]);
 		device_destroy(tspp_class, channel->cdev.dev);
 		cdev_del(&channel->cdev);
 	}
-err_clock:
+
 	sps_deregister_bam_device(device->bam_handle);
+err_clock:
 err_bam:
 	tspp_debugfs_exit(device);
 	for (i = 0; i < TSPP_TSIF_INSTANCES; i++)
 		tsif_debugfs_exit(&device->tsif[i]);
-err_gpio:
 err_irq:
-	tspp_stop_gpios(device);
+	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
+		if (device->tsif[i].tsif_irq)
+			free_irq(device->tsif[i].tsif_irq,  &device->tsif[i]);
+	}
+	if (device->tspp_irq)
+		free_irq(device->tspp_irq, device);
+
 	iounmap(device->bam_props.virt_addr);
 err_map_bam:
 err_res_bam:
@@ -2868,6 +3046,7 @@
 {
 	struct tspp_channel *channel;
 	u32 i;
+	int rc;
 
 	struct tspp_device *device = platform_get_drvdata(pdev);
 
@@ -2879,7 +3058,12 @@
 		cdev_del(&channel->cdev);
 	}
 
-	sps_deregister_bam_device(device->bam_handle);
+	/* de-registering BAM device requires clocks */
+	rc = tspp_clock_start(device);
+	if (rc == 0) {
+		sps_deregister_bam_device(device->bam_handle);
+		tspp_clock_stop(device);
+	}
 
 	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
 		tsif_debugfs_exit(&device->tsif[i]);
@@ -2889,7 +3073,6 @@
 
 	wake_lock_destroy(&device->wake_lock);
 	free_irq(device->tspp_irq, device);
-	tspp_stop_gpios(device);
 
 	iounmap(device->bam_props.virt_addr);
 	iounmap(device->base);
@@ -2903,7 +3086,7 @@
 		clk_put(device->tsif_pclk);
 
 	pm_runtime_disable(&pdev->dev);
-	pm_runtime_put(&pdev->dev);
+
 	kfree(device);
 
 	return 0;
@@ -2928,12 +3111,18 @@
 	.runtime_resume = tspp_runtime_resume,
 };
 
+static struct of_device_id msm_match_table[] = {
+	{.compatible = "qcom,msm_tspp"},
+	{}
+};
+
 static struct platform_driver msm_tspp_driver = {
 	.probe          = msm_tspp_probe,
 	.remove         = __exit_p(msm_tspp_remove),
 	.driver         = {
 		.name   = "msm_tspp",
 		.pm     = &tspp_dev_pm_ops,
+		.of_match_table = msm_match_table,
 	},
 };
 
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 4471fac..56d5d9f 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -57,6 +57,7 @@
 #define INAND_CMD38_ARG_SECERASE 0x80
 #define INAND_CMD38_ARG_SECTRIM1 0x81
 #define INAND_CMD38_ARG_SECTRIM2 0x88
+#define MMC_BLK_TIMEOUT_MS  (10 * 60 * 1000)        /* 10 minute timeout */
 
 #define MMC_SANITIZE_REQ_TIMEOUT 240000 /* msec */
 
@@ -121,7 +122,7 @@
 	struct device_attribute force_ro;
 	struct device_attribute power_ro_lock;
 	struct device_attribute num_wr_reqs_to_start_packing;
-	struct device_attribute min_sectors_to_check_bkops_status;
+	struct device_attribute bkops_check_threshold;
 	int	area_type;
 };
 
@@ -308,43 +309,60 @@
 }
 
 static ssize_t
-min_sectors_to_check_bkops_status_show(struct device *dev,
+bkops_check_threshold_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
-	unsigned int min_sectors_to_check_bkops_status;
 	struct mmc_card *card = md->queue.card;
 	int ret;
 
 	if (!card)
-		return -EINVAL;
-
-	min_sectors_to_check_bkops_status =
-		card->bkops_info.min_sectors_to_queue_delayed_work;
-
-	ret = snprintf(buf, PAGE_SIZE, "%d\n",
-		       min_sectors_to_check_bkops_status);
+		ret = -EINVAL;
+	else
+	    ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		card->bkops_info.size_percentage_to_queue_delayed_work);
 
 	mmc_blk_put(md);
 	return ret;
 }
 
 static ssize_t
-min_sectors_to_check_bkops_status_store(struct device *dev,
+bkops_check_threshold_store(struct device *dev,
 				 struct device_attribute *attr,
 				 const char *buf, size_t count)
 {
 	int value;
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
 	struct mmc_card *card = md->queue.card;
+	unsigned int card_size;
+	int ret = count;
 
-	if (!card)
-		return -EINVAL;
+	if (!card) {
+		ret = -EINVAL;
+		goto exit;
+	}
 
 	sscanf(buf, "%d", &value);
-	if (value >= 0)
-		card->bkops_info.min_sectors_to_queue_delayed_work = value;
+	if ((value <= 0) || (value >= 100)) {
+		ret = -EINVAL;
+		goto exit;
+	}
 
+	card_size = (unsigned int)get_capacity(md->disk);
+	if (card_size <= 0) {
+		ret = -EINVAL;
+		goto exit;
+	}
+	card->bkops_info.size_percentage_to_queue_delayed_work = value;
+	card->bkops_info.min_sectors_to_queue_delayed_work =
+		(card_size * value) / 100;
+
+	pr_debug("%s: size_percentage = %d, min_sectors = %d",
+			mmc_hostname(card->host),
+			card->bkops_info.size_percentage_to_queue_delayed_work,
+			card->bkops_info.min_sectors_to_queue_delayed_work);
+
+exit:
 	mmc_blk_put(md);
 	return count;
 }
@@ -1002,9 +1020,6 @@
 			goto out;
 	}
 
-	if (mmc_can_sanitize(card))
-		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-				 EXT_CSD_SANITIZE_START, 1, 0);
 out_retry:
 	if (err && !mmc_blk_reset(md, card->host, type))
 		goto retry;
@@ -1152,6 +1167,9 @@
 	 */
 	if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
 		u32 status;
+		unsigned long timeout;
+
+		timeout = jiffies + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS);
 		do {
 			int err = get_card_status(card, &status, 5);
 			if (err) {
@@ -1159,6 +1177,17 @@
 				       req->rq_disk->disk_name, err);
 				return MMC_BLK_CMD_ERR;
 			}
+
+			/* Timeout if the device never becomes ready for data
+			 * and never leaves the program state.
+			 */
+			if (time_after(jiffies, timeout)) {
+				pr_err("%s: Card stuck in programming state!"\
+					" %s %s\n", mmc_hostname(card->host),
+					req->rq_disk->disk_name, __func__);
+
+				return MMC_BLK_CMD_ERR;
+			}
 			/*
 			 * Some cards mishandle the status bits,
 			 * so make sure to check both the busy
@@ -2032,9 +2061,12 @@
 	}
 #endif
 
-	if (req && !mq->mqrq_prev->req)
+	if (req && !mq->mqrq_prev->req) {
 		/* claim host only for the first request */
 		mmc_claim_host(card->host);
+		if (card->ext_csd.bkops_en)
+			mmc_stop_bkops(card);
+	}
 
 	ret = mmc_blk_part_switch(card, md);
 	if (ret) {
@@ -2070,9 +2102,12 @@
 	}
 
 out:
-	if (!req)
+	if (!req) {
+		if (mmc_card_need_bkops(card))
+			mmc_start_bkops(card, false);
 		/* release host only when there are no more requests */
 		mmc_release_host(card->host);
+	}
 	return ret;
 }
 
@@ -2091,6 +2126,8 @@
 {
 	struct mmc_blk_data *md;
 	int devidx, ret;
+	unsigned int percentage =
+		BKOPS_SIZE_PERCENTAGE_TO_QUEUE_DELAYED_WORK;
 
 	devidx = find_first_zero_bit(dev_use, max_devices);
 	if (devidx >= max_devices)
@@ -2168,6 +2205,10 @@
 	blk_queue_logical_block_size(md->queue.queue, 512);
 	set_capacity(md->disk, size);
 
+	card->bkops_info.size_percentage_to_queue_delayed_work = percentage;
+	card->bkops_info.min_sectors_to_queue_delayed_work =
+		((unsigned int)size * percentage) / 100;
+
 	if (mmc_host_cmd23(card->host)) {
 		if (mmc_card_mmc(card) ||
 		    (mmc_card_sd(card) &&
@@ -2360,22 +2401,19 @@
 	if (ret)
 		goto num_wr_reqs_to_start_packing_fail;
 
-	md->min_sectors_to_check_bkops_status.show =
-		min_sectors_to_check_bkops_status_show;
-	md->min_sectors_to_check_bkops_status.store =
-		min_sectors_to_check_bkops_status_store;
-	sysfs_attr_init(&md->min_sectors_to_check_bkops_status.attr);
-	md->min_sectors_to_check_bkops_status.attr.name =
-		"min_sectors_to_check_bkops_status";
-	md->min_sectors_to_check_bkops_status.attr.mode = S_IRUGO | S_IWUSR;
+	md->bkops_check_threshold.show = bkops_check_threshold_show;
+	md->bkops_check_threshold.store = bkops_check_threshold_store;
+	sysfs_attr_init(&md->bkops_check_threshold.attr);
+	md->bkops_check_threshold.attr.name = "bkops_check_threshold";
+	md->bkops_check_threshold.attr.mode = S_IRUGO | S_IWUSR;
 	ret = device_create_file(disk_to_dev(md->disk),
-				 &md->min_sectors_to_check_bkops_status);
+				 &md->bkops_check_threshold);
 	if (ret)
-		goto min_sectors_to_check_bkops_status_fails;
+		goto bkops_check_threshold_fails;
 
 	return ret;
 
-min_sectors_to_check_bkops_status_fails:
+bkops_check_threshold_fails:
 	device_remove_file(disk_to_dev(md->disk),
 			   &md->num_wr_reqs_to_start_packing);
 num_wr_reqs_to_start_packing_fail:
@@ -2499,14 +2537,27 @@
 {
 	struct mmc_blk_data *part_md;
 	struct mmc_blk_data *md = mmc_get_drvdata(card);
+	int rc = 0;
 
 	if (md) {
-		mmc_queue_suspend(&md->queue);
+		rc = mmc_queue_suspend(&md->queue);
+		if (rc)
+			goto out;
 		list_for_each_entry(part_md, &md->part, part) {
-			mmc_queue_suspend(&part_md->queue);
+			rc = mmc_queue_suspend(&part_md->queue);
+			if (rc)
+				goto out_resume;
 		}
 	}
-	return 0;
+	goto out;
+
+ out_resume:
+	mmc_queue_resume(&md->queue);
+	list_for_each_entry(part_md, &md->part, part) {
+		mmc_queue_resume(&part_md->queue);
+	}
+ out:
+	return rc;
 }
 
 static int mmc_blk_resume(struct mmc_card *card)
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 8897f18a..b12b13b 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -75,17 +75,6 @@
 		spin_unlock_irq(q->queue_lock);
 
 		if (req || mq->mqrq_prev->req) {
-			/*
-			 * If this is the first request, BKOPs might be in
-			 * progress and needs to be stopped before issuing the
-			 * request
-			 */
-			if (card->ext_csd.bkops_en &&
-			    card->bkops_info.started_delayed_bkops) {
-				card->bkops_info.started_delayed_bkops = false;
-				mmc_stop_bkops(card);
-			}
-
 			set_current_state(TASK_RUNNING);
 			mq->issue_fn(mq, req);
 		} else {
@@ -375,10 +364,11 @@
  * complete any outstanding requests.  This ensures that we
  * won't suspend while a request is being processed.
  */
-void mmc_queue_suspend(struct mmc_queue *mq)
+int mmc_queue_suspend(struct mmc_queue *mq)
 {
 	struct request_queue *q = mq->queue;
 	unsigned long flags;
+	int rc = 0;
 
 	if (!(mq->flags & MMC_QUEUE_SUSPENDED)) {
 		mq->flags |= MMC_QUEUE_SUSPENDED;
@@ -387,8 +377,20 @@
 		blk_stop_queue(q);
 		spin_unlock_irqrestore(q->queue_lock, flags);
 
-		down(&mq->thread_sem);
+		rc = down_trylock(&mq->thread_sem);
+		if (rc) {
+			/*
+			 * Failed to take the lock so better to abort the
+			 * suspend because mmcqd thread is processing requests.
+			 */
+			mq->flags &= ~MMC_QUEUE_SUSPENDED;
+			spin_lock_irqsave(q->queue_lock, flags);
+			blk_start_queue(q);
+			spin_unlock_irqrestore(q->queue_lock, flags);
+			rc = -EBUSY;
+		}
 	}
+	return rc;
 }
 
 /**
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index a8c104e..b6cd82a 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -66,7 +66,7 @@
 extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
 			  const char *);
 extern void mmc_cleanup_queue(struct mmc_queue *);
-extern void mmc_queue_suspend(struct mmc_queue *);
+extern int mmc_queue_suspend(struct mmc_queue *);
 extern void mmc_queue_resume(struct mmc_queue *);
 
 extern unsigned int mmc_queue_map_sg(struct mmc_queue *,
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 91796de..881c7f2 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -44,6 +44,9 @@
 #include "sd_ops.h"
 #include "sdio_ops.h"
 
+/* If the device is not responding */
+#define MMC_CORE_TIMEOUT_MS	(10 * 60 * 1000) /* 10 minute timeout */
+
 /*
  * Background operations can take a long time, depending on the housekeeping
  * operations the card has to perform.
@@ -297,15 +300,12 @@
 	pr_debug("%s: %s: queueing delayed_bkops_work\n",
 		 mmc_hostname(card->host), __func__);
 
-	card->bkops_info.sectors_changed = 0;
-
 	/*
 	 * cancel_delayed_bkops_work will prevent a race condition between
 	 * fetching a request by the mmcqd and the delayed work, in case
 	 * it was removed from the queue work but not started yet
 	 */
 	card->bkops_info.cancel_delayed_work = false;
-	card->bkops_info.started_delayed_bkops = true;
 	queue_delayed_work(system_nrt_wq, &card->bkops_info.dw,
 			   msecs_to_jiffies(
 				   card->bkops_info.delay_ms));
@@ -325,15 +325,26 @@
 void mmc_start_bkops(struct mmc_card *card, bool from_exception)
 {
 	int err;
-	int timeout;
-	bool use_busy_signal;
 
 	BUG_ON(!card);
 	if (!card->ext_csd.bkops_en)
 		return;
 
-	mmc_claim_host(card->host);
+	if ((card->bkops_info.cancel_delayed_work) && !from_exception) {
+		pr_debug("%s: %s: cancel_delayed_work was set, exit\n",
+			 mmc_hostname(card->host), __func__);
+		card->bkops_info.cancel_delayed_work = false;
+		return;
+	}
 
+	/* In case of delayed bkops we might be in race with suspend. */
+	if (!mmc_try_claim_host(card->host))
+		return;
+
+	/*
+	 * Since the cancel_delayed_work can be changed while we are waiting
+	 * for the lock we will to re-check it
+	 */
 	if ((card->bkops_info.cancel_delayed_work) && !from_exception) {
 		pr_debug("%s: %s: cancel_delayed_work was set, exit\n",
 			 mmc_hostname(card->host), __func__);
@@ -347,58 +358,57 @@
 		goto out;
 	}
 
-	err = mmc_read_bkops_status(card);
-	if (err) {
-		pr_err("%s: Failed to read bkops status: %d\n",
-		       mmc_hostname(card->host), err);
+	if (from_exception && mmc_card_need_bkops(card))
 		goto out;
-	}
-
-	if (!card->ext_csd.raw_bkops_status)
-		goto out;
-
-	pr_info("%s: %s: card->ext_csd.raw_bkops_status = 0x%x\n",
-		mmc_hostname(card->host), __func__,
-		card->ext_csd.raw_bkops_status);
 
 	/*
-	 * If the function was called due to exception but there is no need
-	 * for urgent BKOPS, BKOPs will be performed by the delayed BKOPs
-	 * work, before going to suspend
+	 * If the need BKOPS flag is set, there is no need to check if BKOPS
+	 * is needed since we already know that it does
 	 */
-	if (card->ext_csd.raw_bkops_status < EXT_CSD_BKOPS_LEVEL_2 &&
-	    from_exception)
-		goto out;
+	if (!mmc_card_need_bkops(card)) {
+		err = mmc_read_bkops_status(card);
+		if (err) {
+			pr_err("%s: %s: Failed to read bkops status: %d\n",
+			       mmc_hostname(card->host), __func__, err);
+			goto out;
+		}
 
-	if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) {
-		timeout = MMC_BKOPS_MAX_TIMEOUT;
-		use_busy_signal = true;
-	} else {
-		timeout = 0;
-		use_busy_signal = false;
+		if (!card->ext_csd.raw_bkops_status)
+			goto out;
+
+		pr_info("%s: %s: raw_bkops_status=0x%x, from_exception=%d\n",
+			mmc_hostname(card->host), __func__,
+			card->ext_csd.raw_bkops_status,
+			from_exception);
 	}
 
+	/*
+	 * If the function was called due to exception, BKOPS will be performed
+	 * after handling the last pending request
+	 */
+	if (from_exception) {
+		pr_debug("%s: %s: Level %d from exception, exit",
+			 mmc_hostname(card->host), __func__,
+			 card->ext_csd.raw_bkops_status);
+		mmc_card_set_need_bkops(card);
+		goto out;
+	}
+	pr_info("%s: %s: Starting bkops\n", mmc_hostname(card->host), __func__);
+
 	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			   EXT_CSD_BKOPS_START, 1, timeout,
-			   use_busy_signal, use_busy_signal);
+			EXT_CSD_BKOPS_START, 1, 0, false, false);
 	if (err) {
 		pr_warn("%s: Error %d starting bkops\n",
 			mmc_hostname(card->host), err);
 		goto out;
 	}
+	mmc_card_clr_need_bkops(card);
 
-	/*
-	 * For urgent bkops status (LEVEL_2 and more)
-	 * bkops executed synchronously, otherwise
-	 * the operation is in progress
-	 */
-	if (!use_busy_signal) {
-		mmc_card_set_doing_bkops(card);
-		pr_debug("%s: %s: starting the polling thread\n",
-			 mmc_hostname(card->host), __func__);
-		queue_work(system_nrt_wq,
-			   &card->bkops_info.poll_for_completion);
-	}
+	mmc_card_set_doing_bkops(card);
+	pr_debug("%s: %s: starting the polling thread\n",
+		 mmc_hostname(card->host), __func__);
+	queue_work(system_nrt_wq,
+		   &card->bkops_info.poll_for_completion);
 
 out:
 	mmc_release_host(card->host);
@@ -452,7 +462,7 @@
 			pr_debug("%s: %s: completed BKOPs, exit polling\n",
 				 mmc_hostname(card->host), __func__);
 			mmc_card_clr_doing_bkops(card);
-			card->bkops_info.started_delayed_bkops = false;
+			card->bkops_info.sectors_changed = 0;
 			goto out;
 		}
 
@@ -465,8 +475,12 @@
 		msleep(BKOPS_COMPLETION_POLLING_INTERVAL_MS);
 	} while (time_before(jiffies, timeout_jiffies));
 
-	pr_err("%s: %s: exit polling due to timeout\n",
+	pr_err("%s: %s: exit polling due to timeout, stop bkops\n",
 	       mmc_hostname(card->host), __func__);
+	err = mmc_stop_bkops(card);
+	if (err)
+		pr_err("%s: %s: mmc_stop_bkops failed, err=%d\n",
+			       mmc_hostname(card->host), __func__, err);
 
 	return;
 out:
@@ -761,7 +775,9 @@
  *	Send HPI command to stop ongoing background operations to
  *	allow rapid servicing of foreground operations, e.g. read/
  *	writes. Wait until the card comes out of the programming state
- *	to avoid errors in servicing read/write requests.
+ *      to avoid errors in servicing read/write requests.
+ *
+ *      The function should be called with host claimed.
  */
 int mmc_stop_bkops(struct mmc_card *card)
 {
@@ -769,8 +785,6 @@
 
 	BUG_ON(!card);
 
-	mmc_claim_host(card->host);
-
 	/*
 	 * Notify the delayed work to be cancelled, in case it was already
 	 * removed from the queue, but was not started yet
@@ -793,7 +807,6 @@
 	}
 
 out:
-	mmc_release_host(card->host);
 	return err;
 }
 EXPORT_SYMBOL(mmc_stop_bkops);
@@ -1839,6 +1852,7 @@
 {
 	struct mmc_command cmd = {0};
 	unsigned int qty = 0;
+	unsigned long timeout;
 	int err;
 
 	/*
@@ -1916,6 +1930,7 @@
 	if (mmc_host_is_spi(card->host))
 		goto out;
 
+	timeout = jiffies + msecs_to_jiffies(MMC_CORE_TIMEOUT_MS);
 	do {
 		memset(&cmd, 0, sizeof(struct mmc_command));
 		cmd.opcode = MMC_SEND_STATUS;
@@ -1929,8 +1944,19 @@
 			err = -EIO;
 			goto out;
 		}
+
+		/* Timeout if the device never becomes ready for data and
+		 * never leaves the program state.
+		 */
+		if (time_after(jiffies, timeout)) {
+			pr_err("%s: Card stuck in programming state! %s\n",
+				mmc_hostname(card->host), __func__);
+			err =  -EIO;
+			goto out;
+		}
+
 	} while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
-		 R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG);
+		 (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG));
 out:
 	return err;
 }
@@ -2584,6 +2610,7 @@
  * Turn the cache ON/OFF.
  * Turning the cache OFF shall trigger flushing of the data
  * to the non-volatile storage.
+ * This function should be called with host claimed
  */
 int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
 {
@@ -2595,9 +2622,6 @@
 			mmc_card_is_removable(host))
 		return err;
 
-	if (!mmc_try_claim_host(host))
-		return -EBUSY;
-
 	if (card && mmc_card_mmc(card) &&
 			(card->ext_csd.cache_size > 0)) {
 		enable = !!enable;
@@ -2615,7 +2639,6 @@
 				card->ext_csd.cache_ctrl = enable;
 		}
 	}
-	mmc_release_host(host);
 
 	return err;
 }
@@ -2637,9 +2660,6 @@
 	if (cancel_delayed_work(&host->detect))
 		wake_unlock(&host->detect_wake_lock);
 	mmc_flush_scheduled_work();
-	err = mmc_cache_ctrl(host, 0);
-	if (err)
-		goto out;
 
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
@@ -2661,11 +2681,9 @@
 
 		if (!err) {
 			if (host->bus_ops->suspend) {
-				if (mmc_card_doing_bkops(host->card)) {
-					err = mmc_stop_bkops(host->card);
-					if (err)
-						goto stop_bkops_err;
-				}
+				err = mmc_stop_bkops(host->card);
+				if (err)
+					goto stop_bkops_err;
 				err = host->bus_ops->suspend(host);
 			}
 			if (!(host->card && mmc_card_sdio(host->card)))
@@ -2695,7 +2713,6 @@
 	if (!err && !mmc_card_keep_power(host))
 		mmc_power_off(host);
 
-out:
 	return err;
 stop_bkops_err:
 	if (!(host->card && mmc_card_sdio(host->card)))
@@ -2769,7 +2786,9 @@
 	case PM_HIBERNATION_PREPARE:
 	case PM_SUSPEND_PREPARE:
 		if (host->card && mmc_card_mmc(host->card)) {
+			mmc_claim_host(host);
 			err = mmc_stop_bkops(host->card);
+			mmc_release_host(host);
 			if (err) {
 				pr_err("%s: didn't stop bkops\n",
 					mmc_hostname(host));
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 47fd9b9..d4af93d 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1324,20 +1324,16 @@
 
 			/*
 			 * Calculate the time to start the BKOPs checking.
-			 * The idle time of the host controller should be taken
-			 * into account in order to prevent a race condition
-			 * before starting BKOPs and going into suspend.
-			 * If the host controller didn't set its idle time,
+			 * The host controller can set this time in order to
+			 * prevent a race condition before starting BKOPs
+			 * and going into suspend.
+			 * If the host controller didn't set this time,
 			 * a default value is used.
 			 */
 			card->bkops_info.delay_ms = MMC_IDLE_BKOPS_TIME_MS;
-			if (card->bkops_info.host_suspend_tout_ms)
-				card->bkops_info.delay_ms = min(
-					card->bkops_info.delay_ms,
-				      card->bkops_info.host_suspend_tout_ms/2);
-
-			card->bkops_info.min_sectors_to_queue_delayed_work =
-				BKOPS_MIN_SECTORS_TO_QUEUE_DELAYED_WORK;
+			if (card->bkops_info.host_delay_ms)
+				card->bkops_info.delay_ms =
+					card->bkops_info.host_delay_ms;
 		}
 	}
 
@@ -1448,6 +1444,11 @@
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
+
+	err = mmc_cache_ctrl(host, 0);
+	if (err)
+		goto out;
+
 	if (mmc_can_poweroff_notify(host->card))
 		err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
 	else if (mmc_card_can_sleep(host))
@@ -1455,8 +1456,9 @@
 	else if (!mmc_host_is_spi(host))
 		mmc_deselect_cards(host);
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
-	mmc_release_host(host);
 
+out:
+	mmc_release_host(host);
 	return err;
 }
 
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index f8c9720..f982d99 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -21,6 +21,8 @@
 #include "core.h"
 #include "mmc_ops.h"
 
+#define MMC_OPS_TIMEOUT_MS	(10 * 60 * 1000) /* 10 minute timeout */
+
 static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
 {
 	int err;
@@ -386,6 +388,7 @@
 {
 	int err;
 	struct mmc_command cmd = {0};
+	unsigned long timeout;
 	u32 status;
 
 	BUG_ON(!card);
@@ -415,6 +418,7 @@
 		return 0;
 
 	/* Must check status to be sure of no errors */
+	timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS);
 	do {
 		err = mmc_send_status(card, &status);
 		if (err)
@@ -423,6 +427,13 @@
 			break;
 		if (mmc_host_is_spi(card->host))
 			break;
+
+		/* Timeout if the device never leaves the program state. */
+		if (time_after(jiffies, timeout)) {
+			pr_err("%s: Card stuck in programming state! %s\n",
+				mmc_hostname(card->host), __func__);
+			return -ETIMEDOUT;
+		}
 	} while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
 
 	if (mmc_host_is_spi(card->host)) {
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index fd18560..4e76f61 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -162,10 +162,7 @@
 			if (ret)
 				goto out;
 
-			if (card->host->caps &
-				(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-				 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
-				 MMC_CAP_UHS_DDR50)) {
+			if (mmc_host_uhs(card->host)) {
 				if (data & SDIO_UHS_DDR50)
 					card->sw_caps.sd3_bus_mode
 						|= SD_MODE_UHS_DDR50;
@@ -480,8 +477,7 @@
 	 * If the host doesn't support any of the UHS-I modes, fallback on
 	 * default speed.
 	 */
-	if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-	    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)))
+	if (!mmc_host_uhs(card->host))
 		return 0;
 
 	bus_speed = SDIO_SPEED_SDR12;
@@ -491,23 +487,27 @@
 			bus_speed = SDIO_SPEED_SDR104;
 			timing = MMC_TIMING_UHS_SDR104;
 			card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
+			card->sd_bus_speed = UHS_SDR104_BUS_SPEED;
 	} else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
 		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
 			bus_speed = SDIO_SPEED_DDR50;
 			timing = MMC_TIMING_UHS_DDR50;
 			card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
+			card->sd_bus_speed = UHS_DDR50_BUS_SPEED;
 	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
 		    MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
 		    SD_MODE_UHS_SDR50)) {
 			bus_speed = SDIO_SPEED_SDR50;
 			timing = MMC_TIMING_UHS_SDR50;
 			card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
+			card->sd_bus_speed = UHS_SDR50_BUS_SPEED;
 	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
 		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
 		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
 			bus_speed = SDIO_SPEED_SDR25;
 			timing = MMC_TIMING_UHS_SDR25;
 			card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
+			card->sd_bus_speed = UHS_SDR25_BUS_SPEED;
 	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
 		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
 		    MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
@@ -515,6 +515,7 @@
 			bus_speed = SDIO_SPEED_SDR12;
 			timing = MMC_TIMING_UHS_SDR12;
 			card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
+			card->sd_bus_speed = UHS_SDR12_BUS_SPEED;
 	}
 
 	err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
@@ -653,11 +654,7 @@
 	 * systems that claim 1.8v signalling in fact do not support
 	 * it.
 	 */
-	if ((ocr & R4_18V_PRESENT) &&
-		(host->caps &
-			(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-			 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
-			 MMC_CAP_UHS_DDR50))) {
+	if ((ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) {
 		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180,
 				true);
 		if (err) {
@@ -1056,6 +1053,10 @@
 		goto out;
 	}
 
+	if (mmc_host_uhs(host))
+		/* to query card if 1.8V signalling is supported */
+		host->ocr |= R4_18V_PRESENT;
+
 	ret = mmc_sdio_init_card(host, host->ocr, host->card,
 				mmc_card_keep_power(host));
 	if (!ret && host->sdio_irqs)
@@ -1121,6 +1122,10 @@
 	/*
 	 * Detect and init the card.
 	 */
+	if (mmc_host_uhs(host))
+		/* to query card if 1.8V signalling is supported */
+		host->ocr |= R4_18V_PRESENT;
+
 	err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
 	if (err) {
 		if (err == -EAGAIN) {
@@ -1238,79 +1243,6 @@
 
 int sdio_reset_comm(struct mmc_card *card)
 {
-	struct mmc_host *host = card->host;
-	u32 ocr;
-	int err;
-
-	printk("%s():\n", __func__);
-	mmc_claim_host(host);
-
-	mmc_go_idle(host);
-
-	mmc_set_clock(host, host->f_min);
-
-	err = mmc_send_io_op_cond(host, 0, &ocr);
-	if (err)
-		goto err;
-
-	host->ocr = mmc_select_voltage(host, ocr);
-	if (!host->ocr) {
-		err = -EINVAL;
-		goto err;
-	}
-
-	err = mmc_send_io_op_cond(host, host->ocr, &ocr);
-	if (err)
-		goto err;
-
-	if (mmc_host_is_spi(host)) {
-		err = mmc_spi_set_crc(host, use_spi_crc);
-		if (err)
-			goto err;
-	}
-
-	if (!mmc_host_is_spi(host)) {
-		err = mmc_send_relative_addr(host, &card->rca);
-		if (err)
-			goto err;
-		mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
-	}
-	if (!mmc_host_is_spi(host)) {
-		err = mmc_select_card(card);
-		if (err)
-			goto err;
-	}
-
-	/*
-	 * Switch to high-speed (if supported).
-	 */
-	err = sdio_enable_hs(card);
-	if (err > 0)
-		mmc_sd_go_highspeed(card);
-	else if (err)
-		goto err;
-
-	/*
-	 * Change to the card's maximum speed.
-	 */
-	mmc_set_clock(host, mmc_sdio_get_max_clock(card));
-
-	err = sdio_enable_4bit_bus(card);
-	if (err > 0) {
-		if (host->caps & MMC_CAP_8_BIT_DATA)
-			mmc_set_bus_width(host, MMC_BUS_WIDTH_8);
-		else if (host->caps & MMC_CAP_4_BIT_DATA)
-			mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
-	}
-	else if (err)
-		goto err;
-
-	mmc_release_host(host);
-	return 0;
-err:
-	printk("%s: Error resetting SDIO communications (%d)\n",
-	       mmc_hostname(host), err);
-	mmc_release_host(host);
-	return err;
+	return mmc_power_restore_host(card->host);
 }
 EXPORT_SYMBOL(sdio_reset_comm);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 450f363..9a7af35 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2007 Google Inc,
  *  Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
- *  Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2009-2012, The Linux Foundation. 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
@@ -75,6 +75,7 @@
 #define SPS_MIN_XFER_SIZE		MCI_FIFOSIZE
 
 #define MSM_MMC_BUS_VOTING_DELAY	200 /* msecs */
+#define INVALID_TUNING_PHASE		-1
 
 #if defined(CONFIG_DEBUG_FS)
 static void msmsdcc_dbg_createhost(struct msmsdcc_host *);
@@ -158,6 +159,7 @@
 static void msmsdcc_sg_start(struct msmsdcc_host *host);
 static int msmsdcc_vreg_reset(struct msmsdcc_host *host);
 static int msmsdcc_runtime_resume(struct device *dev);
+static int msmsdcc_execute_tuning(struct mmc_host *mmc, u32 opcode);
 static bool msmsdcc_is_wait_for_auto_prog_done(struct msmsdcc_host *host,
 					       struct mmc_request *mrq);
 static bool msmsdcc_is_wait_for_prog_done(struct msmsdcc_host *host,
@@ -254,6 +256,11 @@
 		goto out;
 	}
 
+	memset(host->sps.prod.config.desc.base, 0x00,
+			host->sps.prod.config.desc.size);
+	memset(host->sps.cons.config.desc.base, 0x00,
+			host->sps.cons.config.desc.size);
+
 	/* Restore all BAM pipes connections */
 	rc = msmsdcc_sps_restore_ep(host, &host->sps.prod);
 	if (rc) {
@@ -379,37 +386,26 @@
 static void msmsdcc_reset_and_restore(struct msmsdcc_host *host)
 {
 	if (is_soft_reset(host)) {
-		if (is_sps_mode(host))
-			/*
-			 * delay the SPS BAM reset in thread context as
-			 * sps_connect/sps_disconnect APIs can be called
-			 * only from non-atomic context.
-			 */
-			host->sps.reset_bam = true;
-
 		msmsdcc_soft_reset(host);
 
 		pr_debug("%s: Applied soft reset to Controller\n",
 				mmc_hostname(host->mmc));
 	} else {
-		/*
-		 * When there is a requirement to use this hard reset,
-		 * BAM needs to be reconfigured as well by calling
-		 * msmsdcc_sps_exit and msmsdcc_sps_init.
-		 */
-
 		/* Give Clock reset (hard reset) to controller */
 		u32	mci_clk = 0;
 		u32	mci_mask0 = 0;
+		u32	dll_config = 0;
 
 		/* Save the controller state */
 		mci_clk = readl_relaxed(host->base + MMCICLOCK);
 		mci_mask0 = readl_relaxed(host->base + MMCIMASK0);
 		host->pwr = readl_relaxed(host->base + MMCIPOWER);
+		if (host->tuning_needed)
+			dll_config = readl_relaxed(host->base + MCI_DLL_CONFIG);
 		mb();
 
 		msmsdcc_hard_reset(host);
-		pr_debug("%s: Controller has been reinitialized\n",
+		pr_debug("%s: Applied hard reset to controller\n",
 				mmc_hostname(host->mmc));
 
 		/* Restore the contoller state */
@@ -418,9 +414,19 @@
 		writel_relaxed(mci_clk, host->base + MMCICLOCK);
 		msmsdcc_sync_reg_wr(host);
 		writel_relaxed(mci_mask0, host->base + MMCIMASK0);
+		if (host->tuning_needed)
+			writel_relaxed(dll_config, host->base + MCI_DLL_CONFIG);
 		mb(); /* no delay required after writing to MASK0 register */
 	}
 
+	if (is_sps_mode(host))
+		/*
+		 * delay the SPS BAM reset in thread context as
+		 * sps_connect/sps_disconnect APIs can be called
+		 * only from non-atomic context.
+		 */
+		host->sps.reset_bam = true;
+
 	if (host->dummy_52_needed)
 		host->dummy_52_needed = 0;
 }
@@ -1291,7 +1297,12 @@
 	else if (host->curr.use_wr_data_pend)
 		datactrl |= MCI_DATA_PEND;
 
-	clks = (unsigned long long)data->timeout_ns * host->clk_rate;
+	if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
+		clks = (unsigned long long)data->timeout_ns *
+					   (host->clk_rate / 2);
+	else
+		clks = (unsigned long long)data->timeout_ns * host->clk_rate;
+
 	do_div(clks, 1000000000UL);
 	timeout = data->timeout_clks + (unsigned int)clks*2 ;
 	WARN(!timeout,
@@ -1358,33 +1369,49 @@
 msmsdcc_data_err(struct msmsdcc_host *host, struct mmc_data *data,
 		 unsigned int status)
 {
-	if (status & MCI_DATACRCFAIL) {
-		if (!(data->mrq->cmd->opcode == MMC_BUS_TEST_W
-			|| data->mrq->cmd->opcode == MMC_BUS_TEST_R
-			|| data->mrq->cmd->opcode ==
-				MMC_SEND_TUNING_BLOCK_HS200)) {
-			pr_err("%s: Data CRC error\n",
-			       mmc_hostname(host->mmc));
-			pr_err("%s: opcode 0x%.8x\n", __func__,
-			       data->mrq->cmd->opcode);
-			pr_err("%s: blksz %d, blocks %d\n", __func__,
-			       data->blksz, data->blocks);
-			data->error = -EILSEQ;
+	if ((status & MCI_DATACRCFAIL) || (status & MCI_DATATIMEOUT)) {
+		u32 opcode = data->mrq->cmd->opcode;
+
+		if (!((!host->tuning_in_progress && opcode == MMC_BUS_TEST_W)
+		    || (opcode == MMC_BUS_TEST_R) ||
+		    (host->tuning_in_progress &&
+		    (opcode == MMC_SEND_TUNING_BLOCK_HS200 ||
+		     opcode == MMC_SEND_TUNING_BLOCK)))) {
+			/* Execute full tuning in case of CRC/timeout errors */
+			host->saved_tuning_phase = INVALID_TUNING_PHASE;
+
+			if (status & MCI_DATACRCFAIL) {
+				pr_err("%s: Data CRC error\n",
+				       mmc_hostname(host->mmc));
+				pr_err("%s: opcode 0x%.8x\n", __func__, opcode);
+				pr_err("%s: blksz %d, blocks %d\n", __func__,
+				       data->blksz, data->blocks);
+			} else {
+				pr_err("%s: CMD%d: Data timeout. DAT0 => %d\n",
+					 mmc_hostname(host->mmc), opcode,
+					 (readl_relaxed(host->base
+					 + MCI_TEST_INPUT) & 0x2) ? 1 : 0);
+				msmsdcc_dump_sdcc_state(host);
+			}
 		}
-	} else if (status & MCI_DATATIMEOUT) {
-		/* CRC is optional for the bus test commands, not all
+
+		/*
+		 * CRC is optional for the bus test commands, not all
 		 * cards respond back with CRC. However controller
 		 * waits for the CRC and times out. Hence ignore the
 		 * data timeouts during the Bustest.
 		 */
-		if (!(data->mrq->cmd->opcode == MMC_BUS_TEST_W
-			|| data->mrq->cmd->opcode == MMC_BUS_TEST_R)) {
-			pr_err("%s: CMD%d: Data timeout\n",
-				 mmc_hostname(host->mmc),
-				 data->mrq->cmd->opcode);
-			data->error = -ETIMEDOUT;
-			msmsdcc_dump_sdcc_state(host);
+		if (!((!host->tuning_in_progress && opcode == MMC_BUS_TEST_W)
+		    || (opcode == MMC_BUS_TEST_R))) {
+			if (status & MCI_DATACRCFAIL)
+				data->error = -EILSEQ;
+			else
+				data->error = -ETIMEDOUT;
 		}
+		/* In case of DATA CRC/timeout error, execute tuning again */
+		if (host->tuning_needed && !host->tuning_in_progress)
+			host->tuning_done = false;
+
 	} else if (status & MCI_RXOVERRUN) {
 		pr_err("%s: RX overrun\n", mmc_hostname(host->mmc));
 		data->error = -EIO;
@@ -1735,6 +1762,10 @@
 		pr_err("%s: CMD%d: Command CRC error\n",
 			mmc_hostname(host->mmc), cmd->opcode);
 		msmsdcc_dump_sdcc_state(host);
+		/* Execute full tuning in case of CRC errors */
+		host->saved_tuning_phase = INVALID_TUNING_PHASE;
+		if (host->tuning_needed)
+			host->tuning_done = false;
 		cmd->error = -EILSEQ;
 	}
 
@@ -2151,6 +2182,22 @@
 		}
 	}
 
+	/*
+	 * Check if DLL retuning is required? If yes, perform it here before
+	 * starting new request.
+	 */
+	if (host->tuning_needed && !host->tuning_in_progress &&
+	    !host->tuning_done) {
+		pr_debug("%s: %s: execute_tuning for timing mode = %d\n",
+			 mmc_hostname(mmc), __func__, host->mmc->ios.timing);
+		if (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+			msmsdcc_execute_tuning(mmc,
+					       MMC_SEND_TUNING_BLOCK);
+		else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200)
+			msmsdcc_execute_tuning(mmc,
+					       MMC_SEND_TUNING_BLOCK_HS200);
+	}
+
 	spin_lock_irqsave(&host->lock, flags);
 
 	if (host->eject) {
@@ -3255,20 +3302,7 @@
 			writel_relaxed(clk, host->base + MMCICLOCK);
 			msmsdcc_sync_reg_wr(host);
 
-			/*
-			 * Make sure that we don't double the clock if
-			 * doubled clock rate is already set
-			 */
-			if (!host->ddr_doubled_clk_rate ||
-				(host->ddr_doubled_clk_rate &&
-				(host->ddr_doubled_clk_rate != ios->clock))) {
-				host->ddr_doubled_clk_rate =
-					msmsdcc_get_sup_clk_rate(
-						host, (ios->clock * 2));
-				clock = host->ddr_doubled_clk_rate;
-			}
-		} else {
-			host->ddr_doubled_clk_rate = 0;
+			clock = msmsdcc_get_sup_clk_rate(host, ios->clock * 2);
 		}
 
 		if (clock != host->clk_rate) {
@@ -3315,10 +3349,24 @@
 		/* Card clock frequency must be > 100MHz to enable tuning */
 		clk |= (4 << 14);
 		host->tuning_needed = 1;
-	} else if (ios->timing == MMC_TIMING_UHS_DDR50) {
-		clk |= (3 << 14);
 	} else {
-		clk |= (2 << 14); /* feedback clock */
+		if (ios->timing == MMC_TIMING_UHS_DDR50)
+			clk |= (3 << 14);
+		else
+			clk |= (2 << 14); /* feedback clock */
+
+		host->tuning_done = false;
+		if (atomic_read(&host->clks_on)) {
+			/* Write 1 to DLL_RST bit of MCI_DLL_CONFIG register */
+			writel_relaxed((readl_relaxed(host->base +
+					MCI_DLL_CONFIG) | MCI_DLL_RST),
+					host->base + MCI_DLL_CONFIG);
+
+			/* Write 1 to DLL_PDN bit of MCI_DLL_CONFIG register */
+			writel_relaxed((readl_relaxed(host->base +
+					MCI_DLL_CONFIG) | MCI_DLL_PDN),
+					host->base + MCI_DLL_CONFIG);
+		}
 	}
 
 	/* Select free running MCLK as input clock of cm_dll_sdc4 */
@@ -4036,6 +4084,7 @@
 	u8 phase, *data_buf, tuned_phases[16], tuned_phase_cnt = 0;
 	const u32 *tuning_block_pattern = tuning_block_64;
 	int size = sizeof(tuning_block_64); /* Tuning pattern size in bytes */
+	bool is_tuning_all_phases;
 
 	pr_debug("%s: Enter %s\n", mmc_hostname(mmc), __func__);
 
@@ -4069,7 +4118,13 @@
 		goto out;
 	}
 
-	phase = 0;
+	is_tuning_all_phases = !(host->mmc->card &&
+		(host->saved_tuning_phase != INVALID_TUNING_PHASE));
+retry:
+	if (is_tuning_all_phases)
+		phase = 0; /* start from phase 0 during init */
+	else
+		phase = (u8)host->saved_tuning_phase;
 	do {
 		struct mmc_command cmd = {0};
 		struct mmc_data data = {0};
@@ -4101,9 +4156,16 @@
 		if (!cmd.error && !data.error &&
 			!memcmp(data_buf, tuning_block_pattern, size)) {
 			/* tuning is successful at this tuning point */
+			if (!is_tuning_all_phases)
+				goto kfree;
 			tuned_phases[tuned_phase_cnt++] = phase;
 			pr_debug("%s: %s: found good phase = %d\n",
 				mmc_hostname(mmc), __func__, phase);
+		} else if (!is_tuning_all_phases) {
+			pr_debug("%s: tuning failed at saved phase (%d), retrying\n",
+					mmc_hostname(mmc), (u32)phase);
+			is_tuning_all_phases = true;
+			goto retry;
 		}
 	} while (++phase < 16);
 
@@ -4122,6 +4184,8 @@
 		rc = msmsdcc_config_cm_sdc4_dll_phase(host, phase);
 		if (rc)
 			goto kfree;
+		else
+			host->saved_tuning_phase = phase;
 		pr_debug("%s: %s: finally setting the tuning phase to %d\n",
 				mmc_hostname(mmc), __func__, phase);
 	} else {
@@ -4137,6 +4201,8 @@
 out:
 	spin_lock_irqsave(&host->lock, flags);
 	host->tuning_in_progress = 0;
+	if (!rc)
+		host->tuning_done = true;
 	spin_unlock_irqrestore(&host->lock, flags);
 exit:
 	pr_debug("%s: Exit %s\n", mmc_hostname(mmc), __func__);
@@ -5736,6 +5802,7 @@
 		dev_err(&pdev->dev, "Failed to read MCLK\n");
 
 	set_default_hw_caps(host);
+	host->saved_tuning_phase = INVALID_TUNING_PHASE;
 
 	/*
 	 * Set the register write delay according to min. clock frequency
@@ -6452,9 +6519,20 @@
 	if (host->plat->status_irq)
 		disable_irq(host->plat->status_irq);
 
-	if (!pm_runtime_suspended(dev))
+	/*
+	 * If system comes out of suspend, msmsdcc_pm_resume() sets the
+	 * host->pending_resume flag if the SDCC wasn't runtime suspended.
+	 * Now if the system again goes to suspend without any SDCC activity
+	 * then host->pending_resume flag will remain set which may cause
+	 * the SDCC resume to happen first and then suspend.
+	 * To avoid this unnecessary resume/suspend, make sure that
+	 * pending_resume flag is cleared before calling the
+	 * msmsdcc_runtime_suspend().
+	 */
+	if (!pm_runtime_suspended(dev) && !host->pending_resume)
 		rc = msmsdcc_runtime_suspend(dev);
-
+	/* This flag must not be set if system is entering into suspend */
+	host->pending_resume = false;
 	return rc;
 }
 
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 63bcf74..051c3bf 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -361,7 +361,6 @@
 
 	unsigned int		clk_rate;	/* Current clock rate */
 	unsigned int		pclk_rate;
-	unsigned int		ddr_doubled_clk_rate;
 
 	u32			pwr;
 	struct mmc_platform_data *plat;
@@ -400,6 +399,7 @@
 	bool io_pad_pwr_switch;
 	bool tuning_in_progress;
 	bool tuning_needed;
+	bool tuning_done;
 	bool sdio_gpio_lpm;
 	bool irq_wake_enabled;
 	struct pm_qos_request pm_qos_req_dma;
@@ -415,9 +415,12 @@
 	struct device_attribute	max_bus_bw;
 	struct device_attribute	polling;
 	struct device_attribute idle_timeout;
+	int saved_tuning_phase;
 };
 
-#define MSMSDCC_VERSION_MASK	0xFFFF
+#define MSMSDCC_VERSION_STEP_MASK	0x0000FFFF
+#define MSMSDCC_VERSION_MINOR_MASK	0x0FFF0000
+#define MSMSDCC_VERSION_MINOR_SHIFT	16
 #define MSMSDCC_DMA_SUP	(1 << 0)
 #define MSMSDCC_SPS_BAM_SUP	(1 << 1)
 #define MSMSDCC_SOFT_RESET	(1 << 2)
@@ -443,6 +446,8 @@
 static inline void set_default_hw_caps(struct msmsdcc_host *host)
 {
 	u32 version;
+	u16 step, minor;
+
 	/*
 	 * Lookup the Controller Version, to identify the supported features
 	 * Version number read as 0 would indicate SDCC3 or earlier versions.
@@ -453,13 +458,20 @@
 	if (!version)
 		return;
 
-	version &= MSMSDCC_VERSION_MASK;
+	step = version & MSMSDCC_VERSION_STEP_MASK;
+	minor = (version & MSMSDCC_VERSION_MINOR_MASK) >>
+		MSMSDCC_VERSION_MINOR_SHIFT;
+
 	if (version) /* SDCC v4 and greater */
 		host->hw_caps |= MSMSDCC_AUTO_PROG_DONE |
 			MSMSDCC_SOFT_RESET | MSMSDCC_REG_WR_ACTIVE
 			| MSMSDCC_WAIT_FOR_TX_RX | MSMSDCC_IO_PAD_PWR_SWITCH;
 
-	if (version >= 0x2D) /* SDCC v4 2.1.0 and greater */
+	if ((step == 0x18) && (minor >= 3))
+		/* Version 0x06000018 need hard reset on errors */
+		host->hw_caps &= ~MSMSDCC_SOFT_RESET;
+
+	if (step >= 0x2b) /* SDCC v4 2.1.0 and greater */
 		host->hw_caps |= MSMSDCC_SW_RST | MSMSDCC_SW_RST_CFG;
 }
 
diff --git a/drivers/mmc/host/msm_sdcc_dml.c b/drivers/mmc/host/msm_sdcc_dml.c
index 320f52e..91ab7e3 100644
--- a/drivers/mmc/host/msm_sdcc_dml.c
+++ b/drivers/mmc/host/msm_sdcc_dml.c
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/mmc/host/msm_sdcc_dml.c - Qualcomm MSM SDCC DML Driver
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/mmc/host/msm_sdcc_dml.h b/drivers/mmc/host/msm_sdcc_dml.h
index f0e1b78..bee58d1 100644
--- a/drivers/mmc/host/msm_sdcc_dml.h
+++ b/drivers/mmc/host/msm_sdcc_dml.h
@@ -2,7 +2,7 @@
  *  linux/drivers/mmc/host/msm_sdcc_dml.h - Qualcomm SDCC DML driver
  *					    header file
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/mtd/devices/msm_nand.c b/drivers/mtd/devices/msm_nand.c
index c43abca..9c35e37 100644
--- a/drivers/mtd/devices/msm_nand.c
+++ b/drivers/mtd/devices/msm_nand.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/mtd/devices/msm_nand.h b/drivers/mtd/devices/msm_nand.h
index 8156b92..8ad2116 100644
--- a/drivers/mtd/devices/msm_nand.h
+++ b/drivers/mtd/devices/msm_nand.h
@@ -1,6 +1,6 @@
 /* drivers/mtd/devices/msm_nand.h
  *
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  * Copyright (C) 2007 Google, Inc.
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/mtd/devices/msm_qpic_nand.c b/drivers/mtd/devices/msm_qpic_nand.c
index d709e17..f6794ac 100644
--- a/drivers/mtd/devices/msm_qpic_nand.c
+++ b/drivers/mtd/devices/msm_qpic_nand.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/mtd/tests/mtd_erasepart.c b/drivers/mtd/tests/mtd_erasepart.c
index 67f0f84..0e44df4 100644
--- a/drivers/mtd/tests/mtd_erasepart.c
+++ b/drivers/mtd/tests/mtd_erasepart.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  * Copyright (C) 2006-2008 Nokia Corporation
  *
  * This program is free software; you can redistribute it and/or modify it
diff --git a/drivers/net/ethernet/msm/msm_rmnet.c b/drivers/net/ethernet/msm/msm_rmnet.c
index 61df241..f8f5a55 100644
--- a/drivers/net/ethernet/msm/msm_rmnet.c
+++ b/drivers/net/ethernet/msm/msm_rmnet.c
@@ -3,7 +3,7 @@
  * Virtual Ethernet Interface for MSM7K Networking
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/net/ethernet/msm/msm_rmnet_sdio.c b/drivers/net/ethernet/msm/msm_rmnet_sdio.c
index 14fb612..754cb83 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_sdio.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_sdio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/net/ethernet/msm/msm_rmnet_smux.c b/drivers/net/ethernet/msm/msm_rmnet_smux.c
index e56a64e..49b1794 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_smux.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_smux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -804,7 +804,7 @@
 	for (i = 0; i < RMNET_SMUX_DEVICE_COUNT; i++) {
 		p = netdev_priv(netdevs[i]);
 
-		if ((p != NULL) && (p->device_state == DEVICE_INACTIVE)) {
+		if (p != NULL) {
 			r =  msm_smux_open(p->ch_id,
 					   netdevs[i],
 					   rmnet_smux_notify,
@@ -828,7 +828,7 @@
 	for (i = 0; i < RMNET_SMUX_DEVICE_COUNT; i++) {
 		p = netdev_priv(netdevs[i]);
 
-		if ((p != NULL) && (p->device_state == DEVICE_ACTIVE)) {
+		if (p != NULL) {
 			r =  msm_smux_close(p->ch_id);
 
 			if (r < 0) {
diff --git a/drivers/net/ethernet/msm/qfec.c b/drivers/net/ethernet/msm/qfec.c
index 112e16a..a1ba0dc 100644
--- a/drivers/net/ethernet/msm/qfec.c
+++ b/drivers/net/ethernet/msm/qfec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/net/ethernet/msm/qfec.h b/drivers/net/ethernet/msm/qfec.h
index 310406a..525fd9c6 100644
--- a/drivers/net/ethernet/msm/qfec.h
+++ b/drivers/net/ethernet/msm/qfec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/net/usb/rmnet_usb_ctrl.h b/drivers/net/usb/rmnet_usb.h
similarity index 60%
rename from drivers/net/usb/rmnet_usb_ctrl.h
rename to drivers/net/usb/rmnet_usb.h
index a8f8079..b895969 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.h
+++ b/drivers/net/usb/rmnet_usb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -10,8 +10,8 @@
  * GNU General Public License for more details.
  */
 
-#ifndef __RMNET_USB_CTRL_H
-#define __RMNET_USB_CTRL_H
+#ifndef __RMNET_USB_H
+#define __RMNET_USB_H
 
 #include <linux/mutex.h>
 #include <linux/usb.h>
@@ -19,7 +19,36 @@
 #include <linux/usb/ch9.h>
 #include <linux/usb/cdc.h>
 
-#define CTRL_DEV_MAX_LEN 10
+#define MAX_RMNET_DEVS		4
+#define MAX_RMNET_INSTS_PER_DEV	17
+#define TOTAL_RMNET_DEV_COUNT	(MAX_RMNET_DEVS * MAX_RMNET_INSTS_PER_DEV)
+
+#define CTRL_DEV_MAX_LEN	10
+
+#define RMNET_CTRL_DEV_OPEN	0
+#define RMNET_CTRL_DEV_READY	1
+#define RMNET_CTRL_DEV_MUX_EN	2
+
+/*MUX header bit masks*/
+#define MUX_CTRL_MASK	0x1
+#define MUX_PAD_SHIFT	0x2
+
+/*max padding bytes for n byte alignment*/
+#define MAX_PAD_BYTES(n)	(n-1)
+
+/*
+ *MUX Header Format
+ *BIT 0 : Mux type 0: Data, 1: control
+ *BIT 1: Reserved
+ *BIT 2-7: Pad bytes
+ *BIT 8-15: Mux ID
+ *BIT 16-31: PACKET_LEN_WITH_PADDING (Bytes)
+ */
+struct mux_hdr {
+	__u8	padding_info;
+	__u8	mux_id;
+	__le16	pkt_len_w_padding;
+} __packed;
 
 struct rmnet_ctrl_dev {
 
@@ -28,6 +57,10 @@
 
 	struct cdev		cdev;
 	struct device		*devicep;
+	unsigned		ch_id;
+
+	/*to identify the usb device*/
+	unsigned		id;
 
 	struct usb_interface	*intf;
 	unsigned int		int_pipe;
@@ -48,24 +81,17 @@
 	struct workqueue_struct	*wq;
 	struct work_struct	get_encap_work;
 
-	unsigned		is_opened;
+	unsigned long		status;
 
-	bool			is_connected;
+	bool			claimed;
+
+	unsigned int		mdm_wait_timeout;
 
 	/*input control lines (DSR, CTS, CD, RI)*/
 	unsigned int		cbits_tolocal;
-
 	/*output control lines (DTR, RTS)*/
 	unsigned int		cbits_tomdm;
 
-	/*
-	 * track first resp available from mdm when it boots up
-	 * to avoid bigger  timeout value used by qmuxd
-	 */
-	bool			resp_available;
-
-	unsigned int		mdm_wait_timeout;
-
 	/*counters*/
 	unsigned int		snd_encap_cmd_cnt;
 	unsigned int		get_encap_resp_cnt;
@@ -76,15 +102,17 @@
 	unsigned int		zlp_cnt;
 };
 
-extern struct rmnet_ctrl_dev *ctrl_dev[];
+extern struct workqueue_struct	*usbnet_wq;
 
 extern int rmnet_usb_ctrl_start_rx(struct rmnet_ctrl_dev *);
 extern int rmnet_usb_ctrl_suspend(struct rmnet_ctrl_dev *dev);
-extern int rmnet_usb_ctrl_init(void);
-extern void rmnet_usb_ctrl_exit(void);
+extern int rmnet_usb_ctrl_init(int num_devs, int insts_per_dev);
+extern void rmnet_usb_ctrl_exit(int num_devs, int insts_per_dev);
 extern int rmnet_usb_ctrl_probe(struct usb_interface *intf,
-		struct usb_host_endpoint *status,
-		struct rmnet_ctrl_dev *dev);
+				struct usb_host_endpoint *int_in,
+				unsigned long rmnet_devnum,
+				unsigned long *data);
 extern void rmnet_usb_ctrl_disconnect(struct rmnet_ctrl_dev *);
+extern void rmnet_usb_ctrl_cleanup(struct rmnet_ctrl_dev *dev);
 
 #endif /* __RMNET_USB_H*/
diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c
index c69bdc2..6be0858 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.c
+++ b/drivers/net/usb/rmnet_usb_ctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -19,10 +19,11 @@
 #include <linux/poll.h>
 #include <linux/ratelimit.h>
 #include <linux/debugfs.h>
-#include "rmnet_usb_ctrl.h"
+#include "rmnet_usb.h"
 
-#define DEVICE_NAME			"hsicctl"
-#define NUM_CTRL_CHANNELS		4
+static char *rmnet_dev_names[MAX_RMNET_DEVS] = {"hsicctl"};
+module_param_array(rmnet_dev_names, charp, NULL, S_IRUGO | S_IWUSR);
+
 #define DEFAULT_READ_URB_LENGTH		0x1000
 #define UNLINK_TIMEOUT_MS		500 /*random value*/
 
@@ -93,13 +94,19 @@
 				pr_info(x); \
 		} while (0)
 
-struct rmnet_ctrl_dev		*ctrl_dev[NUM_CTRL_CHANNELS];
-struct class			*ctrldev_classp;
-static dev_t			ctrldev_num;
+/* passed in rmnet_usb_ctrl_init */
+static int num_devs;
+static int insts_per_dev;
+
+/* dynamically allocated 2-D array of num_devs*insts_per_dev ctrl_devs */
+static struct rmnet_ctrl_dev **ctrl_devs;
+static struct class	*ctrldev_classp[MAX_RMNET_DEVS];
+static dev_t		ctrldev_num[MAX_RMNET_DEVS];
 
 struct ctrl_pkt {
 	size_t	data_size;
 	void	*data;
+	void	*ctxt;
 };
 
 struct ctrl_pkt_list_elem {
@@ -109,18 +116,56 @@
 
 static void resp_avail_cb(struct urb *);
 
-static int is_dev_connected(struct rmnet_ctrl_dev *dev)
+static int rmnet_usb_ctrl_dmux(struct ctrl_pkt_list_elem *clist)
 {
-	if (dev) {
-		mutex_lock(&dev->dev_lock);
-		if (!dev->is_connected) {
-			mutex_unlock(&dev->dev_lock);
-			return 0;
-		}
-		mutex_unlock(&dev->dev_lock);
-		return 1;
+	struct mux_hdr	*hdr;
+	size_t		pad_len;
+	size_t		total_len;
+	unsigned int	mux_id;
+
+	hdr = (struct mux_hdr *)clist->cpkt.data;
+	pad_len = hdr->padding_info >> MUX_PAD_SHIFT;
+	if (pad_len > MAX_PAD_BYTES(4)) {
+		pr_err_ratelimited("%s: Invalid pad len %d\n", __func__,
+				pad_len);
+		return -EINVAL;
 	}
-	return 0;
+
+	mux_id = hdr->mux_id;
+	if (!mux_id || mux_id > insts_per_dev) {
+		pr_err_ratelimited("%s: Invalid mux id %d\n", __func__, mux_id);
+		return -EINVAL;
+	}
+
+	total_len = le16_to_cpu(hdr->pkt_len_w_padding);
+	if (!total_len || !(total_len - pad_len)) {
+		pr_err_ratelimited("%s: Invalid pkt length %d\n", __func__,
+				total_len);
+		return -EINVAL;
+	}
+
+	clist->cpkt.data_size = total_len - pad_len;
+
+	return mux_id - 1;
+}
+
+static void rmnet_usb_ctrl_mux(unsigned int id, struct ctrl_pkt *cpkt)
+{
+	struct mux_hdr	*hdr;
+	size_t		len;
+	size_t		pad_len = 0;
+
+	hdr = (struct mux_hdr *)cpkt->data;
+	hdr->mux_id = id + 1;
+	len = cpkt->data_size - sizeof(struct mux_hdr) - MAX_PAD_BYTES(4);
+
+	/*add padding if len is not 4 byte aligned*/
+	pad_len =  ALIGN(len, 4) - len;
+
+	hdr->pkt_len_w_padding = cpu_to_le16(len + pad_len);
+	hdr->padding_info = (pad_len << MUX_PAD_SHIFT) | MUX_CTRL_MASK;
+
+	cpkt->data_size = sizeof(struct mux_hdr) + hdr->pkt_len_w_padding;
 }
 
 static void get_encap_work(struct work_struct *w)
@@ -130,6 +175,9 @@
 			container_of(w, struct rmnet_ctrl_dev, get_encap_work);
 	int			status;
 
+	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status))
+		return;
+
 	udev = interface_to_usbdev(dev->intf);
 
 	status = usb_autopm_get_interface(dev->intf);
@@ -216,14 +264,17 @@
 	case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
 		dev->resp_avail_cnt++;
 
-		usb_mark_last_busy(udev);
-		queue_work(dev->wq, &dev->get_encap_work);
-
-		if (!dev->resp_available) {
-			dev->resp_available = true;
+		/* If MUX is not enabled, wakeup up the open process
+		 * upon first notify response available.
+		 */
+		if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status)) {
+			set_bit(RMNET_CTRL_DEV_READY, &dev->status);
 			wake_up(&dev->open_wait_queue);
 		}
 
+		usb_mark_last_busy(udev);
+		queue_work(dev->wq, &dev->get_encap_work);
+
 		return;
 	default:
 		 dev_err(dev->devicep,
@@ -246,9 +297,9 @@
 {
 	struct usb_device		*udev;
 	struct ctrl_pkt_list_elem	*list_elem = NULL;
-	struct rmnet_ctrl_dev		*dev = urb->context;
+	struct rmnet_ctrl_dev		*rx_dev, *dev = urb->context;
 	void				*cpkt;
-	int				status = 0;
+	int				ch_id, status = 0;
 	size_t				cpkt_size = 0;
 
 	udev = interface_to_usbdev(dev->intf);
@@ -258,7 +309,6 @@
 	switch (urb->status) {
 	case 0:
 		/*success*/
-		dev->get_encap_resp_cnt++;
 		break;
 
 	/*do not resubmit*/
@@ -303,11 +353,27 @@
 	}
 	memcpy(list_elem->cpkt.data, cpkt, cpkt_size);
 	list_elem->cpkt.data_size = cpkt_size;
-	spin_lock(&dev->rx_lock);
-	list_add_tail(&list_elem->list, &dev->rx_list);
-	spin_unlock(&dev->rx_lock);
 
-	wake_up(&dev->read_wait_queue);
+	rx_dev = dev;
+
+	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) {
+		ch_id = rmnet_usb_ctrl_dmux(list_elem);
+		if (ch_id < 0) {
+			kfree(list_elem->cpkt.data);
+			kfree(list_elem);
+			goto resubmit_int_urb;
+		}
+
+		rx_dev = &ctrl_devs[dev->id][ch_id];
+	}
+
+	rx_dev->get_encap_resp_cnt++;
+
+	spin_lock(&rx_dev->rx_lock);
+	list_add_tail(&list_elem->list, &rx_dev->rx_list);
+	spin_unlock(&rx_dev->rx_lock);
+
+	wake_up(&rx_dev->read_wait_queue);
 
 resubmit_int_urb:
 	/*check if it is already submitted in resume*/
@@ -340,8 +406,6 @@
 
 static int rmnet_usb_ctrl_alloc_rx(struct rmnet_ctrl_dev *dev)
 {
-	int	retval = -ENOMEM;
-
 	dev->rcvurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->rcvurb) {
 		pr_err("%s: Error allocating read urb\n", __func__);
@@ -367,14 +431,14 @@
 	kfree(dev->rcvbuf);
 	kfree(dev->in_ctlreq);
 
-	return retval;
+	return -ENOMEM;
 
 }
 static int rmnet_usb_ctrl_write_cmd(struct rmnet_ctrl_dev *dev)
 {
 	struct usb_device	*udev;
 
-	if (!is_dev_connected(dev))
+	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status))
 		return -ENODEV;
 
 	udev = interface_to_usbdev(dev->intf);
@@ -389,7 +453,8 @@
 
 static void ctrl_write_callback(struct urb *urb)
 {
-	struct rmnet_ctrl_dev	*dev = urb->context;
+	struct ctrl_pkt		*cpkt = urb->context;
+	struct rmnet_ctrl_dev	*dev = cpkt->ctxt;
 
 	if (urb->status) {
 		dev->tx_ctrl_err_cnt++;
@@ -400,18 +465,19 @@
 	kfree(urb->setup_packet);
 	kfree(urb->transfer_buffer);
 	usb_free_urb(urb);
+	kfree(cpkt);
 	usb_autopm_put_interface_async(dev->intf);
 }
 
-static int rmnet_usb_ctrl_write(struct rmnet_ctrl_dev *dev, char *buf,
-		size_t size)
+static int rmnet_usb_ctrl_write(struct rmnet_ctrl_dev *dev,
+		struct ctrl_pkt *cpkt, size_t size)
 {
 	int			result;
 	struct urb		*sndurb;
 	struct usb_ctrlrequest	*out_ctlreq;
 	struct usb_device	*udev;
 
-	if (!is_dev_connected(dev))
+	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status))
 		return -ENETRESET;
 
 	udev = interface_to_usbdev(dev->intf);
@@ -435,12 +501,12 @@
 	out_ctlreq->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
 	out_ctlreq->wValue = 0;
 	out_ctlreq->wIndex = dev->intf->cur_altsetting->desc.bInterfaceNumber;
-	out_ctlreq->wLength = cpu_to_le16(size);
+	out_ctlreq->wLength = cpu_to_le16(cpkt->data_size);
 
 	usb_fill_control_urb(sndurb, udev,
 			     usb_sndctrlpipe(udev, 0),
-			     (unsigned char *)out_ctlreq, (void *)buf, size,
-			     ctrl_write_callback, dev);
+			     (unsigned char *)out_ctlreq, (void *)cpkt->data,
+			     cpkt->data_size, ctrl_write_callback, cpkt);
 
 	result = usb_autopm_get_interface(dev->intf);
 	if (result < 0) {
@@ -483,16 +549,15 @@
 	if (!dev)
 		return -ENODEV;
 
-	if (dev->is_opened)
+	if (test_bit(RMNET_CTRL_DEV_OPEN, &dev->status))
 		goto already_opened;
 
-	/*block open to get first response available from mdm*/
-	if (dev->mdm_wait_timeout && !dev->resp_available) {
+	if (dev->mdm_wait_timeout &&
+			!test_bit(RMNET_CTRL_DEV_READY, &dev->status)) {
 		retval = wait_event_interruptible_timeout(
-					dev->open_wait_queue,
-					dev->resp_available,
-					msecs_to_jiffies(dev->mdm_wait_timeout *
-									1000));
+				dev->open_wait_queue,
+				test_bit(RMNET_CTRL_DEV_READY, &dev->status),
+				msecs_to_jiffies(dev->mdm_wait_timeout * 1000));
 		if (retval == 0) {
 			dev_err(dev->devicep, "%s: Timeout opening %s\n",
 						__func__, dev->name);
@@ -504,15 +569,13 @@
 		}
 	}
 
-	if (!dev->resp_available) {
+	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status)) {
 		dev_dbg(dev->devicep, "%s: Connection timedout opening %s\n",
 					__func__, dev->name);
 		return -ETIMEDOUT;
 	}
 
-	mutex_lock(&dev->dev_lock);
-	dev->is_opened = 1;
-	mutex_unlock(&dev->dev_lock);
+	set_bit(RMNET_CTRL_DEV_OPEN, &dev->status);
 
 	file->private_data = dev;
 
@@ -547,9 +610,7 @@
 	}
 	spin_unlock_irqrestore(&dev->rx_lock, flag);
 
-	mutex_lock(&dev->dev_lock);
-	dev->is_opened = 0;
-	mutex_unlock(&dev->dev_lock);
+	clear_bit(RMNET_CTRL_DEV_OPEN, &dev->status);
 
 	time = usb_wait_anchor_empty_timeout(&dev->tx_submitted,
 			UNLINK_TIMEOUT_MS);
@@ -571,7 +632,7 @@
 		return POLLERR;
 
 	poll_wait(file, &dev->read_wait_queue, wait);
-	if (!is_dev_connected(dev)) {
+	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status)) {
 		dev_dbg(dev->devicep, "%s: Device not connected\n",
 			__func__);
 		return POLLERR;
@@ -588,6 +649,7 @@
 {
 	int				retval = 0;
 	int				bytes_to_read;
+	unsigned int			hdr_len = 0;
 	struct rmnet_ctrl_dev		*dev;
 	struct ctrl_pkt_list_elem	*list_elem = NULL;
 	unsigned long			flags;
@@ -599,7 +661,7 @@
 	DBG("%s: Read from %s\n", __func__, dev->name);
 
 ctrl_read:
-	if (!is_dev_connected(dev)) {
+	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status)) {
 		dev_dbg(dev->devicep, "%s: Device not connected\n",
 			__func__);
 		return -ENETRESET;
@@ -609,8 +671,8 @@
 		spin_unlock_irqrestore(&dev->rx_lock, flags);
 
 		retval = wait_event_interruptible(dev->read_wait_queue,
-					!list_empty(&dev->rx_list) ||
-					!is_dev_connected(dev));
+				!list_empty(&dev->rx_list) ||
+				!test_bit(RMNET_CTRL_DEV_READY, &dev->status));
 		if (retval < 0)
 			return retval;
 
@@ -628,7 +690,10 @@
 	}
 	spin_unlock_irqrestore(&dev->rx_lock, flags);
 
-	if (copy_to_user(buf, list_elem->cpkt.data, bytes_to_read)) {
+	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status))
+		hdr_len = sizeof(struct mux_hdr);
+
+	if (copy_to_user(buf, list_elem->cpkt.data + hdr_len, bytes_to_read)) {
 			dev_err(dev->devicep,
 				"%s: copy_to_user failed for %s\n",
 				__func__, dev->name);
@@ -651,7 +716,10 @@
 		size_t size, loff_t *pos)
 {
 	int			status;
+	size_t			total_len;
 	void			*wbuf;
+	void			*actual_data;
+	struct ctrl_pkt		*cpkt;
 	struct rmnet_ctrl_dev	*dev = file->private_data;
 
 	if (!dev)
@@ -660,26 +728,46 @@
 	if (size <= 0)
 		return -EINVAL;
 
-	if (!is_dev_connected(dev))
+	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status))
 		return -ENETRESET;
 
 	DBG("%s: Writing %i bytes on %s\n", __func__, size, dev->name);
 
-	wbuf = kmalloc(size , GFP_KERNEL);
+	total_len = size;
+
+	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status))
+		total_len += sizeof(struct mux_hdr) + MAX_PAD_BYTES(4);
+
+	wbuf = kmalloc(total_len , GFP_KERNEL);
 	if (!wbuf)
 		return -ENOMEM;
 
-	status = copy_from_user(wbuf , buf, size);
+	cpkt = kmalloc(sizeof(struct ctrl_pkt), GFP_KERNEL);
+	if (!cpkt) {
+		kfree(wbuf);
+		return -ENOMEM;
+	}
+	actual_data = cpkt->data = wbuf;
+	cpkt->data_size = total_len;
+	cpkt->ctxt = dev;
+
+	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) {
+		actual_data = wbuf + sizeof(struct mux_hdr);
+		rmnet_usb_ctrl_mux(dev->ch_id, cpkt);
+	}
+
+	status = copy_from_user(actual_data, buf, size);
 	if (status) {
 		dev_err(dev->devicep,
 		"%s: Unable to copy data from userspace %d\n",
 		__func__, status);
 		kfree(wbuf);
+		kfree(cpkt);
 		return status;
 	}
 	DUMP_BUFFER("Write: ", size, buf);
 
-	status = rmnet_usb_ctrl_write(dev, wbuf, size);
+	status = rmnet_usb_ctrl_write(dev, cpkt, size);
 	if (status == size)
 		return size;
 
@@ -779,52 +867,52 @@
 	.poll = rmnet_ctl_poll,
 };
 
-int rmnet_usb_ctrl_probe(struct usb_interface *intf,
-		struct usb_host_endpoint *int_in, struct rmnet_ctrl_dev *dev)
+void rmnet_usb_ctrl_cleanup(struct rmnet_ctrl_dev *dev)
 {
+	if (dev) {
+		usb_free_urb(dev->inturb);
+		kfree(dev->intbuf);
+	}
+}
+
+int rmnet_usb_ctrl_probe(struct usb_interface *intf,
+			 struct usb_host_endpoint *int_in,
+			 unsigned long rmnet_devnum,
+			 unsigned long *data)
+{
+	struct rmnet_ctrl_dev		*dev = NULL;
 	u16				wMaxPacketSize;
 	struct usb_endpoint_descriptor	*ep;
-	struct usb_device		*udev;
+	struct usb_device		*udev = interface_to_usbdev(intf);
 	int				interval;
-	int				ret = 0;
+	int				ret = 0, n;
 
-	udev = interface_to_usbdev(intf);
+	/* Find next available ctrl_dev */
+	for (n = 0; n < insts_per_dev; n++) {
+		dev = &ctrl_devs[rmnet_devnum][n];
+		if (!dev->claimed)
+			break;
+	}
 
-	if (!dev) {
-		pr_err("%s: Ctrl device not found\n", __func__);
+	if (!dev || n == insts_per_dev) {
+		pr_err("%s: No available ctrl devices for %lu\n", __func__,
+			rmnet_devnum);
 		return -ENODEV;
 	}
+
 	dev->int_pipe = usb_rcvintpipe(udev,
 		int_in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
 
-	mutex_lock(&dev->dev_lock);
 	dev->intf = intf;
 
-	/*TBD: for now just update CD status*/
-	dev->cbits_tolocal = ACM_CTRL_CD;
+	dev->id = rmnet_devnum;
 
-	/*send DTR high to modem*/
-	dev->cbits_tomdm = ACM_CTRL_DTR;
-	mutex_unlock(&dev->dev_lock);
-
-	dev->resp_available = false;
 	dev->snd_encap_cmd_cnt = 0;
 	dev->get_encap_resp_cnt = 0;
 	dev->resp_avail_cnt = 0;
 	dev->tx_ctrl_err_cnt = 0;
 	dev->set_ctrl_line_state_cnt = 0;
 
-	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-			USB_CDC_REQ_SET_CONTROL_LINE_STATE,
-			(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE),
-			dev->cbits_tomdm,
-			dev->intf->cur_altsetting->desc.bInterfaceNumber,
-			NULL, 0, USB_CTRL_SET_TIMEOUT);
-	if (ret < 0)
-		return ret;
-
-	dev->set_ctrl_line_state_cnt++;
-
 	dev->inturb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->inturb) {
 		dev_err(dev->devicep, "Error allocating int urb\n");
@@ -861,22 +949,39 @@
 
 	usb_mark_last_busy(udev);
 	ret = rmnet_usb_ctrl_start_rx(dev);
-	if (!ret)
-		dev->is_connected = true;
+	if (ret) {
+		usb_free_urb(dev->inturb);
+		kfree(dev->intbuf);
+		return ret;
+	}
 
-	return ret;
+	dev->claimed = true;
+
+	/*mux info is passed to data parameter*/
+	if (*data)
+		set_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status);
+
+	*data = (unsigned long)dev;
+
+	/* If MUX is enabled, wakeup the open process here */
+	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) {
+		set_bit(RMNET_CTRL_DEV_READY, &dev->status);
+		wake_up(&dev->open_wait_queue);
+	}
+
+	return 0;
 }
 
 void rmnet_usb_ctrl_disconnect(struct rmnet_ctrl_dev *dev)
 {
+	dev->claimed = false;
+
+	clear_bit(RMNET_CTRL_DEV_READY, &dev->status);
 
 	mutex_lock(&dev->dev_lock);
-
 	/*TBD: for now just update CD status*/
 	dev->cbits_tolocal = ~ACM_CTRL_CD;
-
 	dev->cbits_tomdm = ~ACM_CTRL_DTR;
-	dev->is_connected = false;
 	mutex_unlock(&dev->dev_lock);
 
 	wake_up(&dev->read_wait_queue);
@@ -901,50 +1006,53 @@
 	struct rmnet_ctrl_dev	*dev;
 	char			*buf;
 	int			ret;
-	int			i;
+	int			i, n;
 	int			temp = 0;
 
 	buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
-	for (i = 0; i < NUM_CTRL_CHANNELS; i++) {
-		dev = ctrl_dev[i];
-		if (!dev)
-			continue;
-
-		temp += scnprintf(buf + temp, DEBUG_BUF_SIZE - temp,
-				"\n#ctrl_dev: %p     Name: %s#\n"
-				"snd encap cmd cnt         %u\n"
-				"resp avail cnt:           %u\n"
-				"get encap resp cnt:       %u\n"
-				"set ctrl line state cnt:  %u\n"
-				"tx_err_cnt:               %u\n"
-				"cbits_tolocal:            %d\n"
-				"cbits_tomdm:              %d\n"
-				"mdm_wait_timeout:         %u\n"
-				"zlp_cnt:                  %u\n"
-				"get_encap_failure_cnt     %u\n"
-				"dev opened:               %s\n",
-				dev, dev->name,
-				dev->snd_encap_cmd_cnt,
-				dev->resp_avail_cnt,
-				dev->get_encap_resp_cnt,
-				dev->set_ctrl_line_state_cnt,
-				dev->tx_ctrl_err_cnt,
-				dev->cbits_tolocal,
-				dev->cbits_tomdm,
-				dev->mdm_wait_timeout,
-				dev->zlp_cnt,
-				dev->get_encap_failure_cnt,
-				dev->is_opened ? "OPEN" : "CLOSE");
-
+	for (i = 0; i < num_devs; i++) {
+		for (n = 0; n < insts_per_dev; n++) {
+			dev = &ctrl_devs[i][n];
+			temp += scnprintf(buf + temp, DEBUG_BUF_SIZE - temp,
+					"\n#ctrl_dev: %p     Name: %s#\n"
+					"snd encap cmd cnt         %u\n"
+					"resp avail cnt:           %u\n"
+					"get encap resp cnt:       %u\n"
+					"set ctrl line state cnt:  %u\n"
+					"tx_err_cnt:               %u\n"
+					"cbits_tolocal:            %d\n"
+					"cbits_tomdm:              %d\n"
+					"mdm_wait_timeout:         %u\n"
+					"zlp_cnt:                  %u\n"
+					"get_encap_failure_cnt     %u\n"
+					"RMNET_CTRL_DEV_MUX_EN:    %d\n"
+					"RMNET_CTRL_DEV_OPEN:      %d\n"
+					"RMNET_CTRL_DEV_READY:     %d\n",
+					dev, dev->name,
+					dev->snd_encap_cmd_cnt,
+					dev->resp_avail_cnt,
+					dev->get_encap_resp_cnt,
+					dev->set_ctrl_line_state_cnt,
+					dev->tx_ctrl_err_cnt,
+					dev->cbits_tolocal,
+					dev->cbits_tomdm,
+					dev->mdm_wait_timeout,
+					dev->zlp_cnt,
+					dev->get_encap_failure_cnt,
+					test_bit(RMNET_CTRL_DEV_MUX_EN,
+							&dev->status),
+					test_bit(RMNET_CTRL_DEV_OPEN,
+							&dev->status),
+					test_bit(RMNET_CTRL_DEV_READY,
+							&dev->status));
+		}
 	}
 
 	ret = simple_read_from_buffer(ubuf, count, ppos, buf, temp);
-
 	kfree(buf);
-
 	return ret;
 }
 
@@ -952,19 +1060,19 @@
 		buf, size_t count, loff_t *ppos)
 {
 	struct rmnet_ctrl_dev	*dev;
-	int			i;
+	int			i, n;
 
-	for (i = 0; i < NUM_CTRL_CHANNELS; i++) {
-		dev = ctrl_dev[i];
-		if (!dev)
-			continue;
+	for (i = 0; i < num_devs; i++) {
+		for (n = 0; n < insts_per_dev; n++) {
+			dev = &ctrl_devs[i][n];
 
-		dev->snd_encap_cmd_cnt = 0;
-		dev->resp_avail_cnt = 0;
-		dev->get_encap_resp_cnt = 0;
-		dev->set_ctrl_line_state_cnt = 0;
-		dev->tx_ctrl_err_cnt = 0;
-		dev->zlp_cnt = 0;
+			dev->snd_encap_cmd_cnt = 0;
+			dev->resp_avail_cnt = 0;
+			dev->get_encap_resp_cnt = 0;
+			dev->set_ctrl_line_state_cnt = 0;
+			dev->tx_ctrl_err_cnt = 0;
+			dev->zlp_cnt = 0;
+		}
 	}
 	return count;
 }
@@ -999,144 +1107,152 @@
 static void rmnet_usb_ctrl_debugfs_exit(void) { }
 #endif
 
-int rmnet_usb_ctrl_init(void)
+int rmnet_usb_ctrl_init(int no_rmnet_devs, int no_rmnet_insts_per_dev)
 {
 	struct rmnet_ctrl_dev	*dev;
-	int			n;
+	int			i, n;
 	int			status;
 
-	for (n = 0; n < NUM_CTRL_CHANNELS; ++n) {
+	num_devs = no_rmnet_devs;
+	insts_per_dev = no_rmnet_insts_per_dev;
 
-		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-		if (!dev) {
-			status = -ENOMEM;
-			goto error0;
-		}
-		/*for debug purpose*/
-		snprintf(dev->name, CTRL_DEV_MAX_LEN, "hsicctl%d", n);
+	ctrl_devs = kzalloc(num_devs * sizeof(*ctrl_devs), GFP_KERNEL);
+	if (!ctrl_devs)
+		return -ENOMEM;
 
-		dev->wq = create_singlethread_workqueue(dev->name);
-		if (!dev->wq) {
-			pr_err("unable to allocate workqueue");
-			kfree(dev);
-			goto error0;
-		}
+	for (i = 0; i < num_devs; i++) {
+		ctrl_devs[i] = kzalloc(insts_per_dev * sizeof(*ctrl_devs[i]),
+				       GFP_KERNEL);
+		if (!ctrl_devs[i])
+			return -ENOMEM;
 
-		mutex_init(&dev->dev_lock);
-		spin_lock_init(&dev->rx_lock);
-		init_waitqueue_head(&dev->read_wait_queue);
-		init_waitqueue_head(&dev->open_wait_queue);
-		INIT_LIST_HEAD(&dev->rx_list);
-		init_usb_anchor(&dev->tx_submitted);
-		init_usb_anchor(&dev->rx_submitted);
-		INIT_WORK(&dev->get_encap_work, get_encap_work);
-
-		status = rmnet_usb_ctrl_alloc_rx(dev);
-		if (status < 0) {
-			kfree(dev);
-			goto error0;
-		}
-
-		ctrl_dev[n] = dev;
-	}
-
-	status = alloc_chrdev_region(&ctrldev_num, 0, NUM_CTRL_CHANNELS,
-			DEVICE_NAME);
-	if (IS_ERR_VALUE(status)) {
-		pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n",
-		       __func__, status);
-		goto error0;
-	}
-
-	ctrldev_classp = class_create(THIS_MODULE, DEVICE_NAME);
-	if (IS_ERR(ctrldev_classp)) {
-		pr_err("ERROR:%s: class_create() ENOMEM\n", __func__);
-		status = -ENOMEM;
-		goto error1;
-	}
-	for (n = 0; n < NUM_CTRL_CHANNELS; ++n) {
-		cdev_init(&ctrl_dev[n]->cdev, &ctrldev_fops);
-		ctrl_dev[n]->cdev.owner = THIS_MODULE;
-
-		status = cdev_add(&ctrl_dev[n]->cdev, (ctrldev_num + n), 1);
-
+		status = alloc_chrdev_region(&ctrldev_num[i], 0, insts_per_dev,
+					     rmnet_dev_names[i]);
 		if (IS_ERR_VALUE(status)) {
-			pr_err("%s: cdev_add() ret %i\n", __func__, status);
-			kfree(ctrl_dev[n]);
-			goto error2;
+			pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n",
+				__func__, status);
+			return status;
 		}
 
-		ctrl_dev[n]->devicep =
-				device_create(ctrldev_classp, NULL,
-				(ctrldev_num + n), NULL,
-				DEVICE_NAME "%d", n);
+		ctrldev_classp[i] = class_create(THIS_MODULE,
+						 rmnet_dev_names[i]);
+		if (IS_ERR(ctrldev_classp[i])) {
+			pr_err("ERROR:%s: class_create() ENOMEM\n", __func__);
+			status = PTR_ERR(ctrldev_classp[i]);
+			return status;
+		}
 
-		if (IS_ERR(ctrl_dev[n]->devicep)) {
-			pr_err("%s: device_create() ENOMEM\n", __func__);
-			status = -ENOMEM;
-			cdev_del(&ctrl_dev[n]->cdev);
-			kfree(ctrl_dev[n]);
-			goto error2;
+		for (n = 0; n < insts_per_dev; n++) {
+			dev = &ctrl_devs[i][n];
+
+			/*for debug purpose*/
+			snprintf(dev->name, CTRL_DEV_MAX_LEN, "%s%d",
+				 rmnet_dev_names[i], n);
+
+			dev->wq = create_singlethread_workqueue(dev->name);
+			if (!dev->wq) {
+				pr_err("unable to allocate workqueue");
+				kfree(dev);
+				return -ENOMEM;
+			}
+
+			dev->ch_id = n;
+
+			mutex_init(&dev->dev_lock);
+			spin_lock_init(&dev->rx_lock);
+			init_waitqueue_head(&dev->read_wait_queue);
+			init_waitqueue_head(&dev->open_wait_queue);
+			INIT_LIST_HEAD(&dev->rx_list);
+			init_usb_anchor(&dev->tx_submitted);
+			init_usb_anchor(&dev->rx_submitted);
+			INIT_WORK(&dev->get_encap_work, get_encap_work);
+
+			cdev_init(&dev->cdev, &ctrldev_fops);
+			dev->cdev.owner = THIS_MODULE;
+
+			status = cdev_add(&dev->cdev, (ctrldev_num[i] + n), 1);
+			if (status) {
+				pr_err("%s: cdev_add() ret %i\n", __func__,
+					status);
+				destroy_workqueue(dev->wq);
+				kfree(dev);
+				return status;
+			}
+
+			dev->devicep = device_create(ctrldev_classp[i], NULL,
+						     (ctrldev_num[i] + n), NULL,
+						     "%s%d", rmnet_dev_names[i],
+						     n);
+			if (IS_ERR(dev->devicep)) {
+				pr_err("%s: device_create() returned %ld\n",
+					__func__, PTR_ERR(dev->devicep));
+				cdev_del(&dev->cdev);
+				destroy_workqueue(dev->wq);
+				kfree(dev);
+				return PTR_ERR(dev->devicep);
+			}
+
+			/*create /sys/class/hsicctl/hsicctlx/modem_wait*/
+			status = device_create_file(dev->devicep,
+						    &dev_attr_modem_wait);
+			if (status) {
+				device_destroy(dev->devicep->class,
+					       dev->devicep->devt);
+				cdev_del(&dev->cdev);
+				destroy_workqueue(dev->wq);
+				kfree(dev);
+				return status;
+			}
+			dev_set_drvdata(dev->devicep, dev);
+
+			status = rmnet_usb_ctrl_alloc_rx(dev);
+			if (status) {
+				device_remove_file(dev->devicep,
+						   &dev_attr_modem_wait);
+				device_destroy(dev->devicep->class,
+					       dev->devicep->devt);
+				cdev_del(&dev->cdev);
+				destroy_workqueue(dev->wq);
+				kfree(dev);
+				return status;
+			}
 		}
-		/*create /sys/class/hsicctl/hsicctlx/modem_wait*/
-		status = device_create_file(ctrl_dev[n]->devicep,
-					&dev_attr_modem_wait);
-		if (status) {
-			device_destroy(ctrldev_classp,
-				MKDEV(MAJOR(ctrldev_num), n));
-			cdev_del(&ctrl_dev[n]->cdev);
-			kfree(ctrl_dev[n]);
-			goto error2;
-		}
-		dev_set_drvdata(ctrl_dev[n]->devicep, ctrl_dev[n]);
 	}
 
 	rmnet_usb_ctrl_debugfs_init();
 	pr_info("rmnet usb ctrl Initialized.\n");
 	return 0;
-
-error2:
-		while (--n >= 0) {
-			cdev_del(&ctrl_dev[n]->cdev);
-			device_destroy(ctrldev_classp,
-				MKDEV(MAJOR(ctrldev_num), n));
-		}
-
-		class_destroy(ctrldev_classp);
-		n = NUM_CTRL_CHANNELS;
-error1:
-	unregister_chrdev_region(MAJOR(ctrldev_num), NUM_CTRL_CHANNELS);
-error0:
-	while (--n >= 0)
-		kfree(ctrl_dev[n]);
-
-	return status;
 }
 
-void rmnet_usb_ctrl_exit(void)
+static void free_rmnet_ctrl_dev(struct rmnet_ctrl_dev *dev)
 {
-	int	i;
+	kfree(dev->in_ctlreq);
+	kfree(dev->rcvbuf);
+	kfree(dev->intbuf);
+	usb_free_urb(dev->rcvurb);
+	usb_free_urb(dev->inturb);
+	device_remove_file(dev->devicep, &dev_attr_modem_wait);
+	cdev_del(&dev->cdev);
+	destroy_workqueue(dev->wq);
+	device_destroy(dev->devicep->class,
+		       dev->devicep->devt);
+}
 
-	for (i = 0; i < NUM_CTRL_CHANNELS; ++i) {
-		if (!ctrl_dev[i])
-			return;
+void rmnet_usb_ctrl_exit(int no_rmnet_devs, int no_rmnet_insts_per_dev)
+{
+	int i, n;
 
-		kfree(ctrl_dev[i]->in_ctlreq);
-		kfree(ctrl_dev[i]->rcvbuf);
-		kfree(ctrl_dev[i]->intbuf);
-		usb_free_urb(ctrl_dev[i]->rcvurb);
-		usb_free_urb(ctrl_dev[i]->inturb);
-#if defined(DEBUG)
-		device_remove_file(ctrl_dev[i]->devicep, &dev_attr_modem_wait);
-#endif
-		cdev_del(&ctrl_dev[i]->cdev);
-		destroy_workqueue(ctrl_dev[i]->wq);
-		kfree(ctrl_dev[i]);
-		ctrl_dev[i] = NULL;
-		device_destroy(ctrldev_classp, MKDEV(MAJOR(ctrldev_num), i));
+	for (i = 0; i < no_rmnet_devs; i++) {
+		for (n = 0; n < no_rmnet_insts_per_dev; n++)
+			free_rmnet_ctrl_dev(&ctrl_devs[i][n]);
+
+		kfree(ctrl_devs[i]);
+
+		class_destroy(ctrldev_classp[i]);
+		if (ctrldev_num[i])
+			unregister_chrdev_region(ctrldev_num[i], insts_per_dev);
 	}
 
-	class_destroy(ctrldev_classp);
-	unregister_chrdev_region(MAJOR(ctrldev_num), NUM_CTRL_CHANNELS);
+	kfree(ctrl_devs);
 	rmnet_usb_ctrl_debugfs_exit();
 }
diff --git a/drivers/net/usb/rmnet_usb_data.c b/drivers/net/usb/rmnet_usb_data.c
index f0b5595..945e5ac 100644
--- a/drivers/net/usb/rmnet_usb_data.c
+++ b/drivers/net/usb/rmnet_usb_data.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -17,14 +17,48 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/usb.h>
+#include <linux/ratelimit.h>
 #include <linux/usb/usbnet.h>
 #include <linux/msm_rmnet.h>
 
-#include "rmnet_usb_ctrl.h"
+#include "rmnet_usb.h"
 
 #define RMNET_DATA_LEN			2000
-#define HEADROOM_FOR_QOS		8
+#define RMNET_HEADROOM_W_MUX		(sizeof(struct mux_hdr) + \
+					sizeof(struct QMI_QOS_HDR_S))
+#define RMNET_HEADROOM			sizeof(struct QMI_QOS_HDR_S)
+#define RMNET_TAILROOM			MAX_PAD_BYTES(4);
 
+static unsigned int no_rmnet_devs = 1;
+module_param(no_rmnet_devs, uint, S_IRUGO | S_IWUSR);
+
+unsigned int no_rmnet_insts_per_dev = 4;
+module_param(no_rmnet_insts_per_dev, uint, S_IRUGO | S_IWUSR);
+
+/*
+ * To support  mux on multiple devices, bit position represents device
+ * and value represnts if mux is enabled or disabled.
+ * e.g. bit 0: mdm over HSIC, bit1: mdm over hsusb
+ */
+static unsigned long mux_enabled;
+module_param(mux_enabled, ulong, S_IRUGO | S_IWUSR);
+
+static unsigned int no_fwd_rmnet_links;
+module_param(no_fwd_rmnet_links, uint, S_IRUGO | S_IWUSR);
+
+struct usbnet	*unet_list[TOTAL_RMNET_DEV_COUNT];
+
+/* net device name prefixes, indexed by driver_info->data */
+static const char * const rmnet_names[] = {
+	"rmnet_usb%d",
+	"rmnet2_usb%d",
+};
+
+/* net device reverse link name prefixes, indexed by driver_info->data */
+static const char * const rev_rmnet_names[] = {
+	"rev_rmnet_usb%d",
+	"rev_rmnet2_usb%d",
+};
 static int	data_msg_dbg_mask;
 
 enum {
@@ -80,43 +114,121 @@
 #define DBG1(x...) DBG(DEBUG_MASK_LVL1, x)
 #define DBG2(x...) DBG(DEBUG_MASK_LVL2, x)
 
-static void rmnet_usb_setup(struct net_device *);
+static int rmnet_data_start(void);
+static bool rmnet_data_init;
+
+static int rmnet_init(const char *val, const struct kernel_param *kp)
+{
+	int ret = 0;
+
+	if (rmnet_data_init) {
+		pr_err("dynamic setting rmnet params currently unsupported\n");
+		return -EINVAL;
+	}
+
+	ret = param_set_bool(val, kp);
+	if (ret)
+		return ret;
+
+	rmnet_data_start();
+
+	return ret;
+}
+
+static struct kernel_param_ops rmnet_init_ops = {
+	.set = rmnet_init,
+	.get = param_get_bool,
+};
+module_param_cb(rmnet_data_init, &rmnet_init_ops, &rmnet_data_init,
+		S_IRUGO | S_IWUSR);
+
+static void rmnet_usb_setup(struct net_device *, int mux_enabled);
 static int rmnet_ioctl(struct net_device *, struct ifreq *, int);
 
 static int rmnet_usb_suspend(struct usb_interface *iface, pm_message_t message)
 {
-	struct usbnet		*unet;
+	struct usbnet		*unet = usb_get_intfdata(iface);
 	struct rmnet_ctrl_dev	*dev;
+	int			i, n, rdev_cnt, unet_id;
+	int			retval = 0;
 
-	unet = usb_get_intfdata(iface);
+	rdev_cnt = unet->data[4] ? no_rmnet_insts_per_dev : 1;
 
-	dev = (struct rmnet_ctrl_dev *)unet->data[1];
+	for (n = 0; n < rdev_cnt; n++) {
+		unet_id = n + unet->driver_info->data * no_rmnet_insts_per_dev;
+		unet =
+		unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);
 
-	if (work_busy(&dev->get_encap_work))
-		return -EBUSY;
+		dev = (struct rmnet_ctrl_dev *)unet->data[1];
+		spin_lock_irq(&unet->txq.lock);
+		if (work_busy(&dev->get_encap_work) || unet->txq.qlen) {
+			spin_unlock_irq(&unet->txq.lock);
+			retval = -EBUSY;
+			goto abort_suspend;
+		}
 
-	if (usbnet_suspend(iface, message))
-		return -EBUSY;
+		set_bit(EVENT_DEV_ASLEEP, &unet->flags);
+		spin_unlock_irq(&unet->txq.lock);
 
-	usb_kill_anchored_urbs(&dev->rx_submitted);
+		usb_kill_anchored_urbs(&dev->rx_submitted);
+		if (work_busy(&dev->get_encap_work)) {
+			spin_lock_irq(&unet->txq.lock);
+			clear_bit(EVENT_DEV_ASLEEP, &unet->flags);
+			spin_unlock_irq(&unet->txq.lock);
+			retval = -EBUSY;
+			goto abort_suspend;
+		}
+	}
+
+	for (n = 0; n < rdev_cnt; n++) {
+		unet_id = n + unet->driver_info->data * no_rmnet_insts_per_dev;
+		unet =
+		unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);
+
+		dev = (struct rmnet_ctrl_dev *)unet->data[1];
+		netif_device_detach(unet->net);
+		usbnet_terminate_urbs(unet);
+		netif_device_attach(unet->net);
+	}
 
 	return 0;
+
+abort_suspend:
+	for (i = 0; i < n; i++) {
+		unet_id = i + unet->driver_info->data * no_rmnet_insts_per_dev;
+		unet =
+		unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);
+
+		dev = (struct rmnet_ctrl_dev *)unet->data[1];
+		rmnet_usb_ctrl_start_rx(dev);
+		spin_lock_irq(&unet->txq.lock);
+		clear_bit(EVENT_DEV_ASLEEP, &unet->flags);
+		spin_unlock_irq(&unet->txq.lock);
+	}
+	return retval;
 }
 
 static int rmnet_usb_resume(struct usb_interface *iface)
 {
-	int			retval = 0;
-	struct usbnet		*unet;
+	struct usbnet		*unet = usb_get_intfdata(iface);
 	struct rmnet_ctrl_dev	*dev;
+	int			n, rdev_cnt, unet_id;
 
-	unet = usb_get_intfdata(iface);
+	rdev_cnt = unet->data[4] ? no_rmnet_insts_per_dev : 1;
 
-	dev = (struct rmnet_ctrl_dev *)unet->data[1];
+	for (n = 0; n < rdev_cnt; n++) {
+		unet_id = n + unet->driver_info->data * no_rmnet_insts_per_dev;
+		unet =
+		unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(iface);
 
-	usbnet_resume(iface);
-	retval = rmnet_usb_ctrl_start_rx(dev);
+		dev = (struct rmnet_ctrl_dev *)unet->data[1];
+		rmnet_usb_ctrl_start_rx(dev);
+		usb_set_intfdata(iface, unet);
+		unet->suspend_count = 1;
+		usbnet_resume(iface);
+	}
 
-	return retval;
+	return 0;
 }
 
 static int rmnet_usb_bind(struct usbnet *usbnet, struct usb_interface *iface)
@@ -125,9 +237,13 @@
 	struct usb_host_endpoint	*bulk_in = NULL;
 	struct usb_host_endpoint	*bulk_out = NULL;
 	struct usb_host_endpoint	*int_in = NULL;
+	struct driver_info		*info = usbnet->driver_info;
 	int				status = 0;
 	int				i;
 	int				numends;
+	bool				mux;
+
+	mux = test_bit(info->data, &mux_enabled);
 
 	numends = iface->cur_altsetting->desc.bNumEndpoints;
 	for (i = 0; i < numends; i++) {
@@ -158,13 +274,72 @@
 	usbnet->status = int_in;
 
 	/*change name of net device to rmnet_usbx here*/
-	strlcpy(usbnet->net->name, "rmnet_usb%d", IFNAMSIZ);
+	if (mux && (info->in > no_fwd_rmnet_links))
+		strlcpy(usbnet->net->name, rev_rmnet_names[info->data],
+				IFNAMSIZ);
+	else
+		strlcpy(usbnet->net->name, rmnet_names[info->data],
+				IFNAMSIZ);
 
-	/*TBD: update rx_urb_size, curently set to eth frame len by usbnet*/
+	if (mux)
+		usbnet->rx_urb_size = usbnet->hard_mtu + sizeof(struct mux_hdr)
+			+ MAX_PAD_BYTES(4);
 out:
 	return status;
 }
 
+static int rmnet_usb_data_dmux(struct sk_buff *skb,  struct urb *rx_urb)
+{
+	struct mux_hdr	*hdr;
+	size_t		pad_len;
+	size_t		total_len;
+	unsigned int	mux_id;
+
+	hdr = (struct mux_hdr *)skb->data;
+	mux_id = hdr->mux_id;
+	if (!mux_id  || mux_id > no_rmnet_insts_per_dev) {
+		pr_err_ratelimited("%s: Invalid data channel id %u.\n",
+				__func__, mux_id);
+		return -EINVAL;
+	}
+
+	pad_len = hdr->padding_info >> MUX_PAD_SHIFT;
+	if (pad_len > MAX_PAD_BYTES(4)) {
+		pr_err_ratelimited("%s: Invalid pad len %d\n",
+			__func__, pad_len);
+		return -EINVAL;
+	}
+
+	total_len = le16_to_cpu(hdr->pkt_len_w_padding);
+	if (!total_len || !(total_len - pad_len)) {
+		pr_err_ratelimited("%s: Invalid pkt length %d\n", __func__,
+				total_len);
+		return -EINVAL;
+	}
+
+	skb->data = (unsigned char *)(hdr + 1);
+	skb_reset_tail_pointer(skb);
+	rx_urb->actual_length = total_len - pad_len;
+
+	return mux_id - 1;
+}
+
+static void rmnet_usb_data_mux(struct sk_buff *skb, unsigned int id)
+{
+	struct	mux_hdr *hdr;
+	size_t	len;
+
+	hdr = (struct mux_hdr *)skb_push(skb, sizeof(struct mux_hdr));
+	hdr->mux_id = id + 1;
+	len = skb->len - sizeof(struct mux_hdr);
+
+	/*add padding if len is not 4 byte aligned*/
+	skb_put(skb, ALIGN(len, 4) - len);
+
+	hdr->pkt_len_w_padding = cpu_to_le16(skb->len - sizeof(struct mux_hdr));
+	hdr->padding_info = (ALIGN(len, 4) - len) << MUX_PAD_SHIFT;
+}
+
 static struct sk_buff *rmnet_usb_tx_fixup(struct usbnet *dev,
 		struct sk_buff *skb, gfp_t flags)
 {
@@ -178,6 +353,9 @@
 		qmih->flow_id = skb->mark;
 	 }
 
+	if (dev->data[4])
+		rmnet_usb_data_mux(skb, dev->data[3]);
+
 	DBG1("[%s] Tx packet #%lu len=%d mark=0x%x\n",
 	    dev->net->name, dev->net->stats.tx_packets, skb->len, skb->mark);
 
@@ -206,10 +384,35 @@
 	return protocol;
 }
 
-static int rmnet_usb_rx_fixup(struct usbnet *dev,
-	struct sk_buff *skb)
+static void rmnet_usb_rx_complete(struct urb *rx_urb)
 {
+	struct sk_buff	*skb = (struct sk_buff *) rx_urb->context;
+	struct skb_data	*entry = (struct skb_data *) skb->cb;
+	struct usbnet	*dev = entry->dev;
+	unsigned int	unet_offset;
+	unsigned int	unet_id;
+	int		mux_id;
 
+	unet_offset =  dev->driver_info->data * no_rmnet_insts_per_dev;
+
+	if (!rx_urb->status && dev->data[4]) {
+		mux_id = rmnet_usb_data_dmux(skb, rx_urb);
+		if (mux_id < 0) {
+			/*resubmit urb and free skb in rx_complete*/
+			rx_urb->status = -EINVAL;
+		} else {
+			/*map urb to actual network iface based on mux id*/
+			unet_id = unet_offset + mux_id;
+			skb->dev = unet_list[unet_id]->net;
+			entry->dev = unet_list[unet_id];
+		}
+	}
+
+	rx_complete(rx_urb);
+}
+
+static int rmnet_usb_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
 	if (test_bit(RMNET_MODE_LLP_IP, &dev->data[0]))
 		skb->protocol = rmnet_ip_type_trans(skb, dev->net);
 	else /*set zero for eth mode*/
@@ -270,7 +473,6 @@
 	.ndo_validate_addr = 0,
 };
 
-
 static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
 	struct usbnet	*unet = netdev_priv(dev);
@@ -306,7 +508,6 @@
 			dev->mtu = prev_mtu;
 			dev->addr_len = 0;
 			dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
-			dev->needed_headroom = HEADROOM_FOR_QOS;
 			dev->netdev_ops = &rmnet_usb_ops_ip;
 			clear_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);
 			set_bit(RMNET_MODE_LLP_IP, &unet->data[0]);
@@ -365,7 +566,7 @@
 	return rc;
 }
 
-static void rmnet_usb_setup(struct net_device *dev)
+static void rmnet_usb_setup(struct net_device *dev, int mux_enabled)
 {
 	/* Using Ethernet mode by default */
 	dev->netdev_ops = &rmnet_usb_ops_ether;
@@ -373,7 +574,15 @@
 	/* set this after calling ether_setup */
 	dev->mtu = RMNET_DATA_LEN;
 
-	dev->needed_headroom = HEADROOM_FOR_QOS;
+	if (mux_enabled) {
+		dev->needed_headroom = RMNET_HEADROOM_W_MUX;
+
+		/*max pad bytes for 4 byte alignment*/
+		dev->needed_tailroom = RMNET_TAILROOM;
+	} else {
+		dev->needed_headroom = RMNET_HEADROOM;
+	}
+
 	random_ether_addr(dev->dev_addr);
 	dev->watchdog_timeo = 1000; /* 10 seconds? */
 }
@@ -403,7 +612,6 @@
 	seq_printf(s, "tx errors:          %lu\n", unet->net->stats.tx_errors);
 	seq_printf(s, "tx packets:         %lu\n", unet->net->stats.tx_packets);
 	seq_printf(s, "tx bytes:           %lu\n", unet->net->stats.tx_bytes);
-	seq_printf(s, "suspend count:      %d\n", unet->suspend_count);
 	seq_printf(s, "EVENT_DEV_OPEN:     %d\n",
 			test_bit(EVENT_DEV_OPEN, &unet->flags));
 	seq_printf(s, "EVENT_TX_HALT:      %d\n",
@@ -458,21 +666,24 @@
 {
 	struct dentry *root = (struct dentry *)unet->data[2];
 
-	debugfs_remove_recursive(root);
-	unet->data[2] = 0;
+	if (root) {
+		debugfs_remove_recursive(root);
+		unet->data[2] = 0;
+	}
 }
 
 static int rmnet_usb_probe(struct usb_interface *iface,
 		const struct usb_device_id *prod)
 {
 	struct usbnet		*unet;
-	struct driver_info	*info;
+	struct driver_info	*info = (struct driver_info *)prod->driver_info;
 	struct usb_device	*udev;
-	unsigned int		iface_num;
-	static int		first_rmnet_iface_num = -EINVAL;
 	int			status = 0;
+	unsigned int		i, unet_id, rdev_cnt, n = 0;
+	bool			mux;
 
-	iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
+	udev = interface_to_usbdev(iface);
+
 	if (iface->num_altsetting != 1) {
 		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
 			__func__, iface->num_altsetting);
@@ -480,45 +691,63 @@
 		goto out;
 	}
 
-	info = (struct driver_info *)prod->driver_info;
-	if (!test_bit(iface_num, &info->data))
-		return -ENODEV;
+	mux = test_bit(info->data, &mux_enabled);
+	rdev_cnt = mux ? no_rmnet_insts_per_dev : 1;
+	info->in = 0;
 
-	status = usbnet_probe(iface, prod);
-	if (status < 0) {
-		dev_err(&iface->dev, "usbnet_probe failed %d\n", status);
-		goto out;
+	for (n = 0; n < rdev_cnt; n++) {
+
+		/* Use this filed to increment device count this will be
+		 * used by bind to determin the forward link and reverse
+		 * link network interface names.
+		 */
+		info->in++;
+		status = usbnet_probe(iface, prod);
+		if (status < 0) {
+			dev_err(&iface->dev, "usbnet_probe failed %d\n",
+					status);
+			goto out;
+		}
+
+		unet_id = n + info->data * no_rmnet_insts_per_dev;
+
+		unet_list[unet_id] = unet = usb_get_intfdata(iface);
+
+		/*store mux id for later access*/
+		unet->data[3] = n;
+
+		/*save mux info for control and usbnet devices*/
+		unet->data[1] = unet->data[4] = mux;
+
+		/*set rmnet operation mode to eth by default*/
+		set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);
+
+		/*update net device*/
+		rmnet_usb_setup(unet->net, mux);
+
+		/*create /sys/class/net/rmnet_usbx/dbg_mask*/
+		status = device_create_file(&unet->net->dev,
+				&dev_attr_dbg_mask);
+		if (status) {
+			free_netdev(unet->net);
+			usb_put_dev(udev);
+			goto out;
+		}
+
+		status = rmnet_usb_ctrl_probe(iface, unet->status, info->data,
+				&unet->data[1]);
+		if (status) {
+			device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
+			free_netdev(unet->net);
+			usb_put_dev(udev);
+			goto out;
+		}
+
+		status = rmnet_usb_data_debugfs_init(unet);
+		if (status)
+			dev_dbg(&iface->dev,
+					"mode debugfs file is not available\n");
 	}
-	unet = usb_get_intfdata(iface);
-
-	/*set rmnet operation mode to eth by default*/
-	set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);
-
-	/*update net device*/
-	rmnet_usb_setup(unet->net);
-
-	/*create /sys/class/net/rmnet_usbx/dbg_mask*/
-	status = device_create_file(&unet->net->dev, &dev_attr_dbg_mask);
-	if (status)
-		goto out;
-
-	if (first_rmnet_iface_num == -EINVAL)
-		first_rmnet_iface_num = iface_num;
-
-	/*save control device intstance */
-	unet->data[1] = (unsigned long)ctrl_dev	\
-			[iface_num - first_rmnet_iface_num];
-
-	status = rmnet_usb_ctrl_probe(iface, unet->status,
-		(struct rmnet_ctrl_dev *)unet->data[1]);
-	if (status)
-		goto out;
-
-	status = rmnet_usb_data_debugfs_init(unet);
-	if (status)
-		dev_dbg(&iface->dev, "mode debugfs file is not available\n");
-
-	udev = unet->udev;
 
 	usb_enable_autosuspend(udev);
 
@@ -532,83 +761,119 @@
 		pm_runtime_set_autosuspend_delay(&udev->parent->dev, 200);
 	}
 
+	return 0;
+
 out:
+	for (i = 0; i < n; i++) {
+		unet_id = i + info->data * no_rmnet_insts_per_dev;
+		rmnet_usb_ctrl_cleanup(
+			(struct rmnet_ctrl_dev *)unet_list[unet_id]->data[1]);
+		device_remove_file(&unet_list[unet_id]->net->dev,
+				&dev_attr_dbg_mask);
+		free_netdev(unet_list[unet_id]->net);
+		usb_put_dev(udev);
+	}
+
 	return status;
 }
 
 static void rmnet_usb_disconnect(struct usb_interface *intf)
 {
-	struct usbnet		*unet;
+	struct usbnet		*unet = usb_get_intfdata(intf);
 	struct rmnet_ctrl_dev	*dev;
+	unsigned int		n, rdev_cnt, unet_id;
 
-	unet = usb_get_intfdata(intf);
-	if (!unet) {
-		dev_err(&intf->dev, "%s:data device not found\n", __func__);
-		return;
-	}
+	rdev_cnt = unet->data[4] ? no_rmnet_insts_per_dev : 1;
 
 	device_set_wakeup_enable(&unet->udev->dev, 0);
-	rmnet_usb_data_debugfs_cleanup(unet);
 
-	dev = (struct rmnet_ctrl_dev *)unet->data[1];
-	if (!dev) {
-		dev_err(&intf->dev, "%s:ctrl device not found\n", __func__);
-		return;
+	for (n = 0; n < rdev_cnt; n++) {
+		unet_id = n + unet->driver_info->data * no_rmnet_insts_per_dev;
+		unet =
+		unet->data[4] ? unet_list[unet_id] : usb_get_intfdata(intf);
+		device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
+
+		dev = (struct rmnet_ctrl_dev *)unet->data[1];
+		rmnet_usb_ctrl_disconnect(dev);
+		unet->data[0] = 0;
+		unet->data[1] = 0;
+		rmnet_usb_data_debugfs_cleanup(unet);
+		usb_set_intfdata(intf, unet);
+		usbnet_disconnect(intf);
+		unet_list[unet_id] = NULL;
 	}
-	unet->data[0] = 0;
-	unet->data[1] = 0;
-	rmnet_usb_ctrl_disconnect(dev);
-	device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
-	usbnet_disconnect(intf);
 }
 
-/*bit position represents interface number*/
-#define PID9034_IFACE_MASK	0xF0
-#define PID9048_IFACE_MASK	0x1E0
-#define PID904C_IFACE_MASK	0x1C0
-
-static const struct driver_info rmnet_info_pid9034 = {
+static struct driver_info rmnet_info = {
 	.description   = "RmNET net device",
 	.flags         = FLAG_SEND_ZLP,
 	.bind          = rmnet_usb_bind,
 	.tx_fixup      = rmnet_usb_tx_fixup,
 	.rx_fixup      = rmnet_usb_rx_fixup,
+	.rx_complete   = rmnet_usb_rx_complete,
 	.manage_power  = rmnet_usb_manage_power,
-	.data          = PID9034_IFACE_MASK,
+	.data          = 0,
 };
 
-static const struct driver_info rmnet_info_pid9048 = {
+static struct driver_info rmnet_usb_info = {
 	.description   = "RmNET net device",
 	.flags         = FLAG_SEND_ZLP,
 	.bind          = rmnet_usb_bind,
 	.tx_fixup      = rmnet_usb_tx_fixup,
 	.rx_fixup      = rmnet_usb_rx_fixup,
+	.rx_complete   = rmnet_usb_rx_complete,
 	.manage_power  = rmnet_usb_manage_power,
-	.data          = PID9048_IFACE_MASK,
-};
-
-static const struct driver_info rmnet_info_pid904c = {
-	.description   = "RmNET net device",
-	.flags         = FLAG_SEND_ZLP,
-	.bind          = rmnet_usb_bind,
-	.tx_fixup      = rmnet_usb_tx_fixup,
-	.rx_fixup      = rmnet_usb_rx_fixup,
-	.manage_power  = rmnet_usb_manage_power,
-	.data          = PID904C_IFACE_MASK,
+	.data          = 1,
 };
 
 static const struct usb_device_id vidpids[] = {
-	{
-		USB_DEVICE(0x05c6, 0x9034), /* MDM9x15*/
-		.driver_info = (unsigned long)&rmnet_info_pid9034,
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9034, 4),
+	.driver_info = (unsigned long)&rmnet_info,
 	},
-	{
-		USB_DEVICE(0x05c6, 0x9048), /* MDM9x15*/
-		.driver_info = (unsigned long)&rmnet_info_pid9048,
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9034, 5),
+	.driver_info = (unsigned long)&rmnet_info,
 	},
-	{
-		USB_DEVICE(0x05c6, 0x904c), /* MDM9x15*/
-		.driver_info = (unsigned long)&rmnet_info_pid904c,
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9034, 6),
+	.driver_info = (unsigned long)&rmnet_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9034, 7),
+	.driver_info = (unsigned long)&rmnet_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9048, 5),
+	.driver_info = (unsigned long)&rmnet_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9048, 6),
+	.driver_info = (unsigned long)&rmnet_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9048, 7),
+	.driver_info = (unsigned long)&rmnet_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9048, 8),
+	.driver_info = (unsigned long)&rmnet_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x904c, 6),
+	.driver_info = (unsigned long)&rmnet_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x904c, 7),
+	.driver_info = (unsigned long)&rmnet_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x904c, 8),
+	.driver_info = (unsigned long)&rmnet_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9075, 6), /*mux over hsic mdm*/
+	.driver_info = (unsigned long)&rmnet_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9079, 5),
+	.driver_info = (unsigned long)&rmnet_usb_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9079, 6),
+	.driver_info = (unsigned long)&rmnet_usb_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9079, 7),
+	.driver_info = (unsigned long)&rmnet_usb_info,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9079, 8),
+	.driver_info = (unsigned long)&rmnet_usb_info,
 	},
 
 	{ }, /* Terminating entry */
@@ -626,31 +891,36 @@
 	.supports_autosuspend = true,
 };
 
-static int __init rmnet_usb_init(void)
+static int rmnet_data_start(void)
 {
 	int	retval;
 
+	if (no_rmnet_devs > MAX_RMNET_DEVS) {
+		pr_err("ERROR:%s: param no_rmnet_devs(%d) > than maximum(%d)",
+			__func__, no_rmnet_devs, MAX_RMNET_DEVS);
+		return -EINVAL;
+	}
+
+	/* initialize ctrl devices */
+	retval = rmnet_usb_ctrl_init(no_rmnet_devs, no_rmnet_insts_per_dev);
+	if (retval) {
+		err("rmnet_usb_cmux_init failed: %d", retval);
+		return retval;
+	}
+
 	retval = usb_register(&rmnet_usb);
 	if (retval) {
 		err("usb_register failed: %d", retval);
 		return retval;
 	}
-	/* initialize rmnet ctrl device here*/
-	retval = rmnet_usb_ctrl_init();
-	if (retval) {
-		usb_deregister(&rmnet_usb);
-		err("rmnet_usb_cmux_init failed: %d", retval);
-		return retval;
-	}
 
-	return 0;
+	return retval;
 }
-module_init(rmnet_usb_init);
 
 static void __exit rmnet_usb_exit(void)
 {
-	rmnet_usb_ctrl_exit();
 	usb_deregister(&rmnet_usb);
+	rmnet_usb_ctrl_exit(no_rmnet_devs, no_rmnet_insts_per_dev);
 }
 module_exit(rmnet_usb_exit);
 
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index e9130f6..d7c5df1 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -87,7 +87,7 @@
 
 static const char driver_name [] = "usbnet";
 
-static struct workqueue_struct	*usbnet_wq;
+struct workqueue_struct	*usbnet_wq;
 
 static DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
 
@@ -344,12 +344,11 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void rx_complete (struct urb *urb);
-
 static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
 {
 	struct sk_buff		*skb;
 	struct skb_data		*entry;
+	usb_complete_t		complete_fn;
 	int			retval = 0;
 	unsigned long		lockflags;
 	size_t			size = dev->rx_urb_size;
@@ -370,8 +369,13 @@
 	entry->dev = dev;
 	entry->length = 0;
 
+	if (dev->driver_info->rx_complete)
+		complete_fn = dev->driver_info->rx_complete;
+	else
+		complete_fn = rx_complete;
+
 	usb_fill_bulk_urb (urb, dev->udev, dev->in,
-		skb->data, size, rx_complete, skb);
+		skb->data, size, complete_fn, skb);
 
 	spin_lock_irqsave (&dev->rxq.lock, lockflags);
 
@@ -445,7 +449,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void rx_complete (struct urb *urb)
+void rx_complete(struct urb *urb)
 {
 	struct sk_buff		*skb = (struct sk_buff *) urb->context;
 	struct skb_data		*entry = (struct skb_data *) skb->cb;
@@ -531,6 +535,7 @@
 	}
 	netif_dbg(dev, rx_err, dev->net, "no read resubmitted\n");
 }
+EXPORT_SYMBOL_GPL(rx_complete);
 
 static void intr_complete (struct urb *urb)
 {
@@ -666,7 +671,7 @@
 /*-------------------------------------------------------------------------*/
 
 // precondition: never called in_interrupt
-static void usbnet_terminate_urbs(struct usbnet *dev)
+void usbnet_terminate_urbs(struct usbnet *dev)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	int temp;
@@ -691,6 +696,7 @@
 	dev->wait = NULL;
 	remove_wait_queue(&unlink_wakeup, &wait);
 }
+EXPORT_SYMBOL_GPL(usbnet_terminate_urbs);
 
 int usbnet_stop (struct net_device *net)
 {
diff --git a/drivers/net/wireless/libra/libra_sdioif.c b/drivers/net/wireless/libra/libra_sdioif.c
index 1d72a16..9938559 100644
--- a/drivers/net/wireless/libra/libra_sdioif.c
+++ b/drivers/net/wireless/libra/libra_sdioif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c b/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c
index ef0111a..7fa6cfc 100644
--- a/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c
+++ b/drivers/net/wireless/libra/qcomwlan7x27a_pwrif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/net/wireless/libra/qcomwlan_pwrif.c b/drivers/net/wireless/libra/qcomwlan_pwrif.c
index 52b1a51..1d01d65 100644
--- a/drivers/net/wireless/libra/qcomwlan_pwrif.c
+++ b/drivers/net/wireless/libra/qcomwlan_pwrif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/net/wireless/wcnss/qcomwlan_secif.c b/drivers/net/wireless/wcnss/qcomwlan_secif.c
index e2be75c..c16e48f 100644
--- a/drivers/net/wireless/wcnss/qcomwlan_secif.c
+++ b/drivers/net/wireless/wcnss/qcomwlan_secif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/net/wireless/wcnss/wcnss_riva.c b/drivers/net/wireless/wcnss/wcnss_riva.c
index 2d9ad82..d5ac58d 100644
--- a/drivers/net/wireless/wcnss/wcnss_riva.c
+++ b/drivers/net/wireless/wcnss/wcnss_riva.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -44,6 +44,9 @@
 #define RIVA_PMU_CFG_IRIS_XO_MODE         0x6
 #define RIVA_PMU_CFG_IRIS_XO_MODE_48      (3 << 1)
 
+#define RIVA_SPARE_OUT              (msm_riva_base + 0x0b4)
+#define NVBIN_DLND_BIT              BIT(25)
+
 #define VREG_NULL_CONFIG            0x0000
 #define VREG_GET_REGULATOR_MASK     0x0001
 #define VREG_SET_VOLTAGE_MASK       0x0002
@@ -102,6 +105,17 @@
 			pr_err("cxo enable failed\n");
 			goto fail;
 		}
+		/* NV bit is set to indicate that platform driver is capable
+		 * of doing NV download. SSR should not set NV bit; during
+		 * SSR NV bin is downloaded by WLAN drive.
+		 */
+		if (!wcnss_cold_boot_done()) {
+			pr_debug("wcnss: Indicate NV bin download\n");
+			reg = readl_relaxed(RIVA_SPARE_OUT);
+			reg |= NVBIN_DLND_BIT;
+			writel_relaxed(reg, RIVA_SPARE_OUT);
+		}
+
 		writel_relaxed(0, RIVA_PMU_CFG);
 		reg = readl_relaxed(RIVA_PMU_CFG);
 		reg |= RIVA_PMU_CFG_GC_BUS_MUX_SEL_TOP |
@@ -135,15 +149,15 @@
 			wlan_clock = msm_xo_get(MSM_XO_TCXO_A2, id);
 			if (IS_ERR(wlan_clock)) {
 				rc = PTR_ERR(wlan_clock);
-				pr_err("Failed to get MSM_XO_TCXO_A2 voter"
-							" (%d)\n", rc);
+				pr_err("Failed to get MSM_XO_TCXO_A2 voter (%d)\n",
+					rc);
 				goto fail;
 			}
 
 			rc = msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_ON);
 			if (rc < 0) {
-				pr_err("Configuring MSM_XO_MODE_ON failed"
-							" (%d)\n", rc);
+				pr_err("Configuring MSM_XO_MODE_ON failed (%d)\n",
+					rc);
 				goto msm_xo_vote_fail;
 			}
 		}
@@ -151,8 +165,8 @@
 		if (wlan_clock != NULL && !use_48mhz_xo) {
 			rc = msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_OFF);
 			if (rc < 0)
-				pr_err("Configuring MSM_XO_MODE_OFF failed"
-							" (%d)\n", rc);
+				pr_err("Configuring MSM_XO_MODE_OFF failed (%d)\n",
+					rc);
 		}
 	}
 
@@ -359,7 +373,11 @@
 	node = kmalloc(sizeof(struct host_driver), GFP_KERNEL);
 	if (!node)
 		goto err;
-	strncpy(node->name, driver_name, sizeof(node->name));
+	if (strlcpy(node->name, driver_name, sizeof(node->name))
+			>= sizeof(node->name)) {
+		kfree(node);
+		goto err;
+	}
 
 	mutex_lock(&list_lock);
 	/* Lock when the first request is added */
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 48620be..2babf20 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -11,6 +11,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/firmware.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/err.h>
@@ -23,7 +24,10 @@
 #include <linux/jiffies.h>
 #include <linux/gpio.h>
 #include <linux/wakelock.h>
+#include <linux/delay.h>
 #include <mach/peripheral-loader.h>
+#include <mach/msm_smd.h>
+#include <mach/msm_iomap.h>
 
 #define DEVICE "wcnss_wlan"
 #define VERSION "1.01"
@@ -31,6 +35,7 @@
 
 /* module params */
 #define WCNSS_CONFIG_UNSPECIFIED (-1)
+
 static int has_48mhz_xo = WCNSS_CONFIG_UNSPECIFIED;
 module_param(has_48mhz_xo, int, S_IWUSR | S_IRUGO);
 MODULE_PARM_DESC(has_48mhz_xo, "Is an external 48 MHz XO present");
@@ -43,6 +48,92 @@
 #define RIVA_SSR_BIT			BIT(23)
 #define RIVA_SUSPEND_BIT		BIT(24)
 
+#define MSM_RIVA_CCU_BASE			0x03200800
+
+#define CCU_INVALID_ADDR_OFFSET		0x100
+#define CCU_LAST_ADDR0_OFFSET		0x104
+#define CCU_LAST_ADDR1_OFFSET		0x108
+#define CCU_LAST_ADDR2_OFFSET		0x10c
+
+#define WCNSS_CTRL_CHANNEL			"WCNSS_CTRL"
+#define WCNSS_MAX_FRAME_SIZE		500
+#define WCNSS_VERSION_LEN			30
+
+/* message types */
+#define WCNSS_CTRL_MSG_START	0x01000000
+#define	WCNSS_VERSION_REQ		(WCNSS_CTRL_MSG_START + 0)
+#define	WCNSS_VERSION_RSP		(WCNSS_CTRL_MSG_START + 1)
+#define WCNSS_NVBIN_DNLD_REQ  (WCNSS_CTRL_MSG_START + 2)
+#define WCNSS_NVBIN_DNLD_RSP  (WCNSS_CTRL_MSG_START + 3)
+
+
+#define VALID_VERSION(version) \
+	((strncmp(version, "INVALID", WCNSS_VERSION_LEN)) ? 1 : 0)
+
+struct smd_msg_hdr {
+	unsigned int msg_type;
+	unsigned int msg_len;
+};
+
+struct wcnss_version {
+	struct smd_msg_hdr hdr;
+	unsigned char  major;
+	unsigned char  minor;
+	unsigned char  version;
+	unsigned char  revision;
+};
+
+#define NVBIN_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin"
+
+/*
+ * On SMD channel 4K of maximum data can be transferred, including message
+ * header, so NV fragment size as next multiple of 1Kb is 3Kb.
+ */
+#define NV_FRAGMENT_SIZE  3072
+
+/* Macro to find the total number fragments of the NV bin Image */
+#define TOTALFRAGMENTS(x) (((x % NV_FRAGMENT_SIZE) == 0) ? \
+	(x / NV_FRAGMENT_SIZE) : ((x / NV_FRAGMENT_SIZE) + 1))
+
+struct nvbin_dnld_req_params {
+	/*
+	 * Fragment sequence number of the NV bin Image. NV Bin Image
+	 * might not fit into one message due to size limitation of
+	 * the SMD channel FIFO so entire NV blob is chopped into
+	 * multiple fragments starting with seqeunce number 0. The
+	 * last fragment is indicated by marking is_last_fragment field
+	 * to 1. At receiving side, NV blobs would be concatenated
+	 * together without any padding bytes in between.
+	 */
+	unsigned short frag_number;
+
+	/*
+	 * When set to 1 it indicates that no more fragments will
+	 * be sent. Receiver shall send back response message after
+	 * last fragment.
+	 */
+	unsigned short is_last_fragment;
+
+	/* NV Image size (number of bytes) */
+	unsigned int nvbin_buffer_size;
+
+	/*
+	 * Following the 'nvbin_buffer_size', there should be
+	 * nvbin_buffer_size bytes of NV bin Image i.e.
+	 * uint8[nvbin_buffer_size].
+	 */
+};
+
+struct nvbin_dnld_req_msg {
+	/*
+	 * Note: The length specified in nvbin_dnld_req_msg messages
+	 * should be hdr.msg_len = sizeof(nvbin_dnld_req_msg) +
+	 * nvbin_buffer_size.
+	 */
+	struct smd_msg_hdr hdr;
+	struct nvbin_dnld_req_params dnld_req_params;
+};
+
 static struct {
 	struct platform_device *pdev;
 	void		*pil;
@@ -53,11 +144,17 @@
 	const struct dev_pm_ops *pm_ops;
 	int		triggered;
 	int		smd_channel_ready;
+	int		cold_boot_done;
+	smd_channel_t	*smd_ch;
+	unsigned char	wcnss_version[WCNSS_VERSION_LEN];
 	unsigned int	serial_number;
 	int		thermal_mitigation;
 	void		(*tm_notify)(struct device *, int);
 	struct wcnss_wlan_config wlan_config;
 	struct delayed_work wcnss_work;
+	struct work_struct wcnssctrl_version_work;
+	struct work_struct wcnssctrl_nvbin_dnld_work;
+	struct work_struct wcnssctrl_rx_work;
 	struct wake_lock wcnss_wake_lock;
 	void __iomem *msm_wcnss_base;
 } *penv = NULL;
@@ -118,6 +215,62 @@
 static DEVICE_ATTR(thermal_mitigation, S_IRUSR | S_IWUSR,
 	wcnss_thermal_mitigation_show, wcnss_thermal_mitigation_store);
 
+
+static ssize_t wcnss_version_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	if (!penv)
+		return -ENODEV;
+
+	return scnprintf(buf, PAGE_SIZE, "%s", penv->wcnss_version);
+}
+
+static DEVICE_ATTR(wcnss_version, S_IRUSR,
+		wcnss_version_show, NULL);
+
+/* wcnss_reset_intr() is invoked when host drivers fails to
+ * communicate with WCNSS over SMD; so logging these registers
+ * helps to know WCNSS failure reason */
+static void wcnss_log_ccpu_regs(void)
+{
+	void __iomem *ccu_base;
+	void __iomem *ccu_reg;
+	u32 reg = 0;
+
+	ccu_base = ioremap(MSM_RIVA_CCU_BASE, SZ_512);
+	if (!ccu_base) {
+		pr_err("%s: ioremap WCNSS CCU reg failed\n", __func__);
+		return;
+	}
+
+	ccu_reg = ccu_base + CCU_INVALID_ADDR_OFFSET;
+	reg = readl_relaxed(ccu_reg);
+	pr_info("%s: CCU_CCPU_INVALID_ADDR %08x\n", __func__, reg);
+
+	ccu_reg = ccu_base + CCU_LAST_ADDR0_OFFSET;
+	reg = readl_relaxed(ccu_reg);
+	pr_info("%s: CCU_CCPU_LAST_ADDR0 %08x\n", __func__, reg);
+
+	ccu_reg = ccu_base + CCU_LAST_ADDR1_OFFSET;
+	reg = readl_relaxed(ccu_reg);
+	pr_info("%s: CCU_CCPU_LAST_ADDR1 %08x\n", __func__, reg);
+
+	ccu_reg = ccu_base + CCU_LAST_ADDR2_OFFSET;
+	reg = readl_relaxed(ccu_reg);
+	pr_info("%s: CCU_CCPU_LAST_ADDR2 %08x\n", __func__, reg);
+
+	iounmap(ccu_base);
+}
+
+/* interface to reset Riva by sending the reset interrupt */
+void wcnss_reset_intr(void)
+{
+	wcnss_log_ccpu_regs();
+	wmb();
+	__raw_writel(1 << 24, MSM_APCS_GCC_BASE + 0x8);
+}
+EXPORT_SYMBOL(wcnss_reset_intr);
+
 static int wcnss_create_sysfs(struct device *dev)
 {
 	int ret;
@@ -130,11 +283,21 @@
 		return ret;
 
 	ret = device_create_file(dev, &dev_attr_thermal_mitigation);
-	if (ret) {
-		device_remove_file(dev, &dev_attr_serial_number);
-		return ret;
-	}
+	if (ret)
+		goto remove_serial;
+
+	ret = device_create_file(dev, &dev_attr_wcnss_version);
+	if (ret)
+		goto remove_thermal;
+
 	return 0;
+
+remove_thermal:
+	device_remove_file(dev, &dev_attr_thermal_mitigation);
+remove_serial:
+	device_remove_file(dev, &dev_attr_serial_number);
+
+	return ret;
 }
 
 static void wcnss_remove_sysfs(struct device *dev)
@@ -142,6 +305,39 @@
 	if (dev) {
 		device_remove_file(dev, &dev_attr_serial_number);
 		device_remove_file(dev, &dev_attr_thermal_mitigation);
+		device_remove_file(dev, &dev_attr_wcnss_version);
+	}
+}
+static void wcnss_smd_notify_event(void *data, unsigned int event)
+{
+	int len = 0;
+
+	if (penv != data) {
+		pr_err("wcnss: invalid env pointer in smd callback\n");
+		return;
+	}
+	switch (event) {
+	case SMD_EVENT_DATA:
+		len = smd_read_avail(penv->smd_ch);
+		if (len < 0)
+			pr_err("wcnss: failed to read from smd %d\n", len);
+		schedule_work(&penv->wcnssctrl_rx_work);
+		break;
+
+	case SMD_EVENT_OPEN:
+		pr_debug("wcnss: opening WCNSS SMD channel :%s",
+				WCNSS_CTRL_CHANNEL);
+		if (!VALID_VERSION(penv->wcnss_version))
+			schedule_work(&penv->wcnssctrl_version_work);
+		break;
+
+	case SMD_EVENT_CLOSE:
+		pr_debug("wcnss: closing WCNSS SMD channel :%s",
+				WCNSS_CTRL_CHANNEL);
+		break;
+
+	default:
+		break;
 	}
 }
 
@@ -223,6 +419,45 @@
 	.remove	= __devexit_p(wcnss_wlan_ctrl_remove),
 };
 
+static int __devexit
+wcnss_ctrl_remove(struct platform_device *pdev)
+{
+	if (penv && penv->smd_ch)
+		smd_close(penv->smd_ch);
+
+	return 0;
+}
+
+static int __devinit
+wcnss_ctrl_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+
+	if (!penv)
+		return -ENODEV;
+
+	ret = smd_named_open_on_edge(WCNSS_CTRL_CHANNEL, SMD_APPS_WCNSS,
+			&penv->smd_ch, penv, wcnss_smd_notify_event);
+	if (ret < 0) {
+		pr_err("wcnss: cannot open the smd command channel %s: %d\n",
+				WCNSS_CTRL_CHANNEL, ret);
+		return -ENODEV;
+	}
+	smd_disable_read_intr(penv->smd_ch);
+
+	return 0;
+}
+
+/* platform device for WCNSS_CTRL SMD channel */
+static struct platform_driver wcnss_ctrl_driver = {
+	.driver = {
+		.name	= "WCNSS_CTRL",
+		.owner	= THIS_MODULE,
+	},
+	.probe	= wcnss_ctrl_probe,
+	.remove	= __devexit_p(wcnss_ctrl_remove),
+};
+
 struct device *wcnss_wlan_get_device(void)
 {
 	if (penv && penv->pdev && penv->smd_channel_ready)
@@ -430,6 +665,214 @@
 }
 EXPORT_SYMBOL(wcnss_allow_suspend);
 
+int wcnss_cold_boot_done(void)
+{
+	if (penv)
+		return penv->cold_boot_done;
+	else
+		return -ENODEV;
+}
+EXPORT_SYMBOL(wcnss_cold_boot_done);
+
+
+static int wcnss_smd_tx(void *data, int len)
+{
+	int ret = 0;
+
+	ret = smd_write_avail(penv->smd_ch);
+	if (ret < len) {
+		pr_err("wcnss: no space available for smd frame\n");
+		return -ENOSPC;
+	}
+	ret = smd_write(penv->smd_ch, data, len);
+	if (ret < len) {
+		pr_err("wcnss: failed to write Command %d", len);
+		ret = -ENODEV;
+	}
+	return ret;
+}
+
+static void wcnssctrl_rx_handler(struct work_struct *worker)
+{
+	int len = 0;
+	int rc = 0;
+	unsigned char buf[WCNSS_MAX_FRAME_SIZE];
+	struct smd_msg_hdr *phdr;
+	struct wcnss_version *pversion;
+
+	len = smd_read_avail(penv->smd_ch);
+	if (len > WCNSS_MAX_FRAME_SIZE) {
+		pr_err("wcnss: frame larger than the allowed size\n");
+		smd_read(penv->smd_ch, NULL, len);
+		return;
+	}
+	if (len <= 0)
+		return;
+
+	rc = smd_read(penv->smd_ch, buf, len);
+	if (rc < len) {
+		pr_err("wcnss: incomplete data read from smd\n");
+		return;
+	}
+
+	phdr = (struct smd_msg_hdr *)buf;
+
+	switch (phdr->msg_type) {
+
+	case WCNSS_VERSION_RSP:
+		pversion = (struct wcnss_version *)buf;
+		if (len != sizeof(struct wcnss_version)) {
+			pr_err("wcnss: invalid version data from wcnss %d\n",
+				len);
+			return;
+		}
+		snprintf(penv->wcnss_version, WCNSS_VERSION_LEN,
+			"%02x%02x%02x%02x", pversion->major, pversion->minor,
+					pversion->version, pversion->revision);
+		pr_info("wcnss: version %s\n", penv->wcnss_version);
+		/*
+		 * schedule work to download nvbin to riva ccpu,
+		 * only if riva major >= 1 and minor >= 4.
+		 */
+		if ((pversion->major >= 1) && (pversion->minor >= 4)) {
+			pr_info("wcnss: schedule dnld work for riva\n");
+			schedule_work(&penv->wcnssctrl_nvbin_dnld_work);
+		}
+		break;
+
+	case WCNSS_NVBIN_DNLD_RSP:
+		pr_info("wcnss: received WCNSS_NVBIN_DNLD_RSP from ccpu\n");
+		break;
+
+	default:
+		pr_err("wcnss: invalid message type %d\n", phdr->msg_type);
+	}
+	return;
+}
+
+static void wcnss_send_version_req(struct work_struct *worker)
+{
+	struct smd_msg_hdr smd_msg;
+	int ret = 0;
+
+	smd_msg.msg_type = WCNSS_VERSION_REQ;
+	smd_msg.msg_len = sizeof(smd_msg);
+	ret = wcnss_smd_tx(&smd_msg, smd_msg.msg_len);
+	if (ret < 0)
+		pr_err("wcnss: smd tx failed\n");
+
+	return;
+}
+
+static void wcnss_nvbin_dnld_req(struct work_struct *worker)
+{
+	int ret = 0;
+	struct nvbin_dnld_req_msg *dnld_req_msg;
+	unsigned short total_fragments = 0;
+	unsigned short count = 0;
+	unsigned short retry_count = 0;
+	unsigned short cur_frag_size = 0;
+	unsigned char *outbuffer = NULL;
+	const void *nv_blob_addr = NULL;
+	unsigned int nv_blob_size = 0;
+	const struct firmware *nv = NULL;
+	struct device *dev = &penv->pdev->dev;
+
+	ret = request_firmware(&nv, NVBIN_FILE, dev);
+
+	if (ret || !nv || !nv->data || !nv->size) {
+		pr_err("wcnss: wcnss_nvbin_dnld_req: request_firmware failed for %s\n",
+			NVBIN_FILE);
+		return;
+	}
+
+	/*
+	 * First 4 bytes in nv blob is validity bitmap.
+	 * We cannot validate nv, so skip those 4 bytes.
+	 */
+	nv_blob_addr = nv->data + 4;
+	nv_blob_size = nv->size - 4;
+
+	total_fragments = TOTALFRAGMENTS(nv_blob_size);
+
+	pr_info("wcnss: NV bin size: %d, total_fragments: %d\n",
+		nv_blob_size, total_fragments);
+
+	/* get buffer for nv bin dnld req message */
+	outbuffer = kmalloc((sizeof(struct nvbin_dnld_req_msg) +
+		NV_FRAGMENT_SIZE), GFP_KERNEL);
+
+	if (NULL == outbuffer) {
+		pr_err("wcnss: wcnss_nvbin_dnld_req: failed to get buffer\n");
+		goto err_free_nv;
+	}
+
+	dnld_req_msg = (struct nvbin_dnld_req_msg *)outbuffer;
+
+	dnld_req_msg->hdr.msg_type = WCNSS_NVBIN_DNLD_REQ;
+
+	for (count = 0; count < total_fragments; count++) {
+		dnld_req_msg->dnld_req_params.frag_number = count;
+
+		if (count == (total_fragments - 1)) {
+			/* last fragment, take care of boundry condition */
+			cur_frag_size = nv_blob_size % NV_FRAGMENT_SIZE;
+			if (!cur_frag_size)
+				cur_frag_size = NV_FRAGMENT_SIZE;
+
+			dnld_req_msg->dnld_req_params.is_last_fragment = 1;
+		} else {
+			cur_frag_size = NV_FRAGMENT_SIZE;
+			dnld_req_msg->dnld_req_params.is_last_fragment = 0;
+		}
+
+		dnld_req_msg->dnld_req_params.nvbin_buffer_size =
+			cur_frag_size;
+
+		dnld_req_msg->hdr.msg_len =
+			sizeof(struct nvbin_dnld_req_msg) + cur_frag_size;
+
+		/* copy NV fragment */
+		memcpy((outbuffer + sizeof(struct nvbin_dnld_req_msg)),
+			(nv_blob_addr + count * NV_FRAGMENT_SIZE),
+			cur_frag_size);
+
+		ret = wcnss_smd_tx(outbuffer, dnld_req_msg->hdr.msg_len);
+
+		retry_count = 0;
+		while ((ret == -ENOSPC) && (retry_count <= 3)) {
+			pr_debug("wcnss: wcnss_nvbin_dnld_req: smd tx failed, ENOSPC\n");
+			pr_debug("fragment: %d, len: %d, TotFragments: %d, retry_count: %d\n",
+				count, dnld_req_msg->hdr.msg_len,
+				total_fragments, retry_count);
+
+			/* wait and try again */
+			msleep(20);
+			retry_count++;
+			ret = wcnss_smd_tx(outbuffer,
+					dnld_req_msg->hdr.msg_len);
+		}
+
+		if (ret < 0) {
+			pr_err("wcnss: wcnss_nvbin_dnld_req: smd tx failed\n");
+			pr_err("fragment %d, len: %d, TotFragments: %d, retry_count: %d\n",
+				count, dnld_req_msg->hdr.msg_len,
+				total_fragments, retry_count);
+			goto err_dnld;
+		}
+	}
+
+err_dnld:
+	/* free buffer */
+	kfree(outbuffer);
+
+err_free_nv:
+	/* release firmware */
+	release_firmware(nv);
+
+	return;
+}
+
 static int
 wcnss_trigger_config(struct platform_device *pdev)
 {
@@ -448,6 +891,7 @@
 	penv->wlan_config.use_48mhz_xo = has_48mhz_xo;
 
 	penv->thermal_mitigation = 0;
+	strlcpy(penv->wcnss_version, "INVALID", WCNSS_VERSION_LEN);
 
 	penv->gpios_5wire = platform_get_resource_byname(pdev, IORESOURCE_IO,
 							"wcnss_gpios_5wire");
@@ -497,10 +941,9 @@
 		goto fail_res;
 	}
 
-	/* register sysfs entries */
-	ret = wcnss_create_sysfs(&pdev->dev);
-	if (ret)
-		goto fail_sysfs;
+	INIT_WORK(&penv->wcnssctrl_rx_work, wcnssctrl_rx_handler);
+	INIT_WORK(&penv->wcnssctrl_version_work, wcnss_send_version_req);
+	INIT_WORK(&penv->wcnssctrl_nvbin_dnld_work, wcnss_nvbin_dnld_req);
 
 	wake_lock_init(&penv->wcnss_wake_lock, WAKE_LOCK_SUSPEND, "wcnss");
 
@@ -510,12 +953,13 @@
 		goto fail_wake;
 	}
 
+	penv->cold_boot_done = 1;
+
 	return 0;
 
 fail_wake:
 	wake_lock_destroy(&penv->wcnss_wake_lock);
 
-fail_sysfs:
 fail_res:
 	if (penv->pil)
 		pil_put(penv->pil);
@@ -557,6 +1001,8 @@
 static int __devinit
 wcnss_wlan_probe(struct platform_device *pdev)
 {
+	int ret = 0;
+
 	/* verify we haven't been called more than once */
 	if (penv) {
 		dev_err(&pdev->dev, "cannot handle multiple devices.\n");
@@ -571,6 +1017,12 @@
 	}
 	penv->pdev = pdev;
 
+	/* register sysfs entries */
+	ret = wcnss_create_sysfs(&pdev->dev);
+	if (ret)
+		return -ENOENT;
+
+
 #ifdef MODULE
 
 	/*
@@ -626,6 +1078,7 @@
 {
 	platform_driver_register(&wcnss_wlan_driver);
 	platform_driver_register(&wcnss_wlan_ctrl_driver);
+	platform_driver_register(&wcnss_ctrl_driver);
 
 	return 0;
 }
@@ -641,6 +1094,7 @@
 		penv = NULL;
 	}
 
+	platform_driver_unregister(&wcnss_ctrl_driver);
 	platform_driver_unregister(&wcnss_wlan_ctrl_driver);
 	platform_driver_unregister(&wcnss_wlan_driver);
 }
diff --git a/drivers/of/of_slimbus.c b/drivers/of/of_slimbus.c
index 8aaef25..9692185 100644
--- a/drivers/of/of_slimbus.c
+++ b/drivers/of/of_slimbus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/of/of_spmi.c b/drivers/of/of_spmi.c
index 0c23db5..3c51297 100644
--- a/drivers/of/of_spmi.c
+++ b/drivers/of/of_spmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/platform/msm/qpnp-clkdiv.c b/drivers/platform/msm/qpnp-clkdiv.c
index 2a9ba90..c55ed09 100644
--- a/drivers/platform/msm/qpnp-clkdiv.c
+++ b/drivers/platform/msm/qpnp-clkdiv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/platform/msm/qpnp-power-on.c b/drivers/platform/msm/qpnp-power-on.c
index 0119ebe..335d826 100644
--- a/drivers/platform/msm/qpnp-power-on.c
+++ b/drivers/platform/msm/qpnp-power-on.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/platform/msm/qpnp-pwm.c b/drivers/platform/msm/qpnp-pwm.c
index 6f9af36..60942f5 100644
--- a/drivers/platform/msm/qpnp-pwm.c
+++ b/drivers/platform/msm/qpnp-pwm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
 
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/platform/msm/sps/bam.c b/drivers/platform/msm/sps/bam.c
index eb9e8ee..a1b2e1b 100644
--- a/drivers/platform/msm/sps/bam.c
+++ b/drivers/platform/msm/sps/bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -842,21 +842,9 @@
 static void bam_output_register_content(void *base)
 {
 	u32 num_pipes;
-	u32 test_bus_selection[] = {0x1, 0x2, 0x3, 0x4, 0xD, 0x10,
-			0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
 	u32 i;
-	u32 size = sizeof(test_bus_selection) / sizeof(u32);
 
-	for (i = 0; i < size; i++) {
-		bam_write_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL,
-					test_bus_selection[i]);
-
-		SPS_INFO("sps:bam 0x%x(va);BAM_TEST_BUS_REG is"
-			"0x%x when BAM_TEST_BUS_SEL is 0x%x.",
-			(u32) base, bam_read_reg(base, TEST_BUS_REG),
-			bam_read_reg_field(base, TEST_BUS_SEL,
-					BAM_TESTBUS_SEL));
-	}
+	print_bam_test_bus_reg(base, 0);
 
 	print_bam_reg(base);
 
@@ -1359,7 +1347,7 @@
 }
 
 /* output descriptor FIFO of a pipe */
-void print_bam_pipe_desc_fifo(void *virt_addr, u32 pipe_index)
+void print_bam_pipe_desc_fifo(void *virt_addr, u32 pipe_index, u32 option)
 {
 	void *base = virt_addr;
 	u32 pipe = pipe_index;
@@ -1393,33 +1381,93 @@
 
 	desc_fifo = (u32 *) phys_to_virt(desc_fifo_addr);
 
-	SPS_INFO("-------------------- begin of FIFO --------------------\n");
+	if (option == 100) {
+		SPS_INFO("----- start of data blocks -----\n");
+		for (i = 0; i < desc_fifo_size; i += 8) {
+			u32 *data_block_vir;
+			u32 data_block_phy = desc_fifo[i / 4];
 
-	for (i = 0; i < desc_fifo_size; i += 0x10)
-		SPS_INFO("addr 0x%x: 0x%x, 0x%x, 0x%x, 0x%x.\n",
-			desc_fifo_addr + i,
-			desc_fifo[i / 4], desc_fifo[(i / 4) + 1],
-			desc_fifo[(i / 4) + 2], desc_fifo[(i / 4) + 3]);
+			if (data_block_phy) {
+				data_block_vir =
+					(u32 *) phys_to_virt(data_block_phy);
 
-	SPS_INFO("--------------------  end of FIFO  --------------------\n");
+				SPS_INFO("desc addr:0x%x; data addr:0x%x:\n",
+					desc_fifo_addr + i, data_block_phy);
+				SPS_INFO("0x%x, 0x%x, 0x%x, 0x%x\n",
+					data_block_vir[0], data_block_vir[1],
+					data_block_vir[2], data_block_vir[3]);
+				SPS_INFO("0x%x, 0x%x, 0x%x, 0x%x\n",
+					data_block_vir[4], data_block_vir[5],
+					data_block_vir[6], data_block_vir[7]);
+				SPS_INFO("0x%x, 0x%x, 0x%x, 0x%x\n",
+					data_block_vir[8], data_block_vir[9],
+					data_block_vir[10], data_block_vir[11]);
+				SPS_INFO("0x%x, 0x%x, 0x%x, 0x%x\n\n",
+					data_block_vir[12], data_block_vir[13],
+					data_block_vir[14], data_block_vir[15]);
+			}
+		}
+		SPS_INFO("----- end of data blocks -----\n");
+	} else if (option) {
+		u32 size = option * 128;
+		u32 current_desc = bam_pipe_get_desc_read_offset(base,
+								pipe_index);
+		u32 begin = 0;
+		u32 end = desc_fifo_size;
+
+		if (current_desc > size / 2)
+			begin = current_desc - size / 2;
+
+		if (desc_fifo_size > current_desc + size / 2)
+			end = current_desc + size / 2;
+
+		SPS_INFO("------------- begin of partial FIFO -------------\n");
+
+		for (i = begin; i < end; i += 0x10)
+			SPS_INFO("addr 0x%x: 0x%x, 0x%x, 0x%x, 0x%x.\n",
+				desc_fifo_addr + i,
+				desc_fifo[i / 4], desc_fifo[(i / 4) + 1],
+				desc_fifo[(i / 4) + 2], desc_fifo[(i / 4) + 3]);
+
+		SPS_INFO("-------------  end of partial FIFO  -------------\n");
+	} else {
+		SPS_INFO("----------------- begin of FIFO -----------------\n");
+
+		for (i = 0; i < desc_fifo_size; i += 0x10)
+			SPS_INFO("addr 0x%x: 0x%x, 0x%x, 0x%x, 0x%x.\n",
+				desc_fifo_addr + i,
+				desc_fifo[i / 4], desc_fifo[(i / 4) + 1],
+				desc_fifo[(i / 4) + 2], desc_fifo[(i / 4) + 3]);
+
+		SPS_INFO("-----------------  end of FIFO  -----------------\n");
+	}
 }
 
 /* output BAM_TEST_BUS_REG with specified TEST_BUS_SEL */
 void print_bam_test_bus_reg(void *base, u32 tb_sel)
 {
 	u32 i;
-	u32 test_bus_selection[] = {0x1, 0x2, 0x3, 0x4, 0xD, 0x10,
+	u32 test_bus_selection[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
+			0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+			0x20, 0x21, 0x22, 0x23,
 			0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
 	u32 size = sizeof(test_bus_selection) / sizeof(u32);
 
-	if ((base == NULL) || (tb_sel == 0))
+	if (base == NULL) {
+		SPS_ERR("sps:%s:BAM is NULL.\n", __func__);
 		return;
+	}
 
-	SPS_INFO("\nsps:Specified TEST_BUS_SEL value: 0x%x\n", tb_sel);
-	bam_write_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL, tb_sel);
-	SPS_INFO("sps:BAM_TEST_BUS_REG: 0x%x when TEST_BUS_SEL: 0x%x\n\n",
-		bam_read_reg(base, TEST_BUS_REG),
-		bam_read_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL));
+	if (tb_sel) {
+		SPS_INFO("\nsps:Specified TEST_BUS_SEL value: 0x%x\n", tb_sel);
+		bam_write_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL,
+					tb_sel);
+		SPS_INFO("sps:BAM_TEST_BUS_REG:0x%x for TEST_BUS_SEL:0x%x\n\n",
+			bam_read_reg(base, TEST_BUS_REG),
+			bam_read_reg_field(base, TEST_BUS_SEL,
+						BAM_TESTBUS_SEL));
+	}
 
 	/* output other selections */
 	for (i = 0; i < size; i++) {
diff --git a/drivers/platform/msm/sps/bam.h b/drivers/platform/msm/sps/bam.h
index c183fcd..7a2f4e6 100644
--- a/drivers/platform/msm/sps/bam.h
+++ b/drivers/platform/msm/sps/bam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index a3c1cea..6d04bfd 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -91,7 +91,7 @@
 u8 reg_dump_option;
 u32 testbus_sel;
 u32 bam_pipe_sel;
-
+u32 desc_option;
 
 static char *debugfs_buf;
 static u32 debugfs_buf_size;
@@ -106,6 +106,7 @@
 struct dentry *dfile_reg_dump_option;
 struct dentry *dfile_testbus_sel;
 struct dentry *dfile_bam_pipe_sel;
+struct dentry *dfile_desc_option;
 struct dentry *dfile_bam_addr;
 
 static struct sps_bam *phy2bam(u32 phys_addr);
@@ -341,41 +342,187 @@
 		break;
 	case 7: /* output desc FIFO of all pipes */
 		for (i = 0; i < num_pipes; i++)
-			print_bam_pipe_desc_fifo(vir_addr, i);
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		break;
 	case 8: /* output desc FIFO of selected pipes */
 		for (i = 0; i < num_pipes; i++)
 			if (bam_pipe_sel & (1UL << i))
-				print_bam_pipe_desc_fifo(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		break;
 	case 9: /* output desc FIFO of typical pipes */
-		print_bam_pipe_desc_fifo(vir_addr, 4);
-		print_bam_pipe_desc_fifo(vir_addr, 5);
+		print_bam_pipe_desc_fifo(vir_addr, 4, 0);
+		print_bam_pipe_desc_fifo(vir_addr, 5, 0);
 		break;
 	case 10: /* output selected registers and desc FIFO of all pipes */
 		for (i = 0; i < num_pipes; i++) {
 			print_bam_pipe_selected_reg(vir_addr, i);
-			print_bam_pipe_desc_fifo(vir_addr, i);
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		}
 		break;
 	case 11: /* output selected registers and desc FIFO of selected pipes */
 		for (i = 0; i < num_pipes; i++)
 			if (bam_pipe_sel & (1UL << i)) {
 				print_bam_pipe_selected_reg(vir_addr, i);
-				print_bam_pipe_desc_fifo(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
 			}
 		break;
 	case 12: /* output selected registers and desc FIFO of typical pipes */
 		print_bam_pipe_selected_reg(vir_addr, 4);
-		print_bam_pipe_desc_fifo(vir_addr, 4);
+		print_bam_pipe_desc_fifo(vir_addr, 4, 0);
 		print_bam_pipe_selected_reg(vir_addr, 5);
-		print_bam_pipe_desc_fifo(vir_addr, 5);
+		print_bam_pipe_desc_fifo(vir_addr, 5, 0);
 		break;
 	case 13: /* output BAM_TEST_BUS_REG */
 		if (testbus_sel)
 			print_bam_test_bus_reg(vir_addr, testbus_sel);
-		else
-			pr_info("sps:TEST_BUS_SEL should NOT be zero.");
+		else {
+			pr_info("sps:output TEST_BUS_REG for all TEST_BUS_SEL");
+			print_bam_test_bus_reg(vir_addr, testbus_sel);
+		}
+		break;
+	case 14: /* output partial desc FIFO of selected pipes */
+		if (desc_option == 0)
+			desc_option = 1;
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_option);
+		break;
+	case 15: /* output partial data blocks of descriptors */
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+		break;
+	case 16: /* output all registers of selected pipes */
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		break;
+	case 91: /* output testbus register, BAM global regisers
+			and registers of all pipes */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_selected_reg(vir_addr, i);
+		break;
+	case 92: /* output testbus register, BAM global regisers
+			and registers of selected pipes */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		break;
+	case 93: /* output registers and partial desc FIFOs
+			of selected pipes: format 1 */
+		if (desc_option == 0)
+			desc_option = 1;
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_option);
+		break;
+	case 94: /* output registers and partial desc FIFOs
+			of selected pipes: format 2 */
+		if (desc_option == 0)
+			desc_option = 1;
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_option);
+			}
+		break;
+	case 95: /* output registers and desc FIFOs
+			of selected pipes: format 1 */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		break;
+	case 96: /* output registers and desc FIFOs
+			of selected pipes: format 2 */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+			}
+		break;
+	case 97: /* output registers, desc FIFOs and partial data blocks
+			of selected pipes: format 1 */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+		break;
+	case 98: /* output registers, desc FIFOs and partial data blocks
+			of selected pipes: format 2 */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (bam_pipe_sel & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+			}
+		break;
+	case 99: /* output all registers, desc FIFOs and partial data blocks */
+		print_bam_test_bus_reg(vir_addr, testbus_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_desc_fifo(vir_addr, i, 100);
 		break;
 	default:
 		pr_info("sps:no dump option is chosen yet.");
@@ -397,6 +544,7 @@
 	reg_dump_option = 0;
 	testbus_sel = 0;
 	bam_pipe_sel = 0;
+	desc_option = 0;
 	debugfs_buf_size = 0;
 	debugfs_buf_used = 0;
 	wraparound = false;
@@ -446,21 +594,28 @@
 		goto reg_dump_option_err;
 	}
 
-	dfile_testbus_sel = debugfs_create_u32("testbus_sel", 0666,
+	dfile_testbus_sel = debugfs_create_u32("testbus_sel", 0664,
 						dent, &testbus_sel);
 	if (!dfile_testbus_sel || IS_ERR(dfile_testbus_sel)) {
 		pr_err("sps:fail to create debug_fs file for testbus_sel.\n");
 		goto testbus_sel_err;
 	}
 
-	dfile_bam_pipe_sel = debugfs_create_u32("bam_pipe_sel", 0666,
+	dfile_bam_pipe_sel = debugfs_create_u32("bam_pipe_sel", 0664,
 						dent, &bam_pipe_sel);
 	if (!dfile_bam_pipe_sel || IS_ERR(dfile_bam_pipe_sel)) {
 		pr_err("sps:fail to create debug_fs file for bam_pipe_sel.\n");
 		goto bam_pipe_sel_err;
 	}
 
-	dfile_bam_addr = debugfs_create_file("bam_addr", 0666,
+	dfile_desc_option = debugfs_create_u32("desc_option", 0664,
+						dent, &desc_option);
+	if (!dfile_desc_option || IS_ERR(dfile_desc_option)) {
+		pr_err("sps:fail to create debug_fs file for desc_option.\n");
+		goto desc_option_err;
+	}
+
+	dfile_bam_addr = debugfs_create_file("bam_addr", 0664,
 			dent, 0, &sps_bam_addr_ops);
 	if (!dfile_bam_addr || IS_ERR(dfile_bam_addr)) {
 		pr_err("sps:fail to create the file for debug_fs "
@@ -471,6 +626,8 @@
 	return;
 
 bam_addr_err:
+	debugfs_remove(dfile_desc_option);
+desc_option_err:
 	debugfs_remove(dfile_bam_pipe_sel);
 bam_pipe_sel_err:
 	debugfs_remove(dfile_testbus_sel);
@@ -504,6 +661,8 @@
 		debugfs_remove(dfile_testbus_sel);
 	if (dfile_bam_pipe_sel)
 		debugfs_remove(dfile_bam_pipe_sel);
+	if (dfile_desc_option)
+		debugfs_remove(dfile_desc_option);
 	if (dfile_bam_addr)
 		debugfs_remove(dfile_bam_addr);
 	if (dent)
@@ -515,7 +674,7 @@
 
 /* Get the debug info of BAM registers and descriptor FIFOs */
 int sps_get_bam_debug_info(u32 dev, u32 option, u32 para,
-		u32 tb_sel, u8 pre_level)
+		u32 tb_sel, u8 desc_sel)
 {
 	int res = 0;
 	struct sps_bam *bam;
@@ -568,35 +727,35 @@
 		break;
 	case 7: /* output desc FIFO of all pipes */
 		for (i = 0; i < num_pipes; i++)
-			print_bam_pipe_desc_fifo(vir_addr, i);
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		break;
 	case 8: /* output desc FIFO of selected pipes */
 		for (i = 0; i < num_pipes; i++)
 			if (para & (1UL << i))
-				print_bam_pipe_desc_fifo(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		break;
 	case 9: /* output desc FIFO of typical pipes */
-		print_bam_pipe_desc_fifo(vir_addr, 4);
-		print_bam_pipe_desc_fifo(vir_addr, 5);
+		print_bam_pipe_desc_fifo(vir_addr, 4, 0);
+		print_bam_pipe_desc_fifo(vir_addr, 5, 0);
 		break;
 	case 10: /* output selected registers and desc FIFO of all pipes */
 		for (i = 0; i < num_pipes; i++) {
 			print_bam_pipe_selected_reg(vir_addr, i);
-			print_bam_pipe_desc_fifo(vir_addr, i);
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
 		}
 		break;
 	case 11: /* output selected registers and desc FIFO of selected pipes */
 		for (i = 0; i < num_pipes; i++)
 			if (para & (1UL << i)) {
 				print_bam_pipe_selected_reg(vir_addr, i);
-				print_bam_pipe_desc_fifo(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
 			}
 		break;
 	case 12: /* output selected registers and desc FIFO of typical pipes */
 		print_bam_pipe_selected_reg(vir_addr, 4);
-		print_bam_pipe_desc_fifo(vir_addr, 4);
+		print_bam_pipe_desc_fifo(vir_addr, 4, 0);
 		print_bam_pipe_selected_reg(vir_addr, 5);
-		print_bam_pipe_desc_fifo(vir_addr, 5);
+		print_bam_pipe_desc_fifo(vir_addr, 5, 0);
 		break;
 	case 13: /* output BAM_TEST_BUS_REG */
 		if (tb_sel)
@@ -604,6 +763,150 @@
 		else
 			pr_info("sps:TEST_BUS_SEL should NOT be zero.");
 		break;
+	case 14: /* output partial desc FIFO of selected pipes */
+		if (desc_sel == 0)
+			desc_sel = 1;
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_sel);
+		break;
+	case 15: /* output partial data blocks of descriptors */
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+		break;
+	case 16: /* output all registers of selected pipes */
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		break;
+	case 91: /* output testbus register, BAM global regisers
+			and registers of all pipes */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_selected_reg(vir_addr, i);
+		break;
+	case 92: /* output testbus register, BAM global regisers
+			and registers of selected pipes */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		break;
+	case 93: /* output registers and partial desc FIFOs
+			of selected pipes: format 1 */
+		if (desc_sel == 0)
+			desc_sel = 1;
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_sel);
+		break;
+	case 94: /* output registers and partial desc FIFOs
+			of selected pipes: format 2 */
+		if (desc_sel == 0)
+			desc_sel = 1;
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i,
+							desc_sel);
+			}
+		break;
+	case 95: /* output registers and desc FIFOs
+			of selected pipes: format 1 */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		break;
+	case 96: /* output registers and desc FIFOs
+			of selected pipes: format 2 */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+			}
+		break;
+	case 97: /* output registers, desc FIFOs and partial data blocks
+			of selected pipes: format 1 */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i))
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+		break;
+	case 98: /* output registers, desc FIFOs and partial data blocks
+			of selected pipes: format 2 */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			if (para & (1UL << i)) {
+				print_bam_pipe_reg(vir_addr, i);
+				print_bam_pipe_selected_reg(vir_addr, i);
+				print_bam_pipe_desc_fifo(vir_addr, i, 0);
+				print_bam_pipe_desc_fifo(vir_addr, i, 100);
+			}
+		break;
+	case 99: /* output all registers, desc FIFOs and partial data blocks */
+		print_bam_test_bus_reg(vir_addr, tb_sel);
+		print_bam_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_reg(vir_addr, i);
+		print_bam_selected_reg(vir_addr);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_selected_reg(vir_addr, i);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_desc_fifo(vir_addr, i, 0);
+		for (i = 0; i < num_pipes; i++)
+			print_bam_pipe_desc_fifo(vir_addr, i, 100);
+		break;
 	default:
 		pr_info("sps:no option is chosen yet.");
 	}
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index a3bbb73..f413e3a 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -165,7 +165,8 @@
 
 	list_for_each_entry(pipe, &dev->pipes_q, list) {
 		/* Check this pipe's bit in the source mask */
-		if ((source & pipe->pipe_index_mask)) {
+		if (BAM_PIPE_IS_ASSIGNED(pipe)
+				&& (source & pipe->pipe_index_mask)) {
 			/* This pipe has an interrupt pending */
 			pipe_handler(dev, pipe);
 			source &= ~pipe->pipe_index_mask;
@@ -1049,6 +1050,13 @@
 		else {
 			pipe->sys.desc_cache =
 				vmalloc(pipe->desc_size + size);
+
+			if (pipe->sys.desc_cache == NULL) {
+				SPS_ERR("sps:No memory for pipe %d of BAM 0x%x",
+					pipe_index, BAM_ID(dev));
+				return -ENOMEM;
+			}
+
 			memset(pipe->sys.desc_cache, 0, pipe->desc_size + size);
 		}
 
diff --git a/drivers/platform/msm/sps/sps_bam.h b/drivers/platform/msm/sps/sps_bam.h
index 84d2b97..bbc0373 100644
--- a/drivers/platform/msm/sps/sps_bam.h
+++ b/drivers/platform/msm/sps/sps_bam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/platform/msm/sps/sps_core.h b/drivers/platform/msm/sps/sps_core.h
index 5bd7c65..9bd079e 100644
--- a/drivers/platform/msm/sps/sps_core.h
+++ b/drivers/platform/msm/sps/sps_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/platform/msm/sps/sps_dma.c b/drivers/platform/msm/sps/sps_dma.c
index f8b4f51d..b0aa6bd 100644
--- a/drivers/platform/msm/sps/sps_dma.c
+++ b/drivers/platform/msm/sps/sps_dma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/platform/msm/sps/sps_map.c b/drivers/platform/msm/sps/sps_map.c
index d98a8b1..d007b31 100644
--- a/drivers/platform/msm/sps/sps_map.c
+++ b/drivers/platform/msm/sps/sps_map.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/platform/msm/sps/sps_map.h b/drivers/platform/msm/sps/sps_map.h
index 692e47c..7db8043 100644
--- a/drivers/platform/msm/sps/sps_map.h
+++ b/drivers/platform/msm/sps/sps_map.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/platform/msm/sps/sps_mem.c b/drivers/platform/msm/sps/sps_mem.c
index fa22f1c..b44e3c4 100644
--- a/drivers/platform/msm/sps/sps_mem.c
+++ b/drivers/platform/msm/sps/sps_mem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/platform/msm/sps/sps_rm.c b/drivers/platform/msm/sps/sps_rm.c
index c980eb0..2b46203 100644
--- a/drivers/platform/msm/sps/sps_rm.c
+++ b/drivers/platform/msm/sps/sps_rm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -18,6 +18,7 @@
 #include <linux/list.h>		/* list_head */
 #include <linux/slab.h>		/* kzalloc() */
 #include <linux/memory.h>	/* memset */
+#include <linux/interrupt.h>
 
 #include "spsi.h"
 #include "sps_core.h"
@@ -555,8 +556,11 @@
 {
 	struct sps_connection *map = (void *)pipe->map;
 	struct sps_connect *cfg = &pipe->connect;
+	struct sps_bam *bam = pipe->bam;
+	unsigned long flags;
 
 	mutex_lock(&sps_rm->lock);
+	spin_lock_irqsave(&bam->isr_lock, flags);
 
 	/* Free this connection */
 	if (cfg->mode == SPS_MODE_SRC)
@@ -570,6 +574,7 @@
 
 	sps_rm_remove_ref(map);
 
+	spin_unlock_irqrestore(&bam->isr_lock, flags);
 	mutex_unlock(&sps_rm->lock);
 
 	return 0;
@@ -782,6 +787,8 @@
 	if (pipe->client_state == SPS_STATE_CONNECT &&
 	    state == SPS_STATE_DISCONNECT) {
 		struct sps_connection *map;
+		struct sps_bam *bam = pipe->bam;
+		unsigned long flags;
 		u32 pipe_index;
 
 		if (pipe->connect.mode == SPS_MODE_SRC)
@@ -789,8 +796,12 @@
 		else
 			pipe_index = pipe->map->dest.pipe_index;
 
+		if (bam->props.irq > 0)
+			synchronize_irq(bam->props.irq);
 
+		spin_lock_irqsave(&bam->isr_lock, flags);
 		result = sps_bam_pipe_disconnect(pipe->bam, pipe_index);
+		spin_unlock_irqrestore(&bam->isr_lock, flags);
 		if (result) {
 			SPS_ERR("sps:Failed to disconnect BAM 0x%x pipe %d",
 				pipe->bam->props.phys_addr,
diff --git a/drivers/platform/msm/sps/spsi.h b/drivers/platform/msm/sps/spsi.h
index 8a5deff..5b70fb0 100644
--- a/drivers/platform/msm/sps/spsi.h
+++ b/drivers/platform/msm/sps/spsi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -198,7 +198,7 @@
 void print_bam_pipe_selected_reg(void *, u32);
 
 /* output descriptor FIFO of a pipe */
-void print_bam_pipe_desc_fifo(void *, u32);
+void print_bam_pipe_desc_fifo(void *, u32, u32);
 
 /* output BAM_TEST_BUS_REG */
 void print_bam_test_bus_reg(void *, u32);
diff --git a/drivers/platform/msm/ssbi.c b/drivers/platform/msm/ssbi.c
index 265d56f..a08eb48 100644
--- a/drivers/platform/msm/ssbi.c
+++ b/drivers/platform/msm/ssbi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Copyright (c) 2010, Google Inc.
  *
  * Original authors: Code Aurora Forum
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index b7c73de..b5f6d82 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 5bcdf7d..00254dd 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -415,6 +415,14 @@
 	help
 	  Say Y here to enable support for pm8921 chip bms subdevice
 
+config BATTERY_BCL
+	tristate "Battery Current Limit driver"
+	help
+	  Say Y here to enable support for battery current limit
+	  device. The BCL driver will poll BMS if
+	  thermal daemon enables BCL.
+	  It will notify thermal daemon if IBat crosses Imax threshold.
+
 config CHARGER_SMB347
 	tristate "Summit Microelectronics SMB347 Battery Charger"
 	depends on I2C
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 007d75b..f84b527 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -58,3 +58,4 @@
 obj-$(CONFIG_PM8921_CHARGER)	+= pm8921-charger.o
 obj-$(CONFIG_LTC4088_CHARGER)	+= ltc4088-charger.o
 obj-$(CONFIG_CHARGER_SMB347)	+= smb347-charger.o
+obj-$(CONFIG_BATTERY_BCL)	+= battery_current_limit.o
diff --git a/drivers/power/battery_current_limit.c b/drivers/power/battery_current_limit.c
new file mode 100644
index 0000000..d1750ec
--- /dev/null
+++ b/drivers/power/battery_current_limit.c
@@ -0,0 +1,534 @@
+/* Copyright (c) 2012, The Linux Foundation. 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 and
+ * only 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.
+ *
+ */
+#define pr_fmt(fmt)	"%s: " fmt, __func__
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/power_supply.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+
+#define BCL_DEV_NAME "battery_current_limit"
+#define BCL_NAME_LENGTH 20
+/*
+ * Default BCL poll interval 1000 msec
+ */
+#define BCL_POLL_INTERVAL 1000
+/*
+ * Mininum BCL poll interval 10 msec
+ */
+#define MIN_BCL_POLL_INTERVAL 10
+
+static const char bcl_type[] = "bcl";
+
+/*
+ * Battery Current Limit Enable or Not
+ */
+enum bcl_device_mode {
+	BCL_DEVICE_DISABLED = 0,
+	BCL_DEVICE_ENABLED,
+};
+
+/*
+ * Battery Current Limit IBat Imax Threshold Mode
+ */
+enum bcl_ibat_imax_threshold_mode {
+	BCL_IBAT_IMAX_THRESHOLD_DISABLED = 0,
+	BCL_IBAT_IMAX_THRESHOLD_ENABLED,
+};
+
+/*
+ * Battery Current Limit Ibat Imax Trip Type (High and Low Threshold)
+ */
+enum bcl_ibat_imax_threshold_type {
+	BCL_IBAT_IMAX_THRESHOLD_TYPE_LOW = 0,
+	BCL_IBAT_IMAX_THRESHOLD_TYPE_HIGH,
+	BCL_IBAT_IMAX_THRESHOLD_TYPE_MAX,
+};
+
+/**
+ * BCL control block
+ *
+ */
+struct bcl_context {
+	/* BCL device */
+	struct device *dev;
+
+	/* BCL related config parameter */
+	/* BCL mode enable or not */
+	enum bcl_device_mode bcl_mode;
+	/* BCL Ibat/IMax Threshold Activate or Not */
+	enum bcl_ibat_imax_threshold_mode
+		bcl_threshold_mode[BCL_IBAT_IMAX_THRESHOLD_TYPE_MAX];
+	/* BCL Ibat/IMax Threshold value in milli Amp */
+	int bcl_threshold_value_ma[BCL_IBAT_IMAX_THRESHOLD_TYPE_MAX];
+	/* BCL Type */
+	char bcl_type[BCL_NAME_LENGTH];
+	/* BCL poll in usec */
+	int bcl_poll_interval_msec;
+
+	/* BCL realtime value based on poll */
+	/* BCL realtime ibat in milli Amp*/
+	int bcl_ibat_ma;
+	/* BCL realtime calculated imax in milli Amp*/
+	int bcl_imax_ma;
+	/* BCL realtime calculated ocv in uV*/
+	int bcl_ocv_uv;
+	/* BCL realtime vbat in mV*/
+	int bcl_vbat_mv;
+	/* BCL realtime rbat in mOhms*/
+	int bcl_rbat;
+	/* BCL period poll delay work structure  */
+	struct delayed_work     bcl_imax_work;
+
+};
+
+static struct bcl_context *gbcl;
+
+/*
+ * BCL imax calculation and trigger notification to user space
+ * if imax cross threshold
+ */
+static void bcl_calculate_imax_trigger(void)
+{
+	int ibatt_ua, vbatt_uv;
+	int imax_ma;
+	int ibatt_ma, vbatt_mv;
+	int imax_low_threshold;
+	int imax_high_threshold;
+	bool threshold_cross = false;
+	union power_supply_propval ret = {0,};
+	static struct power_supply *psy;
+
+	if (!gbcl) {
+		pr_err("called before initialization\n");
+		return;
+	}
+
+	if (psy == NULL) {
+		psy = power_supply_get_by_name("battery");
+		if (psy == NULL)
+			return;
+	}
+
+	if (psy->get_property(psy, POWER_SUPPLY_PROP_CURRENT_NOW, &ret))
+		return;
+	ibatt_ua = ret.intval;
+
+	if (psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &ret))
+		return;
+	vbatt_uv = ret.intval;
+
+	if (psy->get_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX, &ret))
+		return;
+	imax_ma = ret.intval/1000;
+
+	ibatt_ma = ibatt_ua/1000;
+	vbatt_mv = vbatt_uv/1000;
+
+	gbcl->bcl_ibat_ma = ibatt_ma;
+	gbcl->bcl_imax_ma = imax_ma;
+	gbcl->bcl_vbat_mv = vbatt_mv;
+
+	if (gbcl->bcl_threshold_mode[BCL_IBAT_IMAX_THRESHOLD_TYPE_HIGH]
+		== BCL_IBAT_IMAX_THRESHOLD_ENABLED) {
+		imax_high_threshold =
+		imax_ma - gbcl->bcl_threshold_value_ma
+			[BCL_IBAT_IMAX_THRESHOLD_TYPE_HIGH];
+		if (ibatt_ma >= imax_high_threshold)
+			threshold_cross = true;
+	}
+
+	if (gbcl->bcl_threshold_mode[BCL_IBAT_IMAX_THRESHOLD_TYPE_LOW]
+		== BCL_IBAT_IMAX_THRESHOLD_ENABLED) {
+		imax_low_threshold =
+		imax_ma - gbcl->bcl_threshold_value_ma
+			[BCL_IBAT_IMAX_THRESHOLD_TYPE_LOW];
+		if (ibatt_ma <= imax_low_threshold)
+			threshold_cross = true;
+	}
+
+	if (threshold_cross) {
+		sysfs_notify(&gbcl->dev->kobj,
+				NULL, "type");
+	}
+}
+
+/*
+ * BCL imax work
+ */
+static void bcl_imax_work(struct work_struct *work)
+{
+	struct bcl_context *bcl = container_of(work,
+			struct bcl_context, bcl_imax_work.work);
+
+	if (gbcl->bcl_mode == BCL_DEVICE_ENABLED) {
+		bcl_calculate_imax_trigger();
+		/* restart the delay work for caculating imax */
+		schedule_delayed_work(&bcl->bcl_imax_work,
+			round_jiffies_relative(msecs_to_jiffies
+				(bcl->bcl_poll_interval_msec)));
+	}
+}
+
+/*
+ * Set BCL mode
+ */
+static void bcl_mode_set(enum bcl_device_mode mode)
+{
+	if (!gbcl)
+		return;
+
+	if (gbcl->bcl_mode == mode)
+		return;
+
+	if (gbcl->bcl_mode == BCL_DEVICE_DISABLED
+		&& mode == BCL_DEVICE_ENABLED) {
+		gbcl->bcl_mode = mode;
+		bcl_imax_work(&(gbcl->bcl_imax_work.work));
+		return;
+	} else if (gbcl->bcl_mode == BCL_DEVICE_ENABLED
+		&& mode == BCL_DEVICE_DISABLED) {
+		gbcl->bcl_mode = mode;
+		cancel_delayed_work_sync(&(gbcl->bcl_imax_work));
+		return;
+	}
+
+	return;
+}
+
+#define show_bcl(name, variable, format) \
+static ssize_t \
+name##_show(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	if (gbcl) \
+		return snprintf(buf, PAGE_SIZE, format, gbcl->variable); \
+	else \
+		return  -EPERM; \
+}
+
+show_bcl(type, bcl_type, "%s\n")
+show_bcl(ibat, bcl_ibat_ma, "%d\n")
+show_bcl(imax, bcl_imax_ma, "%d\n")
+show_bcl(vbat, bcl_vbat_mv, "%d\n")
+show_bcl(rbat, bcl_rbat, "%d\n")
+show_bcl(ocv, bcl_ocv_uv, "%d\n")
+show_bcl(poll_interval, bcl_poll_interval_msec, "%d\n")
+
+static ssize_t
+mode_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	if (!gbcl)
+		return -EPERM;
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+		gbcl->bcl_mode == BCL_DEVICE_ENABLED ? "enabled"
+			: "disabled");
+}
+
+static ssize_t
+mode_store(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	if (!gbcl)
+		return -EPERM;
+
+	if (!strncmp(buf, "enabled", 7))
+		bcl_mode_set(BCL_DEVICE_ENABLED);
+	else if (!strncmp(buf, "disabled", 8))
+		bcl_mode_set(BCL_DEVICE_DISABLED);
+	else
+		return -EINVAL;
+
+	return count;
+}
+
+static ssize_t
+ibat_imax_low_threshold_mode_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	if (!gbcl)
+		return -EPERM;
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+		gbcl->bcl_threshold_mode[BCL_IBAT_IMAX_THRESHOLD_TYPE_LOW]
+		== BCL_IBAT_IMAX_THRESHOLD_ENABLED ? "enabled" : "disabled");
+}
+
+static ssize_t
+ibat_imax_low_threshold_mode_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	if (!gbcl)
+		return -EPERM;
+
+	if (!strncmp(buf, "enabled", 7))
+		gbcl->bcl_threshold_mode[BCL_IBAT_IMAX_THRESHOLD_TYPE_LOW]
+			= BCL_IBAT_IMAX_THRESHOLD_ENABLED;
+	else if (!strncmp(buf, "disabled", 8))
+		gbcl->bcl_threshold_mode[BCL_IBAT_IMAX_THRESHOLD_TYPE_LOW]
+			= BCL_IBAT_IMAX_THRESHOLD_DISABLED;
+	else
+		return -EINVAL;
+
+	return count;
+}
+
+static ssize_t
+ibat_imax_low_threshold_value_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	if (!gbcl)
+		return -EPERM;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+	gbcl->bcl_threshold_value_ma[BCL_IBAT_IMAX_THRESHOLD_TYPE_LOW]);
+}
+
+static ssize_t
+ibat_imax_low_threshold_value_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	int value;
+
+	if (!gbcl)
+		return -EPERM;
+
+	if (!sscanf(buf, "%d", &value))
+		return -EINVAL;
+
+	if (value < 0)
+		return -EINVAL;
+
+	gbcl->bcl_threshold_value_ma[BCL_IBAT_IMAX_THRESHOLD_TYPE_LOW]
+			= value;
+
+	return count;
+}
+
+static ssize_t
+ibat_imax_high_threshold_mode_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	if (!gbcl)
+		return -EPERM;
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+		gbcl->bcl_threshold_mode[BCL_IBAT_IMAX_THRESHOLD_TYPE_HIGH]
+		== BCL_IBAT_IMAX_THRESHOLD_ENABLED ? "enabled" : "disabled");
+}
+
+static ssize_t
+ibat_imax_high_threshold_mode_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	if (!gbcl)
+		return -EPERM;
+
+	if (!strncmp(buf, "enabled", 7))
+		gbcl->bcl_threshold_mode[BCL_IBAT_IMAX_THRESHOLD_TYPE_HIGH]
+		= BCL_IBAT_IMAX_THRESHOLD_ENABLED;
+	else if (!strncmp(buf, "disabled", 8))
+		gbcl->bcl_threshold_mode[BCL_IBAT_IMAX_THRESHOLD_TYPE_HIGH]
+		= BCL_IBAT_IMAX_THRESHOLD_DISABLED;
+	else
+		return -EINVAL;
+
+	return count;
+}
+
+static ssize_t
+ibat_imax_high_threshold_value_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	if (!gbcl)
+		return -EPERM;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+	gbcl->bcl_threshold_value_ma[BCL_IBAT_IMAX_THRESHOLD_TYPE_HIGH]);
+}
+
+static ssize_t
+ibat_imax_high_threshold_value_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	int value;
+
+	if (!gbcl)
+		return -EPERM;
+
+	if (!sscanf(buf, "%d", &value))
+		return -EINVAL;
+
+	if (value < 0)
+		return -EINVAL;
+
+	gbcl->bcl_threshold_value_ma[BCL_IBAT_IMAX_THRESHOLD_TYPE_HIGH]
+		= value;
+
+	return count;
+}
+
+static ssize_t
+poll_interval_store(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	int value;
+
+	if (!gbcl)
+		return -EPERM;
+
+	if (!sscanf(buf, "%d", &value))
+		return -EINVAL;
+
+	if (value < MIN_BCL_POLL_INTERVAL)
+		return -EINVAL;
+
+	gbcl->bcl_poll_interval_msec = value;
+
+	return count;
+}
+
+/*
+ * BCL device attributes
+ */
+static struct device_attribute bcl_dev_attr[] = {
+	__ATTR(type, 0444, type_show, NULL),
+	__ATTR(ibat, 0444, ibat_show, NULL),
+	__ATTR(vbat, 0444, vbat_show, NULL),
+	__ATTR(rbat, 0444, rbat_show, NULL),
+	__ATTR(ocv, 0444, ocv_show, NULL),
+	__ATTR(imax, 0444, imax_show, NULL),
+	__ATTR(mode, 0644, mode_show, mode_store),
+	__ATTR(poll_interval, 0644,
+		poll_interval_show, poll_interval_store),
+	__ATTR(ibat_imax_low_threshold_mode, 0644,
+		ibat_imax_low_threshold_mode_show,
+		ibat_imax_low_threshold_mode_store),
+	__ATTR(ibat_imax_high_threshold_mode, 0644,
+		ibat_imax_high_threshold_mode_show,
+		ibat_imax_high_threshold_mode_store),
+	__ATTR(ibat_imax_low_threshold_value, 0644,
+		ibat_imax_low_threshold_value_show,
+		ibat_imax_low_threshold_value_store),
+	__ATTR(ibat_imax_high_threshold_value, 0644,
+		ibat_imax_high_threshold_value_show,
+		ibat_imax_high_threshold_value_store)
+};
+
+static int create_bcl_sysfs(struct bcl_context *bcl)
+{
+	int result = 0;
+	int num_attr = sizeof(bcl_dev_attr)/sizeof(struct device_attribute);
+	int i;
+
+	for (i = 0; i < num_attr; i++) {
+		result = device_create_file(bcl->dev, &bcl_dev_attr[i]);
+		if (result < 0)
+			return result;
+	}
+
+	return 0;
+}
+
+static void remove_bcl_sysfs(struct bcl_context *bcl)
+{
+	int num_attr = sizeof(bcl_dev_attr)/sizeof(struct device_attribute);
+	int i;
+
+	for (i = 0; i < num_attr; i++)
+		device_remove_file(bcl->dev, &bcl_dev_attr[i]);
+
+	return;
+}
+
+static int __devinit bcl_probe(struct platform_device *pdev)
+{
+	struct bcl_context *bcl;
+	int ret = 0;
+
+	bcl = kzalloc(sizeof(struct bcl_context), GFP_KERNEL);
+
+	if (!bcl) {
+		pr_err("Cannot allocate bcl_context\n");
+		return -ENOMEM;
+	}
+
+	gbcl = bcl;
+
+	/* For BCL */
+	/* Init default BCL params */
+	bcl->dev = &pdev->dev;
+	bcl->bcl_mode = BCL_DEVICE_DISABLED;
+	bcl->bcl_threshold_mode[BCL_IBAT_IMAX_THRESHOLD_TYPE_LOW]
+		= BCL_IBAT_IMAX_THRESHOLD_DISABLED;
+	bcl->bcl_threshold_mode[BCL_IBAT_IMAX_THRESHOLD_TYPE_HIGH]
+		= BCL_IBAT_IMAX_THRESHOLD_DISABLED;
+	bcl->bcl_threshold_value_ma[BCL_IBAT_IMAX_THRESHOLD_TYPE_LOW] = 0;
+	bcl->bcl_threshold_value_ma[BCL_IBAT_IMAX_THRESHOLD_TYPE_HIGH] = 0;
+	snprintf(bcl->bcl_type, BCL_NAME_LENGTH, "%s", bcl_type);
+	bcl->bcl_poll_interval_msec = BCL_POLL_INTERVAL;
+	ret = create_bcl_sysfs(bcl);
+	if (ret < 0) {
+		pr_err("Cannot create bcl sysfs\n");
+		kfree(bcl);
+		return ret;
+	}
+	platform_set_drvdata(pdev, bcl);
+	INIT_DELAYED_WORK(&bcl->bcl_imax_work, bcl_imax_work);
+
+	return 0;
+}
+
+static int __devexit bcl_remove(struct platform_device *pdev)
+{
+	remove_bcl_sysfs(gbcl);
+	kfree(gbcl);
+	gbcl = NULL;
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static struct platform_driver bcl_driver = {
+	.probe	= bcl_probe,
+	.remove	= __devexit_p(bcl_remove),
+	.driver	= {
+		.name	= BCL_DEV_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init bcl_init(void)
+{
+	return platform_driver_register(&bcl_driver);
+}
+
+static void __exit bcl_exit(void)
+{
+	platform_driver_unregister(&bcl_driver);
+}
+
+late_initcall(bcl_init);
+module_exit(bcl_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("battery current limit driver");
+MODULE_ALIAS("platform:" BCL_DEV_NAME);
diff --git a/drivers/power/bq27520_fuelgauger.c b/drivers/power/bq27520_fuelgauger.c
index 3c191cd..c5e87c5 100644
--- a/drivers/power/bq27520_fuelgauger.c
+++ b/drivers/power/bq27520_fuelgauger.c
@@ -2,7 +2,7 @@
  * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>
  * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/power/bq27541_fuelgauger.c b/drivers/power/bq27541_fuelgauger.c
index 516a861..2101c5f 100644
--- a/drivers/power/bq27541_fuelgauger.c
+++ b/drivers/power/bq27541_fuelgauger.c
@@ -2,7 +2,7 @@
  * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>
  * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/power/isl9519q.c b/drivers/power/isl9519q.c
index a8467d4..ec1473d 100644
--- a/drivers/power/isl9519q.c
+++ b/drivers/power/isl9519q.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/power/msm_battery.c b/drivers/power/msm_battery.c
index 5abc032..244cd80 100644
--- a/drivers/power/msm_battery.c
+++ b/drivers/power/msm_battery.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/drivers/power/msm_charger.c b/drivers/power/msm_charger.c
index 8594ec2..29dc726 100644
--- a/drivers/power/msm_charger.c
+++ b/drivers/power/msm_charger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/power/pm8058_usb_fix.c b/drivers/power/pm8058_usb_fix.c
index 80b1f87..1287547 100644
--- a/drivers/power/pm8058_usb_fix.c
+++ b/drivers/power/pm8058_usb_fix.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 3662ac5..7c49793 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -23,6 +23,7 @@
 #include <linux/mfd/pm8xxx/pm8921-charger.h>
 #include <linux/mfd/pm8xxx/ccadc.h>
 #include <linux/mfd/pm8xxx/batterydata-lib.h>
+#include <linux/mfd/pm8xxx/batt-alarm.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
@@ -58,6 +59,8 @@
 #define PON_CNTRL_6		0x018
 #define WD_BIT			BIT(7)
 
+#define BATT_ALARM_ACCURACY	50	/* 50mV */
+
 enum pmic_bms_interrupts {
 	PM8921_BMS_SBI_WRITE_OK,
 	PM8921_BMS_CC_THR,
@@ -120,11 +123,13 @@
 	unsigned int		charging_began;
 	unsigned int		start_percent;
 	unsigned int		end_percent;
+	unsigned int		alarm_low_mv;
+	unsigned int		alarm_high_mv;
+
 	int			charge_time_us;
 	int			catch_up_time_us;
 	enum battery_type	batt_type;
 	uint16_t		ocv_reading_at_100;
-	int			cc_reading_at_100;
 	int			max_voltage_uv;
 
 	int			chg_term_ua;
@@ -132,6 +137,7 @@
 	int			amux_2_trim_delta;
 	uint16_t		prev_last_good_ocv_raw;
 	int			rconn_mohm;
+	int			rbatt_capacitive_mohm;
 	struct mutex		last_ocv_uv_mutex;
 	int			last_ocv_uv;
 	int			last_ocv_temp_decidegc;
@@ -155,13 +161,22 @@
 	int			soc_at_cv;
 	int			prev_chg_soc;
 	struct power_supply	*batt_psy;
-	bool			low_voltage_wake_lock_held;
 	struct wake_lock	low_voltage_wake_lock;
 	int			soc_calc_period;
 	int			normal_voltage_calc_ms;
 	int			low_voltage_calc_ms;
 	int			imax_ua;
 	struct wake_lock	soc_wake_lock;
+	int			disable_flat_portion_ocv;
+	int			ocv_dis_high_soc;
+	int			ocv_dis_low_soc;
+	int			high_ocv_correction_limit_uv;
+	int			low_ocv_correction_limit_uv;
+	int			hold_soc_est;
+	int			prev_vbat_batt_terminal_uv;
+	int			vbatt_cutoff_count;
+	int			low_voltage_detect;
+	int			vbatt_cutoff_retries;
 };
 
 /*
@@ -189,6 +204,13 @@
 static int last_real_fcc_mah = -EINVAL;
 static int last_real_fcc_batt_temp = -EINVAL;
 
+static int pm8921_battery_gauge_alarm_notify(struct notifier_block *nb,
+				unsigned long status, void *unused);
+
+static struct notifier_block alarm_notifier = {
+	.notifier_call = pm8921_battery_gauge_alarm_notify,
+};
+
 static int bms_ops_set(const char *val, const struct kernel_param *kp)
 {
 	if (*(int *)kp->arg == -EINVAL)
@@ -376,6 +398,142 @@
 	return val;
 }
 
+static void pm8921_bms_low_voltage_config(struct pm8921_bms_chip *chip,
+								int time_ms)
+{
+	int ms = 0;
+
+	/* if work was pending and was cancelled, calculate SOC immediately */
+	if (!cancel_delayed_work_sync(&chip->calculate_soc_delayed_work))
+		ms = time_ms;
+
+	chip->soc_calc_period = time_ms;
+	schedule_delayed_work(&chip->calculate_soc_delayed_work,
+						msecs_to_jiffies(ms));
+}
+
+static int pm8921_bms_enable_batt_alarm(struct pm8921_bms_chip *chip)
+{
+	int rc = 0;
+
+	rc = pm8xxx_batt_alarm_enable(PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+	if (rc) {
+		pr_err("unable to set batt alarm state rc=%d\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+static int pm8921_bms_configure_batt_alarm(struct pm8921_bms_chip *chip)
+{
+	int rc = 0;
+
+	rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_disable(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
+	if (rc) {
+		pr_err("unable to set batt alarm state rc=%d\n", rc);
+		return rc;
+	}
+
+	/*
+	* The batt-alarm driver requires sane values for both min / max,
+	* regardless of whether they're both activated.
+	*/
+	rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR,
+					chip->alarm_low_mv);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_UPPER_COMPARATOR,
+					chip->alarm_high_mv);
+	if (rc) {
+		pr_err("unable to set batt alarm threshold rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = pm8xxx_batt_alarm_hold_time_set(
+			PM8XXX_BATT_ALARM_HOLD_TIME_16_MS);
+	if (rc) {
+		pr_err("unable to set batt alarm hold time rc=%d\n", rc);
+		return rc;
+	}
+
+	/* PWM enabled at 2Hz */
+	rc = pm8xxx_batt_alarm_pwm_rate_set(1, 7, 4);
+	if (rc) {
+		pr_err("unable to set batt alarm pwm rate rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = pm8xxx_batt_alarm_register_notifier(&alarm_notifier);
+	if (rc) {
+		pr_err("unable to register alarm notifier rc=%d\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+static int pm8921_battery_gauge_alarm_notify(struct notifier_block *nb,
+		unsigned long status, void *unused)
+{
+	int rc;
+
+	if (!the_chip) {
+		pr_err("not initialized\n");
+		return -EINVAL;
+	}
+
+	switch (status) {
+	case 0:
+		pr_debug("spurious interrupt\n");
+		break;
+	case 1:
+		pr_debug("Low voltage alarm triggered\n");
+		/*
+		 * hold the low voltage wakelock until the soc
+		 * work finds it appropriate to release it.
+		 */
+		if (!wake_lock_active(&the_chip->low_voltage_wake_lock)) {
+			pr_debug("Holding low voltage wakelock\n");
+			wake_lock(&the_chip->low_voltage_wake_lock);
+			pm8921_bms_low_voltage_config(the_chip,
+					the_chip->low_voltage_calc_ms);
+		}
+
+		rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
+		if (!rc)
+			rc = pm8xxx_batt_alarm_enable(
+				PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+		if (rc)
+			pr_err("unable to set alarm state rc=%d\n", rc);
+		break;
+	case 2:
+		rc = pm8xxx_batt_alarm_disable(
+			PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+		if (!rc)
+			rc = pm8xxx_batt_alarm_enable(
+				PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
+		if (rc)
+			pr_err("unable to set alarm state rc=%d\n", rc);
+
+		break;
+	default:
+		pr_err("error received\n");
+		break;
+	}
+
+	return 0;
+};
+
+
 #define HOLD_OREG_DATA		BIT(1)
 static int pm_bms_lock_output_data(struct pm8921_bms_chip *chip)
 {
@@ -511,15 +669,15 @@
 #define SLEEP_CLK_HZ		32764
 #define SECONDS_PER_HOUR	3600
 /**
- * ccmicrovolt_to_uvh -
+ * ccmicrovolt_to_pvh -
  * @cc_uv:  coulumb counter converted to uV
  *
- * RETURNS:	coulumb counter based charge in uVh
- *		(micro Volt Hour)
+ * RETURNS:	coulumb counter based charge in pVh
+ *		(pico Volt Hour)
  */
-static s64 ccmicrovolt_to_uvh(s64 cc_uv)
+static s64 ccmicrovolt_to_pvh(s64 cc_uv)
 {
-	return div_s64(cc_uv * CC_READING_TICKS,
+	return div_s64(cc_uv * CC_READING_TICKS * 1000000L,
 			SLEEP_CLK_HZ * SECONDS_PER_HOUR);
 }
 
@@ -596,6 +754,23 @@
 	return 0;
 }
 
+static int get_batt_temp(struct pm8921_bms_chip *chip, int *batt_temp)
+{
+	int rc;
+	struct pm8xxx_adc_chan_result result;
+
+	rc = pm8xxx_adc_read(chip->batt_temp_channel, &result);
+	if (rc) {
+		pr_err("error reading batt_temp_channel = %d, rc = %d\n",
+					chip->batt_temp_channel, rc);
+		return rc;
+	}
+	*batt_temp = result.physical;
+	pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
+						result.measurement);
+	return 0;
+}
+
 #define BMS_MODE_BIT	BIT(6)
 #define EN_VBAT_BIT	BIT(5)
 #define OVERRIDE_MODE_DELAY_MS	20
@@ -606,6 +781,7 @@
 	int16_t vbat_raw;
 	int vsense_uv;
 	int usb_chg;
+	int batt_temp;
 
 	mutex_lock(&the_chip->bms_output_lock);
 
@@ -620,12 +796,13 @@
 	pm_bms_read_output_data(the_chip, VBATT_AVG, &vbat_raw);
 	pm_bms_unlock_output_data(the_chip);
 	pm_bms_masked_write(the_chip, BMS_CONTROL,
-			BMS_MODE_BIT | EN_VBAT_BIT, 0);
+		BMS_MODE_BIT | EN_VBAT_BIT, 0);
 
 	pm8xxx_writeb(the_chip->dev->parent, BMS_S1_DELAY, 0x0B);
 
 	mutex_unlock(&the_chip->bms_output_lock);
 
+	get_batt_temp(the_chip, &batt_temp);
 	usb_chg = usb_chg_plugged_in(the_chip);
 
 	convert_vbatt_raw_to_uv(the_chip, usb_chg, vbat_raw, vbat_uv);
@@ -696,8 +873,8 @@
 {
 	int ibat_ua, vbat_uv, ocv_est_uv;
 	int rc;
-
-	int rbatt_mohm = chip->default_rbatt_mohm + chip->rconn_mohm;
+	int rbatt_mohm = chip->default_rbatt_mohm + chip->rconn_mohm
+				+ chip->rbatt_capacitive_mohm;
 
 	rc = pm8921_bms_get_simultaneous_battery_voltage_and_current(
 							&ibat_ua,
@@ -724,6 +901,93 @@
 	}
 	return reg & WD_BIT;
 }
+
+#define IBAT_TOL_MASK		0x0F
+#define OCV_TOL_MASK			0xF0
+#define IBAT_TOL_DEFAULT	0x03
+#define IBAT_TOL_NOCHG		0x0F
+#define OCV_TOL_DEFAULT		0x20
+#define OCV_TOL_NO_OCV		0x00
+static int pm8921_bms_stop_ocv_updates(void)
+{
+	if (!the_chip) {
+		pr_err("BMS driver has not been initialized yet!\n");
+		return -EINVAL;
+	}
+	pr_debug("stopping ocv updates\n");
+	return pm_bms_masked_write(the_chip, BMS_TOLERANCES,
+			OCV_TOL_MASK, OCV_TOL_NO_OCV);
+}
+
+static int pm8921_bms_start_ocv_updates(void)
+{
+	if (!the_chip) {
+		pr_err("BMS driver has not been initialized yet!\n");
+		return -EINVAL;
+	}
+	pr_debug("starting ocv updates\n");
+	return pm_bms_masked_write(the_chip, BMS_TOLERANCES,
+			OCV_TOL_MASK, OCV_TOL_DEFAULT);
+}
+
+static int reset_bms_for_test(void)
+{
+	int ibat_ua, vbat_uv, rc;
+	int ocv_est_uv;
+
+	if (!the_chip) {
+		pr_err("BMS driver has not been initialized yet!\n");
+		return -EINVAL;
+	}
+
+	rc = pm8921_bms_get_simultaneous_battery_voltage_and_current(
+							&ibat_ua,
+							&vbat_uv);
+	/*
+	 * don't include rbatt and rbatt_capacitve since we expect this to
+	 * be used with a fake battery which does not have internal resistnaces
+	 */
+	ocv_est_uv = vbat_uv + (ibat_ua * the_chip->rconn_mohm) / 1000;
+	pr_debug("forcing ocv to be %d due to bms reset mode\n", ocv_est_uv);
+	the_chip->last_ocv_uv = ocv_est_uv;
+	last_soc = -EINVAL;
+	reset_cc(the_chip);
+	the_chip->last_cc_uah = 0;
+	pm8921_bms_stop_ocv_updates();
+
+	pr_debug("bms reset to ocv = %duv vbat_ua = %d ibat_ua = %d\n",
+			the_chip->last_ocv_uv, vbat_uv, ibat_ua);
+
+	return rc;
+}
+
+static int bms_reset_set(const char *val, const struct kernel_param *kp)
+{
+	int rc;
+
+	rc = param_set_bool(val, kp);
+	if (rc) {
+		pr_err("Unable to set bms_reset: %d\n", rc);
+		return rc;
+	}
+
+	if (*val == 'Y') {
+		rc = reset_bms_for_test();
+		if (rc) {
+			pr_err("Unable to modify bms_reset: %d\n", rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+static struct kernel_param_ops bms_reset_ops = {
+	.set = bms_reset_set,
+	.get = param_get_bool,
+};
+
+static bool bms_reset;
+module_param_cb(bms_reset, &bms_reset_ops, &bms_reset, 0644);
 /*
  * This reflects what should the CC readings should be for
  * a 5mAh discharge. This value is dependent on
@@ -802,19 +1066,9 @@
 		raw->last_good_ocv_uv = chip->last_ocv_uv;
 	}
 
-	/* fake a high OCV if we are just done charging */
-	if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw) {
+	/* stop faking 100% after an OCV event */
+	if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw)
 		chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
-		chip->cc_reading_at_100 = 0;
-	} else {
-		/*
-		 * force 100% ocv by selecting the highest voltage the
-		 * battery could ever reach
-		 */
-		raw->last_good_ocv_uv = chip->max_voltage_uv;
-		chip->last_ocv_uv = chip->max_voltage_uv;
-		chip->last_ocv_temp_decidegc = batt_temp_decidegc;
-	}
 	pr_debug("0p625 = %duV\n", chip->xoadc_v0625);
 	pr_debug("1p25 = %duV\n", chip->xoadc_v125);
 	pr_debug("last_good_ocv_raw= 0x%x, last_good_ocv_uv= %duV\n",
@@ -845,6 +1099,10 @@
 	pr_debug("adding rconn_mohm = %d rbatt = %d\n",
 				the_chip->rconn_mohm, rbatt);
 
+	rbatt += the_chip->rbatt_capacitive_mohm;
+	pr_debug("adding rbatt_capacitive_mohm = %d rbatt = %d\n",
+				the_chip->rbatt_capacitive_mohm, rbatt);
+
 	if (is_between(20, 10, soc_rbatt))
 		rbatt = rbatt
 			+ ((20 - soc_rbatt) * chip->delta_rbatt_mohm) / 10;
@@ -947,19 +1205,16 @@
  */
 static void calculate_cc_uah(struct pm8921_bms_chip *chip, int cc, int *val)
 {
-	int64_t cc_voltage_uv, cc_uvh, cc_uah;
+	int64_t cc_voltage_uv, cc_pvh, cc_uah;
 
 	cc_voltage_uv = cc;
-	cc_voltage_uv -= chip->cc_reading_at_100;
-	pr_debug("cc = %d. after subtracting 0x%x cc = %lld\n",
-					cc, chip->cc_reading_at_100,
-					cc_voltage_uv);
+	pr_debug("cc = %d\n", cc);
 	cc_voltage_uv = cc_to_microvolt(chip, cc_voltage_uv);
 	cc_voltage_uv = pm8xxx_cc_adjust_for_gain(cc_voltage_uv);
 	pr_debug("cc_voltage_uv = %lld microvolts\n", cc_voltage_uv);
-	cc_uvh = ccmicrovolt_to_uvh(cc_voltage_uv);
-	pr_debug("cc_uvh = %lld micro_volt_hour\n", cc_uvh);
-	cc_uah = div_s64(cc_uvh * 1000000LL, chip->r_sense_uohm);
+	cc_pvh = ccmicrovolt_to_pvh(cc_voltage_uv);
+	pr_debug("cc_pvh = %lld pico_volt_hour\n", cc_pvh);
+	cc_uah = div_s64(cc_pvh, chip->r_sense_uohm);
 	*val = cc_uah;
 }
 
@@ -1209,6 +1464,12 @@
 		iavg_ma = DIV_ROUND_CLOSEST(iavg_ma, iavg_num_samples);
 	}
 
+	/*
+	 * if we're in bms reset mode, force uuc to be 3% of fcc
+	 */
+	if (bms_reset)
+		return (fcc_uah * 3) / 100;
+
 	uuc_uah_iavg = calculate_termination_uuc(chip,
 					batt_temp, chargecycles,
 					fcc_uah, iavg_ma,
@@ -1272,10 +1533,7 @@
 
 	/* calculate cc micro_volt_hour */
 	calculate_cc_uah(chip, raw->cc, cc_uah);
-	pr_debug("cc_uah = %duAh raw->cc = %x cc = %lld after subtracting %x\n",
-				*cc_uah, raw->cc,
-				(int64_t)raw->cc - chip->cc_reading_at_100,
-				chip->cc_reading_at_100);
+	pr_debug("cc_uah = %duAh raw->cc = %x\n", *cc_uah, raw->cc);
 
 	soc_rbatt = ((*remaining_charge_uah - *cc_uah) * 100) / *fcc_uah;
 	if (soc_rbatt < 0)
@@ -1350,6 +1608,8 @@
 }
 EXPORT_SYMBOL(pm8921_bms_get_simultaneous_battery_voltage_and_current);
 
+#define SIGN(x) ((x) < 0 ? -1 : 1)
+
 static void find_ocv_for_soc(struct pm8921_bms_chip *chip,
 			int batt_temp,
 			int chargecycles,
@@ -1377,16 +1637,55 @@
 	new_pc = interpolate_pc(chip->pc_temp_ocv_lut, batt_temp_degc, ocv);
 	pr_debug("test revlookup pc = %d for ocv = %d\n", new_pc, ocv);
 
-	while (abs(new_pc - pc) > 1) {
+	if (abs(new_pc - pc) > 0) {
+		/* Maximum spins to make in while-loop when searching in
+		 * full resolution.
+		 */
+		const unsigned int max_spin_count =
+			chip->max_voltage_uv / 1000 - chip->v_cutoff + 1;
+		unsigned int count = 0;
 		int delta_mv = 5;
+		int diff = abs(new_pc - pc);
+		char sign = SIGN(new_pc - pc);
+		char old_sign;
+		int old_diff;
+		int old_ocv;
 
-		if (new_pc > pc)
-			delta_mv = -1 * delta_mv;
+		do {
+			count++;
+			old_ocv = ocv;
+			old_diff = diff;
+			old_sign = sign;
 
-		ocv = ocv + delta_mv;
-		new_pc = interpolate_pc(chip->pc_temp_ocv_lut,
-				batt_temp_degc, ocv);
-		pr_debug("test revlookup pc = %d for ocv = %d\n", new_pc, ocv);
+			if (new_pc > pc)
+				ocv -= delta_mv;
+			else
+				ocv += delta_mv;
+
+			new_pc = interpolate_pc(chip->pc_temp_ocv_lut,
+							batt_temp_degc, ocv);
+			pr_debug("test revlookup pc = %d for ocv = %d\n",
+				new_pc, ocv);
+			diff = abs(new_pc - pc);
+			sign = SIGN(new_pc - pc);
+
+			if (sign != old_sign) {
+				if (delta_mv == 5) {
+					/*
+					 * we crossed our desired PC probably
+					 * becuase we were overcorrecting
+					 */
+					delta_mv = 1;
+				} else {
+					/* we crossed our desired PC even with
+					 * 1mV steps, choose the best of two */
+					if (diff > old_diff)
+						ocv = old_ocv;
+
+					break;
+				}
+			}
+		} while (count <= max_spin_count && diff > 0);
 	}
 
 	*ocv_uv = ocv * 1000;
@@ -1456,6 +1755,8 @@
 			pr_debug("CC_TO_CV ibat_ua = %d CHG SOC %d\n",
 					ibat_ua, soc);
 		}
+
+		chip->prev_vbat_batt_terminal_uv = vbat_batt_terminal_uv;
 		return soc;
 	}
 
@@ -1465,13 +1766,15 @@
 	 */
 
 	/*
-	 * if voltage lessened by more than 10mV (possibly because of
+	 * if the battery terminal voltage lessened (possibly because of
 	 * a sudden increase in system load) keep reporting the prev chg soc
 	 */
-	if (vbat_batt_terminal_uv <= chip->max_voltage_uv - 10000) {
-		pr_debug("vbat_terminals %d < max = %d CC CHG SOC %d\n",
+	if (vbat_batt_terminal_uv < chip->prev_vbat_batt_terminal_uv) {
+		pr_debug("vbat_terminals %d < prev = %d CC CHG SOC %d\n",
 			vbat_batt_terminal_uv,
-			chip->max_voltage_uv, chip->prev_chg_soc);
+			chip->prev_vbat_batt_terminal_uv,
+			chip->prev_chg_soc);
+		chip->prev_vbat_batt_terminal_uv = vbat_batt_terminal_uv;
 		return chip->prev_chg_soc;
 	}
 
@@ -1498,33 +1801,54 @@
 	}
 
 	pr_debug("Reporting CHG SOC %d\n", chip->prev_chg_soc);
+	chip->prev_vbat_batt_terminal_uv = vbat_batt_terminal_uv;
 	return chip->prev_chg_soc;
 }
 
 static void very_low_voltage_check(struct pm8921_bms_chip *chip,
 					int ibat_ua, int vbat_uv)
 {
+	int rc;
 	/*
 	 * if battery is very low (v_cutoff voltage + 20mv) hold
 	 * a wakelock untill soc = 0%
 	 */
-	if (vbat_uv <= (chip->v_cutoff + 20) * 1000
-			&& !chip->low_voltage_wake_lock_held) {
+	if (vbat_uv <= (chip->alarm_low_mv + 20) * 1000 &&
+		!wake_lock_active(&the_chip->low_voltage_wake_lock)) {
 		pr_debug("voltage = %d low holding wakelock\n", vbat_uv);
 		wake_lock(&chip->low_voltage_wake_lock);
-		chip->low_voltage_wake_lock_held = 1;
 		chip->soc_calc_period = chip->low_voltage_calc_ms;
 	}
 
-	if (vbat_uv > (chip->v_cutoff + 20) * 1000
-			&& chip->low_voltage_wake_lock_held) {
+	if (vbat_uv > (chip->alarm_low_mv + 20 + BATT_ALARM_ACCURACY) * 1000
+			&& wake_lock_active(&the_chip->low_voltage_wake_lock)) {
 		pr_debug("voltage = %d releasing wakelock\n", vbat_uv);
-		chip->low_voltage_wake_lock_held = 0;
-		wake_unlock(&chip->low_voltage_wake_lock);
+		chip->vbatt_cutoff_count = 0;
 		chip->soc_calc_period = chip->normal_voltage_calc_ms;
+		rc = pm8921_bms_enable_batt_alarm(chip);
+		if (rc)
+			pr_err("Unable to enable batt alarm\n");
+		wake_unlock(&chip->low_voltage_wake_lock);
 	}
 }
 
+static bool is_voltage_below_cutoff_window(struct pm8921_bms_chip *chip,
+						int ibat_ua, int vbat_uv)
+{
+	if (vbat_uv < (chip->v_cutoff * 1000) && ibat_ua > 0) {
+		chip->vbatt_cutoff_count++;
+		if (chip->vbatt_cutoff_count >= chip->vbatt_cutoff_retries) {
+			pr_debug("cutoff_count >= %d\n",
+					chip->vbatt_cutoff_retries);
+			return true;
+		}
+	} else {
+		chip->vbatt_cutoff_count = 0;
+	}
+
+	return false;
+}
+
 static int last_soc_est = -EINVAL;
 static int adjust_soc(struct pm8921_bms_chip *chip, int soc,
 		int batt_temp, int chargecycles,
@@ -1540,6 +1864,7 @@
 	int m = 0;
 	int rc = 0;
 	int delta_ocv_uv_limit = 0;
+	int correction_limit_uv = 0;
 
 	rc = pm8921_bms_get_simultaneous_battery_voltage_and_current(
 							&ibat_ua,
@@ -1551,6 +1876,15 @@
 
 	very_low_voltage_check(chip, ibat_ua, vbat_uv);
 
+	if (chip->low_voltage_detect &&
+		wake_lock_active(&chip->low_voltage_wake_lock)) {
+		if (is_voltage_below_cutoff_window(chip, ibat_ua, vbat_uv)) {
+			soc = 0;
+			pr_info("Voltage below cutoff, setting soc to 0\n");
+			goto out;
+		}
+	}
+
 	delta_ocv_uv_limit = DIV_ROUND_CLOSEST(ibat_ua, 1000);
 
 	ocv_est_uv = vbat_uv + (ibat_ua * rbatt)/1000;
@@ -1560,6 +1894,12 @@
 						(s64)fcc_uah - uuc_uah);
 	soc_est = bound_soc(soc_est);
 
+	/* never adjust during bms reset mode */
+	if (bms_reset) {
+		pr_debug("bms reset mode, SOC adjustment skipped\n");
+		goto out;
+	}
+
 	if (ibat_ua < 0 && pm8921_is_batfet_closed()) {
 		soc = charging_adjustments(chip, soc, vbat_uv, ibat_ua,
 				batt_temp, chargecycles,
@@ -1569,17 +1909,13 @@
 
 	/*
 	 * do not adjust
-	 * if soc is same as what bms calculated
-	 * if soc_est is between 45 and 25, this is the flat portion of the
-	 * curve where soc_est is not so accurate. We generally don't want to
-	 * adjust when soc_est is inaccurate except for the cases when soc is
-	 * way far off (higher than 50 or lesser than 20).
-	 * Also don't adjust soc if it is above 90 becuase we might pull it low
+	 * if soc_est is same as what bms calculated
+	 * OR if soc_est > 15
+	 * OR if soc it is above 90 because we might pull it low
 	 * and  cause a bad user experience
 	 */
 	if (soc_est == soc
-		|| (is_between(45, chip->adjust_soc_low_threshold, soc_est)
-		&& is_between(50, chip->adjust_soc_low_threshold - 5, soc))
+		|| soc_est > 15
 		|| soc >= 90)
 		goto out;
 
@@ -1628,6 +1964,22 @@
 		pr_debug("new delta ocv = %d\n", delta_ocv_uv);
 	}
 
+	if (chip->last_ocv_uv > 3800000)
+		correction_limit_uv = the_chip->high_ocv_correction_limit_uv;
+	else
+		correction_limit_uv = the_chip->low_ocv_correction_limit_uv;
+
+	if (abs(delta_ocv_uv) > correction_limit_uv) {
+		pr_debug("limiting delta ocv %d limit = %d\n", delta_ocv_uv,
+				correction_limit_uv);
+
+		if (delta_ocv_uv > 0)
+			delta_ocv_uv = correction_limit_uv;
+		else
+			delta_ocv_uv = -1 * correction_limit_uv;
+		pr_debug("new delta ocv = %d\n", delta_ocv_uv);
+	}
+
 	chip->last_ocv_uv -= delta_ocv_uv;
 
 	if (chip->last_ocv_uv >= chip->max_voltage_uv)
@@ -1644,7 +1996,7 @@
 	 * if soc_new is ZERO force it higher so that phone doesnt report soc=0
 	 * soc = 0 should happen only when soc_est == 0
 	 */
-	if (soc_new == 0 && soc_est != 0)
+	if (soc_new == 0 && soc_est >= the_chip->hold_soc_est)
 		soc_new = 1;
 
 	soc = soc_new;
@@ -1810,23 +2162,6 @@
 		power_supply_changed(chip->batt_psy);
 }
 
-static int get_batt_temp(struct pm8921_bms_chip *chip, int *batt_temp)
-{
-	int rc;
-	struct pm8xxx_adc_chan_result result;
-
-	rc = pm8xxx_adc_read(chip->batt_temp_channel, &result);
-	if (rc) {
-		pr_err("error reading batt_temp_channel = %d, rc = %d\n",
-					chip->batt_temp_channel, rc);
-		return rc;
-	}
-	*batt_temp = result.physical;
-	pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
-						result.measurement);
-	return 0;
-}
-
 #define MIN_DELTA_625_UV	1000
 static void calib_hkadc(struct pm8921_bms_chip *chip)
 {
@@ -2058,6 +2393,15 @@
 	calculated_soc = new_calculated_soc;
 	firsttime = 0;
 	get_current_time(&chip->last_recalc_time);
+
+	if (chip->disable_flat_portion_ocv) {
+		if (is_between(chip->ocv_dis_high_soc, chip->ocv_dis_low_soc,
+					calculated_soc)) {
+			pm8921_bms_stop_ocv_updates();
+		} else {
+			pm8921_bms_start_ocv_updates();
+		}
+	}
 	return calculated_soc;
 }
 
@@ -2151,9 +2495,18 @@
 
 	/* last_soc < soc  ... scale and catch up */
 	if (last_soc != -EINVAL && last_soc < soc && soc != 100)
-		soc = scale_soc_while_chg(chip, delta_time_us, soc, last_soc);
+			soc = scale_soc_while_chg(chip, delta_time_us,
+							soc, last_soc);
 
-	last_soc = soc;
+	/* restrict soc to 1% change */
+	if (last_soc != -EINVAL) {
+		if (soc < last_soc && soc != 0)
+			soc = last_soc - 1;
+		if (soc > last_soc && soc != 100)
+			soc = last_soc + 1;
+	}
+
+	last_soc = bound_soc(soc);
 	backup_soc_and_iavg(chip, batt_temp, last_soc);
 	pr_debug("Reported SOC = %d\n", last_soc);
 	chip->t_soc_queried = now;
@@ -2161,6 +2514,65 @@
 	return last_soc;
 }
 
+void pm8921_bms_battery_removed(void)
+{
+	if (!the_chip) {
+		pr_err("called before initialization\n");
+		return;
+	}
+	pr_info("Battery Removed Cleaning up\n");
+
+	cancel_delayed_work_sync(&the_chip->calculate_soc_delayed_work);
+	calculated_soc = 0;
+	the_chip->start_percent = -EINVAL;
+	the_chip->end_percent = -EINVAL;
+	/* cleanup for charge time catchup */
+	the_chip->charge_time_us = 0;
+	the_chip->catch_up_time_us = 0;
+	/* cleanup for charge time adjusting */
+	the_chip->soc_at_cv = -EINVAL;
+	the_chip->soc_at_cv = -EINVAL;
+	the_chip->prev_chg_soc = -EINVAL;
+	the_chip->ibat_at_cv_ua = 0;
+	the_chip->prev_vbat_batt_terminal_uv = 0;
+	/* ocv cleanups */
+	the_chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
+	the_chip->prev_last_good_ocv_raw = OCV_RAW_UNINITIALIZED;
+	the_chip->last_ocv_temp_decidegc = -EINVAL;
+
+	/* cleanup delta time */
+	the_chip->tm_sec = 0;
+
+	/* cc and avg current cleanups */
+	the_chip->prev_iavg_ua = 0;
+	the_chip->last_cc_uah = INT_MIN;
+
+	/* report SOC cleanups */
+	the_chip->t_soc_queried.tv_sec = 0;
+	the_chip->t_soc_queried.tv_nsec = 0;
+
+	last_soc = -EINVAL;
+	/* store invalid soc */
+	pm8xxx_writeb(the_chip->dev->parent, TEMP_SOC_STORAGE, 0);
+
+	/* UUC related data is left as is - use the same historical load avg */
+	update_power_supply(the_chip);
+}
+EXPORT_SYMBOL(pm8921_bms_battery_removed);
+
+void pm8921_bms_battery_inserted(void)
+{
+	if (!the_chip) {
+		pr_err("called before initialization\n");
+		return;
+	}
+
+	pr_info("Battery Inserted\n");
+	the_chip->last_ocv_uv = estimate_ocv(the_chip);
+	schedule_delayed_work(&the_chip->calculate_soc_delayed_work, 0);
+}
+EXPORT_SYMBOL(pm8921_bms_battery_inserted);
+
 void pm8921_bms_invalidate_shutdown_soc(void)
 {
 	int calculate_soc = 0;
@@ -2287,13 +2699,6 @@
 	return calculate_fcc_uah(the_chip, batt_temp, last_chargecycles);
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_get_fcc);
-
-#define IBAT_TOL_MASK		0x0F
-#define OCV_TOL_MASK			0xF0
-#define IBAT_TOL_DEFAULT	0x03
-#define IBAT_TOL_NOCHG		0x0F
-#define OCV_TOL_DEFAULT		0x20
-#define OCV_TOL_NO_OCV		0x00
 void pm8921_bms_charging_began(void)
 {
 	struct pm8921_soc_params raw;
@@ -2376,18 +2781,20 @@
 
 	if (is_battery_full) {
 		the_chip->ocv_reading_at_100 = raw.last_good_ocv_raw;
-		the_chip->cc_reading_at_100 = raw.cc;
 
 		the_chip->last_ocv_uv = the_chip->max_voltage_uv;
 		raw.last_good_ocv_uv = the_chip->max_voltage_uv;
+		raw.cc = 0;
+		/* reset the cc in h/w */
+		reset_cc(the_chip);
+		the_chip->last_ocv_temp_decidegc = batt_temp;
 		/*
 		 * since we are treating this as an ocv event
 		 * forget the old cc value
 		 */
 		the_chip->last_cc_uah = 0;
-		pr_debug("EOC BATT_FULL ocv_reading = 0x%x cc = 0x%x\n",
-				the_chip->ocv_reading_at_100,
-				the_chip->cc_reading_at_100);
+		pr_debug("EOC BATT_FULL ocv_reading = 0x%x\n",
+				the_chip->ocv_reading_at_100);
 	}
 
 	the_chip->end_percent = calculate_state_of_charge(the_chip, &raw,
@@ -2420,22 +2827,6 @@
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_charging_end);
 
-int pm8921_bms_stop_ocv_updates(struct pm8921_bms_chip *chip)
-{
-	pr_debug("stopping ocv updates\n");
-	return pm_bms_masked_write(chip, BMS_TOLERANCES,
-			OCV_TOL_MASK, OCV_TOL_NO_OCV);
-}
-EXPORT_SYMBOL_GPL(pm8921_bms_stop_ocv_updates);
-
-int pm8921_bms_start_ocv_updates(struct pm8921_bms_chip *chip)
-{
-	pr_debug("stopping ocv updates\n");
-	return pm_bms_masked_write(chip, BMS_TOLERANCES,
-			OCV_TOL_MASK, OCV_TOL_DEFAULT);
-}
-EXPORT_SYMBOL_GPL(pm8921_bms_start_ocv_updates);
-
 static irqreturn_t pm8921_bms_sbi_write_ok_handler(int irq, void *data)
 {
 	pr_debug("irq = %d triggered", irq);
@@ -2654,6 +3045,8 @@
 		chip->default_rbatt_mohm
 				= palladium_1500_data.default_rbatt_mohm;
 		chip->delta_rbatt_mohm = palladium_1500_data.delta_rbatt_mohm;
+		chip->rbatt_capacitive_mohm
+			= palladium_1500_data.rbatt_capacitive_mohm;
 		return 0;
 desay:
 		chip->fcc = desay_5200_data.fcc;
@@ -2663,6 +3056,8 @@
 		chip->rbatt_sf_lut = desay_5200_data.rbatt_sf_lut;
 		chip->default_rbatt_mohm = desay_5200_data.default_rbatt_mohm;
 		chip->delta_rbatt_mohm = desay_5200_data.delta_rbatt_mohm;
+		chip->rbatt_capacitive_mohm
+			= desay_5200_data.rbatt_capacitive_mohm;
 		return 0;
 }
 
@@ -2675,6 +3070,8 @@
 	GET_VBAT_VSENSE_SIMULTANEOUS,
 	STOP_OCV,
 	START_OCV,
+	SET_OCV,
+	BATT_PRESENT,
 };
 
 static int test_batt_temp = 5;
@@ -2775,10 +3172,10 @@
 
 	switch (param) {
 	case STOP_OCV:
-		pm8921_bms_stop_ocv_updates(the_chip);
+		pm8921_bms_stop_ocv_updates();
 		break;
 	case START_OCV:
-		pm8921_bms_start_ocv_updates(the_chip);
+		pm8921_bms_start_ocv_updates();
 		break;
 	default:
 		ret = -EINVAL;
@@ -2793,9 +3190,9 @@
 	int ret = 0;
 	struct pm8921_soc_params raw;
 
-	mutex_lock(&the_chip->bms_output_lock);
+	mutex_lock(&the_chip->last_ocv_uv_mutex);
 	read_soc_params_raw(the_chip, &raw, 300);
-	mutex_unlock(&the_chip->bms_output_lock);
+	mutex_lock(&the_chip->last_ocv_uv_mutex);
 
 	*val = 0;
 
@@ -2916,6 +3313,10 @@
 				(void *)STOP_OCV, &calc_fops);
 	debugfs_create_file("start_ocv", 0644, chip->dent,
 				(void *)START_OCV, &calc_fops);
+	debugfs_create_file("set_ocv", 0644, chip->dent,
+				(void *)SET_OCV, &calc_fops);
+	debugfs_create_file("batt_present", 0644, chip->dent,
+				(void *)BATT_PRESENT, &calc_fops);
 
 	debugfs_create_file("simultaneous", 0644, chip->dent,
 			(void *)GET_VBAT_VSENSE_SIMULTANEOUS, &calc_fops);
@@ -3057,6 +3458,20 @@
 	chip->revision = pm8xxx_get_revision(chip->dev->parent);
 	chip->enable_fcc_learning = pdata->enable_fcc_learning;
 
+	chip->disable_flat_portion_ocv = pdata->disable_flat_portion_ocv;
+	chip->ocv_dis_high_soc = pdata->ocv_dis_high_soc;
+	chip->ocv_dis_low_soc = pdata->ocv_dis_low_soc;
+
+	chip->high_ocv_correction_limit_uv
+					= pdata->high_ocv_correction_limit_uv;
+	chip->low_ocv_correction_limit_uv = pdata->low_ocv_correction_limit_uv;
+	chip->hold_soc_est = pdata->hold_soc_est;
+
+	chip->alarm_low_mv = pdata->alarm_low_mv;
+	chip->alarm_high_mv = pdata->alarm_high_mv;
+	chip->low_voltage_detect = pdata->low_voltage_detect;
+	chip->vbatt_cutoff_retries = pdata->vbatt_cutoff_retries;
+
 	mutex_init(&chip->calib_mutex);
 	INIT_WORK(&chip->calib_hkadc_work, calibrate_hkadc_work);
 
@@ -3097,6 +3512,18 @@
 	pm8921_bms_enable_irq(chip, PM8921_BMS_GOOD_OCV);
 	pm8921_bms_enable_irq(chip, PM8921_BMS_OCV_FOR_R);
 
+	rc = pm8921_bms_configure_batt_alarm(chip);
+	if (rc) {
+		pr_err("Couldn't configure battery alarm! rc=%d\n", rc);
+		goto free_irqs;
+	}
+
+	rc = pm8921_bms_enable_batt_alarm(chip);
+	if (rc) {
+		pr_err("Couldn't enable battery alarm! rc=%d\n", rc);
+		goto free_irqs;
+	}
+
 	calculate_soc_work(&(chip->calculate_soc_delayed_work.work));
 
 	rc = get_battery_uvolts(chip, &vbatt);
@@ -3131,6 +3558,18 @@
 	return 0;
 }
 
+static int pm8921_bms_suspend(struct device *dev)
+{
+	/*
+	 * set the last reported soc to invalid, so that
+	 * next time we resume we don't want to restrict
+	 * the decrease of soc by only 1%
+	 */
+	last_soc = -EINVAL;
+
+	return 0;
+}
+
 static int pm8921_bms_resume(struct device *dev)
 {
 	int rc;
@@ -3158,6 +3597,7 @@
 
 static const struct dev_pm_ops pm8921_bms_pm_ops = {
 	.resume		= pm8921_bms_resume,
+	.suspend	= pm8921_bms_suspend,
 };
 
 static struct platform_driver pm8921_bms_driver = {
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 6d48f6b..a3b7bbf 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -213,6 +213,8 @@
  * @alarm_high_mv:		the battery alarm voltage high
  * @cool_temp_dc:		the cool temp threshold in deciCelcius
  * @warm_temp_dc:		the warm temp threshold in deciCelcius
+ * @hysteresis_temp_dc:		the hysteresis between temp thresholds in
+ *				deciCelcius
  * @resume_voltage_delta:	the voltage delta from vdd max at which the
  *				battery should resume charging
  * @term_current:		The charging based term current
@@ -235,6 +237,7 @@
 	unsigned int			alarm_high_mv;
 	int				cool_temp_dc;
 	int				warm_temp_dc;
+	int				hysteresis_temp_dc;
 	unsigned int			temp_check_period;
 	unsigned int			cool_bat_chg_current;
 	unsigned int			warm_bat_chg_current;
@@ -255,12 +258,9 @@
 	struct dentry			*dent;
 	struct bms_notify		bms_notify;
 	int				*usb_trim_table;
-	struct regulator		*vreg_xoadc;
 	bool				ext_charging;
 	bool				ext_charge_done;
 	bool				iusb_fine_res;
-	bool				final_kickstart;
-	bool				lockup_lpm_wrkarnd;
 	DECLARE_BITMAP(enabled_irqs, PM_CHG_MAX_INTS);
 	struct work_struct		battery_id_valid_work;
 	int64_t				batt_id_min;
@@ -294,6 +294,9 @@
 	int				btc_delay_ms;
 	bool				btc_panic_if_cant_stop_chg;
 	int				stop_chg_upon_expiry;
+	bool				disable_aicl;
+	int				usb_type;
+	bool				disable_chg_rmvl_wrkarnd;
 };
 
 /* user space parameter to limit usb current */
@@ -308,8 +311,8 @@
 static int thermal_mitigation;
 
 static struct pm8921_chg_chip *the_chip;
+static void check_temp_thresholds(struct pm8921_chg_chip *chip);
 
-static DEFINE_SPINLOCK(lpm_lock);
 #define LPM_ENABLE_BIT	BIT(2)
 static int pm8921_chg_set_lpm(struct pm8921_chg_chip *chip, int enable)
 {
@@ -338,38 +341,10 @@
 static int pm_chg_write(struct pm8921_chg_chip *chip, u16 addr, u8 reg)
 {
 	int rc;
-	unsigned long flags = 0;
-
-	/* Disable LPM */
-	if (chip->lockup_lpm_wrkarnd) {
-		spin_lock_irqsave(&lpm_lock, flags);
-
-		/*
-		 * This write could have initiated right after a previous write.
-		 * Allow time to settle to go in to lpm from the previous write
-		 */
-		udelay(200);
-		rc = pm8921_chg_set_lpm(chip, 0);
-		if (rc)
-			goto lpm_err;
-
-		/* Wait to come out of LPM */
-		udelay(200);
-	}
 
 	rc = pm8xxx_writeb(chip->dev->parent, addr, reg);
-	if (rc) {
-		pr_err("pm_chg_write failed: addr=%03X, rc=%d\n", addr, rc);
-		goto lpm_err;
-	}
-
-	/* Enable LPM */
-	if (chip->lockup_lpm_wrkarnd)
-		rc = pm8921_chg_set_lpm(chip, 1);
-
-lpm_err:
-	if (chip->lockup_lpm_wrkarnd)
-		spin_unlock_irqrestore(&lpm_lock, flags);
+	if (rc)
+		pr_err("failed: addr=%03X, rc=%d\n", addr, rc);
 
 	return rc;
 }
@@ -401,23 +376,6 @@
 					chip->pmic_chg_irq[irq_id]);
 }
 
-static int is_chg_on_bat(struct pm8921_chg_chip *chip)
-{
-	return !(pm_chg_get_rt_status(chip, DCIN_VALID_IRQ)
-			|| pm_chg_get_rt_status(chip, USBIN_VALID_IRQ));
-}
-
-static void pm8921_chg_bypass_bat_gone_debounce(struct pm8921_chg_chip *chip,
-		int bypass)
-{
-	int rc;
-
-	rc = pm_chg_write(chip, COMPARATOR_OVERRIDE, bypass ? 0x89 : 0x88);
-	if (rc) {
-		pr_err("Failed to set bypass bit to %d rc=%d\n", bypass, rc);
-	}
-}
-
 /* Treat OverVoltage/UnderVoltage as source missing */
 static int is_usb_chg_plugged_in(struct pm8921_chg_chip *chip)
 {
@@ -440,68 +398,77 @@
 static int pm_chg_get_fsm_state(struct pm8921_chg_chip *chip)
 {
 	u8 temp;
-	int err, ret = 0;
+	int err = 0, ret = 0;
 
 	temp = CAPTURE_FSM_STATE_CMD;
-	err = pm_chg_write(chip, CHG_TEST, temp);
+	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
 	if (err) {
 		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
+		goto err_out;
 	}
 
 	temp = READ_BANK_7;
-	err = pm_chg_write(chip, CHG_TEST, temp);
+	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
 	if (err) {
 		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
+		goto err_out;
 	}
 
 	err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &temp);
 	if (err) {
 		pr_err("pm8xxx_readb fail: addr=%03X, rc=%d\n", CHG_TEST, err);
-		return err;
+		goto err_out;
 	}
 	/* get the lower 4 bits */
 	ret = temp & 0xF;
 
 	temp = READ_BANK_4;
-	err = pm_chg_write(chip, CHG_TEST, temp);
+	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
 	if (err) {
 		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
+		goto err_out;
 	}
 
 	err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &temp);
 	if (err) {
 		pr_err("pm8xxx_readb fail: addr=%03X, rc=%d\n", CHG_TEST, err);
-		return err;
+		goto err_out;
 	}
 	/* get the upper 1 bit */
 	ret |= (temp & 0x1) << 4;
+
+err_out:
+	if (err)
+		return err;
+
 	return  ret;
 }
 
 #define READ_BANK_6		0x60
 static int pm_chg_get_regulation_loop(struct pm8921_chg_chip *chip)
 {
-	u8 temp;
-	int err;
+	u8 temp, data;
+	int err = 0;
 
 	temp = READ_BANK_6;
-	err = pm_chg_write(chip, CHG_TEST, temp);
+	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
 	if (err) {
 		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
+		goto err_out;
 	}
 
-	err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &temp);
+	err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &data);
 	if (err) {
 		pr_err("pm8xxx_readb fail: addr=%03X, rc=%d\n", CHG_TEST, err);
-		return err;
+		goto err_out;
 	}
 
+err_out:
+	if (err)
+		return err;
+
 	/* return the lower 4 bits */
-	return temp & CHG_ALL_LOOPS;
+	return data & CHG_ALL_LOOPS;
 }
 
 #define CHG_USB_SUSPEND_BIT  BIT(2)
@@ -1388,6 +1355,7 @@
 	POWER_SUPPLY_PROP_ONLINE,
 	POWER_SUPPLY_PROP_CURRENT_MAX,
 	POWER_SUPPLY_PROP_SCOPE,
+	POWER_SUPPLY_PROP_HEALTH,
 };
 
 static enum power_supply_property pm_power_props_mains[] = {
@@ -1425,7 +1393,7 @@
 			return 0;
 		}
 
-		type = the_chip->usb_psy.type;
+		type = the_chip->usb_type;
 		if (type == POWER_SUPPLY_TYPE_USB_DCP ||
 			type == POWER_SUPPLY_TYPE_USB_ACA ||
 			type == POWER_SUPPLY_TYPE_USB_CDP)
@@ -1438,6 +1406,24 @@
 	return 0;
 }
 
+static int disable_aicl(int disable)
+{
+	if (disable != POWER_SUPPLY_HEALTH_UNKNOWN
+		&& disable != POWER_SUPPLY_HEALTH_GOOD) {
+		pr_err("called with invalid param :%d\n", disable);
+		return -EINVAL;
+	}
+
+	if (!the_chip) {
+		pr_err("%s called before init\n", __func__);
+		return -EINVAL;
+	}
+
+	pr_debug("Disable AICL = %d\n", disable);
+	the_chip->disable_aicl = disable;
+	return 0;
+}
+
 static int switch_usb_to_charge_mode(struct pm8921_chg_chip *chip)
 {
 	int rc;
@@ -1495,12 +1481,28 @@
 		break;
 	case POWER_SUPPLY_PROP_TYPE:
 		return pm8921_set_usb_power_supply_type(val->intval);
+	case POWER_SUPPLY_PROP_HEALTH:
+		/* UNKNOWN(0) means enable aicl, GOOD(1) means disable aicl */
+		return disable_aicl(val->intval);
 	default:
 		return -EINVAL;
 	}
 	return 0;
 }
 
+static int usb_property_is_writeable(struct power_supply *psy,
+						enum power_supply_property psp)
+{
+	switch (psp) {
+	case POWER_SUPPLY_PROP_HEALTH:
+		return 1;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static int pm_power_get_property_usb(struct power_supply *psy,
 				  enum power_supply_property psp,
 				  union power_supply_propval *val)
@@ -1524,7 +1526,7 @@
 	case POWER_SUPPLY_PROP_ONLINE:
 		val->intval = 0;
 
-		if (the_chip->usb_psy.type == POWER_SUPPLY_TYPE_USB)
+		if (the_chip->usb_type == POWER_SUPPLY_TYPE_USB)
 			val->intval = is_usb_chg_plugged_in(the_chip);
 
 		break;
@@ -1535,6 +1537,10 @@
 		else
 			val->intval = POWER_SUPPLY_SCOPE_DEVICE;
 		break;
+	case POWER_SUPPLY_PROP_HEALTH:
+		/* UNKNOWN(0) means enable aicl, GOOD(1) means disable aicl */
+		val->intval = the_chip->disable_aicl;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -1574,13 +1580,18 @@
 	return (int)result.physical;
 }
 
-static unsigned int voltage_based_capacity(struct pm8921_chg_chip *chip)
+static int voltage_based_capacity(struct pm8921_chg_chip *chip)
 {
-	unsigned int current_voltage_uv = get_prop_battery_uvolts(chip);
-	unsigned int current_voltage_mv = current_voltage_uv / 1000;
+	int current_voltage_uv = get_prop_battery_uvolts(chip);
+	int current_voltage_mv = current_voltage_uv / 1000;
 	unsigned int low_voltage = chip->min_voltage_mv;
 	unsigned int high_voltage = chip->max_voltage_mv;
 
+	if (current_voltage_uv < 0) {
+		pr_err("Error reading current voltage\n");
+		return -EIO;
+	}
+
 	if (current_voltage_mv <= low_voltage)
 		return 0;
 	else if (current_voltage_mv >= high_voltage)
@@ -1638,6 +1649,11 @@
 	if (percent_soc == -ENXIO)
 		percent_soc = voltage_based_capacity(chip);
 
+	if (percent_soc < 0) {
+		pr_err("Unable to read battery voltage\n");
+		goto fail_voltage;
+	}
+
 	if (percent_soc <= 10)
 		pr_warn_ratelimited("low battery charge = %d%%\n",
 						percent_soc);
@@ -1658,30 +1674,34 @@
 			pm_chg_vbatdet_set(the_chip, PM8921_CHG_VBATDET_MAX);
 	}
 
+fail_voltage:
 	chip->recent_reported_soc = percent_soc;
 	return percent_soc;
 }
 
-static int get_prop_batt_current_max(struct pm8921_chg_chip *chip)
+static int get_prop_batt_current_max(struct pm8921_chg_chip *chip, int *curr)
 {
-	return pm8921_bms_get_current_max();
+	*curr = 0;
+	*curr = pm8921_bms_get_current_max();
+	if (*curr == -EINVAL)
+		return -EINVAL;
+
+	return 0;
 }
 
-static int get_prop_batt_current(struct pm8921_chg_chip *chip)
+static int get_prop_batt_current(struct pm8921_chg_chip *chip, int *curr)
 {
-	int result_ua, rc;
+	int rc;
 
-	rc = pm8921_bms_get_battery_current(&result_ua);
+	*curr = 0;
+	rc = pm8921_bms_get_battery_current(curr);
 	if (rc == -ENXIO) {
-		rc = pm8xxx_ccadc_get_battery_current(&result_ua);
+		rc = pm8xxx_ccadc_get_battery_current(curr);
 	}
-
-	if (rc) {
+	if (rc)
 		pr_err("unable to get batt current rc = %d\n", rc);
-		return rc;
-	} else {
-		return result_ua;
-	}
+
+	return rc;
 }
 
 static int get_prop_batt_fcc(struct pm8921_chg_chip *chip)
@@ -1694,17 +1714,15 @@
 	return rc;
 }
 
-static int get_prop_batt_charge_now(struct pm8921_chg_chip *chip)
+static int get_prop_batt_charge_now(struct pm8921_chg_chip *chip, int *cc_uah)
 {
 	int rc;
-	int cc_uah;
 
-	rc = pm8921_bms_cc_uah(&cc_uah);
+	*cc_uah = 0;
+	rc = pm8921_bms_cc_uah(cc_uah);
+	if (rc)
+		pr_err("unable to get batt fcc rc = %d\n", rc);
 
-	if (rc == 0)
-		return cc_uah;
-
-	pr_err("unable to get batt fcc rc = %d\n", rc);
 	return rc;
 }
 
@@ -1748,13 +1766,15 @@
 }
 
 #define MAX_TOLERABLE_BATT_TEMP_DDC	680
-static int get_prop_batt_temp(struct pm8921_chg_chip *chip)
+static int get_prop_batt_temp(struct pm8921_chg_chip *chip, int *temp)
 {
 	int rc;
 	struct pm8xxx_adc_chan_result result;
 
-	if (chip->battery_less_hardware)
-		return 300;
+	if (chip->battery_less_hardware) {
+		*temp = 300;
+		return 0;
+	}
 
 	rc = pm8xxx_adc_read(chip->batt_temp_channel, &result);
 	if (rc) {
@@ -1768,16 +1788,19 @@
 		pr_err("BATT_TEMP= %d > 68degC, device will be shutdown\n",
 							(int) result.physical);
 
-	return (int)result.physical;
+	*temp = (int)result.physical;
+
+	return rc;
 }
 
 static int pm_batt_power_get_property(struct power_supply *psy,
 				       enum power_supply_property psp,
 				       union power_supply_propval *val)
 {
+	int rc = 0;
+	int value;
 	struct pm8921_chg_chip *chip = container_of(psy, struct pm8921_chg_chip,
 								batt_psy);
-
 	switch (psp) {
 	case POWER_SUPPLY_PROP_STATUS:
 		val->intval = get_prop_batt_status(chip);
@@ -1789,7 +1812,11 @@
 		val->intval = get_prop_batt_health(chip);
 		break;
 	case POWER_SUPPLY_PROP_PRESENT:
-		val->intval = get_prop_batt_present(chip);
+		rc = get_prop_batt_present(chip);
+		if (rc >= 0) {
+			val->intval = rc;
+			rc = 0;
+		}
 		break;
 	case POWER_SUPPLY_PROP_TECHNOLOGY:
 		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
@@ -1801,36 +1828,57 @@
 		val->intval = chip->min_voltage_mv * 1000;
 		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-		val->intval = get_prop_battery_uvolts(chip);
+		rc = get_prop_battery_uvolts(chip);
+		if (rc >= 0) {
+			val->intval = rc;
+			rc = 0;
+		}
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
-		val->intval = get_prop_batt_capacity(chip);
+		rc = get_prop_batt_capacity(chip);
+		if (rc >= 0) {
+			val->intval = rc;
+			rc = 0;
+		}
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
-		val->intval = get_prop_batt_current(chip);
+		rc = get_prop_batt_current(chip, &value);
+		if (!rc)
+			val->intval = value;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_MAX:
-		val->intval = get_prop_batt_current_max(chip);
+		rc = get_prop_batt_current_max(chip, &value);
+		if (!rc)
+			val->intval = value;
 		break;
 	case POWER_SUPPLY_PROP_TEMP:
-		val->intval = get_prop_batt_temp(chip);
+		rc = get_prop_batt_temp(chip, &value);
+		if (!rc)
+			val->intval = value;
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_FULL:
-		val->intval = get_prop_batt_fcc(chip);
+		rc = get_prop_batt_fcc(chip);
+		if (rc >= 0) {
+			val->intval = rc;
+			rc = 0;
+		}
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_NOW:
-		val->intval = get_prop_batt_charge_now(chip);
+		rc = get_prop_batt_charge_now(chip, &value);
+		if (!rc) {
+			val->intval = value;
+			rc = 0;
+		}
 		break;
 	default:
-		return -EINVAL;
+		rc = -EINVAL;
 	}
 
-	return 0;
+	return rc;
 }
 
 static void (*notify_vbus_state_func_ptr)(int);
 static int usb_chg_current;
-static DEFINE_SPINLOCK(vbus_lock);
 
 int pm8921_charger_register_vbus_sn(void (*callback)(int))
 {
@@ -1859,7 +1907,6 @@
 	}
 }
 
-/* assumes vbus_lock is held */
 static void __pm8921_charger_vbus_draw(unsigned int mA)
 {
 	int i, rc;
@@ -1913,15 +1960,10 @@
 /* USB calls these to tell us how much max usb current the system can draw */
 void pm8921_charger_vbus_draw(unsigned int mA)
 {
-	unsigned long flags;
+	int set_usb_now_ma;
 
 	pr_debug("Enter charge=%d\n", mA);
 
-	if (!the_chip) {
-		pr_err("chip not yet initalized\n");
-		return;
-	}
-
 	/*
 	 * Reject VBUS requests if USB connection is the only available
 	 * power source. This makes sure that if booting without
@@ -1931,10 +1973,10 @@
 	 * This would also apply when the battery has been
 	 * removed from the running system.
 	 */
-	if (!get_prop_batt_present(the_chip)
+	if (mA == 0 && the_chip && !get_prop_batt_present(the_chip)
 		&& !is_dc_chg_plugged_in(the_chip)) {
 		if (!the_chip->has_dc_supply) {
-			pr_err("rejected: no other power source connected\n");
+			pr_err("rejected: no other power source mA = %d\n", mA);
 			return;
 		}
 	}
@@ -1947,23 +1989,26 @@
 	if (usb_target_ma == 0 && mA > USB_WALL_THRESHOLD_MA)
 		usb_target_ma = mA;
 
-	spin_lock_irqsave(&vbus_lock, flags);
-	if (the_chip) {
-		if (mA > USB_WALL_THRESHOLD_MA)
-			__pm8921_charger_vbus_draw(USB_WALL_THRESHOLD_MA);
-		else
-			__pm8921_charger_vbus_draw(mA);
-	} else {
+	if (usb_target_ma)
+		usb_target_ma = mA;
+
+
+	if (mA > USB_WALL_THRESHOLD_MA)
+		set_usb_now_ma = USB_WALL_THRESHOLD_MA;
+	else
+		set_usb_now_ma = mA;
+
+	if (the_chip && the_chip->disable_aicl)
+		set_usb_now_ma = mA;
+
+	if (the_chip)
+		__pm8921_charger_vbus_draw(set_usb_now_ma);
+	else
 		/*
 		 * called before pmic initialized,
 		 * save this value and use it at probe
 		 */
-		if (mA > USB_WALL_THRESHOLD_MA)
-			usb_chg_current = USB_WALL_THRESHOLD_MA;
-		else
-			usb_chg_current = mA;
-	}
-	spin_unlock_irqrestore(&vbus_lock, flags);
+		usb_chg_current = set_usb_now_ma;
 }
 EXPORT_SYMBOL_GPL(pm8921_charger_vbus_draw);
 
@@ -2190,7 +2235,7 @@
 	if (type < POWER_SUPPLY_TYPE_USB && type > POWER_SUPPLY_TYPE_BATTERY)
 		return -EINVAL;
 
-	the_chip->usb_psy.type = type;
+	the_chip->usb_type = type;
 	power_supply_changed(&the_chip->usb_psy);
 	power_supply_changed(&the_chip->dc_psy);
 	return 0;
@@ -2199,103 +2244,22 @@
 
 int pm8921_batt_temperature(void)
 {
+	int temp = 0, rc = 0;
 	if (!the_chip) {
 		pr_err("called before init\n");
 		return -EINVAL;
 	}
-	return get_prop_batt_temp(the_chip);
-}
-
-static int __pm8921_apply_19p2mhz_kickstart(struct pm8921_chg_chip *chip)
-{
-	int err;
-	u8 temp;
-
-
-	temp  = 0xD1;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
+	rc = get_prop_batt_temp(the_chip, &temp);
+	if (rc) {
+		pr_err("Unable to read temperature");
+		return rc;
 	}
-
-	temp  = 0xD3;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
-	}
-
-	temp  = 0xD1;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
-	}
-
-	temp  = 0xD5;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
-	}
-
-	/* Wait a few clock cycles before re-enabling hw clock switching */
-	udelay(183);
-
-	temp  = 0xD1;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
-	}
-
-	temp  = 0xD0;
-	err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp);
-	if (err) {
-		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
-		return err;
-	}
-
-	/* Wait for few clock cycles before re-enabling LPM */
-	udelay(32);
-
-	return 0;
-}
-
-static int pm8921_apply_19p2mhz_kickstart(struct pm8921_chg_chip *chip)
-{
-	int err;
-	unsigned long flags = 0;
-
-	spin_lock_irqsave(&lpm_lock, flags);
-	err = pm8921_chg_set_lpm(chip, 0);
-	if (err) {
-		pr_err("Error settig LPM rc=%d\n", err);
-		goto kick_err;
-	}
-
-	__pm8921_apply_19p2mhz_kickstart(chip);
-
-kick_err:
-	err = pm8921_chg_set_lpm(chip, 1);
-	if (err)
-		pr_err("Error settig LPM rc=%d\n", err);
-
-	spin_unlock_irqrestore(&lpm_lock, flags);
-
-	return err;
+	return temp;
 }
 
 static void handle_usb_insertion_removal(struct pm8921_chg_chip *chip)
 {
-	int usb_present, rc = 0;
-
-	if (chip->lockup_lpm_wrkarnd) {
-		rc = pm8921_apply_19p2mhz_kickstart(chip);
-		if (rc)
-			pr_err("Failed to apply kickstart rc=%d\n", rc);
-	}
+	int usb_present;
 
 	pm_chg_failed_clear(chip, 1);
 	usb_present = is_usb_chg_plugged_in(chip);
@@ -2305,11 +2269,6 @@
 		power_supply_changed(&chip->usb_psy);
 		power_supply_changed(&chip->batt_psy);
 		pm8921_bms_calibrate_hkadc();
-
-		/* Enable/disable bypass if charger is on battery */
-		if (chip->lockup_lpm_wrkarnd)
-			pm8921_chg_bypass_bat_gone_debounce(chip,
-				is_chg_on_bat(chip));
 	}
 	if (usb_present) {
 		schedule_delayed_work(&chip->unplug_check_work,
@@ -2325,10 +2284,6 @@
 
 static void handle_stop_ext_chg(struct pm8921_chg_chip *chip)
 {
-	if (chip->lockup_lpm_wrkarnd)
-		/* Enable bypass if charger is on battery */
-		pm8921_chg_bypass_bat_gone_debounce(chip, is_chg_on_bat(chip));
-
 	if (!chip->ext_psy) {
 		pr_debug("external charger not registered.\n");
 		return;
@@ -2358,10 +2313,6 @@
 	unsigned long delay =
 		round_jiffies_relative(msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
 
-	/* Disable bypass if charger connected and not running on bat */
-	if (chip->lockup_lpm_wrkarnd)
-		pm8921_chg_bypass_bat_gone_debounce(chip, is_chg_on_bat(chip));
-
 	if (!chip->ext_psy) {
 		pr_debug("external charger not registered.\n");
 		return;
@@ -2602,7 +2553,8 @@
 	 * The AICL algorithm will step up the current from 500mA to target
 	 */
 	if (is_usb_chg_plugged_in(chip)
-		&& usb_target_ma > USB_WALL_THRESHOLD_MA) {
+		&& usb_target_ma > USB_WALL_THRESHOLD_MA
+		&& !chip->disable_aicl) {
 		/* decrease usb_target_ma */
 		decrease_usb_ma_value(&usb_target_ma);
 		/* reset here, increase in unplug_check_worker */
@@ -2836,36 +2788,20 @@
 		/* No charger active */
 		if (!(is_usb_chg_plugged_in(chip)
 				&& !(is_dc_chg_plugged_in(chip)))) {
+			get_prop_batt_current(chip, &ibat);
 			pr_debug(
 			"Stop: chg removed reg_loop = %d, fsm = %d ibat = %d\n",
 				pm_chg_get_regulation_loop(chip),
-				pm_chg_get_fsm_state(chip),
-				get_prop_batt_current(chip)
-				);
-			if (chip->lockup_lpm_wrkarnd) {
-				rc = pm8921_apply_19p2mhz_kickstart(chip);
-				if (rc)
-					pr_err("Failed kickstart rc=%d\n", rc);
-
-				/*
-				 * Make sure kickstart happens at least 200 ms
-				 * after charger has been removed.
-				 */
-				if (chip->final_kickstart) {
-					chip->final_kickstart = false;
-					goto check_again_later;
-				}
-			}
+				pm_chg_get_fsm_state(chip), ibat);
 			return;
 		} else {
 			goto check_again_later;
 		}
 	}
 
-	chip->final_kickstart = true;
-
 	/* AICL only for usb wall charger */
-	if ((active_path & USB_ACTIVE_BIT) && usb_target_ma > 0) {
+	if ((active_path & USB_ACTIVE_BIT) && usb_target_ma > 0 &&
+		!chip->disable_aicl) {
 		reg_loop = pm_chg_get_regulation_loop(chip);
 		pr_debug("reg_loop=0x%x usb_ma = %d\n", reg_loop, usb_ma);
 		if ((reg_loop & VIN_ACTIVE_BIT) &&
@@ -2883,9 +2819,9 @@
 	reg_loop = pm_chg_get_regulation_loop(chip);
 	pr_debug("reg_loop=0x%x usb_ma = %d\n", reg_loop, usb_ma);
 
-	ibat = get_prop_batt_current(chip);
-	if (reg_loop & VIN_ACTIVE_BIT) {
-		if (ibat > 0) {
+	rc = get_prop_batt_current(chip, &ibat);
+	if ((reg_loop & VIN_ACTIVE_BIT) && !chip->disable_chg_rmvl_wrkarnd) {
+		if (ibat > 0 && !rc) {
 			pr_debug("revboost ibat = %d fsm = %d loop = 0x%x\n",
 				ibat, pm_chg_get_fsm_state(chip), reg_loop);
 			attempt_reverse_boost_fix(chip);
@@ -2904,7 +2840,8 @@
 			active_path, active_chg_plugged_in);
 	chg_gone = pm_chg_get_rt_status(chip, CHG_GONE_IRQ);
 
-	if (chg_gone == 1  && active_chg_plugged_in == 1) {
+	if (chg_gone == 1  && active_chg_plugged_in == 1 &&
+					!chip->disable_chg_rmvl_wrkarnd) {
 		pr_debug("chg_gone=%d, active_chg_plugged_in = %d\n",
 					chg_gone, active_chg_plugged_in);
 		unplug_ovp_fet_open(chip);
@@ -2913,10 +2850,13 @@
 	/* AICL only for usb wall charger */
 	if (!(reg_loop & VIN_ACTIVE_BIT) && (active_path & USB_ACTIVE_BIT)
 		&& usb_target_ma > 0
-		&& !charging_disabled) {
+		&& !charging_disabled
+		&& !chip->disable_aicl) {
 		/* only increase iusb_max if vin loop not active */
 		if (usb_ma < usb_target_ma) {
 			increase_usb_ma_value(&usb_ma);
+			if (usb_ma > usb_target_ma)
+				usb_ma = usb_target_ma;
 			__pm8921_charger_vbus_draw(usb_ma);
 			pr_debug("usb_now=%d, usb_target = %d\n",
 					usb_ma, usb_target_ma);
@@ -2963,11 +2903,14 @@
 {
 	int i = 0;
 
-	for (i = ARRAY_SIZE(ibatmax_adj_table) - 1; i >= 0; i--) {
-		if (ibat_target_ma <= ibatmax_adj_table[i].ibat_max_ma)
+	for (i = ARRAY_SIZE(ibatmax_adj_table); i > 0; i--) {
+		if (ibat_target_ma >= ibatmax_adj_table[i - 1].ibat_max_ma)
 			break;
 	}
 
+	if (i > 0)
+		i--;
+
 	return ibatmax_adj_table[i].max_adj_ma;
 }
 
@@ -3152,11 +3095,6 @@
 		else
 			handle_stop_ext_chg(chip);
 	} else {
-		if (chip->lockup_lpm_wrkarnd)
-			/* if no external supply call bypass debounce here */
-			pm8921_chg_bypass_bat_gone_debounce(chip,
-				is_chg_on_bat(chip));
-
 		if (dc_present)
 			schedule_delayed_work(&chip->unplug_check_work,
 				msecs_to_jiffies(UNPLUG_CHECK_WAIT_PERIOD_MS));
@@ -3208,6 +3146,9 @@
 
 static void pm_batt_external_power_changed(struct power_supply *psy)
 {
+	if (!the_chip)
+		return;
+
 	/* Only look for an external supply if it hasn't been registered */
 	if (!the_chip->ext_psy)
 		class_for_each_device(power_supply_class, NULL, psy,
@@ -3225,6 +3166,22 @@
 	struct delayed_work *dwork = to_delayed_work(work);
 	struct pm8921_chg_chip *chip = container_of(dwork,
 				struct pm8921_chg_chip, update_heartbeat_work);
+	bool chg_present = chip->usb_present || chip->dc_present;
+
+	/* for battery health when charger is not connected */
+	if (chip->btc_override && !chg_present)
+		schedule_delayed_work(&chip->btc_override_work,
+			round_jiffies_relative(msecs_to_jiffies
+					(chip->btc_delay_ms)));
+
+	/*
+	 * check temp thresholds when charger is present and
+	 * and battery is FULL. The temperature here can impact
+	 * the charging restart conditions.
+	 */
+	if (chip->btc_override && chg_present &&
+				!wake_lock_active(&chip->eoc_wake_lock))
+		check_temp_thresholds(chip);
 
 	power_supply_changed(&chip->batt_psy);
 	if (chip->recent_reported_soc <= 20)
@@ -3244,6 +3201,7 @@
 static int ichg_threshold_ua = -400000;
 module_param(ichg_threshold_ua, int, 0644);
 
+#define MIN_DELTA_MV_TO_INCREASE_VDD_MAX	13
 #define PM8921_CHG_VDDMAX_RES_MV	10
 static void adjust_vdd_max_for_fastchg(struct pm8921_chg_chip *chip,
 						int vbat_batt_terminal_uv)
@@ -3275,6 +3233,14 @@
 
 	delta_mv =  chip->max_voltage_mv - vbat_batt_terminal_mv;
 
+	if (delta_mv > 0) /* meaning we want to increase the vddmax */ {
+		if (delta_mv < MIN_DELTA_MV_TO_INCREASE_VDD_MAX) {
+			pr_debug("vterm = %d is not low enough to inc vdd\n",
+							vbat_batt_terminal_mv);
+			return;
+		}
+	}
+
 	adj_vdd_max_mv = programmed_vdd_max + delta_mv;
 	pr_debug("vdd_max needs to be changed by %d mv from %d to %d\n",
 			delta_mv,
@@ -3286,8 +3252,8 @@
 		return;
 	}
 
-	adj_vdd_max_mv = DIV_ROUND_UP(adj_vdd_max_mv, PM8921_CHG_VDDMAX_RES_MV)
-					* PM8921_CHG_VDDMAX_RES_MV;
+	adj_vdd_max_mv = (adj_vdd_max_mv / PM8921_CHG_VDDMAX_RES_MV)
+						* PM8921_CHG_VDDMAX_RES_MV;
 
 	if (adj_vdd_max_mv > (chip->max_voltage_mv + vdd_max_increase_mv))
 		adj_vdd_max_mv = chip->max_voltage_mv + vdd_max_increase_mv;
@@ -3362,16 +3328,16 @@
 
 static void check_temp_thresholds(struct pm8921_chg_chip *chip)
 {
-	int temp = 0;
+	int temp = 0, rc;
 
-	temp = get_prop_batt_temp(chip);
+	rc = get_prop_batt_temp(chip, &temp);
 	pr_debug("temp = %d, warm_thr_temp = %d, cool_thr_temp = %d\n",
 			temp, chip->warm_temp_dc,
 			chip->cool_temp_dc);
 
 	if (chip->warm_temp_dc != INT_MIN) {
 		if (chip->is_bat_warm
-			&& temp < chip->warm_temp_dc - TEMP_HYSTERISIS_DECIDEGC)
+			&& temp < chip->warm_temp_dc - chip->hysteresis_temp_dc)
 			battery_warm(false);
 		else if (!chip->is_bat_warm && temp >= chip->warm_temp_dc)
 			battery_warm(true);
@@ -3379,7 +3345,7 @@
 
 	if (chip->cool_temp_dc != INT_MIN) {
 		if (chip->is_bat_cool
-			&& temp > chip->cool_temp_dc + TEMP_HYSTERISIS_DECIDEGC)
+			&& temp > chip->cool_temp_dc + chip->hysteresis_temp_dc)
 			battery_cool(false);
 		else if (!chip->is_bat_cool && temp <= chip->cool_temp_dc)
 			battery_cool(true);
@@ -3445,9 +3411,11 @@
 		else
 			vbat_intended = chip->max_voltage_mv;
 
-		if (vbat_batt_terminal_uv / 1000 < vbat_intended) {
-			pr_debug("terminal_uv:%d < vbat_intended:%d.\n",
+		if (vbat_batt_terminal_uv / 1000
+			< vbat_intended - MIN_DELTA_MV_TO_INCREASE_VDD_MAX) {
+			pr_debug("terminal_uv:%d < vbat_intended:%d-hyst:%d\n",
 							vbat_batt_terminal_uv,
+							vbat_intended,
 							vbat_intended);
 			return CHG_IN_PROGRESS;
 		}
@@ -3585,13 +3553,18 @@
 		return;
 	}
 
-	decidegc = get_prop_batt_temp(chip);
+	rc = get_prop_batt_temp(chip, &decidegc);
+	if (rc) {
+		pr_info("Failed to read temperature\n");
+		goto fail_btc_temp;
+	}
 
 	pr_debug("temp=%d\n", decidegc);
 
 	temp = pm_chg_get_rt_status(chip, BATTTEMP_HOT_IRQ);
 	if (temp) {
-		if (decidegc < chip->btc_override_hot_decidegc)
+		if (decidegc < chip->btc_override_hot_decidegc -
+				chip->hysteresis_temp_dc)
 			/* stop forcing batt hot */
 			rc = pm_chg_override_hot(chip, 0);
 			if (rc)
@@ -3606,7 +3579,8 @@
 
 	temp = pm_chg_get_rt_status(chip, BATTTEMP_COLD_IRQ);
 	if (temp) {
-		if (decidegc > chip->btc_override_cold_decidegc)
+		if (decidegc > chip->btc_override_cold_decidegc +
+				chip->hysteresis_temp_dc)
 			/* stop forcing batt cold */
 			rc = pm_chg_override_cold(chip, 0);
 			if (rc)
@@ -3627,6 +3601,7 @@
 		return;
 	}
 
+fail_btc_temp:
 	rc = pm_chg_override_hot(chip, 0);
 	if (rc)
 		pr_err("Couldnt write 0 to hot comp\n");
@@ -3669,7 +3644,8 @@
 
 	end = is_charging_finished(chip, vbat_batt_terminal_uv, ichg_meas_ma);
 
-	if (end == CHG_NOT_IN_PROGRESS) {
+	if (end == CHG_NOT_IN_PROGRESS && (!chip->btc_override ||
+		!(chip->usb_present || chip->dc_present))) {
 		count = 0;
 		goto eoc_worker_stop;
 	}
@@ -3697,7 +3673,8 @@
 		chgdone_irq_handler(chip->pmic_chg_irq[CHGDONE_IRQ], chip);
 	} else {
 		check_temp_thresholds(chip);
-		adjust_vdd_max_for_fastchg(chip, vbat_batt_terminal_uv);
+		if (end != CHG_NOT_IN_PROGRESS)
+			adjust_vdd_max_for_fastchg(chip, vbat_batt_terminal_uv);
 		pr_debug("EOC count = %d\n", count);
 		schedule_delayed_work(&chip->eoc_work,
 			      round_jiffies_relative(msecs_to_jiffies
@@ -3706,9 +3683,9 @@
 	}
 
 eoc_worker_stop:
-	wake_unlock(&chip->eoc_wake_lock);
 	/* set the vbatdet back, in case it was changed to trigger charging */
 	set_appropriate_vbatdet(chip);
+	wake_unlock(&chip->eoc_wake_lock);
 }
 
 /**
@@ -3831,7 +3808,6 @@
 /* determines the initial present states */
 static void __devinit determine_initial_state(struct pm8921_chg_chip *chip)
 {
-	unsigned long flags;
 	int fsm_state;
 	int is_fast_chg;
 
@@ -3843,6 +3819,11 @@
 		schedule_delayed_work(&chip->unplug_check_work,
 			msecs_to_jiffies(UNPLUG_CHECK_WAIT_PERIOD_MS));
 		pm8921_chg_enable_irq(chip, CHG_GONE_IRQ);
+
+		if (chip->btc_override)
+			schedule_delayed_work(&chip->btc_override_work,
+					round_jiffies_relative(msecs_to_jiffies
+						(chip->btc_delay_ms)));
 	}
 
 	pm8921_chg_enable_irq(chip, DCIN_VALID_IRQ);
@@ -3856,12 +3837,16 @@
 	pm8921_chg_enable_irq(chip, VBATDET_LOW_IRQ);
 	pm8921_chg_enable_irq(chip, BAT_TEMP_OK_IRQ);
 
-	spin_lock_irqsave(&vbus_lock, flags);
-	if (usb_chg_current) {
-		/* reissue a vbus draw call */
-		__pm8921_charger_vbus_draw(usb_chg_current);
-	}
-	spin_unlock_irqrestore(&vbus_lock, flags);
+	if (get_prop_batt_present(the_chip) || is_dc_chg_plugged_in(the_chip))
+		if (usb_chg_current)
+			/*
+			 * Reissue a vbus draw call only if a battery
+			 * or DC is present. We don't want to brown out the
+			 * device if usb is its only source
+			 */
+			__pm8921_charger_vbus_draw(usb_chg_current);
+	usb_chg_current = 0;
+
 	/*
 	 * The bootloader could have started charging, a fastchg interrupt
 	 * might not happen. Check the real time status and if it is fast
@@ -3985,6 +3970,91 @@
 	return -EINVAL;
 }
 
+static void pm8921_chg_force_19p2mhz_clk(struct pm8921_chg_chip *chip)
+{
+	int err;
+	u8 temp;
+
+	temp  = 0xD1;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD3;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD1;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD5;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	udelay(183);
+
+	temp  = 0xD1;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD0;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+	udelay(32);
+
+	temp  = 0xD1;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD3;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+}
+
+static void pm8921_chg_set_hw_clk_switching(struct pm8921_chg_chip *chip)
+{
+	int err;
+	u8 temp;
+
+	temp  = 0xD1;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+
+	temp  = 0xD0;
+	err = pm_chg_write(chip, CHG_TEST, temp);
+	if (err) {
+		pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST);
+		return;
+	}
+}
+
 #define VREF_BATT_THERM_FORCE_ON	BIT(7)
 static void detect_battery_removal(struct pm8921_chg_chip *chip)
 {
@@ -4016,15 +4086,8 @@
 	u8 subrev;
 	int rc, vdd_safe, fcc_uah, safety_time = DEFAULT_SAFETY_MINUTES;
 
-	spin_lock_init(&lpm_lock);
-
-	if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8921) {
-		rc = __pm8921_apply_19p2mhz_kickstart(chip);
-		if (rc) {
-			pr_err("Failed to apply kickstart rc=%d\n", rc);
-			return rc;
-		}
-	}
+	/* forcing 19p2mhz before accessing any charger registers */
+	pm8921_chg_force_19p2mhz_clk(chip);
 
 	detect_battery_removal(chip);
 
@@ -4272,45 +4335,6 @@
 		return rc;
 	}
 
-	if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8921) {
-		/* Clear kickstart */
-		rc = pm8xxx_writeb(chip->dev->parent, CHG_TEST, 0xD0);
-		if (rc) {
-			pr_err("Failed to clear kickstart rc=%d\n", rc);
-			return rc;
-		}
-
-		/* From here the lpm_workaround will be active */
-		chip->lockup_lpm_wrkarnd = true;
-
-		/* Enable LPM */
-		pm8921_chg_set_lpm(chip, 1);
-	}
-
-	if (chip->lockup_lpm_wrkarnd) {
-		chip->vreg_xoadc = regulator_get(chip->dev, "vreg_xoadc");
-		if (IS_ERR(chip->vreg_xoadc))
-			return -ENODEV;
-
-		rc = regulator_set_optimum_mode(chip->vreg_xoadc, 10000);
-		if (rc < 0) {
-			pr_err("Failed to set configure HPM rc=%d\n", rc);
-			return rc;
-		}
-
-		rc = regulator_set_voltage(chip->vreg_xoadc, 1800000, 1800000);
-		if (rc) {
-			pr_err("Failed to set L14 voltage rc=%d\n", rc);
-			return rc;
-		}
-
-		rc = regulator_enable(chip->vreg_xoadc);
-		if (rc) {
-			pr_err("Failed to enable L14 rc=%d\n", rc);
-			return rc;
-		}
-	}
-
 	return 0;
 }
 
@@ -4561,19 +4585,16 @@
 	int rc;
 	struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
 
-	if (chip->lockup_lpm_wrkarnd) {
-		rc = regulator_disable(chip->vreg_xoadc);
-		if (rc)
-			pr_err("Failed to disable L14 rc=%d\n", rc);
-
-		rc = pm8921_apply_19p2mhz_kickstart(chip);
-		if (rc)
-			pr_err("Failed to apply kickstart rc=%d\n", rc);
-	}
-
 	rc = pm_chg_masked_write(chip, CHG_CNTRL, VREF_BATT_THERM_FORCE_ON, 0);
 	if (rc)
 		pr_err("Failed to Force Vref therm off rc=%d\n", rc);
+
+	rc = pm8921_chg_set_lpm(chip, 1);
+	if (rc)
+		pr_err("Failed to set lpm rc=%d\n", rc);
+
+	pm8921_chg_set_hw_clk_switching(chip);
+
 	return 0;
 }
 
@@ -4582,15 +4603,11 @@
 	int rc;
 	struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
 
-	if (chip->lockup_lpm_wrkarnd) {
-		rc = regulator_enable(chip->vreg_xoadc);
-		if (rc)
-			pr_err("Failed to enable L14 rc=%d\n", rc);
+	pm8921_chg_force_19p2mhz_clk(chip);
 
-		rc = pm8921_apply_19p2mhz_kickstart(chip);
-		if (rc)
-			pr_err("Failed to apply kickstart rc=%d\n", rc);
-	}
+	rc = pm8921_chg_set_lpm(chip, 0);
+	if (rc)
+		pr_err("Failed to set lpm rc=%d\n", rc);
 
 	rc = pm_chg_masked_write(chip, CHG_CNTRL, VREF_BATT_THERM_FORCE_ON,
 						VREF_BATT_THERM_FORCE_ON);
@@ -4612,6 +4629,8 @@
 					is_usb_chg_plugged_in(the_chip)))
 		schedule_delayed_work(&chip->btc_override_work, 0);
 
+	schedule_delayed_work(&chip->update_heartbeat_work, 0);
+
 	return 0;
 }
 
@@ -4619,6 +4638,8 @@
 {
 	struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
 
+	cancel_delayed_work_sync(&chip->update_heartbeat_work);
+
 	if (chip->btc_override)
 		cancel_delayed_work_sync(&chip->btc_override_work);
 
@@ -4675,6 +4696,11 @@
 	else
 		chip->warm_temp_dc = INT_MIN;
 
+	if (pdata->hysteresis_temp)
+		chip->hysteresis_temp_dc = pdata->hysteresis_temp * 10;
+	else
+		chip->hysteresis_temp_dc = TEMP_HYSTERISIS_DECIDEGC;
+
 	chip->temp_check_period = pdata->temp_check_period;
 	chip->max_bat_chg_current = pdata->max_bat_chg_current;
 	/* Assign to corresponding module parameter */
@@ -4690,6 +4716,7 @@
 	chip->vin_min = pdata->vin_min;
 	chip->thermal_mitigation = pdata->thermal_mitigation;
 	chip->thermal_levels = pdata->thermal_levels;
+	chip->disable_chg_rmvl_wrkarnd = pdata->disable_chg_rmvl_wrkarnd;
 
 	chip->cold_thr = pdata->cold_thr;
 	chip->hot_thr = pdata->hot_thr;
@@ -4724,30 +4751,32 @@
 		pm8921_chg_btc_override_init(chip);
 
 	chip->stop_chg_upon_expiry = pdata->stop_chg_upon_expiry;
+	chip->usb_type = POWER_SUPPLY_TYPE_UNKNOWN;
 
-	chip->usb_psy.name = "usb",
-	chip->usb_psy.type = POWER_SUPPLY_TYPE_USB,
-	chip->usb_psy.supplied_to = pm_power_supplied_to,
-	chip->usb_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to),
-	chip->usb_psy.properties = pm_power_props_usb,
-	chip->usb_psy.num_properties = ARRAY_SIZE(pm_power_props_usb),
-	chip->usb_psy.get_property = pm_power_get_property_usb,
-	chip->usb_psy.set_property = pm_power_set_property_usb,
+	chip->usb_psy.name = "usb";
+	chip->usb_psy.type = POWER_SUPPLY_TYPE_USB;
+	chip->usb_psy.supplied_to = pm_power_supplied_to;
+	chip->usb_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to);
+	chip->usb_psy.properties = pm_power_props_usb;
+	chip->usb_psy.num_properties = ARRAY_SIZE(pm_power_props_usb);
+	chip->usb_psy.get_property = pm_power_get_property_usb;
+	chip->usb_psy.set_property = pm_power_set_property_usb;
+	chip->usb_psy.property_is_writeable = usb_property_is_writeable;
 
-	chip->dc_psy.name = "pm8921-dc",
-	chip->dc_psy.type = POWER_SUPPLY_TYPE_MAINS,
-	chip->dc_psy.supplied_to = pm_power_supplied_to,
-	chip->dc_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to),
-	chip->dc_psy.properties = pm_power_props_mains,
-	chip->dc_psy.num_properties = ARRAY_SIZE(pm_power_props_mains),
-	chip->dc_psy.get_property = pm_power_get_property_mains,
+	chip->dc_psy.name = "pm8921-dc";
+	chip->dc_psy.type = POWER_SUPPLY_TYPE_MAINS;
+	chip->dc_psy.supplied_to = pm_power_supplied_to;
+	chip->dc_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to);
+	chip->dc_psy.properties = pm_power_props_mains;
+	chip->dc_psy.num_properties = ARRAY_SIZE(pm_power_props_mains);
+	chip->dc_psy.get_property = pm_power_get_property_mains;
 
-	chip->batt_psy.name = "battery",
-	chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY,
-	chip->batt_psy.properties = msm_batt_power_props,
-	chip->batt_psy.num_properties = ARRAY_SIZE(msm_batt_power_props),
-	chip->batt_psy.get_property = pm_batt_power_get_property,
-	chip->batt_psy.external_power_changed = pm_batt_external_power_changed,
+	chip->batt_psy.name = "battery";
+	chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY;
+	chip->batt_psy.properties = msm_batt_power_props;
+	chip->batt_psy.num_properties = ARRAY_SIZE(msm_batt_power_props);
+	chip->batt_psy.get_property = pm_batt_power_get_property;
+	chip->batt_psy.external_power_changed = pm_batt_external_power_changed;
 	rc = power_supply_register(chip->dev, &chip->usb_psy);
 	if (rc < 0) {
 		pr_err("power_supply_register usb failed rc = %d\n", rc);
@@ -4769,9 +4798,6 @@
 	platform_set_drvdata(pdev, chip);
 	the_chip = chip;
 
-	/* set initial state of the USB charger type to UNKNOWN */
-	power_supply_set_supply_type(&chip->usb_psy, POWER_SUPPLY_TYPE_UNKNOWN);
-
 	wake_lock_init(&chip->eoc_wake_lock, WAKE_LOCK_SUSPEND, "pm8921_eoc");
 	INIT_DELAYED_WORK(&chip->eoc_work, eoc_worker);
 	INIT_DELAYED_WORK(&chip->vin_collapse_check_work,
@@ -4822,7 +4848,6 @@
 {
 	struct pm8921_chg_chip *chip = platform_get_drvdata(pdev);
 
-	regulator_put(chip->vreg_xoadc);
 	free_irqs(chip);
 	platform_set_drvdata(pdev, NULL);
 	the_chip = NULL;
diff --git a/drivers/power/pm8xxx-ccadc.c b/drivers/power/pm8xxx-ccadc.c
index 7e37daa..5313593 100644
--- a/drivers/power/pm8xxx-ccadc.c
+++ b/drivers/power/pm8xxx-ccadc.c
@@ -81,6 +81,7 @@
 	int			r_sense_uohm;
 	struct delayed_work	calib_ccadc_work;
 	struct mutex		calib_mutex;
+	bool			periodic_wakeup;
 };
 
 static struct pm8xxx_ccadc_chip *the_chip;
@@ -367,7 +368,7 @@
 	return 0;
 }
 
-void pm8xxx_calib_ccadc(void)
+static void __pm8xxx_calib_ccadc(int sample_count)
 {
 	u8 data_msb, data_lsb, sec_cntrl;
 	int result_offset, result_gain;
@@ -379,6 +380,8 @@
 		return;
 	}
 
+	pr_debug("sample_count = %d\n", sample_count);
+
 	mutex_lock(&the_chip->calib_mutex);
 	rc = pm8xxx_readb(the_chip->dev->parent,
 					ADC_ARB_SECP_CNTRL, &sec_cntrl);
@@ -405,7 +408,7 @@
 	}
 
 	result_offset = 0;
-	for (i = 0; i < SAMPLE_COUNT; i++) {
+	for (i = 0; i < sample_count; i++) {
 		/* Short analog inputs to CCADC internally to ground */
 		rc = pm8xxx_writeb(the_chip->dev->parent, ADC_ARB_SECP_RSV,
 							CCADC_CALIB_RSV_GND);
@@ -431,7 +434,7 @@
 		result_offset += result;
 	}
 
-	result_offset = result_offset / SAMPLE_COUNT;
+	result_offset = result_offset / sample_count;
 
 
 	pr_debug("offset result_offset = 0x%x, voltage = %llduV\n",
@@ -470,7 +473,7 @@
 	}
 
 	result_gain = 0;
-	for (i = 0; i < SAMPLE_COUNT; i++) {
+	for (i = 0; i < sample_count; i++) {
 		rc = pm8xxx_writeb(the_chip->dev->parent,
 					ADC_ARB_SECP_RSV, CCADC_CALIB_RSV_25MV);
 		if (rc < 0) {
@@ -494,7 +497,7 @@
 
 		result_gain += result;
 	}
-	result_gain = result_gain / SAMPLE_COUNT;
+	result_gain = result_gain / sample_count;
 
 	/*
 	 * result_offset includes INTRINSIC OFFSET
@@ -519,6 +522,16 @@
 calibration_unlock:
 	mutex_unlock(&the_chip->calib_mutex);
 }
+
+static void pm8xxx_calib_ccadc_quick(void)
+{
+	__pm8xxx_calib_ccadc(2);
+}
+
+void pm8xxx_calib_ccadc(void)
+{
+	__pm8xxx_calib_ccadc(SAMPLE_COUNT);
+}
 EXPORT_SYMBOL(pm8xxx_calib_ccadc);
 
 static void calibrate_ccadc_work(struct work_struct *work)
@@ -737,6 +750,7 @@
 	chip->r_sense_uohm = pdata->r_sense_uohm;
 	chip->calib_delay_ms = pdata->calib_delay_ms;
 	chip->batt_temp_channel = pdata->ccadc_cdata.batt_temp_channel;
+	chip->periodic_wakeup = pdata->periodic_wakeup;
 	mutex_init(&chip->calib_mutex);
 
 	calib_ccadc_read_offset_and_gain(chip,
@@ -793,6 +807,12 @@
 		pr_err("unable to get current time: %d\n", rc);
 		return 0;
 	}
+
+	if (the_chip->periodic_wakeup) {
+		pm8xxx_calib_ccadc_quick();
+		return 0;
+	}
+
 	if (current_time_sec > the_chip->last_calib_time) {
 		time_since_last_calib = current_time_sec -
 					the_chip->last_calib_time;
@@ -803,9 +823,11 @@
 				|| delta_temp > CCADC_CALIB_TEMP_THRESH) {
 			the_chip->last_calib_time = current_time_sec;
 			the_chip->last_calib_temp = batt_temp;
-			pm8xxx_calib_ccadc();
+			cancel_delayed_work(&the_chip->calib_ccadc_work);
+			schedule_delayed_work(&the_chip->calib_ccadc_work, 0);
 		}
 	}
+
 	return 0;
 }
 
diff --git a/drivers/power/pmic8058-charger.c b/drivers/power/pmic8058-charger.c
index 70b5d59..36270cf 100644
--- a/drivers/power/pmic8058-charger.c
+++ b/drivers/power/pmic8058-charger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/power/smb137b.c b/drivers/power/smb137b.c
index 7ff8e28..c1728e0 100644
--- a/drivers/power/smb137b.c
+++ b/drivers/power/smb137b.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011 The Linux Foundation. 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 and
diff --git a/drivers/power/smb349.c b/drivers/power/smb349.c
index f9ca81c..29d8c18 100644
--- a/drivers/power/smb349.c
+++ b/drivers/power/smb349.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. 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 and
diff --git a/drivers/regulator/msm-gpio-regulator.c b/drivers/regulator/msm-gpio-regulator.c
index 15e5b53..f8fdc14 100644
--- a/drivers/regulator/msm-gpio-regulator.c
+++ b/drivers/regulator/msm-gpio-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/regulator/pm8058-xo.c b/drivers/regulator/pm8058-xo.c
index 0d57c02..119cbb2 100644
--- a/drivers/regulator/pm8058-xo.c
+++ b/drivers/regulator/pm8058-xo.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/regulator/pm8xxx-regulator.c b/drivers/regulator/pm8xxx-regulator.c
index dfdbb44..1b67c47 100644
--- a/drivers/regulator/pm8xxx-regulator.c
+++ b/drivers/regulator/pm8xxx-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/regulator/pmic8058-regulator.c b/drivers/regulator/pmic8058-regulator.c
index f9b0319..24c7902 100644
--- a/drivers/regulator/pmic8058-regulator.c
+++ b/drivers/regulator/pmic8058-regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/regulator/pmic8901-regulator.c b/drivers/regulator/pmic8901-regulator.c
index 02c9549..c1d0281 100644
--- a/drivers/regulator/pmic8901-regulator.c
+++ b/drivers/regulator/pmic8901-regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/regulator/qpnp-regulator.c b/drivers/regulator/qpnp-regulator.c
index 44fdbc1..5d392f7 100644
--- a/drivers/regulator/qpnp-regulator.c
+++ b/drivers/regulator/qpnp-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/regulator/stub-regulator.c b/drivers/regulator/stub-regulator.c
index 1c4b935..0d8d086 100644
--- a/drivers/regulator/stub-regulator.c
+++ b/drivers/regulator/stub-regulator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/rtc/qpnp-rtc.c b/drivers/rtc/qpnp-rtc.c
index 5650e74..6d8985e 100644
--- a/drivers/rtc/qpnp-rtc.c
+++ b/drivers/rtc/qpnp-rtc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/rtc/rtc-msm.c b/drivers/rtc/rtc-msm.c
index c17e461..99eb41c 100644
--- a/drivers/rtc/rtc-msm.c
+++ b/drivers/rtc/rtc-msm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2011 The Linux Foundation. All rights reserved.
  * Author: San Mehat <san@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index e53374e..aea91ef 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 37b5f41..4e8312b 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -534,6 +534,17 @@
 			 */
 			mb();
 			complete(&dev->rx_msgq_notify);
+		} else if (mt == SLIM_MSG_MT_CORE &&
+			mc == SLIM_MSG_MC_REPORT_ABSENT) {
+			writel_relaxed(MGR_INT_RX_MSG_RCVD, dev->base +
+						MGR_INT_CLR);
+			/*
+			 * Guarantee that CLR bit write goes through
+			 * before signalling completion
+			 */
+			mb();
+			complete(&dev->rx_msgq_notify);
+
 		} else if (mc == SLIM_MSG_MC_REPLY_INFORMATION ||
 				mc == SLIM_MSG_MC_REPLY_VALUE) {
 			msm_slim_rx_enqueue(dev, rx_buf, len);
@@ -1113,6 +1124,7 @@
 		u16 chh[40];
 		struct slim_ch prop;
 		u32 exp;
+		u16 *grph = NULL;
 		u8 coeff, cc;
 		u8 prrate = buf[6];
 		if (len <= 8)
@@ -1133,6 +1145,9 @@
 					return ret;
 				if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
 					sat->satch[j].req_def++;
+				/* First channel in group from satellite */
+				if (i == 8)
+					grph = &sat->satch[j].chanh;
 				continue;
 			}
 			if (sat->nsatch >= MSM_MAX_SATCH)
@@ -1144,6 +1159,8 @@
 			sat->satch[j].chanh = chh[i - 8];
 			if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
 				sat->satch[j].req_def++;
+			if (i == 8)
+				grph = &sat->satch[j].chanh;
 			sat->nsatch++;
 		}
 		prop.dataf = (enum slim_ch_dataf)((buf[3] & 0xE0) >> 5);
@@ -1164,10 +1181,12 @@
 					true, &chh[0]);
 		else
 			ret = slim_define_ch(&sat->satcl, &prop,
-					&chh[0], 1, false, NULL);
+					chh, 1, true, &chh[0]);
 		dev_dbg(dev->dev, "define sat grp returned:%d", ret);
 		if (ret)
 			return ret;
+		else if (grph)
+			*grph = chh[0];
 
 		/* part of group so activating 1 will take care of rest */
 		if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
@@ -1194,7 +1213,8 @@
 			for (i = 0; i < 6; i++)
 				e_addr[i] = buf[7-i];
 
-			ret = slim_assign_laddr(&dev->ctrl, e_addr, 6, &laddr);
+			ret = slim_assign_laddr(&dev->ctrl, e_addr, 6, &laddr,
+						false);
 			/* Is this Qualcomm ported generic device? */
 			if (!ret && e_addr[5] == QC_MFGID_LSB &&
 				e_addr[4] == QC_MFGID_MSB &&
@@ -1299,6 +1319,8 @@
 						slim_control_ch(&sat->satcl,
 							sat->satch[i].chanh,
 							SLIM_CH_REMOVE, true);
+						slim_dealloc_ch(&sat->satcl,
+							sat->satch[i].chanh);
 						sat->satch[i].reconf = false;
 					}
 				}
@@ -1458,6 +1480,10 @@
 			txn.wbuf = wbuf;
 			gen_ack = true;
 			ret = msm_xfer_msg(&dev->ctrl, &txn);
+			break;
+		case SLIM_MSG_MC_REPORT_ABSENT:
+			dev_info(dev->dev, "Received Report Absent Message\n");
+			break;
 		default:
 			break;
 		}
@@ -1659,7 +1685,8 @@
 				laddr = (u8)((buffer[0] >> 16) & 0xff);
 				sat = addr_to_sat(dev, laddr);
 			}
-		} else if ((index * 4) >= msg_len) {
+		}
+		if ((index * 4) >= msg_len) {
 			index = 0;
 			if (sat) {
 				msm_sat_enqueue(sat, buffer, msg_len);
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 3688bfc..1a8cc0f 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -26,6 +26,7 @@
 #define SLIM_HDL_TO_PORT(hdl)	((u32)(hdl) & 0xFF)
 
 #define SLIM_HDL_TO_CHIDX(hdl)	((u16)(hdl) & 0xFF)
+#define SLIM_GRP_TO_NCHAN(hdl)	((u16)(hdl >> 8) & 0xFF)
 
 #define SLIM_SLAVE_PORT(p, la)	(((la)<<16) | (p))
 #define SLIM_MGR_PORT(p)	((0xFF << 16) | (p))
@@ -176,16 +177,27 @@
 static int slim_drv_probe(struct device *dev)
 {
 	const struct slim_driver *sdrv = to_slim_driver(dev->driver);
+	struct slim_device *sbdev = to_slim_device(dev);
+	struct slim_controller *ctrl = sbdev->ctrl;
 
-	if (sdrv->probe)
-		return sdrv->probe(to_slim_device(dev));
+	if (sdrv->probe) {
+		int ret;
+		ret = sdrv->probe(sbdev);
+		if (ret)
+			return ret;
+		if (sdrv->device_up)
+			queue_work(ctrl->wq, &sbdev->wd);
+		return 0;
+	}
 	return -ENODEV;
 }
 
 static int slim_drv_remove(struct device *dev)
 {
 	const struct slim_driver *sdrv = to_slim_driver(dev->driver);
+	struct slim_device *sbdev = to_slim_device(dev);
 
+	sbdev->notified = false;
 	if (sdrv->remove)
 		return sdrv->remove(to_slim_device(dev));
 	return -ENODEV;
@@ -263,6 +275,23 @@
 	.release	= slim_dev_release,
 };
 
+static void slim_report_present(struct work_struct *work)
+{
+	u8 laddr;
+	int ret;
+	struct slim_driver *sbdrv;
+	struct slim_device *sbdev =
+			container_of(work, struct slim_device, wd);
+	if (sbdev->notified || !sbdev->dev.driver)
+		return;
+	ret = slim_get_logical_addr(sbdev, sbdev->e_addr, 6, &laddr);
+	sbdrv = to_slim_driver(sbdev->dev.driver);
+	if (!ret && sbdrv->device_up) {
+		sbdev->notified = true;
+		sbdrv->device_up(sbdev);
+	}
+}
+
 /*
  * slim_add_device: Add a new device without register board info.
  * @ctrl: Controller to which this device is to be added to.
@@ -271,25 +300,23 @@
  */
 int slim_add_device(struct slim_controller *ctrl, struct slim_device *sbdev)
 {
-	int ret = 0;
-
 	sbdev->dev.bus = &slimbus_type;
 	sbdev->dev.parent = ctrl->dev.parent;
 	sbdev->dev.type = &slim_dev_type;
+	sbdev->dev.driver = NULL;
 	sbdev->ctrl = ctrl;
 	slim_ctrl_get(ctrl);
 	dev_set_name(&sbdev->dev, "%s", sbdev->name);
-	/* probe slave on this controller */
-	ret = device_register(&sbdev->dev);
-
-	if (ret)
-		return ret;
-
 	mutex_init(&sbdev->sldev_reconf);
 	INIT_LIST_HEAD(&sbdev->mark_define);
 	INIT_LIST_HEAD(&sbdev->mark_suspend);
 	INIT_LIST_HEAD(&sbdev->mark_removal);
-	return 0;
+	INIT_WORK(&sbdev->wd, slim_report_present);
+	mutex_lock(&ctrl->m_ctrl);
+	list_add_tail(&sbdev->dev_list, &ctrl->devs);
+	mutex_unlock(&ctrl->m_ctrl);
+	/* probe slave on this controller */
+	return device_register(&sbdev->dev);
 }
 EXPORT_SYMBOL_GPL(slim_add_device);
 
@@ -431,6 +458,11 @@
 	ctrl->sched.slots = kzalloc(SLIM_SL_PER_SUPERFRAME, GFP_KERNEL);
 #endif
 	init_completion(&ctrl->pause_comp);
+
+	INIT_LIST_HEAD(&ctrl->devs);
+	ctrl->wq = create_singlethread_workqueue(dev_name(&ctrl->dev));
+	if (!ctrl->wq)
+		goto err_workq_failed;
 	/*
 	 * If devices on a controller were registered before controller,
 	 * this will make sure that they get probed now that controller is up
@@ -443,6 +475,10 @@
 
 	return 0;
 
+err_workq_failed:
+	kfree(ctrl->sched.chc3);
+	kfree(ctrl->sched.chc1);
+	kfree(ctrl->chans);
 err_chan_failed:
 	kfree(ctrl->ports);
 err_port_failed:
@@ -495,6 +531,7 @@
 
 	wait_for_completion(&ctrl->dev_released);
 	list_del(&ctrl->list);
+	destroy_workqueue(ctrl->wq);
 	/* free bus id */
 	mutex_lock(&slim_lock);
 	idr_remove(&ctrl_idr, ctrl->nr);
@@ -637,13 +674,13 @@
 }
 
 static int ctrl_getlogical_addr(struct slim_controller *ctrl, const u8 *eaddr,
-				u8 e_len, u8 *laddr)
+				u8 e_len, u8 *entry)
 {
 	u8 i;
 	for (i = 0; i < ctrl->num_dev; i++) {
 		if (ctrl->addrt[i].valid &&
 			memcmp(ctrl->addrt[i].eaddr, eaddr, e_len) == 0) {
-			*laddr = i;
+			*entry = i;
 			return 0;
 		}
 	}
@@ -655,22 +692,28 @@
  * @ctrl: Controller with which device is enumerated.
  * @e_addr: 6-byte elemental address of the device.
  * @e_len: buffer length for e_addr
- * @laddr: Return logical address.
+  * @laddr: Return logical address (if valid flag is false)
+  * @valid: true if laddr holds a valid address that controller wants to
+  *	set for this enumeration address. Otherwise framework sets index into
+  *	address table as logical address.
  * Called by controller in response to REPORT_PRESENT. Framework will assign
  * a logical address to this enumeration address.
  * Function returns -EXFULL to indicate that all logical addresses are already
  * taken.
  */
 int slim_assign_laddr(struct slim_controller *ctrl, const u8 *e_addr,
-				u8 e_len, u8 *laddr)
+				u8 e_len, u8 *laddr, bool valid)
 {
 	int ret;
-	u8 i;
+	u8 i = 0;
+	bool exists = false;
+	struct slim_device *sbdev;
 	mutex_lock(&ctrl->m_ctrl);
 	/* already assigned */
-	if (ctrl_getlogical_addr(ctrl, e_addr, e_len, laddr) == 0)
-		i = *laddr;
-	else {
+	if (ctrl_getlogical_addr(ctrl, e_addr, e_len, &i) == 0) {
+		*laddr = ctrl->addrt[i].laddr;
+		exists = true;
+	} else {
 		if (ctrl->num_dev >= 254) {
 			ret = -EXFULL;
 			goto ret_assigned_laddr;
@@ -692,19 +735,42 @@
 		}
 		memcpy(ctrl->addrt[i].eaddr, e_addr, e_len);
 		ctrl->addrt[i].valid = true;
+		/* Preferred address is index into table */
+		if (!valid)
+			*laddr = i;
 	}
 
-	ret = ctrl->set_laddr(ctrl, ctrl->addrt[i].eaddr, 6, i);
+	ret = ctrl->set_laddr(ctrl, (const u8 *)&ctrl->addrt[i].eaddr, 6,
+				*laddr);
 	if (ret) {
 		ctrl->addrt[i].valid = false;
 		goto ret_assigned_laddr;
 	}
-	*laddr = i;
+	ctrl->addrt[i].laddr = *laddr;
 
-	dev_dbg(&ctrl->dev, "setting slimbus l-addr:%x\n", i);
+	dev_dbg(&ctrl->dev, "setting slimbus l-addr:%x\n", *laddr);
 ret_assigned_laddr:
 	mutex_unlock(&ctrl->m_ctrl);
-	return ret;
+	if (exists || ret)
+		return ret;
+
+	pr_info("slimbus:%d laddr:0x%x, EAPC:0x%x:0x%x", ctrl->nr, *laddr,
+				e_addr[1], e_addr[2]);
+	mutex_lock(&ctrl->m_ctrl);
+	list_for_each_entry(sbdev, &ctrl->devs, dev_list) {
+		if (memcmp(sbdev->e_addr, e_addr, 6) == 0) {
+			struct slim_driver *sbdrv;
+			sbdev->laddr = *laddr;
+			if (sbdev->dev.driver) {
+				sbdrv = to_slim_driver(sbdev->dev.driver);
+				if (sbdrv->device_up)
+					queue_work(ctrl->wq, &sbdev->wd);
+			}
+			break;
+		}
+	}
+	mutex_unlock(&ctrl->m_ctrl);
+	return 0;
 }
 EXPORT_SYMBOL_GPL(slim_assign_laddr);
 
@@ -722,12 +788,21 @@
 				u8 e_len, u8 *laddr)
 {
 	int ret = 0;
+	u8 entry;
 	struct slim_controller *ctrl = sb->ctrl;
 	if (!ctrl || !laddr || !e_addr || e_len != 6)
 		return -EINVAL;
 	mutex_lock(&ctrl->m_ctrl);
-	ret = ctrl_getlogical_addr(ctrl, e_addr, e_len, laddr);
+	ret = ctrl_getlogical_addr(ctrl, e_addr, e_len, &entry);
+	if (!ret)
+		*laddr = ctrl->addrt[entry].laddr;
 	mutex_unlock(&ctrl->m_ctrl);
+	if (ret == -ENXIO && ctrl->get_laddr) {
+		ret = ctrl->get_laddr(ctrl, e_addr, e_len, laddr);
+		if (!ret)
+			ret = slim_assign_laddr(ctrl, e_addr, e_len, laddr,
+						true);
+	}
 	return ret;
 }
 EXPORT_SYMBOL_GPL(slim_get_logical_addr);
@@ -880,8 +955,6 @@
 	u16 ec;
 	u8 tid, mlen = 6;
 
-	if (sbdev->laddr != SLIM_LA_MANAGER && sbdev->laddr >= ctrl->num_dev)
-		return -ENXIO;
 	ret = slim_ele_access_sanity(msg, mc, rbuf, wbuf, len);
 	if (ret)
 		goto xfer_err;
@@ -1766,7 +1839,7 @@
 	}
 
 	if (grp)
-		*grph = chanh[0];
+		*grph = ((nchan << 8) | SLIM_HDL_TO_CHIDX(chanh[0]));
 	for (i = 0; i < nchan; i++) {
 		u8 chan = SLIM_HDL_TO_CHIDX(chanh[i]);
 		struct slim_ich *slc = &ctrl->chans[chan];
@@ -2578,7 +2651,15 @@
 		slc->state = SLIM_CH_SUSPENDED;
 	}
 
-	ret = slim_allocbw(sb, &subframe, &clkgear);
+	/*
+	 * Controller can override default channel scheduling algorithm.
+	 * (e.g. if controller needs to use fixed channel scheduling based
+	 * on number of channels)
+	 */
+	if (ctrl->allocbw)
+		ret = ctrl->allocbw(sb, &subframe, &clkgear);
+	else
+		ret = slim_allocbw(sb, &subframe, &clkgear);
 
 	if (!ret) {
 		ret = slim_processtxn(ctrl, SLIM_MSG_DEST_BROADCAST,
@@ -2781,6 +2862,7 @@
 	int ret = 0;
 	/* Get rid of the group flag in MSB if any */
 	u8 chan = SLIM_HDL_TO_CHIDX(chanh);
+	u8 nchan = 0;
 	struct slim_ich *slc = &ctrl->chans[chan];
 	if (!(slc->nextgrp & SLIM_START_GRP))
 		return -EINVAL;
@@ -2841,9 +2923,10 @@
 			}
 		}
 
-		if (!(slc->nextgrp & SLIM_END_GRP))
+		nchan++;
+		if (nchan < SLIM_GRP_TO_NCHAN(chanh))
 			chan = SLIM_HDL_TO_CHIDX(slc->nextgrp);
-	} while (!(slc->nextgrp & SLIM_END_GRP));
+	} while (nchan < SLIM_GRP_TO_NCHAN(chanh));
 	mutex_unlock(&ctrl->m_ctrl);
 	if (!ret && commit == true)
 		ret = slim_reconfigure_now(sb);
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index fd98925..5ba244f 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. 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 and
@@ -215,13 +215,12 @@
 	if (dd->input_block_size == 4 || dd->output_block_size == 4)
 		dd->use_dma = 0;
 
-	/* DM mode is currently unsupported for different block sizes */
-	if (dd->input_block_size != dd->output_block_size)
-		dd->use_dma = 0;
-
-	if (dd->use_dma)
-		dd->burst_size = max(dd->input_block_size, DM_BURST_SIZE);
-
+	if (dd->use_dma) {
+		dd->input_burst_size = max(dd->input_block_size,
+					DM_BURST_SIZE);
+		dd->output_burst_size = max(dd->output_block_size,
+					DM_BURST_SIZE);
+	}
 	return;
 
 fifo_size_err:
@@ -394,7 +393,8 @@
 static void msm_spi_setup_dm_transfer(struct msm_spi *dd)
 {
 	dmov_box *box;
-	int bytes_to_send, num_rows, bytes_sent;
+	int bytes_to_send, bytes_sent;
+	int tx_num_rows, rx_num_rows;
 	u32 num_transfers;
 
 	atomic_set(&dd->rx_irq_called, 0);
@@ -426,64 +426,80 @@
 			      dd->max_trfr_len);
 
 	num_transfers = DIV_ROUND_UP(bytes_to_send, dd->bytes_per_word);
-	dd->unaligned_len = bytes_to_send % dd->burst_size;
-	num_rows = bytes_to_send / dd->burst_size;
+	dd->tx_unaligned_len = bytes_to_send % dd->output_burst_size;
+	dd->rx_unaligned_len = bytes_to_send % dd->input_burst_size;
+	tx_num_rows = bytes_to_send / dd->output_burst_size;
+	rx_num_rows = bytes_to_send / dd->input_burst_size;
 
 	dd->mode = SPI_DMOV_MODE;
 
-	if (num_rows) {
+	if (tx_num_rows) {
 		/* src in 16 MSB, dst in 16 LSB */
 		box = &dd->tx_dmov_cmd->box;
 		box->src_row_addr = dd->cur_transfer->tx_dma + bytes_sent;
-		box->src_dst_len = (dd->burst_size << 16) | dd->burst_size;
-		box->num_rows = (num_rows << 16) | num_rows;
-		box->row_offset = (dd->burst_size << 16) | 0;
+		box->src_dst_len
+			= (dd->output_burst_size << 16) | dd->output_burst_size;
+		box->num_rows = (tx_num_rows << 16) | tx_num_rows;
+		box->row_offset = (dd->output_burst_size << 16) | 0;
 
+		dd->tx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
+				   DMOV_CMD_ADDR(dd->tx_dmov_cmd_dma +
+				   offsetof(struct spi_dmov_cmd, box));
+	} else {
+		dd->tx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
+				   DMOV_CMD_ADDR(dd->tx_dmov_cmd_dma +
+				   offsetof(struct spi_dmov_cmd, single_pad));
+	}
+
+	if (rx_num_rows) {
+		/* src in 16 MSB, dst in 16 LSB */
 		box = &dd->rx_dmov_cmd->box;
 		box->dst_row_addr = dd->cur_transfer->rx_dma + bytes_sent;
-		box->src_dst_len = (dd->burst_size << 16) | dd->burst_size;
-		box->num_rows = (num_rows << 16) | num_rows;
-		box->row_offset = (0 << 16) | dd->burst_size;
+		box->src_dst_len
+			= (dd->input_burst_size << 16) | dd->input_burst_size;
+		box->num_rows = (rx_num_rows << 16) | rx_num_rows;
+		box->row_offset = (0 << 16) | dd->input_burst_size;
 
-		dd->tx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
-				   DMOV_CMD_ADDR(dd->tx_dmov_cmd_dma +
-				   offsetof(struct spi_dmov_cmd, box));
 		dd->rx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
 				   DMOV_CMD_ADDR(dd->rx_dmov_cmd_dma +
 				   offsetof(struct spi_dmov_cmd, box));
 	} else {
-		dd->tx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
-				   DMOV_CMD_ADDR(dd->tx_dmov_cmd_dma +
-				   offsetof(struct spi_dmov_cmd, single_pad));
 		dd->rx_dmov_cmd->cmd_ptr = CMD_PTR_LP |
 				   DMOV_CMD_ADDR(dd->rx_dmov_cmd_dma +
 				   offsetof(struct spi_dmov_cmd, single_pad));
 	}
 
-	if (!dd->unaligned_len) {
+	if (!dd->tx_unaligned_len) {
 		dd->tx_dmov_cmd->box.cmd |= CMD_LC;
-		dd->rx_dmov_cmd->box.cmd |= CMD_LC;
 	} else {
 		dmov_s *tx_cmd = &(dd->tx_dmov_cmd->single_pad);
-		dmov_s *rx_cmd = &(dd->rx_dmov_cmd->single_pad);
-		u32 offset = dd->cur_transfer->len - dd->unaligned_len;
+		u32 tx_offset = dd->cur_transfer->len - dd->tx_unaligned_len;
 
 		if ((dd->multi_xfr) && (dd->read_len <= 0))
-			offset = dd->cur_msg_len - dd->unaligned_len;
+			tx_offset = dd->cur_msg_len - dd->tx_unaligned_len;
 
 		dd->tx_dmov_cmd->box.cmd &= ~CMD_LC;
-		dd->rx_dmov_cmd->box.cmd &= ~CMD_LC;
 
-		memset(dd->tx_padding, 0, dd->burst_size);
-		memset(dd->rx_padding, 0, dd->burst_size);
+		memset(dd->tx_padding, 0, dd->output_burst_size);
 		if (dd->write_buf)
-			memcpy(dd->tx_padding, dd->write_buf + offset,
-			       dd->unaligned_len);
+			memcpy(dd->tx_padding, dd->write_buf + tx_offset,
+			       dd->tx_unaligned_len);
 
 		tx_cmd->src = dd->tx_padding_dma;
-		rx_cmd->dst = dd->rx_padding_dma;
-		tx_cmd->len = rx_cmd->len = dd->burst_size;
+		tx_cmd->len = dd->output_burst_size;
 	}
+
+	if (!dd->rx_unaligned_len) {
+		dd->rx_dmov_cmd->box.cmd |= CMD_LC;
+	} else {
+		dmov_s *rx_cmd = &(dd->rx_dmov_cmd->single_pad);
+		dd->rx_dmov_cmd->box.cmd &= ~CMD_LC;
+
+		memset(dd->rx_padding, 0, dd->input_burst_size);
+		rx_cmd->dst = dd->rx_padding_dma;
+		rx_cmd->len = dd->input_burst_size;
+	}
+
 	/* This also takes care of the padding dummy buf
 	   Since this is set to the correct length, the
 	   dummy bytes won't be actually sent */
@@ -641,7 +657,7 @@
 		if ((!dd->read_buf || op & SPI_OP_MAX_INPUT_DONE_FLAG) &&
 		    (!dd->write_buf || op & SPI_OP_MAX_OUTPUT_DONE_FLAG)) {
 			msm_spi_ack_transfer(dd);
-			if (dd->unaligned_len == 0) {
+			if (dd->rx_unaligned_len == 0) {
 				if (atomic_inc_return(&dd->rx_irq_called) == 1)
 					return IRQ_HANDLED;
 			}
@@ -885,11 +901,11 @@
 						 prev_xfr->len,
 						 DMA_TO_DEVICE);
 			}
-			if (dd->unaligned_len && dd->read_buf) {
-				offset = dd->cur_msg_len - dd->unaligned_len;
+			if (dd->rx_unaligned_len && dd->read_buf) {
+				offset = dd->cur_msg_len - dd->rx_unaligned_len;
 				dma_coherent_post_ops();
 				memcpy(dd->read_buf + offset, dd->rx_padding,
-				       dd->unaligned_len);
+				       dd->rx_unaligned_len);
 				memcpy(dd->cur_transfer->rx_buf,
 				       dd->read_buf + prev_xfr->len,
 				       dd->cur_transfer->len);
@@ -911,11 +927,11 @@
 
 unmap_end:
 	/* If we padded the transfer, we copy it from the padding buf */
-	if (dd->unaligned_len && dd->read_buf) {
-		offset = dd->cur_transfer->len - dd->unaligned_len;
+	if (dd->rx_unaligned_len && dd->read_buf) {
+		offset = dd->cur_transfer->len - dd->rx_unaligned_len;
 		dma_coherent_post_ops();
 		memcpy(dd->read_buf + offset, dd->rx_padding,
-		       dd->unaligned_len);
+		       dd->rx_unaligned_len);
 	}
 }
 
@@ -1600,7 +1616,8 @@
 			"use_dma ?    %s\n"
 			"rx block size = %d bytes\n"
 			"tx block size = %d bytes\n"
-			"burst size = %d bytes\n"
+			"input burst size = %d bytes\n"
+			"output burst size = %d bytes\n"
 			"DMA configuration:\n"
 			"tx_ch=%d, rx_ch=%d, tx_crci= %d, rx_crci=%d\n"
 			"--statistics--\n"
@@ -1615,7 +1632,8 @@
 			dd->use_dma ? "yes" : "no",
 			dd->input_block_size,
 			dd->output_block_size,
-			dd->burst_size,
+			dd->input_burst_size,
+			dd->output_burst_size,
 			dd->tx_dma_chan,
 			dd->rx_dma_chan,
 			dd->tx_dma_crci,
@@ -1744,12 +1762,15 @@
 	}
 }
 
-static inline u32 get_chunk_size(struct msm_spi *dd)
+static inline u32 get_chunk_size(struct msm_spi *dd, int input_burst_size,
+			int output_burst_size)
 {
 	u32 cache_line = dma_get_cache_alignment();
+	int burst_size = (input_burst_size > output_burst_size) ?
+		input_burst_size : output_burst_size;
 
 	return (roundup(sizeof(struct spi_dmov_cmd), DM_BYTE_ALIGN) +
-			  roundup(dd->burst_size, cache_line))*2;
+			  roundup(burst_size, cache_line))*2;
 }
 
 static void msm_spi_teardown_dma(struct msm_spi *dd)
@@ -1765,8 +1786,10 @@
 		msleep(10);
 	}
 
-	dma_free_coherent(NULL, get_chunk_size(dd), dd->tx_dmov_cmd,
-			  dd->tx_dmov_cmd_dma);
+	dma_free_coherent(NULL,
+		get_chunk_size(dd, dd->input_burst_size, dd->output_burst_size),
+		dd->tx_dmov_cmd,
+		dd->tx_dmov_cmd_dma);
 	dd->tx_dmov_cmd = dd->rx_dmov_cmd = NULL;
 	dd->tx_padding = dd->rx_padding = NULL;
 }
@@ -1780,8 +1803,11 @@
 
 	/* We send NULL device, since it requires coherent_dma_mask id
 	   device definition, we're okay with using system pool */
-	dd->tx_dmov_cmd = dma_alloc_coherent(NULL, get_chunk_size(dd),
-					     &dd->tx_dmov_cmd_dma, GFP_KERNEL);
+	dd->tx_dmov_cmd
+		= dma_alloc_coherent(NULL,
+			get_chunk_size(dd, dd->input_burst_size,
+				dd->output_burst_size),
+			&dd->tx_dmov_cmd_dma, GFP_KERNEL);
 	if (dd->tx_dmov_cmd == NULL)
 		return -ENOMEM;
 
@@ -1795,9 +1821,9 @@
 	dd->tx_padding = (u8 *)ALIGN((size_t)&dd->rx_dmov_cmd[1], cache_line);
 	dd->tx_padding_dma = ALIGN(dd->rx_dmov_cmd_dma +
 			      sizeof(struct spi_dmov_cmd), cache_line);
-	dd->rx_padding = (u8 *)ALIGN((size_t)(dd->tx_padding + dd->burst_size),
-				     cache_line);
-	dd->rx_padding_dma = ALIGN(dd->tx_padding_dma + dd->burst_size,
+	dd->rx_padding = (u8 *)ALIGN((size_t)(dd->tx_padding +
+		dd->output_burst_size), cache_line);
+	dd->rx_padding_dma = ALIGN(dd->tx_padding_dma + dd->output_burst_size,
 				      cache_line);
 
 	/* Setup DM commands */
diff --git a/drivers/spi/spi_qsd.h b/drivers/spi/spi_qsd.h
index a0dee34..096f526 100644
--- a/drivers/spi/spi_qsd.h
+++ b/drivers/spi/spi_qsd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. 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 and
@@ -283,7 +283,8 @@
 	struct msm_dmov_cmd      rx_hdr;
 	int                      input_block_size;
 	int                      output_block_size;
-	int                      burst_size;
+	int                      input_burst_size;
+	int                      output_burst_size;
 	atomic_t                 rx_irq_called;
 	atomic_t                 tx_irq_called;
 	/* Used to pad messages unaligned to block size */
@@ -291,7 +292,8 @@
 	dma_addr_t               tx_padding_dma;
 	u8                       *rx_padding;
 	dma_addr_t               rx_padding_dma;
-	u32                      unaligned_len;
+	u32                      tx_unaligned_len;
+	u32                      rx_unaligned_len;
 	/* DMA statistics */
 	int                      stat_dmov_tx_err;
 	int                      stat_dmov_rx_err;
diff --git a/drivers/spmi/qpnp-int.c b/drivers/spmi/qpnp-int.c
index 24e35e4..8cb1036 100644
--- a/drivers/spmi/qpnp-int.c
+++ b/drivers/spmi/qpnp-int.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index ae1eff8..6d2a787 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/spmi/spmi-resources.c b/drivers/spmi/spmi-resources.c
index 97f15ae..d2e06fd 100644
--- a/drivers/spmi/spmi-resources.c
+++ b/drivers/spmi/spmi-resources.c
@@ -1,6 +1,6 @@
 /* Copyright (c) 2002-3 Patrick Mochel
  * Copyright (c) 2002-3 Open Source Development Labs
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 914df95..71b6bd6 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 5bac37d..4a9dd1b 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -283,6 +283,10 @@
 		if (tsk->flags & PF_KTHREAD)
 			continue;
 
+		/* if task no longer has any memory ignore it */
+		if (test_task_flag(tsk, TIF_MM_RELEASED))
+			continue;
+
 		if (time_before_eq(jiffies, lowmem_deathpending_timeout)) {
 			if (test_task_flag(tsk, TIF_MEMDIE)) {
 				rcu_read_unlock();
@@ -327,12 +331,14 @@
 		send_sig(SIGKILL, selected, 0);
 		set_tsk_thread_flag(selected, TIF_MEMDIE);
 		rem -= selected_tasksize;
+		rcu_read_unlock();
 		/* give the system time to free up the memory */
 		msleep_interruptible(20);
-	}
+	} else
+		rcu_read_unlock();
+
 	lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n",
 		     nr_to_scan, sc->gfp_mask, rem);
-	rcu_read_unlock();
 	mutex_unlock(&scan_mutex);
 	return rem;
 }
diff --git a/drivers/staging/gobi/QCUSBNet2k/QCUSBNet.c b/drivers/staging/gobi/QCUSBNet2k/QCUSBNet.c
index e7f72e7..d4b4663 100644
--- a/drivers/staging/gobi/QCUSBNet2k/QCUSBNet.c
+++ b/drivers/staging/gobi/QCUSBNet2k/QCUSBNet.c
@@ -20,7 +20,7 @@
    QCUSBNetModInit
    QCUSBNetModExit
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/staging/gobi/QCUSBNet2k/QMI.c b/drivers/staging/gobi/QCUSBNet2k/QMI.c
index fe7eebe..fb88092 100644
--- a/drivers/staging/gobi/QCUSBNet2k/QMI.c
+++ b/drivers/staging/gobi/QCUSBNet2k/QMI.c
@@ -29,7 +29,7 @@
       QMIWDSEventResp
       QMIDMSGetMEIDResp
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/staging/gobi/QCUSBNet2k/QMI.h b/drivers/staging/gobi/QCUSBNet2k/QMI.h
index 4da1285..633d298 100644
--- a/drivers/staging/gobi/QCUSBNet2k/QMI.h
+++ b/drivers/staging/gobi/QCUSBNet2k/QMI.h
@@ -38,7 +38,7 @@
       QMIWDSEventResp
       QMIDMSGetMEIDResp
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/staging/gobi/QCUSBNet2k/QMIDevice.c b/drivers/staging/gobi/QCUSBNet2k/QMIDevice.c
index 668328c..dbe4bb2 100644
--- a/drivers/staging/gobi/QCUSBNet2k/QMIDevice.c
+++ b/drivers/staging/gobi/QCUSBNet2k/QMIDevice.c
@@ -54,7 +54,7 @@
       SetupQMIWDSCallback
       QMIDMSGetMEID
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/staging/gobi/QCUSBNet2k/QMIDevice.h b/drivers/staging/gobi/QCUSBNet2k/QMIDevice.h
index 6fb9c47..29cc269 100644
--- a/drivers/staging/gobi/QCUSBNet2k/QMIDevice.h
+++ b/drivers/staging/gobi/QCUSBNet2k/QMIDevice.h
@@ -54,7 +54,7 @@
       SetupQMIWDSCallback
       QMIDMSGetMEID
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/staging/gobi/QCUSBNet2k/Structs.h b/drivers/staging/gobi/QCUSBNet2k/Structs.h
index 07e3193..7c93503 100644
--- a/drivers/staging/gobi/QCUSBNet2k/Structs.h
+++ b/drivers/staging/gobi/QCUSBNet2k/Structs.h
@@ -8,7 +8,7 @@
 FUNCTIONS:
    none
 
-Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/staging/qcache/fmem.c b/drivers/staging/qcache/fmem.c
index 8f9e0ef..0609f4a 100644
--- a/drivers/staging/qcache/fmem.c
+++ b/drivers/staging/qcache/fmem.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/staging/qcache/qcache-main.c b/drivers/staging/qcache/qcache-main.c
index 063c6fc..f416cfc 100644
--- a/drivers/staging/qcache/qcache-main.c
+++ b/drivers/staging/qcache/qcache-main.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2010,2011, Dan Magenheimer, Oracle Corp.
  * Copyright (c) 2010,2011, Nitin Gupta
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * Qcache provides an in-kernel "host implementation" for transcendent memory
  * and, thus indirectly, for cleancache and frontswap.  Qcache includes a
diff --git a/drivers/staging/qcache/tmem.c b/drivers/staging/qcache/tmem.c
index e5c3f30..40f2246 100644
--- a/drivers/staging/qcache/tmem.c
+++ b/drivers/staging/qcache/tmem.c
@@ -2,7 +2,7 @@
  * In-kernel transcendent memory (generic implementation)
  *
  * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * The primary purpose of Transcedent Memory ("tmem") is to map object-oriented
  * "handles" (triples containing a pool id, and object id, and an index), to
diff --git a/drivers/staging/qcache/tmem.h b/drivers/staging/qcache/tmem.h
index dd8a6ea..359c201 100644
--- a/drivers/staging/qcache/tmem.h
+++ b/drivers/staging/qcache/tmem.h
@@ -4,7 +4,7 @@
  * Transcendent memory
  *
  * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _TMEM_H_
diff --git a/drivers/thermal/msm8960_tsens.c b/drivers/thermal/msm8960_tsens.c
index f60e318..67e0181 100644
--- a/drivers/thermal/msm8960_tsens.c
+++ b/drivers/thermal/msm8960_tsens.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -64,7 +64,7 @@
 #define TSENS_UPPER_STATUS_CLR		BIT((tsens_status_cntl_start + 2))
 #define TSENS_MAX_STATUS_MASK		BIT((tsens_status_cntl_start + 3))
 
-#define TSENS_MEASURE_PERIOD				4 /* 1 sec. default */
+#define TSENS_MEASURE_PERIOD				1
 #define TSENS_8960_SLP_CLK_ENA				BIT(26)
 
 #define TSENS_THRESHOLD_ADDR		(MSM_CLK_CTL_BASE + 0x00003624)
diff --git a/drivers/thermal/msm8974-tsens.c b/drivers/thermal/msm8974-tsens.c
index 3366bba..875ff00 100644
--- a/drivers/thermal/msm8974-tsens.c
+++ b/drivers/thermal/msm8974-tsens.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/thermal/msm_popmem-tm.c b/drivers/thermal/msm_popmem-tm.c
index 583b2db..26ac048 100644
--- a/drivers/thermal/msm_popmem-tm.c
+++ b/drivers/thermal/msm_popmem-tm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 2dd2592..177ebff 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -29,6 +29,9 @@
 static struct msm_thermal_data msm_thermal_info;
 static uint32_t limited_max_freq = MSM_CPUFREQ_NO_LIMIT;
 static struct delayed_work check_temp_work;
+static bool core_control_enabled;
+static uint32_t cpus_offlined;
+static DEFINE_MUTEX(core_control_mutex);
 
 static int limit_idx;
 static int limit_idx_low;
@@ -42,7 +45,7 @@
 
 	table = cpufreq_frequency_get_table(0);
 	if (table == NULL) {
-		pr_debug("%s: error reading cpufreq table\n", __func__);
+		pr_debug("%s: error reading cpufreq table\n", KBUILD_MODNAME);
 		ret = -EINVAL;
 		goto fail;
 	}
@@ -67,21 +70,82 @@
 
 	limited_max_freq = max_freq;
 	if (max_freq != MSM_CPUFREQ_NO_LIMIT)
-		pr_info("msm_thermal: Limiting cpu%d max frequency to %d\n",
-				cpu, max_freq);
+		pr_info("%s: Limiting cpu%d max frequency to %d\n",
+				KBUILD_MODNAME, cpu, max_freq);
 	else
-		pr_info("msm_thermal: Max frequency reset for cpu%d\n", cpu);
+		pr_info("%s: Max frequency reset for cpu%d\n",
+				KBUILD_MODNAME, cpu);
 
 	ret = cpufreq_update_policy(cpu);
 
 	return ret;
 }
 
-static void check_temp(struct work_struct *work)
+static void __cpuinit do_core_control(long temp)
+{
+	int i = 0;
+	int ret = 0;
+
+	if (!core_control_enabled)
+		return;
+
+	/**
+	 *  Offline cores starting from the max MPIDR to 1, when above limit,
+	 *  The core control mask is non zero and allows the core to be turned
+	 *  off.
+	 *  The core was not previously offlined by this module
+	 *  The core is the next in sequence.
+	 *  If the core was online for some reason, even after it was offlined
+	 *  by this module, offline it again.
+	 *  Online the back on if the temp is below the hysteresis and was
+	 *  offlined by this module and not already online.
+	 */
+	mutex_lock(&core_control_mutex);
+	if (msm_thermal_info.core_control_mask &&
+		temp >= msm_thermal_info.core_limit_temp_degC) {
+		for (i = num_possible_cpus(); i > 0; i--) {
+			if (!(msm_thermal_info.core_control_mask & BIT(i)))
+				continue;
+			if (cpus_offlined & BIT(i) && !cpu_online(i))
+				continue;
+			pr_info("%s: Set Offline: CPU%d Temp: %ld\n",
+					KBUILD_MODNAME, i, temp);
+			ret = cpu_down(i);
+			if (ret)
+				pr_err("%s: Error %d offline core %d\n",
+					KBUILD_MODNAME, ret, i);
+			cpus_offlined |= BIT(i);
+			break;
+		}
+	} else if (msm_thermal_info.core_control_mask && cpus_offlined &&
+		temp <= (msm_thermal_info.core_limit_temp_degC -
+			msm_thermal_info.core_temp_hysteresis_degC)) {
+		for (i = 0; i < num_possible_cpus(); i++) {
+			if (!(cpus_offlined & BIT(i)))
+				continue;
+			cpus_offlined &= ~BIT(i);
+			pr_info("%s: Allow Online CPU%d Temp: %ld\n",
+					KBUILD_MODNAME, i, temp);
+			/* If this core is already online, then bring up the
+			 * next offlined core.
+			 */
+			if (cpu_online(i))
+				continue;
+			ret = cpu_up(i);
+			if (ret)
+				pr_err("%s: Error %d online core %d\n",
+						KBUILD_MODNAME, ret, i);
+			break;
+		}
+	}
+	mutex_unlock(&core_control_mutex);
+}
+
+static void __cpuinit check_temp(struct work_struct *work)
 {
 	static int limit_init;
 	struct tsens_device tsens_dev;
-	unsigned long temp = 0;
+	long temp = 0;
 	uint32_t max_freq = limited_max_freq;
 	int cpu = 0;
 	int ret = 0;
@@ -89,8 +153,8 @@
 	tsens_dev.sensor_num = msm_thermal_info.sensor_id;
 	ret = tsens_get_temp(&tsens_dev, &temp);
 	if (ret) {
-		pr_debug("msm_thermal: Unable to read TSENS sensor %d\n",
-				tsens_dev.sensor_num);
+		pr_debug("%s: Unable to read TSENS sensor %d\n",
+				KBUILD_MODNAME, tsens_dev.sensor_num);
 		goto reschedule;
 	}
 
@@ -102,6 +166,8 @@
 			limit_init = 1;
 	}
 
+	do_core_control(temp);
+
 	if (temp >= msm_thermal_info.limit_temp_degC) {
 		if (limit_idx == limit_idx_low)
 			goto reschedule;
@@ -129,8 +195,9 @@
 	for_each_possible_cpu(cpu) {
 		ret = update_cpu_max_freq(cpu, max_freq);
 		if (ret)
-			pr_debug("Unable to limit cpu%d max freq to %d\n",
-					cpu, max_freq);
+			pr_debug(
+			"%s: Unable to limit cpu%d max freq to %d\n",
+					KBUILD_MODNAME, cpu, max_freq);
 	}
 
 reschedule:
@@ -139,7 +206,36 @@
 				msecs_to_jiffies(msm_thermal_info.poll_ms));
 }
 
-static void disable_msm_thermal(void)
+static int __cpuinit msm_thermal_cpu_callback(struct notifier_block *nfb,
+		unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (unsigned long)hcpu;
+
+	if (action == CPU_UP_PREPARE || action == CPU_UP_PREPARE_FROZEN) {
+		if (core_control_enabled &&
+			(msm_thermal_info.core_control_mask & BIT(cpu)) &&
+			(cpus_offlined & BIT(cpu))) {
+			pr_info(
+			"%s: Preventing cpu%d from coming online.\n",
+				KBUILD_MODNAME, cpu);
+			return NOTIFY_BAD;
+		}
+	}
+
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block __refdata msm_thermal_cpu_notifier = {
+	.notifier_call = msm_thermal_cpu_callback,
+};
+
+/**
+ * We will reset the cpu frequencies limits here. The core online/offline
+ * status will be carried over to the process stopping the msm_thermal, as
+ * we dont want to online a core and bring in the thermal issues.
+ */
+static void __cpuinit disable_msm_thermal(void)
 {
 	int cpu = 0;
 
@@ -155,7 +251,7 @@
 	}
 }
 
-static int set_enabled(const char *val, const struct kernel_param *kp)
+static int __cpuinit set_enabled(const char *val, const struct kernel_param *kp)
 {
 	int ret = 0;
 
@@ -163,9 +259,10 @@
 	if (!enabled)
 		disable_msm_thermal();
 	else
-		pr_info("msm_thermal: no action for enabled = %d\n", enabled);
+		pr_info("%s: no action for enabled = %d\n",
+				KBUILD_MODNAME, enabled);
 
-	pr_info("msm_thermal: enabled = %d\n", enabled);
+	pr_info("%s: enabled = %d\n", KBUILD_MODNAME, enabled);
 
 	return ret;
 }
@@ -178,6 +275,153 @@
 module_param_cb(enabled, &module_ops, &enabled, 0644);
 MODULE_PARM_DESC(enabled, "enforce thermal limit on cpu");
 
+
+/* Call with core_control_mutex locked */
+static int __cpuinit update_offline_cores(int val)
+{
+	int cpu = 0;
+	int ret = 0;
+
+	cpus_offlined = msm_thermal_info.core_control_mask & val;
+	if (!core_control_enabled)
+		return 0;
+
+	for_each_possible_cpu(cpu) {
+		if (!(cpus_offlined & BIT(cpu)))
+		       continue;
+		if (!cpu_online(cpu))
+			continue;
+		ret = cpu_down(cpu);
+		if (ret)
+			pr_err("%s: Unable to offline cpu%d\n",
+				KBUILD_MODNAME, cpu);
+	}
+	return ret;
+}
+
+static ssize_t show_cc_enabled(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", core_control_enabled);
+}
+
+static ssize_t __cpuinit store_cc_enabled(struct kobject *kobj,
+		struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	int ret = 0;
+	int val = 0;
+
+	mutex_lock(&core_control_mutex);
+	ret = kstrtoint(buf, 10, &val);
+	if (ret) {
+		pr_err("%s: Invalid input %s\n", KBUILD_MODNAME, buf);
+		goto done_store_cc;
+	}
+
+	if (core_control_enabled == !!val)
+		goto done_store_cc;
+
+	core_control_enabled = !!val;
+	if (core_control_enabled) {
+		pr_info("%s: Core control enabled\n", KBUILD_MODNAME);
+		register_cpu_notifier(&msm_thermal_cpu_notifier);
+		update_offline_cores(cpus_offlined);
+	} else {
+		pr_info("%s: Core control disabled\n", KBUILD_MODNAME);
+		unregister_cpu_notifier(&msm_thermal_cpu_notifier);
+	}
+
+done_store_cc:
+	mutex_unlock(&core_control_mutex);
+	return count;
+}
+
+static ssize_t show_cpus_offlined(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", cpus_offlined);
+}
+
+static ssize_t __cpuinit store_cpus_offlined(struct kobject *kobj,
+		struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	int ret = 0;
+	uint32_t val = 0;
+
+	mutex_lock(&core_control_mutex);
+	ret = kstrtouint(buf, 10, &val);
+	if (ret) {
+		pr_err("%s: Invalid input %s\n", KBUILD_MODNAME, buf);
+		goto done_cc;
+	}
+
+	if (enabled) {
+		pr_err("%s: Ignoring request; polling thread is enabled.\n",
+				KBUILD_MODNAME);
+		goto done_cc;
+	}
+
+	if (cpus_offlined == val)
+		goto done_cc;
+
+	update_offline_cores(val);
+done_cc:
+	mutex_unlock(&core_control_mutex);
+	return count;
+}
+
+static __cpuinitdata struct kobj_attribute cc_enabled_attr =
+__ATTR(enabled, 0644, show_cc_enabled, store_cc_enabled);
+
+static __cpuinitdata struct kobj_attribute cpus_offlined_attr =
+__ATTR(cpus_offlined, 0644, show_cpus_offlined, store_cpus_offlined);
+
+static __cpuinitdata struct attribute *cc_attrs[] = {
+	&cc_enabled_attr.attr,
+	&cpus_offlined_attr.attr,
+	NULL,
+};
+
+static __cpuinitdata struct attribute_group cc_attr_group = {
+	.attrs = cc_attrs,
+};
+
+static __init int msm_thermal_add_cc_nodes(void)
+{
+	struct kobject *module_kobj = NULL;
+	struct kobject *cc_kobj = NULL;
+	int ret = 0;
+
+	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
+	if (!module_kobj) {
+		pr_err("%s: cannot find kobject for module\n",
+			KBUILD_MODNAME);
+		ret = -ENOENT;
+		goto done_cc_nodes;
+	}
+
+	cc_kobj = kobject_create_and_add("core_control", module_kobj);
+	if (!cc_kobj) {
+		pr_err("%s: cannot create core control kobj\n",
+				KBUILD_MODNAME);
+		ret = -ENOMEM;
+		goto done_cc_nodes;
+	}
+
+	ret = sysfs_create_group(cc_kobj, &cc_attr_group);
+	if (ret) {
+		pr_err("%s: cannot create group\n", KBUILD_MODNAME);
+		goto done_cc_nodes;
+	}
+
+	return 0;
+
+done_cc_nodes:
+	if (cc_kobj)
+		kobject_del(cc_kobj);
+	return ret;
+}
+
 int __devinit msm_thermal_init(struct msm_thermal_data *pdata)
 {
 	int ret = 0;
@@ -187,9 +431,12 @@
 	memcpy(&msm_thermal_info, pdata, sizeof(struct msm_thermal_data));
 
 	enabled = 1;
+	core_control_enabled = 1;
 	INIT_DELAYED_WORK(&check_temp_work, check_temp);
 	schedule_delayed_work(&check_temp_work, 0);
 
+	register_cpu_notifier(&msm_thermal_cpu_notifier);
+
 	return ret;
 }
 
@@ -224,6 +471,23 @@
 
 	key = "qcom,freq-step";
 	ret = of_property_read_u32(node, key, &data.freq_step);
+	if (ret)
+		goto fail;
+
+	key = "qcom,core-limit-temp";
+	ret = of_property_read_u32(node, key, &data.core_limit_temp_degC);
+	if (ret)
+		goto fail;
+
+	key = "qcom,core-temp-hysteresis";
+	ret = of_property_read_u32(node, key, &data.core_temp_hysteresis_degC);
+	if (ret)
+		goto fail;
+
+	key = "qcom,core-control-mask";
+	ret = of_property_read_u32(node, key, &data.core_control_mask);
+	if (ret)
+		goto fail;
 
 fail:
 	if (ret)
@@ -253,3 +517,9 @@
 {
 	return platform_driver_register(&msm_thermal_device_driver);
 }
+
+int __init msm_thermal_late_init(void)
+{
+	return msm_thermal_add_cc_nodes();
+}
+module_init(msm_thermal_late_init);
diff --git a/drivers/thermal/msm_tsens.c b/drivers/thermal/msm_tsens.c
index 401ad88..86bae06 100644
--- a/drivers/thermal/msm_tsens.c
+++ b/drivers/thermal/msm_tsens.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/thermal/pm8xxx-tm.c b/drivers/thermal/pm8xxx-tm.c
index 50238f3..99a9454 100644
--- a/drivers/thermal/pm8xxx-tm.c
+++ b/drivers/thermal/pm8xxx-tm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -33,29 +33,32 @@
 #include <linux/msm_adc.h>
 
 /* Register TEMP_ALARM_CTRL bits */
-#define	TEMP_ALARM_CTRL_ST3_SD		0x80
-#define	TEMP_ALARM_CTRL_ST2_SD		0x40
-#define	TEMP_ALARM_CTRL_STATUS_MASK	0x30
-#define	TEMP_ALARM_CTRL_STATUS_SHIFT	4
-#define	TEMP_ALARM_CTRL_THRESH_MASK	0x0C
-#define	TEMP_ALARM_CTRL_THRESH_SHIFT	2
-#define	TEMP_ALARM_CTRL_OVRD_ST3	0x02
-#define	TEMP_ALARM_CTRL_OVRD_ST2	0x01
-#define	TEMP_ALARM_CTRL_OVRD_MASK	0x03
+#define TEMP_ALARM_CTRL_ST3_SD		0x80
+#define TEMP_ALARM_CTRL_ST2_SD		0x40
+#define TEMP_ALARM_CTRL_STATUS_MASK	0x30
+#define TEMP_ALARM_CTRL_STATUS_SHIFT	4
+#define TEMP_ALARM_CTRL_THRESH_MASK	0x0C
+#define TEMP_ALARM_CTRL_THRESH_SHIFT	2
+#define TEMP_ALARM_CTRL_OVRD_ST3	0x02
+#define TEMP_ALARM_CTRL_OVRD_ST2	0x01
+#define TEMP_ALARM_CTRL_OVRD_MASK	0x03
 
-#define	TEMP_STAGE_STEP			20000	/* Stage step: 20.000 C */
-#define	TEMP_STAGE_HYSTERESIS		2000
+#define TEMP_STAGE_STEP			20000	/* Stage step: 20.000 C */
+#define TEMP_STAGE_HYSTERESIS		2000
 
-#define	TEMP_THRESH_MIN			105000	/* Threshold Min: 105 C */
-#define	TEMP_THRESH_STEP		5000	/* Threshold step: 5 C */
+#define TEMP_THRESH_MIN			105000	/* Threshold Min: 105 C */
+#define TEMP_THRESH_STEP		5000	/* Threshold step: 5 C */
 
 /* Register TEMP_ALARM_PWM bits */
-#define	TEMP_ALARM_PWM_EN_MASK		0xC0
-#define	TEMP_ALARM_PWM_EN_SHIFT		6
-#define	TEMP_ALARM_PWM_PER_PRE_MASK	0x38
-#define	TEMP_ALARM_PWM_PER_PRE_SHIFT	3
-#define	TEMP_ALARM_PWM_PER_DIV_MASK	0x07
-#define	TEMP_ALARM_PWM_PER_DIV_SHIFT	0
+#define TEMP_ALARM_PWM_EN_MASK		0xC0
+#define TEMP_ALARM_PWM_EN_NEVER		0x00
+#define TEMP_ALARM_PWM_EN_SLEEP_B	0x40
+#define TEMP_ALARM_PWM_EN_PWM		0x80
+#define TEMP_ALARM_PWM_EN_ALWAYS	0xC0
+#define TEMP_ALARM_PWM_PER_PRE_MASK	0x38
+#define TEMP_ALARM_PWM_PER_PRE_SHIFT	3
+#define TEMP_ALARM_PWM_PER_DIV_MASK	0x07
+#define TEMP_ALARM_PWM_PER_DIV_SHIFT	0
 
 /* Trips: from critical to less critical */
 #define TRIP_STAGE3			0
@@ -65,10 +68,11 @@
 
 struct pm8xxx_tm_chip {
 	struct pm8xxx_tm_core_data	cdata;
-	struct work_struct		irq_work;
+	struct delayed_work		irq_work;
 	struct device			*dev;
 	struct thermal_zone_device	*tz_dev;
 	unsigned long			temp;
+	unsigned int			prev_stage;
 	enum thermal_device_mode	mode;
 	unsigned int			thresh;
 	unsigned int			stage;
@@ -82,6 +86,9 @@
 	SOFTWARE_OVERRIDE_ENABLED,
 };
 
+/* Delay between TEMP_STAT IRQ going high and status value changing in ms. */
+#define STATUS_REGISTER_DELAY_MS	40
+
 static inline int pm8xxx_tm_read_ctrl(struct pm8xxx_tm_chip *chip, u8 *reg)
 {
 	int rc;
@@ -312,6 +319,10 @@
 	if (!chip)
 		return -EINVAL;
 
+	/* Mask software override requests if they are not allowed. */
+	if (!chip->cdata.allow_software_override)
+		mode = THERMAL_DEVICE_DISABLED;
+
 	if (mode != chip->mode) {
 		if (mode == THERMAL_DEVICE_ENABLED)
 			pm8xxx_tm_shutdown_override(chip,
@@ -421,31 +432,18 @@
 
 static void pm8xxx_tm_work(struct work_struct *work)
 {
+	struct delayed_work *dwork
+		= container_of(work, struct delayed_work, work);
 	struct pm8xxx_tm_chip *chip
-		= container_of(work, struct pm8xxx_tm_chip, irq_work);
-	int rc;
+		= container_of(dwork, struct pm8xxx_tm_chip, irq_work);
+	unsigned long temp = 0;
+	int rc, stage, thresh;
 	u8 reg;
 
 	rc = pm8xxx_tm_read_ctrl(chip, &reg);
 	if (rc < 0)
 		goto bail;
 
-	if (chip->cdata.adc_type == PM8XXX_TM_ADC_NONE) {
-		rc = pm8xxx_tm_update_temp_no_adc(chip);
-		if (rc < 0)
-			goto bail;
-		pr_info("%s: Temp Alarm - stage=%u, threshold=%u, "
-			"temp=%lu mC\n", chip->cdata.tm_name, chip->stage,
-			chip->thresh, chip->temp);
-	} else {
-		chip->stage = (reg & TEMP_ALARM_CTRL_STATUS_MASK)
-				>> TEMP_ALARM_CTRL_STATUS_SHIFT;
-		chip->thresh = (reg & TEMP_ALARM_CTRL_THRESH_MASK)
-				>> TEMP_ALARM_CTRL_THRESH_SHIFT;
-		pr_info("%s: Temp Alarm - stage=%u, threshold=%u\n",
-			chip->cdata.tm_name, chip->stage, chip->thresh);
-	}
-
 	/* Clear status bits. */
 	if (reg & (TEMP_ALARM_CTRL_ST2_SD | TEMP_ALARM_CTRL_ST3_SD)) {
 		reg &= ~(TEMP_ALARM_CTRL_ST2_SD | TEMP_ALARM_CTRL_ST3_SD
@@ -454,24 +452,47 @@
 		pm8xxx_tm_write_ctrl(chip, reg);
 	}
 
+	stage = (reg & TEMP_ALARM_CTRL_STATUS_MASK)
+		>> TEMP_ALARM_CTRL_STATUS_SHIFT;
+	thresh = (reg & TEMP_ALARM_CTRL_THRESH_MASK)
+		>> TEMP_ALARM_CTRL_THRESH_SHIFT;
+
 	thermal_zone_device_update(chip->tz_dev);
 
-	/* Notify user space */
-	if (chip->mode == THERMAL_DEVICE_ENABLED)
-		kobject_uevent(&chip->tz_dev->device.kobj, KOBJ_CHANGE);
+	if (stage != chip->prev_stage) {
+		chip->prev_stage = stage;
+
+		switch (chip->cdata.adc_type) {
+		case PM8XXX_TM_ADC_NONE:
+			rc = pm8xxx_tz_get_temp_no_adc(chip->tz_dev, &temp);
+			break;
+		case PM8XXX_TM_ADC_PM8058_ADC:
+			rc = pm8xxx_tz_get_temp_pm8058_adc(chip->tz_dev, &temp);
+			break;
+		case PM8XXX_TM_ADC_PM8XXX_ADC:
+			rc = pm8xxx_tz_get_temp_pm8xxx_adc(chip->tz_dev, &temp);
+			break;
+		}
+		if (rc < 0)
+			goto bail;
+
+		pr_crit("%s: PMIC Temp Alarm - stage=%u, threshold=%u, temp=%lu mC\n",
+			chip->cdata.tm_name, stage, thresh, temp);
+
+		/* Notify user space */
+		sysfs_notify(&chip->tz_dev->device.kobj, NULL, "type");
+	}
 
 bail:
-	enable_irq(chip->tempstat_irq);
-	enable_irq(chip->overtemp_irq);
+	return;
 }
 
 static irqreturn_t pm8xxx_tm_isr(int irq, void *data)
 {
 	struct pm8xxx_tm_chip *chip = data;
 
-	disable_irq_nosync(chip->tempstat_irq);
-	disable_irq_nosync(chip->overtemp_irq);
-	schedule_work(&chip->irq_work);
+	schedule_delayed_work(&chip->irq_work,
+		msecs_to_jiffies(STATUS_REGISTER_DELAY_MS) + 1);
 
 	return IRQ_HANDLED;
 }
@@ -498,16 +519,15 @@
 		return rc;
 
 	/*
-	 * Set the PMIC alarm module PWM to have a frequency of 8 Hz. This
-	 * helps cut down on the number of unnecessary interrupts fired when
-	 * changing between thermal stages.  Also, Enable the over temperature
-	 * PWM whenever the PMIC is enabled.
+	 * Set the PMIC temperature alarm module to be always on.  This ensures
+	 * that die temperature monitoring is active even if CXO is disabled
+	 * (i.e. when sleep_b is low).  This is necessary since CXO can be
+	 * disabled while the system is still heavily loaded.  Also, using
+	 * the alway-on instead of PWM-enabled configurations ensures that the
+	 * die temperature can be measured by the PMIC ADC without reconfiguring
+	 * the temperature alarm module first.
 	 */
-	reg =  (1 << TEMP_ALARM_PWM_EN_SHIFT)
-		| (3 << TEMP_ALARM_PWM_PER_PRE_SHIFT)
-		| (3 << TEMP_ALARM_PWM_PER_DIV_SHIFT);
-
-	rc = pm8xxx_tm_write_pwm(chip, reg);
+	rc = pm8xxx_tm_write_pwm(chip, TEMP_ALARM_PWM_EN_ALWAYS);
 
 	return rc;
 }
@@ -610,7 +630,7 @@
 	chip->mode = THERMAL_DEVICE_DISABLED;
 	thermal_zone_device_update(chip->tz_dev);
 
-	INIT_WORK(&chip->irq_work, pm8xxx_tm_work);
+	INIT_DELAYED_WORK(&chip->irq_work, pm8xxx_tm_work);
 
 	rc = request_irq(chip->tempstat_irq, pm8xxx_tm_isr, IRQF_TRIGGER_RISING,
 		chip->cdata.irq_name_temp_stat, chip);
@@ -635,7 +655,7 @@
 err_free_irq_tempstat:
 	free_irq(chip->tempstat_irq, chip);
 err_cancel_work:
-	cancel_work_sync(&chip->irq_work);
+	cancel_delayed_work_sync(&chip->irq_work);
 err_free_tz:
 	thermal_zone_device_unregister(chip->tz_dev);
 err_fail_adc:
@@ -651,7 +671,7 @@
 
 	if (chip) {
 		platform_set_drvdata(pdev, NULL);
-		cancel_work_sync(&chip->irq_work);
+		cancel_delayed_work_sync(&chip->irq_work);
 		free_irq(chip->overtemp_irq, chip);
 		free_irq(chip->tempstat_irq, chip);
 		pm8xxx_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED);
@@ -662,6 +682,13 @@
 	return 0;
 }
 
+static void pm8xxx_tm_shutdown(struct platform_device *pdev)
+{
+	struct pm8xxx_tm_chip *chip = platform_get_drvdata(pdev);
+
+	pm8xxx_tm_write_pwm(chip, TEMP_ALARM_PWM_EN_NEVER);
+}
+
 #ifdef CONFIG_PM
 static int pm8xxx_tm_suspend(struct device *dev)
 {
@@ -699,6 +726,7 @@
 static struct platform_driver pm8xxx_tm_driver = {
 	.probe	= pm8xxx_tm_probe,
 	.remove	= __devexit_p(pm8xxx_tm_remove),
+	.shutdown = pm8xxx_tm_shutdown,
 	.driver	= {
 		.name = PM8XXX_TM_DEV_NAME,
 		.owner = THIS_MODULE,
diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c
index 81429c2..02a64be 100644
--- a/drivers/tty/hvc/hvc_dcc.c
+++ b/drivers/tty/hvc/hvc_dcc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/tty/n_smux.c b/drivers/tty/n_smux.c
index 32c081d..0348145 100644
--- a/drivers/tty/n_smux.c
+++ b/drivers/tty/n_smux.c
@@ -1,6 +1,6 @@
 /* drivers/tty/n_smux.c
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index e6f5bf5..9bfdceb 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -2,7 +2,7 @@
  * drivers/serial/msm_serial.c - driver for msm7k serial device and console
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Robert Love <rlove@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
index 34228ec..1f17ba4 100644
--- a/drivers/tty/serial/msm_serial.h
+++ b/drivers/tty/serial/msm_serial.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2007 Google, Inc.
  * Author: Robert Love <rlove@google.com>
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index ee9ff6a..7d58e3f 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -54,6 +54,7 @@
 #include <linux/device.h>
 #include <linux/wakelock.h>
 #include <linux/debugfs.h>
+#include <linux/gpio.h>
 #include <asm/atomic.h>
 #include <asm/irq.h>
 
@@ -141,6 +142,15 @@
 	char rx_to_inject;
 };
 
+/*
+ * UART can be used in 2-wire or 4-wire mode.
+ * Use uart_func_mode to set 2-wire or 4-wire mode.
+ */
+enum uart_func_mode {
+	UART_TWO_WIRE, /* can't support HW Flow control. */
+	UART_FOUR_WIRE,/* can support HW Flow control. */
+};
+
 struct msm_hs_port {
 	struct uart_port uport;
 	unsigned long imr_reg;  /* shadow value of UARTDM_IMR */
@@ -169,6 +179,8 @@
 	struct workqueue_struct *hsuart_wq; /* hsuart workqueue */
 	struct mutex clk_mutex; /* mutex to guard against clock off/clock on */
 	bool tty_flush_receive;
+	bool rx_discard_flush_issued;
+	enum uart_func_mode func_mode;
 };
 
 #define MSM_UARTDM_BURST_SIZE 16   /* DM burst size (in bytes) */
@@ -176,6 +188,7 @@
 #define UARTDM_RX_BUF_SIZE 512
 #define RETRY_TIMEOUT 5
 #define UARTDM_NR 256
+#define RX_FLUSH_COMPLETE_TIMEOUT 300 /* In jiffies */
 
 static struct dentry *debug_base;
 static struct msm_hs_port q_uart_port[UARTDM_NR];
@@ -439,6 +452,133 @@
 	return 0;
 }
 
+/**
+ * msm_hs_config_uart_tx_rx_gpios - Configures UART Tx and RX GPIOs
+ * @port: uart port
+ */
+static int msm_hs_config_uart_tx_rx_gpios(struct uart_port *uport)
+{
+	struct platform_device *pdev = to_platform_device(uport->dev);
+	const struct msm_serial_hs_platform_data *pdata =
+					pdev->dev.platform_data;
+	int ret = -EINVAL;
+
+
+	ret = gpio_request(pdata->uart_tx_gpio, "UART_TX_GPIO");
+	if (unlikely(ret)) {
+		pr_err("gpio request failed for:%d\n",
+				pdata->uart_tx_gpio);
+		goto exit_uart_config;
+	}
+
+	ret = gpio_request(pdata->uart_rx_gpio, "UART_RX_GPIO");
+	if (unlikely(ret)) {
+		pr_err("gpio request failed for:%d\n",
+				pdata->uart_rx_gpio);
+		gpio_free(pdata->uart_tx_gpio);
+		goto exit_uart_config;
+	}
+
+exit_uart_config:
+	return ret;
+}
+
+/**
+ * msm_hs_unconfig_uart_tx_rx_gpios: Unconfigures UART Tx and RX GPIOs
+ * @port: uart port
+ */
+static void msm_hs_unconfig_uart_tx_rx_gpios(struct uart_port *uport)
+{
+	struct platform_device *pdev = to_platform_device(uport->dev);
+	const struct msm_serial_hs_platform_data *pdata =
+						pdev->dev.platform_data;
+
+
+	gpio_free(pdata->uart_tx_gpio);
+	gpio_free(pdata->uart_rx_gpio);
+
+}
+
+/**
+ * msm_hs_config_uart_hwflow_gpios: Configures UART HWFlow GPIOs
+ * @port: uart port
+ */
+static int msm_hs_config_uart_hwflow_gpios(struct uart_port *uport)
+{
+	struct platform_device *pdev = to_platform_device(uport->dev);
+	const struct msm_serial_hs_platform_data *pdata =
+						pdev->dev.platform_data;
+	int ret = -EINVAL;
+
+	ret = gpio_request(pdata->uart_cts_gpio, "UART_CTS_GPIO");
+	if (unlikely(ret)) {
+		pr_err("gpio request failed for:%d\n", pdata->uart_cts_gpio);
+		goto exit_config_uart;
+	}
+
+	ret = gpio_request(pdata->uart_rfr_gpio, "UART_RFR_GPIO");
+	if (unlikely(ret)) {
+		pr_err("gpio request failed for:%d\n", pdata->uart_rfr_gpio);
+		gpio_free(pdata->uart_cts_gpio);
+		goto exit_config_uart;
+	}
+
+exit_config_uart:
+	return ret;
+}
+
+/**
+ * msm_hs_unconfig_uart_hwflow_gpios: Unonfigures UART HWFlow GPIOs
+ * @port: uart port
+ */
+static void msm_hs_unconfig_uart_hwflow_gpios(struct uart_port *uport)
+{
+	struct platform_device *pdev = to_platform_device(uport->dev);
+	const struct msm_serial_hs_platform_data *pdata =
+						pdev->dev.platform_data;
+
+	gpio_free(pdata->uart_cts_gpio);
+	gpio_free(pdata->uart_rfr_gpio);
+
+}
+
+/**
+ * msm_hs_config_uart_gpios: Configures UART GPIOs and returns success or
+ * Failure
+ * @port: uart port
+ */
+static int msm_hs_config_uart_gpios(struct uart_port *uport)
+{
+	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
+	int ret;
+
+	/* Configure UART Tx and Rx GPIOs */
+	ret = msm_hs_config_uart_tx_rx_gpios(uport);
+	if (!ret) {
+		if (msm_uport->func_mode == UART_FOUR_WIRE) {
+			/*if 4-wire uart, configure CTS and RFR GPIOs */
+			ret = msm_hs_config_uart_hwflow_gpios(uport);
+			if (ret)
+				msm_hs_unconfig_uart_tx_rx_gpios(uport);
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * msm_hs_unconfig_uart_gpios: Unconfigures UART GPIOs
+ * @port: uart port
+ */
+static void msm_hs_unconfig_uart_gpios(struct uart_port *port)
+{
+	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(port);
+
+	msm_hs_unconfig_uart_tx_rx_gpios(port);
+	if (msm_uport->func_mode == UART_FOUR_WIRE)
+		msm_hs_unconfig_uart_hwflow_gpios(port);
+}
+
 static int msm_hs_init_clk(struct uart_port *uport)
 {
 	int ret;
@@ -667,6 +807,7 @@
 	unsigned int bps;
 	unsigned long data;
 	unsigned long flags;
+	int ret;
 	unsigned int c_cflag = termios->c_cflag;
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 
@@ -775,8 +916,19 @@
 		 * dsb requires here.
 		 */
 		mb();
+		msm_uport->rx_discard_flush_issued = true;
 		/* do discard flush */
 		msm_dmov_flush(msm_uport->dma_rx_channel, 0);
+		spin_unlock_irqrestore(&uport->lock, flags);
+		pr_debug("%s(): wainting for flush completion.\n",
+							__func__);
+		ret = wait_event_timeout(msm_uport->rx.wait,
+			msm_uport->rx_discard_flush_issued == false,
+			RX_FLUSH_COMPLETE_TIMEOUT);
+		if (!ret)
+			pr_err("%s(): Discard flush completion pending.\n",
+								__func__);
+		spin_lock_irqsave(&uport->lock, flags);
 	}
 
 	msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
@@ -1182,8 +1334,23 @@
 					struct msm_dmov_errdata *err)
 {
 	struct msm_hs_port *msm_uport;
+	struct uart_port *uport;
+	unsigned long flags;
 
 	msm_uport = container_of(cmd_ptr, struct msm_hs_port, rx.xfer);
+	uport = &(msm_uport->uport);
+
+	pr_debug("%s(): called result:%x\n", __func__, result);
+	if (!(result & DMOV_RSLT_ERROR)) {
+		if (result & DMOV_RSLT_FLUSH) {
+			if (msm_uport->rx_discard_flush_issued) {
+				spin_lock_irqsave(&uport->lock, flags);
+				msm_uport->rx_discard_flush_issued = false;
+				spin_unlock_irqrestore(&uport->lock, flags);
+				wake_up(&msm_uport->rx.wait);
+			}
+		}
+	}
 
 	tasklet_schedule(&msm_uport->rx.tlet);
 }
@@ -1329,6 +1496,7 @@
 {
 	unsigned long sr_status;
 	unsigned long flags;
+	int ret;
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 	struct circ_buf *tx_buf = &uport->state->xmit;
 
@@ -1376,10 +1544,23 @@
 	}
 
 	if (msm_uport->rx.flush != FLUSH_SHUTDOWN) {
-		if (msm_uport->rx.flush == FLUSH_NONE)
+		if (msm_uport->rx.flush == FLUSH_NONE) {
 			msm_hs_stop_rx_locked(uport);
+			msm_uport->rx_discard_flush_issued = true;
+		}
 
 		spin_unlock_irqrestore(&uport->lock, flags);
+		if (msm_uport->rx_discard_flush_issued) {
+			pr_debug("%s(): wainting for flush completion.\n",
+								__func__);
+			ret = wait_event_timeout(msm_uport->rx.wait,
+				msm_uport->rx_discard_flush_issued == false,
+				RX_FLUSH_COMPLETE_TIMEOUT);
+			if (!ret)
+				pr_err("%s(): Flush complete pending.\n",
+								__func__);
+		}
+
 		mutex_unlock(&msm_uport->clk_mutex);
 		return 0;  /* come back later to really clock off */
 	}
@@ -1679,9 +1860,13 @@
 		return ret;
 	}
 
-	if (pdata && pdata->gpio_config)
-		if (unlikely(pdata->gpio_config(1)))
-			dev_err(uport->dev, "Cannot configure gpios\n");
+	if (pdata && pdata->config_gpio) {
+		ret = msm_hs_config_uart_gpios(uport);
+		if (ret)
+			goto deinit_uart_clk;
+	} else {
+		pr_debug("%s(): UART GPIOs not specified.\n", __func__);
+	}
 
 	/* Set auto RFR Level */
 	data = msm_hs_read(uport, UARTDM_MR1_ADDR);
@@ -1748,7 +1933,7 @@
 		ret = irq_set_irq_wake(msm_uport->wakeup.irq, 1);
 		if (unlikely(ret)) {
 			pr_err("%s():Err setting wakeup irq\n", __func__);
-			goto deinit_uart_clk;
+			goto unconfigure_uart_gpio;
 		}
 	}
 
@@ -1788,6 +1973,9 @@
 	free_irq(uport->irq, msm_uport);
 free_wake_irq:
 	irq_set_irq_wake(msm_uport->wakeup.irq, 0);
+unconfigure_uart_gpio:
+	if (pdata && pdata->config_gpio)
+		msm_hs_unconfig_uart_gpios(uport);
 deinit_uart_clk:
 	clk_disable_unprepare(msm_uport->clk);
 	if (msm_uport->pclk)
@@ -1965,6 +2153,38 @@
 
 	}
 
+	/* Identify UART functional mode as 2-wire or 4-wire. */
+	if (pdata && pdata->config_gpio) {
+		switch (pdata->config_gpio) {
+		case 4:
+			if (gpio_is_valid(pdata->uart_tx_gpio)
+				&& gpio_is_valid(pdata->uart_rx_gpio)
+				&& gpio_is_valid(pdata->uart_cts_gpio)
+				&& gpio_is_valid(pdata->uart_rfr_gpio)) {
+					msm_uport->func_mode = UART_FOUR_WIRE;
+			} else {
+				pr_err("%s(): Wrong GPIO Number for 4-Wire.\n",
+								__func__);
+				return -EINVAL;
+			}
+			break;
+		case 2:
+			if (gpio_is_valid(pdata->uart_tx_gpio)
+				&& gpio_is_valid(pdata->uart_rx_gpio)) {
+					msm_uport->func_mode = UART_TWO_WIRE;
+			} else {
+				pr_err("%s(): Wrong GPIO Number for 2-Wire.\n",
+								__func__);
+				return -EINVAL;
+			}
+			break;
+		default:
+			pr_err("%s(): Invalid number of GPIOs.\n", __func__);
+			pdata->config_gpio = 0;
+			return -EINVAL;
+		}
+	}
+
 	resource = platform_get_resource_byname(pdev, IORESOURCE_DMA,
 						"uartdm_channels");
 	if (unlikely(!resource))
@@ -2166,9 +2386,8 @@
 	if (use_low_power_wakeup(msm_uport))
 		free_irq(msm_uport->wakeup.irq, msm_uport);
 
-	if (pdata && pdata->gpio_config)
-		if (pdata->gpio_config(0))
-			dev_err(uport->dev, "GPIO config error\n");
+	if (pdata && pdata->config_gpio)
+			msm_hs_unconfig_uart_gpios(uport);
 }
 
 static void __exit msm_serial_hs_exit(void)
diff --git a/drivers/tty/serial/msm_serial_hs_hwreg.h b/drivers/tty/serial/msm_serial_hs_hwreg.h
index 8debc36..401797f 100644
--- a/drivers/tty/serial/msm_serial_hs_hwreg.h
+++ b/drivers/tty/serial/msm_serial_hs_hwreg.h
@@ -1,6 +1,6 @@
 /* drivers/serial/msm_serial_hs_hwreg.h
  *
- * Copyright (c) 2007-2009, 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2009, 2012, The Linux Foundation. All rights reserved.
  * 
  * All source code in this file is licensed under the following license
  * except where indicated.
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index 2b2ce0e..3377a4d 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -2,7 +2,7 @@
  * drivers/serial/msm_serial.c - driver for msm7k serial device and console
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -999,6 +999,9 @@
 {
 	int ret;
 	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
+	struct platform_device *pdev = to_platform_device(port->dev);
+	const struct msm_serial_hslite_platform_data *pdata =
+					pdev->dev.platform_data;
 
 	switch (state) {
 	case 0:
@@ -1010,10 +1013,11 @@
 		break;
 	case 3:
 		clk_en(port, 0);
-		ret = clk_set_rate(msm_hsl_port->clk, 0);
-		if (ret)
-			pr_err("%s(): Error setting UART clock rate to zero.\n",
-								__func__);
+		if (pdata && pdata->set_uart_clk_zero) {
+			ret = clk_set_rate(msm_hsl_port->clk, 0);
+			if (ret)
+				pr_err("Error setting UART clock rate to zero.\n");
+		}
 		break;
 	default:
 		pr_err("%s(): msm_serial_hsl: Unknown PM state %d\n",
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c
index b25e6ee..a0e8af4 100644
--- a/drivers/tty/serial/msm_smd_tty.c
+++ b/drivers/tty/serial/msm_smd_tty.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/tty/smux_ctl.c b/drivers/tty/smux_ctl.c
index c17495b..1b3a7abe 100644
--- a/drivers/tty/smux_ctl.c
+++ b/drivers/tty/smux_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -940,6 +940,7 @@
 static int smux_ctl_remove(struct platform_device *pdev)
 {
 	int i;
+	int ret;
 
 	SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s Begins\n", __func__);
 
@@ -950,6 +951,13 @@
 		devp->abort_wait = 1;
 		wake_up(&devp->write_wait_queue);
 		wake_up(&devp->read_wait_queue);
+
+		if (atomic_read(&devp->ref_count)) {
+			ret = msm_smux_close(devp->id);
+			if (ret)
+				pr_err("%s: unable to close ch %d, ret %d\n",
+						__func__, devp->id, ret);
+		}
 		mutex_unlock(&devp->dev_lock);
 
 		/* Empty RX queue */
diff --git a/drivers/tty/smux_debug.c b/drivers/tty/smux_debug.c
index 86377d6..d467523 100644
--- a/drivers/tty/smux_debug.c
+++ b/drivers/tty/smux_debug.c
@@ -1,6 +1,6 @@
 /* drivers/tty/smux_debug.c
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/tty/smux_loopback.c b/drivers/tty/smux_loopback.c
index c4374bb..c78b453 100644
--- a/drivers/tty/smux_loopback.c
+++ b/drivers/tty/smux_loopback.c
@@ -1,6 +1,6 @@
 /* drivers/tty/smux_loopback.c
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/tty/smux_loopback.h b/drivers/tty/smux_loopback.h
index 85c6c23..02bff80 100644
--- a/drivers/tty/smux_loopback.h
+++ b/drivers/tty/smux_loopback.h
@@ -1,6 +1,6 @@
 /* drivers/tty/smux_loopback.h
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/tty/smux_private.h b/drivers/tty/smux_private.h
index 195ee0f..8fdec86 100644
--- a/drivers/tty/smux_private.h
+++ b/drivers/tty/smux_private.h
@@ -1,6 +1,6 @@
 /* drivers/tty/smux_private.h
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/tty/smux_test.c b/drivers/tty/smux_test.c
index 81ac04b..e1d9975 100644
--- a/drivers/tty/smux_test.c
+++ b/drivers/tty/smux_test.c
@@ -1,6 +1,6 @@
 /* drivers/tty/smux_test.c
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 5f96660..2382640 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -546,14 +546,15 @@
 	if (!usb_match_device(dev, id))
 		return 0;
 
-	/* The interface class, subclass, and protocol should never be
+	/* The interface class, subclass, protocol and number should never be
 	 * checked for a match if the device class is Vendor Specific,
 	 * unless the match record specifies the Vendor ID. */
 	if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
 			!(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
 			(id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
 				USB_DEVICE_ID_MATCH_INT_SUBCLASS |
-				USB_DEVICE_ID_MATCH_INT_PROTOCOL)))
+				USB_DEVICE_ID_MATCH_INT_PROTOCOL |
+				USB_DEVICE_ID_MATCH_INT_NUMBER)))
 		return 0;
 
 	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
@@ -568,6 +569,10 @@
 	    (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
 		return 0;
 
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) &&
+	    (id->bInterfaceNumber != intf->desc.bInterfaceNumber))
+		return 0;
+
 	return 1;
 }
 EXPORT_SYMBOL_GPL(usb_match_one_id);
@@ -1411,7 +1416,6 @@
 	 * (This can't be done in usb_resume_interface()
 	 * above because it doesn't own the right set of locks.)
 	 */
-	pm_runtime_get_sync(dev->parent);
 	status = usb_resume_both(udev, msg);
 	if (status == 0) {
 		pm_runtime_disable(dev);
@@ -1419,7 +1423,6 @@
 		pm_runtime_enable(dev);
 		unbind_no_reset_resume_drivers_interfaces(udev);
 	}
-	pm_runtime_put_sync(dev->parent);
 
 	/* Avoid PM error messages for devices disconnected while suspended
 	 * as we'll display regular disconnect messages just a bit later.
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index b2da64c..3aa16b1 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1535,7 +1535,7 @@
 
 	if (add_uevent_var(env,
 		   "MODALIAS=usb:"
-		   "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
+		   "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02Xin%02X",
 		   le16_to_cpu(usb_dev->descriptor.idVendor),
 		   le16_to_cpu(usb_dev->descriptor.idProduct),
 		   le16_to_cpu(usb_dev->descriptor.bcdDevice),
@@ -1544,7 +1544,8 @@
 		   usb_dev->descriptor.bDeviceProtocol,
 		   alt->desc.bInterfaceClass,
 		   alt->desc.bInterfaceSubClass,
-		   alt->desc.bInterfaceProtocol))
+		   alt->desc.bInterfaceProtocol,
+		   alt->desc.bInterfaceNumber))
 		return -ENOMEM;
 
 	return 0;
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 566d9f9..87678c5 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -840,7 +840,7 @@
 	alt = intf->cur_altsetting;
 
 	return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X"
-			"ic%02Xisc%02Xip%02X\n",
+			"ic%02Xisc%02Xip%02Xin%02X\n",
 			le16_to_cpu(udev->descriptor.idVendor),
 			le16_to_cpu(udev->descriptor.idProduct),
 			le16_to_cpu(udev->descriptor.bcdDevice),
@@ -849,7 +849,8 @@
 			udev->descriptor.bDeviceProtocol,
 			alt->desc.bInterfaceClass,
 			alt->desc.bInterfaceSubClass,
-			alt->desc.bInterfaceProtocol);
+			alt->desc.bInterfaceProtocol,
+			alt->desc.bInterfaceNumber);
 }
 static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
 
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 522e3a4..63906cb 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index 4a37f03..41cbcf2 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -1,7 +1,7 @@
 /**
  * dwc3_otg.c - DesignWare USB3 DRD Controller OTG
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/dwc3/dwc3_otg.h b/drivers/usb/dwc3/dwc3_otg.h
index b60b42a..2d6cab2 100644
--- a/drivers/usb/dwc3/dwc3_otg.h
+++ b/drivers/usb/dwc3/dwc3_otg.h
@@ -1,7 +1,7 @@
 /**
  * dwc3_otg.h - DesignWare USB3 DRD Controller OTG
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index f944c1c..52ea9e1 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -506,6 +506,9 @@
 #define MAX_XPORT_STR_LEN 50
 static char rmnet_transports[MAX_XPORT_STR_LEN];
 
+/*rmnet transport name string - "rmnet_hsic[,rmnet_hsusb]" */
+static char rmnet_xport_names[MAX_XPORT_STR_LEN];
+
 static void rmnet_function_cleanup(struct android_usb_function *f)
 {
 	frmnet_cleanup();
@@ -518,18 +521,28 @@
 	int err = 0;
 	char *ctrl_name;
 	char *data_name;
+	char *tname = NULL;
 	char buf[MAX_XPORT_STR_LEN], *b;
+	char xport_name_buf[MAX_XPORT_STR_LEN], *tb;
 	static int rmnet_initialized, ports;
 
 	if (!rmnet_initialized) {
 		rmnet_initialized = 1;
 		strlcpy(buf, rmnet_transports, sizeof(buf));
 		b = strim(buf);
+
+		strlcpy(xport_name_buf, rmnet_xport_names,
+				sizeof(xport_name_buf));
+		tb = strim(xport_name_buf);
+
 		while (b) {
 			ctrl_name = strsep(&b, ",");
 			data_name = strsep(&b, ",");
 			if (ctrl_name && data_name) {
-				err = frmnet_init_port(ctrl_name, data_name);
+				if (tb)
+					tname = strsep(&tb, ",");
+				err = frmnet_init_port(ctrl_name, data_name,
+						tname);
 				if (err) {
 					pr_err("rmnet: Cannot open ctrl port:"
 						"'%s' data port:'%s'\n",
@@ -573,12 +586,34 @@
 	return size;
 }
 
+static ssize_t rmnet_xport_names_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", rmnet_xport_names);
+}
+
+static ssize_t rmnet_xport_names_store(
+		struct device *device, struct device_attribute *attr,
+		const char *buff, size_t size)
+{
+	strlcpy(rmnet_xport_names, buff, sizeof(rmnet_xport_names));
+
+	return size;
+}
+
 static struct device_attribute dev_attr_rmnet_transports =
 					__ATTR(transports, S_IRUGO | S_IWUSR,
 						rmnet_transports_show,
 						rmnet_transports_store);
+
+static struct device_attribute dev_attr_rmnet_xport_names =
+				__ATTR(transport_names, S_IRUGO | S_IWUSR,
+				rmnet_xport_names_show,
+				rmnet_xport_names_store);
+
 static struct device_attribute *rmnet_function_attributes[] = {
 					&dev_attr_rmnet_transports,
+					&dev_attr_rmnet_xport_names,
 					NULL };
 
 static struct android_usb_function rmnet_function = {
@@ -811,9 +846,33 @@
 	return size;
 }
 
+/*enabled FSERIAL transport names - "serial_hsic[,serial_hsusb]"*/
+static char serial_xport_names[32];
+static ssize_t serial_xport_names_store(
+		struct device *device, struct device_attribute *attr,
+		const char *buff, size_t size)
+{
+	strlcpy(serial_xport_names, buff, sizeof(serial_xport_names));
+
+	return size;
+}
+
+static ssize_t serial_xport_names_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", serial_xport_names);
+}
+
 static DEVICE_ATTR(transports, S_IWUSR, NULL, serial_transports_store);
-static struct device_attribute *serial_function_attributes[] =
-					 { &dev_attr_transports, NULL };
+static struct device_attribute dev_attr_serial_xport_names =
+				__ATTR(transport_names, S_IRUGO | S_IWUSR,
+				serial_xport_names_show,
+				serial_xport_names_store);
+
+static struct device_attribute *serial_function_attributes[] = {
+					&dev_attr_transports,
+					&dev_attr_serial_xport_names,
+					NULL };
 
 static void serial_function_cleanup(struct android_usb_function *f)
 {
@@ -823,8 +882,8 @@
 static int serial_function_bind_config(struct android_usb_function *f,
 					struct usb_configuration *c)
 {
-	char *name;
-	char buf[32], *b;
+	char *name, *xport_name = NULL;
+	char buf[32], *b, xport_name_buf[32], *tb;
 	int err = -1, i;
 	static int serial_initialized = 0, ports = 0;
 
@@ -835,11 +894,16 @@
 	strlcpy(buf, serial_transports, sizeof(buf));
 	b = strim(buf);
 
+	strlcpy(xport_name_buf, serial_xport_names, sizeof(xport_name_buf));
+	tb = strim(xport_name_buf);
+
 	while (b) {
 		name = strsep(&b, ",");
 
 		if (name) {
-			err = gserial_init_port(ports, name);
+			if (tb)
+				xport_name = strsep(&tb, ",");
+			err = gserial_init_port(ports, name, xport_name);
 			if (err) {
 				pr_err("serial: Cannot open port '%s'", name);
 				goto out;
@@ -2041,6 +2105,7 @@
 	struct android_usb_function *f;
 	struct android_configuration *conf;
 	int enabled = 0;
+	static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
 
 	if (!cdev)
 		return -ENODEV;
@@ -2076,7 +2141,7 @@
 					f->disable(f);
 			}
 		dev->enabled = false;
-	} else {
+	} else if (__ratelimit(&rl)) {
 		pr_err("android_usb: already %s\n",
 				dev->enabled ? "enabled" : "disabled");
 	}
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c
index e3c1216..a090a19 100644
--- a/drivers/usb/gadget/ci13xxx_msm.c
+++ b/drivers/usb/gadget/ci13xxx_msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/ci13xxx_msm_hsic.c b/drivers/usb/gadget/ci13xxx_msm_hsic.c
index 6faaf78..443c40c 100644
--- a/drivers/usb/gadget/ci13xxx_msm_hsic.c
+++ b/drivers/usb/gadget/ci13xxx_msm_hsic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 40cc4c7..6de5f04 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -66,9 +66,13 @@
 #include <linux/usb/gadget.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/msm_hsusb.h>
-
+#include <linux/tracepoint.h>
+#include <mach/usb_trace.h>
 #include "ci13xxx_udc.h"
 
+/* Turns on streaming. overrides CI13XXX_DISABLE_STREAMING */
+static unsigned int streaming;
+module_param(streaming, uint, S_IRUGO | S_IWUSR);
 
 /******************************************************************************
  * DEFINE
@@ -136,6 +140,21 @@
 	return n ? n-1 : 32;
 }
 
+struct ci13xxx_ebi_err_entry {
+	u32 *usb_req_buf;
+	u32 usb_req_length;
+	u32 ep_info;
+	struct ci13xxx_ebi_err_entry *next;
+};
+
+struct ci13xxx_ebi_err_data {
+	u32 ebi_err_addr;
+	u32 apkt0;
+	u32 apkt1;
+	struct ci13xxx_ebi_err_entry *ebi_err_entry;
+};
+static struct ci13xxx_ebi_err_data *ebi_err_data;
+
 /******************************************************************************
  * HW block
  *****************************************************************************/
@@ -319,22 +338,22 @@
  */
 static int hw_device_reset(struct ci13xxx *udc)
 {
+	int delay_count = 25; /* 250 usec */
+
 	/* should flush & stop before reset */
 	hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0);
 	hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
 
 	hw_cwrite(CAP_USBCMD, USBCMD_RST, USBCMD_RST);
-	while (hw_cread(CAP_USBCMD, USBCMD_RST))
-		udelay(10);             /* not RTOS friendly */
-
+	while (delay_count--  && hw_cread(CAP_USBCMD, USBCMD_RST))
+		udelay(10);
+	if (delay_count < 0)
+		pr_err("USB controller reset failed\n");
 
 	if (udc->udc_driver->notify_event)
 		udc->udc_driver->notify_event(udc,
 			CI13XXX_CONTROLLER_RESET_EVENT);
 
-	if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING)
-		hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
-
 	/* USBMODE should be configured step by step */
 	hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
 	hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE);
@@ -369,7 +388,15 @@
  */
 static int hw_device_state(u32 dma)
 {
+	struct ci13xxx *udc = _udc;
+
 	if (dma) {
+		if (streaming || !(udc->udc_driver->flags &
+				CI13XXX_DISABLE_STREAMING))
+			hw_cwrite(CAP_USBMODE, USBMODE_SDIS, 0);
+		else
+			hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
+
 		hw_cwrite(CAP_ENDPTLISTADDR, ~0, dma);
 		/* interrupt, error, port change, reset, sleep/suspend */
 		hw_cwrite(CAP_USBINTR, ~0,
@@ -416,7 +443,8 @@
 	int n = hw_ep_bit(num, dir);
 	struct ci13xxx_ep *mEp = &_udc->ci13xxx_ep[n];
 
-	if (_udc->skip_flush || list_empty(&mEp->qh.queue))
+	/* Flush ep0 even when queue is empty */
+	if (_udc->skip_flush || (num && list_empty(&mEp->qh.queue)))
 		return 0;
 
 	start = ktime_get();
@@ -784,6 +812,8 @@
  */
 static int hw_usb_reset(void)
 {
+	int delay_count = 10; /* 100 usec delay */
+
 	hw_usb_set_address(0);
 
 	/* ESS flushes only at end?!? */
@@ -796,8 +826,10 @@
 	hw_cwrite(CAP_ENDPTCOMPLETE,  0,  0);   /* writes its content */
 
 	/* wait until all bits cleared */
-	while (hw_cread(CAP_ENDPTPRIME, ~0))
-		udelay(10);             /* not RTOS friendly */
+	while (delay_count-- && hw_cread(CAP_ENDPTPRIME, ~0))
+		udelay(10);
+	if (delay_count < 0)
+		pr_err("ENDPTPRIME is not cleared during bus reset\n");
 
 	/* reset all endpoints ? */
 
@@ -1728,6 +1760,72 @@
 	return 0;
 }
 
+static void dump_usb_info(void *ignore, unsigned int ebi_addr,
+	unsigned int ebi_apacket0, unsigned int ebi_apacket1)
+{
+	struct ci13xxx *udc = _udc;
+	unsigned long flags;
+	struct list_head   *ptr = NULL;
+	struct ci13xxx_req *req = NULL;
+	struct ci13xxx_ep *mEp;
+	unsigned i;
+	struct ci13xxx_ebi_err_entry *temp_dump;
+	static int count;
+	u32 epdir = 0;
+
+	if (count)
+		return;
+	count++;
+
+	pr_info("%s: USB EBI error detected\n", __func__);
+
+	ebi_err_data = kmalloc(sizeof(struct ci13xxx_ebi_err_data),
+				 GFP_ATOMIC);
+	if (!ebi_err_data) {
+		pr_err("%s: memory alloc failed for ebi_err_data\n", __func__);
+		return;
+	}
+
+	ebi_err_data->ebi_err_entry = kmalloc(
+					sizeof(struct ci13xxx_ebi_err_entry),
+					GFP_ATOMIC);
+	if (!ebi_err_data->ebi_err_entry) {
+		kfree(ebi_err_data);
+		pr_err("%s: memory alloc failed for ebi_err_entry\n", __func__);
+		return;
+	}
+
+	ebi_err_data->ebi_err_addr = ebi_addr;
+	ebi_err_data->apkt0 = ebi_apacket0;
+	ebi_err_data->apkt1 = ebi_apacket1;
+
+	temp_dump = ebi_err_data->ebi_err_entry;
+	pr_info("\n DUMPING USB Requests Information\n");
+	spin_lock_irqsave(udc->lock, flags);
+	for (i = 0; i < hw_ep_max; i++) {
+		list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue) {
+			mEp = &udc->ci13xxx_ep[i];
+			req = list_entry(ptr, struct ci13xxx_req, queue);
+
+			temp_dump->usb_req_buf = req->req.buf;
+			temp_dump->usb_req_length = req->req.length;
+			epdir = mEp->dir;
+			temp_dump->ep_info = mEp->num | (epdir << 15);
+
+			temp_dump->next = kmalloc(
+					  sizeof(struct ci13xxx_ebi_err_entry),
+					  GFP_ATOMIC);
+			if (!temp_dump->next) {
+				pr_err("%s: memory alloc failed\n", __func__);
+				spin_unlock_irqrestore(udc->lock, flags);
+				return;
+			}
+			temp_dump = temp_dump->next;
+		}
+	}
+	spin_unlock_irqrestore(udc->lock, flags);
+}
+
 /******************************************************************************
  * UTIL block
  *****************************************************************************/
@@ -2015,7 +2113,18 @@
 	if (mReq->zptr) {
 		if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0)
 			return -EBUSY;
-		dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma);
+
+		/* The controller may access this dTD one more time.
+		 * Defer freeing this to next zero length dTD completion.
+		 * It is safe to assume that controller will no longer
+		 * access the previous dTD after next dTD completion.
+		 */
+		if (mEp->last_zptr)
+			dma_pool_free(mEp->td_pool, mEp->last_zptr,
+					mEp->last_zdma);
+		mEp->last_zptr = mReq->zptr;
+		mEp->last_zdma = mReq->zdma;
+
 		mReq->zptr = NULL;
 	}
 
@@ -2045,6 +2154,25 @@
 }
 
 /**
+ * restore_original_req: Restore original req's attributes
+ * @mReq: Request
+ *
+ * This function restores original req's attributes.  Call
+ * this function before completing the large req (>16K).
+ */
+static void restore_original_req(struct ci13xxx_req *mReq)
+{
+	mReq->req.buf = mReq->multi.buf;
+	mReq->req.length = mReq->multi.len;
+	if (!mReq->req.status)
+		mReq->req.actual = mReq->multi.actual;
+
+	mReq->multi.len = 0;
+	mReq->multi.actual = 0;
+	mReq->multi.buf = NULL;
+}
+
+/**
  * _ep_nuke: dequeues all endpoint requests
  * @mEp: endpoint
  *
@@ -2097,6 +2225,11 @@
 			mReq->map     = 0;
 		}
 
+		if (mEp->multi_req) {
+			restore_original_req(mReq);
+			mEp->multi_req = false;
+		}
+
 		if (mReq->req.complete != NULL) {
 			spin_unlock(mEp->lock);
 			if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
@@ -2143,9 +2276,10 @@
 	usb_ep_fifo_flush(&udc->ep0out.ep);
 	usb_ep_fifo_flush(&udc->ep0in.ep);
 
-	if (udc->status != NULL) {
-		usb_ep_free_request(&udc->ep0in.ep, udc->status);
-		udc->status = NULL;
+	if (udc->ep0in.last_zptr) {
+		dma_pool_free(udc->ep0in.td_pool, udc->ep0in.last_zptr,
+				udc->ep0in.last_zdma);
+		udc->ep0in.last_zptr = NULL;
 	}
 
 	return 0;
@@ -2190,10 +2324,6 @@
 	if (retval)
 		goto done;
 
-	udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC);
-	if (udc->status == NULL)
-		retval = -ENOMEM;
-
 	spin_lock(udc->lock);
 
  done:
@@ -2262,8 +2392,8 @@
 		return;
 	}
 
-	kfree(req->buf);
-	usb_ep_free_request(ep, req);
+	if (req->status)
+		err("GET_STATUS failed");
 }
 
 /**
@@ -2279,8 +2409,7 @@
 __acquires(mEp->lock)
 {
 	struct ci13xxx_ep *mEp = &udc->ep0in;
-	struct usb_request *req = NULL;
-	gfp_t gfp_flags = GFP_ATOMIC;
+	struct usb_request *req = udc->status;
 	int dir, num, retval;
 
 	trace("%p, %p", mEp, setup);
@@ -2288,19 +2417,9 @@
 	if (mEp == NULL || setup == NULL)
 		return -EINVAL;
 
-	spin_unlock(mEp->lock);
-	req = usb_ep_alloc_request(&mEp->ep, gfp_flags);
-	spin_lock(mEp->lock);
-	if (req == NULL)
-		return -ENOMEM;
-
 	req->complete = isr_get_status_complete;
 	req->length   = 2;
-	req->buf      = kzalloc(req->length, gfp_flags);
-	if (req->buf == NULL) {
-		retval = -ENOMEM;
-		goto err_free_req;
-	}
+	req->buf      = udc->status_buf;
 
 	if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
 		if (setup->wIndex == OTG_STATUS_SELECTOR) {
@@ -2323,18 +2442,7 @@
 	/* else do nothing; reserved for future use */
 
 	spin_unlock(mEp->lock);
-	retval = usb_ep_queue(&mEp->ep, req, gfp_flags);
-	spin_lock(mEp->lock);
-	if (retval)
-		goto err_free_buf;
-
-	return 0;
-
- err_free_buf:
-	kfree(req->buf);
- err_free_req:
-	spin_unlock(mEp->lock);
-	usb_ep_free_request(&mEp->ep, req);
+	retval = usb_ep_queue(&mEp->ep, req, GFP_ATOMIC);
 	spin_lock(mEp->lock);
 	return retval;
 }
@@ -2377,11 +2485,9 @@
 	trace("%p", udc);
 
 	mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in;
-	if (udc->status) {
-		udc->status->context = udc;
-		udc->status->complete = isr_setup_status_complete;
-	} else
-		return -EINVAL;
+	udc->status->context = udc;
+	udc->status->complete = isr_setup_status_complete;
+	udc->status->length = 0;
 
 	spin_unlock(mEp->lock);
 	retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC);
@@ -2436,8 +2542,44 @@
 			break;
 		}
 		req_dequeue = 0;
+
+		if (mEp->multi_req) { /* Large request in progress */
+			unsigned remain_len;
+
+			mReq->multi.actual += mReq->req.actual;
+			remain_len = mReq->multi.len - mReq->multi.actual;
+			if (mReq->req.status || !remain_len ||
+				(mReq->req.actual != mReq->req.length)) {
+				restore_original_req(mReq);
+				mEp->multi_req = false;
+			} else {
+				mReq->req.buf = mReq->multi.buf +
+						mReq->multi.actual;
+				mReq->req.length = min_t(unsigned, remain_len,
+						(4 * CI13XXX_PAGE_SIZE));
+
+				mReq->req.status = -EINPROGRESS;
+				mReq->req.actual = 0;
+				list_del_init(&mReq->queue);
+				retval = _hardware_enqueue(mEp, mReq);
+				if (retval) {
+					err("Large req failed in middle");
+					mReq->req.status = retval;
+					restore_original_req(mReq);
+					mEp->multi_req = false;
+					goto done;
+				} else {
+					list_add_tail(&mReq->queue,
+						&mEp->qh.queue);
+					return 0;
+				}
+			}
+		}
 		list_del_init(&mReq->queue);
+done:
+
 		dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
+
 		if (mReq->req.complete != NULL) {
 			spin_unlock(mEp->lock);
 			if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
@@ -2779,6 +2921,12 @@
 
 	} while (mEp->dir != direction);
 
+	if (mEp->last_zptr) {
+		dma_pool_free(mEp->td_pool, mEp->last_zptr,
+				mEp->last_zdma);
+		mEp->last_zptr = NULL;
+	}
+
 	mEp->desc = NULL;
 	mEp->ep.desc = NULL;
 
@@ -2872,6 +3020,9 @@
 	if (ep == NULL || req == NULL || mEp->desc == NULL)
 		return -EINVAL;
 
+	if (!udc->softconnect)
+		return -ENODEV;
+
 	spin_lock_irqsave(mEp->lock, flags);
 
 	if (!udc->configured && mEp->type !=
@@ -2900,11 +3051,28 @@
 		err("request already in queue");
 		goto done;
 	}
+	if (mEp->multi_req) {
+		retval = -EAGAIN;
+		err("Large request is in progress. come again");
+		goto done;
+	}
 
 	if (req->length > (4 * CI13XXX_PAGE_SIZE)) {
+		if (!list_empty(&mEp->qh.queue)) {
+			retval = -EAGAIN;
+			err("Queue is busy. Large req is not allowed");
+			goto done;
+		}
+		if ((mEp->type != USB_ENDPOINT_XFER_BULK) ||
+				(mEp->dir != RX)) {
+			retval = -EINVAL;
+			err("Larger req is supported only for Bulk OUT");
+			goto done;
+		}
+		mEp->multi_req = true;
+		mReq->multi.len = req->length;
+		mReq->multi.buf = req->buf;
 		req->length = (4 * CI13XXX_PAGE_SIZE);
-		retval = -EMSGSIZE;
-		warn("request length truncated");
 	}
 
 	dbg_queue(_usb_addr(mEp), req, retval);
@@ -2921,6 +3089,8 @@
 	}
 	if (!retval)
 		list_add_tail(&mReq->queue, &mEp->qh.queue);
+	else if (mEp->multi_req)
+		mEp->multi_req = false;
 
  done:
 	spin_unlock_irqrestore(mEp->lock, flags);
@@ -2966,6 +3136,10 @@
 		mReq->map     = 0;
 	}
 	req->status = -ECONNRESET;
+	if (mEp->multi_req) {
+		restore_original_req(mReq);
+		mEp->multi_req = false;
+	}
 
 	if (mReq->req.complete != NULL) {
 		spin_unlock(mEp->lock);
@@ -3289,6 +3463,14 @@
 	retval = usb_ep_enable(&udc->ep0in.ep);
 	if (retval)
 		return retval;
+	udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_KERNEL);
+	if (!udc->status)
+		return -ENOMEM;
+	udc->status_buf = kzalloc(2, GFP_KERNEL); /* for GET_STATUS */
+	if (!udc->status_buf) {
+		usb_ep_free_request(&udc->ep0in.ep, udc->status);
+		return -ENOMEM;
+	}
 	spin_lock_irqsave(udc->lock, flags);
 
 	udc->gadget.ep0 = &udc->ep0in.ep;
@@ -3367,6 +3549,9 @@
 	driver->unbind(&udc->gadget);               /* MAY SLEEP */
 	spin_lock_irqsave(udc->lock, flags);
 
+	usb_ep_free_request(&udc->ep0in.ep, udc->status);
+	kfree(udc->status_buf);
+
 	udc->gadget.dev.driver = NULL;
 
 	/* free resources */
@@ -3583,6 +3768,11 @@
 	pm_runtime_no_callbacks(&udc->gadget.dev);
 	pm_runtime_enable(&udc->gadget.dev);
 
+	retval = register_trace_usb_daytona_invalid_access(dump_usb_info,
+								NULL);
+	if (retval)
+		pr_err("Registering trace failed\n");
+
 	_udc = udc;
 	return retval;
 
@@ -3616,11 +3806,17 @@
 static void udc_remove(void)
 {
 	struct ci13xxx *udc = _udc;
+	int retval;
 
 	if (udc == NULL) {
 		err("EINVAL");
 		return;
 	}
+	retval = unregister_trace_usb_daytona_invalid_access(dump_usb_info,
+									NULL);
+	if (retval)
+		pr_err("Unregistering trace failed\n");
+
 	usb_del_gadget_udc(&udc->gadget);
 
 	if (udc->transceiver) {
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index e3b0f8f..71919f4 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -77,6 +77,13 @@
 	struct usb_ctrlrequest   setup;
 } __attribute__ ((packed));
 
+/* cache of larger request's original attributes */
+struct ci13xxx_multi_req {
+	unsigned             len;
+	unsigned             actual;
+	void                *buf;
+};
+
 /* Extension of usb_request */
 struct ci13xxx_req {
 	struct usb_request   req;
@@ -86,6 +93,7 @@
 	dma_addr_t           dma;
 	struct ci13xxx_td   *zptr;
 	dma_addr_t           zdma;
+	struct ci13xxx_multi_req multi;
 };
 
 /* Extension of usb_ep */
@@ -107,10 +115,14 @@
 	spinlock_t                            *lock;
 	struct device                         *device;
 	struct dma_pool                       *td_pool;
+	struct ci13xxx_td                     *last_zptr;
+	dma_addr_t                            last_zdma;
 	unsigned long dTD_update_fail_count;
 	unsigned long			      prime_fail_count;
 	int				      prime_timer_count;
 	struct timer_list		      prime_timer;
+
+	bool                                  multi_req;
 };
 
 struct ci13xxx;
@@ -141,6 +153,7 @@
 	struct dma_pool           *qh_pool;   /* DMA pool for queue heads */
 	struct dma_pool           *td_pool;   /* DMA pool for transfer descs */
 	struct usb_request        *status;    /* ep0 status request */
+	void                      *status_buf;/* GET_STATUS buffer */
 
 	struct usb_gadget          gadget;     /* USB slave device */
 	struct ci13xxx_ep          ci13xxx_ep[ENDPT_MAX]; /* extended endpts */
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index 9c716d4..ea6d0bd 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2008 by David Brownell
  * Copyright (C) 2008 by Nokia Corporation
  * Copyright (C) 2009 by Samsung Electronics
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011 The Linux Foundation. All rights reserved.
  * Author: Michal Nazarewicz (mina86@mina86.com)
  *
  * This software is distributed under the terms of the GNU General
diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c
index 9d7eb33..4445dc2 100644
--- a/drivers/usb/gadget/f_adb.c
+++ b/drivers/usb/gadget/f_adb.c
@@ -316,7 +316,8 @@
 	}
 
 	/* wait for a request to complete */
-	ret = wait_event_interruptible(dev->read_wq, dev->rx_done);
+	ret = wait_event_interruptible(dev->read_wq, dev->rx_done ||
+				atomic_read(&dev->error));
 	if (ret < 0) {
 		if (ret != -ERESTARTSYS)
 		atomic_set(&dev->error, 1);
@@ -338,6 +339,9 @@
 		r = -EIO;
 
 done:
+	if (atomic_read(&dev->error))
+		wake_up(&dev->write_wq);
+
 	adb_unlock(&dev->read_excl);
 	pr_debug("adb_read returning %d\n", r);
 	return r;
@@ -406,6 +410,9 @@
 	if (req)
 		adb_req_put(dev, &dev->tx_idle, req);
 
+	if (atomic_read(&dev->error))
+		wake_up(&dev->read_wq);
+
 	adb_unlock(&dev->write_excl);
 	pr_debug("adb_write returning %d\n", r);
 	return r;
@@ -413,7 +420,10 @@
 
 static int adb_open(struct inode *ip, struct file *fp)
 {
-	pr_info("adb_open\n");
+	static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
+
+	if (__ratelimit(&rl))
+		pr_info("adb_open\n");
 	if (!_adb_dev)
 		return -ENODEV;
 
@@ -436,7 +446,10 @@
 
 static int adb_release(struct inode *ip, struct file *fp)
 {
-	pr_info("adb_release\n");
+	static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
+
+	if (__ratelimit(&rl))
+		pr_info("adb_release\n");
 
 	/*
 	 * ADB daemon closes the device file after I/O error.  The
diff --git a/drivers/usb/gadget/f_audio_source.c b/drivers/usb/gadget/f_audio_source.c
index 1c029dc..8b6b7fb 100644
--- a/drivers/usb/gadget/f_audio_source.c
+++ b/drivers/usb/gadget/f_audio_source.c
@@ -14,6 +14,8 @@
  *
  */
 
+#include <asm/dma.h>
+#include <linux/dma-mapping.h>
 #include <linux/device.h>
 #include <linux/usb/audio.h>
 #include <linux/wait.h>
@@ -684,6 +686,7 @@
 static int audio_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params)
 {
+	struct snd_dma_buffer *buf = &substream->dma_buffer;
 	unsigned int channels = params_channels(params);
 	unsigned int rate = params_rate(params);
 
@@ -692,13 +695,31 @@
 	if (channels != 2)
 		return -EINVAL;
 
-	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
-		params_buffer_bytes(params));
+	if (!substream->pcm->card->dev->coherent_dma_mask)
+		substream->pcm->card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+	buf->dev.type = SNDRV_DMA_TYPE_DEV;
+	buf->dev.dev = substream->pcm->card->dev;
+	buf->private_data = NULL;
+	buf->area = dma_alloc_coherent(substream->pcm->card->dev,
+			params_buffer_bytes(params),
+			&buf->addr, GFP_KERNEL);
+	if (!buf->area)
+		return -ENOMEM;
+	buf->bytes = params_buffer_bytes(params);
+	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+	return 0;
 }
 
 static int audio_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	return snd_pcm_lib_free_vmalloc_buffer(substream);
+	struct snd_dma_buffer *buf = &substream->dma_buffer;
+
+	if (buf->area != NULL)
+		dma_free_coherent(substream->pcm->card->dev, buf->bytes,
+					buf->area, buf->addr);
+	buf->area = NULL;
+	return 0;
 }
 
 static int audio_pcm_prepare(struct snd_pcm_substream *substream)
@@ -750,6 +771,22 @@
 	return ret;
 }
 
+static int audio_pcm_mmap(struct snd_pcm_substream *substream,
+				struct vm_area_struct *vma)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	if (runtime->dma_addr && runtime->dma_bytes) {
+		return dma_mmap_coherent(substream->pcm->card->dev, vma,
+					runtime->dma_area,
+					runtime->dma_addr,
+					runtime->dma_bytes);
+	} else {
+		pr_err("Physical address or size of buf is NULL");
+		return -EINVAL;
+	}
+}
+
 static struct audio_dev _audio_dev = {
 	.func = {
 		.name = "audio_source",
@@ -774,6 +811,7 @@
 	.prepare	= audio_pcm_prepare,
 	.trigger	= audio_pcm_playback_trigger,
 	.pointer	= audio_pcm_pointer,
+	.mmap		= audio_pcm_mmap,
 };
 
 int audio_source_bind_config(struct usb_configuration *c,
diff --git a/drivers/usb/gadget/f_ccid.c b/drivers/usb/gadget/f_ccid.c
index c8f144a..4e28d34 100644
--- a/drivers/usb/gadget/f_ccid.c
+++ b/drivers/usb/gadget/f_ccid.c
@@ -1,7 +1,7 @@
 /*
  * f_ccid.c -- CCID function Driver
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/f_ccid.h b/drivers/usb/gadget/f_ccid.h
index 4d6a0ea..d899044 100644
--- a/drivers/usb/gadget/f_ccid.h
+++ b/drivers/usb/gadget/f_ccid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/f_diag.h b/drivers/usb/gadget/f_diag.h
index 82d9a25..90497b6 100644
--- a/drivers/usb/gadget/f_diag.h
+++ b/drivers/usb/gadget/f_diag.h
@@ -3,7 +3,7 @@
  * Diag Function Device - Route DIAG frames between SMD and USB
  *
  * Copyright (C) 2008-2009 Google, Inc.
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index 6883b78..d22acbd 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index a8f875a..c8c355a 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -67,6 +67,9 @@
 #define MTP_RESPONSE_OK             0x2001
 #define MTP_RESPONSE_DEVICE_BUSY    0x2019
 
+unsigned int mtp_rx_req_len = MTP_BULK_BUFFER_SIZE;
+module_param(mtp_rx_req_len, uint, S_IRUGO | S_IWUSR);
+
 static const char mtp_shortname[] = "mtp_usb";
 
 struct mtp_dev {
@@ -427,10 +430,17 @@
 		req->complete = mtp_complete_in;
 		mtp_req_put(dev, &dev->tx_idle, req);
 	}
+retry_rx_alloc:
 	for (i = 0; i < RX_REQ_MAX; i++) {
-		req = mtp_request_new(dev->ep_out, MTP_BULK_BUFFER_SIZE);
-		if (!req)
-			goto fail;
+		req = mtp_request_new(dev->ep_out, mtp_rx_req_len);
+		if (!req) {
+			if (mtp_rx_req_len <= MTP_BULK_BUFFER_SIZE)
+				goto fail;
+			for (; i > 0; i--)
+				mtp_request_free(dev->rx_req[i], dev->ep_out);
+			mtp_rx_req_len = MTP_BULK_BUFFER_SIZE;
+			goto retry_rx_alloc;
+		}
 		req->complete = mtp_complete_out;
 		dev->rx_req[i] = req;
 	}
@@ -460,7 +470,7 @@
 
 	DBG(cdev, "mtp_read(%d)\n", count);
 
-	if (count > MTP_BULK_BUFFER_SIZE)
+	if (count > mtp_rx_req_len)
 		return -EINVAL;
 
 	/* we will block until we're online */
@@ -758,8 +768,8 @@
 			read_req = dev->rx_req[cur_buf];
 			cur_buf = (cur_buf + 1) % RX_REQ_MAX;
 
-			read_req->length = (count > MTP_BULK_BUFFER_SIZE
-					? MTP_BULK_BUFFER_SIZE : count);
+			read_req->length = (count > mtp_rx_req_len
+					? mtp_rx_req_len : count);
 			dev->rx_done = 0;
 			ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL);
 			if (ret < 0) {
diff --git a/drivers/usb/gadget/f_qc_ecm.c b/drivers/usb/gadget/f_qc_ecm.c
index 98a29ae..1a8b41e 100644
--- a/drivers/usb/gadget/f_qc_ecm.c
+++ b/drivers/usb/gadget/f_qc_ecm.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2003-2005,2008 David Brownell
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/f_qc_rndis.c b/drivers/usb/gadget/f_qc_rndis.c
index dcf307d..f91f99b 100644
--- a/drivers/usb/gadget/f_qc_rndis.c
+++ b/drivers/usb/gadget/f_qc_rndis.c
@@ -6,7 +6,7 @@
  * Copyright (C) 2008 Nokia Corporation
  * Copyright (C) 2009 Samsung Electronics
  *			Author: Michal Nazarewicz (mina86@mina86.com)
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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
diff --git a/drivers/usb/gadget/f_qdss.c b/drivers/usb/gadget/f_qdss.c
index 0c81904..26e4bd5 100644
--- a/drivers/usb/gadget/f_qdss.c
+++ b/drivers/usb/gadget/f_qdss.c
@@ -1,7 +1,7 @@
 /*
  * f_qdss.c -- QDSS function Driver
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/f_qdss.h b/drivers/usb/gadget/f_qdss.h
index b61244b..24cdf70 100644
--- a/drivers/usb/gadget/f_qdss.h
+++ b/drivers/usb/gadget/f_qdss.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index 1d0b6d4..70dc393 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -1082,7 +1082,8 @@
 	no_data_hsuart_ports = 0;
 }
 
-static int frmnet_init_port(const char *ctrl_name, const char *data_name)
+static int frmnet_init_port(const char *ctrl_name, const char *data_name,
+		const char *port_name)
 {
 	struct f_rmnet			*dev;
 	struct rmnet_ports		*rmnet_port;
@@ -1120,6 +1121,7 @@
 		no_ctrl_smd_ports++;
 		break;
 	case USB_GADGET_XPORT_HSIC:
+		ghsic_ctrl_set_port_name(port_name, ctrl_name);
 		rmnet_port->ctrl_xport_num = no_ctrl_hsic_ports;
 		no_ctrl_hsic_ports++;
 		break;
@@ -1146,6 +1148,7 @@
 		no_data_bam2bam_ports++;
 		break;
 	case USB_GADGET_XPORT_HSIC:
+		ghsic_data_set_port_name(port_name, data_name);
 		rmnet_port->data_xport_num = no_data_hsic_ports;
 		no_data_hsic_ports++;
 		break;
diff --git a/drivers/usb/gadget/f_rmnet.h b/drivers/usb/gadget/f_rmnet.h
index 2d816c6..f4375ba 100644
--- a/drivers/usb/gadget/f_rmnet.h
+++ b/drivers/usb/gadget/f_rmnet.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/f_rmnet_sdio.c b/drivers/usb/gadget/f_rmnet_sdio.c
index 8019356..46e6b12 100644
--- a/drivers/usb/gadget/f_rmnet_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_sdio.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. 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
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index b71f646..42d48f2 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, The Linux Foundation. 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
diff --git a/drivers/usb/gadget/f_rmnet_smd_sdio.c b/drivers/usb/gadget/f_rmnet_smd_sdio.c
index 175afe3..aa6c99a 100644
--- a/drivers/usb/gadget/f_rmnet_smd_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_smd_sdio.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011 The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 02f044e..6a43d4c 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -412,9 +412,14 @@
 static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	struct f_rndis			*rndis = req->context;
-	struct usb_composite_dev	*cdev = rndis->port.func.config->cdev;
+	struct usb_composite_dev	*cdev;
 	int				status = req->status;
 
+	if (!rndis->port.func.config || !rndis->port.func.config->cdev)
+		return;
+	else
+		cdev = rndis->port.func.config->cdev;
+
 	/* after TX:
 	 *  - USB_CDC_GET_ENCAPSULATED_RESPONSE (ep0/control)
 	 *  - RNDIS_RESPONSE_AVAILABLE (status/irq)
@@ -451,10 +456,15 @@
 static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	struct f_rndis			*rndis = req->context;
-	struct usb_composite_dev	*cdev = rndis->port.func.config->cdev;
+	struct usb_composite_dev	*cdev;
 	int				status;
 	rndis_init_msg_type		*buf;
 
+	if (!rndis->port.func.config || !rndis->port.func.config->cdev)
+		return;
+	else
+		cdev = rndis->port.func.config->cdev;
+
 	/* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
 //	spin_lock(&dev->lock);
 	status = rndis_msg_parser(rndis->config, (u8 *) req->buf);
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index 2461960..ddab1ec 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -304,7 +304,6 @@
 		ret = ghsic_ctrl_setup(no_hsic_sports, USB_GADGET_SERIAL);
 		if (ret < 0)
 			return ret;
-		return 0;
 	}
 	if (no_hsuart_sports) {
 		port_idx = ghsuart_data_setup(no_hsuart_sports,
@@ -319,8 +318,6 @@
 				port_idx++;
 			}
 		}
-
-		return 0;
 	}
 	return ret;
 }
@@ -951,9 +948,11 @@
 /**
  * gserial_init_port - bind a gserial_port to its transport
  */
-static int gserial_init_port(int port_num, const char *name)
+static int gserial_init_port(int port_num, const char *name,
+		const char *port_name)
 {
 	enum transport_type transport;
+	int ret = 0;
 
 	if (port_num >= GSERIAL_NO_PORTS)
 		return -ENODEV;
@@ -979,6 +978,9 @@
 		no_smd_ports++;
 		break;
 	case USB_GADGET_XPORT_HSIC:
+		ghsic_ctrl_set_port_name(port_name, name);
+		ghsic_data_set_port_name(port_name, name);
+
 		/*client port number will be updated in gport_setup*/
 		no_hsic_sports++;
 		break;
@@ -994,5 +996,5 @@
 
 	nr_ports++;
 
-	return 0;
+	return ret;
 }
diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
index 55fd59e..de99952 100644
--- a/drivers/usb/gadget/msm72k_udc.c
+++ b/drivers/usb/gadget/msm72k_udc.c
@@ -2,7 +2,7 @@
  * Driver for HighSpeed USB Client Controller in MSM7K
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Author: Mike Lockwood <lockwood@android.com>
  *         Brian Swetland <swetland@google.com>
  *
diff --git a/drivers/usb/gadget/qcom_maemo.c b/drivers/usb/gadget/qcom_maemo.c
index 39686c4..2fb8be0 100644
--- a/drivers/usb/gadget/qcom_maemo.c
+++ b/drivers/usb/gadget/qcom_maemo.c
@@ -4,9 +4,9 @@
  * Copyright (C) 2008 David Brownell
  * Copyright (C) 2008 Nokia Corporation
  * Copyright (C) 2009 Samsung Electronics
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
- * This program from the Code Aurora Forum is free software; you can
+ * This program from The Linux Foundation is free software; you can
  * redistribute it and/or modify it under the GNU General Public License
  * version 2 and only version 2 as published by the Free Software Foundation.
  * The original work available from [git.kernel.org ] is subject to the
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index a9e5d91..f410050 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, Linux Foundation. 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 and
@@ -572,6 +572,11 @@
 
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 	spin_lock_irqsave(&port->port_lock_dl, flags);
+	if (!port->port_usb) {
+		gbam_free_requests(ep, &d->rx_idle);
+		spin_unlock_irqrestore(&port->port_lock_dl, flags);
+		return;
+	}
 	ep = port->port_usb->in;
 	ret = gbam_alloc_requests(ep, &d->tx_idle, bam_mux_tx_q_size,
 			gbam_epin_complete, GFP_ATOMIC);
diff --git a/drivers/usb/gadget/u_bam_data.c b/drivers/usb/gadget/u_bam_data.c
index a105f5d..684ca11 100644
--- a/drivers/usb/gadget/u_bam_data.c
+++ b/drivers/usb/gadget/u_bam_data.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/u_ctrl_hsic.c b/drivers/usb/gadget/u_ctrl_hsic.c
index fdfab96..6143d1b 100644
--- a/drivers/usb/gadget/u_ctrl_hsic.c
+++ b/drivers/usb/gadget/u_ctrl_hsic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
@@ -36,12 +36,6 @@
 
 static unsigned int	no_ctrl_ports;
 
-static const char	*ctrl_bridge_names[] = {
-	"dun_ctrl_hsic0",
-	"rmnet_ctrl_hsic0"
-};
-
-#define CTRL_BRIDGE_NAME_MAX_LEN	20
 #define READ_BUF_LEN			1024
 
 #define CH_OPENED 0
@@ -83,6 +77,7 @@
 static struct {
 	struct gctrl_port	*port;
 	struct platform_driver	pdrv;
+	char			port_name[BRIDGE_NAME_MAX_LEN];
 } gctrl_ports[NUM_PORTS];
 
 static int ghsic_ctrl_receive(void *dev, void *buf, size_t actual)
@@ -336,19 +331,35 @@
 		gser->send_modem_ctrl_bits(gser, ctrl_bits);
 }
 
+static int ghsic_ctrl_get_port_id(const char *pdev_name)
+{
+	struct gctrl_port	*port;
+	int			i;
+
+	for (i = 0; i < no_ctrl_ports; i++) {
+		port = gctrl_ports[i].port;
+		if (!strncmp(port->brdg.name, pdev_name, BRIDGE_NAME_MAX_LEN))
+			return i;
+	}
+
+	return -EINVAL;
+}
+
 static int ghsic_ctrl_probe(struct platform_device *pdev)
 {
 	struct gctrl_port	*port;
 	unsigned long		flags;
+	int			id;
 
 	pr_debug("%s: name:%s\n", __func__, pdev->name);
 
-	if (pdev->id >= no_ctrl_ports) {
-		pr_err("%s: invalid port: %d\n", __func__, pdev->id);
+	id = ghsic_ctrl_get_port_id(pdev->name);
+	if (id < 0 || id >= no_ctrl_ports) {
+		pr_err("%s: invalid port: %d\n", __func__, id);
 		return -EINVAL;
 	}
 
-	port = gctrl_ports[pdev->id].port;
+	port = gctrl_ports[id].port;
 	set_bit(CH_READY, &port->bridge_sts);
 
 	/* if usb is online, start read */
@@ -366,15 +377,17 @@
 	struct gserial		*gser = NULL;
 	struct grmnet		*gr = NULL;
 	unsigned long		flags;
+	int			id;
 
 	pr_debug("%s: name:%s\n", __func__, pdev->name);
 
-	if (pdev->id >= no_ctrl_ports) {
-		pr_err("%s: invalid port: %d\n", __func__, pdev->id);
+	id = ghsic_ctrl_get_port_id(pdev->name);
+	if (id < 0 || id >= no_ctrl_ports) {
+		pr_err("%s: invalid port: %d\n", __func__, id);
 		return -EINVAL;
 	}
 
-	port = gctrl_ports[pdev->id].port;
+	port = gctrl_ports[id].port;
 
 	spin_lock_irqsave(&port->port_lock, flags);
 	if (!port->port_usb) {
@@ -421,15 +434,17 @@
 {
 	struct gctrl_port	*port;
 	struct platform_driver	*pdrv;
+	char			*name;
 
 	port = kzalloc(sizeof(struct gctrl_port), GFP_KERNEL);
 	if (!port)
 		return -ENOMEM;
 
-	port->wq = create_singlethread_workqueue(ctrl_bridge_names[portno]);
+	name = gctrl_ports[portno].port_name;
+
+	port->wq = create_singlethread_workqueue(name);
 	if (!port->wq) {
-		pr_err("%s: Unable to create workqueue:%s\n",
-			__func__, ctrl_bridge_names[portno]);
+		pr_err("%s: Unable to create workqueue:%s\n", __func__, name);
 		return -ENOMEM;
 	}
 
@@ -441,7 +456,7 @@
 	INIT_WORK(&port->connect_w, ghsic_ctrl_connect_w);
 	INIT_WORK(&port->disconnect_w, gctrl_disconnect_w);
 
-	port->brdg.ch_id = portno;
+	port->brdg.name = name;
 	port->brdg.ctx = port;
 	port->brdg.ops.send_pkt = ghsic_ctrl_receive;
 	if (port->gtype == USB_GADGET_SERIAL)
@@ -451,7 +466,7 @@
 	pdrv = &gctrl_ports[portno].pdrv;
 	pdrv->probe = ghsic_ctrl_probe;
 	pdrv->remove = ghsic_ctrl_remove;
-	pdrv->driver.name = ctrl_bridge_names[portno];
+	pdrv->driver.name = name;
 	pdrv->driver.owner = THIS_MODULE;
 
 	platform_driver_register(pdrv);
@@ -461,6 +476,31 @@
 	return 0;
 }
 
+/*portname will be used to find the bridge channel index*/
+void ghsic_ctrl_set_port_name(const char *name, const char *xport_type)
+{
+	static unsigned int port_num;
+
+	if (port_num >= NUM_PORTS) {
+		pr_err("%s: setting xport name for invalid port num %d\n",
+				__func__, port_num);
+		return;
+	}
+
+	/*if no xport name is passed set it to xport type e.g. hsic*/
+	if (!name)
+		strlcpy(gctrl_ports[port_num].port_name, xport_type,
+				BRIDGE_NAME_MAX_LEN);
+	else
+		strlcpy(gctrl_ports[port_num].port_name, name,
+				BRIDGE_NAME_MAX_LEN);
+
+	/*append _ctrl to get ctrl bridge name e.g. serial_hsic_ctrl*/
+	strlcat(gctrl_ports[port_num].port_name, "_ctrl", BRIDGE_NAME_MAX_LEN);
+
+	port_num++;
+}
+
 int ghsic_ctrl_setup(unsigned int num_ports, enum gadget_type gtype)
 {
 	int		first_port_id = no_ctrl_ports;
diff --git a/drivers/usb/gadget/u_ctrl_hsuart.c b/drivers/usb/gadget/u_ctrl_hsuart.c
index a55960e..a9bd53e 100644
--- a/drivers/usb/gadget/u_ctrl_hsuart.c
+++ b/drivers/usb/gadget/u_ctrl_hsuart.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/u_data_hsic.c b/drivers/usb/gadget/u_data_hsic.c
index 44c36db..d89a019 100644
--- a/drivers/usb/gadget/u_data_hsic.c
+++ b/drivers/usb/gadget/u_data_hsic.c
@@ -25,13 +25,6 @@
 
 static unsigned int no_data_ports;
 
-static const char *data_bridge_names[] = {
-	"dun_data_hsic0",
-	"rmnet_data_hsic0"
-};
-
-#define DATA_BRIDGE_NAME_MAX_LEN		20
-
 #define GHSIC_DATA_RMNET_RX_Q_SIZE		50
 #define GHSIC_DATA_RMNET_TX_Q_SIZE		300
 #define GHSIC_DATA_SERIAL_RX_Q_SIZE		10
@@ -130,6 +123,7 @@
 static struct {
 	struct gdata_port	*port;
 	struct platform_driver	pdrv;
+	char			port_name[BRIDGE_NAME_MAX_LEN];
 } gdata_ports[NUM_PORTS];
 
 static unsigned int get_timestamp(void);
@@ -150,22 +144,25 @@
 static int ghsic_data_alloc_requests(struct usb_ep *ep, struct list_head *head,
 		int num,
 		void (*cb)(struct usb_ep *ep, struct usb_request *),
-		gfp_t flags)
+		spinlock_t *lock)
 {
 	int			i;
 	struct usb_request	*req;
+	unsigned long		flags;
 
 	pr_debug("%s: ep:%s head:%p num:%d cb:%p", __func__,
 			ep->name, head, num, cb);
 
 	for (i = 0; i < num; i++) {
-		req = usb_ep_alloc_request(ep, flags);
+		req = usb_ep_alloc_request(ep, GFP_KERNEL);
 		if (!req) {
 			pr_debug("%s: req allocated:%d\n", __func__, i);
 			return list_empty(head) ? -ENOMEM : 0;
 		}
 		req->complete = cb;
+		spin_lock_irqsave(lock, flags);
 		list_add(&req->list, head);
+		spin_unlock_irqrestore(lock, flags);
 	}
 
 	return 0;
@@ -437,20 +434,23 @@
 
 		req = list_first_entry(&port->rx_idle,
 					struct usb_request, list);
+		list_del(&req->list);
+		spin_unlock_irqrestore(&port->rx_lock, flags);
 
 		created = get_timestamp();
-		skb = alloc_skb(ghsic_data_rx_req_size, GFP_ATOMIC);
-		if (!skb)
+		skb = alloc_skb(ghsic_data_rx_req_size, GFP_KERNEL);
+		if (!skb) {
+			spin_lock_irqsave(&port->rx_lock, flags);
+			list_add(&req->list, &port->rx_idle);
 			break;
+		}
 		info = (struct timestamp_info *)skb->cb;
 		info->created = created;
-		list_del(&req->list);
 		req->buf = skb->data;
 		req->length = ghsic_data_rx_req_size;
 		req->context = skb;
 
 		info->rx_queued = get_timestamp();
-		spin_unlock_irqrestore(&port->rx_lock, flags);
 		ret = usb_ep_queue(ep, req, GFP_KERNEL);
 		spin_lock_irqsave(&port->rx_lock, flags);
 		if (ret) {
@@ -481,36 +481,36 @@
 
 	spin_lock_irqsave(&port->rx_lock, flags);
 	ep = port->out;
-	if (!ep) {
-		spin_unlock_irqrestore(&port->rx_lock, flags);
+	spin_unlock_irqrestore(&port->rx_lock, flags);
+	if (!ep)
 		return;
-	}
 
 	ret = ghsic_data_alloc_requests(ep, &port->rx_idle,
-		port->rx_q_size, ghsic_data_epout_complete, GFP_ATOMIC);
+		port->rx_q_size, ghsic_data_epout_complete, &port->rx_lock);
 	if (ret) {
 		pr_err("%s: rx req allocation failed\n", __func__);
-		spin_unlock_irqrestore(&port->rx_lock, flags);
 		return;
 	}
-	spin_unlock_irqrestore(&port->rx_lock, flags);
 
 	spin_lock_irqsave(&port->tx_lock, flags);
 	ep = port->in;
+	spin_unlock_irqrestore(&port->tx_lock, flags);
 	if (!ep) {
-		spin_unlock_irqrestore(&port->tx_lock, flags);
+		spin_lock_irqsave(&port->rx_lock, flags);
+		ghsic_data_free_requests(ep, &port->rx_idle);
+		spin_unlock_irqrestore(&port->rx_lock, flags);
 		return;
 	}
 
 	ret = ghsic_data_alloc_requests(ep, &port->tx_idle,
-		port->tx_q_size, ghsic_data_epin_complete, GFP_ATOMIC);
+		port->tx_q_size, ghsic_data_epin_complete, &port->tx_lock);
 	if (ret) {
 		pr_err("%s: tx req allocation failed\n", __func__);
+		spin_lock_irqsave(&port->rx_lock, flags);
 		ghsic_data_free_requests(ep, &port->rx_idle);
-		spin_unlock_irqrestore(&port->tx_lock, flags);
+		spin_unlock_irqrestore(&port->rx_lock, flags);
 		return;
 	}
-	spin_unlock_irqrestore(&port->tx_lock, flags);
 
 	/* queue out requests */
 	ghsic_data_start_rx(port);
@@ -585,19 +585,35 @@
 	spin_unlock_irqrestore(&port->rx_lock, flags);
 }
 
+static int ghsic_data_get_port_id(const char *pdev_name)
+{
+	struct gdata_port *port;
+	int i;
+
+	for (i = 0; i < no_data_ports; i++) {
+		port = gdata_ports[i].port;
+		if (!strncmp(port->brdg.name, pdev_name, BRIDGE_NAME_MAX_LEN))
+			return i;
+	}
+
+	return -EINVAL;
+}
+
 static int ghsic_data_probe(struct platform_device *pdev)
 {
 	struct gdata_port *port;
+	int id;
 
-	pr_debug("%s: name:%s no_data_ports= %d\n",
-		__func__, pdev->name, no_data_ports);
+	pr_debug("%s: name:%s no_data_ports= %d\n", __func__, pdev->name,
+			no_data_ports);
 
-	if (pdev->id >= no_data_ports) {
-		pr_err("%s: invalid port: %d\n", __func__, pdev->id);
+	id = ghsic_data_get_port_id(pdev->name);
+	if (id < 0 || id >= no_data_ports) {
+		pr_err("%s: invalid port: %d\n", __func__, id);
 		return -EINVAL;
 	}
 
-	port = gdata_ports[pdev->id].port;
+	port = gdata_ports[id].port;
 	set_bit(CH_READY, &port->bridge_sts);
 
 	/* if usb is online, try opening bridge */
@@ -613,15 +629,17 @@
 	struct gdata_port *port;
 	struct usb_ep	*ep_in;
 	struct usb_ep	*ep_out;
+	int id;
 
 	pr_debug("%s: name:%s\n", __func__, pdev->name);
 
-	if (pdev->id >= no_data_ports) {
-		pr_err("%s: invalid port: %d\n", __func__, pdev->id);
+	id = ghsic_data_get_port_id(pdev->name);
+	if (id < 0 || id >= no_data_ports) {
+		pr_err("%s: invalid port: %d\n", __func__, id);
 		return -EINVAL;
 	}
 
-	port = gdata_ports[pdev->id].port;
+	port = gdata_ports[id].port;
 
 	ep_in = port->in;
 	if (ep_in)
@@ -631,6 +649,9 @@
 	if (ep_out)
 		usb_ep_fifo_flush(ep_out);
 
+	/* cancel pending writes to MDM */
+	cancel_work_sync(&port->write_tomdm_w);
+
 	ghsic_data_free_buffers(port);
 
 	cancel_work_sync(&port->connect_w);
@@ -657,15 +678,17 @@
 {
 	struct gdata_port	*port;
 	struct platform_driver	*pdrv;
+	char			*name;
 
 	port = kzalloc(sizeof(struct gdata_port), GFP_KERNEL);
 	if (!port)
 		return -ENOMEM;
 
-	port->wq = create_singlethread_workqueue(data_bridge_names[port_num]);
+	name = gdata_ports[port_num].port_name;
+
+	port->wq = create_singlethread_workqueue(name);
 	if (!port->wq) {
-		pr_err("%s: Unable to create workqueue:%s\n",
-			__func__, data_bridge_names[port_num]);
+		pr_err("%s: Unable to create workqueue:%s\n", __func__, name);
 		kfree(port);
 		return -ENOMEM;
 	}
@@ -687,7 +710,7 @@
 	skb_queue_head_init(&port->rx_skb_q);
 
 	port->gtype = gtype;
-	port->brdg.ch_id = port_num;
+	port->brdg.name = name;
 	port->brdg.ctx = port;
 	port->brdg.ops.send_pkt = ghsic_data_receive;
 	port->brdg.ops.unthrottle_tx = ghsic_data_unthrottle_tx;
@@ -696,7 +719,7 @@
 	pdrv = &gdata_ports[port_num].pdrv;
 	pdrv->probe = ghsic_data_probe;
 	pdrv->remove = ghsic_data_remove;
-	pdrv->driver.name = data_bridge_names[port_num];
+	pdrv->driver.name = name;
 	pdrv->driver.owner = THIS_MODULE;
 
 	platform_driver_register(pdrv);
@@ -728,11 +751,15 @@
 	ghsic_data_free_buffers(port);
 
 	/* disable endpoints */
-	if (port->in)
-		usb_ep_disable(port->out);
-
-	if (port->out)
+	if (port->in) {
 		usb_ep_disable(port->in);
+		port->in->driver_data = NULL;
+	}
+
+	if (port->out) {
+		usb_ep_disable(port->out);
+		port->out->driver_data = NULL;
+	}
 
 	atomic_set(&port->connected, 0);
 
@@ -841,7 +868,7 @@
 }
 
 #if defined(CONFIG_DEBUG_FS)
-#define DEBUG_BUF_SIZE 1024
+#define DEBUG_DATA_BUF_SIZE 4096
 
 static unsigned int	record_timestamp;
 module_param(record_timestamp, uint, S_IRUGO | S_IWUSR);
@@ -912,7 +939,7 @@
 	if (!record_timestamp)
 		return 0;
 
-	buf = kzalloc(sizeof(char) * 4 * DEBUG_BUF_SIZE, GFP_KERNEL);
+	buf = kzalloc(sizeof(char) * DEBUG_DATA_BUF_SIZE, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
@@ -922,7 +949,7 @@
 	for (dbg_inc(&i); i != dbg_data.idx; dbg_inc(&i)) {
 		if (!strnlen(dbg_data.buf[i], DBG_DATA_MSG))
 			continue;
-		j += scnprintf(buf + j, (4 * DEBUG_BUF_SIZE) - j,
+		j += scnprintf(buf + j, DEBUG_DATA_BUF_SIZE - j,
 			       "%s\n", dbg_data.buf[i]);
 	}
 
@@ -950,7 +977,7 @@
 	int			i;
 	int			temp = 0;
 
-	buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
+	buf = kzalloc(sizeof(char) * DEBUG_DATA_BUF_SIZE, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
@@ -961,7 +988,7 @@
 		pdrv = &gdata_ports[i].pdrv;
 
 		spin_lock_irqsave(&port->rx_lock, flags);
-		temp += scnprintf(buf + temp, DEBUG_BUF_SIZE - temp,
+		temp += scnprintf(buf + temp, DEBUG_DATA_BUF_SIZE - temp,
 				"\nName:           %s\n"
 				"#PORT:%d port#:   %p\n"
 				"data_ch_open:	   %d\n"
@@ -986,7 +1013,7 @@
 		spin_unlock_irqrestore(&port->rx_lock, flags);
 
 		spin_lock_irqsave(&port->tx_lock, flags);
-		temp += scnprintf(buf + temp, DEBUG_BUF_SIZE - temp,
+		temp += scnprintf(buf + temp, DEBUG_DATA_BUF_SIZE - temp,
 				"\n******DL INFO******\n\n"
 				"dpkts_to_usbhost: %lu\n"
 				"tx_buf_len:	   %u\n"
@@ -1089,6 +1116,31 @@
 
 #endif
 
+/*portname will be used to find the bridge channel index*/
+void ghsic_data_set_port_name(const char *name, const char *xport_type)
+{
+	static unsigned int port_num;
+
+	if (port_num >= NUM_PORTS) {
+		pr_err("%s: setting xport name for invalid port num %d\n",
+				__func__, port_num);
+		return;
+	}
+
+	/*if no xport name is passed set it to xport type e.g. hsic*/
+	if (!name)
+		strlcpy(gdata_ports[port_num].port_name, xport_type,
+				BRIDGE_NAME_MAX_LEN);
+	else
+		strlcpy(gdata_ports[port_num].port_name, name,
+				BRIDGE_NAME_MAX_LEN);
+
+	/*append _data to get data bridge name: e.g. serial_hsic_data*/
+	strlcat(gdata_ports[port_num].port_name, "_data", BRIDGE_NAME_MAX_LEN);
+
+	port_num++;
+}
+
 int ghsic_data_setup(unsigned num_ports, enum gadget_type gtype)
 {
 	int		first_port_id = no_data_ports;
diff --git a/drivers/usb/gadget/u_data_hsuart.c b/drivers/usb/gadget/u_data_hsuart.c
index ef7a811..2466110 100644
--- a/drivers/usb/gadget/u_data_hsuart.c
+++ b/drivers/usb/gadget/u_data_hsuart.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 0c9aa1a..549c5e0 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -545,6 +545,11 @@
 				switch (retval) {
 				default:
 					DBG(dev, "tx queue err %d\n", retval);
+					new_req->length = 0;
+					spin_lock(&dev->req_lock);
+					list_add_tail(&new_req->list,
+							&dev->tx_reqs);
+					spin_unlock(&dev->req_lock);
 					break;
 				case 0:
 					spin_lock(&dev->req_lock);
@@ -554,7 +559,13 @@
 				}
 			} else {
 				spin_lock(&dev->req_lock);
-				list_add(&new_req->list, &dev->tx_reqs);
+				/*
+				 * Put the idle request at the back of the
+				 * queue. The xmit function will put the
+				 * unfinished request at the beginning of the
+				 * queue.
+				 */
+				list_add_tail(&new_req->list, &dev->tx_reqs);
 				spin_unlock(&dev->req_lock);
 			}
 		} else {
@@ -604,11 +615,13 @@
 	unsigned long		flags;
 	struct usb_ep		*in;
 	u16			cdc_filter;
+	bool			multi_pkt_xfer = false;
 
 	spin_lock_irqsave(&dev->lock, flags);
 	if (dev->port_usb) {
 		in = dev->port_usb->in_ep;
 		cdc_filter = dev->port_usb->cdc_filter;
+		multi_pkt_xfer = dev->port_usb->multi_pkt_xfer;
 	} else {
 		in = NULL;
 		cdc_filter = 0;
@@ -621,7 +634,7 @@
 	}
 
 	/* Allocate memory for tx_reqs to support multi packet transfer */
-	if (dev->port_usb->multi_pkt_xfer && !dev->tx_req_bufsize)
+	if (multi_pkt_xfer && !dev->tx_req_bufsize)
 		alloc_tx_buffer(dev);
 
 	/* apply outgoing CDC or RNDIS filters */
@@ -684,7 +697,7 @@
 	dev->tx_skb_hold_count++;
 	spin_unlock_irqrestore(&dev->req_lock, flags);
 
-	if (dev->port_usb->multi_pkt_xfer) {
+	if (multi_pkt_xfer) {
 		memcpy(req->buf + req->length, skb->data, skb->len);
 		req->length = req->length + skb->len;
 		length = req->length;
@@ -756,8 +769,10 @@
 	}
 
 	if (retval) {
-		if (!dev->port_usb->multi_pkt_xfer)
+		if (!multi_pkt_xfer)
 			dev_kfree_skb_any(skb);
+		else
+			req->length = 0;
 drop:
 		dev->net->stats.tx_dropped++;
 		spin_lock_irqsave(&dev->req_lock, flags);
diff --git a/drivers/usb/gadget/u_qc_ether.c b/drivers/usb/gadget/u_qc_ether.c
index 20933b6..8bd726b 100644
--- a/drivers/usb/gadget/u_qc_ether.c
+++ b/drivers/usb/gadget/u_qc_ether.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2003-2005,2008 David Brownell
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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
diff --git a/drivers/usb/gadget/u_qc_ether.h b/drivers/usb/gadget/u_qc_ether.h
index b3c281b..379c20a 100644
--- a/drivers/usb/gadget/u_qc_ether.h
+++ b/drivers/usb/gadget/u_qc_ether.h
@@ -4,7 +4,7 @@
  * Copyright (C) 2003-2005,2008 David Brownell
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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
diff --git a/drivers/usb/gadget/u_qdss.c b/drivers/usb/gadget/u_qdss.c
index d227c62..8939eed 100644
--- a/drivers/usb/gadget/u_qdss.c
+++ b/drivers/usb/gadget/u_qdss.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/u_rmnet.h b/drivers/usb/gadget/u_rmnet.h
index 0f7c4fb..81ba223 100644
--- a/drivers/usb/gadget/u_rmnet.h
+++ b/drivers/usb/gadget/u_rmnet.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/u_rmnet_ctrl_smd.c b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
index 169008b..2d00570 100644
--- a/drivers/usb/gadget/u_rmnet_ctrl_smd.c
+++ b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/gadget/u_sdio.c b/drivers/usb/gadget/u_sdio.c
index a604e1e..a0cdde2 100644
--- a/drivers/usb/gadget/u_sdio.c
+++ b/drivers/usb/gadget/u_sdio.c
@@ -5,9 +5,9 @@
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 David Brownell
  * Copyright (C) 2008 by Nokia Corporation
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
- * This program from the Code Aurora Forum is free software; you can
+ * This program from The Linux Foundation is free software; you can
  * redistribute it and/or modify it under the GNU General Public License
  * version 2 and only version 2 as published by the Free Software Foundation.
  * The original work available from [kernel.org] is subject to the notice below.
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index fd29b9d..3139c48 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -856,13 +856,6 @@
 	port->open_count = 1;
 	port->openclose = false;
 
-	/* low_latency means ldiscs work is carried in the same context
-	 * of tty_flip_buffer_push. The same can be called from IRQ with
-	 * low_latency = 0. But better to use a dedicated worker thread
-	 * to push the data.
-	 */
-	tty->low_latency = 1;
-
 	/* if connected, start the I/O stream */
 	if (port->port_usb) {
 		struct gserial	*gser = port->port_usb;
@@ -1060,6 +1053,13 @@
 	struct gs_port		*port = tty->driver_data;
 	unsigned long		flags;
 
+	/*
+	 * tty's driver data is set to NULL during port close.  Nothing
+	 * to do here.
+	 */
+	if (!port)
+		return;
+
 	spin_lock_irqsave(&port->port_lock, flags);
 	if (port->port_usb) {
 		/* Kickstart read queue processing.  We don't do xon/xoff,
@@ -1315,7 +1315,8 @@
 		return;
 
 	debugfs_create_file("readstatus", 0444, dent, ui_dev, &debug_adb_ops);
-	debugfs_create_file("reset", 0222, dent, ui_dev, &debug_rst_ops);
+	debugfs_create_file("reset", S_IRUGO | S_IWUSR,
+			dent, ui_dev, &debug_rst_ops);
 }
 #else
 static void usb_debugfs_init(struct gs_port *ui_dev) {}
diff --git a/drivers/usb/gadget/u_smd.c b/drivers/usb/gadget/u_smd.c
index ce285a3..4b02665 100644
--- a/drivers/usb/gadget/u_smd.c
+++ b/drivers/usb/gadget/u_smd.c
@@ -1,7 +1,7 @@
 /*
  * u_smd.c - utilities for USB gadget serial over smd
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * This code also borrows from drivers/usb/gadget/u_serial.c, which is
  * Copyright (C) 2000 - 2003 Al Borchers (alborchers@steinerpoint.com)
@@ -72,6 +72,7 @@
 
 	struct smd_port_info	*pi;
 	struct delayed_work	connect_work;
+	struct work_struct	disconnect_work;
 
 	/* At present, smd does not notify
 	 * control bit change info from modem
@@ -589,6 +590,20 @@
 	}
 }
 
+static void gsmd_disconnect_work(struct work_struct *w)
+{
+	struct gsmd_port *port;
+	struct smd_port_info *pi;
+
+	port = container_of(w, struct gsmd_port, disconnect_work);
+	pi = port->pi;
+
+	pr_debug("%s: port:%p port#%d\n", __func__, port, port->port_num);
+
+	smd_close(port->pi->ch);
+	port->pi->ch = NULL;
+}
+
 static void gsmd_notify_modem(void *gptr, u8 portno, int ctrl_bits)
 {
 	struct gsmd_port *port;
@@ -731,10 +746,8 @@
 				~port->cbits_to_modem);
 	}
 
-	if (port->pi->ch) {
-		smd_close(port->pi->ch);
-		port->pi->ch = NULL;
-	}
+	if (port->pi->ch)
+		queue_work(gsmd_wq, &port->disconnect_work);
 }
 
 #define SMD_CH_MAX_LEN	20
@@ -819,6 +832,7 @@
 	INIT_WORK(&port->pull, gsmd_tx_pull);
 
 	INIT_DELAYED_WORK(&port->connect_work, gsmd_connect_work);
+	INIT_WORK(&port->disconnect_work, gsmd_disconnect_work);
 
 	smd_ports[portno].port = port;
 	pdrv = &smd_ports[portno].pdrv;
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 0512381..6cb663d 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -188,11 +188,11 @@
 	return tbuf;
 }
 
-static int allow_dbg_log(int ep_addr)
+static int allow_dbg_log(struct urb *urb, int ep_addr)
 {
 	int dir, num;
 
-	dir = ep_addr & USB_DIR_IN ? USB_DIR_IN : USB_DIR_OUT;
+	dir = usb_urb_dir_in(urb) ? USB_DIR_IN : USB_DIR_OUT;
 	num = ep_addr & ~USB_DIR_IN;
 	num = 1 << num;
 
@@ -204,9 +204,9 @@
 	return 0;
 }
 
-static char *get_hex_data(char *dbuf, struct urb *urb, int event, int status)
+static char *
+get_hex_data(char *dbuf, struct urb *urb, int event, int status, size_t max_len)
 {
-	int ep_addr = urb->ep->desc.bEndpointAddress;
 	char *ubuf = urb->transfer_buffer;
 	size_t len = event ? \
 		urb->actual_length : urb->transfer_buffer_length;
@@ -214,12 +214,11 @@
 	if (status == -EINPROGRESS)
 		status = 0;
 
-	/*Only dump ep in completions and epout submissions*/
-	if (len && !status &&
-		(((ep_addr & USB_DIR_IN) && event) ||
-		(!(ep_addr & USB_DIR_IN) && !event))) {
-		if (len >= 32)
-			len = 32;
+	/*Only dump ep in successful completions and epout submissions*/
+	if (len && !status && ((usb_urb_dir_in(urb) && event) ||
+			(usb_urb_dir_out(urb) && !event))) {
+		if (len >= max_len)
+			len = max_len;
 		hex_dump_to_buffer(ubuf, len, 32, 4, dbuf, HEX_DUMP_LEN, 0);
 	} else {
 		dbuf = "";
@@ -248,7 +247,7 @@
 	}
 
 	ep_addr = urb->ep->desc.bEndpointAddress;
-	if (!allow_dbg_log(ep_addr))
+	if (!allow_dbg_log(urb, ep_addr))
 		return;
 
 	if ((ep_addr & 0x0f) == 0x0) {
@@ -257,9 +256,9 @@
 			write_lock_irqsave(&dbg_hsic_ctrl.lck, flags);
 			scnprintf(dbg_hsic_ctrl.buf[dbg_hsic_ctrl.idx],
 				DBG_MSG_LEN, "%s: [%s : %p]:[%s] "
-				  "%02x %02x %04x %04x %04x  %u %d",
+				  "%02x %02x %04x %04x %04x  %u %d %s",
 				  get_timestamp(tbuf), event, urb,
-				  (ep_addr & USB_DIR_IN) ? "in" : "out",
+				  usb_urb_dir_in(urb) ? "in" : "out",
 				  urb->setup_packet[0], urb->setup_packet[1],
 				  (urb->setup_packet[3] << 8) |
 				  urb->setup_packet[2],
@@ -267,17 +266,21 @@
 				  urb->setup_packet[4],
 				  (urb->setup_packet[7] << 8) |
 				  urb->setup_packet[6],
-				  urb->transfer_buffer_length, extra);
+				  urb->transfer_buffer_length, extra,
+				  enable_payload_log ? get_hex_data(dbuf, urb,
+				  str_to_event(event), extra, 16) : "");
 
 			dbg_inc(&dbg_hsic_ctrl.idx);
 			write_unlock_irqrestore(&dbg_hsic_ctrl.lck, flags);
 		} else {
 			write_lock_irqsave(&dbg_hsic_ctrl.lck, flags);
 			scnprintf(dbg_hsic_ctrl.buf[dbg_hsic_ctrl.idx],
-				DBG_MSG_LEN, "%s: [%s : %p]:[%s] %u %d",
+				DBG_MSG_LEN, "%s: [%s : %p]:[%s] %u %d %s",
 				  get_timestamp(tbuf), event, urb,
-				  (ep_addr & USB_DIR_IN) ? "in" : "out",
-				  urb->actual_length, extra);
+				  usb_urb_dir_in(urb) ? "in" : "out",
+				  urb->actual_length, extra,
+				  enable_payload_log ? get_hex_data(dbuf, urb,
+				  str_to_event(event), extra, 16) : "");
 
 			dbg_inc(&dbg_hsic_ctrl.idx);
 			write_unlock_irqrestore(&dbg_hsic_ctrl.lck, flags);
@@ -287,11 +290,11 @@
 		scnprintf(dbg_hsic_data.buf[dbg_hsic_data.idx], DBG_MSG_LEN,
 			  "%s: [%s : %p]:ep%d[%s]  %u %d %s",
 			  get_timestamp(tbuf), event, urb, ep_addr & 0x0f,
-			  (ep_addr & USB_DIR_IN) ? "in" : "out",
+			  usb_urb_dir_in(urb) ? "in" : "out",
 			  str_to_event(event) ? urb->actual_length :
 			  urb->transfer_buffer_length, extra,
 			  enable_payload_log ? get_hex_data(dbuf, urb,
-				  str_to_event(event), extra) : "");
+				  str_to_event(event), extra, 32) : "");
 
 		dbg_inc(&dbg_hsic_data.idx);
 		write_unlock_irqrestore(&dbg_hsic_data.lck, flags);
@@ -954,6 +957,7 @@
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 	struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
 	u32 __iomem *status_reg = &ehci->regs->port_status[0];
+	u32 cmd;
 	unsigned long flags;
 	int retries = 0, ret, cnt = RESET_SIGNAL_TIME_USEC;
 
@@ -962,6 +966,19 @@
 			pdata->swfi_latency + 1);
 
 	mehci->bus_reset = 1;
+
+	/* Halt the controller */
+	cmd = ehci_readl(ehci, &ehci->regs->command);
+	cmd &= ~CMD_RUN;
+	ehci_writel(ehci, cmd, &ehci->regs->command);
+	ret = handshake(ehci, &ehci->regs->status, STS_HALT,
+			STS_HALT, 16 * 125);
+	if (ret) {
+		pr_err("halt handshake fatal error\n");
+		dbg_log_event(NULL, "HALT: fatal", 0);
+		goto fail;
+	}
+
 retry:
 	retries++;
 	dbg_log_event(NULL, "RESET: start", retries);
@@ -1811,6 +1828,9 @@
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 	struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
 
+	/* Remove the HCD prior to releasing our resources. */
+	usb_remove_hcd(hcd);
+
 	if (pdata && pdata->swfi_latency)
 		pm_qos_remove_request(&mehci->pm_qos_req_dma);
 
@@ -1840,7 +1860,6 @@
 
 	destroy_workqueue(ehci_wq);
 
-	usb_remove_hcd(hcd);
 	msm_hsic_config_gpios(mehci, 0);
 	msm_hsic_init_vddcx(mehci, 0);
 
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index e8e4e10..66363eb 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -1,6 +1,6 @@
 /* ehci-msm.c - HSUSB Host Controller Driver Implementation
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * Partly derived from ehci-fsl.c and ehci-hcd.c
  * Copyright (c) 2000-2004 by David Brownell
diff --git a/drivers/usb/host/ehci-msm2.c b/drivers/usb/host/ehci-msm2.c
index 6eb083e..18de794 100644
--- a/drivers/usb/host/ehci-msm2.c
+++ b/drivers/usb/host/ehci-msm2.c
@@ -1,6 +1,6 @@
 /* ehci-msm2.c - HSUSB Host Controller Driver Implementation
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * Partly derived from ehci-fsl.c and ehci-hcd.c
  * Copyright (c) 2000-2004 by David Brownell
diff --git a/drivers/usb/host/ehci-msm72k.c b/drivers/usb/host/ehci-msm72k.c
index 816e408..6211cd1c 100644
--- a/drivers/usb/host/ehci-msm72k.c
+++ b/drivers/usb/host/ehci-msm72k.c
@@ -1,6 +1,6 @@
 /* ehci-msm.c - HSUSB Host Controller Driver Implementation
  *
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * Partly derived from ehci-fsl.c and ehci-hcd.c
  * Copyright (c) 2000-2004 by David Brownell
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index b65cc40..b200903 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -44,6 +44,7 @@
 	struct mutex		ifc_mutex;
 	struct diag_bridge_ops	*ops;
 	struct platform_device	*pdev;
+	int			id;
 
 	/* debugging counters */
 	unsigned long		bytes_to_host;
@@ -85,7 +86,7 @@
 static void diag_bridge_delete(struct kref *kref)
 {
 	struct diag_bridge *dev = container_of(kref, struct diag_bridge, kref);
-	int id = dev->pdev->id;
+	int id = dev->id;
 
 	usb_put_dev(dev->udev);
 	__dev[id] = 0;
@@ -459,6 +460,7 @@
 		return -ENOMEM;
 	}
 	__dev[devid] = dev;
+	dev->id = devid;
 
 	dev->udev = usb_get_dev(interface_to_usbdev(ifc));
 	dev->ifc = ifc;
diff --git a/drivers/usb/misc/diag_bridge_test.c b/drivers/usb/misc/diag_bridge_test.c
index 5bc0828..18d8a51 100644
--- a/drivers/usb/misc/diag_bridge_test.c
+++ b/drivers/usb/misc/diag_bridge_test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/usb/misc/ehset.c b/drivers/usb/misc/ehset.c
index 30879e0..ebaf567 100644
--- a/drivers/usb/misc/ehset.c
+++ b/drivers/usb/misc/ehset.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/usb/misc/mdm_ctrl_bridge.c b/drivers/usb/misc/mdm_ctrl_bridge.c
index 2b56ee0..75fce2f 100644
--- a/drivers/usb/misc/mdm_ctrl_bridge.c
+++ b/drivers/usb/misc/mdm_ctrl_bridge.c
@@ -26,11 +26,6 @@
 #include <asm/unaligned.h>
 #include <mach/usb_bridge.h>
 
-static const char *ctrl_bridge_names[] = {
-	"dun_ctrl_hsic0",
-	"rmnet_ctrl_hsic0"
-};
-
 /* polling interval for Interrupt ep */
 #define HS_INTERVAL		7
 #define FS_LS_INTERVAL		3
@@ -40,10 +35,18 @@
 
 #define SUSPENDED		BIT(0)
 
+enum ctrl_bridge_rx_state {
+	RX_IDLE, /* inturb is not queued */
+	RX_WAIT, /* inturb is queued and waiting for data */
+	RX_BUSY, /* inturb is completed. processing RX */
+};
+
 struct ctrl_bridge {
 	struct usb_device	*udev;
 	struct usb_interface	*intf;
 
+	char			*name;
+
 	unsigned int		int_pipe;
 	struct urb		*inturb;
 	void			*intbuf;
@@ -66,6 +69,9 @@
 	/* output control lines (DTR, RTS) */
 	unsigned int		cbits_tomdm;
 
+	spinlock_t lock;
+	enum ctrl_bridge_rx_state rx_state;
+
 	/* counters */
 	unsigned int		snd_encap_cmd;
 	unsigned int		get_encap_res;
@@ -76,8 +82,19 @@
 
 static struct ctrl_bridge	*__dev[MAX_BRIDGE_DEVICES];
 
-/* counter used for indexing ctrl bridge devices */
-static int	ch_id;
+static int get_ctrl_bridge_chid(char *xport_name)
+{
+	struct ctrl_bridge	*dev;
+	int			i;
+
+	for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
+		dev = __dev[i];
+		if (!strncmp(dev->name, xport_name, BRIDGE_NAME_MAX_LEN))
+			return i;
+	}
+
+	return -ENODEV;
+}
 
 unsigned int ctrl_bridge_get_cbits_tohost(unsigned int id)
 {
@@ -125,12 +142,39 @@
 }
 EXPORT_SYMBOL(ctrl_bridge_set_cbits);
 
+static int ctrl_bridge_start_read(struct ctrl_bridge *dev, gfp_t gfp_flags)
+{
+	int	retval = 0;
+	unsigned long flags;
+
+	if (!dev->inturb) {
+		dev_err(&dev->intf->dev, "%s: inturb is NULL\n", __func__);
+		return -ENODEV;
+	}
+
+	retval = usb_submit_urb(dev->inturb, gfp_flags);
+	if (retval < 0 && retval != -EPERM) {
+		dev_err(&dev->intf->dev,
+			"%s error submitting int urb %d\n",
+			__func__, retval);
+	}
+
+	spin_lock_irqsave(&dev->lock, flags);
+	if (retval)
+		dev->rx_state = RX_IDLE;
+	else
+		dev->rx_state = RX_WAIT;
+	spin_unlock_irqrestore(&dev->lock, flags);
+
+	return retval;
+}
+
 static void resp_avail_cb(struct urb *urb)
 {
 	struct ctrl_bridge	*dev = urb->context;
-	int			status = 0;
 	int			resubmit_urb = 1;
 	struct bridge		*brdg = dev->brdg;
+	unsigned long		flags;
 
 	/*usb device disconnect*/
 	if (urb->dev->state == USB_STATE_NOTATTACHED)
@@ -162,12 +206,14 @@
 
 	if (resubmit_urb) {
 		/*re- submit int urb to check response available*/
-		status = usb_submit_urb(dev->inturb, GFP_ATOMIC);
-		if (status)
-			dev_err(&dev->intf->dev,
-				"%s: Error re-submitting Int URB %d\n",
-				__func__, status);
+		ctrl_bridge_start_read(dev, GFP_ATOMIC);
+	} else {
+		spin_lock_irqsave(&dev->lock, flags);
+		dev->rx_state = RX_IDLE;
+		spin_unlock_irqrestore(&dev->lock, flags);
 	}
+
+	usb_autopm_put_interface_async(dev->intf);
 }
 
 static void notification_available_cb(struct urb *urb)
@@ -178,11 +224,16 @@
 	struct bridge			*brdg = dev->brdg;
 	unsigned int			ctrl_bits;
 	unsigned char			*data;
+	unsigned long			flags;
 
 	/*usb device disconnect*/
 	if (urb->dev->state == USB_STATE_NOTATTACHED)
 		return;
 
+	spin_lock_irqsave(&dev->lock, flags);
+	dev->rx_state = RX_IDLE;
+	spin_unlock_irqrestore(&dev->lock, flags);
+
 	switch (urb->status) {
 	case 0:
 		/*success*/
@@ -209,7 +260,11 @@
 
 	switch (ctrl->bNotificationType) {
 	case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
+		spin_lock_irqsave(&dev->lock, flags);
+		dev->rx_state = RX_BUSY;
+		spin_unlock_irqrestore(&dev->lock, flags);
 		dev->resp_avail++;
+		usb_autopm_get_interface_no_resume(dev->intf);
 		usb_fill_control_urb(dev->readurb, dev->udev,
 					usb_rcvctrlpipe(dev->udev, 0),
 					(unsigned char *)dev->in_ctlreq,
@@ -222,6 +277,7 @@
 			dev_err(&dev->intf->dev,
 				"%s: Error submitting Read URB %d\n",
 				__func__, status);
+			usb_autopm_put_interface_async(dev->intf);
 			goto resubmit_int_urb;
 		}
 		return;
@@ -245,48 +301,28 @@
 	}
 
 resubmit_int_urb:
-	status = usb_submit_urb(urb, GFP_ATOMIC);
-	if (status)
-		dev_err(&dev->intf->dev, "%s: Error re-submitting Int URB %d\n",
-		__func__, status);
-}
-
-static int ctrl_bridge_start_read(struct ctrl_bridge *dev)
-{
-	int	retval = 0;
-
-	if (!dev->inturb) {
-		dev_err(&dev->intf->dev, "%s: inturb is NULL\n", __func__);
-		return -ENODEV;
-	}
-
-	retval = usb_submit_urb(dev->inturb, GFP_KERNEL);
-	if (retval < 0)
-		dev_err(&dev->intf->dev,
-			"%s error submitting int urb %d\n",
-			__func__, retval);
-
-	return retval;
+	ctrl_bridge_start_read(dev, GFP_ATOMIC);
 }
 
 int ctrl_bridge_open(struct bridge *brdg)
 {
 	struct ctrl_bridge	*dev;
+	int			ch_id;
 
 	if (!brdg) {
 		err("bridge is null\n");
 		return -EINVAL;
 	}
 
-	if (brdg->ch_id >= MAX_BRIDGE_DEVICES)
-		return -EINVAL;
-
-	dev = __dev[brdg->ch_id];
-	if (!dev) {
-		err("dev is null\n");
-		return -ENODEV;
+	ch_id = get_ctrl_bridge_chid(brdg->name);
+	if (ch_id < 0 || ch_id >= MAX_BRIDGE_DEVICES) {
+		err("%s: %s dev not found\n", __func__, brdg->name);
+		return ch_id;
 	}
 
+	brdg->ch_id = ch_id;
+
+	dev = __dev[ch_id];
 	dev->brdg = brdg;
 	dev->snd_encap_cmd = 0;
 	dev->get_encap_res = 0;
@@ -347,6 +383,7 @@
 	struct urb		*writeurb;
 	struct usb_ctrlrequest	*out_ctlreq;
 	struct ctrl_bridge	*dev;
+	unsigned long		flags;
 
 	if (id >= MAX_BRIDGE_DEVICES) {
 		result = -EINVAL;
@@ -415,12 +452,15 @@
 		goto free_ctrlreq;
 	}
 
+	spin_lock_irqsave(&dev->lock, flags);
 	if (test_bit(SUSPENDED, &dev->flags)) {
 		usb_anchor_urb(writeurb, &dev->tx_deferred);
+		spin_unlock_irqrestore(&dev->lock, flags);
 		goto deferred;
 	}
 
 	usb_anchor_urb(writeurb, &dev->tx_submitted);
+	spin_unlock_irqrestore(&dev->lock, flags);
 	result = usb_submit_urb(writeurb, GFP_ATOMIC);
 	if (result < 0) {
 		dev_err(&dev->intf->dev, "%s: submit URB error %d\n",
@@ -447,6 +487,7 @@
 int ctrl_bridge_suspend(unsigned int id)
 {
 	struct ctrl_bridge	*dev;
+	unsigned long		flags;
 
 	if (id >= MAX_BRIDGE_DEVICES)
 		return -EINVAL;
@@ -455,10 +496,27 @@
 	if (!dev)
 		return -ENODEV;
 
-	set_bit(SUSPENDED, &dev->flags);
+	spin_lock_irqsave(&dev->lock, flags);
+	if (!usb_anchor_empty(&dev->tx_submitted) || dev->rx_state == RX_BUSY) {
+		spin_unlock_irqrestore(&dev->lock, flags);
+		return -EBUSY;
+	}
+	spin_unlock_irqrestore(&dev->lock, flags);
+
 	usb_kill_urb(dev->inturb);
-	usb_kill_urb(dev->readurb);
-	usb_kill_anchored_urbs(&dev->tx_submitted);
+
+	spin_lock_irqsave(&dev->lock, flags);
+	if (dev->rx_state != RX_IDLE) {
+		spin_unlock_irqrestore(&dev->lock, flags);
+		return -EBUSY;
+	}
+	if (!usb_anchor_empty(&dev->tx_submitted)) {
+		spin_unlock_irqrestore(&dev->lock, flags);
+		ctrl_bridge_start_read(dev, GFP_KERNEL);
+		return -EBUSY;
+	}
+	set_bit(SUSPENDED, &dev->flags);
+	spin_unlock_irqrestore(&dev->lock, flags);
 
 	return 0;
 }
@@ -467,6 +525,8 @@
 {
 	struct ctrl_bridge	*dev;
 	struct urb		*urb;
+	unsigned long		flags;
+	int			ret;
 
 	if (id >= MAX_BRIDGE_DEVICES)
 		return -EINVAL;
@@ -475,12 +535,19 @@
 	if (!dev)
 		return -ENODEV;
 
-	if (!test_and_clear_bit(SUSPENDED, &dev->flags))
+	if (!test_bit(SUSPENDED, &dev->flags))
 		return 0;
 
+	spin_lock_irqsave(&dev->lock, flags);
 	/* submit pending write requests */
 	while ((urb = usb_get_from_anchor(&dev->tx_deferred))) {
-		int ret;
+		spin_unlock_irqrestore(&dev->lock, flags);
+		/*
+		 * usb_get_from_anchor() does not drop the
+		 * ref count incremented by the usb_anchro_urb()
+		 * called in Tx submission path. Let us do it.
+		 */
+		usb_put_urb(urb);
 		usb_anchor_urb(urb, &dev->tx_submitted);
 		ret = usb_submit_urb(urb, GFP_ATOMIC);
 		if (ret < 0) {
@@ -490,9 +557,12 @@
 			usb_free_urb(urb);
 			usb_autopm_put_interface_async(dev->intf);
 		}
+		spin_lock_irqsave(&dev->lock, flags);
 	}
+	clear_bit(SUSPENDED, &dev->flags);
+	spin_unlock_irqrestore(&dev->lock, flags);
 
-	return ctrl_bridge_start_read(dev);
+	return ctrl_bridge_start_read(dev, GFP_KERNEL);
 }
 
 #if defined(CONFIG_DEBUG_FS)
@@ -510,7 +580,7 @@
 	if (!buf)
 		return -ENOMEM;
 
-	for (i = 0; i < ch_id; i++) {
+	for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
 		dev = __dev[i];
 		if (!dev)
 			continue;
@@ -525,7 +595,7 @@
 				"cbits_tomdm: %d\n"
 				"cbits_tohost: %d\n"
 				"suspended: %d\n",
-				dev->pdev->name, dev,
+				dev->name, dev,
 				dev->snd_encap_cmd,
 				dev->get_encap_res,
 				dev->resp_avail,
@@ -549,7 +619,7 @@
 	struct ctrl_bridge	*dev;
 	int			i;
 
-	for (i = 0; i < ch_id; i++) {
+	for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
 		dev = __dev[i];
 		if (!dev)
 			continue;
@@ -596,7 +666,7 @@
 
 int
 ctrl_bridge_probe(struct usb_interface *ifc, struct usb_host_endpoint *int_in,
-		int id)
+		char *name, int id)
 {
 	struct ctrl_bridge		*dev;
 	struct usb_device		*udev;
@@ -613,11 +683,14 @@
 		return -ENODEV;
 	}
 
-	dev->pdev = platform_device_alloc(ctrl_bridge_names[id], id);
+	dev->name = name;
+
+	dev->pdev = platform_device_alloc(name, -1);
 	if (!dev->pdev) {
+		retval = -ENOMEM;
 		dev_err(&ifc->dev, "%s: unable to allocate platform device\n",
 			__func__);
-		return -ENOMEM;
+		goto free_name;
 	}
 
 	dev->flags = 0;
@@ -633,7 +706,7 @@
 	if (!dev->inturb) {
 		dev_err(&ifc->dev, "%s: error allocating int urb\n", __func__);
 		retval = -ENOMEM;
-		goto pdev_del;
+		goto pdev_put;
 	}
 
 	wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize);
@@ -685,12 +758,24 @@
 		dev->intf->cur_altsetting->desc.bInterfaceNumber;
 	dev->in_ctlreq->wLength = cpu_to_le16(DEFAULT_READ_URB_LENGTH);
 
-	platform_device_add(dev->pdev);
+	retval = platform_device_add(dev->pdev);
+	if (retval) {
+		dev_err(&ifc->dev, "%s:fail to add pdev\n", __func__);
+		goto free_ctrlreq;
+	}
 
-	ch_id++;
+	retval = ctrl_bridge_start_read(dev, GFP_KERNEL);
+	if (retval) {
+		dev_err(&ifc->dev, "%s:fail to start reading\n", __func__);
+		goto pdev_del;
+	}
 
-	return ctrl_bridge_start_read(dev);
+	return 0;
 
+pdev_del:
+	platform_device_del(dev->pdev);
+free_ctrlreq:
+	kfree(dev->in_ctlreq);
 free_rbuf:
 	kfree(dev->readbuf);
 free_rurb:
@@ -699,8 +784,10 @@
 	kfree(dev->intbuf);
 free_inturb:
 	usb_free_urb(dev->inturb);
-pdev_del:
-	platform_device_unregister(dev->pdev);
+pdev_put:
+	platform_device_put(dev->pdev);
+free_name:
+	dev->name = "none";
 
 	return retval;
 }
@@ -711,8 +798,14 @@
 
 	dev_dbg(&dev->intf->dev, "%s:\n", __func__);
 
+	/*set device name to none to get correct channel id
+	 * at the time of bridge open
+	 */
+	dev->name = "none";
+
 	platform_device_unregister(dev->pdev);
 
+	usb_scuttle_anchored_urbs(&dev->tx_deferred);
 	usb_kill_anchored_urbs(&dev->tx_submitted);
 
 	usb_kill_urb(dev->inturb);
@@ -724,8 +817,6 @@
 
 	usb_free_urb(dev->readurb);
 	usb_free_urb(dev->inturb);
-
-	ch_id--;
 }
 
 int ctrl_bridge_init(void)
@@ -743,6 +834,10 @@
 			goto error;
 		}
 
+		/*transport name will be set during probe*/
+		dev->name = "none";
+
+		spin_lock_init(&dev->lock);
 		init_usb_anchor(&dev->tx_submitted);
 		init_usb_anchor(&dev->tx_deferred);
 
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index 8f91474..11d45b3 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -29,11 +29,37 @@
 #define FLOW_CTRL_DISABLE		300
 #define FLOW_CTRL_SUPPORT		1
 
-static const char	*data_bridge_names[] = {
-	"dun_data_hsic0",
-	"rmnet_data_hsic0"
+#define BRIDGE_DATA_IDX		0
+#define BRIDGE_CTRL_IDX		1
+
+/*for xport : HSIC*/
+static const char * const serial_hsic_bridge_names[] = {
+	"serial_hsic_data",
+	"serial_hsic_ctrl",
 };
 
+static const char * const rmnet_hsic_bridge_names[] = {
+	"rmnet_hsic_data",
+	"rmnet_hsic_ctrl",
+};
+
+/*for xport : HSUSB*/
+static const char * const serial_hsusb_bridge_names[] = {
+	"serial_hsusb_data",
+	"serial_hsusb_ctrl",
+};
+
+static const char * const rmnet_hsusb_bridge_names[] = {
+	"rmnet_hsusb_data",
+	"rmnet_hsusb_ctrl",
+};
+
+/* since driver supports multiple instances, on smp systems
+ * probe might get called from multiple cores, hence use lock
+ * to identify unclaimed bridge device instance
+ */
+static DEFINE_MUTEX(brdg_claim_lock);
+
 static struct workqueue_struct	*bridge_wq;
 
 static unsigned int	fctrl_support = FLOW_CTRL_SUPPORT;
@@ -54,14 +80,16 @@
 static unsigned tx_urb_mult = 20;
 module_param(tx_urb_mult, uint, S_IRUGO|S_IWUSR);
 
-#define TX_HALT   BIT(0)
-#define RX_HALT   BIT(1)
-#define SUSPENDED BIT(2)
+#define TX_HALT   0
+#define RX_HALT   1
+#define SUSPENDED 2
+#define CLAIMED   3
 
 struct data_bridge {
 	struct usb_interface		*intf;
 	struct usb_device		*udev;
 	int				id;
+	char				*name;
 
 	unsigned int			bulk_in;
 	unsigned int			bulk_out;
@@ -71,9 +99,6 @@
 	struct usb_anchor		tx_active;
 	struct usb_anchor		rx_active;
 
-	/* keep track of outgoing URBs during suspend */
-	struct usb_anchor		delayed;
-
 	struct list_head		rx_idle;
 	struct sk_buff_head		rx_done;
 
@@ -102,31 +127,43 @@
 
 static struct data_bridge	*__dev[MAX_BRIDGE_DEVICES];
 
-/* counter used for indexing data bridge devices */
-static int	ch_id;
-
 static unsigned int get_timestamp(void);
 static void dbg_timestamp(char *, struct sk_buff *);
 static int submit_rx_urb(struct data_bridge *dev, struct urb *urb,
 		gfp_t flags);
-static void*	interface[MAX_BRIDGE_DEVICES];
 
-static inline int get_chid(struct usb_interface *iface)
+/* Find an unclaimed bridge device instance */
+static int get_bridge_dev_idx(void)
 {
-	int	i;
+	struct data_bridge	*dev;
+	int			i;
+
+	mutex_lock(&brdg_claim_lock);
 	for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
-		if (interface[i] == iface)
+		dev = __dev[i];
+		if (!test_bit(CLAIMED, &dev->flags)) {
+			set_bit(CLAIMED, &dev->flags);
+			mutex_unlock(&brdg_claim_lock);
+			return i;
+		}
+	}
+	mutex_unlock(&brdg_claim_lock);
+
+	return -ENODEV;
+}
+
+static int get_data_bridge_chid(char *xport_name)
+{
+	struct data_bridge	*dev;
+	int			i;
+
+	for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
+		dev = __dev[i];
+		if (!strncmp(dev->name, xport_name, BRIDGE_NAME_MAX_LEN))
 			return i;
 	}
 
-	return -1;
-}
-
-static inline void set_chid(struct usb_interface *iface, int chid)
-{
-	if (chid >= 0 && chid < MAX_BRIDGE_DEVICES) {
-		interface[chid] = iface;
-	}
+	return -ENODEV;
 }
 
 static inline  bool rx_halted(struct data_bridge *dev)
@@ -341,21 +378,23 @@
 int data_bridge_open(struct bridge *brdg)
 {
 	struct data_bridge	*dev;
+	int			ch_id;
 
 	if (!brdg) {
 		err("bridge is null\n");
 		return -EINVAL;
 	}
 
-	if (brdg->ch_id >= MAX_BRIDGE_DEVICES)
-		return -EINVAL;
-
-	dev = __dev[brdg->ch_id];
-	if (!dev) {
-		err("dev is null\n");
-		return -ENODEV;
+	ch_id = get_data_bridge_chid(brdg->name);
+	if (ch_id < 0 || ch_id >= MAX_BRIDGE_DEVICES) {
+		err("%s: %s dev not found\n", __func__, brdg->name);
+		return ch_id;
 	}
 
+	brdg->ch_id = ch_id;
+
+	dev = __dev[ch_id];
+
 	dev_dbg(&dev->intf->dev, "%s: dev:%p\n", __func__, dev);
 
 	dev->brdg = brdg;
@@ -395,7 +434,6 @@
 
 	usb_kill_anchored_urbs(&dev->tx_active);
 	usb_kill_anchored_urbs(&dev->rx_active);
-	usb_kill_anchored_urbs(&dev->delayed);
 
 	spin_lock_irqsave(&dev->rx_done.lock, flags);
 	while ((skb = __skb_dequeue(&dev->rx_done)))
@@ -554,11 +592,6 @@
 
 	txurb->transfer_flags |= URB_ZERO_PACKET;
 
-	if (test_bit(SUSPENDED, &dev->flags)) {
-		usb_anchor_urb(txurb, &dev->delayed);
-		goto free_urb;
-	}
-
 	pending = atomic_inc_return(&dev->pending_txurbs);
 	usb_anchor_urb(txurb, &dev->tx_active);
 
@@ -598,85 +631,42 @@
 }
 EXPORT_SYMBOL(data_bridge_write);
 
-static int data_bridge_resume(struct data_bridge *dev)
+static int bridge_resume(struct usb_interface *iface)
 {
-	struct urb	*urb;
-	int		retval;
+	int			retval = 0;
+	struct data_bridge	*dev = usb_get_intfdata(iface);
 
-	if (!test_and_clear_bit(SUSPENDED, &dev->flags))
-		return 0;
-
-	while ((urb = usb_get_from_anchor(&dev->delayed))) {
-		usb_anchor_urb(urb, &dev->tx_active);
-		atomic_inc(&dev->pending_txurbs);
-		retval = usb_submit_urb(urb, GFP_ATOMIC);
-		if (retval < 0) {
-			atomic_dec(&dev->pending_txurbs);
-			usb_unanchor_urb(urb);
-
-			/* TODO: need to free urb data */
-			usb_scuttle_anchored_urbs(&dev->delayed);
-			break;
-		}
-		dev->to_modem++;
-		dev->txurb_drp_cnt--;
-	}
+	clear_bit(SUSPENDED, &dev->flags);
 
 	if (dev->brdg)
 		queue_work(dev->wq, &dev->process_rx_w);
 
-	return 0;
-}
-
-static int bridge_resume(struct usb_interface *iface)
-{
-	int			retval = 0;
-	int			oldstate;
-	struct data_bridge	*dev = usb_get_intfdata(iface);
-
-	oldstate = iface->dev.power.power_state.event;
-	iface->dev.power.power_state.event = PM_EVENT_ON;
-
-	if (oldstate & PM_EVENT_SUSPEND) {
-		retval = data_bridge_resume(dev);
-		if (!retval)
-			retval = ctrl_bridge_resume(dev->id);
-	}
+	retval = ctrl_bridge_resume(dev->id);
 
 	return retval;
 }
 
-static int data_bridge_suspend(struct data_bridge *dev, pm_message_t message)
-{
-	if (atomic_read(&dev->pending_txurbs) &&
-		(message.event & PM_EVENT_AUTO))
-		return -EBUSY;
-
-	set_bit(SUSPENDED, &dev->flags);
-
-	usb_kill_anchored_urbs(&dev->tx_active);
-	usb_kill_anchored_urbs(&dev->rx_active);
-
-	return 0;
-}
-
 static int bridge_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	int			retval;
 	struct data_bridge	*dev = usb_get_intfdata(intf);
 
-	retval = data_bridge_suspend(dev, message);
-	if (!retval) {
-		retval = ctrl_bridge_suspend(dev->id);
-		intf->dev.power.power_state.event = message.event;
-	}
+	if (atomic_read(&dev->pending_txurbs))
+		return -EBUSY;
 
-	return retval;
+	retval = ctrl_bridge_suspend(dev->id);
+	if (retval)
+		return retval;
+
+	set_bit(SUSPENDED, &dev->flags);
+	usb_kill_anchored_urbs(&dev->rx_active);
+
+	return 0;
 }
 
 static int data_bridge_probe(struct usb_interface *iface,
 		struct usb_host_endpoint *bulk_in,
-		struct usb_host_endpoint *bulk_out, int id)
+		struct usb_host_endpoint *bulk_out, char *name, int id)
 {
 	struct data_bridge	*dev;
 	int			retval;
@@ -687,15 +677,20 @@
 		return -ENODEV;
 	}
 
-	dev->pdev = platform_device_alloc(data_bridge_names[id], id);
+	dev->pdev = platform_device_alloc(name, -1);
 	if (!dev->pdev) {
 		err("%s: unable to allocate platform device\n", __func__);
 		kfree(dev);
 		return -ENOMEM;
 	}
 
-	dev->flags = 0;
+	/*clear all bits except claimed bit*/
+	clear_bit(RX_HALT, &dev->flags);
+	clear_bit(TX_HALT, &dev->flags);
+	clear_bit(SUSPENDED, &dev->flags);
+
 	dev->id = id;
+	dev->name = name;
 	dev->udev = interface_to_usbdev(iface);
 	dev->intf = iface;
 
@@ -720,7 +715,7 @@
 }
 
 #if defined(CONFIG_DEBUG_FS)
-#define DEBUG_BUF_SIZE	1024
+#define DEBUG_BUF_SIZE	4096
 
 static unsigned int	record_timestamp;
 module_param(record_timestamp, uint, S_IRUGO | S_IWUSR);
@@ -791,7 +786,7 @@
 	if (!record_timestamp)
 		return 0;
 
-	buf = kzalloc(sizeof(char) * 4 * DEBUG_BUF_SIZE, GFP_KERNEL);
+	buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
@@ -801,7 +796,7 @@
 	for (dbg_inc(&i); i != dbg_data.idx; dbg_inc(&i)) {
 		if (!strnlen(dbg_data.buf[i], DBG_DATA_MSG))
 			continue;
-		j += scnprintf(buf + j, (4 * DEBUG_BUF_SIZE) - j,
+		j += scnprintf(buf + j, DEBUG_BUF_SIZE - j,
 			       "%s\n", dbg_data.buf[i]);
 	}
 
@@ -831,7 +826,7 @@
 	if (!buf)
 		return -ENOMEM;
 
-	for (i = 0; i < ch_id; i++) {
+	for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
 		dev = __dev[i];
 		if (!dev)
 			continue;
@@ -851,7 +846,7 @@
 				"suspended:          %d\n"
 				"TX_HALT:            %d\n"
 				"RX_HALT:            %d\n",
-				dev->pdev->name, dev,
+				dev->name, dev,
 				atomic_read(&dev->pending_txurbs),
 				dev->txurb_drp_cnt,
 				dev->to_host,
@@ -881,7 +876,7 @@
 	struct data_bridge	*dev;
 	int			i;
 
-	for (i = 0; i < ch_id; i++) {
+	for (i = 0; i < MAX_BRIDGE_DEVICES; i++) {
 		dev = __dev[i];
 		if (!dev)
 			continue;
@@ -958,9 +953,8 @@
 	int				i;
 	int				status = 0;
 	int				numends;
-	unsigned int			iface_num;
-
-	iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
+	int				ch_id;
+	char				**bname = (char **)id->driver_info;
 
 	if (iface->num_altsetting != 1) {
 		err("%s invalid num_altsetting %u\n",
@@ -968,9 +962,6 @@
 		return -EINVAL;
 	}
 
-	if (!test_bit(iface_num, &id->driver_info))
-		return -ENODEV;
-
 	udev = interface_to_usbdev(iface);
 	usb_get_dev(udev);
 
@@ -998,26 +989,30 @@
 		goto out;
 	}
 
-	status = data_bridge_probe(iface, bulk_in, bulk_out, ch_id);
+	ch_id = get_bridge_dev_idx();
+	if (ch_id < 0) {
+		err("%s all bridge channels claimed. Probe failed\n", __func__);
+		return -ENODEV;
+	}
+
+	status = data_bridge_probe(iface, bulk_in, bulk_out,
+			bname[BRIDGE_DATA_IDX], ch_id);
 	if (status < 0) {
 		dev_err(&iface->dev, "data_bridge_probe failed %d\n", status);
 		goto out;
 	}
 
-	status = ctrl_bridge_probe(iface, int_in, ch_id);
+	status = ctrl_bridge_probe(iface, int_in, bname[BRIDGE_CTRL_IDX],
+			ch_id);
 	if (status < 0) {
 		dev_err(&iface->dev, "ctrl_bridge_probe failed %d\n", status);
 		goto error;
 	}
 
-	set_chid(iface, ch_id);
-
-	ch_id++;
-
 	return 0;
 
 error:
-	platform_device_put(__dev[ch_id]->pdev);
+	platform_device_unregister(__dev[ch_id]->pdev);
 	free_rx_urbs(__dev[ch_id]);
 	usb_set_intfdata(iface, NULL);
 out:
@@ -1029,23 +1024,18 @@
 static void bridge_disconnect(struct usb_interface *intf)
 {
 	struct data_bridge	*dev = usb_get_intfdata(intf);
-	int			chid;
 
 	if (!dev) {
 		err("%s: data device not found\n", __func__);
 		return;
 	}
 
-	ch_id--;	/* leave it for now */
+	/*set device name to none to get correct channel id
+	 * at the time of bridge open
+	 */
+	dev->name = "none";
 
-	chid = get_chid(intf);
-
-	if (chid < 0) {
-		err("%s: invalid interface\n", __func__);
-		return;
-	}
-
-	ctrl_bridge_disconnect(chid);
+	ctrl_bridge_disconnect(dev->id);
 	platform_device_unregister(dev->pdev);
 	usb_set_intfdata(intf, NULL);
 
@@ -1053,27 +1043,40 @@
 
 	usb_put_dev(dev->udev);
 
-	set_chid(NULL, chid);
+	clear_bit(CLAIMED, &dev->flags);
 }
 
-/*bit position represents interface number*/
-#define PID9001_IFACE_MASK	0xC
-#define PID9034_IFACE_MASK	0xC
-#define PID9048_IFACE_MASK	0x18
-#define PID904C_IFACE_MASK	0x28
-
+/*driver info stores data/ctrl bridge name used to match bridge xport name*/
 static const struct usb_device_id bridge_ids[] = {
-	{ USB_DEVICE(0x5c6, 0x9001),
-	.driver_info = PID9001_IFACE_MASK,
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9001, 2),
+	.driver_info = (unsigned long)serial_hsic_bridge_names,
 	},
-	{ USB_DEVICE(0x5c6, 0x9034),
-	.driver_info = PID9034_IFACE_MASK,
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9001, 3),
+	.driver_info = (unsigned long)rmnet_hsic_bridge_names,
 	},
-	{ USB_DEVICE(0x5c6, 0x9048),
-	.driver_info = PID9048_IFACE_MASK,
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9034, 2),
+	.driver_info = (unsigned long)serial_hsic_bridge_names,
 	},
-	{ USB_DEVICE(0x5c6, 0x904c),
-	.driver_info = PID904C_IFACE_MASK,
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9034, 3),
+	.driver_info = (unsigned long)rmnet_hsic_bridge_names,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 3),
+	.driver_info = (unsigned long)serial_hsic_bridge_names,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 4),
+	.driver_info = (unsigned long)rmnet_hsic_bridge_names,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x904c, 3),
+	.driver_info = (unsigned long)serial_hsic_bridge_names,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x904c, 5),
+	.driver_info = (unsigned long)rmnet_hsic_bridge_names,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9079, 3),
+	.driver_info = (unsigned long)serial_hsusb_bridge_names,
+	},
+	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9079, 4),
+	.driver_info = (unsigned long)rmnet_hsusb_bridge_names,
 	},
 
 	{ } /* Terminating entry */
@@ -1118,9 +1121,11 @@
 
 		dev->wq = bridge_wq;
 
+		/*transport name will be set during probe*/
+		dev->name = "none";
+
 		init_usb_anchor(&dev->tx_active);
 		init_usb_anchor(&dev->rx_active);
-		init_usb_anchor(&dev->delayed);
 
 		INIT_LIST_HEAD(&dev->rx_idle);
 
diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c
index f62ae76..f3574d0 100644
--- a/drivers/usb/otg/msm72k_otg.c
+++ b/drivers/usb/otg/msm72k_otg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/usb/serial/csvt.c b/drivers/usb/serial/csvt.c
index 3efdd77..0fee0b5 100644
--- a/drivers/usb/serial/csvt.c
+++ b/drivers/usb/serial/csvt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -28,10 +28,14 @@
 #define CSVT_CTRL_RTS		0x02
 
 /* input control lines*/
-#define CSVT_CTRL_CTS		0x01
+#define CSVT_CTRL_CD		0x01
 #define CSVT_CTRL_DSR		0x02
-#define CSVT_CTRL_RI		0x04
-#define CSVT_CTRL_CD		0x08
+#define CSVT_CTRL_BRK		0x04
+#define CSVT_CTRL_RI		0x08
+
+#define CSVT_CTRL_FRAMING	0x10
+#define CSVT_CTRL_PARITY	0x20
+#define CSVT_CTRL_OVERRUN	0x40
 
 static int debug;
 module_param(debug, int, S_IRUGO | S_IWUSR);
@@ -225,7 +229,7 @@
 		(dev->cbits_tolocal & CSVT_CTRL_DSR ? TIOCM_DSR : 0) |
 		(dev->cbits_tolocal & CSVT_CTRL_RI ? TIOCM_RI : 0) |
 		(dev->cbits_tolocal & CSVT_CTRL_CD ? TIOCM_CD : 0) |
-		(dev->cbits_tolocal & CSVT_CTRL_CTS ? TIOCM_CTS : 0);
+		TIOCM_CTS; /* USB CDC spec did not define CTS control signal */
 	mutex_unlock(&dev->dev_lock);
 
 	dev_dbg(&port->dev, "%s -- %x", __func__, control_state);
@@ -245,15 +249,15 @@
 	dev_dbg(&port->dev, "%s\n", __func__);
 
 	mutex_lock(&dev->dev_lock);
-	if (set & CSVT_CTRL_DTR)
-		dev->cbits_tomdm |= TIOCM_DTR;
-	if (set & CSVT_CTRL_RTS)
-		dev->cbits_tomdm |= TIOCM_RTS;
+	if (set & TIOCM_DTR)
+		dev->cbits_tomdm |= CSVT_CTRL_DTR;
+	if (set & TIOCM_RTS)
+		dev->cbits_tomdm |= CSVT_CTRL_RTS;
 
-	if (clear & CSVT_CTRL_DTR)
-		dev->cbits_tomdm &= ~TIOCM_DTR;
-	if (clear & CSVT_CTRL_RTS)
-		dev->cbits_tomdm &= ~TIOCM_RTS;
+	if (clear & TIOCM_DTR)
+		dev->cbits_tomdm &= ~CSVT_CTRL_DTR;
+	if (clear & TIOCM_RTS)
+		dev->cbits_tomdm &= ~CSVT_CTRL_RTS;
 	mutex_unlock(&dev->dev_lock);
 
 	return csvt_ctrl_write_cmd(dev, port);
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index a749a6d..fd6c48d 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -1,7 +1,7 @@
 /*
  * Qualcomm Serial USB driver
  *
- *	Copyright (c) 2008, 2012 Code Aurora Forum. All rights reserved.
+ *	Copyright (c) 2008, 2012 The Linux Foundation. All rights reserved.
  *	Copyright (c) 2009 Greg Kroah-Hartman <gregkh@suse.de>
  *	Copyright (c) 2009 Novell Inc.
  *
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 0d05e2f..ebe8c6e 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -379,7 +379,7 @@
 		list_add_tail(&urb->urb_list, &portdata->in_urb_list);
 		spin_unlock_irqrestore(&portdata->in_lock, flags);
 
-		schedule_work(&portdata->in_work);
+		queue_work(system_nrt_wq, &portdata->in_work);
 
 		return;
 	}
@@ -498,7 +498,7 @@
 	port->throttle_req = false;
 	port->throttled = false;
 
-	schedule_work(&portdata->in_work);
+	queue_work(system_nrt_wq, &portdata->in_work);
 }
 EXPORT_SYMBOL(usb_wwan_unthrottle);
 
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index 1c16071..a676ed7 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -216,6 +216,10 @@
 	bool
 	select FB_MSM_MIPI_DSI
 
+config FB_MSM_MIPI_DSI_NT35590
+	bool
+	select FB_MSM_MIPI_DSI
+
 config FB_MSM_MIPI_DSI_TC358764_DSI2LVDS
 	bool
 	select FB_MSM_MIPI_DSI
@@ -382,6 +386,15 @@
         select FB_MSM_MIPI_DSI_NT35516
         default n
 
+config FB_MSM_MIPI_NT35590_CMD_720P_PT
+        bool
+        select FB_MSM_MIPI_DSI_NT35590
+        default n
+
+config FB_MSM_MIPI_NT35590_VIDEO_720P_PT
+        bool
+        select FB_MSM_MIPI_DSI_NT35590
+        default n
 
 config FB_MSM_MIPI_CHIMEI_WXGA
 	bool "LVDS Chimei WXGA Panel using Toshiba MIPI DSI-to-LVDS bridge."
@@ -559,6 +572,8 @@
 	select FB_MSM_MIPI_ORISE_CMD_720P_PT
 	select FB_MSM_MIPI_NT35516_VIDEO_QHD_PT
 	select FB_MSM_MIPI_NT35516_CMD_QHD_PT
+	select FB_MSM_MIPI_NT35590_CMD_720P_PT
+	select FB_MSM_MIPI_NT35590_VIDEO_720P_PT
 	select FB_MSM_MIPI_SIMULATOR_VIDEO
 	select FB_MSM_MIPI_CHIMEI_WXGA
 	select FB_MSM_MIPI_CHIMEI_WUXGA
@@ -599,6 +614,8 @@
 	select FB_MSM_MIPI_NT35510_CMD_WVGA_PT
 	select FB_MSM_MIPI_NT35516_VIDEO_QHD_PT
 	select FM_MSM_MIPI_NT35516_CMD_QHD_PT
+	select FM_MSM_MIPI_NT35590_CMD_720P_PT
+	select FM_MSM_MIPI_NT35590_VIDEO_720P_PT
 	select FB_MSM_MIPI_SIMULATOR_VIDEO
 	---help---
 	  Support for LCDC + MIPI panel auto detect
@@ -607,6 +624,7 @@
 	bool "LVDS + MIPI Panel Auto Detect"
 	select FB_MSM_LVDS_CHIMEI_WXGA
 	select FB_MSM_LVDS_FRC_FHD
+	select FB_MSM_MIPI_NT35590_VIDEO_720P_PT
 	select FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
 	select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
 	select FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA
@@ -617,6 +635,7 @@
 	select FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
 	select FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT
 	select FB_MSM_MIPI_NT35510_CMD_WVGA_PT
+	select FB_MSM_MIPI_NT35590_CMD_720P_PT
 	select FB_MSM_MIPI_ORISE_VIDEO_720P_PT
 	select FB_MSM_MIPI_ORISE_CMD_720P_PT
 	select FB_MSM_MIPI_SIMULATOR_VIDEO
@@ -723,6 +742,24 @@
         bool "MIPI NT35516 Command qHD PT Panel"
         select FB_MSM_MIPI_NT35516_CMD_QHD_PT
 
+config FB_MSM_MIPI_NT35590_CMD_720P_PT_PANEL
+        bool "MIPI NT35590 Command 720p PT Panel"
+        select FB_MSM_MIPI_NT35590_CMD_720P_PT
+	---help---
+	Support for Truly NT35590 panel. This
+	panel supports MIPI DSI interface in
+	Command mode. The panel resolution is
+	720p (720x1280).
+
+config FB_MSM_MIPI_NT35590_VIDEO_720P_PT_PANEL
+        bool "MIPI NT35590 Video 720p PT Panel"
+        select FB_MSM_MIPI_NT35590_VIDEO_720P_PT
+	---help---
+	Support for Truly NT35590 panel. This
+	panel supports MIPI DSI interface in
+	Video mode. The panel resolution is
+	720p (720x1280).
+
 config FB_MSM_MIPI_SIMULATOR_VIDEO_PANEL
 	bool "MIPI Simulator Video Panel"
 	select FB_MSM_MIPI_SIMULATOR_VIDEO
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index e49e2ba..ac9d590 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -82,6 +82,7 @@
 obj-$(CONFIG_FB_MSM_MIPI_DSI_TRULY) += mipi_truly.o
 obj-$(CONFIG_FB_MSM_MIPI_DSI_NT35510) += mipi_NT35510.o
 obj-$(CONFIG_FB_MSM_MIPI_DSI_NT35516) += mipi_truly_tft540960_1_e.o
+obj-$(CONFIG_FB_MSM_MIPI_DSI_NT35590) += mipi_NT35590.o
 obj-$(CONFIG_FB_MSM_MIPI_DSI_SIMULATOR) += mipi_simulator.o
 
 # MIPI Bridge
@@ -125,6 +126,7 @@
 obj-y += mipi_renesas_video_fwvga_pt.o mipi_renesas_cmd_fwvga_pt.o
 obj-y += mipi_NT35510_video_wvga_pt.o mipi_NT35510_cmd_wvga_pt.o
 obj-y += mipi_truly_tft540960_1_e_video_qhd_pt.o mipi_truly_tft540960_1_e_cmd_qhd_pt.o
+obj-y += mipi_NT35590_cmd_720p_pt.o mipi_NT35590_video_720p_pt.o
 obj-y += mipi_chimei_wxga_pt.o
 obj-y += mipi_chimei_wuxga.o
 obj-y += mipi_truly_video_wvga_pt.o
@@ -144,6 +146,8 @@
 obj-$(CONFIG_FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT) += mipi_NT35510_video_wvga_pt.o
 obj-$(CONFIG_FB_MSM_MIPI_NT35516_CMD_QHD_PT) += mipi_truly_tft540960_1_e_cmd_qhd_pt.o
 obj-$(CONFIG_FB_MSM_MIPI_NT35516_VIDEO_QHD_PT) += mipi_truly_tft540960_1_e_video_qhd_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_NT35590_CMD_720P_PT) += mipi_NT35590_cmd_720p_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_NT35590_VIDEO_720P_PT) += mipi_NT35590_video_720p_pt.o
 obj-$(CONFIG_FB_MSM_MIPI_SIMULATOR_VIDEO) += mipi_simulator_video.o
 obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WXGA) += mipi_chimei_wxga_pt.o
 obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WUXGA) += mipi_chimei_wuxga.o
diff --git a/drivers/video/msm/adv7520.c b/drivers/video/msm/adv7520.c
index c2f1c0c..0e83d0f 100644
--- a/drivers/video/msm/adv7520.c
+++ b/drivers/video/msm/adv7520.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010,2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010,2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/ebi2_epson_s1d_qvga.c b/drivers/video/msm/ebi2_epson_s1d_qvga.c
index 8821eab..8db3cf9 100644
--- a/drivers/video/msm/ebi2_epson_s1d_qvga.c
+++ b/drivers/video/msm/ebi2_epson_s1d_qvga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/ebi2_host.c b/drivers/video/msm/ebi2_host.c
index 8ba5506..e4eda7d 100644
--- a/drivers/video/msm/ebi2_host.c
+++ b/drivers/video/msm/ebi2_host.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -260,9 +260,10 @@
 
 	iBuf = &mfd->ibuf;
 
-	invalidate_caches((unsigned long)fbi->screen_base,
-		(unsigned long)info->fix.smem_len,
-		(unsigned long)info->fix.smem_start);
+	if (fbi->screen_base)
+		invalidate_caches((unsigned long)fbi->screen_base,
+				  (unsigned long)info->fix.smem_len,
+				  (unsigned long)info->fix.smem_start);
 
 	pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w,
 			iBuf->dma_h);
diff --git a/drivers/video/msm/ebi2_l2f.c b/drivers/video/msm/ebi2_l2f.c
index 767b802..2e944be 100644
--- a/drivers/video/msm/ebi2_l2f.c
+++ b/drivers/video/msm/ebi2_l2f.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/ebi2_lcd.c b/drivers/video/msm/ebi2_lcd.c
index 966f974..a19763c 100644
--- a/drivers/video/msm/ebi2_lcd.c
+++ b/drivers/video/msm/ebi2_lcd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/ebi2_tmd20.c b/drivers/video/msm/ebi2_tmd20.c
index 280373f..7c7b0ef 100644
--- a/drivers/video/msm/ebi2_tmd20.c
+++ b/drivers/video/msm/ebi2_tmd20.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 565052f..ce79b00 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -100,75 +100,14 @@
 const char *video_format_2string(uint32 format)
 {
 	switch (format) {
-	default:
-#ifdef CONFIG_FB_MSM_HDMI_COMMON
-	case HDMI_VFRMT_640x480p60_4_3:    return " 640x 480 p60  4/3";
-	case HDMI_VFRMT_720x480p60_4_3:    return " 720x 480 p60  4/3";
-	case HDMI_VFRMT_720x480p60_16_9:   return " 720x 480 p60 16/9";
-	case HDMI_VFRMT_1280x720p60_16_9:  return "1280x 720 p60 16/9";
-	case HDMI_VFRMT_1920x1080i60_16_9: return "1920x1080 i60 16/9";
-	case HDMI_VFRMT_1440x480i60_4_3:   return "1440x 480 i60  4/3";
-	case HDMI_VFRMT_1440x480i60_16_9:  return "1440x 480 i60 16/9";
-	case HDMI_VFRMT_1440x240p60_4_3:   return "1440x 240 p60  4/3";
-	case HDMI_VFRMT_1440x240p60_16_9:  return "1440x 240 p60 16/9";
-	case HDMI_VFRMT_2880x480i60_4_3:   return "2880x 480 i60  4/3";
-	case HDMI_VFRMT_2880x480i60_16_9:  return "2880x 480 i60 16/9";
-	case HDMI_VFRMT_2880x240p60_4_3:   return "2880x 240 p60  4/3";
-	case HDMI_VFRMT_2880x240p60_16_9:  return "2880x 240 p60 16/9";
-	case HDMI_VFRMT_1440x480p60_4_3:   return "1440x 480 p60  4/3";
-	case HDMI_VFRMT_1440x480p60_16_9:  return "1440x 480 p60 16/9";
-	case HDMI_VFRMT_1920x1080p60_16_9: return "1920x1080 p60 16/9";
-	case HDMI_VFRMT_720x576p50_4_3:    return " 720x 576 p50  4/3";
-	case HDMI_VFRMT_720x576p50_16_9:   return " 720x 576 p50 16/9";
-	case HDMI_VFRMT_1280x720p50_16_9:  return "1280x 720 p50 16/9";
-	case HDMI_VFRMT_1920x1080i50_16_9: return "1920x1080 i50 16/9";
-	case HDMI_VFRMT_1440x576i50_4_3:   return "1440x 576 i50  4/3";
-	case HDMI_VFRMT_1440x576i50_16_9:  return "1440x 576 i50 16/9";
-	case HDMI_VFRMT_1440x288p50_4_3:   return "1440x 288 p50  4/3";
-	case HDMI_VFRMT_1440x288p50_16_9:  return "1440x 288 p50 16/9";
-	case HDMI_VFRMT_2880x576i50_4_3:   return "2880x 576 i50  4/3";
-	case HDMI_VFRMT_2880x576i50_16_9:  return "2880x 576 i50 16/9";
-	case HDMI_VFRMT_2880x288p50_4_3:   return "2880x 288 p50  4/3";
-	case HDMI_VFRMT_2880x288p50_16_9:  return "2880x 288 p50 16/9";
-	case HDMI_VFRMT_1440x576p50_4_3:   return "1440x 576 p50  4/3";
-	case HDMI_VFRMT_1440x576p50_16_9:  return "1440x 576 p50 16/9";
-	case HDMI_VFRMT_1920x1080p50_16_9: return "1920x1080 p50 16/9";
-	case HDMI_VFRMT_1920x1080p24_16_9: return "1920x1080 p24 16/9";
-	case HDMI_VFRMT_1920x1080p25_16_9: return "1920x1080 p25 16/9";
-	case HDMI_VFRMT_1920x1080p30_16_9: return "1920x1080 p30 16/9";
-	case HDMI_VFRMT_2880x480p60_4_3:   return "2880x 480 p60  4/3";
-	case HDMI_VFRMT_2880x480p60_16_9:  return "2880x 480 p60 16/9";
-	case HDMI_VFRMT_2880x576p50_4_3:   return "2880x 576 p50  4/3";
-	case HDMI_VFRMT_2880x576p50_16_9:  return "2880x 576 p50 16/9";
-	case HDMI_VFRMT_1920x1250i50_16_9: return "1920x1250 i50 16/9";
-	case HDMI_VFRMT_1920x1080i100_16_9:return "1920x1080 i100 16/9";
-	case HDMI_VFRMT_1280x720p100_16_9: return "1280x 720 p100 16/9";
-	case HDMI_VFRMT_720x576p100_4_3:   return " 720x 576 p100  4/3";
-	case HDMI_VFRMT_720x576p100_16_9:  return " 720x 576 p100 16/9";
-	case HDMI_VFRMT_1440x576i100_4_3:  return "1440x 576 i100  4/3";
-	case HDMI_VFRMT_1440x576i100_16_9: return "1440x 576 i100 16/9";
-	case HDMI_VFRMT_1920x1080i120_16_9:return "1920x1080 i120 16/9";
-	case HDMI_VFRMT_1280x720p120_16_9: return "1280x 720 p120 16/9";
-	case HDMI_VFRMT_720x480p120_4_3:   return " 720x 480 p120  4/3";
-	case HDMI_VFRMT_720x480p120_16_9:  return " 720x 480 p120 16/9";
-	case HDMI_VFRMT_1440x480i120_4_3:  return "1440x 480 i120  4/3";
-	case HDMI_VFRMT_1440x480i120_16_9: return "1440x 480 i120 16/9";
-	case HDMI_VFRMT_720x576p200_4_3:   return " 720x 576 p200  4/3";
-	case HDMI_VFRMT_720x576p200_16_9:  return " 720x 576 p200 16/9";
-	case HDMI_VFRMT_1440x576i200_4_3:  return "1440x 576 i200  4/3";
-	case HDMI_VFRMT_1440x576i200_16_9: return "1440x 576 i200 16/9";
-	case HDMI_VFRMT_720x480p240_4_3:   return " 720x 480 p240  4/3";
-	case HDMI_VFRMT_720x480p240_16_9:  return " 720x 480 p240 16/9";
-	case HDMI_VFRMT_1440x480i240_4_3:  return "1440x 480 i240  4/3";
-	case HDMI_VFRMT_1440x480i240_16_9: return "1440x 480 i240 16/9";
-#elif defined(CONFIG_FB_MSM_TVOUT)
+#if defined(CONFIG_FB_MSM_TVOUT)
 	case TVOUT_VFRMT_NTSC_M_720x480i:     return "NTSC_M_720x480i";
 	case TVOUT_VFRMT_NTSC_J_720x480i:     return "NTSC_J_720x480i";
 	case TVOUT_VFRMT_PAL_BDGHIN_720x576i: return "PAL_BDGHIN_720x576i";
 	case TVOUT_VFRMT_PAL_M_720x480i:      return "PAL_M_720x480i";
 	case TVOUT_VFRMT_PAL_N_720x480i:      return "PAL_N_720x480i";
 #endif
-
+	default: return "???";
 	}
 }
 EXPORT_SYMBOL(video_format_2string);
@@ -177,84 +116,23 @@
 	struct device_attribute *attr, char *buf)
 {
 	ssize_t ret = snprintf(buf, PAGE_SIZE, "%s\n",
-		video_format_2string(external_common_state->video_resolution));
+		msm_hdmi_mode_2string(external_common_state->video_resolution));
 	DEV_DBG("%s: '%s'\n", __func__,
-		video_format_2string(external_common_state->video_resolution));
+		msm_hdmi_mode_2string(external_common_state->video_resolution));
 	return ret;
 }
 
 #ifdef CONFIG_FB_MSM_HDMI_COMMON
-struct hdmi_disp_mode_timing_type
-	hdmi_common_supported_video_mode_lut[HDMI_VFRMT_MAX] = {
-	HDMI_SETTINGS_640x480p60_4_3,
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p60_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p60_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p60_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i60_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i60_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i60_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x240p60_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x240p60_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480i60_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480i60_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x240p60_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x240p60_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480p60_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480p60_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p60_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p50_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p50_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p50_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i50_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i50_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i50_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x288p50_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x288p50_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576i50_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576i50_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x288p50_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x288p50_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576p50_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576p50_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p50_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p24_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p25_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p30_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480p60_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480p60_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576p50_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576p50_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1250i50_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i100_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p100_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p100_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p100_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i100_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i100_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i120_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p120_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p120_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p120_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i120_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i120_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p200_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p200_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i200_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i200_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p240_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p240_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_4_3),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_16_9),
-	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x1024p60_5_4)
-};
+struct msm_hdmi_mode_timing_info
+	hdmi_common_supported_video_mode_lut[HDMI_VFRMT_MAX];
 EXPORT_SYMBOL(hdmi_common_supported_video_mode_lut);
 
-struct hdmi_disp_mode_timing_type
+struct msm_hdmi_mode_timing_info
 	hdmi_mhl_supported_video_mode_lut[HDMI_VFRMT_MAX] = {
-	HDMI_SETTINGS_640x480p60_4_3,
+	HDMI_VFRMT_640x480p60_4_3_TIMING,
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p60_4_3),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p60_16_9),
-	HDMI_SETTINGS_1280x720p60_16_9,
+	HDMI_VFRMT_1280x720p60_16_9_TIMING,
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i60_16_9),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i60_4_3),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i60_16_9),
@@ -282,9 +160,9 @@
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576p50_4_3),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576p50_16_9),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p50_16_9),
-	HDMI_SETTINGS_1920x1080p24_16_9,
-	HDMI_SETTINGS_1920x1080p25_16_9,
-	HDMI_SETTINGS_1920x1080p30_16_9,
+	HDMI_VFRMT_1920x1080p24_16_9_TIMING,
+	HDMI_VFRMT_1920x1080p25_16_9_TIMING,
+	HDMI_VFRMT_1920x1080p30_16_9_TIMING,
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480p60_4_3),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480p60_16_9),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576p50_4_3),
@@ -310,7 +188,7 @@
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p240_16_9),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_4_3),
 	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_16_9),
-	HDMI_SETTINGS_1280x1024p60_5_4
+	HDMI_VFRMT_1280x1024p60_5_4_TIMING
 };
 EXPORT_SYMBOL(hdmi_mhl_supported_video_mode_lut);
 
@@ -328,10 +206,10 @@
 			.num_of_elements; ++i) {
 			if (ret > 0)
 				ret += snprintf(buf+ret, PAGE_SIZE-ret, ",%d",
-					*video_mode++ + 1);
+					*video_mode++);
 			else
 				ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d",
-					*video_mode++ + 1);
+					*video_mode++);
 		}
 	} else
 		ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d",
@@ -764,7 +642,7 @@
 	ssize_t ret = strnlen(buf, PAGE_SIZE);
 	uint32 video_mode;
 #ifdef CONFIG_FB_MSM_HDMI_COMMON
-	const struct hdmi_disp_mode_timing_type *disp_mode;
+	const struct msm_hdmi_mode_timing_info *disp_mode;
 #endif
 	mutex_lock(&external_common_state_hpd_mutex);
 	if (!external_common_state->hpd_state) {
@@ -775,7 +653,7 @@
 	}
 	mutex_unlock(&external_common_state_hpd_mutex);
 
-	video_mode = atoi(buf)-1;
+	video_mode = atoi(buf);
 	DEV_INFO("%s: video_mode is %d\n", __func__, video_mode);
 	kobject_uevent(external_common_state->uevent_kobj, KOBJ_OFFLINE);
 #ifdef CONFIG_FB_MSM_HDMI_COMMON
@@ -791,7 +669,7 @@
 	external_common_state->video_resolution = video_mode;
 #endif
 	DEV_DBG("%s: 'mode=%d %s' successful (sending OFF/ONLINE)\n", __func__,
-		video_mode, video_format_2string(video_mode));
+		video_mode, msm_hdmi_mode_2string(video_mode));
 	kobject_uevent(external_common_state->uevent_kobj, KOBJ_ONLINE);
 	return ret;
 }
@@ -886,7 +764,7 @@
 	return ret;
 }
 
-static DEVICE_ATTR(video_mode, S_IRUGO | S_IWUGO,
+static DEVICE_ATTR(video_mode, S_IRUGO | S_IWUSR | S_IWGRP,
 	external_common_rda_video_mode, external_common_wta_video_mode);
 static DEVICE_ATTR(video_mode_str, S_IRUGO, external_common_rda_video_mode_str,
 	NULL);
@@ -894,7 +772,7 @@
 static DEVICE_ATTR(hdmi_mode, S_IRUGO, external_common_rda_hdmi_mode, NULL);
 #ifdef CONFIG_FB_MSM_HDMI_COMMON
 static DEVICE_ATTR(edid_modes, S_IRUGO, hdmi_common_rda_edid_modes, NULL);
-static DEVICE_ATTR(hpd, S_IRUGO | S_IWUGO, hdmi_common_rda_hpd,
+static DEVICE_ATTR(hpd, S_IRUGO | S_IWUSR | S_IWGRP, hdmi_common_rda_hpd,
 	hdmi_common_wta_hpd);
 static DEVICE_ATTR(hdcp, S_IRUGO, hdmi_common_rda_hdcp, NULL);
 static DEVICE_ATTR(pa, S_IRUGO,
@@ -912,8 +790,8 @@
 static DEVICE_ATTR(hdcp_present, S_IRUGO, hdmi_common_rda_hdcp_present, NULL);
 #endif
 #ifdef CONFIG_FB_MSM_HDMI_3D
-static DEVICE_ATTR(format_3d, S_IRUGO | S_IWUGO, hdmi_3d_rda_format_3d,
-	hdmi_3d_wta_format_3d);
+static DEVICE_ATTR(format_3d, S_IRUGO | S_IWUSR | S_IWGRP,
+	hdmi_3d_rda_format_3d, hdmi_3d_wta_format_3d);
 #endif
 static DEVICE_ATTR(hdmi_primary, S_IRUGO, hdmi_common_rda_hdmi_primary, NULL);
 static DEVICE_ATTR(audio_data_block, S_IRUGO, hdmi_common_rda_audio_data_block,
@@ -1492,7 +1370,7 @@
 	struct hdmi_disp_mode_list_type *disp_mode_list,
 	uint32 video_format)
 {
-	const struct hdmi_disp_mode_timing_type *timing;
+	const struct msm_hdmi_mode_timing_info *timing;
 	boolean supported = false;
 	boolean mhl_supported = true;
 	limit_supported_video_format(&video_format);
@@ -1503,15 +1381,16 @@
 	timing = hdmi_common_get_supported_mode(video_format);
 	supported = timing != NULL;
 	DEV_DBG("EDID: format: %d [%s], %s\n",
-		video_format, video_format_2string(video_format),
+		video_format, msm_hdmi_mode_2string(video_format),
 		supported ? "Supported" : "Not-Supported");
 
 	if (mhl_is_connected()) {
-		const struct hdmi_disp_mode_timing_type *mhl_timing =
+		const struct msm_hdmi_mode_timing_info *mhl_timing =
 			hdmi_mhl_get_supported_mode(video_format);
 		mhl_supported = mhl_timing != NULL;
 		DEV_DBG("EDID: format: %d [%s], %s by MHL\n",
-			video_format, video_format_2string(video_format),
+			video_format,
+			msm_hdmi_mode_2string(video_format),
 			mhl_supported ? "Supported" : "Not-Supported");
 	}
 
@@ -1521,8 +1400,7 @@
 		if (video_format == external_common_state->video_resolution) {
 			DEV_DBG("%s: Default resolution %d [%s] supported\n",
 					__func__, video_format,
-					video_format_2string(video_format));
-			external_common_state->default_res_supported = true;
+					msm_hdmi_mode_2string(video_format));
 		}
 	}
 }
@@ -1585,7 +1463,7 @@
 	}
 	video_3d_format_2string(video_3d_format, string);
 	DEV_DBG("EDID[3D]: format: %d [%s], %s %s\n",
-		video_format, video_format_2string(video_format),
+		video_format, msm_hdmi_mode_2string(video_format),
 		string, added ? "added" : "NOT added");
 }
 
@@ -1739,7 +1617,7 @@
 			/* Subtract 1 because it is zero based in the driver,
 			 * while the Video identification code is 1 based in the
 			 * CEA_861D spec */
-			video_format = (*svd & 0x7F) - 1;
+			video_format = (*svd & 0x7F);
 			add_supported_video_format(disp_mode_list,
 				video_format);
 			/* Make a note of the preferred video format */
@@ -1781,7 +1659,7 @@
 				&video_format);
 			DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n",
 				__func__, __LINE__,
-				video_format_2string(video_format));
+				msm_hdmi_mode_2string(video_format));
 			add_supported_video_format(disp_mode_list,
 				video_format);
 			if (video_format == HDMI_VFRMT_640x480p60_4_3)
@@ -1806,7 +1684,7 @@
 				&video_format);
 			DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n",
 				__func__, __LINE__,
-				video_format_2string(video_format));
+				msm_hdmi_mode_2string(video_format));
 			add_supported_video_format(disp_mode_list,
 				video_format);
 			if (video_format == HDMI_VFRMT_640x480p60_4_3)
@@ -1834,7 +1712,7 @@
 				&video_format);
 			DEV_DBG("[%s:%d] Block-1 Adding vid fmt = [%s]\n",
 				__func__, __LINE__,
-				video_format_2string(video_format));
+				msm_hdmi_mode_2string(video_format));
 			add_supported_video_format(disp_mode_list,
 				video_format);
 			if (video_format == HDMI_VFRMT_640x480p60_4_3)
@@ -2026,7 +1904,6 @@
 		sizeof(external_common_state->spkr_alloc_data_block));
 	external_common_state->adb_size = 0;
 	external_common_state->sadb_size = 0;
-	external_common_state->default_res_supported = false;
 
 	status = hdmi_common_read_edid_block(0, edid_buf);
 	if (status || !check_edid_header(edid_buf)) {
@@ -2132,7 +2009,6 @@
 	external_common_state->disp_mode_list.num_of_elements = 1;
 	external_common_state->disp_mode_list.disp_mode_list[0] =
 		external_common_state->video_resolution;
-	external_common_state->default_res_supported = true;
 	return status;
 }
 EXPORT_SYMBOL(hdmi_common_read_edid);
@@ -2146,10 +2022,10 @@
 	userformat = var->reserved[3] >> 16;
 
 	if (userformat) {
-		format = userformat-1;
+		format = userformat;
 		DEV_DBG("reserved format is %d\n", format);
 	} else if (hdmi_prim_resolution) {
-		format = hdmi_prim_resolution - 1;
+		format = hdmi_prim_resolution;
 	} else {
 		DEV_DBG("detecting resolution from %dx%d use top 2 bytes of"
 			" var->reserved[3] to specify mode", mfd->var_xres,
@@ -2167,7 +2043,7 @@
 		case 1280:
 			if (mfd->var_yres == 1024)
 				format = HDMI_VFRMT_1280x1024p60_5_4;
-			else if (mfd->var_frame_rate == 50000)
+			else if (mfd->var_frame_rate == 50)
 				format = HDMI_VFRMT_1280x720p50_16_9;
 			else
 				format = HDMI_VFRMT_1280x720p60_16_9;
@@ -2183,13 +2059,13 @@
 			if (mfd->var_yres == 540) {/* interlaced */
 				format = HDMI_VFRMT_1920x1080i60_16_9;
 			} else if (mfd->var_yres == 1080) {
-				if (mfd->var_frame_rate == 50000)
+				if (mfd->var_frame_rate == 50)
 					format = HDMI_VFRMT_1920x1080p50_16_9;
-				else if (mfd->var_frame_rate == 24000)
+				else if (mfd->var_frame_rate == 24)
 					format = HDMI_VFRMT_1920x1080p24_16_9;
-				else if (mfd->var_frame_rate == 25000)
+				else if (mfd->var_frame_rate == 25)
 					format = HDMI_VFRMT_1920x1080p25_16_9;
-				else if (mfd->var_frame_rate == 30000)
+				else if (mfd->var_frame_rate == 30)
 					format = HDMI_VFRMT_1920x1080p30_16_9;
 				else
 					format = HDMI_VFRMT_1920x1080p60_16_9;
@@ -2200,18 +2076,18 @@
 
 	changed = external_common_state->video_resolution != format;
 	if (external_common_state->video_resolution != format)
-		DEV_DBG("switching %s => %s", video_format_2string(
+		DEV_DBG("switching %s => %s", msm_hdmi_mode_2string(
 			external_common_state->video_resolution),
-			video_format_2string(format));
+			msm_hdmi_mode_2string(format));
 	else
-		DEV_DBG("resolution %s", video_format_2string(
+		DEV_DBG("resolution %s", msm_hdmi_mode_2string(
 			external_common_state->video_resolution));
 	external_common_state->video_resolution = format;
 	return changed;
 }
 EXPORT_SYMBOL(hdmi_common_get_video_format_from_drv_data);
 
-const struct hdmi_disp_mode_timing_type *hdmi_common_get_mode(uint32 mode)
+const struct msm_hdmi_mode_timing_info *hdmi_common_get_mode(uint32 mode)
 {
 	if (mode >= HDMI_VFRMT_MAX)
 		return NULL;
@@ -2220,10 +2096,10 @@
 }
 EXPORT_SYMBOL(hdmi_common_get_mode);
 
-const struct hdmi_disp_mode_timing_type *hdmi_common_get_supported_mode(
+const struct msm_hdmi_mode_timing_info *hdmi_common_get_supported_mode(
 	uint32 mode)
 {
-	const struct hdmi_disp_mode_timing_type *ret
+	const struct msm_hdmi_mode_timing_info *ret
 		= hdmi_common_get_mode(mode);
 
 	if (ret == NULL || !ret->supported)
@@ -2232,7 +2108,7 @@
 }
 EXPORT_SYMBOL(hdmi_common_get_supported_mode);
 
-const struct hdmi_disp_mode_timing_type *hdmi_mhl_get_mode(uint32 mode)
+const struct msm_hdmi_mode_timing_info *hdmi_mhl_get_mode(uint32 mode)
 {
 	if (mode >= HDMI_VFRMT_MAX)
 		return NULL;
@@ -2241,10 +2117,10 @@
 }
 EXPORT_SYMBOL(hdmi_mhl_get_mode);
 
-const struct hdmi_disp_mode_timing_type *hdmi_mhl_get_supported_mode(
+const struct msm_hdmi_mode_timing_info *hdmi_mhl_get_supported_mode(
 	uint32 mode)
 {
-	const struct hdmi_disp_mode_timing_type *ret
+	const struct msm_hdmi_mode_timing_info *ret
 		= hdmi_mhl_get_mode(mode);
 
 	if (ret == NULL || !ret->supported)
@@ -2255,7 +2131,7 @@
 
 void hdmi_common_init_panel_info(struct msm_panel_info *pinfo)
 {
-	const struct hdmi_disp_mode_timing_type *timing =
+	const struct msm_hdmi_mode_timing_info *timing =
 		hdmi_common_get_supported_mode(
 		external_common_state->video_resolution);
 
@@ -2265,7 +2141,7 @@
 	pinfo->xres = timing->active_h;
 	pinfo->yres = timing->active_v;
 	pinfo->clk_rate = timing->pixel_freq*1000;
-	pinfo->frame_rate = 60;
+	pinfo->frame_rate = timing->refresh_rate/1000;
 
 	pinfo->lcdc.h_back_porch = timing->back_porch_h;
 	pinfo->lcdc.h_front_porch = timing->front_porch_h;
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
index d8760a0..2c4a9ad 100644
--- a/drivers/video/msm/external_common.h
+++ b/drivers/video/msm/external_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -13,6 +13,7 @@
 #ifndef __EXTERNAL_COMMON_H__
 #define __EXTERNAL_COMMON_H__
 #include <linux/switch.h>
+#include <video/msm_hdmi_modes.h>
 
 #ifdef DEBUG
 #ifndef DEV_DBG_PREFIX
@@ -26,183 +27,13 @@
 #define DEV_WARN(args...)	dev_warn(external_common_state->dev, args)
 #define DEV_ERR(args...)	dev_err(external_common_state->dev, args)
 
-#ifdef CONFIG_FB_MSM_TVOUT
-#define TVOUT_VFRMT_NTSC_M_720x480i		0
-#define TVOUT_VFRMT_NTSC_J_720x480i		1
-#define TVOUT_VFRMT_PAL_BDGHIN_720x576i		2
-#define TVOUT_VFRMT_PAL_M_720x480i		3
-#define TVOUT_VFRMT_PAL_N_720x480i		4
-#elif defined(CONFIG_FB_MSM_HDMI_COMMON)
-/* all video formats defined by EIA CEA 861D */
-#define HDMI_VFRMT_640x480p60_4_3	0
-#define HDMI_VFRMT_720x480p60_4_3	1
-#define HDMI_VFRMT_720x480p60_16_9	2
-#define HDMI_VFRMT_1280x720p60_16_9	3
-#define HDMI_VFRMT_1920x1080i60_16_9	4
-#define HDMI_VFRMT_720x480i60_4_3	5
-#define HDMI_VFRMT_1440x480i60_4_3	HDMI_VFRMT_720x480i60_4_3
-#define HDMI_VFRMT_720x480i60_16_9	6
-#define HDMI_VFRMT_1440x480i60_16_9	HDMI_VFRMT_720x480i60_16_9
-#define HDMI_VFRMT_720x240p60_4_3	7
-#define HDMI_VFRMT_1440x240p60_4_3	HDMI_VFRMT_720x240p60_4_3
-#define HDMI_VFRMT_720x240p60_16_9	8
-#define HDMI_VFRMT_1440x240p60_16_9	HDMI_VFRMT_720x240p60_16_9
-#define HDMI_VFRMT_2880x480i60_4_3	9
-#define HDMI_VFRMT_2880x480i60_16_9	10
-#define HDMI_VFRMT_2880x240p60_4_3	11
-#define HDMI_VFRMT_2880x240p60_16_9	12
-#define HDMI_VFRMT_1440x480p60_4_3	13
-#define HDMI_VFRMT_1440x480p60_16_9	14
-#define HDMI_VFRMT_1920x1080p60_16_9	15
-#define HDMI_VFRMT_720x576p50_4_3	16
-#define HDMI_VFRMT_720x576p50_16_9	17
-#define HDMI_VFRMT_1280x720p50_16_9	18
-#define HDMI_VFRMT_1920x1080i50_16_9	19
-#define HDMI_VFRMT_720x576i50_4_3	20
-#define HDMI_VFRMT_1440x576i50_4_3	HDMI_VFRMT_720x576i50_4_3
-#define HDMI_VFRMT_720x576i50_16_9	21
-#define HDMI_VFRMT_1440x576i50_16_9	HDMI_VFRMT_720x576i50_16_9
-#define HDMI_VFRMT_720x288p50_4_3	22
-#define HDMI_VFRMT_1440x288p50_4_3	HDMI_VFRMT_720x288p50_4_3
-#define HDMI_VFRMT_720x288p50_16_9	23
-#define HDMI_VFRMT_1440x288p50_16_9	HDMI_VFRMT_720x288p50_16_9
-#define HDMI_VFRMT_2880x576i50_4_3	24
-#define HDMI_VFRMT_2880x576i50_16_9	25
-#define HDMI_VFRMT_2880x288p50_4_3	26
-#define HDMI_VFRMT_2880x288p50_16_9	27
-#define HDMI_VFRMT_1440x576p50_4_3	28
-#define HDMI_VFRMT_1440x576p50_16_9	29
-#define HDMI_VFRMT_1920x1080p50_16_9	30
-#define HDMI_VFRMT_1920x1080p24_16_9	31
-#define HDMI_VFRMT_1920x1080p25_16_9	32
-#define HDMI_VFRMT_1920x1080p30_16_9	33
-#define HDMI_VFRMT_2880x480p60_4_3	34
-#define HDMI_VFRMT_2880x480p60_16_9	35
-#define HDMI_VFRMT_2880x576p50_4_3	36
-#define HDMI_VFRMT_2880x576p50_16_9	37
-#define HDMI_VFRMT_1920x1250i50_16_9	38
-#define HDMI_VFRMT_1920x1080i100_16_9	39
-#define HDMI_VFRMT_1280x720p100_16_9	40
-#define HDMI_VFRMT_720x576p100_4_3	41
-#define HDMI_VFRMT_720x576p100_16_9	42
-#define HDMI_VFRMT_720x576i100_4_3	43
-#define HDMI_VFRMT_1440x576i100_4_3	HDMI_VFRMT_720x576i100_4_3
-#define HDMI_VFRMT_720x576i100_16_9	44
-#define HDMI_VFRMT_1440x576i100_16_9	HDMI_VFRMT_720x576i100_16_9
-#define HDMI_VFRMT_1920x1080i120_16_9	45
-#define HDMI_VFRMT_1280x720p120_16_9	46
-#define HDMI_VFRMT_720x480p120_4_3	47
-#define HDMI_VFRMT_720x480p120_16_9	48
-#define HDMI_VFRMT_720x480i120_4_3	49
-#define HDMI_VFRMT_1440x480i120_4_3	HDMI_VFRMT_720x480i120_4_3
-#define HDMI_VFRMT_720x480i120_16_9	50
-#define HDMI_VFRMT_1440x480i120_16_9	HDMI_VFRMT_720x480i120_16_9
-#define HDMI_VFRMT_720x576p200_4_3	51
-#define HDMI_VFRMT_720x576p200_16_9	52
-#define HDMI_VFRMT_720x576i200_4_3	53
-#define HDMI_VFRMT_1440x576i200_4_3	HDMI_VFRMT_720x576i200_4_3
-#define HDMI_VFRMT_720x576i200_16_9	54
-#define HDMI_VFRMT_1440x576i200_16_9	HDMI_VFRMT_720x576i200_16_9
-#define HDMI_VFRMT_720x480p240_4_3	55
-#define HDMI_VFRMT_720x480p240_16_9	56
-#define HDMI_VFRMT_720x480i240_4_3	57
-#define HDMI_VFRMT_1440x480i240_4_3	HDMI_VFRMT_720x480i240_4_3
-#define HDMI_VFRMT_720x480i240_16_9	58
-#define HDMI_VFRMT_1440x480i240_16_9	HDMI_VFRMT_720x480i240_16_9
-#define HDMI_VFRMT_FORCE_32BIT		0x7FFFFFFF
-
-/* Video Identification Codes from 65-127 are reserved for the future */
-#define HDMI_VFRMT_END			127
-
-/* VESA DMT TIMINGS */
-/* DMT ID: 23h, STD code: (81h, 80h), also a part of Established Timing III */
-#define HDMI_VFRMT_1280x1024p60_5_4	(HDMI_VFRMT_END + 1)
-#define DMT_VFRMT_END                   HDMI_VFRMT_1280x1024p60_5_4
-
-#define HDMI_VFRMT_MAX	                (DMT_VFRMT_END + 1)
-
-
+#if defined(CONFIG_FB_MSM_HDMI_COMMON)
 extern int ext_resolution;
 
-struct hdmi_disp_mode_timing_type {
-	uint32	video_format;
-	uint32	active_h;
-	uint32	front_porch_h;
-	uint32	pulse_width_h;
-	uint32	back_porch_h;
-	boolean	active_low_h;
-	uint32	active_v;
-	uint32	front_porch_v;
-	uint32	pulse_width_v;
-	uint32	back_porch_v;
-	boolean	active_low_v;
-	/* Must divide by 1000 to get the actual frequency in MHZ */
-	uint32	pixel_freq;
-	/* Must divide by 1000 to get the actual frequency in HZ */
-	uint32	refresh_rate;
-	boolean	interlaced;
-	boolean	supported;
-};
-
-#define HDMI_SETTINGS_640x480p60_4_3					\
-	{HDMI_VFRMT_640x480p60_4_3,      640,  16,  96,  48,  TRUE,	\
-	 480, 10, 2, 33, TRUE, 25200, 60000, FALSE, TRUE}
-#define HDMI_SETTINGS_720x480p60_4_3					\
-	{HDMI_VFRMT_720x480p60_4_3,      720,  16,  62,  60,  TRUE,	\
-	 480, 9, 6, 30,  TRUE, 27030, 60000, FALSE, TRUE}
-#define HDMI_SETTINGS_720x480p60_16_9					\
-	{HDMI_VFRMT_720x480p60_16_9,     720,  16,  62,  60,  TRUE,	\
-	 480, 9, 6, 30,  TRUE, 27030, 60000, FALSE, TRUE}
-#define HDMI_SETTINGS_1280x720p60_16_9					\
-	{HDMI_VFRMT_1280x720p60_16_9,    1280, 110, 40,  220, FALSE,	\
-	 720, 5, 5, 20, FALSE, 74250, 60000, FALSE, TRUE}
-#define HDMI_SETTINGS_1920x1080i60_16_9					\
-	{HDMI_VFRMT_1920x1080i60_16_9,   1920, 88,  44,  148, FALSE,	\
-	 540, 2, 5, 5, FALSE, 74250, 60000, FALSE, TRUE}
-#define HDMI_SETTINGS_1440x480i60_4_3					\
-	{HDMI_VFRMT_1440x480i60_4_3,     1440, 38,  124, 114, TRUE,	\
-	 240, 4, 3, 15, TRUE, 27000, 60000, TRUE, TRUE}
-#define HDMI_SETTINGS_1440x480i60_16_9					\
-	{HDMI_VFRMT_1440x480i60_16_9,    1440, 38,  124, 114, TRUE,	\
-	 240, 4, 3, 15, TRUE, 27000, 60000, TRUE, TRUE}
-#define HDMI_SETTINGS_1920x1080p60_16_9					\
-	{HDMI_VFRMT_1920x1080p60_16_9,   1920, 88,  44,  148,  FALSE,	\
-	 1080, 4, 5, 36, FALSE, 148500, 60000, FALSE, TRUE}
-#define HDMI_SETTINGS_720x576p50_4_3					\
-	{HDMI_VFRMT_720x576p50_4_3,      720,  12,  64,  68,   TRUE,	\
-	 576,  5, 5, 39, TRUE, 27000, 50000, FALSE, TRUE}
-#define HDMI_SETTINGS_720x576p50_16_9					\
-	{HDMI_VFRMT_720x576p50_16_9,     720,  12,  64,  68,   TRUE,	\
-	 576,  5, 5, 39, TRUE, 27000, 50000, FALSE, TRUE}
-#define HDMI_SETTINGS_1280x720p50_16_9					\
-	{HDMI_VFRMT_1280x720p50_16_9,    1280, 440, 40,  220,  FALSE,	\
-	 720,  5, 5, 20, FALSE, 74250, 50000, FALSE, TRUE}
-#define HDMI_SETTINGS_1440x576i50_4_3					\
-	{HDMI_VFRMT_1440x576i50_4_3,     1440, 24,  126, 138,  TRUE,	\
-	 288,  2, 3, 19, TRUE, 27000, 50000, TRUE, TRUE}
-#define HDMI_SETTINGS_1440x576i50_16_9					\
-	{HDMI_VFRMT_1440x576i50_16_9,    1440, 24,  126, 138,  TRUE,	\
-	 288,  2, 3, 19, TRUE, 27000, 50000, TRUE, TRUE}
-#define HDMI_SETTINGS_1920x1080p50_16_9					\
-	{HDMI_VFRMT_1920x1080p50_16_9,   1920,  528,  44,  148,  FALSE,	\
-	 1080, 4, 5, 36, FALSE, 148500, 50000, FALSE, TRUE}
-#define HDMI_SETTINGS_1920x1080p24_16_9					\
-	{HDMI_VFRMT_1920x1080p24_16_9,   1920,  638,  44,  148,  FALSE,	\
-	 1080, 4, 5, 36, FALSE, 74250, 24000, FALSE, TRUE}
-#define HDMI_SETTINGS_1920x1080p25_16_9					\
-	{HDMI_VFRMT_1920x1080p25_16_9,   1920,  528,  44,  148,  FALSE,	\
-	 1080, 4, 5, 36, FALSE, 74250, 25000, FALSE, TRUE}
-#define HDMI_SETTINGS_1920x1080p30_16_9					\
-	{HDMI_VFRMT_1920x1080p30_16_9,   1920,  88,   44,  148,  FALSE,	\
-	 1080, 4, 5, 36, FALSE, 74250, 30000, FALSE, TRUE}
-#define HDMI_SETTINGS_1280x1024p60_5_4					\
-	{HDMI_VFRMT_1280x1024p60_5_4,   1280,  48,  112,  248,  FALSE, \
-	 1024, 1, 3, 38, FALSE, 108000, 60000, FALSE, TRUE}
-
 /* A lookup table for all the supported display modes by the HDMI
  * hardware and driver.  Use HDMI_SETUP_LUT in the module init to
  * setup the LUT with the supported modes. */
-extern struct hdmi_disp_mode_timing_type
+extern struct msm_hdmi_mode_timing_info
 	hdmi_common_supported_video_mode_lut[HDMI_VFRMT_MAX];
 
 /* Structure that encapsulates all the supported display modes by the HDMI sink
@@ -229,9 +60,9 @@
 
 struct external_common_state_type {
 	boolean hpd_state;
+	boolean pre_suspend_hpd_state;
 	struct kobject *uevent_kobj;
 	uint32 video_resolution;
-	boolean default_res_supported;
 	struct device *dev;
 	struct switch_dev sdev;
 	struct switch_dev audio_sdev;
@@ -269,23 +100,14 @@
 extern struct mutex hdmi_msm_state_mutex;
 
 #ifdef CONFIG_FB_MSM_HDMI_COMMON
-#define VFRMT_NOT_SUPPORTED(VFRMT) \
-	{VFRMT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FALSE}
-#define HDMI_SETUP_LUT(MODE) do {					\
-		struct hdmi_disp_mode_timing_type mode			\
-			= HDMI_SETTINGS_ ## MODE;			\
-		hdmi_common_supported_video_mode_lut[mode.video_format]	\
-			= mode;						\
-	} while (0)
-
 int hdmi_common_read_edid(void);
 const char *video_format_2string(uint32 format);
 bool hdmi_common_get_video_format_from_drv_data(struct msm_fb_data_type *mfd);
-const struct hdmi_disp_mode_timing_type *hdmi_common_get_mode(uint32 mode);
-const struct hdmi_disp_mode_timing_type *hdmi_common_get_supported_mode(
+const struct msm_hdmi_mode_timing_info *hdmi_common_get_mode(uint32 mode);
+const struct msm_hdmi_mode_timing_info *hdmi_common_get_supported_mode(
 	uint32 mode);
-const struct hdmi_disp_mode_timing_type *hdmi_mhl_get_mode(uint32 mode);
-const struct hdmi_disp_mode_timing_type *hdmi_mhl_get_supported_mode(
+const struct msm_hdmi_mode_timing_info *hdmi_mhl_get_mode(uint32 mode);
+const struct msm_hdmi_mode_timing_info *hdmi_mhl_get_supported_mode(
 	uint32 mode);
 void hdmi_common_init_panel_info(struct msm_panel_info *pinfo);
 
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 1dd43ec..e2b0791 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -631,24 +631,16 @@
 /* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */
 static void hdmi_msm_setup_video_mode_lut(void)
 {
-	HDMI_SETUP_LUT(640x480p60_4_3);
-	HDMI_SETUP_LUT(720x480p60_4_3);
-	HDMI_SETUP_LUT(720x480p60_16_9);
-	HDMI_SETUP_LUT(1280x720p60_16_9);
-	HDMI_SETUP_LUT(1920x1080i60_16_9);
-	HDMI_SETUP_LUT(1440x480i60_4_3);
-	HDMI_SETUP_LUT(1440x480i60_16_9);
-	HDMI_SETUP_LUT(1920x1080p60_16_9);
-	HDMI_SETUP_LUT(720x576p50_4_3);
-	HDMI_SETUP_LUT(720x576p50_16_9);
-	HDMI_SETUP_LUT(1280x720p50_16_9);
-	HDMI_SETUP_LUT(1440x576i50_4_3);
-	HDMI_SETUP_LUT(1440x576i50_16_9);
-	HDMI_SETUP_LUT(1920x1080p50_16_9);
-	HDMI_SETUP_LUT(1920x1080p24_16_9);
-	HDMI_SETUP_LUT(1920x1080p25_16_9);
-	HDMI_SETUP_LUT(1920x1080p30_16_9);
-	HDMI_SETUP_LUT(1280x1024p60_5_4);
+	/* Init video mode timings */
+	MSM_HDMI_MODES_INIT_TIMINGS(hdmi_common_supported_video_mode_lut);
+
+	/* Add all supported CEA modes to the lut */
+	MSM_HDMI_MODES_SET_SUPP_TIMINGS(
+		hdmi_common_supported_video_mode_lut, MSM_HDMI_MODES_CEA);
+
+	/* Add any other supported timings (DVI modes, etc.) */
+	MSM_HDMI_MODES_SET_TIMING(hdmi_common_supported_video_mode_lut,
+		HDMI_VFRMT_1280x1024p60_5_4);
 }
 
 #ifdef PORT_DEBUG
@@ -816,9 +808,6 @@
 		kobject_uevent(external_common_state->uevent_kobj,
 			KOBJ_OFFLINE);
 	}
-
-	if (!completion_done(&hdmi_msm_state->hpd_event_processed))
-		complete(&hdmi_msm_state->hpd_event_processed);
 }
 
 static void hdmi_msm_hpd_state_work(struct work_struct *work)
@@ -3056,7 +3045,7 @@
 	uint32 end_h     = 0;
 	uint32 start_v   = 0;
 	uint32 end_v     = 0;
-	const struct hdmi_disp_mode_timing_type *timing =
+	const struct msm_hdmi_mode_timing_info *timing =
 		hdmi_common_get_supported_mode(video_format);
 
 	/* timing register setup */
@@ -3162,7 +3151,7 @@
 	acr_pck_ctrl_reg &= ~(3 << 4);
 
 	if (enabled) {
-		const struct hdmi_disp_mode_timing_type *timing =
+		const struct msm_hdmi_mode_timing_info *timing =
 			hdmi_common_get_supported_mode(video_format);
 		const struct hdmi_msm_audio_arcs *audio_arc =
 			&hdmi_msm_audio_acr_lut[0];
@@ -3626,31 +3615,45 @@
 
 static uint8 hdmi_msm_avi_iframe_lut[][17] = {
 /*	480p60	480i60	576p50	576i50	720p60	 720p50	1080p60	1080i60	1080p50
-	1080i50	1080p24	1080p30	1080p25	640x480p 480p60_16_9 576p50_4_3 */
+	1080i50	1080p24	1080p30	1080p25	640x480p 480p60_16_9 576p50_4_3 1024p*/
+
+	/* Data Byte 01: 0 Y1 Y0 A0 B1 B0 S1 S0 */
 	{0x10,	0x10,	0x10,	0x10,	0x10,	 0x10,	0x10,	0x10,	0x10,
 	 0x10,	0x10,	0x10,	0x10,	0x10, 0x10, 0x10, 0x10}, /*00*/
+	/* Data Byte 02: C1 C0 M1 M0 R3 R2 R1 R0 */
 	{0x18,	0x18,	0x28,	0x28,	0x28,	 0x28,	0x28,	0x28,	0x28,
 	 0x28,	0x28,	0x28,	0x28,	0x18, 0x28, 0x18, 0x08}, /*01*/
+	/* Data Byte 03: ITC EC2 EC1 EC0 Q1 Q0 SC1 SC0 */
 	{0x00,	0x04,	0x04,	0x04,	0x04,	 0x04,	0x04,	0x04,	0x04,
 	 0x04,	0x04,	0x04,	0x04,	0x88, 0x00, 0x04, 0x04}, /*02*/
-	{0x02,	0x06,	0x11,	0x15,	0x04,	 0x13,	0x10,	0x05,	0x1F,
+	/* Data Byte 04: 0 VIC6 VIC5 VIC4 VIC3 VIC2 VIC1 VIC0 */
+	{0x02,	0x06,	0x12,	0x15,	0x04,	 0x13,	0x10,	0x05,	0x1F,
 	 0x14,	0x20,	0x22,	0x21,	0x01, 0x03, 0x11, 0x00}, /*03*/
+	/* Data Byte 05: 0 0 0 0 PR3 PR2 PR1 PR0 */
 	{0x00,	0x01,	0x00,	0x01,	0x00,	 0x00,	0x00,	0x00,	0x00,
 	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00, 0x00}, /*04*/
+	/* Data Byte 06: LSB Line No of End of Top Bar */
 	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
 	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00, 0x00}, /*05*/
+	/* Data Byte 07: MSB Line No of End of Top Bar */
 	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
 	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00, 0x00}, /*06*/
+	/* Data Byte 08: LSB Line No of Start of Bottom Bar */
 	{0xE1,	0xE1,	0x41,	0x41,	0xD1,	 0xd1,	0x39,	0x39,	0x39,
 	 0x39,	0x39,	0x39,	0x39,	0xe1, 0xE1, 0x41, 0x01}, /*07*/
+	/* Data Byte 09: MSB Line No of Start of Bottom Bar */
 	{0x01,	0x01,	0x02,	0x02,	0x02,	 0x02,	0x04,	0x04,	0x04,
 	 0x04,	0x04,	0x04,	0x04,	0x01, 0x01, 0x02, 0x04}, /*08*/
+	/* Data Byte 10: LSB Pixel Number of End of Left Bar */
 	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
 	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00, 0x00}, /*09*/
+	/* Data Byte 11: MSB Pixel Number of End of Left Bar */
 	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
 	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00, 0x00}, /*10*/
+	/* Data Byte 12: LSB Pixel Number of Start of Right Bar */
 	{0xD1,	0xD1,	0xD1,	0xD1,	0x01,	 0x01,	0x81,	0x81,	0x81,
 	 0x81,	0x81,	0x81,	0x81,	0x81, 0xD1, 0xD1, 0x01}, /*11*/
+	/* Data Byte 13: MSB Pixel Number of Start of Right Bar */
 	{0x02,	0x02,	0x02,	0x02,	0x05,	 0x05,	0x07,	0x07,	0x07,
 	 0x07,	0x07,	0x07,	0x07,	0x02, 0x02, 0x02, 0x05}  /*12*/
 };
@@ -4323,8 +4326,7 @@
 
 static int hdmi_msm_power_ctrl(boolean enable)
 {
-	int rc   = 0;
-	int time = 0;
+	int rc = 0;
 
 	if (enable) {
 		/*
@@ -4335,24 +4337,25 @@
 			external_common_state->hpd_feature_on) {
 			DEV_DBG("%s: Turning HPD ciruitry on\n", __func__);
 
+			if (external_common_state->pre_suspend_hpd_state) {
+				external_common_state->pre_suspend_hpd_state =
+					 false;
+
+				hdmi_msm_send_event(HPD_EVENT_OFFLINE);
+			}
+
 			rc = hdmi_msm_hpd_on();
 			if (rc) {
 				DEV_ERR("%s: HPD ON FAILED\n", __func__);
 				return rc;
 			}
-
-			/* Wait for HPD initialization to complete */
-			INIT_COMPLETION(hdmi_msm_state->hpd_event_processed);
-			time = wait_for_completion_interruptible_timeout(
-				&hdmi_msm_state->hpd_event_processed, HZ);
-			if (!time && !external_common_state->hpd_state) {
-				DEV_DBG("%s: cable not detected\n", __func__);
-				queue_work(hdmi_work_queue,
-				    &hdmi_msm_state->hpd_state_work);
-			}
 		}
 	} else {
 		DEV_DBG("%s: Turning HPD ciruitry off\n", __func__);
+
+		external_common_state->pre_suspend_hpd_state =
+			external_common_state->hpd_state;
+
 		hdmi_msm_hpd_off();
 	}
 
@@ -4363,7 +4366,6 @@
 {
 	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
 	int ret = 0;
-	bool changed;
 
 	if (!hdmi_ready()) {
 		DEV_ERR("%s: HDMI/HPD not initialized\n", __func__);
@@ -4375,44 +4377,37 @@
 		goto error;
 	}
 
-	/* Only start transmission with supported resolution */
-	changed = hdmi_common_get_video_format_from_drv_data(mfd);
-	if (changed || external_common_state->default_res_supported) {
-		mutex_lock(&external_common_state_hpd_mutex);
-		if (external_common_state->hpd_state &&
-				hdmi_msm_is_power_on()) {
-			mutex_unlock(&external_common_state_hpd_mutex);
+	hdmi_common_get_video_format_from_drv_data(mfd);
 
-			DEV_INFO("HDMI cable connected %s(%dx%d, %d)\n",
+	mutex_lock(&external_common_state_hpd_mutex);
+	if (external_common_state->hpd_state && hdmi_msm_is_power_on()) {
+		mutex_unlock(&external_common_state_hpd_mutex);
+
+		DEV_INFO("HDMI cable connected %s(%dx%d, %d)\n",
 				__func__, mfd->var_xres, mfd->var_yres,
 				mfd->var_pixclock);
 
-			hdmi_msm_turn_on();
-			hdmi_msm_state->panel_power_on = TRUE;
+		hdmi_msm_turn_on();
+		hdmi_msm_state->panel_power_on = TRUE;
 
-			if (hdmi_msm_state->hdcp_enable) {
-				/* Kick off HDCP Authentication */
-				mutex_lock(&hdcp_auth_state_mutex);
-				hdmi_msm_state->reauth = FALSE;
-				hdmi_msm_state->full_auth_done = FALSE;
-				mutex_unlock(&hdcp_auth_state_mutex);
-				mod_timer(&hdmi_msm_state->hdcp_timer,
-						jiffies + HZ/2);
-			}
-		} else {
-			mutex_unlock(&external_common_state_hpd_mutex);
+		if (hdmi_msm_state->hdcp_enable) {
+			/* Kick off HDCP Authentication */
+			mutex_lock(&hdcp_auth_state_mutex);
+			hdmi_msm_state->reauth = FALSE;
+			hdmi_msm_state->full_auth_done = FALSE;
+			mutex_unlock(&hdcp_auth_state_mutex);
+			mod_timer(&hdmi_msm_state->hdcp_timer, jiffies + HZ/2);
 		}
-
-		hdmi_msm_dump_regs("HDMI-ON: ");
-		DEV_INFO("power=%s DVI= %s\n",
-			hdmi_msm_is_power_on() ? "ON" : "OFF" ,
-			hdmi_msm_is_dvi_mode() ? "ON" : "OFF");
 	} else {
-		DEV_ERR("%s: Video fmt %d not supp. Returning\n",
-				__func__,
-				external_common_state->video_resolution);
+		mutex_unlock(&external_common_state_hpd_mutex);
 	}
 
+	hdmi_msm_dump_regs("HDMI-ON: ");
+
+	DEV_INFO("power=%s DVI= %s\n",
+		hdmi_msm_is_power_on() ? "ON" : "OFF" ,
+		hdmi_msm_is_dvi_mode() ? "ON" : "OFF");
+
 error:
 	/* Set HPD cable sense polarity */
 	hdmi_msm_hpd_polarity_setup();
@@ -4497,6 +4492,7 @@
 		cancel_work_sync(&hdmi_msm_state->hdcp_reauth_work);
 		cancel_work_sync(&hdmi_msm_state->hdcp_work);
 		del_timer_sync(&hdmi_msm_state->hdcp_timer);
+		hdmi_msm_state->reauth = FALSE;
 
 		hdcp_deauthenticate();
 	}
@@ -4790,8 +4786,6 @@
 		rc = hdmi_msm_hpd_on();
 	} else {
 		if (external_common_state->hpd_state) {
-			external_common_state->hpd_state = 0;
-
 			/* Send offline event to switch OFF HDMI and HAL FD */
 			hdmi_msm_send_event(HPD_EVENT_OFFLINE);
 
@@ -4799,6 +4793,8 @@
 			INIT_COMPLETION(hdmi_msm_state->hpd_event_processed);
 			wait_for_completion_interruptible_timeout(
 				&hdmi_msm_state->hpd_event_processed, HZ);
+
+			external_common_state->hpd_state = 0;
 		}
 
 		hdmi_msm_hpd_off();
diff --git a/drivers/video/msm/hdmi_msm.h b/drivers/video/msm/hdmi_msm.h
index ed8c568..26dbad0 100644
--- a/drivers/video/msm/hdmi_msm.h
+++ b/drivers/video/msm/hdmi_msm.h
@@ -120,7 +120,7 @@
 void hdmi_msm_reset_core(void);
 void hdmi_msm_init_phy(int video_format);
 void hdmi_msm_powerdown_phy(void);
-void hdmi_frame_ctrl_cfg(const struct hdmi_disp_mode_timing_type *timing);
+void hdmi_frame_ctrl_cfg(const struct msm_hdmi_mode_timing_info *timing);
 void hdmi_msm_phy_status_poll(void);
 #endif
 
diff --git a/drivers/video/msm/hdmi_sii9022.c b/drivers/video/msm/hdmi_sii9022.c
index 3d27488..c1b5e03 100644
--- a/drivers/video/msm/hdmi_sii9022.c
+++ b/drivers/video/msm/hdmi_sii9022.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc.c b/drivers/video/msm/lcdc.c
index 1bd4302..24c4ec9 100644
--- a/drivers/video/msm/lcdc.c
+++ b/drivers/video/msm/lcdc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_auo_wvga.c b/drivers/video/msm/lcdc_auo_wvga.c
index 6b0733f..70a28d2 100644
--- a/drivers/video/msm/lcdc_auo_wvga.c
+++ b/drivers/video/msm/lcdc_auo_wvga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_chimei_wxga.c b/drivers/video/msm/lcdc_chimei_wxga.c
index 7453ecb..cab7bb3 100644
--- a/drivers/video/msm/lcdc_chimei_wxga.c
+++ b/drivers/video/msm/lcdc_chimei_wxga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_external.c b/drivers/video/msm/lcdc_external.c
index ca82def..b699610 100644
--- a/drivers/video/msm/lcdc_external.c
+++ b/drivers/video/msm/lcdc_external.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_gordon.c b/drivers/video/msm/lcdc_gordon.c
index b675787..ecb23f0 100644
--- a/drivers/video/msm/lcdc_gordon.c
+++ b/drivers/video/msm/lcdc_gordon.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_nt35582_wvga.c b/drivers/video/msm/lcdc_nt35582_wvga.c
index 9ecf4b9..2152b1a 100644
--- a/drivers/video/msm/lcdc_nt35582_wvga.c
+++ b/drivers/video/msm/lcdc_nt35582_wvga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_panel.c b/drivers/video/msm/lcdc_panel.c
index 5705325..5de2557 100644
--- a/drivers/video/msm/lcdc_panel.c
+++ b/drivers/video/msm/lcdc_panel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_prism.c b/drivers/video/msm/lcdc_prism.c
index d127f63..fb040ca 100644
--- a/drivers/video/msm/lcdc_prism.c
+++ b/drivers/video/msm/lcdc_prism.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_samsung_oled_pt.c b/drivers/video/msm/lcdc_samsung_oled_pt.c
index 16790f3..409496e 100644
--- a/drivers/video/msm/lcdc_samsung_oled_pt.c
+++ b/drivers/video/msm/lcdc_samsung_oled_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_samsung_wsvga.c b/drivers/video/msm/lcdc_samsung_wsvga.c
index 6b35e52..ced8344 100644
--- a/drivers/video/msm/lcdc_samsung_wsvga.c
+++ b/drivers/video/msm/lcdc_samsung_wsvga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_sharp_wvga_pt.c b/drivers/video/msm/lcdc_sharp_wvga_pt.c
index 2ba2618..ee125e2 100644
--- a/drivers/video/msm/lcdc_sharp_wvga_pt.c
+++ b/drivers/video/msm/lcdc_sharp_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_st15.c b/drivers/video/msm/lcdc_st15.c
index cdae358..3effac9 100644
--- a/drivers/video/msm/lcdc_st15.c
+++ b/drivers/video/msm/lcdc_st15.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_toshiba_fwvga_pt.c b/drivers/video/msm/lcdc_toshiba_fwvga_pt.c
index 77606cf..65c6415 100644
--- a/drivers/video/msm/lcdc_toshiba_fwvga_pt.c
+++ b/drivers/video/msm/lcdc_toshiba_fwvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_toshiba_wvga_pt.c b/drivers/video/msm/lcdc_toshiba_wvga_pt.c
index f0aa8f5..30248ff 100644
--- a/drivers/video/msm/lcdc_toshiba_wvga_pt.c
+++ b/drivers/video/msm/lcdc_toshiba_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_truly_ips3p2335.c b/drivers/video/msm/lcdc_truly_ips3p2335.c
index b2f4ab8..89ede49 100644
--- a/drivers/video/msm/lcdc_truly_ips3p2335.c
+++ b/drivers/video/msm/lcdc_truly_ips3p2335.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lcdc_wxga.c b/drivers/video/msm/lcdc_wxga.c
index 3204704..dca57de 100644
--- a/drivers/video/msm/lcdc_wxga.c
+++ b/drivers/video/msm/lcdc_wxga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/logo.c b/drivers/video/msm/logo.c
index 57d754e..7b3cdef 100644
--- a/drivers/video/msm/logo.c
+++ b/drivers/video/msm/logo.c
@@ -82,16 +82,18 @@
 		       __func__, __LINE__, info->node);
 		goto err_logo_free_data;
 	}
-	bits = (unsigned short *)(info->screen_base);
-	while (count > 3) {
-		unsigned n = ptr[0];
-		if (n > max)
-			break;
-		memset16(bits, ptr[1], n << 1);
-		bits += n;
-		max -= n;
-		ptr += 2;
-		count -= 4;
+	if (info->screen_base) {
+		bits = (unsigned short *)(info->screen_base);
+		while (count > 3) {
+			unsigned n = ptr[0];
+			if (n > max)
+				break;
+			memset16(bits, ptr[1], n << 1);
+			bits += n;
+			max -= n;
+			ptr += 2;
+			count -= 4;
+		}
 	}
 
 err_logo_free_data:
diff --git a/drivers/video/msm/lvds.c b/drivers/video/msm/lvds.c
index e9bbceb..53c8041 100644
--- a/drivers/video/msm/lvds.c
+++ b/drivers/video/msm/lvds.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -63,6 +63,7 @@
 static void lvds_init(struct msm_fb_data_type *mfd)
 {
 	unsigned int lvds_intf = 0, lvds_phy_cfg0 = 0;
+	mdp_clk_ctrl(1);
 
 	MDP_OUTP(MDP_BASE + 0xc2034, 0x33);
 	usleep(1000);
@@ -231,6 +232,7 @@
 	usleep(1);
 	/* MDP_LVDSPHY_CFG0, enable serialization */
 	MDP_OUTP(MDP_BASE +  0xc3100, lvds_phy_cfg0);
+	mdp_clk_ctrl(0);
 }
 
 static int lvds_off(struct platform_device *pdev)
@@ -244,9 +246,11 @@
 	if (lvds_clk)
 		clk_disable_unprepare(lvds_clk);
 
+	mdp_clk_ctrl(1);
 	MDP_OUTP(MDP_BASE +  0xc3100, 0x0);
 	MDP_OUTP(MDP_BASE + 0xc3000, 0x0);
 	usleep(10);
+	mdp_clk_ctrl(0);
 
 	if (lvds_pdata && lvds_pdata->lcdc_power_save)
 		lvds_pdata->lcdc_power_save(0);
diff --git a/drivers/video/msm/lvds_chimei_wxga.c b/drivers/video/msm/lvds_chimei_wxga.c
index 39aa852..181ec6a 100644
--- a/drivers/video/msm/lvds_chimei_wxga.c
+++ b/drivers/video/msm/lvds_chimei_wxga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/lvds_frc_fhd.c b/drivers/video/msm/lvds_frc_fhd.c
index 7739588..36d26c5 100644
--- a/drivers/video/msm/lvds_frc_fhd.c
+++ b/drivers/video/msm/lvds_frc_fhd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index b4c1e76..796f67f 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -2,7 +2,7 @@
  * MSM MDDI Transport
  *
  * Copyright (C) 2007 Google Incorporated
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/video/msm/mddi_ext.c b/drivers/video/msm/mddi_ext.c
index dc79fed..83831b0 100644
--- a/drivers/video/msm/mddi_ext.c
+++ b/drivers/video/msm/mddi_ext.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddi_ext_lcd.c b/drivers/video/msm/mddi_ext_lcd.c
index da79513..aa4d484 100644
--- a/drivers/video/msm/mddi_ext_lcd.c
+++ b/drivers/video/msm/mddi_ext_lcd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddi_orise.c b/drivers/video/msm/mddi_orise.c
index fa48c75..bf9f1fa 100644
--- a/drivers/video/msm/mddi_orise.c
+++ b/drivers/video/msm/mddi_orise.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddi_prism.c b/drivers/video/msm/mddi_prism.c
index ec2bf57..c2fa8b9 100644
--- a/drivers/video/msm/mddi_prism.c
+++ b/drivers/video/msm/mddi_prism.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddi_quickvx.c b/drivers/video/msm/mddi_quickvx.c
index 95e7d41..e4b7736 100644
--- a/drivers/video/msm/mddi_quickvx.c
+++ b/drivers/video/msm/mddi_quickvx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddi_sharp.c b/drivers/video/msm/mddi_sharp.c
index 6a9008f..c10d01a 100644
--- a/drivers/video/msm/mddi_sharp.c
+++ b/drivers/video/msm/mddi_sharp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddi_toshiba.c b/drivers/video/msm/mddi_toshiba.c
index 9727453..f06a2fd 100644
--- a/drivers/video/msm/mddi_toshiba.c
+++ b/drivers/video/msm/mddi_toshiba.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddi_toshiba.h b/drivers/video/msm/mddi_toshiba.h
index 646f5e9..854817f 100644
--- a/drivers/video/msm/mddi_toshiba.h
+++ b/drivers/video/msm/mddi_toshiba.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddi_toshiba_vga.c b/drivers/video/msm/mddi_toshiba_vga.c
index 73749f9..3b4a85d 100644
--- a/drivers/video/msm/mddi_toshiba_vga.c
+++ b/drivers/video/msm/mddi_toshiba_vga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddi_toshiba_wvga.c b/drivers/video/msm/mddi_toshiba_wvga.c
index c1925e1..7e7b036 100644
--- a/drivers/video/msm/mddi_toshiba_wvga.c
+++ b/drivers/video/msm/mddi_toshiba_wvga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddi_toshiba_wvga_pt.c b/drivers/video/msm/mddi_toshiba_wvga_pt.c
index 8da1485..bdb04ff 100644
--- a/drivers/video/msm/mddi_toshiba_wvga_pt.c
+++ b/drivers/video/msm/mddi_toshiba_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddihost.c b/drivers/video/msm/mddihost.c
index c6acf9f..c2a7af3 100644
--- a/drivers/video/msm/mddihost.c
+++ b/drivers/video/msm/mddihost.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddihost.h b/drivers/video/msm/mddihost.h
index 52bc67c..db2df38 100644
--- a/drivers/video/msm/mddihost.h
+++ b/drivers/video/msm/mddihost.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddihost_e.c b/drivers/video/msm/mddihost_e.c
index d53aa6f..275e4ee 100644
--- a/drivers/video/msm/mddihost_e.c
+++ b/drivers/video/msm/mddihost_e.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddihosti.c b/drivers/video/msm/mddihosti.c
index 1a5a3fd..b4429f6 100644
--- a/drivers/video/msm/mddihosti.c
+++ b/drivers/video/msm/mddihosti.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mddihosti.h b/drivers/video/msm/mddihosti.h
index 166d15c..96675a0 100644
--- a/drivers/video/msm/mddihosti.h
+++ b/drivers/video/msm/mddihosti.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index ea887dc..5e1e0d8 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -65,9 +65,10 @@
 int mdp_iommu_split_domain;
 u32 mdp_max_clk = 266667000;
 u64 mdp_max_bw = 2000000000;
-
+u32 mdp_bw_ab_factor = MDP4_BW_AB_DEFAULT_FACTOR;
+u32 mdp_bw_ib_factor = MDP4_BW_IB_DEFAULT_FACTOR;
 static struct platform_device *mdp_init_pdev;
-static struct regulator *footswitch;
+static struct regulator *footswitch, *dsi_pll_vdda, *dsi_pll_vddio;
 static unsigned int mdp_footswitch_on;
 
 struct completion mdp_ppp_comp;
@@ -533,7 +534,7 @@
 	return ret;
 }
 
-DEFINE_MUTEX(mdp_lut_push_sem);
+spinlock_t mdp_lut_push_lock;
 static int mdp_lut_i;
 
 static int mdp_lut_hw_update(struct fb_cmap *cmap)
@@ -571,6 +572,7 @@
 static int mdp_lut_update_nonlcdc(struct fb_info *info, struct fb_cmap *cmap)
 {
 	int ret;
+	unsigned long flags;
 
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	mdp_clk_ctrl(1);
@@ -581,11 +583,10 @@
 	if (ret)
 		return ret;
 
-	mutex_lock(&mdp_lut_push_sem);
+	spin_lock_irqsave(&mdp_lut_push_lock, flags);
 	mdp_lut_push = 1;
 	mdp_lut_push_i = mdp_lut_i;
-	mutex_unlock(&mdp_lut_push_sem);
-
+	spin_unlock_irqrestore(&mdp_lut_push_lock, flags);
 	mdp_lut_i = (mdp_lut_i + 1)%2;
 
 	return 0;
@@ -656,13 +657,15 @@
 static void mdp_lut_enable(void)
 {
 	uint32_t out;
+	unsigned long flags;
+
 	if (mdp_lut_push) {
-		mutex_lock(&mdp_lut_push_sem);
+		spin_lock_irqsave(&mdp_lut_push_lock, flags);
 		mdp_lut_push = 0;
 		out = inpdw(MDP_BASE + 0x90070) & ~((0x1 << 10) | 0x7);
 		MDP_OUTP(MDP_BASE + 0x90070,
 				(mdp_lut_push_i << 10) | 0x7 | out);
-		mutex_unlock(&mdp_lut_push_sem);
+		spin_unlock_irqrestore(&mdp_lut_push_lock, flags);
 	}
 }
 
@@ -1642,6 +1645,15 @@
 	spin_unlock(&mdp_lock);
 }
 
+void mdp_pipe_kickoff_simplified(uint32 term)
+{
+	if (term == MDP_OVERLAY0_TERM) {
+		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		mdp_lut_enable();
+		outpdw(MDP_BASE + 0x0004, 0);
+	}
+}
+
 void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd)
 {
 	unsigned long flag;
@@ -1712,6 +1724,7 @@
 		outpdw(MDP_BASE + 0x0014, 0x0);	/* start DMA */
 	} else if (term == MDP_OVERLAY0_TERM) {
 		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		mdp_lut_enable();
 		outpdw(MDP_BASE + 0x0004, 0);
 	} else if (term == MDP_OVERLAY1_TERM) {
 		mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
@@ -2187,6 +2200,7 @@
 
 	/* initialize spin lock and workqueue */
 	spin_lock_init(&mdp_spin_lock);
+	spin_lock_init(&mdp_lut_push_lock);
 	mdp_dma_wq = create_singlethread_workqueue("mdp_dma_wq");
 	mdp_vsync_wq = create_singlethread_workqueue("mdp_vsync_wq");
 	mdp_pipe_ctrl_wq = create_singlethread_workqueue("mdp_pipe_ctrl_wq");
@@ -2314,6 +2328,12 @@
 	},
 };
 
+static int mdp_fps_level_change(struct platform_device *pdev, u32 fps_level)
+{
+	int ret = 0;
+	ret = panel_next_fps_level_change(pdev, fps_level);
+	return ret;
+}
 static int mdp_off(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -2324,7 +2344,11 @@
 	atomic_set(&vsync_cntrl.suspend, 1);
 	atomic_set(&vsync_cntrl.vsync_resume, 0);
 	complete_all(&vsync_cntrl.vsync_wait);
+
 	mdp_clk_ctrl(1);
+
+	ret = panel_next_early_off(pdev);
+
 	if (mfd->panel.type == MIPI_CMD_PANEL)
 		mdp4_dsi_cmd_off(pdev);
 	else if (mfd->panel.type == MIPI_VIDEO_PANEL)
@@ -2339,12 +2363,11 @@
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	ret = panel_next_off(pdev);
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
 	mdp_clk_ctrl(0);
 #ifdef CONFIG_MSM_BUS_SCALING
 	mdp_bus_scale_update_request(0, 0);
 #endif
-	if (mdp_rev >= MDP_REV_41 && mfd->panel.type == MIPI_CMD_PANEL)
-		mdp_dsi_cmd_overlay_suspend(mfd);
 	pr_debug("%s:-\n", __func__);
 	return ret;
 }
@@ -2371,6 +2394,22 @@
 
 	pr_debug("%s:+\n", __func__);
 
+	if (!(mfd->cont_splash_done)) {
+		if (mfd->panel.type == MIPI_VIDEO_PANEL)
+			mdp4_dsi_video_splash_done();
+
+		/* Clks are enabled in probe.
+		Disabling clocks now */
+		mdp_clk_ctrl(0);
+		mfd->cont_splash_done = 1;
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	ret = panel_next_on(pdev);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+
 	if (mdp_rev >= MDP_REV_40) {
 		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 		mdp_clk_ctrl(1);
@@ -2399,11 +2438,6 @@
 		atomic_set(&vsync_cntrl.suspend, 1);
 	}
 
-	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
-
-	ret = panel_next_on(pdev);
-	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
-
 	mdp_histogram_ctrl_all(TRUE);
 
 	if (ret == 0)
@@ -2593,18 +2627,40 @@
 	}
 	disable_irq(mdp_irq);
 
+	dsi_pll_vdda = regulator_get(&pdev->dev, "dsi_pll_vdda");
+	if (IS_ERR(dsi_pll_vdda)) {
+		dsi_pll_vdda = NULL;
+	} else {
+		if (mdp_rev == MDP_REV_42 || mdp_rev == MDP_REV_44) {
+			ret = regulator_set_voltage(dsi_pll_vdda, 1200000,
+				1200000);
+			if (ret) {
+				pr_err("set_voltage failed for dsi_pll_vdda, ret=%d\n",
+					ret);
+			}
+		}
+	}
+
+	dsi_pll_vddio = regulator_get(&pdev->dev, "dsi_pll_vddio");
+	if (IS_ERR(dsi_pll_vddio)) {
+		dsi_pll_vddio = NULL;
+	} else {
+		if (mdp_rev == MDP_REV_42) {
+			ret = regulator_set_voltage(dsi_pll_vddio, 1800000,
+				1800000);
+			if (ret) {
+				pr_err("set_voltage failed for dsi_pll_vddio, ret=%d\n",
+					ret);
+			}
+		}
+	}
+
 	footswitch = regulator_get(&pdev->dev, "vdd");
-	if (IS_ERR(footswitch))
+	if (IS_ERR(footswitch)) {
 		footswitch = NULL;
-	else {
+	} else {
 		regulator_enable(footswitch);
 		mdp_footswitch_on = 1;
-
-		if (mdp_rev == MDP_REV_42 && !cont_splashScreen) {
-			regulator_disable(footswitch);
-			msleep(20);
-			regulator_enable(footswitch);
-		}
 	}
 
 	mdp_clk = clk_get(&pdev->dev, "core_clk");
@@ -2655,6 +2711,17 @@
 
 	MSM_FB_DEBUG("mdp_clk: mdp_clk=%d\n", (int)clk_get_rate(mdp_clk));
 #endif
+
+	if (mdp_rev == MDP_REV_42 && !cont_splashScreen) {
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		/* DSI Video Timing generator disable */
+		outpdw(MDP_BASE + 0xE0000, 0x0);
+		/* Clear MDP Interrupt Enable register */
+		outpdw(MDP_BASE + 0x50, 0x0);
+		/* Set Overlay Proc 0 to reset state */
+		outpdw(MDP_BASE + 0x10004, 0x3);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	}
 	return 0;
 }
 
@@ -2673,7 +2740,6 @@
 #if defined(CONFIG_FB_MSM_MIPI_DSI) && defined(CONFIG_FB_MSM_MDP40)
 	struct mipi_panel_info *mipi;
 #endif
-	static int contSplash_update_done;
 
 	if ((pdev->id == 0) && (pdev->num_resources > 0)) {
 		mdp_init_pdev = pdev;
@@ -2694,6 +2760,13 @@
 			return -ENOMEM;
 		}
 
+		if (mdp_pdata->mdp_max_bw)
+			mdp_max_bw = mdp_pdata->mdp_max_bw;
+		if (mdp_pdata->mdp_bw_ab_factor)
+			mdp_bw_ab_factor = mdp_pdata->mdp_bw_ab_factor;
+		if (mdp_pdata->mdp_bw_ib_factor)
+			mdp_bw_ib_factor = mdp_pdata->mdp_bw_ib_factor;
+
 		mdp_rev = mdp_pdata->mdp_rev;
 
 		mdp_iommu_split_domain = mdp_pdata->mdp_iommu_split_domain;
@@ -2743,21 +2816,6 @@
 	mfd->mdp_rev = mdp_rev;
 	mfd->vsync_init = NULL;
 
-	if (mdp_pdata) {
-		if (mdp_pdata->cont_splash_enabled) {
-			mfd->cont_splash_done = 0;
-			if (!contSplash_update_done) {
-				if (mfd->panel.type == MIPI_VIDEO_PANEL ||
-				    mfd->panel.type == LCDC_PANEL)
-					mdp_pipe_ctrl(MDP_CMD_BLOCK,
-						MDP_BLOCK_POWER_ON, FALSE);
-				mdp_clk_ctrl(1);
-				contSplash_update_done = 1;
-			}
-		} else
-			mfd->cont_splash_done = 1;
-	}
-
 	mfd->ov0_wb_buf = MDP_ALLOC(sizeof(struct mdp_buf_type));
 	mfd->ov1_wb_buf = MDP_ALLOC(sizeof(struct mdp_buf_type));
 	memset((void *)mfd->ov0_wb_buf, 0, sizeof(struct mdp_buf_type));
@@ -2786,10 +2844,60 @@
 		rc = -ENOMEM;
 		goto mdp_probe_err;
 	}
+
+	if (mdp_pdata) {
+		if (mdp_pdata->cont_splash_enabled &&
+				 mfd->panel_info.pdest == DISPLAY_1) {
+			char *cp;
+			uint32 bpp = 3;
+			/*read panel wxh and calculate splash screen
+			  size*/
+			mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+			mdp_clk_ctrl(1);
+
+			mdp_pdata->splash_screen_size =
+				inpdw(MDP_BASE + 0x90004);
+			mdp_pdata->splash_screen_size =
+				(((mdp_pdata->splash_screen_size >> 16) &
+				  0x00000FFF) * (
+					  mdp_pdata->splash_screen_size &
+					  0x00000FFF)) * bpp;
+
+			mdp_pdata->splash_screen_addr =
+				inpdw(MDP_BASE + 0x90008);
+
+			mfd->copy_splash_buf = dma_alloc_coherent(NULL,
+					mdp_pdata->splash_screen_size,
+					(dma_addr_t *) &(mfd->copy_splash_phys),
+					GFP_KERNEL);
+
+			if (!mfd->copy_splash_buf) {
+				pr_err("DMA ALLOC FAILED for SPLASH\n");
+				return -ENOMEM;
+			}
+			cp = (char *)ioremap(
+					mdp_pdata->splash_screen_addr,
+					mdp_pdata->splash_screen_size);
+			if (!cp) {
+				pr_err("IOREMAP FAILED for SPLASH\n");
+				return -ENOMEM;
+			}
+			memcpy(mfd->copy_splash_buf, cp,
+					mdp_pdata->splash_screen_size);
+
+			MDP_OUTP(MDP_BASE + 0x90008,
+					mfd->copy_splash_phys);
+		}
+
+		mfd->cont_splash_done = (1 - mdp_pdata->cont_splash_enabled);
+	}
+
 	/* data chain */
 	pdata = msm_fb_dev->dev.platform_data;
 	pdata->on = mdp_on;
 	pdata->off = mdp_off;
+	pdata->fps_level_change = mdp_fps_level_change;
 	pdata->late_init = NULL;
 	pdata->next = pdev;
 
@@ -3142,6 +3250,17 @@
 		return;
 	}
 
+	if (dsi_pll_vddio)
+		regulator_enable(dsi_pll_vddio);
+
+	if (dsi_pll_vdda)
+		regulator_enable(dsi_pll_vdda);
+
+	mipi_dsi_prepare_clocks();
+	mipi_dsi_ahb_ctrl(1);
+	mipi_dsi_phy_ctrl(1);
+	mipi_dsi_clk_enable();
+
 	if (on && !mdp_footswitch_on) {
 		pr_debug("Enable MDP FS\n");
 		regulator_enable(footswitch);
@@ -3152,9 +3271,31 @@
 		mdp_footswitch_on = 0;
 	}
 
+	mipi_dsi_clk_disable();
+	mipi_dsi_phy_ctrl(0);
+	mipi_dsi_ahb_ctrl(0);
+	mipi_dsi_unprepare_clocks();
+
+	if (dsi_pll_vdda)
+		regulator_disable(dsi_pll_vdda);
+
+	if (dsi_pll_vddio)
+		regulator_disable(dsi_pll_vddio);
+
 	mutex_unlock(&mdp_suspend_mutex);
 }
 
+void mdp_free_splash_buffer(struct msm_fb_data_type *mfd)
+{
+	if (mfd->copy_splash_buf) {
+		dma_free_coherent(NULL,	mdp_pdata->splash_screen_size,
+			mfd->copy_splash_buf,
+			(dma_addr_t) mfd->copy_splash_phys);
+
+		mfd->copy_splash_buf = NULL;
+	}
+}
+
 #ifdef CONFIG_PM
 static void mdp_suspend_sub(void)
 {
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index 7bcea6e..c90c284 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -733,6 +733,7 @@
 
 void mdp_hw_init(void);
 int mdp_ppp_pipe_wait(void);
+void mdp_pipe_kickoff_simplified(uint32 term);
 void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd);
 void mdp_clk_ctrl(int on);
 void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
@@ -776,7 +777,7 @@
 int mdp_lcdc_on(struct platform_device *pdev);
 int mdp_lcdc_off(struct platform_device *pdev);
 void mdp_lcdc_update(struct msm_fb_data_type *mfd);
-
+void mdp_free_splash_buffer(struct msm_fb_data_type *mfd);
 #ifdef CONFIG_FB_MSM_MDP303
 int mdp_dsi_video_on(struct platform_device *pdev);
 int mdp_dsi_video_off(struct platform_device *pdev);
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 3a2dd23..024c58f 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+/*
+ * Copyright (c) 2009-2013, The Linux Foundation. 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 and
@@ -30,8 +31,10 @@
 extern u32 mdp_max_clk;
 
 extern u64 mdp_max_bw;
-#define MDP4_BW_AB_FACTOR (115)	/* 1.15 */
-#define MDP4_BW_IB_FACTOR (125)	/* 1.25 */
+extern u32 mdp_bw_ab_factor;
+extern u32 mdp_bw_ib_factor;
+#define MDP4_BW_AB_DEFAULT_FACTOR (115)	/* 1.15 */
+#define MDP4_BW_IB_DEFAULT_FACTOR (125)	/* 1.25 */
 #define MDP_BUS_SCALE_AB_STEP (0x4000000)
 
 #define MDP4_OVERLAYPROC0_BASE	0x10000
@@ -266,7 +269,6 @@
 #define IOMMU_FREE_LIST_MAX 32
 
 struct iommu_free_list {
-	int total;
 	int fndx;
 	struct ion_handle *ihdl[IOMMU_FREE_LIST_MAX];
 };
@@ -295,6 +297,8 @@
 	uint32 src_format;
 	uint32 src_width;	/* source img width */
 	uint32 src_height;	/* source img height */
+	uint32 prev_src_width;	/* source img width */
+	uint32 prev_src_height;	/* source img height */
 	uint32 is_3d;
 	uint32 src_width_3d;	/* source img width */
 	uint32 src_height_3d;	/* source img height */
@@ -489,6 +493,8 @@
 void mdp4_dtv_wait4vsync(int cndx);
 void mdp4_dtv_vsync_ctrl(struct fb_info *info, int enable);
 void mdp4_dtv_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
+void mdp4_dtv_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
+int mdp4_dtv_pipe_commit(int cndx, int wait);
 #else
 static inline void mdp4_overlay_dtv_start(void)
 {
@@ -535,10 +541,18 @@
 {
 	return;
 }
-static inline void mdp4_dtv_base_swap(struct mdp4_overlay_pipe *pipe)
+static inline void mdp4_dtv_base_swap(int cndx, struct mdp4_overlay_pipe *pipe)
 {
 	/* empty */
 }
+static inline void mdp4_dtv_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe)
+{
+	/* empty */
+}
+static inline int mdp4_dtv_pipe_commit(int cndx, int wait)
+{
+	return 0;
+}
 #endif /* CONFIG_FB_MSM_DTV */
 
 void mdp4_dtv_set_black_screen(void);
@@ -555,6 +569,7 @@
 int mdp4_atv_off(struct platform_device *pdev);
 void mdp4_dsi_video_fxn_register(cmd_fxn_t fxn);
 void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd);
+void mdp4_overlay_free_base_pipe(struct msm_fb_data_type *mfd);
 void mdp4_lcdc_vsync_ctrl(struct fb_info *info, int enable);
 void mdp4_overlay0_done_dsi_video(int cndx);
 void mdp4_overlay0_done_dsi_cmd(int cndx);
@@ -564,7 +579,6 @@
 int mdp4_dsi_video_pipe_commit(int cndx, int wait);
 int mdp4_dsi_cmd_pipe_commit(int cndx, int wait);
 int mdp4_lcdc_pipe_commit(int cndx, int wait);
-int mdp4_dtv_pipe_commit(int cndx, int wait);
 int mdp4_dsi_cmd_update_cnt(int cndx);
 void mdp4_dsi_rdptr_init(int cndx);
 void mdp4_dsi_vsync_init(int cndx);
@@ -608,7 +622,6 @@
 void mdp4_mixer_stage_commit(int mixer);
 void mdp4_dsi_cmd_do_update(int cndx, struct mdp4_overlay_pipe *pipe);
 void mdp4_lcdc_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
-void mdp4_dtv_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
 void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe);
 void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc);
 void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe);
@@ -630,6 +643,7 @@
 void mdp4_overlay_lcdc_vsync_push(struct msm_fb_data_type *mfd,
 				struct mdp4_overlay_pipe *pipe);
 void mdp4_mddi_overlay_dmas_restore(void);
+void mdp4_overlay_solidfill_init(struct mdp4_overlay_pipe *pipe);
 
 #ifndef CONFIG_FB_MSM_MIPI_DSI
 void mdp4_mddi_dma_busy_wait(struct msm_fb_data_type *mfd);
@@ -693,6 +707,10 @@
 void mdp4_dsi_video_overlay_blt(struct msm_fb_data_type *mfd,
 					struct msmfb_overlay_blt *req);
 void mdp4_dsi_video_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
+void mdp4_dsi_video_free_base_pipe(struct msm_fb_data_type *mfd);
+void mdp4_dsi_cmd_free_base_pipe(struct msm_fb_data_type *mfd);
+void mdp4_lcdc_free_base_pipe(struct msm_fb_data_type *mfd);
+void mdp4_dtv_free_base_pipe(struct msm_fb_data_type *mfd);
 
 #ifdef CONFIG_FB_MSM_MDP40
 static inline void mdp3_dsi_cmd_dma_busy_wait(struct msm_fb_data_type *mfd)
@@ -777,15 +795,16 @@
 
 
 #ifdef CONFIG_FB_MSM_MIPI_DSI
-void mdp_dsi_cmd_overlay_suspend(struct msm_fb_data_type *mfd);
 int mdp4_dsi_cmd_on(struct platform_device *pdev);
 int mdp4_dsi_cmd_off(struct platform_device *pdev);
 int mdp4_dsi_video_off(struct platform_device *pdev);
 int mdp4_dsi_video_on(struct platform_device *pdev);
+int mdp4_dsi_video_splash_done(void);
 void mdp4_primary_vsync_dsi_video(void);
 void mdp4_dsi_cmd_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
 void mdp4_dsi_cmd_wait4vsync(int cndx);
 void mdp4_dsi_video_wait4vsync(int cndx);
+void mdp4_mixer_reset(int mixer);
 void mdp4_dsi_cmd_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
 void mdp4_dsi_video_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
 void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info, int enable);
@@ -850,12 +869,10 @@
 {
 	/* empty */
 }
-#ifdef CONFIG_FB_MSM_MDP40
-static inline void mdp_dsi_cmd_overlay_suspend(struct msm_fb_data_type *mfd)
+
+static int mdp4_dsi_video_splash_done(void)
 {
-	/* empty */
 }
-#endif
 #endif /* CONFIG_FB_MSM_MIPI_DSI */
 
 void mdp4_dsi_cmd_kickoff_ui(struct msm_fb_data_type *mfd,
@@ -918,6 +935,7 @@
 int mdp4_pcc_cfg(struct mdp_pcc_cfg_data *cfg_ptr);
 int mdp4_argc_cfg(struct mdp_pgc_lut_data *pgc_ptr);
 int mdp4_qseed_cfg(struct mdp_qseed_cfg_data *cfg);
+int mdp4_calib_config(struct mdp_calib_config_data *cfg);
 int mdp4_qseed_access_cfg(struct mdp_qseed_cfg *cfg, uint32_t base);
 u32  mdp4_allocate_writeback_buf(struct msm_fb_data_type *mfd, u32 mix_num);
 void mdp4_init_writeback_buf(struct msm_fb_data_type *mfd, u32 mix_num);
@@ -940,10 +958,10 @@
 			      struct msm_fb_data_type *mfd);
 int mdp4_calc_blt_mdp_bw(struct msm_fb_data_type *mfd,
 			 struct mdp4_overlay_pipe *pipe);
-int mdp4_overlay_mdp_perf_req(struct msm_fb_data_type *mfd,
-				struct mdp4_overlay_pipe *plist);
+int mdp4_overlay_mdp_perf_req(struct msm_fb_data_type *mfd);
 void mdp4_overlay_mdp_perf_upd(struct msm_fb_data_type *mfd, int flag);
 int mdp4_overlay_reset(void);
+void mdp4_vg_csc_restore(void);
 
 #ifndef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
 static inline void mdp4_wfd_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe)
@@ -965,9 +983,9 @@
 int mdp4_wfd_pipe_commit(struct msm_fb_data_type *mfd, int cndx, int wait);
 #endif
 #ifdef CONFIG_FB_MSM_OVERLAY
-int mdp4_unmap_sec_resource(void);
+int mdp4_unmap_sec_resource(struct msm_fb_data_type *mfd);
 #else
-static inline void mdp4_unmap_sec_resource(void);
+static inline void mdp4_unmap_sec_resource(struct msm_fb_data_type *mfd);
 {
 	/* empty */
 	return 0;
diff --git a/drivers/video/msm/mdp4_dtv.c b/drivers/video/msm/mdp4_dtv.c
index 4b83224..ba810a9 100644
--- a/drivers/video/msm/mdp4_dtv.c
+++ b/drivers/video/msm/mdp4_dtv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index c4d3e23..3356e61 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -52,15 +52,14 @@
 	uint32 mixer_cfg[MDP4_MIXER_MAX];
 	uint32 flush[MDP4_MIXER_MAX];
 	struct iommu_free_list iommu_free[MDP4_MIXER_MAX];
+	struct iommu_free_list iommu_free_prev[MDP4_MIXER_MAX];
+	uint32 dmap_cfg[5];
 	uint32 cs_controller;
 	uint32 panel_3d;
 	uint32 panel_mode;
 	uint32 mixer0_played;
 	uint32 mixer1_played;
 	uint32 mixer2_played;
-	uint32 sec_mapped;
-	uint32 mmu_clk_on;
-	uint32 sec_active;
 } mdp4_overlay_db = {
 	.cs_controller = CS_CONTROLLER_0,
 	.plist = {
@@ -120,12 +119,36 @@
 struct mdp4_overlay_perf perf_request;
 struct mdp4_overlay_perf perf_current;
 
+void  mdp4_overlay_free_base_pipe(struct msm_fb_data_type *mfd)
+{
+	if (!hdmi_prim_display && mfd->index == 0) {
+		if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
+			mdp4_dsi_video_free_base_pipe(mfd);
+		else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+			mdp4_dsi_cmd_free_base_pipe(mfd);
+		else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
+			mdp4_lcdc_free_base_pipe(mfd);
+	} else if (hdmi_prim_display || mfd->index == 1) {
+		mdp4_dtv_free_base_pipe(mfd);
+	}
+}
+
 static struct ion_client *display_iclient;
 
-static int mdp4_map_sec_resource(void)
+static int mdp4_map_sec_resource(struct msm_fb_data_type *mfd)
 {
 	int ret = 0;
-	if (ctrl->sec_mapped)
+
+	if (!mfd) {
+		pr_err("%s: mfd is invalid\n", __func__);
+		return -ENODEV;
+	}
+
+	pr_debug("%s %d mfd->index=%d,mapped=%d,active=%d\n",
+		__func__, __LINE__,
+		 mfd->index, mfd->sec_mapped, mfd->sec_active);
+
+	if (mfd->sec_mapped)
 		return 0;
 
 	ret = mdp_enable_iommu_clocks();
@@ -138,24 +161,34 @@
 		pr_err("ION heap secure failed heap id %d ret %d\n",
 			   ION_CP_MM_HEAP_ID, ret);
 	else
-		ctrl->sec_mapped = 1;
+		mfd->sec_mapped = 1;
 	mdp_disable_iommu_clocks();
 	return ret;
 }
 
-int mdp4_unmap_sec_resource(void)
+int mdp4_unmap_sec_resource(struct msm_fb_data_type *mfd)
 {
 	int ret = 0;
-	if ((ctrl->sec_mapped == 0) || (ctrl->sec_active))
+
+	if (!mfd) {
+		pr_err("%s: mfd is invalid\n", __func__);
+		return -ENODEV;
+	}
+
+	if ((mfd->sec_mapped == 0) || (mfd->sec_active))
 		return 0;
 
+	pr_debug("%s %d mfd->index=%d,mapped=%d,active=%d\n",
+		__func__, __LINE__,
+		 mfd->index, mfd->sec_mapped, mfd->sec_active);
+
 	ret = mdp_enable_iommu_clocks();
 	if (ret) {
 		pr_err("IOMMU clock enabled failed while close\n");
 		return ret;
 	}
 	msm_ion_unsecure_heap(ION_HEAP(ION_CP_MM_HEAP_ID));
-	ctrl->sec_mapped = 0;
+	mfd->sec_mapped = 0;
 	mdp_disable_iommu_clocks();
 	return ret;
 }
@@ -171,16 +204,22 @@
 {
 	int i;
 	struct ion_handle *ihdl;
-	struct iommu_free_list *flist;
+	struct iommu_free_list *flist, *pflist;
+
+	if (mixer >= MDP4_MIXER_MAX)
+		return;
 
 	mutex_lock(&iommu_mutex);
+
+	pflist = &ctrl->iommu_free_prev[mixer];
 	flist = &ctrl->iommu_free[mixer];
-	if (flist->total == 0) {
-		mutex_unlock(&iommu_mutex);
-		return;
+	pr_debug("%s: mixer=%d fndx=%d %d\n", __func__,
+			mixer, pflist->fndx, flist->fndx);
+	if (pflist->fndx == 0) {
+		goto flist_to_pflist;
 	}
 	for (i = 0; i < IOMMU_FREE_LIST_MAX; i++) {
-		ihdl = flist->ihdl[i];
+		ihdl = pflist->ihdl[i];
 		if (ihdl == NULL)
 			continue;
 		pr_debug("%s: mixer=%d i=%d ihdl=0x%p\n", __func__,
@@ -192,11 +231,12 @@
 			(int)mdp4_stat.iommu_map, (int)mdp4_stat.iommu_unmap,
 				(int)mdp4_stat.iommu_drop);
 		ion_free(display_iclient, ihdl);
-		flist->ihdl[i] = NULL;
 	}
 
-	flist->fndx = 0;
-	flist->total = 0;
+flist_to_pflist:
+	/* move flist to pflist*/
+	memcpy(pflist, flist, sizeof(*pflist));
+	memset(flist, 0, sizeof(*flist));
 	mutex_unlock(&iommu_mutex);
 }
 
@@ -215,7 +255,6 @@
 	pr_debug("%s: add mixer=%d fndx=%d ihdl=0x%p\n", __func__,
 				mixer, flist->fndx, ihdl);
 
-	flist->total++;
 	flist->ihdl[flist->fndx++] = ihdl;
 }
 
@@ -544,6 +583,7 @@
 	mask = 0x0FFFFFFF;
 	dma2_cfg_reg = (dma2_cfg_reg & mask) | (curr & ~mask);
 	MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
+	ctrl->dmap_cfg[0] = dma2_cfg_reg;
 
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
@@ -567,24 +607,40 @@
 		off = 0;
 		if (pipe->dmap_cnt & 0x01)
 			off = pipe->src_height * pipe->src_width * bpp;
+		ctrl->dmap_cfg[2] = pipe->dma_blt_addr + off;
 		MDP_OUTP(MDP_BASE + 0x90008, pipe->dma_blt_addr + off);
 		/* RGB888, output of overlay blending */
 		MDP_OUTP(MDP_BASE + 0x9000c, pipe->src_width * bpp);
+                ctrl->dmap_cfg[3] = pipe->src_width * bpp;
 	} else {
 		MDP_OUTP(MDP_BASE + 0x90008, pipe->srcp0_addr);
+		ctrl->dmap_cfg[2] = pipe->srcp0_addr;
 		MDP_OUTP(MDP_BASE + 0x9000c, pipe->srcp0_ystride);
+		ctrl->dmap_cfg[3] = pipe->srcp0_ystride;
 	}
 	/* dma_p source */
 	MDP_OUTP(MDP_BASE + 0x90004,
 			(pipe->src_height << 16 | pipe->src_width));
+	ctrl->dmap_cfg[1] = (pipe->src_height << 16 | pipe->src_width);
 
 	/* dma_p dest */
 	MDP_OUTP(MDP_BASE + 0x90010, (pipe->dst_y << 16 | pipe->dst_x));
+	ctrl->dmap_cfg[4] = (pipe->dst_y << 16 | pipe->dst_x);
 
 	if (!in_interrupt())
 		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
+static void mdp4_overlay_dmap_reconfig(void)
+{
+        MDP_OUTP(MDP_BASE + 0x90000, ctrl->dmap_cfg[0]);
+        MDP_OUTP(MDP_BASE + 0x90004, ctrl->dmap_cfg[1]);
+        MDP_OUTP(MDP_BASE + 0x90008, ctrl->dmap_cfg[2]);
+        MDP_OUTP(MDP_BASE + 0x9000c, ctrl->dmap_cfg[3]);
+        MDP_OUTP(MDP_BASE + 0x90010, ctrl->dmap_cfg[4]);
+}
+
+
 #define MDP4_VG_PHASE_STEP_DEFAULT	0x20000000
 #define MDP4_VG_PHASE_STEP_SHIFT	29
 
@@ -682,6 +738,41 @@
 	}
 }
 
+void mdp4_overlay_solidfill_init(struct mdp4_overlay_pipe *pipe)
+{
+	char *base;
+	uint32 src_size, src_xy, dst_size, dst_xy;
+	uint32 format;
+	uint32 off;
+	int i;
+
+	src_size = ((pipe->src_h << 16) | pipe->src_w);
+	src_xy = ((pipe->src_y << 16) | pipe->src_x);
+	dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
+	dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
+
+	base = MDP_BASE + MDP4_VIDEO_BASE;
+	off = MDP4_VIDEO_OFF;	/* 0x10000 */
+	mdp_clk_ctrl(1);
+	for(i = 0; i < 4; i++) {	/* 4 pipes */
+		format = inpdw(base + 0x50);
+		format |= MDP4_FORMAT_SOLID_FILL;
+		outpdw(base + 0x0000, src_size);/* MDP_RGB_SRC_SIZE */
+		outpdw(base + 0x0004, src_xy);	/* MDP_RGB_SRC_XY */
+		outpdw(base + 0x0008, dst_size);/* MDP_RGB_DST_SIZE */
+		outpdw(base + 0x000c, dst_xy);	/* MDP_RGB_DST_XY */
+		outpdw(base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */
+		outpdw(base + 0x1008, 0x0);/* Black */
+		base += off;
+	}
+	/*
+	 * keep it at primary
+	 * will be picked up at first commit
+	 */
+	ctrl->flush[MDP4_MIXER0] = 0x3c; /* all pipes */
+	mdp_clk_ctrl(0);
+}
+
 void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe)
 {
 	char *rgb_base;
@@ -742,6 +833,7 @@
 		op_mode &= ~(MDP4_OP_FLIP_LR + MDP4_OP_SCALEX_EN);
 		op_mode &= ~(MDP4_OP_FLIP_UD + MDP4_OP_SCALEY_EN);
 		outpdw(rgb_base + 0x0058, op_mode);/* MDP_RGB_OP_MODE */
+		outpdw(rgb_base + 0x1008, 0x0);/* Black */
 	} else {
 		if (pipe->op_mode & MDP4_OP_FLIP_LR && mdp_rev >= MDP_REV_42) {
 			/* Enable x-scaling bit to enable LR flip */
@@ -766,36 +858,52 @@
 	*luma_off = 0;
 	*chroma_off = 0;
 
-	if (pipe->src_x && (pipe->frame_format ==
+	if ((pipe->src_x || pipe->src_y) && (pipe->frame_format ==
 		MDP4_FRAME_FORMAT_LINEAR)) {
-		src_xy = (pipe->src_y << 16) | pipe->src_x;
-		src_xy &= 0xffff0000;
+		src_xy = 0;
 		outpdw(vg_base + 0x0004, src_xy);	/* MDP_RGB_SRC_XY */
 
 		switch (pipe->src_format) {
 		case MDP_Y_CR_CB_H2V2:
 		case MDP_Y_CR_CB_GH2V2:
 		case MDP_Y_CB_CR_H2V2:
-				*luma_off = pipe->src_x;
-				*chroma_off = pipe->src_x/2;
+			*luma_off = pipe->src_x +
+				(pipe->src_y * pipe->srcp0_ystride);
+			*chroma_off = pipe->src_x / 2 +
+				((pipe->src_y / 2) * pipe->srcp1_ystride);
 			break;
 
 		case MDP_Y_CBCR_H2V2_TILE:
 		case MDP_Y_CRCB_H2V2_TILE:
 		case MDP_Y_CBCR_H2V2:
 		case MDP_Y_CRCB_H2V2:
+			*luma_off = pipe->src_x +
+				(pipe->src_y * pipe->srcp0_ystride);
+			*chroma_off = pipe->src_x +
+				((pipe->src_y / 2) * pipe->srcp1_ystride);
+			break;
+
 		case MDP_Y_CRCB_H1V1:
 		case MDP_Y_CBCR_H1V1:
+			*luma_off = pipe->src_x +
+				(pipe->src_y * pipe->srcp0_ystride);
+			*chroma_off = pipe->src_x +
+				((pipe->src_y * 2) * pipe->srcp1_ystride);
+			break;
+
 		case MDP_Y_CRCB_H2V1:
 		case MDP_Y_CBCR_H2V1:
-			*luma_off = pipe->src_x;
-			*chroma_off = pipe->src_x;
+			*luma_off = pipe->src_x +
+				(pipe->src_y * pipe->srcp0_ystride);
+			*chroma_off = pipe->src_x +
+				(pipe->src_y * pipe->srcp1_ystride);
 			break;
 
 		case MDP_YCRYCB_H2V1:
 			if (pipe->src_x & 0x1)
 				pipe->src_x += 1;
-			*luma_off += pipe->src_x * 2;
+			*luma_off += pipe->src_x * 2 +
+				((pipe->src_y * 2) * pipe->srcp0_ystride);
 			break;
 
 		case MDP_ARGB_8888:
@@ -808,7 +916,8 @@
 		case MDP_RGB_888:
 		case MDP_YCBCR_H1V1:
 		case MDP_YCRCB_H1V1:
-			*luma_off = pipe->src_x * pipe->bpp;
+			*luma_off = (pipe->src_x * pipe->bpp) +
+					(pipe->src_y * pipe->srcp0_ystride);
 			break;
 
 		default:
@@ -908,8 +1017,29 @@
 	outpdw(vg_base + 0x0008, dst_size);	/* MDP_RGB_DST_SIZE */
 	outpdw(vg_base + 0x000c, dst_xy);	/* MDP_RGB_DST_XY */
 
-	if (pipe->frame_format != MDP4_FRAME_FORMAT_LINEAR)
+	if (pipe->frame_format != MDP4_FRAME_FORMAT_LINEAR) {
+		struct mdp4_overlay_pipe *real_pipe;
+		u32 psize, csize;
+
+		/*
+		 * video tile frame size register is NOT double buffered.
+		 * when this register updated, it kicks in immediatly
+		 * During transition from smaller resolution to higher
+		 * resolution  it may have possibility that mdp still fetch
+		 * from smaller resolution buffer with new higher resolution
+		 * frame size. This will cause iommu page fault.
+		 */
+		real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
+		psize = real_pipe->prev_src_height * real_pipe->prev_src_width;
+		csize = pipe->src_height * pipe->src_width;
+		if (psize && (csize > psize)) {
+			frame_size = (real_pipe->prev_src_height << 16 |
+					real_pipe->prev_src_width);
+		}
 		outpdw(vg_base + 0x0048, frame_size);	/* TILE frame size */
+		real_pipe->prev_src_height = pipe->src_height;
+		real_pipe->prev_src_width = pipe->src_width;
+	}
 
 	/*
 	 * Adjust src X offset to avoid MDP from overfetching pixels
@@ -1588,9 +1718,13 @@
 	cnt = 0;
 	ndx = MDP4_MIXER_STAGE_BASE;
 	for ( ; ndx < MDP4_MIXER_STAGE_MAX; ndx++) {
-		pipe = ctrl->stage[mixer_num][ndx];
+		pipe = &ctrl->plist[ndx];
 		if (pipe == NULL)
 			continue;
+
+		if (!pipe->pipe_used)
+			continue;
+
 		info->z_order = pipe->mixer_stage - MDP4_MIXER_STAGE0;
 		/* z_order == -1, means base layer */
 		info->ptype = pipe->pipe_type;
@@ -1603,6 +1737,50 @@
 	return cnt;
 }
 
+void mdp4_mixer_reset(int mixer)
+{
+	uint32 data, data1, mask;
+	int i, ndx, min, max, bit;
+
+	mdp_clk_ctrl(1);
+	/* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1  */
+	data = inpdw(MDP_BASE + 0x10100);
+	data1 = data;
+
+	if (mixer == 0) {
+		min = 1;
+		max = 8;
+		bit = 0x03; /* mixer0, dmap */
+	} else {
+		min = 9;
+		max = 0xf;
+		bit = 0x0C; /* mixer1, dmae */
+	}
+	mask = 0x0f;
+	for (i = 0 ; i < 8 ; i++) {
+		ndx = data & mask;
+		ndx >>= (i * 4);
+		if (ndx >= min && ndx <= max)
+			data1 &= ~mask;  /* unstage pipe from mixer */
+		mask <<= 4;
+	}
+	pr_debug("%s: => MIXER_RESET, data1=%x data=%x bit=%x\n",
+				__func__, data1, data, bit);
+	/* unstage pipes of mixer to be reset */
+	outpdw(MDP_BASE + 0x10100, data1); /* MDP_LAYERMIXER_IN_CFG */
+	outpdw(MDP_BASE + 0x18000, 0);
+
+	mdp4_sw_reset(bit); /* reset mixer */   /* 0 => mixer0, dmap */
+
+	/* restore origianl stage */
+	outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
+	outpdw(MDP_BASE + 0x18000, 0);
+
+	mdp4_vg_csc_restore();
+	mdp4_overlay_dmap_reconfig();
+	mdp_clk_ctrl(0);
+}
+
 void mdp4_mixer_stage_commit(int mixer)
 {
 	struct mdp4_overlay_pipe *pipe;
@@ -1633,7 +1811,8 @@
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	mdp_clk_ctrl(1);
 
-	mdp4_mixer_blend_setup(mixer);
+	if (data)
+		mdp4_mixer_blend_setup(mixer);
 
 	off = 0;
 	if (data != ctrl->mixer_cfg[mixer]) {
@@ -1887,29 +2066,21 @@
 	}
 
 	format = inpdw(base + 0x50);
-	if (blend->solidfill) {
-		format |= MDP4_FORMAT_SOLID_FILL;
-		/*
-		 * If solid fill is enabled, flip and scale
-		 * have to be disabled. otherwise, h/w
-		 * underruns.
-		 */
-		op_mode = inpdw(base + 0x0058);
-		op_mode &= ~(MDP4_OP_FLIP_LR + MDP4_OP_SCALEX_EN);
-		op_mode &= ~(MDP4_OP_FLIP_UD + MDP4_OP_SCALEY_EN);
-		outpdw(base + 0x0058, op_mode);
-		outpdw(base + 0x1008, 0);	/* black */
-		/*
-		 * Set src size and dst size same to avoid underruns
-		 */
-		outpdw(base + 0x0000, inpdw(base + 0x0008));
-	} else {
-		u32 src_size = ((pipe->src_h << 16) | pipe->src_w);
-		outpdw(base + 0x0000, src_size);
-		format &= ~MDP4_FORMAT_SOLID_FILL;
-		blend->solidfill_pipe = NULL;
-	}
-
+	format |= MDP4_FORMAT_SOLID_FILL;
+	/*
+	 * If solid fill is enabled, flip and scale
+	 * have to be disabled. otherwise, h/w
+	 * underruns.
+	 */
+	op_mode = inpdw(base + 0x0058);
+	op_mode &= ~(MDP4_OP_FLIP_LR + MDP4_OP_SCALEX_EN);
+	op_mode &= ~(MDP4_OP_FLIP_UD + MDP4_OP_SCALEY_EN);
+	outpdw(base + 0x0058, op_mode);
+	outpdw(base + 0x1008, 0);	/* black */
+	/*
+	 * Set src size and dst size same to avoid underruns
+	 */
+	outpdw(base + 0x0000, inpdw(base + 0x0008));
 	outpdw(base + 0x50, format);
 
 	mdp4_overlay_reg_flush(pipe, 0);
@@ -1941,6 +2112,98 @@
 	}
 }
 
+static void mdp4_set_blend_by_op(struct mdp4_overlay_pipe *s_pipe,
+					struct mdp4_overlay_pipe *d_pipe,
+					int alpha_drop,
+					struct blend_cfg *blend)
+{
+	int d_alpha, s_alpha;
+	u32 op;
+
+	d_alpha = d_pipe->alpha_enable;
+	s_alpha = s_pipe->alpha_enable;
+	/* base on fg's alpha */
+	blend->fg_alpha = s_pipe->alpha;
+	blend->bg_alpha = 0x0ff - s_pipe->alpha;
+	blend->op = MDP4_BLEND_FG_ALPHA_FG_CONST |
+	MDP4_BLEND_BG_ALPHA_BG_CONST;
+	blend->co3_sel = 1; /* use fg alpha */
+	op = s_pipe->blend_op;
+	if (op == BLEND_OP_OPAQUE) {
+		blend->bg_alpha = 0;
+		blend->fg_alpha = 0xff;
+	} else if ((op == BLEND_OP_PREMULTIPLIED) &&
+			(!alpha_drop) && s_alpha) {
+		blend->op = MDP4_BLEND_FG_ALPHA_FG_CONST |
+			MDP4_BLEND_BG_INV_ALPHA |
+			MDP4_BLEND_BG_ALPHA_FG_PIXEL;
+		if (blend->fg_alpha != 0xff) {
+			blend->bg_alpha = blend->fg_alpha;
+			blend->op |= MDP4_BLEND_BG_MOD_ALPHA;
+		}
+	} else if (!alpha_drop && s_alpha) {
+		blend->op = MDP4_BLEND_FG_ALPHA_FG_PIXEL |
+			MDP4_BLEND_BG_INV_ALPHA |
+			MDP4_BLEND_BG_ALPHA_FG_PIXEL;
+		if (blend->fg_alpha != 0xff) {
+			blend->bg_alpha = blend->fg_alpha;
+			blend->op |= MDP4_BLEND_FG_MOD_ALPHA |
+				MDP4_BLEND_BG_MOD_ALPHA;
+		}
+	}
+	if (!s_alpha && d_alpha)
+		blend->co3_sel = 0;
+	pr_debug("%s: op %d bg alpha %d, fg alpha %d blend: %x\n",
+		__func__, op, blend->bg_alpha, blend->fg_alpha, blend->op);
+}
+
+static void mdp4_set_blend_by_fmt(struct mdp4_overlay_pipe *s_pipe,
+					struct mdp4_overlay_pipe *d_pipe,
+					int alpha_drop,
+					struct blend_cfg *blend)
+{
+	int ptype, d_alpha, s_alpha;
+	d_alpha = d_pipe->alpha_enable;
+	s_alpha = s_pipe->alpha_enable;
+	/* base on fg's alpha */
+	blend->bg_alpha = 0x0ff - s_pipe->alpha;
+	blend->fg_alpha = s_pipe->alpha;
+	blend->co3_sel = 1; /* use fg alpha */
+
+	if (s_pipe->is_fg) {
+		if (s_pipe->alpha == 0xff) {
+			blend->solidfill = 1;
+			blend->solidfill_pipe = d_pipe;
+		}
+	} else if (s_alpha) {
+		if (!alpha_drop) {
+			blend->op = MDP4_BLEND_BG_ALPHA_FG_PIXEL;
+			if (!(s_pipe->flags & MDP_BLEND_FG_PREMULT))
+				blend->op |=
+					MDP4_BLEND_FG_ALPHA_FG_PIXEL;
+		} else
+			blend->op = MDP4_BLEND_BG_ALPHA_FG_CONST;
+
+		blend->op |= MDP4_BLEND_BG_INV_ALPHA;
+	} else if (d_alpha) {
+		ptype = mdp4_overlay_format2type(s_pipe->src_format);
+		if (ptype == OVERLAY_TYPE_VIDEO &&
+			(!(s_pipe->flags & MDP_BACKEND_COMPOSITION))) {
+			blend->op = (MDP4_BLEND_FG_ALPHA_BG_PIXEL |
+				MDP4_BLEND_FG_INV_ALPHA);
+			if (!(s_pipe->flags & MDP_BLEND_FG_PREMULT))
+				blend->op |=
+					MDP4_BLEND_BG_ALPHA_BG_PIXEL;
+			blend->co3_sel = 0; /* use bg alpha */
+		} else {
+			/* s_pipe is rgb without alpha */
+			blend->op = (MDP4_BLEND_FG_ALPHA_FG_CONST |
+				    MDP4_BLEND_BG_ALPHA_BG_CONST);
+			blend->bg_alpha = 0;
+		}
+	}
+}
+
 /*
  * D(i+1) = Ks * S + Kd * D(i)
  */
@@ -1949,8 +2212,7 @@
 	struct mdp4_overlay_pipe *d_pipe;
 	struct mdp4_overlay_pipe *s_pipe;
 	struct blend_cfg *blend;
-	int i, off, ptype, alpha_drop;
-	int d_alpha, s_alpha;
+	int i, off, alpha_drop;
 	unsigned char *overlay_base;
 	uint32 c0, c1, c2;
 
@@ -1970,7 +2232,6 @@
 		if (s_pipe == NULL) {
 			blend++;
 			d_pipe = NULL;
-			d_alpha = 0;
 			continue;
 		}
 		alpha_drop = 0;	/* per stage */
@@ -1984,53 +2245,17 @@
 			alpha_drop = 1;
 
 		d_pipe = mdp4_background_layer(mixer, s_pipe);
-		d_alpha = d_pipe->alpha_enable;
-		s_alpha = s_pipe->alpha_enable;
 		pr_debug("%s: stage=%d: bg: ndx=%d da=%d dalpha=%x "
 			"fg: ndx=%d sa=%d salpha=%x is_fg=%d alpha_drop=%d\n",
-		 __func__, i-2, d_pipe->pipe_ndx, d_alpha, d_pipe->alpha,
-		s_pipe->pipe_ndx, s_alpha, s_pipe->alpha, s_pipe->is_fg,
-		alpha_drop);
-
-		/* base on fg's alpha */
-		blend->bg_alpha = 0x0ff - s_pipe->alpha;
-		blend->fg_alpha = s_pipe->alpha;
-		blend->co3_sel = 1; /* use fg alpha */
-		pr_debug("%s: bg alpha %d, fg alpha %d\n",
-			__func__, blend->bg_alpha, blend->fg_alpha);
-		if (s_pipe->is_fg) {
-			if (s_pipe->alpha == 0xff) {
-				blend->solidfill = 1;
-				blend->solidfill_pipe = d_pipe;
-			}
-		} else if (s_alpha) {
-			if (!alpha_drop) {
-				blend->op = MDP4_BLEND_BG_ALPHA_FG_PIXEL;
-				if (!(s_pipe->flags & MDP_BLEND_FG_PREMULT))
-					blend->op |=
-						MDP4_BLEND_FG_ALPHA_FG_PIXEL;
-				else
-					blend->fg_alpha = 0xff;
-				blend->op |= MDP4_BLEND_BG_INV_ALPHA;
-			} else
-				blend->op = MDP4_BLEND_BG_ALPHA_FG_CONST;
-		} else if (d_alpha) {
-			ptype = mdp4_overlay_format2type(s_pipe->src_format);
-			if (ptype == OVERLAY_TYPE_VIDEO &&
-				(!(s_pipe->flags & MDP_BACKEND_COMPOSITION))) {
-				blend->op = (MDP4_BLEND_FG_ALPHA_BG_PIXEL |
-					MDP4_BLEND_FG_INV_ALPHA);
-				if (!(s_pipe->flags & MDP_BLEND_FG_PREMULT))
-					blend->op |=
-						MDP4_BLEND_BG_ALPHA_BG_PIXEL;
-				blend->co3_sel = 0; /* use bg alpha */
-			} else {
-				/* s_pipe is rgb without alpha */
-				blend->op = (MDP4_BLEND_FG_ALPHA_FG_CONST |
-					    MDP4_BLEND_BG_ALPHA_BG_CONST);
-				blend->bg_alpha = 0;
-			}
-		}
+		__func__, i-2, d_pipe->pipe_ndx, d_pipe->alpha_enable,
+		d_pipe->alpha, s_pipe->pipe_ndx, s_pipe->alpha_enable,
+		s_pipe->alpha, s_pipe->is_fg, alpha_drop);
+		if ((s_pipe->blend_op == BLEND_OP_NOT_DEFINED) ||
+			(s_pipe->blend_op >= BLEND_OP_MAX))
+			mdp4_set_blend_by_fmt(s_pipe, d_pipe,
+				alpha_drop, blend);
+		else
+			mdp4_set_blend_by_op(s_pipe, d_pipe, alpha_drop, blend);
 
 		if (s_pipe->transp != MDP_TRANSP_NOP) {
 			if (s_pipe->is_fg) {
@@ -2085,8 +2310,10 @@
 		if (i == MDP4_MIXER_STAGE3)
 			off -= 4;
 
-		if (blend->solidfill_pipe)
+		if (blend->solidfill_pipe && blend->solidfill)
 			mdp4_overlay_bg_solidfill(blend);
+		else
+			blend->solidfill_pipe = NULL;
 
 		outpdw(overlay_base + off + 0x108, blend->fg_alpha);
 		outpdw(overlay_base + off + 0x10c, blend->bg_alpha);
@@ -2205,7 +2432,7 @@
 
 	/* No need for borderfill pipe */
 	if (pipe->pipe_type != OVERLAY_TYPE_BF)
-		mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+		mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 1);
 
 	iom = pipe->iommu;
 
@@ -2466,6 +2693,7 @@
 	pipe->is_fg = req->is_fg;/* control alpha and color key */
 
 	pipe->alpha = req->alpha & 0x0ff;
+	pipe->blend_op = req->blend_op;
 
 	pipe->transp = req->transp_mask;
 
@@ -2476,14 +2704,170 @@
 	return 0;
 }
 
+static int mdp4_calc_req_mdp_clk(struct msm_fb_data_type *mfd,
+				 u32 src_h, u32 dst_h, u32 src_w, u32 dst_w)
+{
+	u32 pclk, hsync;
+	u32 xscale, yscale;
+	u32 shift = 16;
+	u64 rst;
+
+	pr_debug("%s: pipe sets: panel res(x,y)=(%d,%d)\n",
+		 __func__,  mfd->panel_info.xres, mfd->panel_info.yres);
+
+	pr_debug("%s: src_h=%d, dst_h=%d, src_w=%d, dst_w=%d\n",
+		 __func__, src_h, dst_h, src_w, dst_w);
+
+	pclk = (mfd->panel_info.type == MIPI_VIDEO_PANEL ||
+		mfd->panel_info.type == MIPI_CMD_PANEL) ?
+		mfd->panel_info.mipi.dsi_pclk_rate :
+		mfd->panel_info.clk_rate;
+
+	if (!pclk) {
+		pr_err("%s panel pixel clk is zero!\n", __func__);
+		return mdp_max_clk;
+	}
+
+	pr_debug("%s: mdp panel pixel clk is %d.\n", __func__, pclk);
+
+	hsync = mfd->panel_info.lcdc.h_back_porch +
+		mfd->panel_info.lcdc.h_front_porch +
+		mfd->panel_info.lcdc.h_pulse_width +
+		mfd->panel_info.xres;
+
+	/*
+	 * For the scaling cases, adding extra 20% margin
+	 */
+	if ((src_h != dst_h) || (src_w != dst_w)) {
+		hsync *= 100;
+		hsync /= 120;
+	}
+
+	if (!hsync) {
+		pr_err("%s: panel hsync is zero!\n", __func__);
+		return mdp_max_clk;
+	}
+
+	pr_debug("%s: panel hsync is %d.\n", __func__, hsync);
+
+	if (!src_h) {
+		pr_err("%s: src_h is zero!\n", __func__);
+		return mdp_max_clk;
+	}
+
+	if (!dst_h) {
+		pr_err("%s: dst_h is zero!\n", __func__);
+		return mdp_max_clk;
+	}
+
+	if (!src_w) {
+		pr_err("%s: src_w is zero!\n", __func__);
+		return mdp_max_clk;
+	}
+
+	if (!dst_w) {
+		pr_err("%s: dst_w is zero!\n", __func__);
+		return mdp_max_clk;
+	}
+
+	xscale = mfd->panel_info.xres;
+	xscale += src_w;
+
+	if (xscale < dst_w) {
+		pr_err("%s: xres+src_w cannot be less than dst_w!\n",
+		       __func__);
+		return mdp_max_clk;
+	}
+
+	xscale -= dst_w;
+	xscale <<= shift;
+	xscale /= hsync;
+	pr_debug("%s: the right %d shifted xscale is %d.\n",
+		 __func__, shift, xscale);
+
+	if (src_h > dst_h) {
+		yscale = src_h;
+		yscale <<= shift;
+		yscale /= dst_h;
+	} else {		/* upscale */
+		yscale = dst_h;
+		yscale <<= shift;
+		yscale /= src_h;
+	}
+
+	yscale *= src_w;
+	yscale /= hsync;
+
+	pr_debug("%s: the right %d shifted yscale is %d.\n",
+		 __func__, shift, yscale);
+
+	rst = pclk;
+	if (yscale > xscale)
+		rst *= yscale;
+	else
+		rst *= xscale;
+
+	rst >>= shift;
+
+	/*
+	 * There is one special case for the panels that have low
+	 * v_back_porch (<=4), mdp clk should be fast enough to buffer
+	 * 4 lines input during back porch time if scaling is
+	 * required(FIR).
+	 */
+	if ((mfd->panel_info.lcdc.v_back_porch <= 4) &&
+	    (src_h != dst_h) &&
+	    (mfd->panel_info.lcdc.v_back_porch)) {
+		u32 clk = 0;
+		clk = 4 * (pclk >> shift) / mfd->panel_info.lcdc.v_back_porch;
+		clk <<= shift;
+		pr_debug("%s: mdp clk rate %d based on low vbp %d\n",
+			 __func__, clk, mfd->panel_info.lcdc.v_back_porch);
+		rst = (rst > clk) ? rst : clk;
+	}
+
+	/*
+	 * If the calculated mdp clk is less than panel pixel clk,
+	 * most likely due to upscaling, mdp clk rate will be set to
+	 * greater than pclk. Now the driver uses 1.15 as the
+	 * factor. Ideally this factor is passed from board file.
+	 */
+	if (rst < pclk) {
+		rst = ((pclk >> shift) * 23 / 20) << shift;
+		pr_debug("%s calculated mdp clk is less than pclk.\n",
+			__func__);
+	}
+	pr_debug("%s: required mdp clk %d\n", __func__, (u32)rst);
+
+	return (u32)rst;
+}
+
+static int mdp4_calc_req_blt(struct msm_fb_data_type *mfd,
+			     struct mdp_overlay *req)
+{
+	int ret = 0;
+
+	if (!req) {
+		pr_err("%s: req is null!\n", __func__);
+		return ret;
+	}
+
+	if (!mfd) {
+		pr_err("%s: mfd is null!\n", __func__);
+		return ret;
+	}
+
+	if (mdp4_calc_req_mdp_clk
+		(mfd, req->src_rect.h, req->dst_rect.h,
+		 req->src_rect.w, req->dst_rect.w) > mdp_max_clk)
+		ret = -EINVAL;
+
+	return ret;
+}
+
 static int mdp4_calc_pipe_mdp_clk(struct msm_fb_data_type *mfd,
 				  struct mdp4_overlay_pipe *pipe)
 {
-	u32 pclk;
-	u32 xscale, yscale;
-	u32 hsync = 0;
-	u32 shift = 16;
-	u64 rst;
 	int ret = -EINVAL;
 
 	if (!pipe) {
@@ -2506,146 +2890,13 @@
 		return 0;
 	}
 
-	pr_debug("%s: pipe sets: panel res(x,y)=(%d,%d)\n",
-		 __func__,  mfd->panel_info.xres, mfd->panel_info.yres);
 	pr_debug("%s: src(w,h)(%d,%d),src(x,y)(%d,%d)\n",
 		 __func__,  pipe->src_w, pipe->src_h, pipe->src_x, pipe->src_y);
 	pr_debug("%s: dst(w,h)(%d,%d),dst(x,y)(%d,%d)\n",
 		 __func__, pipe->dst_w, pipe->dst_h, pipe->dst_x, pipe->dst_y);
 
-	pclk = (mfd->panel_info.type == MIPI_VIDEO_PANEL ||
-		mfd->panel_info.type == MIPI_CMD_PANEL) ?
-		mfd->panel_info.mipi.dsi_pclk_rate :
-		mfd->panel_info.clk_rate;
-	if (!pclk) {
-		pipe->req_clk = mdp_max_clk;
-		pr_err("%s panel pixel clk is zero!\n", __func__);
-		return ret;
-	}
-	pr_debug("%s: mdp panel pixel clk is %d.\n",
-		 __func__, pclk);
-
-	if (!pipe->dst_h) {
-		pr_err("%s: pipe dst_h is zero!\n", __func__);
-		pipe->req_clk = mdp_max_clk;
-		return ret;
-	}
-
-	if (!pipe->src_h) {
-		pr_err("%s: pipe src_h is zero!\n", __func__);
-		pipe->req_clk = mdp_max_clk;
-		return ret;
-	}
-
-	if (!pipe->dst_w) {
-		pr_err("%s: pipe dst_w is zero!\n", __func__);
-		pipe->req_clk = mdp_max_clk;
-		return ret;
-	}
-
-	if (!pipe->dst_h) {
-		pr_err("%s: pipe dst_h is zero!\n", __func__);
-		pipe->req_clk = mdp_max_clk;
-		return ret;
-	}
-
-	/*
-	 * For the scaling cases, make more margin by removing porch
-	 * values and adding extra 20%.
-	 */
-	if ((pipe->src_h != pipe->dst_h) ||
-	    (pipe->src_w != pipe->dst_w)) {
-		hsync = mfd->panel_info.xres;
-		hsync *= 100;
-		hsync /= 120;
-		pr_debug("%s: panel hsync is %d. with scaling\n",
-			__func__, hsync);
-
-	} else {
-		hsync = mfd->panel_info.lcdc.h_back_porch +
-			mfd->panel_info.lcdc.h_front_porch +
-			mfd->panel_info.lcdc.h_pulse_width +
-			mfd->panel_info.xres;
-		pr_debug("%s: panel hsync is %d.\n",
-			__func__, hsync);
-	}
-
-	if (!hsync) {
-		pipe->req_clk = mdp_max_clk;
-		pr_err("%s: panel hsync is zero!\n", __func__);
-		return 0;
-	}
-
-	xscale = mfd->panel_info.xres;
-	xscale += pipe->src_w;
-
-	if (xscale < pipe->dst_w) {
-		pipe->req_clk = mdp_max_clk;
-		pr_err("%s: xres+src_w cannot be less than dst_w!\n",
-		       __func__);
-		return ret;
-	}
-
-	xscale -= pipe->dst_w;
-	xscale <<= shift;
-	xscale /= hsync;
-	pr_debug("%s: the right %d shifted xscale is %d.\n",
-		 __func__, shift, xscale);
-
-	if (pipe->src_h > pipe->dst_h) {
-		yscale = pipe->src_h;
-		yscale <<= shift;
-		yscale /= pipe->dst_h;
-	} else {		/* upscale */
-		yscale = pipe->dst_h;
-		yscale <<= shift;
-		yscale /= pipe->src_h;
-	}
-
-	yscale *= pipe->src_w;
-	yscale /= hsync;
-
-	pr_debug("%s: the right %d shifted yscale is %d.\n",
-		 __func__, shift, yscale);
-
-	rst = pclk;
-	if (yscale > xscale)
-		rst *= yscale;
-	else
-		rst *= xscale;
-
-	rst >>= shift;
-
-	/*
-	 * There is one special case for the panels that have low
-	 * v_back_porch (<=4), mdp clk should be fast enough to buffer
-	 * 4 lines input during back porch time if scaling is
-	 * required(FIR).
-	 */
-	if ((mfd->panel_info.lcdc.v_back_porch <= 4) &&
-	    (pipe->src_h != pipe->dst_h) &&
-	    (mfd->panel_info.lcdc.v_back_porch)) {
-		u32 clk = 0;
-		clk = 4 * (pclk >> shift) / mfd->panel_info.lcdc.v_back_porch;
-		clk <<= shift;
-		pr_debug("%s: mdp clk rate %d based on low vbp %d\n",
-			 __func__, clk, mfd->panel_info.lcdc.v_back_porch);
-		rst = (rst > clk) ? rst : clk;
-	}
-
-	/*
-	 * If the calculated mdp clk is less than panel pixel clk,
-	 * most likely due to upscaling, mdp clk rate will be set to
-	 * greater than pclk. Now the driver uses 1.15 as the
-	 * factor. Ideally this factor is passed from board file.
-	 */
-	if (rst < pclk) {
-		rst = ((pclk >> shift) * 23 / 20) << shift;
-		pr_debug("%s calculated mdp clk is less than pclk.\n",
-			__func__);
-	}
-
-	pipe->req_clk = (u32) rst;
+	pipe->req_clk = mdp4_calc_req_mdp_clk
+		(mfd, pipe->src_h, pipe->dst_h, pipe->src_w, pipe->dst_w);
 
 	pr_debug("%s: required mdp clk %d mixer %d pipe ndx %d\n",
 		 __func__, pipe->req_clk, pipe->mixer_num, pipe->pipe_ndx);
@@ -2674,10 +2925,12 @@
 	quota = pipe->src_w * pipe->src_h * fps * pipe->bpp;
 
 	quota >>= shift;
-	/* factor 1.15 for ab */
-	pipe->bw_ab_quota = quota * MDP4_BW_AB_FACTOR / 100;
-	/* factor 1.25 for ib */
-	pipe->bw_ib_quota = quota * MDP4_BW_IB_FACTOR / 100;
+
+	pipe->bw_ab_quota = quota * mdp_bw_ab_factor / 100;
+	pipe->bw_ib_quota = quota * mdp_bw_ib_factor / 100;
+	pr_debug("%s max_bw=%llu ab_factor=%d ib_factor=%d\n", __func__,
+		mdp_max_bw, mdp_bw_ab_factor, mdp_bw_ib_factor);
+
 	/* down scaling factor for ib */
 	if ((pipe->dst_h) && (pipe->src_h) &&
 	    (pipe->src_h > pipe->dst_h)) {
@@ -2728,10 +2981,10 @@
 	quota >>= shift;
 
 	perf_req->mdp_ov_ab_bw[pipe->mixer_num] =
-		quota * MDP4_BW_AB_FACTOR / 100;
+		quota * mdp_bw_ab_factor / 100;
 
 	perf_req->mdp_ov_ib_bw[pipe->mixer_num] =
-		quota * MDP4_BW_IB_FACTOR / 100;
+		quota * mdp_bw_ib_factor / 100;
 
 	perf_req->mdp_ov_ab_bw[pipe->mixer_num] <<= shift;
 	perf_req->mdp_ov_ib_bw[pipe->mixer_num] <<= shift;
@@ -2747,13 +3000,12 @@
 	return 0;
 }
 
-int mdp4_overlay_mdp_perf_req(struct msm_fb_data_type *mfd,
-			      struct mdp4_overlay_pipe *plist)
+int mdp4_overlay_mdp_perf_req(struct msm_fb_data_type *mfd)
 {
 	u32 worst_mdp_clk = 0;
 	int i;
 	struct mdp4_overlay_perf *perf_req = &perf_request;
-	struct mdp4_overlay_pipe *pipe = plist;
+	struct mdp4_overlay_pipe *pipe;
 	u32 cnt = 0;
 	int ret = -EINVAL;
 	u64 ab_quota_total = 0, ib_quota_total = 0;
@@ -2763,10 +3015,7 @@
 		return ret;
 	}
 
-	if (!plist) {
-		pr_err("%s: plist is null!\n", __func__);
-		return ret;
-	}
+	pipe = ctrl->plist;
 
 	for (i = 0; i < MDP4_MIXER_MAX; i++)
 		perf_req->use_ov_blt[i] = 0;
@@ -3116,6 +3365,14 @@
 
 	mixer = mfd->panel_info.pdest;	/* DISPLAY_1 or DISPLAY_2 */
 
+	ret = mdp4_calc_req_blt(mfd, req);
+
+	if (ret < 0) {
+		mutex_unlock(&mfd->dma->ov_mutex);
+		pr_err("%s: blt mode is required! ret=%d\n", __func__, ret);
+		return ret;
+	}
+
 	ret = mdp4_overlay_req2pipe(req, mixer, &pipe, mfd);
 
 	if (ret < 0) {
@@ -3124,6 +3381,11 @@
 		return ret;
 	}
 
+	if (pipe->flags & MDP_SECURE_OVERLAY_SESSION) {
+		mdp4_map_sec_resource(mfd);
+		mfd->sec_active = TRUE;
+	}
+
 	/* return id back to user */
 	req->id = pipe->pipe_ndx;	/* pipe_ndx start from 1 */
 	pipe->req_data = *req;		/* keep original req */
@@ -3139,10 +3401,6 @@
 		}
 	}
 
-	if (pipe->flags & MDP_SECURE_OVERLAY_SESSION) {
-		mdp4_map_sec_resource();
-		ctrl->sec_active = TRUE;
-	}
 	mdp4_stat.overlay_set[pipe->mixer_num]++;
 
 	if (pipe->flags & MDP_OVERLAY_PP_CFG_EN) {
@@ -3242,7 +3500,7 @@
 	mdp4_stat.overlay_unset[pipe->mixer_num]++;
 
 	if (pipe->flags & MDP_SECURE_OVERLAY_SESSION)
-		ctrl->sec_active = FALSE;
+		mfd->sec_active = FALSE;
 	mdp4_overlay_pipe_free(pipe);
 
 	mutex_unlock(&mfd->dma->ov_mutex);
@@ -3269,6 +3527,13 @@
 int mdp4_overlay_vsync_ctrl(struct fb_info *info, int enable)
 {
 	int cmd;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	if (mfd == NULL)
+		return -ENODEV;
+
+	if (!mfd->panel_power_on)
+		return -EINVAL;
 
 	if (enable)
 		cmd = 1;
@@ -3496,7 +3761,7 @@
 		}
 	}
 
-	mdp4_overlay_mdp_perf_req(mfd, ctrl->plist);
+	mdp4_overlay_mdp_perf_req(mfd);
 
 	if (pipe->mixer_num == MDP4_MIXER0) {
 		if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
@@ -3569,7 +3834,7 @@
 	msm_fb_signal_timeline(mfd);
 
 	mdp4_overlay_mdp_perf_upd(mfd, 0);
-	mdp4_unmap_sec_resource();
+	mdp4_unmap_sec_resource(mfd);
 	mutex_unlock(&mfd->dma->ov_mutex);
 
 	return ret;
diff --git a/drivers/video/msm/mdp4_overlay_atv.c b/drivers/video/msm/mdp4_overlay_atv.c
index 90c3da9..4cbac09 100644
--- a/drivers/video/msm/mdp4_overlay_atv.c
+++ b/drivers/video/msm/mdp4_overlay_atv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 5877719..81c73e7 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -41,6 +41,8 @@
  */
 #define VSYNC_EXPIRE_TICK 4
 
+#define VSYNC_MIN_DIFF_MS 4
+
 static struct vsycn_ctrl {
 	struct device *dev;
 	int inited;
@@ -70,9 +72,9 @@
 	struct vsync_update vlist[2];
 	int vsync_enabled;
 	int clk_enabled;
-	int new_update;
 	int clk_control;
 	ktime_t vsync_time;
+	u32 last_vsync_ms;
 	struct work_struct clk_work;
 } vsync_ctrl_db[MAX_CONTROLLER];
 
@@ -155,7 +157,7 @@
 	int cndx = 0;
 	struct vsycn_ctrl *vctrl;
 	struct mdp4_overlay_pipe *pipe;
-	int need_wait;
+	int need_wait = 0;
 
 	vctrl = &vsync_ctrl_db[cndx];
 	pipe = vctrl->base_pipe;
@@ -250,6 +252,21 @@
 	mdp4_stat.overlay_play[pipe->mixer_num]++;
 }
 
+static void mdp4_dsi_cmd_pipe_clean(struct vsync_update *vp)
+{
+	struct mdp4_overlay_pipe *pipe;
+	int i;
+
+	pipe = vp->plist;
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+			pipe->pipe_used = 0; /* clear */
+		}
+	}
+	vp->update_cnt = 0;     /* empty queue */
+}
+
 static void mdp4_dsi_cmd_blt_ov_update(struct mdp4_overlay_pipe *pipe);
 static int mdp4_dsi_cmd_clk_check(struct vsycn_ctrl *vctrl);
 
@@ -272,6 +289,12 @@
 	undx =  vctrl->update_ndx;
 	vp = &vctrl->vlist[undx];
 	pipe = vctrl->base_pipe;
+	if (pipe == NULL) {
+		pr_err("%s: NO base pipe\n", __func__);
+		mutex_unlock(&vctrl->update_lock);
+		return 0;
+	}
+
 	mixer = pipe->mixer_num;
 
 	mdp_update_pm(vctrl->mfd, vctrl->vsync_time);
@@ -290,10 +313,13 @@
 		if (vctrl->blt_free == 0)
 			mdp4_free_writeback_buf(vctrl->mfd, mixer);
 	}
-	mutex_unlock(&vctrl->update_lock);
 
-	if (mdp4_dsi_cmd_clk_check(vctrl) < 0)
+	if (mdp4_dsi_cmd_clk_check(vctrl) < 0) {
+		mdp4_dsi_cmd_pipe_clean(vp);
+		mutex_unlock(&vctrl->update_lock);
 		return 0;
+	}
+	mutex_unlock(&vctrl->update_lock);
 
 	/* free previous committed iommu back to pool */
 	mdp4_overlay_iommu_unmap_freelist(mixer);
@@ -384,7 +410,7 @@
 	pr_debug("%s: kickoff, pid=%d\n", __func__, current->pid);
 	/* kickoff overlay engine */
 	mdp4_stat.kickoff_ov0++;
-	outpdw(MDP_BASE + 0x0004, 0);
+	mdp_pipe_kickoff_simplified(MDP_OVERLAY0_TERM);
 	mb(); /* make sure kickoff ececuted */
 	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
 
@@ -428,8 +454,9 @@
 			mipi_dsi_clk_cfg(1);
 			mdp_clk_ctrl(1);
 			vctrl->clk_enabled = 1;
-			vctrl->new_update = 1;
 			clk_set_on = 1;
+			vctrl->last_vsync_ms =
+				ktime_to_ms(ktime_get()) - VSYNC_MIN_DIFF_MS;
 		}
 		if (clk_set_on) {
 			vsync_irq_enable(INTR_PRIMARY_RDPTR,
@@ -512,6 +539,8 @@
 static void primary_rdptr_isr(int cndx)
 {
 	struct vsycn_ctrl *vctrl;
+	u32 cur_vsync_ms;
+	int vsync_diff;
 
 	vctrl = &vsync_ctrl_db[cndx];
 	pr_debug("%s: ISR, tick=%d pan=%d cpu=%d\n", __func__,
@@ -520,13 +549,15 @@
 
 	spin_lock(&vctrl->spin_lock);
 	vctrl->vsync_time = ktime_get();
+	cur_vsync_ms =  ktime_to_ms(vctrl->vsync_time);
+	vsync_diff = (int)(cur_vsync_ms - vctrl->last_vsync_ms);
 
-	if (vctrl->new_update) {
-		vctrl->new_update = 0;
+	if ((vsync_diff >= 0) && (vsync_diff < VSYNC_MIN_DIFF_MS)) {
 		spin_unlock(&vctrl->spin_lock);
 		return;
 	}
 
+	vctrl->last_vsync_ms = cur_vsync_ms;
 	complete_all(&vctrl->vsync_comp);
 	vctrl->wait_vsync_cnt = 0;
 
@@ -746,6 +777,7 @@
 
 	tear_en = (1 << which);
 
+	mdp_clk_ctrl(1);
 	if ((mfd->use_mdp_vsync) && (mfd->ibuf.vsync_enable) &&
 		(mfd->panel_info.lcd.vsync_enable)) {
 
@@ -767,6 +799,28 @@
 		data &= ~tear_en;
 		MDP_OUTP(MDP_BASE + 0x20c, data);
 	}
+	mdp_clk_ctrl(0);
+}
+
+void mdp4_dsi_cmd_free_base_pipe(struct msm_fb_data_type *mfd)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[0];
+	pipe = vctrl->base_pipe;
+
+	if (pipe == NULL)
+		return ;
+	/* adb stop */
+	if (pipe->pipe_type == OVERLAY_TYPE_BF)
+		mdp4_overlay_borderfill_stage_down(pipe);
+
+	/* base pipe may change after borderfill_stage_down */
+	pipe = vctrl->base_pipe;
+	mdp4_mixer_stage_down(pipe, 1);
+	mdp4_overlay_pipe_free(pipe);
+	vctrl->base_pipe = NULL;
 }
 
 void mdp4_dsi_cmd_base_swap(int cndx, struct mdp4_overlay_pipe *pipe)
@@ -874,6 +928,8 @@
 	/* disable dsi trigger */
 	MDP_OUTP(MDP_BASE + 0x000a4, 0x00);
 
+	mdp4_overlay_solidfill_init(pipe);
+
 	mdp4_overlay_setup_pipe_addr(mfd, pipe);
 
 	mdp4_overlay_rgb_setup(pipe);
@@ -999,9 +1055,12 @@
 	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
 	mfd->cont_splash_done = 1;
 
+	mutex_lock(&mfd->dma->ov_mutex);
+
 	vctrl = &vsync_ctrl_db[cndx];
 	vctrl->mfd = mfd;
 	vctrl->dev = mfd->fbi->dev;
+	vctrl->vsync_enabled = 0;
 
 	mdp_clk_ctrl(1);
 	mdp4_overlay_update_dsi_cmd(mfd);
@@ -1011,6 +1070,8 @@
 
 	atomic_set(&vctrl->suspend, 0);
 
+	mutex_unlock(&mfd->dma->ov_mutex);
+
 	pr_debug("%s-:\n", __func__);
 
 	return ret;
@@ -1027,21 +1088,24 @@
 	int undx;
 	int need_wait, cnt;
 	unsigned long flags;
+	int mixer = 0;
 
 	pr_debug("%s+: pid=%d\n", __func__, current->pid);
 
 	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
 
+	mutex_lock(&mfd->dma->ov_mutex);
+
 	vctrl = &vsync_ctrl_db[cndx];
 	pipe = vctrl->base_pipe;
 	if (pipe == NULL) {
 		pr_err("%s: NO base pipe\n", __func__);
+		mutex_unlock(&mfd->dma->ov_mutex);
 		return ret;
 	}
 
 	need_wait = 0;
 	mutex_lock(&vctrl->update_lock);
-	atomic_set(&vctrl->suspend, 1);
 
 	complete_all(&vctrl->vsync_comp);
 
@@ -1072,14 +1136,6 @@
 		pr_err("%s: Error, SET_CLK_OFF by force\n", __func__);
 	}
 
-	/* sanity check, free pipes besides base layer */
-	mdp4_overlay_unset_mixer(pipe->mixer_num);
-	mdp4_mixer_stage_down(pipe, 1);
-	if (mfd->ref_cnt == 0) {
-		mdp4_overlay_pipe_free(pipe);
-		vctrl->base_pipe = NULL;
-	}
-
 	if (vctrl->vsync_enabled) {
 		vsync_irq_disable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
 		vctrl->vsync_enabled = 0;
@@ -1092,46 +1148,45 @@
 		 * pipe's iommu will be freed at next overlay play
 		 * and iommu_drop statistic will be increased by one
 		 */
-		vp->update_cnt = 0;     /* empty queue */
+		pr_warn("%s: update_cnt=%d\n", __func__, vp->update_cnt);
+		mdp4_dsi_cmd_pipe_clean(vp);
 	}
 
-	undx =  vctrl->update_ndx;
-	vp = &vctrl->vlist[undx];
-	if (vp->update_cnt) {
-		/*
-		 * pipe's iommu will be freed at next overlay play
-		 * and iommu_drop statistic will be increased by one
-		 */
-		vp->update_cnt = 0;     /* empty queue */
-	}
-
-	pr_debug("%s-:\n", __func__);
-	return ret;
-}
-
-void mdp_dsi_cmd_overlay_suspend(struct msm_fb_data_type *mfd)
-{
-	int cndx = 0;
-	struct vsycn_ctrl *vctrl;
-	struct mdp4_overlay_pipe *pipe;
-
-	vctrl = &vsync_ctrl_db[cndx];
-	pipe = vctrl->base_pipe;
-	/* dis-engage rgb0 from mixer0 */
 	if (pipe) {
+		/* sanity check, free pipes besides base layer */
+		mixer = pipe->mixer_num;
+		mdp4_overlay_unset_mixer(mixer);
 		if (mfd->ref_cnt == 0) {
 			/* adb stop */
 			if (pipe->pipe_type == OVERLAY_TYPE_BF)
 				mdp4_overlay_borderfill_stage_down(pipe);
 
-			/* pipe == rgb1 */
-			mdp4_overlay_unset_mixer(pipe->mixer_num);
+			/* base pipe may change after borderfill_stage_down */
+			pipe = vctrl->base_pipe;
+			mdp4_mixer_stage_down(pipe, 1);
+			mdp4_overlay_pipe_free(pipe);
 			vctrl->base_pipe = NULL;
 		} else {
+			/* system suspending */
 			mdp4_mixer_stage_down(pipe, 1);
 			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 1);
 		}
 	}
+
+	atomic_set(&vctrl->suspend, 1);
+
+	/*
+	 * clean up ion freelist
+	 * there need two stage to empty ion free list
+	 * therefore need call unmap freelist twice
+	 */
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+
+	mutex_unlock(&mfd->dma->ov_mutex);
+
+	pr_debug("%s-:\n", __func__);
+	return ret;
 }
 
 static int mdp4_dsi_cmd_clk_check(struct vsycn_ctrl *vctrl)
@@ -1139,9 +1194,7 @@
 	int clk_set_on = 0;
 	unsigned long flags;
 
-	mutex_lock(&vctrl->update_lock);
 	if (atomic_read(&vctrl->suspend)) {
-		mutex_unlock(&vctrl->update_lock);
 		pr_err("%s: suspended, no more pan display\n", __func__);
 		return -EPERM;
 	}
@@ -1163,8 +1216,6 @@
 		vsync_irq_enable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
 	}
 
-	mutex_unlock(&vctrl->update_lock);
-
 	return 0;
 }
 
@@ -1189,11 +1240,6 @@
 		return;
 	}
 
-	if (mdp4_dsi_cmd_clk_check(vctrl) < 0) {
-		mutex_unlock(&mfd->dma->ov_mutex);
-		return;
-	}
-
 	if (pipe->mixer_stage == MDP4_MIXER_STAGE_BASE) {
 		mdp4_mipi_vsync_enable(mfd, pipe, 0);
 		mdp4_overlay_setup_pipe_addr(mfd, pipe);
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index a98bf35..4abc019 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -42,6 +42,7 @@
 static int first_pixel_start_x;
 static int first_pixel_start_y;
 static int dsi_video_enabled;
+static int vsync_irq_cnt;
 
 #define MAX_CONTROLLER	1
 
@@ -144,6 +145,21 @@
 	mdp4_stat.overlay_play[pipe->mixer_num]++;
 }
 
+static void mdp4_dsi_video_pipe_clean(struct vsync_update *vp)
+{
+	struct mdp4_overlay_pipe *pipe;
+	int i;
+
+	pipe = vp->plist;
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+			pipe->pipe_used = 0; /* clear */
+		}
+	}
+	vp->update_cnt = 0;     /* empty queue */
+}
+
 static void mdp4_dsi_video_blt_ov_update(struct mdp4_overlay_pipe *pipe);
 static void mdp4_dsi_video_wait4dmap(int cndx);
 static void mdp4_dsi_video_wait4ov(int cndx);
@@ -166,6 +182,12 @@
 	undx =  vctrl->update_ndx;
 	vp = &vctrl->vlist[undx];
 	pipe = vctrl->base_pipe;
+	if (pipe == NULL) {
+		pr_err("%s: NO base pipe\n", __func__);
+		mutex_unlock(&vctrl->update_lock);
+		return 0;
+	}
+
 	mixer = pipe->mixer_num;
 
 	mdp_update_pm(vctrl->mfd, vctrl->vsync_time);
@@ -186,9 +208,6 @@
 	}
 	mutex_unlock(&vctrl->update_lock);
 
-	/* free previous committed iommu back to pool */
-	mdp4_overlay_iommu_unmap_freelist(mixer);
-
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
 	if (vctrl->ov_koff != vctrl->ov_done) {
 		spin_unlock_irqrestore(&vctrl->spin_lock, flags);
@@ -217,9 +236,38 @@
 			cnt++;
 			real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
 			if (real_pipe && real_pipe->pipe_used) {
-				/* pipe not unset */
+				/*
+				 * commit pipes which are in pending queue
+				 * and not be unset yet
+				 */
 				mdp4_overlay_vsync_commit(pipe);
 			}
+		}
+	}
+
+	mdp4_mixer_stage_commit(mixer);
+
+	/* start timing generator & mmu if they are not started yet */
+	mdp4_overlay_dsi_video_start();
+
+	/*
+	 * there has possibility that pipe commit come very close to next vsync
+	 * this may cause two consecutive pie_commits happen within same vsync
+	 * period which casue iommu page fault when previous iommu buffer
+	 * freed. Set ION_IOMMU_UNMAP_DELAYED flag at ion_map_iommu() to
+	 * add delay unmap iommu buffer to fix this problem.
+	 * Also ion_unmap_iommu() may take as long as 9 ms to free an ion buffer.
+	 * therefore mdp4_overlay_iommu_unmap_freelist(mixer) should be called
+	 * ater stage_commit() to ensure pipe_commit (up to stage_commit)
+	 * is completed within vsync period.
+	 */
+
+	/* free previous committed iommu back to pool */
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+
+	pipe = vp->plist;
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
 			/* free previous iommu to freelist
 			* which will be freed at next
 			* pipe_commit
@@ -229,11 +277,6 @@
 		}
 	}
 
-	mdp4_mixer_stage_commit(mixer);
-
-	/* start timing generator & mmu if they are not started yet */
-	mdp4_overlay_dsi_video_start();
-
 	pipe = vctrl->base_pipe;
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
 	if (pipe->ov_blt_addr) {
@@ -268,7 +311,6 @@
 static void mdp4_video_vsync_irq_ctrl(int cndx, int enable)
 {
 	struct vsycn_ctrl *vctrl;
-	static int vsync_irq_cnt;
 
 	vctrl = &vsync_ctrl_db[cndx];
 
@@ -284,6 +326,8 @@
 			if (vsync_irq_cnt == 0)
 				vsync_irq_disable(INTR_PRIMARY_VSYNC,
 						MDP_PRIM_VSYNC_TERM);
+			vctrl->wait_vsync_cnt = 0;
+			complete_all(&vctrl->vsync_comp);
 		}
 	}
 	pr_debug("%s: enable=%d cnt=%d\n", __func__, enable, vsync_irq_cnt);
@@ -315,6 +359,7 @@
 	struct vsycn_ctrl *vctrl;
 	struct mdp4_overlay_pipe *pipe;
 	unsigned long flags;
+	int ret;
 
 	if (cndx >= MAX_CONTROLLER) {
 		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
@@ -335,8 +380,12 @@
 
 	vctrl->wait_vsync_cnt++;
 	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+	/* double the timeout in vsync time stamp generation */
+	ret = wait_for_completion_interruptible_timeout(&vctrl->vsync_comp,
+		msecs_to_jiffies(VSYNC_PERIOD * 8));
+	if (ret <= 0)
+		pr_err("%s timeout ret=%d", __func__, ret);
 
-	wait_for_completion(&vctrl->vsync_comp);
 	mdp4_video_vsync_irq_ctrl(cndx, 0);
 	mdp4_stat.wait4vsync0++;
 }
@@ -403,6 +452,10 @@
 	ssize_t ret = 0;
 	unsigned long flags;
 	u64 vsync_tick;
+	ktime_t ctime;
+	u32 ctick, ptick;
+	int diff;
+
 
 	cndx = 0;
 	vctrl = &vsync_ctrl_db[0];
@@ -411,6 +464,29 @@
 		atomic_read(&vctrl->vsync_resume) == 0)
 		return 0;
 
+	/*
+	 * show_event thread keep spinning on vctrl->vsync_comp
+	 * race condition on x.done if multiple thread blocked
+	 * at wait_for_completion(&vctrl->vsync_comp)
+	 *
+	 * if show_event thread waked up first then it will come back
+	 * and call INIT_COMPLETION(vctrl->vsync_comp) which set x.done = 0
+	 * then second thread wakeed up which set x.done = 0x7ffffffd
+	 * after that wait_for_completion will never wait.
+	 * To avoid this, force show_event thread to sleep 5 ms here
+	 * since it has full vsycn period (16.6 ms) to wait
+	 */
+	ctime = ktime_get();
+	ctick = (u32)ktime_to_us(ctime);
+	ptick = (u32)ktime_to_us(vctrl->vsync_time);
+	ptick += 5000;	/* 5ms */
+	diff = ptick - ctick;
+	if (diff > 0) {
+		if (diff > 1000) /* 1 ms */
+			diff = 1000;
+		usleep(diff);
+	}
+
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
 	if (vctrl->wait_vsync_cnt == 0)
 		INIT_COMPLETION(vctrl->vsync_comp);
@@ -419,6 +495,7 @@
 	ret = wait_for_completion_interruptible_timeout(&vctrl->vsync_comp,
 		msecs_to_jiffies(VSYNC_PERIOD * 4));
 	if (ret <= 0) {
+		complete_all(&vctrl->vsync_comp);
 		vctrl->wait_vsync_cnt = 0;
 		vctrl->vsync_time = ktime_get();
 	}
@@ -458,6 +535,27 @@
 	spin_lock_init(&vctrl->spin_lock);
 }
 
+void mdp4_dsi_video_free_base_pipe(struct msm_fb_data_type *mfd)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[0];
+	pipe = vctrl->base_pipe;
+
+	if (pipe == NULL)
+		return ;
+	/* adb stop */
+	if (pipe->pipe_type == OVERLAY_TYPE_BF)
+		mdp4_overlay_borderfill_stage_down(pipe);
+
+	/* base pipe may change after borderfill_stage_down */
+	pipe = vctrl->base_pipe;
+	mdp4_mixer_stage_down(pipe, 1);
+	mdp4_overlay_pipe_free(pipe);
+	vctrl->base_pipe = NULL;
+}
+
 void mdp4_dsi_video_base_swap(int cndx, struct mdp4_overlay_pipe *pipe)
 {
 	struct vsycn_ctrl *vctrl;
@@ -471,6 +569,27 @@
 	vctrl->base_pipe = pipe;
 }
 
+/* timing generator off */
+static void mdp4_dsi_video_tg_off(struct vsycn_ctrl *vctrl)
+{
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0); /* turn off timing generator */
+	/* some delay after turning off the tg */
+	msleep(20);
+}
+
+int mdp4_dsi_video_splash_done(void)
+{
+	struct vsycn_ctrl *vctrl;
+	int cndx = 0;
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	mdp4_dsi_video_tg_off(vctrl);
+	mipi_dsi_controller_cfg(0);
+
+	return 0;
+}
+
 int mdp4_dsi_video_on(struct platform_device *pdev)
 {
 	int dsi_width;
@@ -525,9 +644,13 @@
 	if (mfd->key != MFD_KEY)
 		return -EINVAL;
 
+	mutex_lock(&mfd->dma->ov_mutex);
+
 	vctrl->mfd = mfd;
 	vctrl->dev = mfd->fbi->dev;
 	vctrl->blt_ctrl = pinfo->lcd.blt_ctrl;
+	vctrl->vsync_irq_enabled = 0;
+	vsync_irq_cnt = 0;
 
 	/* mdp clock on */
 	mdp_clk_ctrl(1);
@@ -546,6 +669,7 @@
 		pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0);
 		if (pipe == NULL) {
 			printk(KERN_INFO "%s: pipe_alloc failed\n", __func__);
+			mutex_unlock(&mfd->dma->ov_mutex);
 			return -EBUSY;
 		}
 		pipe->pipe_used++;
@@ -568,16 +692,6 @@
 
 	atomic_set(&vctrl->suspend, 0);
 
-	if (!(mfd->cont_splash_done)) {
-		mfd->cont_splash_done = 1;
-		MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0);
-		mdp4_dsi_video_wait4vsync(0);
-		mipi_dsi_controller_cfg(0);
-		/* Clks are enabled in probe.
-		   Disabling clocks now */
-		mdp_clk_ctrl(0);
-	}
-
 	pipe->src_height = fbi->var.yres;
 	pipe->src_width = fbi->var.xres;
 	pipe->src_h = fbi->var.yres;
@@ -597,6 +711,8 @@
 	pipe->dst_h = fbi->var.yres;
 	pipe->dst_w = fbi->var.xres;
 
+	mdp4_overlay_solidfill_init(pipe);
+
 	mdp4_overlay_mdp_pipe_req(pipe, mfd);
 	mdp4_calc_blt_mdp_bw(mfd, pipe);
 
@@ -688,6 +804,7 @@
 
 	mdp_histogram_ctrl_all(TRUE);
 	mdp4_overlay_dsi_video_start();
+	mutex_unlock(&mfd->dma->ov_mutex);
 
 	return ret;
 }
@@ -701,18 +818,21 @@
 	struct mdp4_overlay_pipe *pipe;
 	struct vsync_update *vp;
 	unsigned long flags;
+	int mixer = 0;
 	int undx, need_wait = 0;
 
 	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	mutex_lock(&mfd->dma->ov_mutex);
 	vctrl = &vsync_ctrl_db[cndx];
 	pipe = vctrl->base_pipe;
 
-	atomic_set(&vctrl->suspend, 1);
-	atomic_set(&vctrl->vsync_resume, 0);
-
 	mdp4_dsi_video_wait4vsync(cndx);
 
+	atomic_set(&vctrl->vsync_resume, 0);
+
 	complete_all(&vctrl->vsync_comp);
+	vctrl->wait_vsync_cnt = 0;
 
 	if (pipe->ov_blt_addr) {
 		spin_lock_irqsave(&vctrl->spin_lock, flags);
@@ -725,8 +845,6 @@
 
 	mdp_histogram_ctrl_all(FALSE);
 
-	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0);
-
 	dsi_video_enabled = 0;
 
 	undx =  vctrl->update_ndx;
@@ -736,22 +854,14 @@
 		 * pipe's iommu will be freed at next overlay play
 		 * and iommu_drop statistic will be increased by one
 		 */
-		vp->update_cnt = 0;     /* empty queue */
-	}
-
-	undx =  vctrl->update_ndx;
-	vp = &vctrl->vlist[undx];
-	if (vp->update_cnt) {
-		/*
-		 * pipe's iommu will be freed at next overlay play
-		 * and iommu_drop statistic will be increased by one
-		 */
-		vp->update_cnt = 0;     /* empty queue */
+		pr_warn("%s: update_cnt=%d\n", __func__, vp->update_cnt);
+		mdp4_dsi_video_pipe_clean(vp);
 	}
 
 	if (pipe) {
 		/* sanity check, free pipes besides base layer */
-		mdp4_overlay_unset_mixer(pipe->mixer_num);
+		mixer = pipe->mixer_num;
+		mdp4_overlay_unset_mixer(mixer);
 		if (mfd->ref_cnt == 0) {
 			/* adb stop */
 			if (pipe->pipe_type == OVERLAY_TYPE_BF)
@@ -762,7 +872,6 @@
 			mdp4_mixer_stage_down(pipe, 1);
 			mdp4_overlay_pipe_free(pipe);
 			vctrl->base_pipe = NULL;
-			msleep(20);
 		} else {
 			/* system suspending */
 			mdp4_mixer_stage_down(vctrl->base_pipe, 1);
@@ -771,15 +880,29 @@
 		}
 	}
 
+	mdp4_dsi_video_tg_off(vctrl);
+
+	atomic_set(&vctrl->suspend, 1);
+
 	if (vctrl->vsync_irq_enabled) {
 		vctrl->vsync_irq_enabled = 0;
-		vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
+		mdp4_video_vsync_irq_ctrl(cndx, 0);
 	}
 
+	/*
+	 * clean up ion freelist
+	 * there need two stage to empty ion free list
+	 * therefore need call unmap freelist twice
+	 */
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+
 	/* mdp clock off */
 	mdp_clk_ctrl(0);
 	mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 
+	mutex_unlock(&mfd->dma->ov_mutex);
+
 	return ret;
 }
 
@@ -935,18 +1058,15 @@
 	int cndx;
 	struct vsycn_ctrl *vctrl;
 
-
 	cndx = 0;
 	vctrl = &vsync_ctrl_db[cndx];
 	pr_debug("%s: cpu=%d\n", __func__, smp_processor_id());
 
 	spin_lock(&vctrl->spin_lock);
-	vctrl->vsync_time = ktime_get();
 
-	if (vctrl->wait_vsync_cnt) {
-		complete_all(&vctrl->vsync_comp);
-		vctrl->wait_vsync_cnt = 0;
-	}
+	vctrl->vsync_time = ktime_get();
+	complete_all(&vctrl->vsync_comp);
+	vctrl->wait_vsync_cnt = 0;
 	spin_unlock(&vctrl->spin_lock);
 }
 
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 2ffb80a..06363d6 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -114,6 +114,27 @@
 	pr_debug("%s: IRQ-dis done, term=%x\n", __func__, term);
 }
 
+void mdp4_dtv_free_base_pipe(struct msm_fb_data_type *mfd)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[0];
+	pipe = vctrl->base_pipe;
+
+	if (pipe == NULL)
+		return ;
+
+	if (hdmi_prim_display) {
+		/* adb stop */
+		if (pipe->pipe_type == OVERLAY_TYPE_BF)
+			mdp4_overlay_borderfill_stage_down(pipe);
+
+		/* pipe == rgb2 */
+		vctrl->base_pipe = NULL;
+	}
+}
+
 void mdp4_overlay_dtv_start(void)
 {
 	if (!dtv_enabled) {
@@ -163,6 +184,21 @@
 	mdp4_stat.overlay_play[pipe->mixer_num]++;
 }
 
+static void mdp4_dtv_pipe_clean(struct vsync_update *vp)
+{
+	struct mdp4_overlay_pipe *pipe;
+	int i;
+
+	pipe = vp->plist;
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+			pipe->pipe_used = 0; /* clear */
+		}
+	}
+	vp->update_cnt = 0;     /* empty queue */
+}
+
 static void mdp4_dtv_blt_ov_update(struct mdp4_overlay_pipe *pipe);
 static void mdp4_dtv_wait4dmae(int cndx);
 
@@ -183,8 +219,12 @@
 	undx =  vctrl->update_ndx;
 	vp = &vctrl->vlist[undx];
 	pipe = vctrl->base_pipe;
+	if (pipe == NULL) {
+		pr_err("%s: NO base pipe\n", __func__);
+		mutex_unlock(&vctrl->update_lock);
+		return 0;
+	}
 	mixer = pipe->mixer_num;
-	mdp4_overlay_iommu_unmap_freelist(mixer);
 
 	mdp_update_pm(vctrl->mfd, vctrl->vsync_time);
 
@@ -208,6 +248,31 @@
 				/* pipe not unset */
 				mdp4_overlay_vsync_commit(pipe);
 			}
+		}
+	}
+	mdp4_mixer_stage_commit(mixer);
+
+	 /* start timing generator & mmu if they are not started yet */
+	mdp4_overlay_dtv_start();
+
+	/*
+	 * there has possibility that pipe commit come very close to next vsync
+	 * this may cause two consecutive pie_commits happen within same vsync
+	 * period which casue iommu page fault when previous iommu buffer
+	 * freed. Set ION_IOMMU_UNMAP_DELAYED flag at ion_map_iommu() to
+	 * add delay unmap iommu buffer to fix this problem.
+	 * Also ion_unmap_iommu() may take as long as 9 ms to free an ion buffer.
+	 * therefore mdp4_overlay_iommu_unmap_freelist(mixer) should be called
+	 * ater stage_commit() to ensure pipe_commit (up to stage_commit)
+	 * is completed within vsync period.
+	 */
+
+	/* free previous committed iommu back to pool */
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+
+	pipe = vp->plist;
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
 			/* free previous iommu to freelist
 			* which will be freed at next
 			* pipe_commit
@@ -216,10 +281,6 @@
 			pipe->pipe_used = 0; /* clear */
 		}
 	}
-	mdp4_mixer_stage_commit(mixer);
-
-	 /* start timing generator & mmu if they are not started yet */
-	mdp4_overlay_dtv_start();
 
 	pipe = vctrl->base_pipe;
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
@@ -350,6 +411,9 @@
 	ssize_t ret = 0;
 	unsigned long flags;
 	u64 vsync_tick;
+	ktime_t ctime;
+	u32 ctick, ptick;
+	int diff;
 
 	cndx = 0;
 	vctrl = &vsync_ctrl_db[0];
@@ -359,6 +423,29 @@
 		atomic_read(&vctrl->vsync_resume) == 0)
 		return 0;
 
+	/*
+	 * show_event thread keep spinning on vctrl->vsync_comp
+	 * race condition on x.done if multiple thread blocked
+	 * at wait_for_completion(&vctrl->vsync_comp)
+	 *
+	 * if show_event thread waked up first then it will come back
+	 * and call INIT_COMPLETION(vctrl->vsync_comp) which set x.done = 0
+	 * then second thread wakeed up which set x.done = 0x7ffffffd
+	 * after that wait_for_completion will never wait.
+	 * To avoid this, force show_event thread to sleep 5 ms here
+	 * since it has full vsycn period (16.6 ms) to wait
+	 */
+	ctime = ktime_get();
+	ctick = (u32)ktime_to_us(ctime);
+	ptick = (u32)ktime_to_us(vctrl->vsync_time);
+	ptick += 5000;	/* 5ms */
+	diff = ptick - ctick;
+	if (diff > 0) {
+		if (diff > 1000) /* 1 ms */
+			diff = 1000;
+		usleep(diff);
+	}
+
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
 	if (vctrl->wait_vsync_cnt == 0)
 		INIT_COMPLETION(vctrl->vsync_comp);
@@ -555,20 +642,6 @@
 	return 0;
 }
 
-static int mdp4_dtv_stop(struct msm_fb_data_type *mfd)
-{
-	int cndx = 0;
-	struct vsycn_ctrl *vctrl;
-
-	vctrl = &vsync_ctrl_db[cndx];
-	if (vctrl->base_pipe == NULL)
-		return -EINVAL;
-
-	MDP_OUTP(MDP_BASE + DTV_BASE, 0);
-
-	return 0;
-}
-
 int mdp4_dtv_on(struct platform_device *pdev)
 {
 	struct msm_fb_data_type *mfd;
@@ -586,7 +659,10 @@
 	if (mfd->key != MFD_KEY)
 		return -EINVAL;
 
+	mutex_lock(&mfd->dma->ov_mutex);
+
 	vctrl->dev = mfd->fbi->dev;
+	vctrl->vsync_irq_enabled = 0;
 
 	mdp_footswitch_ctrl(TRUE);
 	/* Mdp clock enable */
@@ -599,6 +675,7 @@
 		if (mdp4_overlay_dtv_set(mfd, NULL)) {
 			pr_warn("%s: dtv_pipe is NULL, dtv_set failed\n",
 				__func__);
+			mutex_unlock(&mfd->dma->ov_mutex);
 			return -EINVAL;
 		}
 	}
@@ -609,11 +686,27 @@
 
 	atomic_set(&vctrl->suspend, 0);
 
+	mutex_unlock(&mfd->dma->ov_mutex);
+
 	pr_info("%s:\n", __func__);
 
 	return ret;
 }
 
+/* timing generator off */
+static void mdp4_dtv_tg_off(struct vsycn_ctrl *vctrl)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	INIT_COMPLETION(vctrl->vsync_comp);
+	vctrl->wait_vsync_cnt++;
+	MDP_OUTP(MDP_BASE + DTV_BASE, 0); /* turn off timing generator */
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	mdp4_dtv_wait4vsync(0);
+}
+
 int mdp4_dtv_off(struct platform_device *pdev)
 {
 	struct msm_fb_data_type *mfd;
@@ -623,23 +716,26 @@
 	struct vsycn_ctrl *vctrl;
 	struct mdp4_overlay_pipe *pipe;
 	struct vsync_update *vp;
+	int mixer = 0;
 
 	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
 
-	vctrl = &vsync_ctrl_db[cndx];
+	mutex_lock(&mfd->dma->ov_mutex);
 
-	atomic_set(&vctrl->suspend, 1);
-	atomic_set(&vctrl->vsync_resume, 0);
+	vctrl = &vsync_ctrl_db[cndx];
 
 	mdp4_dtv_wait4vsync(cndx);
 
+	atomic_set(&vctrl->vsync_resume, 0);
+
 	complete_all(&vctrl->vsync_comp);
+	vctrl->wait_vsync_cnt = 0;
 
 	pipe = vctrl->base_pipe;
 	if (pipe != NULL) {
-		mdp4_dtv_stop(mfd);
+		mixer = pipe->mixer_num;
 		/* sanity check, free pipes besides base layer */
-		mdp4_overlay_unset_mixer(pipe->mixer_num);
+		mdp4_overlay_unset_mixer(mixer);
 		if (hdmi_prim_display && mfd->ref_cnt == 0) {
 			/* adb stop */
 			if (pipe->pipe_type == OVERLAY_TYPE_BF)
@@ -654,6 +750,10 @@
 		}
 	}
 
+	mdp4_dtv_tg_off(vctrl);
+
+	atomic_set(&vctrl->suspend, 1);
+
 	mdp4_overlay_panel_mode_unset(MDP4_MIXER1, MDP4_PANEL_DTV);
 
 	undx =  vctrl->update_ndx;
@@ -663,25 +763,26 @@
 		 * pipe's iommu will be freed at next overlay play
 		 * and iommu_drop statistic will be increased by one
 		 */
-		vp->update_cnt = 0;     /* empty queue */
-	}
-
-	undx =  vctrl->update_ndx;
-	vp = &vctrl->vlist[undx];
-	if (vp->update_cnt) {
-		/*
-		 * pipe's iommu will be freed at next overlay play
-		 * and iommu_drop statistic will be increased by one
-		 */
-		vp->update_cnt = 0;     /* empty queue */
+		pr_warn("%s: update_cnt=%d\n", __func__, vp->update_cnt);
+		mdp4_dtv_pipe_clean(vp);
 	}
 
 	ret = panel_next_off(pdev);
 	mdp_footswitch_ctrl(FALSE);
 
+	/*
+	 * clean up ion freelist
+	 * there need two stage to empty ion free list
+	 * therefore need call unmap freelist twice
+	 */
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+
 	/* Mdp clock disable */
 	mdp_clk_ctrl(0);
 
+	mutex_unlock(&mfd->dma->ov_mutex);
+
 	pr_info("%s:\n", __func__);
 	return ret;
 }
@@ -798,6 +899,8 @@
 
 	mdp4_overlay_mdp_pipe_req(pipe, mfd);
 	mdp4_calc_blt_mdp_bw(mfd, pipe);
+	mdp4_overlay_mdp_perf_req(mfd);
+	mdp4_overlay_mdp_perf_upd(mfd, 1);
 
 	ret = mdp4_overlay_format2pipe(pipe);
 	if (ret < 0)
@@ -860,7 +963,7 @@
 
 	if (pipe->mixer_stage == MDP4_MIXER_STAGE_BASE &&
 			pipe->pipe_type == OVERLAY_TYPE_RGB) {
-		result = mdp4_dtv_stop(mfd);
+		mdp4_dtv_tg_off(vctrl);
 		vctrl->base_pipe = NULL;
 	}
 	return result;
@@ -880,10 +983,8 @@
 	spin_lock(&vctrl->spin_lock);
 	vctrl->vsync_time = ktime_get();
 
-	if (vctrl->wait_vsync_cnt) {
-		complete_all(&vctrl->vsync_comp);
-		vctrl->wait_vsync_cnt = 0;
-	}
+	complete_all(&vctrl->vsync_comp);
+	vctrl->wait_vsync_cnt = 0;
 	spin_unlock(&vctrl->spin_lock);
 }
 
@@ -1099,7 +1200,7 @@
 	}
 
 	mdp4_overlay_mdp_perf_upd(mfd, 1);
-	mdp4_dtv_pipe_commit(0, 0);
+	mdp4_dtv_pipe_commit(0, 1);
 	mdp4_overlay_mdp_perf_upd(mfd, 0);
 	mutex_unlock(&mfd->dma->ov_mutex);
 }
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index a5f640f..b96ae2a 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2013, The Linux Foundation. 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 and
@@ -148,6 +148,21 @@
 	mdp4_stat.overlay_play[pipe->mixer_num]++;
 }
 
+static void mdp4_lcdc_pipe_clean(struct vsync_update *vp)
+{
+	struct mdp4_overlay_pipe *pipe;
+	int i;
+
+	pipe = vp->plist;
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+			pipe->pipe_used = 0; /* clear */
+		}
+	}
+	vp->update_cnt = 0;     /* empty queue */
+}
+
 static void mdp4_lcdc_blt_ov_update(struct mdp4_overlay_pipe *pipe);
 static void mdp4_lcdc_wait4dmap(int cndx);
 static void mdp4_lcdc_wait4ov(int cndx);
@@ -170,6 +185,11 @@
 	undx =  vctrl->update_ndx;
 	vp = &vctrl->vlist[undx];
 	pipe = vctrl->base_pipe;
+	if (pipe == NULL) {
+		pr_err("%s: NO base pipe\n", __func__);
+		mutex_unlock(&vctrl->update_lock);
+		return 0;
+	}
 	mixer = pipe->mixer_num;
 
 	mdp_update_pm(vctrl->mfd, vctrl->vsync_time);
@@ -225,12 +245,6 @@
 				/* pipe not unset */
 				mdp4_overlay_vsync_commit(pipe);
 			}
-			/* free previous iommu to freelist
-			 * which will be freed at next
-			 * pipe_commit
-			 */
-			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
-			pipe->pipe_used = 0; /* clear */
 		}
 	}
 
@@ -239,6 +253,33 @@
 	/* start timing generator & mmu if they are not started yet */
 	mdp4_overlay_lcdc_start();
 
+	/*
+	 * there has possibility that pipe commit come very close to next vsync
+	 * this may cause two consecutive pie_commits happen within same vsync
+	 * period which casue iommu page fault when previous iommu buffer
+	 * freed. Set ION_IOMMU_UNMAP_DELAYED flag at ion_map_iommu() to
+	 * add delay unmap iommu buffer to fix this problem.
+	 * Also ion_unmap_iommu() may take as long as 9 ms to free an ion buffer.
+	 * therefore mdp4_overlay_iommu_unmap_freelist(mixer) should be called
+	 * ater stage_commit() to ensure pipe_commit (up to stage_commit)
+	 * is completed within vsync period.
+	 */
+
+	/* free previous committed iommu back to pool */
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+
+	pipe = vp->plist;
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
+			/* free previous iommu to freelist
+			* which will be freed at next
+			* pipe_commit
+			*/
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+			pipe->pipe_used = 0; /* clear */
+		}
+	}
+
 	pipe = vctrl->base_pipe;
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
 	if (pipe->ov_blt_addr) {
@@ -332,9 +373,6 @@
 	if (atomic_read(&vctrl->suspend) > 0)
 		return;
 
-	/* start timing generator & mmu if they are not started yet */
-	mdp4_overlay_lcdc_start();
-
 	mdp4_lcdc_vsync_irq_ctrl(cndx, 1);
 
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
@@ -391,6 +429,9 @@
 	ssize_t ret = 0;
 	unsigned long flags;
 	u64 vsync_tick;
+	ktime_t ctime;
+	u32 ctick, ptick;
+	int diff;
 
 	cndx = 0;
 	vctrl = &vsync_ctrl_db[0];
@@ -399,6 +440,29 @@
 		atomic_read(&vctrl->vsync_resume) == 0)
 		return 0;
 
+	/*
+	 * show_event thread keep spinning on vctrl->vsync_comp
+	 * race condition on x.done if multiple thread blocked
+	 * at wait_for_completion(&vctrl->vsync_comp)
+	 *
+	 * if show_event thread waked up first then it will come back
+	 * and call INIT_COMPLETION(vctrl->vsync_comp) which set x.done = 0
+	 * then second thread wakeed up which set x.done = 0x7ffffffd
+	 * after that wait_for_completion will never wait.
+	 * To avoid this, force show_event thread to sleep 5 ms here
+	 * since it has full vsycn period (16.6 ms) to wait
+	 */
+	ctime = ktime_get();
+	ctick = (u32)ktime_to_us(ctime);
+	ptick = (u32)ktime_to_us(vctrl->vsync_time);
+	ptick += 5000;	/* 5ms */
+	diff = ptick - ctick;
+	if (diff > 0) {
+		if (diff > 1000) /* 1 ms */
+			diff = 1000;
+		usleep(diff);
+	}
+
 	spin_lock_irqsave(&vctrl->spin_lock, flags);
 	if (vctrl->wait_vsync_cnt == 0)
 		INIT_COMPLETION(vctrl->vsync_comp);
@@ -446,6 +510,27 @@
 	spin_lock_init(&vctrl->spin_lock);
 }
 
+void mdp4_lcdc_free_base_pipe(struct msm_fb_data_type *mfd)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[0];
+	pipe = vctrl->base_pipe;
+
+	if (pipe == NULL)
+		return ;
+	/* adb stop */
+	if (pipe->pipe_type == OVERLAY_TYPE_BF)
+		mdp4_overlay_borderfill_stage_down(pipe);
+
+	/* base pipe may change after borderfill_stage_down */
+	pipe = vctrl->base_pipe;
+	mdp4_mixer_stage_down(pipe, 1);
+	mdp4_overlay_pipe_free(pipe);
+	vctrl->base_pipe = NULL;
+}
+
 void mdp4_lcdc_base_swap(int cndx, struct mdp4_overlay_pipe *pipe)
 {
 	struct vsycn_ctrl *vctrl;
@@ -511,8 +596,11 @@
 	if (mfd->key != MFD_KEY)
 		return -EINVAL;
 
+	mutex_lock(&mfd->dma->ov_mutex);
+
 	vctrl->mfd = mfd;
 	vctrl->dev = mfd->fbi->dev;
+	vctrl->vsync_irq_enabled = 0;
 
 	/* mdp clock on */
 	mdp_clk_ctrl(1);
@@ -567,6 +655,8 @@
 	pipe->srcp0_ystride = fbi->fix.line_length;
 	pipe->bpp = bpp;
 
+	mdp4_overlay_solidfill_init(pipe);
+
 	mdp4_overlay_mdp_pipe_req(pipe, mfd);
 	mdp4_calc_blt_mdp_bw(mfd, pipe);
 
@@ -579,6 +669,7 @@
 
 	mdp4_overlay_reg_flush(pipe, 1);
 	mdp4_mixer_stage_up(pipe, 0);
+	mdp4_mixer_stage_commit(pipe->mixer_num);
 
 
 	/*
@@ -673,10 +764,25 @@
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 
 	mdp_histogram_ctrl_all(TRUE);
+	mdp4_overlay_lcdc_start();
+	mutex_unlock(&mfd->dma->ov_mutex);
 
 	return ret;
 }
 
+/* timing generator off */
+static void mdp4_lcdc_tg_off(struct vsycn_ctrl *vctrl)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	INIT_COMPLETION(vctrl->vsync_comp);
+	vctrl->wait_vsync_cnt++;
+	MDP_OUTP(MDP_BASE + LCDC_BASE, 0); /* turn off timing generator */
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	mdp4_lcdc_wait4vsync(0);
+}
 int mdp4_lcdc_off(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -687,17 +793,20 @@
 	struct vsync_update *vp;
 	unsigned long flags;
 	int undx, need_wait = 0;
+	int mixer = 0;
 
 	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	mutex_lock(&mfd->dma->ov_mutex);
 	vctrl = &vsync_ctrl_db[cndx];
 	pipe = vctrl->base_pipe;
 
-	atomic_set(&vctrl->suspend, 1);
+	mdp4_lcdc_wait4vsync(cndx);
+
 	atomic_set(&vctrl->vsync_resume, 0);
 
-	msleep(20);	/* >= 17 ms */
-
 	complete_all(&vctrl->vsync_comp);
+	vctrl->wait_vsync_cnt = 0;
 
 	if (pipe->ov_blt_addr) {
 		spin_lock_irqsave(&vctrl->spin_lock, flags);
@@ -710,8 +819,6 @@
 
 	mdp_histogram_ctrl_all(FALSE);
 
-	MDP_OUTP(MDP_BASE + LCDC_BASE, 0);
-
 	lcdc_enabled = 0;
 
 	undx =  vctrl->update_ndx;
@@ -721,22 +828,14 @@
 		 * pipe's iommu will be freed at next overlay play
 		 * and iommu_drop statistic will be increased by one
 		 */
-		vp->update_cnt = 0;     /* empty queue */
-	}
-
-	undx =  vctrl->update_ndx;
-	vp = &vctrl->vlist[undx];
-	if (vp->update_cnt) {
-		/*
-		 * pipe's iommu will be freed at next overlay play
-		 * and iommu_drop statistic will be increased by one
-		 */
-		vp->update_cnt = 0;     /* empty queue */
+		pr_warn("%s: update_cnt=%d\n", __func__, vp->update_cnt);
+		mdp4_lcdc_pipe_clean(vp);
 	}
 
 	if (pipe) {
 		/* sanity check, free pipes besides base layer */
-		mdp4_overlay_unset_mixer(pipe->mixer_num);
+		mixer = pipe->mixer_num;
+		mdp4_overlay_unset_mixer(mixer);
 		if (mfd->ref_cnt == 0) {
 			/* adb stop */
 			if (pipe->pipe_type == OVERLAY_TYPE_BF)
@@ -755,10 +854,24 @@
 		}
 	}
 
+	mdp4_lcdc_tg_off(vctrl);
+
+	atomic_set(&vctrl->suspend, 1);
+
+	/*
+	 * clean up ion freelist
+	 * there need two stage to empty ion free list
+	 * therefore need call unmap freelist twice
+	 */
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+
 	/* MDP clock disable */
 	mdp_clk_ctrl(0);
 	mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 
+	mutex_unlock(&mfd->dma->ov_mutex);
+
 	return ret;
 }
 
@@ -824,11 +937,8 @@
 	spin_lock(&vctrl->spin_lock);
 	vctrl->vsync_time = ktime_get();
 
-	if (vctrl->wait_vsync_cnt) {
-		complete_all(&vctrl->vsync_comp);
-		vctrl->wait_vsync_cnt = 0;
-	}
-
+	complete_all(&vctrl->vsync_comp);
+	vctrl->wait_vsync_cnt = 0;
 	spin_unlock(&vctrl->spin_lock);
 }
 
diff --git a/drivers/video/msm/mdp4_overlay_mddi.c b/drivers/video/msm/mdp4_overlay_mddi.c
index be4a89a..717bba9 100644
--- a/drivers/video/msm/mdp4_overlay_mddi.c
+++ b/drivers/video/msm/mdp4_overlay_mddi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index 205febd..748f07d 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -91,7 +91,7 @@
 static int mdp4_overlay_writeback_update(struct msm_fb_data_type *mfd);
 static void mdp4_wfd_queue_wakeup(struct msm_fb_data_type *mfd,
 		struct msmfb_writeback_data_list *node);
-static void mdp4_wfd_dequeue_update(struct msm_fb_data_type *mfd,
+static int mdp4_wfd_dequeue_update(struct msm_fb_data_type *mfd,
 		struct msmfb_writeback_data_list **wfdnode);
 
 int mdp4_overlay_writeback_on(struct platform_device *pdev)
@@ -174,6 +174,7 @@
 }
 
 static void mdp4_wfd_wait4ov(int cndx);
+static void mdp4_writeback_pipe_clean(struct vsync_update *vp);
 
 int mdp4_overlay_writeback_off(struct platform_device *pdev)
 {
@@ -215,7 +216,8 @@
 		 * pipe's iommu will be freed at next overlay play
 		 * and iommu_drop statistic will be increased by one
 		 */
-		vp->update_cnt = 0;     /* empty queue */
+		pr_warn("%s: update_cnt=%d\n", __func__, vp->update_cnt);
+		mdp4_writeback_pipe_clean(vp);
 	}
 
 	ret = panel_next_off(pdev);
@@ -334,6 +336,21 @@
 	mdp4_stat.overlay_play[pipe->mixer_num]++;
 }
 
+static void mdp4_writeback_pipe_clean(struct vsync_update *vp)
+{
+	struct mdp4_overlay_pipe *pipe;
+	int i;
+
+	pipe = vp->plist;
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+			pipe->pipe_used = 0; /* clear */
+		}
+	}
+	vp->update_cnt = 0;     /* empty queue */
+}
+
 int mdp4_wfd_pipe_commit(struct msm_fb_data_type *mfd,
 			int cndx, int wait)
 {
@@ -346,6 +363,7 @@
 	unsigned long flags;
 	int cnt = 0;
 	struct msmfb_writeback_data_list *node = NULL;
+	int rc = 0;
 
 	vctrl = &vsync_ctrl_db[cndx];
 
@@ -366,8 +384,18 @@
 	vp->update_cnt = 0;     /* reset */
 	mutex_unlock(&vctrl->update_lock);
 
-	mdp4_wfd_dequeue_update(mfd, &node);
-
+	rc = mdp4_wfd_dequeue_update(mfd, &node);
+	if (rc != 0) {
+		pr_err("%s: mdp4_wfd_dequeue_update failed !! mfd=%x\n",
+			__func__, (int)mfd);
+		pipe = vp->plist;
+		for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+			pipe->pipe_used = 0;
+			pr_debug("%s: dequeue update failed, unsetting pipes\n",
+				__func__);
+		}
+		return cnt;
+	}
 	/* free previous committed iommu back to pool */
 	mdp4_overlay_iommu_unmap_freelist(mixer);
 
@@ -757,7 +785,7 @@
 	return rc;
 }
 
-static void mdp4_wfd_dequeue_update(struct msm_fb_data_type *mfd,
+static int mdp4_wfd_dequeue_update(struct msm_fb_data_type *mfd,
 			struct msmfb_writeback_data_list **wfdnode)
 {
 	struct vsycn_ctrl *vctrl;
@@ -765,7 +793,7 @@
 	struct msmfb_writeback_data_list *node = NULL;
 
 	if (mfd && !mfd->panel_power_on)
-		return;
+		return -EPERM;
 
 	pr_debug("%s:+ mfd=%x\n", __func__, (int)mfd);
 
@@ -792,8 +820,18 @@
 	if (!pipe->ov_blt_addr) {
 		pr_err("%s: no writeback buffer 0x%x, %p\n", __func__,
 			(unsigned int)pipe->ov_blt_addr, node);
+
+		if (node) {
+			mutex_lock(&mfd->writeback_mutex);
+			list_add_tail(&node->active_entry,
+				&mfd->writeback_free_queue);
+			node->state = IN_FREE_QUEUE;
+			mfd->writeback_active_cnt--;
+			mutex_unlock(&mfd->writeback_mutex);
+		}
+
 		mutex_unlock(&mfd->unregister_mutex);
-		return;
+		return -EINVAL;
 	}
 
 	mdp4_overlay_writeback_update(mfd);
@@ -801,6 +839,7 @@
 	*wfdnode = node;
 
 	mutex_unlock(&mfd->unregister_mutex);
+	return 0;
 }
 
 static void mdp4_wfd_queue_wakeup(struct msm_fb_data_type *mfd,
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index 08849e6..fe32e05 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2009-2013, Code Aurora Forum. All rights reserved.
+/*
+ * Copyright (c) 2009-2013, The Linux Foundation. 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 and
@@ -199,13 +200,14 @@
 
 	bits &= 0x1f;	/* 5 bits */
 	outpdw(MDP_BASE + 0x001c, bits);	/* MDP_SW_RESET */
+	wmb();
 
 	while (inpdw(MDP_BASE + 0x001c) & bits) /* self clear when complete */
 		;
 	/* MDP cmd block disable */
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 
-	MSM_FB_DEBUG("mdp4_sw_reset: 0x%x\n", (int)bits);
+	pr_debug("mdp4_sw_reset: 0x%x\n", (int)bits);
 }
 
 void mdp4_overlay_cfg(int overlayer, int blt_mode, int refresh, int direct_out)
@@ -391,6 +393,7 @@
 	int i;
 	/* MDP cmd block enable */
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	mdp_clk_ctrl(1);
 
 #ifdef MDP4_ERROR
 	/*
@@ -466,6 +469,7 @@
 
 	/* MDP cmd block disable */
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	mdp_clk_ctrl(0);
 }
 
 
@@ -1389,6 +1393,14 @@
 	},
 };
 
+void mdp4_vg_csc_restore(void)
+{
+        int i;
+
+        for (i = 0; i < CSC_MAX_BLOCKS; i++)
+                mdp4_csc_config(&csc_cfg_matrix[i]);
+}
+
 
 void mdp4_vg_csc_update(struct mdp_csc *p)
 {
@@ -3083,3 +3095,102 @@
 error:
 	return ret;
 }
+
+static int is_valid_calib_addr(void *addr)
+{
+	int ret = 0;
+	unsigned int ptr;
+
+	ptr = (unsigned int) addr;
+
+	if (mdp_rev >= MDP_REV_30 && mdp_rev < MDP_REV_40) {
+		/* if request is outside the MDP reg-map or is not aligned 4 */
+		if (ptr == 0x0 || ptr > 0xF0600 || ptr % 0x4)
+			goto end;
+
+		if (ptr >= 0x90000 && ptr < 0x94000) {
+			if (ptr == 0x90000 || ptr == 0x90070)
+				ret = 1;
+			else if (ptr >= 0x93400 && ptr <= 0x93420)
+				ret = 1;
+			else if (ptr >= 0x93500 && ptr <= 0x93508)
+				ret = 1;
+			else if (ptr >= 0x93580 && ptr <= 0x93588)
+				ret = 1;
+			else if (ptr >= 0x93600 && ptr <= 0x93614)
+				ret = 1;
+			else if (ptr >= 0x93680 && ptr <= 0x93694)
+				ret = 1;
+			else if (ptr >= 0x93800 && ptr <= 0x93BFC)
+				ret = 1;
+		}
+	} else if (mdp_rev >= MDP_REV_40 && mdp_rev <= MDP_REV_44) {
+		/* if request is outside the MDP reg-map or is not aligned 4 */
+		if (ptr > 0xF0600 || ptr % 0x4)
+			goto end;
+
+		if (ptr < 0x90000) {
+			if (ptr == 0x0 || ptr == 0x4 || ptr == 0x28200 ||
+								ptr == 0x28204)
+				ret = 1;
+		} else if (ptr < 0x95000) {
+			if (ptr == 0x90000 || ptr == 0x90070)
+				ret = 1;
+			else if (ptr >= 0x93400 && ptr <= 0x93420)
+				ret = 1;
+			else if (ptr >= 0x93500 && ptr <= 0x93508)
+				ret = 1;
+			else if (ptr >= 0x93580 && ptr <= 0x93588)
+				ret = 1;
+			else if (ptr >= 0x93600 && ptr <= 0x93614)
+				ret = 1;
+			else if (ptr >= 0x93680 && ptr <= 0x93694)
+				ret = 1;
+			else if (ptr >= 0x94800 && ptr <= 0x94BFC)
+				ret = 1;
+		} else if (ptr < 0x9A000) {
+			if (ptr >= 0x98800 && ptr <= 0x9883C)
+				ret = 1;
+			else if (ptr >= 0x98880 && ptr <= 0x988AC)
+				ret = 1;
+			else if (ptr >= 0x98900 && ptr <= 0x9893C)
+				ret = 1;
+			else if (ptr >= 0x98980 && ptr <= 0x989BC)
+				ret = 1;
+			else if (ptr >= 0x98A00 && ptr <= 0x98A3C)
+				ret = 1;
+			else if (ptr >= 0x98A80 && ptr <= 0x98ABC)
+				ret = 1;
+			else if (ptr >= 0x99000 && ptr <= 0x993FC)
+				ret = 1;
+			else if (ptr >= 0x99800 && ptr <= 0x99BFC)
+				ret = 1;
+		} else if (ptr >= 0x9A000 && ptr <= 0x9a08c) {
+			ret = 1;
+		}
+	}
+end:
+	return ret;
+}
+
+int mdp4_calib_config(struct mdp_calib_config_data *cfg)
+{
+	int ret = -1;
+	void *ptr = (void *) cfg->addr;
+
+	if (is_valid_calib_addr(ptr))
+		ret = 0;
+	else
+		return ret;
+
+	ptr = (void *)(((unsigned int) ptr) + MDP_BASE);
+	mdp_clk_ctrl(1);
+	if (cfg->ops & MDP_PP_OPS_READ) {
+		cfg->data = inpdw(ptr);
+		ret = 1;
+	} else if (cfg->ops & MDP_PP_OPS_WRITE) {
+		outpdw(ptr, cfg->data);
+	}
+	mdp_clk_ctrl(0);
+	return ret;
+}
diff --git a/drivers/video/msm/mdp4_wfd_writeback.c b/drivers/video/msm/mdp4_wfd_writeback.c
index 7ec3dba..7876f9a 100644
--- a/drivers/video/msm/mdp4_wfd_writeback.c
+++ b/drivers/video/msm/mdp4_wfd_writeback.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp4_wfd_writeback_panel.c b/drivers/video/msm/mdp4_wfd_writeback_panel.c
index 40ffb65..c3d0431 100644
--- a/drivers/video/msm/mdp4_wfd_writeback_panel.c
+++ b/drivers/video/msm/mdp4_wfd_writeback_panel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp4_wfd_writeback_util.h b/drivers/video/msm/mdp4_wfd_writeback_util.h
index 2d62713..582d198 100644
--- a/drivers/video/msm/mdp4_wfd_writeback_util.h
+++ b/drivers/video/msm/mdp4_wfd_writeback_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp_cursor.c b/drivers/video/msm/mdp_cursor.c
index f8c08e3..93ff388 100644
--- a/drivers/video/msm/mdp_cursor.c
+++ b/drivers/video/msm/mdp_cursor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp_debugfs.c b/drivers/video/msm/mdp_debugfs.c
index 0fad0a7..68727f4 100644
--- a/drivers/video/msm/mdp_debugfs.c
+++ b/drivers/video/msm/mdp_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp_dma.c b/drivers/video/msm/mdp_dma.c
index cee40c2..ffb3257 100644
--- a/drivers/video/msm/mdp_dma.c
+++ b/drivers/video/msm/mdp_dma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp_dma_dsi_video.c b/drivers/video/msm/mdp_dma_dsi_video.c
index 89657d9..6dbe9d4 100644
--- a/drivers/video/msm/mdp_dma_dsi_video.c
+++ b/drivers/video/msm/mdp_dma_dsi_video.c
@@ -108,6 +108,7 @@
 
 	vsync_cntrl.dev = mfd->fbi->dev;
 	atomic_set(&vsync_cntrl.suspend, 0);
+	vsync_cntrl.vsync_irq_enabled = 0;
 	bpp = fbi->var.bits_per_pixel / 8;
 	buf = (uint8 *) fbi->fix.smem_start;
 
diff --git a/drivers/video/msm/mdp_dma_lcdc.c b/drivers/video/msm/mdp_dma_lcdc.c
index 668ce53..b80f9ea 100644
--- a/drivers/video/msm/mdp_dma_lcdc.c
+++ b/drivers/video/msm/mdp_dma_lcdc.c
@@ -126,6 +126,7 @@
 	var = &fbi->var;
 	vsync_cntrl.dev = mfd->fbi->dev;
 	atomic_set(&vsync_cntrl.suspend, 0);
+	vsync_cntrl.vsync_irq_enabled = 0;
 
 	/* MDP cmd block enable */
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
diff --git a/drivers/video/msm/mdp_dma_s.c b/drivers/video/msm/mdp_dma_s.c
index 22d79be..c5a2402 100644
--- a/drivers/video/msm/mdp_dma_s.c
+++ b/drivers/video/msm/mdp_dma_s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp_dma_tv.c b/drivers/video/msm/mdp_dma_tv.c
index b578ba2..ee2e323 100644
--- a/drivers/video/msm/mdp_dma_tv.c
+++ b/drivers/video/msm/mdp_dma_tv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp_hw_init.c b/drivers/video/msm/mdp_hw_init.c
index ff3ad41..3818ed4 100644
--- a/drivers/video/msm/mdp_hw_init.c
+++ b/drivers/video/msm/mdp_hw_init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp_lcdc.c b/drivers/video/msm/mdp_lcdc.c
index 62b0975..22bab96 100644
--- a/drivers/video/msm/mdp_lcdc.c
+++ b/drivers/video/msm/mdp_lcdc.c
@@ -1,7 +1,7 @@
 /* drivers/video/msm/mdp_lcdc.c
  *
  * Copyright (c) 2009 Google Inc.
- * Copyright (c) 2009 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
index 8999395..71551b9 100644
--- a/drivers/video/msm/mdp_ppp.c
+++ b/drivers/video/msm/mdp_ppp.c
@@ -1,7 +1,7 @@
 /* drivers/video/msm/src/drv/mdp/mdp_ppp.c
  *
  * Copyright (C) 2007 Google Incorporated
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/video/msm/mdp_ppp22.c b/drivers/video/msm/mdp_ppp22.c
index 9016f0a..799ce52 100644
--- a/drivers/video/msm/mdp_ppp22.c
+++ b/drivers/video/msm/mdp_ppp22.c
@@ -1,6 +1,6 @@
 /* drivers/video/msm/mdp_ppp22.c
  *
- * Copyright (C) 2007 Code Aurora Forum. All rights reserved.
+ * Copyright (C) 2007 The Linux Foundation. All rights reserved.
  * Copyright (C) 2007 Google Incorporated
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/video/msm/mdp_ppp31.c b/drivers/video/msm/mdp_ppp31.c
index 91764fe..2d28358 100644
--- a/drivers/video/msm/mdp_ppp31.c
+++ b/drivers/video/msm/mdp_ppp31.c
@@ -1,6 +1,6 @@
 /* drivers/video/msm/mdp_ppp31.c
  *
- * Copyright (C) 2009 Code Aurora Forum. All rights reserved.
+ * Copyright (C) 2009 The Linux Foundation. All rights reserved.
  * Copyright (C) 2009 Google Incorporated
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/video/msm/mdp_ppp_v20.c b/drivers/video/msm/mdp_ppp_v20.c
index 418528e..4062d3a 100644
--- a/drivers/video/msm/mdp_ppp_v20.c
+++ b/drivers/video/msm/mdp_ppp_v20.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp_ppp_v31.c b/drivers/video/msm/mdp_ppp_v31.c
index ee6af53..3c149b1 100644
--- a/drivers/video/msm/mdp_ppp_v31.c
+++ b/drivers/video/msm/mdp_ppp_v31.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdp_vsync.c b/drivers/video/msm/mdp_vsync.c
index cc350d3..b574a5a 100644
--- a/drivers/video/msm/mdp_vsync.c
+++ b/drivers/video/msm/mdp_vsync.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 6145d67..db7c836 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index d051828..0a357be 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index 57fce1a..52baa3e 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 7bc0105..adaf52b 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -1,5 +1,5 @@
 
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index bfb7fae..5fab93e 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 6a9db8f..094c253 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -2,7 +2,7 @@
  * Core MDSS framebuffer driver.
  *
  * Copyright (C) 2007 Google Incorporated
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index 72e0814..3e3c04b 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 4696c40..4bfbc9d 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -1,7 +1,7 @@
 /*
  * MDSS MDP Interface (used by framebuffer core)
  *
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  * Copyright (C) 2007 Google Incorporated
  *
  * This software is licensed under the terms of the GNU General Public
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 776bf8b..e454d50 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index d29ecd6..fca8d08 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_formats.h b/drivers/video/msm/mdss/mdss_mdp_formats.h
index 07eefc1..b73f1e9 100644
--- a/drivers/video/msm/mdss/mdss_mdp_formats.h
+++ b/drivers/video/msm/mdss/mdss_mdp_formats.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index 8825cc6..d013a4f 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index bc64d2e..3f06bc3 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index af422b7..cd6bd14 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 2e9a2dc..9950790 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 9a8260f..3a30ca1 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index db840a8..b84a075 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_rotator.c b/drivers/video/msm/mdss/mdss_mdp_rotator.c
index dc1cb0d..a5d072b 100644
--- a/drivers/video/msm/mdss/mdss_mdp_rotator.c
+++ b/drivers/video/msm/mdss/mdss_mdp_rotator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_rotator.h b/drivers/video/msm/mdss/mdss_mdp_rotator.h
index 1e4b81e0..7d39c72 100644
--- a/drivers/video/msm/mdss/mdss_mdp_rotator.h
+++ b/drivers/video/msm/mdss/mdss_mdp_rotator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 8f77e21..60fe263 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index d21c42f..d92c18e 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
index 3ec3a5d..7ee3829 100644
--- a/drivers/video/msm/mdss/mdss_panel.h
+++ b/drivers/video/msm/mdss/mdss_panel.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/mdss_wb.c b/drivers/video/msm/mdss/mdss_wb.c
index a26d339..a0a4837 100644
--- a/drivers/video/msm/mdss/mdss_wb.c
+++ b/drivers/video/msm/mdss/mdss_wb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c
index c766ec7..b92a6ca 100644
--- a/drivers/video/msm/mdss/msm_mdss_io_8974.c
+++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mhl/mhl_8334.c b/drivers/video/msm/mhl/mhl_8334.c
index 646dd29..1a29677 100644
--- a/drivers/video/msm/mhl/mhl_8334.c
+++ b/drivers/video/msm/mhl/mhl_8334.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mhl/mhl_i2c_utils.c b/drivers/video/msm/mhl/mhl_i2c_utils.c
index ee069bb..d3eec74 100644
--- a/drivers/video/msm/mhl/mhl_i2c_utils.c
+++ b/drivers/video/msm/mhl/mhl_i2c_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mhl/mhl_i2c_utils.h b/drivers/video/msm/mhl/mhl_i2c_utils.h
index 5a2d199..9e4a4fa 100644
--- a/drivers/video/msm/mhl/mhl_i2c_utils.h
+++ b/drivers/video/msm/mhl/mhl_i2c_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mhl_api.h b/drivers/video/msm/mhl_api.h
index a4364ea..26037ce 100644
--- a/drivers/video/msm/mhl_api.h
+++ b/drivers/video/msm/mhl_api.h
@@ -1,5 +1,5 @@
 
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_NT35510.c b/drivers/video/msm/mipi_NT35510.c
index 94c24ee..50a038e 100644
--- a/drivers/video/msm/mipi_NT35510.c
+++ b/drivers/video/msm/mipi_NT35510.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_NT35510.h b/drivers/video/msm/mipi_NT35510.h
index 5c81875..58ac05a 100644
--- a/drivers/video/msm/mipi_NT35510.h
+++ b/drivers/video/msm/mipi_NT35510.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c b/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c
index 1524ce6..0f9fece 100644
--- a/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c
+++ b/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_NT35510_video_wvga_pt.c b/drivers/video/msm/mipi_NT35510_video_wvga_pt.c
index 8a364ba..6f2a372 100644
--- a/drivers/video/msm/mipi_NT35510_video_wvga_pt.c
+++ b/drivers/video/msm/mipi_NT35510_video_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_NT35590.c b/drivers/video/msm/mipi_NT35590.c
new file mode 100644
index 0000000..2b42ddf
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35590.c
@@ -0,0 +1,1608 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 and
+ * only 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.
+ *
+ */
+
+#include <linux/leds.h>
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_NT35590.h"
+
+static struct dsi_buf nt35590_tx_buf;
+static struct dsi_buf nt35590_rx_buf;
+
+static int wled_trigger_initialized;
+
+static char display_off[2] = {0x28, 0x00};
+static char enter_sleep[2] = {0x10, 0x00};
+
+static struct dsi_cmd_desc nt35590_display_off_cmds[] = {
+	{DTYPE_DCS_WRITE, 1, 0, 0, 50, sizeof(display_off), display_off},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 50, sizeof(enter_sleep), enter_sleep}
+};
+
+static char disp_on0[2] = {0xFF, 0xEE};
+static char disp_on1[2] = {0x26, 0x08};
+static char disp_on2[2] = {0x26, 0x00};
+static char disp_on3[2] = {0xFF, 0x00}; /* WaitTime(10) */
+
+static char lane[2] = {0xBA, 0x03}; /* MIPI 4 lane */
+/* Fix 180 degree orientation */
+/* static char disp_on_rotate[2] = {0x36, 0xd7}; */
+
+static char command_mode[2] = {0xC2, 0x08}; /* Setting 0x08 for MIPI cmd mode */
+
+static char video_mode[2] = {0xC2, 0x03}; /* Setting 0x03 for MIPI video mode */
+static char video_timing[] = {0x3B, 0x03, 0x09, 0x3, 0x2, 0x2};
+
+static char disp_on6[2] = {0xFF, 0x01}; /* CMD page select */
+static char disp_on7[2] = {0xFB, 0x01}; /* RELOAD CMD1 */
+static char disp_on8[2] = {0x00, 0x4A};
+static char disp_on9[2] = {0x01, 0x33};
+static char disp_on10[2] = {0x02, 0x53};
+static char disp_on11[2] = {0x03, 0x55};
+static char disp_on12[2] = {0x04, 0x55};
+static char disp_on13[2] = {0x05, 0x33};
+static char disp_on14[2] = {0x06, 0x22};
+static char disp_on15[2] = {0x08, 0x56};
+static char disp_on16[2] = {0x09, 0x8F};
+static char disp_on17[2] = {0x36, 0x73};
+static char disp_on18[2] = {0x0B, 0x9F};
+static char disp_on19[2] = {0x0C, 0x9F};
+static char disp_on20[2] = {0x0D, 0x2F};
+static char disp_on21[2] = {0x0E, 0x24};
+static char disp_on22[2] = {0x11, 0x83};
+static char disp_on23[2] = {0x12, 0x03};
+static char disp_on24[2] = {0x71, 0x2C};
+static char disp_on25[2] = {0x6F, 0x03};
+static char disp_on26[2] = {0x0F, 0x0A};
+static char disp_on27[2] = {0xFF, 0x05}; /* CMD page select */
+static char disp_on28[2] = {0xFB, 0x01}; /* RELOAD CMD1 */
+static char disp_on29[2] = {0x01, 0x00};
+static char disp_on30[2] = {0x02, 0x8B}; /* 60 TE signals from panel */
+static char disp_on31[2] = {0x03, 0x82};
+static char disp_on32[2] = {0x04, 0x82};
+static char disp_on33[2] = {0x05, 0x30};
+static char disp_on34[2] = {0x06, 0x33};
+static char disp_on35[2] = {0x07, 0x01};
+static char disp_on36[2] = {0x08, 0x00};
+static char disp_on37[2] = {0x09, 0x46};
+static char disp_on38[2] = {0x0A, 0x46};
+static char disp_on39[2] = {0x0D, 0x0B};
+static char disp_on40[2] = {0x0E, 0x1D};
+static char disp_on41[2] = {0x0F, 0x08};
+static char disp_on42[2] = {0x10, 0x53};
+static char disp_on43[2] = {0x11, 0x00};
+static char disp_on44[2] = {0x12, 0x00};
+static char disp_on45[2] = {0x14, 0x01};
+static char disp_on46[2] = {0x15, 0x00};
+static char disp_on47[2] = {0x16, 0x05};
+static char disp_on48[2] = {0x17, 0x00};
+static char disp_on49[2] = {0x19, 0x7F};
+static char disp_on50[2] = {0x1A, 0xFF};
+static char disp_on51[2] = {0x1B, 0x0F};
+static char disp_on52[2] = {0x1C, 0x00};
+static char disp_on53[2] = {0x1D, 0x00};
+static char disp_on54[2] = {0x1E, 0x00};
+static char disp_on55[2] = {0x1F, 0x07};
+static char disp_on56[2] = {0x20, 0x00};
+static char disp_on57[2] = {0x21, 0x06};
+static char disp_on58[2] = {0x22, 0x55};
+static char disp_on59[2] = {0x23, 0x4D};
+static char disp_on60[2] = {0x2D, 0x02};
+static char disp_on61[2] = {0x28, 0x01};
+static char disp_on62[2] = {0x2F, 0x02};
+static char disp_on63[2] = {0x83, 0x01};
+static char disp_on64[2] = {0x9E, 0x58};
+static char disp_on65[2] = {0x9F, 0x6A};
+static char disp_on66[2] = {0xA0, 0x01};
+static char disp_on67[2] = {0xA2, 0x10};
+static char disp_on68[2] = {0xBB, 0x0A};
+static char disp_on69[2] = {0xBC, 0x0A};
+static char disp_on70[2] = {0x32, 0x08};
+static char disp_on71[2] = {0x33, 0xB8};
+static char disp_on72[2] = {0x36, 0x01};
+static char disp_on73[2] = {0x37, 0x00};
+static char disp_on74[2] = {0x43, 0x00};
+static char disp_on75[2] = {0x4B, 0x21};
+static char disp_on76[2] = {0x4C, 0x03};
+static char disp_on77[2] = {0x50, 0x21};
+static char disp_on78[2] = {0x51, 0x03};
+static char disp_on79[2] = {0x58, 0x21};
+static char disp_on80[2] = {0x59, 0x03};
+static char disp_on81[2] = {0x5D, 0x21};
+static char disp_on82[2] = {0x5E, 0x03};
+static char disp_on83[2] = {0x6C, 0x00};
+static char disp_on84[2] = {0x6D, 0x00};
+static char disp_on85[2] = {0xFB, 0x01};
+static char disp_on86[2] = {0xFF, 0x01}; /* Enter CMD2,Page0 */
+static char disp_on87[2] = {0xFB, 0x01};
+/* Gamma+ R settings start */
+static char disp_on88[2] = {0x75, 0x00};
+static char disp_on89[2] = {0x76, 0x7D};
+static char disp_on90[2] = {0x77, 0x00};
+static char disp_on91[2] = {0x78, 0x8A};
+static char disp_on92[2] = {0x79, 0x00};
+static char disp_on93[2] = {0x7A, 0x9C};
+static char disp_on94[2] = {0x7B, 0x00};
+static char disp_on95[2] = {0x7C, 0xB1};
+static char disp_on96[2] = {0x7D, 0x00};
+static char disp_on97[2] = {0x7E, 0xBF};
+static char disp_on98[2] = {0x7F, 0x00};
+static char disp_on99[2] = {0x80, 0xCF};
+static char disp_on100[2] = {0x81, 0x00};
+static char disp_on101[2] = {0x82, 0xDD};
+static char disp_on102[2] = {0x83, 0x00};
+static char disp_on103[2] = {0x84, 0xE8};
+static char disp_on104[2] = {0x85, 0x00};
+static char disp_on105[2] = {0x86, 0xF2};
+static char disp_on106[2] = {0x87, 0x01};
+static char disp_on107[2] = {0x88, 0x1F};
+static char disp_on108[2] = {0x89, 0x01};
+static char disp_on109[2] = {0x8A, 0x41};
+static char disp_on110[2] = {0x8B, 0x01};
+static char disp_on111[2] = {0x8C, 0x78};
+static char disp_on112[2] = {0x8D, 0x01};
+static char disp_on113[2] = {0x8E, 0xA5};
+static char disp_on114[2] = {0x8F, 0x01};
+static char disp_on115[2] = {0x90, 0xEE};
+static char disp_on116[2] = {0x91, 0x02};
+static char disp_on117[2] = {0x92, 0x29};
+static char disp_on118[2] = {0x93, 0x02};
+static char disp_on119[2] = {0x94, 0x2A};
+static char disp_on120[2] = {0x95, 0x02};
+static char disp_on121[2] = {0x96, 0x5D};
+static char disp_on122[2] = {0x97, 0x02};
+static char disp_on123[2] = {0x98, 0x93};
+static char disp_on124[2] = {0x99, 0x02};
+static char disp_on125[2] = {0x9A, 0xB8};
+static char disp_on126[2] = {0x9B, 0x02};
+static char disp_on127[2] = {0x9C, 0xE7};
+static char disp_on128[2] = {0x9D, 0x03};
+static char disp_on129[2] = {0x9E, 0x07};
+static char disp_on130[2] = {0x9F, 0x03};
+static char disp_on131[2] = {0xA0, 0x37};
+static char disp_on132[2] = {0xA2, 0x03};
+static char disp_on133[2] = {0xA3, 0x46};
+static char disp_on134[2] = {0xA4, 0x03};
+static char disp_on135[2] = {0xA5, 0x56};
+static char disp_on136[2] = {0xA6, 0x03};
+static char disp_on137[2] = {0xA7, 0x66};
+static char disp_on138[2] = {0xA9, 0x03};
+static char disp_on139[2] = {0xAA, 0x7A};
+static char disp_on140[2] = {0xAB, 0x03};
+static char disp_on141[2] = {0xAC, 0x93};
+static char disp_on142[2] = {0xAD, 0x03};
+static char disp_on143[2] = {0xAE, 0xA3};
+static char disp_on144[2] = {0xAF, 0x03};
+static char disp_on145[2] = {0xB0, 0xB4};
+static char disp_on146[2] = {0xB1, 0x03};
+static char disp_on147[2] = {0xB2, 0xCB};
+/* Gamma+ R settings end */
+/* Gamma- R settings start */
+static char disp_on148[2] = {0xB3, 0x00};
+static char disp_on149[2] = {0xB4, 0x7D};
+static char disp_on150[2] = {0xB5, 0x00};
+static char disp_on151[2] = {0xB6, 0x8A};
+static char disp_on152[2] = {0xB7, 0x00};
+static char disp_on153[2] = {0xB8, 0x9C};
+static char disp_on154[2] = {0xB9, 0x00};
+static char disp_on155[2] = {0xBA, 0xB1};
+static char disp_on156[2] = {0xBB, 0x00};
+static char disp_on157[2] = {0xBC, 0xBF};
+static char disp_on158[2] = {0xBD, 0x00};
+static char disp_on159[2] = {0xBE, 0xCF};
+static char disp_on160[2] = {0xBF, 0x00};
+static char disp_on161[2] = {0xC0, 0xDD};
+static char disp_on162[2] = {0xC1, 0x00};
+static char disp_on163[2] = {0xC2, 0xE8};
+static char disp_on164[2] = {0xC3, 0x00};
+static char disp_on165[2] = {0xC4, 0xF2};
+static char disp_on166[2] = {0xC5, 0x01};
+static char disp_on167[2] = {0xC6, 0x1F};
+static char disp_on168[2] = {0xC7, 0x01};
+static char disp_on169[2] = {0xC8, 0x41};
+static char disp_on170[2] = {0xC9, 0x01};
+static char disp_on171[2] = {0xCA, 0x78};
+static char disp_on172[2] = {0xCB, 0x01};
+static char disp_on173[2] = {0xCC, 0xA5};
+static char disp_on174[2] = {0xCD, 0x01};
+static char disp_on175[2] = {0xCE, 0xEE};
+static char disp_on176[2] = {0xCF, 0x02};
+static char disp_on177[2] = {0xD0, 0x29};
+static char disp_on178[2] = {0xD1, 0x02};
+static char disp_on179[2] = {0xD2, 0x2A};
+static char disp_on180[2] = {0xD3, 0x02};
+static char disp_on181[2] = {0xD4, 0x5D};
+static char disp_on182[2] = {0xD5, 0x02};
+static char disp_on183[2] = {0xD6, 0x93};
+static char disp_on184[2] = {0xD7, 0x02};
+static char disp_on185[2] = {0xD8, 0xB8};
+static char disp_on186[2] = {0xD9, 0x02};
+static char disp_on187[2] = {0xDA, 0xE7};
+static char disp_on188[2] = {0xDB, 0x03};
+static char disp_on189[2] = {0xDC, 0x07};
+static char disp_on190[2] = {0xDD, 0x03};
+static char disp_on191[2] = {0xDE, 0x37};
+static char disp_on192[2] = {0xDF, 0x03};
+static char disp_on193[2] = {0xE0, 0x46};
+static char disp_on194[2] = {0xE1, 0x03};
+static char disp_on195[2] = {0xE2, 0x56};
+static char disp_on196[2] = {0xE3, 0x03};
+static char disp_on197[2] = {0xE4, 0x66};
+static char disp_on198[2] = {0xE5, 0x03};
+static char disp_on199[2] = {0xE6, 0x7A};
+static char disp_on200[2] = {0xE7, 0x03};
+static char disp_on201[2] = {0xE8, 0x93};
+static char disp_on202[2] = {0xE9, 0x03};
+static char disp_on203[2] = {0xEA, 0xA3};
+static char disp_on204[2] = {0xEB, 0x03};
+static char disp_on205[2] = {0xEC, 0xB4};
+static char disp_on206[2] = {0xED, 0x03};
+static char disp_on207[2] = {0xEE, 0xCB};
+/* Gamma- R settings end */
+/* Gamma+ G settings start */
+static char disp_on208[2] = {0xEF, 0x00};
+static char disp_on209[2] = {0xF0, 0xED};
+static char disp_on210[2] = {0xF1, 0x00};
+static char disp_on211[2] = {0xF2, 0xF3};
+static char disp_on212[2] = {0xF3, 0x00};
+static char disp_on213[2] = {0xF4, 0xFE};
+static char disp_on214[2] = {0xF5, 0x01};
+static char disp_on215[2] = {0xF6, 0x09};
+static char disp_on216[2] = {0xF7, 0x01};
+static char disp_on217[2] = {0xF8, 0x13};
+static char disp_on218[2] = {0xF9, 0x01};
+static char disp_on219[2] = {0xFA, 0x1D};
+/* Gamma+ G settings end */
+static char disp_on220[2] = {0xFF, 0x02}; /* Enter CMD */
+static char disp_on221[2] = {0xFB, 0x01};
+/* Gamma+ G settings start */
+static char disp_on222[2] = {0x00, 0x01};
+static char disp_on223[2] = {0x01, 0x26};
+static char disp_on224[2] = {0x02, 0x01};
+static char disp_on225[2] = {0x03, 0x2F};
+static char disp_on226[2] = {0x04, 0x01};
+static char disp_on227[2] = {0x05, 0x37};
+static char disp_on228[2] = {0x06, 0x01};
+static char disp_on229[2] = {0x07, 0x56};
+static char disp_on230[2] = {0x08, 0x01};
+static char disp_on231[2] = {0x09, 0x70};
+static char disp_on232[2] = {0x0A, 0x01};
+static char disp_on233[2] = {0x0B, 0x9D};
+static char disp_on234[2] = {0x0C, 0x01};
+static char disp_on235[2] = {0x0D, 0xC2};
+static char disp_on236[2] = {0x0E, 0x01};
+static char disp_on237[2] = {0x0F, 0xFF};
+static char disp_on238[2] = {0x10, 0x02};
+static char disp_on239[2] = {0x11, 0x31};
+static char disp_on240[2] = {0x12, 0x02};
+static char disp_on241[2] = {0x13, 0x32};
+static char disp_on242[2] = {0x14, 0x02};
+static char disp_on243[2] = {0x15, 0x60};
+static char disp_on244[2] = {0x16, 0x02};
+static char disp_on245[2] = {0x17, 0x94};
+static char disp_on246[2] = {0x18, 0x02};
+static char disp_on247[2] = {0x19, 0xB5};
+static char disp_on248[2] = {0x1A, 0x02};
+static char disp_on249[2] = {0x1B, 0xE3};
+static char disp_on250[2] = {0x1C, 0x03};
+static char disp_on251[2] = {0x1D, 0x03};
+static char disp_on252[2] = {0x1E, 0x03};
+static char disp_on253[2] = {0x1F, 0x2D};
+static char disp_on254[2] = {0x20, 0x03};
+static char disp_on255[2] = {0x21, 0x3A};
+static char disp_on256[2] = {0x22, 0x03};
+static char disp_on257[2] = {0x23, 0x48};
+static char disp_on258[2] = {0x24, 0x03};
+static char disp_on259[2] = {0x25, 0x57};
+static char disp_on260[2] = {0x26, 0x03};
+static char disp_on261[2] = {0x27, 0x68};
+static char disp_on262[2] = {0x28, 0x03};
+static char disp_on263[2] = {0x29, 0x7B};
+static char disp_on264[2] = {0x2A, 0x03};
+static char disp_on265[2] = {0x2B, 0x90};
+static char disp_on266[2] = {0x2D, 0x03};
+static char disp_on267[2] = {0x2F, 0xA0};
+static char disp_on268[2] = {0x30, 0x03};
+static char disp_on269[2] = {0x31, 0xCB};
+/* Gamma+ G settings end */
+/* Gamma- G settings start */
+static char disp_on270[2] = {0x32, 0x00};
+static char disp_on271[2] = {0x33, 0xED};
+static char disp_on272[2] = {0x34, 0x00};
+static char disp_on273[2] = {0x35, 0xF3};
+static char disp_on274[2] = {0x36, 0x00};
+static char disp_on275[2] = {0x37, 0xFE};
+static char disp_on276[2] = {0x38, 0x01};
+static char disp_on277[2] = {0x39, 0x09};
+static char disp_on278[2] = {0x3A, 0x01};
+static char disp_on279[2] = {0x3B, 0x13};
+static char disp_on280[2] = {0x3D, 0x01};
+static char disp_on281[2] = {0x3F, 0x1D};
+static char disp_on282[2] = {0x40, 0x01};
+static char disp_on283[2] = {0x41, 0x26};
+static char disp_on284[2] = {0x42, 0x01};
+static char disp_on285[2] = {0x43, 0x2F};
+static char disp_on286[2] = {0x44, 0x01};
+static char disp_on287[2] = {0x45, 0x37};
+static char disp_on288[2] = {0x46, 0x01};
+static char disp_on289[2] = {0x47, 0x56};
+static char disp_on290[2] = {0x48, 0x01};
+static char disp_on291[2] = {0x49, 0x70};
+static char disp_on292[2] = {0x4A, 0x01};
+static char disp_on293[2] = {0x4B, 0x9D};
+static char disp_on294[2] = {0x4C, 0x01};
+static char disp_on295[2] = {0x4D, 0xC2};
+static char disp_on296[2] = {0x4E, 0x01};
+static char disp_on297[2] = {0x4F, 0xFF};
+static char disp_on298[2] = {0x50, 0x02};
+static char disp_on299[2] = {0x51, 0x31};
+static char disp_on300[2] = {0x52, 0x02};
+static char disp_on301[2] = {0x53, 0x32};
+static char disp_on302[2] = {0x54, 0x02};
+static char disp_on303[2] = {0x55, 0x60};
+static char disp_on304[2] = {0x56, 0x02};
+static char disp_on305[2] = {0x58, 0x94};
+static char disp_on306[2] = {0x59, 0x02};
+static char disp_on307[2] = {0x5A, 0xB5};
+static char disp_on308[2] = {0x5B, 0x02};
+static char disp_on309[2] = {0x5C, 0xE3};
+static char disp_on310[2] = {0x5D, 0x03};
+static char disp_on311[2] = {0x5E, 0x03};
+static char disp_on312[2] = {0x5F, 0x03};
+static char disp_on313[2] = {0x60, 0x2D};
+static char disp_on314[2] = {0x61, 0x03};
+static char disp_on315[2] = {0x62, 0x3A};
+static char disp_on316[2] = {0x63, 0x03};
+static char disp_on317[2] = {0x64, 0x48};
+static char disp_on318[2] = {0x65, 0x03};
+static char disp_on319[2] = {0x66, 0x57};
+static char disp_on320[2] = {0x67, 0x03};
+static char disp_on321[2] = {0x68, 0x68};
+static char disp_on322[2] = {0x69, 0x03};
+static char disp_on323[2] = {0x6A, 0x7B};
+static char disp_on324[2] = {0x6B, 0x03};
+static char disp_on325[2] = {0x6C, 0x90};
+static char disp_on326[2] = {0x6D, 0x03};
+static char disp_on327[2] = {0x6E, 0xA0};
+static char disp_on328[2] = {0x6F, 0x03};
+static char disp_on329[2] = {0x70, 0xCB};
+/* Gamma- G settings end */
+/* Gamma+ B settings start */
+static char disp_on330[2] = {0x71, 0x00};
+static char disp_on331[2] = {0x72, 0x19};
+static char disp_on332[2] = {0x73, 0x00};
+static char disp_on333[2] = {0x74, 0x36};
+static char disp_on334[2] = {0x75, 0x00};
+static char disp_on335[2] = {0x76, 0x55};
+static char disp_on336[2] = {0x77, 0x00};
+static char disp_on337[2] = {0x78, 0x70};
+static char disp_on338[2] = {0x79, 0x00};
+static char disp_on339[2] = {0x7A, 0x83};
+static char disp_on340[2] = {0x7B, 0x00};
+static char disp_on341[2] = {0x7C, 0x99};
+static char disp_on342[2] = {0x7D, 0x00};
+static char disp_on343[2] = {0x7E, 0xA8};
+static char disp_on344[2] = {0x7F, 0x00};
+static char disp_on345[2] = {0x80, 0xB7};
+static char disp_on346[2] = {0x81, 0x00};
+static char disp_on347[2] = {0x82, 0xC5};
+static char disp_on348[2] = {0x83, 0x00};
+static char disp_on349[2] = {0x84, 0xF7};
+static char disp_on350[2] = {0x85, 0x01};
+static char disp_on351[2] = {0x86, 0x1E};
+static char disp_on352[2] = {0x87, 0x01};
+static char disp_on353[2] = {0x88, 0x60};
+static char disp_on354[2] = {0x89, 0x01};
+static char disp_on355[2] = {0x8A, 0x95};
+static char disp_on356[2] = {0x8B, 0x01};
+static char disp_on357[2] = {0x8C, 0xE1};
+static char disp_on358[2] = {0x8D, 0x02};
+static char disp_on359[2] = {0x8E, 0x20};
+static char disp_on360[2] = {0x8F, 0x02};
+static char disp_on361[2] = {0x90, 0x23};
+static char disp_on362[2] = {0x91, 0x02};
+static char disp_on363[2] = {0x92, 0x59};
+static char disp_on364[2] = {0x93, 0x02};
+static char disp_on365[2] = {0x94, 0x94};
+static char disp_on366[2] = {0x95, 0x02};
+static char disp_on367[2] = {0x96, 0xB4};
+static char disp_on368[2] = {0x97, 0x02};
+static char disp_on369[2] = {0x98, 0xE1};
+static char disp_on370[2] = {0x99, 0x03};
+static char disp_on371[2] = {0x9A, 0x01};
+static char disp_on372[2] = {0x9B, 0x03};
+static char disp_on373[2] = {0x9C, 0x28};
+static char disp_on374[2] = {0x9D, 0x03};
+static char disp_on375[2] = {0x9E, 0x30};
+static char disp_on376[2] = {0x9F, 0x03};
+static char disp_on377[2] = {0xA0, 0x37};
+static char disp_on378[2] = {0xA2, 0x03};
+static char disp_on379[2] = {0xA3, 0x3B};
+static char disp_on380[2] = {0xA4, 0x03};
+static char disp_on381[2] = {0xA5, 0x40};
+static char disp_on382[2] = {0xA6, 0x03};
+static char disp_on383[2] = {0xA7, 0x50};
+static char disp_on384[2] = {0xA9, 0x03};
+static char disp_on385[2] = {0xAA, 0x6D};
+static char disp_on386[2] = {0xAB, 0x03};
+static char disp_on387[2] = {0xAC, 0x80};
+static char disp_on388[2] = {0xAD, 0x03};
+static char disp_on389[2] = {0xAE, 0xCB};
+/* Gamma+ B settings end */
+/* Gamma- B settings start */
+static char disp_on390[2] = {0xAF, 0x00};
+static char disp_on391[2] = {0xB0, 0x19};
+static char disp_on392[2] = {0xB1, 0x00};
+static char disp_on393[2] = {0xB2, 0x36};
+static char disp_on394[2] = {0xB3, 0x00};
+static char disp_on395[2] = {0xB4, 0x55};
+static char disp_on396[2] = {0xB5, 0x00};
+static char disp_on397[2] = {0xB6, 0x70};
+static char disp_on398[2] = {0xB7, 0x00};
+static char disp_on399[2] = {0xB8, 0x83};
+static char disp_on400[2] = {0xB9, 0x00};
+static char disp_on401[2] = {0xBA, 0x99};
+static char disp_on402[2] = {0xBB, 0x00};
+static char disp_on403[2] = {0xBC, 0xA8};
+static char disp_on404[2] = {0xBD, 0x00};
+static char disp_on405[2] = {0xBE, 0xB7};
+static char disp_on406[2] = {0xBF, 0x00};
+static char disp_on407[2] = {0xC0, 0xC5};
+static char disp_on408[2] = {0xC1, 0x00};
+static char disp_on409[2] = {0xC2, 0xF7};
+static char disp_on410[2] = {0xC3, 0x01};
+static char disp_on411[2] = {0xC4, 0x1E};
+static char disp_on412[2] = {0xC5, 0x01};
+static char disp_on413[2] = {0xC6, 0x60};
+static char disp_on414[2] = {0xC7, 0x01};
+static char disp_on415[2] = {0xC8, 0x95};
+static char disp_on416[2] = {0xC9, 0x01};
+static char disp_on417[2] = {0xCA, 0xE1};
+static char disp_on418[2] = {0xCB, 0x02};
+static char disp_on419[2] = {0xCC, 0x20};
+static char disp_on420[2] = {0xCD, 0x02};
+static char disp_on421[2] = {0xCE, 0x23};
+static char disp_on422[2] = {0xCF, 0x02};
+static char disp_on423[2] = {0xD0, 0x59};
+static char disp_on424[2] = {0xD1, 0x02};
+static char disp_on425[2] = {0xD2, 0x94};
+static char disp_on426[2] = {0xD3, 0x02};
+static char disp_on427[2] = {0xD4, 0xB4};
+static char disp_on428[2] = {0xD5, 0x02};
+static char disp_on429[2] = {0xD6, 0xE1};
+static char disp_on430[2] = {0xD7, 0x03};
+static char disp_on431[2] = {0xD8, 0x01};
+static char disp_on432[2] = {0xD9, 0x03};
+static char disp_on433[2] = {0xDA, 0x28};
+static char disp_on434[2] = {0xDB, 0x03};
+static char disp_on435[2] = {0xDC, 0x30};
+static char disp_on436[2] = {0xDD, 0x03};
+static char disp_on437[2] = {0xDE, 0x37};
+static char disp_on438[2] = {0xDF, 0x03};
+static char disp_on439[2] = {0xE0, 0x3B};
+static char disp_on440[2] = {0xE1, 0x03};
+static char disp_on441[2] = {0xE2, 0x40};
+static char disp_on442[2] = {0xE3, 0x03};
+static char disp_on443[2] = {0xE4, 0x50};
+static char disp_on444[2] = {0xE5, 0x03};
+static char disp_on445[2] = {0xE6, 0x6D};
+static char disp_on446[2] = {0xE7, 0x03};
+static char disp_on447[2] = {0xE8, 0x80};
+static char disp_on448[2] = {0xE9, 0x03};
+static char disp_on449[2] = {0xEA, 0xCB};
+/* Gamma- B settings end */
+static char disp_on450[2] = {0xFF, 0x01};
+static char disp_on451[2] = {0xFB, 0x01};
+static char disp_on452[2] = {0xFF, 0x02};
+static char disp_on453[2] = {0xFB, 0x01};
+static char disp_on454[2] = {0xFF, 0x04};
+static char disp_on455[2] = {0xFB, 0x01};
+static char disp_on456[2] = {0xFF, 0x00};
+static char disp_on457[2] = {0x11, 0x00}; /* Sleep out, WaitTime(100) */
+static char disp_on458[2] = {0xFF, 0xEE};
+static char disp_on459[2] = {0x12, 0x50};
+static char disp_on460[2] = {0x13, 0x02};
+static char disp_on461[2] = {0x6A, 0x60};
+static char disp_on462[2] = {0xFF, 0x00};
+static char disp_on463[2] = {0x29, 0x00}; /* Display on */
+
+static struct dsi_cmd_desc nt35590_cmd_display_on_cmds[] = {
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on0), disp_on0},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on1), disp_on1},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on2), disp_on2},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 10, sizeof(disp_on3), disp_on3},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(lane), lane},
+	/*{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on_rotate),
+		 disp_on_rotate},*/
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(command_mode), command_mode},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on6), disp_on6},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on7), disp_on7},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on8), disp_on8},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on9), disp_on9},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on10), disp_on10},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on11), disp_on11},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on12), disp_on12},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on13), disp_on13},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on14), disp_on14},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on15), disp_on15},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on16), disp_on16},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on17), disp_on17},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on18), disp_on18},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on19), disp_on19},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on20), disp_on20},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on21), disp_on21},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on22), disp_on22},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on23), disp_on23},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on24), disp_on24},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on25), disp_on25},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on26), disp_on26},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on27), disp_on27},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on28), disp_on28},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on29), disp_on29},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on30), disp_on30},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on31), disp_on31},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on32), disp_on32},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on33), disp_on33},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on34), disp_on34},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on35), disp_on35},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on36), disp_on36},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on37), disp_on37},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on38), disp_on38},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on39), disp_on39},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on40), disp_on40},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on41), disp_on41},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on42), disp_on42},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on43), disp_on43},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on44), disp_on44},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on45), disp_on45},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on46), disp_on46},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on47), disp_on47},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on48), disp_on48},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on49), disp_on49},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on50), disp_on50},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on51), disp_on51},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on52), disp_on52},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on53), disp_on53},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on54), disp_on54},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on55), disp_on55},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on56), disp_on56},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on57), disp_on57},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on58), disp_on58},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on59), disp_on59},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on60), disp_on60},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on61), disp_on61},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on62), disp_on62},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on63), disp_on63},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on64), disp_on64},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on65), disp_on65},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on66), disp_on66},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on67), disp_on67},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on68), disp_on68},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on69), disp_on69},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on70), disp_on70},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on71), disp_on71},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on72), disp_on72},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on73), disp_on73},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on74), disp_on74},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on75), disp_on75},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on76), disp_on76},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on77), disp_on77},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on78), disp_on78},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on79), disp_on79},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on80), disp_on80},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on81), disp_on81},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on82), disp_on82},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on83), disp_on83},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on84), disp_on84},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on85), disp_on85},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on86), disp_on86},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on87), disp_on87},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on88), disp_on88},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on89), disp_on89},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on90), disp_on90},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on91), disp_on91},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on92), disp_on92},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on93), disp_on93},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on94), disp_on94},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on95), disp_on95},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on96), disp_on96},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on97), disp_on97},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on98), disp_on98},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on99), disp_on99},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on100), disp_on100},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on101), disp_on101},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on102), disp_on102},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on103), disp_on103},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on104), disp_on104},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on105), disp_on105},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on106), disp_on106},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on107), disp_on107},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on108), disp_on108},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on109), disp_on109},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on110), disp_on110},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on111), disp_on111},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on112), disp_on112},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on113), disp_on113},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on114), disp_on114},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on115), disp_on115},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on116), disp_on116},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on117), disp_on117},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on118), disp_on118},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on119), disp_on119},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on120), disp_on120},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on121), disp_on121},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on122), disp_on122},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on123), disp_on123},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on124), disp_on124},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on125), disp_on125},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on126), disp_on126},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on127), disp_on127},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on128), disp_on128},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on129), disp_on129},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on130), disp_on130},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on131), disp_on131},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on132), disp_on132},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on133), disp_on133},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on134), disp_on134},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on135), disp_on135},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on136), disp_on136},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on137), disp_on137},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on138), disp_on138},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on139), disp_on139},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on140), disp_on140},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on141), disp_on141},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on142), disp_on142},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on143), disp_on143},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on144), disp_on144},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on145), disp_on145},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on146), disp_on146},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on147), disp_on147},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on148), disp_on148},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on149), disp_on149},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on150), disp_on150},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on151), disp_on151},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on152), disp_on152},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on153), disp_on153},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on154), disp_on154},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on155), disp_on155},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on156), disp_on156},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on157), disp_on157},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on158), disp_on158},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on159), disp_on159},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on160), disp_on150},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on161), disp_on161},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on162), disp_on162},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on163), disp_on163},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on164), disp_on164},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on165), disp_on165},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on166), disp_on166},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on167), disp_on167},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on168), disp_on168},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on169), disp_on169},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on170), disp_on170},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on171), disp_on171},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on172), disp_on172},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on173), disp_on173},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on174), disp_on174},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on175), disp_on175},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on176), disp_on176},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on177), disp_on177},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on178), disp_on178},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on179), disp_on179},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on180), disp_on180},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on181), disp_on181},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on182), disp_on182},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on183), disp_on183},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on184), disp_on184},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on185), disp_on185},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on186), disp_on186},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on187), disp_on187},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on188), disp_on188},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on189), disp_on189},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on190), disp_on190},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on191), disp_on191},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on192), disp_on192},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on193), disp_on193},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on194), disp_on194},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on195), disp_on195},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on196), disp_on196},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on197), disp_on197},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on198), disp_on198},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on199), disp_on199},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on200), disp_on200},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on201), disp_on201},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on202), disp_on202},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on203), disp_on203},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on204), disp_on204},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on205), disp_on205},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on206), disp_on206},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on207), disp_on207},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on208), disp_on208},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on209), disp_on209},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on210), disp_on210},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on211), disp_on211},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on212), disp_on212},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on213), disp_on213},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on214), disp_on214},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on215), disp_on215},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on216), disp_on216},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on217), disp_on217},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on218), disp_on218},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on219), disp_on219},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on220), disp_on220},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on221), disp_on221},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on222), disp_on222},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on223), disp_on223},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on224), disp_on224},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on225), disp_on225},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on226), disp_on226},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on227), disp_on227},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on228), disp_on228},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on229), disp_on229},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on230), disp_on230},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on231), disp_on231},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on232), disp_on232},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on233), disp_on233},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on234), disp_on234},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on235), disp_on235},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on236), disp_on236},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on237), disp_on237},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on238), disp_on238},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on239), disp_on239},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on240), disp_on240},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on241), disp_on241},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on242), disp_on242},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on243), disp_on243},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on244), disp_on244},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on245), disp_on245},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on246), disp_on246},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on247), disp_on247},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on248), disp_on248},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on249), disp_on249},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on250), disp_on250},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on251), disp_on251},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on252), disp_on252},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on253), disp_on253},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on254), disp_on254},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on255), disp_on255},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on256), disp_on256},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on257), disp_on257},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on258), disp_on258},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on259), disp_on259},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on260), disp_on260},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on261), disp_on261},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on262), disp_on262},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on263), disp_on263},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on264), disp_on264},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on265), disp_on265},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on266), disp_on266},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on267), disp_on267},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on268), disp_on268},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on269), disp_on269},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on270), disp_on270},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on271), disp_on271},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on272), disp_on272},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on273), disp_on273},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on274), disp_on274},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on275), disp_on275},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on276), disp_on276},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on277), disp_on277},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on278), disp_on278},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on279), disp_on279},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on280), disp_on280},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on281), disp_on281},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on282), disp_on282},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on283), disp_on283},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on284), disp_on284},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on285), disp_on285},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on286), disp_on286},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on287), disp_on287},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on288), disp_on288},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on289), disp_on289},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on290), disp_on290},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on291), disp_on291},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on292), disp_on292},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on293), disp_on293},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on294), disp_on294},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on295), disp_on295},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on296), disp_on296},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on297), disp_on297},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on298), disp_on298},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on299), disp_on299},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on300), disp_on300},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on301), disp_on301},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on302), disp_on302},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on303), disp_on303},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on304), disp_on304},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on305), disp_on305},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on306), disp_on306},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on307), disp_on307},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on308), disp_on308},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on309), disp_on309},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on310), disp_on310},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on311), disp_on311},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on312), disp_on312},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on313), disp_on313},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on314), disp_on314},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on315), disp_on315},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on316), disp_on316},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on317), disp_on317},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on318), disp_on318},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on319), disp_on319},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on320), disp_on320},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on321), disp_on321},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on322), disp_on322},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on323), disp_on323},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on324), disp_on324},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on325), disp_on325},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on326), disp_on326},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on327), disp_on327},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on328), disp_on328},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on329), disp_on329},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on330), disp_on330},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on331), disp_on331},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on332), disp_on332},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on333), disp_on333},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on334), disp_on334},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on335), disp_on335},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on336), disp_on336},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on337), disp_on337},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on338), disp_on338},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on339), disp_on339},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on340), disp_on340},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on341), disp_on341},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on342), disp_on342},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on343), disp_on343},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on344), disp_on344},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on345), disp_on345},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on346), disp_on346},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on347), disp_on347},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on348), disp_on348},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on349), disp_on349},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on350), disp_on350},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on351), disp_on351},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on352), disp_on352},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on353), disp_on353},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on354), disp_on354},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on355), disp_on355},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on356), disp_on356},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on357), disp_on357},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on358), disp_on358},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on359), disp_on359},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on360), disp_on360},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on361), disp_on361},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on362), disp_on362},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on363), disp_on363},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on364), disp_on364},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on365), disp_on365},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on366), disp_on366},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on367), disp_on367},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on368), disp_on368},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on369), disp_on369},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on370), disp_on370},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on371), disp_on371},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on372), disp_on372},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on373), disp_on373},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on374), disp_on374},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on375), disp_on375},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on376), disp_on376},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on377), disp_on377},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on378), disp_on378},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on379), disp_on379},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on380), disp_on380},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on381), disp_on381},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on382), disp_on382},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on383), disp_on383},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on384), disp_on384},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on385), disp_on385},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on386), disp_on386},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on387), disp_on387},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on388), disp_on388},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on389), disp_on389},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on390), disp_on390},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on391), disp_on391},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on392), disp_on392},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on393), disp_on393},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on394), disp_on394},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on395), disp_on395},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on396), disp_on396},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on397), disp_on397},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on398), disp_on398},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on399), disp_on399},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on400), disp_on400},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on401), disp_on401},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on402), disp_on402},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on403), disp_on403},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on404), disp_on404},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on405), disp_on405},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on406), disp_on406},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on407), disp_on407},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on408), disp_on408},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on409), disp_on409},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on410), disp_on410},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on411), disp_on411},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on412), disp_on412},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on413), disp_on413},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on414), disp_on414},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on415), disp_on415},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on416), disp_on416},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on417), disp_on417},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on418), disp_on418},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on419), disp_on419},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on420), disp_on420},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on421), disp_on421},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on422), disp_on422},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on423), disp_on423},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on424), disp_on424},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on425), disp_on425},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on426), disp_on426},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on427), disp_on427},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on428), disp_on428},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on429), disp_on429},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on430), disp_on430},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on431), disp_on431},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on432), disp_on432},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on433), disp_on433},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on434), disp_on434},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on435), disp_on435},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on436), disp_on436},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on437), disp_on437},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on438), disp_on438},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on439), disp_on439},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on440), disp_on440},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on441), disp_on441},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on442), disp_on442},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on443), disp_on443},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on444), disp_on444},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on445), disp_on445},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on446), disp_on446},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on447), disp_on447},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on448), disp_on448},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on449), disp_on449},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on450), disp_on450},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on451), disp_on451},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on452), disp_on452},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on453), disp_on453},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on454), disp_on454},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on455), disp_on455},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on456), disp_on456},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 100, sizeof(disp_on457), disp_on457},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on458), disp_on458},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on459), disp_on459},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on460), disp_on460},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on461), disp_on461},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on462), disp_on462},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 120, sizeof(disp_on463), disp_on463},
+};
+
+static struct dsi_cmd_desc nt35590_video_display_on_cmds[] = {
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on0), disp_on0},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on1), disp_on1},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on2), disp_on2},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 10, sizeof(disp_on3), disp_on3},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(lane), lane},
+	/*{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on_rotate),
+		disp_on_rotate},*/
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video_mode), video_mode},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video_timing), video_timing},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on6), disp_on6},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on7), disp_on7},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on8), disp_on8},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on9), disp_on9},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on10), disp_on10},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on11), disp_on11},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on12), disp_on12},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on13), disp_on13},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on14), disp_on14},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on15), disp_on15},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on16), disp_on16},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on17), disp_on17},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on18), disp_on18},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on19), disp_on19},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on20), disp_on20},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on21), disp_on21},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on22), disp_on22},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on23), disp_on23},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on24), disp_on24},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on25), disp_on25},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on26), disp_on26},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on27), disp_on27},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on28), disp_on28},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on29), disp_on29},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on30), disp_on30},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on31), disp_on31},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on32), disp_on32},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on33), disp_on33},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on34), disp_on34},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on35), disp_on35},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on36), disp_on36},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on37), disp_on37},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on38), disp_on38},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on39), disp_on39},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on40), disp_on40},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on41), disp_on41},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on42), disp_on42},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on43), disp_on43},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on44), disp_on44},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on45), disp_on45},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on46), disp_on46},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on47), disp_on47},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on48), disp_on48},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on49), disp_on49},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on50), disp_on50},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on51), disp_on51},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on52), disp_on52},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on53), disp_on53},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on54), disp_on54},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on55), disp_on55},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on56), disp_on56},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on57), disp_on57},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on58), disp_on58},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on59), disp_on59},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on60), disp_on60},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on61), disp_on61},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on62), disp_on62},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on63), disp_on63},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on64), disp_on64},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on65), disp_on65},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on66), disp_on66},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on67), disp_on67},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on68), disp_on68},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on69), disp_on69},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on70), disp_on70},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on71), disp_on71},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on72), disp_on72},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on73), disp_on73},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on74), disp_on74},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on75), disp_on75},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on76), disp_on76},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on77), disp_on77},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on78), disp_on78},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on79), disp_on79},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on80), disp_on80},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on81), disp_on81},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on82), disp_on82},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on83), disp_on83},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on84), disp_on84},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on85), disp_on85},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on86), disp_on86},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on87), disp_on87},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on88), disp_on88},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on89), disp_on89},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on90), disp_on90},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on91), disp_on91},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on92), disp_on92},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on93), disp_on93},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on94), disp_on94},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on95), disp_on95},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on96), disp_on96},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on97), disp_on97},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on98), disp_on98},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on99), disp_on99},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on100), disp_on100},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on101), disp_on101},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on102), disp_on102},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on103), disp_on103},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on104), disp_on104},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on105), disp_on105},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on106), disp_on106},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on107), disp_on107},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on108), disp_on108},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on109), disp_on109},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on110), disp_on110},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on111), disp_on111},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on112), disp_on112},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on113), disp_on113},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on114), disp_on114},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on115), disp_on115},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on116), disp_on116},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on117), disp_on117},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on118), disp_on118},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on119), disp_on119},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on120), disp_on120},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on121), disp_on121},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on122), disp_on122},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on123), disp_on123},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on124), disp_on124},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on125), disp_on125},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on126), disp_on126},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on127), disp_on127},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on128), disp_on128},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on129), disp_on129},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on130), disp_on130},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on131), disp_on131},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on132), disp_on132},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on133), disp_on133},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on134), disp_on134},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on135), disp_on135},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on136), disp_on136},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on137), disp_on137},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on138), disp_on138},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on139), disp_on139},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on140), disp_on140},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on141), disp_on141},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on142), disp_on142},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on143), disp_on143},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on144), disp_on144},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on145), disp_on145},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on146), disp_on146},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on147), disp_on147},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on148), disp_on148},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on149), disp_on149},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on150), disp_on150},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on151), disp_on151},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on152), disp_on152},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on153), disp_on153},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on154), disp_on154},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on155), disp_on155},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on156), disp_on156},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on157), disp_on157},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on158), disp_on158},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on159), disp_on159},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on160), disp_on150},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on161), disp_on161},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on162), disp_on162},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on163), disp_on163},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on164), disp_on164},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on165), disp_on165},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on166), disp_on166},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on167), disp_on167},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on168), disp_on168},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on169), disp_on169},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on170), disp_on170},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on171), disp_on171},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on172), disp_on172},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on173), disp_on173},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on174), disp_on174},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on175), disp_on175},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on176), disp_on176},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on177), disp_on177},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on178), disp_on178},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on179), disp_on179},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on180), disp_on180},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on181), disp_on181},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on182), disp_on182},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on183), disp_on183},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on184), disp_on184},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on185), disp_on185},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on186), disp_on186},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on187), disp_on187},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on188), disp_on188},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on189), disp_on189},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on190), disp_on190},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on191), disp_on191},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on192), disp_on192},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on193), disp_on193},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on194), disp_on194},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on195), disp_on195},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on196), disp_on196},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on197), disp_on197},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on198), disp_on198},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on199), disp_on199},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on200), disp_on200},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on201), disp_on201},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on202), disp_on202},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on203), disp_on203},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on204), disp_on204},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on205), disp_on205},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on206), disp_on206},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on207), disp_on207},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on208), disp_on208},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on209), disp_on209},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on210), disp_on210},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on211), disp_on211},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on212), disp_on212},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on213), disp_on213},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on214), disp_on214},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on215), disp_on215},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on216), disp_on216},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on217), disp_on217},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on218), disp_on218},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on219), disp_on219},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on220), disp_on220},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on221), disp_on221},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on222), disp_on222},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on223), disp_on223},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on224), disp_on224},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on225), disp_on225},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on226), disp_on226},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on227), disp_on227},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on228), disp_on228},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on229), disp_on229},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on230), disp_on230},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on231), disp_on231},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on232), disp_on232},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on233), disp_on233},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on234), disp_on234},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on235), disp_on235},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on236), disp_on236},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on237), disp_on237},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on238), disp_on238},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on239), disp_on239},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on240), disp_on240},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on241), disp_on241},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on242), disp_on242},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on243), disp_on243},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on244), disp_on244},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on245), disp_on245},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on246), disp_on246},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on247), disp_on247},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on248), disp_on248},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on249), disp_on249},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on250), disp_on250},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on251), disp_on251},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on252), disp_on252},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on253), disp_on253},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on254), disp_on254},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on255), disp_on255},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on256), disp_on256},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on257), disp_on257},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on258), disp_on258},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on259), disp_on259},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on260), disp_on260},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on261), disp_on261},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on262), disp_on262},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on263), disp_on263},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on264), disp_on264},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on265), disp_on265},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on266), disp_on266},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on267), disp_on267},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on268), disp_on268},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on269), disp_on269},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on270), disp_on270},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on271), disp_on271},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on272), disp_on272},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on273), disp_on273},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on274), disp_on274},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on275), disp_on275},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on276), disp_on276},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on277), disp_on277},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on278), disp_on278},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on279), disp_on279},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on280), disp_on280},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on281), disp_on281},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on282), disp_on282},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on283), disp_on283},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on284), disp_on284},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on285), disp_on285},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on286), disp_on286},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on287), disp_on287},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on288), disp_on288},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on289), disp_on289},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on290), disp_on290},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on291), disp_on291},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on292), disp_on292},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on293), disp_on293},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on294), disp_on294},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on295), disp_on295},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on296), disp_on296},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on297), disp_on297},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on298), disp_on298},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on299), disp_on299},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on300), disp_on300},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on301), disp_on301},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on302), disp_on302},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on303), disp_on303},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on304), disp_on304},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on305), disp_on305},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on306), disp_on306},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on307), disp_on307},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on308), disp_on308},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on309), disp_on309},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on310), disp_on310},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on311), disp_on311},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on312), disp_on312},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on313), disp_on313},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on314), disp_on314},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on315), disp_on315},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on316), disp_on316},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on317), disp_on317},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on318), disp_on318},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on319), disp_on319},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on320), disp_on320},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on321), disp_on321},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on322), disp_on322},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on323), disp_on323},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on324), disp_on324},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on325), disp_on325},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on326), disp_on326},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on327), disp_on327},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on328), disp_on328},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on329), disp_on329},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on330), disp_on330},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on331), disp_on331},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on332), disp_on332},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on333), disp_on333},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on334), disp_on334},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on335), disp_on335},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on336), disp_on336},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on337), disp_on337},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on338), disp_on338},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on339), disp_on339},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on340), disp_on340},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on341), disp_on341},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on342), disp_on342},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on343), disp_on343},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on344), disp_on344},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on345), disp_on345},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on346), disp_on346},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on347), disp_on347},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on348), disp_on348},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on349), disp_on349},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on350), disp_on350},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on351), disp_on351},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on352), disp_on352},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on353), disp_on353},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on354), disp_on354},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on355), disp_on355},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on356), disp_on356},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on357), disp_on357},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on358), disp_on358},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on359), disp_on359},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on360), disp_on360},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on361), disp_on361},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on362), disp_on362},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on363), disp_on363},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on364), disp_on364},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on365), disp_on365},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on366), disp_on366},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on367), disp_on367},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on368), disp_on368},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on369), disp_on369},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on370), disp_on370},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on371), disp_on371},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on372), disp_on372},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on373), disp_on373},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on374), disp_on374},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on375), disp_on375},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on376), disp_on376},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on377), disp_on377},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on378), disp_on378},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on379), disp_on379},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on380), disp_on380},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on381), disp_on381},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on382), disp_on382},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on383), disp_on383},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on384), disp_on384},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on385), disp_on385},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on386), disp_on386},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on387), disp_on387},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on388), disp_on388},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on389), disp_on389},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on390), disp_on390},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on391), disp_on391},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on392), disp_on392},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on393), disp_on393},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on394), disp_on394},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on395), disp_on395},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on396), disp_on396},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on397), disp_on397},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on398), disp_on398},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on399), disp_on399},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on400), disp_on400},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on401), disp_on401},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on402), disp_on402},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on403), disp_on403},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on404), disp_on404},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on405), disp_on405},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on406), disp_on406},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on407), disp_on407},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on408), disp_on408},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on409), disp_on409},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on410), disp_on410},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on411), disp_on411},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on412), disp_on412},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on413), disp_on413},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on414), disp_on414},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on415), disp_on415},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on416), disp_on416},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on417), disp_on417},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on418), disp_on418},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on419), disp_on419},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on420), disp_on420},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on421), disp_on421},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on422), disp_on422},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on423), disp_on423},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on424), disp_on424},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on425), disp_on425},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on426), disp_on426},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on427), disp_on427},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on428), disp_on428},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on429), disp_on429},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on430), disp_on430},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on431), disp_on431},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on432), disp_on432},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on433), disp_on433},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on434), disp_on434},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on435), disp_on435},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on436), disp_on436},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on437), disp_on437},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on438), disp_on438},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on439), disp_on439},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on440), disp_on440},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on441), disp_on441},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on442), disp_on442},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on443), disp_on443},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on444), disp_on444},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on445), disp_on445},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on446), disp_on446},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on447), disp_on447},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on448), disp_on448},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on449), disp_on449},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on450), disp_on450},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on451), disp_on451},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on452), disp_on452},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on453), disp_on453},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on454), disp_on454},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on455), disp_on455},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on456), disp_on456},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 100, sizeof(disp_on457), disp_on457},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on458), disp_on458},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on459), disp_on459},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on460), disp_on460},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on461), disp_on461},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(disp_on462), disp_on462},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 120, sizeof(disp_on463), disp_on463},
+};
+
+static int mipi_nt35590_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct mipi_panel_info *mipi;
+	mfd = platform_get_drvdata(pdev);
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	pr_err("%s: Enter\n", __func__);
+	mipi  = &mfd->panel_info.mipi;
+
+	if (mipi->mode == DSI_VIDEO_MODE) {
+		mipi_dsi_cmds_tx(&nt35590_tx_buf,
+			nt35590_video_display_on_cmds,
+			ARRAY_SIZE(nt35590_video_display_on_cmds));
+	} else if (mipi->mode == DSI_CMD_MODE) {
+		mipi_dsi_cmds_tx(&nt35590_tx_buf,
+			nt35590_cmd_display_on_cmds,
+			ARRAY_SIZE(nt35590_cmd_display_on_cmds));
+	}
+	pr_err("%s: Exit\n", __func__);
+
+	return 0;
+}
+
+static int mipi_nt35590_lcd_off(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	pr_err("mipi_nt35590_lcd_off E\n");
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mipi_dsi_cmds_tx(&nt35590_tx_buf, nt35590_display_off_cmds,
+			ARRAY_SIZE(nt35590_display_off_cmds));
+
+	pr_err("mipi_nt35590_lcd_off X\n");
+	return 0;
+}
+
+static int __devinit mipi_nt35590_lcd_probe(struct platform_device *pdev)
+{
+	struct platform_device *pthisdev = NULL;
+	struct msm_fb_data_type *mfd;
+	struct mipi_panel_info *mipi;
+
+	if (pdev->id == 0) {
+		/* No board specific panel data as of now */
+		return 0;
+	}
+
+	pthisdev = msm_fb_add_device(pdev);
+	if (pthisdev) {
+		mfd = platform_get_drvdata(pthisdev);
+		if (!mfd)
+			return -ENODEV;
+		if (mfd->key != MFD_KEY)
+			return -EINVAL;
+
+		mipi  = &mfd->panel_info.mipi;
+
+		mipi->dlane_swap = 0;
+	}
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = mipi_nt35590_lcd_probe,
+	.driver = {
+		.name   = "mipi_NT35590",
+	},
+};
+
+DEFINE_LED_TRIGGER(bkl_led_trigger);
+static void mipi_nt35590_set_backlight(struct msm_fb_data_type *mfd)
+{
+	if (wled_trigger_initialized)
+		led_trigger_event(bkl_led_trigger, mfd->bl_level);
+	return;
+}
+
+static struct msm_fb_panel_data nt35590_panel_data = {
+	.on	= mipi_nt35590_lcd_on,
+	.off = mipi_nt35590_lcd_off,
+	.set_backlight = mipi_nt35590_set_backlight,
+};
+
+static int ch_used[3];
+
+static int mipi_nt35590_lcd_init(void)
+{
+	mipi_dsi_buf_alloc(&nt35590_tx_buf, DSI_BUF_SIZE);
+	mipi_dsi_buf_alloc(&nt35590_rx_buf, DSI_BUF_SIZE);
+
+	led_trigger_register_simple("bkl_trigger", &bkl_led_trigger);
+	pr_info("%s: SUCCESS (WLED TRIGGER)\n", __func__);
+	wled_trigger_initialized = 1;
+
+	return platform_driver_register(&this_driver);
+}
+
+int mipi_nt35590_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel)
+{
+	struct platform_device *pdev = NULL;
+	int ret;
+
+	if ((channel >= 3) || ch_used[channel])
+		return -ENODEV;
+
+	ch_used[channel] = TRUE;
+
+	ret = mipi_nt35590_lcd_init();
+	if (ret) {
+		pr_err("mipi_nt35590_lcd_init() failed with ret %u\n", ret);
+		return ret;
+	}
+
+	pdev = platform_device_alloc("mipi_NT35590", (panel << 8)|channel);
+	if (!pdev)
+		return -ENOMEM;
+
+	nt35590_panel_data.panel_info = *pinfo;
+	ret = platform_device_add_data(pdev, &nt35590_panel_data,
+				sizeof(nt35590_panel_data));
+	if (ret) {
+		pr_debug("%s: platform_device_add_data failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		pr_debug("%s: platform_device_register failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	return 0;
+
+err_device_put:
+	platform_device_put(pdev);
+	return ret;
+}
diff --git a/drivers/video/msm/mipi_NT35590.h b/drivers/video/msm/mipi_NT35590.h
new file mode 100644
index 0000000..c92e69e
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35590.h
@@ -0,0 +1,20 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 and
+ * only 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.
+ *
+ */
+
+#ifndef MIPI_NT35590_H
+#define MIPI_NT35590_H
+
+int mipi_nt35590_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel);
+
+#endif  /* MIPI_NT35590_H */
diff --git a/drivers/video/msm/mipi_NT35590_cmd_720p_pt.c b/drivers/video/msm/mipi_NT35590_cmd_720p_pt.c
new file mode 100644
index 0000000..25c2913
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35590_cmd_720p_pt.c
@@ -0,0 +1,100 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 and
+ * only 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.
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_NT35590.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_cmd_mode_phy_db = {
+	/* DSI Bit Clock at 485 MHz, 4 lane, RGB888 */
+	/* regulator */
+	{0x09, 0x08, 0x05, 0x00, 0x20},
+	/* timing   */
+	{0x93, 0x21, 0x17, 0x00, 0x59, 0x61, 0x1B, 0x24,
+	0x22, 0x03, 0x04, 0xa0},
+	/* phy ctrl */
+	{0x5f, 0x00, 0x00, 0x10},
+	/* strength */
+	{0xff, 0x00, 0x06, 0x00},
+	/* pll control */
+	{0x00, 0xcb, 0x31, 0xd9, 0x00, 0x20, 0x07, 0x62,
+	0x41, 0x0f, 0x01,
+	0x00, 0x14, 0x03, 0x0, 0x2, 0x0, 0x20, 0x0, 0x01},
+};
+
+static int mipi_cmd_nt35590_720p_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_cmd_nt35590_720p"))
+		return 0;
+
+	pinfo.xres = 720;
+	pinfo.yres = 1280;
+	pinfo.type = MIPI_CMD_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 164;
+	pinfo.lcdc.h_front_porch = 140;
+	pinfo.lcdc.h_pulse_width = 8;
+	pinfo.lcdc.v_back_porch = 13;
+	pinfo.lcdc.v_front_porch = 10;
+	pinfo.lcdc.v_pulse_width = 5;
+
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = 255;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+	pinfo.clk_rate = 485000000;
+	pinfo.mipi.esc_byte_ratio = 4;
+
+	pinfo.lcd.vsync_enable = TRUE;
+	pinfo.lcd.hw_vsync_mode = TRUE;
+	pinfo.lcd.refx100 = 6200; /* adjust refx100 to prevent tearing */
+
+	pinfo.mipi.mode = DSI_CMD_MODE;
+	pinfo.mipi.dst_format = DSI_CMD_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+	pinfo.mipi.data_lane2 = TRUE;
+	pinfo.mipi.data_lane3 = TRUE;
+	pinfo.mipi.t_clk_post = 0x04;
+	pinfo.mipi.t_clk_pre = 0x1d;
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.te_sel = 1; /* TE from vsync gpio */
+	pinfo.mipi.interleave_max = 1;
+	pinfo.mipi.insert_dcs_cmd = TRUE;
+	pinfo.mipi.wr_mem_continue = 0x3c;
+	pinfo.mipi.wr_mem_start = 0x2c;
+	pinfo.mipi.dsi_phy_db = &dsi_cmd_mode_phy_db;
+	pinfo.mipi.tx_eot_append = 0x01;
+	pinfo.mipi.rx_eot_ignore = 0x0;
+
+	ret = mipi_nt35590_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_720P_PT);
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_cmd_nt35590_720p_pt_init);
diff --git a/drivers/video/msm/mipi_NT35590_video_720p_pt.c b/drivers/video/msm/mipi_NT35590_video_720p_pt.c
new file mode 100644
index 0000000..d508a95
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35590_video_720p_pt.c
@@ -0,0 +1,110 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 and
+ * only 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.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_NT35590.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+	/* DSI Bit Clock at 485 MHz, 4 lane, RGB888 */
+	/* regulator */
+	{0x09, 0x08, 0x05, 0x00, 0x20},
+	/* timing   */
+	{0x93, 0x21, 0x17, 0x00, 0x59, 0x61, 0x1B, 0x24,
+	0x22, 0x03, 0x04, 0xa0},
+	/* phy ctrl */
+	{0x5f, 0x00, 0x00, 0x10},
+	/* strength */
+	{0xff, 0x00, 0x06, 0x00},
+	/* pll control */
+	{0x00, 0xcb, 0x31, 0xd9, 0x00, 0x20, 0x07, 0x62,
+	0x41, 0x0f, 0x01,
+	0x00, 0x14, 0x03, 0x0, 0x2, 0x0, 0x20, 0x0, 0x01},
+};
+
+static int mipi_video_nt35590_720p_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_video_nt35590_720p"))
+		return 0;
+
+	pinfo.xres = 720;
+	pinfo.yres = 1280;
+	pinfo.type = MIPI_VIDEO_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 164;
+	pinfo.lcdc.h_front_porch = 140;
+	pinfo.lcdc.h_pulse_width = 8;
+	pinfo.lcdc.v_back_porch = 13;
+	pinfo.lcdc.v_front_porch = 10;
+	pinfo.lcdc.v_pulse_width = 5;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	/* number of dot_clk cycles HSYNC active edge is
+	delayed from VSYNC active edge */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.clk_rate = 485000000;
+	pinfo.mipi.esc_byte_ratio = 4;
+	pinfo.bl_max = 255;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+	pinfo.mipi.mode = DSI_VIDEO_MODE;
+	/* send HSA and HE following VS/VE packet */
+	pinfo.mipi.pulse_mode_hsa_he = TRUE;
+	pinfo.mipi.hfp_power_stop = TRUE; /* LP-11 during the HFP period */
+	pinfo.mipi.hbp_power_stop = TRUE; /* LP-11 during the HBP period */
+	pinfo.mipi.hsa_power_stop = TRUE; /* LP-11 during the HSA period */
+	/* LP-11 or let Command Mode Engine send packets in
+	HS or LP mode for the BLLP of the last line of a frame */
+	pinfo.mipi.eof_bllp_power_stop = TRUE;
+	/* LP-11 or let Command Mode Engine send packets in
+	HS or LP mode for packets sent during BLLP period */
+	pinfo.mipi.bllp_power_stop = TRUE;
+
+	pinfo.mipi.traffic_mode = DSI_BURST_MODE;
+	pinfo.mipi.dst_format =  DSI_VIDEO_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB; /* RGB */
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+	pinfo.mipi.data_lane2 = TRUE;
+	pinfo.mipi.data_lane3 = TRUE;
+
+	pinfo.mipi.t_clk_post = 0x04;
+	pinfo.mipi.t_clk_pre = 0x1d;
+
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.frame_rate = 60; /* FIXME */
+
+	pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+	/* append EOT at the end of data burst */
+	pinfo.mipi.tx_eot_append = 0x01;
+
+	ret = mipi_nt35590_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_720P_PT);
+
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_video_nt35590_720p_pt_init);
diff --git a/drivers/video/msm/mipi_chimei_wuxga.c b/drivers/video/msm/mipi_chimei_wuxga.c
index e9e291e..3645d61 100644
--- a/drivers/video/msm/mipi_chimei_wuxga.c
+++ b/drivers/video/msm/mipi_chimei_wuxga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_chimei_wxga_pt.c b/drivers/video/msm/mipi_chimei_wxga_pt.c
index 88a5193..8b1b828 100644
--- a/drivers/video/msm/mipi_chimei_wxga_pt.c
+++ b/drivers/video/msm/mipi_chimei_wxga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
index 55f8b94..4816059 100644
--- a/drivers/video/msm/mipi_dsi.c
+++ b/drivers/video/msm/mipi_dsi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. 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 and
@@ -45,6 +45,8 @@
 
 static int mipi_dsi_off(struct platform_device *pdev);
 static int mipi_dsi_on(struct platform_device *pdev);
+static int mipi_dsi_fps_level_change(struct platform_device *pdev,
+					u32 fps_level);
 
 static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
 static int pdev_list_cnt;
@@ -63,6 +65,14 @@
 
 struct device dsi_dev;
 
+static int mipi_dsi_fps_level_change(struct platform_device *pdev,
+					u32 fps_level)
+{
+	mipi_dsi_wait4video_done();
+	mipi_dsi_configure_fb_divider(fps_level);
+	return 0;
+}
+
 static int mipi_dsi_off(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -152,7 +162,6 @@
 	fbi = mfd->fbi;
 	var = &fbi->var;
 	pinfo = &mfd->panel_info;
-	esc_byte_ratio = pinfo->mipi.esc_byte_ratio;
 
 	if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_power_save)
 		mipi_dsi_pdata->dsi_power_save(1);
@@ -322,6 +331,12 @@
 	return ret;
 }
 
+static int mipi_dsi_early_off(struct platform_device *pdev)
+{
+	return panel_next_early_off(pdev);
+}
+
+
 static int mipi_dsi_late_init(struct platform_device *pdev)
 {
 	return panel_next_late_init(pdev);
@@ -421,11 +436,13 @@
 
 		if (mipi_dsi_pdata->splash_is_enabled &&
 			!mipi_dsi_pdata->splash_is_enabled()) {
+			mipi_dsi_prepare_clocks();
 			mipi_dsi_ahb_ctrl(1);
 			MIPI_OUTP(MIPI_DSI_BASE + 0x118, 0);
 			MIPI_OUTP(MIPI_DSI_BASE + 0x0, 0);
 			MIPI_OUTP(MIPI_DSI_BASE + 0x200, 0);
 			mipi_dsi_ahb_ctrl(0);
+			mipi_dsi_unprepare_clocks();
 		}
 		mipi_dsi_resource_initialized = 1;
 
@@ -446,9 +463,6 @@
 	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
 		return -ENOMEM;
 
-	if (!mfd->cont_splash_done)
-		cont_splash_clk_ctrl(1);
-
 	mdp_dev = platform_device_alloc("mdp", pdev->id);
 	if (!mdp_dev)
 		return -ENOMEM;
@@ -474,7 +488,9 @@
 	pdata = mdp_dev->dev.platform_data;
 	pdata->on = mipi_dsi_on;
 	pdata->off = mipi_dsi_off;
+	pdata->fps_level_change = mipi_dsi_fps_level_change;
 	pdata->late_init = mipi_dsi_late_init;
+	pdata->early_off = mipi_dsi_early_off;
 	pdata->next = pdev;
 
 	/*
@@ -585,6 +601,11 @@
 
 	pdev_list[pdev_list_cnt++] = pdev;
 
+	esc_byte_ratio = pinfo->mipi.esc_byte_ratio;
+
+	if (!mfd->cont_splash_done)
+		cont_splash_clk_ctrl(1);
+
 return 0;
 
 mipi_dsi_probe_err:
diff --git a/drivers/video/msm/mipi_dsi.h b/drivers/video/msm/mipi_dsi.h
index d9a7555..7d994f2 100644
--- a/drivers/video/msm/mipi_dsi.h
+++ b/drivers/video/msm/mipi_dsi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2013, The Linux Foundation. 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 and
@@ -268,6 +268,7 @@
 #define CMD_REQ_COMMIT	0x0002
 #define CMD_CLK_CTRL	0x0004
 #define CMD_REQ_NO_MAX_PKT_SIZE 0x0008
+#define CMD_REQ_SINGLE_TX 0x0010
 
 struct dcs_cmd_req {
 	struct dsi_cmd_desc *cmds;
@@ -293,6 +294,8 @@
 int mipi_dsi_buf_alloc(struct dsi_buf *, int size);
 int mipi_dsi_cmd_dma_add(struct dsi_buf *dp, struct dsi_cmd_desc *cm);
 int mipi_dsi_cmds_tx(struct dsi_buf *dp, struct dsi_cmd_desc *cmds, int cnt);
+int mipi_dsi_cmds_single_tx(struct dsi_buf *dp, struct dsi_cmd_desc *cmds,
+								int cnt);
 
 int mipi_dsi_cmd_dma_tx(struct dsi_buf *dp);
 int mipi_dsi_cmd_reg_tx(uint32 data);
@@ -313,8 +316,6 @@
 void mipi_dsi_set_tear_off(struct msm_fb_data_type *mfd);
 void mipi_dsi_set_backlight(struct msm_fb_data_type *mfd, int level);
 void mipi_dsi_cmd_backlight_tx(struct dsi_buf *dp);
-void mipi_dsi_clk_enable(void);
-void mipi_dsi_clk_disable(void);
 void mipi_dsi_pre_kickoff_action(void);
 void mipi_dsi_post_kickoff_action(void);
 void mipi_dsi_pre_kickoff_add(struct dsi_kickoff_action *act);
@@ -328,16 +329,47 @@
 irqreturn_t mipi_dsi_isr(int irq, void *ptr);
 
 void mipi_set_tx_power_mode(int mode);
-void mipi_dsi_phy_ctrl(int on);
 void mipi_dsi_phy_init(int panel_ndx, struct msm_panel_info const *panel_info,
 	int target_type);
 int mipi_dsi_clk_div_config(uint8 bpp, uint8 lanes,
 			    uint32 *expected_dsi_pclk);
 int mipi_dsi_clk_init(struct platform_device *pdev);
 void mipi_dsi_clk_deinit(struct device *dev);
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+void mipi_dsi_clk_enable(void);
+void mipi_dsi_clk_disable(void);
 void mipi_dsi_prepare_clocks(void);
 void mipi_dsi_unprepare_clocks(void);
 void mipi_dsi_ahb_ctrl(u32 enable);
+void mipi_dsi_phy_ctrl(int on);
+#else
+static inline void mipi_dsi_clk_enable(void)
+{
+	/* empty */
+}
+void mipi_dsi_clk_disable(void)
+{
+	/* empty */
+}
+void mipi_dsi_prepare_clocks(void)
+{
+	/* empty */
+}
+void mipi_dsi_unprepare_clocks(void)
+{
+	/* empty */
+}
+void mipi_dsi_ahb_ctrl(u32 enable)
+{
+	/* empty */
+}
+void mipi_dsi_phy_ctrl(int on)
+{
+	/* empty */
+}
+#endif
+
 void cont_splash_clk_ctrl(int enable);
 void mipi_dsi_turn_on_clks(void);
 void mipi_dsi_turn_off_clks(void);
@@ -347,6 +379,8 @@
 struct dcs_cmd_req *mipi_dsi_cmdlist_get(void);
 void mipi_dsi_cmdlist_commit(int from_mdp);
 void mipi_dsi_cmd_mdp_busy(void);
+void mipi_dsi_configure_fb_divider(u32 fps_level);
+void mipi_dsi_wait4video_done(void);
 
 #ifdef CONFIG_FB_MSM_MDP303
 void update_lane_config(struct msm_panel_info *pinfo);
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
index d2c9b0a..9e4160c 100644
--- a/drivers/video/msm/mipi_dsi_host.c
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -1,5 +1,5 @@
 
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. 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 and
@@ -930,8 +930,8 @@
 	MIPI_OUTP(MIPI_DSI_BASE + 0x00c8, data); /* DSI_EOT_PACKET_CTRL */
 
 
-	/* allow only ack-err-status  to generate interrupt */
-	MIPI_OUTP(MIPI_DSI_BASE + 0x0108, 0x13ff3fe0); /* DSI_ERR_INT_MASK0 */
+	/* allow only ack-err-status + fifo underrun to generate interrupt */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0108, 0x13ff37e0); /* DSI_ERR_INT_MASK0 */
 
 	intr_ctrl |= DSI_INTR_ERROR_MASK;
 	MIPI_OUTP(MIPI_DSI_BASE + 0x010c, intr_ctrl); /* DSI_INTL_CTRL */
@@ -1032,7 +1032,7 @@
 }
 
 
-static void mipi_dsi_wait4video_done(void)
+void mipi_dsi_wait4video_done(void)
 {
 	unsigned long flag;
 
@@ -1041,7 +1041,8 @@
 	mipi_dsi_enable_irq(DSI_VIDEO_TERM);
 	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
 
-	wait_for_completion(&dsi_video_comp);
+	wait_for_completion_timeout(&dsi_video_comp,
+					msecs_to_jiffies(VSYNC_PERIOD * 4));
 }
 
 void mipi_dsi_mdp_busy_wait(void)
@@ -1187,6 +1188,62 @@
 	return cnt;
 }
 
+/*
+ * mipi_dsi_cmds_single_tx:
+ * thread context only
+ */
+int mipi_dsi_cmds_single_tx(struct dsi_buf *tp, struct dsi_cmd_desc *cmds,
+								int cnt)
+{
+	struct dsi_cmd_desc *cm;
+	uint32 dsi_ctrl, ctrl;
+	int i, j = 0, k = 0, cmd_len = 0, video_mode;
+	char *cmds_tx;
+	char *bp;
+
+	if (tp == NULL || cmds == NULL) {
+		pr_err("%s: Null commands", __func__);
+		return -EINVAL;
+	}
+
+	/* turn on cmd mode
+	* for video mode, do not send cmds more than
+	* one pixel line, since it only transmit it
+	* during BLLP.
+	*/
+	dsi_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0000);
+	video_mode = dsi_ctrl & 0x02; /* VIDEO_MODE_EN */
+	if (video_mode) {
+		ctrl = dsi_ctrl | 0x04; /* CMD_MODE_EN */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0000, ctrl);
+	}
+
+	cm = cmds;
+	cmds_tx = kmalloc((DSI_BUF_SIZE + DSI_HOST_HDR_SIZE) * cnt, GFP_KERNEL);
+	mipi_dsi_buf_init(tp);
+	mipi_dsi_enable_irq(DSI_CMD_TERM);
+	for (i = 0; i < cnt; i++) {
+		mipi_dsi_buf_init(tp);
+		mipi_dsi_cmd_dma_add(tp, cm);
+		bp = tp->data;
+		for (j = 0; j < tp->len; j++) {
+			*(cmds_tx + k) = *bp++;
+			k++;
+		}
+		cmd_len = cmd_len + tp->len;
+		cm++;
+	}
+	tp->data = cmds_tx;
+	tp->len = cmd_len;
+	mipi_dsi_cmd_dma_tx(tp);
+	kfree(cmds_tx);
+
+	if (video_mode)
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0000, dsi_ctrl); /* restore */
+
+	return cnt;
+}
+
 /* MIPI_DSI_MRPS, Maximum Return Packet Size */
 static char max_pktsize[2] = {0x00, 0x00}; /* LSB tx first, 10 bytes */
 
@@ -1557,7 +1614,10 @@
 
 	mipi_dsi_buf_init(&dsi_tx_buf);
 	tp = &dsi_tx_buf;
-	ret = mipi_dsi_cmds_tx(tp, req->cmds, req->cmds_cnt);
+	if (req->flags & CMD_REQ_SINGLE_TX)
+		ret = mipi_dsi_cmds_single_tx(tp, req->cmds, req->cmds_cnt);
+	else
+		ret = mipi_dsi_cmds_tx(tp, req->cmds, req->cmds_cnt);
 
 	if (req->cb)
 		req->cb(ret);
@@ -1718,7 +1778,9 @@
 
 	if (status & 0x44444489) {
 		MIPI_OUTP(MIPI_DSI_BASE + 0x0008, status);
-		pr_debug("%s: status=%x\n", __func__, status);
+		pr_err("%s: Error: status=%x\n", __func__, status);
+		mipi_dsi_sw_reset();
+		mdp4_mixer_reset(0);
 	}
 }
 
@@ -1759,7 +1821,13 @@
 #endif
 	if (isr & DSI_INTR_ERROR) {
 		mipi_dsi_mdp_stat_inc(STAT_DSI_ERROR);
+		spin_lock(&dsi_mdp_lock);
+		dsi_ctrl_lock = FALSE;
+		dsi_mdp_busy = FALSE;
+		mipi_dsi_disable_irq_nosync(DSI_MDP_TERM);
 		mipi_dsi_error();
+		complete(&dsi_mdp_comp);
+		spin_unlock(&dsi_mdp_lock);
 	}
 
 	if (isr & DSI_INTR_VIDEO_DONE) {
diff --git a/drivers/video/msm/mipi_lgit.h b/drivers/video/msm/mipi_lgit.h
index 4d26bc0..65e8ca2 100644
--- a/drivers/video/msm/mipi_lgit.h
+++ b/drivers/video/msm/mipi_lgit.h
@@ -11,7 +11,7 @@
  *       copyright notice, this list of conditions and the following
  *       disclaimer in the documentation and/or other materials provided
  *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     * Neither the name of The Linux Foundation nor the names of its
  *       contributors may be used to endorse or promote products derived
  *       from this software without specific prior written permission.
  *
diff --git a/drivers/video/msm/mipi_novatek.c b/drivers/video/msm/mipi_novatek.c
index 52a42cc..9bcf957 100644
--- a/drivers/video/msm/mipi_novatek.c
+++ b/drivers/video/msm/mipi_novatek.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_novatek.h b/drivers/video/msm/mipi_novatek.h
index f84de9a..7abe863 100644
--- a/drivers/video/msm/mipi_novatek.h
+++ b/drivers/video/msm/mipi_novatek.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
index 4c1aa63..d2820a8 100644
--- a/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
+++ b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_novatek_video_qhd_pt.c b/drivers/video/msm/mipi_novatek_video_qhd_pt.c
index 7a9d556..8881b60 100644
--- a/drivers/video/msm/mipi_novatek_video_qhd_pt.c
+++ b/drivers/video/msm/mipi_novatek_video_qhd_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_orise.c b/drivers/video/msm/mipi_orise.c
index d1d6956..2fd5ff4 100644
--- a/drivers/video/msm/mipi_orise.c
+++ b/drivers/video/msm/mipi_orise.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_orise.h b/drivers/video/msm/mipi_orise.h
index 1659479..da4b59f 100644
--- a/drivers/video/msm/mipi_orise.h
+++ b/drivers/video/msm/mipi_orise.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_orise_cmd_720p_pt.c b/drivers/video/msm/mipi_orise_cmd_720p_pt.c
index c2a158d..9b7020a 100644
--- a/drivers/video/msm/mipi_orise_cmd_720p_pt.c
+++ b/drivers/video/msm/mipi_orise_cmd_720p_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_orise_video_720p_pt.c b/drivers/video/msm/mipi_orise_video_720p_pt.c
index da8b5e5..1484576 100644
--- a/drivers/video/msm/mipi_orise_video_720p_pt.c
+++ b/drivers/video/msm/mipi_orise_video_720p_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_renesas.c b/drivers/video/msm/mipi_renesas.c
index c842672..3fa2606 100644
--- a/drivers/video/msm/mipi_renesas.c
+++ b/drivers/video/msm/mipi_renesas.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_renesas.h b/drivers/video/msm/mipi_renesas.h
index 59ccfd0..67f777f 100644
--- a/drivers/video/msm/mipi_renesas.h
+++ b/drivers/video/msm/mipi_renesas.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c b/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
index 2ebfad4..1bf86a7 100644
--- a/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
+++ b/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_renesas_video_fwvga_pt.c b/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
index 144d9ff..b7f7704 100644
--- a/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
+++ b/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_simulator.c b/drivers/video/msm/mipi_simulator.c
index c751472..e2d4b15 100644
--- a/drivers/video/msm/mipi_simulator.c
+++ b/drivers/video/msm/mipi_simulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_simulator.h b/drivers/video/msm/mipi_simulator.h
index 274ce8f..6c0a60c 100644
--- a/drivers/video/msm/mipi_simulator.h
+++ b/drivers/video/msm/mipi_simulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_simulator_video.c b/drivers/video/msm/mipi_simulator_video.c
index 845df75..258a7ec 100644
--- a/drivers/video/msm/mipi_simulator_video.c
+++ b/drivers/video/msm/mipi_simulator_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_tc358764_dsi2lvds.c b/drivers/video/msm/mipi_tc358764_dsi2lvds.c
index 1583168..c962123 100644
--- a/drivers/video/msm/mipi_tc358764_dsi2lvds.c
+++ b/drivers/video/msm/mipi_tc358764_dsi2lvds.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_tc358764_dsi2lvds.h b/drivers/video/msm/mipi_tc358764_dsi2lvds.h
index 1b949f0..671c191 100644
--- a/drivers/video/msm/mipi_tc358764_dsi2lvds.h
+++ b/drivers/video/msm/mipi_tc358764_dsi2lvds.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_toshiba.c b/drivers/video/msm/mipi_toshiba.c
index 498e122..8b306f3 100644
--- a/drivers/video/msm/mipi_toshiba.c
+++ b/drivers/video/msm/mipi_toshiba.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
@@ -184,6 +184,7 @@
 static int mipi_toshiba_lcd_on(struct platform_device *pdev)
 {
 	struct msm_fb_data_type *mfd;
+	struct dcs_cmd_req cmdreq;
 
 	mfd = platform_get_drvdata(pdev);
 
@@ -192,24 +193,36 @@
 	if (mfd->key != MFD_KEY)
 		return -EINVAL;
 
-	if (TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WVGA_PT)
-		mipi_dsi_cmds_tx(&toshiba_tx_buf,
-			toshiba_wvga_display_on_cmds,
-			ARRAY_SIZE(toshiba_wvga_display_on_cmds));
-	else if (TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WSVGA_PT ||
-		TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WUXGA)
-		mipi_dsi_cmds_tx(&toshiba_tx_buf,
-			toshiba_wsvga_display_on_cmds,
-			ARRAY_SIZE(toshiba_wsvga_display_on_cmds));
-	else
+	if (TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WVGA_PT) {
+		cmdreq.cmds = toshiba_wvga_display_on_cmds;
+		cmdreq.cmds_cnt = ARRAY_SIZE(toshiba_wvga_display_on_cmds);
+		cmdreq.flags = CMD_REQ_COMMIT;
+		cmdreq.rlen = 0;
+		cmdreq.cb = NULL;
+		mipi_dsi_cmdlist_put(&cmdreq);
+	} else if (TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WSVGA_PT ||
+		TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WUXGA) {
+		cmdreq.cmds = toshiba_wsvga_display_on_cmds;
+		cmdreq.cmds_cnt = ARRAY_SIZE(toshiba_wsvga_display_on_cmds);
+		cmdreq.flags = CMD_REQ_COMMIT;
+		cmdreq.rlen = 0;
+		cmdreq.cb = NULL;
+		mipi_dsi_cmdlist_put(&cmdreq);
+	} else
 		return -EINVAL;
 
 	return 0;
 }
 
+static int mipi_toshiba_early_off(struct platform_device *pdev)
+{
+	return 0;
+}
+
 static int mipi_toshiba_lcd_off(struct platform_device *pdev)
 {
 	struct msm_fb_data_type *mfd;
+	struct dcs_cmd_req cmdreq;
 
 	mfd = platform_get_drvdata(pdev);
 
@@ -218,9 +231,13 @@
 	if (mfd->key != MFD_KEY)
 		return -EINVAL;
 
-	mipi_dsi_cmds_tx(&toshiba_tx_buf, toshiba_display_off_cmds,
-			ARRAY_SIZE(toshiba_display_off_cmds));
+	cmdreq.cmds = toshiba_display_off_cmds;
+	cmdreq.cmds_cnt = ARRAY_SIZE(toshiba_display_off_cmds);
+	cmdreq.flags = CMD_REQ_COMMIT;
+	cmdreq.rlen = 0;
+	cmdreq.cb = NULL;
 
+	mipi_dsi_cmdlist_put(&cmdreq);
 	return 0;
 }
 
@@ -302,6 +319,7 @@
 	.on		= mipi_toshiba_lcd_on,
 	.off		= mipi_toshiba_lcd_off,
 	.late_init	= mipi_toshiba_lcd_late_init,
+	.early_off	= mipi_toshiba_early_off,
 	.set_backlight  = mipi_toshiba_set_backlight,
 };
 
diff --git a/drivers/video/msm/mipi_toshiba.h b/drivers/video/msm/mipi_toshiba.h
index dd446b9..faff16d 100644
--- a/drivers/video/msm/mipi_toshiba.h
+++ b/drivers/video/msm/mipi_toshiba.h
@@ -1,5 +1,5 @@
 
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
index eb2946b..f604f0c 100644
--- a/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
+++ b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_toshiba_video_wuxga.c b/drivers/video/msm/mipi_toshiba_video_wuxga.c
index 8eddce4..ed7895e 100644
--- a/drivers/video/msm/mipi_toshiba_video_wuxga.c
+++ b/drivers/video/msm/mipi_toshiba_video_wuxga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_toshiba_video_wvga_pt.c b/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
index d6cabfc..fdd4d1c 100644
--- a/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
+++ b/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_truly.c b/drivers/video/msm/mipi_truly.c
index fd2a3ea..6fcab32 100644
--- a/drivers/video/msm/mipi_truly.c
+++ b/drivers/video/msm/mipi_truly.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_truly.h b/drivers/video/msm/mipi_truly.h
index 900e6f6..4c12ff9 100644
--- a/drivers/video/msm/mipi_truly.h
+++ b/drivers/video/msm/mipi_truly.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_truly_tft540960_1_e.c b/drivers/video/msm/mipi_truly_tft540960_1_e.c
index 50db66e..456517a 100644
--- a/drivers/video/msm/mipi_truly_tft540960_1_e.c
+++ b/drivers/video/msm/mipi_truly_tft540960_1_e.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_truly_tft540960_1_e.h b/drivers/video/msm/mipi_truly_tft540960_1_e.h
index 8cbfb80..d7329d6 100644
--- a/drivers/video/msm/mipi_truly_tft540960_1_e.h
+++ b/drivers/video/msm/mipi_truly_tft540960_1_e.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c b/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c
index 3423241..ad7ebe9 100644
--- a/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c
+++ b/drivers/video/msm/mipi_truly_tft540960_1_e_cmd_qhd_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_truly_tft540960_1_e_video_qhd_pt.c b/drivers/video/msm/mipi_truly_tft540960_1_e_video_qhd_pt.c
index 3c0c0b7..d62cfc9 100644
--- a/drivers/video/msm/mipi_truly_tft540960_1_e_video_qhd_pt.c
+++ b/drivers/video/msm/mipi_truly_tft540960_1_e_video_qhd_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/mipi_truly_video_wvga_pt.c b/drivers/video/msm/mipi_truly_video_wvga_pt.c
index 03ef32b..3fc14d2 100644
--- a/drivers/video/msm/mipi_truly_video_wvga_pt.c
+++ b/drivers/video/msm/mipi_truly_video_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/msm_dss_io_7x27a.c b/drivers/video/msm/msm_dss_io_7x27a.c
index 18e8ac5..8610a21 100644
--- a/drivers/video/msm/msm_dss_io_7x27a.c
+++ b/drivers/video/msm/msm_dss_io_7x27a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/msm_dss_io_8960.c b/drivers/video/msm/msm_dss_io_8960.c
index 682a45a..add4027 100644
--- a/drivers/video/msm/msm_dss_io_8960.c
+++ b/drivers/video/msm/msm_dss_io_8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. 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 and
@@ -326,7 +326,10 @@
 }
 
 #define PREF_DIV_RATIO 27
+#define VCO_MINIMUM 600
 struct dsiphy_pll_divider_config pll_divider_config;
+u32 vco_level_100;
+u32 vco_min_allowed;
 
 int mipi_dsi_phy_pll_config(u32 clk_rate)
 {
@@ -368,10 +371,35 @@
 	return 0;
 }
 
+void mipi_dsi_configure_fb_divider(u32 fps_level)
+{
+	u32 fb_div_req, fb_div_req_by_2;
+	u32 vco_required;
+
+	vco_required = vco_level_100 * fps_level/100;
+	if (vco_required < vco_min_allowed) {
+		printk(KERN_WARNING "Can not change fps. Min level allowed is \
+	%d \n", (vco_min_allowed * 100 / vco_level_100) + 1);
+		return;
+	}
+
+	fb_div_req = vco_required * PREF_DIV_RATIO / 27;
+	fb_div_req_by_2 = (fb_div_req / 2) - 1;
+
+	pll_divider_config.fb_divider = fb_div_req;
+
+	/* DSIPHY_PLL_CTRL_1 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x204, fb_div_req_by_2 & 0xff);
+	wmb();
+}
+
 int mipi_dsi_clk_div_config(uint8 bpp, uint8 lanes,
 			    uint32 *expected_dsi_pclk)
 {
 	u32 fb_divider, rate, vco;
+	u32 fb_div_min, fb_div_by_2_min,
+			 fb_div_by_2;
+	u32 vco_level_75;
 	u32 div_ratio = 0;
 	struct dsi_clk_mnd_table const *mnd_entry = mnd_table;
 	if (pll_divider_config.clk_rate == 0)
@@ -414,6 +442,17 @@
 	pll_divider_config.dsi_clk_divider =
 			(mnd_entry->dsiclk_div) * div_ratio;
 
+	vco_level_100 = vco;
+	fb_div_by_2 = (fb_divider / 2) - 1;
+	fb_div_by_2_min = (fb_div_by_2 / 256) * 256;
+	fb_div_min = (fb_div_by_2_min + 1) * 2;
+	vco_min_allowed = (fb_div_min * 27 / PREF_DIV_RATIO);
+	vco_level_75 = vco_level_100 * 75 / 100;
+	if (vco_min_allowed < VCO_MINIMUM)
+		vco_min_allowed = VCO_MINIMUM;
+	if (vco_min_allowed < vco_level_75)
+		vco_min_allowed = vco_level_75;
+
 	if (mnd_entry->dsiclk_d == 0) {
 		dsicore_clk.mnd_mode = 0;
 		dsicore_clk.src = 0x3;
@@ -594,6 +633,12 @@
 {
 	static int cont_splash_clks_enabled;
 	if (enable && !cont_splash_clks_enabled) {
+		if (clk_set_rate(dsi_byte_div_clk, 1) < 0)      /* divided by 1 */
+			pr_err("%s: dsi_byte_div_clk - "
+				"clk_set_rate failed\n", __func__);
+		if (clk_set_rate(dsi_esc_clk, esc_byte_ratio) < 0) /* divided by esc */
+			pr_err("%s: dsi_esc_clk - "                      /* clk ratio */
+				"clk_set_rate failed\n", __func__);
 			clk_prepare_enable(dsi_byte_div_clk);
 			clk_prepare_enable(dsi_esc_clk);
 			cont_splash_clks_enabled = 1;
@@ -609,8 +654,6 @@
 	clk_prepare(amp_pclk);
 	clk_prepare(dsi_m_pclk);
 	clk_prepare(dsi_s_pclk);
-	clk_prepare(dsi_byte_div_clk);
-	clk_prepare(dsi_esc_clk);
 }
 
 void mipi_dsi_unprepare_clocks(void)
@@ -658,16 +701,16 @@
 	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, pll_ctrl | 0x01);
 	mipi_dsi_phy_rdy_poll();
 
-	if (clk_set_rate(dsi_byte_div_clk, 1) < 0)	/* divided by 1 */
+	if (clk_set_rate(dsi_byte_div_clk, 1) < 0)      /* divided by 1 */
 		pr_err("%s: dsi_byte_div_clk - "
 			"clk_set_rate failed\n", __func__);
 	if (clk_set_rate(dsi_esc_clk, esc_byte_ratio) < 0) /* divided by esc */
-		pr_err("%s: dsi_esc_clk - "			 /* clk ratio */
+		pr_err("%s: dsi_esc_clk - "                      /* clk ratio */
 			"clk_set_rate failed\n", __func__);
 	mipi_dsi_pclk_ctrl(&dsi_pclk, 1);
 	mipi_dsi_clk_ctrl(&dsicore_clk, 1);
-	clk_enable(dsi_byte_div_clk);
-	clk_enable(dsi_esc_clk);
+	clk_prepare_enable(dsi_byte_div_clk);
+	clk_prepare_enable(dsi_esc_clk);
 	mipi_dsi_clk_on = 1;
 	mdp4_stat.dsi_clk_on++;
 }
@@ -779,7 +822,7 @@
 	HDMI_OUTP_ND(HDMI_PHY_REG_2, 0x7F); /*0b01111111*/
 }
 
-void hdmi_frame_ctrl_cfg(const struct hdmi_disp_mode_timing_type *timing)
+void hdmi_frame_ctrl_cfg(const struct msm_hdmi_mode_timing_info *timing)
 {
 	/*  0x02C8 HDMI_FRAME_CTRL
 	 *  31 INTERLACED_EN   Interlaced or progressive enable bit
diff --git a/drivers/video/msm/msm_dss_io_8x60.c b/drivers/video/msm/msm_dss_io_8x60.c
index c79c4c7..d60bfad 100644
--- a/drivers/video/msm/msm_dss_io_8x60.c
+++ b/drivers/video/msm/msm_dss_io_8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index a415ff9..6ecf64c 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -61,7 +61,11 @@
 static unsigned char *fbram_phys;
 static int fbram_size;
 static boolean bf_supported;
-
+/* Set backlight on resume after 50 ms after first
+ * pan display on the panel. This is to avoid panel specific
+ * transients during resume.
+ */
+unsigned long backlight_duration = (HZ/20);
 static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
 static int pdev_list_cnt;
 
@@ -122,10 +126,11 @@
 #define MSM_FB_MAX_DBGFS 1024
 #define MAX_BACKLIGHT_BRIGHTNESS 255
 
-/* 900 ms for fence time out */
-#define WAIT_FENCE_TIMEOUT 900
-/* 950 ms for display operation time out */
-#define WAIT_DISP_OP_TIMEOUT 950
+#define WAIT_FENCE_FIRST_TIMEOUT MSEC_PER_SEC
+#define WAIT_FENCE_FINAL_TIMEOUT 10 * MSEC_PER_SEC
+/* Display op timeout should be greater than total timeout */
+#define WAIT_DISP_OP_TIMEOUT (WAIT_FENCE_FIRST_TIMEOUT +\
+        WAIT_FENCE_FINAL_TIMEOUT) * MDP_MAX_FENCE_FD
 #define MAX_TIMELINE_NAME_LEN 16
 
 int msm_fb_debugfs_file_index;
@@ -266,6 +271,28 @@
 	return ret;
 }
 
+static ssize_t msm_fb_fps_level_change(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+	struct msm_fb_panel_data *pdata =
+		(struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+	unsigned long val;
+	int ret;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	if ((val <= 0) || (val > 100))
+		return -EINVAL;
+	if (pdata->fps_level_change)
+		pdata->fps_level_change(mfd->pdev, (u32)val);
+	return count;
+}
+
 static ssize_t msm_fb_msm_fb_type(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
@@ -321,8 +348,11 @@
 }
 
 static DEVICE_ATTR(msm_fb_type, S_IRUGO, msm_fb_msm_fb_type, NULL);
+static DEVICE_ATTR(msm_fb_fps_level, S_IRUGO | S_IWUGO, NULL, \
+				msm_fb_fps_level_change);
 static struct attribute *msm_fb_attrs[] = {
 	&dev_attr_msm_fb_type.attr,
+	&dev_attr_msm_fb_fps_level.attr,
 	NULL,
 };
 static struct attribute_group msm_fb_attr_group = {
@@ -346,6 +376,8 @@
 	sysfs_remove_group(&mfd->fbi->dev->kobj, &msm_fb_attr_group);
 }
 
+static void bl_workqueue_handler(struct work_struct *work);
+
 static int msm_fb_probe(struct platform_device *pdev)
 {
 	struct msm_fb_data_type *mfd;
@@ -356,14 +388,21 @@
 
 	if ((pdev->id == 0) && (pdev->num_resources > 0)) {
 		msm_fb_pdata = pdev->dev.platform_data;
-		fbram_size =
-			pdev->resource[0].end - pdev->resource[0].start + 1;
-		fbram_phys = (char *)pdev->resource[0].start;
-		fbram = __va(fbram_phys);
+		if (pdev->resource[0].start) {
+			fbram_size =
+				pdev->resource[0].end -
+				pdev->resource[0].start + 1;
+			fbram_phys = (char *)pdev->resource[0].start;
+			fbram = __va(fbram_phys);
 
-		if (!fbram) {
-			printk(KERN_ERR "fbram ioremap failed!\n");
-			return -ENOMEM;
+			if (!fbram) {
+				printk(KERN_ERR "fbram ioremap failed!\n");
+				return -ENOMEM;
+			}
+		} else {
+			fbram_size = 0;
+			fbram_phys = NULL;
+			fbram = NULL;
 		}
 		MSM_FB_DEBUG("msm_fb_probe:  phy_Addr = 0x%x virt = 0x%x\n",
 			     (int)fbram_phys, (int)fbram);
@@ -384,6 +423,8 @@
 
 	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
 
+	INIT_DELAYED_WORK(&mfd->backlight_worker, bl_workqueue_handler);
+
 	if (!mfd)
 		return -ENODEV;
 
@@ -551,7 +592,18 @@
 	 */
 	mfd->suspend.sw_refreshing_enable = mfd->sw_refreshing_enable;
 	mfd->suspend.op_enable = mfd->op_enable;
-	mfd->suspend.panel_power_on = mfd->panel_power_on;
+
+	/*
+	 * For HDMI/DTV, panel needs not to be turned ON during resume
+	 * as power_ctrl will turn ON the HPD at resume which will turn
+	 * ON the panel in case the HDMI cable is still connected.
+	 */
+	if (mfd->panel_info.type == HDMI_PANEL ||
+	    mfd->panel_info.type == DTV_PANEL)
+		mfd->suspend.panel_power_on = false;
+	else
+		mfd->suspend.panel_power_on = mfd->panel_power_on;
+
 	mfd->suspend.op_suspend = true;
 
 	if (mfd->op_enable) {
@@ -790,11 +842,14 @@
 	struct fb_info *fbi = mfd->fbi;
 	switch (mfd->fbi->var.bits_per_pixel) {
 	case 32:
-		memset32_io((void *)fbi->screen_base, 0xFF000000,
-							fbi->fix.smem_len);
+		if (fbi->screen_base)
+			memset32_io((void *)fbi->screen_base, 0xFF000000,
+				    fbi->fix.smem_len);
 		break;
 	default:
-		memset32_io((void *)fbi->screen_base, 0x00, fbi->fix.smem_len);
+		if (fbi->screen_base)
+			memset32_io((void *)fbi->screen_base, 0x00,
+				    fbi->fix.smem_len);
 		break;
 	}
 #endif
@@ -851,7 +906,8 @@
 								bl_min_lvl);
 
 	/* update current backlight to use new scaling*/
-	msm_fb_set_backlight(mfd, curr_bl);
+	if (mfd->panel_power_on && bl_updated)
+		msm_fb_set_backlight(mfd, curr_bl);
 	up(&mfd->sem);
 
 	return ret;
@@ -880,12 +936,10 @@
 	struct msm_fb_panel_data *pdata;
 	__u32 temp = bkl_lvl;
 
-	if (!mfd->panel_power_on || !bl_updated) {
-		unset_bl_level = bkl_lvl;
+	unset_bl_level = bkl_lvl;
+
+	if (!mfd->panel_power_on || !bl_updated)
 		return;
-	} else {
-		unset_bl_level = 0;
-	}
 
 	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
 
@@ -908,9 +962,6 @@
 	struct msm_fb_panel_data *pdata = NULL;
 	int ret = 0;
 
-	if (!op_enable)
-		return -EPERM;
-
 	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
 	if ((!pdata) || (!pdata->on) || (!pdata->off)) {
 		printk(KERN_ERR "msm_fb_blank_sub: no panel operation detected!\n");
@@ -922,7 +973,9 @@
 		if (!mfd->panel_power_on) {
 			ret = pdata->on(mfd->pdev);
 			if (ret == 0) {
+				down(&mfd->sem);
 				mfd->panel_power_on = TRUE;
+				up(&mfd->sem);
 				mfd->panel_driver_on = mfd->op_enable;
 			}
 		}
@@ -938,17 +991,20 @@
 
 			mfd->op_enable = FALSE;
 			curr_pwr_state = mfd->panel_power_on;
+			down(&mfd->sem);
 			mfd->panel_power_on = FALSE;
+			bl_updated = 0;
+			up(&mfd->sem);
+			cancel_delayed_work_sync(&mfd->backlight_worker);
 
 			if (mfd->msmfb_no_update_notify_timer.function)
 				del_timer(&mfd->msmfb_no_update_notify_timer);
 			complete(&mfd->msmfb_no_update_notify);
 
-			bl_updated = 0;
-
 			/* clean fb to prevent displaying old fb */
-			memset((void *)info->screen_base, 0,
-					info->fix.smem_len);
+			if (info->screen_base)
+				memset((void *)info->screen_base, 0,
+				       info->fix.smem_len);
 
 			ret = pdata->off(mfd->pdev);
 			if (ret)
@@ -1066,8 +1122,15 @@
 	}
 	msm_fb_pan_idle(mfd);
 	if (mfd->op_enable == 0) {
-		if (blank_mode == FB_BLANK_UNBLANK)
+		if (blank_mode == FB_BLANK_UNBLANK) {
 			mfd->suspend.panel_power_on = TRUE;
+			/* if unblank is called when system is in suspend,
+			wait for the system to resume */
+			while (mfd->suspend.op_suspend) {
+				pr_debug("waiting for system to resume\n");
+				msleep(20);
+			}
+		}
 		else
 			mfd->suspend.panel_power_on = FALSE;
 	}
@@ -1097,6 +1160,10 @@
 	u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
 	unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	if (!start)
+		return -EINVAL;
+
 	msm_fb_pan_idle(mfd);
 	if (off >= len) {
 		/* memory mapped io */
@@ -1442,12 +1509,16 @@
 		pr_err("error: not enough memory!\n");
 		return -ENOMEM;
 	}
-	fbram_offset = PAGE_ALIGN((int)fbram)-(int)fbram;
-	fbram += fbram_offset;
-	fbram_phys += fbram_offset;
-	fbram_size -= fbram_offset;
 
-	if (!bf_supported || mfd->index == 0)
+	if (fbram) {
+		fbram_offset = PAGE_ALIGN((int)fbram)-(int)fbram;
+		fbram += fbram_offset;
+		fbram_phys += fbram_offset;
+		fbram_size -= fbram_offset;
+	} else
+		fbram_offset = 0;
+
+	if ((!bf_supported || mfd->index == 0) && fbram)
 		if (fbram_size < fix->smem_len) {
 			pr_err("error: no more framebuffer memory!\n");
 			return -ENOMEM;
@@ -1456,31 +1527,33 @@
 	fbi->screen_base = fbram;
 	fbi->fix.smem_start = (unsigned long)fbram_phys;
 
-	msm_iommu_map_contig_buffer(fbi->fix.smem_start,
-					DISPLAY_WRITE_DOMAIN,
-					GEN_POOL,
-					fbi->fix.smem_len,
-					SZ_4K,
-					0,
-					&(mfd->display_iova));
+	if (fbi->fix.smem_start) {
+		msm_iommu_map_contig_buffer(fbi->fix.smem_start,
+					    DISPLAY_WRITE_DOMAIN,
+					    GEN_POOL,
+					    fbi->fix.smem_len,
+					    SZ_4K,
+					    0,
+					    &(mfd->display_iova));
 
-	msm_iommu_map_contig_buffer(fbi->fix.smem_start,
-					DISPLAY_READ_DOMAIN,
-					GEN_POOL,
-					fbi->fix.smem_len,
-					SZ_4K,
-					0,
-					&(mfd->display_iova));
+		msm_iommu_map_contig_buffer(fbi->fix.smem_start,
+					    DISPLAY_READ_DOMAIN,
+					    GEN_POOL,
+					    fbi->fix.smem_len,
+					    SZ_4K,
+					    0,
+					    &(mfd->display_iova));
 
-	msm_iommu_map_contig_buffer(fbi->fix.smem_start,
-					ROTATOR_SRC_DOMAIN,
-					GEN_POOL,
-					fbi->fix.smem_len,
-					SZ_4K,
-					0,
-					&(mfd->rotator_iova));
+		msm_iommu_map_contig_buffer(fbi->fix.smem_start,
+					    ROTATOR_SRC_DOMAIN,
+					    GEN_POOL,
+					    fbi->fix.smem_len,
+					    SZ_4K,
+					    0,
+					    &(mfd->rotator_iova));
+	}
 
-	if (!bf_supported || mfd->index == 0)
+	if ((!bf_supported || mfd->index == 0) && fbi->screen_base)
 		memset(fbi->screen_base, 0x0, fix->smem_len);
 
 	mfd->op_enable = TRUE;
@@ -1529,9 +1602,11 @@
 		return -EPERM;
 	}
 
-	fbram += fix->smem_len;
-	fbram_phys += fix->smem_len;
-	fbram_size -= fix->smem_len;
+	if (fbram) {
+		fbram += fix->smem_len;
+		fbram_phys += fix->smem_len;
+		fbram_size -= fix->smem_len;
+	}
 
 	MSM_FB_INFO
 	    ("FrameBuffer[%d] %dx%d size=%d bytes is registered successfully!\n",
@@ -1702,6 +1777,14 @@
 			return 0;
 	}
 
+	if (mfd->op_enable == 0) {
+		if (info->node == 2)
+			return -EPERM;
+		/* if system is in suspend mode, do not unblank */
+		mfd->ref_cnt++;
+		return 0;
+	}
+
 	if (!mfd->ref_cnt) {
 		if (!bf_supported ||
 			(info->node != 1 && info->node != 2))
@@ -1713,11 +1796,10 @@
 		if (mfd->is_panel_ready && !mfd->is_panel_ready())
 			unblank = false;
 
-		if (unblank) {
+		if (unblank && (mfd->panel_info.type != DTV_PANEL)) {
 			if (msm_fb_blank_sub(FB_BLANK_UNBLANK, info, TRUE)) {
-				MSM_FB_ERR("%s: can't turn on display!\n",
-					__func__);
-				return -EPERM;
+				pr_err("msm_fb_open: can't turn on display\n");
+				return -EINVAL;
 			}
 		}
 	}
@@ -1726,6 +1808,11 @@
 	return 0;
 }
 
+static void msm_fb_free_base_pipe(struct msm_fb_data_type *mfd)
+{
+	return 	mdp4_overlay_free_base_pipe(mfd);
+}
+
 static int msm_fb_release(struct fb_info *info, int user)
 {
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
@@ -1739,12 +1826,16 @@
 	msm_fb_pan_idle(mfd);
 	mfd->ref_cnt--;
 
-	if ((!mfd->ref_cnt) && (mfd->op_enable)) {
-		if ((ret =
-		     msm_fb_blank_sub(FB_BLANK_POWERDOWN, info,
-				      mfd->op_enable)) != 0) {
-			printk(KERN_ERR "msm_fb_release: can't turn off display!\n");
-			return ret;
+	if (!mfd->ref_cnt) {
+		if (mfd->op_enable) {
+			ret = msm_fb_blank_sub(FB_BLANK_POWERDOWN, info,
+							mfd->op_enable);
+			if (ret != 0) {
+				printk(KERN_ERR "msm_fb_release: can't turn off display!\n");
+				return ret;
+			}
+		} else {
+			msm_fb_free_base_pipe(mfd);
 		}
 	}
 
@@ -1757,7 +1848,15 @@
 	int i, ret = 0;
 	/* buf sync */
 	for (i = 0; i < mfd->acq_fen_cnt; i++) {
-		ret = sync_fence_wait(mfd->acq_fen[i], WAIT_FENCE_TIMEOUT);
+		ret = sync_fence_wait(mfd->acq_fen[i],
+				WAIT_FENCE_FIRST_TIMEOUT);
+		if (ret == -ETIME) {
+			pr_warn("%s: sync_fence_wait timed out!"
+				"Waiting %ld more seconds\n",
+				__func__,WAIT_FENCE_FINAL_TIMEOUT/MSEC_PER_SEC);
+			ret = sync_fence_wait(mfd->acq_fen[i],
+					WAIT_FENCE_FINAL_TIMEOUT);
+		}
 		if (ret < 0) {
 			pr_err("%s: sync_fence_wait failed! ret = %x\n",
 				__func__, ret);
@@ -1776,7 +1875,8 @@
 int msm_fb_signal_timeline(struct msm_fb_data_type *mfd)
 {
 	mutex_lock(&mfd->sync_mutex);
-	if (mfd->timeline) {
+	if (mfd->timeline && !list_empty((const struct list_head *)
+				(&(mfd->timeline->obj.active_list_head)))) {
 		sw_sync_timeline_inc(mfd->timeline, 1);
 		mfd->timeline_value++;
 	}
@@ -1887,6 +1987,23 @@
 	return ret;
 }
 
+static void bl_workqueue_handler(struct work_struct *work)
+{
+	struct msm_fb_data_type *mfd = container_of(to_delayed_work(work),
+				struct msm_fb_data_type, backlight_worker);
+	struct msm_fb_panel_data *pdata = mfd->pdev->dev.platform_data;
+
+	down(&mfd->sem);
+	if ((pdata) && (pdata->set_backlight) && (!bl_updated)
+					&& (mfd->panel_power_on)) {
+		mfd->bl_level = unset_bl_level;
+		pdata->set_backlight(mfd);
+		bl_level_old = unset_bl_level;
+		bl_updated = 1;
+	}
+	up(&mfd->sem);
+}
+
 static int msm_fb_pan_display(struct fb_var_screeninfo *var,
 			      struct fb_info *info)
 {
@@ -1903,7 +2020,6 @@
 	struct mdp_dirty_region dirty;
 	struct mdp_dirty_region *dirtyPtr = NULL;
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-	struct msm_fb_panel_data *pdata;
 
 	/*
 	 * If framebuffer is 2, io pen display is not allowed.
@@ -1992,23 +2108,17 @@
 
 	mdp_dma_pan_update(info);
 	msm_fb_signal_timeline(mfd);
-	if (mdp4_unmap_sec_resource())
+	if (mdp4_unmap_sec_resource(mfd))
 		pr_err("%s: unmap secure res failed\n", __func__);
 
 	up(&msm_fb_pan_sem);
 
-	if (unset_bl_level && !bl_updated) {
-		pdata = (struct msm_fb_panel_data *)mfd->pdev->
-			dev.platform_data;
-		if ((pdata) && (pdata->set_backlight)) {
-			down(&mfd->sem);
-			mfd->bl_level = unset_bl_level;
-			pdata->set_backlight(mfd);
-			bl_level_old = unset_bl_level;
-			up(&mfd->sem);
-			bl_updated = 1;
-		}
-	}
+	if (!bl_updated)
+		schedule_delayed_work(&mfd->backlight_worker,
+					backlight_duration);
+
+	if (info->node == 0 && (mfd->cont_splash_done)) /* primary */
+		mdp_free_splash_buffer(mfd);
 
 	++mfd->panel_info.frame_count;
 	return 0;
@@ -2036,6 +2146,9 @@
 	complete_all(&mfd->commit_comp);
 	mutex_unlock(&mfd->sync_mutex);
 
+	if (unset_bl_level && !bl_updated)
+		schedule_delayed_work(&mfd->backlight_worker,
+					backlight_duration);
 }
 
 static int msm_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -2140,24 +2253,28 @@
 	return 0;
 }
 
-int msm_fb_check_frame_rate(struct msm_fb_data_type *mfd
-						, struct fb_info *info)
+int msm_fb_get_frame_rate(struct fb_var_screeninfo *var)
 {
-	int panel_height, panel_width, var_frame_rate, fps_mod;
-	struct fb_var_screeninfo *var = &info->var;
-	fps_mod = 0;
-	if ((mfd->panel_info.type == DTV_PANEL) ||
-		(mfd->panel_info.type == HDMI_PANEL)) {
-		panel_height = var->yres + var->upper_margin +
+	int panel_height, panel_width;
+
+	panel_height = var->yres + var->upper_margin +
 			var->vsync_len + var->lower_margin;
-		panel_width = var->xres + var->right_margin +
+	panel_width  = var->xres + var->right_margin +
 			var->hsync_len + var->left_margin;
-		var_frame_rate = ((var->pixclock)/(panel_height * panel_width));
-		if (mfd->var_frame_rate != var_frame_rate) {
+	return (var->pixclock)/(panel_height * panel_width);
+}
+
+int msm_fb_check_frame_rate(struct msm_fb_data_type *mfd, struct fb_info *info)
+{
+	int fps_mod = 0;
+	struct fb_var_screeninfo *var = &info->var;
+
+	if ((mfd->panel_info.type == DTV_PANEL) ||
+	    (mfd->panel_info.type == HDMI_PANEL)) {
+		if (mfd->var_frame_rate != msm_fb_get_frame_rate(var))
 			fps_mod = 1;
-			mfd->var_frame_rate = var_frame_rate;
-		}
 	}
+
 	return fps_mod;
 }
 
@@ -2199,25 +2316,28 @@
 	}
 
 	if ((mfd->var_pixclock != var->pixclock) ||
-		(mfd->hw_refresh && ((mfd->fb_imgType != old_imgType) ||
-				(mfd->var_pixclock != var->pixclock) ||
-				(mfd->var_xres != var->xres) ||
-				(mfd->var_yres != var->yres) ||
-				(msm_fb_check_frame_rate(mfd, info))))) {
+		(mfd->hw_refresh &&
+			((mfd->fb_imgType != old_imgType) ||
+			 (mfd->var_xres   != var->xres) ||
+			 (mfd->var_yres   != var->yres) ||
+			 (msm_fb_check_frame_rate(mfd, info))))) {
 		mfd->var_xres = var->xres;
 		mfd->var_yres = var->yres;
-		mfd->var_pixclock = var->pixclock;
+		mfd->var_pixclock   = var->pixclock;
+		mfd->var_frame_rate = msm_fb_get_frame_rate(var);
+
+		if (mfd->update_panel_info)
+			mfd->update_panel_info(mfd);
+
 		blank = 1;
 	}
 	mfd->fbi->fix.line_length = msm_fb_line_length(mfd->index, var->xres,
 						       var->bits_per_pixel/8);
 
-	if (blank) {
+	if ((mfd->panel_info.type == DTV_PANEL) && !mfd->panel_power_on) {
+		msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable);
+	} else if (blank) {
 		msm_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable);
-
-		if (mfd->update_panel_info)
-			mfd->update_panel_info(mfd);
-
 		msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable);
 	}
 
@@ -3172,7 +3292,6 @@
 	int	ret;
 	struct msmfb_overlay_data req;
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-	struct msm_fb_panel_data *pdata;
 
 	if (mfd->overlay_play_enable == 0)	/* nothing to do */
 		return 0;
@@ -3206,18 +3325,8 @@
 
 	ret = mdp4_overlay_play(info, &req);
 
-	if (unset_bl_level && !bl_updated) {
-		pdata = (struct msm_fb_panel_data *)mfd->pdev->
-			dev.platform_data;
-		if ((pdata) && (pdata->set_backlight)) {
-			down(&mfd->sem);
-			mfd->bl_level = unset_bl_level;
-			pdata->set_backlight(mfd);
-			bl_level_old = unset_bl_level;
-			up(&mfd->sem);
-			bl_updated = 1;
-		}
-	}
+	if (info->node == 0 && (mfd->cont_splash_done)) /* primary */
+		mdp_free_splash_buffer(mfd);
 
 	return ret;
 }
@@ -3572,6 +3681,10 @@
 		ret = mdp4_qseed_cfg((struct mdp_qseed_cfg_data *)
 						&pp_ptr->data.qseed_cfg_data);
 		break;
+	case mdp_op_calib_cfg:
+		ret = mdp4_calib_config((struct mdp_calib_config_data *)
+						&pp_ptr->data.calib_cfg);
+		break;
 #endif
 	case mdp_bl_scale_cfg:
 		ret = mdp_bl_scale_config(mfd, (struct mdp_bl_scale_data *)
@@ -3590,7 +3703,8 @@
 static int msmfb_handle_buf_sync_ioctl(struct msm_fb_data_type *mfd,
 						struct mdp_buf_sync *buf_sync)
 {
-	int i, fence_cnt = 0, ret = 0;
+	int i, ret = 0;
+	u32 threshold;
 	int acq_fen_fd[MDP_MAX_FENCE_FD];
 	struct sync_fence *fence;
 
@@ -3619,15 +3733,18 @@
 		}
 		mfd->acq_fen[i] = fence;
 	}
-	fence_cnt = i;
+	mfd->acq_fen_cnt = i;
 	if (ret)
 		goto buf_sync_err_1;
-	mfd->acq_fen_cnt = fence_cnt;
 	if (buf_sync->flags & MDP_BUF_SYNC_FLAG_WAIT) {
 		msm_fb_wait_for_fence(mfd);
 	}
+	if (mfd->panel.type == WRITEBACK_PANEL)
+		threshold = 1;
+	else
+		threshold = 2;
 	mfd->cur_rel_sync_pt = sw_sync_pt_create(mfd->timeline,
-			mfd->timeline_value + 2);
+			mfd->timeline_value + threshold);
 	if (mfd->cur_rel_sync_pt == NULL) {
 		pr_err("%s: cannot create sync point", __func__);
 		ret = -ENOMEM;
@@ -3666,7 +3783,7 @@
 	mfd->cur_rel_fence = NULL;
 	mfd->cur_rel_fen_fd = 0;
 buf_sync_err_1:
-	for (i = 0; i < fence_cnt; i++)
+	for (i = 0; i < mfd->acq_fen_cnt; i++)
 		sync_fence_put(mfd->acq_fen[i]);
 	mfd->acq_fen_cnt = 0;
 	mutex_unlock(&mfd->sync_mutex);
@@ -4010,6 +4127,8 @@
 			return ret;
 
 		ret = msmfb_handle_pp_ioctl(mfd, &mdp_pp);
+		if (ret == 1)
+			ret = copy_to_user(argp, &mdp_pp, sizeof(mdp_pp));
 		break;
 	case MSMFB_BUFFER_SYNC:
 		ret = copy_from_user(&buf_sync, argp, sizeof(buf_sync));
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index bb34ac2..7a6b1d2 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -84,6 +84,7 @@
 
 	struct device *dev;
 	boolean op_enable;
+	struct delayed_work backlight_worker;
 	uint32 fb_imgType;
 	boolean sw_currently_refreshing;
 	boolean sw_refreshing_enable;
@@ -213,6 +214,10 @@
 	void *msm_fb_backup;
 	boolean panel_driver_on;
 	int vsync_sysfs_created;
+	void *copy_splash_buf;
+	unsigned char *copy_splash_phys;
+	uint32 sec_mapped;
+	uint32 sec_active;
 };
 struct msm_fb_backup_type {
 	struct fb_info info;
diff --git a/drivers/video/msm/msm_fb_bl.c b/drivers/video/msm/msm_fb_bl.c
index b21adee..cdedc6f 100644
--- a/drivers/video/msm/msm_fb_bl.c
+++ b/drivers/video/msm/msm_fb_bl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/msm_fb_def.h b/drivers/video/msm/msm_fb_def.h
index 1c1f392..dcd648b 100644
--- a/drivers/video/msm/msm_fb_def.h
+++ b/drivers/video/msm/msm_fb_def.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/msm_fb_panel.c b/drivers/video/msm/msm_fb_panel.c
index c604f02..3d2e1ce 100644
--- a/drivers/video/msm/msm_fb_panel.c
+++ b/drivers/video/msm/msm_fb_panel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. 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 and
@@ -78,6 +78,31 @@
 	return ret;
 }
 
+int panel_next_fps_level_change(struct platform_device *pdev,
+					 u32 fps_level)
+{
+	int ret = 0;
+	struct msm_fb_panel_data *pdata;
+	struct msm_fb_panel_data *next_pdata;
+	struct platform_device *next_pdev;
+
+	pdata = (struct msm_fb_panel_data *)pdev->dev.platform_data;
+
+	if (pdata) {
+		next_pdev = pdata->next;
+		if (next_pdev) {
+			next_pdata =
+			    (struct msm_fb_panel_data *)next_pdev->dev.
+			    platform_data;
+			if ((next_pdata) && (next_pdata->fps_level_change))
+				ret = next_pdata->fps_level_change(next_pdev,
+							 fps_level);
+		}
+	}
+
+	return ret;
+}
+
 int panel_next_late_init(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -100,6 +125,28 @@
 	return ret;
 }
 
+int panel_next_early_off(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_fb_panel_data *pdata;
+	struct msm_fb_panel_data *next_pdata;
+	struct platform_device *next_pdev;
+
+	pdata = (struct msm_fb_panel_data *)pdev->dev.platform_data;
+
+	if (pdata) {
+		next_pdev = pdata->next;
+		if (next_pdev) {
+			next_pdata = (struct msm_fb_panel_data *)
+					next_pdev->dev.platform_data;
+			if ((next_pdata) && (next_pdata->early_off))
+				ret = next_pdata->early_off(next_pdev);
+		}
+	}
+
+	return ret;
+}
+
 struct platform_device *msm_fb_device_alloc(struct msm_fb_panel_data *pdata,
 						u32 type, u32 id)
 {
diff --git a/drivers/video/msm/msm_fb_panel.h b/drivers/video/msm/msm_fb_panel.h
index 311dcd1..c6e5d63 100644
--- a/drivers/video/msm/msm_fb_panel.h
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. 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 and
@@ -196,9 +196,12 @@
 	int (*on) (struct platform_device *pdev);
 	int (*off) (struct platform_device *pdev);
 	int (*late_init) (struct platform_device *pdev);
+	int (*early_off) (struct platform_device *pdev);
 	int (*power_ctrl) (boolean enable);
 	struct platform_device *next;
 	int (*clk_func) (int enable);
+	int (*fps_level_change) (struct platform_device *pdev,
+					u32 fps_level);
 };
 
 /*===========================================================================
@@ -208,7 +211,10 @@
 						u32 type, u32 id);
 int panel_next_on(struct platform_device *pdev);
 int panel_next_off(struct platform_device *pdev);
+int panel_next_fps_level_change(struct platform_device *pdev,
+					u32 fps_level);
 int panel_next_late_init(struct platform_device *pdev);
+int panel_next_early_off(struct platform_device *pdev);
 
 int lcdc_device_register(struct msm_panel_info *pinfo);
 
diff --git a/drivers/video/msm/tvenc.c b/drivers/video/msm/tvenc.c
index 30dc854..2f3ee97 100644
--- a/drivers/video/msm/tvenc.c
+++ b/drivers/video/msm/tvenc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/tvenc.h b/drivers/video/msm/tvenc.h
index c64c160..0368cb8 100644
--- a/drivers/video/msm/tvenc.h
+++ b/drivers/video/msm/tvenc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/tvout_msm.c b/drivers/video/msm/tvout_msm.c
index 468dfed..5c67e79 100644
--- a/drivers/video/msm/tvout_msm.c
+++ b/drivers/video/msm/tvout_msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
index 9bdcba6..89186f6 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
@@ -88,7 +88,13 @@
 			ddl_context->dram_base_a.align_virtual_addr;
 	}
 	if (!status) {
-		ddl_context->metadata_shared_input.mem_type = DDL_CMD_MEM;
+		if (res_trk_get_enable_sec_metadata()) {
+			ddl_context->metadata_shared_input.mem_type =
+				DDL_CMD_MEM;
+		} else {
+			ddl_context->metadata_shared_input.mem_type =
+				DDL_FW_MEM;
+		}
 		ptr = ddl_pmem_alloc(&ddl_context->metadata_shared_input,
 			DDL_METADATA_TOTAL_INPUTBUFSIZE,
 			DDL_LINEAR_BUFFER_ALIGN_BYTES);
@@ -198,7 +204,9 @@
 		ddl->client_state = DDL_CLIENT_OPEN;
 		ddl->codec_data.hdr.decoding = decoding;
 		ddl->decoding = decoding;
-		ddl_set_default_meta_data_hdr(ddl);
+		if (!res_trk_check_for_sec_session() ||
+				res_trk_get_enable_sec_metadata())
+			ddl_set_default_meta_data_hdr(ddl);
 		ddl_set_initial_default_values(ddl);
 		*ddl_handle	= (u32 *) ddl;
 	} else {
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
index 5c1ee21..3a7e443 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
index db8a777..e6d0260 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
index 671d45c..75aa031 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
@@ -70,7 +70,6 @@
 	case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED:
 	case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE:
 	case VIDC_1080P_ERROR_DIVIDE_BY_ZERO:
-	case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
 	case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE:
 	case VIDC_1080P_ERROR_VSP_NOT_READY:
 	case VIDC_1080P_ERROR_BUFFER_FULL_STATE:
@@ -236,13 +235,13 @@
 	case VIDC_1080P_ERROR_MV_RANGE_ERR:
 	case VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR:
 	case VIDC_1080P_ERROR_SLICE_ADDR_INVALID:
-	case VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED:
 	case VIDC_1080P_ERROR_NALU_HEADER_ERROR:
 	case VIDC_1080P_ERROR_SPS_PARSE_ERROR:
 	case VIDC_1080P_ERROR_PPS_PARSE_ERROR:
 	case VIDC_1080P_ERROR_HEADER_NOT_FOUND:
 	case VIDC_1080P_ERROR_SLICE_PARSE_ERROR:
 	case VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED:
+	case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
 		vcd_status = VCD_ERR_BITSTREAM_ERR;
 		DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR (%u)",
 			(u32)ddl_context->cmd_err_status);
@@ -256,6 +255,9 @@
 				(u32)ddl_context->cmd_err_status);
 		}
 		break;
+	case VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED:
+		vcd_status = VCD_ERR_BITSTREAM_ERR;
+		break;
 	default:
 		break;
 	}
@@ -367,7 +369,7 @@
 	disp_status = ddl_handle_core_warnings(
 		ddl_context->disp_pic_err_status);
 	if (!status && !disp_status) {
-		DDL_MSG_ERROR("ddl_warning:Unknown");
+		DDL_MSG_HIGH("ddl_warning:Unknown");
 		status = ddl_handle_hw_fatal_errors(ddl);
 		if (!status)
 			status = ddl_handle_core_recoverable_errors(ddl);
@@ -397,7 +399,7 @@
 
 	if ((ddl->cmd_state != DDL_CMD_HEADER_PARSE) ||
 		(ddl->client_state != DDL_CLIENT_WAIT_FOR_INITCODECDONE)) {
-		DDL_MSG_ERROR("STATE-CRITICAL-HDDONE");
+		DDL_MSG_HIGH("STATE-CRITICAL-HDDONE");
 		return false;
 	}
 
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index 0b5b5f6..360a85a 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -172,22 +172,16 @@
 				    (in_out_frame->vcd_frm.buff_ion_handle)) {
 					struct ddl_context *ddl_context =
 						ddl_get_context();
-					unsigned long *vaddr =
-						(unsigned long *)((u32)
-						in_out_frame->vcd_frm.virtual +
-						decoder->meta_data_offset);
-					DDL_MSG_LOW("%s: Cache clean: vaddr"\
-						" (%p), offset %u, size %u",
-						__func__,
-						in_out_frame->vcd_frm.virtual,
-						decoder->meta_data_offset,
-						decoder->suffix);
+					DDL_MSG_LOW("%s: Cache clean: size %u",
+						__func__, in_out_frame->vcd_frm.
+						alloc_len);
 					msm_ion_do_cache_op(
 						ddl_context->video_ion_client,
 						in_out_frame->vcd_frm.\
 						buff_ion_handle,
-						vaddr,
-						(unsigned long)decoder->suffix,
+						NULL,
+						(unsigned long)in_out_frame->
+						vcd_frm.alloc_len,
 						ION_IOC_CLEAN_CACHES);
 				}
 			}
@@ -258,47 +252,60 @@
 	struct ddl_context *ddl_context = ddl->ddl_context;
 	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
 	struct ddl_dec_buffers *dec_buffers = &decoder->hw_bufs;
-	struct ddl_frame_data_tag *frame;
+	struct vcd_frame_data *vcd_frm;
 	u32 luma[DDL_MAX_BUFFER_COUNT], chroma[DDL_MAX_BUFFER_COUNT];
 	u32 mv[DDL_MAX_BUFFER_COUNT], luma_size, i, dpb;
-	frame = &decoder->dp_buf.dec_pic_buffers[0];
 	luma_size = ddl_get_yuv_buf_size(decoder->frame_size.width,
 			decoder->frame_size.height, DDL_YUV_BUF_TYPE_TILE);
 	dpb = decoder->dp_buf.no_of_dec_pic_buf;
-	DDL_MSG_LOW("%s Decoder num DPB buffers = %u Luma Size = %u"
+	DDL_MSG_LOW("%s: Decoder num DPB buffers = %u Luma Size = %u",
 				 __func__, dpb, luma_size);
 	if (dpb > DDL_MAX_BUFFER_COUNT)
 		dpb = DDL_MAX_BUFFER_COUNT;
 	for (i = 0; i < dpb; i++) {
-		if (!(res_trk_check_for_sec_session()) &&
-			frame[i].vcd_frm.virtual) {
-			if (luma_size <= frame[i].vcd_frm.alloc_len) {
-				memset(frame[i].vcd_frm.virtual,
-					 0x10101010, luma_size);
-				memset(frame[i].vcd_frm.virtual + luma_size,
-					 0x80808080,
-					frame[i].vcd_frm.alloc_len - luma_size);
-				if (frame[i].vcd_frm.ion_flag
-					== ION_FLAG_CACHED) {
-					msm_ion_do_cache_op(
-					ddl_context->video_ion_client,
-					frame[i].vcd_frm.buff_ion_handle,
-					(unsigned long *)frame[i].
-					vcd_frm.virtual,
-					(unsigned long)frame[i].
-					vcd_frm.alloc_len,
-					ION_IOC_CLEAN_INV_CACHES);
+		vcd_frm = &decoder->dp_buf.dec_pic_buffers[i].vcd_frm;
+		if (!res_trk_check_for_sec_session()) {
+			u8 *kernel_vaddr = NULL;
+			if (luma_size <= vcd_frm->alloc_len) {
+				kernel_vaddr = (u8 *)ion_map_kernel(
+						ddl_context->video_ion_client,
+						vcd_frm->buff_ion_handle);
+				if (IS_ERR_OR_NULL(kernel_vaddr)) {
+					DDL_MSG_ERROR("%s(): ION_MAP for "\
+					"DPB[%u] failed\n", __func__, i);
+				} else {
+					memset(kernel_vaddr, 0x10101010,
+						luma_size);
+					memset(kernel_vaddr + luma_size,
+						0x80808080,
+						vcd_frm->alloc_len - luma_size);
+					if (vcd_frm->ion_flag ==
+						ION_FLAG_CACHED) {
+						msm_ion_do_cache_op(
+						ddl_context->video_ion_client,
+						vcd_frm->buff_ion_handle,
+						(unsigned long *)kernel_vaddr,
+						(unsigned long)vcd_frm->
+						alloc_len,
+						ION_IOC_CLEAN_INV_CACHES);
+					}
+					ion_unmap_kernel(
+						ddl_context->video_ion_client,
+						vcd_frm->buff_ion_handle);
+					kernel_vaddr = NULL;
 				}
 			} else {
-				DDL_MSG_ERROR("luma size error");
+				DDL_MSG_ERROR("%s: err: luma_size (%u), "\
+					"alloc_len (%u)", __func__,
+					luma_size, vcd_frm->alloc_len);
 				return VCD_ERR_FAIL;
 			}
 		}
 
 		luma[i] = DDL_OFFSET(ddl_context->dram_base_a.
-			align_physical_addr, frame[i].vcd_frm.physical);
+			align_physical_addr, vcd_frm->physical);
 		chroma[i] = luma[i] + luma_size;
-		DDL_MSG_LOW("%s Decoder Luma address = %x Chroma address = %x"
+		DDL_MSG_LOW("%s: Decoder Luma address = %x Chroma address = %x",
 					__func__, luma[i], chroma[i]);
 	}
 	switch (decoder->codec.codec) {
@@ -814,13 +821,13 @@
 		height, DDL_YUV_BUF_TYPE_TILE);
 	sz_dpb_c = ddl_get_yuv_buf_size(width, height>>1,
 		DDL_YUV_BUF_TYPE_TILE);
-	if (input_format ==
-		VCD_BUFFER_FORMAT_NV12_16M2KA) {
+	if ((input_format == VCD_BUFFER_FORMAT_NV12_16M2KA) ||
+		(input_format == VCD_BUFFER_FORMAT_NV21_16M2KA)) {
 		sz_cur_y = ddl_get_yuv_buf_size(width, height,
 			DDL_YUV_BUF_TYPE_LINEAR);
 		sz_cur_c = ddl_get_yuv_buf_size(width, height>>1,
 			DDL_YUV_BUF_TYPE_LINEAR);
-	} else if (VCD_BUFFER_FORMAT_TILE_4x2 == input_format) {
+	} else if (input_format == VCD_BUFFER_FORMAT_TILE_4x2) {
 		sz_cur_y = sz_dpb_y;
 		sz_cur_c = sz_dpb_c;
 	} else
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index 415a3d1..0bb7c3b 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -377,12 +377,12 @@
 				input_vcd_frm->data_len <=
 				seq_hdr_info.dec_frm_size) {
 				seq_hdr_only_frame = true;
-				input_vcd_frm->offset +=
-					seq_hdr_info.dec_frm_size;
-				input_vcd_frm->data_len = 0;
 				eos_present =
 				input_vcd_frm->flags & VCD_FRAME_FLAG_EOS;
 				if (!eos_present) {
+					input_vcd_frm->data_len = 0;
+					input_vcd_frm->offset +=
+						seq_hdr_info.dec_frm_size;
 					input_vcd_frm->flags |=
 						VCD_FRAME_FLAG_CODECCONFIG;
 					ddl->input_frame.frm_trans_end =
@@ -408,6 +408,10 @@
 						seq_hdr_info.dec_frm_size);
 				}
 			}
+			DDL_MSG_INFO("profile %u level %u progressive %u",
+					decoder->profile.profile,
+					decoder->level.level,
+					decoder->progressive_only);
 			if (need_reconfig) {
 				struct ddl_frame_data_tag *payload =
 					&ddl->input_frame;
@@ -995,7 +999,7 @@
 		ddl_encoder_eos_done(ddl_context);
 	break;
 	case VIDC_1080P_RISC2HOST_CMD_ERROR_RET:
-		DDL_MSG_ERROR("CMD_ERROR_INTR");
+		DDL_MSG_HIGH("CMD_ERROR_INTR");
 		return_status = ddl_handle_core_errors(ddl_context);
 	break;
 	case VIDC_1080P_RISC2HOST_CMD_INIT_BUFFERS_RET:
@@ -1769,7 +1773,7 @@
 	if (!IS_ERR_OR_NULL(output_frame->buff_ion_handle)) {
 		msm_ion_do_cache_op(ddl_context->video_ion_client,
 			output_frame->buff_ion_handle,
-			(unsigned long *) output_frame->virtual,
+			(unsigned long *)NULL,
 			(unsigned long) output_frame->alloc_len,
 			ION_IOC_INV_CACHES);
 	}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
index e17dd00..6a26c13 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
@@ -14,6 +14,7 @@
 #include "vcd_ddl.h"
 #include "vcd_ddl_shared_mem.h"
 #include "vcd_ddl_metadata.h"
+#include "vcd_res_tracker_api.h"
 
 static u32 *ddl_metadata_hdr_entry(struct ddl_client_context *ddl,
 	u32 meta_data)
@@ -188,6 +189,8 @@
 	u32 flag = decoder->meta_data_enable_flag;
 	u32 suffix = 0, size = 0;
 	if (!flag) {
+		output_buf_req->meta_buffer_size =
+			DDL_SECURE_METADATA_DEFAULT_SIZE;
 		decoder->suffix = 0;
 		return;
 	}
@@ -493,7 +496,7 @@
 			align_physical_addr, decoder->dp_buf.
 			dec_pic_buffers[loopc].vcd_frm.physical));
 		}
-	} else {
+	} else if (res_trk_get_enable_sec_metadata()) {
 		*buffer++ = decoder->actual_output_buf_req.meta_buffer_size;
 		for (loopc = 0; loopc < dpb; ++loopc) {
 			*buffer++ = DDL_ADDR_OFFSET(ddl_context->dram_base_a,
@@ -507,8 +510,8 @@
 	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
 	struct vcd_frame_data *out_frame =
 		&(ddl->output_frame.vcd_frm);
-	u32 *qfiller_hdr, *qfiller, start_addr;
-	u32 qfiller_size;
+	out_frame->metadata_offset = 0;
+	out_frame->metadata_len = 0;
 	if (!encoder->meta_data_enable_flag) {
 		out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
 		return;
@@ -517,19 +520,11 @@
 		out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
 		return;
 	}
+	DDL_MSG_LOW("%s: data_len/metadata_offset : %d/%d", __func__,
+		out_frame->data_len, encoder->meta_data_offset);
+	out_frame->metadata_offset = encoder->meta_data_offset;
+	out_frame->metadata_len = encoder->suffix;
 	out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
-	DDL_MSG_LOW("processing metadata for encoder");
-	start_addr = (u32) ((u8 *)out_frame->virtual + out_frame->offset);
-	qfiller = (u32 *)((out_frame->data_len +
-				start_addr + 3) & ~3);
-	qfiller_size = (u32)((encoder->meta_data_offset +
-		(u8 *) out_frame->virtual) - (u8 *) qfiller);
-	qfiller_hdr = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER);
-	*qfiller++ = qfiller_size;
-	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_VERSION_INDEX];
-	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_PORT_INDEX];
-	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_TYPE_INDEX];
-	*qfiller = (u32)(qfiller_size - DDL_METADATA_HDR_SIZE);
 }
 
 void ddl_process_decoder_metadata(struct ddl_client_context *ddl)
@@ -537,9 +532,8 @@
 	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
 	struct vcd_frame_data *output_frame =
 		&(ddl->output_frame.vcd_frm);
-	u32 *qfiller_hdr, *qfiller;
-	u32 qfiller_size;
-
+	output_frame->metadata_offset = 0;
+	output_frame->metadata_len = 0;
 	if (!decoder->meta_data_enable_flag) {
 		output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
 		return;
@@ -553,26 +547,11 @@
 		output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
 		return;
 	}
-	DDL_MSG_LOW("processing metadata for decoder");
-	DDL_MSG_LOW("data_len/metadata_offset : %d/%d",
+	DDL_MSG_LOW("%s: data_len/metadata_offset : %d/%d", __func__,
 		output_frame->data_len, decoder->meta_data_offset);
+	output_frame->metadata_offset = decoder->meta_data_offset;
+	output_frame->metadata_len = decoder->suffix;
 	output_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
-	if (!(decoder->meta_data_enable_flag & VCD_METADATA_SEPARATE_BUF)
-		&& (output_frame->data_len != decoder->meta_data_offset)) {
-		qfiller = (u32 *)((u32)((output_frame->data_len +
-			output_frame->offset  +
-				(u8 *) output_frame->virtual) + 3) & ~3);
-		qfiller_size = (u32)((decoder->meta_data_offset +
-				(u8 *) output_frame->virtual) -
-				(u8 *) qfiller);
-		qfiller_hdr = ddl_metadata_hdr_entry(ddl,
-				VCD_METADATA_QCOMFILLER);
-		*qfiller++ = qfiller_size;
-		*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_VERSION_INDEX];
-		*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_PORT_INDEX];
-		*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_TYPE_INDEX];
-		*qfiller = (u32)(qfiller_size - DDL_METADATA_HDR_SIZE);
-	}
 }
 
 void ddl_set_mp2_dump_default(struct ddl_decoder_data *decoder, u32 flag)
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h
index e03a9b7..8cee92f 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -19,6 +19,7 @@
 #define DDL_METADATA_EXTRAPAD_SIZE      256
 #define DDL_METADATA_HDR_SIZE            20
 #define DDL_METADATA_EXTRADATANONE_SIZE  24
+#define DDL_SECURE_METADATA_DEFAULT_SIZE  8192
 #define DDL_METADATA_ALIGNSIZE(x) ((x) = (((x) + 0x7) & ~0x7))
 #define DDL_METADATA_MANDATORY \
 	(VCD_METADATA_DATANONE | VCD_METADATA_QCOMFILLER)
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index af19912..aef9ff5 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -898,8 +898,10 @@
 			property_hdr->sz &&
 			((buffer_format->buffer_format ==
 			VCD_BUFFER_FORMAT_NV12_16M2KA) ||
-			(VCD_BUFFER_FORMAT_TILE_4x2 ==
-			buffer_format->buffer_format))) {
+			(buffer_format->buffer_format ==
+			VCD_BUFFER_FORMAT_TILE_4x2) ||
+			(buffer_format->buffer_format ==
+			VCD_BUFFER_FORMAT_NV21_16M2KA))) {
 			if (buffer_format->buffer_format !=
 				encoder->buf_format.buffer_format) {
 				encoder->buf_format = *buffer_format;
@@ -1043,6 +1045,7 @@
 		u32 num_mb, num_slices;
 		struct vcd_property_hdr slice_property_hdr;
 		struct vcd_property_meta_data_enable slice_meta_data;
+		slice_meta_data.meta_data_enable_flag = 0;
 		DDL_MSG_HIGH("Set property VCD_I_SLICE_DELIVERY_MODE\n");
 		if (sizeof(u32) == property_hdr->sz &&
 			encoder->codec.codec == VCD_CODEC_H264 &&
@@ -1311,6 +1314,13 @@
 			vcd_status = VCD_S_SUCCESS;
 		}
 	break;
+	case VCD_I_ENABLE_SEC_METADATA:
+		if (sizeof(u32) == property_hdr->sz) {
+			*(u32 *)property_value =
+				res_trk_get_enable_sec_metadata();
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
 	case VCD_I_DISABLE_DMX:
 		if (sizeof(u32) == property_hdr->sz) {
 			*(u32 *)property_value = decoder->dmx_disable;
@@ -1937,12 +1947,14 @@
 		encoder->input_buf_req.min_count;
 	encoder->input_buf_req.max_count    = DDL_MAX_BUFFER_COUNT;
 	encoder->input_buf_req.sz = y_cb_cr_size;
-	if (encoder->buf_format.buffer_format ==
-		VCD_BUFFER_FORMAT_NV12_16M2KA)
+	if ((encoder->buf_format.buffer_format ==
+		VCD_BUFFER_FORMAT_NV12_16M2KA) ||
+		(encoder->buf_format.buffer_format ==
+		VCD_BUFFER_FORMAT_NV21_16M2KA))
 		encoder->input_buf_req.align =
 			DDL_LINEAR_BUFFER_ALIGN_BYTES;
-	else if (VCD_BUFFER_FORMAT_TILE_4x2 ==
-		encoder->buf_format.buffer_format)
+	else if (encoder->buf_format.buffer_format ==
+		VCD_BUFFER_FORMAT_TILE_4x2)
 		encoder->input_buf_req.align = DDL_TILE_BUFFER_ALIGN_BYTES;
 	encoder->client_input_buf_req = encoder->input_buf_req;
 	memset(&encoder->output_buf_req , 0 ,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index a947d4b..05acc6e 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -113,6 +113,11 @@
 				goto unmap_ion_alloc;
 			}
 			addr->alloced_phys_addr = (phys_addr_t) iova;
+
+			msm_ion_do_cache_op(ddl_context->video_ion_client,
+					addr->alloc_handle,
+					addr->virtual_base_addr,
+					sz, ION_IOC_CLEAN_INV_CACHES);
 		}
 		if (!addr->alloced_phys_addr) {
 			DDL_MSG_ERROR("%s():DDL ION client physical failed\n",
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
index 6817101..d7b4b10 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -44,6 +44,7 @@
 #define DDL_MSG_HIGH(x...)
 #endif
 
+#define DDL_MSG_INFO(x...)   printk(KERN_INFO x)
 #define DDL_MSG_ERROR(x...)  printk(KERN_INFO x)
 #define DDL_MSG_FATAL(x...)  printk(KERN_INFO x)
 
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
index 9d6744a..957bb8f 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -723,8 +723,15 @@
 	default:
 	break;
 	}
-	if (encoder->buf_format.buffer_format ==
-		VCD_BUFFER_FORMAT_NV12_16M2KA)
+	if ((encoder->buf_format.buffer_format ==
+			VCD_BUFFER_FORMAT_NV21_16M2KA)) {
+		DDL_MSG_LOW("NV21 Input format is set to the core");
+		vidc_1080p_set_enc_NV21(true);
+	}
+	if ((encoder->buf_format.buffer_format ==
+		VCD_BUFFER_FORMAT_NV12_16M2KA) ||
+		(encoder->buf_format.buffer_format ==
+		VCD_BUFFER_FORMAT_NV21_16M2KA))
 		mem_access_method = VIDC_1080P_TILE_LINEAR;
 	else
 		mem_access_method = VIDC_1080P_TILE_64x32;
@@ -769,7 +776,8 @@
 	struct vcd_frame_data *stream = &(ddl->output_frame.vcd_frm);
 	struct vcd_frame_data *input_vcd_frm =
 		&(ddl->input_frame.vcd_frm);
-	u32 dpb_addr_y[4], dpb_addr_c[4];
+	u32 dpb_addr_y[VIDC_1080P_MAX_DEC_DPB];
+	u32 dpb_addr_c[VIDC_1080P_MAX_DEC_DPB];
 	u32 index, y_addr, c_addr;
 
 	DDL_MSG_LOW("%s\n", __func__);
@@ -877,7 +885,8 @@
 	struct ddl_enc_buffers *enc_buffers = &(encoder->hw_bufs);
 	struct vcd_frame_data *input_vcd_frm =
 		&(ddl->input_frame.vcd_frm);
-	u32 dpb_addr_y[4], dpb_addr_c[4];
+	u32 dpb_addr_y[VIDC_1080P_MAX_DEC_DPB];
+	u32 dpb_addr_c[VIDC_1080P_MAX_DEC_DPB];
 	u32 index, y_addr, c_addr;
 	u32 bitstream_size;
 	struct vidc_1080p_enc_slice_batch_in_param *slice_batch_in =
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.c b/drivers/video/msm/vidc/1080p/ddl/vidc.c
index 3c445bc..5bfb184 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -1110,3 +1110,8 @@
 	VIDC_HWIO_OUT(REG_666957,
 		VIDC_1080P_DEC_TYPE_FRAME_START_REALLOC | instance_id);
 }
+
+void vidc_1080p_set_enc_NV21(u32 enc_nv21)
+{
+	VIDC_HWIO_OUT(REG_515664, enc_nv21);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.h b/drivers/video/msm/vidc/1080p/ddl/vidc.h
index 9ac3233..4cb0c54 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.h
@@ -191,6 +191,7 @@
 #define VIDC_1080P_ITLB_MISS_EXCEPTION_HANDLER        0x100
 #define VIDC_1080P_DATA_PAGE_FAULT_EXCEPTION_HANDLER  0x200
 #define VIDC_1080P_INST_PAGE_FAULT_EXCEPTION_HANDLER  0x400
+#define VIDC_1080P_MAX_DEC_DPB                        19
 #define VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR           8
 #define VIDC_1080P_SLICE_BATCH_IN_SIZE(idx)           (4 * sizeof(u32) + \
 							idx * sizeof(u32))
@@ -586,4 +587,6 @@
 	u32 *intermediate_stage_counter);
 void vidc_1080p_get_exception_status(u32 *exception_status);
 void vidc_1080p_frame_start_realloc(u32 instance_id);
+void vidc_1080p_set_enc_NV21(u32 enc_nv21);
+
 #endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h
index a5a8e57..d63a45b 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h
index 819cd6c..92e911f 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010,2013, The Linux Foundation. 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 and
@@ -3603,6 +3603,22 @@
 #define HWIO_REG_515564_MSLICE_BIT_BMSK  0xffffffff
 #define HWIO_REG_515564_MSLICE_BIT_SHFT  0
 
+#define HWIO_REG_515664_ADDR  (VIDC_BLACKBIRD_REG_BASE + 0x0000c548)
+#define HWIO_REG_515664_PHYS  (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c548)
+#define HWIO_REG_515664_RMSK  0xffffffff
+#define HWIO_REG_515664_SHFT  0
+#define HWIO_REG_515664_IN    in_dword_masked(\
+	HWIO_REG_515664_ADDR, HWIO_REG_515664_RMSK)
+#define HWIO_REG_515664_INM(m)  in_dword_masked(\
+	HWIO_REG_515664_ADDR, m)
+#define HWIO_REG_515664_OUT(v)  out_dword(HWIO_REG_515664_ADDR, v)
+#define HWIO_REG_515664_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_515664_ADDR, m, v, HWIO_REG_515664_IN);
+#define HWIO_REG_515664_NV21_SEL_BMSK   0xffffffff
+#define HWIO_REG_515664_NV21_SEL_SHFT   0
+
+
+
 #define HWIO_REG_886210_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c518)
 #define HWIO_REG_886210_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c518)
 #define HWIO_REG_886210_RMSK  0xffff
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c
index 5206182..cf62332 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c
@@ -15,8 +15,6 @@
 #include "vidc_hwio.h"
 #include "vidc_pix_cache.h"
 
-
-#define VIDC_1080P_MAX_DEC_DPB 19
 #define VIDC_TILE_MULTIPLY_FACTOR 8192
 
 void vidc_pix_cache_sw_reset(void)
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h
index e8a93a1..c70b113 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index 9dfb5d1..ff0de80 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -544,7 +544,6 @@
 	u32 enc_perf_level = 0, dec_perf_level = 0;
 	u32 bus_clk_index, client_type = 0;
 	int rc = 0;
-	bool turbo_enabled = false;
 	bool turbo_supported =
 		!resource_context.vidc_platform_data->disable_turbo;
 
@@ -554,9 +553,6 @@
 			dec_perf_level += cctxt_itr->reqd_perf_lvl;
 		else
 			enc_perf_level += cctxt_itr->reqd_perf_lvl;
-
-		if (cctxt_itr->is_turbo_enabled)
-			turbo_enabled = true;
 		cctxt_itr = cctxt_itr->next;
 	}
 
@@ -573,18 +569,8 @@
 
 	if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0)
 		bus_clk_index = 2;
-	else if ((!turbo_supported || !turbo_enabled) && bus_clk_index == 3) {
-		if (!turbo_supported)
-			VCDRES_MSG_MED("Warning: Turbo mode not supported "\
-					" falling back to 1080p bus\n");
+	else if (!turbo_supported && bus_clk_index == 3)
 		bus_clk_index = 2;
-	}
-
-	if (bus_clk_index == 3)
-		dev_ctxt->turbo_mode_set = true;
-	else
-		dev_ctxt->turbo_mode_set = false;
-
 	bus_clk_index = (bus_clk_index << 1) + (client_type + 1);
 	VCDRES_MSG_LOW("%s(), bus_clk_index = %d", __func__, bus_clk_index);
 	VCDRES_MSG_LOW("%s(),context.pcl = %x", __func__, resource_context.pcl);
@@ -640,11 +626,8 @@
 		*pn_set_perf_lvl = RESTRK_1080P_TURBO_PERF_LEVEL;
 	}
 
-	if ((!turbo_supported || !dev_ctxt->turbo_mode_set) &&
+	if (!turbo_supported &&
 		 *pn_set_perf_lvl == RESTRK_1080P_TURBO_PERF_LEVEL) {
-		if (!turbo_supported)
-			VCDRES_MSG_ERROR("Warning: Turbo mode not supported "\
-					" falling back to 1080p clocks\n");
 		vidc_freq = vidc_clk_table[2];
 		*pn_set_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL;
 	}
@@ -756,6 +739,9 @@
 			resource_context.vidc_platform_data->disable_dmx;
 			resource_context.disable_fullhd =
 			resource_context.vidc_platform_data->disable_fullhd;
+			resource_context.enable_sec_metadata =
+			resource_context.vidc_platform_data->
+				enable_sec_metadata;
 #ifdef CONFIG_MSM_BUS_SCALING
 			resource_context.vidc_bus_client_pdata =
 			resource_context.vidc_platform_data->
@@ -914,6 +900,10 @@
 {
 	return resource_context.disable_fullhd;
 }
+u32 res_trk_get_enable_sec_metadata(void)
+{
+	return resource_context.enable_sec_metadata;
+}
 
 int res_trk_enable_iommu_clocks(void)
 {
@@ -1025,9 +1015,9 @@
 	mutex_unlock(&resource_context.secure_lock);
 	return 0;
 unsecure_cmd_heap:
-	msm_ion_unsecure_heap(ION_HEAP(resource_context.memtype));
-unsecure_memtype_heap:
 	msm_ion_unsecure_heap(ION_HEAP(resource_context.cmd_mem_type));
+unsecure_memtype_heap:
+	msm_ion_unsecure_heap(ION_HEAP(resource_context.memtype));
 disable_iommu_clks:
 	res_trk_disable_iommu_clocks();
 error_open:
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
index a980230..2fa82ac 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -53,6 +53,7 @@
 	struct ion_client *res_ion_client;
 	u32 disable_dmx;
 	u32 disable_fullhd;
+	u32 enable_sec_metadata;
 	enum ddl_mem_area res_mem_type;
 	u32 mmu_clks_on;
 	u32 secure_session;
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
index ee876f4..15ffa96 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -34,6 +34,7 @@
 u32 res_trk_get_enable_ion(void);
 u32 res_trk_is_cp_enabled(void);
 u32 res_trk_get_disable_fullhd(void);
+u32 res_trk_get_enable_sec_metadata(void);
 struct ion_client *res_trk_get_ion_client(void);
 u32 res_trk_get_disable_dmx(void);
 u32 res_trk_get_min_dpb_count(void);
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
index a144e06..9b27abd 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
index e6d3527..7a79a40 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012 The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h
index 53cc93e..3796e8f 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h
index 9fdb668..78b05ec 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
index 91136f3..6e43a7c 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c
index 965c3aa..23948d4 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h
index a136de8..ba8dbcb 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
index 6a69955..4cbd984 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
index 15adf21..b97fae6 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
index 7e201cf..32a4047 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
index fe71dc1..817a98e 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c
index 2a74da8..5d87533 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h
index ed43861..7c9ac95 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
index 3aebdaf..cdb6313 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
index 3b40640..f5f5d7f 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h
index 59bb620..633292b 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.c b/drivers/video/msm/vidc/720p/ddl/vidc.c
index de6cbbb..da969ef 100644
--- a/drivers/video/msm/vidc/720p/ddl/vidc.c
+++ b/drivers/video/msm/vidc/720p/ddl/vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.h b/drivers/video/msm/vidc/720p/ddl/vidc.h
index 509482b..a09034f 100644
--- a/drivers/video/msm/vidc/720p/ddl/vidc.h
+++ b/drivers/video/msm/vidc/720p/ddl/vidc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
index 1a75286..9b184e8 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
index 5f126fd..e1781b6 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
index a20d9f2..537f3c8 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 3efc4d3..92fa3ed 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -273,7 +273,8 @@
 		(vcd_frame_data->flags & VCD_FRAME_FLAG_EOS)) {
 
 		if (res_trk_check_for_sec_session() &&
-				event == VCD_EVT_RESP_OUTPUT_DONE) {
+			res_trk_get_enable_sec_metadata() &&
+			event == VCD_EVT_RESP_OUTPUT_DONE) {
 			DBG("Buffer Index = %d", buffer_index);
 			if (buffer_index != -1) {
 				if (client_ctx->meta_addr_table[buffer_index].
@@ -311,6 +312,12 @@
 		    vcd_frame_data->data_len;
 		vdec_msg->vdec_msg_info.msgdata.output_frame.flags =
 		    vcd_frame_data->flags;
+		/* metadata offset in output buffer for non-secure mode */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.metadata_len =
+			(size_t)vcd_frame_data->metadata_len;
+		/* metadata offset in output buffer for non-secure mode */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.metadata_offset =
+			(size_t)vcd_frame_data->metadata_offset;
 		/* Timestamp pass-through from input frame */
 		vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp =
 		    vcd_frame_data->time_stamp;
@@ -380,13 +387,11 @@
 				pmem_fd, kernel_vaddr, buffer_index,
 				&buff_handle);
 		if (ion_flag == ION_FLAG_CACHED && buff_handle) {
-			DBG("%s: Cache invalidate: vaddr (%p), "\
-				"size %u\n", __func__,
-				(void *)kernel_vaddr,
+			DBG("%s: Cache invalidate: size %u", __func__,
 				vcd_frame_data->alloc_len);
 			msm_ion_do_cache_op(client_ctx->user_ion_client,
 					buff_handle,
-					(unsigned long *) kernel_vaddr,
+					(unsigned long *) NULL,
 					(unsigned long)vcd_frame_data->\
 					alloc_len,
 					ION_IOC_INV_CACHES);
@@ -735,6 +740,22 @@
 		return true;
 }
 
+static u32 vid_dec_get_enable_secure_metadata(struct video_client_ctx
+				*client_ctx, u32 *enable_sec_metadata)
+{
+
+	struct vcd_property_hdr vcd_property_hdr;
+	if (!client_ctx || !enable_sec_metadata)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_ENABLE_SEC_METADATA;
+	vcd_property_hdr.sz = sizeof(u32);
+	if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+						 enable_sec_metadata))
+		return false;
+	else
+		return true;
+}
+
 static u32 vid_dec_get_disable_dmx_support(struct video_client_ctx *client_ctx,
 					   u32 *disable_dmx)
 {
@@ -1648,7 +1669,7 @@
 			if (ion_flag == ION_FLAG_CACHED && buff_handle) {
 				msm_ion_do_cache_op(client_ctx->user_ion_client,
 				buff_handle,
-				(unsigned long *)kernel_vaddr,
+				(unsigned long *) NULL,
 				(unsigned long) vcd_input_buffer.data_len,
 				ION_IOC_CLEAN_CACHES);
 			}
@@ -2006,6 +2027,7 @@
 	}
 	case VDEC_IOCTL_CMD_PAUSE:
 	{
+		DBG("VDEC_IOCTL_CMD_PAUSE\n");
 		result = vid_dec_pause_resume(client_ctx, true);
 		if (!result)
 			return -EIO;
@@ -2059,6 +2081,7 @@
 	}
 	case VDEC_IOCTL_SET_PERF_CLK:
 	{
+		DBG("VDEC_IOCTL_SET_PERF_CLK\n");
 		vid_dec_set_turbo_clk(client_ctx);
 		break;
 	}
@@ -2242,6 +2265,23 @@
 		break;
 	}
 
+	case VDEC_IOCTL_GET_ENABLE_SEC_METADATA:
+	{
+		u32 enable_sec_metadata;
+		DBG("VDEC_IOCTL_GET_ENABLE_SEC_METADATA\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		result = vid_dec_get_enable_secure_metadata(client_ctx,
+					&enable_sec_metadata);
+		if (result) {
+			if (copy_to_user(vdec_msg.out, &enable_sec_metadata,
+					sizeof(u32)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+
 	case VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT:
 	{
 		u32 disable_dmx;
@@ -2334,7 +2374,11 @@
 		if (copy_from_user(&meta_buffers, vdec_msg.in,
 						   sizeof(meta_buffers)))
 			return -EFAULT;
-		result = vid_dec_set_meta_buffers(client_ctx, &meta_buffers);
+		if (res_trk_get_enable_sec_metadata())
+			result =
+			vid_dec_set_meta_buffers(client_ctx, &meta_buffers);
+		else
+			ERR("ERROR : Meta data is not enabled.\n");
 
 		if (!result)
 			return -EIO;
@@ -2343,7 +2387,10 @@
 	case VDEC_IOCTL_FREE_META_BUFFERS:
 	{
 		DBG("VDEC_IOCTL_FREE_META_BUFFERS\n");
-		result = vid_dec_free_meta_buffers(client_ctx);
+		if (res_trk_get_enable_sec_metadata())
+			result = vid_dec_free_meta_buffers(client_ctx);
+		else
+			ERR("ERROR : Can't free. Meta data is not enabled.\n");
 		if (!result)
 			return -EIO;
 		break;
@@ -2394,6 +2441,7 @@
 	}
 	case VDEC_IOCTL_SET_IDR_ONLY_DECODING:
 	{
+		DBG("VDEC_IOCTL_SET_IDR_ONLY_DECODING\n");
 		result = vid_dec_set_idr_only_decoding(client_ctx);
 		if (!result)
 			return -EIO;
@@ -2401,6 +2449,7 @@
 	}
 	case VDEC_IOCTL_SET_CONT_ON_RECONFIG:
 	{
+		DBG("VDEC_IOCTL_SET_CONT_ON_RECONFIG\n");
 		result = vid_dec_set_cont_on_reconfig(client_ctx);
 		if (!result)
 			return -EIO;
diff --git a/drivers/video/msm/vidc/common/dec/vdec_internal.h b/drivers/video/msm/vidc/common/dec/vdec_internal.h
index 89da9a2..a7a32a5 100644
--- a/drivers/video/msm/vidc/common/dec/vdec_internal.h
+++ b/drivers/video/msm/vidc/common/dec/vdec_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 2353553..1722972 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -254,6 +254,12 @@
 			vcd_frame_data->time_stamp;
 		venc_msg->venc_msg_info.buf.sz =
 			vcd_frame_data->alloc_len;
+		/* Metadata length */
+		venc_msg->venc_msg_info.buf.metadata_len =
+			vcd_frame_data->metadata_len;
+		/* Metadata offset */
+		venc_msg->venc_msg_info.buf.metadata_offset =
+			vcd_frame_data->metadata_offset;
 
 		/* Decoded picture width and height */
 		venc_msg->venc_msg_info.msgdata_size =
@@ -270,7 +276,7 @@
 		if (ion_flag == ION_FLAG_CACHED && buff_handle) {
 			msm_ion_do_cache_op(client_ctx->user_ion_client,
 				buff_handle,
-				(unsigned long *) kernel_vaddr,
+				(unsigned long *) NULL,
 				(unsigned long)venc_msg->venc_msg_info.buf.sz,
 				ION_IOC_CLEAN_INV_CACHES);
 		}
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index 8779432..e60fc46 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -123,6 +123,10 @@
 			format.buffer_format =
 				VCD_BUFFER_FORMAT_NV12_16M2KA;
 			break;
+		case VEN_INPUTFMT_NV21_16M2KA:
+			format.buffer_format =
+				VCD_BUFFER_FORMAT_NV21_16M2KA;
+			break;
 		default:
 			status = false;
 			break;
@@ -152,6 +156,9 @@
 			case VCD_BUFFER_FORMAT_TILE_4x2:
 				*input_format = VEN_INPUTFMT_NV21;
 				break;
+			case VCD_BUFFER_FORMAT_NV21_16M2KA:
+				*input_format = VEN_INPUTFMT_NV21_16M2KA;
+				break;
 			default:
 				status = false;
 				break;
@@ -1692,7 +1699,7 @@
 				msm_ion_do_cache_op(
 				client_ctx->user_ion_client,
 				buff_handle,
-				(unsigned long *) vcd_input_buffer.virtual,
+				(unsigned long *) NULL,
 				(unsigned long) vcd_input_buffer.data_len,
 				ION_IOC_CLEAN_CACHES);
 			}
@@ -1863,7 +1870,7 @@
 					VIDEO_DOMAIN,
 					VIDEO_MAIN_POOL,
 					SZ_4K,
-					0,
+					control->buffer_size * 2,
 					(unsigned long *)&iova,
 					(unsigned long *)&buffer_size,
 					0, 0);
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.h b/drivers/video/msm/vidc/common/enc/venc_internal.h
index 4ef64bb..e724b21 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.h
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index 65dde68..fd1d4c1 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -470,6 +470,42 @@
 			client_ctx->h264_mv_ion_handle = NULL;
 		}
 	}
+
+	if (client_ctx->vcd_meta_buffer.client_data)
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		client_ctx->vcd_meta_buffer.client_data);
+	if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_ion_handle)) {
+			ion_unmap_kernel(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_ion_handle);
+		if (!res_trk_check_for_sec_session() &&
+		   (res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
+			ion_unmap_iommu(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_ion_handle,
+				VIDEO_DOMAIN,
+				VIDEO_MAIN_POOL);
+		}
+		ion_free(client_ctx->user_ion_client,
+			client_ctx->meta_buffer_ion_handle);
+		client_ctx->meta_buffer_ion_handle = NULL;
+	}
+
+	if (client_ctx->vcd_meta_buffer.client_data_iommu)
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		client_ctx->vcd_meta_buffer.client_data_iommu);
+	if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_iommu_ion_handle)) {
+		ion_unmap_kernel(client_ctx->user_ion_client,
+			client_ctx->meta_buffer_iommu_ion_handle);
+		if (res_trk_check_for_sec_session() &&
+		   (res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
+			ion_unmap_iommu(client_ctx->user_ion_client,
+				client_ctx->meta_buffer_iommu_ion_handle,
+				VIDEO_DOMAIN,
+				VIDEO_MAIN_POOL);
+		}
+		ion_free(client_ctx->user_ion_client,
+			client_ctx->meta_buffer_iommu_ion_handle);
+		client_ctx->meta_buffer_iommu_ion_handle = NULL;
+	}
 bail_out_cleanup:
 	return;
 }
@@ -644,16 +680,6 @@
 				 __func__);
 				goto bail_out_add;
 			}
-			*kernel_vaddr = (unsigned long)
-				ion_map_kernel(
-				client_ctx->user_ion_client,
-				buff_ion_handle);
-			if (IS_ERR_OR_NULL((void *)*kernel_vaddr)) {
-				ERR("%s():ION virtual addr fail\n",
-				 __func__);
-				*kernel_vaddr = (unsigned long)NULL;
-				goto ion_free_error;
-			}
 			if (res_trk_check_for_sec_session() ||
 			   (res_trk_get_core_type() == (u32)VCD_CORE_720P)) {
 				if (ion_phys(client_ctx->user_ion_client,
@@ -677,8 +703,7 @@
 						length,
 						(unsigned long *) &iova,
 						(unsigned long *) &buffer_size,
-						0,
-						ION_IOMMU_UNMAP_DELAYED);
+						0, 0);
 				if (ret || !iova) {
 					ERR(
 					"%s():ION iommu map fail, ret = %d, iova = 0x%lx\n",
@@ -692,6 +717,7 @@
 						 iova;
 			}
 		}
+		(*kernel_vaddr) = phys_addr;
 		phys_addr += buffer_addr_offset;
 		(*kernel_vaddr) += buffer_addr_offset;
 		buf_addr_table[*num_of_buffers].user_vaddr = user_vaddr;
@@ -712,9 +738,6 @@
 	mutex_unlock(&client_ctx->enrty_queue_lock);
 	return true;
 ion_map_error:
-	if (*kernel_vaddr && buff_ion_handle)
-		ion_unmap_kernel(client_ctx->user_ion_client, buff_ion_handle);
-ion_free_error:
 	if (!IS_ERR_OR_NULL(buff_ion_handle))
 		ion_free(client_ctx->user_ion_client, buff_ion_handle);
 bail_out_add:
@@ -835,8 +858,6 @@
 	}
 	*kernel_vaddr = buf_addr_table[i].kernel_vaddr;
 	if (buf_addr_table[i].buff_ion_handle) {
-		ion_unmap_kernel(client_ctx->user_ion_client,
-				buf_addr_table[i].buff_ion_handle);
 		if (!res_trk_check_for_sec_session() &&
 		   (res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
 			ion_unmap_iommu(client_ctx->user_ion_client,
diff --git a/drivers/video/msm/vidc/common/init/vidc_init_internal.h b/drivers/video/msm/vidc/common/init/vidc_init_internal.h
index 1d903ad..b62280f 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init_internal.h
+++ b/drivers/video/msm/vidc/common/init/vidc_init_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/common/vcd/vcd.h b/drivers/video/msm/vidc/common/vcd/vcd.h
index 8f44a56..122db76 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.c b/drivers/video/msm/vidc/common/vcd/vcd_api.c
index 30e09ef..fd2d01b 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_api.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_api.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
index 5d092c5..a8c99c1 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
@@ -1745,7 +1745,7 @@
 	 vcd_get_buffer_requirements_cmn,
 	 NULL,
 	 NULL,
-	 NULL,
+	 vcd_free_buffer_cmn,
 	 vcd_fill_output_buffer_cmn,
 	 vcd_clnt_cb_in_flushing,
 	 },
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h
index 9f2d63d..ba1884d 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_core.h b/drivers/video/msm/vidc/common/vcd/vcd_core.h
index ae97561..9508a8d 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_core.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -147,7 +147,6 @@
 	u32 reqd_perf_lvl;
 	u32 curr_perf_lvl;
 	u32 set_perf_lvl_pending;
-	bool turbo_mode_set;
 };
 
 struct vcd_clnt_status {
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
index d6af45d..9074358 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
@@ -220,8 +220,6 @@
 						   VCD_DEVICE_STATE_INITING,
 						   ev_code);
 	}
-	dev_ctxt->turbo_mode_set = 0;
-
 	return rc;
 }
 
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h
index 2443c33..898f284 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c
index 44d270a..4b70eed 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h
index 26ce019..aecbc8d 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
index fe0e131..c4af39c 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
@@ -224,8 +224,13 @@
 		buffer = list_entry(sched_cctxt->ip_frm_list.prev,
 			struct vcd_buffer_entry, sched_list);
 		buffer->frame.flags |= VCD_FRAME_FLAG_EOS;
-	} else
+		VCD_MSG_LOW("%s: added EOS flag to last buffer entry",
+			__func__);
+	} else {
 		rc = VCD_ERR_QEMPTY;
+		VCD_MSG_HIGH("%s: EOS need to be processed as last buffer",
+			__func__);
+	}
 	return rc;
 }
 
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index 592ded1..3e20fbc 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -1726,6 +1726,7 @@
 	u32 rc;
 	struct ddl_frame_data_tag ddl_frm;
 
+	VCD_MSG_LOW("%s: ", __func__);
 	prop_hdr.prop_id = DDL_I_DPB_RETRIEVE;
 	prop_hdr.sz = sizeof(struct ddl_frame_data_tag);
 	memset(&ddl_frm, 0, sizeof(ddl_frm));
@@ -1815,19 +1816,25 @@
 	*pb_eos_handled = false;
 
 	if (input_frame->virtual &&
-			input_frame->data_len)
+			input_frame->data_len) {
+		VCD_MSG_LOW("%s: data available with EOS buffer", __func__);
 		return VCD_S_SUCCESS;
+	}
 
 	input_frame->data_len = 0;
 	rc = vcd_sched_mark_client_eof(cctxt->sched_clnt_hdl);
-	if (VCD_FAILED(rc) && rc != VCD_ERR_QEMPTY)
+	if (VCD_FAILED(rc) && rc != VCD_ERR_QEMPTY) {
+		VCD_MSG_LOW("%s: rc = %u", __func__, rc);
 		return rc;
+	}
 
-	if (rc == VCD_S_SUCCESS)
+	if (rc == VCD_S_SUCCESS) {
 		*pb_eos_handled = true;
-	else if (cctxt->decoding && !input_frame->virtual)
+		VCD_MSG_LOW("%s: EOS handled", __func__);
+	} else if (cctxt->decoding && !input_frame->virtual) {
 		cctxt->sched_clnt_hdl->tkns++;
-	else if (!cctxt->decoding) {
+		VCD_MSG_LOW("%s: decoding & virtual addr is NULL", __func__);
+	} else if (!cctxt->decoding) {
 		vcd_send_frame_done_in_eos(cctxt, input_frame, false);
 		if (cctxt->status.mask & VCD_EOS_WAIT_OP_BUF) {
 			vcd_do_client_state_transition(cctxt,
@@ -1841,6 +1848,8 @@
 	if (*pb_eos_handled &&
 		input_frame->virtual &&
 		!input_frame->data_len) {
+		VCD_MSG_LOW("%s: sending INPUT_DONE as eos was handled",
+			__func__);
 		cctxt->callback(VCD_EVT_RESP_INPUT_DONE,
 				  VCD_S_SUCCESS,
 				  input_frame,
@@ -2031,7 +2040,7 @@
 	}
 
 	if (VCD_FAILED(status)) {
-		VCD_MSG_ERROR("INPUT_DONE returned err = 0x%x", status);
+		VCD_MSG_HIGH("INPUT_DONE returned err = 0x%x", status);
 		vcd_handle_input_done_failed(cctxt, transc);
 	} else
 		cctxt->status.mask |= VCD_FIRST_IP_DONE;
@@ -2445,6 +2454,7 @@
 	struct vcd_sequence_hdr seq_hdr;
 	struct vcd_property_sps_pps_for_idr_enable idr_enable;
 	struct vcd_property_codec codec;
+	u8 *kernel_vaddr = NULL;
 	*handled = true;
 	prop_hdr.prop_id = DDL_I_SEQHDR_PRESENT;
 	prop_hdr.sz = sizeof(seqhdr_present);
@@ -2472,7 +2482,26 @@
 			if (!cctxt->secure) {
 				prop_hdr.prop_id = VCD_I_SEQ_HEADER;
 				prop_hdr.sz = sizeof(struct vcd_sequence_hdr);
-				seq_hdr.sequence_header = frm_entry->virtual;
+				if (vcd_get_ion_status()) {
+					kernel_vaddr = (u8 *)ion_map_kernel(
+						cctxt->vcd_ion_client,
+						frm_entry->buff_ion_handle);
+					if (IS_ERR_OR_NULL(kernel_vaddr)) {
+						VCD_MSG_ERROR("%s: 0x%x = "\
+						"ion_map_kernel(0x%x, 0x%x) fail",
+						__func__,
+						(u32)kernel_vaddr,
+						(u32)cctxt->vcd_ion_client,
+						(u32)frm_entry->
+						buff_ion_handle);
+						return VCD_ERR_FAIL;
+					}
+				} else {
+					VCD_MSG_ERROR("%s: ION status is NULL",
+						__func__);
+					return VCD_ERR_FAIL;
+				}
+				seq_hdr.sequence_header = kernel_vaddr;
 				seq_hdr.sequence_header_len =
 					frm_entry->alloc_len;
 				rc = ddl_get_property(cctxt->ddl_handle,
@@ -2483,6 +2512,8 @@
 					frm_entry->time_stamp = 0;
 					frm_entry->flags |=
 						VCD_FRAME_FLAG_CODECCONFIG;
+					VCD_MSG_LOW("%s: header len = %u",
+						__func__, frm_entry->data_len);
 				} else
 					VCD_MSG_ERROR("rc = 0x%x. Failed:"
 							"ddl_get_property: VCD_I_SEQ_HEADER",
@@ -2524,6 +2555,16 @@
 		VCD_MSG_ERROR(
 			"rc = 0x%x. Failed: ddl_get_property:VCD_I_CODEC",
 			rc);
+	if (kernel_vaddr) {
+		if (!IS_ERR_OR_NULL(frm_entry->buff_ion_handle)) {
+			ion_map_kernel(cctxt->vcd_ion_client,
+				frm_entry->buff_ion_handle);
+		} else {
+			VCD_MSG_ERROR("%s: Invalid ion_handle (0x%x)",
+				__func__, (u32)frm_entry->buff_ion_handle);
+			rc = VCD_ERR_FAIL;
+		}
+	}
 	return rc;
 }
 
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_util.c b/drivers/video/msm/vidc/common/vcd/vcd_util.c
index ba991f1..98bc7f5 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_util.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_util.h b/drivers/video/msm/vidc/common/vcd/vcd_util.h
index 7164029..7571b25 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_util.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index dd73104..3bf1490 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -9,7 +9,7 @@
 /*
  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * Copyright (c) 2009-2010, Code Aurora Forum.
+ * Copyright (c) 2009-2010, The Linux Foundation.
  * All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
diff --git a/include/linux/adv7520.h b/include/linux/adv7520.h
index 96db7b7..f64dbdf 100644
--- a/include/linux/adv7520.h
+++ b/include/linux/adv7520.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/bma150.h b/include/linux/bma150.h
index a3d1c4f..d62a4d9 100644
--- a/include/linux/bma150.h
+++ b/include/linux/bma150.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
old mode 100644
new mode 100755
index d3ee879..969b400
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -20,12 +20,14 @@
 #define DEINIT_TYPE			16
 #define USER_SPACE_DATA_TYPE		32
 #define DCI_DATA_TYPE			64
+#define CALLBACK_DATA_TYPE		128
 #define USB_MODE			1
 #define MEMORY_DEVICE_MODE		2
 #define NO_LOGGING_MODE			3
 #define UART_MODE			4
 #define SOCKET_MODE			5
 #define CALLBACK_MODE			6
+#define MEMORY_DEVICE_MODE_NRT		7
 /* different values that go in for diag_data_type */
 #define DATA_TYPE_EVENT         	0
 #define DATA_TYPE_F3            	1
@@ -43,6 +45,10 @@
 #define DIAG_IOCTL_DCI_REG		23
 #define DIAG_IOCTL_DCI_STREAM_INIT	24
 #define DIAG_IOCTL_DCI_HEALTH_STATS	25
+#define DIAG_IOCTL_DCI_LOG_STATUS	26
+#define DIAG_IOCTL_DCI_EVENT_STATUS	27
+#define DIAG_IOCTL_DCI_CLEAR_LOGS	28
+#define DIAG_IOCTL_DCI_CLEAR_EVENTS	29
 #define DIAG_IOCTL_REMOTE_DEV		32
 
 /* PC Tools IDs */
@@ -112,10 +118,10 @@
 /* This needs to be modified manually now, when we add
  a new RANGE of SSIDs to the msg_mask_tbl */
 #define MSG_MASK_TBL_CNT		24
-#define EVENT_LAST_ID			0x099F
+#define EVENT_LAST_ID			0x09AB
 
 #define MSG_SSID_0			0
-#define MSG_SSID_0_LAST			93
+#define MSG_SSID_0_LAST			94
 #define MSG_SSID_1			500
 #define MSG_SSID_1_LAST			506
 #define MSG_SSID_2			1000
@@ -278,6 +284,9 @@
 	MSG_LVL_LOW,
 	MSG_LVL_MED,
 	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW,
+	MSG_LVL_HIGH,
 	MSG_LVL_LOW
 };
 
@@ -713,7 +722,7 @@
 /* LOG CODES */
 
 #define LOG_0	0x0
-#define LOG_1	0x1750
+#define LOG_1	0x1755
 #define LOG_2	0x0
 #define LOG_3	0x0
 #define LOG_4	0x4910
diff --git a/include/linux/fmem.h b/include/linux/fmem.h
index e4fa82c..cda4a0f 100644
--- a/include/linux/fmem.h
+++ b/include/linux/fmem.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/fsm_dfe_hh.h b/include/linux/fsm_dfe_hh.h
index 7938518..db96794 100644
--- a/include/linux/fsm_dfe_hh.h
+++ b/include/linux/fsm_dfe_hh.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/fsm_rfic_ftr.h b/include/linux/fsm_rfic_ftr.h
index 18b7947..6288a33 100644
--- a/include/linux/fsm_rfic_ftr.h
+++ b/include/linux/fsm_rfic_ftr.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 1e49be4..7b3823e 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -23,6 +23,7 @@
 #define ___GFP_REPEAT		0x400u
 #define ___GFP_NOFAIL		0x800u
 #define ___GFP_NORETRY		0x1000u
+#define ___GFP_CMA		0x2000u
 #define ___GFP_COMP		0x4000u
 #define ___GFP_ZERO		0x8000u
 #define ___GFP_NOMEMALLOC	0x10000u
@@ -51,7 +52,9 @@
 #define __GFP_HIGHMEM	((__force gfp_t)___GFP_HIGHMEM)
 #define __GFP_DMA32	((__force gfp_t)___GFP_DMA32)
 #define __GFP_MOVABLE	((__force gfp_t)___GFP_MOVABLE)  /* Page is movable */
-#define GFP_ZONEMASK	(__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)
+#define __GFP_CMA	((__force gfp_t)___GFP_CMA)
+#define GFP_ZONEMASK	(__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE| \
+			__GFP_CMA)
 /*
  * Action modifiers - doesn't change the zoning
  *
@@ -124,7 +127,7 @@
 #endif
 
 /* This mask makes up all the page movable related flags */
-#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
+#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE|__GFP_CMA)
 
 /* Control page allocator reclaim behavior */
 #define GFP_RECLAIM_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\
@@ -157,8 +160,14 @@
 		return MIGRATE_UNMOVABLE;
 
 	/* Group based on mobility */
+#ifndef CONFIG_CMA
 	return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) |
 		((gfp_flags & __GFP_RECLAIMABLE) != 0);
+#else
+	return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) |
+		(((gfp_flags & __GFP_CMA) != 0) << 1) |
+		((gfp_flags & __GFP_RECLAIMABLE) != 0);
+#endif
 }
 
 #ifdef CONFIG_HIGHMEM
diff --git a/include/linux/gpio-pm8xxx-rpc.h b/include/linux/gpio-pm8xxx-rpc.h
index 5b6f097..cb8247f 100644
--- a/include/linux/gpio-pm8xxx-rpc.h
+++ b/include/linux/gpio-pm8xxx-rpc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index d3999b4..c737eb7 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -211,9 +211,24 @@
 alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma,
 					unsigned long vaddr)
 {
+#ifndef CONFIG_CMA
 	return __alloc_zeroed_user_highpage(__GFP_MOVABLE, vma, vaddr);
+#else
+	return __alloc_zeroed_user_highpage(__GFP_MOVABLE|__GFP_CMA, vma,
+						vaddr);
+#endif
 }
 
+#ifdef CONFIG_CMA
+static inline struct page *
+alloc_zeroed_user_highpage_movable_cma(struct vm_area_struct *vma,
+						unsigned long vaddr)
+{
+	return __alloc_zeroed_user_highpage(__GFP_MOVABLE|__GFP_CMA, vma,
+						vaddr);
+}
+#endif
+
 static inline void clear_highpage(struct page *page)
 {
 	void *kaddr = kmap_atomic(page);
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index 5c3c728..0b9c86a 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2010 Samsung Electronics Co.Ltd
  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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
diff --git a/include/linux/i2c/bq27520.h b/include/linux/i2c/bq27520.h
index 70c5a4c..c1e5e06 100644
--- a/include/linux/i2c/bq27520.h
+++ b/include/linux/i2c/bq27520.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/i2c/isa1200.h b/include/linux/i2c/isa1200.h
index ffadf96..65a6bf5 100644
--- a/include/linux/i2c/isa1200.h
+++ b/include/linux/i2c/isa1200.h
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2009 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
- *  Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2010-2012, The Linux Foundation. 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
diff --git a/include/linux/i2c/isl9519.h b/include/linux/i2c/isl9519.h
index 8c98bf7..3499674 100644
--- a/include/linux/i2c/isl9519.h
+++ b/include/linux/i2c/isl9519.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/i2c/smb137b.h b/include/linux/i2c/smb137b.h
index a72b895..7367ac5 100644
--- a/include/linux/i2c/smb137b.h
+++ b/include/linux/i2c/smb137b.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/i2c/smb349.h b/include/linux/i2c/smb349.h
index 2adacb3..40e1fac 100644
--- a/include/linux/i2c/smb349.h
+++ b/include/linux/i2c/smb349.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012 The Linux Foundation. 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 and
diff --git a/include/linux/i2c/sx150x.h b/include/linux/i2c/sx150x.h
index e73dfd9..a2060bd 100644
--- a/include/linux/i2c/sx150x.h
+++ b/include/linux/i2c/sx150x.h
@@ -1,7 +1,7 @@
 /*
  * Driver for the Semtech SX150x I2C GPIO Expanders
  *
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index a2b59d7..1ca1b83 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1074,6 +1074,90 @@
 #define WLAN_HT_SMPS_CONTROL_STATIC	1
 #define WLAN_HT_SMPS_CONTROL_DYNAMIC	3
 
+/**
+ * struct ieee80211_vht_mcs_info - VHT MCS information
+ * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams
+ * @rx_highest: Indicates highest long GI VHT PPDU data rate
+ *	STA can receive. Rate expressed in units of 1 Mbps.
+ *	If this field is 0 this value should not be used to
+ *	consider the highest RX data rate supported.
+ * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams
+ * @tx_highest: Indicates highest long GI VHT PPDU data rate
+ *	STA can transmit. Rate expressed in units of 1 Mbps.
+ *	If this field is 0 this value should not be used to
+ *	consider the highest TX data rate supported.
+ */
+struct ieee80211_vht_mcs_info {
+	__le16 rx_mcs_map;
+	__le16 rx_highest;
+	__le16 tx_mcs_map;
+	__le16 tx_highest;
+} __packed;
+
+/**
+ * struct ieee80211_vht_cap - VHT capabilities
+ *
+ * This structure is the "VHT capabilities element" as
+ * described in 802.11ac D3.0 8.4.2.160
+ * @vht_cap_info: VHT capability info
+ * @supp_mcs: VHT MCS supported rates
+ */
+struct ieee80211_vht_cap {
+	__le32 vht_cap_info;
+	struct ieee80211_vht_mcs_info supp_mcs;
+} __packed;
+
+/**
+ * struct ieee80211_vht_operation - VHT operation IE
+ *
+ * This structure is the "VHT operation element" as
+ * described in 802.11ac D3.0 8.4.2.161
+ * @chan_width: Operating channel width
+ * @center_freq_seg1_idx: center freq segment 1 index
+ * @center_freq_seg2_idx: center freq segment 2 index
+ * @basic_mcs_set: VHT Basic MCS rate set
+ */
+struct ieee80211_vht_operation {
+	u8 chan_width;
+	u8 center_freq_seg1_idx;
+	u8 center_freq_seg2_idx;
+	__le16 basic_mcs_set;
+} __packed;
+
+
+#define IEEE80211_VHT_MCS_ZERO_TO_SEVEN_SUPPORT 0
+#define IEEE80211_VHT_MCS_ZERO_TO_EIGHT_SUPPORT 1
+#define IEEE80211_VHT_MCS_ZERO_TO_NINE_SUPPORT  2
+#define IEEE80211_VHT_MCS_NOT_SUPPORTED 3
+
+/* 802.11ac VHT Capabilities */
+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895                0x00000000
+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991                0x00000001
+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454               0x00000002
+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ              0x00000004
+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ     0x00000008
+#define IEEE80211_VHT_CAP_RXLDPC                              0x00000010
+#define IEEE80211_VHT_CAP_SHORT_GI_80                         0x00000020
+#define IEEE80211_VHT_CAP_SHORT_GI_160                        0x00000040
+#define IEEE80211_VHT_CAP_TXSTBC                              0x00000080
+#define IEEE80211_VHT_CAP_RXSTBC_1                            0x00000100
+#define IEEE80211_VHT_CAP_RXSTBC_2                            0x00000200
+#define IEEE80211_VHT_CAP_RXSTBC_3                            0x00000300
+#define IEEE80211_VHT_CAP_RXSTBC_4                            0x00000400
+#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE               0x00000800
+#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE               0x00001000
+#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX             0x00006000
+#define IEEE80211_VHT_CAP_SOUNDING_DIMENTION_MAX              0x00030000
+#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE               0x00080000
+#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE               0x00100000
+#define IEEE80211_VHT_CAP_VHT_TXOP_PS                         0x00200000
+#define IEEE80211_VHT_CAP_HTC_VHT                             0x00400000
+#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT          0x00800000
+#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB   0x08000000
+#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB     0x0c000000
+#define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN                  0x10000000
+#define IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN                  0x20000000
+
 /* Authentication algorithms */
 #define WLAN_AUTH_OPEN 0
 #define WLAN_AUTH_SHARED_KEY 1
@@ -1334,6 +1418,9 @@
 	WLAN_EID_DSE_REGISTERED_LOCATION = 58,
 	WLAN_EID_SUPPORTED_REGULATORY_CLASSES = 59,
 	WLAN_EID_EXT_CHANSWITCH_ANN = 60,
+
+	WLAN_EID_VHT_CAPABILITY = 191,
+	WLAN_EID_VHT_OPERATION = 192,
 };
 
 /* Action category code */
diff --git a/include/linux/input/cy8c_ts.h b/include/linux/input/cy8c_ts.h
index d25f31d..a451c44 100644
--- a/include/linux/input/cy8c_ts.h
+++ b/include/linux/input/cy8c_ts.h
@@ -2,7 +2,7 @@
  * Cypress CY8CTMA300 Prototype touchscreen driver.
  *
  * Copyright (C) 2009, 2010 Cypress Semiconductor, Inc.
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. 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
diff --git a/include/linux/input/ft5x06_ts.h b/include/linux/input/ft5x06_ts.h
index b2fb3c4..a379d38 100644
--- a/include/linux/input/ft5x06_ts.h
+++ b/include/linux/input/ft5x06_ts.h
@@ -3,7 +3,7 @@
  * FocalTech ft5x06 TouchScreen driver header file.
  *
  * Copyright (c) 2010  Focal tech Ltd.
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/include/linux/input/kp_flip_switch.h b/include/linux/input/kp_flip_switch.h
index 31c0cc4..68c226b 100644
--- a/include/linux/input/kp_flip_switch.h
+++ b/include/linux/input/kp_flip_switch.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/input/mpu3050.h b/include/linux/input/mpu3050.h
index 6006abb..61a2920 100644
--- a/include/linux/input/mpu3050.h
+++ b/include/linux/input/mpu3050.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/input/pmic8xxx-keypad.h b/include/linux/input/pmic8xxx-keypad.h
index 5f1e2f9..4292328 100644
--- a/include/linux/input/pmic8xxx-keypad.h
+++ b/include/linux/input/pmic8xxx-keypad.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/input/pmic8xxx-pwrkey.h b/include/linux/input/pmic8xxx-pwrkey.h
index a32eafd..9230a75 100644
--- a/include/linux/input/pmic8xxx-pwrkey.h
+++ b/include/linux/input/pmic8xxx-pwrkey.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/input/qci_kbd.h b/include/linux/input/qci_kbd.h
index 5afda7d..20fd9e9 100644
--- a/include/linux/input/qci_kbd.h
+++ b/include/linux/input/qci_kbd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/input/synaptics_dsx.h b/include/linux/input/synaptics_dsx.h
new file mode 100644
index 0000000..56616d7
--- /dev/null
+++ b/include/linux/input/synaptics_dsx.h
@@ -0,0 +1,62 @@
+/*
+ * Synaptics RMI4 touchscreen driver
+ *
+ * Copyright (C) 2012 Synaptics Incorporated
+ *
+ * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
+ * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
+ * Copyright (c) 2013, The Linux Foundation. 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.
+ */
+
+#ifndef _SYNAPTICS_DSX_H_
+#define _SYNAPTICS_DSX_H_
+
+/*
+ * struct synaptics_rmi4_capacitance_button_map - 0d button map
+ * @nbuttons: number of buttons
+ * @map: button map
+ */
+struct synaptics_rmi4_capacitance_button_map {
+	unsigned char nbuttons;
+	unsigned char *map;
+};
+
+/*
+ * struct synaptics_rmi4_platform_data - rmi4 platform data
+ * @x_flip: x flip flag
+ * @y_flip: y flip flag
+ * @regulator_en: regulator enable flag
+ * @irq_gpio: attention interrupt gpio
+ * @irq_flags: flags used by the irq
+ * @reset_gpio: reset gpio
+ * @panel_x: panel maximum values on the x
+ * @panel_y: panel maximum values on the y
+ * @gpio_config: pointer to gpio configuration function
+ * @capacitance_button_map: pointer to 0d button map
+ */
+struct synaptics_rmi4_platform_data {
+	bool x_flip;
+	bool y_flip;
+	bool regulator_en;
+	bool i2c_pull_up;
+	unsigned irq_gpio;
+	u32 irq_flags;
+	u32 reset_flags;
+	unsigned reset_gpio;
+	unsigned panel_x;
+	unsigned panel_y;
+	int (*gpio_config)(unsigned gpio, bool configure);
+	struct synaptics_rmi4_capacitance_button_map *capacitance_button_map;
+};
+
+#endif
diff --git a/include/linux/input/tdisc_shinetsu.h b/include/linux/input/tdisc_shinetsu.h
index 88f84f2..973606a 100644
--- a/include/linux/input/tdisc_shinetsu.h
+++ b/include/linux/input/tdisc_shinetsu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 3af0c6b..7fee5ff 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -2,7 +2,7 @@
  * include/linux/ion.h
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h
index f28053c..8aa758d 100644
--- a/include/linux/iopoll.h
+++ b/include/linux/iopoll.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012 The Linux Foundation. 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 and
diff --git a/include/linux/ks8851.h b/include/linux/ks8851.h
index 6970f47..bfa4d3b 100644
--- a/include/linux/ks8851.h
+++ b/include/linux/ks8851.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/leds-msm-tricolor.h b/include/linux/leds-msm-tricolor.h
index 314645e..3302676 100644
--- a/include/linux/leds-msm-tricolor.h
+++ b/include/linux/leds-msm-tricolor.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/leds-pm8xxx.h b/include/linux/leds-pm8xxx.h
index a5959af..f643027 100644
--- a/include/linux/leds-pm8xxx.h
+++ b/include/linux/leds-pm8xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/include/linux/leds-pmic8058.h b/include/linux/leds-pmic8058.h
index cbfde9f..a4bf0ea 100644
--- a/include/linux/leds-pmic8058.h
+++ b/include/linux/leds-pmic8058.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/legacy_ion.h b/include/linux/legacy_ion.h
index a99a3e3..8dfdae1 100644
--- a/include/linux/legacy_ion.h
+++ b/include/linux/legacy_ion.h
@@ -2,7 +2,7 @@
  * include/linux/ion.h
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/include/linux/libra_sdioif.h b/include/linux/libra_sdioif.h
index 99b7d04..d1a42cc 100644
--- a/include/linux/libra_sdioif.h
+++ b/include/linux/libra_sdioif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, The Linux Foundation. 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 and
diff --git a/include/linux/m_adcproc.h b/include/linux/m_adcproc.h
index e36a90a..e7628b0 100644
--- a/include/linux/m_adcproc.h
+++ b/include/linux/m_adcproc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/memory_alloc.h b/include/linux/memory_alloc.h
index e7049f8..b649451 100644
--- a/include/linux/memory_alloc.h
+++ b/include/linux/memory_alloc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/marimba-codec.h b/include/linux/mfd/marimba-codec.h
index bfda146..2fbbc0e 100644
--- a/include/linux/mfd/marimba-codec.h
+++ b/include/linux/mfd/marimba-codec.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/marimba-tsadc.h b/include/linux/mfd/marimba-tsadc.h
index 6a05b43..247fedd 100644
--- a/include/linux/mfd/marimba-tsadc.h
+++ b/include/linux/mfd/marimba-tsadc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/marimba.h b/include/linux/mfd/marimba.h
index 32fe748..473d39b 100644
--- a/include/linux/mfd/marimba.h
+++ b/include/linux/mfd/marimba.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/batt-alarm.h b/include/linux/mfd/pm8xxx/batt-alarm.h
index f10715d..b266f3e 100644
--- a/include/linux/mfd/pm8xxx/batt-alarm.h
+++ b/include/linux/mfd/pm8xxx/batt-alarm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/batterydata-lib.h b/include/linux/mfd/pm8xxx/batterydata-lib.h
index c55e47e..62326ef 100644
--- a/include/linux/mfd/pm8xxx/batterydata-lib.h
+++ b/include/linux/mfd/pm8xxx/batterydata-lib.h
@@ -88,6 +88,8 @@
  *			readings from bms are not available.
  * @delta_rbatt_mohm:	the resistance to be added towards lower soc to
  *			compensate for battery capacitance.
+ * @rbatt_capacitve_mohm: the resistance to be added to compensate for
+ *				battery capacitance
  */
 
 struct bms_battery_data {
@@ -99,6 +101,7 @@
 	struct sf_lut		*rbatt_sf_lut;
 	int			default_rbatt_mohm;
 	int			delta_rbatt_mohm;
+	int			rbatt_capacitive_mohm;
 };
 
 #if defined(CONFIG_PM8921_BMS) || \
diff --git a/include/linux/mfd/pm8xxx/ccadc.h b/include/linux/mfd/pm8xxx/ccadc.h
index e4d5a67f..a29486f 100644
--- a/include/linux/mfd/pm8xxx/ccadc.h
+++ b/include/linux/mfd/pm8xxx/ccadc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -26,11 +26,15 @@
  * @ccadc_cdata:	core data for the ccadc driver containing channel info
  * @r_sense_uohm:		sense resistor value in (micro Ohms)
  * @calib_delay_ms:	how often should the adc calculate gain and offset
+ * @periodic_wakeup:	a flag to indicate that this system wakeups periodically
+ *			for calibration/other housekeeping activities. The ccadc
+ *			does a quick calibration while resuming
  */
 struct pm8xxx_ccadc_platform_data {
 	struct pm8xxx_ccadc_core_data	ccadc_cdata;
 	int				r_sense_uohm;
 	unsigned int			calib_delay_ms;
+	bool				periodic_wakeup;
 };
 
 #define CCADC_READING_RESOLUTION_N	542535
diff --git a/include/linux/mfd/pm8xxx/core.h b/include/linux/mfd/pm8xxx/core.h
index 38c589d..282593c 100644
--- a/include/linux/mfd/pm8xxx/core.h
+++ b/include/linux/mfd/pm8xxx/core.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/gpio.h b/include/linux/mfd/pm8xxx/gpio.h
index ccd9c10..333d13f 100644
--- a/include/linux/mfd/pm8xxx/gpio.h
+++ b/include/linux/mfd/pm8xxx/gpio.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/irq.h b/include/linux/mfd/pm8xxx/irq.h
index 78fbed3..9ae6fd4 100644
--- a/include/linux/mfd/pm8xxx/irq.h
+++ b/include/linux/mfd/pm8xxx/irq.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index c4b0ea4..fa97ba9 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/mpp.h b/include/linux/mfd/pm8xxx/mpp.h
index 2a934e5..90596f8 100644
--- a/include/linux/mfd/pm8xxx/mpp.h
+++ b/include/linux/mfd/pm8xxx/mpp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/nfc.h b/include/linux/mfd/pm8xxx/nfc.h
index e58e0a9..e4a495d 100644
--- a/include/linux/mfd/pm8xxx/nfc.h
+++ b/include/linux/mfd/pm8xxx/nfc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010,2011 The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/pm8018.h b/include/linux/mfd/pm8xxx/pm8018.h
index daacdd4..002623c 100644
--- a/include/linux/mfd/pm8xxx/pm8018.h
+++ b/include/linux/mfd/pm8xxx/pm8018.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/pm8038.h b/include/linux/mfd/pm8xxx/pm8038.h
index 9e25b5c..5c9219c 100644
--- a/include/linux/mfd/pm8xxx/pm8038.h
+++ b/include/linux/mfd/pm8xxx/pm8038.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/pm8821-irq.h b/include/linux/mfd/pm8xxx/pm8821-irq.h
index af985e6..4d9b8b8 100644
--- a/include/linux/mfd/pm8xxx/pm8821-irq.h
+++ b/include/linux/mfd/pm8xxx/pm8821-irq.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/pm8821.h b/include/linux/mfd/pm8xxx/pm8821.h
index 7ed7617..e5877ac 100644
--- a/include/linux/mfd/pm8xxx/pm8821.h
+++ b/include/linux/mfd/pm8xxx/pm8821.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -21,6 +21,7 @@
 #include <linux/device.h>
 #include <linux/mfd/pm8xxx/pm8821-irq.h>
 #include <linux/mfd/pm8xxx/mpp.h>
+#include <linux/mfd/pm8xxx/tm.h>
 
 #define PM8821_NR_IRQS		(112)
 #define PM8821_NR_MPPS		(4)
@@ -38,6 +39,8 @@
 		PM8821_IRQ_BLOCK_BIT(PM8821_MPP_BLOCK_START, (mpp)-1))
 
 /* PMIC Interrupts */
+#define PM8821_OVERTEMP_IRQ		PM8821_IRQ_BLOCK_BIT(5, 2)
+#define PM8821_TEMPSTAT_IRQ		PM8821_IRQ_BLOCK_BIT(5, 7)
 
 struct pm8821_platform_data {
 	int					irq_base;
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 12214d9..a19c0b6 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -41,6 +41,19 @@
  *				voltage higher than cutoff voltage
  * @low_voltage_calc_ms:	The period of soc calculation in ms when battery
  *				voltage is near cutoff voltage
+ * @disable_flat_portion_ocv:	feature to disable ocv updates while in sleep
+ * @ocv_dis_high_soc:		the high soc percent when ocv should be disabled
+ * @ocv_dis_low_soc:		the low soc percent when ocv should be enabled
+ * @low_voltage_detect:		feature to enable 0 SOC reporting on low volatge
+ * @vbatt_cutoff_retries:	number of tries before we report a 0 SOC
+ * @high_ocv_correction_limit_uv:	the max amount of OCV corrections
+ *					allowed when ocv is high
+ *					(higher than 3.8V)
+ * @low_ocv_correction_limit_uv:	the max amount of OCV corrections
+ *					allowed when ocv is low
+ *					(lower or equal to 3.8V)
+ * @hold_soc_est:		the min est soc below which the calculated soc
+ *				is allowed to go to 0%
  */
 struct pm8921_bms_platform_data {
 	struct pm8xxx_bms_core_data	bms_cdata;
@@ -50,6 +63,8 @@
 	unsigned int			v_cutoff;
 	unsigned int			max_voltage_uv;
 	unsigned int			rconn_mohm;
+	unsigned int			alarm_low_mv;
+	unsigned int			alarm_high_mv;
 	int				enable_fcc_learning;
 	int				shutdown_soc_valid_limit;
 	int				ignore_shutdown_soc;
@@ -57,6 +72,14 @@
 	int				chg_term_ua;
 	int				normal_voltage_calc_ms;
 	int				low_voltage_calc_ms;
+	int				disable_flat_portion_ocv;
+	int				ocv_dis_high_soc;
+	int				ocv_dis_low_soc;
+	int				low_voltage_detect;
+	int				vbatt_cutoff_retries;
+	int				high_ocv_correction_limit_uv;
+	int				low_ocv_correction_limit_uv;
+	int				hold_soc_est;
 };
 
 #if defined(CONFIG_PM8921_BMS) || defined(CONFIG_PM8921_BMS_MODULE)
@@ -144,6 +167,19 @@
  *			value upon wakeup from sleep.
  */
 int pm8921_bms_cc_uah(int *cc_uah);
+
+/**
+ * pm8921_bms_battery_removed -	function to be called to tell the bms that
+ *			the battery is removed. The bms resets its internal
+ *			history data used to report soc.
+ */
+void pm8921_bms_battery_removed(void);
+/**
+ * pm8921_bms_battery_inseted -	function to be called to tell the bms that
+ *			the battery was inserted. The bms initiates calculations
+ *			for reporting soc.
+ */
+void pm8921_bms_battery_inserted(void);
 #else
 static inline int pm8921_bms_get_vsense_avg(int *result)
 {
@@ -190,6 +226,8 @@
 {
 	return -ENXIO;
 }
+static inline void pm8921_bms_battery_removed(void) {}
+static inline void pm8921_bms_battery_inserted(void) {}
 #endif
 
 #endif
diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h
index ab52309..5439fd1 100644
--- a/include/linux/mfd/pm8xxx/pm8921-charger.h
+++ b/include/linux/mfd/pm8xxx/pm8921-charger.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -165,6 +165,7 @@
 	unsigned int			warm_bat_chg_current;
 	unsigned int			cool_bat_voltage;
 	unsigned int			warm_bat_voltage;
+	int				hysteresis_temp;
 	unsigned int			(*get_batt_capacity_percent) (void);
 	int64_t				batt_id_min;
 	int64_t				batt_id_max;
@@ -188,6 +189,7 @@
 	int				btc_delay_ms;
 	int				btc_panic_if_cant_stop_chg;
 	int				stop_chg_upon_expiry;
+	bool				disable_chg_rmvl_wrkarnd;
 };
 
 enum pm8921_charger_source {
diff --git a/include/linux/mfd/pm8xxx/pm8921.h b/include/linux/mfd/pm8xxx/pm8921.h
index 92bb94b..aabbb21 100644
--- a/include/linux/mfd/pm8xxx/pm8921.h
+++ b/include/linux/mfd/pm8xxx/pm8921.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/pm8xxx-adc.h b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
index 84f8e03..f40633a 100644
--- a/include/linux/mfd/pm8xxx/pm8xxx-adc.h
+++ b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/pwm.h b/include/linux/mfd/pm8xxx/pwm.h
index 09b165e..6d95e3a 100644
--- a/include/linux/mfd/pm8xxx/pwm.h
+++ b/include/linux/mfd/pm8xxx/pwm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/regulator.h b/include/linux/mfd/pm8xxx/regulator.h
index 83492d2..31c2684 100644
--- a/include/linux/mfd/pm8xxx/regulator.h
+++ b/include/linux/mfd/pm8xxx/regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/rtc.h b/include/linux/mfd/pm8xxx/rtc.h
index bb3f98a..2ce37a0 100644
--- a/include/linux/mfd/pm8xxx/rtc.h
+++ b/include/linux/mfd/pm8xxx/rtc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/spk.h b/include/linux/mfd/pm8xxx/spk.h
index 2905a1d..9835b85 100644
--- a/include/linux/mfd/pm8xxx/spk.h
+++ b/include/linux/mfd/pm8xxx/spk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/tm.h b/include/linux/mfd/pm8xxx/tm.h
index 6974754..74b77ec 100644
--- a/include/linux/mfd/pm8xxx/tm.h
+++ b/include/linux/mfd/pm8xxx/tm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -22,21 +22,55 @@
 
 #define PM8XXX_TM_DEV_NAME	"pm8xxx-tm"
 
+/**
+ * enum pm8xxx_tm_adc_type - support ADC API types for PMIC thermal manager
+ * %PM8XXX_TM_ADC_NONE:		Do not call any ADC API and instead estimate
+ *				PMIC temerature based on over temperature stage.
+ * %PM8XXX_TM_ADC_PM8058_ADC:	Use the pmic8058-xoadc ADC API
+ * %PM8XXX_TM_ADC_PM8XXX_ADC:	Use the pm8xxx-adc ADC API
+ */
 enum pm8xxx_tm_adc_type {
-	PM8XXX_TM_ADC_NONE,	/* Estimates temp based on overload level. */
+	PM8XXX_TM_ADC_NONE,
 	PM8XXX_TM_ADC_PM8058_ADC,
 	PM8XXX_TM_ADC_PM8XXX_ADC,
 };
 
+/**
+ * struct pm8xxx_tm_core_data - PM8XXX thermal manager core data
+ * @tm_name:			Thermal zone name for the device
+ * @irq_name_temp_stat:		String name used to identify TEMP_STAT IRQ
+ * @irq_name_over_temp:		String name used to identify OVER_TEMP IRQ
+ * @reg_addr_temp_alarm_ctrl:	PMIC SSBI address for temp alarm control
+ *				register
+ * @reg_addr_temp_alarm_pwm:	PMIC SSBI address for temp alarm pwm register
+ * @adc_type:			Determines which ADC API to use in order to read
+ *				the PMIC die temperature.
+ * @adc_channel:		ADC channel identifier
+ *				If adc_type == PM8XXX_TM_ADC_PM8XXX_ADC, then
+ *				use a value from enum pm8xxx_adc_channels.
+ *				If adc_type == PM8XXX_TM_ADC_PM8058_ADC, then
+ *				use a channel value specified in
+ *				<linux/pmic8058-xoadc.h>
+ * @default_no_adc_temp:	Default temperature in millicelcius to report
+ *				while stage == 0 and stage has never been
+ *				greater than 0 if adc_type == PM8XXX_TM_ADC_NONE
+ * @allow_software_override:	true --> writing "enabled" to thermalfs mode
+ *				file results in software override of PMIC
+ *				automatic over temperature shutdown
+ *				false --> PMIC automatic over temperature
+ *				shutdown always enabled.  mode file cannot be
+ *				set to "enabled".
+ */
 struct pm8xxx_tm_core_data {
-	int				adc_channel;
-	unsigned long			default_no_adc_temp;
-	enum pm8xxx_tm_adc_type		adc_type;
-	u16				reg_addr_temp_alarm_ctrl;
-	u16				reg_addr_temp_alarm_pwm;
-	char				*tm_name;
-	char				*irq_name_temp_stat;
-	char				*irq_name_over_temp;
+	char			*tm_name;
+	char			*irq_name_temp_stat;
+	char			*irq_name_over_temp;
+	u16			reg_addr_temp_alarm_ctrl;
+	u16			reg_addr_temp_alarm_pwm;
+	enum pm8xxx_tm_adc_type	adc_type;
+	int			adc_channel;
+	unsigned long		default_no_adc_temp;
+	bool			allow_software_override;
 };
 
 #endif
diff --git a/include/linux/mfd/pm8xxx/upl.h b/include/linux/mfd/pm8xxx/upl.h
index b0e94a9..6a315ab 100644
--- a/include/linux/mfd/pm8xxx/upl.h
+++ b/include/linux/mfd/pm8xxx/upl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010,2011 The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pm8xxx/vibrator.h b/include/linux/mfd/pm8xxx/vibrator.h
index cfea1c9..3594bb0 100644
--- a/include/linux/mfd/pm8xxx/vibrator.h
+++ b/include/linux/mfd/pm8xxx/vibrator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pmic8058.h b/include/linux/mfd/pmic8058.h
index ff7a329..19e783f 100644
--- a/include/linux/mfd/pmic8058.h
+++ b/include/linux/mfd/pmic8058.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/pmic8901.h b/include/linux/mfd/pmic8901.h
index f5b34be..bf64bec 100644
--- a/include/linux/mfd/pmic8901.h
+++ b/include/linux/mfd/pmic8901.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/tps65023.h b/include/linux/mfd/tps65023.h
index 4cce091..b6ad6e5 100644
--- a/include/linux/mfd/tps65023.h
+++ b/include/linux/mfd/tps65023.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index f6d164d..f83187d 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -129,6 +129,7 @@
 	struct mutex io_lock;
 	struct mutex xfer_lock;
 	struct mutex irq_lock;
+	struct mutex nested_irq_lock;
 	u8 version;
 
 	unsigned int irq_base;
@@ -177,6 +178,8 @@
 
 bool wcd9xxx_lock_sleep(struct wcd9xxx *wcd9xxx);
 void wcd9xxx_unlock_sleep(struct wcd9xxx *wcd9xxx);
+void wcd9xxx_nested_irq_lock(struct wcd9xxx *wcd9xxx);
+void wcd9xxx_nested_irq_unlock(struct wcd9xxx *wcd9xxx);
 enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg(struct wcd9xxx *wcd9xxx,
 				enum wcd9xxx_pm_state o,
 				enum wcd9xxx_pm_state n);
diff --git a/include/linux/mfd/wcd9xxx/pdata.h b/include/linux/mfd/wcd9xxx/pdata.h
index e831f0b..5055a7f 100644
--- a/include/linux/mfd/wcd9xxx/pdata.h
+++ b/include/linux/mfd/wcd9xxx/pdata.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/wcd9xxx/wcd9304_registers.h b/include/linux/mfd/wcd9xxx/wcd9304_registers.h
index f7c483c..a7f9e4a 100644
--- a/include/linux/mfd/wcd9xxx/wcd9304_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9304_registers.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -409,114 +409,163 @@
 #define SITAR_A_CDC_ANC1_SMLPF_CTL__POR			(0x00000000)
 #define SITAR_A_CDC_ANC1_DCFLT_CTL			(0x20B)
 #define SITAR_A_CDC_ANC1_DCFLT_CTL__POR			(0x00000000)
-#define SITAR_A_CDC_TX1_VOL_CTL_TIMER			(0x220)
-#define SITAR_A_CDC_TX1_VOL_CTL_TIMER__POR			(0x00000000)
-#define SITAR_A_CDC_TX1_VOL_CTL_GAIN			(0x221)
-#define SITAR_A_CDC_TX1_VOL_CTL_GAIN__POR			(0x00000000)
-#define SITAR_A_CDC_TX2_VOL_CTL_GAIN			(0x229)
-#define SITAR_A_CDC_TX2_VOL_CTL_GAIN__POR			   (0x00000000)
-#define SITAR_A_CDC_TX3_VOL_CTL_GAIN			(0x231)
-#define SITAR_A_CDC_TX3_VOL_CTL_GAIN__POR			   (0x00000000)
-#define SITAR_A_CDC_TX4_VOL_CTL_GAIN			(0x239)
-#define SITAR_A_CDC_TX4_VOL_CTL_GAIN__POR			   (0x00000000)
-#define SITAR_A_CDC_TX5_VOL_CTL_GAIN			(0x241)
-#define SITAR_A_CDC_TX5_VOL_CTL_GAIN__POR			   (0x00000000)
-#define SITAR_A_CDC_TX1_VOL_CTL_CFG			 (0x222)
-#define SITAR_A_CDC_TX1_VOL_CTL_CFG__POR			    (0x00000000)
-#define SITAR_A_CDC_TX2_VOL_CTL_CFG			 (0x22A)
-#define SITAR_A_CDC_TX2_VOL_CTL_CFG__POR			    (0x00000000)
-#define SITAR_A_CDC_TX3_VOL_CTL_CFG			 (0x232)
-#define SITAR_A_CDC_TX3_VOL_CTL_CFG__POR			    (0x00000000)
-#define SITAR_A_CDC_TX4_VOL_CTL_CFG			 (0x23A)
-#define SITAR_A_CDC_TX4_VOL_CTL_CFG__POR			    (0x00000000)
+#define SITAR_A_CDC_ANC2_CTL			(0x280)
+#define SITAR_A_CDC_ANC2_CTL__POR			(0x00000000)
+#define SITAR_A_CDC_ANC2_SHIFT			(0x281)
+#define SITAR_A_CDC_ANC2_SHIFT__POR			(0x00000000)
+#define SITAR_A_CDC_ANC2_IIR_B1_CTL		(0x282)
+#define SITAR_A_CDC_ANC2_IIR_B1_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_ANC2_IIR_B2_CTL		(0x283)
+#define SITAR_A_CDC_ANC2_IIR_B2_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_ANC2_IIR_B3_CTL		(0x284)
+#define SITAR_A_CDC_ANC2_IIR_B3_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_ANC2_IIR_B4_CTL		(0x285)
+#define SITAR_A_CDC_ANC2_IIR_B4_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_ANC2_LPF_B1_CTL		(0x286)
+#define SITAR_A_CDC_ANC2_LPF_B1_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_ANC2_LPF_B2_CTL		(0x287)
+#define SITAR_A_CDC_ANC2_LPF_B2_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_ANC2_LPF_B3_CTL		(0x288)
+#define SITAR_A_CDC_ANC2_LPF_B3_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_ANC2_SPARE			(0x289)
+#define SITAR_A_CDC_ANC2_SPARE__POR			(0x00000000)
+#define SITAR_A_CDC_ANC2_SMLPF_CTL		(0x28A)
+#define SITAR_A_CDC_ANC2_SMLPF_CTL__POR			(0x00000000)
+#define SITAR_A_CDC_ANC2_DCFLT_CTL		(0x28B)
+#define SITAR_A_CDC_ANC2_DCFLT_CTL__POR			(0x00000000)
 
+#define SITAR_A_CDC_TX1_VOL_CTL_TIMER		(0x220)
+#define SITAR_A_CDC_TX1_VOL_CTL_TIMER__POR		(0x00000000)
+#define SITAR_A_CDC_TX1_VOL_CTL_GAIN		(0x221)
+#define SITAR_A_CDC_TX1_VOL_CTL_GAIN__POR		(0x00000000)
+#define SITAR_A_CDC_TX1_VOL_CTL_CFG		(0x222)
+#define SITAR_A_CDC_TX1_VOL_CTL_CFG__POR		(0x00000000)
 #define SITAR_A_CDC_TX1_MUX_CTL			(0x223)
 #define SITAR_A_CDC_TX1_MUX_CTL__POR			(0x00000008)
-#define SITAR_A_CDC_TX1_CLK_FS_CTL                      (0x00000224)
-#define SITAR_A_CDC_TX1_CLK_FS_CTL__POR                 (0x00000003)
-#define SITAR_A_CDC_TX2_CLK_FS_CTL                      (0x0000022C)
-#define SITAR_A_CDC_TX2_CLK_FS_CTL__POR                 (0x00000003)
-#define SITAR_A_CDC_TX3_CLK_FS_CTL                      (0x00000234)
-#define SITAR_A_CDC_TX3_CLK_FS_CTL__POR                 (0x00000003)
-#define SITAR_A_CDC_TX4_CLK_FS_CTL                      (0x0000023C)
-#define SITAR_A_CDC_TX4_CLK_FS_CTL__POR                 (0x00000003)
-#define SITAR_A_CDC_TX1_DMIC_CTL			(0x225)
+#define SITAR_A_CDC_TX1_CLK_FS_CTL		(0x224)
+#define SITAR_A_CDC_TX1_CLK_FS_CTL__POR			(0x00000003)
+#define SITAR_A_CDC_TX1_DMIC_CTL		(0x225)
 #define SITAR_A_CDC_TX1_DMIC_CTL__POR			(0x00000000)
-#define SITAR_A_CDC_TX2_MUX_CTL                 (0x22B)
+
+#define SITAR_A_CDC_TX2_VOL_CTL_TIMER		(0x228)
+#define SITAR_A_CDC_TX2_VOL_CTL_TIMER__POR		(0x00000000)
+#define SITAR_A_CDC_TX2_VOL_CTL_GAIN		(0x229)
+#define SITAR_A_CDC_TX2_VOL_CTL_GAIN__POR		(0x00000000)
+#define SITAR_A_CDC_TX2_VOL_CTL_CFG		(0x22A)
+#define SITAR_A_CDC_TX2_VOL_CTL_CFG__POR		(0x00000000)
+#define SITAR_A_CDC_TX2_MUX_CTL			(0x22B)
 #define SITAR_A_CDC_TX2_MUX_CTL__POR			(0x00000008)
-#define SITAR_A_CDC_TX3_MUX_CTL                 (0x233)
+#define SITAR_A_CDC_TX2_CLK_FS_CTL		(0x22C)
+#define SITAR_A_CDC_TX2_CLK_FS_CTL__POR			(0x00000003)
+#define SITAR_A_CDC_TX2_DMIC_CTL		(0x22D)
+#define SITAR_A_CDC_TX2_DMIC_CTL__POR			(0x00000000)
+
+#define SITAR_A_CDC_TX3_VOL_CTL_TIMER		(0x230)
+#define SITAR_A_CDC_TX3_VOL_CTL_TIMER__POR		(0x00000000)
+#define SITAR_A_CDC_TX3_VOL_CTL_GAIN		(0x231)
+#define SITAR_A_CDC_TX3_VOL_CTL_GAIN__POR		(0x00000000)
+#define SITAR_A_CDC_TX3_VOL_CTL_CFG		(0x232)
+#define SITAR_A_CDC_TX3_VOL_CTL_CFG__POR		(0x00000000)
+#define SITAR_A_CDC_TX3_MUX_CTL			(0x233)
 #define SITAR_A_CDC_TX3_MUX_CTL__POR			(0x00000008)
-#define SITAR_A_CDC_TX4_MUX_CTL                 (0x23B)
+#define SITAR_A_CDC_TX3_CLK_FS_CTL		(0x234)
+#define SITAR_A_CDC_TX3_CLK_FS_CTL__POR			(0x00000003)
+#define SITAR_A_CDC_TX3_DMIC_CTL		(0x235)
+#define SITAR_A_CDC_TX3_DMIC_CTL__POR			(0x00000000)
+
+#define SITAR_A_CDC_TX4_VOL_CTL_TIMER		(0x239)
+#define SITAR_A_CDC_TX4_VOL_CTL_TIMER__POR		(0x00000000)
+#define SITAR_A_CDC_TX4_VOL_CTL_GAIN		(0x23A)
+#define SITAR_A_CDC_TX4_VOL_CTL_GAIN__POR		(0x00000000)
+#define SITAR_A_CDC_TX4_VOL_CTL_CFG		(0x23B)
+#define SITAR_A_CDC_TX4_VOL_CTL_CFG__POR		(0x00000000)
+#define SITAR_A_CDC_TX4_MUX_CTL			(0x23C)
 #define SITAR_A_CDC_TX4_MUX_CTL__POR			(0x00000008)
-#define SITAR_A_CDC_TX5_MUX_CTL                 (0x243)
+#define SITAR_A_CDC_TX4_CLK_FS_CTL		(0x23D)
+#define SITAR_A_CDC_TX4_CLK_FS_CTL__POR			(0x00000003)
+#define SITAR_A_CDC_TX4_DMIC_CTL		(0x23E)
+#define SITAR_A_CDC_TX4_DMIC_CTL__POR			(0x00000000)
+
+#define SITAR_A_CDC_TX5_VOL_CTL_TIMER		(0x240)
+#define SITAR_A_CDC_TX5_VOL_CTL_TIMER__POR		(0x00000000)
+#define SITAR_A_CDC_TX5_VOL_CTL_GAIN		(0x241)
+#define SITAR_A_CDC_TX5_VOL_CTL_GAIN__POR		(0x00000000)
+#define SITAR_A_CDC_TX5_VOL_CTL_CFG		(0x242)
+#define SITAR_A_CDC_TX5_VOL_CTL_CFG__POR		(0x00000000)
+#define SITAR_A_CDC_TX5_MUX_CTL			(0x243)
 #define SITAR_A_CDC_TX5_MUX_CTL__POR			(0x00000008)
+#define SITAR_A_CDC_TX5_CLK_FS_CTL		(0x244)
+#define SITAR_A_CDC_TX5_CLK_FS_CTL__POR			(0x00000003)
+#define SITAR_A_CDC_TX5_DMIC_CTL		(0x245)
+#define SITAR_A_CDC_TX5_DMIC_CTL__POR			(0x00000000)
 
 #define SITAR_A_CDC_SRC1_PDA_CFG			(0x2A0)
 #define SITAR_A_CDC_SRC1_PDA_CFG__POR			(0x00000000)
 #define SITAR_A_CDC_SRC1_FS_CTL			(0x2A1)
 #define SITAR_A_CDC_SRC1_FS_CTL__POR			(0x0000001b)
+#define SITAR_A_CDC_SRC2_PDA_CFG		(0x2A8)
+#define SITAR_A_CDC_SRC2_PDA_CFG__POR			(0x00000000)
+#define SITAR_A_CDC_SRC2_FS_CTL			(0x2A9)
+#define SITAR_A_CDC_SRC2_FS_CTL__POR			(0x0000001b)
 
-#define SITAR_A_CDC_RX1_B1_CTL                  (0x000002B0)
+#define SITAR_A_CDC_RX1_B1_CTL                  (0x2B0)
 #define SITAR_A_CDC_RX1_B1_CTL__POR			 (0x00000000)
-#define SITAR_A_CDC_RX2_B1_CTL                  (0x000002B8)
-#define SITAR_A_CDC_RX2_B1_CTL__POR			 (0x00000000)
-#define SITAR_A_CDC_RX3_B1_CTL                  (0x000002C0)
-#define SITAR_A_CDC_RX3_B1_CTL__POR			 (0x00000000)
-
-#define SITAR_A_CDC_RX1_B2_CTL                  (0x000002B1)
+#define SITAR_A_CDC_RX1_B2_CTL                  (0x2B1)
 #define SITAR_A_CDC_RX1_B2_CTL__POR			 (0x00000000)
-#define SITAR_A_CDC_RX2_B2_CTL                  (0x000002B9)
-#define SITAR_A_CDC_RX2_B2_CTL__POR			 (0x00000000)
-#define SITAR_A_CDC_RX3_B2_CTL                  (0x000002C1)
-#define SITAR_A_CDC_RX3_B2_CTL__POR			 (0x00000000)
-
-#define SITAR_A_CDC_RX1_B3_CTL                  (0x000002B2)
+#define SITAR_A_CDC_RX1_B3_CTL                  (0x2B2)
 #define SITAR_A_CDC_RX1_B3_CTL__POR			 (0x00000000)
-#define SITAR_A_CDC_RX2_B3_CTL                  (0x000002BA)
-#define SITAR_A_CDC_RX2_B3_CTL__POR			 (0x00000000)
-#define SITAR_A_CDC_RX3_B3_CTL                  (0x000002C2)
-#define SITAR_A_CDC_RX3_B3_CTL__POR			 (0x00000000)
-
-#define SITAR_A_CDC_RX1_B4_CTL                  (0x000002B3)
+#define SITAR_A_CDC_RX1_B4_CTL                  (0x2B3)
 #define SITAR_A_CDC_RX1_B4_CTL__POR			 (0x00000000)
-#define SITAR_A_CDC_RX2_B4_CTL                  (0x000002BB)
-#define SITAR_A_CDC_RX2_B4_CTL__POR			 (0x00000000)
-#define SITAR_A_CDC_RX3_B4_CTL                  (0x000002C3)
-#define SITAR_A_CDC_RX3_B4_CTL__POR			 (0x00000000)
-
-#define SITAR_A_CDC_RX1_B5_CTL                  (0x000002B4)
+#define SITAR_A_CDC_RX1_B5_CTL                  (0x2B4)
 #define SITAR_A_CDC_RX1_B5_CTL__POR			 (0x00000078)
-#define SITAR_A_CDC_RX2_B5_CTL                  (0x000002BC)
-#define SITAR_A_CDC_RX2_B5_CTL__POR			 (0x00000078)
-#define SITAR_A_CDC_RX3_B5_CTL                  (0x000002C4)
-#define SITAR_A_CDC_RX3_B5_CTL__POR			 (0x00000078)
-
-#define SITAR_A_CDC_RX1_B6_CTL                  (0x000002B5)
+#define SITAR_A_CDC_RX1_B6_CTL                  (0x2B5)
 #define SITAR_A_CDC_RX1_B6_CTL__POR			 (0x00000080)
-#define SITAR_A_CDC_RX2_B6_CTL                  (0x000002BD)
+#define SITAR_A_CDC_RX1_VOL_CTL_B1_CTL		(0x2B6)
+#define SITAR_A_CDC_RX1_VOL_CTL_B1_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_RX1_VOL_CTL_B2_CTL		(0x2B7)
+#define SITAR_A_CDC_RX1_VOL_CTL_B2_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_RX2_B1_CTL                  (0x2B8)
+#define SITAR_A_CDC_RX2_B1_CTL__POR			 (0x00000000)
+#define SITAR_A_CDC_RX2_B2_CTL                  (0x2B9)
+#define SITAR_A_CDC_RX2_B2_CTL__POR			 (0x00000000)
+#define SITAR_A_CDC_RX2_B3_CTL                  (0x2BA)
+#define SITAR_A_CDC_RX2_B3_CTL__POR			 (0x00000000)
+#define SITAR_A_CDC_RX2_B4_CTL                  (0x2BB)
+#define SITAR_A_CDC_RX2_B4_CTL__POR			 (0x00000000)
+#define SITAR_A_CDC_RX2_B5_CTL                  (0x2BC)
+#define SITAR_A_CDC_RX2_B5_CTL__POR			 (0x00000078)
+#define SITAR_A_CDC_RX2_B6_CTL                  (0x2BD)
 #define SITAR_A_CDC_RX2_B6_CTL__POR			 (0x00000080)
-#define SITAR_A_CDC_RX3_B6_CTL                  (0x000002C5)
+#define SITAR_A_CDC_RX2_VOL_CTL_B1_CTL		(0x2BE)
+#define SITAR_A_CDC_RX2_VOL_CTL_B1_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_RX2_VOL_CTL_B2_CTL		(0x2BF)
+#define SITAR_A_CDC_RX2_VOL_CTL_B2_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_RX3_B1_CTL                  (0x2C0)
+#define SITAR_A_CDC_RX3_B1_CTL__POR			 (0x00000000)
+#define SITAR_A_CDC_RX3_B2_CTL                  (0x2C1)
+#define SITAR_A_CDC_RX3_B2_CTL__POR			 (0x00000000)
+#define SITAR_A_CDC_RX3_B3_CTL                  (0x2C2)
+#define SITAR_A_CDC_RX3_B3_CTL__POR			 (0x00000000)
+#define SITAR_A_CDC_RX3_B4_CTL                  (0x2C3)
+#define SITAR_A_CDC_RX3_B4_CTL__POR			 (0x00000000)
+#define SITAR_A_CDC_RX3_B5_CTL                  (0x2C4)
+#define SITAR_A_CDC_RX3_B5_CTL__POR			 (0x00000078)
+#define SITAR_A_CDC_RX3_B6_CTL                  (0x2C5)
 #define SITAR_A_CDC_RX3_B6_CTL__POR			 (0x00000080)
+#define SITAR_A_CDC_RX3_VOL_CTL_B1_CTL		(0x2C6)
+#define SITAR_A_CDC_RX3_VOL_CTL_B1_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_RX3_VOL_CTL_B2_CTL		(0x2C7)
+#define SITAR_A_CDC_RX3_VOL_CTL_B2_CTL__POR		(0x00000000)
 
-
-#define SITAR_A_CDC_RX1_VOL_CTL_B1_CTL			(0x2B6)
-#define SITAR_A_CDC_RX1_VOL_CTL_B1_CTL__POR			(0x00000000)
-#define SITAR_A_CDC_RX1_VOL_CTL_B2_CTL			(0x2B7)
-#define SITAR_A_CDC_RX1_VOL_CTL_B2_CTL__POR			(0x00000000)
-#define SITAR_A_CDC_RX2_VOL_CTL_B2_CTL                  (0x2BF)
-#define SITAR_A_CDC_RX2_VOL_CTL_B2_CTL__POR                     (0x00000000)
-#define SITAR_A_CDC_RX3_VOL_CTL_B2_CTL			(0x2C7)
-#define SITAR_A_CDC_RX3_VOL_CTL_B2_CTL__POR                     (0x00000000)
-
-#define SITAR_A_CDC_CLK_ANC_RESET_CTL			(0x300)
-#define SITAR_A_CDC_CLK_ANC_RESET_CTL__POR			(0x00000000)
-#define SITAR_A_CDC_CLK_RX_RESET_CTL			(0x301)
-#define SITAR_A_CDC_CLK_RX_RESET_CTL__POR			(0x00000000)
-#define SITAR_A_CDC_CLK_TX_RESET_B1_CTL			(0x302)
-#define SITAR_A_CDC_CLK_TX_RESET_B1_CTL__POR			(0x00000000)
-#define SITAR_A_CDC_CLK_TX_RESET_B2_CTL			(0x303)
-#define SITAR_A_CDC_CLK_TX_RESET_B2_CTL__POR			(0x00000000)
-#define SITAR_A_CDC_CLK_DMIC_CTL			(0x304)
+#define SITAR_A_CDC_CLK_ANC_RESET_CTL		(0x300)
+#define SITAR_A_CDC_CLK_ANC_RESET_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_CLK_RX_RESET_CTL		(0x301)
+#define SITAR_A_CDC_CLK_RX_RESET_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_CLK_TX_RESET_B1_CTL		(0x302)
+#define SITAR_A_CDC_CLK_TX_RESET_B1_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_CLK_TX_RESET_B2_CTL		(0x303)
+#define SITAR_A_CDC_CLK_TX_RESET_B2_CTL__POR		(0x00000000)
+#define SITAR_A_CDC_CLK_DMIC_CTL		(0x304)
 #define SITAR_A_CDC_CLK_DMIC_CTL__POR			(0x00000000)
 #define SITAR_A_CDC_CLK_RX_I2S_CTL			(0x305)
 #define SITAR_A_CDC_CLK_RX_I2S_CTL__POR			(0x00000003)
@@ -654,7 +703,23 @@
 #define SITAR_A_CDC_COMP1_SHUT_DOWN_STATUS__POR		(0x00000003)
 #define SITAR_A_CDC_COMP1_FS_CFG			(0x377)
 #define SITAR_A_CDC_COMP1_FS_CFG__POR			(0x0000001b)
-#define SITAR_A_CDC_CONN_RX1_B1_CTL			(0x380)
+#define SITAR_A_CDC_COMP2_B1_CTL		(0x378)
+#define SITAR_A_CDC_COMP2_B1_CTL__POR			(0x00000030)
+#define SITAR_A_CDC_COMP2_B2_CTL		(0x379)
+#define SITAR_A_CDC_COMP2_B2_CTL__POR			(0x000000b5)
+#define SITAR_A_CDC_COMP2_B3_CTL		(0x37A)
+#define SITAR_A_CDC_COMP2_B3_CTL__POR			(0x00000028)
+#define SITAR_A_CDC_COMP2_B4_CTL		(0x37B)
+#define SITAR_A_CDC_COMP2_B4_CTL__POR			(0x0000003c)
+#define SITAR_A_CDC_COMP2_B5_CTL		(0x37C)
+#define SITAR_A_CDC_COMP2_B5_CTL__POR			(0x0000001f)
+#define SITAR_A_CDC_COMP2_B6_CTL		(0x37D)
+#define SITAR_A_CDC_COMP2_B6_CTL__POR			(0x00000000)
+#define SITAR_A_CDC_COMP2_SHUT_DOWN_STATUS	(0x37E)
+#define SITAR_A_CDC_COMP2_SHUT_DOWN_STATUS__POR		(0x00000003)
+#define SITAR_A_CDC_COMP2_FS_CFG		(0x37F)
+#define SITAR_A_CDC_COMP2_FS_CFG__POR			(0x0000001b)
+#define SITAR_A_CDC_CONN_RX1_B1_CTL		(0x380)
 #define SITAR_A_CDC_CONN_RX1_B1_CTL__POR		(0x00000000)
 #define SITAR_A_CDC_CONN_RX1_B2_CTL			(0x381)
 #define SITAR_A_CDC_CONN_RX1_B2_CTL__POR		(0x00000000)
diff --git a/include/linux/mfd/wcd9xxx/wcd9320_registers.h b/include/linux/mfd/wcd9xxx/wcd9320_registers.h
index 5725e6e..9a20397 100644
--- a/include/linux/mfd/wcd9xxx/wcd9320_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9320_registers.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
index 0d5d058..2b033d0 100644
--- a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
+++ b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h b/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h
index c66e953..73dda8f 100644
--- a/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9xxx_registers.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/mhl_8334.h b/include/linux/mhl_8334.h
index 1b19103..c654c08 100644
--- a/include/linux/mhl_8334.h
+++ b/include/linux/mhl_8334.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/mhl_defs.h b/include/linux/mhl_defs.h
index 094874e..9e85f07 100644
--- a/include/linux/mhl_defs.h
+++ b/include/linux/mhl_defs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/mhl_devcap.h b/include/linux/mhl_devcap.h
index 6d01daf..40a87fe 100644
--- a/include/linux/mhl_devcap.h
+++ b/include/linux/mhl_devcap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 8b6b0c1..e592709 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -233,34 +233,37 @@
 /**
  * struct mmc_bkops_info - BKOPS data
  * @dw:	Idle time bkops delayed work
- * @host_suspend_tout_ms:	The host controller idle time,
- * before getting into suspend
+ * @host_delay_ms:	The host controller time to start bkops
  * @delay_ms:	The time to start the BKOPS
  *        delayed work once MMC thread is idle
+ * @min_sectors_to_queue_delayed_work: the changed
+ *        number of sectors that should issue check for BKOPS
+ *        need
+ * @size_percentage_to_queue_delayed_work: the changed
+ *        percentage of sectors that should issue check for
+ *        BKOPS need
  * @poll_for_completion:	Poll on BKOPS completion
  * @cancel_delayed_work: A flag to indicate if the delayed work
  *        should be cancelled
- * @started_delayed_bkops:  A flag to indicate if the delayed
- *        work was scheduled
  * @sectors_changed:  number of  sectors written or
  *       discard since the last idle BKOPS were scheduled
  */
 struct mmc_bkops_info {
 	struct delayed_work	dw;
-	unsigned int		host_suspend_tout_ms;
+	unsigned int		host_delay_ms;
 	unsigned int		delay_ms;
 	unsigned int		min_sectors_to_queue_delayed_work;
+	unsigned int		size_percentage_to_queue_delayed_work;
 /*
  * A default time for checking the need for non urgent BKOPS once mmcqd
  * is idle.
  */
-#define MMC_IDLE_BKOPS_TIME_MS 2000
+#define MMC_IDLE_BKOPS_TIME_MS 200
 	struct work_struct	poll_for_completion;
 /* Polling timeout and interval for waiting on non-blocking BKOPs completion */
-#define BKOPS_COMPLETION_POLLING_TIMEOUT_MS 10000 /* in ms */
+#define BKOPS_COMPLETION_POLLING_TIMEOUT_MS (4 * 60 * 1000) /* in ms */
 #define BKOPS_COMPLETION_POLLING_INTERVAL_MS 1000 /* in ms */
 	bool			cancel_delayed_work;
-	bool			started_delayed_bkops;
 	unsigned int		sectors_changed;
 /*
  * Since canceling the delayed work might have significant effect on the
@@ -268,9 +271,8 @@
  * mmcqd thread is idle.
  * The delayed work for idle BKOPS will be scheduled only after a significant
  * amount of write or discard data.
- * 100MB is chosen based on benchmark tests.
  */
-#define BKOPS_MIN_SECTORS_TO_QUEUE_DELAYED_WORK 204800 /* 100MB */
+#define BKOPS_SIZE_PERCENTAGE_TO_QUEUE_DELAYED_WORK 1 /* 1% */
 };
 
 /*
@@ -296,6 +298,7 @@
 #define MMC_CARD_REMOVED	(1<<7)		/* card has been removed */
 #define MMC_STATE_HIGHSPEED_200	(1<<8)		/* card is in HS200 mode */
 #define MMC_STATE_DOING_BKOPS	(1<<10)		/* card is doing BKOPS */
+#define MMC_STATE_NEED_BKOPS	(1<<11)		/* card needs to do BKOPS */
 	unsigned int		quirks; 	/* card quirks */
 #define MMC_QUIRK_LENIENT_FN0	(1<<0)		/* allow SDIO FN0 writes outside of the VS CCCR range */
 #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)	/* use func->cur_blksize */
@@ -467,6 +470,7 @@
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)	((c) && ((c)->state & MMC_CARD_REMOVED))
 #define mmc_card_doing_bkops(c)	((c)->state & MMC_STATE_DOING_BKOPS)
+#define mmc_card_need_bkops(c)	((c)->state & MMC_STATE_NEED_BKOPS)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -480,7 +484,8 @@
 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
 #define mmc_card_set_doing_bkops(c)	((c)->state |= MMC_STATE_DOING_BKOPS)
 #define mmc_card_clr_doing_bkops(c)	((c)->state &= ~MMC_STATE_DOING_BKOPS)
-
+#define mmc_card_set_need_bkops(c)	((c)->state |= MMC_STATE_NEED_BKOPS)
+#define mmc_card_clr_need_bkops(c)	((c)->state &= ~MMC_STATE_NEED_BKOPS)
 /*
  * Quirk add/remove for MMC products.
  */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index f435221..c798cf9 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -468,6 +468,14 @@
 	return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC);
 }
 
+static inline int mmc_host_uhs(struct mmc_host *host)
+{
+	return host->caps &
+		(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+		 MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
+		 MMC_CAP_UHS_DDR50);
+}
+
 #ifdef CONFIG_MMC_CLKGATE
 void mmc_host_clk_hold(struct mmc_host *host);
 void mmc_host_clk_release(struct mmc_host *host);
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 90980b7..6e12694 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -390,6 +390,7 @@
 	 * process to make sure that the system is not starved.
 	 */
 	unsigned long		min_cma_pages;
+	bool			cma_alloc;
 #endif
 	struct free_area	free_area[MAX_ORDER];
 
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index bc124da..839767f 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -78,6 +78,9 @@
  *	of a given interface; other interfaces may support other classes.
  * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass.
  * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass.
+ * @bInterfaceNumber: Number of interface; composite devices may use
+ *	fixed interface numbers to differentiate between vendor-specific
+ *	interfaces.
  * @driver_info: Holds information used by the driver.  Usually it holds
  *	a pointer to a descriptor understood by the driver, or perhaps
  *	device flags.
@@ -115,6 +118,9 @@
 	__u8		bInterfaceSubClass;
 	__u8		bInterfaceProtocol;
 
+	/* Used for vendor-specific interface matches */
+	__u8		bInterfaceNumber;
+
 	/* not matched against */
 	kernel_ulong_t	driver_info;
 };
@@ -130,6 +136,7 @@
 #define USB_DEVICE_ID_MATCH_INT_CLASS		0x0080
 #define USB_DEVICE_ID_MATCH_INT_SUBCLASS	0x0100
 #define USB_DEVICE_ID_MATCH_INT_PROTOCOL	0x0200
+#define USB_DEVICE_ID_MATCH_INT_NUMBER		0x0400
 
 #define HID_ANY_ID				(~0)
 
diff --git a/include/linux/msm-charger.h b/include/linux/msm-charger.h
index 14ffae31..93ed7cf 100644
--- a/include/linux/msm-charger.h
+++ b/include/linux/msm-charger.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/msm_audio.h b/include/linux/msm_audio.h
index f2a39e4..04d4e5b 100644
--- a/include/linux/msm_audio.h
+++ b/include/linux/msm_audio.h
@@ -1,7 +1,7 @@
 /* include/linux/msm_audio.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/include/linux/msm_audio_aac.h b/include/linux/msm_audio_aac.h
index 620e5ab..e03c4f8 100644
--- a/include/linux/msm_audio_aac.h
+++ b/include/linux/msm_audio_aac.h
@@ -14,6 +14,9 @@
 #define AUDIO_GET_AAC_ENC_CONFIG  _IOR(AUDIO_IOCTL_MAGIC, \
   (AUDIO_MAX_COMMON_IOCTL_NUM+4), struct msm_audio_aac_enc_config)
 
+#define AUDIO_SET_AAC_MIX_CONFIG  _IOR(AUDIO_IOCTL_MAGIC, \
+	(AUDIO_MAX_COMMON_IOCTL_NUM+5), unsigned)
+
 #define AUDIO_AAC_FORMAT_ADTS		-1
 #define	AUDIO_AAC_FORMAT_RAW		0x0000
 #define	AUDIO_AAC_FORMAT_PSUEDO_RAW	0x0001
diff --git a/include/linux/msm_dsps.h b/include/linux/msm_dsps.h
index a5ac256..1f997ba 100644
--- a/include/linux/msm_dsps.h
+++ b/include/linux/msm_dsps.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/msm_ion.h b/include/linux/msm_ion.h
index 2ba7588..edf2401 100644
--- a/include/linux/msm_ion.h
+++ b/include/linux/msm_ion.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (c) 2012-2013, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/include/linux/msm_ipc.h b/include/linux/msm_ipc.h
index 44fa8eb..7b6bf41 100644
--- a/include/linux/msm_ipc.h
+++ b/include/linux/msm_ipc.h
@@ -45,6 +45,14 @@
 	unsigned char reserved;
 };
 
+struct config_sec_rules_args {
+	int num_group_info;
+	uint32_t service_id;
+	uint32_t instance_id;
+	unsigned reserved;
+	gid_t group_id[0];
+};
+
 #define IPC_ROUTER_IOCTL_MAGIC (0xC3)
 
 #define IPC_ROUTER_IOCTL_GET_VERSION \
@@ -62,6 +70,9 @@
 #define IPC_ROUTER_IOCTL_BIND_CONTROL_PORT \
 	_IOR(IPC_ROUTER_IOCTL_MAGIC, 4, unsigned int)
 
+#define IPC_ROUTER_IOCTL_CONFIG_SEC_RULES \
+	_IOR(IPC_ROUTER_IOCTL_MAGIC, 5, struct config_sec_rules_args)
+
 struct msm_ipc_server_info {
 	uint32_t node_id;
 	uint32_t port_id;
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 6912087..67056df 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -13,6 +13,8 @@
 #define KGSL_CONTEXT_TRASH_STATE	0x00000020
 #define KGSL_CONTEXT_PER_CONTEXT_TS	0x00000040
 #define KGSL_CONTEXT_USER_GENERATED_TS	0x00000080
+#define KGSL_CONTEXT_NO_FAULT_TOLERANCE 0x00000200
+
 
 #define KGSL_CONTEXT_INVALID 0xffffffff
 
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index c685fce..394394b 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -276,8 +276,10 @@
 	struct msmfb_img img;
 };
 
+#define MDP_PP_OPS_ENABLE 0x1
 #define MDP_PP_OPS_READ 0x2
 #define MDP_PP_OPS_WRITE 0x4
+#define MDP_PP_OPS_DISABLE 0x8
 
 struct mdp_qseed_cfg {
 	uint32_t table_num;
@@ -291,8 +293,19 @@
 	struct mdp_qseed_cfg qseed_data;
 };
 
+struct mdp_sharp_cfg {
+	uint32_t flags;
+	uint32_t strength;
+	uint32_t edge_thr;
+	uint32_t smooth_thr;
+	uint32_t noise_thr;
+};
+
 #define MDP_OVERLAY_PP_CSC_CFG      0x1
 #define MDP_OVERLAY_PP_QSEED_CFG    0x2
+#define MDP_OVERLAY_PP_PA_CFG    0x4
+#define MDP_OVERLAY_PP_IGC_CFG    0x8
+#define MDP_OVERLAY_PP_SHARP_CFG    0x10
 
 #define MDP_CSC_FLAG_ENABLE	0x1
 #define MDP_CSC_FLAG_YUV_IN	0x2
@@ -313,10 +326,36 @@
 	struct mdp_csc_cfg csc_data;
 };
 
+struct mdp_pa_cfg {
+	uint32_t flags;
+	uint32_t hue_adj;
+	uint32_t sat_adj;
+	uint32_t val_adj;
+	uint32_t cont_adj;
+};
+
+struct mdp_igc_lut_data {
+	uint32_t block;
+	uint32_t len, ops;
+	uint32_t *c0_c1_data;
+	uint32_t *c2_data;
+};
+
 struct mdp_overlay_pp_params {
 	uint32_t config_ops;
 	struct mdp_csc_cfg csc_cfg;
 	struct mdp_qseed_cfg qseed_cfg[2];
+	struct mdp_pa_cfg pa_cfg;
+	struct mdp_igc_lut_data igc_cfg;
+	struct mdp_sharp_cfg sharp_cfg;
+};
+
+enum {
+	BLEND_OP_NOT_DEFINED = 0,
+	BLEND_OP_OPAQUE,
+	BLEND_OP_PREMULTIPLIED,
+	BLEND_OP_COVERAGE,
+	BLEND_OP_MAX,
 };
 
 struct mdp_overlay {
@@ -327,6 +366,7 @@
 	uint32_t is_fg;		/* control alpha & transp */
 	uint32_t alpha;
 	uint32_t transp_mask;
+	uint32_t blend_op;
 	uint32_t flags;
 	uint32_t id;
 	uint32_t user_data[8];
@@ -431,13 +471,6 @@
 	mdp_lut_max,
 };
 
-struct mdp_igc_lut_data {
-	uint32_t block;
-	uint32_t len, ops;
-	uint32_t *c0_c1_data;
-	uint32_t *c2_data;
-};
-
 struct mdp_ar_gc_lut_data {
 	uint32_t x_start;
 	uint32_t slope;
@@ -483,6 +516,11 @@
 	uint32_t data;
 };
 
+struct mdp_pa_cfg_data {
+	uint32_t block;
+	struct mdp_pa_cfg pa_data;
+};
+
 enum {
 	mdp_op_pcc_cfg,
 	mdp_op_csc_cfg,
@@ -490,6 +528,7 @@
 	mdp_op_qseed_cfg,
 	mdp_bl_scale_cfg,
 	mdp_op_calib_cfg,
+	mdp_op_pa_cfg,
 	mdp_op_max,
 };
 
@@ -502,6 +541,7 @@
 		struct mdp_qseed_cfg_data qseed_cfg_data;
 		struct mdp_bl_scale_data bl_scale_data;
 		struct mdp_calib_config_data calib_cfg;
+		struct mdp_pa_cfg_data pa_cfg_data;
 	} data;
 };
 
@@ -563,7 +603,7 @@
 	int z_order;
 };
 
-#define MAX_PIPE_PER_MIXER  4
+#define MAX_PIPE_PER_MIXER  5
 
 struct msmfb_mixer_info_req {
 	int mixer_num;
diff --git a/include/linux/msm_rmnet.h b/include/linux/msm_rmnet.h
index 063a8f1..01d52b6 100644
--- a/include/linux/msm_rmnet.h
+++ b/include/linux/msm_rmnet.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/msm_rotator.h b/include/linux/msm_rotator.h
index 17ae867..6a8d286 100644
--- a/include/linux/msm_rotator.h
+++ b/include/linux/msm_rotator.h
@@ -12,6 +12,8 @@
 		_IOW(MSM_ROTATOR_IOCTL_MAGIC, 2, struct msm_rotator_data_info)
 #define MSM_ROTATOR_IOCTL_FINISH   \
 		_IOW(MSM_ROTATOR_IOCTL_MAGIC, 3, int)
+#define MSM_ROTATOR_IOCTL_BUFFER_SYNC   \
+		_IOW(MSM_ROTATOR_IOCTL_MAGIC, 4, struct msm_rotator_buf_sync)
 
 #define ROTATOR_VERSION_01	0xA5B4C301
 
@@ -21,6 +23,13 @@
 	ROTATOR_IMEM_CLK
 };
 
+struct msm_rotator_buf_sync {
+	uint32_t session_id;
+	uint32_t flags;
+	int acq_fen_fd;
+	int rel_fen_fd;
+};
+
 struct msm_rotator_img_info {
 	unsigned int session_id;
 	struct msmfb_img  src;
@@ -41,6 +50,7 @@
 	unsigned int version_key;
 	struct msmfb_data src_chroma;
 	struct msmfb_data dst_chroma;
+	uint32_t wait_for_finish;
 };
 
 struct msm_rot_clocks {
diff --git a/include/linux/msm_rpcrouter.h b/include/linux/msm_rpcrouter.h
index 01d3809..cd304f3 100644
--- a/include/linux/msm_rpcrouter.h
+++ b/include/linux/msm_rpcrouter.h
@@ -1,6 +1,6 @@
 /* include/linux/msm_rpcrouter.h
  *
- * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, The Linux Foundation. All rights reserved.
  * Copyright (C) 2007 Google, Inc.
  * Author: San Mehat <san@android.com>
  *
diff --git a/include/linux/msm_smd_pkt.h b/include/linux/msm_smd_pkt.h
index dc7328f..cba9f6f 100644
--- a/include/linux/msm_smd_pkt.h
+++ b/include/linux/msm_smd_pkt.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/msm_ssbi.h b/include/linux/msm_ssbi.h
index 647bc06..6858d00 100644
--- a/include/linux/msm_ssbi.h
+++ b/include/linux/msm_ssbi.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2010 Google, Inc.
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  * Author: Dima Zavin <dima@android.com>
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index 8b7bb7c..aa14f76 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
@@ -17,9 +17,12 @@
 struct msm_thermal_data {
 	uint32_t sensor_id;
 	uint32_t poll_ms;
-	uint32_t limit_temp_degC;
-	uint32_t temp_hysteresis_degC;
+	int32_t limit_temp_degC;
+	int32_t temp_hysteresis_degC;
 	uint32_t freq_step;
+	int32_t core_limit_temp_degC;
+	int32_t core_temp_hysteresis_degC;
+	uint32_t core_control_mask;
 };
 
 #ifdef CONFIG_THERMAL_MONITOR
diff --git a/include/linux/msm_tsens.h b/include/linux/msm_tsens.h
index 1b0d399..5837094 100644
--- a/include/linux/msm_tsens.h
+++ b/include/linux/msm_tsens.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/msm_vidc_dec.h b/include/linux/msm_vidc_dec.h
index cc864f0..7edf6cf 100644
--- a/include/linux/msm_vidc_dec.h
+++ b/include/linux/msm_vidc_dec.h
@@ -220,6 +220,9 @@
 #define VDEC_IOCTL_FREE_META_BUFFERS \
 	_IO(VDEC_IOCTL_MAGIC, 40)
 
+#define VDEC_IOCTL_GET_ENABLE_SEC_METADATA \
+	_IOR(VDEC_IOCTL_MAGIC, 41, struct vdec_ioctl_msg)
+
 enum vdec_picture {
 	PICTURE_TYPE_I,
 	PICTURE_TYPE_P,
@@ -552,6 +555,8 @@
 	enum vdec_interlaced_format interlaced_format;
 	struct vdec_aspectratioinfo aspect_ratio_info;
 	struct vdec_sep_metadatainfo metadata_info;
+	size_t metadata_len;
+	size_t metadata_offset;
 };
 
 union vdec_msgdata {
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index b70ba97..7914723 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -144,6 +144,8 @@
 #define VEN_INPUTFMT_NV12	1/* NV12 Linear */
 #define VEN_INPUTFMT_NV21	2/* NV21 Linear */
 #define VEN_INPUTFMT_NV12_16M2KA	3/* NV12 Linear */
+#define VEN_INPUTFMT_NV21_16M2KA	4
+
 
 /*Different allowed rotation modes.*/
 #define VEN_ROTATION_0	1/* 0 degrees */
@@ -493,6 +495,8 @@
  long long	timestamp;
  unsigned long	flags;
  void	*clientdata;
+	unsigned long	metadata_len;
+	unsigned long	metadata_offset;
 };
 
 struct venc_basecfg{
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index d5ed103..a1e1561 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -170,6 +170,9 @@
  *	%NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
  *	%NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
  *	%NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT.
+ *	%NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS.
+ *	The channel to use can be set on the interface or be given using the
+ *	%NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width.
  * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
  * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface
  * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP
@@ -554,6 +557,57 @@
  * @NL80211_CMD_SET_NOACK_MAP: sets a bitmap for the individual TIDs whether
  *      No Acknowledgement Policy should be applied.
  *
+ * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels
+ *	independently of the userspace SME, send this event indicating
+ *	%NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the
+ *	attributes determining channel width.
+ *
+ * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by
+ *	its %NL80211_ATTR_WDEV identifier. It must have been created with
+ *	%NL80211_CMD_NEW_INTERFACE previously. After it has been started, the
+ *	P2P Device can be used for P2P operations, e.g. remain-on-channel and
+ *	public action frame TX.
+ * @NL80211_CMD_STOP_P2P_DEVICE: Stop the given P2P Device, identified by
+ *	its %NL80211_ATTR_WDEV identifier.
+ *
+ * @NL80211_CMD_CONN_FAILED: connection request to an AP failed; used to
+ *	notify userspace that AP has rejected the connection request from a
+ *	station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON
+ *	is used for this.
+ *
+ * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames
+ *	for IBSS or MESH vif.
+ *
+ * @NL80211_CMD_SET_MAC_ACL: sets ACL for MAC address based access control.
+ *	This is to be used with the drivers advertising the support of MAC
+ *	address based access control. List of MAC addresses is passed in
+ *	%NL80211_ATTR_MAC_ADDRS and ACL policy is passed in
+ *	%NL80211_ATTR_ACL_POLICY. Driver will enable ACL with this list, if it
+ *	is not already done. The new list will replace any existing list. Driver
+ *	will clear its ACL when the list of MAC addresses passed is empty. This
+ *	command is used in AP/P2P GO mode. Driver has to make sure to clear its
+ *	ACL list during %NL80211_CMD_STOP_AP.
+ *
+ * @NL80211_CMD_RADAR_DETECT: Start a Channel availability check (CAC). Once
+ *	a radar is detected or the channel availability scan (CAC) has finished
+ *	or was aborted, or a radar was detected, usermode will be notified with
+ *	this event. This command is also used to notify userspace about radars
+ *	while operating on this channel.
+ *	%NL80211_ATTR_RADAR_EVENT is used to inform about the type of the
+ *	event.
+ *
+ * @NL80211_CMD_GET_PROTOCOL_FEATURES: Get global nl80211 protocol features,
+ *	i.e. features for the nl80211 protocol rather than device features.
+ *	Returns the features in the %NL80211_ATTR_PROTOCOL_FEATURES bitmap.
+ *
+ * @NL80211_CMD_UPDATE_FT_IES: Pass down the most up-to-date Fast Transition
+ *	Information Element to the WLAN driver
+ *
+ * @NL80211_CMD_FT_EVENT: Send a Fast transition event from the WLAN driver
+ *	to the supplicant. This will carry the target AP's MAC address along
+ *	with the relevant Information Elements. This event is used to report
+ *	received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE).
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -695,6 +749,25 @@
 
 	NL80211_CMD_SET_NOACK_MAP,
 
+
+	NL80211_CMD_CH_SWITCH_NOTIFY,
+
+	NL80211_CMD_START_P2P_DEVICE,
+	NL80211_CMD_STOP_P2P_DEVICE,
+
+	NL80211_CMD_CONN_FAILED,
+
+	NL80211_CMD_SET_MCAST_RATE,
+
+	NL80211_CMD_SET_MAC_ACL,
+
+	NL80211_CMD_RADAR_DETECT,
+
+	NL80211_CMD_GET_PROTOCOL_FEATURES,
+
+	NL80211_CMD_UPDATE_FT_IES,
+	NL80211_CMD_FT_EVENT,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -1270,6 +1343,72 @@
  * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds
  *      or 0 to disable background scan.
  *
+ * @NL80211_ATTR_USER_REG_HINT_TYPE: type of regulatory hint passed from
+ *	userspace. If unset it is assumed the hint comes directly from
+ *	a user. If set code could specify exactly what type of source
+ *	was used to provide the hint. For the different types of
+ *	allowed user regulatory hints see nl80211_user_reg_hint_type.
+ *
+ * @NL80211_ATTR_CONN_FAILED_REASON: The reason for which AP has rejected
+ *	the connection request from a station. nl80211_connect_failed_reason
+ *	enum has different reasons of connection failure.
+ *
+ * @NL80211_ATTR_SAE_DATA: SAE elements in Authentication frames. This starts
+ *	with the Authentication transaction sequence number field.
+ *
+ * @NL80211_ATTR_VHT_CAPABILITY: VHT Capability information element (from
+ *	association request when used with NL80211_CMD_NEW_STATION)
+ *
+ * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32)
+ *
+ * @NL80211_ATTR_P2P_CTWINDOW: P2P GO Client Traffic Window (u8), used with
+ *	the START_AP and SET_BSS commands
+ * @NL80211_ATTR_P2P_OPPPS: P2P GO opportunistic PS (u8), used with the
+ *	START_AP and SET_BSS commands. This can have the values 0 or 1;
+ *	if not given in START_AP 0 is assumed, if not given in SET_BSS
+ *	no change is made.
+ *
+ * @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode
+ *	defined in &enum nl80211_mesh_power_mode.
+ *
+ * @NL80211_ATTR_ACL_POLICY: ACL policy, see &enum nl80211_acl_policy,
+ *	carried in a u32 attribute
+ *
+ * @NL80211_ATTR_MAC_ADDRS: Array of nested MAC addresses, used for
+ *	MAC ACL.
+ *
+ * @NL80211_ATTR_MAC_ACL_MAX: u32 attribute to advertise the maximum
+ *	number of MAC addresses that a device can support for MAC
+ *	ACL.
+ *
+ * @NL80211_ATTR_RADAR_EVENT: Type of radar event for notification to userspace,
+ *	contains a value of enum nl80211_radar_event (u32).
+ *
+ * @NL80211_ATTR_EXT_CAPA: 802.11 extended capabilities that the kernel driver
+ *	has and handles. The format is the same as the IE contents. See
+ *	802.11-2012 8.4.2.29 for more information.
+ * @NL80211_ATTR_EXT_CAPA_MASK: Extended capabilities that the kernel driver
+ *	has set in the %NL80211_ATTR_EXT_CAPA value, for multibit fields.
+ *
+ * @NL80211_ATTR_STA_CAPABILITY: Station capabilities (u16) are advertised to
+ *	the driver, e.g., to enable TDLS power save (PU-APSD).
+ *
+ * @NL80211_ATTR_STA_EXT_CAPABILITY: Station extended capabilities are
+ *	advertised to the driver, e.g., to enable TDLS off channel operations
+ *	and PU-APSD.
+ *
+ * @NL80211_ATTR_PROTOCOL_FEATURES: global nl80211 feature flags, see
+ *	&enum nl80211_protocol_features, the attribute is a u32.
+ *
+ * @NL80211_ATTR_SPLIT_WIPHY_DUMP: flag attribute, userspace supports
+ *	receiving the data for a single wiphy split across multiple
+ *	messages, given with wiphy dump message
+ *
+ * @NL80211_ATTR_MDID: Mobility Domain Identifier
+ *
+ * @NL80211_ATTR_IE_RIC: Resource Information Container Information
+ *	Element
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1521,6 +1660,50 @@
 
 	NL80211_ATTR_BG_SCAN_PERIOD,
 
+	NL80211_ATTR_WDEV,
+
+	NL80211_ATTR_USER_REG_HINT_TYPE,
+
+	NL80211_ATTR_CONN_FAILED_REASON,
+
+	NL80211_ATTR_SAE_DATA,
+
+	NL80211_ATTR_VHT_CAPABILITY,
+
+	NL80211_ATTR_SCAN_FLAGS,
+
+	NL80211_ATTR_CHANNEL_WIDTH,
+	NL80211_ATTR_CENTER_FREQ1,
+	NL80211_ATTR_CENTER_FREQ2,
+
+	NL80211_ATTR_P2P_CTWINDOW,
+	NL80211_ATTR_P2P_OPPPS,
+
+	NL80211_ATTR_LOCAL_MESH_POWER_MODE,
+
+	NL80211_ATTR_ACL_POLICY,
+
+	NL80211_ATTR_MAC_ADDRS,
+
+	NL80211_ATTR_MAC_ACL_MAX,
+
+	NL80211_ATTR_RADAR_EVENT,
+
+	NL80211_ATTR_EXT_CAPA,
+	NL80211_ATTR_EXT_CAPA_MASK,
+
+	NL80211_ATTR_STA_CAPABILITY,
+	NL80211_ATTR_STA_EXT_CAPABILITY,
+
+	NL80211_ATTR_PROTOCOL_FEATURES,
+	NL80211_ATTR_SPLIT_WIPHY_DUMP,
+
+	NL80211_ATTR_DISABLE_VHT,
+	NL80211_ATTR_VHT_CAPABILITY_MASK,
+
+	NL80211_ATTR_MDID,
+	NL80211_ATTR_IE_RIC,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -1564,6 +1747,7 @@
 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY	16
 #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY	24
 #define NL80211_HT_CAPABILITY_LEN		26
+#define NL80211_VHT_CAPABILITY_LEN		12
 
 #define NL80211_MAX_NR_CIPHER_SUITES		5
 #define NL80211_MAX_NR_AKM_SUITES		2
@@ -1663,9 +1847,14 @@
  * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
  * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
  * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
- * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate
+ * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 MHz dualchannel bitrate
  * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
  * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined
+ * @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8)
+ * @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8)
+ * @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate
+ * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: 80+80 MHz VHT rate
+ * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate
  * @__NL80211_RATE_INFO_AFTER_LAST: internal use
  */
 enum nl80211_rate_info {
@@ -1674,6 +1863,11 @@
 	NL80211_RATE_INFO_MCS,
 	NL80211_RATE_INFO_40_MHZ_WIDTH,
 	NL80211_RATE_INFO_SHORT_GI,
+	NL80211_RATE_INFO_VHT_MCS,
+	NL80211_RATE_INFO_VHT_NSS,
+	NL80211_RATE_INFO_80_MHZ_WIDTH,
+	NL80211_RATE_INFO_80P80_MHZ_WIDTH,
+	NL80211_RATE_INFO_160_MHZ_WIDTH,
 
 	/* keep last */
 	__NL80211_RATE_INFO_AFTER_LAST,
@@ -1832,6 +2026,9 @@
  * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
  * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
  * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
+ * @NL80211_BAND_ATTR_VHT_MCS_SET: 32-byte attribute containing the MCS set as
+ *	defined in 802.11ac
+ * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE
  * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
  * @__NL80211_BAND_ATTR_AFTER_LAST: internal use
  */
@@ -1845,6 +2042,9 @@
 	NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
 	NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
 
+	NL80211_BAND_ATTR_VHT_MCS_SET,
+	NL80211_BAND_ATTR_VHT_CAPA,
+
 	/* keep last */
 	__NL80211_BAND_ATTR_AFTER_LAST,
 	NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
diff --git a/include/linux/of_coresight.h b/include/linux/of_coresight.h
index 47a05c9..6a5e4d4 100644
--- a/include/linux/of_coresight.h
+++ b/include/linux/of_coresight.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/of_slimbus.h b/include/linux/of_slimbus.h
index 8e1dc65..f686cdc 100644
--- a/include/linux/of_slimbus.h
+++ b/include/linux/of_slimbus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/of_spmi.h b/include/linux/of_spmi.h
index fe09dec..b22696b 100644
--- a/include/linux/of_spmi.h
+++ b/include/linux/of_spmi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/ofn_atlab.h b/include/linux/ofn_atlab.h
index 16c34d7..6e3a277 100644
--- a/include/linux/ofn_atlab.h
+++ b/include/linux/ofn_atlab.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. 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 and
diff --git a/include/linux/platform_data/qcom_crypto_device.h b/include/linux/platform_data/qcom_crypto_device.h
index 08aa784..37cf3c8 100644
--- a/include/linux/platform_data/qcom_crypto_device.h
+++ b/include/linux/platform_data/qcom_crypto_device.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/platform_data/qcom_wcnss_device.h b/include/linux/platform_data/qcom_wcnss_device.h
index e904084..be9a09a 100644
--- a/include/linux/platform_data/qcom_wcnss_device.h
+++ b/include/linux/platform_data/qcom_wcnss_device.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/pmic8058-charger.h b/include/linux/pmic8058-charger.h
index 0fbc828..a11c4ed 100644
--- a/include/linux/pmic8058-charger.h
+++ b/include/linux/pmic8058-charger.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/pmic8058-othc.h b/include/linux/pmic8058-othc.h
index 4c59845..bd96c3f 100644
--- a/include/linux/pmic8058-othc.h
+++ b/include/linux/pmic8058-othc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/pmic8058-pwm.h b/include/linux/pmic8058-pwm.h
index d380170..a9fc0db 100644
--- a/include/linux/pmic8058-pwm.h
+++ b/include/linux/pmic8058-pwm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/pmic8058-xoadc.h b/include/linux/pmic8058-xoadc.h
index 5163b65..bc4772d 100644
--- a/include/linux/pmic8058-xoadc.h
+++ b/include/linux/pmic8058-xoadc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/power/ltc4088-charger.h b/include/linux/power/ltc4088-charger.h
index 7a0bacf..e7c7e63 100644
--- a/include/linux/power/ltc4088-charger.h
+++ b/include/linux/power/ltc4088-charger.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/qcomwlan7x27a_pwrif.h b/include/linux/qcomwlan7x27a_pwrif.h
index 16e1783..fc022ae 100644
--- a/include/linux/qcomwlan7x27a_pwrif.h
+++ b/include/linux/qcomwlan7x27a_pwrif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/qcomwlan_pwrif.h b/include/linux/qcomwlan_pwrif.h
index 74d2a80..fc5f1e8 100644
--- a/include/linux/qcomwlan_pwrif.h
+++ b/include/linux/qcomwlan_pwrif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/qcomwlan_secif.h b/include/linux/qcomwlan_secif.h
index 8c6e425..b0f5308 100644
--- a/include/linux/qcomwlan_secif.h
+++ b/include/linux/qcomwlan_secif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/qcota.h b/include/linux/qcota.h
index afc6b7f..cf62f02 100644
--- a/include/linux/qcota.h
+++ b/include/linux/qcota.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/qfp_fuse.h b/include/linux/qfp_fuse.h
index 8e3fd5e..d2f8961 100644
--- a/include/linux/qfp_fuse.h
+++ b/include/linux/qfp_fuse.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/qpnp/clkdiv.h b/include/linux/qpnp/clkdiv.h
index c75a922..5253711 100644
--- a/include/linux/qpnp/clkdiv.h
+++ b/include/linux/qpnp/clkdiv.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/qpnp/pin.h b/include/linux/qpnp/pin.h
index fa9c30f..1653f87 100644
--- a/include/linux/qpnp/pin.h
+++ b/include/linux/qpnp/pin.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/qpnp/pwm.h b/include/linux/qpnp/pwm.h
index 50c15e9..bf7908b 100644
--- a/include/linux/qpnp/pwm.h
+++ b/include/linux/qpnp/pwm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index 19a1d97..9888f37 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/regulator/krait-regulator.h b/include/linux/regulator/krait-regulator.h
index eb1c3fd..2a0895e 100644
--- a/include/linux/regulator/krait-regulator.h
+++ b/include/linux/regulator/krait-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/regulator/msm-gpio-regulator.h b/include/linux/regulator/msm-gpio-regulator.h
index 9efda85..0269aa7 100644
--- a/include/linux/regulator/msm-gpio-regulator.h
+++ b/include/linux/regulator/msm-gpio-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/regulator/pm8058-xo.h b/include/linux/regulator/pm8058-xo.h
index a2b8aeb..29cdd01 100644
--- a/include/linux/regulator/pm8058-xo.h
+++ b/include/linux/regulator/pm8058-xo.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/regulator/pm8xxx-regulator.h b/include/linux/regulator/pm8xxx-regulator.h
index 4ca624b..7461c6a 100644
--- a/include/linux/regulator/pm8xxx-regulator.h
+++ b/include/linux/regulator/pm8xxx-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/linux/regulator/pmic8058-regulator.h b/include/linux/regulator/pmic8058-regulator.h
index 3eeaa61..ee1d93d 100644
--- a/include/linux/regulator/pmic8058-regulator.h
+++ b/include/linux/regulator/pmic8058-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/regulator/pmic8901-regulator.h b/include/linux/regulator/pmic8901-regulator.h
index ec842bc..60d9353 100644
--- a/include/linux/regulator/pmic8901-regulator.h
+++ b/include/linux/regulator/pmic8901-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/linux/regulator/qpnp-regulator.h b/include/linux/regulator/qpnp-regulator.h
index ca8ccd7..ec580ab 100644
--- a/include/linux/regulator/qpnp-regulator.h
+++ b/include/linux/regulator/qpnp-regulator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/regulator/stub-regulator.h b/include/linux/regulator/stub-regulator.h
index e7f4110..d43171d 100644
--- a/include/linux/regulator/stub-regulator.h
+++ b/include/linux/regulator/stub-regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/remote_spinlock.h b/include/linux/remote_spinlock.h
index 8d7c7e7..5d426f5 100644
--- a/include/linux/remote_spinlock.h
+++ b/include/linux/remote_spinlock.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2011, The Linux Foundation. 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 and
diff --git a/include/linux/rmt_storage_client.h b/include/linux/rmt_storage_client.h
index f56819a..077a42a 100644
--- a/include/linux/rmt_storage_client.h
+++ b/include/linux/rmt_storage_client.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, The Linux Foundation. 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 and
diff --git a/include/linux/rq_stats.h b/include/linux/rq_stats.h
index e04063f..0accf38 100644
--- a/include/linux/rq_stats.h
+++ b/include/linux/rq_stats.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
@@ -19,6 +19,7 @@
 	unsigned long rq_poll_total_jiffies;
 	unsigned long def_timer_last_jiffy;
 	unsigned int def_interval;
+	unsigned int hotplug_disabled;
 	int64_t def_start_time;
 	struct attribute_group *attr_group;
 	struct kobject *kobj;
diff --git a/include/linux/rtc-msm.h b/include/linux/rtc-msm.h
index f8f6a16..324d66a 100644
--- a/include/linux/rtc-msm.h
+++ b/include/linux/rtc-msm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 0a1428e..67889bf 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2304,7 +2304,7 @@
 }
 
 /* mmput gets rid of the mappings and all user-space */
-extern void mmput(struct mm_struct *);
+extern int mmput(struct mm_struct *);
 /* Grab a reference to a task's mm, if it is not already going away */
 extern struct mm_struct *get_task_mm(struct task_struct *task);
 /*
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index 75b132b..f06f632 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -143,10 +143,15 @@
  * struct slim_addrt: slimbus address used internally by the slimbus framework.
  * @valid: If the device is still there or if the address can be reused.
  * @eaddr: 6-bytes-long elemental address
+ * @laddr: It is possible that controller will set a predefined logical address
+ *	rather than the one assigned by framework. (i.e. logical address may
+ *	not be same as index into this table). This entry will store the
+ *	logical address value for this enumeration address.
  */
 struct slim_addrt {
 	bool	valid;
 	u8	eaddr[6];
+	u8	laddr;
 };
 
 /*
@@ -479,6 +484,8 @@
  * @m_ctrl: Mutex protecting controller data structures (ports, channels etc)
  * @addrt: Logical address table
  * @num_dev: Number of active slimbus slaves on this bus
+ * @devs: List of devices on this controller
+ * @wq: Workqueue per controller used to notify devices when they report present
  * @txnt: Table of transactions having transaction ID
  * @last_tid: size of the table txnt (can't grow beyond 256 since TID is 8-bits)
  * @ports: Ports associated with this controller
@@ -496,6 +503,11 @@
  * @set_laddr: Setup logical address at laddr for the slave with elemental
  *	address e_addr. Drivers implementing controller will be expected to
  *	send unicast message to this device with its logical address.
+ * @allocbw: Controller can override default reconfiguration and channel
+ *	scheduling algorithm.
+ * @get_laddr: It is possible that controller needs to set fixed logical
+ *	address table and get_laddr can be used in that case so that controller
+ *	can do this assignment.
  * @wakeup: This function pointer implements controller-specific procedure
  *	to wake it up from clock-pause. Framework will call this to bring
  *	the controller out of clock pause.
@@ -525,6 +537,8 @@
 	struct mutex		m_ctrl;
 	struct slim_addrt	*addrt;
 	u8			num_dev;
+	struct list_head	devs;
+	struct workqueue_struct *wq;
 	struct slim_msg_txn	**txnt;
 	u8			last_tid;
 	struct slim_port	*ports;
@@ -538,6 +552,10 @@
 				struct slim_msg_txn *txn);
 	int			(*set_laddr)(struct slim_controller *ctrl,
 				const u8 *ea, u8 elen, u8 laddr);
+	int			(*allocbw)(struct slim_device *sb,
+				int *subfrmc, int *clkgear);
+	int			(*get_laddr)(struct slim_controller *ctrl,
+				const u8 *ea, u8 elen, u8 *laddr);
 	int			(*wakeup)(struct slim_controller *ctrl);
 	int			(*config_port)(struct slim_controller *ctrl,
 				u8 port);
@@ -569,6 +587,7 @@
 	int				(*suspend)(struct slim_device *sldev,
 					pm_message_t pmesg);
 	int				(*resume)(struct slim_device *sldev);
+	int				(*device_up)(struct slim_device *sldev);
 
 	struct device_driver		driver;
 	const struct slim_device_id	*id_table;
@@ -601,6 +620,11 @@
  *  @mark_define: List of channels pending definition/activation.
  *  @mark_suspend: List of channels pending suspend.
  *  @mark_removal: List of channels pending removal.
+ *  @notified: Flag to indicate whether this device has been notified. The
+ *	device may report present multiple times, but should be notified only
+ *	first time it has reported present.
+ *  @dev_list: List of devices on a controller
+ *  @wd: Work structure associated with workqueue for presence notification
  *  @sldev_reconf: Mutex to protect the pending data-channel lists.
  *  @pending_msgsl: Message bandwidth reservation request by this client in
  *	slots that's pending reconfiguration.
@@ -619,6 +643,9 @@
 	struct list_head	mark_define;
 	struct list_head	mark_suspend;
 	struct list_head	mark_removal;
+	bool			notified;
+	struct list_head	dev_list;
+	struct work_struct	wd;
 	struct mutex		sldev_reconf;
 	u32			pending_msgsl;
 	u32			cur_msgsl;
@@ -966,14 +993,17 @@
  * @ctrl: Controller with which device is enumerated.
  * @e_addr: 6-byte elemental address of the device.
  * @e_len: buffer length for e_addr
- * @laddr: Return logical address.
+ * @laddr: Return logical address (if valid flag is false)
+ * @valid: true if laddr holds a valid address that controller wants to
+ *	set for this enumeration address. Otherwise framework sets index into
+ *	address table as logical address.
  * Called by controller in response to REPORT_PRESENT. Framework will assign
  * a logical address to this enumeration address.
  * Function returns -EXFULL to indicate that all logical addresses are already
  * taken.
  */
 extern int slim_assign_laddr(struct slim_controller *ctrl, const u8 *e_addr,
-				u8 e_len, u8 *laddr);
+				u8 e_len, u8 *laddr, bool valid);
 
 /*
  * slim_msg_response: Deliver Message response received from a device to the
diff --git a/include/linux/smsc3503.h b/include/linux/smsc3503.h
index 66ba003..8d28a03 100644
--- a/include/linux/smsc3503.h
+++ b/include/linux/smsc3503.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/include/linux/smux.h b/include/linux/smux.h
index 24a6371..56b18fa 100644
--- a/include/linux/smux.h
+++ b/include/linux/smux.h
@@ -1,6 +1,6 @@
 /* include/linux/smux.h
  *
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index f94b5c5..d179eab 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/test-iosched.h b/include/linux/test-iosched.h
index 1e428c5..5997271 100644
--- a/include/linux/test-iosched.h
+++ b/include/linux/test-iosched.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/tspp.h b/include/linux/tspp.h
index 551fbb0..c790c28 100644
--- a/include/linux/tspp.h
+++ b/include/linux/tspp.h
@@ -88,5 +88,7 @@
 	_IOW(TSPP_IOCTL_BASE, 5, struct tspp_system_keys)
 #define TSPP_IOCTL_BUFFER_SIZE		\
 	_IOW(TSPP_IOCTL_BASE, 6, struct tspp_buffer)
+#define TSPP_IOCTL_CLOSE_STREAM		\
+	_IO(TSPP_IOCTL_BASE, 7)
 
 #endif /* _TSPP_H_ */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 44c64e8..e8114f0 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -771,6 +771,22 @@
 	.bInterfaceProtocol = (pr)
 
 /**
+ * USB_DEVICE_INTERFACE_NUMBER - describe a usb device with a specific interface number
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ * @num: bInterfaceNumber value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific interface number of devices.
+ */
+#define USB_DEVICE_INTERFACE_NUMBER(vend, prod, num) \
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+		       USB_DEVICE_ID_MATCH_INT_NUMBER, \
+	.idVendor = (vend), \
+	.idProduct = (prod), \
+	.bInterfaceNumber = (num)
+
+/**
  * USB_DEVICE_INFO - macro used to describe a class of usb devices
  * @cl: bDeviceClass value
  * @sc: bDeviceSubClass value
diff --git a/include/linux/usb/ccid_desc.h b/include/linux/usb/ccid_desc.h
index 2d1ae74..334a045 100644
--- a/include/linux/usb/ccid_desc.h
+++ b/include/linux/usb/ccid_desc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 0396adc..61c9460 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Author: Brian Swetland <swetland@google.com>
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/include/linux/usb/usb_qdss.h b/include/linux/usb/usb_qdss.h
index 94a2c37..662d992 100644
--- a/include/linux/usb/usb_qdss.h
+++ b/include/linux/usb/usb_qdss.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 72f5c96..642c4fe 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -131,6 +131,9 @@
 	/* link reset handling, called from defer_kevent */
 	int	(*link_reset)(struct usbnet *);
 
+	/*in case if usbnet wrapper wants to override rx_complete()*/
+	void (*rx_complete) (struct urb *);
+
 	/* fixup rx packet (strip framing) */
 	int	(*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);
 
@@ -228,5 +231,7 @@
 extern void usbnet_set_msglevel(struct net_device *, u32);
 extern void usbnet_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
 extern int usbnet_nway_reset(struct net_device *net);
+extern void usbnet_terminate_urbs(struct usbnet *dev);
+extern void rx_complete(struct urb *urb);
 
 #endif /* __LINUX_USB_USBNET_H */
diff --git a/include/linux/vcm.h b/include/linux/vcm.h
index 776b8b2..3ea8c88 100644
--- a/include/linux/vcm.h
+++ b/include/linux/vcm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/vcm_alloc.h b/include/linux/vcm_alloc.h
index f0e4ea4..06d7ee1 100644
--- a/include/linux/vcm_alloc.h
+++ b/include/linux/vcm_alloc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/vcm_mm.h b/include/linux/vcm_mm.h
index 4cc5358..b113fc2 100644
--- a/include/linux/vcm_mm.h
+++ b/include/linux/vcm_mm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/vcm_types.h b/include/linux/vcm_types.h
index 7ec20a6..cea1de5 100644
--- a/include/linux/vcm_types.h
+++ b/include/linux/vcm_types.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 6f29b78..eaf7ed3 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -26,6 +26,7 @@
 };
 
 #define WCNSS_WLAN_IRQ_INVALID -1
+#define HAVE_WCNSS_RESET_INTR 1
 
 struct device *wcnss_wlan_get_device(void);
 struct resource *wcnss_wlan_get_memory_map(struct device *dev);
@@ -51,6 +52,9 @@
 void wcnss_allow_suspend(void);
 void wcnss_prevent_suspend(void);
 void wcnss_ssr_boot_notify(void);
+void wcnss_reset_intr(void);
+int wcnss_cold_boot_done(void);
+
 #define wcnss_wlan_get_drvdata(dev) dev_get_drvdata(dev)
 #define wcnss_wlan_set_drvdata(dev, data) dev_set_drvdata((dev), (data))
 
diff --git a/include/media/gpio-ir-recv.h b/include/media/gpio-ir-recv.h
index 3eab611..f4d6db4 100644
--- a/include/media/gpio-ir-recv.h
+++ b/include/media/gpio-ir-recv.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/media/msm/vcd_api.h b/include/media/msm/vcd_api.h
index 7472fb2..ec535ce5 100644
--- a/include/media/msm/vcd_api.h
+++ b/include/media/msm/vcd_api.h
@@ -78,6 +78,8 @@
 	u32 desc_size;
 	struct ion_handle *buff_ion_handle;
 	struct vcd_aspect_ratio aspect_ratio_info;
+	u32 metadata_len;
+	u32 metadata_offset;
 };
 
 struct vcd_sequence_hdr {
diff --git a/include/media/msm/vcd_property.h b/include/media/msm/vcd_property.h
index 698dd3b..5b83214 100644
--- a/include/media/msm/vcd_property.h
+++ b/include/media/msm/vcd_property.h
@@ -59,6 +59,8 @@
 #define VCD_I_ENABLE_VUI_TIMING_INFO (VCD_START_BASE + 0x2B)
 #define VCD_I_SET_EXT_METABUFFER (VCD_START_BASE + 0x2C)
 #define VCD_I_FREE_EXT_METABUFFER (VCD_START_BASE + 0x2D)
+#define VCD_I_ENABLE_SEC_METADATA (VCD_START_BASE + 0x2E)
+
 
 #define VCD_START_REQ      (VCD_START_BASE + 0x1000)
 #define VCD_I_REQ_IFRAME   (VCD_START_REQ + 0x1)
@@ -149,7 +151,8 @@
 	VCD_BUFFER_FORMAT_NV12      = 0x1,
 	VCD_BUFFER_FORMAT_TILE_4x2    = 0x2,
 	VCD_BUFFER_FORMAT_NV12_16M2KA = 0x3,
-	VCD_BUFFER_FORMAT_TILE_1x1    = 0x4
+	VCD_BUFFER_FORMAT_TILE_1x1    = 0x4,
+	VCD_BUFFER_FORMAT_NV21_16M2KA = 0x5
 };
 
 struct vcd_property_buffer_format {
diff --git a/include/media/msm/vcd_status.h b/include/media/msm/vcd_status.h
index 7e8ec0b..9b67ed0 100644
--- a/include/media/msm/vcd_status.h
+++ b/include/media/msm/vcd_status.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/include/media/msm/vidc_type.h b/include/media/msm/vidc_type.h
index d4db0a0..04d28b2 100644
--- a/include/media/msm/vidc_type.h
+++ b/include/media/msm/vidc_type.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 90d01da..121d8de 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2013, The Linux Foundation. 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 and
@@ -308,10 +308,11 @@
 
 #define MSM_MAX_CAMERA_CONFIGS 2
 
-#define PP_SNAP  0x01
-#define PP_RAW_SNAP ((0x01)<<1)
-#define PP_PREV  ((0x01)<<2)
-#define PP_THUMB ((0x01)<<3)
+#define PP_SNAP  BIT(0)
+#define PP_RAW_SNAP BIT(1)
+#define PP_PREV  BIT(2)
+#define PP_THUMB BIT(3)
+#define PP_RDI   BIT(4)
 #define PP_MASK		(PP_SNAP|PP_RAW_SNAP|PP_PREV|PP_THUMB)
 
 #define MSM_CAM_CTRL_CMD_DONE  0
@@ -1016,8 +1017,8 @@
 #define CFG_GPIO_OP                   54
 #define CFG_SET_VISION_MODE           55
 #define CFG_SET_VISION_AE             56
-#define CFG_MAX                       57
-
+#define CFG_HDR_UPDATE                57
+#define CFG_MAX                       58
 
 #define MOVE_NEAR	0
 #define MOVE_FAR	1
@@ -1034,20 +1035,6 @@
 #define SENSOR_QVGA_SIZE		2
 #define SENSOR_INVALID_SIZE		3
 
-#define CAMERA_EFFECT_OFF		0
-#define CAMERA_EFFECT_MONO		1
-#define CAMERA_EFFECT_NEGATIVE		2
-#define CAMERA_EFFECT_SOLARIZE		3
-#define CAMERA_EFFECT_SEPIA		4
-#define CAMERA_EFFECT_POSTERIZE		5
-#define CAMERA_EFFECT_WHITEBOARD	6
-#define CAMERA_EFFECT_BLACKBOARD	7
-#define CAMERA_EFFECT_AQUA		8
-#define CAMERA_EFFECT_EMBOSS		9
-#define CAMERA_EFFECT_SKETCH		10
-#define CAMERA_EFFECT_NEON		11
-#define CAMERA_EFFECT_MAX		12
-
 /* QRD */
 #define CAMERA_EFFECT_BW		10
 #define CAMERA_EFFECT_BLUISH	12
@@ -1234,6 +1221,8 @@
 struct exp_gain_cfg {
 	uint16_t gain;
 	uint32_t line;
+	int32_t luma_avg;
+	uint16_t fgain;
 };
 
 struct focus_cfg {
@@ -1344,6 +1333,17 @@
 	uint16_t frame_length_lines;
 };
 
+enum sensor_hdr_update_t {
+	SENSOR_HDR_UPDATE_AWB,
+	SENSOR_HDR_UPDATE_LSC,
+};
+
+struct sensor_hdr_update_parm_t {
+	enum sensor_hdr_update_t type;
+	uint16_t awb_gain_r, awb_gain_b;
+	uint8_t lsc_table[504];
+};
+
 struct sensor_driver_params_type {
 	struct msm_camera_i2c_reg_setting *init_settings;
 	uint16_t init_settings_size;
@@ -1660,6 +1660,7 @@
 		struct sensor_output_info_t output_info;
 		struct msm_eeprom_data_t eeprom_data;
 		struct csi_lane_params_t csi_lane_params;
+		struct sensor_hdr_update_parm_t hdr_update_parm;
 		/* QRD */
 		uint16_t antibanding;
 		uint8_t contrast;
diff --git a/include/media/msm_gestures.h b/include/media/msm_gestures.h
index c9af034..a6efd4f 100644
--- a/include/media/msm_gestures.h
+++ b/include/media/msm_gestures.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 7577504..19953ac 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -239,6 +239,8 @@
 #define VFE_CMD_TEST_GEN_CFG                            162
 #define VFE_CMD_SELECT_RDI                              163
 #define VFE_CMD_SET_STATS_VER                           164
+#define VFE_CMD_RGB_ALL_CFG                             165
+#define VFE_CMD_RGB_ALL_UPDATE                          166
 
 struct msm_isp_cmd {
 	int32_t  id;
diff --git a/include/media/msm_vidc.h b/include/media/msm_vidc.h
index 2efe31c..f757d03 100644
--- a/include/media/msm_vidc.h
+++ b/include/media/msm_vidc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index d6aa28e..84789f1 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved.
  *
  * This file is based on include/net/bluetooth/hci_core.h
  *
diff --git a/include/media/tavarua.h b/include/media/tavarua.h
index acfd360..881b851 100644
--- a/include/media/tavarua.h
+++ b/include/media/tavarua.h
@@ -104,6 +104,7 @@
 #define MARIMBA_2_1	0x02010204
 #define BAHAMA_1_0	0x0302010A
 #define BAHAMA_2_0	0x04020205
+#define BAHAMA_2_1      0x04020309
 #define WAIT_TIMEOUT 2000
 #define RADIO_INIT_TIME 15
 #define TAVARUA_DELAY 10
diff --git a/include/media/user-rc-input.h b/include/media/user-rc-input.h
index e58e40f..0eb9aec 100644
--- a/include/media/user-rc-input.h
+++ b/include/media/user-rc-input.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/media/vcap_fmt.h b/include/media/vcap_fmt.h
index 00e0375..00bad1e 100644
--- a/include/media/vcap_fmt.h
+++ b/include/media/vcap_fmt.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/media/vcap_v4l2.h b/include/media/vcap_v4l2.h
index cf99435..ff1c1aa 100644
--- a/include/media/vcap_v4l2.h
+++ b/include/media/vcap_v4l2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/media/videobuf-msm-mem.h b/include/media/videobuf-msm-mem.h
index 19dd93e..5e9790c 100644
--- a/include/media/videobuf-msm-mem.h
+++ b/include/media/videobuf-msm-mem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/media/videobuf2-msm-mem.h b/include/media/videobuf2-msm-mem.h
index f80ddcd..49625c4 100644
--- a/include/media/videobuf2-msm-mem.h
+++ b/include/media/videobuf2-msm-mem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index ec517b0..15d1817 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2010-2012 The Linux Foundation.  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 and
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 660a4a9..e909195 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2010-2013 The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -63,6 +63,7 @@
 #define BT_SECURITY_LOW		1
 #define BT_SECURITY_MEDIUM	2
 #define BT_SECURITY_HIGH	3
+#define BT_SECURITY_VERY_HIGH	4
 
 #define BT_DEFER_SETUP	7
 #define BT_FLUSHABLE	8
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 3a7cd5d..d88448f 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum. All rights reserved.
+   Copyright (c) 2000-2001, 2010-2012 The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -119,6 +119,7 @@
 #define HCIINQUIRY	_IOR('H', 240, int)
 
 /* HCI timeouts */
+#define HCI_DISCONN_AUTH_FAILED_TIMEOUT	(10)	/* 10 ms */
 #define HCI_CONNECT_TIMEOUT	(40000)	/* 40 seconds */
 #define HCI_DISCONN_TIMEOUT	(2000)	/* 2 seconds */
 #define HCI_PAIRING_TIMEOUT	(60000)	/* 60 seconds */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index d55ec26..efc11bb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2000-2001, 2010-2012, The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index e312ab3..9c2b735 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2010-2012 The Linux Foundation.  All rights reserved.
    Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
    Copyright (C) 2010 Google Inc.
 
diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h
index 6d94c34..8c85c98 100644
--- a/include/net/bluetooth/sco.h
+++ b/include/net/bluetooth/sco.h
@@ -1,7 +1,7 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
    Copyright (C) 2000-2001 Qualcomm Incorporated
-   Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2011, The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 71845dd..f0f2842 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -126,6 +126,7 @@
 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
 int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
 int smp_link_encrypt_cmplt(struct l2cap_conn *conn, __u8 status, __u8 encrypt);
+void smp_conn_security_fail(struct l2cap_conn *conn, __u8 code, __u8 reason);
 void smp_timeout(unsigned long l2cap_conn);
 
 #endif /* __SMP_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a166ee3..efe817b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -211,6 +211,22 @@
 };
 
 /**
+ * struct ieee80211_sta_vht_cap - STA's VHT capabilities
+ *
+ * This structure describes most essential parameters needed
+ * to describe 802.11ac VHT capabilities for an STA.
+ *
+ * @vht_supported: is VHT supported by the STA
+ * @cap: VHT capabilities map as described in 802.11ac spec
+ * @vht_mcs: Supported VHT MCS rates
+ */
+struct ieee80211_sta_vht_cap {
+	bool vht_supported;
+	u32 cap; /* use IEEE80211_VHT_CAP_ */
+	struct ieee80211_vht_mcs_info vht_mcs;
+};
+
+/**
  * struct ieee80211_supported_band - frequency band definition
  *
  * This structure describes a frequency band a wiphy
@@ -233,6 +249,7 @@
 	int n_channels;
 	int n_bitrates;
 	struct ieee80211_sta_ht_cap ht_cap;
+	struct ieee80211_sta_vht_cap vht_cap;
 };
 
 /*
@@ -445,12 +462,14 @@
 /**
  * enum station_parameters_apply_mask - station parameter values to apply
  * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp)
+ * @STATION_PARAM_APPLY_CAPABILITY: apply new capability
  *
  * Not all station parameters have in-band "no change" signalling,
  * for those that don't these flags will are used.
  */
 enum station_parameters_apply_mask {
 	STATION_PARAM_APPLY_UAPSD = BIT(0),
+	STATION_PARAM_APPLY_CAPABILITY = BIT(1),
 };
 
 /**
@@ -471,6 +490,7 @@
  * @plink_action: plink action to take
  * @plink_state: set the peer link state for a station
  * @ht_capa: HT capabilities of station
+ * @vht_capa: VHT capabilities of station
  * @uapsd_queues: bitmap of queues configured for uapsd. same format
  *	as the AC bitmap in the QoS info field
  * @max_sp: max Service Period. same format as the MAX_SP in the
@@ -478,6 +498,9 @@
  * @sta_modify_mask: bitmap indicating which parameters changed
  *	(for those that don't have a natural "no change" value),
  *	see &enum station_parameters_apply_mask
+ * @capability: station capability
+ * @ext_capab: extended capabilities of the station
+ * @ext_capab_len: number of extended capabilities
  */
 struct station_parameters {
 	u8 *supported_rates;
@@ -490,8 +513,12 @@
 	u8 plink_action;
 	u8 plink_state;
 	struct ieee80211_ht_cap *ht_capa;
+	struct ieee80211_vht_cap *vht_capa;
 	u8 uapsd_queues;
 	u8 max_sp;
+	u16 capability;
+	u8 *ext_capab;
+	u8 ext_capab_len;
 };
 
 /**
@@ -551,14 +578,24 @@
  * Used by the driver to indicate the specific rate transmission
  * type for 802.11n transmissions.
  *
- * @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled
- * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission
+ * @RATE_INFO_FLAGS_MCS: mcs field filled with HT MCS
+ * @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS
+ * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 MHz width transmission
+ * @RATE_INFO_FLAGS_80_MHZ_WIDTH: 80 MHz width transmission
+ * @RATE_INFO_FLAGS_80P80_MHZ_WIDTH: 80+80 MHz width transmission
+ * @RATE_INFO_FLAGS_160_MHZ_WIDTH: 160 MHz width transmission
  * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval
+ * @RATE_INFO_FLAGS_60G: 60GHz MCS
  */
 enum rate_info_flags {
-	RATE_INFO_FLAGS_MCS		= 1<<0,
-	RATE_INFO_FLAGS_40_MHZ_WIDTH	= 1<<1,
-	RATE_INFO_FLAGS_SHORT_GI	= 1<<2,
+	RATE_INFO_FLAGS_MCS			= BIT(0),
+	RATE_INFO_FLAGS_VHT_MCS			= BIT(1),
+	RATE_INFO_FLAGS_40_MHZ_WIDTH		= BIT(2),
+	RATE_INFO_FLAGS_80_MHZ_WIDTH		= BIT(3),
+	RATE_INFO_FLAGS_80P80_MHZ_WIDTH		= BIT(4),
+	RATE_INFO_FLAGS_160_MHZ_WIDTH		= BIT(5),
+	RATE_INFO_FLAGS_SHORT_GI		= BIT(6),
+	RATE_INFO_FLAGS_60G			= BIT(7),
 };
 
 /**
@@ -569,11 +606,13 @@
  * @flags: bitflag of flags from &enum rate_info_flags
  * @mcs: mcs index if struct describes a 802.11n bitrate
  * @legacy: bitrate in 100kbit/s for 802.11abg
+ * @nss: number of streams (VHT only)
  */
 struct rate_info {
 	u8 flags;
 	u8 mcs;
 	u16 legacy;
+	u8 nss;
 };
 
 /**
@@ -1318,6 +1357,21 @@
 };
 
 /**
+ * struct cfg80211_update_ft_ies_params - FT IE Information
+ *
+ * This structure provides information needed to update the fast transition IE
+ *
+ * @md: The Mobility Domain ID, 2 Octet value
+ * @ie: Fast Transition IEs
+ * @ie_len: Length of ft_ie in octets
+ */
+struct cfg80211_update_ft_ies_params {
+	u16 md;
+	const u8 *ie;
+	size_t ie_len;
+};
+
+/**
  * struct cfg80211_ops - backend description for wireless configuration
  *
  * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -1697,6 +1751,8 @@
 				  u16 noack_map);
 
 	struct ieee80211_channel *(*get_channel)(struct wiphy *wiphy);
+	int	(*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
+				 struct cfg80211_update_ft_ies_params *ftie);
 };
 
 /*
@@ -3367,6 +3423,31 @@
  */
 u16 cfg80211_calculate_bitrate(struct rate_info *rate);
 
+/**
+ * struct cfg80211_ft_event - FT Information Elements
+ * @ies: FT IEs
+ * @ies_len: length of the FT IE in bytes
+ * @target_ap: target AP's MAC address
+ * @ric_ies: RIC IE
+ * @ric_ies_len: length of the RIC IE in bytes
+ */
+struct cfg80211_ft_event_params {
+	const u8 *ies;
+	size_t ies_len;
+	const u8 *target_ap;
+	const u8 *ric_ies;
+	size_t ric_ies_len;
+};
+
+/**
+ * cfg80211_ft_event - notify userspace about FT IE and RIC IE
+ * @netdev: network device
+ * @ft_event: IE information
+ */
+void cfg80211_ft_event(struct net_device *netdev,
+		       struct cfg80211_ft_event_params *ft_event);
+
+
 /* Logging, debugging and troubleshooting/diagnostic helpers. */
 
 /* wiphy_printk helpers, similar to dev_printk */
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index ac4ec09..d1398f3 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h
index 90872c9..51bb216 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -1278,6 +1278,17 @@
 	struct asm_dual_mono channel_map;
 } __packed;
 
+#define ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG        0x00010DD8
+
+/* Structure for AAC decoder stereo coefficient setting. */
+
+struct asm_aac_stereo_mix_coeff_selection_param {
+	struct apr_hdr				hdr;
+	u32					param_id;
+	u32					param_size;
+	u32					aac_stereo_mix_coeff_flag;
+} __packed;
+
 #define ASM_ENCDEC_DEC_CHAN_MAP				 0x00010D82
 struct asm_stream_cmd_encdec_channelmap {
 	struct apr_hdr hdr;
diff --git a/include/sound/compress_offload.h b/include/sound/compress_offload.h
index e59d29c..3034ddc 100644
--- a/include/sound/compress_offload.h
+++ b/include/sound/compress_offload.h
@@ -169,4 +169,6 @@
  *
  */
 #define SND_COMPR_TRIGGER_DRAIN 7 /*FIXME move this to pcm.h */
+
+#define SNDRV_COMPRESS_METADATA_MODE          _IOW('C', 0x99, bool)
 #endif
diff --git a/include/sound/dai.h b/include/sound/dai.h
index 4d3fb96..031fe3b 100644
--- a/include/sound/dai.h
+++ b/include/sound/dai.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/include/sound/msm-dai-q6-v2.h b/include/sound/msm-dai-q6-v2.h
index 3d5ffdd..cae213a 100644
--- a/include/sound/msm-dai-q6-v2.h
+++ b/include/sound/msm-dai-q6-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/sound/msm-dai-q6.h b/include/sound/msm-dai-q6.h
index 042aa6f..a39d3dc 100644
--- a/include/sound/msm-dai-q6.h
+++ b/include/sound/msm-dai-q6.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h
index cb2f3d7..a800f9a 100644
--- a/include/sound/q6adm-v2.h
+++ b/include/sound/q6adm-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/sound/q6adm.h b/include/sound/q6adm.h
index 676c4cb..bb8c994 100644
--- a/include/sound/q6adm.h
+++ b/include/sound/q6adm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h
index 8ccc9f4..79ef7dd 100644
--- a/include/sound/q6afe-v2.h
+++ b/include/sound/q6afe-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/sound/q6afe.h b/include/sound/q6afe.h
index a7264e8..1b7a790 100644
--- a/include/sound/q6afe.h
+++ b/include/sound/q6afe.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, The Linux Foundation. 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 and
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 2ee5ff7..e5b9d6b 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -242,6 +242,8 @@
 int q6asm_cfg_dual_mono_aac(struct audio_client *ac,
 			uint16_t sce_left, uint16_t sce_right);
 
+int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff);
+
 int q6asm_enc_cfg_blk_qcelp(struct audio_client *ac, uint32_t frames_per_buf,
 		uint16_t min_rate, uint16_t max_rate,
 		uint16_t reduced_rate_level, uint16_t rate_modulation_cmd);
@@ -294,7 +296,7 @@
 /* Enable Mute/unmute flag */
 int q6asm_set_mute(struct audio_client *ac, int muteflag);
 
-uint64_t q6asm_get_session_time(struct audio_client *ac);
+int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp);
 
 /* Client can set the IO mode to either AIO/SIO mode */
 int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode);
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index 4021d48..5099500 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. 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 and
@@ -81,18 +81,18 @@
 
 #define SESSION_MAX	0x08
 
-#define SOFT_PAUSE_PERIOD       30   /* ramp up/down for 30ms    */
+#define SOFT_PAUSE_PERIOD       30   /* ramp up/down for 30ms */
 #define SOFT_PAUSE_STEP_LINEAR  0    /* Step value 0ms or 0us */
-#define SOFT_PAUSE_STEP         2000 /* Step value 2000ms or 2000us */
+#define SOFT_PAUSE_STEP         0    /* Step value 0ms or 0us */
 enum {
 	SOFT_PAUSE_CURVE_LINEAR = 0,
 	SOFT_PAUSE_CURVE_EXP,
 	SOFT_PAUSE_CURVE_LOG,
 };
 
-#define SOFT_VOLUME_PERIOD       30   /* ramp up/down for 30ms    */
+#define SOFT_VOLUME_PERIOD       30   /* ramp up/down for 30ms */
 #define SOFT_VOLUME_STEP_LINEAR  0    /* Step value 0ms or 0us */
-#define SOFT_VOLUME_STEP         2000 /* Step value 2000ms or 2000us */
+#define SOFT_VOLUME_STEP         0    /* Step value 0ms or 0us */
 enum {
 	SOFT_VOLUME_CURVE_LINEAR = 0,
 	SOFT_VOLUME_CURVE_EXP,
@@ -150,6 +150,7 @@
 	struct mutex	       cmd_lock;
 
 	atomic_t		cmd_state;
+	atomic_t		cmd_close_state;
 	atomic_t		time_flag;
 	atomic_t		nowait_cmd_cnt;
 	wait_queue_head_t	cmd_wait;
@@ -262,6 +263,8 @@
 int q6asm_cfg_dual_mono_aac(struct audio_client *ac,
 			uint16_t sce_left, uint16_t sce_right);
 
+int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff);
+
 int q6asm_set_encdec_chan_map(struct audio_client *ac,
 			uint32_t num_channels);
 
@@ -320,7 +323,7 @@
 /* Enable Mute/unmute flag */
 int q6asm_set_mute(struct audio_client *ac, int muteflag);
 
-uint64_t q6asm_get_session_time(struct audio_client *ac);
+int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp);
 
 /* Client can set the IO mode to either AIO/SIO mode */
 int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode);
diff --git a/include/sound/q6audio-v2.h b/include/sound/q6audio-v2.h
index 1a5dce1..38c3ab2 100644
--- a/include/sound/q6audio-v2.h
+++ b/include/sound/q6audio-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 17fef15..2b66a2e 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -2,7 +2,7 @@
  * linux/sound/soc-dai.h -- ALSA SoC Layer
  *
  * Copyright:	2005-2008 Wolfson Microelectronics. PLC.
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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
diff --git a/include/video/Kbuild b/include/video/Kbuild
index ad3e622..53e13cb 100644
--- a/include/video/Kbuild
+++ b/include/video/Kbuild
@@ -1,3 +1,4 @@
 header-y += edid.h
 header-y += sisfb.h
 header-y += uvesafb.h
+header-y += msm_hdmi_modes.h
diff --git a/include/video/msm_hdmi_modes.h b/include/video/msm_hdmi_modes.h
new file mode 100644
index 0000000..b9d3892
--- /dev/null
+++ b/include/video/msm_hdmi_modes.h
@@ -0,0 +1,332 @@
+#ifndef __MSM_HDMI_MODES_H__
+#define __MSM_HDMI_MODES_H__
+#include <linux/types.h>
+
+struct msm_hdmi_mode_timing_info {
+	uint32_t	video_format;
+	uint32_t	active_h;
+	uint32_t	front_porch_h;
+	uint32_t	pulse_width_h;
+	uint32_t	back_porch_h;
+	uint32_t	active_low_h;
+	uint32_t	active_v;
+	uint32_t	front_porch_v;
+	uint32_t	pulse_width_v;
+	uint32_t	back_porch_v;
+	uint32_t	active_low_v;
+	/* Must divide by 1000 to get the actual frequency in MHZ */
+	uint32_t	pixel_freq;
+	/* Must divide by 1000 to get the actual frequency in HZ */
+	uint32_t	refresh_rate;
+	uint32_t	interlaced;
+	uint32_t	supported;
+};
+
+#define MSM_HDMI_MODES_CEA		1
+#define MSM_HDMI_MODES_XTND		2
+#define MSM_HDMI_MODES_DVI		4
+#define MSM_HDMI_MODES_ALL		7
+
+/* all video formats defined by CEA 861D */
+#define HDMI_VFRMT_UNKNOWN		0
+#define HDMI_VFRMT_640x480p60_4_3	1
+#define HDMI_VFRMT_720x480p60_4_3	2
+#define HDMI_VFRMT_720x480p60_16_9	3
+#define HDMI_VFRMT_1280x720p60_16_9	4
+#define HDMI_VFRMT_1920x1080i60_16_9	5
+#define HDMI_VFRMT_720x480i60_4_3	6
+#define HDMI_VFRMT_1440x480i60_4_3	HDMI_VFRMT_720x480i60_4_3
+#define HDMI_VFRMT_720x480i60_16_9	7
+#define HDMI_VFRMT_1440x480i60_16_9	HDMI_VFRMT_720x480i60_16_9
+#define HDMI_VFRMT_720x240p60_4_3	8
+#define HDMI_VFRMT_1440x240p60_4_3	HDMI_VFRMT_720x240p60_4_3
+#define HDMI_VFRMT_720x240p60_16_9	9
+#define HDMI_VFRMT_1440x240p60_16_9	HDMI_VFRMT_720x240p60_16_9
+#define HDMI_VFRMT_2880x480i60_4_3	10
+#define HDMI_VFRMT_2880x480i60_16_9	11
+#define HDMI_VFRMT_2880x240p60_4_3	12
+#define HDMI_VFRMT_2880x240p60_16_9	13
+#define HDMI_VFRMT_1440x480p60_4_3	14
+#define HDMI_VFRMT_1440x480p60_16_9	15
+#define HDMI_VFRMT_1920x1080p60_16_9	16
+#define HDMI_VFRMT_720x576p50_4_3	17
+#define HDMI_VFRMT_720x576p50_16_9	18
+#define HDMI_VFRMT_1280x720p50_16_9	19
+#define HDMI_VFRMT_1920x1080i50_16_9	20
+#define HDMI_VFRMT_720x576i50_4_3	21
+#define HDMI_VFRMT_1440x576i50_4_3	HDMI_VFRMT_720x576i50_4_3
+#define HDMI_VFRMT_720x576i50_16_9	22
+#define HDMI_VFRMT_1440x576i50_16_9	HDMI_VFRMT_720x576i50_16_9
+#define HDMI_VFRMT_720x288p50_4_3	23
+#define HDMI_VFRMT_1440x288p50_4_3	HDMI_VFRMT_720x288p50_4_3
+#define HDMI_VFRMT_720x288p50_16_9	24
+#define HDMI_VFRMT_1440x288p50_16_9	HDMI_VFRMT_720x288p50_16_9
+#define HDMI_VFRMT_2880x576i50_4_3	25
+#define HDMI_VFRMT_2880x576i50_16_9	26
+#define HDMI_VFRMT_2880x288p50_4_3	27
+#define HDMI_VFRMT_2880x288p50_16_9	28
+#define HDMI_VFRMT_1440x576p50_4_3	29
+#define HDMI_VFRMT_1440x576p50_16_9	30
+#define HDMI_VFRMT_1920x1080p50_16_9	31
+#define HDMI_VFRMT_1920x1080p24_16_9	32
+#define HDMI_VFRMT_1920x1080p25_16_9	33
+#define HDMI_VFRMT_1920x1080p30_16_9	34
+#define HDMI_VFRMT_2880x480p60_4_3	35
+#define HDMI_VFRMT_2880x480p60_16_9	36
+#define HDMI_VFRMT_2880x576p50_4_3	37
+#define HDMI_VFRMT_2880x576p50_16_9	38
+#define HDMI_VFRMT_1920x1250i50_16_9	39
+#define HDMI_VFRMT_1920x1080i100_16_9	40
+#define HDMI_VFRMT_1280x720p100_16_9	41
+#define HDMI_VFRMT_720x576p100_4_3	42
+#define HDMI_VFRMT_720x576p100_16_9	43
+#define HDMI_VFRMT_720x576i100_4_3	44
+#define HDMI_VFRMT_1440x576i100_4_3	HDMI_VFRMT_720x576i100_4_3
+#define HDMI_VFRMT_720x576i100_16_9	45
+#define HDMI_VFRMT_1440x576i100_16_9	HDMI_VFRMT_720x576i100_16_9
+#define HDMI_VFRMT_1920x1080i120_16_9	46
+#define HDMI_VFRMT_1280x720p120_16_9	47
+#define HDMI_VFRMT_720x480p120_4_3	48
+#define HDMI_VFRMT_720x480p120_16_9	49
+#define HDMI_VFRMT_720x480i120_4_3	50
+#define HDMI_VFRMT_1440x480i120_4_3	HDMI_VFRMT_720x480i120_4_3
+#define HDMI_VFRMT_720x480i120_16_9	51
+#define HDMI_VFRMT_1440x480i120_16_9	HDMI_VFRMT_720x480i120_16_9
+#define HDMI_VFRMT_720x576p200_4_3	52
+#define HDMI_VFRMT_720x576p200_16_9	53
+#define HDMI_VFRMT_720x576i200_4_3	54
+#define HDMI_VFRMT_1440x576i200_4_3	HDMI_VFRMT_720x576i200_4_3
+#define HDMI_VFRMT_720x576i200_16_9	55
+#define HDMI_VFRMT_1440x576i200_16_9	HDMI_VFRMT_720x576i200_16_9
+#define HDMI_VFRMT_720x480p240_4_3	56
+#define HDMI_VFRMT_720x480p240_16_9	57
+#define HDMI_VFRMT_720x480i240_4_3	58
+#define HDMI_VFRMT_1440x480i240_4_3	HDMI_VFRMT_720x480i240_4_3
+#define HDMI_VFRMT_720x480i240_16_9	59
+#define HDMI_VFRMT_1440x480i240_16_9	HDMI_VFRMT_720x480i240_16_9
+#define HDMI_VFRMT_1280x720p24_16_9	60
+#define HDMI_VFRMT_1280x720p25_16_9	61
+#define HDMI_VFRMT_1280x720p30_16_9	62
+#define HDMI_VFRMT_1920x1080p120_16_9	63
+#define HDMI_VFRMT_1920x1080p100_16_9	64
+/* Video Identification Codes from 65-127 are reserved for the future */
+#define HDMI_VFRMT_END			127
+
+/* extended video formats */
+#define HDMI_VFRMT_3840x2160p30_16_9	(HDMI_VFRMT_END + 1)
+#define HDMI_VFRMT_3840x2160p25_16_9	(HDMI_VFRMT_END + 2)
+#define HDMI_VFRMT_3840x2160p24_16_9	(HDMI_VFRMT_END + 3)
+#define HDMI_VFRMT_4096x2160p24_16_9	(HDMI_VFRMT_END + 4)
+#define HDMI_EVFRMT_END			HDMI_VFRMT_4096x2160p24_16_9
+
+/* VESA DMT TIMINGS */
+#define HDMI_VFRMT_2560x1600p60_16_9	(HDMI_EVFRMT_END + 1)
+#define HDMI_VFRMT_1280x1024p60_5_4	(HDMI_EVFRMT_END + 2)
+#define VESA_DMT_VFRMT_END		HDMI_VFRMT_1280x1024p60_5_4
+#define HDMI_VFRMT_MAX			(VESA_DMT_VFRMT_END + 1)
+#define HDMI_VFRMT_FORCE_32BIT		0x7FFFFFFF
+
+/* Timing information for supported modes */
+#define VFRMT_NOT_SUPPORTED(VFRMT) \
+	{VFRMT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false}
+
+#define HDMI_VFRMT_640x480p60_4_3_TIMING				\
+	{HDMI_VFRMT_640x480p60_4_3, 640, 16, 96, 48, true,		\
+	 480, 10, 2, 33, true, 25200, 60000, false, true}
+#define HDMI_VFRMT_720x480p60_4_3_TIMING				\
+	{HDMI_VFRMT_720x480p60_4_3, 720, 16, 62, 60, true,		\
+	 480, 9, 6, 30, true, 27030, 60000, false, true}
+#define HDMI_VFRMT_720x480p60_16_9_TIMING				\
+	{HDMI_VFRMT_720x480p60_16_9, 720, 16, 62, 60, true,		\
+	 480, 9, 6, 30, true, 27030, 60000, false, true}
+#define HDMI_VFRMT_1280x720p60_16_9_TIMING				\
+	{HDMI_VFRMT_1280x720p60_16_9, 1280, 110, 40, 220, false,	\
+	 720, 5, 5, 20, false, 74250, 60000, false, true}
+#define HDMI_VFRMT_1920x1080i60_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080i60_16_9, 1920, 88, 44, 148, false,	\
+	 540, 2, 5, 5, false, 74250, 60000, false, true}
+#define HDMI_VFRMT_1440x480i60_4_3_TIMING				\
+	{HDMI_VFRMT_1440x480i60_4_3, 1440, 38, 124, 114, true,		\
+	 240, 4, 3, 15, true, 27000, 60000, true, true}
+#define HDMI_VFRMT_1440x480i60_16_9_TIMING				\
+	{HDMI_VFRMT_1440x480i60_16_9, 1440, 38, 124, 114, true,		\
+	 240, 4, 3, 15, true, 27000, 60000, true, true}
+#define HDMI_VFRMT_1920x1080p60_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p60_16_9, 1920, 88, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 148500, 60000, false, true}
+#define HDMI_VFRMT_720x576p50_4_3_TIMING				\
+	{HDMI_VFRMT_720x576p50_4_3, 720, 12, 64, 68, true,		\
+	 576,  5, 5, 39, true, 27000, 50000, false, true}
+#define HDMI_VFRMT_720x576p50_16_9_TIMING				\
+	{HDMI_VFRMT_720x576p50_16_9, 720, 12, 64, 68, true,		\
+	 576,  5, 5, 39, true, 27000, 50000, false, true}
+#define HDMI_VFRMT_1280x720p50_16_9_TIMING				\
+	{HDMI_VFRMT_1280x720p50_16_9, 1280, 440, 40, 220, false,	\
+	 720,  5, 5, 20, false, 74250, 50000, false, true}
+#define HDMI_VFRMT_1440x576i50_4_3_TIMING				\
+	{HDMI_VFRMT_1440x576i50_4_3, 1440, 24, 126, 138, true,		\
+	 288,  2, 3, 19, true, 27000, 50000, true, true}
+#define HDMI_VFRMT_1440x576i50_16_9_TIMING				\
+	{HDMI_VFRMT_1440x576i50_16_9, 1440, 24, 126, 138, true,		\
+	 288,  2, 3, 19, true, 27000, 50000, true, true}
+#define HDMI_VFRMT_1920x1080p50_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p50_16_9, 1920, 528, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 148500, 50000, false, true}
+#define HDMI_VFRMT_1920x1080p24_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p24_16_9, 1920, 638, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 74250, 24000, false, true}
+#define HDMI_VFRMT_1920x1080p25_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p25_16_9, 1920, 528, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 74250, 25000, false, true}
+#define HDMI_VFRMT_1920x1080p30_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p30_16_9, 1920, 88, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 74250, 30000, false, true}
+#define HDMI_VFRMT_1280x1024p60_5_4_TIMING				\
+	{HDMI_VFRMT_1280x1024p60_5_4, 1280, 48, 112, 248, false,	\
+	1024, 1, 3, 38, false, 108000, 60000, false, true}
+#define HDMI_VFRMT_2560x1600p60_16_9_TIMING				\
+	{HDMI_VFRMT_2560x1600p60_16_9, 2560, 48, 32, 80, false,		\
+	 1600, 3, 6, 37, false, 268500, 60000, false, true}
+#define HDMI_VFRMT_3840x2160p30_16_9_TIMING				\
+	{HDMI_VFRMT_3840x2160p30_16_9, 3840, 176, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 30000, false, true}
+#define HDMI_VFRMT_3840x2160p25_16_9_TIMING				\
+	{HDMI_VFRMT_3840x2160p25_16_9, 3840, 1056, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 25000, false, true}
+#define HDMI_VFRMT_3840x2160p24_16_9_TIMING				\
+	{HDMI_VFRMT_3840x2160p24_16_9, 3840, 1276, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 24000, false, true}
+#define HDMI_VFRMT_4096x2160p24_16_9_TIMING				\
+	{HDMI_VFRMT_4096x2160p24_16_9, 4096, 1020, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 24000, false, true}
+
+#define MSM_HDMI_MODES_SET_TIMING(LUT, MODE) do {		\
+	struct msm_hdmi_mode_timing_info mode = MODE##_TIMING;	\
+	LUT[MODE] = mode;\
+	} while (0)
+
+static inline void MSM_HDMI_MODES_INIT_TIMINGS(
+	struct msm_hdmi_mode_timing_info *lut)
+{
+	int i;
+
+	for (i = 0; i < HDMI_VFRMT_MAX; i++) {
+		struct msm_hdmi_mode_timing_info mode = VFRMT_NOT_SUPPORTED(i);
+		lut[i] = mode;
+	}
+}
+
+static inline void MSM_HDMI_MODES_SET_SUPP_TIMINGS(
+	struct msm_hdmi_mode_timing_info *lut, int type)
+{
+	if (type & MSM_HDMI_MODES_CEA) {
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_640x480p60_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x480p60_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x480p60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1280x720p60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080i60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x480i60_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x480i60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x576p50_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x576p50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1280x720p50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x576i50_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x576i50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p24_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p25_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p30_16_9);
+	}
+
+	if (type & MSM_HDMI_MODES_XTND) {
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_3840x2160p30_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_3840x2160p25_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_3840x2160p24_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_4096x2160p24_16_9);
+	}
+
+	if (type & MSM_HDMI_MODES_DVI) {
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1280x1024p60_5_4);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_2560x1600p60_16_9);
+	}
+}
+
+static inline const char *msm_hdmi_mode_2string(uint32_t mode)
+{
+	switch (mode) {
+	case HDMI_VFRMT_UNKNOWN:		return "Unknown";
+	case HDMI_VFRMT_640x480p60_4_3:		return "640x480 p60 4/3";
+	case HDMI_VFRMT_720x480p60_4_3:		return "720x480 p60 4/3";
+	case HDMI_VFRMT_720x480p60_16_9:	return "720x480 p60 16/9";
+	case HDMI_VFRMT_1280x720p60_16_9:	return "1280x 720 p60 16/9";
+	case HDMI_VFRMT_1920x1080i60_16_9:	return "1920x1080 i60 16/9";
+	case HDMI_VFRMT_1440x480i60_4_3:	return "1440x480 i60 4/3";
+	case HDMI_VFRMT_1440x480i60_16_9:	return "1440x480 i60 16/9";
+	case HDMI_VFRMT_1440x240p60_4_3:	return "1440x240 p60 4/3";
+	case HDMI_VFRMT_1440x240p60_16_9:	return "1440x240 p60 16/9";
+	case HDMI_VFRMT_2880x480i60_4_3:	return "2880x480 i60 4/3";
+	case HDMI_VFRMT_2880x480i60_16_9:	return "2880x480 i60 16/9";
+	case HDMI_VFRMT_2880x240p60_4_3:	return "2880x240 p60 4/3";
+	case HDMI_VFRMT_2880x240p60_16_9:	return "2880x240 p60 16/9";
+	case HDMI_VFRMT_1440x480p60_4_3:	return "1440x480 p60 4/3";
+	case HDMI_VFRMT_1440x480p60_16_9:	return "1440x480 p60 16/9";
+	case HDMI_VFRMT_1920x1080p60_16_9:	return "1920x1080 p60 16/9";
+	case HDMI_VFRMT_720x576p50_4_3:		return "720x576 p50 4/3";
+	case HDMI_VFRMT_720x576p50_16_9:	return "720x576 p50 16/9";
+	case HDMI_VFRMT_1280x720p50_16_9:	return "1280x720 p50 16/9";
+	case HDMI_VFRMT_1920x1080i50_16_9:	return "1920x1080 i50 16/9";
+	case HDMI_VFRMT_1440x576i50_4_3:	return "1440x576 i50 4/3";
+	case HDMI_VFRMT_1440x576i50_16_9:	return "1440x576 i50 16/9";
+	case HDMI_VFRMT_1440x288p50_4_3:	return "1440x288 p50 4/3";
+	case HDMI_VFRMT_1440x288p50_16_9:	return "1440x288 p50 16/9";
+	case HDMI_VFRMT_2880x576i50_4_3:	return "2880x576 i50 4/3";
+	case HDMI_VFRMT_2880x576i50_16_9:	return "2880x576 i50 16/9";
+	case HDMI_VFRMT_2880x288p50_4_3:	return "2880x288 p50 4/3";
+	case HDMI_VFRMT_2880x288p50_16_9:	return "2880x288 p50 16/9";
+	case HDMI_VFRMT_1440x576p50_4_3:	return "1440x576 p50 4/3";
+	case HDMI_VFRMT_1440x576p50_16_9:	return "1440x576 p50 16/9";
+	case HDMI_VFRMT_1920x1080p50_16_9:	return "1920x1080 p50 16/9";
+	case HDMI_VFRMT_1920x1080p24_16_9:	return "1920x1080 p24 16/9";
+	case HDMI_VFRMT_1920x1080p25_16_9:	return "1920x1080 p25 16/9";
+	case HDMI_VFRMT_1920x1080p30_16_9:	return "1920x1080 p30 16/9";
+	case HDMI_VFRMT_2880x480p60_4_3:	return "2880x480 p60 4/3";
+	case HDMI_VFRMT_2880x480p60_16_9:	return "2880x480 p60 16/9";
+	case HDMI_VFRMT_2880x576p50_4_3:	return "2880x576 p50 4/3";
+	case HDMI_VFRMT_2880x576p50_16_9:	return "2880x576 p50 16/9";
+	case HDMI_VFRMT_1920x1250i50_16_9:	return "1920x1250 i50 16/9";
+	case HDMI_VFRMT_1920x1080i100_16_9:	return "1920x1080 i100 16/9";
+	case HDMI_VFRMT_1280x720p100_16_9:	return "1280x720 p100 16/9";
+	case HDMI_VFRMT_720x576p100_4_3:	return "720x576 p100 4/3";
+	case HDMI_VFRMT_720x576p100_16_9:	return "720x576 p100 16/9";
+	case HDMI_VFRMT_1440x576i100_4_3:	return "1440x576 i100 4/3";
+	case HDMI_VFRMT_1440x576i100_16_9:	return "1440x576 i100 16/9";
+	case HDMI_VFRMT_1920x1080i120_16_9:	return "1920x1080 i120 16/9";
+	case HDMI_VFRMT_1280x720p120_16_9:	return "1280x720 p120 16/9";
+	case HDMI_VFRMT_720x480p120_4_3:	return "720x480 p120 4/3";
+	case HDMI_VFRMT_720x480p120_16_9:	return "720x480 p120 16/9";
+	case HDMI_VFRMT_1440x480i120_4_3:	return "1440x480 i120 4/3";
+	case HDMI_VFRMT_1440x480i120_16_9:	return "1440x480 i120 16/9";
+	case HDMI_VFRMT_720x576p200_4_3:	return "720x576 p200 4/3";
+	case HDMI_VFRMT_720x576p200_16_9:	return "720x576 p200 16/9";
+	case HDMI_VFRMT_1440x576i200_4_3:	return "1440x576 i200 4/3";
+	case HDMI_VFRMT_1440x576i200_16_9:	return "1440x576 i200 16/9";
+	case HDMI_VFRMT_720x480p240_4_3:	return "720x480 p240 4/3";
+	case HDMI_VFRMT_720x480p240_16_9:	return "720x480 p240 16/9";
+	case HDMI_VFRMT_1440x480i240_4_3:	return "1440x480 i240 4/3";
+	case HDMI_VFRMT_1440x480i240_16_9:	return "1440x480 i240 16/9";
+	case HDMI_VFRMT_1280x720p24_16_9:	return "1280x720 p24 16/9";
+	case HDMI_VFRMT_1280x720p25_16_9:	return "1280x720 p25 16/9";
+	case HDMI_VFRMT_1280x720p30_16_9:	return "1280x720 p30 16/9";
+	case HDMI_VFRMT_1920x1080p120_16_9:	return "1920x1080 p120 16/9";
+	case HDMI_VFRMT_1920x1080p100_16_9:	return "1920x1080 p100 16/9";
+	case HDMI_VFRMT_3840x2160p30_16_9:	return "3840x2160 p30 16/9";
+	case HDMI_VFRMT_3840x2160p25_16_9:	return "3840x2160 p25 16/9";
+	case HDMI_VFRMT_3840x2160p24_16_9:	return "3840x2160 p24 16/9";
+	case HDMI_VFRMT_4096x2160p24_16_9:	return "4096x2160 p24 16/9";
+	case HDMI_VFRMT_2560x1600p60_16_9:	return "2560x1600 p60 16/9";
+	case HDMI_VFRMT_1280x1024p60_5_4:	return "1280x1042 p60 5/4";
+	default:				return "???";
+	}
+}
+#endif /* __MSM_HDMI_MODES_H__ */
diff --git a/kernel/exit.c b/kernel/exit.c
index d8bd3b42..6096e80 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -639,6 +639,7 @@
 {
 	struct mm_struct *mm = tsk->mm;
 	struct core_state *core_state;
+	int mm_released;
 
 	mm_release(tsk, mm);
 	if (!mm)
@@ -683,7 +684,10 @@
 	enter_lazy_tlb(mm, current);
 	task_unlock(tsk);
 	mm_update_next_owner(mm);
-	mmput(mm);
+
+	mm_released = mmput(mm);
+	if (mm_released)
+		set_tsk_thread_flag(tsk, TIF_MM_RELEASED);
 }
 
 /*
diff --git a/kernel/fork.c b/kernel/fork.c
index c0bf8c7..0de735c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -581,8 +581,9 @@
 /*
  * Decrement the use count and release all resources for an mm.
  */
-void mmput(struct mm_struct *mm)
+int mmput(struct mm_struct *mm)
 {
+	int mm_freed = 0;
 	might_sleep();
 
 	if (atomic_dec_and_test(&mm->mm_users)) {
@@ -600,7 +601,9 @@
 		if (mm->binfmt)
 			module_put(mm->binfmt->module);
 		mmdrop(mm);
+		mm_freed = 1;
 	}
+	return mm_freed;
 }
 EXPORT_SYMBOL_GPL(mmput);
 
diff --git a/lib/memory_alloc.c b/lib/memory_alloc.c
index d931e14..cc7424f 100644
--- a/lib/memory_alloc.c
+++ b/lib/memory_alloc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 6e42cc2..69b9521 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -913,12 +913,14 @@
  * This array describes the order lists are fallen back to when
  * the free lists for the desirable migrate type are depleted
  */
-static int fallbacks[MIGRATE_TYPES][3] = {
+static int fallbacks[MIGRATE_TYPES][4] = {
 	[MIGRATE_UNMOVABLE]   = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE,     MIGRATE_RESERVE },
 	[MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE,   MIGRATE_MOVABLE,     MIGRATE_RESERVE },
-	[MIGRATE_MOVABLE]     = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE,   MIGRATE_RESERVE },
 #ifdef CONFIG_CMA
+	[MIGRATE_MOVABLE]     = { MIGRATE_CMA,         MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE },
 	[MIGRATE_CMA]         = { MIGRATE_RESERVE }, /* Never used */
+#else
+	[MIGRATE_MOVABLE]     = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE,   MIGRATE_RESERVE },
 #endif
 	[MIGRATE_RESERVE]     = { MIGRATE_RESERVE }, /* Never used */
 	[MIGRATE_ISOLATE]     = { MIGRATE_RESERVE }, /* Never used */
@@ -1041,10 +1043,17 @@
 			 * pages to the preferred allocation list. If falling
 			 * back for a reclaimable kernel allocation, be more
 			 * aggressive about taking ownership of free pages
+			 *
+			 * On the other hand, never change migration
+			 * type of MIGRATE_CMA pageblocks nor move CMA
+			 * pages on different free lists. We don't
+			 * want unmovable pages to be allocated from
+			 * MIGRATE_CMA areas.
 			 */
-			if (unlikely(current_order >= pageblock_order / 2) ||
-			    start_migratetype == MIGRATE_RECLAIMABLE ||
-			    page_group_by_mobility_disabled) {
+			if (!is_migrate_cma(migratetype) &&
+			    (unlikely(current_order >= pageblock_order / 2) ||
+			     start_migratetype == MIGRATE_RECLAIMABLE ||
+			     page_group_by_mobility_disabled)) {
 				int pages;
 				pages = move_freepages_block(zone, page,
 								start_migratetype);
@@ -1063,12 +1072,14 @@
 			rmv_page_order(page);
 
 			/* Take ownership for orders >= pageblock_order */
-			if (current_order >= pageblock_order)
+			if (current_order >= pageblock_order &&
+			    !is_migrate_cma(migratetype))
 				change_pageblock_range(page, current_order,
 							start_migratetype);
 
 			expand(zone, page, order, current_order, area,
-			       start_migratetype);
+			       is_migrate_cma(migratetype)
+			     ? migratetype : start_migratetype);
 
 			trace_mm_page_alloc_extfrag(page, order, current_order,
 				start_migratetype, migratetype);
@@ -1089,27 +1100,52 @@
 {
 	struct page *page;
 
-#ifdef CONFIG_CMA
-	if (migratetype == MIGRATE_MOVABLE)
-		migratetype = MIGRATE_CMA;
-#endif
+retry_reserve:
+	page = __rmqueue_smallest(zone, order, migratetype);
 
-	for(;;) {
-		page = __rmqueue_smallest(zone, order, migratetype);
-		if (likely(page) || migratetype == MIGRATE_RESERVE)
-			break;
-
-		if (is_migrate_cma(migratetype)) {
-			migratetype = MIGRATE_MOVABLE;
-			continue;
-		}
-
+	if (unlikely(!page) && migratetype != MIGRATE_RESERVE) {
 		page = __rmqueue_fallback(zone, order, migratetype);
-		if (page)
-			break;
 
-		/* Use MIGRATE_RESERVE rather than fail an allocation. */
-		migratetype = MIGRATE_RESERVE;
+		/*
+		 * Use MIGRATE_RESERVE rather than fail an allocation. goto
+		 * is used because __rmqueue_smallest is an inline function
+		 * and we want just one call site
+		 */
+		if (!page) {
+			migratetype = MIGRATE_RESERVE;
+			goto retry_reserve;
+		}
+	}
+
+	trace_mm_page_alloc_zone_locked(page, order, migratetype);
+	return page;
+}
+
+static struct page *__rmqueue_cma(struct zone *zone, unsigned int order,
+							int migratetype)
+{
+	struct page *page = 0;
+#ifdef CONFIG_CMA
+	if (migratetype == MIGRATE_MOVABLE && !zone->cma_alloc)
+		page = __rmqueue_smallest(zone, order, MIGRATE_CMA);
+	if (!page)
+#endif
+retry_reserve :
+		page = __rmqueue_smallest(zone, order, migratetype);
+
+
+	if (unlikely(!page) && migratetype != MIGRATE_RESERVE) {
+		page = __rmqueue_fallback(zone, order, migratetype);
+
+		/*
+		 * Use MIGRATE_RESERVE rather than fail an allocation. goto
+		 * is used because __rmqueue_smallest is an inline function
+		 * and we want just one call site
+		 */
+		if (!page) {
+			migratetype = MIGRATE_RESERVE;
+			goto retry_reserve;
+		}
 	}
 
 	trace_mm_page_alloc_zone_locked(page, order, migratetype);
@@ -1123,13 +1159,17 @@
  */
 static int rmqueue_bulk(struct zone *zone, unsigned int order,
 			unsigned long count, struct list_head *list,
-			int migratetype, int cold)
+			int migratetype, int cold, int cma)
 {
 	int mt = migratetype, i;
 
 	spin_lock(&zone->lock);
 	for (i = 0; i < count; ++i) {
-		struct page *page = __rmqueue(zone, order, migratetype);
+		struct page *page;
+		if (cma)
+			page = __rmqueue_cma(zone, order, migratetype);
+		else
+			page = __rmqueue(zone, order, migratetype);
 		if (unlikely(page == NULL))
 			break;
 
@@ -1333,7 +1373,8 @@
 	 * excessively into the page allocator
 	 */
 	if (migratetype >= MIGRATE_PCPTYPES) {
-		if (unlikely(migratetype == MIGRATE_ISOLATE)) {
+		if (unlikely(migratetype == MIGRATE_ISOLATE) ||
+			     is_migrate_cma(migratetype)) {
 			free_one_page(zone, page, 0, migratetype);
 			goto out;
 		}
@@ -1475,7 +1516,8 @@
 		if (list_empty(list)) {
 			pcp->count += rmqueue_bulk(zone, 0,
 					pcp->batch, list,
-					migratetype, cold);
+					migratetype, cold,
+					gfp_flags & __GFP_CMA);
 			if (unlikely(list_empty(list)))
 				goto failed;
 		}
@@ -1502,7 +1544,10 @@
 			WARN_ON_ONCE(order > 1);
 		}
 		spin_lock_irqsave(&zone->lock, flags);
-		page = __rmqueue(zone, order, migratetype);
+		if (gfp_flags & __GFP_CMA)
+			page = __rmqueue_cma(zone, order, migratetype);
+		else
+			page = __rmqueue(zone, order, migratetype);
 		spin_unlock(&zone->lock);
 		if (!page)
 			goto failed;
@@ -5879,6 +5924,8 @@
 	if (ret)
 		goto done;
 
+	zone->cma_alloc = 1;
+
 	ret = __alloc_contig_migrate_range(start, end);
 	if (ret)
 		goto done;
@@ -5943,6 +5990,7 @@
 done:
 	undo_isolate_page_range(pfn_max_align_down(start),
 				pfn_max_align_up(end), migratetype);
+	zone->cma_alloc = 0;
 	return ret;
 }
 
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index ba638d1..c19be91 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2010-2012 The Linux Foundation.  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 and
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index fb85c02..50f73be 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2010-2012 The Linux Foundation.  All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 345b70f..7ecbc70 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2010-2012 The Linux Foundation.  All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 15d3585..7bc1d40 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 The Linux Foundation. All rights reserved.
+   Copyright (c) 2000-2001, 2010-2013 The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -1567,7 +1567,28 @@
 
 static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
 {
+	struct hci_cp_le_start_enc *cp;
+	struct hci_conn *conn;
+
 	BT_DBG("%s status 0x%x", hdev->name, status);
+	if (!status) {
+		return;
+	}
+
+	BT_DBG("%s Le start enc failed 0x%x", hdev->name, status);
+	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
+	if (!cp) {
+		BT_DBG("CP is null");
+		return;
+	}
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
+	if (conn) {
+		BT_DBG("conn exists");
+		hci_conn_put(conn);
+	}
+	hci_dev_unlock(hdev);
 }
 
 static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1870,6 +1891,7 @@
 			} else {
 				conn->state = BT_CONNECTED;
 				hci_proto_connect_cfm(conn, ev->status);
+				conn->disc_timeout = HCI_DISCONN_AUTH_FAILED_TIMEOUT;
 				hci_conn_put(conn);
 			}
 		} else {
@@ -2046,7 +2068,7 @@
 							sizeof(cp), &cp);
 		goto unlock;
 	} else  if (!(lmp_ssp_capable(conn)) && conn->auth_initiator &&
-		(conn->pending_sec_level == BT_SECURITY_HIGH)) {
+		(conn->pending_sec_level == BT_SECURITY_VERY_HIGH)) {
 		conn->pending_sec_level = BT_SECURITY_MEDIUM;
 	}
 
@@ -2669,6 +2691,12 @@
 		BT_DBG("Conn pending sec level is %d, ssp is %d, key len is %d",
 			conn->pending_sec_level, conn->ssp_mode, key->pin_len);
 	}
+	if (conn && (conn->ssp_mode == 0) &&
+		(conn->pending_sec_level == BT_SECURITY_VERY_HIGH) &&
+		(key->pin_len != 16)) {
+		BT_DBG("Security is high ignoring this key");
+		goto not_found;
+	}
 
 	if (key->key_type == 0x04 && conn && conn->auth_type != 0xff &&
 						(conn->auth_type & 0x01)) {
@@ -2853,14 +2881,14 @@
 
 		conn->ssp_mode = (ev->features[0] & 0x01);
 		/*In case if remote device ssp supported/2.0 device
-		reduce the security level to MEDIUM if it is HIGH*/
+		reduce the security level to MEDIUM if it is VERY HIGH*/
 		if (!conn->ssp_mode && conn->auth_initiator &&
-			(conn->pending_sec_level == BT_SECURITY_HIGH))
+			(conn->pending_sec_level == BT_SECURITY_VERY_HIGH))
 			conn->pending_sec_level = BT_SECURITY_MEDIUM;
 
 		if (conn->ssp_mode && conn->auth_initiator &&
 			conn->io_capability != 0x03) {
-			conn->pending_sec_level = BT_SECURITY_HIGH;
+			conn->pending_sec_level = BT_SECURITY_VERY_HIGH;
 			conn->auth_type = HCI_AT_DEDICATED_BONDING_MITM;
 		}
 	}
@@ -2921,12 +2949,13 @@
 	case 0x1a:	/* Unsupported Remote Feature */
 	case 0x1f:	/* Unspecified error */
 		if (conn->out && conn->attempt < 2) {
-			if (!conn->hdev->is_wbs)
+			if (!conn->hdev->is_wbs) {
 				conn->pkt_type =
 					(hdev->esco_type & SCO_ESCO_MASK) |
 					(hdev->esco_type & EDR_ESCO_MASK);
-			hci_setup_sync(conn, conn->link->handle);
-			goto unlock;
+				hci_setup_sync(conn, conn->link->handle);
+				goto unlock;
+			}
 		}
 		/* fall through */
 
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 61c2ca1..550f601 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2011, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2000-2001, 2011, The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 0a4c7d6..255419e 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -166,7 +166,8 @@
 {
 	BT_DBG("conn %p", conn);
 
-	queue_work(conn->hdev->workqueue, &conn->work_del);
+	if (conn->hdev)
+		queue_work(conn->hdev->workqueue, &conn->work_del);
 }
 
 static inline char *host_bustostr(int bus)
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index d80c0e3..ba09f4a 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -1,7 +1,7 @@
 /*
    HIDP implementation for Linux Bluetooth stack (BlueZ).
    Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
-   Copyright (c) 2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2012 The Linux Foundation.  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
@@ -93,40 +93,15 @@
 	return NULL;
 }
 
-static struct device *hidp_get_device(struct hidp_session *session)
-{
-	bdaddr_t *dst = &session->bdaddr;
-
-	struct device *device = NULL;
-	struct hci_dev *hdev;
-
-	hdev = hci_get_route(dst, BDADDR_ANY);
-	if (!hdev)
-		return NULL;
-
-	session->conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
-	if (session->conn)
-		device = &session->conn->dev;
-
-	hci_dev_put(hdev);
-
-	return device;
-}
-
 static void __hidp_link_session(struct hidp_session *session)
 {
 	__module_get(THIS_MODULE);
 	list_add(&session->list, &hidp_session_list);
-
-	hci_conn_hold_device(session->conn);
 }
 
 static void __hidp_unlink_session(struct hidp_session *session)
 {
-	struct device *dev;
-
-	dev = hidp_get_device(session);
-	if (dev)
+	if (session->conn)
 		hci_conn_put_device(session->conn);
 
 	list_del(&session->list);
@@ -660,6 +635,28 @@
 	return 0;
 }
 
+static struct hci_conn *hidp_get_connection(struct hidp_session *session)
+{
+	bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src;
+	bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst;
+	struct hci_conn *conn;
+	struct hci_dev *hdev;
+
+	hdev = hci_get_route(dst, src);
+	if (!hdev)
+		return NULL;
+
+	hci_dev_lock_bh(hdev);
+	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+	if (conn)
+		hci_conn_hold_device(conn);
+	hci_dev_unlock_bh(hdev);
+
+	hci_dev_put(hdev);
+
+	return conn;
+}
+
 static int hidp_setup_input(struct hidp_session *session,
 				struct hidp_connadd_req *req)
 {
@@ -707,7 +704,7 @@
 		input->relbit[0] |= BIT_MASK(REL_WHEEL);
 	}
 
-	input->dev.parent = hidp_get_device(session);
+	input->dev.parent = &session->conn->dev;
 
 	input->event = hidp_input_event;
 
@@ -808,7 +805,7 @@
 	strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64);
 	strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64);
 
-	hid->dev.parent = hidp_get_device(session);
+	hid->dev.parent = &session->conn->dev;
 	hid->ll_driver = &hidp_hid_driver;
 
 	hid->hid_output_raw_report = hidp_output_raw_report;
@@ -866,6 +863,12 @@
 	session->intr_sock = intr_sock;
 	session->state     = BT_CONNECTED;
 
+	session->conn = hidp_get_connection(session);
+	if (!session->conn) {
+		err = -ENOTCONN;
+		goto failed;
+	}
+
 	setup_timer(&session->timer, hidp_idle_timeout, (unsigned long)session);
 
 	skb_queue_head_init(&session->ctrl_transmit);
@@ -874,6 +877,8 @@
 	session->flags   = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
 	session->idle_to = req->idle_to;
 
+	__hidp_link_session(session);
+
 	if (req->rd_size > 0) {
 		err = hidp_setup_hid(session, req);
 		if (err && err != -ENODEV)
@@ -886,8 +891,6 @@
 			goto purge;
 	}
 
-	__hidp_link_session(session);
-
 	hidp_set_timer(session);
 
 	err = kernel_thread(hidp_session, session, CLONE_KERNEL);
@@ -909,8 +912,6 @@
 unlink:
 	hidp_del_timer(session);
 
-	__hidp_unlink_session(session);
-
 	if (session->input) {
 		input_unregister_device(session->input);
 		session->input = NULL;
@@ -925,6 +926,8 @@
 	session->rd_data = NULL;
 
 purge:
+	__hidp_unlink_session(session);
+
 	skb_queue_purge(&session->ctrl_transmit);
 	skb_queue_purge(&session->intr_transmit);
 
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 44e2feb..6ff8460 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2010-2013 The Linux Foundation. All rights reserved.
    Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
    Copyright (C) 2010 Google Inc.
 
@@ -94,12 +94,18 @@
 static u16 l2cap_get_smallest_flushto(struct l2cap_chan_list *l);
 static void l2cap_set_acl_flushto(struct hci_conn *hcon, u16 flush_to);
 static void l2cap_queue_acl_data(struct work_struct *worker);
+static void l2cap_queue_smp_data(struct work_struct *worker);
 static struct att_channel_parameters{
 	struct sk_buff *skb;
 	struct l2cap_conn *conn;
 	__le16 cid;
 	int dir;
 } att_chn_params;
+static struct smp_channel_params{
+	struct sk_buff *skb;
+	struct l2cap_conn *conn;
+	__le16 cid;
+} smp_chn_params;
 
 /* ---- L2CAP channels ---- */
 static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
@@ -610,6 +616,7 @@
 {
 	if (sk->sk_type == SOCK_RAW) {
 		switch (l2cap_pi(sk)->sec_level) {
+		case BT_SECURITY_VERY_HIGH:
 		case BT_SECURITY_HIGH:
 			return HCI_AT_DEDICATED_BONDING_MITM;
 		case BT_SECURITY_MEDIUM:
@@ -621,12 +628,14 @@
 		if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
 			l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
 
-		if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
+		if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH ||
+			l2cap_pi(sk)->sec_level == BT_SECURITY_VERY_HIGH)
 			return HCI_AT_NO_BONDING_MITM;
 		else
 			return HCI_AT_NO_BONDING;
 	} else {
 		switch (l2cap_pi(sk)->sec_level) {
+		case BT_SECURITY_VERY_HIGH:
 		case BT_SECURITY_HIGH:
 			return HCI_AT_GENERAL_BONDING_MITM;
 		case BT_SECURITY_MEDIUM:
@@ -956,6 +965,8 @@
 
 	sk_for_each(sk, node, &l2cap_sk_list.head) {
 
+		BT_DBG("sock %p scid %d check cid : %d ", sk, l2cap_pi(sk)->scid, cid);
+
 		if (incoming && !l2cap_pi(sk)->incoming)
 			continue;
 
@@ -1217,6 +1228,7 @@
 		kfree(conn);
 	}
 	att_chn_params.conn = NULL;
+  smp_chn_params.conn = NULL;
 	BT_DBG("att_chn_params.conn set to NULL");
 }
 
@@ -7390,6 +7402,7 @@
 	struct sock *sk;
 	u16 cid, len;
 	__le16 psm;
+	struct work_struct *smp_worker;
 
 	skb_pull(skb, L2CAP_HDR_SIZE);
 	cid = __le16_to_cpu(lh->cid);
@@ -7419,8 +7432,39 @@
 		break;
 
 	case L2CAP_CID_SMP:
+		BT_DBG("get socket state");
+		sk = l2cap_find_sock_by_fixed_cid_and_dir(
+		   L2CAP_CID_LE_DATA, conn->src, conn->dst, 1);
+		if (sk) {
+			BT_DBG("socket exists sk %p", sk);
+			bh_lock_sock(sk);
+
+			if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) {
+				BT_DBG("socket state sk %p state %d", sk, sk->sk_state);
+				smp_chn_params.cid = L2CAP_CID_LE_DATA;
+				smp_chn_params.conn = conn;
+				smp_chn_params.skb = skb;
+				smp_worker = kzalloc(sizeof(*smp_worker), GFP_ATOMIC);
+				if (!smp_worker) {
+					BT_ERR("Out of memory smp_worker");
+				} else {
+					INIT_WORK(smp_worker, l2cap_queue_smp_data);
+					BT_DBG("schedule smp_worker");
+					schedule_work(smp_worker);
+				}
+
+				bh_unlock_sock(sk);
+				goto done;
+			} else {
+				BT_DBG("Socket state is BT_BOUND and BT_CONNECTED ");
+				bh_unlock_sock(sk);
+			}
+		}
+
 		if (smp_sig_channel(conn, skb))
 			l2cap_conn_del(conn->hcon, EACCES, 0);
+
+done:
 		break;
 
 	default:
@@ -7533,7 +7577,8 @@
 		if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
 			l2cap_sock_clear_timer(sk);
 			l2cap_sock_set_timer(sk, HZ * 5);
-		} else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
+		} else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH ||
+			l2cap_pi(sk)->sec_level == BT_SECURITY_VERY_HIGH)
 			__l2cap_sock_close(sk, ECONNREFUSED);
 	} else {
 		if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
@@ -7806,6 +7851,68 @@
 	return 0;
 }
 
+static void l2cap_queue_smp_data(struct work_struct *worker)
+{
+	struct sock *sk = NULL;
+	struct hci_conn *hcon = NULL;
+	int attempts = 0;
+	__u8 reason;
+
+	for (attempts = 0; attempts < 40; attempts++) {
+		msleep(50);
+		BT_DBG("sock state check attempt %d", attempts);
+		if (!smp_chn_params.conn) {
+			BT_DBG("smp_chn_params.conn is NULL");
+			return;
+		}
+		sk = l2cap_find_sock_by_fixed_cid_and_dir(
+		   smp_chn_params.cid,
+		   smp_chn_params.conn->src,
+		   smp_chn_params.conn->dst, 1);
+
+		if (!sk) {
+			BT_DBG("sock does not exist");
+			goto err;
+		}
+
+		bh_lock_sock(sk);
+		if (sk->sk_state == BT_CONNECTED) {
+			BT_DBG("sock state BT_CONNECTED");
+
+			bh_unlock_sock(sk);
+			if (smp_sig_channel(
+			   smp_chn_params.conn,
+			   smp_chn_params.skb))
+				l2cap_conn_del(
+				   smp_chn_params.conn->hcon,
+				   EACCES, 0);
+			return;
+		}
+		bh_unlock_sock(sk);
+	}
+
+err:
+	//If sock state is not connected after 40 attepmts
+	//respond to the remote saying SMP_UNSPECIFIED
+	hcon = smp_chn_params.conn->hcon;
+	reason = SMP_UNSPECIFIED;
+	BT_ERR("SMP_CMD_PAIRING_FAIL: %d", reason);
+	smp_conn_security_fail(
+	   smp_chn_params.conn,
+	   SMP_CMD_PAIRING_FAIL,
+	   reason);
+	del_timer(&hcon->smp_timer);
+	clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
+	mgmt_auth_failed(hcon->hdev->id,
+					 smp_chn_params.conn->dst,
+					 reason);
+	hci_conn_put(hcon);
+
+	kfree_skb(smp_chn_params.skb);
+	l2cap_conn_del(smp_chn_params.conn->hcon, EACCES, 0);
+}
+
+
 static void l2cap_queue_acl_data(struct work_struct *worker)
 {
 	struct sock *sk = NULL;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 761f868..d778ae3 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2011-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2000-2001, 2011-2012 The Linux Foundation.  All rights reserved.
    Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
    Copyright (C) 2010 Google Inc.
 
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 1cd09f9..dc6281e 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1,7 +1,7 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
    Copyright (C) 2010  Nokia Corporation
-   Copyright (c) 2011-2012 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2011-2012 The Linux Foundation.  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
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index dc4bf2f..195271a 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1,5 +1,6 @@
 /*
    RFCOMM implementation for Linux Bluetooth stack (BlueZ).
+   Copyright (c) 2013 The Linux Foundation.  All rights reserved.
    Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
    Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
 
@@ -262,6 +263,7 @@
 	__u8 auth_type;
 
 	switch (d->sec_level) {
+	case BT_SECURITY_VERY_HIGH:
 	case BT_SECURITY_HIGH:
 		auth_type = HCI_AT_GENERAL_BONDING_MITM;
 		break;
@@ -2163,7 +2165,8 @@
 				set_bit(RFCOMM_SEC_PENDING, &d->flags);
 				rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
 				continue;
-			} else if (d->sec_level == BT_SECURITY_HIGH) {
+			} else if (d->sec_level == BT_SECURITY_HIGH ||
+				d->sec_level == BT_SECURITY_VERY_HIGH) {
 				__rfcomm_dlc_close(d, ECONNREFUSED);
 				continue;
 			}
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 66cc1f0..297729c 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -1,5 +1,6 @@
 /*
    RFCOMM implementation for Linux Bluetooth stack (BlueZ).
+   Copyright (c) 2013 The Linux Foundation.  All rights reserved.
    Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
    Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
 
@@ -707,12 +708,13 @@
 			break;
 		}
 
-		if (sec.level > BT_SECURITY_HIGH) {
+		if (sec.level > BT_SECURITY_VERY_HIGH) {
 			err = -EINVAL;
 			break;
 		}
 
 		rfcomm_pi(sk)->sec_level = sec.level;
+		BT_DBG("set to %d", sec.level);
 		break;
 
 	case BT_DEFER_SETUP:
@@ -763,6 +765,7 @@
 			opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
 			break;
 		case BT_SECURITY_HIGH:
+		case BT_SECURITY_VERY_HIGH:
 			opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT |
 							RFCOMM_LM_SECURE;
 			break;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 8cec741..3170190 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -1,7 +1,7 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
    Copyright (C) 2000-2001 Qualcomm Incorporated
-   Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2011, The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 517779f..75a74ac 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1,5 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
+   Copyright (c) 2013 The Linux Foundation.  All rights reserved.
    Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 
    This program is free software; you can redistribute it and/or modify
@@ -213,6 +214,7 @@
 static __u8 seclevel_to_authreq(__u8 level)
 {
 	switch (level) {
+	case BT_SECURITY_VERY_HIGH:
 	case BT_SECURITY_HIGH:
 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
 
@@ -1033,6 +1035,12 @@
 	return 0;
 }
 
+void smp_conn_security_fail(struct l2cap_conn *conn, u8 code, u8 reason)
+{
+	BT_DBG("smp: %d %d ", code, reason);
+	smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), &reason);
+}
+
 int smp_link_encrypt_cmplt(struct l2cap_conn *conn, u8 status, u8 encrypt)
 {
 	struct hci_conn *hcon = conn->hcon;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 5063fa3..8861f91 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -145,6 +145,12 @@
 {
 	struct fib_info *fi = container_of(head, struct fib_info, rcu);
 
+	change_nexthops(fi) {
+		if (nexthop_nh->nh_dev)
+			dev_put(nexthop_nh->nh_dev);
+	} endfor_nexthops(fi);
+
+	release_net(fi->fib_net);
 	if (fi->fib_metrics != (u32 *) dst_default_metrics)
 		kfree(fi->fib_metrics);
 	kfree(fi);
@@ -156,13 +162,7 @@
 		pr_warn("Freeing alive fib_info %p\n", fi);
 		return;
 	}
-	change_nexthops(fi) {
-		if (nexthop_nh->nh_dev)
-			dev_put(nexthop_nh->nh_dev);
-		nexthop_nh->nh_dev = NULL;
-	} endfor_nexthops(fi);
 	fib_info_cnt--;
-	release_net(fi->fib_net);
 	call_rcu(&fi->rcu, free_fib_info_rcu);
 }
 
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 677d659..685553b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -984,9 +984,11 @@
 		return -ENOENT;
 	}
 
-	/* in station mode, supported rates are only valid with TDLS */
+	/* in station mode, some updates are only valid with TDLS */
 	if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-	    params->supported_rates &&
+	    (params->supported_rates || params->ht_capa || params->vht_capa ||
+	     params->sta_modify_mask ||
+	     (params->sta_flags_mask & BIT(NL80211_STA_FLAG_WME))) &&
 	    !test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
 		mutex_unlock(&local->sta_mtx);
 		return -EINVAL;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index db8fae5..a99a715 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -378,6 +378,7 @@
 	IEEE80211_STA_UAPSD_ENABLED	= BIT(7),
 	IEEE80211_STA_NULLFUNC_ACKED	= BIT(8),
 	IEEE80211_STA_RESET_SIGNAL_AVE	= BIT(9),
+	IEEE80211_STA_DISABLE_VHT	= BIT(11),
 };
 
 struct ieee80211_mgd_auth_data {
@@ -1475,6 +1476,8 @@
 				struct ieee80211_channel *channel,
 				enum nl80211_channel_type channel_type);
 
+u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
+			       u32 cap);
 /* internal work items */
 void ieee80211_work_init(struct ieee80211_local *local);
 void ieee80211_add_work(struct ieee80211_work *wk);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 1633648..018e3fb 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -673,7 +673,7 @@
 	int result, i;
 	enum ieee80211_band band;
 	int channels, max_bitrates;
-	bool supp_ht;
+	bool supp_ht, supp_vht;
 	static const u32 cipher_suites[] = {
 		/* keep WEP first, it may be removed below */
 		WLAN_CIPHER_SUITE_WEP40,
@@ -706,6 +706,7 @@
 	channels = 0;
 	max_bitrates = 0;
 	supp_ht = false;
+	supp_vht = false;
 	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 		struct ieee80211_supported_band *sband;
 
@@ -723,6 +724,7 @@
 		if (max_bitrates < sband->n_bitrates)
 			max_bitrates = sband->n_bitrates;
 		supp_ht = supp_ht || sband->ht_cap.ht_supported;
+		supp_vht = supp_vht || sband->vht_cap.vht_supported;
 	}
 
 	local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) +
@@ -798,6 +800,10 @@
 	if (supp_ht)
 		local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
 
+	if (supp_vht)
+		local->scan_ies_len +=
+			2 + sizeof(struct ieee80211_vht_cap);
+
 	if (!local->ops->hw_scan) {
 		/* For hw_scan, driver needs to set these up. */
 		local->hw.wiphy->max_scan_ssids = 4;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 20c680b..a48a35c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -383,6 +383,26 @@
 	ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
 }
 
+static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
+				 struct sk_buff *skb,
+				 struct ieee80211_supported_band *sband)
+{
+	u8 *pos;
+	u32 cap;
+	struct ieee80211_sta_vht_cap vht_cap;
+
+	BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap));
+
+	memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));
+
+	/* determine capability flags */
+	cap = vht_cap.cap;
+
+	/* reserve and fill IE */
+	pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
+	ieee80211_ie_build_vht_cap(pos, &vht_cap, cap);
+}
+
 static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
 {
 	struct ieee80211_local *local = sdata->local;
@@ -428,6 +448,7 @@
 			4 + /* power capability */
 			2 + 2 * sband->n_channels + /* supported channels */
 			2 + sizeof(struct ieee80211_ht_cap) + /* HT */
+			2 + sizeof(struct ieee80211_vht_cap) + /* VHT */
 			assoc_data->ie_len + /* extra IEs */
 			9, /* WMM */
 			GFP_KERNEL);
@@ -560,6 +581,9 @@
 		ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie,
 				    sband, local->oper_channel, ifmgd->ap_smps);
 
+	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
+		ieee80211_add_vht_ie(sdata, skb, sband);
+
 	/* if present, add any custom non-vendor IEs that go after HT */
 	if (assoc_data->ie_len && assoc_data->ie) {
 		noffset = ieee80211_ie_split_vendor(assoc_data->ie,
@@ -3289,6 +3313,7 @@
 
 	ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
 	ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
+	ifmgd->flags &= ~IEEE80211_STA_DISABLE_VHT;
 
 	ifmgd->beacon_crc_valid = false;
 
@@ -3299,14 +3324,21 @@
 	 * We can set this to true for non-11n hardware, that'll be checked
 	 * separately along with the peer capabilities.
 	 */
-	for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
+	for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) {
 		if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
 		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
-		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
+		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) {
 			ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+			ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
+			netdev_info(sdata->dev,
+				    "disabling HT/VHT due to WEP/TKIP use\n");
+		}
+	}
 
-	if (req->flags & ASSOC_REQ_DISABLE_HT)
+	if (req->flags & ASSOC_REQ_DISABLE_HT) {
 		ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+		ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
+	}
 
 	/* Also disable HT if we don't support it or the AP doesn't use WMM */
 	sband = local->hw.wiphy->bands[req->bss->channel->band];
@@ -3314,6 +3346,14 @@
 	    local->hw.queues < 4 || !bss->wmm_used)
 		ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
 
+	/* disable VHT if we don't support it or the AP doesn't use WMM */
+	if (!sband->vht_cap.vht_supported ||
+	    local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) {
+		ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
+		netdev_info(sdata->dev,
+			    "disabling VHT as WMM/QoS is not supported\n");
+	}
+
 	memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
 	memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask,
 	       sizeof(ifmgd->ht_capa_mask));
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 32f7a3b..1faea9d 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1031,6 +1031,9 @@
 		pos += noffset - offset;
 	}
 
+	if (sband->vht_cap.vht_supported)
+		pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap,
+						 sband->vht_cap.cap);
 	return pos - buffer;
 }
 
@@ -1611,6 +1614,27 @@
 	return pos;
 }
 
+u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
+							   u32 cap)
+{
+	__le32 tmp;
+
+	*pos++ = WLAN_EID_VHT_CAPABILITY;
+	*pos++ = sizeof(struct ieee80211_vht_cap);
+	memset(pos, 0, sizeof(struct ieee80211_vht_cap));
+
+	/* capability flags */
+	tmp = cpu_to_le32(cap);
+	memcpy(pos, &tmp, sizeof(u32));
+	pos += sizeof(u32);
+
+	/* VHT MCS set */
+	memcpy(pos, &vht_cap->vht_mcs, sizeof(vht_cap->vht_mcs));
+	pos += sizeof(vht_cap->vht_mcs);
+
+	return pos;
+}
+
 u8 *ieee80211_ie_build_ht_info(u8 *pos,
 			       struct ieee80211_sta_ht_cap *ht_cap,
 			       struct ieee80211_channel *channel,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e73504e..72c9a89 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -206,6 +206,25 @@
 	[NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
 	[NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
 	[NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
+	[NL80211_ATTR_WDEV] = { .type = NLA_U64 },
+	[NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
+	[NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, },
+	[NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
+	[NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
+	[NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
+	[NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
+	[NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
+	[NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
+	[NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
+	[NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
+	[NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
+	[NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
+	[NL80211_ATTR_VHT_CAPABILITY_MASK] = {
+		.len = NL80211_VHT_CAPABILITY_LEN,
+	},
+	[NL80211_ATTR_MDID] = { .type = NLA_U16 },
+	[NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
+				  .len = IEEE80211_MAX_DATA_LEN },
 };
 
 /* policy for the key attributes */
@@ -811,6 +830,15 @@
 				dev->wiphy.bands[band]->ht_cap.ampdu_density);
 		}
 
+		/* add VHT info */
+		if (dev->wiphy.bands[band]->vht_cap.vht_supported &&
+		    (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
+			     sizeof(dev->wiphy.bands[band]->vht_cap.vht_mcs),
+			     &dev->wiphy.bands[band]->vht_cap.vht_mcs) ||
+		     nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
+				 dev->wiphy.bands[band]->vht_cap.cap)))
+			goto nla_put_failure;
+
 		/* add frequencies */
 		nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
 		if (!nl_freqs)
@@ -2369,25 +2397,46 @@
 
 	rate = nla_nest_start(msg, attr);
 	if (!rate)
-		goto nla_put_failure;
+		return false;
 
 	/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
 	bitrate = cfg80211_calculate_bitrate(info);
 	if (bitrate > 0)
-		NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
+		nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
 
-	if (info->flags & RATE_INFO_FLAGS_MCS)
-		NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS, info->mcs);
-	if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
-		NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
-	if (info->flags & RATE_INFO_FLAGS_SHORT_GI)
-		NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
+	if (info->flags & RATE_INFO_FLAGS_MCS) {
+		if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
+			return false;
+		if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
+		    nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
+			return false;
+		if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
+		    nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
+			return false;
+	} else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
+		if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
+			return false;
+		if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
+			return false;
+		if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
+		    nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
+			return false;
+		if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH &&
+		    nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH))
+			return false;
+		if (info->flags & RATE_INFO_FLAGS_80P80_MHZ_WIDTH &&
+		    nla_put_flag(msg, NL80211_RATE_INFO_80P80_MHZ_WIDTH))
+			return false;
+		if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH &&
+		    nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH))
+			return false;
+		if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
+		    nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
+			return false;
+	}
 
 	nla_nest_end(msg, rate);
 	return true;
-
-nla_put_failure:
-	return false;
 }
 
 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
@@ -2622,6 +2671,54 @@
 	return ERR_PTR(ret);
 }
 
+static struct nla_policy
+nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
+	[NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
+	[NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
+};
+
+static int nl80211_set_station_tdls(struct genl_info *info,
+				    struct station_parameters *params)
+{
+	struct nlattr *tb[NL80211_STA_WME_MAX + 1];
+	struct nlattr *nla;
+	int err;
+
+	/* Dummy STA entry gets updated once the peer capabilities are known */
+	if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
+		params->ht_capa =
+			nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
+	if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+		params->vht_capa =
+			nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
+
+	/* parse WME attributes if present */
+	if (!info->attrs[NL80211_ATTR_STA_WME])
+		return 0;
+
+	nla = info->attrs[NL80211_ATTR_STA_WME];
+	err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
+			       nl80211_sta_wme_policy);
+	if (err)
+		return err;
+
+	if (tb[NL80211_STA_WME_UAPSD_QUEUES])
+		params->uapsd_queues = nla_get_u8(
+			tb[NL80211_STA_WME_UAPSD_QUEUES]);
+	if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
+		return -EINVAL;
+
+	if (tb[NL80211_STA_WME_MAX_SP])
+		params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
+
+	if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
+		return -EINVAL;
+
+	params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
+
+	return 0;
+}
+
 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2650,6 +2747,19 @@
 			nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
 	}
 
+	if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
+		params.capability =
+			nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
+		params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
+	}
+
+	if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
+		params.ext_capab =
+			nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+		params.ext_capab_len =
+			nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+	}
+
 	if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
 		params.listen_interval =
 		    nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
@@ -2698,6 +2808,14 @@
 				  BIT(NL80211_STA_FLAG_MFP)))
 			return -EINVAL;
 
+		if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
+			return -EINVAL;
+		if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
+			return -EINVAL;
+		if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
+		    info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+			return -EINVAL;
+
 		/* must be last in here for error handling */
 		params.vlan = get_vlan(info, rdev);
 		if (IS_ERR(params.vlan))
@@ -2712,7 +2830,17 @@
 		 * to change the flag.
 		 */
 		params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
-		/* fall through */
+		/* Include parameters for TDLS peer (driver will check) */
+		err = nl80211_set_station_tdls(info, &params);
+		if (err)
+			return err;
+		/* disallow things sta doesn't support */
+		if (params.plink_action)
+			return -EINVAL;
+		if (params.sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
+					      BIT(NL80211_STA_FLAG_WME)))
+			return -EINVAL;
+		break;
 	case NL80211_IFTYPE_ADHOC:
 		/* disallow things sta doesn't support */
 		if (params.plink_action)
@@ -2721,6 +2849,9 @@
 			return -EINVAL;
 		if (params.listen_interval >= 0)
 			return -EINVAL;
+		if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
+		    info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+			return -EINVAL;
 		/* reject any changes other than AUTHORIZED */
 		if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
 			return -EINVAL;
@@ -2733,6 +2864,13 @@
 			return -EINVAL;
 		if (params.listen_interval >= 0)
 			return -EINVAL;
+		if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
+			return -EINVAL;
+		if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
+			return -EINVAL;
+		if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
+		    info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+			return -EINVAL;
 		/*
 		 * No special handling for TDLS here -- the userspace
 		 * mesh code doesn't have this bug.
@@ -2757,12 +2895,6 @@
 	return err;
 }
 
-static struct nla_policy
-nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
-	[NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
-	[NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
-};
-
 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2797,10 +2929,27 @@
 	if (!params.aid || params.aid > IEEE80211_MAX_AID)
 		return -EINVAL;
 
+	if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
+		params.capability =
+			nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
+		params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
+	}
+
+	if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
+		params.ext_capab =
+			nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+		params.ext_capab_len =
+			nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
+	}
+
 	if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
 		params.ht_capa =
 			nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
 
+	if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
+		params.vht_capa =
+			nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
+
 	if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
 		params.plink_action =
 		    nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
@@ -2862,6 +3011,7 @@
 			return -EINVAL;
 		break;
 	case NL80211_IFTYPE_STATION:
+	case NL80211_IFTYPE_P2P_CLIENT:
 		/* Only TDLS peers can be added */
 		if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
 			return -EINVAL;
@@ -6299,6 +6449,27 @@
 	return 0;
 }
 
+static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct cfg80211_update_ft_ies_params ft_params;
+	struct net_device *dev = info->user_ptr[1];
+
+	if (!rdev->ops->update_ft_ies)
+		return -EOPNOTSUPP;
+
+	if (!info->attrs[NL80211_ATTR_MDID] ||
+	    !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+		return -EINVAL;
+
+	memset(&ft_params, 0, sizeof(ft_params));
+	ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
+	ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+	ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+
+	return rdev->ops->update_ft_ies(&rdev->wiphy, dev, &ft_params);
+}
+
 #define NL80211_FLAG_NEED_WIPHY		0x01
 #define NL80211_FLAG_NEED_NETDEV	0x02
 #define NL80211_FLAG_NEED_RTNL		0x04
@@ -6887,6 +7058,14 @@
 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
 				  NL80211_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL80211_CMD_UPDATE_FT_IES,
+		.doit = nl80211_update_ft_ies,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
 
 };
 
@@ -8124,6 +8303,48 @@
 	.notifier_call = nl80211_netlink_notify,
 };
 
+void cfg80211_ft_event(struct net_device *netdev,
+		       struct cfg80211_ft_event_params *ft_event)
+{
+	struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	struct sk_buff *msg;
+	void *hdr;
+	int err;
+
+	if (!ft_event->target_ap)
+		return;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+	nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+	nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap);
+	if (ft_event->ies)
+		nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies);
+	if (ft_event->ric_ies)
+		nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
+			ft_event->ric_ies);
+
+	err = genlmsg_end(msg, hdr);
+	if (err < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_mlme_mcgrp.id, GFP_KERNEL);
+}
+EXPORT_SYMBOL(cfg80211_ft_event);
+
 /* initialisation/exit functions */
 
 int nl80211_init(void)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index a448b80..7dcb067 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -876,13 +876,86 @@
 	return err;
 }
 
+static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
+{
+	static const u32 base[4][10] = {
+		{   6500000,
+		   13000000,
+		   19500000,
+		   26000000,
+		   39000000,
+		   52000000,
+		   58500000,
+		   65000000,
+		   78000000,
+		   0,
+		},
+		{  13500000,
+		   27000000,
+		   40500000,
+		   54000000,
+		   81000000,
+		  108000000,
+		  121500000,
+		  135000000,
+		  162000000,
+		  180000000,
+		},
+		{  29300000,
+		   58500000,
+		   87800000,
+		  117000000,
+		  175500000,
+		  234000000,
+		  263300000,
+		  292500000,
+		  351000000,
+		  390000000,
+		},
+		{  58500000,
+		  117000000,
+		  175500000,
+		  234000000,
+		  351000000,
+		  468000000,
+		  526500000,
+		  585000000,
+		  702000000,
+		  780000000,
+		},
+	};
+	u32 bitrate;
+	int idx;
+
+	if (WARN_ON_ONCE(rate->mcs > 9))
+		return 0;
+
+	idx = rate->flags & (RATE_INFO_FLAGS_160_MHZ_WIDTH |
+			     RATE_INFO_FLAGS_80P80_MHZ_WIDTH) ? 3 :
+		  rate->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH ? 2 :
+		  rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH ? 1 : 0;
+
+	bitrate = base[idx][rate->mcs];
+	bitrate *= rate->nss;
+
+	if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+		bitrate = (bitrate / 9) * 10;
+
+	/* do NOT round down here */
+	return (bitrate + 50000) / 100000;
+}
+
 u16 cfg80211_calculate_bitrate(struct rate_info *rate)
 {
 	int modulation, streams, bitrate;
 
-	if (!(rate->flags & RATE_INFO_FLAGS_MCS))
+	if (!(rate->flags & RATE_INFO_FLAGS_MCS) &&
+	    !(rate->flags & RATE_INFO_FLAGS_VHT_MCS))
 		return rate->legacy;
 
+	if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
+		return cfg80211_calculate_bitrate_vht(rate);
+
 	/* the formula below does only work for MCS values smaller than 32 */
 	if (rate->mcs >= 32)
 		return 0;
diff --git a/scripts/build-all.py b/scripts/build-all.py
index 296d9ad..52ebe26 100755
--- a/scripts/build-all.py
+++ b/scripts/build-all.py
@@ -1,6 +1,6 @@
 #! /usr/bin/env python
 
-# Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+# Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -9,7 +9,7 @@
 #     * Redistributions in binary form must reproduce the above copyright
 #       notice, this list of conditions and the following disclaimer in the
 #       documentation and/or other materials provided with the distribution.
-#     * Neither the name of Code Aurora nor
+#     * Neither the name of The Linux Foundation nor
 #       the names of its contributors may be used to endorse or promote
 #       products derived from this software without specific prior written
 #       permission.
diff --git a/scripts/gcc-wrapper.py b/scripts/gcc-wrapper.py
index 583a5ce..27e76a7 100755
--- a/scripts/gcc-wrapper.py
+++ b/scripts/gcc-wrapper.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+# Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -10,7 +10,7 @@
 #     * Redistributions in binary form must reproduce the above copyright
 #       notice, this list of conditions and the following disclaimer in the
 #       documentation and/or other materials provided with the distribution.
-#     * Neither the name of Code Aurora nor
+#     * Neither the name of The Linux Foundation nor
 #       the names of its contributors may be used to endorse or promote
 #       products derived from this software without specific prior written
 #       permission.
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 44ddaa5..f527f4f 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -156,7 +156,7 @@
 }
 
 /* USB is special because the bcdDevice can be matched against a numeric range */
-/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */
+/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */
 static void do_usb_entry(struct usb_device_id *id,
 			 unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
 			 unsigned char range_lo, unsigned char range_hi,
@@ -210,6 +210,9 @@
 	ADD(alias, "ip",
 	    id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
 	    id->bInterfaceProtocol);
+	ADD(alias, "in",
+	    id->match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER,
+	    id->bInterfaceNumber);
 
 	add_wildcard(alias);
 	buf_printf(&mod->dev_table_buf,
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 4636247..4cbbc96 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2604,6 +2604,7 @@
 	case SNDRV_COMPRESS_GET_PARAMS:
 	case SNDRV_COMPRESS_TSTAMP:
 	case SNDRV_COMPRESS_DRAIN:
+	case SNDRV_COMPRESS_METADATA_MODE:
 		return snd_compressed_ioctl(substream, cmd, arg);
 	}
 	snd_printd("unknown ioctl = 0x%x\n", cmd);
diff --git a/sound/soc/codecs/cs8427.c b/sound/soc/codecs/cs8427.c
index 23870a4..9e7c3ee 100644
--- a/sound/soc/codecs/cs8427.c
+++ b/sound/soc/codecs/cs8427.c
@@ -2,7 +2,7 @@
  *  Routines for control of the CS8427 via i2c bus
  *  IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic
  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *  Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/codecs/msm_stub.c b/sound/soc/codecs/msm_stub.c
index 7e603b4..4a9d663 100644
--- a/sound/soc/codecs/msm_stub.c
+++ b/sound/soc/codecs/msm_stub.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/sound/soc/codecs/timpani.c b/sound/soc/codecs/timpani.c
index 786b2d6..f80c0fc 100644
--- a/sound/soc/codecs/timpani.c
+++ b/sound/soc/codecs/timpani.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/sound/soc/codecs/timpani.h b/sound/soc/codecs/timpani.h
index bd14eea..bfa0b8b 100644
--- a/sound/soc/codecs/timpani.h
+++ b/sound/soc/codecs/timpani.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/sound/soc/codecs/wcd9304-tables.c b/sound/soc/codecs/wcd9304-tables.c
index f0d76e8..83c0c1d 100644
--- a/sound/soc/codecs/wcd9304-tables.c
+++ b/sound/soc/codecs/wcd9304-tables.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -419,6 +419,10 @@
 	[SITAR_A_QFUSE_DATA_OUT1] = 1,
 	[SITAR_A_QFUSE_DATA_OUT2] = 1,
 	[SITAR_A_QFUSE_DATA_OUT3] = 1,
+	[SITAR_A_QFUSE_DATA_OUT4] = 1,
+	[SITAR_A_QFUSE_DATA_OUT5] = 1,
+	[SITAR_A_QFUSE_DATA_OUT6] = 1,
+	[SITAR_A_QFUSE_DATA_OUT7] = 1,
 	[SITAR_A_CDC_CTL] = 1,
 	[SITAR_A_LEAKAGE_CTL] = 1,
 	[SITAR_A_INTR_MODE] = 1,
@@ -428,6 +432,9 @@
 	[SITAR_A_INTR_STATUS0] = 1,
 	[SITAR_A_INTR_STATUS1] = 1,
 	[SITAR_A_INTR_STATUS2] = 1,
+	[SITAR_A_INTR_CLEAR0] = 1,
+	[SITAR_A_INTR_CLEAR1] = 1,
+	[SITAR_A_INTR_CLEAR2] = 1,
 	[SITAR_A_INTR_LEVEL0] = 1,
 	[SITAR_A_INTR_LEVEL1] = 1,
 	[SITAR_A_INTR_LEVEL2] = 1,
@@ -593,24 +600,76 @@
 	[SITAR_A_CDC_ANC1_SPARE] = 1,
 	[SITAR_A_CDC_ANC1_SMLPF_CTL] = 1,
 	[SITAR_A_CDC_ANC1_DCFLT_CTL] = 1,
+	[SITAR_A_CDC_ANC2_CTL] = 1,
+	[SITAR_A_CDC_ANC2_SHIFT] = 1,
+	[SITAR_A_CDC_ANC2_IIR_B1_CTL] = 1,
+	[SITAR_A_CDC_ANC2_IIR_B2_CTL] = 1,
+	[SITAR_A_CDC_ANC2_IIR_B3_CTL] = 1,
+	[SITAR_A_CDC_ANC2_IIR_B4_CTL] = 1,
+	[SITAR_A_CDC_ANC2_LPF_B1_CTL] = 1,
+	[SITAR_A_CDC_ANC2_LPF_B2_CTL] = 1,
+	[SITAR_A_CDC_ANC2_LPF_B3_CTL] = 1,
+	[SITAR_A_CDC_ANC2_SPARE] = 1,
+	[SITAR_A_CDC_ANC2_SMLPF_CTL] = 1,
+	[SITAR_A_CDC_ANC2_DCFLT_CTL] = 1,
 	[SITAR_A_CDC_TX1_VOL_CTL_TIMER] = 1,
 	[SITAR_A_CDC_TX1_VOL_CTL_GAIN] = 1,
 	[SITAR_A_CDC_TX1_VOL_CTL_CFG] = 1,
 	[SITAR_A_CDC_TX1_MUX_CTL] = 1,
 	[SITAR_A_CDC_TX1_CLK_FS_CTL] = 1,
 	[SITAR_A_CDC_TX1_DMIC_CTL] = 1,
+	[SITAR_A_CDC_TX2_VOL_CTL_TIMER] = 1,
+	[SITAR_A_CDC_TX2_VOL_CTL_GAIN] = 1,
+	[SITAR_A_CDC_TX2_VOL_CTL_CFG] = 1,
+	[SITAR_A_CDC_TX2_MUX_CTL] = 1,
+	[SITAR_A_CDC_TX2_CLK_FS_CTL] = 1,
+	[SITAR_A_CDC_TX2_DMIC_CTL] = 1,
+	[SITAR_A_CDC_TX3_VOL_CTL_TIMER] = 1,
+	[SITAR_A_CDC_TX3_VOL_CTL_GAIN] = 1,
+	[SITAR_A_CDC_TX3_VOL_CTL_CFG] = 1,
+	[SITAR_A_CDC_TX3_MUX_CTL] = 1,
+	[SITAR_A_CDC_TX3_CLK_FS_CTL] = 1,
+	[SITAR_A_CDC_TX3_DMIC_CTL] = 1,
+	[SITAR_A_CDC_TX4_VOL_CTL_TIMER] = 1,
+	[SITAR_A_CDC_TX4_VOL_CTL_GAIN] = 1,
+	[SITAR_A_CDC_TX4_VOL_CTL_CFG] = 1,
+	[SITAR_A_CDC_TX4_MUX_CTL] = 1,
+	[SITAR_A_CDC_TX4_CLK_FS_CTL] = 1,
+	[SITAR_A_CDC_TX4_DMIC_CTL] = 1,
+	[SITAR_A_CDC_TX5_VOL_CTL_TIMER] = 1,
+	[SITAR_A_CDC_TX5_VOL_CTL_GAIN] = 1,
+	[SITAR_A_CDC_TX5_VOL_CTL_CFG] = 1,
+	[SITAR_A_CDC_TX5_MUX_CTL] = 1,
+	[SITAR_A_CDC_TX5_CLK_FS_CTL] = 1,
+	[SITAR_A_CDC_TX5_DMIC_CTL] = 1,
 	[SITAR_A_CDC_SRC1_PDA_CFG] = 1,
 	[SITAR_A_CDC_SRC1_FS_CTL] = 1,
+	[SITAR_A_CDC_SRC2_PDA_CFG] = 1,
+	[SITAR_A_CDC_SRC2_FS_CTL] = 1,
 	[SITAR_A_CDC_RX1_B1_CTL] = 1,
 	[SITAR_A_CDC_RX1_B2_CTL] = 1,
 	[SITAR_A_CDC_RX1_B3_CTL] = 1,
 	[SITAR_A_CDC_RX1_B4_CTL] = 1,
 	[SITAR_A_CDC_RX1_B5_CTL] = 1,
-	[SITAR_A_CDC_RX2_B5_CTL] = 1,
-	[SITAR_A_CDC_RX3_B5_CTL] = 1,
 	[SITAR_A_CDC_RX1_B6_CTL] = 1,
 	[SITAR_A_CDC_RX1_VOL_CTL_B1_CTL] = 1,
 	[SITAR_A_CDC_RX1_VOL_CTL_B2_CTL] = 1,
+	[SITAR_A_CDC_RX2_B1_CTL] = 1,
+	[SITAR_A_CDC_RX2_B2_CTL] = 1,
+	[SITAR_A_CDC_RX2_B3_CTL] = 1,
+	[SITAR_A_CDC_RX2_B4_CTL] = 1,
+	[SITAR_A_CDC_RX2_B5_CTL] = 1,
+	[SITAR_A_CDC_RX2_B6_CTL] = 1,
+	[SITAR_A_CDC_RX2_VOL_CTL_B1_CTL] = 1,
+	[SITAR_A_CDC_RX2_VOL_CTL_B2_CTL] = 1,
+	[SITAR_A_CDC_RX3_B1_CTL] = 1,
+	[SITAR_A_CDC_RX3_B2_CTL] = 1,
+	[SITAR_A_CDC_RX3_B3_CTL] = 1,
+	[SITAR_A_CDC_RX3_B4_CTL] = 1,
+	[SITAR_A_CDC_RX3_B5_CTL] = 1,
+	[SITAR_A_CDC_RX3_B6_CTL] = 1,
+	[SITAR_A_CDC_RX3_VOL_CTL_B1_CTL] = 1,
+	[SITAR_A_CDC_RX3_VOL_CTL_B2_CTL] = 1,
 	[SITAR_A_CDC_CLK_ANC_RESET_CTL] = 1,
 	[SITAR_A_CDC_CLK_RX_RESET_CTL] = 1,
 	[SITAR_A_CDC_CLK_TX_RESET_B1_CTL] = 1,
@@ -652,6 +711,21 @@
 	[SITAR_A_CDC_IIR1_COEF_B3_CTL] = 1,
 	[SITAR_A_CDC_IIR1_COEF_B4_CTL] = 1,
 	[SITAR_A_CDC_IIR1_COEF_B5_CTL] = 1,
+	[SITAR_A_CDC_IIR2_GAIN_B1_CTL] = 1,
+	[SITAR_A_CDC_IIR2_GAIN_B2_CTL] = 1,
+	[SITAR_A_CDC_IIR2_GAIN_B3_CTL] = 1,
+	[SITAR_A_CDC_IIR2_GAIN_B4_CTL] = 1,
+	[SITAR_A_CDC_IIR2_GAIN_B5_CTL] = 1,
+	[SITAR_A_CDC_IIR2_GAIN_B6_CTL] = 1,
+	[SITAR_A_CDC_IIR2_GAIN_B7_CTL] = 1,
+	[SITAR_A_CDC_IIR2_GAIN_B8_CTL] = 1,
+	[SITAR_A_CDC_IIR2_CTL] = 1,
+	[SITAR_A_CDC_IIR2_GAIN_TIMER_CTL] = 1,
+	[SITAR_A_CDC_IIR2_COEF_B1_CTL] = 1,
+	[SITAR_A_CDC_IIR2_COEF_B2_CTL] = 1,
+	[SITAR_A_CDC_IIR2_COEF_B3_CTL] = 1,
+	[SITAR_A_CDC_IIR2_COEF_B4_CTL] = 1,
+	[SITAR_A_CDC_IIR2_COEF_B5_CTL] = 1,
 	[SITAR_A_CDC_TOP_GAIN_UPDATE] = 1,
 	[SITAR_A_CDC_TOP_RDAC_DOUT_CTL] = 1,
 	[SITAR_A_CDC_DEBUG_B1_CTL] = 1,
@@ -669,6 +743,14 @@
 	[SITAR_A_CDC_COMP1_B6_CTL] = 1,
 	[SITAR_A_CDC_COMP1_SHUT_DOWN_STATUS] = 1,
 	[SITAR_A_CDC_COMP1_FS_CFG] = 1,
+	[SITAR_A_CDC_COMP2_B1_CTL] = 1,
+	[SITAR_A_CDC_COMP2_B2_CTL] = 1,
+	[SITAR_A_CDC_COMP2_B3_CTL] = 1,
+	[SITAR_A_CDC_COMP2_B4_CTL] = 1,
+	[SITAR_A_CDC_COMP2_B5_CTL] = 1,
+	[SITAR_A_CDC_COMP2_B6_CTL] = 1,
+	[SITAR_A_CDC_COMP2_SHUT_DOWN_STATUS] = 1,
+	[SITAR_A_CDC_COMP2_FS_CFG] = 1,
 	[SITAR_A_CDC_CONN_RX1_B1_CTL] = 1,
 	[SITAR_A_CDC_CONN_RX1_B2_CTL] = 1,
 	[SITAR_A_CDC_CONN_RX1_B3_CTL] = 1,
diff --git a/sound/soc/codecs/wcd9304.c b/sound/soc/codecs/wcd9304.c
index e819c9f..83c5383 100644
--- a/sound/soc/codecs/wcd9304.c
+++ b/sound/soc/codecs/wcd9304.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -34,6 +34,9 @@
 #include <linux/kernel.h>
 #include <linux/gpio.h>
 #include <linux/wait.h>
+#include <linux/irq.h>
+#include <linux/wakelock.h>
+#include <linux/suspend.h>
 #include "wcd9304.h"
 
 #define WCD9304_RATES (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|\
@@ -49,7 +52,8 @@
 #define MBHC_FW_READ_ATTEMPTS 15
 #define MBHC_FW_READ_TIMEOUT 2000000
 
-#define SITAR_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR)
+#define SITAR_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | \
+			SND_JACK_OC_HPHR | SND_JACK_UNSUPPORTED)
 
 #define SITAR_I2S_MASTER_MODE_MASK 0x08
 
@@ -60,6 +64,8 @@
 #define NUM_CODEC_DAIS 2
 #define SLIM_CLOSE_TIMEOUT 1000
 
+#define VDDIO_MICBIAS_MV 1800
+
 struct sitar_codec_dai_data {
 	u32 rate;
 	u32 *ch_num;
@@ -83,12 +89,15 @@
 #define MBHC_NUM_DCE_PLUG_DETECT 3
 #define SITAR_MBHC_FAKE_INSERT_LOW 10
 #define SITAR_MBHC_FAKE_INSERT_HIGH 80
-#define SITAR_MBHC_FAKE_INSERT_VOLT_DELTA_MV 500
+#define SITAR_MBHC_FAKE_INSERT_VOLT_DELTA_MV 300
 #define SITAR_HS_DETECT_PLUG_TIME_MS (5 * 1000)
 #define SITAR_HS_DETECT_PLUG_INERVAL_MS 100
 #define NUM_ATTEMPTS_TO_REPORT 5
 #define SITAR_MBHC_STATUS_REL_DETECTION 0x0C
 #define SITAR_MBHC_GPIO_REL_DEBOUNCE_TIME_MS 200
+#define SITAR_MBHC_GND_MIC_SWAP_THRESHOLD 2
+#define SITAR_MIC_GND_SWAP_DELAY_US 5000
+#define SITAR_USLEEP_RANGE_TOLERANCE 100
 
 #define CUT_OF_FREQ_MASK 0x30
 #define CF_MIN_3DB_4HZ 0x0
@@ -104,6 +113,8 @@
 	struct snd_kcontrol *kcontrol, int event);
 static int sitar_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event);
+static enum sitar_mbhc_plug_type
+sitar_codec_decide_gpio_plug(struct snd_soc_codec *codec);
 
 enum sitar_bandgap_type {
 	SITAR_BANDGAP_OFF = 0,
@@ -166,6 +177,7 @@
 	u16 v_no_mic;
 	u8 npoll;
 	u8 nbounce_wait;
+	s16 adj_v_hs_max;
 };
 
 enum sitar_mbhc_plug_type {
@@ -174,6 +186,7 @@
 	PLUG_TYPE_HEADSET,
 	PLUG_TYPE_HEADPHONE,
 	PLUG_TYPE_HIGH_HPH,
+	PLUG_TYPE_GND_MIC_SWAP,
 };
 
 enum sitar_mbhc_state {
@@ -272,6 +285,9 @@
 	bool hs_detect_work_stop;
 	struct delayed_work mbhc_btn_dwork;
 	unsigned long mbhc_last_resume; /* in jiffies */
+
+	bool gpio_irq_resend;
+	struct wake_lock irq_resend_wlock;
 };
 
 #ifdef CONFIG_DEBUG_FS
@@ -1035,6 +1051,42 @@
 	return 0;
 }
 
+static void sitar_enable_classg(struct snd_soc_codec *codec,
+	bool enable)
+{
+
+	if (enable) {
+		snd_soc_update_bits(codec,
+			SITAR_A_CDC_CLK_OTHR_RESET_CTL, 0x10, 0x00);
+		snd_soc_update_bits(codec, SITAR_A_CP_STATIC, 0x07, 0x00);
+		snd_soc_update_bits(codec, SITAR_A_CP_STATIC, 0x08, 0x00);
+		snd_soc_update_bits(codec, SITAR_A_CP_STATIC, 0x10, 0x00);
+
+	} else {
+		snd_soc_update_bits(codec,
+			SITAR_A_CDC_CLK_OTHR_RESET_CTL, 0x10, 0x10);
+		snd_soc_update_bits(codec, SITAR_A_CP_STATIC, 0x07, 0x03);
+		snd_soc_update_bits(codec, SITAR_A_CP_STATIC, 0x08, 0x08);
+		snd_soc_update_bits(codec, SITAR_A_CP_STATIC, 0x10, 0x10);
+	}
+}
+
+static bool sitar_is_hph_pa_on(struct snd_soc_codec *codec)
+{
+	u8 hph_reg_val = 0;
+	hph_reg_val = snd_soc_read(codec, SITAR_A_RX_HPH_CNP_EN);
+
+	return (hph_reg_val & 0x30) ? true : false;
+}
+
+static bool sitar_is_line_pa_on(struct snd_soc_codec *codec)
+{
+	u8 line_reg_val = 0;
+	line_reg_val = snd_soc_read(codec, SITAR_A_RX_LINE_CNP_EN);
+
+	return (line_reg_val & 0x03) ? true : false;
+}
+
 static int sitar_codec_enable_lineout(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
@@ -1058,6 +1110,15 @@
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
+		if (sitar_is_hph_pa_on(codec)) {
+			snd_soc_update_bits(codec, SITAR_A_CDC_RX1_B6_CTL,
+				0x20, 0x00);
+			sitar_enable_classg(codec, false);
+		} else {
+			snd_soc_update_bits(codec, SITAR_A_CDC_RX1_B6_CTL,
+				0x20, 0x20);
+			sitar_enable_classg(codec, true);
+		}
 		snd_soc_update_bits(codec, lineout_gain_reg, 0x10, 0x10);
 		break;
 	case SND_SOC_DAPM_POST_PMU:
@@ -1066,6 +1127,11 @@
 		usleep_range(16000, 16000);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
+		if (sitar_is_hph_pa_on(codec))
+			sitar_enable_classg(codec, true);
+		else
+			sitar_enable_classg(codec, false);
+
 		snd_soc_update_bits(codec, lineout_gain_reg, 0x10, 0x00);
 		break;
 	}
@@ -1408,14 +1474,6 @@
 	return rc;
 }
 
-static bool sitar_is_hph_pa_on(struct snd_soc_codec *codec)
-{
-	u8 hph_reg_val = 0;
-	hph_reg_val = snd_soc_read(codec, SITAR_A_RX_HPH_CNP_EN);
-
-	return (hph_reg_val & 0x30) ? true : false;
-}
-
 static bool sitar_is_hph_dac_on(struct snd_soc_codec *codec, int left)
 {
 	u8 hph_reg_val = 0;
@@ -1875,6 +1933,11 @@
 			SITAR_RELEASE_LOCK(sitar->codec_resource_lock);
 		}
 
+		if (sitar_is_line_pa_on(codec))
+			sitar_enable_classg(codec, false);
+		else
+			sitar_enable_classg(codec, true);
+
 		break;
 
 	case SND_SOC_DAPM_POST_PMD:
@@ -1907,6 +1970,11 @@
 				w->name);
 		usleep_range(10000, 10000);
 
+		if (sitar_is_line_pa_on(codec))
+			sitar_enable_classg(codec, true);
+		else
+			sitar_enable_classg(codec, false);
+
 		break;
 	}
 	return 0;
@@ -1961,24 +2029,21 @@
 	pr_debug("%s %d\n", __func__, event);
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		snd_soc_update_bits(codec, SITAR_A_CDC_CLK_OTHR_RESET_CTL, 0x10,
-			0x00);
 		snd_soc_update_bits(codec, SITAR_A_CDC_CLK_OTHR_CTL, 0x01,
 			0x01);
 		snd_soc_update_bits(codec, SITAR_A_CDC_CLSG_CTL, 0x08, 0x08);
 		usleep_range(200, 200);
-		snd_soc_update_bits(codec, SITAR_A_CP_STATIC, 0x10, 0x00);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		snd_soc_update_bits(codec, SITAR_A_CDC_CLK_OTHR_RESET_CTL, 0x10,
-			0x10);
-		usleep_range(20, 20);
-		snd_soc_update_bits(codec, SITAR_A_CP_STATIC, 0x08, 0x08);
-		snd_soc_update_bits(codec, SITAR_A_CP_STATIC, 0x10, 0x10);
 		snd_soc_update_bits(codec, SITAR_A_CDC_CLSG_CTL, 0x08, 0x00);
+		/*
+		 * This delay is for the class G controller to settle down
+		 * after turn OFF. The delay is as per the hardware spec for
+		 * the codec
+		 */
+		usleep_range(20, 20);
 		snd_soc_update_bits(codec, SITAR_A_CDC_CLK_OTHR_CTL, 0x01,
 			0x00);
-		snd_soc_update_bits(codec, SITAR_A_CP_STATIC, 0x08, 0x00);
 		break;
 	}
 	return 0;
@@ -2541,6 +2606,12 @@
 		(choice == SITAR_BANDGAP_AUDIO_MODE)) {
 		sitar_codec_enable_audio_mode_bandgap(codec);
 	} else if (choice == SITAR_BANDGAP_MBHC_MODE) {
+		/*
+		 * bandgap mode becomes fast,
+		 * mclk should be off or clk buff source shouldn't be VBG
+		 * Let's turn off mclk always
+		 */
+		WARN_ON(snd_soc_read(codec, SITAR_A_CLK_BUFF_EN2) & (1 << 2));
 		snd_soc_update_bits(codec, SITAR_A_BIAS_CURR_CTL_2, 0x0C, 0x08);
 		snd_soc_update_bits(codec, SITAR_A_BIAS_CENTRAL_BG_CTL, 0x2,
 			0x2);
@@ -2576,23 +2647,23 @@
 {
 	struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
 
+	pr_debug("%s: enable = %d\n", __func__, enable);
 	if (enable) {
 		snd_soc_update_bits(codec, SITAR_A_RC_OSC_FREQ, 0x10, 0);
+		/* bandgap mode to fast */
 		snd_soc_write(codec, SITAR_A_BIAS_OSC_BG_CTL, 0x17);
 		usleep_range(5, 5);
-		snd_soc_update_bits(codec, SITAR_A_RC_OSC_FREQ, 0x80,
-			0x80);
-		snd_soc_update_bits(codec, SITAR_A_RC_OSC_TEST, 0x80,
-			0x80);
+		snd_soc_update_bits(codec, SITAR_A_RC_OSC_FREQ, 0x80, 0x80);
+		snd_soc_update_bits(codec, SITAR_A_RC_OSC_TEST, 0x80, 0x80);
 		usleep_range(10, 10);
 		snd_soc_update_bits(codec, SITAR_A_RC_OSC_TEST, 0x80, 0);
-		usleep_range(20, 20);
+		usleep_range(10000, 10000);
 		snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN1, 0x08, 0x08);
 	} else {
-		snd_soc_update_bits(codec, SITAR_A_BIAS_OSC_BG_CTL, 0x1,
-			0);
+		snd_soc_update_bits(codec, SITAR_A_BIAS_OSC_BG_CTL, 0x1, 0);
 		snd_soc_update_bits(codec, SITAR_A_RC_OSC_FREQ, 0x80, 0);
-		snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN1, 0x08, 0x00);
+		/* clk source to ext clk and clk buff ref to VBG */
+		snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN1, 0x0C, 0x04);
 	}
 	sitar->config_mode_active = enable ? true : false;
 
@@ -2606,23 +2677,28 @@
 
 	pr_debug("%s\n", __func__);
 
+	/* transit to RCO requires mclk off */
+	WARN_ON(snd_soc_read(codec, SITAR_A_CLK_BUFF_EN2) & (1 << 2));
 	if (config_mode) {
+		/* enable RCO and switch to it */
 		sitar_codec_enable_config_mode(codec, 1);
 		snd_soc_write(codec, SITAR_A_CLK_BUFF_EN2, 0x00);
 		snd_soc_write(codec, SITAR_A_CLK_BUFF_EN2, 0x02);
 		snd_soc_write(codec, SITAR_A_CLK_BUFF_EN1, 0x0D);
 		usleep_range(1000, 1000);
-	} else
+	} else {
+		/* switch to MCLK */
 		snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN1, 0x08, 0x00);
 
-	if (!config_mode && sitar->mbhc_polling_active) {
-		snd_soc_write(codec, SITAR_A_CLK_BUFF_EN2, 0x02);
-		sitar_codec_enable_config_mode(codec, 0);
-
+		if (sitar->mbhc_polling_active) {
+			snd_soc_write(codec, SITAR_A_CLK_BUFF_EN2, 0x02);
+			sitar_codec_enable_config_mode(codec, 0);
+		}
 	}
 
-	snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN1, 0x05, 0x05);
+	snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN1, 0x01, 0x01);
 	snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN2, 0x02, 0x00);
+	/* on MCLK */
 	snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN2, 0x04, 0x04);
 	usleep_range(50, 50);
 	sitar->clock_active = true;
@@ -2633,9 +2709,10 @@
 	struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
 	pr_debug("%s\n", __func__);
 	snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN2, 0x04, 0x00);
-	ndelay(160);
+	usleep_range(50, 50);
 	snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN2, 0x02, 0x02);
 	snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN1, 0x05, 0x00);
+	usleep_range(50, 50);
 	sitar->clock_active = false;
 }
 
@@ -2651,6 +2728,20 @@
 	}
 }
 
+static s16 sitar_get_current_v_hs_max(struct sitar_priv *sitar)
+{
+	s16 v_hs_max;
+	struct sitar_mbhc_plug_type_cfg *plug_type;
+
+	plug_type = SITAR_MBHC_CAL_PLUG_TYPE_PTR(sitar->mbhc_cfg.calibration);
+	if ((sitar->mbhc_data.micb_mv != VDDIO_MICBIAS_MV) &&
+	    sitar->mbhc_micbias_switched)
+		v_hs_max = sitar->mbhc_data.adj_v_hs_max;
+	else
+		v_hs_max = plug_type->v_hs_max;
+	return v_hs_max;
+}
+
 static void sitar_codec_calibrate_hs_polling(struct snd_soc_codec *codec)
 {
 	u8 *n_ready, *n_cic;
@@ -2754,16 +2845,18 @@
 	if (mclk_enable) {
 		sitar->mclk_enabled = true;
 
-		if (sitar->mbhc_polling_active && (sitar->mclk_enabled)) {
+		if (sitar->mbhc_polling_active) {
 			sitar_codec_pause_hs_polling(codec);
+			sitar_codec_disable_clock_block(codec);
 			sitar_codec_enable_bandgap(codec,
-					SITAR_BANDGAP_AUDIO_MODE);
+						   SITAR_BANDGAP_AUDIO_MODE);
 			sitar_codec_enable_clock_block(codec, 0);
 			sitar_codec_calibrate_hs_polling(codec);
 			sitar_codec_start_hs_polling(codec);
 		} else {
+			sitar_codec_disable_clock_block(codec);
 			sitar_codec_enable_bandgap(codec,
-					SITAR_BANDGAP_AUDIO_MODE);
+						   SITAR_BANDGAP_AUDIO_MODE);
 			sitar_codec_enable_clock_block(codec, 0);
 		}
 	} else {
@@ -2777,21 +2870,20 @@
 		sitar->mclk_enabled = false;
 
 		if (sitar->mbhc_polling_active) {
-			if (!sitar->mclk_enabled) {
-				sitar_codec_pause_hs_polling(codec);
-				sitar_codec_enable_bandgap(codec,
-					SITAR_BANDGAP_MBHC_MODE);
-				sitar_enable_rx_bias(codec, 1);
-				sitar_codec_enable_clock_block(codec, 1);
-				sitar_codec_calibrate_hs_polling(codec);
-				sitar_codec_start_hs_polling(codec);
-			}
+			sitar_codec_pause_hs_polling(codec);
+			sitar_codec_disable_clock_block(codec);
+			sitar_codec_enable_bandgap(codec,
+						   SITAR_BANDGAP_MBHC_MODE);
+			sitar_enable_rx_bias(codec, 1);
+			sitar_codec_enable_clock_block(codec, 1);
+			sitar_codec_calibrate_hs_polling(codec);
+			sitar_codec_start_hs_polling(codec);
 			snd_soc_update_bits(codec, SITAR_A_CLK_BUFF_EN1,
 					0x05, 0x01);
 		} else {
 			sitar_codec_disable_clock_block(codec);
 			sitar_codec_enable_bandgap(codec,
-				SITAR_BANDGAP_OFF);
+						   SITAR_BANDGAP_OFF);
 		}
 	}
 	if (dapm)
@@ -3437,6 +3529,7 @@
 	}
 
 	if (!sitar->mclk_enabled) {
+		sitar_codec_disable_clock_block(codec);
 		sitar_codec_enable_bandgap(codec, SITAR_BANDGAP_MBHC_MODE);
 		sitar_enable_rx_bias(codec, 1);
 		sitar_codec_enable_clock_block(codec, 1);
@@ -3703,6 +3796,22 @@
 	return ret;
 }
 
+static s16 sitar_scale_v_micb_vddio(struct sitar_priv *sitar, int volt_val,
+				    bool tovddio)
+{
+	int k_val_ratio;
+	int vddio_k, mb_k;
+	vddio_k = sitar_find_k_value(sitar->pdata->micbias.ldoh_v,
+				     VDDIO_MICBIAS_MV);
+	mb_k = sitar_find_k_value(sitar->pdata->micbias.ldoh_v,
+				  sitar->mbhc_data.micb_mv);
+	if (tovddio)
+		k_val_ratio = volt_val * vddio_k / mb_k;
+	else
+		k_val_ratio = volt_val * mb_k / vddio_k;
+	return k_val_ratio;
+}
+
 static void sitar_mbhc_calc_thres(struct snd_soc_codec *codec)
 {
 	struct sitar_priv *sitar;
@@ -3739,6 +3848,10 @@
 	for (i = 0; i < btn_det->num_btn; i++)
 		btn_mv = btn_high[i] > btn_mv ? btn_high[i] : btn_mv;
 
+	if (sitar->mbhc_data.micb_mv != VDDIO_MICBIAS_MV)
+		sitar->mbhc_data.adj_v_hs_max =
+		    sitar_scale_v_micb_vddio(sitar, plug_type->v_hs_max, true);
+
 	sitar->mbhc_data.v_b1_h = sitar_codec_v_sta_dce(codec, DCE, btn_mv);
 	btn_delta_mv = btn_mv + btn_det->v_btn_press_delta_sta;
 
@@ -3950,8 +4063,8 @@
 				sitar->buttons_pressed &=
 							~SITAR_JACK_BUTTON_MASK;
 			}
-			pr_debug("%s: Reporting removal %d\n", __func__,
-				 jack_type);
+			pr_debug("%s: Reporting removal %d(%x)\n", __func__,
+				 jack_type, sitar->hph_status);
 			sitar_snd_soc_jack_report(sitar,
 						  sitar->mbhc_cfg.headset_jack,
 						  sitar->hph_status,
@@ -3970,13 +4083,15 @@
 
 		if (jack_type == SND_JACK_HEADPHONE)
 			sitar->current_plug = PLUG_TYPE_HEADPHONE;
+		else if (jack_type == SND_JACK_UNSUPPORTED)
+			sitar->current_plug = PLUG_TYPE_GND_MIC_SWAP;
 		else if (jack_type == SND_JACK_HEADSET) {
 			sitar->mbhc_polling_active = true;
 			sitar->current_plug = PLUG_TYPE_HEADSET;
 		}
 		if (sitar->mbhc_cfg.headset_jack) {
-			pr_debug("%s: Reporting insertion %d\n", __func__,
-				 jack_type);
+			pr_debug("%s: Reporting insertion %d(%x)\n", __func__,
+				 jack_type, sitar->hph_status);
 			sitar_snd_soc_jack_report(sitar,
 						  sitar->mbhc_cfg.headset_jack,
 						  sitar->hph_status,
@@ -3993,23 +4108,26 @@
 		sitar->mbhc_cfg.gpio_level_insert);
 }
 
-static bool sitar_is_invalid_insert_delta(struct snd_soc_codec *codec,
+static bool sitar_is_inval_ins_delta(struct snd_soc_codec *codec,
 					int mic_volt, int mic_volt_prev)
 {
-	int delta = abs(mic_volt - mic_volt_prev);
-	if (delta > SITAR_MBHC_FAKE_INSERT_VOLT_DELTA_MV) {
-		pr_debug("%s: volt delta %dmv\n", __func__, delta);
-		return true;
-	}
-	return false;
+	return abs(mic_volt - mic_volt_prev) >
+				SITAR_MBHC_FAKE_INSERT_VOLT_DELTA_MV;
 }
 
-static bool sitar_is_invalid_insertion_range(struct snd_soc_codec *codec,
-				       s32 mic_volt)
+static bool sitar_is_inval_ins_range(struct snd_soc_codec *codec,
+				       s32 mic_volt,  bool *highv)
 {
 	bool invalid = false;
+	s16 v_hs_max;
+	struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
 
-	if (mic_volt < SITAR_MBHC_FAKE_INSERT_HIGH
+	v_hs_max = sitar_get_current_v_hs_max(sitar);
+	*highv = mic_volt > v_hs_max;
+
+	if (*highv)
+		invalid = true;
+	else if (mic_volt < SITAR_MBHC_FAKE_INSERT_HIGH
 			&& (mic_volt > SITAR_MBHC_FAKE_INSERT_LOW)) {
 		invalid = true;
 	}
@@ -4017,38 +4135,6 @@
 	return invalid;
 }
 
-static bool sitar_codec_is_invalid_plug(struct snd_soc_codec *codec,
-	s32 mic_mv[MBHC_NUM_DCE_PLUG_DETECT],
-	enum sitar_mbhc_plug_type plug_type[MBHC_NUM_DCE_PLUG_DETECT])
-{
-	int i;
-	bool r = false;
-	struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
-	struct sitar_mbhc_plug_type_cfg *plug_type_ptr =
-		SITAR_MBHC_CAL_PLUG_TYPE_PTR(sitar->mbhc_cfg.calibration);
-
-	for (i = 0 ; i < MBHC_NUM_DCE_PLUG_DETECT && !r; i++) {
-		if (mic_mv[i] < plug_type_ptr->v_no_mic)
-			plug_type[i] = PLUG_TYPE_HEADPHONE;
-		else if (mic_mv[i] < plug_type_ptr->v_hs_max)
-			plug_type[i] = PLUG_TYPE_HEADSET;
-		else if (mic_mv[i] > plug_type_ptr->v_hs_max)
-			plug_type[i] = PLUG_TYPE_HIGH_HPH;
-
-		r = sitar_is_invalid_insertion_range(codec, mic_mv[i]);
-		if (!r && i > 0) {
-			if (plug_type[i-1] != plug_type[i])
-				r = true;
-			else
-				r = sitar_is_invalid_insert_delta(codec,
-							mic_mv[i],
-							mic_mv[i - 1]);
-		}
-	}
-
-	return r;
-}
-
 /* called under codec_resource_lock acquisition */
 void sitar_find_plug_and_report(struct snd_soc_codec *codec,
 				enum sitar_mbhc_plug_type plug_type)
@@ -4057,11 +4143,21 @@
 
 	if (plug_type == PLUG_TYPE_HEADPHONE
 		&& sitar->current_plug == PLUG_TYPE_NONE) {
-		/* Nothing was reported previously
-		 * reporte a headphone
+		/*
+		 * Nothing was reported previously
+		 * report a headphone or unsupported
 		 */
 		sitar_codec_report_plug(codec, 1, SND_JACK_HEADPHONE);
 		sitar_codec_cleanup_hs_polling(codec);
+	} else if (plug_type == PLUG_TYPE_GND_MIC_SWAP) {
+		if (sitar->current_plug == PLUG_TYPE_HEADSET)
+			sitar_codec_report_plug(codec, 0, SND_JACK_HEADSET);
+		else if (sitar->current_plug == PLUG_TYPE_HEADPHONE)
+			sitar_codec_report_plug(codec, 0, SND_JACK_HEADPHONE);
+
+		sitar_codec_report_plug(codec, 1, SND_JACK_UNSUPPORTED);
+		msleep(100);
+		sitar_codec_cleanup_hs_polling(codec);
 	} else if (plug_type == PLUG_TYPE_HEADSET) {
 		/* If Headphone was reported previously, this will
 		 * only report the mic line
@@ -4077,6 +4173,9 @@
 		sitar->lpi_enabled = true;
 		/* TODO ::: sitar_codec_enable_hs_detect */
 		pr_err("%s(): High impedence hph not supported\n", __func__);
+	} else {
+		WARN(1, "Unexpected current plug_type %d, plug_type %d\n",
+			sitar->current_plug, plug_type);
 	}
 }
 
@@ -4107,11 +4206,9 @@
 {
 	struct sitar_priv *sitar;
 	struct snd_soc_codec *codec;
-	int retry = 0, i;
+	int retry = 0, pt_gnd_mic_swap_cnt = 0;
 	bool correction = false;
-	s32 mic_mv[MBHC_NUM_DCE_PLUG_DETECT];
-	short mb_v[MBHC_NUM_DCE_PLUG_DETECT];
-	enum sitar_mbhc_plug_type plug_type[MBHC_NUM_DCE_PLUG_DETECT];
+	enum sitar_mbhc_plug_type plug_type;
 	unsigned long timeout;
 
 	sitar = container_of(work, struct sitar_priv, hs_correct_plug_work);
@@ -4148,37 +4245,54 @@
 
 		/* can race with removal interrupt */
 		SITAR_ACQUIRE_LOCK(sitar->codec_resource_lock);
-		for (i = 0; i < MBHC_NUM_DCE_PLUG_DETECT; i++) {
-			mb_v[i] = __sitar_codec_sta_dce(codec, 1, true, true);
-			mic_mv[i] = sitar_codec_sta_dce_v(codec, 1 , mb_v[i]);
-			pr_debug("%s : DCE run %d, mic_mv = %d(%x)\n",
-				 __func__, retry, mic_mv[i], mb_v[i]);
-		}
+		plug_type = sitar_codec_decide_gpio_plug(codec);
 		SITAR_RELEASE_LOCK(sitar->codec_resource_lock);
 
-		if (sitar_codec_is_invalid_plug(codec, mic_mv, plug_type)) {
+		if (plug_type == PLUG_TYPE_INVALID) {
 			pr_debug("Invalid plug in attempt # %d\n", retry);
 			if (retry == NUM_ATTEMPTS_TO_REPORT &&
 			    sitar->current_plug == PLUG_TYPE_NONE) {
 				sitar_codec_report_plug(codec, 1,
 							SND_JACK_HEADPHONE);
 			}
-		} else if (!sitar_codec_is_invalid_plug(codec, mic_mv,
-							plug_type) &&
-			   plug_type[0] == PLUG_TYPE_HEADPHONE) {
+		} else if (plug_type == PLUG_TYPE_HEADPHONE) {
 			pr_debug("Good headphone detected, continue polling mic\n");
-			if (sitar->current_plug == PLUG_TYPE_NONE) {
+			if (sitar->current_plug == PLUG_TYPE_NONE)
 				sitar_codec_report_plug(codec, 1,
 							SND_JACK_HEADPHONE);
-			}
 		} else {
+			if (plug_type == PLUG_TYPE_GND_MIC_SWAP) {
+				pt_gnd_mic_swap_cnt++;
+				if (pt_gnd_mic_swap_cnt <
+					SITAR_MBHC_GND_MIC_SWAP_THRESHOLD)
+					continue;
+				else if (pt_gnd_mic_swap_cnt >
+					SITAR_MBHC_GND_MIC_SWAP_THRESHOLD) {
+					/*
+					 * This is due to GND/MIC switch didn't
+					 * work,  Report unsupported plug
+					 */
+				} else if (sitar->mbhc_cfg.swap_gnd_mic) {
+					/*
+					 * if switch is toggled, check again,
+					 * otherwise report unsupported plug
+					 */
+					if (sitar->mbhc_cfg.swap_gnd_mic(codec))
+						continue;
+				}
+			} else
+				pt_gnd_mic_swap_cnt = 0;
+
 			SITAR_ACQUIRE_LOCK(sitar->codec_resource_lock);
 			/* Turn off override */
 			sitar_turn_onoff_override(codec, false);
-			sitar_find_plug_and_report(codec, plug_type[0]);
+			/*
+			 * The valid plug also includes PLUG_TYPE_GND_MIC_SWAP
+			 */
+			sitar_find_plug_and_report(codec, plug_type);
 			SITAR_RELEASE_LOCK(sitar->codec_resource_lock);
 			pr_debug("Attempt %d found correct plug %d\n", retry,
-				 plug_type[0]);
+				 plug_type);
 			correction = true;
 			break;
 		}
@@ -4195,46 +4309,135 @@
 }
 
 /* called under codec_resource_lock acquisition */
-static void sitar_codec_decide_gpio_plug(struct snd_soc_codec *codec)
+static void sitar_codec_hphr_gnd_switch(struct snd_soc_codec *codec, bool on)
 {
-	struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
-	short mb_v[MBHC_NUM_DCE_PLUG_DETECT];
-	s32 mic_mv[MBHC_NUM_DCE_PLUG_DETECT];
-	enum sitar_mbhc_plug_type plug_type[MBHC_NUM_DCE_PLUG_DETECT];
-	int i;
+	snd_soc_update_bits(codec, SITAR_A_MBHC_HPH, 0x01, on);
+	if (on)
+		usleep_range(SITAR_MIC_GND_SWAP_DELAY_US,
+			SITAR_MIC_GND_SWAP_DELAY_US +
+			SITAR_USLEEP_RANGE_TOLERANCE);
+}
 
+/* called under codec_resource_lock acquisition */
+static enum sitar_mbhc_plug_type
+sitar_codec_decide_gpio_plug(struct snd_soc_codec *codec)
+{
+	bool gndswitch;
+	int scaled;
+	struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
+	int num_det = MBHC_NUM_DCE_PLUG_DETECT + 1;
+	short mb_v[num_det];
+	s32 mic_mv[num_det];
+	enum sitar_mbhc_plug_type plug_type[num_det];
+	int i;
+	bool inval;
+	bool highdelta;
+	bool ahighv = false, highv, r = false;
+	bool gndmicswapped = false;
+
+	struct sitar_mbhc_plug_type_cfg *plug_type_ptr =
+		SITAR_MBHC_CAL_PLUG_TYPE_PTR(sitar->mbhc_cfg.calibration);
 	pr_debug("%s: enter\n", __func__);
 
 	sitar_turn_onoff_override(codec, true);
-	mb_v[0] = sitar_codec_setup_hs_polling(codec);
-	mic_mv[0] = sitar_codec_sta_dce_v(codec, 1, mb_v[0]);
-	pr_debug("%s: DCE run 1, mic_mv = %d\n", __func__, mic_mv[0]);
 
-	for (i = 1; i < MBHC_NUM_DCE_PLUG_DETECT; i++) {
-		mb_v[i] = __sitar_codec_sta_dce(codec, 1, true, true);
-		mic_mv[i] = sitar_codec_sta_dce_v(codec, 1 , mb_v[i]);
-		pr_debug("%s: DCE run %d, mic_mv = %d\n", __func__, i + 1,
-			 mic_mv[i]);
+	/* GND and MIC swap detection requires at least 2 rounds of DCE */
+	BUG_ON(num_det < 2);
+
+	plug_type[0] = PLUG_TYPE_INVALID;
+
+
+	for (i = 0; i < num_det; i++) {
+		gndswitch = (i == (num_det - 2));
+		if (i == 0) {
+			mb_v[0] = sitar_codec_setup_hs_polling(codec);
+			mic_mv[0] = sitar_codec_sta_dce_v(codec, 1, mb_v[0]);
+			pr_debug("%s: DCE run 1, mic_mv = %d\n",
+				__func__, mic_mv[0]);
+			inval = sitar_is_inval_ins_range(codec, mic_mv[0],
+							&highv);
+			ahighv |= highv;
+			scaled = mic_mv[i];
+		} else {
+			if (gndswitch)
+				sitar_codec_hphr_gnd_switch(codec, true);
+			mb_v[i] = __sitar_codec_sta_dce(codec, 1, true, true);
+			mic_mv[i] = sitar_codec_sta_dce_v(codec, 1 , mb_v[i]);
+			pr_debug("%s: DCE run %d, mic_mv = %d\n",
+					__func__, i + 1, mic_mv[i]);
+			scaled = mic_mv[i];
+
+			/* !gndswitch & vddioswitch means the previous DCE
+			 * was done with gndswitch, don't compare with DCE
+			 * with gndswitch */
+			highdelta = sitar_is_inval_ins_delta(codec, scaled,
+							mic_mv[i - 1]);
+			inval = (sitar_is_inval_ins_range(codec, mic_mv[i],
+							&highv) ||
+							highdelta);
+			ahighv |= highv;
+			if (gndswitch)
+				sitar_codec_hphr_gnd_switch(codec, false);
+
+			/* claim UNSUPPORTED plug insertion when
+			 * good headset is detected but HPHR GND switch makes
+			 * delta difference */
+			if (i == (num_det - 2) && highdelta && !ahighv)
+				gndmicswapped = true;
+			else if (i == (num_det - 1) && inval) {
+				if (gndmicswapped)
+					plug_type[0] = PLUG_TYPE_GND_MIC_SWAP;
+				else
+					plug_type[0] = PLUG_TYPE_INVALID;
+			}
+		}
+		pr_debug("%s: DCE #%d, %04x, V %d, scaled V %d, GND %d, " \
+			"inval %d\n", __func__,
+			i + 1, mb_v[i] & 0xffff, mic_mv[i], scaled, gndswitch,
+			inval);
+		/* don't need to run further DCEs */
+		if (ahighv && inval)
+			break;
+		mic_mv[i] = scaled;
 	}
 	sitar_turn_onoff_override(codec, false);
 
 	if (sitar_hs_gpio_level_remove(sitar)) {
 		pr_debug("%s: GPIO value is low when determining plug\n",
 			 __func__);
-		return;
+		return PLUG_TYPE_INVALID;
 	}
 
-	if (sitar_codec_is_invalid_plug(codec, mic_mv, plug_type)) {
-		sitar_schedule_hs_detect_plug(sitar);
-	} else if (plug_type[0] == PLUG_TYPE_HEADPHONE) {
-		sitar_codec_report_plug(codec, 1, SND_JACK_HEADPHONE);
-		sitar_schedule_hs_detect_plug(sitar);
-	} else if (plug_type[0] == PLUG_TYPE_HEADSET) {
-		pr_debug("%s: Valid plug found, determine plug type\n",
-			 __func__);
-		sitar_find_plug_and_report(codec, plug_type[0]);
+	if ((plug_type[0] != PLUG_TYPE_GND_MIC_SWAP && !inval)) {
+		for (i = 0 ; i < num_det && !r; i++) {
+			if (mic_mv[i] < plug_type_ptr->v_no_mic)
+				plug_type[i] = PLUG_TYPE_HEADPHONE;
+			else if (mic_mv[i] < plug_type_ptr->v_hs_max)
+				plug_type[i] = PLUG_TYPE_HEADSET;
+			else if (mic_mv[i] > plug_type_ptr->v_hs_max)
+				plug_type[i] = PLUG_TYPE_HIGH_HPH;
+
+			r = sitar_is_inval_ins_range(codec, mic_mv[i], &r);
+			if (!r && i > 0) {
+				if (plug_type[i-1] != plug_type[i])
+					r = true;
+				else
+					r = sitar_is_inval_ins_delta(codec,
+								mic_mv[i],
+								mic_mv[i - 1]);
+			}
+			if (i > 0 && (plug_type[i - 1] != plug_type[i])) {
+				pr_err("%s: Detect attempt %d and %d are not same",
+				__func__, i - 1, i);
+				plug_type[0] = PLUG_TYPE_INVALID;
+				inval = true;
+				break;
+			}
+		}
 	}
 
+	pr_debug("%s: Detected plug type %d\n", __func__, plug_type[0]);
+	return plug_type[0];
 }
 
 /* called under codec_resource_lock acquisition */
@@ -4254,7 +4457,7 @@
 		pr_debug("%s: GPIO value is low when determining "
 				 "plug\n", __func__);
 	else
-		sitar_codec_decide_gpio_plug(codec);
+		sitar_schedule_hs_detect_plug(sitar);
 
 	return;
 }
@@ -4302,6 +4505,9 @@
 		if (priv->current_plug == PLUG_TYPE_HEADPHONE) {
 			sitar_codec_report_plug(codec, 0, SND_JACK_HEADPHONE);
 			is_removed = true;
+		} else if (priv->current_plug == PLUG_TYPE_GND_MIC_SWAP) {
+			sitar_codec_report_plug(codec, 0, SND_JACK_UNSUPPORTED);
+			is_removed = true;
 		} else if (priv->current_plug == PLUG_TYPE_HEADSET) {
 			sitar_codec_pause_hs_polling(codec);
 			sitar_codec_cleanup_hs_polling(codec);
@@ -4342,9 +4548,18 @@
 {
 	int r = IRQ_HANDLED;
 	struct snd_soc_codec *codec = data;
+	struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
 
 	if (unlikely(wcd9xxx_lock_sleep(codec->control_data) == false)) {
 		pr_warn("%s(): Failed to hold suspend\n", __func__);
+		/*
+		 * Give up this IRQ for now and resend this IRQ so IRQ can be
+		 * handled after system resume
+		 */
+		SITAR_ACQUIRE_LOCK(sitar->codec_resource_lock);
+		sitar->gpio_irq_resend = true;
+		SITAR_RELEASE_LOCK(sitar->codec_resource_lock);
+		wake_lock_timeout(&sitar->irq_resend_wlock, HZ);
 		r = IRQ_NONE;
 	} else {
 		sitar_hs_gpio_handler(codec);
@@ -4767,8 +4982,10 @@
 
 	if (sitar) {
 		codec = sitar->codec;
-		if (sitar->hphlocp_cnt++ < SITAR_OCP_ATTEMPT) {
+		if ((sitar->hphlocp_cnt < SITAR_OCP_ATTEMPT) &&
+		    (!sitar->hphrocp_cnt)) {
 			pr_info("%s: retry\n", __func__);
+			sitar->hphlocp_cnt++;
 			snd_soc_update_bits(codec, SITAR_A_RX_HPH_OCP_CTL, 0x10,
 					    0x00);
 			snd_soc_update_bits(codec, SITAR_A_RX_HPH_OCP_CTL, 0x10,
@@ -4776,7 +4993,6 @@
 		} else {
 			wcd9xxx_disable_irq(codec->control_data,
 					  SITAR_IRQ_HPH_PA_OCPL_FAULT);
-			sitar->hphlocp_cnt = 0;
 			sitar->hph_status |= SND_JACK_OC_HPHL;
 			if (sitar->mbhc_cfg.headset_jack)
 				sitar_snd_soc_jack_report(sitar,
@@ -4800,8 +5016,10 @@
 
 	if (sitar) {
 		codec = sitar->codec;
-		if (sitar->hphrocp_cnt++ < SITAR_OCP_ATTEMPT) {
+		if ((sitar->hphrocp_cnt < SITAR_OCP_ATTEMPT) &&
+		    (!sitar->hphlocp_cnt)) {
 			pr_info("%s: retry\n", __func__);
+			sitar->hphrocp_cnt++;
 			snd_soc_update_bits(codec, SITAR_A_RX_HPH_OCP_CTL, 0x10,
 					   0x00);
 			snd_soc_update_bits(codec, SITAR_A_RX_HPH_OCP_CTL, 0x10,
@@ -4809,7 +5027,6 @@
 		} else {
 			wcd9xxx_disable_irq(codec->control_data,
 					 SITAR_IRQ_HPH_PA_OCPR_FAULT);
-			sitar->hphrocp_cnt = 0;
 			sitar->hph_status |= SND_JACK_OC_HPHR;
 			if (sitar->mbhc_cfg.headset_jack)
 				sitar_snd_soc_jack_report(sitar,
@@ -4853,7 +5070,7 @@
 		   priv->mbhc_cfg.gpio_level_insert) {
 		pr_debug("%s: Valid insertion, "
 			 "detect plug type\n", __func__);
-		sitar_codec_decide_gpio_plug(codec);
+		sitar_schedule_hs_detect_plug(priv);
 	} else {
 		pr_debug("%s: Invalid insertion, "
 			 "stop plug detection\n", __func__);
@@ -5128,6 +5345,7 @@
 	SITAR_REG_VAL(SITAR_A_CDC_RX1_B6_CTL, 0x80),
 
 	SITAR_REG_VAL(SITAR_A_CDC_CLSG_FREQ_THRESH_B3_CTL, 0x1B),
+	SITAR_REG_VAL(SITAR_A_CDC_CLSG_FREQ_THRESH_B4_CTL, 0x5B),
 
 };
 
@@ -5358,6 +5576,13 @@
 	}
 	wcd9xxx_disable_irq(codec->control_data, SITAR_IRQ_HPH_PA_OCPR_FAULT);
 
+	/*
+	 * Register suspend lock and notifier to resend edge triggered
+	 * gpio IRQs
+	 */
+	wake_lock_init(&sitar->irq_resend_wlock, WAKE_LOCK_SUSPEND,
+			"sitar_gpio_irq_resend");
+	sitar->gpio_irq_resend = false;
 	for (i = 0; i < ARRAY_SIZE(sitar_dai); i++) {
 		switch (sitar_dai[i].id) {
 		case AIF1_PB:
@@ -5410,6 +5635,9 @@
 {
 	int i;
 	struct sitar_priv *sitar = snd_soc_codec_get_drvdata(codec);
+
+	wake_lock_destroy(&sitar->irq_resend_wlock);
+
 	wcd9xxx_free_irq(codec->control_data, SITAR_IRQ_SLIMBUS, sitar);
 	wcd9xxx_free_irq(codec->control_data, SITAR_IRQ_MBHC_RELEASE, sitar);
 	wcd9xxx_free_irq(codec->control_data, SITAR_IRQ_MBHC_POTENTIAL, sitar);
@@ -5487,10 +5715,27 @@
 
 static int sitar_resume(struct device *dev)
 {
+	int irq;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct sitar_priv *sitar = platform_get_drvdata(pdev);
 	dev_dbg(dev, "%s: system resume\n", __func__);
-	sitar->mbhc_last_resume = jiffies;
+	if (sitar) {
+		SITAR_ACQUIRE_LOCK(sitar->codec_resource_lock);
+		sitar->mbhc_last_resume = jiffies;
+		if (sitar->gpio_irq_resend) {
+			WARN_ON(!sitar->mbhc_cfg.gpio_irq);
+			sitar->gpio_irq_resend = false;
+
+			irq = sitar->mbhc_cfg.gpio_irq;
+			pr_debug("%s: Resending GPIO IRQ %d\n", __func__, irq);
+			irq_set_pending(irq);
+			check_irq_resend(irq_to_desc(irq), irq);
+
+			/* release suspend lock */
+			wake_unlock(&sitar->irq_resend_wlock);
+		}
+		SITAR_RELEASE_LOCK(sitar->codec_resource_lock);
+	}
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wcd9304.h b/sound/soc/codecs/wcd9304.h
index 70b3f0b..b0456b7 100644
--- a/sound/soc/codecs/wcd9304.h
+++ b/sound/soc/codecs/wcd9304.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -175,6 +175,8 @@
 	unsigned int gpio;
 	unsigned int gpio_irq;
 	int gpio_level_insert;
+	/* swap_gnd_mic returns true if extern GND/MIC swap switch toggled */
+	bool (*swap_gnd_mic) (struct snd_soc_codec *);
 };
 
 extern int sitar_hs_detect(struct snd_soc_codec *codec,
diff --git a/sound/soc/codecs/wcd9310-tables.c b/sound/soc/codecs/wcd9310-tables.c
index 2cba59d..b7cea9b 100644
--- a/sound/soc/codecs/wcd9310-tables.c
+++ b/sound/soc/codecs/wcd9310-tables.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 2c860ad..1eb29f9 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -54,9 +54,11 @@
 #define TABLA_CFILT_SLOW_MODE 0x40
 #define MBHC_FW_READ_ATTEMPTS 15
 #define MBHC_FW_READ_TIMEOUT 2000000
+#define COMP_DIGITAL_DB_GAIN_APPLY(a, b) \
+	(((a) <= 0) ? ((a) - b) : (a))
 
 #define SLIM_CLOSE_TIMEOUT 1000
-
+#define COMP_BRINGUP_WAIT_TIME  2000
 enum {
 	MBHC_USE_HPHL_TRIGGER = 1,
 	MBHC_USE_MB_TRIGGER = 2
@@ -82,6 +84,7 @@
 #define AIF3_PB  6
 
 #define NUM_CODEC_DAIS 6
+#define MAX_PA_GAIN_OPTIONS  13
 
 struct tabla_codec_dai_data {
 	u32 rate;
@@ -92,9 +95,6 @@
 	wait_queue_head_t dai_wait;
 };
 
-#define TABLA_COMP_DIGITAL_GAIN_HP_OFFSET 3
-#define TABLA_COMP_DIGITAL_GAIN_LINEOUT_OFFSET 6
-
 #define TABLA_MCLK_RATE_12288KHZ 12288000
 #define TABLA_MCLK_RATE_9600KHZ 9600000
 
@@ -121,7 +121,9 @@
 
 #define TABLA_MBHC_GND_MIC_SWAP_THRESHOLD 2
 
-#define TABLA_ACQUIRE_LOCK(x) do { mutex_lock(&x); } while (0)
+#define TABLA_ACQUIRE_LOCK(x) do { \
+	mutex_lock_nested(&x, SINGLE_DEPTH_NESTING); \
+} while (0)
 #define TABLA_RELEASE_LOCK(x) do { mutex_unlock(&x); } while (0)
 
 static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
@@ -210,6 +212,28 @@
 	u32 shutdown_timeout;
 };
 
+struct comp_dgtl_gain_offset {
+	u8 whole_db_gain;
+	u8 half_db_gain;
+};
+
+const static struct comp_dgtl_gain_offset
+			comp_dgtl_gain[MAX_PA_GAIN_OPTIONS] = {
+	{0, 0},
+	{1, 1},
+	{3, 0},
+	{4, 1},
+	{6, 0},
+	{7, 1},
+	{9, 0},
+	{10, 1},
+	{12, 0},
+	{13, 1},
+	{15, 0},
+	{16, 1},
+	{18, 0},
+};
+
 /* Data used by MBHC */
 struct mbhc_internal_cal_data {
 	u16 dce_z;
@@ -328,6 +352,7 @@
 	/*compander*/
 	int comp_enabled[COMPANDER_MAX];
 	u32 comp_fs[COMPANDER_MAX];
+	u8  comp_gain_offset[TABLA_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS - 1];
 
 	/* Maintain the status of AUX PGA */
 	int aux_pga_cnt;
@@ -468,6 +493,8 @@
 		snd_soc_update_bits(codec, TABLA_A_CDC_CLSG_CTL, 0x08, 0x00);
 		snd_soc_update_bits(codec, TABLA_A_CDC_CLK_OTHR_CTL, 0x01,
 			0x00);
+		snd_soc_update_bits(codec, TABLA_A_CDC_CLK_OTHR_RESET_CTL, 0x10,
+			0x00);
 		snd_soc_update_bits(codec, TABLA_A_CP_STATIC, 0x08, 0x00);
 		break;
 	}
@@ -497,7 +524,10 @@
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+	mutex_lock(&codec->dapm.codec->mutex);
 	ucontrol->value.integer.value[0] = (tabla->anc_func == true ? 1 : 0);
+	mutex_unlock(&codec->dapm.codec->mutex);
 	return 0;
 }
 
@@ -760,34 +790,51 @@
 
 static int tabla_compander_gain_offset(
 	struct snd_soc_codec *codec, u32 enable,
-	unsigned int reg, int mask, int event, u32 comp)
+	unsigned int pa_reg, unsigned int vol_reg,
+	int mask, int event,
+	struct comp_dgtl_gain_offset *gain_offset,
+	int index)
 {
-	int pa_mode = snd_soc_read(codec, reg) & mask;
-	int gain_offset = 0;
-	/*  if PMU && enable is 1-> offset is 3
-	 *  if PMU && enable is 0-> offset is 0
-	 *  if PMD && pa_mode is PA -> offset is 0: PMU compander is off
-	 *  if PMD && pa_mode is comp -> offset is -3: PMU compander is on.
-	 */
+	unsigned int pa_gain = snd_soc_read(codec, pa_reg);
+	unsigned int digital_vol = snd_soc_read(codec, vol_reg);
+	int pa_mode = pa_gain & mask;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+	pr_debug("%s: pa_gain(0x%x=0x%x)digital_vol(0x%x=0x%x)event(0x%x) index(%d)\n",
+		 __func__, pa_reg, pa_gain, vol_reg, digital_vol, event, index);
+	if (((pa_gain & 0xF) + 1) > ARRAY_SIZE(comp_dgtl_gain) ||
+		(index >= ARRAY_SIZE(tabla->comp_gain_offset))) {
+		pr_err("%s: Out of array boundary\n", __func__);
+		return -EINVAL;
+	}
 
 	if (SND_SOC_DAPM_EVENT_ON(event) && (enable != 0)) {
-		if (comp == COMPANDER_1)
-			gain_offset = TABLA_COMP_DIGITAL_GAIN_HP_OFFSET;
-		if (comp == COMPANDER_2)
-			gain_offset = TABLA_COMP_DIGITAL_GAIN_LINEOUT_OFFSET;
+		gain_offset->whole_db_gain = COMP_DIGITAL_DB_GAIN_APPLY(
+		  (digital_vol - comp_dgtl_gain[pa_gain & 0xF].whole_db_gain),
+		  comp_dgtl_gain[pa_gain & 0xF].half_db_gain);
+		pr_debug("%s: listed whole_db_gain:0x%x, adjusted whole_db_gain:0x%x\n",
+			 __func__, comp_dgtl_gain[pa_gain & 0xF].whole_db_gain,
+			 gain_offset->whole_db_gain);
+		gain_offset->half_db_gain =
+				comp_dgtl_gain[pa_gain & 0xF].half_db_gain;
+		tabla->comp_gain_offset[index] = digital_vol -
+						 gain_offset->whole_db_gain ;
 	}
 	if (SND_SOC_DAPM_EVENT_OFF(event) && (pa_mode == 0)) {
-		if (comp == COMPANDER_1)
-			gain_offset = -TABLA_COMP_DIGITAL_GAIN_HP_OFFSET;
-		if (comp == COMPANDER_2)
-			gain_offset = -TABLA_COMP_DIGITAL_GAIN_LINEOUT_OFFSET;
-
+		gain_offset->whole_db_gain = digital_vol +
+					     tabla->comp_gain_offset[index];
+		pr_debug("%s: listed whole_db_gain:0x%x, adjusted whole_db_gain:0x%x\n",
+			 __func__, comp_dgtl_gain[pa_gain & 0xF].whole_db_gain,
+			 gain_offset->whole_db_gain);
+		gain_offset->half_db_gain = 0;
 	}
-	pr_debug("%s: compander #%d gain_offset %d\n",
-		 __func__, comp + 1, gain_offset);
-	return gain_offset;
-}
 
+	pr_debug("%s: half_db_gain(%d)whole_db_gain(%d)comp_gain_offset[%d](%d)\n",
+		 __func__, gain_offset->half_db_gain,
+		 gain_offset->whole_db_gain, index,
+		 tabla->comp_gain_offset[index]);
+	return 0;
+}
 
 static int tabla_config_gain_compander(
 				struct snd_soc_codec *codec,
@@ -795,8 +842,7 @@
 {
 	int value = 0;
 	int mask = 1 << 4;
-	int gain = 0;
-	int gain_offset;
+	struct comp_dgtl_gain_offset gain_offset = {0, 0};
 	if (compander >= COMPANDER_MAX) {
 		pr_err("%s: Error, invalid compander channel\n", __func__);
 		return -EINVAL;
@@ -806,43 +852,61 @@
 		value = 1 << 4;
 
 	if (compander == COMPANDER_1) {
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_HPH_L_GAIN, mask, event, compander);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_HPH_L_GAIN,
+				TABLA_A_CDC_RX1_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 0);
 		snd_soc_update_bits(codec, TABLA_A_RX_HPH_L_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_HPH_R_GAIN, mask, event, compander);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX1_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_HPH_R_GAIN,
+				TABLA_A_CDC_RX2_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 1);
 		snd_soc_update_bits(codec, TABLA_A_RX_HPH_R_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX2_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
 	} else if (compander == COMPANDER_2) {
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_1_GAIN, mask, event, compander);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_1_GAIN,
+				TABLA_A_CDC_RX3_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 2);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_1_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_3_GAIN, mask, event, compander);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX3_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_3_GAIN,
+				TABLA_A_CDC_RX4_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 3);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_3_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_2_GAIN, mask, event, compander);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX4_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_2_GAIN,
+				TABLA_A_CDC_RX5_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 4);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_2_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_4_GAIN, mask, event, compander);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX5_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_4_GAIN,
+				TABLA_A_CDC_RX6_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 5);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_4_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX6_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
 	}
 	return 0;
 }
@@ -866,7 +930,7 @@
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 	int comp = ((struct soc_multi_mixer_control *)
-					kcontrol->private_value)->max;
+					kcontrol->private_value)->shift;
 	int value = ucontrol->value.integer.value[0];
 	pr_debug("%s: compander #%d enable %d\n",
 		 __func__, comp + 1, value);
@@ -879,7 +943,6 @@
 	return 0;
 }
 
-
 static int tabla_config_compander(struct snd_soc_dapm_widget *w,
 						  struct snd_kcontrol *kcontrol,
 						  int event)
@@ -887,106 +950,155 @@
 	struct snd_soc_codec *codec = w->codec;
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 	u32 rate = tabla->comp_fs[w->shift];
-	u32 status;
-	unsigned long timeout;
-	pr_debug("%s: compander #%d enable %d event %d\n",
+
+	pr_debug("%s: compander #%d enable %d event %d widget name %s\n",
 		 __func__, w->shift + 1,
-		 tabla->comp_enabled[w->shift], event);
+		 tabla->comp_enabled[w->shift], event , w->name);
+	if (tabla->comp_enabled[w->shift] == 0)
+		goto rtn;
+	if ((w->shift == COMPANDER_1) && (tabla->anc_func)) {
+		pr_debug("%s: ANC is enabled so compander #%d cannot be enabled\n",
+			 __func__, w->shift + 1);
+		goto rtn;
+	}
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		if (tabla->comp_enabled[w->shift] != 0) {
-			/* Enable both L/R compander clocks */
-			snd_soc_update_bits(codec,
-					TABLA_A_CDC_CLK_RX_B2_CTL,
-					1 << comp_shift[w->shift],
-					1 << comp_shift[w->shift]);
-			/* Clear the HALT for the compander*/
-			snd_soc_update_bits(codec,
-					TABLA_A_CDC_COMP1_B1_CTL +
-					w->shift * 8, 1 << 2, 0);
-			/* Toggle compander reset bits*/
-			snd_soc_update_bits(codec,
-					TABLA_A_CDC_CLK_OTHR_RESET_CTL,
-					1 << comp_shift[w->shift],
-					1 << comp_shift[w->shift]);
-			snd_soc_update_bits(codec,
-					TABLA_A_CDC_CLK_OTHR_RESET_CTL,
-					1 << comp_shift[w->shift], 0);
-			tabla_config_gain_compander(codec, w->shift, 1, event);
-			/* Compander enable -> 0x370/0x378*/
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
-					    w->shift * 8, 0x03, 0x03);
-			/* Update the RMS meter resampling*/
-			snd_soc_update_bits(codec,
-					TABLA_A_CDC_COMP1_B3_CTL +
-					w->shift * 8, 0xFF, 0x01);
-			snd_soc_update_bits(codec,
-					    TABLA_A_CDC_COMP1_B2_CTL +
-					    w->shift * 8, 0xF0, 0x50);
-			/* Wait for 1ms*/
-			usleep_range(5000, 5000);
-		}
+		/* Update compander sample rate */
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_FS_CFG +
+				    w->shift * 8, 0x07, rate);
+		/* Enable both L/R compander clocks */
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_CLK_RX_B2_CTL,
+				    1 << comp_shift[w->shift],
+				    1 << comp_shift[w->shift]);
+		/* Toggle compander reset bits */
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+				    1 << comp_shift[w->shift],
+				    1 << comp_shift[w->shift]);
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+				    1 << comp_shift[w->shift], 0);
+		tabla_config_gain_compander(codec, w->shift, 1, event);
+		/* Compander enable -> 0x370/0x378 */
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+				    w->shift * 8, 0x03, 0x03);
+		/* Update the RMS meter resampling */
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_COMP1_B3_CTL +
+				    w->shift * 8, 0xFF, 0x01);
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_COMP1_B2_CTL +
+				    w->shift * 8, 0xF0, 0x50);
+		usleep_range(COMP_BRINGUP_WAIT_TIME, COMP_BRINGUP_WAIT_TIME);
 		break;
 	case SND_SOC_DAPM_POST_PMU:
-		/* Set sample rate dependent paramater*/
-		if (tabla->comp_enabled[w->shift] != 0) {
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_FS_CFG +
-			w->shift * 8, 0x07,	rate);
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
-			w->shift * 8, 0x0F,
-			comp_samp_params[rate].peak_det_timeout);
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
-			w->shift * 8, 0xF0,
-			comp_samp_params[rate].rms_meter_div_fact);
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B3_CTL +
-			w->shift * 8, 0xFF,
-			comp_samp_params[rate].rms_meter_resamp_fact);
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
-			w->shift * 8, 0x38,
-			comp_samp_params[rate].shutdown_timeout);
+		/* Set sample rate dependent paramater */
+		if (w->shift == COMPANDER_1) {
+			snd_soc_update_bits(codec,
+					    TABLA_A_CDC_CLSG_CTL,
+					    0x11, 0x00);
+			snd_soc_write(codec,
+				      TABLA_A_CDC_CONN_CLSG_CTL, 0x11);
 		}
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
+				    w->shift * 8, 0x0F,
+				    comp_samp_params[rate].peak_det_timeout);
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
+				    w->shift * 8, 0xF0,
+				    comp_samp_params[rate].rms_meter_div_fact);
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B3_CTL +
+				w->shift * 8, 0xFF,
+				comp_samp_params[rate].rms_meter_resamp_fact);
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+				    w->shift * 8, 0x38,
+				    comp_samp_params[rate].shutdown_timeout);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		if (tabla->comp_enabled[w->shift] != 0) {
-			status = snd_soc_read(codec,
-					TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS +
-					w->shift * 8);
-			pr_debug("%s: compander #%d shutdown status %d in event %d\n",
-				 __func__, w->shift + 1, status, event);
-			/* Halt the compander*/
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
-					    w->shift * 8, 1 << 2, 1 << 2);
-		}
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		if (tabla->comp_enabled[w->shift] != 0) {
-			/* Wait up to a second for shutdown complete */
-			timeout = jiffies + HZ;
-			do {
-				status = snd_soc_read(codec,
-					TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS +
-					w->shift * 8);
-				if (status == 0x3)
-					break;
-				usleep_range(5000, 5000);
-			} while (!(time_after(jiffies, timeout)));
-			/* Restore the gain */
-			tabla_config_gain_compander(codec, w->shift,
-						tabla->comp_enabled[w->shift],
-						event);
-			/* Disable the compander*/
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
-					    w->shift * 8, 0x03, 0x00);
-			/* Turn off the clock for compander in pair*/
-			snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_B2_CTL,
-					    0x03 << comp_shift[w->shift], 0);
-			/* Clear the HALT for the compander*/
+		/* Disable the compander */
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+				    w->shift * 8, 0x03, 0x00);
+		/* Toggle compander reset bits */
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+				    1 << comp_shift[w->shift],
+				    1 << comp_shift[w->shift]);
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+				    1 << comp_shift[w->shift], 0);
+		/* Turn off the clock for compander in pair */
+		snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_B2_CTL,
+				    0x03 << comp_shift[w->shift], 0);
+		/* Restore the gain */
+		tabla_config_gain_compander(codec, w->shift,
+					    tabla->comp_enabled[w->shift],
+					    event);
+		if (w->shift == COMPANDER_1) {
 			snd_soc_update_bits(codec,
-					    TABLA_A_CDC_COMP1_B1_CTL +
-					    w->shift * 8, 1 << 2, 0);
+					    TABLA_A_CDC_CLSG_CTL,
+					    0x11, 0x11);
+			snd_soc_write(codec,
+				      TABLA_A_CDC_CONN_CLSG_CTL, 0x14);
 		}
 		break;
 	}
+rtn:
+	return 0;
+}
+
+static int tabla_codec_hphr_dem_input_selection(struct snd_soc_dapm_widget *w,
+						struct snd_kcontrol *kcontrol,
+						int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	pr_debug("%s: compander#1->enable(%d) reg(0x%x = 0x%x) event(%d)\n",
+		__func__, tabla->comp_enabled[COMPANDER_1],
+		TABLA_A_CDC_RX1_B6_CTL,
+		snd_soc_read(codec, TABLA_A_CDC_RX1_B6_CTL), event);
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		if (tabla->comp_enabled[COMPANDER_1] && !tabla->anc_func)
+			snd_soc_update_bits(codec, TABLA_A_CDC_RX1_B6_CTL,
+					    1 << w->shift, 0);
+		else
+			snd_soc_update_bits(codec, TABLA_A_CDC_RX1_B6_CTL,
+					    1 << w->shift, 1 << w->shift);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX1_B6_CTL,
+				    1 << w->shift, 0);
+		break;
+	}
+	return 0;
+}
+
+static int tabla_codec_hphl_dem_input_selection(struct snd_soc_dapm_widget *w,
+						struct snd_kcontrol *kcontrol,
+						int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	pr_debug("%s: compander#1->enable(%d) reg(0x%x = 0x%x) event(%d)\n",
+		__func__, tabla->comp_enabled[COMPANDER_1],
+		TABLA_A_CDC_RX2_B6_CTL,
+		snd_soc_read(codec, TABLA_A_CDC_RX2_B6_CTL), event);
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		if (tabla->comp_enabled[COMPANDER_1] && !tabla->anc_func)
+			snd_soc_update_bits(codec, TABLA_A_CDC_RX2_B6_CTL,
+					    1 << w->shift, 0);
+		else
+			snd_soc_update_bits(codec, TABLA_A_CDC_RX2_B6_CTL,
+					    1 << w->shift, 1 << w->shift);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX2_B6_CTL,
+				    1 << w->shift, 0);
+		break;
+	}
 	return 0;
 }
 
@@ -1218,9 +1330,9 @@
 	tabla_get_iir_band_audio_mixer, tabla_put_iir_band_audio_mixer),
 	SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
 	tabla_get_iir_band_audio_mixer, tabla_put_iir_band_audio_mixer),
-	SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, 1, COMPANDER_1, 0,
+	SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
 				   tabla_get_compander, tabla_set_compander),
-	SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, 0, COMPANDER_2, 0,
+	SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
 				   tabla_get_compander, tabla_set_compander),
 };
 
@@ -1330,7 +1442,7 @@
 	"ZERO", "EAR_HPH_L", "EAR_LINE_1",
 };
 
-static const char *iir1_inp1_text[] = {
+static const char *const iir_inp1_text[] = {
 	"ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
 	"DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
 };
@@ -1478,7 +1590,10 @@
 	SOC_ENUM_SINGLE(TABLA_A_CDC_CONN_ANC_B2_CTL, 0, 3, anc1_fb_mux_text);
 
 static const struct soc_enum iir1_inp1_mux_enum =
-	SOC_ENUM_SINGLE(TABLA_A_CDC_CONN_EQ1_B1_CTL, 0, 18, iir1_inp1_text);
+	SOC_ENUM_SINGLE(TABLA_A_CDC_CONN_EQ1_B1_CTL, 0, 18, iir_inp1_text);
+
+static const struct soc_enum iir2_inp1_mux_enum =
+	SOC_ENUM_SINGLE(TABLA_A_CDC_CONN_EQ2_B1_CTL, 0, 18, iir_inp1_text);
 
 static const struct snd_kcontrol_new rx_mix1_inp1_mux =
 	SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
@@ -1703,6 +1818,9 @@
 static const struct snd_kcontrol_new iir1_inp1_mux =
 	SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
 
+static const struct snd_kcontrol_new iir2_inp1_mux =
+	SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum);
+
 static const struct snd_kcontrol_new anc1_mux =
 	SOC_DAPM_ENUM("ANC1 MUX Mux", anc1_mux_enum);
 
@@ -2316,6 +2434,9 @@
 		return;
 	}
 
+	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.ctl_reg, 0x01, 0x01);
+	msleep(250);
+	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.ctl_reg, 0x01, 0x00);
 	snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
 	pr_debug("%s: leave\n", __func__);
 }
@@ -3514,6 +3635,7 @@
 	{"RX1 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX1 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX1 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX1 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX1 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX1 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX1 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3522,6 +3644,7 @@
 	{"RX1 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX1 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX1 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX1 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX1 MIX1 INP3", "RX1", "SLIM RX1"},
 	{"RX1 MIX1 INP3", "RX2", "SLIM RX2"},
 	{"RX1 MIX1 INP3", "RX3", "SLIM RX3"},
@@ -3537,6 +3660,7 @@
 	{"RX2 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX2 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX2 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX2 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX2 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX2 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX2 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3545,6 +3669,7 @@
 	{"RX2 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX2 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX2 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX2 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX3 MIX1 INP1", "RX1", "SLIM RX1"},
 	{"RX3 MIX1 INP1", "RX2", "SLIM RX2"},
 	{"RX3 MIX1 INP1", "RX3", "SLIM RX3"},
@@ -3553,6 +3678,7 @@
 	{"RX3 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX3 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX3 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX3 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX3 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX3 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX3 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3561,6 +3687,7 @@
 	{"RX3 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX3 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX3 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX3 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX4 MIX1 INP1", "RX1", "SLIM RX1"},
 	{"RX4 MIX1 INP1", "RX2", "SLIM RX2"},
 	{"RX4 MIX1 INP1", "RX3", "SLIM RX3"},
@@ -3569,6 +3696,7 @@
 	{"RX4 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX4 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX4 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX4 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX4 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX4 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX4 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3577,6 +3705,7 @@
 	{"RX4 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX4 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX4 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX4 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX5 MIX1 INP1", "RX1", "SLIM RX1"},
 	{"RX5 MIX1 INP1", "RX2", "SLIM RX2"},
 	{"RX5 MIX1 INP1", "RX3", "SLIM RX3"},
@@ -3585,6 +3714,7 @@
 	{"RX5 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX5 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX5 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX5 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX5 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX5 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX5 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3593,6 +3723,7 @@
 	{"RX5 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX5 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX5 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX5 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX6 MIX1 INP1", "RX1", "SLIM RX1"},
 	{"RX6 MIX1 INP1", "RX2", "SLIM RX2"},
 	{"RX6 MIX1 INP1", "RX3", "SLIM RX3"},
@@ -3601,6 +3732,7 @@
 	{"RX6 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX6 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX6 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX6 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX6 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX6 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX6 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3609,6 +3741,7 @@
 	{"RX6 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX6 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX6 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX6 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX7 MIX1 INP1", "RX1", "SLIM RX1"},
 	{"RX7 MIX1 INP1", "RX2", "SLIM RX2"},
 	{"RX7 MIX1 INP1", "RX3", "SLIM RX3"},
@@ -3617,6 +3750,7 @@
 	{"RX7 MIX1 INP1", "RX6", "SLIM RX6"},
 	{"RX7 MIX1 INP1", "RX7", "SLIM RX7"},
 	{"RX7 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX7 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX7 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX7 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX7 MIX1 INP2", "RX3", "SLIM RX3"},
@@ -3625,12 +3759,20 @@
 	{"RX7 MIX1 INP2", "RX6", "SLIM RX6"},
 	{"RX7 MIX1 INP2", "RX7", "SLIM RX7"},
 	{"RX7 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX7 MIX1 INP2", "IIR2", "IIR2"},
+
 	{"RX1 MIX2 INP1", "IIR1", "IIR1"},
+	{"RX1 MIX2 INP1", "IIR2", "IIR2"},
 	{"RX1 MIX2 INP2", "IIR1", "IIR1"},
+	{"RX1 MIX2 INP2", "IIR2", "IIR2"},
 	{"RX2 MIX2 INP1", "IIR1", "IIR1"},
+	{"RX2 MIX2 INP1", "IIR2", "IIR2"},
 	{"RX2 MIX2 INP2", "IIR1", "IIR1"},
+	{"RX2 MIX2 INP2", "IIR2", "IIR2"},
 	{"RX3 MIX2 INP1", "IIR1", "IIR1"},
+	{"RX3 MIX2 INP1", "IIR2", "IIR2"},
 	{"RX3 MIX2 INP2", "IIR1", "IIR1"},
+	{"RX3 MIX2 INP2", "IIR2", "IIR2"},
 
 	/* Decimator Inputs */
 	{"DEC1 MUX", "DMIC1", "DMIC1"},
@@ -3728,6 +3870,18 @@
 	{"IIR1 INP1 MUX", "DEC9", "DEC9 MUX"},
 	{"IIR1 INP1 MUX", "DEC10", "DEC10 MUX"},
 
+	{"IIR2", NULL, "IIR2 INP1 MUX"},
+	{"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"},
+	{"IIR2 INP1 MUX", "DEC3", "DEC3 MUX"},
+	{"IIR2 INP1 MUX", "DEC4", "DEC4 MUX"},
+	{"IIR2 INP1 MUX", "DEC5", "DEC5 MUX"},
+	{"IIR2 INP1 MUX", "DEC6", "DEC6 MUX"},
+	{"IIR2 INP1 MUX", "DEC7", "DEC7 MUX"},
+	{"IIR2 INP1 MUX", "DEC8", "DEC8 MUX"},
+	{"IIR2 INP1 MUX", "DEC9", "DEC9 MUX"},
+	{"IIR2 INP1 MUX", "DEC10", "DEC10 MUX"},
+
 	{"MIC BIAS1 Internal1", NULL, "LDO_H"},
 	{"MIC BIAS1 Internal2", NULL, "LDO_H"},
 	{"MIC BIAS1 External", NULL, "LDO_H"},
@@ -5033,8 +5187,12 @@
 		&rx6_dsm_mux, tabla_codec_reset_interpolator,
 		SND_SOC_DAPM_PRE_PMU),
 
-	SND_SOC_DAPM_MIXER("RX1 CHAIN", TABLA_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
-	SND_SOC_DAPM_MIXER("RX2 CHAIN", TABLA_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER_E("RX1 CHAIN", SND_SOC_NOPM, 5, 0, NULL,
+		0, tabla_codec_hphr_dem_input_selection,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
+	SND_SOC_DAPM_MIXER_E("RX2 CHAIN", SND_SOC_NOPM, 5, 0, NULL,
+		0, tabla_codec_hphl_dem_input_selection,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
 
 	SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
 		&rx_mix1_inp1_mux),
@@ -5266,6 +5424,9 @@
 	SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
 	SND_SOC_DAPM_PGA("IIR1", TABLA_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
 
+	SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux),
+	SND_SOC_DAPM_PGA("IIR2", TABLA_A_CDC_CLK_SD_CTL, 1, 0, NULL, 0),
+
 	/* AUX PGA */
 	SND_SOC_DAPM_ADC_E("AUX_PGA_Left", NULL, TABLA_A_AUX_L_EN, 7, 0,
 		tabla_codec_enable_aux_pga, SND_SOC_DAPM_PRE_PMU |
@@ -7484,6 +7645,7 @@
 {
 	bool insert;
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
 	bool is_removed = false;
 
 	pr_debug("%s: enter\n", __func__);
@@ -7493,6 +7655,7 @@
 	usleep_range(TABLA_GPIO_IRQ_DEBOUNCE_TIME_US,
 		     TABLA_GPIO_IRQ_DEBOUNCE_TIME_US);
 
+	wcd9xxx_nested_irq_lock(core);
 	TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
 
 	/* cancel pending button press */
@@ -7564,6 +7727,7 @@
 
 	tabla->in_gpio_handler = false;
 	TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
+	wcd9xxx_nested_irq_unlock(core);
 	pr_debug("%s: leave\n", __func__);
 }
 
diff --git a/sound/soc/codecs/wcd9310.h b/sound/soc/codecs/wcd9310.h
index 4c9f8b4..b002316 100644
--- a/sound/soc/codecs/wcd9310.h
+++ b/sound/soc/codecs/wcd9310.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/sound/soc/codecs/wcd9320-tables.c b/sound/soc/codecs/wcd9320-tables.c
index 68a4670..ff3281e 100644
--- a/sound/soc/codecs/wcd9320-tables.c
+++ b/sound/soc/codecs/wcd9320-tables.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 136024c..92b495f 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/codecs/wcd9320.h b/sound/soc/codecs/wcd9320.h
index 739ab17..8fde2c4 100644
--- a/sound/soc/codecs/wcd9320.h
+++ b/sound/soc/codecs/wcd9320.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/apq8064-i2s.c b/sound/soc/msm/apq8064-i2s.c
index 9897baf4..77d7c4d 100644
--- a/sound/soc/msm/apq8064-i2s.c
+++ b/sound/soc/msm/apq8064-i2s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index 7bccabb..24453ec 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -43,8 +43,9 @@
 #define MSM_SLIM_0_RX_MAX_CHANNELS		2
 #define MSM_SLIM_0_TX_MAX_CHANNELS		4
 
-#define BTSCO_RATE_8KHZ 8000
-#define BTSCO_RATE_16KHZ 16000
+#define SAMPLE_RATE_8KHZ 8000
+#define SAMPLE_RATE_16KHZ 16000
+#define SAMPLE_RATE_48KHZ 48000
 
 #define BOTTOM_SPK_AMP_POS	0x1
 #define BOTTOM_SPK_AMP_NEG	0x2
@@ -69,6 +70,7 @@
 enum {
 	SLIM_1_RX_1 = 145, /* BT-SCO and USB TX */
 	SLIM_1_TX_1 = 146, /* BT-SCO and USB RX */
+	SLIM_1_TX_2 = 147, /* USB RX */
 	SLIM_3_RX_1 = 151, /* External echo-cancellation ref */
 	SLIM_3_RX_2 = 152, /* External echo-cancellation ref */
 	SLIM_3_TX_1 = 153, /* HDMI RX */
@@ -92,10 +94,12 @@
 static int msm_slim_0_tx_ch = 1;
 static int msm_slim_3_rx_ch = 1;
 
-static int msm_btsco_rate = BTSCO_RATE_8KHZ;
+static int msm_slim_1_rate = SAMPLE_RATE_8KHZ;
 static int msm_btsco_ch = 1;
-static int msm_hdmi_rx_ch = 2;
+static int msm_slim_1_rx_ch = 1;
+static int msm_slim_1_tx_ch = 1;
 
+static int msm_hdmi_rx_ch = 2;
 static int hdmi_rate_variable;
 static int rec_mode = INCALL_REC_MONO;
 
@@ -690,11 +694,14 @@
 	SOC_ENUM_SINGLE_EXT(2, hdmi_rate),
 };
 
-static const char *btsco_rate_text[] = {"8000", "16000"};
-static const struct soc_enum msm_btsco_enum[] = {
-		SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
+static const char * const slim1_rate_text[] = {"8000", "16000", "48000"};
+static const struct soc_enum msm_slim_1_rate_enum[] = {
+	SOC_ENUM_SINGLE_EXT(3, slim1_rate_text),
 };
-
+static const char * const slim1_tx_ch_text[] = {"One", "Two"};
+static const struct soc_enum msm_slim_1_tx_ch_enum[] = {
+	SOC_ENUM_SINGLE_EXT(2, slim1_tx_ch_text),
+};
 static int msm_slim_0_rx_ch_get(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
@@ -710,7 +717,7 @@
 	msm_slim_0_rx_ch = ucontrol->value.integer.value[0] + 1;
 
 	pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__,
-			msm_slim_0_rx_ch);
+		 msm_slim_0_rx_ch);
 	return 1;
 }
 
@@ -733,6 +740,27 @@
 	return 1;
 }
 
+static int msm_slim_1_tx_ch_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: msm_slim_1_tx_ch  = %d\n", __func__,
+		 msm_slim_1_tx_ch);
+
+	ucontrol->value.integer.value[0] = msm_slim_1_tx_ch - 1;
+	return 0;
+}
+
+static int msm_slim_1_tx_ch_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	msm_slim_1_tx_ch = ucontrol->value.integer.value[0] + 1;
+
+	pr_debug("%s: msm_slim_1_tx_ch = %d\n", __func__,
+		 msm_slim_1_tx_ch);
+
+	return 1;
+}
+
 static int msm_slim_3_rx_ch_get(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
@@ -752,31 +780,35 @@
 	return 1;
 }
 
-static int msm_btsco_rate_get(struct snd_kcontrol *kcontrol,
+static int msm_slim_1_rate_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	pr_debug("%s: msm_btsco_rate  = %d", __func__,
-					msm_btsco_rate);
-	ucontrol->value.integer.value[0] = msm_btsco_rate;
+	pr_debug("%s: msm_slim_1_rate  = %d", __func__,
+		 msm_slim_1_rate);
+
+	ucontrol->value.integer.value[0] = msm_slim_1_rate;
 	return 0;
 }
 
-static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol,
+static int msm_slim_1_rate_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
 	switch (ucontrol->value.integer.value[0]) {
 	case 8000:
-		msm_btsco_rate = BTSCO_RATE_8KHZ;
+		msm_slim_1_rate = SAMPLE_RATE_8KHZ;
 		break;
 	case 16000:
-		msm_btsco_rate = BTSCO_RATE_16KHZ;
+		msm_slim_1_rate = SAMPLE_RATE_16KHZ;
+		break;
+	case 48000:
+		msm_slim_1_rate = SAMPLE_RATE_48KHZ;
 		break;
 	default:
-		msm_btsco_rate = BTSCO_RATE_8KHZ;
+		msm_slim_1_rate = SAMPLE_RATE_8KHZ;
 		break;
 	}
-	pr_debug("%s: msm_btsco_rate = %d\n", __func__,
-					msm_btsco_rate);
+	pr_debug("%s: msm_slim_1_rate = %d\n", __func__,
+		 msm_slim_1_rate);
 	return 0;
 }
 
@@ -838,15 +870,17 @@
 		msm_slim_0_rx_ch_get, msm_slim_0_rx_ch_put),
 	SOC_ENUM_EXT("SLIM_0_TX Channels", msm_enum[2],
 		msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put),
-	SOC_ENUM_EXT("Internal BTSCO SampleRate", msm_btsco_enum[0],
-		msm_btsco_rate_get, msm_btsco_rate_put),
+	SOC_ENUM_EXT("SLIM_1_TX Channels", msm_slim_1_tx_ch_enum[0],
+		      msm_slim_1_tx_ch_get, msm_slim_1_tx_ch_put),
+	SOC_ENUM_EXT("SLIM_1 SampleRate", msm_slim_1_rate_enum[0],
+		      msm_slim_1_rate_get, msm_slim_1_rate_put),
 	SOC_SINGLE_EXT("Incall Rec Mode", SND_SOC_NOPM, 0, 1, 0,
 			msm_incall_rec_mode_get, msm_incall_rec_mode_put),
 	SOC_ENUM_EXT("SLIM_3_RX Channels", msm_enum[1],
 		msm_slim_3_rx_ch_get, msm_slim_3_rx_ch_put),
 	SOC_ENUM_EXT("HDMI_RX Channels", msm_enum[3],
 		msm_hdmi_rx_ch_get, msm_hdmi_rx_ch_put),
-	SOC_ENUM_EXT("HDMI RX Rate", msm_enum[1],
+	SOC_ENUM_EXT("HDMI RX Rate", msm_enum[4],
 					msm_hdmi_rate_get,
 					msm_hdmi_rate_put),
 };
@@ -1090,7 +1124,7 @@
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	int ret = 0;
-	unsigned int rx_ch = SLIM_1_RX_1, tx_ch = SLIM_1_TX_1;
+	unsigned int rx_ch = SLIM_1_RX_1, tx_ch[2] = {SLIM_1_TX_1, SLIM_1_TX_2};
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		pr_debug("%s: APQ BT/USB TX -> SLIMBUS_1_RX -> MDM TX shared ch %d\n",
@@ -1104,10 +1138,11 @@
 			goto end;
 		}
 	} else {
-		pr_debug("%s: MDM RX -> SLIMBUS_1_TX -> APQ BT/USB Rx shared ch %d\n",
-			__func__, tx_ch);
+		pr_debug("%s: MDM RX ->SLIMBUS_1_TX ->APQ BT/USB Rx shared ch %d %d\n",
+			  __func__, tx_ch[0], tx_ch[1]);
 
-		ret = snd_soc_dai_set_channel_map(cpu_dai, 1, &tx_ch, 0, 0);
+		ret = snd_soc_dai_set_channel_map(cpu_dai, msm_slim_1_tx_ch,
+						  tx_ch, 0, 0);
 		if (ret < 0) {
 			pr_err("%s: Erorr %d setting SLIM_1 TX channel map\n",
 				__func__, ret);
@@ -1401,6 +1436,24 @@
 	return 0;
 }
 
+static int msm_slim_4_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+			struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+			SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels = hw_param_interval(params,
+			SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	rate->min = rate->max = 48000;
+	channels->min = channels->max = 1;
+
+	pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
+			channels->min, channels->max);
+	return 0;
+}
+
+
 static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 			struct snd_pcm_hw_params *params)
 {
@@ -1426,11 +1479,11 @@
 	pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
 			channels->min, channels->max);
 
-	if (channels->max < 2)
-		channels->min = channels->max = 2;
 	if (!hdmi_rate_variable)
 		rate->min = rate->max = 48000;
 	channels->min = channels->max = msm_hdmi_rx_ch;
+	if (channels->max < 2)
+		channels->min = channels->max = 2;
 
 	return 0;
 }
@@ -1440,16 +1493,46 @@
 					struct snd_pcm_hw_params *params)
 {
 	struct snd_interval *rate = hw_param_interval(params,
+						      SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	rate->min = rate->max = msm_slim_1_rate;
+	channels->min = channels->max = msm_btsco_ch;
+
+	return 0;
+}
+static int msm_slim_1_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					    struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+						      SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	rate->min = rate->max = msm_slim_1_rate;
+	channels->min = channels->max = msm_slim_1_rx_ch;
+
+	return 0;
+}
+
+static int msm_slim_1_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					    struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
 					SNDRV_PCM_HW_PARAM_RATE);
 
 	struct snd_interval *channels = hw_param_interval(params,
 					SNDRV_PCM_HW_PARAM_CHANNELS);
 
-	rate->min = rate->max = msm_btsco_rate;
-	channels->min = channels->max = msm_btsco_ch;
+	rate->min = rate->max = msm_slim_1_rate;
+	channels->min = channels->max = msm_slim_1_tx_ch;
 
 	return 0;
 }
+
 static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
 					struct snd_pcm_hw_params *params)
 {
@@ -1810,20 +1893,18 @@
 		.codec_name = "snd-soc-dummy",
 	},
 	{
-		.name = "VoLTE",
-		.stream_name = "VoLTE",
-		.cpu_dai_name   = "VoLTE",
-		.platform_name  = "msm-pcm-voice",
+		.name = "VoLTE Stub",
+		.stream_name = "VoLTE Stub",
+		.cpu_dai_name   = "VOLTE_STUB",
+		.platform_name  = "msm-pcm-hostless",
 		.dynamic = 1,
 		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
-				SND_SOC_DPCM_TRIGGER_POST},
+			    SND_SOC_DPCM_TRIGGER_POST},
 		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
 		.ignore_suspend = 1,
-		/* this dainlink has playback support */
 		.ignore_pmdown_time = 1,
 		.codec_dai_name = "snd-soc-dummy-dai",
 		.codec_name = "snd-soc-dummy",
-		.be_id = MSM_FRONTEND_DAI_VOLTE,
 	},
 	{
 		.name = "MSM8960 LowLatency",
@@ -1840,6 +1921,21 @@
 		.ignore_pmdown_time = 1,
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
 	},
+	{
+		.name = "Voice2 Stub",
+		.stream_name = "Voice2 Stub",
+		.cpu_dai_name = "VOICE2_STUB",
+		.platform_name = "msm-pcm-hostless",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		/* this dainlink has playback support */
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
 	/* Backend DAI Links */
 	{
 		.name = LPASS_BE_SLIMBUS_0_RX,
@@ -2013,7 +2109,7 @@
 		.codec_dai_name = "msm-stub-rx",
 		.no_pcm = 1,
 		.be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX,
-		.be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+		.be_hw_params_fixup = msm_slim_1_rx_be_hw_params_fixup,
 		.ops = &msm_slimbus_1_be_ops,
 		.ignore_pmdown_time = 1, /* this dainlink has playback support */
 
@@ -2027,7 +2123,7 @@
 		.codec_dai_name = "msm-stub-tx",
 		.no_pcm = 1,
 		.be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
-		.be_hw_params_fixup =  msm_btsco_be_hw_params_fixup,
+		.be_hw_params_fixup =  msm_slim_1_tx_be_hw_params_fixup,
 		.ops = &msm_slimbus_1_be_ops,
 	},
 	/* Ultrasound TX Back End DAI Link */
@@ -2064,7 +2160,7 @@
 		.codec_dai_name = "msm-stub-rx",
 		.no_pcm = 1,
 		.be_id = MSM_BACKEND_DAI_SLIMBUS_4_RX,
-		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.be_hw_params_fixup = msm_slim_4_rx_be_hw_params_fixup,
 		.ops = &msm_slimbus_4_be_ops,
 		.ignore_pmdown_time = 1, /* this dainlink has playback support */
 	},
diff --git a/sound/soc/msm/lpass-dma.c b/sound/soc/msm/lpass-dma.c
index 66c1836..39a7f7f 100644
--- a/sound/soc/msm/lpass-dma.c
+++ b/sound/soc/msm/lpass-dma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/lpass-i2s.c b/sound/soc/msm/lpass-i2s.c
index 9583c52..795f4ee 100644
--- a/sound/soc/msm/lpass-i2s.c
+++ b/sound/soc/msm/lpass-i2s.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/lpass-pcm.c b/sound/soc/msm/lpass-pcm.c
index efd7c06..33d5e64 100644
--- a/sound/soc/msm/lpass-pcm.c
+++ b/sound/soc/msm/lpass-pcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/lpass-pcm.h b/sound/soc/msm/lpass-pcm.h
index 3bec9a7..e7e5597 100644
--- a/sound/soc/msm/lpass-pcm.h
+++ b/sound/soc/msm/lpass-pcm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/mdm9615.c b/sound/soc/msm/mdm9615.c
index b80a0a9..54f5f63 100644
--- a/sound/soc/msm/mdm9615.c
+++ b/sound/soc/msm/mdm9615.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index 9e042e5..0dcb958 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -134,7 +134,7 @@
 static int msm_slim_0_rx_ch = 1;
 static int msm_slim_0_tx_ch = 1;
 static int msm_hdmi_rx_ch = 8;
-
+static int hdmi_rate_variable;
 static struct clk *codec_clk;
 static int clk_users;
 
@@ -517,6 +517,7 @@
 static const char *slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
 static const char * const hdmi_rx_ch_text[] = {"Two", "Three", "Four",
 					"Five", "Six", "Seven", "Eight"};
+static const char * const hdmi_rate[] = {"Default", "Variable"};
 
 
 static const struct soc_enum msm_enum[] = {
@@ -524,6 +525,7 @@
 	SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
 	SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
 	SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text),
+	SOC_ENUM_SINGLE_EXT(2, hdmi_rate),
 
 };
 
@@ -585,6 +587,21 @@
 }
 
 
+static int msm_hdmi_rate_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	hdmi_rate_variable = ucontrol->value.integer.value[0];
+	pr_debug("%s: hdmi_rate_variable = %d\n", __func__, hdmi_rate_variable);
+	return 0;
+}
+
+static int msm_hdmi_rate_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = hdmi_rate_variable;
+	return 0;
+}
+
 static const struct snd_kcontrol_new tabla_msm_controls[] = {
 	SOC_ENUM_EXT("Speaker Function", msm_enum[0], msm_get_spk,
 		msm_set_spk),
@@ -594,7 +611,9 @@
 		msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put),
 	SOC_ENUM_EXT("HDMI_RX Channels", msm_enum[3],
 		msm_hdmi_rx_ch_get, msm_hdmi_rx_ch_put),
-
+	SOC_ENUM_EXT("HDMI RX Rate", msm_enum[4],
+					msm_hdmi_rate_get,
+					msm_hdmi_rate_put),
 };
 
 static void *def_tabla_mbhc_cal(void)
@@ -850,7 +869,9 @@
 	pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
 			channels->min, channels->max);
 
-	rate->min = rate->max = 48000;
+	/*Configure the sample rate as 48000 KHz for the LPCM playback*/
+	if (!hdmi_rate_variable)
+		rate->min = rate->max = 48000;
 	channels->min =  channels->max = msm_hdmi_rx_ch;
 
 	return 0;
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 2725299..ab02d86 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -141,6 +141,7 @@
 		} else
 			atomic_set(&prtd->pending_buffer, 0);
 		if (runtime->status->hw_ptr >= runtime->control->appl_ptr) {
+			atomic_set(&prtd->pending_buffer, 1);
 			runtime->render_flag |= SNDRV_RENDER_STOPPED;
 			break;
 		}
@@ -598,6 +599,7 @@
 				(prtd->out_head + 1) & (runtime->periods - 1);
 
 		runtime->render_flag &= ~SNDRV_RENDER_STOPPED;
+		atomic_set(&prtd->pending_buffer, 0);
 		return 0;
 	}
 	return 0;
@@ -637,12 +639,12 @@
 				break;
 			}
 		}
+		atomic_set(&prtd->pending_buffer, 1);
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		pr_debug("%s: Trigger start\n", __func__);
 		q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
 		atomic_set(&prtd->start, 1);
-		atomic_set(&prtd->pending_buffer, 1);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 		pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
@@ -762,6 +764,7 @@
 	runtime->private_data = compr;
 	atomic_set(&prtd->eos, 0);
 	compressed_audio.prtd =  &compr->prtd;
+
 	return 0;
 }
 
@@ -945,22 +948,23 @@
 				prtd->audio_client->perf_mode,
 				prtd->session_id,
 				substream->stream);
+			ret = compressed_set_volume(0);
+			if (ret < 0)
+				pr_err("%s : Set Volume failed : %d",
+					__func__, ret);
 
+			ret = q6asm_set_softpause(prtd->audio_client,
+					&softpause);
+			if (ret < 0)
+				pr_err("%s: Send SoftPause Param failed ret=%d\n",
+					__func__, ret);
+			ret = q6asm_set_softvolume(prtd->audio_client,
+					&softvol);
+			if (ret < 0)
+				pr_err("%s: Send SoftVolume Param failed ret=%d\n",
+					__func__, ret);
 			break;
 		}
-		ret = compressed_set_volume(compressed_audio.volume);
-		if (ret < 0)
-			pr_err("%s : Set Volume failed : %d", __func__, ret);
-
-		ret = q6asm_set_softpause(prtd->audio_client, &softpause);
-		if (ret < 0)
-			pr_err("%s: Send SoftPause Param failed ret=%d\n",
-				__func__, ret);
-		ret = q6asm_set_softvolume(prtd->audio_client, &softvol);
-		if (ret < 0)
-			pr_err("%s: Send SoftVolume Param failed ret=%d\n",
-				__func__, ret);
-
 	} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 		switch (compr->info.codec_param.codec.id) {
 		case SND_AUDIOCODEC_AMRWB:
@@ -1054,11 +1058,10 @@
 		pr_debug("SNDRV_COMPRESS_TSTAMP\n");
 
 		memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
-		timestamp = q6asm_get_session_time(prtd->audio_client);
-		if (timestamp < 0) {
-			pr_err("%s: Get Session Time return value =%lld\n",
-				__func__, timestamp);
-			return -EAGAIN;
+		rc = q6asm_get_session_time(prtd->audio_client, &timestamp);
+		if (rc < 0) {
+			pr_err("%s: fail to get session tstamp\n", __func__);
+			return rc;
 		}
 		temp = (timestamp * 2 * runtime->channels);
 		temp = temp * (runtime->rate/1000);
diff --git a/sound/soc/msm/msm-compr-q6.h b/sound/soc/msm/msm-compr-q6.h
index cb7f714..d91854e 100644
--- a/sound/soc/msm/msm-compr-q6.h
+++ b/sound/soc/msm/msm-compr-q6.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 16a4aaa..ec5b76d 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -455,8 +455,8 @@
 	},
 	{
 		.playback = {
-			.stream_name = "SGLTE Playback",
-			.aif_name = "SGLTE_DL",
+			.stream_name = "Voice2 Playback",
+			.aif_name = "VOICE2_DL",
 			.rates = SNDRV_PCM_RATE_8000_48000,
 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
 			.channels_min = 1,
@@ -465,8 +465,8 @@
 			.rate_max =     48000,
 		},
 		.capture = {
-			.stream_name = "SGLTE Capture",
-			.aif_name = "SGLTE_UL",
+			.stream_name = "Voice2 Capture",
+			.aif_name = "VOICE2_UL",
 			.rates = SNDRV_PCM_RATE_8000_48000,
 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
 			.channels_min = 1,
@@ -475,8 +475,57 @@
 			.rate_max =     48000,
 		},
 		.ops = &msm_fe_dai_ops,
-		.name = "SGLTE",
+		.name = "Voice2",
 	},
+	{
+		.playback = {
+			.stream_name = "VoLTE Stub Playback",
+			.aif_name = "VOLTE_STUB_DL",
+			.rates = SNDRV_PCM_RATE_8000_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min = 8000,
+			.rate_max = 48000,
+		},
+		.capture = {
+			.stream_name = "VoLTE Stub Capture",
+			.aif_name = "VOLTE_STUB_UL",
+			.rates = SNDRV_PCM_RATE_8000_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min = 8000,
+			.rate_max = 48000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "VOLTE_STUB",
+	},
+	{
+		.playback = {
+			.stream_name = "Voice2 Stub Playback",
+			.aif_name = "VOICE2_STUB_DL",
+			.rates = SNDRV_PCM_RATE_8000_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min = 8000,
+			.rate_max = 48000,
+		},
+		.capture = {
+			.stream_name = "VoLTE Stub Capture",
+			.aif_name = "VOICE2_STUB_UL",
+			.rates = SNDRV_PCM_RATE_8000_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min = 8000,
+			.rate_max = 48000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "VOICE2_STUB",
+	},
+
 };
 
 static __devinit int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm-dai-q6-hdmi.c b/sound/soc/msm/msm-dai-q6-hdmi.c
index 2b3dd5f..99290a1 100644
--- a/sound/soc/msm/msm-dai-q6-hdmi.c
+++ b/sound/soc/msm/msm-dai-q6-hdmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
@@ -91,11 +91,25 @@
 	u32 channel_allocation = 0;
 	u32 level_shift  = 0; /* 0dB */
 	bool down_mix = FALSE;
+	int sample_rate = 48000;
 
 	dai_data->channels = params_channels(params);
 	dai_data->rate = params_rate(params);
 	dai_data->port_config.hdmi_multi_ch.reserved = 0;
 
+	switch (dai_data->rate) {
+	case 48000:
+		sample_rate = HDMI_SAMPLE_RATE_48KHZ;
+		break;
+	case 44100:
+		sample_rate = HDMI_SAMPLE_RATE_44_1KHZ;
+		break;
+	case 32000:
+		sample_rate = HDMI_SAMPLE_RATE_32KHZ;
+		break;
+	}
+	hdmi_msm_audio_sample_rate_reset(sample_rate);
+
 	switch (dai_data->channels) {
 	case 2:
 		channel_allocation  = 0;
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index ee1ab79..5f3c036 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm-dai-stub.c b/sound/soc/msm/msm-dai-stub.c
index b2bfa2c..c8125e8 100644
--- a/sound/soc/msm/msm-dai-stub.c
+++ b/sound/soc/msm/msm-dai-stub.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm-dai.c b/sound/soc/msm/msm-dai.c
index 61e4675..b821814 100644
--- a/sound/soc/msm/msm-dai.c
+++ b/sound/soc/msm/msm-dai.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  *
  * Derived from msm-pcm.c and msm7201.c.
  *
diff --git a/sound/soc/msm/msm-lowlatency-pcm-q6.c b/sound/soc/msm/msm-lowlatency-pcm-q6.c
index 3b4b0e1..a8673d9 100644
--- a/sound/soc/msm/msm-lowlatency-pcm-q6.c
+++ b/sound/soc/msm/msm-lowlatency-pcm-q6.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm-multi-ch-pcm-q6.c b/sound/soc/msm/msm-multi-ch-pcm-q6.c
index 5b0759c..dcd57a2 100644
--- a/sound/soc/msm/msm-multi-ch-pcm-q6.c
+++ b/sound/soc/msm/msm-multi-ch-pcm-q6.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm-mvs.c b/sound/soc/msm/msm-mvs.c
index eca9864..88c0b4e 100644
--- a/sound/soc/msm/msm-mvs.c
+++ b/sound/soc/msm/msm-mvs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/sound/soc/msm/msm-pcm-afe.c b/sound/soc/msm/msm-pcm-afe.c
index b7b4d51..e01c759 100644
--- a/sound/soc/msm/msm-pcm-afe.c
+++ b/sound/soc/msm/msm-pcm-afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -322,8 +322,8 @@
 				(app_cb)q6asm_event_handler, prtd);
 	if (!prtd->audio_client) {
 		pr_debug("%s: Could not allocate memory\n", __func__);
-		kfree(prtd);
 		mutex_unlock(&prtd->lock);
+		kfree(prtd);
 		return -ENOMEM;
 	}
 	hrtimer_init(&prtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
diff --git a/sound/soc/msm/msm-pcm-afe.h b/sound/soc/msm/msm-pcm-afe.h
index 9be11f3..674c7b5 100644
--- a/sound/soc/msm/msm-pcm-afe.h
+++ b/sound/soc/msm/msm-pcm-afe.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm-pcm-hostless.c b/sound/soc/msm/msm-pcm-hostless.c
index c9b23d0..789749f 100644
--- a/sound/soc/msm/msm-pcm-hostless.c
+++ b/sound/soc/msm/msm-pcm-hostless.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm-pcm-lpa.c b/sound/soc/msm/msm-pcm-lpa.c
index 5f37ead..27dab2e 100644
--- a/sound/soc/msm/msm-pcm-lpa.c
+++ b/sound/soc/msm/msm-pcm-lpa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -84,10 +84,12 @@
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct audio_aio_write_param param;
 	struct audio_buffer *buf = NULL;
+	struct output_meta_data_st output_meta_data;
 	unsigned long flag = 0;
 	int i = 0;
 
 	pr_debug("%s\n", __func__);
+	memset(&output_meta_data, 0x0, sizeof(struct output_meta_data_st));
 	spin_lock_irqsave(&the_locks.event_lock, flag);
 	switch (opcode) {
 	case ASM_DATA_EVENT_WRITE_DONE: {
@@ -116,17 +118,36 @@
 			pr_debug("%s:lpa driver underrun\n", __func__);
 			break;
 		}
-		pr_debug("%s:writing %d bytes of buffer to dsp 2\n",
-				__func__, prtd->pcm_count);
 
-		param.paddr = (unsigned long)buf[0].phys
-				+ (prtd->out_head * prtd->pcm_count);
-		param.len = prtd->pcm_count;
-		param.msw_ts = 0;
-		param.lsw_ts = 0;
+		pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n",
+				__func__, prtd->pcm_count, prtd->out_head);
+		pr_debug("%s:writing buffer[%d] from 0x%08x\n",
+				__func__, prtd->out_head,
+				((unsigned int)buf[0].phys
+				+ (prtd->out_head * prtd->pcm_count)));
+
+		if (prtd->meta_data_mode) {
+			memcpy(&output_meta_data, (char *)(buf->data +
+				prtd->out_head * prtd->pcm_count),
+				sizeof(struct output_meta_data_st));
+			param.len = output_meta_data.frame_size;
+		} else {
+			param.len = prtd->pcm_count;
+		}
+
+		pr_debug("meta_data_length: %d, frame_length: %d\n",
+			 output_meta_data.meta_data_length,
+			 output_meta_data.frame_size);
+
+		param.paddr = (unsigned long)buf[0].phys +
+				(prtd->out_head * prtd->pcm_count) +
+				output_meta_data.meta_data_length;
+		param.msw_ts = output_meta_data.timestamp_msw;
+		param.lsw_ts = output_meta_data.timestamp_lsw;
 		param.flags = NO_TIMESTAMP;
-		param.uid =  (unsigned long)buf[0].phys
-				+ (prtd->out_head * prtd->pcm_count);
+		param.uid =  (unsigned long)buf[0].phys +
+				(prtd->out_head * prtd->pcm_count) +
+				output_meta_data.meta_data_length;
 		for (i = 0; i < sizeof(struct audio_aio_write_param)/4;
 					i++, ++ptrmem)
 			pr_debug("cmd[%d]=0x%08x\n", i, *ptrmem);
@@ -162,12 +183,27 @@
 				" of buffer to dsp\n",
 				__func__, prtd->pcm_count);
 			buf = prtd->audio_client->port[IN].buf;
-			param.paddr = (unsigned long)buf[prtd->out_head].phys;
-			param.len = prtd->pcm_count;
-			param.msw_ts = 0;
-			param.lsw_ts = 0;
+
+			pr_debug("%s:writing buffer[%d] from 0x%08x\n",
+				__func__, prtd->out_head,
+				((unsigned int)buf[0].phys +
+				(prtd->out_head * prtd->pcm_count)));
+
+			if (prtd->meta_data_mode) {
+				memcpy(&output_meta_data, (char *)(buf->data +
+					prtd->out_head * prtd->pcm_count),
+					sizeof(struct output_meta_data_st));
+				param.len = output_meta_data.frame_size;
+			} else {
+				param.len = prtd->pcm_count;
+			}
+			param.paddr = (unsigned long)buf[prtd->out_head].phys +
+					output_meta_data.meta_data_length;
+			param.msw_ts = output_meta_data.timestamp_msw;
+			param.lsw_ts = output_meta_data.timestamp_lsw;
 			param.flags = NO_TIMESTAMP;
-			param.uid =  (unsigned long)buf[prtd->out_head].phys;
+			param.uid = (unsigned long)buf[prtd->out_head].phys +
+					output_meta_data.meta_data_length;
 			if (q6asm_async_write(prtd->audio_client,
 						&param) < 0)
 				pr_err("%s:q6asm_async_write failed\n",
@@ -230,24 +266,43 @@
 	struct msm_audio *prtd = runtime->private_data;
 	struct audio_aio_write_param param;
 	struct audio_buffer *buf = NULL;
+	struct output_meta_data_st output_meta_data;
 
 	pr_err("%s\n", __func__);
 	if (runtime->render_flag & SNDRV_RENDER_STOPPED) {
 		buf = prtd->audio_client->port[IN].buf;
+
 		pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n",
 				__func__, prtd->pcm_count, prtd->out_head);
 		pr_debug("%s:writing buffer[%d] from 0x%08x\n",
 				__func__, prtd->out_head,
 				((unsigned int)buf[0].phys
 				+ (prtd->out_head * prtd->pcm_count)));
-		param.paddr = (unsigned long)buf[0].phys
-				+ (prtd->out_head * prtd->pcm_count);
-		param.len = prtd->pcm_count;
-		param.msw_ts = 0;
-		param.lsw_ts = 0;
+
+		if (prtd->meta_data_mode) {
+			memcpy(&output_meta_data, (char *)(buf->data +
+				prtd->out_head * prtd->pcm_count),
+				sizeof(struct output_meta_data_st));
+			param.len = output_meta_data.frame_size;
+		} else {
+			param.len = prtd->pcm_count;
+		}
+		pr_debug("meta_data_length: %d, frame_length: %d\n",
+			 output_meta_data.meta_data_length,
+			 output_meta_data.frame_size);
+		pr_debug("timestamp_msw: %d, timestamp_lsw: %d\n",
+			 output_meta_data.timestamp_msw,
+			 output_meta_data.timestamp_lsw);
+
+		param.paddr = (unsigned long)buf[0].phys +
+				(prtd->out_head * prtd->pcm_count) +
+				output_meta_data.meta_data_length;
+		param.msw_ts = output_meta_data.timestamp_msw;
+		param.lsw_ts = output_meta_data.timestamp_lsw;
 		param.flags = NO_TIMESTAMP;
-		param.uid =  (unsigned long)buf[0].phys
-				+ (prtd->out_head * prtd->pcm_count);
+		param.uid =  (unsigned long)buf[0].phys +
+				(prtd->out_head * prtd->pcm_count +
+				output_meta_data.meta_data_length);
 		if (q6asm_async_write(prtd->audio_client, &param) < 0)
 			pr_err("%s:q6asm_async_write failed\n",
 			__func__);
@@ -270,13 +325,13 @@
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 		prtd->pcm_irq_pos = 0;
+		atomic_set(&prtd->pending_buffer, 1);
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		pr_debug("SNDRV_PCM_TRIGGER_START\n");
 		q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
 		atomic_set(&prtd->start, 1);
 		atomic_set(&prtd->stop, 0);
-		atomic_set(&prtd->pending_buffer, 1);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 		pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
@@ -336,6 +391,7 @@
 		return -ENOMEM;
 	}
 	prtd->audio_client->perf_mode = false;
+	prtd->meta_data_mode = false;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		ret = q6asm_open_write(prtd->audio_client, FORMAT_LINEAR_PCM);
 		if (ret < 0) {
@@ -445,6 +501,7 @@
 		SNDRV_PCM_STREAM_PLAYBACK);
 	pr_debug("%s\n", __func__);
 	q6asm_audio_client_free(prtd->audio_client);
+	prtd->meta_data_mode = false;
 	kfree(prtd);
 
 	return 0;
@@ -561,11 +618,10 @@
 		pr_debug("SNDRV_COMPRESS_TSTAMP\n");
 
 		memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
-		timestamp = q6asm_get_session_time(prtd->audio_client);
-		if (timestamp < 0) {
-			pr_err("%s: Get Session Time return value =%lld\n",
-				__func__, timestamp);
-			return -EAGAIN;
+		rc = q6asm_get_session_time(prtd->audio_client, &timestamp);
+		if (rc < 0) {
+			pr_err("%s: fail to get session tstamp\n", __func__);
+			return rc;
 		}
 		temp = (timestamp * 2 * runtime->channels);
 		temp = temp * (runtime->rate/1000);
@@ -591,6 +647,14 @@
 			pr_err("Flush cmd timeout\n");
 		prtd->pcm_irq_pos = 0;
 		break;
+	case SNDRV_COMPRESS_METADATA_MODE:
+		if (!atomic_read(&prtd->start)) {
+			pr_debug("Metadata mode enabled\n");
+			prtd->meta_data_mode = true;
+			return 0;
+		}
+		pr_debug("Metadata mode not enabled\n");
+		return -EPERM;
 	default:
 		break;
 	}
diff --git a/sound/soc/msm/msm-pcm-q6.c b/sound/soc/msm/msm-pcm-q6.c
index 3189c28..62deb63 100644
--- a/sound/soc/msm/msm-pcm-q6.c
+++ b/sound/soc/msm/msm-pcm-q6.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -41,7 +41,8 @@
 
 #define PLAYBACK_NUM_PERIODS	8
 #define PLAYBACK_PERIOD_SIZE	2048
-#define CAPTURE_NUM_PERIODS	2
+#define CAPTURE_MIN_NUM_PERIODS 2
+#define CAPTURE_MAX_NUM_PERIODS 16
 #define CAPTURE_MAX_PERIOD_SIZE 4096
 #define CAPTURE_MIN_PERIOD_SIZE 320
 
@@ -57,11 +58,12 @@
 	.rate_max =             48000,
 	.channels_min =         1,
 	.channels_max =         4,
-	.buffer_bytes_max =     CAPTURE_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
+	.buffer_bytes_max =     CAPTURE_MAX_NUM_PERIODS *
+				CAPTURE_MAX_PERIOD_SIZE,
 	.period_bytes_min =	CAPTURE_MIN_PERIOD_SIZE,
 	.period_bytes_max =     CAPTURE_MAX_PERIOD_SIZE,
-	.periods_min =          CAPTURE_NUM_PERIODS,
-	.periods_max =          CAPTURE_NUM_PERIODS,
+	.periods_min =          CAPTURE_MIN_NUM_PERIODS,
+	.periods_max =          CAPTURE_MAX_NUM_PERIODS,
 	.fifo_size =            0,
 };
 
@@ -90,7 +92,7 @@
 	8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
 };
 
-static uint32_t in_frame_info[CAPTURE_NUM_PERIODS][2];
+static uint32_t in_frame_info[CAPTURE_MAX_NUM_PERIODS][2];
 
 static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
 	.count = ARRAY_SIZE(supported_sample_rates),
@@ -365,8 +367,8 @@
 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 		ret = snd_pcm_hw_constraint_minmax(runtime,
 			SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
-			CAPTURE_NUM_PERIODS * CAPTURE_MIN_PERIOD_SIZE,
-			CAPTURE_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE);
+			CAPTURE_MIN_NUM_PERIODS * CAPTURE_MIN_PERIOD_SIZE,
+			CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE);
 		if (ret < 0) {
 			pr_err("constraint for buffer bytes min max ret = %d\n",
 									ret);
@@ -673,6 +675,10 @@
 			prtd->audio_client,
 			(params_buffer_bytes(params) / params_periods(params)),
 				params_periods(params));
+		pr_debug("buff bytes = %d, period size = %d,\
+			period count = %d\n", params_buffer_bytes(params),
+			params_periods(params),
+			params_buffer_bytes(params) / params_periods(params));
 	} else {
 		ret = q6asm_audio_client_buf_alloc_contiguous(dir,
 			prtd->audio_client,
diff --git a/sound/soc/msm/msm-pcm-q6.h b/sound/soc/msm/msm-pcm-q6.h
index 4038b6b..0522f54 100644
--- a/sound/soc/msm/msm-pcm-q6.h
+++ b/sound/soc/msm/msm-pcm-q6.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2009,2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009,2011 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -82,6 +82,7 @@
 	int mmap_flag;
 	atomic_t pending_buffer;
 	int cmd_interrupt;
+	bool meta_data_mode;
 };
 
 struct output_meta_data_st {
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 1846379..d560dbb 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -75,6 +75,7 @@
 			INT_RX_VOL_MAX_STEPS);
 
 static int msm_route_ec_ref_rx;
+static int msm_route_ext_ec_ref;
 
 /* Equal to Frontend after last of the MULTIMEDIA SESSIONS */
 #define MAX_EQ_SESSIONS		MSM_FRONTEND_DAI_CS_VOICE
@@ -553,8 +554,8 @@
 		session_id = voc_get_session_id(VOICE_SESSION_NAME);
 	else if (val == MSM_FRONTEND_DAI_VOLTE)
 		session_id = voc_get_session_id(VOLTE_SESSION_NAME);
-	else if (val == MSM_FRONTEND_DAI_SGLTE)
-		session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+	else if (val == MSM_FRONTEND_DAI_VOICE2)
+		session_id = voc_get_session_id(VOICE2_SESSION_NAME);
 	else
 		session_id = voc_get_session_id(VOIP_SESSION_NAME);
 
@@ -1136,6 +1137,57 @@
 	msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put),
 };
 
+static int msm_routing_ext_ec_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: ext_ec_ref_rx  = %x\n", __func__, msm_route_ext_ec_ref);
+
+	mutex_lock(&routing_lock);
+	ucontrol->value.integer.value[0] = msm_route_ext_ec_ref;
+	mutex_unlock(&routing_lock);
+	return 0;
+}
+
+static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+	int mux = ucontrol->value.enumerated.item[0];
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	int ret = 0;
+
+	pr_debug("%s: msm_route_ec_ref_rx = %d value = %ld\n",
+		 __func__, msm_route_ext_ec_ref,
+		 ucontrol->value.integer.value[0]);
+
+	mutex_lock(&routing_lock);
+	switch (ucontrol->value.integer.value[0]) {
+	case 1:
+		msm_route_ext_ec_ref = MI2S_TX;
+		ret = voc_set_ext_ec_ref(msm_route_ext_ec_ref, true);
+		break;
+	default:
+		msm_route_ext_ec_ref = AFE_PORT_INVALID;
+		ret = voc_set_ext_ec_ref(msm_route_ext_ec_ref, false);
+		break;
+	}
+	snd_soc_dapm_mux_update_power(widget, kcontrol, 1, mux, e);
+	mutex_unlock(&routing_lock);
+	return ret;
+}
+
+static const char * const ext_ec_ref_rx[] = {"NONE", "MI2S_TX"};
+
+static const struct soc_enum msm_route_ext_ec_ref_rx_enum[] = {
+	SOC_ENUM_SINGLE_EXT(2, ext_ec_ref_rx),
+};
+
+static const struct snd_kcontrol_new voc_ext_ec_mux =
+	SOC_DAPM_ENUM_EXT("VOC_EXT_EC MUX Mux", msm_route_ext_ec_ref_rx_enum[0],
+			  msm_routing_ext_ec_get, msm_routing_ext_ec_put);
+
+
 static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = {
 	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_RX ,
 	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -1453,8 +1505,8 @@
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_PRI_I2S_RX,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_PRI_I2S_RX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_PRI_I2S_RX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
 };
 
@@ -1468,8 +1520,8 @@
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_I2S_RX,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_SEC_I2S_RX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
 };
 
@@ -1483,8 +1535,8 @@
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
 };
 
@@ -1498,11 +1550,17 @@
 	SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX,
 	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
 	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_INT_BT_SCO_RX ,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
 };
 
@@ -1516,8 +1574,14 @@
 	SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_MI2S_RX,
 	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
 	msm_routing_put_voice_stub_mixer),
-	SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_MI2S_RX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_MI2S_RX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_MI2S_RX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_MI2S_RX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
 };
 
@@ -1531,11 +1595,17 @@
 	SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AFE_PCM_RX,
 	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
 	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AFE_PCM_RX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AFE_PCM_RX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AFE_PCM_RX,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_AFE_PCM_RX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_AFE_PCM_RX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
 };
 
@@ -1549,11 +1619,17 @@
 	SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AUXPCM_RX,
 	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
 	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AUXPCM_RX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AUXPCM_RX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AUXPCM_RX,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_AUXPCM_RX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_AUXPCM_RX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
 };
 
@@ -1567,8 +1643,8 @@
 	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
 };
 
@@ -1585,8 +1661,14 @@
 	SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_HDMI_RX,
 	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
 	msm_routing_put_voice_stub_mixer),
-	SOC_SINGLE_EXT("SGLTE", MSM_BACKEND_DAI_HDMI_RX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_HDMI_RX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_HDMI_RX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_HDMI_RX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
 };
 
@@ -1594,18 +1676,36 @@
 	SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_EXTPROC_RX,
 	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
 	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_EXTPROC_RX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_EXTPROC_RX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
 };
 
 static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = {
 	SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX,
 	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
 	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
 };
 
 static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = {
 	SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX,
 	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
 	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
 };
 
 static const struct snd_kcontrol_new tx_voice_mixer_controls[] = {
@@ -1653,27 +1753,27 @@
 	msm_routing_put_voice_mixer),
 };
 
-static const struct snd_kcontrol_new tx_sglte_mixer_controls[] = {
-	SOC_SINGLE_EXT("PRI_TX_SGLTE", MSM_BACKEND_DAI_PRI_I2S_TX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+static const struct snd_kcontrol_new tx_voice2_mixer_controls[] = {
+	SOC_SINGLE_EXT("PRI_TX_Voice2", MSM_BACKEND_DAI_PRI_I2S_TX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("MI2S_TX_SGLTE", MSM_BACKEND_DAI_MI2S_TX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("MI2S_TX_Voice2", MSM_BACKEND_DAI_MI2S_TX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("SLIM_0_TX_SGLTE", MSM_BACKEND_DAI_SLIMBUS_0_TX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("SLIM_0_TX_Voice2", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_SGLTE",
-	MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_SGLTE, 1, 0,
+	SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice2",
+	MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICE2, 1, 0,
 	msm_routing_get_voice_mixer, msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("AFE_PCM_TX_SGLTE", MSM_BACKEND_DAI_AFE_PCM_TX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("AFE_PCM_TX_Voice2", MSM_BACKEND_DAI_AFE_PCM_TX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("AUX_PCM_TX_SGLTE", MSM_BACKEND_DAI_AUXPCM_TX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_AUXPCM_TX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
-	SOC_SINGLE_EXT("SEC_AUX_PCM_TX_SGLTE", MSM_BACKEND_DAI_SEC_AUXPCM_TX,
-	MSM_FRONTEND_DAI_SGLTE, 1, 0, msm_routing_get_voice_mixer,
+	SOC_SINGLE_EXT("SEC_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_SEC_AUXPCM_TX,
+	MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
 };
 static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
@@ -1727,6 +1827,60 @@
 	msm_routing_put_voice_stub_mixer),
 };
 
+static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = {
+	SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("PRIMARY_I2S_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+	MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+};
+
+static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = {
+	SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("PRIMARY_I2S_TX", MSM_BACKEND_DAI_PRI_I2S_TX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+	MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
+	msm_routing_put_voice_stub_mixer),
+};
+
 static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
 	SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
 	MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
@@ -2104,8 +2258,8 @@
 	SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("VoLTE_DL", "VoLTE Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("VoLTE_UL", "VoLTE Capture", 0, 0, 0, 0),
-	SND_SOC_DAPM_AIF_IN("SGLTE_DL", "SGLTE Playback", 0, 0, 0, 0),
-	SND_SOC_DAPM_AIF_OUT("SGLTE_UL", "SGLTE Capture", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("VOICE2_DL", "Voice2 Playback", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("VOICE2_UL", "Voice2 Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback",
 		0, 0, 0, 0),
@@ -2169,6 +2323,12 @@
 			    0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("VOLTE_STUB_DL", "VOLTE_STUB Playback", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("VOLTE_STUB_UL", "VOLTE_STUB Capture", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("VOICE2_STUB_DL",
+			    "VOICE2_STUB Playback", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("VOICE2_STUB_UL",
+			     "VOICE2_STUB Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("STUB_RX", "Stub Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("STUB_TX", "Stub Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0),
@@ -2257,9 +2417,9 @@
 	SND_SOC_DAPM_MIXER("VoLTE_Tx Mixer",
 				SND_SOC_NOPM, 0, 0, tx_volte_mixer_controls,
 				ARRAY_SIZE(tx_volte_mixer_controls)),
-	SND_SOC_DAPM_MIXER("SGLTE_Tx Mixer",
-				SND_SOC_NOPM, 0, 0, tx_sglte_mixer_controls,
-				ARRAY_SIZE(tx_sglte_mixer_controls)),
+	SND_SOC_DAPM_MIXER("Voice2_Tx Mixer",
+			   SND_SOC_NOPM, 0, 0, tx_voice2_mixer_controls,
+			   ARRAY_SIZE(tx_voice2_mixer_controls)),
 	SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 	int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)),
 	SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
@@ -2300,10 +2460,16 @@
 	ARRAY_SIZE(sbus_3_rx_port_mixer_controls)),
 	SND_SOC_DAPM_MIXER("MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0,
 	mi2s_rx_port_mixer_controls, ARRAY_SIZE(mi2s_rx_port_mixer_controls)),
-
+	SND_SOC_DAPM_MIXER("VoLTE Stub Tx Mixer", SND_SOC_NOPM, 0, 0,
+			   tx_volte_stub_mixer_controls,
+			   ARRAY_SIZE(tx_volte_stub_mixer_controls)),
+	SND_SOC_DAPM_MIXER("Voice2 Stub Tx Mixer", SND_SOC_NOPM, 0, 0,
+			   tx_voice2_stub_mixer_controls,
+			   ARRAY_SIZE(tx_voice2_stub_mixer_controls)),
 	/* Virtual Pins to force backends ON atm */
 	SND_SOC_DAPM_OUTPUT("BE_OUT"),
 	SND_SOC_DAPM_INPUT("BE_IN"),
+	SND_SOC_DAPM_MUX("VOC_EXT_EC MUX", SND_SOC_NOPM, 0, 0, &voc_ext_ec_mux),
 
 };
 
@@ -2423,53 +2589,55 @@
 
 	{"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"PRI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
-	{"PRI_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+	{"PRI_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
 	{"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
 
 	{"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"SEC_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
-	{"SEC_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+	{"SEC_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
 	{"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"},
 
 	{"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"SLIM_0_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
-	{"SLIM_0_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+	{"SLIM_0_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
 	{"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
 
 	{"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"INTERNAL_BT_SCO_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
-	{"INTERNAL_BT_SCO_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+	{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
 	{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
 
 	{"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"AFE_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
-	{"AFE_PCM_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+	{"AFE_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
 	{"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"},
 
 	{"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
-	{"AUX_PCM_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+	{"AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
 	{"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"},
 
 	{"SEC_AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"SEC_AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
-	{"SEC_AUX_PCM_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+	{"SEC_AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
 	{"SEC_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX_Voice Mixer"},
 
 	{"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"HDMI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
-	{"HDMI_RX_Voice Mixer", "SGLTE", "SGLTE_DL"},
+	{"HDMI_RX_Voice Mixer", "Voice2", "VOICE2_DL"},
 	{"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"HDMI", NULL, "HDMI_RX_Voice Mixer"},
 	{"HDMI", NULL, "HDMI_DL_HL"},
 
+	{"VOC_EXT_EC MUX", "MI2S_TX" , "MI2S_TX"},
+	{"CS-VOICE_UL1", NULL, "VOC_EXT_EC MUX"},
 	{"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
 	{"Voice_Tx Mixer", "MI2S_TX_Voice", "MI2S_TX"},
 	{"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
@@ -2485,14 +2653,14 @@
 	{"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"},
 	{"VoLTE_Tx Mixer", "SEC_AUX_PCM_TX_VoLTE", "SEC_AUX_PCM_TX"},
 	{"VoLTE_UL", NULL, "VoLTE_Tx Mixer"},
-	{"SGLTE_Tx Mixer", "PRI_TX_SGLTE", "PRI_I2S_TX"},
-	{"SGLTE_Tx Mixer", "MI2S_TX_SGLTE", "MI2S_TX"},
-	{"SGLTE_Tx Mixer", "SLIM_0_TX_SGLTE", "SLIMBUS_0_TX"},
-	{"SGLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_SGLTE", "INT_BT_SCO_TX"},
-	{"SGLTE_Tx Mixer", "AFE_PCM_TX_SGLTE", "PCM_TX"},
-	{"SGLTE_Tx Mixer", "AUX_PCM_TX_SGLTE", "AUX_PCM_TX"},
-	{"SGLTE_Tx Mixer", "SEC_AUX_PCM_TX_SGLTE", "SEC_AUX_PCM_TX"},
-	{"SGLTE_UL", NULL, "SGLTE_Tx Mixer"},
+	{"Voice2_Tx Mixer", "PRI_TX_Voice2", "PRI_I2S_TX"},
+	{"Voice2_Tx Mixer", "MI2S_TX_Voice2", "MI2S_TX"},
+	{"Voice2_Tx Mixer", "SLIM_0_TX_Voice2", "SLIMBUS_0_TX"},
+	{"Voice2_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice2", "INT_BT_SCO_TX"},
+	{"Voice2_Tx Mixer", "AFE_PCM_TX_Voice2", "PCM_TX"},
+	{"Voice2_Tx Mixer", "AUX_PCM_TX_Voice2", "AUX_PCM_TX"},
+	{"Voice2_Tx Mixer", "SEC_AUX_PCM_TX_Voice2", "SEC_AUX_PCM_TX"},
+	{"VOICE2_UL", NULL, "Voice2_Tx Mixer"},
 	{"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
 	{"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"},
 	{"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"},
@@ -2536,17 +2704,50 @@
 	{"Voice Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"},
 	{"VOICE_STUB_UL", NULL, "Voice Stub Tx Mixer"},
 
+	{"VoLTE Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"},
+	{"VoLTE Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
+	{"VoLTE Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+	{"VoLTE Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"},
+	{"VoLTE Stub Tx Mixer", "MI2S_TX", "MI2S_TX"},
+	{"VoLTE Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"},
+	{"VoLTE Stub Tx Mixer", "PRIMARY_I2S_TX", "PRI_I2S_TX"},
+	{"VoLTE Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"},
+	{"VOLTE_STUB_UL", NULL, "VoLTE Stub Tx Mixer"},
+
+	{"Voice2 Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"},
+	{"Voice2 Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
+	{"Voice2 Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+	{"Voice2 Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"},
+	{"Voice2 Stub Tx Mixer", "MI2S_TX", "MI2S_TX"},
+	{"Voice2 Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"},
+	{"Voice2 Stub Tx Mixer", "PRIMARY_I2S_TX", "PRI_I2S_TX"},
+	{"Voice2 Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"},
+	{"VOICE2_STUB_UL", NULL, "Voice2 Stub Tx Mixer"},
+
 	{"STUB_RX Mixer", "Voice Stub", "VOICE_STUB_DL"},
+	{"STUB_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+	{"STUB_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
 	{"STUB_RX", NULL, "STUB_RX Mixer"},
 	{"SLIMBUS_1_RX Mixer", "Voice Stub", "VOICE_STUB_DL"},
+	{"SLIMBUS_1_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+	{"SLIMBUS_1_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
 	{"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"},
 	{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+	{"INTERNAL_BT_SCO_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+	{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
 	{"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+	{"MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+	{"MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
 	{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
 	{"HDMI_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+	{"HDMI_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+	{"HDMI_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
 	{"AFE_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
-
+	{"AFE_PCM_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+	{"AFE_PCM_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
 	{"SLIMBUS_3_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+	{"SLIMBUS_3_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
+	{"SLIMBUS_3_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
 	{"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"},
 
 	{"SLIMBUS_1_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index 23e3943..48d70b9 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -66,7 +66,9 @@
 	MSM_FRONTEND_DAI_AFE_TX,
 	MSM_FRONTEND_DAI_VOICE_STUB,
 	MSM_FRONTEND_DAI_VOLTE,
-	MSM_FRONTEND_DAI_SGLTE,
+	MSM_FRONTEND_DAI_VOICE2,
+	MSM_FRONTEND_DAI_VOLTE_STUB,
+	MSM_FRONTEND_DAI_VOICE2_STUB,
 	MSM_FRONTEND_DAI_MAX,
 };
 
diff --git a/sound/soc/msm/msm-pcm-voice.c b/sound/soc/msm/msm-pcm-voice.c
index 91f4edc..4f9b822 100644
--- a/sound/soc/msm/msm-pcm-voice.c
+++ b/sound/soc/msm/msm-pcm-voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -59,9 +59,10 @@
 		return false;
 }
 
-static int is_sglte(struct msm_voice *psglte)
+static int is_voice2(struct msm_voice *pvoice2)
+
 {
-	if (psglte == &voice_info[SGLTE_SESSION_INDEX])
+	if (pvoice2 == &voice_info[VOICE2_SESSION_INDEX])
 		return true;
 	else
 		return false;
@@ -100,15 +101,15 @@
 	if (!strncmp("VoLTE", substream->pcm->id, 5)) {
 		voice = &voice_info[VOLTE_SESSION_INDEX];
 		pr_debug("%s: Open VoLTE Substream Id=%s\n",
-				__func__, substream->pcm->id);
-	} else if (!strncmp("SGLTE", substream->pcm->id, 5)) {
-		voice = &voice_info[SGLTE_SESSION_INDEX];
-		pr_debug("%s: Open SGLTE Substream Id=%s\n",
-				__func__, substream->pcm->id);
+			 __func__, substream->pcm->id);
+	} else if (!strncmp("Voice2", substream->pcm->id, 6)) {
+		voice = &voice_info[VOICE2_SESSION_INDEX];
+		pr_debug("%s: Open Voice2 Substream Id=%s\n",
+			 __func__, substream->pcm->id);
 	} else {
 		voice = &voice_info[VOICE_SESSION_INDEX];
 		pr_debug("%s: Open VOICE Substream Id=%s\n",
-				__func__, substream->pcm->id);
+			 __func__, substream->pcm->id);
 	}
 	mutex_lock(&voice->lock);
 
@@ -174,8 +175,8 @@
 		pr_debug("end voice call\n");
 		if (is_volte(prtd))
 			session_id = voc_get_session_id(VOLTE_SESSION_NAME);
-		else if (is_sglte(prtd))
-			session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+		else if (is_voice2(prtd))
+			session_id = voc_get_session_id(VOICE2_SESSION_NAME);
 		else
 			session_id = voc_get_session_id(VOICE_SESSION_NAME);
 		voc_end_voice_call(session_id);
@@ -201,8 +202,8 @@
 	if (prtd->playback_start && prtd->capture_start) {
 		if (is_volte(prtd))
 			session_id = voc_get_session_id(VOLTE_SESSION_NAME);
-		else if (is_sglte(prtd))
-			session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+		else if (is_voice2(prtd))
+			session_id = voc_get_session_id(VOICE2_SESSION_NAME);
 		else
 			session_id = voc_get_session_id(VOICE_SESSION_NAME);
 		voc_start_voice_call(session_id);
@@ -233,8 +234,8 @@
 	pr_debug("%s: cmd = %d\n", __func__, cmd);
 	if (is_volte(prtd))
 		session_id = voc_get_session_id(VOLTE_SESSION_NAME);
-	else if (is_sglte(prtd))
-		session_id = voc_get_session_id(SGLTE_SESSION_NAME);
+	else if (is_voice2(prtd))
+		session_id = voc_get_session_id(VOICE2_SESSION_NAME);
 	else
 		session_id = voc_get_session_id(VOICE_SESSION_NAME);
 
@@ -308,20 +309,21 @@
 	return 0;
 }
 
-static int msm_sglte_volume_get(struct snd_kcontrol *kcontrol,
+static int msm_voice2_volume_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.integer.value[0] = 0;
 	return 0;
 }
 
-static int msm_sglte_volume_put(struct snd_kcontrol *kcontrol,
+static int msm_voice2_volume_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
 	int volume = ucontrol->value.integer.value[0];
 	pr_debug("%s: volume: %d\n", __func__, volume);
-	voc_set_rx_vol_index(voc_get_session_id(SGLTE_SESSION_NAME),
-						RX_PATH, volume);
+
+	voc_set_rx_vol_index(voc_get_session_id(VOICE2_SESSION_NAME),
+			     RX_PATH, volume);
 	return 0;
 }
 
@@ -363,21 +365,21 @@
 	return 0;
 }
 
-static int msm_sglte_mute_get(struct snd_kcontrol *kcontrol,
+static int msm_voice2_mute_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.integer.value[0] = 0;
 	return 0;
 }
 
-static int msm_sglte_mute_put(struct snd_kcontrol *kcontrol,
+static int msm_voice2_mute_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
 	int mute = ucontrol->value.integer.value[0];
 
 	pr_debug("%s: mute=%d\n", __func__, mute);
 
-	voc_set_tx_mute(voc_get_session_id(SGLTE_SESSION_NAME), TX_PATH, mute);
+	voc_set_tx_mute(voc_get_session_id(VOICE2_SESSION_NAME), TX_PATH, mute);
 
 	return 0;
 }
@@ -422,22 +424,22 @@
 	return 0;
 }
 
-static int msm_sglte_rx_device_mute_get(struct snd_kcontrol *kcontrol,
+static int msm_voice2_rx_device_mute_get(struct snd_kcontrol *kcontrol,
 					struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.integer.value[0] =
-		voc_get_rx_device_mute(voc_get_session_id(SGLTE_SESSION_NAME));
+		voc_get_rx_device_mute(voc_get_session_id(VOICE2_SESSION_NAME));
 	return 0;
 }
 
-static int msm_sglte_rx_device_mute_put(struct snd_kcontrol *kcontrol,
+static int msm_voice2_rx_device_mute_put(struct snd_kcontrol *kcontrol,
 					struct snd_ctl_elem_value *ucontrol)
 {
 	int mute = ucontrol->value.integer.value[0];
 
 	pr_debug("%s: mute=%d\n", __func__, mute);
 
-	voc_set_rx_device_mute(voc_get_session_id(SGLTE_SESSION_NAME), mute);
+	voc_set_rx_device_mute(voc_get_session_id(VOICE2_SESSION_NAME), mute);
 
 	return 0;
 }
@@ -464,6 +466,7 @@
 
 	voc_set_tty_mode(voc_get_session_id(VOICE_SESSION_NAME), tty_mode);
 
+	voc_set_tty_mode(voc_get_session_id(VOICE2_SESSION_NAME), tty_mode);
 	return 0;
 }
 static int msm_voice_widevoice_put(struct snd_kcontrol *kcontrol,
@@ -475,7 +478,8 @@
 
 	voc_set_widevoice_enable(voc_get_session_id(VOICE_SESSION_NAME),
 				 wv_enable);
-
+	voc_set_widevoice_enable(voc_get_session_id(VOICE2_SESSION_NAME),
+				 wv_enable);
 	return 0;
 }
 
@@ -496,7 +500,9 @@
 	pr_debug("%s: st enable=%d\n", __func__, st_enable);
 
 	voc_set_pp_enable(voc_get_session_id(VOICE_SESSION_NAME),
-			MODULE_ID_VOICE_MODULE_ST, st_enable);
+			  MODULE_ID_VOICE_MODULE_ST, st_enable);
+	voc_set_pp_enable(voc_get_session_id(VOICE2_SESSION_NAME),
+			  MODULE_ID_VOICE_MODULE_ST, st_enable);
 
 	return 0;
 }
@@ -518,7 +524,9 @@
 	pr_debug("%s: fens enable=%d\n", __func__, fens_enable);
 
 	voc_set_pp_enable(voc_get_session_id(VOICE_SESSION_NAME),
-			MODULE_ID_VOICE_MODULE_FENS, fens_enable);
+			  MODULE_ID_VOICE_MODULE_FENS, fens_enable);
+	voc_set_pp_enable(voc_get_session_id(VOICE2_SESSION_NAME),
+			  MODULE_ID_VOICE_MODULE_FENS, fens_enable);
 
 	return 0;
 }
@@ -555,13 +563,13 @@
 				msm_volte_mute_get, msm_volte_mute_put),
 	SOC_SINGLE_EXT("VoLTE Rx Volume", SND_SOC_NOPM, 0, 5, 0,
 				msm_volte_volume_get, msm_volte_volume_put),
-	SOC_SINGLE_EXT("SGLTE Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
-				msm_sglte_rx_device_mute_get,
-				msm_sglte_rx_device_mute_put),
-	SOC_SINGLE_EXT("SGLTE Tx Mute", SND_SOC_NOPM, 0, 1, 0,
-				msm_sglte_mute_get, msm_sglte_mute_put),
-	SOC_SINGLE_EXT("SGLTE Rx Volume", SND_SOC_NOPM, 0, 5, 0,
-				msm_sglte_volume_get, msm_sglte_volume_put),
+	SOC_SINGLE_EXT("Voice2 Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
+		       msm_voice2_rx_device_mute_get,
+		       msm_voice2_rx_device_mute_put),
+	SOC_SINGLE_EXT("Voice2 Tx Mute", SND_SOC_NOPM, 0, 1, 0,
+		       msm_voice2_mute_get, msm_voice2_mute_put),
+	SOC_SINGLE_EXT("Voice2 Rx Volume", SND_SOC_NOPM, 0, 5, 0,
+		       msm_voice2_volume_get, msm_voice2_volume_put),
 };
 
 static struct snd_pcm_ops msm_pcm_ops = {
@@ -624,7 +632,7 @@
 	memset(&voice_info, 0, sizeof(voice_info));
 	mutex_init(&voice_info[VOICE_SESSION_INDEX].lock);
 	mutex_init(&voice_info[VOLTE_SESSION_INDEX].lock);
-	mutex_init(&voice_info[SGLTE_SESSION_INDEX].lock);
+	mutex_init(&voice_info[VOICE2_SESSION_INDEX].lock);
 
 	return platform_driver_register(&msm_pcm_driver);
 }
diff --git a/sound/soc/msm/msm-pcm-voice.h b/sound/soc/msm/msm-pcm-voice.h
index 41aca89..b96ab01 100644
--- a/sound/soc/msm/msm-pcm-voice.h
+++ b/sound/soc/msm/msm-pcm-voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011,2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -16,7 +16,7 @@
 enum {
 	VOICE_SESSION_INDEX,
 	VOLTE_SESSION_INDEX,
-	SGLTE_SESSION_INDEX,
+	VOICE2_SESSION_INDEX,
 	VOICE_SESSION_INDEX_MAX,
 };
 
diff --git a/sound/soc/msm/msm-pcm-voip.c b/sound/soc/msm/msm-pcm-voip.c
index 359414b..dcc23ce 100644
--- a/sound/soc/msm/msm-pcm-voip.c
+++ b/sound/soc/msm/msm-pcm-voip.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
@@ -230,6 +230,27 @@
 
 	return 0;
 }
+static int msm_voip_fens_put(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	int fens_enable = ucontrol->value.integer.value[0];
+
+	pr_debug("%s: FENS_VOIP enable=%d\n", __func__, fens_enable);
+
+	voc_set_pp_enable(voc_get_session_id(VOIP_SESSION_NAME),
+				MODULE_ID_VOICE_MODULE_FENS, fens_enable);
+
+	return 0;
+}
+
+static int msm_voip_fens_get(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] =
+			voc_get_pp_enable(voc_get_session_id(VOIP_SESSION_NAME),
+				 MODULE_ID_VOICE_MODULE_FENS);
+	return 0;
+}
 
 static struct snd_kcontrol_new msm_voip_controls[] = {
 	SOC_SINGLE_EXT("Voip Tx Mute", SND_SOC_NOPM, 0, 1, 0,
@@ -241,6 +262,8 @@
 				msm_voip_mode_rate_config_put),
 	SOC_SINGLE_EXT("Voip Dtx Mode", SND_SOC_NOPM, 0, 1, 0,
 				msm_voip_dtx_mode_get, msm_voip_dtx_mode_put),
+	SOC_SINGLE_EXT("FENS_VOIP Enable", SND_SOC_NOPM, 0, 1, 0,
+			   msm_voip_fens_get, msm_voip_fens_put),
 };
 
 static int msm_pcm_voip_probe(struct snd_soc_platform *platform)
diff --git a/sound/soc/msm/msm-pcm.c b/sound/soc/msm/msm-pcm.c
index ea31985..d40ca67 100644
--- a/sound/soc/msm/msm-pcm.c
+++ b/sound/soc/msm/msm-pcm.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/msm-pcm.h b/sound/soc/msm/msm-pcm.h
index 6e1325b..d391d9a 100644
--- a/sound/soc/msm/msm-pcm.h
+++ b/sound/soc/msm/msm-pcm.h
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/msm-voip.c b/sound/soc/msm/msm-voip.c
index b1bb2c4..ec70791 100644
--- a/sound/soc/msm/msm-voip.c
+++ b/sound/soc/msm/msm-voip.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/sound/soc/msm/msm7201.c b/sound/soc/msm/msm7201.c
index 2a73fd6..ba368d1 100644
--- a/sound/soc/msm/msm7201.c
+++ b/sound/soc/msm/msm7201.c
@@ -1,6 +1,6 @@
 /* linux/sound/soc/msm/msm7201.c
  *
- * Copyright (c) 2008-2009, 2011, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011, 2012 The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/sound/soc/msm/msm7k-pcm.c b/sound/soc/msm/msm7k-pcm.c
index 1f23a92..a9193a2 100644
--- a/sound/soc/msm/msm7k-pcm.c
+++ b/sound/soc/msm/msm7k-pcm.c
@@ -1,6 +1,6 @@
 /* linux/sound/soc/msm/msm7k-pcm.c
  *
- * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/sound/soc/msm/msm7kv2-dai.c b/sound/soc/msm/msm7kv2-dai.c
index e8d51ac..44fdc02 100644
--- a/sound/soc/msm/msm7kv2-dai.c
+++ b/sound/soc/msm/msm7kv2-dai.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  *
  * Derived from msm-pcm.c and msm7201.c.
  *
diff --git a/sound/soc/msm/msm7kv2-dsp.c b/sound/soc/msm/msm7kv2-dsp.c
index 50bf6fb..8484a8f 100644
--- a/sound/soc/msm/msm7kv2-dsp.c
+++ b/sound/soc/msm/msm7kv2-dsp.c
@@ -1,6 +1,6 @@
 /* Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/msm7kv2-pcm.c b/sound/soc/msm/msm7kv2-pcm.c
index c64a3ff..2b7a438 100644
--- a/sound/soc/msm/msm7kv2-pcm.c
+++ b/sound/soc/msm/msm7kv2-pcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/sound/soc/msm/msm7kv2-pcm.h b/sound/soc/msm/msm7kv2-pcm.h
index fec7cf5..bcf6b4d4 100644
--- a/sound/soc/msm/msm7kv2-pcm.h
+++ b/sound/soc/msm/msm7kv2-pcm.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/msm7x30.c b/sound/soc/msm/msm7x30.c
index 94e37ca..664baab 100644
--- a/sound/soc/msm/msm7x30.c
+++ b/sound/soc/msm/msm7x30.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
diff --git a/sound/soc/msm/msm8660-apq-wm8903.c b/sound/soc/msm/msm8660-apq-wm8903.c
index e697c3f..f93a269 100644
--- a/sound/soc/msm/msm8660-apq-wm8903.c
+++ b/sound/soc/msm/msm8660-apq-wm8903.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm8660.c b/sound/soc/msm/msm8660.c
index 4cbfd45..6d7d2ee 100644
--- a/sound/soc/msm/msm8660.c
+++ b/sound/soc/msm/msm8660.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index c960d15..e1744d95 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -24,6 +24,7 @@
 #include <sound/jack.h>
 #include <asm/mach-types.h>
 #include <mach/socinfo.h>
+#include <linux/mfd/pm8xxx/pm8038.h>
 #include "msm-pcm-routing.h"
 #include "../codecs/wcd9304.h"
 
@@ -50,19 +51,32 @@
 #define GPIO_AUX_PCM_SYNC 65
 #define GPIO_AUX_PCM_CLK 66
 
+#define GPIO_HS_US_EURO_SEL_GPIO 80
+#define GPIO_HS_US_EURO_SEL_GPIO_SGLTE 66
+
+#define GPIO_HS_DET 37
+#define GPIO_HS_DET_SGLTE 50
+
+#define PM8038_GPIO_BASE		NR_GPIO_IRQS
+#define PM8038_GPIO_PM_TO_SYS(pm_gpio)  (pm_gpio - 1 + PM8038_GPIO_BASE)
+#define MSM8930_JACK_TYPES		(SND_JACK_HEADSET | SND_JACK_OC_HPHL | \
+					SND_JACK_OC_HPHR | SND_JACK_UNSUPPORTED)
+
 static int msm8930_spk_control;
 static int msm8930_slim_0_rx_ch = 1;
 static int msm8930_slim_0_tx_ch = 1;
 static int msm8930_pmic_spk_gain = DEFAULT_PMIC_SPK_GAIN;
+static int us_euro_gpio;
 
 static int msm8930_ext_spk_pamp;
 static int msm8930_btsco_rate = BTSCO_RATE_8KHZ;
 static int msm8930_btsco_ch = 1;
 static int hdmi_rate_variable;
+static int msm_hdmi_rx_ch = 2;
 static struct clk *codec_clk;
 static int clk_users;
 
-static int msm8930_headset_gpios_configured;
+static int msm8930_useuro_gpio_requested;
 
 static struct snd_soc_jack hs_jack;
 static struct snd_soc_jack button_jack;
@@ -71,6 +85,28 @@
 static int msm8930_enable_codec_ext_clk(
 		struct snd_soc_codec *codec, int enable,
 		bool dapm);
+static bool msm8930_swap_gnd_mic(struct snd_soc_codec *codec);
+
+static u32 spkr_boost_enable_gpio = PM8038_GPIO_PM_TO_SYS(0x1);
+
+struct pm_gpio SPKR_ON = {
+	.direction      = PM_GPIO_DIR_OUT,
+	.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+	.output_value   = 1,
+	.pull      = PM_GPIO_PULL_NO,
+	.vin_sel   = PM_GPIO_VIN_S4,
+	.out_strength   = PM_GPIO_STRENGTH_MED,
+	.function       = PM_GPIO_FUNC_NORMAL,
+};
+struct pm_gpio SPKR_OFF = {
+	.direction      = PM_GPIO_DIR_OUT,
+	.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+	.output_value   = 0,
+	.pull      = PM_GPIO_PULL_NO,
+	.vin_sel   = PM_GPIO_VIN_S4,
+	.out_strength   = PM_GPIO_STRENGTH_MED,
+	.function       = PM_GPIO_FUNC_NORMAL,
+};
 
 static struct sitar_mbhc_config mbhc_cfg = {
 	.headset_jack = &hs_jack,
@@ -83,9 +119,9 @@
 	.gpio = 0,
 	.gpio_irq = 0,
 	.gpio_level_insert = 1,
+	.swap_gnd_mic = NULL,
 };
 
-
 static void msm8930_ext_control(struct snd_soc_codec *codec)
 {
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
@@ -179,6 +215,21 @@
 						  __func__, SPKR_BOOST_GPIO);
 						return;
 					}
+				} else if (socinfo_get_platform_subtype() ==
+						PLATFORM_SUBTYPE_SGLTE) {
+					ret = pm8xxx_gpio_config(
+							spkr_boost_enable_gpio,
+							&SPKR_ON);
+					if (ret) {
+						pr_err("%s: Failure: spkr" \
+							"boost gpio ON %u\n",
+						  __func__, spkr_boost_enable_gpio);
+						return;
+					} else {
+						pr_debug("%s:Config PMIC8038" \
+					"gpio for speaker ON successfully\n",
+						__func__);
+					}
 				}
 				pm8xxx_spk_enable(MSM8930_SPK_ON);
 			}
@@ -198,6 +249,7 @@
 
 static void msm8960_ext_spk_power_amp_off(u32 spk)
 {
+	int ret = 0;
 	if (spk & (SPK_AMP_POS | SPK_AMP_NEG)) {
 		if (!msm8930_ext_spk_pamp)
 			return;
@@ -214,6 +266,18 @@
 					__func__, SPKR_BOOST_GPIO);
 			gpio_direction_output(SPKR_BOOST_GPIO, 0);
 			gpio_free(SPKR_BOOST_GPIO);
+		} else if (socinfo_get_platform_subtype() ==
+				PLATFORM_SUBTYPE_SGLTE) {
+			ret = pm8xxx_gpio_config(spkr_boost_enable_gpio,
+						&SPKR_OFF);
+			if (ret) {
+				pr_err("%s: Failure: spkr boost gpio OFF %u\n",
+				  __func__, spkr_boost_enable_gpio);
+				return;
+			} else {
+				pr_debug("%s:Config PMIC8038 gpio for speaker" \
+				" OFF successfully\n", __func__);
+			}
 		}
 
 		pm8xxx_spk_enable(MSM8930_SPK_OFF);
@@ -293,6 +357,17 @@
 	return 0;
 }
 
+static bool msm8930_swap_gnd_mic(struct snd_soc_codec *codec)
+{
+	int value = 0;
+
+	value = gpio_get_value_cansleep(us_euro_gpio);
+	pr_debug("%s: US EURO select switch %d to %d\n", __func__, value,
+			!value);
+	gpio_set_value_cansleep(us_euro_gpio, !value);
+	return true;
+}
+
 static int msm8930_mclk_event(struct snd_soc_dapm_widget *w,
 		struct snd_kcontrol *kcontrol, int event)
 {
@@ -391,10 +466,37 @@
 
 };
 
+static const struct snd_soc_dapm_route common_audio_map_sglte[] = {
+
+	{"RX_BIAS", NULL, "MCLK"},
+	{"LDO_H", NULL, "MCLK"},
+
+	{"MIC BIAS1 Internal1", NULL, "MCLK"},
+	{"MIC BIAS2 Internal1", NULL, "MCLK"},
+
+	/* Speaker path */
+	{"Ext Spk Left Pos", NULL, "LINEOUT1"},
+	{"Ext Spk Left Neg", NULL, "LINEOUT2"},
+
+	/* Headset Mic */
+	{"AMIC2", NULL, "MIC BIAS2 External"},
+	{"MIC BIAS2 External", NULL, "Headset Mic"},
+
+	/* Microphone path */
+	{"AMIC1", NULL, "MIC BIAS1 External"},
+	{"MIC BIAS1 External", NULL, "ANCLeft Headset Mic"},
+
+	{"AMIC3", NULL, "MIC BIAS1 External"},
+	{"MIC BIAS1 External", NULL, "ANCRight Headset Mic"},
+
+	{"HEADPHONE", NULL, "LDO_H"},
+};
+
 static const char *spk_function[] = {"Off", "On"};
 static const char *slim0_rx_ch_text[] = {"One", "Two"};
 static const char *slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
-
+static char const *hdmi_rx_ch_text[] = {"Two", "Three", "Four", "Five",
+					"Six", "Seven", "Eight"};
 static const char * const hdmi_rate[] = {"Default", "Variable"};
 
 static const struct soc_enum msm8930_enum[] = {
@@ -402,6 +504,7 @@
 	SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
 	SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
 	SOC_ENUM_SINGLE_EXT(2, hdmi_rate),
+	SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text),
 };
 
 static const char *btsco_rate_text[] = {"8000", "16000"};
@@ -508,6 +611,25 @@
 	return ret;
 }
 
+static int msm_hdmi_rx_ch_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: msm_hdmi_rx_ch  = %d\n", __func__,
+		msm_hdmi_rx_ch);
+	ucontrol->value.integer.value[0] = msm_hdmi_rx_ch - 2;
+	return 0;
+}
+
+static int msm_hdmi_rx_ch_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	msm_hdmi_rx_ch = ucontrol->value.integer.value[0] + 2;
+
+	pr_debug("%s: msm_hdmi_rx_ch = %d\n", __func__,
+		msm_hdmi_rx_ch);
+	return 1;
+}
+
 static int msm8930_hdmi_rate_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -537,6 +659,8 @@
 	SOC_ENUM_EXT("HDMI RX Rate", msm8930_enum[3],
 					msm8930_hdmi_rate_get,
 					msm8930_hdmi_rate_put),
+	SOC_ENUM_EXT("HDMI_RX Channels", msm8930_enum[4],
+				msm_hdmi_rx_ch_get, msm_hdmi_rx_ch_put),
 };
 
 static void *def_sitar_mbhc_cal(void)
@@ -687,8 +811,12 @@
 	snd_soc_dapm_new_controls(dapm, msm8930_dapm_widgets,
 				ARRAY_SIZE(msm8930_dapm_widgets));
 
-	snd_soc_dapm_add_routes(dapm, common_audio_map,
-		ARRAY_SIZE(common_audio_map));
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
+		snd_soc_dapm_add_routes(dapm, common_audio_map_sglte,
+			ARRAY_SIZE(common_audio_map_sglte));
+	else
+		snd_soc_dapm_add_routes(dapm, common_audio_map,
+			ARRAY_SIZE(common_audio_map));
 
 	snd_soc_dapm_enable_pin(dapm, "Ext Spk Left Pos");
 	snd_soc_dapm_enable_pin(dapm, "Ext Spk Left Neg");
@@ -696,7 +824,7 @@
 	snd_soc_dapm_sync(dapm);
 
 	err = snd_soc_jack_new(codec, "Headset Jack",
-		(SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR),
+		MSM8930_JACK_TYPES,
 		&hs_jack);
 	if (err) {
 		pr_err("failed to create new jack\n");
@@ -711,7 +839,30 @@
 	}
 	codec_clk = clk_get(cpu_dai->dev, "osr_clk");
 
-	mbhc_cfg.gpio = 37;
+	/*
+	 * Switch is present only in 8930 CDP and SGLTE
+	 */
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE ||
+		machine_is_msm8930_cdp())
+		mbhc_cfg.swap_gnd_mic = msm8930_swap_gnd_mic;
+
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE) {
+		mbhc_cfg.gpio = GPIO_HS_DET_SGLTE;
+		mbhc_cfg.gpio_level_insert = 0;
+	} else
+		mbhc_cfg.gpio = GPIO_HS_DET;
+
+	/*
+	 * GPIO for headset detect is present in all devices
+	 * MTP/Fluid/CDP/SGLTE
+	 */
+	err = gpio_request(mbhc_cfg.gpio, "HEADSET_DETECT");
+	if (err) {
+		pr_err("%s: Failed to request gpio %d\n",
+				__func__, mbhc_cfg.gpio);
+		return err;
+	}
+
 	mbhc_cfg.gpio_irq = gpio_to_irq(mbhc_cfg.gpio);
 	sitar_hs_detect(codec, &mbhc_cfg);
 
@@ -778,7 +929,9 @@
 
 	if (!hdmi_rate_variable)
 		rate->min = rate->max = 48000;
-	channels->min = channels->max = 2;
+	channels->min = channels->max = msm_hdmi_rx_ch;
+	if (channels->max < 2)
+		channels->min = channels->max = 2;
 
 	return 0;
 }
@@ -1106,9 +1259,9 @@
 		.be_id = MSM_FRONTEND_DAI_VOLTE,
 	},
 	{
-		.name = "SGLTE",
-		.stream_name = "SGLTE",
-		.cpu_dai_name   = "SGLTE",
+		.name = "Voice2",
+		.stream_name = "Voice2",
+		.cpu_dai_name   = "Voice2",
 		.platform_name  = "msm-pcm-voice",
 		.dynamic = 1,
 		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
@@ -1119,7 +1272,7 @@
 		.ignore_pmdown_time = 1,
 		.codec_dai_name = "snd-soc-dummy-dai",
 		.codec_name = "snd-soc-dummy",
-		.be_id = MSM_FRONTEND_DAI_SGLTE,
+		.be_id = MSM_FRONTEND_DAI_VOICE2,
 	},
 	{
 		.name = "MSM8960 LowLatency",
@@ -1324,23 +1477,31 @@
 static int msm8930_configure_headset_mic_gpios(void)
 {
 	int ret;
-	ret = gpio_request(80, "US_EURO_SWITCH");
+
+	if (!us_euro_gpio)
+		return 0;
+
+	ret = gpio_request(us_euro_gpio, "US_EURO_SWITCH");
 	if (ret) {
-		pr_err("%s: Failed to request gpio 80\n", __func__);
+		pr_err("%s: Failed to request gpio %d\n", __func__,
+						us_euro_gpio);
 		return ret;
 	}
-	ret = gpio_direction_output(80, 0);
+	ret = gpio_direction_output(us_euro_gpio, 0);
 	if (ret) {
 		pr_err("%s: Unable to set direction\n", __func__);
-		gpio_free(80);
+		gpio_free(us_euro_gpio);
+		return ret;
 	}
-	msm8930_headset_gpios_configured = 0;
+	msm8930_useuro_gpio_requested = 1;
 	return 0;
 }
 static void msm8930_free_headset_mic_gpios(void)
 {
-	if (msm8930_headset_gpios_configured)
-		gpio_free(80);
+	if (msm8930_useuro_gpio_requested) {
+		gpio_free(us_euro_gpio);
+		msm8930_useuro_gpio_requested = 0;
+	}
 }
 
 static int __init msm8930_audio_init(void)
@@ -1372,11 +1533,13 @@
 		return ret;
 	}
 
-	if (msm8930_configure_headset_mic_gpios()) {
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
+		us_euro_gpio = GPIO_HS_US_EURO_SEL_GPIO_SGLTE;
+	else
+		us_euro_gpio = GPIO_HS_US_EURO_SEL_GPIO;
+
+	if (msm8930_configure_headset_mic_gpios())
 		pr_err("%s Fail to configure headset mic gpios\n", __func__);
-		msm8930_headset_gpios_configured = 0;
-	} else
-		msm8930_headset_gpios_configured = 1;
 
 	atomic_set(&auxpcm_rsc_ref, 0);
 	return ret;
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 1eb51c30..94db8147 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013 The Linux Foundation. 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 and
@@ -74,6 +74,7 @@
 static int msm8960_btsco_rate = SAMPLE_RATE_8KHZ;
 static int msm8960_btsco_ch = 1;
 static int hdmi_rate_variable;
+static int msm_hdmi_rx_ch = 2;
 static int msm8960_auxpcm_rate = SAMPLE_RATE_8KHZ;
 
 static struct clk *codec_clk;
@@ -549,6 +550,8 @@
 static const char *spk_function[] = {"Off", "On"};
 static const char *slim0_rx_ch_text[] = {"One", "Two"};
 static const char *slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
+static char const *hdmi_rx_ch_text[] = {"Two", "Three", "Four", "Five",
+					"Six", "Seven", "Eight"};
 static const char * const hdmi_rate[] = {"Default", "Variable"};
 
 static const struct soc_enum msm8960_enum[] = {
@@ -556,6 +559,7 @@
 	SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
 	SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
 	SOC_ENUM_SINGLE_EXT(2, hdmi_rate),
+	SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text),
 };
 
 static const char *btsco_rate_text[] = {"8000", "16000"};
@@ -662,6 +666,25 @@
 	return 0;
 }
 
+static int msm_hdmi_rx_ch_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: msm_hdmi_rx_ch  = %d\n", __func__,
+			msm_hdmi_rx_ch);
+	ucontrol->value.integer.value[0] = msm_hdmi_rx_ch - 2;
+	return 0;
+}
+
+static int msm_hdmi_rx_ch_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	msm_hdmi_rx_ch = ucontrol->value.integer.value[0] + 2;
+
+	pr_debug("%s: msm_hdmi_rx_ch = %d\n", __func__,
+		msm_hdmi_rx_ch);
+	return 1;
+}
+
 static int msm8960_hdmi_rate_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -691,6 +714,8 @@
 	SOC_ENUM_EXT("HDMI RX Rate", msm8960_enum[3],
 					msm8960_hdmi_rate_get,
 					msm8960_hdmi_rate_put),
+	SOC_ENUM_EXT("HDMI_RX Channels", msm8960_enum[4],
+		msm_hdmi_rx_ch_get, msm_hdmi_rx_ch_put),
 };
 
 static void *def_tabla_mbhc_cal(void)
@@ -742,21 +767,21 @@
 	btn_low = tabla_mbhc_cal_btn_det_mp(btn_cfg, TABLA_BTN_DET_V_BTN_LOW);
 	btn_high = tabla_mbhc_cal_btn_det_mp(btn_cfg, TABLA_BTN_DET_V_BTN_HIGH);
 	btn_low[0] = -50;
-	btn_high[0] = 10;
-	btn_low[1] = 11;
-	btn_high[1] = 52;
-	btn_low[2] = 53;
-	btn_high[2] = 94;
-	btn_low[3] = 95;
-	btn_high[3] = 133;
-	btn_low[4] = 134;
-	btn_high[4] = 171;
-	btn_low[5] = 172;
-	btn_high[5] = 208;
-	btn_low[6] = 209;
-	btn_high[6] = 244;
-	btn_low[7] = 245;
-	btn_high[7] = 330;
+	btn_high[0] = 21;
+	btn_low[1] = 22;
+	btn_high[1] = 67;
+	btn_low[2] = 68;
+	btn_high[2] = 111;
+	btn_low[3] = 112;
+	btn_high[3] = 153;
+	btn_low[4] = 154;
+	btn_high[4] = 191;
+	btn_low[5] = 192;
+	btn_high[5] = 233;
+	btn_low[6] = 234;
+	btn_high[6] = 272;
+	btn_low[7] = 273;
+	btn_high[7] = 400;
 	n_ready = tabla_mbhc_cal_btn_det_mp(btn_cfg, TABLA_BTN_DET_N_READY);
 	n_ready[0] = 80;
 	n_ready[1] = 68;
@@ -1038,10 +1063,11 @@
 	pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
 			channels->min, channels->max);
 
-	if (channels->max < 2)
-		channels->min = channels->max = 2;
 	if (!hdmi_rate_variable)
 		rate->min = rate->max = 48000;
+	channels->min = channels->max = msm_hdmi_rx_ch;
+	if (channels->max < 2)
+		channels->min = channels->max = 2;
 
 	return 0;
 }
@@ -1371,9 +1397,9 @@
 		.be_id = MSM_FRONTEND_DAI_VOLTE,
 	},
 	{
-		.name = "SGLTE",
-		.stream_name = "SGLTE",
-		.cpu_dai_name   = "SGLTE",
+		.name = "Voice2",
+		.stream_name = "Voice2",
+		.cpu_dai_name   = "Voice2",
 		.platform_name  = "msm-pcm-voice",
 		.dynamic = 1,
 		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
@@ -1383,7 +1409,7 @@
 		.ignore_pmdown_time = 1,/* this dainlink has playback support */
 		.codec_dai_name = "snd-soc-dummy-dai",
 		.codec_name = "snd-soc-dummy",
-		.be_id = MSM_FRONTEND_DAI_SGLTE,
+		.be_id = MSM_FRONTEND_DAI_VOICE2,
 	},
 	{
 		.name = "MSM8960 LowLatency",
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 68b4edf..a798793 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm8x60-dai.c b/sound/soc/msm/msm8x60-dai.c
index 8130f07..6312c2c 100644
--- a/sound/soc/msm/msm8x60-dai.c
+++ b/sound/soc/msm/msm8x60-dai.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * Derived from msm-pcm.c and msm7201.c.
  *
diff --git a/sound/soc/msm/msm8x60-pcm.c b/sound/soc/msm/msm8x60-pcm.c
index 6f5ad32..7993435 100644
--- a/sound/soc/msm/msm8x60-pcm.c
+++ b/sound/soc/msm/msm8x60-pcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm8x60-pcm.h b/sound/soc/msm/msm8x60-pcm.h
index d7c9ad8..31f0e63 100644
--- a/sound/soc/msm/msm8x60-pcm.h
+++ b/sound/soc/msm/msm8x60-pcm.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/msm8x60.c b/sound/soc/msm/msm8x60.c
index 48ce610..fcc3f32 100644
--- a/sound/soc/msm/msm8x60.c
+++ b/sound/soc/msm/msm8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/msm_audio_mvs.h b/sound/soc/msm/msm_audio_mvs.h
index 2660b77..6ee457c 100644
--- a/sound/soc/msm/msm_audio_mvs.h
+++ b/sound/soc/msm/msm_audio_mvs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/mvs-dai.c b/sound/soc/msm/mvs-dai.c
index 521c5e5..206afd2 100644
--- a/sound/soc/msm/mvs-dai.c
+++ b/sound/soc/msm/mvs-dai.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/qdsp6/q6adm.c b/sound/soc/msm/qdsp6/q6adm.c
index 6292a6f..f6d12a8 100644
--- a/sound/soc/msm/qdsp6/q6adm.c
+++ b/sound/soc/msm/qdsp6/q6adm.c
@@ -687,8 +687,8 @@
 				rate = 16000;
 		}
 
-		if (open.topology_id  == 0)
-			open.topology_id = topology;
+        if ((open.topology_id  == 0) || (port_id == VOICE_RECORD_RX) || (port_id == VOICE_RECORD_TX))
+          open.topology_id = topology;
 
 		open.channel_config = channel_mode & 0x00FF;
 		open.rate  = rate;
@@ -842,8 +842,8 @@
 				rate = 16000;
 		}
 
-		if (open.topology_id  == 0)
-			open.topology_id = topology;
+        if ((open.topology_id  == 0) || (port_id == VOICE_RECORD_RX) || (port_id == VOICE_RECORD_TX))
+          open.topology_id = topology;
 
 		open.channel_config = channel_mode & 0x00FF;
 		open.rate  = rate;
@@ -888,6 +888,8 @@
 	int ret = 0, i = 0;
 	/* Assumes port_ids have already been validated during adm_open */
 	int index = afe_get_port_index(copp_id);
+	int copp_cnt;
+
 	if (index < 0 || index >= AFE_MAX_PORTS) {
 		pr_err("%s: invalid port idx %d token %d\n",
 					__func__, index, copp_id);
@@ -910,9 +912,19 @@
 	route.hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS;
 	route.num_sessions = 1;
 	route.session[0].id = session_id;
-	route.session[0].num_copps = num_copps;
 
-	for (i = 0; i < num_copps; i++) {
+	if (num_copps < ADM_MAX_COPPS) {
+		copp_cnt = num_copps;
+	} else {
+		copp_cnt = ADM_MAX_COPPS;
+		/* print out warning for now as playback/capture to/from
+		 * COPPs more than maximum allowed is extremely unlikely
+		 */
+		pr_warn("%s: max out routable COPPs\n", __func__);
+	}
+
+	route.session[0].num_copps = copp_cnt;
+	for (i = 0; i < copp_cnt; i++) {
 		int tmp;
 		port_id[i] = afe_convert_virtual_to_portid(port_id[i]);
 
@@ -925,7 +937,8 @@
 			route.session[0].copp_id[i] =
 					atomic_read(&this_adm.copp_id[tmp]);
 	}
-	if (num_copps % 2)
+
+	if (copp_cnt % 2)
 		route.session[0].copp_id[i] = 0;
 
 	switch (path) {
@@ -962,10 +975,17 @@
 	for (i = 0; i < num_copps; i++)
 		send_adm_cal(port_id[i], path);
 
-	for (i = 0; i < num_copps; i++)
-		rtac_add_adm_device(port_id[i],	atomic_read(&this_adm.copp_id
-			[afe_get_port_index(port_id[i])]),
-			path, session_id);
+	for (i = 0; i < num_copps; i++) {
+		int tmp;
+		tmp = afe_get_port_index(port_id[i]);
+		if (tmp >= 0 && tmp < AFE_MAX_PORTS)
+			rtac_add_adm_device(port_id[i],
+				atomic_read(&this_adm.copp_id[tmp]),
+				path, session_id);
+		else
+			pr_debug("%s: Invalid port index %d",
+				__func__, tmp);
+	}
 	return 0;
 
 fail_cmd:
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index dd6dfb6..aaebad5 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -1595,7 +1595,7 @@
 				goto afe_error;
 			}
 
-			if (param[1] < 0 || param[1] > 100) {
+			if (param[1] > 100) {
 				pr_err("%s: Error, volume shoud be 0 to 100"
 					" percentage param = %lu\n",
 					__func__, param[1]);
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 0575f6e..01f4852 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -894,7 +893,11 @@
 		case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
 		case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED:
 		case ASM_STREAM_CMD_OPEN_READ_COMPRESSED:
-			if (atomic_read(&ac->cmd_state) && wakeup_flag) {
+			if (payload[0] == ASM_STREAM_CMD_CLOSE) {
+				atomic_set(&ac->cmd_close_state, 0);
+				wake_up(&ac->cmd_wait);
+			} else if (atomic_read(&ac->cmd_state) &&
+					wakeup_flag) {
 				atomic_set(&ac->cmd_state, 0);
 				if (payload[1] == ADSP_EUNSUPPORTED) {
 					pr_debug("paload[1]:%d unsupported",
@@ -2045,6 +2048,39 @@
 	return -EINVAL;
 }
 
+int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff)
+{
+	struct asm_aac_stereo_mix_coeff_selection_param aac_mix_coeff;
+	int rc = 0;
+	q6asm_add_hdr(ac, &aac_mix_coeff.hdr, sizeof(aac_mix_coeff), TRUE);
+	aac_mix_coeff.hdr.opcode =
+		 ASM_STREAM_CMD_SET_ENCDEC_PARAM;
+	aac_mix_coeff.param_id =
+		ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG;
+	aac_mix_coeff.param_size =
+		 sizeof(struct asm_aac_stereo_mix_coeff_selection_param);
+	aac_mix_coeff.aac_stereo_mix_coeff_flag	= mix_coeff;
+	pr_debug("%s, mix_coeff = %u", __func__, mix_coeff);
+	rc = apr_send_pkt(ac->apr, (uint32_t *) &aac_mix_coeff);
+	if (rc < 0) {
+		pr_err("%s:Command opcode[0x%x]paramid[0x%x] failed\n",
+			__func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM,
+			ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(ac->cmd_wait,
+			(atomic_read(&ac->cmd_state) == 0), 5*HZ);
+	if (!rc) {
+		pr_err("%s:timeout opcode[0x%x]\n", __func__,
+						aac_mix_coeff.hdr.opcode);
+		goto fail_cmd;
+	}
+	return 0;
+fail_cmd:
+	return -EINVAL;
+}
+
 int q6asm_set_encdec_chan_map(struct audio_client *ac,
 			uint32_t num_channels)
 {
@@ -3651,13 +3687,13 @@
 	return -EINVAL;
 }
 
-uint64_t q6asm_get_session_time(struct audio_client *ac)
+int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp)
 {
 	struct apr_hdr hdr;
 	int rc;
 
-	if (!ac || ac->apr == NULL) {
-		pr_err("APR handle NULL\n");
+	if (!ac || ac->apr == NULL || tstamp == NULL) {
+		pr_err("APR handle or tstamp NULL\n");
 		return -EINVAL;
 	}
 	q6asm_add_hdr(ac, &hdr, sizeof(hdr), FALSE);
@@ -3679,7 +3715,9 @@
 			__func__);
 		goto fail_cmd;
 	}
-	return ac->time_stamp;
+
+	*tstamp = ac->time_stamp;
+	return 0;
 
 fail_cmd:
 	return -EINVAL;
@@ -3722,7 +3760,8 @@
 	case CMD_CLOSE:
 		pr_debug("%s:CMD_CLOSE\n", __func__);
 		hdr.opcode = ASM_STREAM_CMD_CLOSE;
-		state = &ac->cmd_state;
+		atomic_set(&ac->cmd_close_state, 1);
+		state = &ac->cmd_close_state;
 		break;
 	default:
 		pr_err("Invalid format[%d]\n", cmd);
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index cb2e39b..3cae913 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -1,4 +1,4 @@
-/*  Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/*  Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -31,11 +31,6 @@
 #define CMD_STATUS_SUCCESS 0
 #define CMD_STATUS_FAIL 1
 
-#define VOC_PATH_PASSIVE 0
-#define VOC_PATH_FULL 1
-#define VOC_PATH_VOLTE_PASSIVE 2
-#define VOC_PATH_SGLTE_PASSIVE 3
-
 #define CAL_BUFFER_SIZE		4096
 #define NUM_CVP_CAL_BLOCKS	75
 #define NUM_CVS_CAL_BLOCKS	15
@@ -76,6 +71,7 @@
 static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv);
 static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv);
 static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv);
+static int voice_send_set_device_cmd_v2(struct voice_data *v);
 
 static u16 voice_get_mvm_handle(struct voice_data *v)
 {
@@ -156,9 +152,9 @@
 		else if (!strncmp(name, "VoLTE session", 13))
 			session_id =
 			common.voice[VOC_PATH_VOLTE_PASSIVE].session_id;
-		else if (!strncmp(name, "SGLTE session", 13))
+		else if (!strncmp(name, "Voice2 session", 14))
 			session_id =
-			common.voice[VOC_PATH_SGLTE_PASSIVE].session_id;
+			common.voice[VOC_PATH_VOICE2_PASSIVE].session_id;
 		else
 			session_id = common.voice[VOC_PATH_FULL].session_id;
 
@@ -199,9 +195,9 @@
 	return (session_id == common.voice[VOC_PATH_VOLTE_PASSIVE].session_id);
 }
 
-static bool is_sglte_session(u16 session_id)
+static bool is_voice2_session(u16 session_id)
 {
-	return (session_id == common.voice[VOC_PATH_SGLTE_PASSIVE].session_id);
+	return (session_id == common.voice[VOC_PATH_VOICE2_PASSIVE].session_id);
 }
 
 /* Only for memory allocated in the voice driver */
@@ -356,9 +352,9 @@
 		pr_err("%s: apr_mvm is NULL.\n", __func__);
 		return -EINVAL;
 	}
-	pr_debug("%s: VoLTE/SGLTE command to MVM\n", __func__);
+	pr_debug("%s: VoLTE/Voice2 command to MVM\n", __func__);
 	if (is_volte_session(v->session_id) ||
-			is_sglte_session(v->session_id)) {
+			is_voice2_session(v->session_id)) {
 
 		mvm_handle = voice_get_mvm_handle(v);
 		mvm_voice_ctl_cmd.hdr.hdr_field = APR_HDR_FIELD(
@@ -434,7 +430,7 @@
 	if (!mvm_handle) {
 		if (is_voice_session(v->session_id) ||
 				is_volte_session(v->session_id) ||
-				is_sglte_session(v->session_id)) {
+				is_voice2_session(v->session_id)) {
 			mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
 						APR_MSG_TYPE_SEQ_CMD,
 						APR_HDR_LEN(APR_HDR_SIZE),
@@ -454,7 +450,7 @@
 				strlcpy(mvm_session_cmd.mvm_session.name,
 				"default volte voice",
 				sizeof(mvm_session_cmd.mvm_session.name) - 1);
-			} else if (is_sglte_session(v->session_id)) {
+			} else if (is_voice2_session(v->session_id)) {
 				strlcpy(mvm_session_cmd.mvm_session.name,
 				"default modem voice2",
 				sizeof(mvm_session_cmd.mvm_session.name));
@@ -521,7 +517,7 @@
 	if (!cvs_handle) {
 		if (is_voice_session(v->session_id) ||
 			is_volte_session(v->session_id) ||
-			is_sglte_session(v->session_id)) {
+			is_voice2_session(v->session_id)) {
 			pr_debug("%s: creating CVS passive session\n",
 				 __func__);
 
@@ -542,7 +538,7 @@
 				strlcpy(cvs_session_cmd.cvs_session.name,
 				"default volte voice",
 				sizeof(cvs_session_cmd.cvs_session.name) - 1);
-			} else if (is_sglte_session(v->session_id)) {
+			} else if (is_voice2_session(v->session_id)) {
 				strlcpy(cvs_session_cmd.cvs_session.name,
 				"default modem voice2",
 				sizeof(cvs_session_cmd.cvs_session.name));
@@ -1206,7 +1202,7 @@
 						APR_PKT_VER);
 	cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
-	pr_debug(" send create cvp setdev, pkt size = %d\n",
+	pr_debug("send create cvp setdev, pkt size = %d\n",
 			cvp_setdev_cmd.hdr.pkt_size);
 	cvp_setdev_cmd.hdr.src_port = v->session_id;
 	cvp_setdev_cmd.hdr.dest_port = cvp_handle;
@@ -1252,6 +1248,91 @@
 	return -EINVAL;
 }
 
+static int voice_send_set_device_cmd_v2(struct voice_data *v)
+{
+	struct cvp_set_device_cmd_v2  cvp_setdev_cmd_v2;
+	int ret = 0;
+	void *apr_cvp;
+	u16 cvp_handle;
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+
+		return -EINVAL;
+	}
+	apr_cvp = common.apr_q6_cvp;
+
+	if (!apr_cvp) {
+		pr_err("%s: apr_cvp is NULL.\n", __func__);
+
+		return -EINVAL;
+	}
+	cvp_handle = voice_get_cvp_handle(v);
+
+	/* set device and wait for response */
+	cvp_setdev_cmd_v2.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+						APR_HDR_LEN(APR_HDR_SIZE),
+						APR_PKT_VER);
+	cvp_setdev_cmd_v2.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(cvp_setdev_cmd_v2) - APR_HDR_SIZE);
+	cvp_setdev_cmd_v2.hdr.src_port = v->session_id;
+	cvp_setdev_cmd_v2.hdr.dest_port = cvp_handle;
+	cvp_setdev_cmd_v2.hdr.token = 0;
+	cvp_setdev_cmd_v2.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE_V2;
+
+	/* Use default topology if invalid value in ACDB */
+	cvp_setdev_cmd_v2.cvp_set_device_v2.tx_topology_id =
+				get_voice_tx_topology();
+	if (cvp_setdev_cmd_v2.cvp_set_device_v2.tx_topology_id == 0)
+		cvp_setdev_cmd_v2.cvp_set_device_v2.tx_topology_id =
+				VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
+
+	cvp_setdev_cmd_v2.cvp_set_device_v2.rx_topology_id =
+				get_voice_rx_topology();
+	if (cvp_setdev_cmd_v2.cvp_set_device_v2.rx_topology_id == 0)
+		cvp_setdev_cmd_v2.cvp_set_device_v2.rx_topology_id =
+				VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
+	cvp_setdev_cmd_v2.cvp_set_device_v2.tx_port_id = v->dev_tx.port_id;
+	cvp_setdev_cmd_v2.cvp_set_device_v2.rx_port_id = v->dev_rx.port_id;
+
+	if (common.ec_ref_ext == true) {
+		cvp_setdev_cmd_v2.cvp_set_device_v2.vocproc_mode =
+				VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING;
+		cvp_setdev_cmd_v2.cvp_set_device_v2.ec_ref_port_id =
+				common.ec_port_id;
+	} else {
+		cvp_setdev_cmd_v2.cvp_set_device_v2.vocproc_mode =
+				VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
+		cvp_setdev_cmd_v2.cvp_set_device_v2.ec_ref_port_id =
+				VSS_IVOCPROC_PORT_ID_NONE;
+	}
+	pr_debug("%s:topology=%d , tx_port_id=%d, rx_port_id=%d\n"
+		 "ec_ref_port_id = %x\n", __func__,
+		 cvp_setdev_cmd_v2.cvp_set_device_v2.tx_topology_id,
+		 cvp_setdev_cmd_v2.cvp_set_device_v2.tx_port_id,
+		 cvp_setdev_cmd_v2.cvp_set_device_v2.rx_port_id,
+		 cvp_setdev_cmd_v2.cvp_set_device_v2.ec_ref_port_id);
+
+	v->cvp_state = CMD_STATUS_FAIL;
+	ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd_v2);
+	if (ret < 0) {
+		pr_err("Fail in sending VSS_IVOCPROC_CMD_SET_DEVICE_V2\n");
+		goto fail;
+	}
+	pr_debug("wait for cvp create session event\n");
+	ret = wait_event_timeout(v->cvp_wait,
+			(v->cvp_state == CMD_STATUS_SUCCESS),
+			msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: wait_event timeout\n", __func__);
+		goto fail;
+	}
+
+	return 0;
+fail:
+	return -EINVAL;
+}
+
 static int voice_send_stop_voice_cmd(struct voice_data *v)
 {
 	struct apr_hdr mvm_stop_voice_cmd;
@@ -2159,7 +2240,13 @@
 		pr_err("%s: wait_event timeout\n", __func__);
 		goto fail;
 	}
-
+	if (common.ec_ref_ext == true) {
+		ret = voice_send_set_device_cmd_v2(v);
+		if (ret < 0)
+			pr_err("%s:  set device V2 failed rc =%x\n",
+			       __func__, ret);
+			goto fail;
+	}
 	/* send cvs cal */
 	ret = voice_send_cvs_map_memory_cmd(v);
 	if (!ret)
@@ -3110,7 +3197,8 @@
 		voice_send_cvp_deregister_vol_cal_table_cmd(v);
 		voice_send_cvp_deregister_cal_cmd(v);
 		voice_send_cvp_unmap_memory_cmd(v);
-
+		if (common.ec_ref_ext == true)
+			voc_set_ext_ec_ref(AFE_PORT_INVALID, false);
 		v->voc_state = VOC_CHANGE;
 	}
 
@@ -3134,10 +3222,20 @@
 	mutex_lock(&v->lock);
 
 	if (v->voc_state == VOC_CHANGE) {
-		ret = voice_send_set_device_cmd(v);
-		if (ret < 0) {
-			pr_err("%s:  set device failed\n", __func__);
-			goto fail;
+
+		if (common.ec_ref_ext == true) {
+			ret = voice_send_set_device_cmd_v2(v);
+			if (ret < 0)
+				pr_err("%s: set device V2 failed\n"
+				       "rc =%x\n", __func__, ret);
+				goto fail;
+		} else {
+			ret = voice_send_set_device_cmd(v);
+			if (ret < 0) {
+				pr_err("%s: set device failed rc=%x\n",
+				       __func__, ret);
+				goto fail;
+			}
 		}
 		/* send cvp and vol cal */
 		ret = voice_send_cvp_map_memory_cmd(v);
@@ -3521,7 +3619,8 @@
 		if (ret < 0)
 			pr_err("%s:  destroy voice failed\n", __func__);
 		voice_destroy_mvm_cvs_session(v);
-
+		if (common.ec_ref_ext == true)
+			voc_set_ext_ec_ref(AFE_PORT_INVALID, false);
 		v->voc_state = VOC_RELEASE;
 	}
 	mutex_unlock(&v->lock);
@@ -3691,6 +3790,28 @@
 	return ret;
 }
 
+int voc_set_ext_ec_ref(uint16_t port_id, bool state)
+{
+	int ret = 0;
+
+	mutex_lock(&common.common_lock);
+	if (state == true) {
+		if (port_id == AFE_PORT_INVALID) {
+			pr_err("%s: Invalid port id", __func__);
+			ret = -EINVAL;
+			goto fail;
+		}
+		common.ec_port_id = port_id;
+		common.ec_ref_ext = true;
+	} else {
+		common.ec_ref_ext = false;
+		common.ec_port_id = port_id;
+	}
+fail:
+	mutex_unlock(&common.common_lock);
+	return ret;
+}
+
 void voc_register_mvs_cb(ul_cb_fn ul_cb,
 			   dl_cb_fn dl_cb,
 			   void *private_data)
@@ -4012,6 +4133,7 @@
 				wake_up(&v->cvp_wait);
 				break;
 			case VSS_IVOCPROC_CMD_SET_DEVICE:
+			case VSS_IVOCPROC_CMD_SET_DEVICE_V2:
 			case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
 			case VSS_IVOCPROC_CMD_ENABLE:
 			case VSS_IVOCPROC_CMD_DISABLE:
@@ -4124,7 +4246,7 @@
 	common.default_mute_val = 0;  /* default is un-mute */
 	common.default_vol_val = 0;
 	common.default_sample_val = 8000;
-
+	common.ec_ref_ext = false;
 	/* Initialize MVS info. */
 	common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
 
diff --git a/sound/soc/msm/qdsp6/q6voice.h b/sound/soc/msm/qdsp6/q6voice.h
index 34b1b52..a90e164 100644
--- a/sound/soc/msm/qdsp6/q6voice.h
+++ b/sound/soc/msm/qdsp6/q6voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
@@ -643,6 +643,8 @@
 
 #define VSS_IVOCPROC_CMD_SET_DEVICE			0x000100C4
 
+#define VSS_IVOCPROC_CMD_SET_DEVICE_V2			0x000112C6
+
 #define VSS_IVOCPROC_CMD_SET_VP3_DATA			0x000110EB
 
 #define VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX		0x000110EE
@@ -698,6 +700,9 @@
 #define VOICE_CMD_GET_PARAM				0x00011007
 #define VOICE_EVT_GET_PARAM_ACK				0x00011008
 
+/* Default AFE port ID. Applicable to Tx and Rx. */
+#define VSS_IVOCPROC_PORT_ID_NONE			0xFFFF
+
 struct vss_ivocproc_cmd_create_full_control_session_t {
 	uint16_t direction;
 	/*
@@ -767,6 +772,32 @@
 	*/
 } __packed;
 
+/* Internal EC */
+#define VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING 0x00010F7C
+
+/* External EC */
+#define VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING 0x00010F7D
+
+struct vss_ivocproc_cmd_set_device_v2_t {
+	uint16_t tx_port_id;
+	/* Tx device port ID to which the vocproc connects. */
+	uint32_t tx_topology_id;
+	/* Tx path topology ID. */
+	uint16_t rx_port_id;
+	/* Rx device port ID to which the vocproc connects. */
+	uint32_t rx_topology_id;
+	/* Rx path topology ID. */
+	uint32_t vocproc_mode;
+	/* Vocproc mode. The supported values:
+	 * VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING - 0x00010F7C
+	 * VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING - 0x00010F7D
+	 */
+	uint16_t ec_ref_port_id;
+	/* Port ID to which the vocproc connects for receiving
+	 * echo cancellation reference signal.
+	 */
+} __packed;
+
 struct vss_ivocproc_cmd_register_calibration_data_t {
 	uint32_t phys_addr;
 	/* Phsical address to be registered with vocproc. Calibration data
@@ -816,6 +847,11 @@
 	struct vss_ivocproc_cmd_set_device_t cvp_set_device;
 } __packed;
 
+struct cvp_set_device_cmd_v2 {
+	struct apr_hdr hdr;
+	struct vss_ivocproc_cmd_set_device_v2_t cvp_set_device_v2;
+} __packed;
+
 struct cvp_set_vp3_data_cmd {
 	struct apr_hdr hdr;
 } __packed;
@@ -945,6 +981,8 @@
 	uint32_t default_mute_val;
 	uint32_t default_vol_val;
 	uint32_t default_sample_val;
+	bool ec_ref_ext;
+	uint16_t ec_port_id;
 
 	/* APR to MVM in the Q6 */
 	void *apr_q6_mvm;
@@ -1009,9 +1047,17 @@
 #define VOICE_SESSION_NAME "Voice session"
 #define VOIP_SESSION_NAME "VoIP session"
 #define VOLTE_SESSION_NAME "VoLTE session"
-#define SGLTE_SESSION_NAME "SGLTE session"
+#define VOICE2_SESSION_NAME "Voice2 session"
+
+#define VOC_PATH_PASSIVE 0
+#define VOC_PATH_FULL 1
+#define VOC_PATH_VOLTE_PASSIVE 2
+#define VOC_PATH_VOICE2_PASSIVE 3
+
 uint16_t voc_get_session_id(char *name);
 
 int voc_start_playback(uint32_t set);
 int voc_start_record(uint32_t port_id, uint32_t set);
+int voc_set_ext_ec_ref(uint16_t port_id, bool state);
+
 #endif
diff --git a/sound/soc/msm/qdsp6v2/audio_ocmem.c b/sound/soc/msm/qdsp6v2/audio_ocmem.c
index c046b63..3969cff 100644
--- a/sound/soc/msm/qdsp6v2/audio_ocmem.c
+++ b/sound/soc/msm/qdsp6v2/audio_ocmem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/audio_ocmem.h b/sound/soc/msm/qdsp6v2/audio_ocmem.h
index e915516..08bb1f3 100644
--- a/sound/soc/msm/qdsp6v2/audio_ocmem.h
+++ b/sound/soc/msm/qdsp6v2/audio_ocmem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
index 6f3249a..3284380 100644
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -281,7 +281,6 @@
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct compr_audio *compr;
 	struct msm_audio *prtd;
-	int ret = 0;
 	struct asm_softpause_params softpause = {
 		.enable = SOFT_PAUSE_ENABLE,
 		.period = SOFT_PAUSE_PERIOD,
@@ -293,6 +292,7 @@
 		.step = SOFT_VOLUME_STEP,
 		.rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
 	};
+	int ret = 0;
 
 	/* Capture path */
 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -337,7 +337,7 @@
 	populate_codec_list(compr, runtime);
 	runtime->private_data = compr;
 	compressed_audio.prtd =  &compr->prtd;
-	ret = compressed_set_volume(compressed_audio.volume);
+	ret = compressed_set_volume(0);
 	if (ret < 0)
 		pr_err("%s : Set Volume failed : %d", __func__, ret);
 
@@ -524,8 +524,8 @@
 		pr_debug("SNDRV_COMPRESS_TSTAMP\n");
 
 		memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
-		timestamp = q6asm_get_session_time(prtd->audio_client);
-		if (timestamp < 0) {
+		rc = q6asm_get_session_time(prtd->audio_client, &timestamp);
+		if (rc < 0) {
 			pr_err("%s: Get Session Time return value =%lld\n",
 				__func__, timestamp);
 			return -EAGAIN;
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.h b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.h
index 9830300..d6e3ec6 100644
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 3eab972..3813417 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
index cab689d..98401d9 100644
--- a/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index 4593784..b6ecaa6 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h
index 20d6377..146992a 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
index 047e0f0..a6c8f16 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 and
@@ -502,8 +502,8 @@
 		pr_debug("SNDRV_COMPRESS_TSTAMP\n");
 
 		memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
-		timestamp = q6asm_get_session_time(prtd->audio_client);
-		if (timestamp < 0) {
+		rc = q6asm_get_session_time(prtd->audio_client, &timestamp);
+		if (rc < 0) {
 			pr_err("%s: Get Session Time return value =%lld\n",
 				__func__, timestamp);
 			return -EAGAIN;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index c9f9593..57ccea1 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
index 44395b7..e70d1d7 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index fbbb3a5..1f053e0 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index 32e18d8..e66a314 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
index 206e881..9d046bd 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h
index 64c0848..d0b119c 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
index 492569b..7e7e9c9 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index e5837b2..25b9b76 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 0b25545..f56b3d6 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 4ec3f91..82b92aa 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -1887,6 +1887,13 @@
 	return -EINVAL;
 }
 
+/* Support for selecting stereo mixing coefficients for B family not done */
+int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff)
+{
+	/* To Be Done */
+	return 0;
+}
+
 int q6asm_enc_cfg_blk_qcelp(struct audio_client *ac, uint32_t frames_per_buf,
 		uint16_t min_rate, uint16_t max_rate,
 		uint16_t reduced_rate_level, uint16_t rate_modulation_cmd)
@@ -3191,13 +3198,13 @@
 	return -EINVAL;
 }
 
-uint64_t q6asm_get_session_time(struct audio_client *ac)
+int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp)
 {
 	struct apr_hdr hdr;
 	int rc;
 
-	if (!ac || ac->apr == NULL) {
-		pr_err("APR handle NULL\n");
+	if (!ac || ac->apr == NULL || tstamp == NULL) {
+		pr_err("APR handle NULL or tstamp NULL\n");
 		return -EINVAL;
 	}
 	q6asm_add_hdr(ac, &hdr, sizeof(hdr), TRUE);
@@ -3219,7 +3226,9 @@
 			__func__);
 		goto fail_cmd;
 	}
-	return ac->time_stamp;
+
+	*tstamp = ac->time_stamp;
+	return 0;
 
 fail_cmd:
 	return -EINVAL;
diff --git a/sound/soc/msm/qdsp6v2/q6audio-v2.c b/sound/soc/msm/qdsp6v2/q6audio-v2.c
index 8c524fa..775af95 100644
--- a/sound/soc/msm/qdsp6v2/q6audio-v2.c
+++ b/sound/soc/msm/qdsp6v2/q6audio-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
index 2c31d39..557b326 100644
--- a/sound/soc/msm/qdsp6v2/q6core.c
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/q6core.h b/sound/soc/msm/qdsp6v2/q6core.h
index 5cb6098..ff611d5 100644
--- a/sound/soc/msm/qdsp6v2/q6core.h
+++ b/sound/soc/msm/qdsp6v2/q6core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 26cb0fe..d44eadd 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -1,4 +1,4 @@
-/*  Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/*  Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index ad4e52d..771d8de 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. 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 and
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 6f07ae1..b281be4 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1650,9 +1650,11 @@
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
-	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
 		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
+		break;
 	}
 
 out:
diff --git a/tools/perf/builtin-periodic.c b/tools/perf/builtin-periodic.c
index a0785c2..ce9837d 100644
--- a/tools/perf/builtin-periodic.c
+++ b/tools/perf/builtin-periodic.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. 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 and