Merge "msm: kgsl: Always resume the GPU regardless of its state"
diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt
index 1c044eb..19472c9 100644
--- a/Documentation/devicetree/bindings/arm/pmu.txt
+++ b/Documentation/devicetree/bindings/arm/pmu.txt
@@ -9,6 +9,7 @@
 - compatible : should be one of
 	"arm,cortex-a9-pmu"
 	"arm,cortex-a8-pmu"
+	"arm,cortex-a7-pmu"
 	"arm,arm1176-pmu"
 	"arm,arm1136-pmu"
 - interrupts : 1 combined interrupt or 1 per core.
diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt
index 052feeb..aa0aa8c 100644
--- a/Documentation/devicetree/bindings/gpu/adreno.txt
+++ b/Documentation/devicetree/bindings/gpu/adreno.txt
@@ -66,7 +66,6 @@
 			   and when coming back out of resume
 - qcom,step-pwrlevel:	   How many qcom,gpu-pwrlevel should be decremented at once
 - qcom,idle-timeout:	   This property represents the time in microseconds for idle timeout.
-- qcom,nap-allowed:	   Boolean. <0> or <1> to disable/enable nap.
 - qcom,chipid:		   If it exists this property is used to replace
 			   the chip identification read from the GPU hardware.
 			   This is used to override faulty hardware readings.
@@ -105,7 +104,6 @@
 
 		qcom,initial-pwrlevel = <1>;
 		qcom,idle-timeout = <83>; //<HZ/12>
-		qcom,nap-allowed = <1>;
 		qcom,clk-map = <0x00000016>; //KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE
 
 		/* Bus Scale Settings */
diff --git a/Documentation/devicetree/bindings/input/touchscreen/ft5x06-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/ft5x06-ts.txt
new file mode 100644
index 0000000..d77e96c
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/ft5x06-ts.txt
@@ -0,0 +1,53 @@
+FocalTech touch controller
+
+The focaltech controller is connected to host processor
+via i2c. The controller generates interrupts when the
+user touches the panel. The host controller is expected
+to read the touch coordinates over i2c and pass the coordinates
+to the rest of the system.
+
+Required properties:
+
+ - compatible		: should be "focaltech,5x06"
+ - 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.
+ - vdd-supply		: Power supply needed to power up the device
+ - vcc_i2c-supply	: Power source required to power up i2c bus
+ - focaltech,family-id	: family identification of the controller
+ - focaltech,irq-gpio	: irq gpio which is to provide interrupts to host,
+				same as "interrupts" node. It will also
+				contain active low or active high information.
+ - focaltech,reset-gpio	: reset gpio to control the reset of chip
+ - focaltech,display-coords : display coordinates in pixels. It is a four
+				tuple consisting of min x, min y, max x and
+				max y values
+
+Optional properties:
+
+ - focaltech,panel-coords : panel coordinates for the chip in pixels.
+				It is a four tuple consisting of min x,
+				min y, max x and max y values
+ - focaltech,i2c-pull-up : to specify pull up is required
+ - focaltech,no-force-update : to specify force update is allowed
+ - focaltech,button-map : button map of key codes. The number
+				of key codes depend on panel
+
+Example:
+	i2c@f9924000 {
+		ft5x06_ts@38 {
+			compatible = "focaltech,5x06";
+			reg = <0x38>;
+			interrupt-parent = <&msmgpio>;
+			interrupts = <61 0x2>;
+			vdd-supply = <&pm8941_l22>;
+			vcc_i2c-supply = <&pm8941_s3>;
+			focaltech,reset-gpio = <&msmgpio 60 0x00>;
+			focaltech,irq-gpio = <&msmgpio 61 0x00>;
+			focaltech,panel-coords = <0 0 480 800>;
+			focaltech,display-coords = <0 0 480 800>;
+			focaltech,button-map= <158 102 139 217>;
+			focaltech,family-id = <0x0a>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt b/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
index d24139b..0f35e73 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
@@ -12,7 +12,6 @@
 
 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
@@ -48,6 +47,5 @@
 			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/iommu/msm_iommu_v1.txt b/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
index b3f1aef..26a119c 100644
--- a/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
+++ b/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
@@ -13,6 +13,7 @@
 - qcom,iommu-secure-id : Secure identifier for the IOMMU block
 - qcom,secure-context : boolean indicating that a context is secure and
   programmed by the secure environment.
+- qcom,vdd-supply: Regulator needed to access IOMMU
 - qcom,alt-vdd-supply : Alternative regulator needed to access IOMMU
   configuration registers.
 - interrupts : should contain the performance monitor overflow interrupt number.
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp.txt b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
index 5a668b2..ff95d43 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
@@ -71,6 +71,7 @@
 - linux,default-trigger: trigger the led from external modules such as display
 - qcom,default-state:  default state of the led, should be "on" or "off"
 - qcom,turn-off-delay-ms: delay in millisecond for turning off the led when its default-state is "on". Value is being ignored in case default-state is "off".
+- qcom,use-blink: Use blink sysfs entry for switching into lpg mode.  For optimal use, set default mode to pwm.  All required lpg parameters must be supplied.
 
 MPP LED is an LED controled through a Multi Purpose Pin.
 
@@ -80,6 +81,7 @@
 - qcom,source-sel: select power source, default 1 (enabled)
 - qcom,mode-ctrl: select operation mode, default 0x60 = Mode Sink
 - qcom,mode: mode the led should operate in, options "pwm", "lpg" and "manual"
+- qcom,use-blink: Use blink sysfs entry for switching into lpg mode.  For optimal use, set default mode to pwm.  All required lpg parameters must be supplied.
 
 Required properties for PWM mode only:
 - qcom,pwm-channel: pwm channel the led will operate on
@@ -161,8 +163,19 @@
 			label = "rgb";
 			linux,name = "led:rgb_red";
 			qcom,mode = "pwm";
-			qcom,pwm-channel = <6>;
 			qcom,pwm-us = <1000>;
+			qcom,pwm-channel = <6>;
+			qcom,max-current = <12>;
+			qcom,default-state = "off";
+			qcom,id = <3>;
+			linux,default-trigger =
+				"battery-charging";
+		};
+		qcom,rgb_lpg {
+			label = "rgb";
+			linux,name = "led:rgb_green";
+			qcom,mode = "lpg";
+			qcom,pwm-channel = <5>;
 			qcom,duty-ms = <20>;
 			qcom,start-idx = <1>;
 			qcom,idx-len = <10>;
@@ -175,10 +188,10 @@
 				"battery-charging";
 		};
 
-		qcom,rgb_lpg {
+		qcom,rgb_blink {
 			label = "rgb";
 			linux,name = "led:rgb_blue";
-			qcom,mode = "lpg";
+			qcom,mode = "pwm";
 			qcom,pwm-channel = <4>;
 			qcom,start-idx = <1>;
 			qcom,idx-len = <10>;
@@ -193,6 +206,8 @@
 			qcom,turn-off-delay-ms = <500>;
 			qcom,id = <5>;
 			linux,default-trigger = "none";
+			qcom,pwm-us = <1000>;
+			qcom,use-blink;
 		};
 	};
 
diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
index ded8f77..d6980ac 100644
--- a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
+++ b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
@@ -20,6 +20,8 @@
 - qcom,gpio-proxy-unvote: GPIO used by the modem to trigger proxy unvoting in
   the apps.
 - qcom,gpio-force-stop: GPIO used by the apps to force the modem to shutdown.
+- qcom,gpio-stop-ack: GPIO used by the modem to ack force stop or a graceful stop
+		      to the apps.
 
 Optional properties:
 - vdd_mss-supply:     Reference to the regulator that supplies the processor.
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 82ac057..8d41295 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -15,6 +15,7 @@
 denx	Denx Software Engineering
 epson	Seiko Epson Corp.
 est	ESTeem Wireless Modems
+focaltech Focaltech systems
 fsl	Freescale Semiconductor
 GEFanuc	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 gef	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/apq8026-mtp.dts
similarity index 73%
copy from arch/arm/boot/dts/msm8226-mtp.dts
copy to arch/arm/boot/dts/apq8026-mtp.dts
index 2881274..e14a6856 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/apq8026-mtp.dts
@@ -10,15 +10,13 @@
  * GNU General Public License for more details.
  */
 
+
 /dts-v1/;
-/include/ "msm8226.dtsi"
+/include/ "apq8026.dtsi"
 /include/ "msm8226-mtp.dtsi"
 
 / {
-	model = "Qualcomm MSM 8226 MTP";
-	compatible = "qcom,msm8226-mtp", "qcom,msm8226", "qcom,mtp";
-	qcom,msm-id = <145 8 0>,
-		      <158 8 0>,
-		      <159 8 0>,
-		      <198 8 0>;
+	model = "Qualcomm APQ 8026 MTP";
+	compatible = "qcom,apq8026-mtp", "qcom,apq8026", "qcom,mtp";
+	qcom,msm-id = <199 8 0>;
 };
diff --git a/arch/arm/boot/dts/msm8226-cdp.dts b/arch/arm/boot/dts/apq8026-xpm.dts
similarity index 73%
copy from arch/arm/boot/dts/msm8226-cdp.dts
copy to arch/arm/boot/dts/apq8026-xpm.dts
index da517eb..67152af 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dts
+++ b/arch/arm/boot/dts/apq8026-xpm.dts
@@ -10,15 +10,13 @@
  * GNU General Public License for more details.
  */
 
+
 /dts-v1/;
-/include/ "msm8226.dtsi"
+/include/ "apq8026.dtsi"
 /include/ "msm8226-cdp.dtsi"
 
 / {
-	model = "Qualcomm MSM 8226 CDP";
-	compatible = "qcom,msm8226-cdp", "qcom,msm8226", "qcom,cdp";
-	qcom,msm-id = <145 1 0>,
-		      <158 1 0>,
-		      <159 1 0>,
-		      <198 1 0>;
+	model = "Qualcomm APQ 8026 XPM";
+	compatible = "qcom,apq8026-xpm", "qcom,apq8026", "qcom,xpm";
+	qcom,msm-id = <199 14 0>;
 };
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/apq8026.dtsi
similarity index 71%
copy from arch/arm/boot/dts/msm8226-mtp.dts
copy to arch/arm/boot/dts/apq8026.dtsi
index 2881274..db6576a 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/apq8026.dtsi
@@ -10,15 +10,15 @@
  * GNU General Public License for more details.
  */
 
-/dts-v1/;
+/*
+ * Only 8026-specific property overrides should be placed inside this
+ * file. Device definitions should be placed inside the msm8226.dtsi
+ * file.
+ */
+
 /include/ "msm8226.dtsi"
-/include/ "msm8226-mtp.dtsi"
 
 / {
-	model = "Qualcomm MSM 8226 MTP";
-	compatible = "qcom,msm8226-mtp", "qcom,msm8226", "qcom,mtp";
-	qcom,msm-id = <145 8 0>,
-		      <158 8 0>,
-		      <159 8 0>,
-		      <198 8 0>;
+	model = "Qualcomm APQ 8026";
+	compatible = "qcom,apq8026";
 };
diff --git a/arch/arm/boot/dts/apq8074-dragonboard.dtsi b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
index 8e4f368..6b4d1d3 100644
--- a/arch/arm/boot/dts/apq8074-dragonboard.dtsi
+++ b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
@@ -199,6 +199,26 @@
 			"DMIC6", "MIC BIAS4 External",
 			"MIC BIAS4 External", "Digital Mic6";
 	};
+
+	qcom,pronto@fb21b000 {
+		status = "disabled";
+	};
+
+	qcom,iris-fm {
+		status = "disabled";
+	};
+
+	qcom,wcnss-wlan@fb000000 {
+		status = "disabled";
+	};
+
+	qcom,smd-wcnss {
+		status = "disabled";
+	};
+
+	qcom,smsm-wcnss {
+		status = "disabled";
+	};
 };
 
 &mdss_fb0 {
diff --git a/arch/arm/boot/dts/apq8084-regulator.dtsi b/arch/arm/boot/dts/apq8084-regulator.dtsi
index 00991b3..998b469 100644
--- a/arch/arm/boot/dts/apq8084-regulator.dtsi
+++ b/arch/arm/boot/dts/apq8084-regulator.dtsi
@@ -325,3 +325,53 @@
 	};
 };
 
+&rpm_bus {
+	rpm-regulator-smpb1 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpb";
+		qcom,resource-id = <1>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+
+		pma8084_s1_ao: regulator-s1-ao {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s1_ao";
+			qcom,set = <1>;
+			regulator-min-microvolt = <675000>;
+			regulator-max-microvolt = <1050000>;
+		};
+	};
+
+	rpm-regulator-smpb2 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "smpb";
+		qcom,resource-id = <2>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+
+		pma8084_s2_corner_ao: regulator-s2-corner-ao {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_s2_corner_ao";
+			qcom,set = <1>;
+			regulator-min-microvolt = <1>;
+			regulator-max-microvolt = <7>;
+			qcom,use-voltage-corner;
+		};
+	};
+
+	rpm-regulator-ldoa12 {
+		compatible = "qcom,rpm-regulator-smd-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <12>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+
+		pma8084_l12_ao: regulator-l12-ao {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8084_l12_ao";
+			qcom,set = <1>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/apq8084.dtsi b/arch/arm/boot/dts/apq8084.dtsi
index c74e59d..d4adb2a 100644
--- a/arch/arm/boot/dts/apq8084.dtsi
+++ b/arch/arm/boot/dts/apq8084.dtsi
@@ -136,6 +136,21 @@
 		#interrupt-cells = <3>;
 	};
 
+	i2c_0: i2c@f9925000 { /* BLSP1 QUP3 */
+		cell-index = <0>;
+		compatible = "qcom,i2c-qup";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg-names = "qup_phys_addr";
+		reg = <0xf9925000 0x1000>;
+		interrupt-names = "qup_err_intr";
+		interrupts = <0 97 0>;
+		qcom,i2c-bus-freq = <100000>;
+		qcom,i2c-src-freq = <50000000>;
+		qcom,sda-gpio = <&msmgpio 10 0>;
+		qcom,scl-gpio = <&msmgpio 11 0>;
+	};
+
 	usb3: qcom,ssusb@f9200000 {
 		compatible = "qcom,dwc-usb3-msm";
 		reg = <0xf9200000 0xfc000>,
diff --git a/arch/arm/boot/dts/dsi-v2-panel-truly-wvga-video.dtsi b/arch/arm/boot/dts/dsi-v2-panel-truly-wvga-video.dtsi
index a3718aa..891eac3 100644
--- a/arch/arm/boot/dts/dsi-v2-panel-truly-wvga-video.dtsi
+++ b/arch/arm/boot/dts/dsi-v2-panel-truly-wvga-video.dtsi
@@ -55,62 +55,62 @@
 
 		qcom,on-cmds-dsi-state = "DSI_LP_MODE";
 		qcom,panel-on-cmds = [
-					05 01 00 00 01 02
+					05 01 00 00 00 02
 						01 00
-					23 01 00 00 01 02
+					23 01 00 00 00 02
 						b0 04
-					29 01 00 00 01 03
+					29 01 00 00 00 03
 						b3 02 00
-					23 01 00 00 01 02
+					23 01 00 00 00 02
 						bd 00
-					29 01 00 00 01 03
+					29 01 00 00 00 03
 						c0 18 66
-					29 01 00 00 01 10
+					29 01 00 00 00 10
 						c1 23 31 99 21 20 00 30 28 0c 0c
 						00 00 00 21 01
-					29 01 00 00 01 07
+					29 01 00 00 00 07
 						c2 10 06 06 01 03 00
-					29 01 00 00 01 19
+					29 01 00 00 00 19
 						c8 04 10 18 20 2e 46 3c 28 1f 18
 						10 04 04 10 18 20 2e 46 3c 28 1f 18 10 04
-					29 01 00 00 01 19
+					29 01 00 00 00 19
 						c9 04 10 18 20 2e 46 3c 28 1f 18
 						10 04 04 10 18 20 2e 46 3c 28 1f 18 10 04
-					29 01 00 00 01 19
+					29 01 00 00 00 19
 						ca 04 10 18 20 2e 46 3c 28 1f 18
 						10 04 04 10 18 20 2e 46 3c 28 1f 18 10 04
-					29 01 00 00 01 11
+					29 01 00 00 00 11
 						d0 29 03 ce a6 00 43 20 10 01 00
 						01 01 00 03 01 00
-					29 01 00 00 01 08
+					29 01 00 00 00 08
 						d1 18 0C 23 03 75 02 50
-					23 01 00 00 01 02
+					23 01 00 00 00 02
 						d3 11
-					29 01 00 00 01 03
+					29 01 00 00 00 03
 						d5 2a 2a
-					29 01 00 00 01 03
+					29 01 00 00 00 03
 						de 01 41
-					23 01 00 00 01 02
+					23 01 00 00 00 02
 						e6 51
-					23 01 00 00 01 02
+					23 01 00 00 00 02
 						fa 03
 					23 01 00 00 64 02
 						d6 28
-					39 01 00 00 01 05
+					39 01 00 00 00 05
 						2a 00 00 01 df
-					39 01 00 00 01 05
+					39 01 00 00 00 05
 						2b 00 00 03 1f
-					15 01 00 00 01 02
+					15 01 00 00 00 02
 						35 00
-					39 01 00 00 01 03
+					39 01 00 00 00 03
 						44 00 50
-					15 01 00 00 01 02
+					15 01 00 00 00 02
 						36 c1
-					15 01 00 00 01 02
+					15 01 00 00 00 02
 						3a 77
-					05 01 00 00 96 02
+					05 01 00 00 7D 02
 						11 00
-					05 01 00 00 64 02
+					05 01 00 00 14 02
 						29 00
 					];
 		qcom,panel-off-cmds = [05 01 00 00 32 02 28 00
diff --git a/arch/arm/boot/dts/mpq8092-iommu.dtsi b/arch/arm/boot/dts/mpq8092-iommu.dtsi
index c6693e1..56369dc 100644
--- a/arch/arm/boot/dts/mpq8092-iommu.dtsi
+++ b/arch/arm/boot/dts/mpq8092-iommu.dtsi
@@ -14,20 +14,27 @@
 
 &jpeg_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_jpeg>;
 };
 
 &mdp_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_mdss>;
 };
 
 &venus_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_venus>;
 };
 
 &kgsl_iommu {
 	status = "ok";
+	qcom,needs-alt-core-clk;
+	vdd-supply = <&gdsc_oxili_cx>;
+	qcom,alt-vdd-supply = <&gdsc_oxili_gx>;
 };
 
 &vfe_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_vfe>;
 };
diff --git a/arch/arm/boot/dts/mpq8092.dtsi b/arch/arm/boot/dts/mpq8092.dtsi
index 946b54d..cc19cce 100644
--- a/arch/arm/boot/dts/mpq8092.dtsi
+++ b/arch/arm/boot/dts/mpq8092.dtsi
@@ -69,6 +69,11 @@
 		status = "disabled";
 	};
 
+	qcom,msm-imem@fe805000 {
+                compatible = "qcom,msm-imem";
+                reg = <0xfe805000 0x1000>; /* Address and size of IMEM */
+	};
+
 	spmi_bus: qcom,spmi@fc4c0000 {
 		cell-index = <0>;
 		compatible = "qcom,spmi-pmic-arb";
diff --git a/arch/arm/boot/dts/msm-iommu-v1.dtsi b/arch/arm/boot/dts/msm-iommu-v1.dtsi
index d497259..4492077 100644
--- a/arch/arm/boot/dts/msm-iommu-v1.dtsi
+++ b/arch/arm/boot/dts/msm-iommu-v1.dtsi
@@ -19,10 +19,16 @@
 		reg = <0xfda64000 0x10000>;
 		reg-names = "iommu_base";
 		interrupts = <0 67 0>;
-		vdd-supply = <&gdsc_jpeg>;
 		qcom,needs-alt-core-clk;
 		label = "jpeg_iommu";
 		status = "disabled";
+		qcom,msm-bus,name = "jpeg_ebi";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<62 512 0 0>,
+				<62 512 0 1000>;
 
 		qcom,iommu-pmu-ngroups = <1>;
 		qcom,iommu-pmu-ncounters = <8>;
@@ -109,9 +115,15 @@
 		reg = <0xfd928000 0x10000>;
 		reg-names = "iommu_base";
 		interrupts = <0 73 0>;
-		vdd-supply = <&gdsc_mdss>;
 		qcom,iommu-secure-id = <1>;
 		label = "mdp_iommu";
+		qcom,msm-bus,name = "mdp_ebi";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<22 512 0 0>,
+				<22 512 0 1000>;
 		status = "disabled";
 
 		qcom,iommu-pmu-ngroups = <1>;
@@ -208,10 +220,16 @@
 		       0xfdce0004 0x4>;
 		reg-names = "iommu_base", "clk_base";
 		interrupts = <0 45 0>;
-		vdd-supply = <&gdsc_venus>;
 		qcom,iommu-secure-id = <0>;
 		qcom,needs-alt-core-clk;
 		label = "venus_iommu";
+		qcom,msm-bus,name = "venus_ebi";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<63 512 0 0>,
+				<63 512 0 1000>;
 		status = "disabled";
 
 		qcom,iommu-pmu-ngroups = <1>;
@@ -319,10 +337,14 @@
 		reg = <0xfdb10000 0x10000>;
 		reg-names = "iommu_base";
 		interrupts = <0 38 0>;
-		vdd-supply = <&gdsc_oxili_cx>;
-		qcom,alt-vdd-supply = <&gdsc_oxili_gx>;
-		qcom,needs-alt-core-clk;
 		label = "kgsl_iommu";
+		qcom,msm-bus,name = "kgsl_ebi";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<26 512 0 0>,
+				<26 512 0 1000>;
 		status = "disabled";
 
 		qcom,iommu-pmu-ngroups = <1>;
@@ -396,9 +418,15 @@
 		reg = <0xfda44000 0x10000>;
 		reg-names = "iommu_base";
 		interrupts = <0 62 0>;
-		vdd-supply = <&gdsc_vfe>;
 		qcom,needs-alt-core-clk;
 		label = "vfe_iommu";
+		qcom,msm-bus,name = "vfe_ebi";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<29 512 0 0>,
+				<29 512 0 1000>;
 		status = "disabled";
 
 		qcom,iommu-pmu-ngroups = <1>;
diff --git a/arch/arm/boot/dts/msm-pm8110.dtsi b/arch/arm/boot/dts/msm-pm8110.dtsi
index 2e8700a..1877f40 100644
--- a/arch/arm/boot/dts/msm-pm8110.dtsi
+++ b/arch/arm/boot/dts/msm-pm8110.dtsi
@@ -53,7 +53,7 @@
 			status = "disabled";
 
 			qcom,vddmax-mv = <4200>;
-			qcom,vddsafe-mv = <4200>;
+			qcom,vddsafe-mv = <4230>;
 			qcom,vinmin-mv = <4200>;
 			qcom,vbatdet-mv = <4100>;
 			qcom,ibatmax-ma = <1500>;
@@ -280,6 +280,15 @@
 			qcom,adc-vdd-reference = <1800>;
 		};
 
+		qcom,temp-alarm@2400 {
+			compatible = "qcom,qpnp-temp-alarm";
+			reg = <0x2400 0x100>;
+			interrupts = <0x0 0x24 0x0>;
+			label = "pm8110_tz";
+			qcom,channel-num = <8>;
+			qcom,threshold-set = <0>;
+		};
+
 		pm8110_bms: qcom,bms {
 			spmi-dev-container;
 			compatible = "qcom,qpnp-bms";
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index fe0000a..d429f72 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -57,7 +57,7 @@
 			status = "disabled";
 
 			qcom,vddmax-mv = <4200>;
-			qcom,vddsafe-mv = <4200>;
+			qcom,vddsafe-mv = <4230>;
 			qcom,vinmin-mv = <4200>;
 			qcom,vbatdet-delta-mv = <150>;
 			qcom,ibatmax-ma = <1500>;
@@ -793,9 +793,10 @@
 
                 qcom,leds@d300 {
                         compatible = "qcom,leds-qpnp";
-                        status = "disable";
+                        status = "okay";
                         reg = <0xd300 0x100>;
                         label = "flash";
+			flash_boost-supply = <&pm8226_chg_boost>;
                         pm8226_flash0: qcom,flash_0 {
                                 qcom,max-current = <1000>;
                                 qcom,default-state = "off";
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index c78a144..b4e557e 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -173,7 +173,7 @@
 			status = "disabled";
 
 			qcom,vddmax-mv = <4200>;
-			qcom,vddsafe-mv = <4200>;
+			qcom,vddsafe-mv = <4230>;
 			qcom,vinmin-mv = <4300>;
 			qcom,ibatmax-ma = <1500>;
 			qcom,ibatterm-ma = <100>;
diff --git a/arch/arm/boot/dts/msm8226-cdp.dtsi b/arch/arm/boot/dts/msm8226-cdp.dtsi
index c1ab954..e489dbb 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-cdp.dtsi
@@ -34,7 +34,6 @@
 			synaptics,irq-gpio = <&msmgpio 17 0x2008>;
 			synaptics,button-map = <139 102 158>;
 			synaptics,i2c-pull-up;
-			synaptics,reg-en;
 		};
 	};
 
@@ -300,7 +299,7 @@
 				qcom,cs-out-en;
 				qcom,op-fdbck = <1>;
 				qcom,default-state = "on";
-				qcom,max-current = <25>;
+				qcom,max-current = <20>;
 				qcom,ctrl-delay-us = <0>;
 				qcom,boost-curr-lim = <3>;
 				qcom,cp-sel = <0>;
diff --git a/arch/arm/boot/dts/msm8226-gpu.dtsi b/arch/arm/boot/dts/msm8226-gpu.dtsi
index d83df1e..590f733 100644
--- a/arch/arm/boot/dts/msm8226-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8226-gpu.dtsi
@@ -25,7 +25,6 @@
 		qcom,initial-pwrlevel = <1>;
 
 		qcom,idle-timeout = <8>; //<HZ/12>
-		qcom,nap-allowed = <1>;
 		qcom,strtstp-sleepwake;
 		qcom,clk-map = <0x00000016>; /* KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE */
 
diff --git a/arch/arm/boot/dts/msm8226-iommu.dtsi b/arch/arm/boot/dts/msm8226-iommu.dtsi
index 460068b..ff3e0a5 100644
--- a/arch/arm/boot/dts/msm8226-iommu.dtsi
+++ b/arch/arm/boot/dts/msm8226-iommu.dtsi
@@ -14,6 +14,7 @@
 
 &jpeg_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_jpeg>;
 	qcom,iommu-enable-halt;
 
 	qcom,iommu-bfb-regs =  <0x204c
@@ -51,6 +52,7 @@
 
 &mdp_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_mdss>;
 	qcom,iommu-enable-halt;
 
 	qcom,iommu-bfb-regs =  <0x204c
@@ -94,6 +96,7 @@
 
 &venus_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_venus>;
 	qcom,iommu-enable-halt;
 
 	qcom,iommu-bfb-regs =  <0x204c
@@ -157,7 +160,10 @@
 
 &kgsl_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_oxili_cx>;
+	qcom,alt-vdd-supply = <&gdsc_oxili_gx>;
 	qcom,iommu-enable-halt;
+	qcom,needs-alt-core-clk;
 
 	qcom,iommu-bfb-regs =  <0x204c
 				0x2050
@@ -188,6 +194,7 @@
 
 &vfe_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_vfe>;
 	qcom,iommu-enable-halt;
 
 	qcom,iommu-bfb-regs =  <0x204c
diff --git a/arch/arm/boot/dts/msm8226-mtp.dtsi b/arch/arm/boot/dts/msm8226-mtp.dtsi
index a9ae3b0..ae57797 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-mtp.dtsi
@@ -34,7 +34,6 @@
 			synaptics,irq-gpio = <&msmgpio 17 0x2008>;
 			synaptics,button-map = <139 102 158>;
 			synaptics,i2c-pull-up;
-			synaptics,reg-en;
 		};
 	};
 
@@ -103,6 +102,21 @@
 	};
 };
 
+&usb_otg {
+	#address-cells = <0>;
+	interrupt-parent = <&usb_otg>;
+	interrupts = <0 1 2>;
+	#interrupt-cells = <1>;
+	interrupt-map-mask = <0xffffffff>;
+	interrupt-map = <0 &intc 0 134 0
+			1 &intc 0 140 0
+			2 &spmi_bus 0x0 0x0 0x9 0x0>;
+	interrupt-names = "core_irq", "async_irq", "pmic_id_irq";
+
+	qcom,hsusb-otg-mode = <3>;
+	vbus_otg-supply = <&usb_otg_sw>;
+};
+
 &sdcc1 {
 	vdd-supply = <&pm8226_l17>;
 	qcom,vdd-always-on;
@@ -292,7 +306,7 @@
 				qcom,cs-out-en;
 				qcom,op-fdbck = <1>;
 				qcom,default-state = "on";
-				qcom,max-current = <25>;
+				qcom,max-current = <20>;
 				qcom,ctrl-delay-us = <0>;
 				qcom,boost-curr-lim = <3>;
 				qcom,cp-sel = <0>;
diff --git a/arch/arm/boot/dts/msm8226-qrd.dtsi b/arch/arm/boot/dts/msm8226-qrd.dtsi
index 1698ac1..a60ff26 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-qrd.dtsi
@@ -34,7 +34,6 @@
 			synaptics,irq-gpio = <&msmgpio 17 0x2008>;
 			synaptics,button-map = <139 102 158>;
 			synaptics,i2c-pull-up;
-			synaptics,reg-en;
 		};
 	};
 
@@ -296,7 +295,7 @@
 				qcom,cs-out-en;
 				qcom,op-fdbck = <1>;
 				qcom,default-state = "on";
-				qcom,max-current = <25>;
+				qcom,max-current = <20>;
 				qcom,ctrl-delay-us = <0>;
 				qcom,boost-curr-lim = <3>;
 				qcom,cp-sel = <0>;
diff --git a/arch/arm/boot/dts/msm8226-cdp.dts b/arch/arm/boot/dts/msm8226-v1-cdp.dts
similarity index 91%
rename from arch/arm/boot/dts/msm8226-cdp.dts
rename to arch/arm/boot/dts/msm8226-v1-cdp.dts
index da517eb..9c49840 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dts
+++ b/arch/arm/boot/dts/msm8226-v1-cdp.dts
@@ -11,7 +11,7 @@
  */
 
 /dts-v1/;
-/include/ "msm8226.dtsi"
+/include/ "msm8226-v1.dtsi"
 /include/ "msm8226-cdp.dtsi"
 
 / {
@@ -20,5 +20,6 @@
 	qcom,msm-id = <145 1 0>,
 		      <158 1 0>,
 		      <159 1 0>,
-		      <198 1 0>;
+		      <198 1 0>,
+		      <205 1 0>;
 };
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/msm8226-v1-mtp.dts
similarity index 91%
rename from arch/arm/boot/dts/msm8226-mtp.dts
rename to arch/arm/boot/dts/msm8226-v1-mtp.dts
index 2881274..b1d46b1 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-v1-mtp.dts
@@ -11,7 +11,7 @@
  */
 
 /dts-v1/;
-/include/ "msm8226.dtsi"
+/include/ "msm8226-v1.dtsi"
 /include/ "msm8226-mtp.dtsi"
 
 / {
@@ -20,5 +20,6 @@
 	qcom,msm-id = <145 8 0>,
 		      <158 8 0>,
 		      <159 8 0>,
-		      <198 8 0>;
+		      <198 8 0>,
+		      <205 8 0>;
 };
diff --git a/arch/arm/boot/dts/msm8226-qrd.dts b/arch/arm/boot/dts/msm8226-v1-qrd.dts
similarity index 91%
rename from arch/arm/boot/dts/msm8226-qrd.dts
rename to arch/arm/boot/dts/msm8226-v1-qrd.dts
index e364de7..d2aabac 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dts
+++ b/arch/arm/boot/dts/msm8226-v1-qrd.dts
@@ -11,7 +11,7 @@
  */
 
 /dts-v1/;
-/include/ "msm8226.dtsi"
+/include/ "msm8226-v1.dtsi"
 /include/ "msm8226-qrd.dtsi"
 
 / {
@@ -20,5 +20,6 @@
 	qcom,msm-id = <145 11 0>,
 		      <158 11 0>,
 		      <159 11 0>,
-		      <198 11 0>;
+		      <198 11 0>,
+		      <205 11 0>;
 };
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/msm8226-v1.dtsi
similarity index 70%
copy from arch/arm/boot/dts/msm8226-mtp.dts
copy to arch/arm/boot/dts/msm8226-v1.dtsi
index 2881274..d471bec 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-v1.dtsi
@@ -10,15 +10,10 @@
  * GNU General Public License for more details.
  */
 
-/dts-v1/;
-/include/ "msm8226.dtsi"
-/include/ "msm8226-mtp.dtsi"
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm8226.dtsi file.
+ */
 
-/ {
-	model = "Qualcomm MSM 8226 MTP";
-	compatible = "qcom,msm8226-mtp", "qcom,msm8226", "qcom,mtp";
-	qcom,msm-id = <145 8 0>,
-		      <158 8 0>,
-		      <159 8 0>,
-		      <198 8 0>;
-};
+/include/ "msm8226.dtsi"
diff --git a/arch/arm/boot/dts/msm8226-cdp.dts b/arch/arm/boot/dts/msm8226-v2-cdp.dts
similarity index 76%
copy from arch/arm/boot/dts/msm8226-cdp.dts
copy to arch/arm/boot/dts/msm8226-v2-cdp.dts
index da517eb..2b18491 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dts
+++ b/arch/arm/boot/dts/msm8226-v2-cdp.dts
@@ -11,14 +11,15 @@
  */
 
 /dts-v1/;
-/include/ "msm8226.dtsi"
+/include/ "msm8226-v2.dtsi"
 /include/ "msm8226-cdp.dtsi"
 
 / {
-	model = "Qualcomm MSM 8226 CDP";
+	model = "Qualcomm MSM 8226v2 CDP";
 	compatible = "qcom,msm8226-cdp", "qcom,msm8226", "qcom,cdp";
-	qcom,msm-id = <145 1 0>,
-		      <158 1 0>,
-		      <159 1 0>,
-		      <198 1 0>;
+	qcom,msm-id = <145 1 0x20000>,
+		      <158 1 0x20000>,
+		      <159 1 0x20000>,
+		      <198 1 0x20000>,
+		      <205 1 0x20000>;
 };
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/msm8226-v2-mtp.dts
similarity index 76%
copy from arch/arm/boot/dts/msm8226-mtp.dts
copy to arch/arm/boot/dts/msm8226-v2-mtp.dts
index 2881274..f15dd4c 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-v2-mtp.dts
@@ -11,14 +11,15 @@
  */
 
 /dts-v1/;
-/include/ "msm8226.dtsi"
+/include/ "msm8226-v2.dtsi"
 /include/ "msm8226-mtp.dtsi"
 
 / {
-	model = "Qualcomm MSM 8226 MTP";
+	model = "Qualcomm MSM 8226v2 MTP";
 	compatible = "qcom,msm8226-mtp", "qcom,msm8226", "qcom,mtp";
-	qcom,msm-id = <145 8 0>,
-		      <158 8 0>,
-		      <159 8 0>,
-		      <198 8 0>;
+	qcom,msm-id = <145 8 0x20000>,
+		      <158 8 0x20000>,
+		      <159 8 0x20000>,
+		      <198 8 0x20000>,
+		      <205 8 0x20000>;
 };
diff --git a/arch/arm/boot/dts/msm8226-qrd.dts b/arch/arm/boot/dts/msm8226-v2-qrd.dts
similarity index 75%
copy from arch/arm/boot/dts/msm8226-qrd.dts
copy to arch/arm/boot/dts/msm8226-v2-qrd.dts
index e364de7..1a89d78 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dts
+++ b/arch/arm/boot/dts/msm8226-v2-qrd.dts
@@ -11,14 +11,15 @@
  */
 
 /dts-v1/;
-/include/ "msm8226.dtsi"
+/include/ "msm8226-v2.dtsi"
 /include/ "msm8226-qrd.dtsi"
 
 / {
-	model = "Qualcomm MSM 8226 QRD";
+	model = "Qualcomm MSM 8226v2 QRD";
 	compatible = "qcom,msm8226-qrd", "qcom,msm8226", "qcom,qrd";
-	qcom,msm-id = <145 11 0>,
-		      <158 11 0>,
-		      <159 11 0>,
-		      <198 11 0>;
+	qcom,msm-id = <145 11 0x20000>,
+		      <158 11 0x20000>,
+		      <159 11 0x20000>,
+		      <198 11 0x20000>,
+		      <205 11 0x20000>;
 };
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/msm8226-v2.dtsi
similarity index 70%
copy from arch/arm/boot/dts/msm8226-mtp.dts
copy to arch/arm/boot/dts/msm8226-v2.dtsi
index 2881274..d471bec 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-v2.dtsi
@@ -10,15 +10,10 @@
  * GNU General Public License for more details.
  */
 
-/dts-v1/;
-/include/ "msm8226.dtsi"
-/include/ "msm8226-mtp.dtsi"
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm8226.dtsi file.
+ */
 
-/ {
-	model = "Qualcomm MSM 8226 MTP";
-	compatible = "qcom,msm8226-mtp", "qcom,msm8226", "qcom,mtp";
-	qcom,msm-id = <145 8 0>,
-		      <158 8 0>,
-		      <159 8 0>,
-		      <198 8 0>;
-};
+/include/ "msm8226.dtsi"
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 26e834f..7c98104 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -241,7 +241,7 @@
 		};
 	};
 
-        usb@f9a55000 {
+        usb_otg: usb@f9a55000 {
 		compatible = "qcom,hsusb-otg";
 		reg = <0xf9a55000 0x400>;
 		interrupts = <0 134 0>, <0 140 0>;
@@ -259,7 +259,7 @@
 		qcom,hsusb-otg-disable-reset;
 		qcom,dp-manual-pullup;
 
-		qcom,msm-bus,name = "usb2";
+		qcom,msm-bus,name = "usb";
 		qcom,msm-bus,num-cases = <2>;
 		qcom,msm-bus,num-paths = <1>;
 		qcom,msm-bus,vectors-KBps =
@@ -847,6 +847,7 @@
 		qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
 		qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>;
 		qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>;
+		qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>;
 
 		/* GPIO output to mss */
 		qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
@@ -1011,6 +1012,12 @@
 				<55 512 0 0>,
 				<55 512 3936000 393600>;
 	};
+
+	cpu-pmu {
+		compatible = "arm,cortex-a7-pmu";
+		qcom,irq-is-percpu;
+		interrupts = <1 7 0xf00>;
+	};
 };
 
 &gdsc_venus {
diff --git a/arch/arm/boot/dts/msm8610-cdp.dts b/arch/arm/boot/dts/msm8610-cdp.dts
index 1868a25..bbdc2b8 100644
--- a/arch/arm/boot/dts/msm8610-cdp.dts
+++ b/arch/arm/boot/dts/msm8610-cdp.dts
@@ -132,6 +132,16 @@
 			debounce-interval = <15>;
 		};
 	};
+
+    sound {
+        qcom,audio-routing =
+            "RX_BIAS", "MCLK",
+            "INT_LDO_H", "MCLK",
+            "MIC BIAS External", "Handset Mic",
+            "MIC BIAS Internal2", "Headset Mic",
+            "AMIC1", "MIC BIAS External",
+            "AMIC2", "MIC BIAS Internal2";
+    };
 };
 
 &i2c_cdc  {
diff --git a/arch/arm/boot/dts/msm8610-gpu.dtsi b/arch/arm/boot/dts/msm8610-gpu.dtsi
index d1b30ee..7e3ee0d 100644
--- a/arch/arm/boot/dts/msm8610-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8610-gpu.dtsi
@@ -25,7 +25,6 @@
 		qcom,initial-pwrlevel = <1>;
 
 		qcom,idle-timeout = <8>; /* <HZ/12> */
-		qcom,nap-allowed = <1>;
 		qcom,strtstp-sleepwake;
 		qcom,clk-map = <0x000005E>; /* KGSL_CLK_CORE |
 			KGSL_CLK_IFACE | KGSL_CLK_MEM | KGSL_CLK_MEM_IFACE |
diff --git a/arch/arm/boot/dts/msm8610-mtp.dts b/arch/arm/boot/dts/msm8610-mtp.dts
index b52bfc9..9406a09 100644
--- a/arch/arm/boot/dts/msm8610-mtp.dts
+++ b/arch/arm/boot/dts/msm8610-mtp.dts
@@ -132,6 +132,16 @@
 			debounce-interval = <15>;
 		};
 	};
+
+    sound {
+        qcom,audio-routing =
+            "RX_BIAS", "MCLK",
+            "INT_LDO_H", "MCLK",
+            "MIC BIAS External", "Handset Mic",
+            "MIC BIAS Internal2", "Headset Mic",
+            "AMIC1", "MIC BIAS External",
+            "AMIC2", "MIC BIAS Internal2";
+    };
 };
 
 &i2c_cdc  {
diff --git a/arch/arm/boot/dts/msm8610-qrd.dts b/arch/arm/boot/dts/msm8610-qrd.dts
new file mode 100644
index 0000000..deeb051
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-qrd.dts
@@ -0,0 +1,266 @@
+/* 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.
+ */
+
+/dts-v1/;
+
+/include/ "msm8610.dtsi"
+
+/ {
+	model = "Qualcomm MSM 8610 QRD";
+	compatible = "qcom,msm8610-qrd", "qcom,msm8610", "qcom,qrd";
+	qcom,msm-id = <147 11 0>, <165 11 0>, <161 11 0>, <162 11 0>,
+				  <163 11 0>, <164 11 0>, <166 11 0>;
+};
+
+&soc {
+	i2c@f9923000{
+		focaltech@38{
+			compatible = "focaltech,5x06";
+			reg = <0x38>;
+			interrupt-parent = <&msmgpio>;
+			interrupts = <1 0x2>;
+			vdd-supply = <&pm8110_l19>;
+			vcc_i2c-supply = <&pm8110_l14>;
+			focaltech,family-id = <0x06>;
+			focaltech,reset-gpio = <&msmgpio 0 0x00>;
+			focaltech,irq-gpio = <&msmgpio 1 0x00>;
+			focaltech,display-coords = <0 0 480 800>;
+			focaltech,panel-coords = <0 0 480 800>;
+			focaltech,button-map= <139 102 158>;
+			focaltech,no-force-update;
+			focaltech,i2c-pull-up;
+		};
+	};
+
+	gen-vkeys {
+		compatible = "qcom,gen-vkeys";
+		label = "ft5x06_ts";
+		qcom,disp-maxx = <480>;
+		qcom,disp-maxy = <800>;
+		qcom,panel-maxx = <481>;
+		qcom,panel-maxy = <940>;
+		qcom,key-codes = <139 0 102 158 0 0 0>;
+		qcom,y-offset = <0>;
+	};
+	serial@f991e000 {
+		status = "ok";
+	};
+
+	gpio_keys {
+                compatible = "gpio-keys";
+                input-name = "gpio-keys";
+
+                camera_snapshot {
+                        label = "camera_snapshot";
+                        gpios = <&msmgpio 73 0x1>;
+                        linux,input-type = <1>;
+                        linux,code = <0x2fe>;
+                        gpio-key,wakeup;
+                        debounce-interval = <15>;
+                };
+
+                camera_focus {
+                        label = "camera_focus";
+                        gpios = <&msmgpio 74 0x1>;
+                        linux,input-type = <1>;
+                        linux,code = <0x210>;
+                        gpio-key,wakeup;
+                        debounce-interval = <15>;
+                };
+
+                vol_up {
+                        label = "volume_up";
+                        gpios = <&msmgpio 72 0x1>;
+                        linux,input-type = <1>;
+                        linux,code = <115>;
+                        gpio-key,wakeup;
+                        debounce-interval = <15>;
+		};
+	};
+
+	i2c@f9927000  {
+                        msm8x10_wcd_codec@0d{
+                        compatible = "qcom,msm8x10-wcd-i2c";
+                        reg = <0x0d>;
+                        cdc-vdda-cp-supply = <&pm8110_s4>;
+                        qcom,cdc-vdda-cp-voltage = <2150000 2150000>;
+                        qcom,cdc-vdda-cp-current = <650000>;
+
+                        cdc-vdda-h-supply = <&pm8110_l6>;
+                        qcom,cdc-vdda-h-voltage = <1800000 1800000>;
+                        qcom,cdc-vdda-h-current = <250000>;
+
+                        cdc-vdd-px-supply = <&pm8110_l6>;
+                        qcom,cdc-vdd-px-voltage = <1800000 1800000>;
+                        qcom,cdc-vdd-px-current = <10000>;
+
+                        cdc-vdd-1p2v-supply = <&pm8110_l4>;
+                        qcom,cdc-vdd-1p2v-voltage = <1200000 1200000>;
+                        qcom,cdc-vdd-1p2v-current = <5000>;
+
+                        cdc-vdd-mic-bias-supply = <&pm8110_l20>;
+                        qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>;
+                        qcom,cdc-vdd-mic-bias-current = <25000>;
+
+                        qcom,cdc-micbias-cfilt-sel = <0x0>;
+                        qcom,cdc-micbias-cfilt-mv = <1800000>;
+                        qcom,cdc-mclk-clk-rate = <12288000>;
+                };
+
+                msm8x10_wcd_codec@77{
+                        compatible = "qcom,msm8x10-wcd-i2c";
+                        reg = <0x77>;
+                };
+
+                msm8x10_wcd_codec@66{
+                        compatible = "qcom,msm8x10-wcd-i2c";
+                        reg = <0x66>;
+                };
+
+                msm8x10_wcd_codec@55{
+                        compatible = "qcom,msm8x10-wcd-i2c";
+                        reg = <0x55>;
+                };
+	};
+
+    sound {
+        qcom,audio-routing =
+            "RX_BIAS", "MCLK",
+            "INT_LDO_H", "MCLK",
+            "MIC BIAS Internal1", "Handset Mic",
+            "MIC BIAS Internal2", "Headset Mic",
+            "AMIC1", "MIC BIAS Internal1",
+            "AMIC2", "MIC BIAS Internal2";
+    };
+};
+
+&spmi_bus {
+	qcom,pm8110@0 {
+		qcom,leds@a100 {
+			status = "okay";
+			qcom,led_mpp_2 {
+				label = "mpp";
+				linux,name = "wled-homerow";
+				linux-default-trigger = "hr-trigger";
+				qcom,default-state = "off";
+				qcom,max-current = <40>;
+				qcom,id = <6>;
+				qcom,source-sel = <1>;
+				qcom,mode-ctrl = <0x61>;
+			};
+		};
+
+		qcom,leds@a200 {
+			status = "okay";
+			qcom,led_mpp_3 {
+				label = "mpp";
+				linux,name = "wled-backlight";
+				linux,default-trigger = "bkl-trigger";
+				qcom,default-state = "on";
+				qcom,max-current = <40>;
+				qcom,id = <6>;
+				qcom,source-sel = <1>;
+				qcom,mode-ctrl = <0x10>;
+			};
+		};
+	};
+};
+
+&spmi_bus {
+	qcom,pm8110@1 {
+		qcom,vibrator@c000 {
+			status = "okay";
+			qcom,vib-timeout-ms = <15000>;
+			qcom,vib-vtg-level-mV = <3100>;
+		};
+	};
+};
+
+&sdhc_1 {
+	vdd-supply = <&pm8110_l17>;
+	qcom,vdd-always-on;
+	qcom,vdd-lpm-sup;
+	qcom,vdd-voltage-level = <2900000 2900000>;
+	qcom,vdd-current-level = <200 400000>;
+
+	vdd-io-supply = <&pm8110_l6>;
+	qcom,vdd-io-always-on;
+	qcom,vdd-io-voltage-level = <1800000 1800000>;
+	qcom,vdd-io-current-level = <200 60000>;
+
+	qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+	qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+	qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+	qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+	qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+	qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
+	qcom,nonremovable;
+
+	status = "ok";
+};
+
+&sdhc_2 {
+	vdd-supply = <&pm8110_l18>;
+	qcom,vdd-voltage-level = <2950000 2950000>;
+	qcom,vdd-current-level = <15000 400000>;
+
+	vdd-io-supply = <&pm8110_l21>;
+	qcom,vdd-io-always-on;
+	qcom,vdd-io-lpm-sup;
+	qcom,vdd-io-voltage-level = <1800000 2950000>;
+	qcom,vdd-io-current-level = <200 50000>;
+
+	qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+	qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+	qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+	qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+	qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+
+	#address-cells = <0>;
+	interrupt-parent = <&sdhc_2>;
+	interrupts = <0 1 2>;
+	#interrupt-cells = <1>;
+	interrupt-map-mask = <0xffffffff>;
+	interrupt-map = <0 &intc 0 125 0
+			1 &intc 0 221 0
+			2 &msmgpio 42 0x3>;
+	interrupt-names = "hc_irq", "pwr_irq", "status_irq";
+	cd-gpios = <&msmgpio 42 0x1>;
+
+	status = "ok";
+};
+
+&pm8110_chg {
+	status = "ok";
+
+	qcom,chgr@1000 {
+		status = "ok";
+	};
+
+	qcom,buck@1100 {
+		status = "ok";
+	};
+
+	qcom,bat-if@1200 {
+		status = "ok";
+	};
+
+	qcom,usb-chgpth@1300 {
+		status = "ok";
+	};
+
+	qcom,chg-misc@1600 {
+		status = "ok";
+	};
+};
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index 2c17780..09520c5 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -233,8 +233,27 @@
 			regulator-max-microvolt = <1800000>;
 			qcom,init-voltage = <1800000>;
 			status = "okay";
+		};
+
+		pm8110_l10_ao: regulator-l10-ao {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8110_l10_ao";
+			qcom,set = <1>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
 			qcom,consumer-supplies = "vdd_sr2_pll", "";
 		};
+
+		pm8110_l10_so: regulator-l10-so {
+			compatible = "qcom,rpm-regulator-smd";
+			regulator-name = "8110_l10_so";
+			qcom,set = <2>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			qcom,init-enable = <0>;
+		};
 	};
 
 	rpm-regulator-ldoa12 {
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 5f71b0d..f5a19fe 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -719,6 +719,7 @@
 		qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
 		qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>;
 		qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>;
+		qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>;
 
 		/* GPIO output to mss */
 		qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
@@ -1004,6 +1005,17 @@
 		qcom,hw-settle-time = <2>;
 		qcom,fast-avg-setup = <0>;
 	};
+
+	chan@13 {
+		label = "pa_therm0";
+		reg = <0x13>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <0>;
+		qcom,calibration-type = "ratiometric";
+		qcom,scale-function = <2>;
+		qcom,hw-settle-time = <2>;
+		qcom,fast-avg-setup = <0>;
+	};
 };
 
 &pm8110_adc_tm {
@@ -1043,4 +1055,17 @@
 		qcom,fast-avg-setup = <3>;
 		qcom,btm-channel-number = <0x70>;
 	};
+
+	chan@13 {
+		label = "pa_therm0";
+		reg = <0x13>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <0>;
+		qcom,calibration-type = "ratiometric";
+		qcom,scale-function = <2>;
+		qcom,hw-settle-time = <2>;
+		qcom,fast-avg-setup = <0>;
+		qcom,btm-channel-number = <0x78>;
+		qcom,thermal-node;
+	};
 };
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
index e0b572e..cf968d2 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
@@ -35,6 +35,7 @@
 		qcom,csiphy-sd-index = <0>;
 		qcom,csid-sd-index = <0>;
 		qcom,mount-angle = <0>;
+		qcom,actuator-src = <&actuator0>;
 		qcom,sensor-name = "s5k3l1yx";
 		qcom,vdd-cx-supply = <&pm8841_s2>;
 		qcom,vdd-cx-name = "qcom,vdd-cx";
@@ -50,12 +51,15 @@
 		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
 		qcom,gpio-no-mux = <0>;
 		gpios = <&msmgpio 15 0>,
-			<&msmgpio 90 0>;
+			<&msmgpio 90 0>,
+			<&msmgpio 89 0>;
 		qcom,gpio-reset = <1>;
-		qcom,gpio-req-tbl-num = <0 1>;
-		qcom,gpio-req-tbl-flags = <1 0>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
 		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
-					  "CAM_RESET1";
+					  "CAM_RESET1",
+					  "CAM_STANDBY";
 		qcom,gpio-set-tbl-num = <1 1>;
 		qcom,gpio-set-tbl-flags = <0 2>;
 		qcom,gpio-set-tbl-delay = <1000 30000>;
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 3e65b8a..2a60df4 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -599,6 +599,13 @@
 	};
 
 	gpio@e300 { /* GPIO 36 */
+		qcom,mode = <1>;  /* QPNP_PIN_MODE_DIG_OUT */
+		qcom,output-type = <0>; /* QPNP_PIN_OUT_BUF_CMOS */
+		qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+		qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+		qcom,out-strength = <3>; /* QPNP_PIN_OUT_STRENGTH_HIGH */
+		qcom,src-sel = <3>; /* QPNP_PIN_SEL_FUNC_2 */
+		qcom,master-en = <1>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8974-gpu.dtsi b/arch/arm/boot/dts/msm8974-gpu.dtsi
index 5172a5a..06b9c18 100644
--- a/arch/arm/boot/dts/msm8974-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpu.dtsi
@@ -26,7 +26,6 @@
 		qcom,step-pwrlevel = <2>;
 
 		qcom,idle-timeout = <8>; //<HZ/12>
-		qcom,nap-allowed = <1>;
 		qcom,strtstp-sleepwake;
 		qcom,clk-map = <0x0000006>; //KGSL_CLK_CORE | KGSL_CLK_IFACE
 
diff --git a/arch/arm/boot/dts/msm8974-v1-iommu.dtsi b/arch/arm/boot/dts/msm8974-v1-iommu.dtsi
index c6693e1..56369dc 100644
--- a/arch/arm/boot/dts/msm8974-v1-iommu.dtsi
+++ b/arch/arm/boot/dts/msm8974-v1-iommu.dtsi
@@ -14,20 +14,27 @@
 
 &jpeg_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_jpeg>;
 };
 
 &mdp_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_mdss>;
 };
 
 &venus_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_venus>;
 };
 
 &kgsl_iommu {
 	status = "ok";
+	qcom,needs-alt-core-clk;
+	vdd-supply = <&gdsc_oxili_cx>;
+	qcom,alt-vdd-supply = <&gdsc_oxili_gx>;
 };
 
 &vfe_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_vfe>;
 };
diff --git a/arch/arm/boot/dts/msm8974-v2-iommu.dtsi b/arch/arm/boot/dts/msm8974-v2-iommu.dtsi
index 64eff43..03f7e80 100644
--- a/arch/arm/boot/dts/msm8974-v2-iommu.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2-iommu.dtsi
@@ -14,6 +14,7 @@
 
 &venus_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_venus>;
 	qcom,iommu-enable-halt;
 
 	qcom,iommu-bfb-regs =  <0x204c
@@ -96,6 +97,7 @@
 
 &jpeg_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_jpeg>;
 	qcom,iommu-enable-halt;
 
 	qcom,iommu-bfb-regs =  <0x204c
@@ -133,6 +135,7 @@
 
 &mdp_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_mdss>;
 	qcom,iommu-enable-halt;
 
 	qcom,iommu-bfb-regs =  <0x204c
@@ -176,7 +179,10 @@
 
 &kgsl_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_oxili_cx>;
+	qcom,alt-vdd-supply = <&gdsc_oxili_gx>;
 	qcom,iommu-enable-halt;
+	qcom,needs-alt-core-clk;
 
 	qcom,iommu-bfb-regs =  <0x204c
 				0x2050
@@ -207,6 +213,7 @@
 
 &vfe_iommu {
 	status = "ok";
+	vdd-supply = <&gdsc_vfe>;
 	qcom,iommu-enable-halt;
 
 	qcom,iommu-bfb-regs =  <0x204c
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index a585586..5ae8808 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -64,7 +64,7 @@
 
 		adsp_mem: adsp_region {
 			linux,contiguous-region;
-			reg = <0 0x2000000>;
+			reg = <0 0x2F00000>;
 			label = "adsp_mem";
 		};
 
@@ -1177,6 +1177,7 @@
 		qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
 		qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>;
 		qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>;
+		qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>;
 
 		/* GPIO output to mss */
 		qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 947364c..f654545 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -165,6 +165,7 @@
 		qcom,hsusb-otg-lpm-on-dev-suspend;
 		qcom,hsusb-otg-clk-always-on-workaround;
 		qcom,hsusb-otg-delay-lpm-hndshk-on-disconnect;
+		qcom,hsusb-otg-delay-lpm;
 
 		qcom,msm-bus,name = "usb2";
 		qcom,msm-bus,num-cases = <2>;
@@ -771,6 +772,7 @@
 		qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
 		qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>;
 		qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>;
+		qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>;
 
 		/* GPIO output to mss */
 		qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/msmsamarium-rumi.dts
similarity index 70%
copy from arch/arm/boot/dts/msm8226-mtp.dts
copy to arch/arm/boot/dts/msmsamarium-rumi.dts
index 2881274..9a679a4 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/msmsamarium-rumi.dts
@@ -11,14 +11,15 @@
  */
 
 /dts-v1/;
-/include/ "msm8226.dtsi"
-/include/ "msm8226-mtp.dtsi"
+
+/include/ "msmsamarium.dtsi"
 
 / {
-	model = "Qualcomm MSM 8226 MTP";
-	compatible = "qcom,msm8226-mtp", "qcom,msm8226", "qcom,mtp";
-	qcom,msm-id = <145 8 0>,
-		      <158 8 0>,
-		      <159 8 0>,
-		      <198 8 0>;
+	model = "Qualcomm MSM SAMARIUM RUMI";
+	compatible = "qcom,msmsamarium-rumi", "qcom,msmsamarium", "qcom,rumi";
+	qcom,msm-id = <195 0 0>;
+};
+
+&uartblsp0dm2{
+	status = "ok";
 };
diff --git a/arch/arm/configs/apq8084_defconfig b/arch/arm/configs/apq8084_defconfig
index 549bc73..a004835 100644
--- a/arch/arm/configs/apq8084_defconfig
+++ b/arch/arm/configs/apq8084_defconfig
@@ -353,8 +353,9 @@
 CONFIG_QPNP_PWM=y
 CONFIG_QPNP_POWER_ON=y
 CONFIG_QPNP_CLKDIV=y
-CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_V1=y
 CONFIG_IOMMU_PGTABLES_L2=y
+CONFIG_IOMMU_NON_SECURE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
diff --git a/arch/arm/configs/mpq8092_defconfig b/arch/arm/configs/mpq8092_defconfig
index c06161d..5d05596 100644
--- a/arch/arm/configs/mpq8092_defconfig
+++ b/arch/arm/configs/mpq8092_defconfig
@@ -50,6 +50,7 @@
 CONFIG_MSM_SYSMON_COMM=y
 CONFIG_MSM_DIRECT_SCLK_ACCESS=y
 CONFIG_MSM_WATCHDOG_V2=y
+CONFIG_MSM_MEMORY_DUMP=y
 CONFIG_MSM_DLOAD_MODE=y
 CONFIG_MSM_RUN_QUEUE_STATS=y
 CONFIG_MSM_SPM_V2=y
@@ -331,7 +332,7 @@
 CONFIG_QPNP_PWM=y
 CONFIG_QPNP_POWER_ON=y
 CONFIG_QPNP_CLKDIV=y
-CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_V1=y
 CONFIG_IOMMU_PGTABLES_L2=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
diff --git a/arch/arm/configs/msm8226-perf_defconfig b/arch/arm/configs/msm8226-perf_defconfig
index 98eb4d4..d58f7fb 100644
--- a/arch/arm/configs/msm8226-perf_defconfig
+++ b/arch/arm/configs/msm8226-perf_defconfig
@@ -79,6 +79,9 @@
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_USE_OF=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
@@ -209,12 +212,15 @@
 CONFIG_DUMMY=y
 # CONFIG_MSM_RMNET is not set
 CONFIG_MSM_RMNET_BAM=y
+CONFIG_USB_USBNET=y
 CONFIG_WCNSS_CORE=y
 CONFIG_WCNSS_CORE_PRONTO=y
 CONFIG_WCNSS_MEM_PRE_ALLOC=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
 CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
@@ -251,6 +257,7 @@
 CONFIG_THERMAL_MONITOR=y
 CONFIG_THERMAL_QPNP_ADC_TM=y
 CONFIG_WCD9306_CODEC=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_STUB=y
 CONFIG_REGULATOR_QPNP=y
 CONFIG_MEDIA_SUPPORT=y
@@ -272,6 +279,7 @@
 CONFIG_MSM_VIDC_V4L2=y
 CONFIG_MSM_WFD=y
 CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_USB_VIDEO_CLASS=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
@@ -289,11 +297,35 @@
 # CONFIG_BACKLIGHT_GENERIC is not set
 CONFIG_SOUND=y
 CONFIG_SND=y
+CONFIG_SND_USB_AUDIO=y
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_MSM8226=y
 CONFIG_UHID=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_MAGICMOUSE=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_MSM=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CSVT=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_GADGET_DEBUG_FS=y
@@ -332,7 +364,7 @@
 CONFIG_QPNP_PWM=y
 CONFIG_QPNP_POWER_ON=y
 CONFIG_QPNP_VIBRATOR=y
-CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_V1=y
 CONFIG_CORESIGHT=y
 CONFIG_CORESIGHT_TMC=y
 CONFIG_CORESIGHT_TPIU=y
@@ -382,3 +414,11 @@
 CONFIG_CRYPTO_DEV_QCE=y
 CONFIG_CRYPTO_DEV_QCEDEV=m
 CONFIG_CRC_CCITT=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPPOE=y
+CONFIG_N_HDLC=y
+CONFIG_UNIX98_PTYS=y
diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
index c18f8cb..07378b2 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -79,6 +79,9 @@
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_USE_OF=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
@@ -210,12 +213,15 @@
 CONFIG_TUN=y
 # CONFIG_MSM_RMNET is not set
 CONFIG_MSM_RMNET_BAM=y
+CONFIG_USB_USBNET=y
 CONFIG_WCNSS_CORE=y
 CONFIG_WCNSS_CORE_PRONTO=y
 CONFIG_WCNSS_MEM_PRE_ALLOC=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
 CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
@@ -254,6 +260,7 @@
 CONFIG_THERMAL_QPNP=y
 CONFIG_THERMAL_QPNP_ADC_TM=y
 CONFIG_WCD9306_CODEC=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_STUB=y
 CONFIG_REGULATOR_QPNP=y
 CONFIG_MEDIA_SUPPORT=y
@@ -297,6 +304,7 @@
 # CONFIG_MEDIA_TUNER_TDA18218 is not set
 # CONFIG_MEDIA_TUNER_TDA18212 is not set
 CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_USB_VIDEO_CLASS=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
@@ -314,11 +322,35 @@
 # CONFIG_BACKLIGHT_GENERIC is not set
 CONFIG_SOUND=y
 CONFIG_SND=y
+CONFIG_SND_USB_AUDIO=y
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_MSM8226=y
 CONFIG_UHID=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_MAGICMOUSE=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_MSM=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CSVT=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_GADGET_DEBUG_FS=y
@@ -357,7 +389,7 @@
 CONFIG_QPNP_PWM=y
 CONFIG_QPNP_POWER_ON=y
 CONFIG_QPNP_VIBRATOR=y
-CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_V1=y
 CONFIG_CORESIGHT=y
 CONFIG_CORESIGHT_TMC=y
 CONFIG_CORESIGHT_TPIU=y
@@ -407,3 +439,11 @@
 CONFIG_CRYPTO_DEV_QCE=y
 CONFIG_CRYPTO_DEV_QCEDEV=m
 CONFIG_CRC_CCITT=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPPOE=y
+CONFIG_N_HDLC=y
+CONFIG_UNIX98_PTYS=y
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index 3c56bd2..3bbff5c 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -82,6 +82,9 @@
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_USE_OF=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
@@ -255,6 +258,7 @@
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8974=y
 CONFIG_THERMAL_MONITOR=y
+CONFIG_THERMAL_QPNP=y
 CONFIG_THERMAL_QPNP_ADC_TM=y
 CONFIG_WCD9306_CODEC=y
 CONFIG_REGULATOR_STUB=y
@@ -272,6 +276,7 @@
 CONFIG_MSM_CSIPHY=y
 CONFIG_MSM_CSID=y
 CONFIG_MSM_ISPIF=y
+# CONFIG_MSM_ISPIF_V1 is not set
 CONFIG_MSMB_CAMERA=y
 CONFIG_OV9724=y
 CONFIG_MSMB_JPEG=y
@@ -342,7 +347,7 @@
 CONFIG_QPNP_PWM=y
 CONFIG_QPNP_POWER_ON=y
 CONFIG_QPNP_VIBRATOR=y
-CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_V0=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index eab374a..d11773f 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -80,6 +80,9 @@
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_USE_OF=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
@@ -253,6 +256,7 @@
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8974=y
 CONFIG_THERMAL_MONITOR=y
+CONFIG_THERMAL_QPNP=y
 CONFIG_THERMAL_QPNP_ADC_TM=y
 CONFIG_WCD9306_CODEC=y
 CONFIG_REGULATOR_STUB=y
@@ -264,12 +268,14 @@
 # CONFIG_MSM_CAMERA is not set
 CONFIG_OV8825=y
 CONFIG_MSM_CAMERA_SENSOR=y
-CONFIG_MSM_CPP=y
+# CONFIG_MSM_CPP is not set
 CONFIG_MSM_CCI=y
-CONFIG_MSM_CSI30_HEADER=y
+CONFIG_MSM_CSI22_HEADER=y
+CONFIG_MSM_CSI20_HEADER=y
 CONFIG_MSM_CSIPHY=y
 CONFIG_MSM_CSID=y
 CONFIG_MSM_ISPIF=y
+# CONFIG_MSM_ISPIF_V1 is not set
 CONFIG_MSMB_CAMERA=y
 CONFIG_OV9724=y
 CONFIG_MSMB_JPEG=y
@@ -361,7 +367,7 @@
 CONFIG_QPNP_PWM=y
 CONFIG_QPNP_POWER_ON=y
 CONFIG_QPNP_VIBRATOR=y
-CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_V0=y
 CONFIG_CORESIGHT=y
 CONFIG_CORESIGHT_TMC=y
 CONFIG_CORESIGHT_TPIU=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 80520e6..aefc7c9 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -505,7 +505,7 @@
 CONFIG_SPS=y
 CONFIG_SPS_SUPPORT_BAMDMA=y
 CONFIG_MSM_AVTIMER=y
-CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_V0=y
 CONFIG_IOMMU_PGTABLES_L2=y
 CONFIG_MOBICORE_SUPPORT=m
 CONFIG_MOBICORE_API=m
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 77615e7..fbad97a 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -505,7 +505,7 @@
 CONFIG_MSM_SSBI=y
 CONFIG_SPS=y
 CONFIG_SPS_SUPPORT_BAMDMA=y
-CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_V0=y
 CONFIG_IOMMU_PGTABLES_L2=y
 CONFIG_MOBICORE_SUPPORT=m
 CONFIG_MOBICORE_API=m
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 64a67f5..6c12216 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -373,6 +373,7 @@
 CONFIG_HID_APPLE=y
 CONFIG_HID_MAGICMOUSE=y
 CONFIG_HID_MICROSOFT=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_SUSPEND=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
@@ -440,7 +441,7 @@
 CONFIG_QPNP_CLKDIV=y
 CONFIG_QPNP_REVID=y
 CONFIG_QPNP_COINCELL=y
-CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_V1=y
 CONFIG_IOMMU_PGTABLES_L2=y
 CONFIG_MOBICORE_SUPPORT=m
 CONFIG_MOBICORE_API=m
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index b0c1284..967f62d 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -379,6 +379,7 @@
 CONFIG_HID_APPLE=y
 CONFIG_HID_MAGICMOUSE=y
 CONFIG_HID_MICROSOFT=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_SUSPEND=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
@@ -446,7 +447,7 @@
 CONFIG_QPNP_CLKDIV=y
 CONFIG_QPNP_REVID=y
 CONFIG_QPNP_COINCELL=y
-CONFIG_MSM_IOMMU=y
+CONFIG_MSM_IOMMU_V1=y
 CONFIG_MSM_IOMMU_PMON=y
 CONFIG_IOMMU_PGTABLES_L2=y
 CONFIG_MOBICORE_SUPPORT=m
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index c440f47..6e94b32 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -742,6 +742,7 @@
 static struct of_device_id armpmu_of_device_ids[] = {
 	{.compatible = "arm,cortex-a9-pmu"},
 	{.compatible = "arm,cortex-a8-pmu"},
+	{.compatible = "arm,cortex-a7-pmu"},
 	{.compatible = "arm,cortex-a5-pmu"},
 	{.compatible = "arm,arm1136-pmu"},
 	{.compatible = "arm,arm1176-pmu"},
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 86eb7d1..7824502 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -458,9 +458,6 @@
 	select MSM_BUS_SCALING
 	select CPU_FREQ_MSM
 	select CPU_FREQ
-	select CPU_FREQ_GOV_USERSPACE
-	select CPU_FREQ_GOV_ONDEMAND
-	select CPU_FREQ_GOV_POWERSAVE
 	select MSM_PIL
 	select MSM_RUN_QUEUE_STATS
 	select ARM_HAS_SG_CHAIN
@@ -500,8 +497,6 @@
 	select MSM_BUS_SCALING
 	select CPU_FREQ_MSM
 	select CPU_FREQ
-	select CPU_FREQ_GOV_USERSPACE
-	select CPU_FREQ_GOV_ONDEMAND
 	select MSM_PIL
 	select MSM_RUN_QUEUE_STATS
 	select ARM_HAS_SG_CHAIN
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index e1fd642..3469c66 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -84,12 +84,17 @@
 # MSM8226
    zreladdr-$(CONFIG_ARCH_MSM8226)	:= 0x00008000
         dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-sim.dtb
-        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-cdp.dtb
-        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-mtp.dtb
-        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-qrd.dtb
+        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-v1-cdp.dtb
+        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-v1-mtp.dtb
+        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-v1-qrd.dtb
+        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-v2-cdp.dtb
+        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-v2-mtp.dtb
+        dtb-$(CONFIG_ARCH_MSM8226)	+= msm8226-v2-qrd.dtb
         dtb-$(CONFIG_ARCH_MSM8226)	+= msm8926-cdp.dtb
         dtb-$(CONFIG_ARCH_MSM8226)	+= msm8926-mtp.dtb
         dtb-$(CONFIG_ARCH_MSM8226)	+= msm8926-qrd.dtb
+        dtb-$(CONFIG_ARCH_MSM8226)	+= apq8026-xpm.dtb
+        dtb-$(CONFIG_ARCH_MSM8226)	+= apq8026-mtp.dtb
 
 # FSM9XXX
    zreladdr-$(CONFIG_ARCH_FSM9XXX)	:= 0x10008000
@@ -112,3 +117,4 @@
 # MSMSAMARIUM
    zreladdr-$(CONFIG_ARCH_MSMSAMARIUM)	:= 0x00008000
 	dtb-$(CONFIG_ARCH_MSMSAMARIUM)	+= msmsamarium-sim.dtb
+	dtb-$(CONFIG_ARCH_MSMSAMARIUM)	+= msmsamarium-rumi.dtb
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index 6b15883..bb0a6cc 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -255,7 +255,6 @@
 	.num_levels = 5,
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/10,
-	.nap_allowed = true,
 	.strtstp_sleepwake = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
diff --git a/arch/arm/mach-msm/board-8084-gpiomux.c b/arch/arm/mach-msm/board-8084-gpiomux.c
index 8d5bb49..27f2e0d 100644
--- a/arch/arm/mach-msm/board-8084-gpiomux.c
+++ b/arch/arm/mach-msm/board-8084-gpiomux.c
@@ -17,6 +17,27 @@
 #include <mach/board.h>
 #include <mach/gpiomux.h>
 
+static struct gpiomux_setting gpio_i2c_config = {
+	.func = GPIOMUX_FUNC_3,
+	.drv  = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct msm_gpiomux_config msm_blsp_configs[] __initdata = {
+	{
+		.gpio      = 10,		/* BLSP1 QUP3 I2C_SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_i2c_config,
+		},
+	},
+	{
+		.gpio      = 11,		/* BLSP1 QUP3 I2C_SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_i2c_config,
+		},
+	},
+};
+
 void __init apq8084_init_gpiomux(void)
 {
 	int rc;
@@ -26,4 +47,6 @@
 		pr_err("%s failed %d\n", __func__, rc);
 		return;
 	}
+
+	msm_gpiomux_install(msm_blsp_configs, ARRAY_SIZE(msm_blsp_configs));
 }
diff --git a/arch/arm/mach-msm/board-8226-gpiomux.c b/arch/arm/mach-msm/board-8226-gpiomux.c
index 6491452..378edc8 100644
--- a/arch/arm/mach-msm/board-8226-gpiomux.c
+++ b/arch/arm/mach-msm/board-8226-gpiomux.c
@@ -485,7 +485,7 @@
 	msm_gpiomux_install(msm_auxpcm_configs,
 			ARRAY_SIZE(msm_auxpcm_configs));
 
-	if (of_board_is_cdp() || of_board_is_mtp())
+	if (of_board_is_cdp() || of_board_is_mtp() || of_board_is_xpm())
 		msm_gpiomux_install(usb_otg_sw_configs,
 					ARRAY_SIZE(usb_otg_sw_configs));
 }
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index 0205919..4645d34 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -136,6 +136,7 @@
 static const char *msm8226_dt_match[] __initconst = {
 	"qcom,msm8226",
 	"qcom,msm8926",
+	"qcom,apq8026",
 	NULL
 };
 
diff --git a/arch/arm/mach-msm/board-8930-gpu.c b/arch/arm/mach-msm/board-8930-gpu.c
index 0c6a271..12a6ab1 100644
--- a/arch/arm/mach-msm/board-8930-gpu.c
+++ b/arch/arm/mach-msm/board-8930-gpu.c
@@ -145,7 +145,6 @@
 	.num_levels = 4,
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/12,
-	.nap_allowed = true,
 	.strtstp_sleepwake = false,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
diff --git a/arch/arm/mach-msm/board-krypton.c b/arch/arm/mach-msm/board-krypton.c
index 7b7b7cd..ff7c8e0 100644
--- a/arch/arm/mach-msm/board-krypton.c
+++ b/arch/arm/mach-msm/board-krypton.c
@@ -41,6 +41,10 @@
 	.size = ARRAY_SIZE(msm_clocks_dummy),
 };
 
+static struct of_dev_auxdata msmkrypton_auxdata_lookup[] __initdata = {
+	{}
+};
+
 /*
  * Used to satisfy dependencies for devices that need to be
  * run early or in a particular order. Most likely your device doesn't fall
@@ -64,7 +68,7 @@
 		pr_err("%s: socinfo_init() failed\n", __func__);
 
 	msmkrypton_init_gpiomux();
-	board_dt_populate(adata);
+	board_dt_populate(msmkrypton_auxdata_lookup);
 	msmkrypton_add_drivers();
 }
 
diff --git a/arch/arm/mach-msm/clock-8084.c b/arch/arm/mach-msm/clock-8084.c
index b7f9fd7..bec9f1b4 100644
--- a/arch/arm/mach-msm/clock-8084.c
+++ b/arch/arm/mach-msm/clock-8084.c
@@ -49,6 +49,8 @@
 	CLK_DUMMY("sleep_a_clk",   NULL, "f9200000.qcom,ssusb", OFF),
 	CLK_DUMMY("utmi_clk",   NULL, "f9200000.qcom,ssusb", OFF),
 	CLK_DUMMY("ref_clk",    NULL, "f9200000.qcom,ssusb", OFF),
+	CLK_DUMMY("dfab_clk",	DFAB_CLK,	"msm_sps", OFF),
+	CLK_DUMMY("dma_bam_pclk",	DMA_BAM_P_CLK,	"msm_sps", OFF),
 	CLK_DUMMY("",	ufs_axi_clk_src.c,	"", OFF),
 	CLK_DUMMY("",	usb30_master_clk_src.c,	"", OFF),
 	CLK_DUMMY("",	usb30_sec_master_clk_src.c,	"", OFF),
@@ -73,12 +75,13 @@
 	CLK_DUMMY("",	usb_hsic_system_clk_src.c,	"", OFF),
 	CLK_DUMMY("",	gcc_bam_dma_ahb_clk.c,	"", OFF),
 	CLK_DUMMY("",	gcc_bam_dma_inactivity_timers_clk.c,	"", OFF),
-	CLK_DUMMY("",	gcc_blsp1_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("iface_clk",	gcc_blsp1_ahb_clk.c,	"f9925000.i2c", OFF),
 	CLK_DUMMY("",	gcc_blsp1_qup1_i2c_apps_clk.c,	"", OFF),
 	CLK_DUMMY("",	gcc_blsp1_qup1_spi_apps_clk.c,	"", OFF),
 	CLK_DUMMY("",	gcc_blsp1_qup2_i2c_apps_clk.c,	"", OFF),
 	CLK_DUMMY("",	gcc_blsp1_qup2_spi_apps_clk.c,	"", OFF),
-	CLK_DUMMY("",	gcc_blsp1_qup3_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("core_clk",	gcc_blsp1_qup3_i2c_apps_clk.c,	"f9925000.i2c",
+									OFF),
 	CLK_DUMMY("",	gcc_blsp1_qup3_spi_apps_clk.c,	"", OFF),
 	CLK_DUMMY("",	gcc_blsp1_qup4_i2c_apps_clk.c,	"", OFF),
 	CLK_DUMMY("",	gcc_blsp1_qup4_spi_apps_clk.c,	"", OFF),
@@ -345,6 +348,27 @@
 	CLK_DUMMY("",	vpu_maple_clk.c,	"", OFF),
 	CLK_DUMMY("",	vpu_sleep_clk.c,	"", OFF),
 	CLK_DUMMY("",	vpu_vdp_clk.c,	"", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fda64000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fda64000.qcom,iommu", OFF),
+	CLK_DUMMY("alt_core_clk", NULL, "fda64000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fda44000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fda44000.qcom,iommu", OFF),
+	CLK_DUMMY("alt_core_clk", NULL, "fda44000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fd928000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fd928000.qcom,iommu", oFF),
+	CLK_DUMMY("core_clk", NULL, "fdb10000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fdb10000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fdc84000.qcom,iommu", OFF),
+	CLK_DUMMY("alt_core_clk", NULL, "fdc84000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fdc84000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "f9bc4000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "f9bc4000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fdee4000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fdee4000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fe054000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fe054000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk", NULL, "fe064000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk", NULL, "fe064000.qcom,iommu", OFF),
 };
 
 struct clock_init_data msm8084_clock_init_data __initdata = {
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 9a1611e..1e91d5b 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5437,9 +5437,9 @@
 	CLK_LOOKUP("npl_clk",		npl_tv_clk.c,		""),
 
 	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	"kgsl-3d0.0"),
-	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	"footswitch-8x60.2"),
+	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	"footswitch-8x60.11"),
 	CLK_LOOKUP("bus_clk",
-			    gfx3d_axi_clk.c, "footswitch-8x60.2"),
+			    gfx3d_axi_clk.c, "footswitch-8x60.11"),
 	CLK_LOOKUP("iface_clk",         vcap_p_clk.c,           ""),
 	CLK_LOOKUP("iface_clk",         vcap_p_clk.c,           "msm_vcap.0"),
 	CLK_LOOKUP("iface_clk",         vcap_p_clk.c,	"footswitch-8x60.10"),
@@ -5493,7 +5493,7 @@
 	CLK_LOOKUP("master_iface_clk",	dsi2_m_p_clk.c,		"mipi_dsi.2"),
 	CLK_LOOKUP("slave_iface_clk",	dsi2_s_p_clk.c,		"mipi_dsi.2"),
 	CLK_LOOKUP("iface_clk",		gfx3d_p_clk.c,	"kgsl-3d0.0"),
-	CLK_LOOKUP("iface_clk",		gfx3d_p_clk.c,	"footswitch-8x60.2"),
+	CLK_LOOKUP("iface_clk",		gfx3d_p_clk.c,	"footswitch-8x60.11"),
 	CLK_LOOKUP("master_iface_clk",	hdmi_m_p_clk.c,		"hdmi_msm.1"),
 	CLK_LOOKUP("slave_iface_clk",	hdmi_s_p_clk.c,		"hdmi_msm.1"),
 	CLK_LOOKUP("iface_clk",		ijpeg_p_clk.c,		"msm_gemini.0"),
diff --git a/arch/arm/mach-msm/cpuidle.c b/arch/arm/mach-msm/cpuidle.c
index e87c7b5..7c06268 100644
--- a/arch/arm/mach-msm/cpuidle.c
+++ b/arch/arm/mach-msm/cpuidle.c
@@ -14,7 +14,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/cpuidle.h>
-#include <linux/cpu_pm.h>
 
 #include <mach/cpuidle.h>
 
@@ -75,8 +74,6 @@
 	int i;
 	enum msm_pm_sleep_mode pm_mode;
 
-	cpu_pm_enter();
-
 	pm_mode = msm_pm_idle_enter(dev, drv, index);
 
 	for (i = 0; i < dev->state_count; i++) {
@@ -90,7 +87,6 @@
 		}
 	}
 
-	cpu_pm_exit();
 	local_irq_enable();
 
 	return ret;
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 14fe79d..4daccb1 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -2230,11 +2230,12 @@
 
 static struct fs_driver_data gfx3d_fs_data = {
 	.clks = (struct fs_clk_data[]){
-		{ .name = "core_clk", .reset_rate = 27000000 },
+		{ .name = "core_clk", .reset_rate = 1800000 },
 		{ .name = "iface_clk" },
 		{ .name = "bus_clk" },
 		{ 0 }
 	},
+	.reset_delay_us = 10,
 	.bus_port0 = MSM_BUS_MASTER_GRAPHICS_3D,
 	.bus_port1 = MSM_BUS_MASTER_GRAPHICS_3D_PORT1,
 };
@@ -2323,7 +2324,7 @@
 	FS_8X60(FS_IJPEG,  "vdd",	"msm_gemini.0",	&ijpeg_fs_data),
 	FS_8X60(FS_VFE,    "vdd",	"msm_vfe.0",	&vfe_fs_data),
 	FS_8X60(FS_VPE,    "vdd",	"msm_vpe.0",	&vpe_fs_data),
-	FS_8X60(FS_GFX3D,  "vdd",	"kgsl-3d0.0",	&gfx3d_fs_data),
+	FS_8X60(FS_GFX3D_8064, "vdd",	"kgsl-3d0.0",	&gfx3d_fs_data),
 	FS_8X60(FS_VED,    "vdd",	"msm_vidc.0",	&ved_fs_data),
 	FS_8X60(FS_VCAP,   "vdd",	"msm_vcap.0",	&vcap_fs_data),
 };
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index cb8ffc1..71f58a6 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -3512,7 +3512,6 @@
 	.num_levels = ARRAY_SIZE(grp3d_freq) + 1,
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/12,
-	.nap_allowed = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.bus_scale_table = &grp3d_bus_scale_pdata,
@@ -3579,7 +3578,6 @@
 	.num_levels = ARRAY_SIZE(grp2d_freq) + 1,
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/5,
-	.nap_allowed = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.bus_scale_table = &grp2d0_bus_scale_pdata,
@@ -3646,7 +3644,6 @@
 	.num_levels = ARRAY_SIZE(grp2d_freq) + 1,
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/5,
-	.nap_allowed = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.bus_scale_table = &grp2d1_bus_scale_pdata,
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 907af68..446d6b6 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -942,7 +942,6 @@
 	.set_grp_async = set_grp_xbar_async,
 	.idle_timeout = HZ,
 	.strtstp_sleepwake = true,
-	.nap_allowed = false,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM,
 };
 
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index 397a9d4..cdbf2ea 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -1294,7 +1294,6 @@
 	.num_levels = 3,
 	.set_grp_async = set_grp3d_async,
 	.idle_timeout = HZ/20,
-	.nap_allowed = true,
 	.idle_needed = true,
 	.clk_map = KGSL_CLK_SRC | KGSL_CLK_CORE |
 		KGSL_CLK_IFACE | KGSL_CLK_MEM,
@@ -1337,7 +1336,6 @@
 	/* HW workaround, run Z180 SYNC @ 192 MHZ */
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/10,
-	.nap_allowed = true,
 	.idle_needed = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE,
 };
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index 91a7394..05858a5 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -802,7 +802,6 @@
 	.num_levels = 5,
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/5,
-	.nap_allowed = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.bus_scale_table = &grp3d_bus_scale_pdata,
@@ -849,7 +848,6 @@
 	.num_levels = 2,
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/10,
-	.nap_allowed = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.bus_scale_table = &grp2d0_bus_scale_pdata,
@@ -896,7 +894,6 @@
 	.num_levels = 2,
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/10,
-	.nap_allowed = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.bus_scale_table = &grp2d1_bus_scale_pdata,
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index 581c563..67bbd5e 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -25,7 +25,10 @@
 #include <mach/msm_bus.h>
 #include <mach/scm-io.h>
 #include <mach/clk.h>
+#include <mach/rpm.h>
+
 #include "footswitch.h"
+#include "rpm_resources.h"
 
 #ifdef CONFIG_MSM_SECURE_IO
 #undef readl_relaxed
@@ -239,7 +242,8 @@
 		return rc;
 
 	/* Allow core memory to collapse when its clock is gated. */
-	clk_set_flags(fs->core_clk, CLKFLAG_NORETAIN_MEM);
+	if (fs->desc.id != FS_GFX3D_8064)
+		clk_set_flags(fs->core_clk, CLKFLAG_NORETAIN_MEM);
 
 	/* Halt all bus ports in the power domain. */
 	if (fs->bus_port0) {
@@ -442,6 +446,120 @@
 	return rc;
 }
 
+static void force_bus_clocks(bool enforce)
+{
+	static struct msm_rpm_iv_pair iv;
+	int ret;
+
+	if (enforce) {
+		iv.id = MSM_RPM_STATUS_ID_RPM_CTL;
+		ret = msm_rpm_get_status(&iv, 1);
+		if (ret)
+			pr_err("Failed to read RPM_CTL resource status\n");
+
+		iv.id = MSM_RPM_ID_RPM_CTL;
+		iv.value |= BIT(6);
+	} else {
+		iv.id = MSM_RPM_ID_RPM_CTL;
+		iv.value &= ~BIT(6);
+	}
+
+	ret = msm_rpmrs_set(MSM_RPM_CTX_SET_0, &iv, 1);
+	if (ret)
+		pr_err("Force bus clocks request=%d failed\n", enforce);
+}
+
+static int gfx3d_8064_footswitch_enable(struct regulator_dev *rdev)
+{
+	struct footswitch *fs = rdev_get_drvdata(rdev);
+	struct fs_clk_data *clock;
+	uint32_t regval, rc = 0;
+
+	mutex_lock(&claim_lock);
+	fs->is_claimed = true;
+	mutex_unlock(&claim_lock);
+
+	/* Return early if already enabled. */
+	regval = readl_relaxed(fs->gfs_ctl_reg);
+	if ((regval & (ENABLE_BIT | CLAMP_BIT)) == ENABLE_BIT)
+		return 0;
+
+	/* Un-halt all bus ports in the power domain. */
+	if (fs->bus_port0) {
+		rc = msm_bus_axi_portunhalt(fs->bus_port0);
+		if (rc) {
+			pr_err("%s port 0 unhalt failed.\n", fs->desc.name);
+			goto err;
+		}
+	}
+	if (fs->bus_port1) {
+		rc = msm_bus_axi_portunhalt(fs->bus_port1);
+		if (rc) {
+			pr_err("%s port 1 unhalt failed.\n", fs->desc.name);
+			goto err_port2_halt;
+		}
+	}
+
+	/* Apply AFAB/EBI clock limits. */
+	force_bus_clocks(true);
+
+	/* Enable the power rail at the footswitch. */
+	regval |= ENABLE_BIT;
+	writel_relaxed(regval, fs->gfs_ctl_reg);
+	/* Wait for the rail to fully charge. */
+	mb();
+	udelay(1);
+
+	/* Make sure required clocks are on at the correct rates. */
+	rc = setup_clocks(fs);
+	if (rc)
+		goto err_setup_clocks;
+
+	/*
+	 * (Re-)Assert resets for all clocks in the clock domain, since
+	 * footswitch_enable() is first called before footswitch_disable()
+	 * and resets should be asserted before power is restored.
+	 */
+	for (clock = fs->clk_data; clock->clk; clock++)
+		; /* Do nothing */
+	for (clock--; clock >= fs->clk_data; clock--)
+		clk_reset(clock->clk, CLK_RESET_ASSERT);
+	/* Wait for synchronous resets to propagate. */
+	udelay(fs->reset_delay_us);
+
+	/* Un-clamp the I/O ports. */
+	regval &= ~CLAMP_BIT;
+	writel_relaxed(regval, fs->gfs_ctl_reg);
+
+	/* Deassert resets for all clocks in the power domain. */
+	for (clock = fs->clk_data; clock->clk; clock++)
+		clk_reset(clock->clk, CLK_RESET_DEASSERT);
+
+	/* Prevent core memory from collapsing when its clock is gated. */
+	clk_set_flags(fs->core_clk, CLKFLAG_RETAIN_MEM);
+
+	/* Return clocks to their state before this function. */
+	restore_clocks(fs);
+
+	/* Remove AFAB/EBI clock limits after any transients have settled. */
+	udelay(30);
+	force_bus_clocks(false);
+
+	fs->is_enabled = true;
+	return 0;
+
+err_setup_clocks:
+	regval &= ~ENABLE_BIT;
+	writel_relaxed(regval, fs->gfs_ctl_reg);
+	force_bus_clocks(false);
+	msm_bus_axi_porthalt(fs->bus_port1);
+err_port2_halt:
+	msm_bus_axi_porthalt(fs->bus_port0);
+err:
+	return rc;
+}
+
+
 static struct regulator_ops standard_fs_ops = {
 	.is_enabled = footswitch_is_enabled,
 	.enable = footswitch_enable,
@@ -454,6 +572,12 @@
 	.disable = gfx2d_footswitch_disable,
 };
 
+static struct regulator_ops gfx3d_8064_fs_ops = {
+	.is_enabled = footswitch_is_enabled,
+	.enable = gfx3d_8064_footswitch_enable,
+	.disable = footswitch_disable,
+};
+
 #define FOOTSWITCH(_id, _name, _ops, _gfs_ctl_reg) \
 	[(_id)] = { \
 		.desc = { \
@@ -468,6 +592,8 @@
 static struct footswitch footswitches[] = {
 	FOOTSWITCH(FS_GFX2D0, "fs_gfx2d0", &gfx2d_fs_ops, GFX2D0_GFS_CTL_REG),
 	FOOTSWITCH(FS_GFX2D1, "fs_gfx2d1", &gfx2d_fs_ops, GFX2D1_GFS_CTL_REG),
+	FOOTSWITCH(FS_GFX3D_8064, "fs_gfx3d", &gfx3d_8064_fs_ops,
+		   GFX3D_GFS_CTL_REG),
 	FOOTSWITCH(FS_GFX3D,  "fs_gfx3d", &standard_fs_ops, GFX3D_GFS_CTL_REG),
 	FOOTSWITCH(FS_IJPEG,  "fs_ijpeg", &standard_fs_ops, GEMINI_GFS_CTL_REG),
 	FOOTSWITCH(FS_MDP,    "fs_mdp",   &standard_fs_ops, MDP_GFS_CTL_REG),
diff --git a/arch/arm/mach-msm/footswitch.h b/arch/arm/mach-msm/footswitch.h
index 57e8eba..b961f42 100644
--- a/arch/arm/mach-msm/footswitch.h
+++ b/arch/arm/mach-msm/footswitch.h
@@ -28,7 +28,8 @@
 #define FS_VFE		8
 #define FS_VPE		9
 #define FS_VCAP		10
-#define MAX_FS		11
+#define FS_GFX3D_8064	11
+#define MAX_FS		12
 
 struct fs_clk_data {
 	const char *name;
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 70c696c..68cfb2e 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -21,6 +21,8 @@
 
 extern pgprot_t     pgprot_kernel;
 extern struct bus_type msm_iommu_sec_bus_type;
+extern struct iommu_access_ops iommu_access_ops_v0;
+extern struct iommu_access_ops iommu_access_ops_v1;
 
 /* Domain attributes */
 #define MSM_IOMMU_DOMAIN_PT_CACHEABLE	0x1
@@ -229,6 +231,8 @@
 void *msm_iommu_lock_initialize(void);
 void msm_iommu_mutex_lock(void);
 void msm_iommu_mutex_unlock(void);
+void msm_set_iommu_access_ops(struct iommu_access_ops *ops);
+struct iommu_access_ops *msm_get_iommu_access_ops(void);
 #else
 static inline void *msm_iommu_lock_initialize(void)
 {
@@ -236,6 +240,14 @@
 }
 static inline void msm_iommu_mutex_lock(void) { }
 static inline void msm_iommu_mutex_unlock(void) { }
+static inline void msm_set_iommu_access_ops(struct iommu_access_ops *ops)
+{
+
+}
+static inline struct iommu_access_ops *msm_get_iommu_access_ops(void)
+{
+	return NULL;
+}
 #endif
 
 #ifdef CONFIG_MSM_IOMMU_GPU_SYNC
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-v1.h b/arch/arm/mach-msm/include/mach/iommu_hw-v1.h
index 554f7e0..1c20d04 100644
--- a/arch/arm/mach-msm/include/mach/iommu_hw-v1.h
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-v1.h
@@ -93,6 +93,8 @@
 #define SET_NSCR0(b, v)          SET_GLOBAL_REG(NSCR0, (b), (v))
 #define SET_NSCR2(b, v)          SET_GLOBAL_REG(NSCR2, (b), (v))
 #define SET_NSACR(b, v)          SET_GLOBAL_REG(NSACR, (b), (v))
+#define SET_NSGFAR(b, v)         SET_GLOBAL_REG(NSGFAR, (b), (v))
+#define SET_NSGFSRRESTORE(b, v)  SET_GLOBAL_REG(NSGFSRRESTORE, (b), (v))
 #define SET_PMCR(b, v)           SET_GLOBAL_REG(PMCR, (b), (v))
 #define SET_SMR_N(b, N, v)       SET_GLOBAL_REG_N(SMR, N, (b), (v))
 #define SET_S2CR_N(b, N, v)      SET_GLOBAL_REG_N(S2CR, N, (b), (v))
@@ -215,26 +217,34 @@
 #define GET_ATSR(b, c)           GET_CTX_REG(CB_ATSR, (b), (c))
 
 /* Global Register field setters / getters */
-/* Configuration Register: CR0 */
+/* Configuration Register: CR0/NSCR0 */
 #define SET_CR0_NSCFG(b, v)        SET_GLOBAL_FIELD(b, CR0, NSCFG, v)
 #define SET_CR0_WACFG(b, v)        SET_GLOBAL_FIELD(b, CR0, WACFG, v)
 #define SET_CR0_RACFG(b, v)        SET_GLOBAL_FIELD(b, CR0, RACFG, v)
 #define SET_CR0_SHCFG(b, v)        SET_GLOBAL_FIELD(b, CR0, SHCFG, v)
 #define SET_CR0_SMCFCFG(b, v)      SET_GLOBAL_FIELD(b, CR0, SMCFCFG, v)
+#define SET_NSCR0_SMCFCFG(b, v)    SET_GLOBAL_FIELD(b, NSCR0, SMCFCFG, v)
 #define SET_CR0_MTCFG(b, v)        SET_GLOBAL_FIELD(b, CR0, MTCFG, v)
 #define SET_CR0_BSU(b, v)          SET_GLOBAL_FIELD(b, CR0, BSU, v)
 #define SET_CR0_FB(b, v)           SET_GLOBAL_FIELD(b, CR0, FB, v)
 #define SET_CR0_PTM(b, v)          SET_GLOBAL_FIELD(b, CR0, PTM, v)
 #define SET_CR0_VMIDPNE(b, v)      SET_GLOBAL_FIELD(b, CR0, VMIDPNE, v)
 #define SET_CR0_USFCFG(b, v)       SET_GLOBAL_FIELD(b, CR0, USFCFG, v)
+#define SET_NSCR0_USFCFG(b, v)     SET_GLOBAL_FIELD(b, NSCR0, USFCFG, v)
 #define SET_CR0_GSE(b, v)          SET_GLOBAL_FIELD(b, CR0, GSE, v)
 #define SET_CR0_STALLD(b, v)       SET_GLOBAL_FIELD(b, CR0, STALLD, v)
+#define SET_NSCR0_STALLD(b, v)     SET_GLOBAL_FIELD(b, NSCR0, STALLD, v)
 #define SET_CR0_TRANSIENTCFG(b, v) SET_GLOBAL_FIELD(b, CR0, TRANSIENTCFG, v)
 #define SET_CR0_GCFGFIE(b, v)      SET_GLOBAL_FIELD(b, CR0, GCFGFIE, v)
+#define SET_NSCR0_GCFGFIE(b, v)    SET_GLOBAL_FIELD(b, NSCR0, GCFGFIE, v)
 #define SET_CR0_GCFGFRE(b, v)      SET_GLOBAL_FIELD(b, CR0, GCFGFRE, v)
+#define SET_NSCR0_GCFGFRE(b, v)    SET_GLOBAL_FIELD(b, NSCR0, GCFGFRE, v)
 #define SET_CR0_GFIE(b, v)         SET_GLOBAL_FIELD(b, CR0, GFIE, v)
+#define SET_NSCR0_GFIE(b, v)       SET_GLOBAL_FIELD(b, NSCR0, GFIE, v)
 #define SET_CR0_GFRE(b, v)         SET_GLOBAL_FIELD(b, CR0, GFRE, v)
+#define SET_NSCR0_GFRE(b, v)       SET_GLOBAL_FIELD(b, NSCR0, GFRE, v)
 #define SET_CR0_CLIENTPD(b, v)     SET_GLOBAL_FIELD(b, CR0, CLIENTPD, v)
+#define SET_NSCR0_CLIENTPD(b, v)   SET_GLOBAL_FIELD(b, NSCR0, CLIENTPD, v)
 
 #define GET_CR0_NSCFG(b)           GET_GLOBAL_FIELD(b, CR0, NSCFG)
 #define GET_CR0_WACFG(b)           GET_GLOBAL_FIELD(b, CR0, WACFG)
@@ -949,6 +959,8 @@
 #define NSCR0		(0x0400)
 #define NSCR2		(0x0408)
 #define NSACR		(0x0410)
+#define NSGFAR		(0x0440)
+#define NSGFSRRESTORE	(0x044C)
 #define SMR		(0x0800)
 #define S2CR		(0x0C00)
 
@@ -1400,6 +1412,7 @@
 #define CR0_RACFG_MASK          0x03
 #define CR0_SHCFG_MASK          0x03
 #define CR0_SMCFCFG_MASK        0x01
+#define NSCR0_SMCFCFG_MASK      0x01
 #define CR0_MTCFG_MASK          0x01
 #define CR0_MEMATTR_MASK        0x0F
 #define CR0_BSU_MASK            0x03
@@ -1407,14 +1420,21 @@
 #define CR0_PTM_MASK            0x01
 #define CR0_VMIDPNE_MASK        0x01
 #define CR0_USFCFG_MASK         0x01
+#define NSCR0_USFCFG_MASK       0x01
 #define CR0_GSE_MASK            0x01
 #define CR0_STALLD_MASK         0x01
+#define NSCR0_STALLD_MASK       0x01
 #define CR0_TRANSIENTCFG_MASK   0x03
 #define CR0_GCFGFIE_MASK        0x01
+#define NSCR0_GCFGFIE_MASK      0x01
 #define CR0_GCFGFRE_MASK        0x01
+#define NSCR0_GCFGFRE_MASK      0x01
 #define CR0_GFIE_MASK           0x01
+#define NSCR0_GFIE_MASK         0x01
 #define CR0_GFRE_MASK           0x01
+#define NSCR0_GFRE_MASK         0x01
 #define CR0_CLIENTPD_MASK       0x01
+#define NSCR0_CLIENTPD_MASK     0x01
 
 /* Configuration Register 2 */
 #define CR2_BPVMID_MASK         0xFF
@@ -1764,6 +1784,7 @@
 #define CR0_RACFG_SHIFT            24
 #define CR0_SHCFG_SHIFT            22
 #define CR0_SMCFCFG_SHIFT          21
+#define NSCR0_SMCFCFG_SHIFT        21
 #define CR0_MTCFG_SHIFT            20
 #define CR0_MEMATTR_SHIFT          16
 #define CR0_BSU_SHIFT              14
@@ -1771,14 +1792,21 @@
 #define CR0_PTM_SHIFT              12
 #define CR0_VMIDPNE_SHIFT          11
 #define CR0_USFCFG_SHIFT           10
+#define NSCR0_USFCFG_SHIFT         10
 #define CR0_GSE_SHIFT              9
 #define CR0_STALLD_SHIFT           8
+#define NSCR0_STALLD_SHIFT         8
 #define CR0_TRANSIENTCFG_SHIFT     6
 #define CR0_GCFGFIE_SHIFT          5
+#define NSCR0_GCFGFIE_SHIFT        5
 #define CR0_GCFGFRE_SHIFT          4
+#define NSCR0_GCFGFRE_SHIFT        4
 #define CR0_GFIE_SHIFT             2
+#define NSCR0_GFIE_SHIFT           2
 #define CR0_GFRE_SHIFT             1
+#define NSCR0_GFRE_SHIFT           1
 #define CR0_CLIENTPD_SHIFT         0
+#define NSCR0_CLIENTPD_SHIFT       0
 
 /* Configuration Register: CR2 */
 #define CR2_BPVMID_SHIFT           0
diff --git a/arch/arm/mach-msm/include/mach/iommu_perfmon.h b/arch/arm/mach-msm/include/mach/iommu_perfmon.h
index dc4671c..45683f4 100644
--- a/arch/arm/mach-msm/include/mach/iommu_perfmon.h
+++ b/arch/arm/mach-msm/include/mach/iommu_perfmon.h
@@ -144,8 +144,6 @@
 	unsigned int (*read_counter)(struct iommu_pmon_counter *);
 };
 
-extern struct iommu_access_ops iommu_access_ops_v0;
-extern struct iommu_access_ops iommu_access_ops_v1;
 #define MSM_IOMMU_PMU_NO_EVENT_CLASS -1
 
 #ifdef CONFIG_MSM_IOMMU_PMON
diff --git a/arch/arm/mach-msm/include/mach/kgsl.h b/arch/arm/mach-msm/include/mach/kgsl.h
index 2216183..2d7e8df 100644
--- a/arch/arm/mach-msm/include/mach/kgsl.h
+++ b/arch/arm/mach-msm/include/mach/kgsl.h
@@ -81,7 +81,6 @@
 	int (*set_grp_async)(void);
 	unsigned int idle_timeout;
 	bool strtstp_sleepwake;
-	unsigned int nap_allowed;
 	unsigned int clk_map;
 	unsigned int idle_needed;
 	unsigned int step_mul;
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index 5aaab18..d52686c 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -41,6 +41,7 @@
 #define of_board_is_cdp()	of_machine_is_compatible("qcom,cdp")
 #define of_board_is_mtp()	of_machine_is_compatible("qcom,mtp")
 #define of_board_is_qrd()	of_machine_is_compatible("qcom,qrd")
+#define of_board_is_xpm()	of_machine_is_compatible("qcom,xpm")
 
 #define machine_is_msm8974()	of_machine_is_compatible("qcom,msm8974")
 #define machine_is_msm9625()	of_machine_is_compatible("qcom,msm9625")
@@ -69,6 +70,7 @@
 #define of_board_is_cdp()		0
 #define of_board_is_mtp()		0
 #define of_board_is_qrd()		0
+#define of_board_is_xpm()		0
 
 #define machine_is_msm8974()		0
 #define machine_is_msm9625()		0
diff --git a/arch/arm/mach-msm/include/mach/subsystem_restart.h b/arch/arm/mach-msm/include/mach/subsystem_restart.h
index 35b1f76..962429e 100644
--- a/arch/arm/mach-msm/include/mach/subsystem_restart.h
+++ b/arch/arm/mach-msm/include/mach/subsystem_restart.h
@@ -75,6 +75,8 @@
 extern void subsys_unregister(struct subsys_device *dev);
 
 extern void subsys_default_online(struct subsys_device *dev);
+extern void subsys_set_crash_status(struct subsys_device *dev, bool crashed);
+extern bool subsys_get_crash_status(struct subsys_device *dev);
 
 #else
 
@@ -114,6 +116,12 @@
 static inline void subsys_unregister(struct subsys_device *dev) { }
 
 static inline void subsys_default_online(struct subsys_device *dev) { }
+static inline
+void subsys_set_crash_status(struct subsys_device *dev, bool crashed) { }
+static inline bool subsys_get_crash_status(struct subsys_device *dev)
+{
+	return false;
+}
 
 #endif /* CONFIG_MSM_SUBSYSTEM_RESTART */
 
diff --git a/arch/arm/mach-msm/include/mach/usb_bam.h b/arch/arm/mach-msm/include/mach/usb_bam.h
index bc76f56..a3e993d 100644
--- a/arch/arm/mach-msm/include/mach/usb_bam.h
+++ b/arch/arm/mach-msm/include/mach/usb_bam.h
@@ -298,7 +298,7 @@
  * Resets the USB BAM that has A2 pipes
  *
  */
-int usb_bam_a2_reset(void);
+int usb_bam_a2_reset(bool to_reconnect);
 
 /**
  * Indicates if the client of the USB BAM is ready to start
@@ -308,6 +308,14 @@
  *
  */
 int usb_bam_client_ready(bool ready);
+
+/**
+* Returns upon reset completion if reset is in progress
+* immediately otherwise.
+*
+*/
+void usb_bam_reset_complete(void);
+
 /**
 * Returns qdss index from the connections array.
 *
@@ -403,7 +411,7 @@
 	return -ENODEV;
 }
 
-static inline int usb_bam_a2_reset(void)
+static inline int usb_bam_a2_reset(bool to_reconnect)
 {
 	return -ENODEV;
 }
@@ -413,6 +421,11 @@
 	return -ENODEV;
 }
 
+static inline void usb_bam_reset_complete(void)
+{
+	return;
+}
+
 static inline int usb_bam_get_qdss_idx(u8 num)
 {
 	return -ENODEV;
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index 12f5a8e..20a5249 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -189,6 +189,7 @@
 {
 	unsigned long iova;
 	int ret;
+	struct iommu_domain *domain;
 
 	if (size & (align - 1))
 		return -EINVAL;
@@ -204,8 +205,14 @@
 	if (ret)
 		return -ENOMEM;
 
-	ret = msm_iommu_map_iova_phys(msm_get_iommu_domain(domain_no), iova,
-					phys, size, cached);
+	domain = msm_get_iommu_domain(domain_no);
+	if (!domain) {
+		pr_err("%s: Could not find domain %u. Unable to map\n",
+			__func__, domain_no);
+		msm_free_iova_address(iova, domain_no, partition_no, size);
+		return -EINVAL;
+	}
+	ret = msm_iommu_map_iova_phys(domain, iova, phys, size, cached);
 
 	if (ret)
 		msm_free_iova_address(iova, domain_no, partition_no, size);
@@ -221,10 +228,18 @@
 					unsigned int partition_no,
 					unsigned long size)
 {
+	struct iommu_domain *domain;
+
 	if (!msm_use_iommu())
 		return;
 
-	iommu_unmap_range(msm_get_iommu_domain(domain_no), iova, size);
+	domain = msm_get_iommu_domain(domain_no);
+	if (domain) {
+		iommu_unmap_range(domain, iova, size);
+	} else {
+		pr_err("%s: Could not find domain %u. Unable to unmap\n",
+			__func__, domain_no);
+	}
 	msm_free_iova_address(iova, domain_no, partition_no, size);
 }
 EXPORT_SYMBOL(msm_iommu_unmap_contig_buffer);
@@ -232,10 +247,10 @@
 static struct msm_iova_data *find_domain(int domain_num)
 {
 	struct rb_root *root = &domain_root;
-	struct rb_node *p = root->rb_node;
+	struct rb_node *p;
 
 	mutex_lock(&domain_mutex);
-
+	p = root->rb_node;
 	while (p) {
 		struct msm_iova_data *node;
 
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index 41fd485..841ccf3 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -466,6 +466,7 @@
 			    struct rr_packet *pkt, int clone)
 {
 	struct rr_packet *temp_pkt = pkt;
+	void (*notify)(unsigned event, void *priv);
 
 	if (unlikely(!port_ptr || !pkt))
 		return -EINVAL;
@@ -484,9 +485,10 @@
 	wake_lock(&port_ptr->port_rx_wake_lock);
 	list_add_tail(&temp_pkt->list, &port_ptr->port_rx_q);
 	wake_up(&port_ptr->port_rx_wait_q);
-	if (port_ptr->notify)
-		port_ptr->notify(MSM_IPC_ROUTER_READ_CB, port_ptr->priv);
+	notify = port_ptr->notify;
 	mutex_unlock(&port_ptr->port_rx_q_lock_lhb3);
+	if (notify)
+		notify(MSM_IPC_ROUTER_READ_CB, port_ptr->priv);
 	return 0;
 }
 
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 f1c8726..9b16944 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
@@ -59,6 +59,8 @@
 		return 1;
 
 	switch (w) {
+	case 0:
+		WARN(1, "AXI: Divide by 0 attempted\n");
 	case 1: return bw;
 	case 2:	return (bw >> 1);
 	case 4:	return (bw >> 2);
@@ -426,8 +428,10 @@
 			req_clk);
 		bwsum_hz = BW_TO_CLK_FREQ_HZ(hop->node_info->buswidth,
 			bwsum);
-		/* Account for multiple channels */
-		bwsum_hz = msm_bus_div64(hop->node_info->num_sports, bwsum_hz);
+		/* Account for multiple channels if any */
+		if (hop->node_info->num_sports > 1)
+			bwsum_hz = msm_bus_div64(hop->node_info->num_sports,
+				bwsum_hz);
 		MSM_BUS_DBG("AXI: Hop: %d, ports: %d, bwsum_hz: %llu\n",
 				hop->node_info->id, hop->node_info->num_sports,
 				bwsum_hz);
diff --git a/arch/arm/mach-msm/perf_debug.c b/arch/arm/mach-msm/perf_debug.c
index 5bf88a2..70420db 100644
--- a/arch/arm/mach-msm/perf_debug.c
+++ b/arch/arm/mach-msm/perf_debug.c
@@ -30,6 +30,8 @@
 	"5  Perf: Add DT support for L1 and L2 PMU\n"
 	"6  Perf: Add cortex A5 device tree support\n"
 	"7  Perf: Add L1 counters to tracepoints\n"
+	"8  Perf: Add cortex A7 perf support\n"
+	"9  ARM: dts: msm: add perf-events support for msm8226\n"
 ;
 
 static ssize_t desc_read(struct file *fp, char __user *buf,
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index 37b69ef..8cf6011 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -79,6 +79,8 @@
 #define EXTERNAL_BHS_STATUS		BIT(4)
 #define BHS_TIMEOUT_US			50
 
+#define STOP_ACK_TIMEOUT_MS		1000
+
 struct mba_data {
 	void __iomem *rmb_base;
 	void __iomem *io_clamp_reg;
@@ -94,7 +96,9 @@
 	bool crash_shutdown;
 	bool ignore_errors;
 	int err_fatal_irq;
+	unsigned int stop_ack_irq;
 	int force_stop_gpio;
+	struct completion stop_ack;
 };
 
 static int pbl_mba_boot_timeout_ms = 1000;
@@ -484,16 +488,36 @@
 		return IRQ_HANDLED;
 
 	pr_err("Fatal error on the modem.\n");
+	subsys_set_crash_status(drv->subsys, true);
 	restart_modem(drv);
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t modem_stop_ack_intr_handler(int irq, void *dev_id)
+{
+	struct mba_data *drv = dev_id;
+	pr_info("Received stop ack interrupt from modem\n");
+	complete(&drv->stop_ack);
+	return IRQ_HANDLED;
+}
+
 static int modem_shutdown(const struct subsys_desc *subsys)
 {
 	struct mba_data *drv = subsys_to_drv(subsys);
+	unsigned long ret;
 
 	if (subsys->is_not_loadable)
 		return 0;
+
+	if (!subsys_get_crash_status(drv->subsys)) {
+		gpio_set_value(drv->force_stop_gpio, 1);
+		ret = wait_for_completion_timeout(&drv->stop_ack,
+				msecs_to_jiffies(STOP_ACK_TIMEOUT_MS));
+		if (!ret)
+			pr_warn("Timed out on stop ack from modem.\n");
+		gpio_set_value(drv->force_stop_gpio, 0);
+	}
+
 	pil_shutdown(&drv->desc);
 	pil_shutdown(&drv->q6->desc);
 	return 0;
@@ -511,6 +535,7 @@
 	 * run concurrently with either the watchdog bite error handler or the
 	 * SMSM callback, making it safe to unset the flag below.
 	 */
+	init_completion(&drv->stop_ack);
 	drv->ignore_errors = false;
 	ret = pil_boot(&drv->q6->desc);
 	if (ret)
@@ -525,7 +550,10 @@
 {
 	struct mba_data *drv = subsys_to_drv(subsys);
 	drv->crash_shutdown = true;
-	gpio_set_value(drv->force_stop_gpio, 1);
+	if (!subsys_get_crash_status(drv->subsys)) {
+		gpio_set_value(drv->force_stop_gpio, 1);
+		mdelay(STOP_ACK_TIMEOUT_MS);
+	}
 }
 
 static struct ramdump_segment smem_segments[] = {
@@ -582,6 +610,7 @@
 	if (drv->ignore_errors)
 		return IRQ_HANDLED;
 	pr_err("Watchdog bite received from modem software!\n");
+	subsys_set_crash_status(drv->subsys, true);
 	restart_modem(drv);
 	return IRQ_HANDLED;
 }
@@ -594,6 +623,7 @@
 	if (desc->is_not_loadable)
 		return 0;
 
+	init_completion(&drv->stop_ack);
 	ret = pil_boot(&drv->q6->desc);
 	if (ret)
 		return ret;
@@ -688,6 +718,14 @@
 		goto err_irq;
 	}
 
+	ret = devm_request_irq(&pdev->dev, drv->stop_ack_irq,
+			modem_stop_ack_intr_handler,
+			IRQF_TRIGGER_RISING, "pil-mss", drv);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Unable to register SMP2P stop ack handler!\n");
+		goto err_irq;
+	}
+
 	drv->adsp_state_notifier = subsys_notif_register_notifier("adsp",
 						&adsp_state_notifier_block);
 	if (IS_ERR(drv->adsp_state_notifier)) {
@@ -822,7 +860,7 @@
 static int __devinit pil_mss_driver_probe(struct platform_device *pdev)
 {
 	struct mba_data *drv;
-	int ret, err_fatal_gpio, is_not_loadable;
+	int ret, err_fatal_gpio, is_not_loadable, stop_ack_gpio;
 
 	drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
 	if (!drv)
@@ -849,6 +887,16 @@
 	if (drv->err_fatal_irq < 0)
 		return drv->err_fatal_irq;
 
+	stop_ack_gpio = of_get_named_gpio(pdev->dev.of_node,
+			"qcom,gpio-stop-ack", 0);
+	if (stop_ack_gpio < 0)
+		return stop_ack_gpio;
+
+	ret = gpio_to_irq(stop_ack_gpio);
+	if (ret < 0)
+		return ret;
+	drv->stop_ack_irq = ret;
+
 	/* Get the GPIO pin for writing the outbound bits: add more as needed */
 	drv->force_stop_gpio = of_get_named_gpio(pdev->dev.of_node,
 			"qcom,gpio-force-stop", 0);
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 7792276..545723c 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -59,6 +59,7 @@
 #include "timer.h"
 #include "pm-boot.h"
 #include <mach/event_timer.h>
+#include <linux/cpu_pm.h>
 
 #define SCM_L2_RETENTION	(0x2)
 #define SCM_CMD_TERMINATE_PC	(0x2)
@@ -484,6 +485,9 @@
 		pr_info("CPU%u: %s: notify_rpm %d\n",
 			cpu, __func__, (int) notify_rpm);
 
+	if (from_idle == true)
+		cpu_pm_enter();
+
 	ret = msm_spm_set_low_power_mode(
 			MSM_SPM_MODE_POWER_COLLAPSE, notify_rpm);
 	WARN_ON(ret);
@@ -516,6 +520,10 @@
 
 	ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false);
 	WARN_ON(ret);
+
+	if (from_idle == true)
+		cpu_pm_exit();
+
 	return collapsed;
 }
 
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index 8e507ff..a5e04cd 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -137,6 +137,7 @@
  * @dentry: debugfs directory for this device
  * @do_ramdump_on_put: ramdump on subsystem_put() if true
  * @err_ready: completion variable to record error ready from subsystem
+ * @crashed: indicates if subsystem has crashed
  */
 struct subsys_device {
 	struct subsys_desc *desc;
@@ -160,6 +161,7 @@
 	struct miscdevice misc_dev;
 	char miscdevice_name[32];
 	struct completion err_ready;
+	bool crashed;
 };
 
 static struct subsys_device *to_subsys(struct device *d)
@@ -813,6 +815,15 @@
 }
 EXPORT_SYMBOL(subsystem_crashed);
 
+void subsys_set_crash_status(struct subsys_device *dev, bool crashed)
+{
+	dev->crashed = true;
+}
+
+bool subsys_get_crash_status(struct subsys_device *dev)
+{
+	return dev->crashed;
+}
 #ifdef CONFIG_DEBUG_FS
 static ssize_t subsys_debugfs_read(struct file *filp, char __user *ubuf,
 		size_t cnt, loff_t *ppos)
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index 6e948b7..71eda68 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -199,7 +199,7 @@
 	}
 
 	buf = kzalloc(sizeof(char) * buf_size, GFP_KERNEL);
-	if (!buf) {
+	if (ZERO_OR_NULL_PTR(buf)) {
 		pr_err("diag: %s, Error allocating memory\n", __func__);
 		return -ENOMEM;
 	}
@@ -267,7 +267,7 @@
 	}
 
 	buf = kzalloc(sizeof(char) * buf_size, GFP_KERNEL);
-	if (!buf) {
+	if (ZERO_OR_NULL_PTR(buf)) {
 		pr_err("diag: %s, Error allocating memory\n", __func__);
 		return -ENOMEM;
 	}
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 66e1abc..90a4154 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -595,7 +595,7 @@
 	}
 	head_params = kzalloc(pkt_params.count*sizeof(
 		struct bindpkt_params), GFP_KERNEL);
-	if (!head_params) {
+	if (ZERO_OR_NULL_PTR(head_params)) {
 		pr_err("diag: unable to alloc memory\n");
 		return -ENOMEM;
 	} else
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 960fdb9..13cbc8f 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -87,7 +87,7 @@
 			pkt_params->count = msg->count_entries;
 			pkt_params->params = kzalloc(pkt_params->count *
 				sizeof(struct bindpkt_params), GFP_KERNEL);
-			if (pkt_params->params == NULL) {
+			if (ZERO_OR_NULL_PTR(pkt_params->params)) {
 				pr_alert("diag: In %s, Memory alloc fail\n",
 					__func__);
 				kfree(pkt_params);
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 75d0d39..bff9db5 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -2729,8 +2729,14 @@
 					pce_dev->ce_sps.ce_burst_size);
 	pce_dev->ce_sps.result_dump = (uint32_t)vaddr;
 	pce_dev->ce_sps.result = (struct ce_result_dump_format *)vaddr;
-	vaddr += 128;
+	vaddr += CRYPTO_RESULT_DUMP_SIZE;
 
+	pce_dev->ce_sps.ignore_buffer = (uint32_t)vaddr;
+	vaddr += pce_dev->ce_sps.ce_burst_size * 2;
+
+	if ((vaddr - pce_dev->coh_vmem) > pce_dev->memsize)
+		panic("qce50: Not enough coherent memory. Allocate %x , need %x",
+			 pce_dev->memsize, vaddr - pce_dev->coh_vmem);
 	return 0;
 }
 
diff --git a/drivers/gpu/ion/ion_page_pool.c b/drivers/gpu/ion/ion_page_pool.c
index e8b5489..495dd24 100644
--- a/drivers/gpu/ion/ion_page_pool.c
+++ b/drivers/gpu/ion/ion_page_pool.c
@@ -44,6 +44,7 @@
 
 	sg_init_table(&sg, 1);
 	sg_set_page(&sg, page, PAGE_SIZE << pool->order, 0);
+	sg_dma_address(&sg) = sg_phys(&sg);
 	dma_sync_sg_for_device(NULL, &sg, 1, DMA_BIDIRECTIONAL);
 
 	return page;
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index fb6dc2d..2bab7c4 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -88,6 +88,7 @@
 		}
 		sg_init_table(&sg, 1);
 		sg_set_page(&sg, page, PAGE_SIZE << order, 0);
+		sg_dma_address(&sg) = sg_phys(&sg);
 		dma_sync_sg_for_device(NULL, &sg, 1, DMA_BIDIRECTIONAL);
 	}
 	if (!page)
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index d7bf193..5ad2394 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -166,6 +166,15 @@
 	/* version of pfp microcode that supports sync_lock
 	   between CPU and GPU for IOMMU-v0 programming */
 	unsigned int sync_lock_pfp_ver;
+	/* PM4 jump table index */
+	unsigned int pm4_jt_idx;
+	/* PM4 jump table load addr */
+	unsigned int pm4_jt_addr;
+	/* PFP jump table index */
+	unsigned int pfp_jt_idx;
+	/* PFP jump table load addr */
+	unsigned int pfp_jt_addr;
+
 } adreno_gpulist[] = {
 	{ ADRENO_REV_A200, 0, 2, ANY_ID, ANY_ID,
 		"yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev,
@@ -202,10 +211,11 @@
 		512, 0, 2, SZ_512K, 0x3FF037, 0x3FF016 },
 	{ ADRENO_REV_A330, 3, 3, 0, ANY_ID,
 		"a330_pm4.fw", "a330_pfp.fw", &adreno_a3xx_gpudev,
-		512, 0, 2, SZ_1M, NO_VER, NO_VER },
+		512, 0, 2, SZ_1M, NO_VER, NO_VER, 0x8AD, 0x2E4, 0x201, 0x200 },
 	{ ADRENO_REV_A305B, 3, 0, 5, 0x10,
 		"a330_pm4.fw", "a330_pfp.fw", &adreno_a3xx_gpudev,
-		512, 0, 2, SZ_128K, NO_VER, NO_VER },
+		512, 0, 2, SZ_128K, NO_VER, NO_VER, 0x8AD, 0x2E4,
+		0x201, 0x200 },
 	{ ADRENO_REV_A305C, 3, 0, 5, 0x20,
 		"a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev,
 		512, 0, 2, SZ_128K, 0x3FF037, 0x3FF016 },
@@ -527,12 +537,8 @@
 
 	device->pwrctrl.irq_last = 1;
 	if (device->requested_state == KGSL_STATE_NONE) {
-		if (device->pwrctrl.nap_allowed == true) {
-			kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
-			queue_work(device->work_queue, &device->idle_check_ws);
-		} else if (device->pwrscale.policy != NULL) {
-			queue_work(device->work_queue, &device->idle_check_ws);
-		}
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
+		queue_work(device->work_queue, &device->idle_check_ws);
 	}
 
 	/* Reset the time-out in our idle timer */
@@ -1122,6 +1128,10 @@
 	adreno_dev->pix_shader_start = adreno_gpulist[i].pix_shader_start;
 	adreno_dev->instruction_size = adreno_gpulist[i].instruction_size;
 	adreno_dev->gmem_size = adreno_gpulist[i].gmem_size;
+	adreno_dev->pm4_jt_idx = adreno_gpulist[i].pm4_jt_idx;
+	adreno_dev->pm4_jt_addr = adreno_gpulist[i].pm4_jt_addr;
+	adreno_dev->pfp_jt_idx = adreno_gpulist[i].pfp_jt_idx;
+	adreno_dev->pfp_jt_addr = adreno_gpulist[i].pfp_jt_addr;
 	adreno_dev->gpulist_index = i;
 }
 
@@ -1509,10 +1519,6 @@
 		&pdata->idle_timeout))
 		pdata->idle_timeout = HZ/12;
 
-	if (adreno_of_read_property(pdev->dev.of_node, "qcom,nap-allowed",
-		&pdata->nap_allowed))
-		pdata->nap_allowed = 1;
-
 	pdata->strtstp_sleepwake = of_property_read_bool(pdev->dev.of_node,
 						"qcom,strtstp-sleepwake");
 
@@ -2183,10 +2189,70 @@
 	}
 }
 
+/**
+ * adreno_soft_reset() -  Do a soft reset of the GPU hardware
+ * @device: KGSL device to soft reset
+ *
+ * "soft reset" the GPU hardware - this is a fast path GPU reset
+ * The GPU hardware is reset but we never pull power so we can skip
+ * a lot of the standard adreno_stop/adreno_start sequence
+ */
+int adreno_soft_reset(struct kgsl_device *device)
+{
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+	int ret;
+
+	/* If the jump table index is 0 soft reset is not supported */
+	if ((!adreno_dev->pm4_jt_idx) || (!adreno_dev->gpudev->soft_reset)) {
+		dev_WARN_ONCE(device->dev, 1, "Soft reset not supported");
+		return -EINVAL;
+	}
+
+	adreno_dev->drawctxt_active = NULL;
+
+	/* Stop the ringbuffer */
+	adreno_ringbuffer_stop(&adreno_dev->ringbuffer);
+
+	/* Delete the idle timer */
+	del_timer_sync(&device->idle_timer);
+
+	/* Make sure we are totally awake */
+	kgsl_pwrctrl_enable(device);
+
+	/* Reset the GPU */
+	adreno_dev->gpudev->soft_reset(adreno_dev);
+
+	/* Reinitialize the GPU */
+	adreno_dev->gpudev->start(adreno_dev);
+
+	/* Enable IRQ */
+	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
+	device->ftbl->irqctrl(device, 1);
+
+	/*
+	 * Restart the ringbuffer - we can go down the warm start path because
+	 * power was never yanked
+	 */
+	ret = adreno_ringbuffer_warm_start(&adreno_dev->ringbuffer);
+	if (ret)
+		return ret;
+
+	device->reset_counter++;
+
+	return 0;
+}
+
 static int
 _adreno_ft_restart_device(struct kgsl_device *device,
 			   struct kgsl_context *context)
 {
+	/* If device soft reset fails try hard reset */
+	if (adreno_soft_reset(device))
+		KGSL_DEV_ERR_ONCE(device, "Device soft reset failed\n");
+	else
+		/* Soft reset is successful */
+		goto reset_done;
+
 	/* restart device */
 	if (adreno_stop(device)) {
 		KGSL_FT_ERR(device, "Device stop failed\n");
@@ -2203,6 +2269,7 @@
 		return 1;
 	}
 
+reset_done:
 	if (context) {
 		struct adreno_context *adreno_context = context->devctxt;
 		kgsl_mmu_setstate(&device->mmu, adreno_context->pagetable,
@@ -2309,6 +2376,7 @@
 	struct adreno_context *last_active_ctx = adreno_dev->drawctxt_active;
 	unsigned int long_ib = 0;
 	static int no_context_ft;
+	struct kgsl_mmu *mmu = &device->mmu;
 
 	context = idr_find(&device->context_idr, ft_data->context_id);
 	if (context == NULL) {
@@ -2382,12 +2450,13 @@
 
 	/* Do not try the reply if hang is due to a pagefault */
 	if (adreno_context && adreno_context->pagefault) {
+		/* Resume MMU */
+		mmu->mmu_ops->mmu_pagefault_resume(mmu);
 		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;
 	}
 
@@ -2762,8 +2831,6 @@
 	switch (type) {
 	case KGSL_PROP_PWRCTRL: {
 			unsigned int enable;
-			struct kgsl_device_platform_data *pdata =
-				kgsl_device_get_drvdata(device);
 
 			if (sizebytes != sizeof(enable))
 				break;
@@ -2775,12 +2842,11 @@
 			}
 
 			if (enable) {
-				if (pdata->nap_allowed)
-					device->pwrctrl.nap_allowed = true;
+				device->pwrctrl.ctrl_flags = 0;
 				adreno_dev->fast_hang_detect = 1;
 				kgsl_pwrscale_enable(device);
 			} else {
-				device->pwrctrl.nap_allowed = false;
+				device->pwrctrl.ctrl_flags = KGSL_PWR_ON;
 				adreno_dev->fast_hang_detect = 0;
 				kgsl_pwrscale_disable(device);
 			}
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 816940f..782209d 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -110,6 +110,10 @@
 	unsigned int mharb;
 	struct adreno_gpudev *gpudev;
 	unsigned int wait_timeout;
+	unsigned int pm4_jt_idx;
+	unsigned int pm4_jt_addr;
+	unsigned int pfp_jt_idx;
+	unsigned int pfp_jt_addr;
 	unsigned int istore_size;
 	unsigned int pix_shader_start;
 	unsigned int instruction_size;
@@ -200,6 +204,7 @@
 	void (*coresight_disable) (struct kgsl_device *device);
 	void (*coresight_config_debug_reg) (struct kgsl_device *device,
 			int debug_reg, unsigned int val);
+	void (*soft_reset)(struct adreno_device *device);
 };
 
 /*
@@ -330,6 +335,9 @@
 int adreno_perfcounter_put(struct adreno_device *adreno_dev,
 	unsigned int groupid, unsigned int countable);
 
+int adreno_soft_reset(struct kgsl_device *device);
+
+
 static inline int adreno_is_a200(struct adreno_device *adreno_dev)
 {
 	return (adreno_dev->gpurev == ADRENO_REV_A200);
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 884b72b..29855f7 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -3461,6 +3461,30 @@
 	ARRAY_SIZE(a3xx_perfcounter_groups),
 };
 
+/*
+ * a3xx_soft_reset() - Soft reset GPU
+ * @adreno_dev: Pointer to adreno device
+ *
+ * Soft reset the GPU by doing a AHB write of value 1 to RBBM_SW_RESET
+ * register. This is used when we want to reset the GPU without
+ * turning off GFX power rail. The reset when asserted resets
+ * all the HW logic, restores GPU registers to default state and
+ * flushes out pending VBIF transactions.
+ */
+static void a3xx_soft_reset(struct adreno_device *adreno_dev)
+{
+	struct kgsl_device *device = &adreno_dev->dev;
+	unsigned int reg;
+
+	adreno_regwrite(device, A3XX_RBBM_SW_RESET_CMD, 1);
+	/*
+	 * Do a dummy read to get a brief read cycle delay for the reset to take
+	 * effect
+	 */
+	adreno_regread(device, A3XX_RBBM_SW_RESET_CMD, &reg);
+	adreno_regwrite(device, A3XX_RBBM_SW_RESET_CMD, 0);
+}
+
 /* Defined in adreno_a3xx_snapshot.c */
 void *a3xx_snapshot(struct adreno_device *adreno_dev, void *snapshot,
 	int *remain, int hang);
@@ -3488,4 +3512,5 @@
 	.coresight_enable = a3xx_coresight_enable,
 	.coresight_disable = a3xx_coresight_disable,
 	.coresight_config_debug_reg = a3xx_coresight_config_debug_reg,
+	.soft_reset = a3xx_soft_reset,
 };
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 4e95e93..d12853f 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -14,6 +14,8 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/log2.h>
+#include <linux/time.h>
+#include <linux/delay.h>
 
 #include "kgsl.h"
 #include "kgsl_sharedmem.h"
@@ -242,8 +244,16 @@
 	return ret;
 }
 
-
-int adreno_ringbuffer_load_pm4_ucode(struct kgsl_device *device)
+/**
+ * adreno_ringbuffer_load_pm4_ucode() - Load pm4 ucode
+ * @device: Pointer to a KGSL device
+ * @start: Starting index in pm4 ucode to load
+ * @addr: Address to load the pm4 ucode
+ *
+ * Load the pm4 ucode from @start at @addr.
+ */
+int adreno_ringbuffer_load_pm4_ucode(struct kgsl_device *device,
+					unsigned int start, unsigned int addr)
 {
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	int i;
@@ -258,8 +268,8 @@
 		adreno_dev->pm4_fw_version);
 
 	adreno_regwrite(device, REG_CP_DEBUG, CP_DEBUG_DEFAULT);
-	adreno_regwrite(device, REG_CP_ME_RAM_WADDR, 0);
-	for (i = 1; i < adreno_dev->pm4_fw_size; i++)
+	adreno_regwrite(device, REG_CP_ME_RAM_WADDR, addr);
+	for (i = start; i < adreno_dev->pm4_fw_size; i++)
 		adreno_regwrite(device, REG_CP_ME_RAM_DATA,
 			adreno_dev->pm4_fw[i]);
 
@@ -297,7 +307,16 @@
 	return ret;
 }
 
-int adreno_ringbuffer_load_pfp_ucode(struct kgsl_device *device)
+/**
+ * adreno_ringbuffer_load_pfp_ucode() - Load pfp ucode
+ * @device: Pointer to a KGSL device
+ * @start: Starting index in pfp ucode to load
+ * @addr: Address to load the pfp ucode
+ *
+ * Load the pfp ucode from @start at @addr.
+ */
+int adreno_ringbuffer_load_pfp_ucode(struct kgsl_device *device,
+					unsigned int start, unsigned int addr)
 {
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	int i;
@@ -311,8 +330,9 @@
 	KGSL_DRV_INFO(device, "loading pfp ucode version: %d\n",
 			adreno_dev->pfp_fw_version);
 
-	adreno_regwrite(device, adreno_dev->gpudev->reg_cp_pfp_ucode_addr, 0);
-	for (i = 1; i < adreno_dev->pfp_fw_size; i++)
+	adreno_regwrite(device, adreno_dev->gpudev->reg_cp_pfp_ucode_addr,
+						addr);
+	for (i = start; i < adreno_dev->pfp_fw_size; i++)
 		adreno_regwrite(device,
 		adreno_dev->gpudev->reg_cp_pfp_ucode_data,
 		adreno_dev->pfp_fw[i]);
@@ -320,7 +340,13 @@
 	return 0;
 }
 
-int adreno_ringbuffer_start(struct adreno_ringbuffer *rb)
+/**
+ * _ringbuffer_start_common() - Ringbuffer start
+ * @rb: Pointer to adreno ringbuffer
+ *
+ * Setup ringbuffer for GPU.
+ */
+int _ringbuffer_start_common(struct adreno_ringbuffer *rb)
 {
 	int status;
 	/*cp_rb_cntl_u cp_rb_cntl; */
@@ -420,16 +446,6 @@
 	adreno_regwrite(device, REG_SCRATCH_UMSK,
 			     GSL_RB_MEMPTRS_SCRATCH_MASK);
 
-	/* load the CP ucode */
-	status = adreno_ringbuffer_load_pm4_ucode(device);
-	if (status != 0)
-		return status;
-
-	/* load the prefetch parser ucode */
-	status = adreno_ringbuffer_load_pfp_ucode(device);
-	if (status != 0)
-		return status;
-
 	/* CP ROQ queue sizes (bytes) - RB:16, ST:16, IB1:32, IB2:64 */
 	if (adreno_is_a305(adreno_dev) || adreno_is_a305c(adreno_dev) ||
 		adreno_is_a320(adreno_dev))
@@ -457,6 +473,54 @@
 	return status;
 }
 
+/**
+ * adreno_ringbuffer_warm_start() - Ringbuffer warm start
+ * @rb: Pointer to adreno ringbuffer
+ *
+ * Start the ringbuffer but load only jump tables part of the
+ * microcode.
+ */
+int adreno_ringbuffer_warm_start(struct adreno_ringbuffer *rb)
+{
+	int status;
+	struct kgsl_device *device = rb->device;
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+	/* load the CP ucode */
+	status = adreno_ringbuffer_load_pm4_ucode(device,
+			adreno_dev->pm4_jt_idx, adreno_dev->pm4_jt_addr);
+	if (status != 0)
+		return status;
+
+	/* load the prefetch parser ucode */
+	status = adreno_ringbuffer_load_pfp_ucode(device,
+			adreno_dev->pfp_jt_idx, adreno_dev->pfp_jt_addr);
+	if (status != 0)
+		return status;
+
+	return _ringbuffer_start_common(rb);
+}
+
+int adreno_ringbuffer_start(struct adreno_ringbuffer *rb)
+{
+	int status;
+
+	if (rb->flags & KGSL_FLAGS_STARTED)
+		return 0;
+
+	/* load the CP ucode */
+	status = adreno_ringbuffer_load_pm4_ucode(rb->device, 1, 0);
+	if (status != 0)
+		return status;
+
+	/* load the prefetch parser ucode */
+	status = adreno_ringbuffer_load_pfp_ucode(rb->device, 1, 0);
+	if (status != 0)
+		return status;
+
+	return _ringbuffer_start_common(rb);
+}
+
 void adreno_ringbuffer_stop(struct adreno_ringbuffer *rb)
 {
 	struct kgsl_device *device = rb->device;
diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h
index 115533e..f59b834 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.h
+++ b/drivers/gpu/msm/adreno_ringbuffer.h
@@ -97,6 +97,8 @@
 
 int adreno_ringbuffer_init(struct kgsl_device *device);
 
+int adreno_ringbuffer_warm_start(struct adreno_ringbuffer *rb);
+
 int adreno_ringbuffer_start(struct adreno_ringbuffer *rb);
 
 void adreno_ringbuffer_stop(struct adreno_ringbuffer *rb);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 86e70c8..1d2c341 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -525,7 +525,6 @@
 static int kgsl_suspend_device(struct kgsl_device *device, pm_message_t state)
 {
 	int status = -EINVAL;
-	unsigned int nap_allowed_saved;
 	struct kgsl_pwrscale_policy *policy_saved;
 
 	if (!device)
@@ -534,8 +533,6 @@
 	KGSL_PWR_WARN(device, "suspend start\n");
 
 	mutex_lock(&device->mutex);
-	nap_allowed_saved = device->pwrctrl.nap_allowed;
-	device->pwrctrl.nap_allowed = false;
 	policy_saved = device->pwrscale.policy;
 	device->pwrscale.policy = NULL;
 	kgsl_pwrctrl_request_state(device, KGSL_STATE_SUSPEND);
@@ -545,6 +542,12 @@
 	 */
 	kgsl_active_count_wait(device);
 
+	/*
+	 * An interrupt could have snuck in and requested NAP in
+	 * the meantime, make sure we're on the SUSPEND path.
+	 */
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_SUSPEND);
+
 	/* Don't let the timer wake us during suspended sleep. */
 	del_timer_sync(&device->idle_timer);
 	switch (device->state) {
@@ -575,7 +578,6 @@
 			goto end;
 	}
 	kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
-	device->pwrctrl.nap_allowed = nap_allowed_saved;
 	device->pwrscale.policy = policy_saved;
 	status = 0;
 
@@ -3336,7 +3338,6 @@
 
 int kgsl_postmortem_dump(struct kgsl_device *device, int manual)
 {
-	bool saved_nap;
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
 
 	BUG_ON(device == NULL);
@@ -3356,8 +3357,8 @@
 	if (device->pm_dump_enable) {
 
 		KGSL_LOG_DUMP(device,
-			"POWER: NAP ALLOWED = %d | START_STOP_SLEEP_WAKE = %d\n"
-			, pwr->nap_allowed, pwr->strtstp_sleepwake);
+			"POWER: START_STOP_SLEEP_WAKE = %d\n",
+			pwr->strtstp_sleepwake);
 
 		KGSL_LOG_DUMP(device,
 			"POWER: FLAGS = %08lX | ACTIVE POWERLEVEL = %08X",
@@ -3374,11 +3375,6 @@
 	flush_workqueue(device->work_queue);
 	mutex_lock(&device->mutex);
 
-	/* Turn off napping to make sure we have the clocks full
-	   attention through the following process */
-	saved_nap = device->pwrctrl.nap_allowed;
-	device->pwrctrl.nap_allowed = false;
-
 	/* Force on the clocks */
 	kgsl_pwrctrl_wake(device);
 
@@ -3388,9 +3384,6 @@
 	/*Call the device specific postmortem dump function*/
 	device->ftbl->postmortem_dump(device, manual);
 
-	/* Restore nap mode */
-	device->pwrctrl.nap_allowed = saved_nap;
-
 	/* 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
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index b86e0e1..0bacc5e 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -919,7 +919,7 @@
 	if (iommu->sync_lock_initialized)
 		return status;
 
-	iommu_access_ops = get_iommu_access_ops_v0();
+	iommu_access_ops = msm_get_iommu_access_ops();
 
 	if (iommu_access_ops && iommu_access_ops->iommu_lock_initialize) {
 		lock_phy_addr = (uint32_t)
@@ -1735,10 +1735,36 @@
 	return ret;
 }
 
-static void kgsl_iommu_stop(struct kgsl_mmu *mmu)
+void kgsl_iommu_pagefault_resume(struct kgsl_mmu *mmu)
 {
 	struct kgsl_iommu *iommu = mmu->priv;
 	int i, j;
+
+	if (mmu->fault) {
+		for (i = 0; i < iommu->unit_count; i++) {
+			struct kgsl_iommu_unit *iommu_unit =
+						&iommu->iommu_units[i];
+			for (j = 0; j < iommu_unit->dev_count; j++) {
+				if (iommu_unit->dev[j].fault) {
+					kgsl_iommu_enable_clk(mmu, j);
+					_iommu_lock();
+					KGSL_IOMMU_SET_CTX_REG(iommu,
+						iommu_unit,
+						iommu_unit->dev[j].ctx_id,
+						RESUME, 1);
+					_iommu_unlock();
+					iommu_unit->dev[j].fault = 0;
+				}
+			}
+		}
+		mmu->fault = 0;
+	}
+}
+
+
+static void kgsl_iommu_stop(struct kgsl_mmu *mmu)
+{
+	struct kgsl_iommu *iommu = mmu->priv;
 	/*
 	 *  stop device mmu
 	 *
@@ -1751,25 +1777,7 @@
 
 		mmu->flags &= ~KGSL_FLAGS_STARTED;
 
-		if (mmu->fault) {
-			for (i = 0; i < iommu->unit_count; i++) {
-				struct kgsl_iommu_unit *iommu_unit =
-					&iommu->iommu_units[i];
-				for (j = 0; j < iommu_unit->dev_count; j++) {
-					if (iommu_unit->dev[j].fault) {
-						kgsl_iommu_enable_clk(mmu, j);
-						_iommu_lock();
-						KGSL_IOMMU_SET_CTX_REG(iommu,
-						iommu_unit,
-						iommu_unit->dev[j].ctx_id,
-						RESUME, 1);
-						_iommu_unlock();
-						iommu_unit->dev[j].fault = 0;
-					}
-				}
-			}
-			mmu->fault = 0;
-		}
+		kgsl_iommu_pagefault_resume(mmu);
 	}
 	/* switch off MMU clocks and cancel any events it has queued */
 	iommu->clk_event_queued = false;
@@ -1987,6 +1995,7 @@
 	.mmu_setstate = kgsl_iommu_setstate,
 	.mmu_device_setstate = kgsl_iommu_default_setstate,
 	.mmu_pagefault = NULL,
+	.mmu_pagefault_resume = kgsl_iommu_pagefault_resume,
 	.mmu_get_current_ptbase = kgsl_iommu_get_current_ptbase,
 	.mmu_enable_clk = kgsl_iommu_enable_clk,
 	.mmu_disable_clk_on_ts = kgsl_iommu_disable_clk_on_ts,
diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h
index 53b3946..5c4b17e 100644
--- a/drivers/gpu/msm/kgsl_iommu.h
+++ b/drivers/gpu/msm/kgsl_iommu.h
@@ -83,20 +83,6 @@
 	int ctx_reg;
 };
 
-#ifdef CONFIG_MSM_IOMMU
-extern struct iommu_access_ops iommu_access_ops_v0;
-
-static inline struct iommu_access_ops *get_iommu_access_ops_v0(void)
-{
-	return &iommu_access_ops_v0;
-}
-#else
-static inline struct iommu_access_ops *get_iommu_access_ops_v0(void)
-{
-	return NULL;
-}
-#endif
-
 /*
  * Max number of iommu units that the gpu core can have
  * On APQ8064, KGSL can control a maximum of 2 IOMMU units.
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index a4fffec..27cfc40 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -141,6 +141,8 @@
 	void (*mmu_pagefault) (struct kgsl_mmu *mmu);
 	phys_addr_t (*mmu_get_current_ptbase)
 			(struct kgsl_mmu *mmu);
+	void (*mmu_pagefault_resume)
+			(struct kgsl_mmu *mmu);
 	void (*mmu_disable_clk_on_ts)
 		(struct kgsl_mmu *mmu, uint32_t ts, bool ts_valid);
 	int (*mmu_enable_clk)
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 5b386b3..847c59e 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -482,49 +482,6 @@
 			pwr->pwrlevels[pwr->active_pwrlevel].gpu_freq);
 }
 
-static int kgsl_pwrctrl_pwrnap_store(struct device *dev,
-				     struct device_attribute *attr,
-				     const char *buf, size_t count)
-{
-	char temp[20];
-	unsigned long val;
-	struct kgsl_device *device = kgsl_device_from_dev(dev);
-	struct kgsl_pwrctrl *pwr;
-	int rc;
-
-	if (device == NULL)
-		return 0;
-	pwr = &device->pwrctrl;
-
-	snprintf(temp, sizeof(temp), "%.*s",
-			 (int)min(count, sizeof(temp) - 1), buf);
-	rc = strict_strtoul(temp, 0, &val);
-	if (rc)
-		return rc;
-
-	mutex_lock(&device->mutex);
-
-	if (val == 1)
-		pwr->nap_allowed = true;
-	else if (val == 0)
-		pwr->nap_allowed = false;
-
-	mutex_unlock(&device->mutex);
-
-	return count;
-}
-
-static int kgsl_pwrctrl_pwrnap_show(struct device *dev,
-				    struct device_attribute *attr,
-				    char *buf)
-{
-	struct kgsl_device *device = kgsl_device_from_dev(dev);
-	if (device == NULL)
-		return 0;
-	return snprintf(buf, PAGE_SIZE, "%d\n", device->pwrctrl.nap_allowed);
-}
-
-
 static int kgsl_pwrctrl_idle_timer_store(struct device *dev,
 					struct device_attribute *attr,
 					const char *buf, size_t count)
@@ -759,7 +716,6 @@
 DEVICE_ATTR(gpuclk, 0644, kgsl_pwrctrl_gpuclk_show, kgsl_pwrctrl_gpuclk_store);
 DEVICE_ATTR(max_gpuclk, 0644, kgsl_pwrctrl_max_gpuclk_show,
 	kgsl_pwrctrl_max_gpuclk_store);
-DEVICE_ATTR(pwrnap, 0664, kgsl_pwrctrl_pwrnap_show, kgsl_pwrctrl_pwrnap_store);
 DEVICE_ATTR(idle_timer, 0644, kgsl_pwrctrl_idle_timer_show,
 	kgsl_pwrctrl_idle_timer_store);
 DEVICE_ATTR(gpubusy, 0444, kgsl_pwrctrl_gpubusy_show,
@@ -797,7 +753,6 @@
 static const struct device_attribute *pwrctrl_attr_list[] = {
 	&dev_attr_gpuclk,
 	&dev_attr_max_gpuclk,
-	&dev_attr_pwrnap,
 	&dev_attr_idle_timer,
 	&dev_attr_gpubusy,
 	&dev_attr_gputop,
@@ -1091,7 +1046,6 @@
 
 	pwr->power_flags = 0;
 
-	pwr->nap_allowed = pdata->nap_allowed;
 	pwr->idle_needed = pdata->idle_needed;
 	pwr->interval_timeout = pdata->idle_timeout;
 	pwr->strtstp_sleepwake = pdata->strtstp_sleepwake;
@@ -1618,9 +1572,8 @@
 
 	INIT_COMPLETION(device->suspend_gate);
 
-	if (device->pwrctrl.nap_allowed == true &&
-			(device->state == KGSL_STATE_ACTIVE &&
-			device->requested_state == KGSL_STATE_NONE)) {
+	if (device->state == KGSL_STATE_ACTIVE &&
+			device->requested_state == KGSL_STATE_NONE) {
 		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
 		if (kgsl_pwrctrl_sleep(device) && device->pwrctrl.irq_last) {
 			kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 5cadaa7..3bf65ee 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -23,6 +23,8 @@
 #define KGSL_PWRLEVEL_NOMINAL 1
 #define KGSL_PWRLEVEL_LAST_OFFSET 2
 
+#define KGSL_PWR_ON	0xFFFF
+
 #define KGSL_MAX_CLKS 6
 
 struct platform_device;
@@ -57,7 +59,6 @@
  * @gpu_reg - pointer to the regulator structure for gpu_reg
  * @gpu_cx - pointer to the regulator structure for gpu_cx
  * @pcl - bus scale identifier
- * @nap_allowed - true if the device supports naps
  * @idle_needed - true if the device needs a idle before clock change
  * @irq_name - resource name for the IRQ
  * @clk_stats - structure of clock statistics
@@ -85,7 +86,6 @@
 	struct regulator *gpu_reg;
 	struct regulator *gpu_cx;
 	uint32_t pcl;
-	unsigned int nap_allowed;
 	unsigned int idle_needed;
 	const char *irq_name;
 	s64 time;
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 7004ad7..78e2859 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -216,8 +216,7 @@
 		}
 	}
 
-	if ((device->pwrctrl.nap_allowed == true) &&
-		(device->requested_state == KGSL_STATE_NONE)) {
+	if (device->requested_state == KGSL_STATE_NONE) {
 		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
 		queue_work(device->work_queue, &device->idle_check_ws);
 	}
diff --git a/drivers/gud/Makefile b/drivers/gud/Makefile
index 3a16bb7..ef0e083 100644
--- a/drivers/gud/Makefile
+++ b/drivers/gud/Makefile
@@ -10,7 +10,8 @@
 		mobicore_driver/ops.o \
 		mobicore_driver/mem.o \
 		mobicore_driver/api.o \
-		mobicore_driver/main.o
+		mobicore_driver/main.o \
+		mobicore_driver/pm.o
 
 mckernelapi-objs := mobicore_kernelapi/main.o \
 		mobicore_kernelapi/clientlib.o \
diff --git a/drivers/gud/mobicore_driver/main.c b/drivers/gud/mobicore_driver/main.c
index b5cb1a6..6f91974 100644
--- a/drivers/gud/mobicore_driver/main.c
+++ b/drivers/gud/mobicore_driver/main.c
@@ -51,7 +51,6 @@
 };
 
 struct device mcd_debug_subname = {
-	.init_name = "", /* Set to 'mcd' at mc_init() time */
 	.driver = &mcd_debug_name
 };
 
@@ -1343,6 +1342,10 @@
 
 	ret = mc_init_l2_tables();
 
+#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
+	ret = mc_pm_clock_initialize();
+#endif
+
 	/*
 	 * initialize unique number counter which we can use for
 	 * handles. It is limited to 2^32, but this should be
@@ -1398,6 +1401,10 @@
 
 	mc_fastcall_destroy();
 
+#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
+	mc_pm_clock_finalize();
+#endif
+
 	MCDRV_DBG_VERBOSE(mcd, "exit");
 }
 
diff --git a/drivers/gud/mobicore_driver/ops.c b/drivers/gud/mobicore_driver/ops.c
index 05c80b7..9d4af72 100644
--- a/drivers/gud/mobicore_driver/ops.c
+++ b/drivers/gud/mobicore_driver/ops.c
@@ -60,7 +60,16 @@
 {
 	struct fastcall_work *fc_work =
 		container_of(work, struct fastcall_work, work);
+
+#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
+	mc_pm_clock_enable();
+#endif
+
 	smc(fc_work->data);
+
+#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
+	mc_pm_clock_disable();
+#endif
 }
 
 void mc_fastcall(void *data)
@@ -114,7 +123,16 @@
 {
 	struct fastcall_work_struct *fc_work =
 		container_of(work, struct fastcall_work_struct, work);
+
+#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
+	mc_pm_clock_enable();
+#endif
+
 	smc(fc_work->data);
+
+#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
+	mc_pm_clock_disable();
+#endif
 }
 
 void mc_fastcall(void *data)
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 7febcb6..4768f39 100644
--- a/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h
+++ b/drivers/gud/mobicore_driver/platforms/msm8960_surf_std/platform.h
@@ -43,4 +43,7 @@
  */
 #define MC_VM_UNMAP
 
+/* Enable Power Management for Crypto Engine */
+#define MC_CRYPTO_CLOCK_MANAGEMENT
+
 #endif /* _MC_PLATFORM_H_ */
diff --git a/drivers/gud/mobicore_driver/pm.c b/drivers/gud/mobicore_driver/pm.c
new file mode 100644
index 0000000..3ad2015
--- /dev/null
+++ b/drivers/gud/mobicore_driver/pm.c
@@ -0,0 +1,295 @@
+/*
+ * 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/module.h>
+#include <linux/timer.h>
+#include <linux/suspend.h>
+#include <linux/device.h>
+
+#include "main.h"
+#include "pm.h"
+#include "fastcall.h"
+#include "ops.h"
+#include "logging.h"
+#include "debug.h"
+
+#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
+	#include <linux/clk.h>
+	#include <linux/err.h>
+
+	struct clk *mc_ce_iface_clk = NULL;
+	struct clk *mc_ce_core_clk = NULL;
+	struct clk *mc_ce_bus_clk = NULL;
+#endif /* MC_CRYPTO_CLOCK_MANAGEMENT */
+
+#ifdef MC_PM_RUNTIME
+
+static struct mc_context *ctx;
+
+static bool sleep_ready(void)
+{
+	if (!ctx->mcp)
+		return false;
+
+	if (!ctx->mcp->flags.sleep_mode.ReadyToSleep & READY_TO_SLEEP)
+		return false;
+
+	return true;
+}
+
+static void mc_suspend_handler(struct work_struct *work)
+{
+	if (!ctx->mcp)
+		return;
+
+	ctx->mcp->flags.sleep_mode.SleepReq = REQ_TO_SLEEP;
+	_nsiq();
+}
+DECLARE_WORK(suspend_work, mc_suspend_handler);
+
+static inline void dump_sleep_params(struct mc_flags *flags)
+{
+	MCDRV_DBG(mcd, "MobiCore IDLE=%d!", flags->schedule);
+	MCDRV_DBG(mcd,
+		  "MobiCore Request Sleep=%d!", flags->sleep_mode.SleepReq);
+	MCDRV_DBG(mcd, "MobiCore Sleep Ready=%d!",
+		  flags->sleep_mode.ReadyToSleep);
+}
+
+static int mc_suspend_notifier(struct notifier_block *nb,
+	unsigned long event, void *dummy)
+{
+	struct mc_mcp_buffer *mcp = ctx->mcp;
+	/* We have noting to say if MobiCore is not initialized */
+	if (!mcp)
+		return 0;
+
+#ifdef MC_MEM_TRACES
+	mobicore_log_read();
+#endif
+
+	switch (event) {
+	case PM_SUSPEND_PREPARE:
+		/*
+		 * Make sure we have finished all the work otherwise
+		 * we end up in a race condition
+		 */
+		cancel_work_sync(&suspend_work);
+		/*
+		 * We can't go to sleep if MobiCore is not IDLE
+		 * or not Ready to sleep
+		 */
+		dump_sleep_params(&mcp->flags);
+		if (!sleep_ready()) {
+			ctx->mcp->flags.sleep_mode.SleepReq = REQ_TO_SLEEP;
+			schedule_work_on(0, &suspend_work);
+			flush_work(&suspend_work);
+			if (!sleep_ready()) {
+				dump_sleep_params(&mcp->flags);
+				ctx->mcp->flags.sleep_mode.SleepReq = 0;
+				MCDRV_DBG_ERROR(mcd, "MobiCore can't SLEEP!");
+				return NOTIFY_BAD;
+			}
+		}
+		break;
+	case PM_POST_SUSPEND:
+		MCDRV_DBG(mcd, "Resume MobiCore system!");
+		ctx->mcp->flags.sleep_mode.SleepReq = 0;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static struct notifier_block mc_notif_block = {
+	.notifier_call = mc_suspend_notifier,
+};
+
+#ifdef MC_BL_NOTIFIER
+
+static int bL_switcher_notifier_handler(struct notifier_block *this,
+			unsigned long event, void *ptr)
+{
+	unsigned int mpidr, cpu, cluster;
+	struct mc_mcp_buffer *mcp = ctx->mcp;
+
+	if (!mcp)
+		return 0;
+
+	asm volatile ("mrc\tp15, 0, %0, c0, c0, 5" : "=r" (mpidr));
+	cpu = mpidr & 0x3;
+	cluster = (mpidr >> 8) & 0xf;
+	MCDRV_DBG(mcd, "%s switching!!, cpu: %u, Out=%u\n",
+		  (event == SWITCH_ENTER ? "Before" : "After"), cpu, cluster);
+
+	if (cpu != 0)
+		return 0;
+
+	switch (event) {
+	case SWITCH_ENTER:
+		if (!sleep_ready()) {
+			ctx->mcp->flags.sleep_mode.SleepReq = REQ_TO_SLEEP;
+			_nsiq();
+			/* By this time we should be ready for sleep or we are
+			 * in the middle of something important */
+			if (!sleep_ready()) {
+				dump_sleep_params(&mcp->flags);
+				MCDRV_DBG(mcd,
+					  "MobiCore: Don't allow switch!\n");
+				ctx->mcp->flags.sleep_mode.SleepReq = 0;
+				return -EPERM;
+			}
+		}
+		break;
+	case SWITCH_EXIT:
+			ctx->mcp->flags.sleep_mode.SleepReq = 0;
+			break;
+	default:
+		MCDRV_DBG(mcd, "MobiCore: Unknown switch event!\n");
+	}
+
+	return 0;
+}
+
+static struct notifier_block switcher_nb = {
+	.notifier_call = bL_switcher_notifier_handler,
+};
+#endif
+
+int mc_pm_initialize(struct mc_context *context)
+{
+	int ret = 0;
+
+	ctx = context;
+
+	ret = register_pm_notifier(&mc_notif_block);
+	if (ret)
+		MCDRV_DBG_ERROR(mcd, "device pm register failed\n");
+#ifdef MC_BL_NOTIFIER
+	if (register_bL_swicher_notifier(&switcher_nb))
+		MCDRV_DBG_ERROR(mcd,
+				"Failed to register to bL_switcher_notifier\n");
+#endif
+
+	return ret;
+}
+
+int mc_pm_free(void)
+{
+	int ret = unregister_pm_notifier(&mc_notif_block);
+	if (ret)
+		MCDRV_DBG_ERROR(mcd, "device pm unregister failed\n");
+#ifdef MC_BL_NOTIFIER
+	ret = unregister_bL_swicher_notifier(&switcher_nb);
+	if (ret)
+		MCDRV_DBG_ERROR(mcd, "device bl unregister failed\n");
+#endif
+	return ret;
+}
+
+#endif /* MC_PM_RUNTIME */
+
+#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
+
+int mc_pm_clock_initialize(void)
+{
+	int ret = 0;
+
+	/* Get core clk */
+	mc_ce_core_clk = clk_get(mcd, "core_clk");
+	if (IS_ERR(mc_ce_core_clk)) {
+		ret = PTR_ERR(mc_ce_core_clk);
+		MCDRV_DBG_ERROR(mcd, "cannot get core clock\n");
+		goto error;
+	}
+	/* Get Interface clk */
+	mc_ce_iface_clk = clk_get(mcd, "iface_clk");
+	if (IS_ERR(mc_ce_iface_clk)) {
+		clk_put(mc_ce_core_clk);
+		ret = PTR_ERR(mc_ce_iface_clk);
+		MCDRV_DBG_ERROR(mcd, "cannot get iface clock\n");
+		goto error;
+	}
+	/* Get AXI clk */
+	mc_ce_bus_clk = clk_get(mcd, "bus_clk");
+	if (IS_ERR(mc_ce_bus_clk)) {
+		clk_put(mc_ce_iface_clk);
+		clk_put(mc_ce_core_clk);
+		ret = PTR_ERR(mc_ce_bus_clk);
+		MCDRV_DBG_ERROR(mcd, "cannot get AXI bus clock\n");
+		goto error;
+	}
+	return ret;
+
+error:
+	mc_ce_core_clk = NULL;
+	mc_ce_iface_clk = NULL;
+	mc_ce_bus_clk = NULL;
+
+	return ret;
+}
+
+void mc_pm_clock_finalize(void)
+{
+	if (mc_ce_iface_clk != NULL)
+		clk_put(mc_ce_iface_clk);
+
+	if (mc_ce_core_clk != NULL)
+		clk_put(mc_ce_core_clk);
+
+	if (mc_ce_bus_clk != NULL)
+		clk_put(mc_ce_bus_clk);
+}
+
+int mc_pm_clock_enable(void)
+{
+	int rc = 0;
+
+	rc = clk_prepare_enable(mc_ce_core_clk);
+	if (rc) {
+		MCDRV_DBG_ERROR(mcd, "cannot enable clock\n");
+	} else {
+		rc = clk_prepare_enable(mc_ce_iface_clk);
+		if (rc) {
+			clk_disable_unprepare(mc_ce_core_clk);
+			MCDRV_DBG_ERROR(mcd, "cannot enable clock\n");
+		} else {
+			rc = clk_prepare_enable(mc_ce_bus_clk);
+			if (rc) {
+				clk_disable_unprepare(mc_ce_iface_clk);
+				MCDRV_DBG_ERROR(mcd, "cannot enable clock\n");
+			}
+		}
+	}
+	return rc;
+}
+
+void mc_pm_clock_disable(void)
+{
+	if (mc_ce_iface_clk != NULL)
+		clk_disable_unprepare(mc_ce_iface_clk);
+
+	if (mc_ce_core_clk != NULL)
+		clk_disable_unprepare(mc_ce_core_clk);
+
+	if (mc_ce_bus_clk != NULL)
+		clk_disable_unprepare(mc_ce_bus_clk);
+}
+
+#endif /* MC_CRYPTO_CLOCK_MANAGEMENT */
diff --git a/drivers/gud/mobicore_driver/pm.h b/drivers/gud/mobicore_driver/pm.h
index 3e73b8b..332da34 100644
--- a/drivers/gud/mobicore_driver/pm.h
+++ b/drivers/gud/mobicore_driver/pm.h
@@ -31,5 +31,13 @@
 int mc_pm_initialize(struct mc_context *context);
 /* Free all Power Management resources*/
 int mc_pm_free(void);
+/* Initialize secure crypto clocks */
+int mc_pm_clock_initialize(void);
+/* Free secure crypto clocks */
+void mc_pm_clock_finalize(void);
+/* Enable secure crypto clocks */
+int mc_pm_clock_enable(void);
+/* Disable secure crypto clocks */
+void mc_pm_clock_disable(void);
 
 #endif /* _MC_PM_H_ */
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
index f74f2d5..d43bfbe 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, The Linux Foundation. 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
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/input/ft5x06_ts.h>
 
@@ -51,6 +52,7 @@
 #define POINT_READ_BUF	(3 + FT_TOUCH_STEP * CFG_MAX_TOUCH_POINTS)
 
 /*register address*/
+#define FT5X06_REG_ID		0xA3
 #define FT5X06_REG_PMODE	0xA5
 #define FT5X06_REG_FW_VER	0xA6
 #define FT5X06_REG_POINT_RATE	0x88
@@ -67,6 +69,9 @@
 #define FT5X06_I2C_VTG_MIN_UV	1800000
 #define FT5X06_I2C_VTG_MAX_UV	1800000
 
+#define FT5X06_COORDS_ARR_SIZE	4
+#define MAX_BUTTONS		4
+
 struct ts_event {
 	u16 x[CFG_MAX_TOUCH_POINTS];	/*x coordinate */
 	u16 y[CFG_MAX_TOUCH_POINTS];	/*y coordinate */
@@ -398,16 +403,139 @@
 };
 #endif
 
+#ifdef CONFIG_OF
+static int ft5x06_get_dt_coords(struct device *dev, char *name,
+				struct ft5x06_ts_platform_data *pdata)
+{
+	u32 coords[FT5X06_COORDS_ARR_SIZE];
+	struct property *prop;
+	struct device_node *np = dev->of_node;
+	int coords_size, rc;
+
+	prop = of_find_property(np, name, NULL);
+	if (!prop)
+		return -EINVAL;
+	if (!prop->value)
+		return -ENODATA;
+
+	coords_size = prop->length / sizeof(u32);
+	if (coords_size != FT5X06_COORDS_ARR_SIZE) {
+		dev_err(dev, "invalid %s\n", name);
+		return -EINVAL;
+	}
+
+	rc = of_property_read_u32_array(np, name, coords, coords_size);
+	if (rc && (rc != -EINVAL)) {
+		dev_err(dev, "Unable to read %s\n", name);
+		return rc;
+	}
+
+	if (!strcmp(name, "focaltech,panel-coords")) {
+		pdata->panel_minx = coords[0];
+		pdata->panel_miny = coords[1];
+		pdata->panel_maxx = coords[2];
+		pdata->panel_maxy = coords[3];
+	} else if (!strcmp(name, "focaltech,display-coords")) {
+		pdata->x_min = coords[0];
+		pdata->y_min = coords[1];
+		pdata->x_max = coords[2];
+		pdata->y_max = coords[3];
+	} else {
+		dev_err(dev, "unsupported property %s\n", name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ft5x06_parse_dt(struct device *dev,
+			struct ft5x06_ts_platform_data *pdata)
+{
+	int rc;
+	struct device_node *np = dev->of_node;
+	struct property *prop;
+	u32 temp_val, num_buttons;
+	u32 button_map[MAX_BUTTONS];
+
+	rc = ft5x06_get_dt_coords(dev, "focaltech,panel-coords", pdata);
+	if (rc && (rc != -EINVAL))
+		return rc;
+
+	rc = ft5x06_get_dt_coords(dev, "focaltech,display-coords", pdata);
+	if (rc)
+		return rc;
+
+	pdata->i2c_pull_up = of_property_read_bool(np,
+						"focaltech,i2c-pull-up");
+
+	pdata->no_force_update = of_property_read_bool(np,
+						"focaltech,no-force-update");
+	/* reset, irq gpio info */
+	pdata->reset_gpio = of_get_named_gpio_flags(np, "focaltech,reset-gpio",
+				0, &pdata->reset_gpio_flags);
+	if (pdata->reset_gpio < 0)
+		return pdata->reset_gpio;
+
+	pdata->irq_gpio = of_get_named_gpio_flags(np, "focaltech,irq-gpio",
+				0, &pdata->irq_gpio_flags);
+	if (pdata->irq_gpio < 0)
+		return pdata->irq_gpio;
+
+	rc = of_property_read_u32(np, "focaltech,family-id", &temp_val);
+	if (!rc)
+		pdata->family_id = temp_val;
+	else
+		return rc;
+
+	prop = of_find_property(np, "focaltech,button-map", NULL);
+	if (prop) {
+		num_buttons = prop->length / sizeof(temp_val);
+		if (num_buttons > MAX_BUTTONS)
+			return -EINVAL;
+
+		rc = of_property_read_u32_array(np,
+			"focaltech,button-map", button_map,
+			num_buttons);
+		if (rc) {
+			dev_err(dev, "Unable to read key codes\n");
+			return rc;
+		}
+	}
+
+	return 0;
+}
+#else
+static int ft5x06_parse_dt(struct device *dev,
+			struct ft5x06_ts_platform_data *pdata)
+{
+	return -ENODEV;
+}
+#endif
+
 static int ft5x06_ts_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id)
 {
-	const struct ft5x06_ts_platform_data *pdata = client->dev.platform_data;
+	struct ft5x06_ts_platform_data *pdata;
 	struct ft5x06_ts_data *data;
 	struct input_dev *input_dev;
 	u8 reg_value;
 	u8 reg_addr;
 	int err;
 
+	if (client->dev.of_node) {
+		pdata = devm_kzalloc(&client->dev,
+			sizeof(struct ft5x06_ts_platform_data), GFP_KERNEL);
+		if (!pdata) {
+			dev_err(&client->dev, "Failed to allocate memory\n");
+			return -ENOMEM;
+		}
+
+		err = ft5x06_parse_dt(&client->dev, pdata);
+		if (err)
+			return err;
+	} else
+		pdata = client->dev.platform_data;
+
 	if (!pdata) {
 		dev_err(&client->dev, "Invalid pdata\n");
 		return -EINVAL;
@@ -447,9 +575,9 @@
 	__set_bit(BTN_TOUCH, input_dev->keybit);
 	__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
 
-	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
+	input_set_abs_params(input_dev, ABS_MT_POSITION_X, pdata->x_min,
 			     pdata->x_max, 0, 0);
-	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
+	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, pdata->y_min,
 			     pdata->y_max, 0, 0);
 	input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
 			     CFG_MAX_TOUCH_POINTS, 0, 0);
@@ -524,6 +652,19 @@
 	/* make sure CTP already finish startup process */
 	msleep(FT_STARTUP_DLY);
 
+	/* check the controller id */
+	reg_addr = FT5X06_REG_ID;
+	err = ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
+	if (err < 0) {
+		dev_err(&client->dev, "version read failed");
+		return err;
+	}
+
+	if (pdata->family_id != reg_value) {
+		dev_err(&client->dev, "%s:Unsupported controller\n", __func__);
+		goto free_reset_gpio;
+	}
+
 	/*get some register information */
 	reg_addr = FT5X06_REG_FW_VER;
 	err = ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
@@ -626,12 +767,22 @@
 
 MODULE_DEVICE_TABLE(i2c, ft5x06_ts_id);
 
+#ifdef CONFIG_OF
+static struct of_device_id ft5x06_match_table[] = {
+	{ .compatible = "focaltech,5x06",},
+	{ },
+};
+#else
+#define ft5x06_match_table NULL
+#endif
+
 static struct i2c_driver ft5x06_ts_driver = {
 	.probe = ft5x06_ts_probe,
 	.remove = __devexit_p(ft5x06_ts_remove),
 	.driver = {
 		   .name = "ft5x06_ts",
 		   .owner = THIS_MODULE,
+		.of_match_table = ft5x06_match_table,
 #ifdef CONFIG_PM
 		   .pm = &ft5x06_ts_pm_ops,
 #endif
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
index ba94178..b9dd4ae 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -114,6 +114,12 @@
 static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count);
 
+static ssize_t synaptics_rmi4_mode_suspend_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t synaptics_rmi4_mode_resume_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
 #if defined(CONFIG_FB)
 static int fb_notifier_callback(struct notifier_block *self,
 				unsigned long event, void *data);
@@ -237,6 +243,12 @@
 	__ATTR(full_pm_cycle, (S_IRUGO | S_IWUGO),
 			synaptics_rmi4_full_pm_cycle_show,
 			synaptics_rmi4_full_pm_cycle_store),
+	__ATTR(mode_suspend, S_IWUGO,
+			synaptics_rmi4_show_error,
+			synaptics_rmi4_mode_suspend_store),
+	__ATTR(mode_resume, S_IWUGO,
+			synaptics_rmi4_show_error,
+			synaptics_rmi4_mode_resume_store),
 #endif
 	__ATTR(reset, S_IWUGO,
 			synaptics_rmi4_show_error,
@@ -288,6 +300,34 @@
 	return count;
 }
 
+static ssize_t synaptics_rmi4_mode_suspend_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;
+
+	synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev));
+
+	return count;
+}
+
+static ssize_t synaptics_rmi4_mode_resume_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;
+
+	synaptics_rmi4_resume(&(rmi4_data->input_dev->dev));
+
+	return count;
+}
+
 #ifdef CONFIG_FB
 static void configure_sleep(struct synaptics_rmi4_data *rmi4_data)
 {
@@ -1031,8 +1071,6 @@
 
 	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");
 
@@ -1865,25 +1903,23 @@
 	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);
-		}
+	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 (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;
 		}
 	}
 
@@ -1915,22 +1951,18 @@
 	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);
+	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);
+	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 (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,
@@ -1947,23 +1979,21 @@
 	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 = 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;
-		}
+	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) {
@@ -1990,18 +2020,14 @@
 	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);
+	regulator_disable(rmi4_data->vdd);
 error_reg_en_vdd:
-	if (rmi4_data->board->regulator_en)
-		reg_set_optimum_mode_check(rmi4_data->vdd, 0);
+	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);
-	}
+	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);
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index aa69475..6324dff 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -14,12 +14,32 @@
 if IOMMU_SUPPORT
 
 # MSM IOMMU support
+
+# MSM_IOMMU always gets selected by whoever wants it.
 config MSM_IOMMU
-	bool "MSM IOMMU Support"
-	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8974 || ARCH_MPQ8092 || ARCH_MSM8610 || ARCH_MSM8226 || ARCH_APQ8084
+	bool
+
+# MSM IOMMUv0 support
+config MSM_IOMMU_V0
+	bool "MSM IOMMUv0 Support"
+	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8610
 	select IOMMU_API
+	select MSM_IOMMU
 	help
-	  Support for the IOMMUs found on certain Qualcomm SOCs.
+	  Support for the IOMMUs (v0) found on certain Qualcomm SOCs.
+	  These IOMMUs allow virtualization of the address space used by most
+	  cores within the multimedia subsystem.
+
+	  If unsure, say N here.
+
+# MSM IOMMUv1 support
+config MSM_IOMMU_V1
+	bool "MSM IOMMUv1 Support"
+	depends on ARCH_MSM8974 || ARCH_MPQ8092 || ARCH_MSM8226 || ARCH_APQ8084
+	select IOMMU_API
+	select MSM_IOMMU
+	help
+	  Support for the IOMMUs (v1) found on certain Qualcomm SOCs.
 	  These IOMMUs allow virtualization of the address space used by most
 	  cores within the multimedia subsystem.
 
@@ -28,7 +48,7 @@
 # MSM IOMMU CPU-GPU sync programming support
 config MSM_IOMMU_GPU_SYNC
 	bool "MSM IOMMU CPU-GPU Sync Support"
-	depends on (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8930) && MSM_IOMMU && MSM_REMOTE_SPINLOCK_SFPB
+	depends on (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8930) && MSM_IOMMU_V0 && MSM_REMOTE_SPINLOCK_SFPB
 	help
 	  Say Y here if you want to synchronize access to IOMMU configuration
 	  port between CPU and GPU. CPU will grab a remote spinlock before
@@ -55,6 +75,20 @@
          section mappings and TLB misses should be quite infrequent.
          Most people can probably say Y here.
 
+config IOMMU_NON_SECURE
+	bool "Turns on programming of secure SMMU by kernel"
+	depends on MSM_IOMMU
+        help
+         Say Y here if you want the kernel to program all SMMUs regardless of
+         whether SMMUs are secure or not. A secure SMMU is an SMMU that has
+         its global address space programmed by the secure environment. In
+         addition some of the context banks might be owned/programmed by the
+         secure environment for a secure SMMU. Enabling this feature can be
+         used during testing when the secure environment is not available
+         and the kernel needs to program all the SMMUs.
+
+         If unsure, say N here.
+
 # AMD IOMMU support
 config AMD_IOMMU
 	bool "AMD IOMMU support"
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 096b53e..29a8b39 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -1,9 +1,14 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
-obj-$(CONFIG_MSM_IOMMU) += msm_iommu-v0.o msm_iommu_dev-v0.o
-ifdef CONFIG_OF
-obj-$(CONFIG_MSM_IOMMU) += msm_iommu-v1.o msm_iommu_dev-v1.o msm_iommu_pagetable.o msm_iommu_sec.o
+obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
+obj-$(CONFIG_MSM_IOMMU_V0) += msm_iommu-v0.o msm_iommu_dev-v0.o
+obj-$(CONFIG_MSM_IOMMU_V1) += msm_iommu-v1.o msm_iommu_dev-v1.o msm_iommu_pagetable.o msm_iommu_sec.o
+obj-$(CONFIG_MSM_IOMMU_PMON) += msm_iommu_perfmon.o
+ifdef CONFIG_MSM_IOMMU_V0
+obj-$(CONFIG_MSM_IOMMU_PMON) += msm_iommu_perfmon-v0.o
 endif
-obj-$(CONFIG_MSM_IOMMU_PMON) += msm_iommu_perfmon.o msm_iommu_perfmon-v0.o msm_iommu_perfmon-v1.o
+ifdef CONFIG_MSM_IOMMU_V1
+obj-$(CONFIG_MSM_IOMMU_PMON) += msm_iommu_perfmon-v1.o
+endif
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
diff --git a/drivers/iommu/msm_iommu-v0.c b/drivers/iommu/msm_iommu-v0.c
index eadbd64..49bfdb8 100644
--- a/drivers/iommu/msm_iommu-v0.c
+++ b/drivers/iommu/msm_iommu-v0.c
@@ -52,10 +52,6 @@
 #define MSM_IOMMU_ATTR_CACHED_WB_NWA	0x2
 #define MSM_IOMMU_ATTR_CACHED_WT	0x3
 
-struct bus_type msm_iommu_sec_bus_type = {
-	.name = "msm_iommu_sec_bus",
-};
-
 static int msm_iommu_unmap_range(struct iommu_domain *domain, unsigned int va,
 				 unsigned int len);
 
@@ -224,7 +220,6 @@
 	.iommu_lock_acquire = _iommu_lock_acquire,
 	.iommu_lock_release = _iommu_lock_release,
 };
-EXPORT_SYMBOL(iommu_access_ops_v0);
 
 static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va)
 {
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index 5ee8794..653487b 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -42,15 +42,18 @@
 
 static int __enable_regulators(struct msm_iommu_drvdata *drvdata)
 {
-	int ret = regulator_enable(drvdata->gdsc);
-	if (ret)
-		goto fail;
+	int ret = 0;
+	if (drvdata->gdsc) {
+		ret = regulator_enable(drvdata->gdsc);
+		if (ret)
+			goto fail;
 
-	if (drvdata->alt_gdsc)
-		ret = regulator_enable(drvdata->alt_gdsc);
+		if (drvdata->alt_gdsc)
+			ret = regulator_enable(drvdata->alt_gdsc);
 
-	if (ret)
-		regulator_disable(drvdata->gdsc);
+		if (ret)
+			regulator_disable(drvdata->gdsc);
+	}
 fail:
 	return ret;
 }
@@ -60,7 +63,8 @@
 	if (drvdata->alt_gdsc)
 		regulator_disable(drvdata->alt_gdsc);
 
-	regulator_disable(drvdata->gdsc);
+	if (drvdata->gdsc)
+		regulator_disable(drvdata->gdsc);
 }
 
 static int apply_bus_vote(struct msm_iommu_drvdata *drvdata, unsigned int vote)
@@ -137,7 +141,6 @@
 	.iommu_lock_acquire = _iommu_lock_acquire,
 	.iommu_lock_release = _iommu_lock_release,
 };
-EXPORT_SYMBOL(iommu_access_ops_v1);
 
 void iommu_halt(const struct msm_iommu_drvdata *iommu_drvdata)
 {
@@ -256,12 +259,46 @@
 	mb();
 }
 
+#ifdef CONFIG_IOMMU_NON_SECURE
+static void __reset_iommu_secure(void __iomem *base)
+{
+	SET_NSACR(base, 0);
+	SET_NSCR2(base, 0);
+	SET_NSGFAR(base, 0);
+	SET_NSGFSRRESTORE(base, 0);
+	mb();
+}
+
+static void __program_iommu_secure(void __iomem *base)
+{
+	SET_NSCR0_SMCFCFG(base, 1);
+	SET_NSCR0_USFCFG(base, 1);
+	SET_NSCR0_STALLD(base, 1);
+	SET_NSCR0_GCFGFIE(base, 1);
+	SET_NSCR0_GCFGFRE(base, 1);
+	SET_NSCR0_GFIE(base, 1);
+	SET_NSCR0_GFRE(base, 1);
+	SET_NSCR0_CLIENTPD(base, 0);
+}
+
+#else
+static inline void __reset_iommu_secure(void __iomem *base)
+{
+}
+
+static inline void __program_iommu_secure(void __iomem *base)
+{
+}
+
+#endif
+
 /*
  * May only be called for non-secure iommus
  */
 static void __program_iommu(void __iomem *base)
 {
 	__reset_iommu(base);
+	__reset_iommu_secure(base);
 
 	SET_CR0_SMCFCFG(base, 1);
 	SET_CR0_USFCFG(base, 1);
@@ -272,6 +309,8 @@
 	SET_CR0_GFRE(base, 1);
 	SET_CR0_CLIENTPD(base, 0);
 
+	__program_iommu_secure(base);
+
 	mb(); /* Make sure writes complete before returning */
 }
 
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
new file mode 100644
index 0000000..ebecd11
--- /dev/null
+++ b/drivers/iommu/msm_iommu.c
@@ -0,0 +1,97 @@
+/* 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.
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/export.h>
+#include <linux/iommu.h>
+#include <mach/iommu.h>
+
+static DEFINE_MUTEX(iommu_list_lock);
+static LIST_HEAD(iommu_list);
+
+static struct iommu_access_ops *iommu_access_ops;
+
+struct bus_type msm_iommu_sec_bus_type = {
+	.name = "msm_iommu_sec_bus",
+};
+
+void msm_set_iommu_access_ops(struct iommu_access_ops *ops)
+{
+	iommu_access_ops = ops;
+}
+
+struct iommu_access_ops *msm_get_iommu_access_ops()
+{
+	BUG_ON(iommu_access_ops == NULL);
+	return iommu_access_ops;
+}
+EXPORT_SYMBOL(msm_get_iommu_access_ops);
+
+void msm_iommu_add_drv(struct msm_iommu_drvdata *drv)
+{
+	mutex_lock(&iommu_list_lock);
+	list_add(&drv->list, &iommu_list);
+	mutex_unlock(&iommu_list_lock);
+}
+
+void msm_iommu_remove_drv(struct msm_iommu_drvdata *drv)
+{
+	mutex_lock(&iommu_list_lock);
+	list_del(&drv->list);
+	mutex_unlock(&iommu_list_lock);
+}
+
+static int find_iommu_ctx(struct device *dev, void *data)
+{
+	struct msm_iommu_ctx_drvdata *c;
+
+	c = dev_get_drvdata(dev);
+	if (!c || !c->name)
+		return 0;
+
+	return !strcmp(data, c->name);
+}
+
+static struct device *find_context(struct device *dev, const char *name)
+{
+	return device_find_child(dev, (void *)name, find_iommu_ctx);
+}
+
+struct device *msm_iommu_get_ctx(const char *ctx_name)
+{
+	struct msm_iommu_drvdata *drv;
+	struct device *dev = NULL;
+
+	mutex_lock(&iommu_list_lock);
+	list_for_each_entry(drv, &iommu_list, list) {
+		dev = find_context(drv->dev, ctx_name);
+		if (dev)
+			break;
+	}
+	mutex_unlock(&iommu_list_lock);
+
+	put_device(dev);
+
+	if (!dev || !dev_get_drvdata(dev)) {
+		pr_debug("Could not find context <%s>\n", ctx_name);
+		dev = ERR_PTR(-EPROBE_DEFER);
+	}
+
+	return dev;
+}
+EXPORT_SYMBOL(msm_iommu_get_ctx);
+
diff --git a/drivers/iommu/msm_iommu_dev-v0.c b/drivers/iommu/msm_iommu_dev-v0.c
index 4ee65d8..2d0fba2 100644
--- a/drivers/iommu/msm_iommu_dev-v0.c
+++ b/drivers/iommu/msm_iommu_dev-v0.c
@@ -32,64 +32,8 @@
 #include <mach/iommu.h>
 #include <mach/msm_bus.h>
 
-static DEFINE_MUTEX(iommu_list_lock);
-static LIST_HEAD(iommu_list);
-
 static struct of_device_id msm_iommu_v0_ctx_match_table[];
-
-void msm_iommu_add_drv(struct msm_iommu_drvdata *drv)
-{
-	mutex_lock(&iommu_list_lock);
-	list_add(&drv->list, &iommu_list);
-	mutex_unlock(&iommu_list_lock);
-}
-
-void msm_iommu_remove_drv(struct msm_iommu_drvdata *drv)
-{
-	mutex_lock(&iommu_list_lock);
-	list_del(&drv->list);
-	mutex_unlock(&iommu_list_lock);
-}
-
-static int find_iommu_ctx(struct device *dev, void *data)
-{
-	struct msm_iommu_ctx_drvdata *c;
-
-	c = dev_get_drvdata(dev);
-	if (!c || !c->name)
-		return 0;
-
-	return !strcmp(data, c->name);
-}
-
-static struct device *find_context(struct device *dev, const char *name)
-{
-	return device_find_child(dev, (void *)name, find_iommu_ctx);
-}
-
-struct device *msm_iommu_get_ctx(const char *ctx_name)
-{
-	struct msm_iommu_drvdata *drv;
-	struct device *dev = NULL;
-
-	mutex_lock(&iommu_list_lock);
-	list_for_each_entry(drv, &iommu_list, list) {
-		dev = find_context(drv->dev, ctx_name);
-		if (dev)
-			break;
-	}
-	mutex_unlock(&iommu_list_lock);
-
-	put_device(dev);
-
-	if (!dev || !dev_get_drvdata(dev)) {
-		pr_debug("Could not find context <%s>\n", ctx_name);
-		dev = ERR_PTR(-EPROBE_DEFER);
-	}
-
-	return dev;
-}
-EXPORT_SYMBOL(msm_iommu_get_ctx);
+static struct iommu_access_ops *msm_iommu_access_ops;
 
 static void msm_iommu_reset(void __iomem *base, void __iomem *glb_base, int ncb)
 {
@@ -454,7 +398,7 @@
 
 	drvdata->dev = &pdev->dev;
 
-	iommu_access_ops_v0.iommu_clk_on(drvdata);
+	msm_iommu_access_ops->iommu_clk_on(drvdata);
 
 	msm_iommu_reset(drvdata->base, drvdata->glb_base, drvdata->ncb);
 
@@ -462,7 +406,7 @@
 	if (ret)
 		goto fail_clk;
 
-	iommu_access_ops_v0.iommu_clk_off(drvdata);
+	msm_iommu_access_ops->iommu_clk_off(drvdata);
 
 	pr_info("device %s mapped at %p, with %d ctx banks\n",
 		drvdata->name, drvdata->base, drvdata->ncb);
@@ -478,7 +422,7 @@
 			pr_info("%s: pmon not available.\n", drvdata->name);
 		} else {
 			pmon_info->iommu.base = drvdata->base;
-			pmon_info->iommu.ops = &iommu_access_ops_v0;
+			pmon_info->iommu.ops = msm_iommu_access_ops;
 			pmon_info->iommu.hw_ops = iommu_pm_get_hw_ops_v0();
 			pmon_info->iommu.iommu_name = drvdata->name;
 			pmon_info->iommu.always_on = 1;
@@ -497,7 +441,7 @@
 	return 0;
 
 fail_clk:
-	iommu_access_ops_v0.iommu_clk_off(drvdata);
+	msm_iommu_access_ops->iommu_clk_off(drvdata);
 fail:
 	__put_bus_vote_client(drvdata);
 fail_mem:
@@ -697,9 +641,9 @@
 		goto fail;
 	}
 
-	iommu_access_ops_v0.iommu_clk_on(drvdata);
+	msm_iommu_access_ops->iommu_clk_on(drvdata);
 	__program_m2v_tables(drvdata, ctx_drvdata);
-	iommu_access_ops_v0.iommu_clk_off(drvdata);
+	msm_iommu_access_ops->iommu_clk_off(drvdata);
 
 	dev_info(&pdev->dev, "context %s using bank %d\n", ctx_drvdata->name,
 							   ctx_drvdata->num);
@@ -746,6 +690,11 @@
 static int __init msm_iommu_driver_init(void)
 {
 	int ret;
+
+	if (msm_soc_version_supports_iommu_v0()) {
+		msm_set_iommu_access_ops(&iommu_access_ops_v0);
+		msm_iommu_access_ops = msm_get_iommu_access_ops();
+	}
 	ret = platform_driver_register(&msm_iommu_driver);
 	if (ret != 0) {
 		pr_err("Failed to register IOMMU driver\n");
diff --git a/drivers/iommu/msm_iommu_dev-v1.c b/drivers/iommu/msm_iommu_dev-v1.c
index 958b7b1..119a126 100644
--- a/drivers/iommu/msm_iommu_dev-v1.c
+++ b/drivers/iommu/msm_iommu_dev-v1.c
@@ -115,8 +115,35 @@
 static void __put_bus_vote_client(struct msm_iommu_drvdata *drvdata)
 {
 	msm_bus_scale_unregister_client(drvdata->bus_client);
+	drvdata->bus_client = 0;
 }
 
+#ifdef CONFIG_IOMMU_NON_SECURE
+static inline void get_secure_id(struct device_node *node,
+			  struct msm_iommu_drvdata *drvdata)
+{
+}
+
+static inline void get_secure_ctx(struct device_node *node,
+				  struct msm_iommu_ctx_drvdata *ctx_drvdata)
+{
+	ctx_drvdata->secure_context = 0;
+}
+#else
+static void get_secure_id(struct device_node *node,
+			  struct msm_iommu_drvdata *drvdata)
+{
+	of_property_read_u32(node, "qcom,iommu-secure-id", &drvdata->sec_id);
+}
+
+static void get_secure_ctx(struct device_node *node,
+			   struct msm_iommu_ctx_drvdata *ctx_drvdata)
+{
+	ctx_drvdata->secure_context =
+			of_property_read_bool(node, "qcom,secure-context");
+}
+#endif
+
 static int msm_iommu_parse_dt(struct platform_device *pdev,
 				struct msm_iommu_drvdata *drvdata)
 {
@@ -153,8 +180,7 @@
 		goto fail;
 
 	drvdata->sec_id = -1;
-	of_property_read_u32(pdev->dev.of_node, "qcom,iommu-secure-id",
-				&drvdata->sec_id);
+	get_secure_id(pdev->dev.of_node, drvdata);
 
 	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clk_base");
 	if (r) {
@@ -263,13 +289,19 @@
 
 	drvdata->glb_base = drvdata->base;
 
-	drvdata->gdsc = devm_regulator_get(&pdev->dev, "vdd");
-	if (IS_ERR(drvdata->gdsc))
-		return PTR_ERR(drvdata->gdsc);
+	if (of_get_property(pdev->dev.of_node, "vdd-supply", NULL)) {
 
-	drvdata->alt_gdsc = devm_regulator_get(&pdev->dev, "qcom,alt-vdd");
-	if (IS_ERR(drvdata->alt_gdsc))
-		drvdata->alt_gdsc = NULL;
+		drvdata->gdsc = devm_regulator_get(&pdev->dev, "vdd");
+		if (IS_ERR(drvdata->gdsc))
+			return PTR_ERR(drvdata->gdsc);
+
+		drvdata->alt_gdsc = devm_regulator_get(&pdev->dev,
+							"qcom,alt-vdd");
+		if (IS_ERR(drvdata->alt_gdsc))
+			drvdata->alt_gdsc = NULL;
+	} else {
+		pr_debug("Warning: No regulator specified for IOMMU\n");
+	}
 
 	drvdata->pclk = devm_clk_get(&pdev->dev, "iface_clk");
 	if (IS_ERR(drvdata->pclk))
@@ -306,8 +338,6 @@
 
 	platform_set_drvdata(pdev, drvdata);
 
-	msm_iommu_sec_set_access_ops(&iommu_access_ops_v1);
-
 	pmon_info = msm_iommu_pm_alloc(&pdev->dev);
 	if (pmon_info != NULL) {
 		ret = msm_iommu_pmon_parse_dt(pdev, pmon_info);
@@ -316,7 +346,7 @@
 			pr_info("%s: pmon not available.\n", drvdata->name);
 		} else {
 			pmon_info->iommu.base = drvdata->base;
-			pmon_info->iommu.ops = &iommu_access_ops_v1;
+			pmon_info->iommu.ops = msm_get_iommu_access_ops();
 			pmon_info->iommu.hw_ops = iommu_pm_get_hw_ops_v1();
 			pmon_info->iommu.iommu_name = drvdata->name;
 			ret = msm_iommu_pm_iommu_register(pmon_info);
@@ -356,8 +386,7 @@
 	int irq = 0, ret = 0;
 	u32 nsid;
 
-	ctx_drvdata->secure_context = of_property_read_bool(pdev->dev.of_node,
-							"qcom,secure-context");
+	get_secure_ctx(pdev->dev.of_node, ctx_drvdata);
 
 	if (ctx_drvdata->secure_context) {
 		irq = platform_get_irq(pdev, 1);
@@ -495,6 +524,10 @@
 {
 	int ret;
 
+	if (!msm_soc_version_supports_iommu_v0()) {
+		msm_set_iommu_access_ops(&iommu_access_ops_v1);
+		msm_iommu_sec_set_access_ops(&iommu_access_ops_v1);
+	}
 	ret = platform_driver_register(&msm_iommu_driver);
 	if (ret != 0) {
 		pr_err("Failed to register IOMMU driver\n");
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index 2ea7128..4835d62 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -308,6 +308,7 @@
 	struct pwm_duty_cycles	*duty_cycles;
 	u8	mode;
 	u8	enable;
+	bool use_blink;
 };
 
 /**
@@ -1283,8 +1284,122 @@
 	return count;
 }
 
+static int qpnp_pwm_init(struct pwm_config_data *pwm_cfg,
+					struct spmi_device *spmi_dev,
+					const char *name)
+{
+	int rc, start_idx, idx_len;
+
+	if (pwm_cfg->pwm_channel != -1) {
+		pwm_cfg->pwm_dev =
+			pwm_request(pwm_cfg->pwm_channel, name);
+
+		if (IS_ERR_OR_NULL(pwm_cfg->pwm_dev)) {
+			dev_err(&spmi_dev->dev,
+				"could not acquire PWM Channel %d, " \
+				"error %ld\n",
+				pwm_cfg->pwm_channel,
+				PTR_ERR(pwm_cfg->pwm_dev));
+			pwm_cfg->pwm_dev = NULL;
+			return -ENODEV;
+		}
+
+		if (pwm_cfg->mode == LPG_MODE) {
+			start_idx =
+			pwm_cfg->duty_cycles->start_idx;
+			idx_len =
+			pwm_cfg->duty_cycles->num_duty_pcts;
+
+			if (idx_len >= PWM_LUT_MAX_SIZE &&
+					start_idx) {
+				dev_err(&spmi_dev->dev,
+					"Wrong LUT size or index\n");
+				return -EINVAL;
+			}
+			if ((start_idx + idx_len) >
+					PWM_LUT_MAX_SIZE) {
+				dev_err(&spmi_dev->dev,
+					"Exceed LUT limit\n");
+				return -EINVAL;
+			}
+			rc = pwm_lut_config(pwm_cfg->pwm_dev,
+				PM_PWM_PERIOD_MIN, /* ignored by hardware */
+				pwm_cfg->duty_cycles->duty_pcts,
+				pwm_cfg->lut_params);
+			if (rc < 0) {
+				dev_err(&spmi_dev->dev, "Failed to " \
+					"configure pwm LUT\n");
+				return rc;
+			}
+		}
+	} else {
+		dev_err(&spmi_dev->dev,
+			"Invalid PWM channel\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void led_blink(struct qpnp_led_data *led,
+			struct pwm_config_data *pwm_cfg)
+{
+	u8 previous_mode;
+
+	previous_mode = pwm_cfg->mode;
+	if (pwm_cfg->use_blink) {
+		if (led->cdev.brightness) {
+			if (led->id == QPNP_ID_LED_MPP)
+				led->mpp_cfg->pwm_mode = LPG_MODE;
+			pwm_cfg->mode = LPG_MODE;
+			pwm_free(pwm_cfg->pwm_dev);
+			qpnp_pwm_init(pwm_cfg, led->spmi_dev, led->cdev.name);
+			qpnp_led_set(&led->cdev, led->cdev.brightness);
+			if (led->id == QPNP_ID_LED_MPP)
+				led->mpp_cfg->pwm_mode = previous_mode;
+			pwm_cfg->mode = previous_mode;
+		} else {
+			pwm_free(pwm_cfg->pwm_dev);
+			qpnp_pwm_init(pwm_cfg, led->spmi_dev, led->cdev.name);
+			qpnp_led_set(&led->cdev, led->cdev.brightness);
+		}
+	}
+}
+
+static ssize_t blink_store(struct device *dev,
+	struct device_attribute *attr,
+	const char *buf, size_t count)
+{
+	struct qpnp_led_data *led;
+	unsigned long blinking;
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	ssize_t ret = -EINVAL;
+
+	ret = kstrtoul(buf, 10, &blinking);
+	if (ret)
+		return ret;
+	led = container_of(led_cdev, struct qpnp_led_data, cdev);
+	led->cdev.brightness = blinking ? led->cdev.max_brightness : 0;
+
+	switch (led->id) {
+	case QPNP_ID_LED_MPP:
+		led_blink(led, led->mpp_cfg->pwm_cfg);
+		break;
+	case QPNP_ID_RGB_RED:
+	case QPNP_ID_RGB_GREEN:
+	case QPNP_ID_RGB_BLUE:
+		led_blink(led, led->rgb_cfg->pwm_cfg);
+		break;
+	default:
+		dev_err(&led->spmi_dev->dev, "Invalid LED id type for blink\n");
+		return -EINVAL;
+	}
+	return count;
+}
+
 static DEVICE_ATTR(led_mode, 0664, NULL, led_mode_store);
 static DEVICE_ATTR(strobe, 0664, NULL, led_strobe_type_store);
+static DEVICE_ATTR(blink, 0664, NULL, blink_store);
 
 static struct attribute *led_attrs[] = {
 	&dev_attr_led_mode.attr,
@@ -1296,6 +1411,15 @@
 	.attrs = led_attrs,
 };
 
+static struct attribute *blink_attrs[] = {
+	&dev_attr_blink.attr,
+	NULL
+};
+
+static const struct attribute_group blink_attr_group = {
+	.attrs = blink_attrs,
+};
+
 static int __devinit qpnp_flash_init(struct qpnp_led_data *led)
 {
 	int rc;
@@ -1387,63 +1511,6 @@
 	return 0;
 }
 
-static int __devinit qpnp_pwm_init(struct pwm_config_data *pwm_cfg,
-					struct spmi_device *spmi_dev,
-					const char *name)
-{
-	int rc, start_idx, idx_len;
-
-	if (pwm_cfg->pwm_channel != -1) {
-		pwm_cfg->pwm_dev =
-			pwm_request(pwm_cfg->pwm_channel, name);
-
-		if (IS_ERR_OR_NULL(pwm_cfg->pwm_dev)) {
-			dev_err(&spmi_dev->dev,
-				"could not acquire PWM Channel %d, " \
-				"error %ld\n",
-				pwm_cfg->pwm_channel,
-				PTR_ERR(pwm_cfg->pwm_dev));
-			pwm_cfg->pwm_dev = NULL;
-			return -ENODEV;
-		}
-
-		if (pwm_cfg->mode == LPG_MODE) {
-			start_idx =
-			pwm_cfg->duty_cycles->start_idx;
-			idx_len =
-			pwm_cfg->duty_cycles->num_duty_pcts;
-
-			if (idx_len >= PWM_LUT_MAX_SIZE &&
-					start_idx) {
-				dev_err(&spmi_dev->dev,
-					"Wrong LUT size or index\n");
-				return -EINVAL;
-			}
-			if ((start_idx + idx_len) >
-					PWM_LUT_MAX_SIZE) {
-				dev_err(&spmi_dev->dev,
-					"Exceed LUT limit\n");
-				return -EINVAL;
-			}
-			rc = pwm_lut_config(pwm_cfg->pwm_dev,
-				PM_PWM_PERIOD_MIN, /* ignored by hardware */
-				pwm_cfg->duty_cycles->duty_pcts,
-				pwm_cfg->lut_params);
-			if (rc < 0) {
-				dev_err(&spmi_dev->dev, "Failed to " \
-					"configure pwm LUT\n");
-				return rc;
-			}
-		}
-	} else {
-		dev_err(&spmi_dev->dev,
-			"Invalid PWM channel\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 static int __devinit qpnp_kpdbl_init(struct qpnp_led_data *led)
 {
 	int rc;
@@ -1845,14 +1912,18 @@
 			return rc;
 	}
 
-	if (pwm_cfg->mode == LPG_MODE) {
+	pwm_cfg->use_blink =
+		of_property_read_bool(node, "qcom,use-blink");
+
+	if (pwm_cfg->mode == LPG_MODE || pwm_cfg->use_blink) {
 		pwm_cfg->duty_cycles =
 			devm_kzalloc(&spmi_dev->dev,
 			sizeof(struct pwm_duty_cycles), GFP_KERNEL);
 		if (!pwm_cfg->duty_cycles) {
 			dev_err(&spmi_dev->dev,
 				"Unable to allocate memory\n");
-			return -ENOMEM;
+			rc = -ENOMEM;
+			goto bad_lpg_params;
 		}
 
 		prop = of_find_property(node, "qcom,duty-pcts",
@@ -1860,11 +1931,13 @@
 		if (!prop) {
 			dev_err(&spmi_dev->dev, "Looking up property " \
 				"node qcom,duty-pcts failed\n");
-			return -ENODEV;
+			rc =  -ENODEV;
+			goto bad_lpg_params;
 		} else if (!pwm_cfg->duty_cycles->num_duty_pcts) {
 			dev_err(&spmi_dev->dev, "Invalid length of " \
 				"duty pcts\n");
-			return -EINVAL;
+			rc =  -EINVAL;
+			goto bad_lpg_params;
 		}
 
 		pwm_cfg->duty_cycles->duty_pcts =
@@ -1874,7 +1947,8 @@
 		if (!pwm_cfg->duty_cycles->duty_pcts) {
 			dev_err(&spmi_dev->dev,
 				"Unable to allocate memory\n");
-			return -ENOMEM;
+			rc =  -ENOMEM;
+			goto bad_lpg_params;
 		}
 
 		temp_cfg = devm_kzalloc(&spmi_dev->dev,
@@ -1883,7 +1957,8 @@
 		if (!temp_cfg) {
 			dev_err(&spmi_dev->dev, "Failed to allocate " \
 				"memory for duty pcts\n");
-			return -ENOMEM;
+			rc = -ENOMEM;
+			goto bad_lpg_params;
 		}
 
 		memcpy(temp_cfg, prop->value,
@@ -1898,21 +1973,21 @@
 			pwm_cfg->lut_params.start_idx = val;
 			pwm_cfg->duty_cycles->start_idx = val;
 		} else
-			return rc;
+			goto bad_lpg_params;
 
 		pwm_cfg->lut_params.lut_pause_hi = 0;
 		rc = of_property_read_u32(node, "qcom,pause-hi", &val);
 		if (!rc)
 			pwm_cfg->lut_params.lut_pause_hi = val;
 		else if (rc != -EINVAL)
-			return rc;
+			goto bad_lpg_params;
 
 		pwm_cfg->lut_params.lut_pause_lo = 0;
 		rc = of_property_read_u32(node, "qcom,pause-lo", &val);
 		if (!rc)
 			pwm_cfg->lut_params.lut_pause_lo = val;
 		else if (rc != -EINVAL)
-			return rc;
+			goto bad_lpg_params;
 
 		pwm_cfg->lut_params.ramp_step_ms =
 				QPNP_LUT_RAMP_STEP_DEFAULT;
@@ -1920,19 +1995,28 @@
 		if (!rc)
 			pwm_cfg->lut_params.ramp_step_ms = val;
 		else if (rc != -EINVAL)
-			return rc;
+			goto bad_lpg_params;
 
 		pwm_cfg->lut_params.flags = QPNP_LED_PWM_FLAGS;
 		rc = of_property_read_u32(node, "qcom,lut-flags", &val);
 		if (!rc)
 			pwm_cfg->lut_params.flags = (u8) val;
 		else if (rc != -EINVAL)
-			return rc;
+			goto bad_lpg_params;
 
 		pwm_cfg->lut_params.idx_len =
 			pwm_cfg->duty_cycles->num_duty_pcts;
 	}
 	return 0;
+
+bad_lpg_params:
+	pwm_cfg->use_blink = false;
+	if (pwm_cfg->mode == PWM_MODE) {
+		dev_err(&spmi_dev->dev, "LPG parameters not set for" \
+			" blink mode, defaulting to PWM mode\n");
+		return 0;
+	}
+	return rc;
 };
 
 static int qpnp_led_get_mode(const char *mode)
@@ -2273,6 +2357,26 @@
 
 		}
 
+		if (led->id == QPNP_ID_LED_MPP) {
+			if (!led->mpp_cfg->pwm_cfg)
+				break;
+			if (led->mpp_cfg->pwm_cfg->use_blink) {
+				rc = sysfs_create_group(&led->cdev.dev->kobj,
+					&blink_attr_group);
+				if (rc)
+					goto fail_id_check;
+			}
+		} else if ((led->id == QPNP_ID_RGB_RED) ||
+			(led->id == QPNP_ID_RGB_GREEN) ||
+			(led->id == QPNP_ID_RGB_BLUE)) {
+			if (led->rgb_cfg->pwm_cfg->use_blink) {
+				rc = sysfs_create_group(&led->cdev.dev->kobj,
+					&blink_attr_group);
+				if (rc)
+					goto fail_id_check;
+			}
+		}
+
 		/* configure default state */
 		if (led->default_on) {
 			led->cdev.brightness = led->cdev.max_brightness;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 74a920c..2a2656f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -420,7 +420,7 @@
 
 static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr,
 	uint32_t bufq_handle, uint32_t buf_index,
-	struct timeval *tv, uint32_t frame_id)
+	struct timeval *tv, uint32_t frame_id, uint32_t output_format)
 {
 	int rc = -1;
 	unsigned long flags;
@@ -467,6 +467,7 @@
 		} else {
 			buf_info->vb2_buf->v4l2_buf.timestamp = *tv;
 			buf_info->vb2_buf->v4l2_buf.sequence  = frame_id;
+			buf_info->vb2_buf->v4l2_buf.reserved = output_format;
 			buf_mgr->vb2_ops->buf_done(buf_info->vb2_buf,
 				bufq->session_id, bufq->stream_id);
 		}
@@ -577,7 +578,7 @@
 			else
 				rc = msm_isp_buf_done(buf_mgr,
 					info->handle, info->buf_idx,
-					buf_info->tv, buf_info->frame_id);
+					buf_info->tv, buf_info->frame_id, 0);
 		}
 	} else {
 		bufq = msm_isp_get_bufq(buf_mgr, info->handle);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
index fda1a57..6d6ff9d 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
@@ -108,7 +108,7 @@
 
 	int (*buf_done) (struct msm_isp_buf_mgr *buf_mgr,
 		uint32_t bufq_handle, uint32_t buf_index,
-		struct timeval *tv, uint32_t frame_id);
+		struct timeval *tv, uint32_t frame_id, uint32_t output_format);
 	int (*buf_divert) (struct msm_isp_buf_mgr *buf_mgr,
 		uint32_t bufq_handle, uint32_t buf_index,
 		struct timeval *tv, uint32_t frame_id);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
index ff9c9b8..2c5e136 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
@@ -38,6 +38,10 @@
 		.compatible = "qcom,vfe40",
 		.data = &vfe40_hw_info,
 	},
+	{
+		.compatible = "qcom,vfe32",
+		.data = &vfe32_hw_info,
+	},
 	{}
 };
 
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index 6de6e74..f1f4c17 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -207,12 +207,21 @@
 	AVALIABLE,
 	INACTIVE,
 	ACTIVE,
-	PAUSE,
+	PAUSED,
 	START_PENDING,
 	STOP_PENDING,
+	PAUSE_PENDING,
+	RESUME_PENDING,
 	STARTING,
 	STOPPING,
-	PAUSE_PENDING,
+	PAUSING,
+	RESUMING,
+};
+
+enum msm_vfe_axi_cfg_update_state {
+	NO_AXI_CFG_UPDATE,
+	APPLYING_UPDATE_RESUME,
+	UPDATE_REQUESTED,
 };
 
 #define VFE_NO_DROP            0xFFFFFFFF
@@ -251,6 +260,7 @@
 	uint32_t init_frame_drop;
 	uint32_t burst_frame_count;/*number of sof before burst stop*/
 	uint8_t framedrop_update;
+	spinlock_t lock;
 
 	/*Bandwidth calculation info*/
 	uint32_t max_width;
@@ -263,6 +273,7 @@
 	uint32_t runtime_burst_frame_count;/*number of sof before burst stop*/
 	uint32_t runtime_num_burst_capture;
 	uint8_t runtime_framedrop_update;
+	uint32_t runtime_output_format;
 };
 
 struct msm_vfe_axi_composite_info {
@@ -298,6 +309,7 @@
 		composite_info[MAX_NUM_COMPOSITE_MASK];
 	uint8_t num_used_composite_mask;
 	uint32_t stream_update;
+	atomic_t axi_cfg_update;
 	enum msm_isp_camif_update_state pipeline_update;
 	struct msm_vfe_src_info src_info[VFE_SRC_MAX];
 	uint16_t stream_handle_cnt;
@@ -407,6 +419,7 @@
 	struct msm_vfe_error_info error_info;
 	struct msm_isp_buf_mgr *buf_mgr;
 	int dump_reg;
+	int vfe_clk_idx;
 	uint32_t vfe_open_cnt;
 };
 
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index 3a94af3..4c5f258 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -22,7 +22,7 @@
 #include "msm.h"
 #include "msm_camera_io_util.h"
 
-#define VFE32_BURST_LEN 3
+#define VFE32_BURST_LEN 1
 #define VFE32_UB_SIZE 1024
 #define VFE32_EQUAL_SLICE_UB 204
 #define VFE32_WM_BASE(idx) (0x4C + 0x18 * idx)
@@ -40,7 +40,17 @@
 	(~(ping_pong >> (idx + VFE32_STATS_PING_PONG_OFFSET)) & 0x1))
 
 #define VFE32_CLK_IDX 0
-static struct msm_cam_clk_info msm_vfe32_clk_info[] = {
+static struct msm_cam_clk_info msm_vfe32_1_clk_info[] = {
+	/*vfe32 clock info for B-family: 8610 */
+	{"vfe_clk_src", 266670000},
+	{"vfe_clk", -1},
+	{"vfe_ahb_clk", -1},
+	{"csi_vfe_clk", -1},
+	{"bus_clk", -1},
+};
+
+static struct msm_cam_clk_info msm_vfe32_2_clk_info[] = {
+	/*vfe32 clock info for A-family: 8960 */
 	{"vfe_clk", 266667000},
 	{"vfe_pclk", -1},
 	{"csi_vfe_clk", -1},
@@ -49,6 +59,7 @@
 static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev)
 {
 	int rc = -1;
+	vfe_dev->vfe_clk_idx = 0;
 	rc = msm_isp_init_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
 	if (rc < 0) {
 		pr_err("%s: Bandwidth registration Failed!\n", __func__);
@@ -63,10 +74,18 @@
 		}
 	}
 
-	rc = msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
-		 vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 1);
-	if (rc < 0)
-		goto clk_enable_failed;
+	rc = msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_1_clk_info,
+		 vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_1_clk_info), 1);
+	if (rc < 0) {
+		rc = msm_cam_clk_enable(&vfe_dev->pdev->dev,
+			 msm_vfe32_2_clk_info, vfe_dev->vfe_clk,
+			ARRAY_SIZE(msm_vfe32_2_clk_info), 1);
+		if (rc < 0)
+			goto clk_enable_failed;
+		else
+			vfe_dev->vfe_clk_idx = 2;
+	} else
+		vfe_dev->vfe_clk_idx = 1;
 
 	vfe_dev->vfe_base = ioremap(vfe_dev->vfe_mem->start,
 		resource_size(vfe_dev->vfe_mem));
@@ -87,8 +106,14 @@
 irq_req_failed:
 	iounmap(vfe_dev->vfe_base);
 vfe_remap_failed:
-	msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
-		 vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 0);
+	if (vfe_dev->vfe_clk_idx == 1)
+		msm_cam_clk_enable(&vfe_dev->pdev->dev,
+				msm_vfe32_1_clk_info, vfe_dev->vfe_clk,
+				ARRAY_SIZE(msm_vfe32_1_clk_info), 0);
+	if (vfe_dev->vfe_clk_idx == 2)
+		msm_cam_clk_enable(&vfe_dev->pdev->dev,
+				msm_vfe32_2_clk_info, vfe_dev->vfe_clk,
+				ARRAY_SIZE(msm_vfe32_2_clk_info), 0);
 clk_enable_failed:
 	regulator_disable(vfe_dev->fs_vfe);
 fs_failed:
@@ -102,8 +127,14 @@
 	free_irq(vfe_dev->vfe_irq->start, vfe_dev);
 	tasklet_kill(&vfe_dev->vfe_tasklet);
 	iounmap(vfe_dev->vfe_base);
-	msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
-		 vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 0);
+	if (vfe_dev->vfe_clk_idx == 1)
+		msm_cam_clk_enable(&vfe_dev->pdev->dev,
+				msm_vfe32_1_clk_info, vfe_dev->vfe_clk,
+				ARRAY_SIZE(msm_vfe32_1_clk_info), 0);
+	if (vfe_dev->vfe_clk_idx == 2)
+		msm_cam_clk_enable(&vfe_dev->pdev->dev,
+				msm_vfe32_2_clk_info, vfe_dev->vfe_clk,
+				ARRAY_SIZE(msm_vfe32_2_clk_info), 0);
 	regulator_disable(vfe_dev->fs_vfe);
 	msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
 }
@@ -330,7 +361,18 @@
 static void msm_vfe32_axi_reload_wm(
 	struct vfe_device *vfe_dev, uint32_t reload_mask)
 {
-	msm_camera_io_w_mb(reload_mask, vfe_dev->vfe_base + 0x38);
+	if (!vfe_dev->pdev->dev.of_node) {
+		/*vfe32 A-family: 8960*/
+		msm_camera_io_w_mb(reload_mask, vfe_dev->vfe_base + 0x38);
+	} else {
+		/*vfe32 B-family: 8610*/
+		msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x24);
+		msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x28);
+		msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x20);
+		msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x18);
+		msm_camera_io_w(0x9AAAAAAA , vfe_dev->vfe_base + 0x600);
+		msm_camera_io_w(reload_mask, vfe_dev->vfe_base + 0x38);
+	}
 }
 
 static void msm_vfe32_axi_enable_wm(struct vfe_device *vfe_dev,
@@ -638,6 +680,7 @@
 		} else {
 			switch (stream_info->output_format) {
 			case V4L2_PIX_FMT_NV12:
+			case V4L2_PIX_FMT_NV14:
 			case V4L2_PIX_FMT_NV16:
 				xbar_cfg |= 0x3 << 3; /*PAIR_STREAM_SWAP_CTRL*/
 				break;
@@ -913,14 +956,22 @@
 		goto vfe_no_resource;
 	}
 
-	vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe_imgwr");
+	if (!vfe_dev->pdev->dev.of_node)
+		vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe_imgwr");
+	else
+		vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe0");
+
 	if (!vfe_dev->iommu_ctx[0]) {
 		pr_err("%s: no iommux ctx resource?\n", __func__);
 		rc = -ENODEV;
 		goto vfe_no_resource;
 	}
 
-	vfe_dev->iommu_ctx[1] = msm_iommu_get_ctx("vfe_misc");
+	if (!vfe_dev->pdev->dev.of_node)
+		vfe_dev->iommu_ctx[1] = msm_iommu_get_ctx("vfe_misc");
+	else
+		vfe_dev->iommu_ctx[1] = msm_iommu_get_ctx("vfe0");
+
 	if (!vfe_dev->iommu_ctx[1]) {
 		pr_err("%s: no iommux ctx resource?\n", __func__);
 		rc = -ENODEV;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index 7bf8511..1c146d0 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -531,6 +531,8 @@
 		msm_isp_axi_stream_update(vfe_dev);
 	if (atomic_read(&vfe_dev->stats_data.stats_update))
 		msm_isp_stats_stream_update(vfe_dev);
+	if (atomic_read(&vfe_dev->axi_data.axi_cfg_update))
+		msm_isp_axi_cfg_update(vfe_dev);
 	msm_isp_update_framedrop_reg(vfe_dev);
 	msm_isp_update_error_frame_count(vfe_dev);
 
@@ -819,6 +821,7 @@
 	uint32_t wm_base = VFE40_WM_BASE(stream_info->wm[plane_idx]);
 
 	if (!stream_info->frame_based) {
+		msm_camera_io_w(0x0, vfe_dev->vfe_base + wm_base);
 		/*WR_IMAGE_SIZE*/
 		val =
 			((msm_isp_cal_word_per_line(
@@ -895,6 +898,7 @@
 		} else {
 			switch (stream_info->output_format) {
 			case V4L2_PIX_FMT_NV12:
+			case V4L2_PIX_FMT_NV14:
 			case V4L2_PIX_FMT_NV16:
 				xbar_cfg |= 0x3 << 4; /*PAIR_STREAM_SWAP_CTRL*/
 				break;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index e3d036f6..f470d36 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -43,6 +43,7 @@
 
 	memset(&axi_data->stream_info[i], 0,
 		   sizeof(struct msm_vfe_axi_stream));
+	spin_lock_init(&axi_data->stream_info[i].lock);
 	axi_data->stream_info[i].session_id = stream_cfg_cmd->session_id;
 	axi_data->stream_info[i].stream_id = stream_cfg_cmd->stream_id;
 	axi_data->stream_info[i].buf_divert = stream_cfg_cmd->buf_divert;
@@ -101,6 +102,8 @@
 		break;
 	case V4L2_PIX_FMT_NV12:
 	case V4L2_PIX_FMT_NV21:
+	case V4L2_PIX_FMT_NV14:
+	case V4L2_PIX_FMT_NV41:
 	case V4L2_PIX_FMT_NV16:
 	case V4L2_PIX_FMT_NV61:
 		stream_info->num_planes = 2;
@@ -142,6 +145,7 @@
 	}
 
 	stream_info->output_format = stream_cfg_cmd->output_format;
+	stream_info->runtime_output_format = stream_info->output_format;
 	stream_info->stream_src = stream_cfg_cmd->stream_src;
 	stream_info->frame_based = stream_cfg_cmd->frame_base;
 	return 0;
@@ -197,6 +201,15 @@
 			size = plane_cfg[plane_idx].output_height *
 				plane_cfg[plane_idx].output_width / 2;
 		break;
+	case V4L2_PIX_FMT_NV14:
+	case V4L2_PIX_FMT_NV41:
+		if (plane_cfg[plane_idx].output_plane_format == Y_PLANE)
+			size = plane_cfg[plane_idx].output_height *
+				plane_cfg[plane_idx].output_width;
+		else
+			size = plane_cfg[plane_idx].output_height *
+				plane_cfg[plane_idx].output_width / 8;
+		break;
 	case V4L2_PIX_FMT_NV16:
 	case V4L2_PIX_FMT_NV61:
 		size = plane_cfg[plane_idx].output_height *
@@ -278,19 +291,32 @@
 	struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd)
 {
 	int rc = 0, i;
+	unsigned long flags;
 	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
 	struct msm_vfe_axi_stream *stream_info;
 	enum msm_vfe_axi_state valid_state =
 		(stream_cfg_cmd->cmd == START_STREAM) ? INACTIVE : ACTIVE;
-
 	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
 		stream_info = &axi_data->stream_info[
 			HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
+		spin_lock_irqsave(&stream_info->lock, flags);
 		if (stream_info->state != valid_state) {
-			pr_err("%s: Invalid stream state\n", __func__);
-			rc = -EINVAL;
-			break;
+			if ((stream_info->state == PAUSING ||
+				stream_info->state == PAUSED ||
+				stream_info->state == RESUME_PENDING ||
+				stream_info->state == RESUMING) &&
+				stream_cfg_cmd->cmd == STOP_STREAM) {
+				stream_info->state = ACTIVE;
+			} else {
+				pr_err("%s: Invalid stream state: %d\n",
+					__func__, stream_info->state);
+				spin_unlock_irqrestore(
+					&stream_info->lock, flags);
+				rc = -EINVAL;
+				break;
+			}
 		}
+		spin_unlock_irqrestore(&stream_info->lock, flags);
 
 		if (stream_cfg_cmd->cmd == START_STREAM) {
 			stream_info->bufq_handle =
@@ -379,6 +405,7 @@
 
 	sof_event.frame_id = vfe_dev->axi_data.src_info[frame_src].frame_id;
 	sof_event.timestamp = ts->event_time;
+	sof_event.mono_timestamp = ts->buf_time;
 	msm_isp_send_event(vfe_dev, ISP_EVENT_SOF, &sof_event);
 }
 
@@ -548,7 +575,8 @@
 	if (stream_info->state == INACTIVE)
 		return;
 	for (i = 0; i < stream_info->num_planes; i++) {
-		if (stream_info->state == START_PENDING)
+		if (stream_info->state == START_PENDING ||
+			stream_info->state == RESUME_PENDING)
 			vfe_dev->hw_info->vfe_ops.axi_ops.
 				enable_wm(vfe_dev, stream_info->wm[i], 1);
 		else
@@ -558,7 +586,7 @@
 
 	if (stream_info->state == START_PENDING)
 		axi_data->num_active_stream++;
-	else
+	else if (stream_info->state == STOP_PENDING)
 		axi_data->num_active_stream--;
 }
 
@@ -594,6 +622,60 @@
 		complete(&vfe_dev->stream_config_complete);
 }
 
+static void msm_isp_reload_ping_pong_offset(struct vfe_device *vfe_dev,
+		struct msm_vfe_axi_stream *stream_info)
+{
+	int i, j;
+	uint32_t flag;
+	struct msm_isp_buffer *buf;
+	for (i = 0; i < 2; i++) {
+		buf = stream_info->buf[i];
+		flag = i ? VFE_PONG_FLAG : VFE_PING_FLAG;
+		for (j = 0; j < stream_info->num_planes; j++) {
+			vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
+				vfe_dev, stream_info->wm[j], flag,
+				buf->mapped_info[j].paddr +
+				stream_info->plane_cfg[j].plane_addr_offset);
+		}
+	}
+}
+
+void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev)
+{
+	int i, j;
+	uint32_t update_state;
+	unsigned long flags;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	struct msm_vfe_axi_stream *stream_info;
+	for (i = 0; i < MAX_NUM_STREAM; i++) {
+		stream_info = &axi_data->stream_info[i];
+		if (stream_info->stream_type == BURST_STREAM ||
+			stream_info->state == AVALIABLE)
+			continue;
+		spin_lock_irqsave(&stream_info->lock, flags);
+		if (stream_info->state == PAUSING) {
+			/*AXI Stopped, apply update*/
+			stream_info->state = PAUSED;
+			msm_isp_reload_ping_pong_offset(vfe_dev, stream_info);
+			for (j = 0; j < stream_info->num_planes; j++)
+				vfe_dev->hw_info->vfe_ops.axi_ops.
+					cfg_wm_reg(vfe_dev, stream_info, j);
+			/*Resume AXI*/
+			stream_info->state = RESUME_PENDING;
+			msm_isp_axi_stream_enable_cfg(
+				vfe_dev, &axi_data->stream_info[i]);
+			stream_info->state = RESUMING;
+		} else if (stream_info->state == RESUMING) {
+			stream_info->runtime_output_format =
+				stream_info->output_format;
+			stream_info->state = ACTIVE;
+		}
+		spin_unlock_irqrestore(&stream_info->lock, flags);
+	}
+
+	update_state = atomic_dec_return(&axi_data->axi_cfg_update);
+}
+
 static void msm_isp_cfg_pong_address(struct vfe_device *vfe_dev,
 		struct msm_vfe_axi_stream *stream_info)
 {
@@ -690,6 +772,8 @@
 				buf_event.u.buf_done.handle =
 					stream_info->bufq_handle;
 				buf_event.u.buf_done.buf_idx = buf->buf_idx;
+				buf_event.u.buf_done.output_format =
+					stream_info->runtime_output_format;
 				msm_isp_send_event(vfe_dev,
 					ISP_EVENT_BUF_DIVERT + stream_idx,
 					&buf_event);
@@ -697,7 +781,8 @@
 		} else {
 			vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr,
 				buf->bufq_handle, buf->buf_idx,
-				&ts->buf_time, frame_id);
+				&ts->buf_time, frame_id,
+				stream_info->runtime_output_format);
 		}
 	}
 }
@@ -745,7 +830,7 @@
 			&axi_data->stream_info[
 			HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
 		if (stream_info->stream_src >= RDI_INTF_0)
-			return;
+			continue;
 		if (stream_info->stream_src == PIX_ENCODER ||
 			stream_info->stream_src == PIX_VIEWFINDER ||
 			stream_info->stream_src == IDEAL_RAW) {
@@ -954,10 +1039,11 @@
 	vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev);
 
 	msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd);
-	if (camif_update == ENABLE_CAMIF)
+	if (camif_update == ENABLE_CAMIF) {
+		vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id = 0;
 		vfe_dev->hw_info->vfe_ops.core_ops.
 			update_camif_state(vfe_dev, camif_update);
-
+	}
 	if (wait_for_complete)
 		rc = msm_isp_axi_wait_for_cfg_done(vfe_dev, camif_update);
 
@@ -1045,40 +1131,87 @@
 
 int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
 {
-	int rc = 0;
+	int rc = 0, i, j;
 	struct msm_vfe_axi_stream *stream_info;
 	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
 	struct msm_vfe_axi_stream_update_cmd *update_cmd = arg;
-	stream_info = &axi_data->stream_info[
-			HANDLE_TO_IDX(update_cmd->stream_handle)];
-	if (stream_info->state != ACTIVE && stream_info->state != INACTIVE) {
-		pr_err("%s: Invalid stream state\n", __func__);
-		return -EINVAL;
+	struct msm_vfe_axi_stream_cfg_update_info *update_info;
+
+	if (update_cmd->update_type == UPDATE_STREAM_AXI_CONFIG &&
+		atomic_read(&axi_data->axi_cfg_update)) {
+		pr_err("%s: AXI stream config updating\n", __func__);
+		return -EBUSY;
 	}
 
-	switch (update_cmd->update_type) {
-	case ENABLE_STREAM_BUF_DIVERT:
-		stream_info->buf_divert = 1;
-		break;
-	case DISABLE_STREAM_BUF_DIVERT:
-		stream_info->buf_divert = 0;
-		vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr,
-				stream_info->bufq_handle,
-				MSM_ISP_BUFFER_FLUSH_DIVERTED);
-		break;
-	case UPDATE_STREAM_FRAMEDROP_PATTERN: {
-		uint32_t framedrop_period =
-			msm_isp_get_framedrop_period(update_cmd->skip_pattern);
-		stream_info->runtime_init_frame_drop = 0;
-		stream_info->framedrop_pattern = 0x1;
-		stream_info->framedrop_period = framedrop_period - 1;
-		vfe_dev->hw_info->vfe_ops.axi_ops.
-			cfg_framedrop(vfe_dev, stream_info);
-		break;
+	for (i = 0; i < update_cmd->num_streams; i++) {
+		update_info = &update_cmd->update_info[i];
+		stream_info = &axi_data->stream_info[
+				HANDLE_TO_IDX(update_info->stream_handle)];
+		if (stream_info->state != ACTIVE &&
+			stream_info->state != INACTIVE) {
+			pr_err("%s: Invalid stream state\n", __func__);
+			return -EINVAL;
+		}
+		if (stream_info->state == ACTIVE &&
+			stream_info->stream_type == BURST_STREAM) {
+			pr_err("%s: Cannot update active burst stream\n",
+				__func__);
+			return -EINVAL;
+		}
 	}
-	default:
-		pr_err("%s: Invalid update type\n", __func__);
-		return -EINVAL;
+
+	for (i = 0; i < update_cmd->num_streams; i++) {
+		update_info = &update_cmd->update_info[i];
+		stream_info = &axi_data->stream_info[
+				HANDLE_TO_IDX(update_info->stream_handle)];
+
+		switch (update_cmd->update_type) {
+		case ENABLE_STREAM_BUF_DIVERT:
+			stream_info->buf_divert = 1;
+			break;
+		case DISABLE_STREAM_BUF_DIVERT:
+			stream_info->buf_divert = 0;
+			vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr,
+					stream_info->bufq_handle,
+					MSM_ISP_BUFFER_FLUSH_DIVERTED);
+			break;
+		case UPDATE_STREAM_FRAMEDROP_PATTERN: {
+			uint32_t framedrop_period =
+				msm_isp_get_framedrop_period(
+				   update_info->skip_pattern);
+			stream_info->runtime_init_frame_drop = 0;
+			stream_info->framedrop_pattern = 0x1;
+			stream_info->framedrop_period = framedrop_period - 1;
+			vfe_dev->hw_info->vfe_ops.axi_ops.
+				cfg_framedrop(vfe_dev, stream_info);
+			break;
+		}
+		case UPDATE_STREAM_AXI_CONFIG: {
+			for (j = 0; j < stream_info->num_planes; j++) {
+				stream_info->plane_cfg[j] =
+					update_info->plane_cfg[j];
+			}
+			stream_info->output_format = update_info->output_format;
+			if (stream_info->state == ACTIVE) {
+				stream_info->state = PAUSE_PENDING;
+				msm_isp_axi_stream_enable_cfg(
+					vfe_dev, stream_info);
+				stream_info->state = PAUSING;
+				atomic_set(&axi_data->axi_cfg_update,
+					UPDATE_REQUESTED);
+			} else {
+				for (j = 0; j < stream_info->num_planes; j++)
+					vfe_dev->hw_info->vfe_ops.axi_ops.
+					cfg_wm_reg(vfe_dev, stream_info, j);
+				stream_info->runtime_output_format =
+					stream_info->output_format;
+			}
+			break;
+		}
+		default:
+			pr_err("%s: Invalid update type\n", __func__);
+			return -EINVAL;
+		}
 	}
 	return rc;
 }
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
index 3d775f9..7d282bd 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
@@ -41,6 +41,7 @@
 int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg);
 int msm_isp_release_axi_stream(struct vfe_device *vfe_dev, void *arg);
 int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg);
+void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev);
 
 void msm_isp_axi_stream_update(struct vfe_device *vfe_dev);
 
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index ee205c0..ac44c61 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -647,6 +647,8 @@
 		break;
 	case V4L2_PIX_FMT_NV12:
 	case V4L2_PIX_FMT_NV21:
+	case V4L2_PIX_FMT_NV14:
+	case V4L2_PIX_FMT_NV41:
 	case V4L2_PIX_FMT_NV16:
 	case V4L2_PIX_FMT_NV61:
 		val = CAL_WORD(pixel_per_line, 1, 8);
@@ -691,6 +693,8 @@
 		return 12;
 	case V4L2_PIX_FMT_NV12:
 	case V4L2_PIX_FMT_NV21:
+	case V4L2_PIX_FMT_NV14:
+	case V4L2_PIX_FMT_NV41:
 		return 8;
 	case V4L2_PIX_FMT_NV16:
 	case V4L2_PIX_FMT_NV61:
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index 9fe9065..27aba5c 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -455,6 +455,9 @@
 {
 	struct msm_command_ack *cmd_ack = d1;
 
+	if (!(&cmd_ack->command_q))
+		return 0;
+
 	msm_queue_drain(&cmd_ack->command_q, struct msm_command, list);
 
 	return 0;
@@ -462,7 +465,7 @@
 
 static void msm_remove_session_cmd_ack_q(struct msm_session *session)
 {
-	if (!session)
+	if ((!session) || !(&session->command_ack_q))
 		return;
 
 	/* to ensure error handling purpose, it needs to detach all subdevs
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
index 895f452..154ee87 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -62,6 +62,7 @@
 			(bufs->vb2_buf->v4l2_buf.index == buf_info->index)) {
 			bufs->vb2_buf->v4l2_buf.sequence  = buf_info->frame_id;
 			bufs->vb2_buf->v4l2_buf.timestamp = buf_info->timestamp;
+			bufs->vb2_buf->v4l2_buf.reserved = 0;
 			ret = buf_mngr_dev->vb2_ops.buf_done
 					(bufs->vb2_buf,
 						buf_info->session_id,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index b115738..300daca 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -435,6 +435,8 @@
 		return -EFAULT;
 	}
 
+	kfree(a_ctrl->i2c_reg_tbl);
+
 	a_ctrl->i2c_reg_tbl =
 		kmalloc(sizeof(struct msm_camera_i2c_reg_tbl) *
 		(set_info->af_tuning_params.total_steps + 1), GFP_KERNEL);
@@ -608,6 +610,9 @@
 		if (rc < 0)
 			pr_err("cci_init failed\n");
 	}
+	kfree(a_ctrl->i2c_reg_tbl);
+	a_ctrl->i2c_reg_tbl = NULL;
+
 	CDBG("Exit\n");
 	return rc;
 }
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index 1c8662b..676862f 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -714,40 +714,40 @@
 			complete(&cci_dev->cci_master_info[MASTER_1].
 				reset_complete);
 		}
-	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) ||
+	}
+	if ((irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) ||
 		(irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) ||
 		(irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK)) {
 		cci_dev->cci_master_info[MASTER_0].status = 0;
 		complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
-	} else if ((irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) ||
+	}
+	if ((irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) ||
 		(irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) ||
 		(irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK)) {
 		cci_dev->cci_master_info[MASTER_1].status = 0;
 		complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
-	} else if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) {
+	}
+	if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) {
 		cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
 		msm_camera_io_w(CCI_M0_RESET_RMSK,
 			cci_dev->base + CCI_RESET_CMD_ADDR);
-	} else if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) {
+	}
+	if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) {
 		cci_dev->cci_master_info[MASTER_1].reset_pending = TRUE;
 		msm_camera_io_w(CCI_M1_RESET_RMSK,
 			cci_dev->base + CCI_RESET_CMD_ADDR);
-	} else if (irq & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) {
+	}
+	if (irq & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) {
 		pr_err("%s:%d MASTER_0 error %x\n", __func__, __LINE__, irq);
 		cci_dev->cci_master_info[MASTER_0].status = -EINVAL;
 		msm_camera_io_w(CCI_M0_HALT_REQ_RMSK,
 			cci_dev->base + CCI_HALT_REQ_ADDR);
-	} else if (irq & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) {
+	}
+	if (irq & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) {
 		pr_err("%s:%d MASTER_1 error %x\n", __func__, __LINE__, irq);
 		cci_dev->cci_master_info[MASTER_1].status = -EINVAL;
 		msm_camera_io_w(CCI_M1_HALT_REQ_RMSK,
 			cci_dev->base + CCI_HALT_REQ_ADDR);
-	} else {
-		pr_err("%s unhandled irq 0x%x\n", __func__, irq);
-		cci_dev->cci_master_info[MASTER_0].status = 0;
-		complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
-		cci_dev->cci_master_info[MASTER_1].status = 0;
-		complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
 	}
 	return IRQ_HANDLED;
 }
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 42d4f95..6e8c809 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -61,6 +61,18 @@
 	[ilog2(HAL_COLOR_FORMAT_BGR888)] = HFI_COLOR_FORMAT_BGR888,
 };
 
+static int nal_type[] = {
+	[ilog2(HAL_NAL_FORMAT_STARTCODES)] = HFI_NAL_FORMAT_STARTCODES,
+	[ilog2(HAL_NAL_FORMAT_ONE_NAL_PER_BUFFER)] =
+		HFI_NAL_FORMAT_ONE_NAL_PER_BUFFER,
+	[ilog2(HAL_NAL_FORMAT_ONE_BYTE_LENGTH)] =
+		HFI_NAL_FORMAT_ONE_BYTE_LENGTH,
+	[ilog2(HAL_NAL_FORMAT_TWO_BYTE_LENGTH)] =
+		HFI_NAL_FORMAT_TWO_BYTE_LENGTH,
+	[ilog2(HAL_NAL_FORMAT_FOUR_BYTE_LENGTH)] =
+		HFI_NAL_FORMAT_FOUR_BYTE_LENGTH,
+};
+
 static inline int hal_to_hfi_type(int property, int hal_type)
 {
 	if (hal_type && (roundup_pow_of_two(hal_type) != hal_type)) {
@@ -85,6 +97,9 @@
 	case HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT:
 		return (hal_type >= ARRAY_SIZE(color_format)) ?
 			-ENOTSUPP : color_format[hal_type];
+	case HAL_PARAM_NAL_STREAM_FORMAT_SELECT:
+		return (hal_type >= ARRAY_SIZE(nal_type)) ?
+			-ENOTSUPP : nal_type[hal_type];
 	default:
 		return -ENOTSUPP;
 	}
@@ -717,40 +732,20 @@
 	}
 	case HAL_PARAM_NAL_STREAM_FORMAT_SELECT:
 	{
-		struct hal_nal_stream_format_supported *prop =
-			(struct hal_nal_stream_format_supported *)pdata;
+		struct hfi_nal_stream_format_select *hfi;
+		struct hal_nal_stream_format_select *prop =
+			(struct hal_nal_stream_format_select *)pdata;
 		pkt->rg_property_data[0] =
 			HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT;
+		hfi = (struct hfi_nal_stream_format_select *)
+			&pkt->rg_property_data[1];
 		dprintk(VIDC_DBG, "data is :%d",
-				prop->nal_stream_format_supported);
-
-		switch (prop->nal_stream_format_supported) {
-		case HAL_NAL_FORMAT_STARTCODES:
-			pkt->rg_property_data[1] =
-				HFI_NAL_FORMAT_STARTCODES;
-			break;
-		case HAL_NAL_FORMAT_ONE_NAL_PER_BUFFER:
-			pkt->rg_property_data[1] =
-				HFI_NAL_FORMAT_ONE_NAL_PER_BUFFER;
-			break;
-		case HAL_NAL_FORMAT_ONE_BYTE_LENGTH:
-			pkt->rg_property_data[1] =
-				HFI_NAL_FORMAT_ONE_BYTE_LENGTH;
-			break;
-		case HAL_NAL_FORMAT_TWO_BYTE_LENGTH:
-			pkt->rg_property_data[1] =
-				HFI_NAL_FORMAT_TWO_BYTE_LENGTH;
-			break;
-		case HAL_NAL_FORMAT_FOUR_BYTE_LENGTH:
-			pkt->rg_property_data[1] =
-				HFI_NAL_FORMAT_FOUR_BYTE_LENGTH;
-			break;
-		default:
-			dprintk(VIDC_ERR, "Invalid nal format: 0x%x",
-				  prop->nal_stream_format_supported);
-			break;
-		}
-		pkt->size += sizeof(u32) * 2;
+				prop->nal_stream_format_select);
+		hfi->nal_stream_format_select = hal_to_hfi_type(
+				HAL_PARAM_NAL_STREAM_FORMAT_SELECT,
+				prop->nal_stream_format_select);
+		pkt->size += sizeof(u32) +
+			sizeof(struct hfi_nal_stream_format_select);
 		break;
 	}
 	case HAL_PARAM_VDEC_OUTPUT_ORDER:
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index bead12b..29ae7b4 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -69,6 +69,12 @@
 	"Extradata mpeg2 seqdisp",
 };
 
+static const char *const perf_level[] = {
+	"Nominal",
+	"Performance",
+	"Turbo"
+};
+
 static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
 	{
 		.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT,
@@ -230,6 +236,19 @@
 		.qmenu = mpeg_video_vidc_extradata,
 		.step = 0,
 	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL,
+		.name = "Encoder Performance Level",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL,
+		.maximum = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO,
+		.default_value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL,
+		.menu_skip_mask = ~(
+			(1 << V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL) |
+			(1 << V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO)),
+		.qmenu = perf_level,
+		.step = 0,
+	},
 };
 
 #define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls)
@@ -700,7 +719,7 @@
 int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
 {
 	u64 us_per_frame = 0;
-	int rc = 0, fps = 0, rem = 0;
+	int rc = 0, fps = 0;
 	if (a->parm.output.timeperframe.denominator) {
 		switch (a->type) {
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
@@ -726,11 +745,12 @@
 	}
 
 	fps = USEC_PER_SEC;
-	rem = do_div(fps, us_per_frame);
-	if (rem) {
-		/* Effectively fps = ceil((float)USEC_PER_SEC/us_per_frame) */
-		fps++;
-	}
+	do_div(fps, us_per_frame);
+
+	if ((fps % 15 == 14) || (fps % 24 == 23))
+		fps = fps + 1;
+	else if ((fps % 24 == 1) || (fps % 15 == 1))
+		fps = fps - 1;
 
 	if (inst->prop.fps != fps) {
 		dprintk(VIDC_PROF, "reported fps changed for %p: %d->%d\n",
@@ -1142,7 +1162,6 @@
 int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec)
 {
 	int rc = 0;
-	struct v4l2_event dqevent = {0};
 	struct msm_vidc_core *core = inst->core;
 
 	if (!dec || !inst || !inst->core) {
@@ -1174,16 +1193,15 @@
 			dprintk(VIDC_ERR,
 				"Core %p in bad state, Sending CLOSE event\n",
 					core);
-			dqevent.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
-			v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+			msm_vidc_queue_v4l2_event(inst,
+					V4L2_EVENT_MSM_VIDC_CLOSE_DONE);
 			goto exit;
 		}
 		rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
 		/* Clients rely on this event for joining poll thread.
 		 * This event should be returned even if firmware has
 		 * failed to respond */
-		dqevent.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
-		v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+		msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_CLOSE_DONE);
 		break;
 	default:
 		dprintk(VIDC_ERR, "Unknown Decoder Command\n");
@@ -1240,7 +1258,7 @@
 	u32 control_idx = 0;
 	enum hal_property property_id = 0;
 	u32 property_val = 0;
-	void *pdata;
+	void *pdata = NULL;
 	struct hfi_device *hdev;
 
 	if (!inst || !inst->core || !inst->core->device) {
@@ -1304,8 +1322,9 @@
 		pdata = &hal_property;
 		break;
 	case V4L2_CID_MPEG_VIDC_VIDEO_SECURE:
-		inst->mode = VIDC_SECURE;
-		dprintk(VIDC_DBG, "Setting secure mode to :%d\n", inst->mode);
+		inst->flags |= VIDC_SECURE;
+		dprintk(VIDC_DBG, "Setting secure mode to: %d\n",
+				!!(inst->flags & VIDC_SECURE));
 		break;
 	case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA:
 	{
@@ -1316,6 +1335,22 @@
 		pdata = &extra;
 		break;
 	}
+	case V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL:
+		switch (ctrl->val) {
+		case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL:
+			inst->flags &= ~VIDC_TURBO;
+			break;
+		case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
+			inst->flags |= VIDC_TURBO;
+			break;
+		default:
+			dprintk(VIDC_ERR, "Perf mode %x not supported",
+					ctrl->val);
+			rc = -ENOTSUPP;
+			break;
+		}
+
+		break;
 	default:
 		break;
 	}
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index b8b3453..7fc2595 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -21,7 +21,7 @@
 #define MSM_VENC_DVC_NAME "msm_venc_8974"
 #define MIN_NUM_OUTPUT_BUFFERS 4
 #define MIN_NUM_CAPTURE_BUFFERS 4
-#define MIN_BIT_RATE 64000
+#define MIN_BIT_RATE 32000
 #define MAX_BIT_RATE 160000000
 #define DEFAULT_BIT_RATE 64000
 #define BIT_RATE_STEP 100
@@ -108,6 +108,12 @@
 	"Extradata aspect ratio",
 };
 
+static const char *const perf_level[] = {
+	"Nominal",
+	"Performance",
+	"Turbo"
+};
+
 enum msm_venc_ctrl_cluster {
 	MSM_VENC_CTRL_CLUSTER_QP = 1 << 0,
 	MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD = 1 << 1,
@@ -124,18 +130,6 @@
 
 static struct msm_vidc_ctrl msm_venc_ctrls[] = {
 	{
-		.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE,
-		.name = "Frame Rate",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.minimum = MIN_FRAME_RATE,
-		.maximum = MAX_FRAME_RATE,
-		.default_value = MIN_FRAME_RATE,
-		.step = 1,
-		.menu_skip_mask = 0,
-		.qmenu = NULL,
-		.cluster = MSM_VENC_CTRL_CLUSTER_TIMING,
-	},
-	{
 		.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD,
 		.name = "IDR Period",
 		.type = V4L2_CTRL_TYPE_INTEGER,
@@ -676,6 +670,19 @@
 		.default_value =
 			V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED,
 	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL,
+		.name = "Encoder Performance Level",
+		.type = V4L2_CTRL_TYPE_MENU,
+		.minimum = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL,
+		.maximum = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO,
+		.default_value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL,
+		.menu_skip_mask = ~(
+			(1 << V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL) |
+			(1 << V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO)),
+		.qmenu = perf_level,
+		.step = 0,
+	},
 };
 
 #define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls)
@@ -1160,7 +1167,6 @@
 static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
 {
 	int rc = 0;
-	struct hal_frame_rate frame_rate;
 	struct hal_request_iframe request_iframe;
 	struct hal_bitrate bitrate;
 	struct hal_profile_level profile_level;
@@ -1202,13 +1208,6 @@
 	})
 
 	switch (ctrl->id) {
-	case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE:
-		property_id =
-			HAL_CONFIG_FRAME_RATE;
-		frame_rate.frame_rate = ctrl->val;
-		frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
-		pdata = &frame_rate;
-		break;
 	case V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD:
 		property_id =
 			HAL_CONFIG_VENC_IDR_PERIOD;
@@ -1722,8 +1721,9 @@
 		pdata = &enable;
 		break;
 	case V4L2_CID_MPEG_VIDC_VIDEO_SECURE:
-		inst->mode = VIDC_SECURE;
-		dprintk(VIDC_INFO, "Setting secure mode to :%d\n", inst->mode);
+		inst->flags |= VIDC_SECURE;
+		dprintk(VIDC_INFO, "Setting secure mode to: %d\n",
+				!!(inst->flags & VIDC_SECURE));
 		break;
 	case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA:
 	{
@@ -1782,6 +1782,22 @@
 
 		pdata = &enable;
 		break;
+	case V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL:
+		switch (ctrl->val) {
+		case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL:
+			inst->flags &= ~VIDC_TURBO;
+			break;
+		case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
+			inst->flags |= VIDC_TURBO;
+			break;
+		default:
+			dprintk(VIDC_ERR, "Perf mode %x not supported",
+					ctrl->val);
+			rc = -ENOTSUPP;
+			break;
+		}
+
+		break;
 	default:
 		rc = -ENOTSUPP;
 		break;
@@ -1875,7 +1891,6 @@
 int msm_venc_cmd(struct msm_vidc_inst *inst, struct v4l2_encoder_cmd *enc)
 {
 	int rc = 0;
-	struct v4l2_event dqevent = {0};
 	struct msm_vidc_core *core;
 	core = inst->core;
 	switch (enc->cmd) {
@@ -1885,8 +1900,8 @@
 	case V4L2_ENC_CMD_STOP:
 		if (inst->state == MSM_VIDC_CORE_INVALID ||
 			core->state == VIDC_CORE_INVALID) {
-			dqevent.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
-			v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+			msm_vidc_queue_v4l2_event(inst,
+					V4L2_EVENT_MSM_VIDC_CLOSE_DONE);
 			return rc;
 		}
 		rc = msm_comm_release_scratch_buffers(inst);
@@ -1901,8 +1916,7 @@
 		/* Clients rely on this event for joining poll thread.
 		 * This event should be returned even if firmware has
 		 * failed to respond */
-		dqevent.type = V4L2_EVENT_MSM_VIDC_CLOSE_DONE;
-		v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+		msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_CLOSE_DONE);
 		break;
 	}
 	if (rc)
@@ -1963,7 +1977,7 @@
 {
 	u32 property_id = 0, us_per_frame = 0;
 	void *pdata;
-	int rc = 0, fps = 0, rem = 0;
+	int rc = 0, fps = 0;
 	struct hal_frame_rate frame_rate;
 	struct hfi_device *hdev;
 
@@ -2000,11 +2014,12 @@
 	}
 
 	fps = USEC_PER_SEC;
-	rem = do_div(fps, us_per_frame);
-	if (rem) {
-		/* Effectively fps = ceil((float)USEC_PER_SEC/us_per_frame) */
-		fps++;
-	}
+	do_div(fps, us_per_frame);
+
+	if ((fps % 15 == 14) || (fps % 24 == 23))
+		fps = fps + 1;
+	else if ((fps % 24 == 1) || (fps % 15 == 1))
+		fps = fps - 1;
 
 	if (inst->prop.fps != fps) {
 		dprintk(VIDC_PROF, "reported fps changed for %p: %d->%d\n",
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index de4a206..bd05180 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -46,6 +46,28 @@
 	u32 __mbs = (__h >> 4) * (__w >> 4);\
 	__mbs;\
 })
+static bool is_turbo_requested(struct msm_vidc_core *core,
+		enum session_type type)
+{
+	struct msm_vidc_inst *inst = NULL;
+
+	list_for_each_entry(inst, &core->instances, list) {
+		bool wants_turbo = false;
+
+		mutex_lock(&inst->lock);
+		if (inst->session_type == type &&
+			inst->state >= MSM_VIDC_OPEN_DONE &&
+			inst->state < MSM_VIDC_STOP_DONE) {
+			wants_turbo = inst->flags & VIDC_TURBO;
+		}
+		mutex_unlock(&inst->lock);
+
+		if (wants_turbo)
+			return true;
+	}
+
+	return false;
+}
 
 static int msm_comm_get_load(struct msm_vidc_core *core,
 	enum session_type type)
@@ -61,30 +83,8 @@
 		if (inst->session_type == type &&
 			inst->state >= MSM_VIDC_OPEN_DONE &&
 			inst->state < MSM_VIDC_STOP_DONE) {
-			int stride, scanlines, rc;
-			struct hfi_device *hdev;
-
-			hdev = inst->core->device;
-			if (!hdev) {
-				dprintk(VIDC_ERR,
-						"No hdev (probably in bad state)\n");
-				mutex_unlock(&inst->lock);
-				return -EINVAL;
-			}
-
-			rc = call_hfi_op(hdev, get_stride_scanline,
-					COLOR_FMT_NV12,
-					inst->prop.width, inst->prop.height,
-					&stride, &scanlines);
-			if (rc) {
-				dprintk(VIDC_WARN,
-						"Failed to determine stride/scan when getting load. Perf. might be affected\n");
-				stride = inst->prop.width;
-				scanlines = inst->prop.height;
-			}
-
-			num_mbs_per_sec += NUM_MBS_PER_SEC(stride, scanlines,
-					inst->prop.fps);
+			num_mbs_per_sec += NUM_MBS_PER_SEC(inst->prop.height,
+					inst->prop.width, inst->prop.fps);
 		}
 		mutex_unlock(&inst->lock);
 	}
@@ -109,7 +109,10 @@
 		return -EINVAL;
 	}
 
-	load = msm_comm_get_load(core, type);
+	if (is_turbo_requested(core, type))
+		load = core->resources.max_load;
+	else
+		load = msm_comm_get_load(core, type);
 
 	rc = call_hfi_op(hdev, scale_bus, hdev->hfi_device_data,
 					 load, type, mtype);
@@ -373,7 +376,7 @@
 	return rc;
 }
 
-static void queue_v4l2_event(struct msm_vidc_inst *inst, int event_type)
+void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type)
 {
 	struct v4l2_event event = {.id = 0, .type = event_type};
 	v4l2_event_queue_fh(&inst->event_handler, &event);
@@ -389,7 +392,7 @@
 	mutex_lock(&inst->lock);
 	inst->session = NULL;
 	inst->state = MSM_VIDC_CORE_INVALID;
-	queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
+	msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
 	mutex_unlock(&inst->lock);
 }
 
@@ -465,7 +468,7 @@
 		}
 		rc = msm_vidc_check_session_supported(inst);
 		if (!rc) {
-			queue_v4l2_event(inst, event);
+			msm_vidc_queue_v4l2_event(inst, event);
 		}
 
 		return;
@@ -559,7 +562,7 @@
 	struct msm_vidc_inst *inst;
 	if (response) {
 		inst = (struct msm_vidc_inst *)response->session_id;
-		queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_FLUSH_DONE);
+		msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_FLUSH_DONE);
 	} else {
 		dprintk(VIDC_ERR, "Failed to get valid response for flush\n");
 	}
@@ -577,7 +580,8 @@
 			mutex_lock(&inst->sync_lock);
 			inst->state = MSM_VIDC_CORE_INVALID;
 			mutex_unlock(&inst->sync_lock);
-			queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
+			msm_vidc_queue_v4l2_event(inst,
+					V4L2_EVENT_MSM_VIDC_SYS_ERROR);
 		}
 	} else {
 		dprintk(VIDC_ERR,
@@ -616,7 +620,7 @@
 				}
 				inst->session = NULL;
 				mutex_unlock(&inst->lock);
-				queue_v4l2_event(inst,
+				msm_vidc_queue_v4l2_event(inst,
 						V4L2_EVENT_MSM_VIDC_SYS_ERROR);
 			}
 		} else {
@@ -648,7 +652,8 @@
 	mutex_unlock(&core->lock);
 	list_for_each_entry(inst, &core->instances, list) {
 		if (inst) {
-			queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
+			msm_vidc_queue_v4l2_event(inst,
+					V4L2_EVENT_MSM_VIDC_SYS_ERROR);
 			mutex_lock(&inst->lock);
 			inst->state = MSM_VIDC_CORE_INVALID;
 			if (inst->core)
@@ -954,8 +959,14 @@
 			__func__, hdev);
 		return -EINVAL;
 	}
-	num_mbs_per_sec = msm_comm_get_load(core, MSM_VIDC_ENCODER);
-	num_mbs_per_sec += msm_comm_get_load(core, MSM_VIDC_DECODER);
+
+	if (is_turbo_requested(core, MSM_VIDC_ENCODER) ||
+			is_turbo_requested(core, MSM_VIDC_DECODER)) {
+		num_mbs_per_sec = core->resources.max_load;
+	} else {
+		num_mbs_per_sec = msm_comm_get_load(core, MSM_VIDC_ENCODER);
+		num_mbs_per_sec += msm_comm_get_load(core, MSM_VIDC_DECODER);
+	}
 
 	dprintk(VIDC_INFO, "num_mbs_per_sec = %d\n", num_mbs_per_sec);
 	rc = call_hfi_op(hdev, scale_clocks,
@@ -1564,7 +1575,7 @@
 		scratch_buf->buffer_count_actual,
 		scratch_buf->buffer_size);
 
-	if (inst->mode == VIDC_SECURE)
+	if (inst->flags & VIDC_SECURE)
 		smem_flags |= SMEM_SECURE;
 
 	if (scratch_buf->buffer_size) {
@@ -1652,7 +1663,7 @@
 		return rc;
 	}
 
-	if (inst->mode == VIDC_SECURE)
+	if (inst->flags & VIDC_SECURE)
 		smem_flags |= SMEM_SECURE;
 
 	if (persist_buf->buffer_size) {
@@ -2265,7 +2276,8 @@
 			}
 		}
 	}
-	queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_FLUSH_DONE);
+
+	msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_FLUSH_DONE);
 	return;
 }
 int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
@@ -2471,7 +2483,6 @@
 {
 	struct msm_vidc_core_capability *capability;
 	int rc = 0;
-	struct v4l2_event dqevent;
 	struct hfi_device *hdev;
 
 	if (!inst || !inst->core || !inst->core->device) {
@@ -2500,9 +2511,7 @@
 		mutex_lock(&inst->sync_lock);
 		inst->state = MSM_VIDC_CORE_INVALID;
 		mutex_unlock(&inst->sync_lock);
-		dqevent.type = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
-		dqevent.id = 0;
-		v4l2_event_queue_fh(&inst->event_handler, &dqevent);
+		msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
 		wake_up(&inst->kernel_event_queue);
 	}
 	return rc;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index d9a2332..15f4e3f 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -168,9 +168,9 @@
 	int samples;
 };
 
-enum msm_vidc_mode {
-	VIDC_NON_SECURE,
-	VIDC_SECURE,
+enum msm_vidc_modes {
+	VIDC_SECURE = 1 << 0,
+	VIDC_TURBO = 1 << 1,
 };
 
 struct msm_vidc_core_capability {
@@ -225,7 +225,7 @@
 	void *priv;
 	struct msm_vidc_debug debug;
 	struct buf_count count;
-	enum msm_vidc_mode mode;
+	enum msm_vidc_modes flags;
 	struct msm_vidc_core_capability capability;
 };
 
@@ -254,4 +254,6 @@
 int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
 	enum hal_ssr_trigger_type type);
 int msm_vidc_check_session_supported(struct msm_vidc_inst *inst);
+void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type);
+
 #endif
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 2bf47a4..389c13f 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -754,6 +754,10 @@
 	u32 nal_stream_format_supported;
 };
 
+struct hal_nal_stream_format_select {
+	u32 nal_stream_format_select;
+};
+
 struct hal_multi_view_format {
 	u32 views;
 	u32 rg_view_order[1];
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 6234dba..2b6d6bb 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -476,6 +476,9 @@
 	u32 nal_stream_format_supported;
 };
 
+struct hfi_nal_stream_format_select {
+	u32 nal_stream_format_select;
+};
 #define HFI_PICTURE_TYPE_I					0x01
 #define HFI_PICTURE_TYPE_P					0x02
 #define HFI_PICTURE_TYPE_B					0x04
diff --git a/drivers/media/platform/msm/wfd/enc-venus-subdev.c b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
index 9e42c7a..8121471 100644
--- a/drivers/media/platform/msm/wfd/enc-venus-subdev.c
+++ b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
@@ -78,6 +78,26 @@
 	return venc_ion_client ? 0 : -ENOMEM;
 }
 
+static int invalidate_cache(struct ion_client *client,
+		struct mem_region *mregion)
+{
+	if (!client || !mregion) {
+		WFD_MSG_ERR(
+			"Failed to flush ion buffer: invalid client or region\n");
+		return -EINVAL;
+	} else if (!mregion->ion_handle) {
+		WFD_MSG_ERR(
+			"Failed to flush ion buffer: not an ion buffer\n");
+		return -EINVAL;
+	}
+
+	return msm_ion_do_cache_op(client,
+			mregion->ion_handle,
+			mregion->kvaddr,
+			mregion->size,
+			ION_IOC_INV_CACHES);
+
+}
 static int next_free_index(struct index_bitmap *index_bitmap)
 {
 	int index = find_first_zero_bit(index_bitmap->bitmap,
@@ -237,6 +257,16 @@
 				vb->v4l2_planes[0].bytesused =
 					buffer.m.planes[0].bytesused;
 
+				/* Buffer is on its way to userspace, so
+				 * invalidate the cache */
+				rc = invalidate_cache(venc_ion_client, mregion);
+				if (rc) {
+					WFD_MSG_WARN(
+						"Failed to invalidate cache %d\n",
+						rc);
+					/* Not fatal, move on */
+				}
+
 				inst->vmops.op_buffer_done(
 					inst->vmops.cbdata, 0, vb);
 			} else if (buffer.type == BUF_TYPE_INPUT &&
@@ -266,13 +296,24 @@
 static long set_default_properties(struct venc_inst *inst)
 {
 	struct v4l2_control ctrl = {0};
+	int rc;
 
 	/* Set the IDR period as 1.  The venus core doesn't give
 	 * the sps/pps for I-frames, only IDR. */
 	ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
 	ctrl.value = 1;
+	rc = msm_vidc_s_ctrl(inst->vidc_context, &ctrl);
+	if (rc)
+		WFD_MSG_WARN("Failed to set IDR period\n");
 
-	return msm_vidc_s_ctrl(inst->vidc_context, &ctrl);
+	/* Set the default rc mode to VBR/VFR, client can change later */
+	ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
+	ctrl.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR;
+	rc = msm_vidc_s_ctrl(inst->vidc_context, &ctrl);
+	if (rc)
+		WFD_MSG_WARN("Failed to set rc mode\n");
+
+	return 0;
 }
 
 static int subscribe_events(struct venc_inst *inst)
diff --git a/drivers/media/platform/msm/wfd/mdp-5-subdev.c b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
index 6399117..97204ae 100644
--- a/drivers/media/platform/msm/wfd/mdp-5-subdev.c
+++ b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
@@ -73,7 +73,7 @@
 	mops->cookie = inst;
 	return 0;
 mdp_secure_fail:
-	msm_fb_writeback_terminate(inst->mdp);
+	msm_fb_writeback_terminate(fbi);
 mdp_open_fail:
 	kfree(inst);
 	return rc;
@@ -83,19 +83,12 @@
 {
 	struct mdp_instance *inst = arg;
 	int rc = 0;
-	struct fb_info *fbi = NULL;
 	if (inst) {
 		rc = msm_fb_writeback_start(inst->mdp);
 		if (rc) {
 			WFD_MSG_ERR("Failed to start MDP mode\n");
 			goto exit;
 		}
-		fbi = msm_fb_get_writeback_fb();
-		if (!fbi) {
-			WFD_MSG_ERR("Failed to acquire mdp instance\n");
-			rc = -ENODEV;
-			goto exit;
-		}
 	}
 exit:
 	return rc;
@@ -105,7 +98,6 @@
 {
 	struct mdp_instance *inst = arg;
 	int rc = 0;
-	struct fb_info *fbi = NULL;
 	if (inst) {
 		rc = msm_fb_writeback_stop(inst->mdp);
 		if (rc) {
@@ -113,7 +105,6 @@
 			return rc;
 		}
 
-		fbi = (struct fb_info *)inst->mdp;
 	}
 	return 0;
 }
@@ -121,12 +112,10 @@
 static int mdp_close(struct v4l2_subdev *sd, void *arg)
 {
 	struct mdp_instance *inst = arg;
-	struct fb_info *fbi = NULL;
 	if (inst) {
-		fbi = (struct fb_info *)inst->mdp;
 		if (inst->secure)
 			msm_fb_writeback_set_secure(inst->mdp, false);
-		msm_fb_writeback_terminate(fbi);
+		msm_fb_writeback_terminate(inst->mdp);
 		kfree(inst);
 	}
 	return 0;
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 130ff48..3d0abce 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -283,14 +283,6 @@
 	},
 };
 
-
-enum wcd9xxx_chipid_major {
-	TABLA_MAJOR = cpu_to_le16(0x100),
-	SITAR_MAJOR = cpu_to_le16(0x101),
-	TAIKO_MAJOR = cpu_to_le16(0x102),
-	TAPAN_MAJOR = cpu_to_le16(0x103),
-};
-
 static const struct wcd9xxx_codec_type wcd9xxx_codecs[] = {
 	{
 		TABLA_MAJOR, cpu_to_le16(0x1), tabla1x_devs,
@@ -1729,6 +1721,7 @@
 	.id_table = tapan_slimtest_id,
 	.resume = wcd9xxx_slim_resume,
 	.suspend = wcd9xxx_slim_suspend,
+	.device_up = wcd9xxx_slim_device_up,
 };
 
 static struct i2c_device_id wcd9xxx_id_table[] = {
diff --git a/drivers/mfd/wcd9xxx-irq.c b/drivers/mfd/wcd9xxx-irq.c
index 5efd905..062351d 100644
--- a/drivers/mfd/wcd9xxx-irq.c
+++ b/drivers/mfd/wcd9xxx-irq.c
@@ -193,10 +193,24 @@
 	mutex_unlock(&wcd9xxx->nested_irq_lock);
 }
 
-static void wcd9xxx_irq_dispatch(struct wcd9xxx *wcd9xxx, int irqbit)
+static bool wcd9xxx_is_mbhc_irq(struct wcd9xxx *wcd9xxx, int irqbit)
 {
 	if ((irqbit <= WCD9XXX_IRQ_MBHC_INSERTION) &&
-	    (irqbit >= WCD9XXX_IRQ_MBHC_REMOVAL)) {
+	    (irqbit >= WCD9XXX_IRQ_MBHC_REMOVAL))
+		return true;
+	else if (wcd9xxx->codec_type->id_major == TAIKO_MAJOR &&
+		 irqbit == WCD9320_IRQ_MBHC_JACK_SWITCH)
+		return true;
+	else if (wcd9xxx->codec_type->id_major == TAPAN_MAJOR &&
+		 irqbit == WCD9306_IRQ_MBHC_JACK_SWITCH)
+		return true;
+	else
+		return false;
+}
+
+static void wcd9xxx_irq_dispatch(struct wcd9xxx *wcd9xxx, int irqbit)
+{
+	if (wcd9xxx_is_mbhc_irq(wcd9xxx, irqbit)) {
 		wcd9xxx_nested_irq_lock(wcd9xxx);
 		wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_INTR_CLEAR0 +
 					   BIT_BYTE(irqbit),
diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c
index 2c14be7..14dd313 100644
--- a/drivers/mmc/core/cd-gpio.c
+++ b/drivers/mmc/core/cd-gpio.c
@@ -20,12 +20,44 @@
 struct mmc_cd_gpio {
 	unsigned int gpio;
 	char label[0];
+	bool status;
 };
 
+static int mmc_cd_get_status(struct mmc_host *host)
+{
+	int ret = -ENOSYS;
+	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
+
+	if (!cd || !gpio_is_valid(cd->gpio))
+		goto out;
+
+	ret = !gpio_get_value_cansleep(cd->gpio) ^
+		!!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH);
+out:
+	return ret;
+}
+
 static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
 {
-	/* Schedule a card detection after a debounce timeout */
-	mmc_detect_change(dev_id, msecs_to_jiffies(100));
+	struct mmc_host *host = dev_id;
+	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
+	int status;
+
+	status = mmc_cd_get_status(host);
+	if (unlikely(status < 0))
+		goto out;
+
+	if (status ^ cd->status) {
+		pr_info("%s: slot status change detected (%d -> %d), GPIO_ACTIVE_%s\n",
+				mmc_hostname(host), cd->status, status,
+				(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) ?
+				"HIGH" : "LOW");
+		cd->status = status;
+
+		/* Schedule a card detection after a debounce timeout */
+		mmc_detect_change(host, msecs_to_jiffies(100));
+	}
+out:
 	return IRQ_HANDLED;
 }
 
@@ -49,16 +81,22 @@
 	if (ret < 0)
 		goto egpioreq;
 
+	cd->gpio = gpio;
+	host->hotplug.irq = irq;
+	host->hotplug.handler_priv = cd;
+
+	ret = mmc_cd_get_status(host);
+	if (ret < 0)
+		goto eirqreq;
+
+	cd->status = ret;
+
 	ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
 				   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				   cd->label, host);
 	if (ret < 0)
 		goto eirqreq;
 
-	cd->gpio = gpio;
-	host->hotplug.irq = irq;
-	host->hotplug.handler_priv = cd;
-
 	return 0;
 
 eirqreq:
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 3d525e1..04687fa 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1073,8 +1073,13 @@
 
 		if (!err && R1_CURRENT_STATE(status) == R1_STATE_TRAN)
 			break;
-		if (time_after(jiffies, prg_wait))
-			err = -ETIMEDOUT;
+		if (time_after(jiffies, prg_wait)) {
+			err = mmc_send_status(card, &status);
+			if (!err && R1_CURRENT_STATE(status) != R1_STATE_TRAN)
+				err = -ETIMEDOUT;
+			else
+				break;
+		}
 	} while (!err);
 
 out:
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 3c0576e..c73bf01 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1119,6 +1119,7 @@
 	int len, i;
 	int clk_table_len;
 	u32 *clk_table = NULL;
+	enum of_gpio_flags flags = OF_GPIO_ACTIVE_LOW;
 
 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
@@ -1126,7 +1127,9 @@
 		goto out;
 	}
 
-	pdata->status_gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, 0);
+	pdata->status_gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &flags);
+	if (gpio_is_valid(pdata->status_gpio) & !(flags & OF_GPIO_ACTIVE_LOW))
+		pdata->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
 
 	of_property_read_u32(np, "qcom,bus-width", &bus_width);
 	if (bus_width == 8)
@@ -2235,16 +2238,16 @@
 		goto pclk_disable;
 	}
 
-	ret = clk_prepare_enable(msm_host->clk);
-	if (ret)
-		goto pclk_disable;
-
 	/* Set to the minimum supported clock frequency */
 	ret = clk_set_rate(msm_host->clk, sdhci_msm_get_min_clock(host));
 	if (ret) {
 		dev_err(&pdev->dev, "MClk rate set failed (%d)\n", ret);
-		goto clk_disable;
+		goto pclk_disable;
 	}
+	ret = clk_prepare_enable(msm_host->clk);
+	if (ret)
+		goto pclk_disable;
+
 	msm_host->clk_rate = sdhci_msm_get_min_clock(host);
 	atomic_set(&msm_host->clks_on, 1);
 
diff --git a/drivers/net/ethernet/msm/msm_rmnet_smux.c b/drivers/net/ethernet/msm/msm_rmnet_smux.c
index 5fe724e..e2bd82d 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_smux.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_smux.c
@@ -55,7 +55,7 @@
 #define DBG2(x...) DBG(DEBUG_MASK_LVL2, x)
 
 /* Configure device instances */
-#define RMNET_SMUX_DEVICE_COUNT (1)
+#define RMNET_SMUX_DEVICE_COUNT (2)
 
 /* allow larger frames */
 #define RMNET_DATA_LEN 2000
diff --git a/drivers/net/ethernet/msm/msm_rmnet_wwan.c b/drivers/net/ethernet/msm/msm_rmnet_wwan.c
index f90ee3d..98bdccc 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_wwan.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_wwan.c
@@ -547,7 +547,7 @@
 
 static void wwan_tx_timeout(struct net_device *dev)
 {
-	pr_warning("[%s] wwan_tx_timeout()\n", dev->name);
+	pr_warning("[%s] wwan_tx_timeout(), data stall in UL\n", dev->name);
 }
 
 /**
diff --git a/drivers/platform/msm/ipa/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_debugfs.c
index cec92e8..aaf5cc0 100644
--- a/drivers/platform/msm/ipa/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_debugfs.c
@@ -15,7 +15,7 @@
 #include <linux/debugfs.h>
 #include <linux/stringify.h>
 #include "ipa_i.h"
-
+#include "ipa_rm_i.h"
 
 #define IPA_MAX_MSG_LEN 4096
 #define IPA_DBG_CNTR_ON 127265
@@ -104,6 +104,7 @@
 static struct dentry *dfile_dbg_cnt;
 static struct dentry *dfile_msg;
 static struct dentry *dfile_ip4_nat;
+static struct dentry *dfile_rm_stats;
 static char dbg_buff[IPA_MAX_MSG_LEN];
 static s8 ep_reg_idx;
 
@@ -949,6 +950,20 @@
 	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
 }
 
+static ssize_t ipa_rm_read_stats(struct file *file, char __user *ubuf,
+		size_t count, loff_t *ppos)
+{
+	int result, nbytes, cnt = 0;
+	result = ipa_rm_stat(dbg_buff, IPA_MAX_MSG_LEN);
+	if (result < 0) {
+		nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
+				"Error in printing RM stat %d\n", result);
+		cnt += nbytes;
+	} else
+		cnt += result;
+	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
+}
+
 const struct file_operations ipa_gen_reg_ops = {
 	.read = ipa_read_gen_reg,
 };
@@ -993,6 +1008,10 @@
 	.read = ipa_read_nat4,
 };
 
+const struct file_operations ipa_rm_stats = {
+	.read = ipa_rm_read_stats,
+};
+
 void ipa_debugfs_init(void)
 {
 	const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH;
@@ -1090,6 +1109,13 @@
 		goto fail;
 	}
 
+	dfile_rm_stats = debugfs_create_file("rm_stats", read_only_mode,
+		dent, 0,
+		&ipa_rm_stats);
+	if (!dfile_rm_stats || IS_ERR(dfile_rm_stats)) {
+		IPAERR("fail to create file for debug_fs rm_stats\n");
+		goto fail;
+	}
 	return;
 
 fail:
diff --git a/drivers/platform/msm/ipa/ipa_rm.c b/drivers/platform/msm/ipa/ipa_rm.c
index 38bff2c..e057c5a 100644
--- a/drivers/platform/msm/ipa/ipa_rm.c
+++ b/drivers/platform/msm/ipa/ipa_rm.c
@@ -430,6 +430,46 @@
 }
 
 /**
+ * ipa_rm_stat() - print RM stat
+ * @buf: [in] The user buff used to print
+ * @size: [in] The size of buf
+ * Returns: number of bytes used on success, negative on failure
+ *
+ * This function is called by ipa_debugfs in order to receive
+ * a full picture of the current state of the RM
+ */
+
+int ipa_rm_stat(char *buf, int size)
+{
+	int i, cnt = 0, result = EINVAL;
+	struct ipa_rm_resource *resource = NULL;
+
+	if (!buf || size < 0)
+		goto bail;
+
+	read_lock(&ipa_rm_ctx->lock);
+	for (i = 0; i < IPA_RM_RESOURCE_PROD_MAX; ++i) {
+		result = ipa_rm_dep_graph_get_resource(
+				ipa_rm_ctx->dep_graph,
+				i,
+				&resource);
+		if (!result) {
+			result = ipa_rm_resource_producer_print_stat(
+							resource, buf + cnt,
+							size-cnt);
+			if (result < 0)
+				goto bail;
+			cnt += result;
+		}
+	}
+	result = cnt;
+
+bail:
+	read_unlock(&ipa_rm_ctx->lock);
+	return result;
+}
+
+/**
  * ipa_rm_exit() - free all IPA RM resources
  */
 void ipa_rm_exit(void)
diff --git a/drivers/platform/msm/ipa/ipa_rm_i.h b/drivers/platform/msm/ipa/ipa_rm_i.h
index ce5d3ae..b853e2b 100644
--- a/drivers/platform/msm/ipa/ipa_rm_i.h
+++ b/drivers/platform/msm/ipa/ipa_rm_i.h
@@ -63,6 +63,8 @@
 
 int ipa_rm_initialize(void);
 
+int ipa_rm_stat(char *buf, int size);
+
 void ipa_rm_exit(void);
 
 #endif /* _IPA_RM_I_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_rm_resource.c b/drivers/platform/msm/ipa/ipa_rm_resource.c
index 06c7f21..7142dc7 100644
--- a/drivers/platform/msm/ipa/ipa_rm_resource.c
+++ b/drivers/platform/msm/ipa/ipa_rm_resource.c
@@ -525,10 +525,11 @@
 		consumer_result = ipa_rm_resource_consumer_request(
 				(struct ipa_rm_resource_cons *)depends_on);
 		spin_lock_irqsave(&resource->state_lock, flags);
-		if (consumer_result != -EINPROGRESS)
+		if (consumer_result != -EINPROGRESS) {
 			resource->state = prev_state;
 			((struct ipa_rm_resource_prod *)
 					resource)->pending_request--;
+		}
 		result = consumer_result;
 		break;
 	}
@@ -913,3 +914,197 @@
 	spin_unlock_irqrestore(&consumer->resource.state_lock, flags);
 	return;
 }
+
+/*
+ * ipa_rm_resource_producer_print_stat() - print the
+ * resource status and all his dependencies
+ *
+ * @resource: [in] Resource resource
+ * @buff: [in] The buf used to print
+ * @size: [in] Buf size
+ *
+ * Returns: number of bytes used on success, negative on failure
+ */
+
+int ipa_rm_resource_producer_print_stat(
+				struct ipa_rm_resource *resource,
+				char *buf,
+				int size){
+
+	int i, nbytes, cnt = 0;
+	unsigned long flags;
+	struct ipa_rm_resource *consumer;
+
+	if (!buf || size < 0)
+		return -EINVAL;
+	switch (resource->name) {
+	case IPA_RM_RESOURCE_BRIDGE_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			"BRIDGE_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_A2_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			"A2_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_USB_PROD:
+			nbytes = scnprintf(buf + cnt, size - cnt,
+			 "USB_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_HSIC_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			 "HSIC_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_STD_ECM_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			 "STD_ECM_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_WWAN_0_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			 "WWAN_0_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_WWAN_1_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			"WWAN_1_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_WWAN_2_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			"WWAN_2_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_WWAN_3_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+				 "WWAN_3_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_WWAN_4_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			"WWAN_4_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_WWAN_5_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			 "WWAN_5_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_WWAN_6_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			"WWAN_6_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_WWAN_7_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			 "WWAN_7_PROD[");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RESOURCE_WLAN_PROD:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			 "WLAN_PROD[");
+		cnt += nbytes;
+		break;
+	default:
+		return -EPERM;
+	}
+	spin_lock_irqsave(&resource->state_lock, flags);
+	switch (resource->state) {
+	case IPA_RM_RELEASED:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			"Released] -> ");
+		cnt += nbytes;
+		break;
+	case IPA_RM_REQUEST_IN_PROGRESS:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			"Request In Progress] -> ");
+		cnt += nbytes;
+		break;
+	case IPA_RM_GRANTED:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			"Granted] -> ");
+		cnt += nbytes;
+		break;
+	case IPA_RM_RELEASE_IN_PROGRESS:
+		nbytes = scnprintf(buf + cnt, size - cnt,
+			"Release In Progress] -> ");
+		cnt += nbytes;
+		break;
+	default:
+		spin_unlock_irqrestore(
+			&resource->state_lock,
+			flags);
+		return -EPERM;
+	}
+	spin_unlock_irqrestore(
+			&resource->state_lock,
+			flags);
+	for (i = 0; i < resource->peers_list->max_peers; ++i) {
+		consumer =
+			ipa_rm_peers_list_get_resource(
+			i,
+			resource->peers_list);
+		if (consumer) {
+			switch (consumer->name) {
+			case IPA_RM_RESOURCE_A2_CONS:
+				nbytes = scnprintf(buf + cnt,
+						size - cnt,
+						 " A2_CONS[");
+				cnt += nbytes;
+				break;
+			case IPA_RM_RESOURCE_USB_CONS:
+				nbytes = scnprintf(buf + cnt,
+						size - cnt,
+						 " USB_CONS[");
+				cnt += nbytes;
+				break;
+			case IPA_RM_RESOURCE_HSIC_CONS:
+				nbytes = scnprintf(buf + cnt,
+						size - cnt,
+						 " HSIC_CONS[");
+				cnt += nbytes;
+				break;
+			default:
+				return -EPERM;
+			}
+			spin_lock_irqsave(&consumer->state_lock, flags);
+			switch (consumer->state) {
+			case IPA_RM_RELEASED:
+				nbytes = scnprintf(buf + cnt, size - cnt,
+					"Released], ");
+				cnt += nbytes;
+				break;
+			case IPA_RM_REQUEST_IN_PROGRESS:
+				nbytes = scnprintf(buf + cnt, size - cnt,
+						"Request In Progress], ");
+				cnt += nbytes;
+					break;
+			case IPA_RM_GRANTED:
+				nbytes = scnprintf(buf + cnt, size - cnt,
+						"Granted], ");
+				cnt += nbytes;
+				break;
+			case IPA_RM_RELEASE_IN_PROGRESS:
+				nbytes = scnprintf(buf + cnt, size - cnt,
+						"Release In Progress], ");
+				cnt += nbytes;
+				break;
+			default:
+				spin_unlock_irqrestore(
+						&consumer->state_lock,
+						flags);
+				return -EPERM;
+			}
+			spin_unlock_irqrestore(
+					&consumer->state_lock,
+					flags);
+		}
+	}
+	nbytes = scnprintf(buf + cnt, size - cnt,
+			 "\n");
+	cnt += nbytes;
+	return cnt;
+}
diff --git a/drivers/platform/msm/ipa/ipa_rm_resource.h b/drivers/platform/msm/ipa/ipa_rm_resource.h
index 0fc3677..3fe474b 100644
--- a/drivers/platform/msm/ipa/ipa_rm_resource.h
+++ b/drivers/platform/msm/ipa/ipa_rm_resource.h
@@ -128,4 +128,9 @@
 				enum ipa_rm_event event,
 				bool notify_registered_only);
 
+int ipa_rm_resource_producer_print_stat(
+		struct ipa_rm_resource *resource,
+		char *buf,
+		int size);
+
 #endif /* _IPA_RM_RESOURCE_H_ */
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 6b77609..c39de83 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -94,6 +94,7 @@
 	u8 pipes_enabled_per_bam[MAX_BAMS];
 	u32 inactivity_timer_ms[MAX_BAMS];
 	bool is_bam_inactivity[MAX_BAMS];
+	struct completion reset_done;
 };
 
 static char *bam_enable_strings[MAX_BAMS] = {
@@ -1554,6 +1555,10 @@
 	}
 
 	peer_handshake_info.client_ready = ready;
+	if (peer_handshake_info.state == USB_BAM_SM_PLUG_ACKED && !ready) {
+		pr_debug("Starting reset sequence");
+		INIT_COMPLETION(ctx.reset_done);
+	}
 
 	spin_unlock(&usb_bam_peer_handshake_info_lock);
 	if (!queue_work(ctx.usb_bam_wq,
@@ -1755,6 +1760,7 @@
 	case USB_BAM_SM_PLUG_ACKED:
 		if (!peer_handshake_info.client_ready) {
 			spin_unlock(&usb_bam_peer_handshake_info_lock);
+			pr_debug("Starting A2 reset sequence");
 			smsm_change_state(SMSM_APPS_STATE,
 				SMSM_USB_PLUG_UNPLUG, 0);
 			spin_lock(&usb_bam_peer_handshake_info_lock);
@@ -1767,6 +1773,8 @@
 			peer_handshake_info.reset_event.
 				callback(peer_handshake_info.reset_event.param);
 			spin_lock(&usb_bam_peer_handshake_info_lock);
+			complete_all(&ctx.reset_done);
+			pr_debug("Finished reset sequence");
 			peer_handshake_info.state = USB_BAM_SM_INIT;
 			peer_handshake_info.ack_received = 0;
 		}
@@ -2054,7 +2062,17 @@
 }
 EXPORT_SYMBOL(usb_bam_disconnect_ipa);
 
-int usb_bam_a2_reset(void)
+void usb_bam_reset_complete(void)
+{
+	pr_debug("Waiting for reset compelte");
+	if (wait_for_completion_interruptible_timeout(&ctx.reset_done,
+			10*HZ) <= 0)
+		pr_warn("Timeout while waiting for reset");
+
+	pr_debug("Finished Waiting for reset complete");
+}
+
+int usb_bam_a2_reset(bool to_reconnect)
 {
 	struct usb_bam_pipe_connect *pipe_connect;
 	int i;
@@ -2095,6 +2113,9 @@
 	if (bam != -1 && sps_device_reset(ctx.h_bam[bam]))
 		pr_err("%s: BAM reset failed\n", __func__);
 
+	if (!to_reconnect)
+		return ret;
+
 	/* Reconnect A2 pipes */
 	for (i = 0; i < ctx.max_connections; i++) {
 		pipe_connect = &usb_bam_connections[i];
@@ -2574,6 +2595,8 @@
 
 	spin_lock_init(&usb_bam_peer_handshake_info_lock);
 	INIT_WORK(&peer_handshake_info.reset_event.event_w, usb_bam_sm_work);
+	init_completion(&ctx.reset_done);
+	complete(&ctx.reset_done);
 
 	ctx.usb_bam_wq = alloc_workqueue("usb_bam_wq",
 		WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 816aa4f..28dd539 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -1443,8 +1443,6 @@
 	int rc;
 	bool charging, charging_since_last_report;
 
-	soc = chip->calculated_soc;
-
 	rc = qpnp_vadc_read(LR_MUX1_BATT_THERM, &result);
 
 	if (rc) {
@@ -1457,6 +1455,8 @@
 	batt_temp = (int)result.physical;
 
 	mutex_lock(&chip->last_soc_mutex);
+	soc = chip->calculated_soc;
+
 	last_change_sec = chip->last_soc_change_sec;
 	calculate_delta_time(&last_change_sec, &time_since_last_change_sec);
 
@@ -1550,18 +1550,18 @@
 		return report_cc_based_soc(chip);
 }
 
-#define VBATT_ERROR_MARGIN	20000
+#define VDD_MAX_ERR		5000
+#define VDD_STEP_SIZE		10000
 static int charging_adjustments(struct qpnp_bms_chip *chip,
 				struct soc_params *params, int soc,
 				int vbat_uv, int ibat_ua, int batt_temp)
 {
 	int chg_soc, soc_ibat, batt_terminal_uv, weight_ibat, weight_cc;
 
-	batt_terminal_uv = vbat_uv + VBATT_ERROR_MARGIN
-				+ (ibat_ua * chip->r_conn_mohm) / 1000;
+	batt_terminal_uv = vbat_uv + (ibat_ua * chip->r_conn_mohm) / 1000;
 
 	if (chip->soc_at_cv == -EINVAL) {
-		if (batt_terminal_uv >= chip->max_voltage_uv) {
+		if (batt_terminal_uv >= chip->max_voltage_uv - VDD_MAX_ERR) {
 			chip->soc_at_cv = soc;
 			chip->prev_chg_soc = soc;
 			chip->ibat_at_cv_ua = ibat_ua;
@@ -1585,7 +1585,7 @@
 	 * if voltage lessened (possibly because of a system load)
 	 * keep reporting the prev chg soc
 	 */
-	if (batt_terminal_uv <= chip->prev_batt_terminal_uv) {
+	if (batt_terminal_uv <= chip->prev_batt_terminal_uv - VDD_STEP_SIZE) {
 		pr_debug("batt_terminal_uv %d < (max = %d - 10000); CC CHG SOC %d\n",
 			batt_terminal_uv, chip->prev_batt_terminal_uv,
 			chip->prev_chg_soc);
@@ -1600,7 +1600,9 @@
 	weight_ibat = bound_soc(linear_interpolate(1, chip->soc_at_cv,
 					100, 100, chip->prev_chg_soc));
 	weight_cc = 100 - weight_ibat;
-	chg_soc = bound_soc((soc_ibat * weight_ibat + weight_cc * soc)/100);
+	chg_soc = bound_soc(DIV_ROUND_CLOSEST(soc_ibat * weight_ibat
+			+ weight_cc * soc, 100));
+
 	pr_debug("weight_ibat = %d, weight_cc = %d, soc_ibat = %d, soc_cc = %d\n",
 			weight_ibat, weight_cc, soc_ibat, soc);
 
@@ -1932,9 +1934,9 @@
 					new_calculated_soc);
 
 done_calculating:
+	mutex_lock(&chip->last_soc_mutex);
 	chip->calculated_soc = new_calculated_soc;
 	pr_debug("CC based calculated SOC = %d\n", chip->calculated_soc);
-	mutex_lock(&chip->last_soc_mutex);
 	if (chip->last_soc_invalid) {
 		chip->last_soc_invalid = false;
 		chip->last_soc = -EINVAL;
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 476aaa2..f051af2 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -349,11 +349,16 @@
 qpnp_chg_read(struct qpnp_chg_chip *chip, u8 *val,
 			u16 base, int count)
 {
-	int rc;
+	int rc = 0;
 	struct spmi_device *spmi = chip->spmi;
 
-	rc = spmi_ext_register_readl(spmi->ctrl, spmi->sid, base, val,
-					count);
+	if (base == 0) {
+		pr_err("base cannot be zero base=0x%02x sid=0x%02x rc=%d\n",
+			base, spmi->sid, rc);
+		return -EINVAL;
+	}
+
+	rc = spmi_ext_register_readl(spmi->ctrl, spmi->sid, base, val, count);
 	if (rc) {
 		pr_err("SPMI read failed base=0x%02x sid=0x%02x rc=%d\n", base,
 				spmi->sid, rc);
@@ -366,11 +371,16 @@
 qpnp_chg_write(struct qpnp_chg_chip *chip, u8 *val,
 			u16 base, int count)
 {
-	int rc;
+	int rc = 0;
 	struct spmi_device *spmi = chip->spmi;
 
-	rc = spmi_ext_register_writel(spmi->ctrl, spmi->sid, base, val,
-					count);
+	if (base == 0) {
+		pr_err("base cannot be zero base=0x%02x sid=0x%02x rc=%d\n",
+			base, spmi->sid, rc);
+		return -EINVAL;
+	}
+
+	rc = spmi_ext_register_writel(spmi->ctrl, spmi->sid, base, val, count);
 	if (rc) {
 		pr_err("write failed base=0x%02x sid=0x%02x rc=%d\n",
 			base, spmi->sid, rc);
@@ -2161,7 +2171,7 @@
 			rc |= devm_request_irq(chip->dev,
 				chip->chg_vbatdet_lo.irq,
 				qpnp_chg_vbatdet_lo_irq_handler,
-				IRQF_TRIGGER_RISING,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				"vbat-det-lo", chip);
 			if (rc < 0) {
 				pr_err("Can't request %d vbat-det-lo: %d\n",
@@ -2940,12 +2950,14 @@
 	struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
 	int rc = 0;
 
-	rc = qpnp_chg_masked_write(chip,
-	chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
-		VREF_BATT_THERM_FORCE_ON,
-		VREF_BATT_THERM_FORCE_ON, 1);
-	if (rc)
-		pr_debug("failed to force on VREF_BAT_THM rc=%d\n", rc);
+	if (chip->bat_if_base) {
+		rc = qpnp_chg_masked_write(chip,
+			chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
+			VREF_BATT_THERM_FORCE_ON,
+			VREF_BATT_THERM_FORCE_ON, 1);
+		if (rc)
+			pr_debug("failed to force on VREF_BAT_THM rc=%d\n", rc);
+	}
 
 	return rc;
 }
@@ -2955,12 +2967,14 @@
 	struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
 	int rc = 0;
 
-	rc = qpnp_chg_masked_write(chip,
-	chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
-		VREF_BATT_THERM_FORCE_ON,
-		VREF_BAT_THM_ENABLED_FSM, 1);
-	if (rc)
-		pr_debug("failed to enable FSM ctrl VREF_BAT_THM rc=%d\n", rc);
+	if (chip->bat_if_base) {
+		rc = qpnp_chg_masked_write(chip,
+			chip->bat_if_base + BAT_IF_VREF_BAT_THM_CTRL,
+			VREF_BATT_THERM_FORCE_ON,
+			VREF_BAT_THM_ENABLED_FSM, 1);
+		if (rc)
+			pr_debug("failed to set FSM VREF_BAT_THM rc=%d\n", rc);
+	}
 
 	return rc;
 }
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index 18dd054..1a4c3f3 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -481,6 +481,16 @@
 	else if (dd->mode == SPI_BAM_MODE)
 		spi_config |= SPI_CFG_INPUT_FIRST;
 
+	/*
+	 * HS_MODE improves signal stability for spi-clk high rates
+	 * but is invalid in LOOPBACK mode.
+	 */
+	if ((dd->clock_speed >= SPI_HS_MIN_RATE) &&
+	   !(dd->cur_msg->spi->mode & SPI_LOOP))
+		spi_config |= SPI_CFG_HS_MODE;
+	else
+		spi_config &= ~SPI_CFG_HS_MODE;
+
 	writel_relaxed(spi_config, dd->base + SPI_CONFIG);
 }
 
diff --git a/drivers/spi/spi_qsd.h b/drivers/spi/spi_qsd.h
index b749cc0..fd1adf0 100644
--- a/drivers/spi/spi_qsd.h
+++ b/drivers/spi/spi_qsd.h
@@ -72,14 +72,17 @@
 #define SPI_INPUT_FIFO                QSD_REG(0x0200) QUP_REG(0x0218)
 #define SPI_STATE                     QSD_REG(SPI_OPERATIONAL) QUP_REG(0x0004)
 
-/* SPI_CONFIG fields */
-#define SPI_CFG_INPUT_FIRST           0x00000200
+/* QUP_CONFIG fields */
+#define SPI_CFG_N                     0x0000001F
 #define SPI_NO_INPUT                  0x00000080
 #define SPI_NO_OUTPUT                 0x00000040
-#define SPI_CFG_LOOPBACK              0x00000100
-#define SPI_CFG_N                     0x0000001F
 #define SPI_EN_EXT_OUT_FLAG           0x00010000
 
+/* SPI_CONFIG fields */
+#define SPI_CFG_LOOPBACK              0x00000100
+#define SPI_CFG_INPUT_FIRST           0x00000200
+#define SPI_CFG_HS_MODE               0x00000400
+
 /* SPI_IO_CONTROL fields */
 #define SPI_IO_C_FORCE_CS             0x00000800
 #define SPI_IO_C_CLK_IDLE_HIGH        0x00000400
@@ -143,6 +146,9 @@
 #define SPI_NUM_CHIPSELECTS           4
 #define SPI_SUPPORTED_MODES  (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP)
 
+/* high speed mode is when bus rate is greater then 26MHz */
+#define SPI_HS_MIN_RATE               (26000000)
+
 #define SPI_DELAY_THRESHOLD           1
 /* Default timeout is 10 milliseconds */
 #define SPI_DEFAULT_TIMEOUT           10
diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c
index f373422..4829b83 100644
--- a/drivers/staging/android/timed_output.c
+++ b/drivers/staging/android/timed_output.c
@@ -100,8 +100,8 @@
 void timed_output_dev_unregister(struct timed_output_dev *tdev)
 {
 	device_remove_file(tdev->dev, &dev_attr_enable);
-	device_destroy(timed_output_class, MKDEV(0, tdev->index));
 	dev_set_drvdata(tdev->dev, NULL);
+	device_destroy(timed_output_class, MKDEV(0, tdev->index));
 }
 EXPORT_SYMBOL_GPL(timed_output_dev_unregister);
 
diff --git a/drivers/tty/smux_ctl.c b/drivers/tty/smux_ctl.c
index 1b3a7abe..dcbfe9a 100644
--- a/drivers/tty/smux_ctl.c
+++ b/drivers/tty/smux_ctl.c
@@ -50,6 +50,7 @@
 
 static uint32_t smux_ctl_ch_id[] = {
 	SMUX_DATA_CTL_0,
+	SMUX_DATA_CTL_1,
 };
 
 #define SMUX_CTL_NUM_CHANNELS ARRAY_SIZE(smux_ctl_ch_id)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 04da6f8..bb2879b 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -427,6 +427,14 @@
 		reg &= ~DWC3_GUSB3PIPECTL_DIS_RXDET_U3_RXDET;
 		dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 	}
+	/*
+	 * clear Elastic buffer mode in GUSBPIPE_CTRL(0) register, otherwise
+	 * it results in high link errors and could cause SS mode transfer
+	 * failure.
+	 */
+	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+	reg &= ~DWC3_GUSB3PIPECTL_ELASTIC_BUF_MODE;
+	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
 	if (!dwc->ev_buffs) {
 		ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 3fb89cd..5db7420 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -195,6 +195,7 @@
 #define DWC3_GUSB3PIPECTL_SUSPHY	(1 << 17)
 #define DWC3_GUSB3PIPECTL_DELAY_P1P2P3	(7 << 19)
 #define DWC3_GUSB3PIPECTL_DIS_RXDET_U3_RXDET	(1 << 22)
+#define DWC3_GUSB3PIPECTL_ELASTIC_BUF_MODE	(1 << 0)
 
 /* Global TX Fifo Size Register */
 #define DWC3_GTXFIFOSIZ_TXFDEF(n)	((n) & 0xffff)
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index a3b2617..be9a4b5 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -498,7 +498,7 @@
 
 	power_supply_set_supply_type(dotg->psy, power_supply_type);
 
-	if ((dotg->charger->chg_type == DWC3_CDP_CHARGER) && mA > 2)
+	if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
 		mA = DWC3_IDEV_CHG_MAX;
 
 	if (dotg->charger->max_power == mA)
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index a258c30..939eb6d 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -1979,6 +1979,7 @@
 	for (i = 1; i < 5; i++)
 		mReq->ptr->page[i] = (mReq->req.dma + i * CI13XXX_PAGE_SIZE) &
 							~TD_RESERVED_MASK;
+	wmb();
 
 	/* Remote Wakeup */
 	if (udc->suspended) {
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 1530474..4c5b38d 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -57,7 +57,7 @@
 #define TD_CURR_OFFSET        (0x0FFFUL <<  0)
 #define TD_FRAME_NUM          (0x07FFUL <<  0)
 #define TD_RESERVED_MASK      (0x0FFFUL <<  0)
-} __attribute__ ((packed));
+} __attribute__ ((packed, aligned(4)));
 
 /* DMA layout of queue heads */
 struct ci13xxx_qh {
@@ -75,7 +75,7 @@
 	/* 9 */
 	u32 RESERVED;
 	struct usb_ctrlrequest   setup;
-} __attribute__ ((packed));
+} __attribute__ ((packed, aligned(4)));
 
 /* cache of larger request's original attributes */
 struct ci13xxx_multi_req {
diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index aaacd43..4db4b7a 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.c
@@ -1455,6 +1455,7 @@
 	mbim_union_desc.bSlaveInterface0 = status;
 
 	mbim->bam_port.cdev = cdev;
+	mbim->bam_port.func = &mbim->function;
 
 	status = -ENODEV;
 
@@ -1574,6 +1575,7 @@
 {
 	struct f_mbim	*mbim = func_to_mbim(f);
 
+	bam_data_destroy(mbim->port_num);
 	if (gadget_is_dualspeed(c->cdev->gadget))
 		usb_free_descriptors(f->hs_descriptors);
 	usb_free_descriptors(f->descriptors);
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index 37189d8..4586d80 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -696,8 +696,8 @@
 			break;
 		}
 
-		if (count > MTP_BULK_BUFFER_SIZE)
-			xfer = MTP_BULK_BUFFER_SIZE;
+		if (count > mtp_tx_req_len)
+			xfer = mtp_tx_req_len;
 		else
 			xfer = count;
 		if (xfer && copy_from_user(req->buf, buf, xfer)) {
@@ -789,8 +789,8 @@
 			break;
 		}
 
-		if (count > MTP_BULK_BUFFER_SIZE)
-			xfer = MTP_BULK_BUFFER_SIZE;
+		if (count > mtp_tx_req_len)
+			xfer = mtp_tx_req_len;
 		else
 			xfer = count;
 
diff --git a/drivers/usb/gadget/f_qc_ecm.c b/drivers/usb/gadget/f_qc_ecm.c
index a6b443f..3db5b51 100644
--- a/drivers/usb/gadget/f_qc_ecm.c
+++ b/drivers/usb/gadget/f_qc_ecm.c
@@ -846,6 +846,7 @@
 
 	DBG(c->cdev, "ecm unbind\n");
 
+	bam_data_destroy(0);
 	if (gadget_is_dualspeed(c->cdev->gadget))
 		usb_free_descriptors(f->hs_descriptors);
 	usb_free_descriptors(f->descriptors);
diff --git a/drivers/usb/gadget/f_qc_rndis.c b/drivers/usb/gadget/f_qc_rndis.c
index 267cf53..c1ab552 100644
--- a/drivers/usb/gadget/f_qc_rndis.c
+++ b/drivers/usb/gadget/f_qc_rndis.c
@@ -725,14 +725,14 @@
 		 */
 		rndis->port.cdc_filter = 0;
 
+		if (rndis_qc_bam_connect(rndis))
+			goto fail;
+
 		DBG(cdev, "RNDIS RX/TX early activation ...\n");
 		net = gether_qc_connect_name(&rndis->port, "rndis0", false);
 		if (IS_ERR(net))
 			return PTR_ERR(net);
 
-		if (rndis_qc_bam_connect(rndis))
-			goto fail;
-
 		rndis_set_param_dev(rndis->config, net,
 				&rndis->port.cdc_filter);
 	} else
@@ -976,6 +976,8 @@
 {
 	struct f_rndis_qc		*rndis = func_to_rndis_qc(f);
 
+	pr_debug("rndis_qc_unbind: free");
+	bam_data_destroy(0);
 	rndis_deregister(rndis->config);
 	rndis_exit();
 
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index b71f903..9dd9978 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -778,6 +778,7 @@
 	unsigned long flags;
 
 	if (d->trans == USB_GADGET_XPORT_BAM2BAM) {
+		usb_bam_reset_complete();
 		ret = usb_bam_connect(d->src_connection_idx, &d->src_pipe_idx);
 		if (ret) {
 			pr_err("%s: usb_bam_connect (src) failed: err:%d\n",
@@ -916,7 +917,7 @@
 	msm_hw_bam_disable(1);
 
 	/* Reset BAM */
-	ret = usb_bam_a2_reset();
+	ret = usb_bam_a2_reset(0);
 	if (ret) {
 		pr_err("%s: BAM reset failed %d\n", __func__, ret);
 		goto reenable_eps;
diff --git a/drivers/usb/gadget/u_bam_data.c b/drivers/usb/gadget/u_bam_data.c
index c638164..5c7e52f 100644
--- a/drivers/usb/gadget/u_bam_data.c
+++ b/drivers/usb/gadget/u_bam_data.c
@@ -145,69 +145,24 @@
 	struct bam_data_port	*port = (struct bam_data_port *)param;
 	struct bam_data_ch_info *d;
 	int ret;
-	bool reenable_eps = false;
 
 	d = &port->data_ch;
 
 	pr_debug("%s: reset by peer\n", __func__);
 
-	/* Disable the relevant EPs if currently EPs are enabled */
-	if (port->port_usb && port->port_usb->in &&
-	  port->port_usb->in->driver_data) {
-		usb_ep_disable(port->port_usb->out);
-		usb_ep_disable(port->port_usb->in);
-
-		port->port_usb->in->driver_data = NULL;
-		port->port_usb->out->driver_data = NULL;
-		reenable_eps = true;
-	}
-
 	/* Disable BAM */
 	msm_hw_bam_disable(1);
 
 	/* Reset BAM */
-	ret = usb_bam_a2_reset();
+	ret = usb_bam_a2_reset(0);
 	if (ret) {
 		pr_err("%s: BAM reset failed %d\n", __func__, ret);
-		goto reenable_eps;
+		return ret;
 	}
 
 	/* Enable BAM */
 	msm_hw_bam_disable(0);
 
-reenable_eps:
-	/* Re-Enable the relevant EPs, if EPs were originally enabled */
-	if (reenable_eps) {
-		if (config_ep_by_speed(port->port_usb->cdev->gadget,
-			port->port_usb->func, port->port_usb->in) ||
-		    config_ep_by_speed(port->port_usb->cdev->gadget,
-			port->port_usb->func, port->port_usb->out)) {
-			pr_err("%s: config_ep_by_speed failed", __func__);
-				port->port_usb->in->desc = NULL;
-				port->port_usb->out->desc = NULL;
-				return -EINVAL;
-		}
-		ret = usb_ep_enable(port->port_usb->in);
-		if (ret) {
-			pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
-				__func__, port->port_usb->in);
-			return ret;
-		}
-		port->port_usb->in->driver_data = port;
-
-		ret = usb_ep_enable(port->port_usb->out);
-		if (ret) {
-			pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
-				__func__, port->port_usb->out);
-			port->port_usb->in->driver_data = 0;
-			return ret;
-		}
-		port->port_usb->out->driver_data = port;
-
-		bam_data_start_endless_rx(port);
-		bam_data_start_endless_tx(port);
-	}
-
 	/* Unregister the peer reset callback */
 	usb_bam_register_peer_reset_cb(NULL, NULL);
 
@@ -244,6 +199,7 @@
 	int ret;
 
 	pr_debug("%s: Connect workqueue started", __func__);
+	usb_bam_reset_complete();
 
 	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
 		if (d->func_type == USB_FUNC_MBIM) {
@@ -504,6 +460,23 @@
 	return 0;
 }
 
+int bam_data_destroy(unsigned int no_bam2bam_port)
+{
+	struct bam_data_ch_info	*d;
+	struct bam_data_port	*port;
+
+	port = bam2bam_data_ports[no_bam2bam_port];
+	d = &port->data_ch;
+
+	pr_debug("bam_data_destroy: Freeing ports\n");
+	bam2bam_data_port_free(no_bam2bam_port);
+	if (bam_data_wq)
+		destroy_workqueue(bam_data_wq);
+	bam_data_wq = NULL;
+
+	return 0;
+}
+
 int bam_data_setup(unsigned int no_bam2bam_port)
 {
 	int	i;
@@ -516,6 +489,11 @@
 		return -EINVAL;
 	}
 
+	if (bam_data_wq) {
+		pr_debug("bam_data is already setup");
+		return 0;
+	}
+
 	bam_data_wq = alloc_workqueue("k_bam_data",
 				      WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
 	if (!bam_data_wq) {
diff --git a/drivers/usb/gadget/u_bam_data.h b/drivers/usb/gadget/u_bam_data.h
index 5ce678d..61f653a 100644
--- a/drivers/usb/gadget/u_bam_data.h
+++ b/drivers/usb/gadget/u_bam_data.h
@@ -36,6 +36,8 @@
 
 int bam_data_setup(unsigned int no_bam2bam_port);
 
+int bam_data_destroy(unsigned int no_bam2bam_port);
+
 void bam_data_suspend(u8 port_num);
 
 void bam_data_resume(u8 port_num);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index c5304e1..f16a0b6 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -2130,7 +2130,8 @@
 	if (mehci->enable_hbm)
 		hbm_init(hcd, pdata->disable_park_mode);
 
-	msm_bam_set_hsic_host_dev(&pdev->dev);
+	if (pdata && pdata->consider_ipa_handshake)
+		msm_bam_set_hsic_host_dev(&pdev->dev);
 
 	return 0;
 
@@ -2155,7 +2156,8 @@
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 	struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
 
-	msm_bam_set_hsic_host_dev(NULL);
+	if (pdata && pdata->consider_ipa_handshake)
+		msm_bam_set_hsic_host_dev(NULL);
 
 	/* If the device was removed no need to call pm_runtime_disable */
 	if (pdev->dev.power.power_state.event != PM_EVENT_INVALID)
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index c2c783c..5055dcf 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1259,7 +1259,14 @@
 		/* Set max current limit */
 		if (power_supply_set_current_limit(psy, 0))
 			goto psy_error;
+	} else {
+		if (power_supply_set_online(psy, true))
+			goto psy_error;
+		/* Current has changed (100/2 --> 500) */
+		if (power_supply_set_current_limit(psy, 1000*mA))
+			goto psy_error;
 	}
+
 	power_supply_changed(psy);
 	return 0;
 
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 0ff19a2..e5b6603 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -94,7 +94,7 @@
 static struct msm_bus_scale_pdata mdp_bus_ppp_scale_table = {
 	.usecase = mdp_bus_ppp_usecases,
 	.num_usecases = ARRAY_SIZE(mdp_bus_ppp_usecases),
-	.name = "mdp3",
+	.name = "mdp3_ppp",
 };
 
 struct mdp3_bus_handle_map mdp3_bus_handle[MDP3_BUS_HANDLE_MAX] = {
@@ -206,18 +206,7 @@
 	unsigned long flag;
 
 	spin_lock_irqsave(&mdp3_res->irq_lock, flag);
-	if (mdp3_res->irq_ref_count[type] <= 0) {
-		pr_debug("interrupt %d not enabled\n", type);
-		spin_unlock_irqrestore(&mdp3_res->irq_lock, flag);
-		return;
-	}
-	mdp3_res->irq_ref_count[type] -= 1;
-	if (mdp3_res->irq_ref_count[type] == 0) {
-		mdp3_res->irq_mask &= ~BIT(type);
-		MDP3_REG_WRITE(MDP3_REG_INTR_ENABLE, mdp3_res->irq_mask);
-		if (!mdp3_res->irq_mask)
-			disable_irq(mdp3_res->irq);
-	}
+	mdp3_irq_disable_nosync(type);
 	spin_unlock_irqrestore(&mdp3_res->irq_lock, flag);
 }
 
@@ -773,11 +762,6 @@
 	if (rc)
 		return rc;
 
-	rc = mdp3_iommu_attach(MDP3_IOMMU_CTX_DMA_0);
-	if (rc) {
-		pr_err("fail to attach DMA-P context 0\n");
-		return rc;
-	}
 	mdp3_res->bus_handle = mdp3_bus_handle;
 	rc = mdp3_bus_scale_register();
 	if (rc) {
@@ -942,19 +926,31 @@
 	return ret;
 }
 
-int mdp3_ppp_iommu_attach(void)
+int mdp3_iommu_enable(int client)
 {
 	int rc;
-	rc = mdp3_iommu_attach(MDP3_IOMMU_CTX_PPP_0);
-	rc |= mdp3_iommu_attach(MDP3_IOMMU_CTX_PPP_1);
+
+	if (client == MDP3_CLIENT_DMA_P) {
+		rc = mdp3_iommu_attach(MDP3_IOMMU_CTX_DMA_0);
+	} else {
+		rc = mdp3_iommu_attach(MDP3_IOMMU_CTX_PPP_0);
+		rc |= mdp3_iommu_attach(MDP3_IOMMU_CTX_PPP_1);
+	}
+
 	return rc;
 }
 
-int mdp3_ppp_iommu_dettach(void)
+int mdp3_iommu_disable(int client)
 {
 	int rc;
-	rc = mdp3_iommu_dettach(MDP3_IOMMU_CTX_PPP_0);
-	rc = mdp3_iommu_dettach(MDP3_IOMMU_CTX_PPP_1);
+
+	if (client == MDP3_CLIENT_DMA_P) {
+		rc = mdp3_iommu_dettach(MDP3_IOMMU_CTX_DMA_0);
+	} else {
+		rc = mdp3_iommu_dettach(MDP3_IOMMU_CTX_PPP_0);
+		rc |= mdp3_iommu_dettach(MDP3_IOMMU_CTX_PPP_1);
+	}
+
 	return rc;
 }
 
diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h
index 31fcd0e..1afae01 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -146,8 +146,8 @@
 int mdp3_bus_scale_set_quota(int client, u64 ab_quota, u64 ib_quota);
 int mdp3_put_img(struct mdp3_img_data *data);
 int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data);
-int mdp3_ppp_iommu_attach(void);
-int mdp3_ppp_iommu_dettach(void);
+int mdp3_iommu_enable(int client);
+int mdp3_iommu_disable(int client);
 
 #define MDP3_REG_WRITE(addr, val) writel_relaxed(val, mdp3_res->mdp_base + addr)
 #define MDP3_REG_READ(addr) readl_relaxed(mdp3_res->mdp_base + addr)
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index ce68013..734756c 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -398,10 +398,18 @@
 		goto on_error;
 	}
 
+	rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P);
+	if (rc) {
+		pr_err("fail to attach MDP DMA SMMU\n");
+		goto on_error;
+	}
+
 	/* request bus bandwidth before DSI DMA traffic */
 	rc = mdp3_ctrl_res_req_bus(mfd, 1);
-	if (rc)
+	if (rc) {
 		pr_err("fail to request bus resource\n");
+		goto on_error;
+	}
 
 	panel = mdp3_session->panel;
 	if (panel->event_handler)
@@ -431,9 +439,6 @@
 	rc = mdp3_ctrl_intf_init(mfd, mdp3_session->intf);
 	if (rc) {
 		pr_err("display interface init failed\n");
-
-
-
 		goto on_error;
 	}
 
@@ -493,6 +498,11 @@
 	rc = mdp3_ctrl_res_req_clk(mfd, 0);
 	if (rc)
 		pr_err("mdp clock resource release failed\n");
+
+	rc = mdp3_iommu_disable(MDP3_CLIENT_DMA_P);
+	if (rc)
+		pr_err("fail to dettach MDP DMA SMMU\n");
+
 off_error:
 	mdp3_session->status = 0;
 	mutex_unlock(&mdp3_session->lock);
diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
index 3f31932..af316d3 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.c
+++ b/drivers/video/msm/mdss/mdp3_ppp.c
@@ -901,7 +901,7 @@
 	req = mdp3_ppp_next_req(&ppp_stat->req_q);
 	mutex_lock(&ppp_stat->config_ppp_mutex);
 
-	mdp3_ppp_iommu_attach();
+	mdp3_iommu_enable(MDP3_CLIENT_PPP);
 	mdp3_ppp_turnon(mfd, 1);
 	while (req) {
 		mdp3_ppp_wait_for_fence(req);
@@ -926,7 +926,7 @@
 		mutex_unlock(&ppp_stat->req_mutex);
 	}
 	mdp3_ppp_turnon(mfd, 0);
-	mdp3_ppp_iommu_dettach();
+	mdp3_iommu_disable(MDP3_CLIENT_PPP);
 	mutex_unlock(&ppp_stat->config_ppp_mutex);
 }
 
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 3bb4bdc..1311dab 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -120,6 +120,7 @@
 
 	struct early_suspend early_suspend;
 	void *debug_data;
+	int current_bus_idx;
 };
 extern struct mdss_data_type *mdss_res;
 
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 6b210af..72e3c64 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -212,7 +212,7 @@
 int mdss_dsi_buf_alloc(struct dsi_buf *dp, int size)
 {
 
-	dp->start = kmalloc(size, GFP_KERNEL);
+	dp->start = dma_alloc_writecombine(NULL, size, &dp->dmap, GFP_KERNEL);
 	if (dp->start == NULL) {
 		pr_err("%s:%u\n", __func__, __LINE__);
 		return -ENOMEM;
@@ -237,7 +237,7 @@
 	struct dsi_ctrl_hdr *dchdr;
 	char *bp;
 	u32 *hp;
-	int i, len;
+	int i, len = 0;
 
 	dchdr = &cm->dchdr;
 	bp = mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
@@ -268,8 +268,9 @@
 		*hp |= DSI_HDR_LAST;
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+	len += DSI_HOST_HDR_SIZE;
 
-	return dp->len;
+	return len;
 }
 
 /*
@@ -312,8 +313,7 @@
 	}
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-
-	return dp->len;	/* 4 bytes */
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 
 /*
@@ -356,7 +356,7 @@
 	}
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-	return dp->len;	/* 4 bytes */
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 
 /*
@@ -367,7 +367,7 @@
 	struct dsi_ctrl_hdr *dchdr;
 	char *bp;
 	u32 *hp;
-	int i, len;
+	int i, len = 0;
 
 	dchdr = &cm->dchdr;
 	bp = mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
@@ -402,7 +402,8 @@
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
 
-	return dp->len;
+	len += DSI_HOST_HDR_SIZE;
+	return len;
 }
 
 /*
@@ -436,7 +437,7 @@
 	*hp |= DSI_HDR_DATA2(0);
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-	return dp->len;
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 
 /*
@@ -467,8 +468,7 @@
 	*hp |= DSI_HDR_DATA2(cm->payload[1]);	/* parameter */
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-
-	return dp->len;
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 /*
  * mipi dsi dcs read with 0 parameters
@@ -498,8 +498,7 @@
 	*hp |= DSI_HDR_DATA2(0);
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-
-	return dp->len;	/* 4 bytes */
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 
 static int mdss_dsi_cm_on(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
@@ -517,8 +516,7 @@
 		*hp |= DSI_HDR_LAST;
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-
-	return dp->len;	/* 4 bytes */
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 
 static int mdss_dsi_cm_off(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
@@ -536,8 +534,7 @@
 		*hp |= DSI_HDR_LAST;
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-
-	return dp->len;	/* 4 bytes */
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 
 static int mdss_dsi_peripheral_on(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
@@ -555,8 +552,7 @@
 		*hp |= DSI_HDR_LAST;
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-
-	return dp->len;	/* 4 bytes */
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 
 static int mdss_dsi_peripheral_off(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
@@ -574,8 +570,7 @@
 		*hp |= DSI_HDR_LAST;
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-
-	return dp->len;	/* 4 bytes */
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 
 static int mdss_dsi_set_max_pktsize(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
@@ -601,8 +596,7 @@
 	*hp |= DSI_HDR_DATA2(cm->payload[1]);
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-
-	return dp->len;	/* 4 bytes */
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 
 static int mdss_dsi_null_pkt(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
@@ -622,8 +616,7 @@
 		*hp |= DSI_HDR_LAST;
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-
-	return dp->len;	/* 4 bytes */
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 
 static int mdss_dsi_blank_pkt(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
@@ -643,8 +636,7 @@
 		*hp |= DSI_HDR_LAST;
 
 	mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
-
-	return dp->len;	/* 4 bytes */
+	return DSI_HOST_HDR_SIZE; /* 4 bytes */
 }
 
 /*
@@ -1134,12 +1126,44 @@
 	return 4;
 }
 
-
 static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
 					struct dsi_buf *tp);
 
 static int mdss_dsi_cmd_dma_rx(struct mdss_dsi_ctrl_pdata *ctrl,
 			struct dsi_buf *rp, int rlen);
+
+static int mdss_dsi_cmds2buf_tx(struct mdss_dsi_ctrl_pdata *ctrl,
+			struct dsi_cmd_desc *cmds, int cnt)
+{
+	struct dsi_buf *tp;
+	struct dsi_cmd_desc *cm;
+	struct dsi_ctrl_hdr *dchdr;
+	int len, tot = 0;
+
+	tp = &ctrl->tx_buf;
+	mdss_dsi_buf_init(tp);
+	cm = cmds;
+	len = 0;
+	while (cnt--) {
+		dchdr = &cm->dchdr;
+		mdss_dsi_buf_reserve(tp, len);
+		len = mdss_dsi_cmd_dma_add(tp, cm);
+		tot += len;
+		if (dchdr->last) {
+			tp->data = tp->start; /* begin of buf */
+			mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
+			mdss_dsi_cmd_dma_tx(ctrl, tp);
+			if (dchdr->wait)
+				usleep(dchdr->wait * 1000);
+
+			mdss_dsi_buf_init(tp);
+			len = 0;
+		}
+		cm++;
+	}
+	return tot;
+}
+
 /*
  * mdss_dsi_cmds_tx:
  * thread context only
@@ -1147,11 +1171,8 @@
 int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl,
 		struct dsi_cmd_desc *cmds, int cnt)
 {
-	struct dsi_buf *tp;
-	struct dsi_cmd_desc *cm;
-	struct dsi_ctrl_hdr *dchdr;
 	u32 dsi_ctrl, data;
-	int i, video_mode;
+	int video_mode;
 
 	if (ctrl->shared_pdata.broadcast_enable) {
 		if (ctrl->ndx == DSI_CTRL_0) {
@@ -1187,18 +1208,7 @@
 		MIPI_OUTP((ctrl->ctrl_base) + 0x0004, data);
 	}
 
-	tp = &ctrl->tx_buf;
-	cm = cmds;
-	for (i = 0; i < cnt; i++) {
-		mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
-		mdss_dsi_buf_init(tp);
-		mdss_dsi_cmd_dma_add(tp, cm);
-		mdss_dsi_cmd_dma_tx(ctrl, tp);
-		dchdr = &cm->dchdr;
-		if (dchdr->wait)
-			usleep(dchdr->wait * 1000);
-		cm++;
-	}
+	mdss_dsi_cmds2buf_tx(ctrl, cmds, cnt);
 
 	if (video_mode)
 		MIPI_OUTP((ctrl->ctrl_base) + 0x0004,
@@ -1350,11 +1360,6 @@
 	len = ALIGN(tp->len, 4);
 	size = ALIGN(tp->len, SZ_4K);
 
-	tp->dmap = dma_map_single(&dsi_dev, tp->data, size, DMA_TO_DEVICE);
-	if (dma_mapping_error(&dsi_dev, tp->dmap)) {
-		pr_err("%s: dmap mapp failed\n", __func__);
-		return -ENOMEM;
-	}
 
 	if (is_mdss_iommu_attached()) {
 		int ret = msm_iommu_map_contig_buffer(tp->dmap,
@@ -1399,8 +1404,6 @@
 		msm_iommu_unmap_contig_buffer(addr,
 			mdss_get_iommu_domain(domain), 0, size);
 
-	dma_unmap_single(&dsi_dev, tp->dmap, size, DMA_TO_DEVICE);
-	tp->dmap = 0;
 	return tp->len;
 }
 
@@ -1438,6 +1441,13 @@
 void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl)
 {
 	unsigned long flag;
+	u32 data;
+
+	/* DSI_INTL_CTRL */
+	data = MIPI_INP((ctrl->ctrl_base) + 0x0110);
+	data |= DSI_INTR_VIDEO_DONE_MASK;
+
+	MIPI_OUTP((ctrl->ctrl_base) + 0x0110, data);
 
 	spin_lock_irqsave(&ctrl->mdp_lock, flag);
 	INIT_COMPLETION(ctrl->video_comp);
@@ -1446,6 +1456,10 @@
 
 	wait_for_completion_timeout(&ctrl->video_comp,
 			msecs_to_jiffies(VSYNC_PERIOD * 4));
+
+	data = MIPI_INP((ctrl->ctrl_base) + 0x0110);
+	data &= ~DSI_INTR_VIDEO_DONE_MASK;
+	MIPI_OUTP((ctrl->ctrl_base) + 0x0110, data);
 }
 
 static void mdss_dsi_wait4video_eng_busy(struct mdss_dsi_ctrl_pdata *ctrl)
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 61fb41c..e16f2df 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -96,13 +96,14 @@
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
 	if (!mfd)
 		pr_err("%s mfd NULL\n", __func__);
+	mfd->no_update.value = NOTIFY_TYPE_NO_UPDATE;
 	complete(&mfd->no_update.comp);
 }
 
 static int mdss_fb_notify_update(struct msm_fb_data_type *mfd,
 							unsigned long *argp)
 {
-	int ret, notify;
+	int ret, notify, to_user;
 
 	ret = copy_from_user(&notify, argp, sizeof(int));
 	if (ret) {
@@ -117,14 +118,18 @@
 		INIT_COMPLETION(mfd->update.comp);
 		ret = wait_for_completion_interruptible_timeout(
 						&mfd->update.comp, 4 * HZ);
+		to_user = mfd->update.value;
 	} else {
 		INIT_COMPLETION(mfd->no_update.comp);
 		ret = wait_for_completion_interruptible_timeout(
 						&mfd->no_update.comp, 4 * HZ);
+		to_user = mfd->no_update.value;
 	}
 	if (ret == 0)
 		ret = -ETIMEDOUT;
-	return (ret > 0) ? 0 : ret;
+	else if (ret > 0)
+		ret = copy_to_user(argp, &to_user, sizeof(int));
+	return ret;
 }
 
 static int lcd_backlight_registered;
@@ -140,15 +145,18 @@
 
 	/* This maps android backlight level 0 to 255 into
 	   driver backlight level 0 to bl_max with rounding */
-	bl_lvl = (2 * value * mfd->panel_info->bl_max +
-		  MDSS_MAX_BL_BRIGHTNESS) / (2 * MDSS_MAX_BL_BRIGHTNESS);
+	MDSS_BRIGHT_TO_BL(bl_lvl, value, mfd->panel_info->bl_max,
+						MDSS_MAX_BL_BRIGHTNESS);
 
 	if (!bl_lvl && value)
 		bl_lvl = 1;
 
-	mutex_lock(&mfd->bl_lock);
-	mdss_fb_set_backlight(mfd, bl_lvl);
-	mutex_unlock(&mfd->bl_lock);
+	if (!IS_CALIB_MODE_BL(mfd) && (!mfd->ext_bl_ctrl || !value ||
+							!mfd->bl_level)) {
+		mutex_lock(&mfd->bl_lock);
+		mdss_fb_set_backlight(mfd, bl_lvl);
+		mutex_unlock(&mfd->bl_lock);
+	}
 }
 
 static struct led_classdev backlight_led = {
@@ -534,7 +542,7 @@
 	struct mdss_panel_data *pdata;
 	u32 temp = bkl_lvl;
 
-	if (!mfd->panel_power_on || !bl_updated) {
+	if ((!mfd->panel_power_on || !bl_updated) && !IS_CALIB_MODE_BL(mfd)) {
 		unset_bl_level = bkl_lvl;
 		return;
 	} else {
@@ -544,7 +552,8 @@
 	pdata = dev_get_platdata(&mfd->pdev->dev);
 
 	if ((pdata) && (pdata->set_backlight)) {
-		mdss_fb_scale_bl(mfd, &temp);
+		if (!IS_CALIB_MODE_BL(mfd))
+			mdss_fb_scale_bl(mfd, &temp);
 		/*
 		 * Even though backlight has been scaled, want to show that
 		 * backlight has been set to bkl_lvl to those that read from
@@ -602,6 +611,9 @@
 			ret = mfd->mdp.on_fnc(mfd);
 			if (ret == 0)
 				mfd->panel_power_on = true;
+			mutex_lock(&mfd->update.lock);
+			mfd->update.type = NOTIFY_TYPE_UPDATE;
+			mutex_unlock(&mfd->update.lock);
 		}
 		break;
 
@@ -613,7 +625,11 @@
 		if (mfd->panel_power_on && mfd->mdp.off_fnc) {
 			int curr_pwr_state;
 
+			mutex_lock(&mfd->update.lock);
+			mfd->update.type = NOTIFY_TYPE_SUSPEND;
+			mutex_unlock(&mfd->update.lock);
 			del_timer(&mfd->no_update.timer);
+			mfd->no_update.value = NOTIFY_TYPE_SUSPEND;
 			complete(&mfd->no_update.comp);
 
 			mfd->op_enable = false;
@@ -964,6 +980,7 @@
 
 	mfd->op_enable = true;
 
+	mutex_init(&mfd->update.lock);
 	mutex_init(&mfd->no_update.lock);
 	mutex_init(&mfd->sync_mutex);
 	init_timer(&mfd->no_update.timer);
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index 05fdec4..98bca03 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -26,7 +26,7 @@
 #define MSM_FB_MAX_DEV_LIST 32
 
 #define MSM_FB_ENABLE_DBGFS
-#define WAIT_FENCE_FIRST_TIMEOUT MSEC_PER_SEC
+#define WAIT_FENCE_FIRST_TIMEOUT (3 * 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 + \
@@ -50,6 +50,7 @@
 	struct timer_list timer;
 	struct completion comp;
 	struct mutex lock;
+	int value;
 };
 
 struct msm_fb_data_type;
@@ -74,6 +75,12 @@
 	void *private1;
 };
 
+#define IS_CALIB_MODE_BL(mfd) (((mfd)->calib_mode) & MDSS_CALIB_MODE_BL)
+#define MDSS_BRIGHT_TO_BL(out, v, bl_max, max_bright) do {\
+					out = (2 * (v) * (bl_max) + max_bright)\
+					/ (2 * max_bright);\
+					} while (0)
+
 struct msm_fb_data_type {
 	u32 key;
 	u32 index;
@@ -101,6 +108,8 @@
 	unsigned long cursor_buf_phys;
 	unsigned long cursor_buf_iova;
 
+	u32 ext_bl_ctrl;
+	u32 calib_mode;
 	u32 bl_level;
 	u32 bl_scale;
 	u32 bl_min_lvl;
@@ -141,6 +150,25 @@
 	struct mdp_display_commit disp_commit;
 };
 
+static inline void mdss_fb_update_notify_update(struct msm_fb_data_type *mfd)
+{
+	int needs_complete = 0;
+	mutex_lock(&mfd->update.lock);
+	mfd->update.value = mfd->update.type;
+	needs_complete = mfd->update.value == NOTIFY_TYPE_UPDATE;
+	mutex_unlock(&mfd->update.lock);
+	if (needs_complete) {
+		complete(&mfd->update.comp);
+		mutex_lock(&mfd->no_update.lock);
+		if (mfd->no_update.timer.function)
+			del_timer(&(mfd->no_update.timer));
+
+		mfd->no_update.timer.expires = jiffies + (2 * HZ);
+		add_timer(&mfd->no_update.timer);
+		mutex_unlock(&mfd->no_update.lock);
+	}
+}
+
 int mdss_fb_get_phys_info(unsigned long *start, unsigned long *len, int fb_num);
 void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl);
 void mdss_fb_update_backlight(struct msm_fb_data_type *mfd);
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index d8ca555..c4bf67e 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -345,7 +345,6 @@
 
 int mdss_mdp_bus_scale_set_quota(u64 ab_quota, u64 ib_quota)
 {
-	static int current_bus_idx;
 	int bus_idx;
 
 	if (mdss_res->bus_hdl < 1) {
@@ -359,9 +358,10 @@
 		int num_cases = mdp_bus_scale_table.num_usecases;
 		struct msm_bus_vectors *vect = NULL;
 
-		bus_idx = (current_bus_idx % (num_cases - 1)) + 1;
+		bus_idx = (mdss_res->current_bus_idx % (num_cases - 1)) + 1;
 
-		vect = mdp_bus_scale_table.usecase[current_bus_idx].vectors;
+		vect = mdp_bus_scale_table.usecase[mdss_res->current_bus_idx].
+			vectors;
 
 		/* avoid performing updates for small changes */
 		if ((ALIGN(ab_quota, SZ_64M) == ALIGN(vect->ab, SZ_64M)) &&
@@ -377,7 +377,7 @@
 		pr_debug("bus scale idx=%d ab=%llu ib=%llu\n", bus_idx,
 				vect->ab, vect->ib);
 	}
-	current_bus_idx = bus_idx;
+	mdss_res->current_bus_idx = bus_idx;
 	return msm_bus_scale_client_update_request(mdss_res->bus_hdl, bus_idx);
 }
 
@@ -626,8 +626,14 @@
 		if (mdata->vsync_ena)
 			mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, enable);
 
-		if (!enable)
+		if (!enable) {
+			msm_bus_scale_client_update_request(
+				mdss_res->bus_hdl, 0);
 			pm_runtime_put(&mdata->pdev->dev);
+		} else {
+			msm_bus_scale_client_update_request(
+				mdss_res->bus_hdl, mdss_res->current_bus_idx);
+		}
 	}
 
 	mutex_unlock(&mdp_clk_lock);
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index d9ec19b..f59cdaa 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -496,6 +496,8 @@
 int mdss_mdp_ad_input(struct msm_fb_data_type *mfd,
 				struct mdss_ad_input *input, int wait);
 int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_off);
+int mdss_mdp_calib_mode(struct msm_fb_data_type *mfd,
+				struct mdss_calib_cfg *cfg);
 
 struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(struct mdss_mdp_mixer *mixer,
 					  u32 type);
@@ -544,6 +546,8 @@
 int mdss_mdp_limited_lut_igc_config(struct mdss_mdp_ctl *ctl);
 int mdss_mdp_calib_config(struct mdp_calib_config_data *cfg, u32 *copyback);
 
+int mdss_mdp_pipe_is_staged(struct mdss_mdp_pipe *pipe);
+
 #define mfd_to_mdp5_data(mfd) (mfd->mdp.private1)
 #define mfd_to_mdata(mfd) (((struct mdss_overlay_private *)\
 				(mfd->mdp.private1))->mdata)
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 5d9050c..1cd2dbd 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -23,7 +23,8 @@
 /* truncate at 1k */
 #define MDSS_MDP_BUS_FACTOR_SHIFT 10
 /* 1.5 bus fudge factor */
-#define MDSS_MDP_BUS_FUDGE_FACTOR(val) (((val) / 2) * 3)
+#define MDSS_MDP_BUS_FUDGE_FACTOR_IB(val) (((val) / 2) * 3)
+#define MDSS_MDP_BUS_FUDGE_FACTOR_AB(val) (val << 1)
 /* 1.25 clock fudge factor */
 #define MDSS_MDP_CLK_FUDGE_FACTOR(val) (((val) * 5) / 4)
 
@@ -81,7 +82,8 @@
 	}
 	if (flags & MDSS_MDP_PERF_UPDATE_BUS) {
 		bus_ab_quota = bus_ib_quota << MDSS_MDP_BUS_FACTOR_SHIFT;
-		bus_ib_quota = MDSS_MDP_BUS_FUDGE_FACTOR(bus_ib_quota);
+		bus_ab_quota = MDSS_MDP_BUS_FUDGE_FACTOR_AB(bus_ab_quota);
+		bus_ib_quota = MDSS_MDP_BUS_FUDGE_FACTOR_IB(bus_ib_quota);
 		bus_ib_quota <<= MDSS_MDP_BUS_FACTOR_SHIFT;
 
 		mdss_mdp_bus_scale_set_quota(bus_ab_quota, bus_ib_quota);
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
index 238170d..bd4f3ea 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -440,7 +440,7 @@
 	null_handle.vsync_handler = NULL;
 	mdss_mdp_cmd_vsync_ctrl(ctl, &null_handle);
 
-	mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctl->intf_num,
+	mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num,
 				   NULL, NULL);
 	mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
 				   NULL, NULL);
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index 0c08eda..e06695f 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -349,8 +349,13 @@
 
 	rc = wait_for_completion_interruptible_timeout(&ctx->wb_comp,
 			KOFF_TIMEOUT);
-	WARN(rc <= 0, "writeback kickoff timed out (%d) ctl=%d\n",
-							rc, ctl->num);
+	if (rc <= 0) {
+		rc = -ENODEV;
+		WARN(1, "writeback kickoff timed out (%d) ctl=%d\n",
+						rc, ctl->num);
+	} else {
+		rc = 0;
+	}
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); /* clock off */
 
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 49b579f..fcaa80b 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -174,22 +174,6 @@
 			return -EINVAL;
 		}
 
-		if ((fmt->chroma_sample == MDSS_MDP_CHROMA_420 ||
-		     fmt->chroma_sample == MDSS_MDP_CHROMA_H2V1) &&
-		    ((req->src_rect.w * (MAX_UPSCALE_RATIO / 2)) < dst_w)) {
-			pr_err("too much YUV upscaling Width %d->%d\n",
-			       req->src_rect.w, req->dst_rect.w);
-			return -EINVAL;
-		}
-
-		if ((fmt->chroma_sample == MDSS_MDP_CHROMA_420 ||
-		     fmt->chroma_sample == MDSS_MDP_CHROMA_H1V2) &&
-		    (req->src_rect.h * (MAX_UPSCALE_RATIO / 2)) < dst_h) {
-			pr_err("too much YUV upscaling Height %d->%d\n",
-			       req->src_rect.h, req->dst_rect.h);
-			return -EINVAL;
-		}
-
 		if (req->flags & MDP_BWC_EN) {
 			if ((req->src.width != req->src_rect.w) ||
 			    (req->src.height != req->src_rect.h)) {
@@ -197,6 +181,25 @@
 				return -EINVAL;
 			}
 		}
+
+		if (req->flags & MDP_DEINTERLACE) {
+			if (req->flags & MDP_SOURCE_ROTATED_90) {
+				if ((req->src_rect.w % 4) != 0) {
+					pr_err("interlaced rect not h/4\n");
+					return -EINVAL;
+				}
+			} else if ((req->src_rect.h % 4) != 0) {
+				pr_err("interlaced rect not h/4\n");
+				return -EINVAL;
+			}
+		}
+	} else {
+		if (req->flags & MDP_DEINTERLACE) {
+			if ((req->src_rect.h % 4) != 0) {
+				pr_err("interlaced rect h not multiple of 4\n");
+				return -EINVAL;
+			}
+		}
 	}
 
 	if (fmt->is_yuv) {
@@ -207,13 +210,6 @@
 		}
 	}
 
-	if (req->flags & MDP_DEINTERLACE) {
-		if ((req->src.width % 4 != 0) || (req->src.height % 4 != 0)) {
-			pr_err("interlaced fmt w,h need to be even post div\n");
-			return -EINVAL;
-		}
-	}
-
 	return 0;
 }
 
@@ -696,7 +692,7 @@
 int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd)
 {
 	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
-	struct mdss_mdp_pipe *pipe;
+	struct mdss_mdp_pipe *pipe, *next;
 	struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
 	int ret;
 
@@ -710,7 +706,8 @@
 		return ret;
 	}
 
-	list_for_each_entry(pipe, &mdp5_data->pipes_used, used_list) {
+	list_for_each_entry_safe(pipe, next, &mdp5_data->pipes_used,
+			used_list) {
 		struct mdss_mdp_data *buf;
 		if (pipe->back_buf.num_planes) {
 			buf = &pipe->back_buf;
@@ -718,6 +715,13 @@
 			pipe->params_changed++;
 			buf = &pipe->front_buf;
 		} else if (!pipe->params_changed) {
+			if (pipe->mixer) {
+				if (!mdss_mdp_pipe_is_staged(pipe)) {
+					list_del(&pipe->used_list);
+					list_add(&pipe->cleanup_list,
+						 &mdp5_data->pipes_cleanup);
+				}
+			}
 			continue;
 		} else if (pipe->front_buf.num_planes) {
 			buf = &pipe->front_buf;
@@ -750,15 +754,7 @@
 
 	ret = mdss_mdp_display_wait4comp(mdp5_data->ctl);
 
-	complete(&mfd->update.comp);
-	mutex_lock(&mfd->no_update.lock);
-	if (mfd->no_update.timer.function)
-		del_timer(&(mfd->no_update.timer));
-
-	mfd->no_update.timer.expires = jiffies + (2 * HZ);
-	add_timer(&mfd->no_update.timer);
-	mutex_unlock(&mfd->no_update.lock);
-
+	mdss_fb_update_notify_update(mfd);
 commit_fail:
 	mdss_mdp_overlay_cleanup(mfd);
 
@@ -1561,6 +1557,9 @@
 		ret = mdss_mdp_calib_config((struct mdp_calib_config_data *)
 					 &mdp_pp.data.calib_cfg, &copyback);
 		break;
+	case mdp_op_calib_mode:
+		ret = mdss_mdp_calib_mode(mfd, &mdp_pp.data.mdss_calib_cfg);
+		break;
 	default:
 		pr_err("Unsupported request to MDP_PP IOCTL. %d = op\n",
 								mdp_pp.op);
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 3ae01dc..3b91ced 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -22,6 +22,7 @@
 #define SMP_MB_SIZE		(mdss_res->smp_mb_size)
 #define SMP_MB_CNT		(mdss_res->smp_mb_cnt)
 #define SMP_ENTRIES_PER_MB	(SMP_MB_SIZE / 16)
+#define SMP_MB_ENTRY_SIZE	16
 #define MAX_BPP 4
 
 static DEFINE_MUTEX(mdss_mdp_sspp_lock);
@@ -95,17 +96,31 @@
 
 static void mdss_mdp_smp_set_wm_levels(struct mdss_mdp_pipe *pipe, int mb_cnt)
 {
-	u32 entries, val, wm[3];
+	u32 fetch_size, val, wm[3];
 
-	entries = mb_cnt * SMP_ENTRIES_PER_MB;
-	val = entries >> 2;
+	fetch_size = mb_cnt * SMP_MB_SIZE;
+
+	/*
+	 * when doing hflip, one line is reserved to be consumed down the
+	 * pipeline. This line will always be marked as full even if it doesn't
+	 * have any data. In order to generate proper priority levels ignore
+	 * this region while setting up watermark levels
+	 */
+	if (pipe->flags & MDP_FLIP_LR) {
+		u8 bpp = pipe->src_fmt->is_yuv ? 1 :
+			pipe->src_fmt->bpp;
+		fetch_size -= (pipe->src.w * bpp);
+	}
+
+	/* 1/4 of SMP pool that is being fetched */
+	val = (fetch_size / SMP_MB_ENTRY_SIZE) >> 2;
 
 	wm[0] = val;
 	wm[1] = wm[0] + val;
 	wm[2] = wm[1] + val;
 
-	pr_debug("pnum=%d watermarks %u,%u,%u\n", pipe->num,
-			wm[0], wm[1], wm[2]);
+	pr_debug("pnum=%d fetch_size=%u watermarks %u,%u,%u\n", pipe->num,
+			fetch_size, wm[0], wm[1], wm[2]);
 	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_0, wm[0]);
 	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_1, wm[1]);
 	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_2, wm[2]);
@@ -710,3 +725,8 @@
 
 	return ret;
 }
+
+int mdss_mdp_pipe_is_staged(struct mdss_mdp_pipe *pipe)
+{
+	return (pipe == pipe->mixer->stage_pipe[pipe->mixer_stage]);
+}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index b6f91f4..5d7a0c9 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -1055,6 +1055,10 @@
 		if (ret < 0)
 			pr_warn("ad_setup(dspp%d) returns %d", dspp_num, ret);
 	}
+	/* call calibration specific processing here */
+	if (ctl->mfd->calib_mode)
+		goto flush_exit;
+
 	/* nothing to update */
 	if ((!flags) && (!(opmode)) && (ret <= 0))
 		goto dspp_exit;
@@ -1145,6 +1149,7 @@
 	if (pp_sts->pgc_sts & PP_STS_ENABLE)
 		opmode |= (1 << 22);
 
+flush_exit:
 	writel_relaxed(opmode, basel + MDSS_MDP_REG_DSPP_OP_MODE);
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, BIT(13 + dspp_num));
 	wmb();
@@ -2771,7 +2776,8 @@
 	if (!ad || ad->cfg.mode == MDSS_AD_MODE_AUTO_BL)
 		return -EINVAL;
 
-	pr_debug("backlight level changed, trigger update to AD");
+	pr_debug("backlight level changed (%d), trigger update to AD",
+						mfd->bl_level);
 	input.mode = ad->cfg.mode;
 	if (MDSS_AD_MODE_DATA_MATCH(ad->cfg.mode, MDSS_AD_INPUT_AMBIENT))
 		input.in.amb_light = ad->ad_data;
@@ -2854,14 +2860,16 @@
 	int ret = 0;
 	struct mdss_ad_info *ad;
 	struct mdss_mdp_ctl *ctl;
+	u32 bl;
 
 	ad = mdss_mdp_get_ad(mfd);
 	if (!ad)
 		return -EINVAL;
 
 	mutex_lock(&ad->lock);
-	if (!PP_AD_STATE_IS_INITCFG(ad->state) &&
-			!PP_AD_STS_IS_DIRTY(ad->sts)) {
+	if ((!PP_AD_STATE_IS_INITCFG(ad->state) &&
+			!PP_AD_STS_IS_DIRTY(ad->sts)) &&
+			!input->mode == MDSS_AD_MODE_CALIB) {
 		pr_warn("AD not initialized or configured.");
 		ret = -EPERM;
 		goto error;
@@ -2894,6 +2902,25 @@
 		ad->sts |= PP_AD_STS_DIRTY_VSYNC;
 		ad->sts |= PP_AD_STS_DIRTY_DATA;
 		break;
+	case MDSS_AD_MODE_CALIB:
+		wait = 0;
+		if (mfd->calib_mode) {
+			bl = input->in.calib_bl;
+			if (bl >= AD_BL_LIN_LEN) {
+				pr_warn("calib_bl 255 max!");
+				break;
+			}
+			mutex_unlock(&ad->lock);
+			mutex_lock(&mfd->bl_lock);
+			MDSS_BRIGHT_TO_BL(bl, bl, mfd->panel_info->bl_max,
+							MDSS_MAX_BL_BRIGHTNESS);
+			mdss_fb_set_backlight(mfd, bl);
+			mutex_unlock(&mfd->bl_lock);
+			mutex_lock(&ad->lock);
+		} else {
+			pr_warn("should be in calib mode");
+		}
+		break;
 	default:
 		pr_warn("invalid default %d", input->mode);
 		ret = -EINVAL;
@@ -3111,6 +3138,7 @@
 		ad->state |= PP_AD_STATE_RUN;
 		mutex_lock(&mfd->bl_lock);
 		mfd->mdp.update_ad_input = pp_update_ad_input;
+		mfd->ext_bl_ctrl = ad->cfg.bl_ctrl_mode;
 		mutex_unlock(&mfd->bl_lock);
 
 	} else {
@@ -3135,6 +3163,7 @@
 			memset(&ad->cfg, 0, sizeof(struct mdss_ad_cfg));
 			mutex_lock(&mfd->bl_lock);
 			mfd->mdp.update_ad_input = NULL;
+			mfd->ext_bl_ctrl = 0;
 			mutex_unlock(&mfd->bl_lock);
 		}
 		ad->state &= ~PP_AD_STATE_RUN;
@@ -3230,6 +3259,9 @@
 	mutex_lock(&mfd->lock);
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, BIT(13 + ad->num));
 	mutex_unlock(&mfd->lock);
+
+	/* Trigger update notify to wake up those waiting for display updates */
+	mdss_fb_update_notify_update(mfd);
 }
 
 #define PP_AD_LUT_LEN 33
@@ -3332,9 +3364,6 @@
 	return ret;
 }
 
-
-
-
 int mdss_mdp_calib_config(struct mdp_calib_config_data *cfg, u32 *copyback)
 {
 	int ret = -1;
@@ -3358,3 +3387,14 @@
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 	return ret;
 }
+
+int mdss_mdp_calib_mode(struct msm_fb_data_type *mfd,
+				struct mdss_calib_cfg *cfg)
+{
+	if (!mdss_pp_res || !mfd)
+		return -EINVAL;
+	mutex_lock(&mdss_pp_mutex);
+	mfd->calib_mode = cfg->calib_mask;
+	mutex_unlock(&mdss_pp_mutex);
+	return 0;
+}
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 27b2104..74d2a9c 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -246,6 +246,9 @@
 			ps->rau_h[1] = 4;
 		} else
 			ps->ystride[1] = 32 * 2;
+
+		/* account for both chroma components */
+		ps->ystride[1] <<= 1;
 	} else if (fmt->fetch_planes == MDSS_MDP_PLANE_INTERLEAVED) {
 		ps->rau_cnt = DIV_ROUND_UP(w, 32);
 		ps->ystride[0] = 32 * 4 * fmt->bpp;
@@ -261,6 +264,10 @@
 	ps->ystride[1] *= ps->rau_cnt;
 	ps->num_planes = 2;
 
+	pr_debug("BWC rau_cnt=%d strides={%d,%d} heights={%d,%d}\n",
+		ps->rau_cnt, ps->ystride[0], ps->ystride[1],
+		ps->rau_h[0], ps->rau_h[1]);
+
 	return 0;
 }
 
@@ -269,7 +276,7 @@
 {
 	struct mdss_mdp_format_params *fmt;
 	int i, rc;
-	u32 bpp, ystride0_off, ystride1_off;
+	u32 bpp;
 	if (ps == NULL)
 		return -EINVAL;
 
@@ -284,24 +291,23 @@
 	memset(ps, 0, sizeof(struct mdss_mdp_plane_sizes));
 
 	if (bwc_mode) {
-		u32 meta_size;
+		u32 height, meta_size;
 
 		rc = mdss_mdp_get_rau_strides(w, h, fmt, ps);
 		if (rc)
 			return rc;
 
+		height = DIV_ROUND_UP(h, ps->rau_h[0]);
 		meta_size = DIV_ROUND_UP(ps->rau_cnt, 8);
-		ps->ystride[0] += meta_size;
 		ps->ystride[1] += meta_size;
+		ps->ystride[0] += ps->ystride[1] + meta_size;
+		ps->plane_size[0] = ps->ystride[0] * height;
 
-		ystride0_off = DIV_ROUND_UP(h, ps->rau_h[0]);
-		ystride1_off = DIV_ROUND_UP(h, ps->rau_h[1]);
-		ps->plane_size[0] = (ps->ystride[0] * ystride0_off) +
-				    (ps->ystride[1] * ystride1_off);
-		ps->ystride[0] += ps->ystride[1];
 		ps->ystride[1] = 2;
-		ps->plane_size[1] = ps->rau_cnt * ps->ystride[1] *
-				   (ystride0_off + ystride1_off);
+		ps->plane_size[1] = 2 * ps->rau_cnt * height;
+
+		pr_debug("BWC data stride=%d size=%d meta size=%d\n",
+			ps->ystride[0], ps->plane_size[0], ps->plane_size[1]);
 	} else {
 		if (fmt->fetch_planes == MDSS_MDP_PLANE_INTERLEAVED) {
 			ps->num_planes = 1;
@@ -558,7 +564,8 @@
 	u32 pixel_total;
 	struct mdss_panel_info *panel_info = mfd->panel_info;
 
-	if (panel_info->type == MIPI_VIDEO_PANEL) {
+	if ((panel_info->type == MIPI_VIDEO_PANEL) ||
+			(panel_info->type == MIPI_CMD_PANEL)) {
 		frame_rate = panel_info->mipi.frame_rate;
 	} else {
 		pixel_total = (panel_info->lcdc.h_back_porch +
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index 1f8244d..0bb68f9 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -251,8 +251,8 @@
 	if (wb->secure_pipe)
 		mdss_mdp_pipe_destroy(wb->secure_pipe);
 	mutex_unlock(&wb->lock);
-
-	mdp5_data->ctl->is_secure = false;
+	if (mdp5_data->ctl)
+		mdp5_data->ctl->is_secure = false;
 	mdp5_data->wb = NULL;
 	mutex_unlock(&mdss_mdp_wb_buf_lock);
 
diff --git a/drivers/video/msm/mdss/mhl_sii8334.c b/drivers/video/msm/mdss/mhl_sii8334.c
index 9cae431..3f03725 100644
--- a/drivers/video/msm/mdss/mhl_sii8334.c
+++ b/drivers/video/msm/mdss/mhl_sii8334.c
@@ -1933,6 +1933,72 @@
 
 MODULE_DEVICE_TABLE(i2c, mhl_sii_i2c_id);
 
+#if defined(CONFIG_PM) || defined(CONFIG_PM_SLEEP)
+static int mhl_i2c_suspend_sub(struct i2c_client *client)
+{
+	enable_irq_wake(client->irq);
+	disable_irq(client->irq);
+	return 0;
+}
+
+static int mhl_i2c_resume_sub(struct i2c_client *client)
+{
+	disable_irq_wake(client->irq);
+	enable_irq(client->irq);
+	return 0;
+}
+#endif /* defined(CONFIG_PM) || defined(CONFIG_PM_SLEEP) */
+
+#if defined(CONFIG_PM) && !defined(CONFIG_PM_SLEEP)
+static int mhl_i2c_suspend(struct i2c_client *client, pm_message_t state)
+{
+	if (!client)
+		return -ENODEV;
+	pr_debug("%s: mhl suspend\n", __func__);
+	return mhl_i2c_suspend_sub(client);
+}
+
+static int mhl_i2c_resume(struct i2c_client *client)
+{
+	if (!client)
+		return -ENODEV;
+	pr_debug("%s: mhl resume\n", __func__);
+	return mhl_i2c_resume_sub(client);
+}
+#else
+#define mhl_i2c_suspend NULL
+#define mhl_i2c_resume NULL
+#endif /* defined(CONFIG_PM) && !defined(CONFIG_PM_SLEEP) */
+
+#ifdef CONFIG_PM_SLEEP
+static int mhl_i2c_pm_suspend(struct device *dev)
+{
+	struct i2c_client *client =
+		container_of(dev, struct i2c_client, dev);
+
+	if (!client)
+		return -ENODEV;
+	pr_debug("%s: mhl pm suspend\n", __func__);
+	return mhl_i2c_suspend_sub(client);
+
+}
+
+static int mhl_i2c_pm_resume(struct device *dev)
+{
+	struct i2c_client *client =
+		container_of(dev, struct i2c_client, dev);
+
+	if (!client)
+		return -ENODEV;
+	pr_debug("%s: mhl pm resume\n", __func__);
+	return mhl_i2c_resume_sub(client);
+}
+
+static const struct dev_pm_ops mhl_i2c_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mhl_i2c_pm_suspend, mhl_i2c_pm_resume)
+};
+#endif /* CONFIG_PM_SLEEP */
+
 static struct of_device_id mhl_match_table[] = {
 	{.compatible = COMPATIBLE_NAME,},
 	{ },
@@ -1943,9 +2009,16 @@
 		.name = MHL_DRIVER_NAME,
 		.owner = THIS_MODULE,
 		.of_match_table = mhl_match_table,
+#ifdef CONFIG_PM_SLEEP
+		.pm = &mhl_i2c_pm_ops,
+#endif /* CONFIG_PM_SLEEP */
 	},
 	.probe = mhl_i2c_probe,
 	.remove =  mhl_i2c_remove,
+#if defined(CONFIG_PM) && !defined(CONFIG_PM_SLEEP)
+	.suspend = mhl_i2c_suspend,
+	.resume = mhl_i2c_resume,
+#endif /* defined(CONFIG_PM) && !defined(CONFIG_PM_SLEEP) */
 	.id_table = mhl_sii_i2c_id,
 };
 
diff --git a/include/linux/coresight-stm.h b/include/linux/coresight-stm.h
index 3f35dd9..298fc9a 100644
--- a/include/linux/coresight-stm.h
+++ b/include/linux/coresight-stm.h
@@ -7,6 +7,7 @@
 	OST_ENTITY_TRACE_PRINTK		= 0x02,
 	OST_ENTITY_TRACE_MARKER		= 0x04,
 	OST_ENTITY_DEV_NODE		= 0x08,
+	OST_ENTITY_DIAG			= 0xEE,
 	OST_ENTITY_QVIEW		= 0xFE,
 	OST_ENTITY_MAX			= 0xFF,
 };
diff --git a/include/linux/input/ft5x06_ts.h b/include/linux/input/ft5x06_ts.h
index a379d38..af8c332 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, The Linux Foundation. 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
@@ -18,12 +18,28 @@
 #ifndef __LINUX_FT5X06_TS_H__
 #define __LINUX_FT5X06_TS_H__
 
+#define FT5X06_ID		0x55
+#define FT5X16_ID		0x0A
+#define FT5X36_ID		0x14
+#define FT6X06_ID		0x06
+
 struct ft5x06_ts_platform_data {
-	unsigned long irqflags;
+	u32 irqflags;
+	u32 irq_gpio;
+	u32 irq_gpio_flags;
+	u32 reset_gpio;
+	u32 reset_gpio_flags;
+	u32 family_id;
 	u32 x_max;
 	u32 y_max;
-	u32 irq_gpio;
-	u32 reset_gpio;
+	u32 x_min;
+	u32 y_min;
+	u32 panel_minx;
+	u32 panel_miny;
+	u32 panel_maxx;
+	u32 panel_maxy;
+	bool no_force_update;
+	bool i2c_pull_up;
 	int (*power_init) (bool);
 	int (*power_on) (bool);
 };
diff --git a/include/linux/input/synaptics_dsx.h b/include/linux/input/synaptics_dsx.h
index f90f59e..73016d6 100644
--- a/include/linux/input/synaptics_dsx.h
+++ b/include/linux/input/synaptics_dsx.h
@@ -35,7 +35,6 @@
  * 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
@@ -47,7 +46,6 @@
 struct synaptics_rmi4_platform_data {
 	bool x_flip;
 	bool y_flip;
-	bool regulator_en;
 	bool i2c_pull_up;
 	unsigned irq_gpio;
 	u32 irq_flags;
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index 0d1f49f..e688bd9 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -76,7 +76,8 @@
 	WCD9XXX_IRQ_EAR_PA_OCPL_FAULT,
 	WCD9XXX_IRQ_HPH_L_PA_STARTUP,
 	WCD9XXX_IRQ_HPH_R_PA_STARTUP,
-	WCD9XXX_IRQ_EAR_PA_STARTUP,
+	WCD9320_IRQ_EAR_PA_STARTUP,
+	WCD9306_IRQ_MBHC_JACK_SWITCH = WCD9320_IRQ_EAR_PA_STARTUP,
 	WCD9310_NUM_IRQS,
 	WCD9XXX_IRQ_RESERVED_0 = WCD9310_NUM_IRQS,
 	WCD9XXX_IRQ_RESERVED_1,
@@ -85,7 +86,7 @@
 	WCD9XXX_IRQ_MAD_BEACON,
 	WCD9XXX_IRQ_MAD_ULTRASOUND,
 	WCD9XXX_IRQ_SPEAKER_CLIPPING,
-	WCD9XXX_IRQ_MBHC_JACK_SWITCH,
+	WCD9320_IRQ_MBHC_JACK_SWITCH,
 	WCD9XXX_IRQ_VBAT_MONITOR_ATTACK,
 	WCD9XXX_IRQ_VBAT_MONITOR_RELEASE,
 	WCD9XXX_NUM_IRQS,
@@ -153,6 +154,13 @@
 #define WCD9XXX_CH(xport, xshift) \
 	{.port = xport, .shift = xshift}
 
+enum wcd9xxx_chipid_major {
+	TABLA_MAJOR = cpu_to_le16(0x100),
+	SITAR_MAJOR = cpu_to_le16(0x101),
+	TAIKO_MAJOR = cpu_to_le16(0x102),
+	TAPAN_MAJOR = cpu_to_le16(0x103),
+};
+
 struct wcd9xxx_codec_type {
 	u16 id_major;
 	u16 id_minor;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 27b0c4b..dbafdfc 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -279,6 +279,7 @@
 #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
 #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
 #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
+#define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */
 
 #define MMC_CAP2_PACKED_RD	(1 << 12)	/* Allow packed read */
 #define MMC_CAP2_PACKED_WR	(1 << 13)	/* Allow packed write */
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 6d41c13..18921a0 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -50,7 +50,7 @@
 #define MSMFB_HISTOGRAM_START	_IOR(MSMFB_IOCTL_MAGIC, 144, \
 						struct mdp_histogram_start_req)
 #define MSMFB_HISTOGRAM_STOP	_IOR(MSMFB_IOCTL_MAGIC, 145, unsigned int)
-#define MSMFB_NOTIFY_UPDATE	_IOW(MSMFB_IOCTL_MAGIC, 146, unsigned int)
+#define MSMFB_NOTIFY_UPDATE	_IOWR(MSMFB_IOCTL_MAGIC, 146, unsigned int)
 
 #define MSMFB_OVERLAY_3D       _IOWR(MSMFB_IOCTL_MAGIC, 147, \
 						struct msmfb_overlay_3d)
@@ -90,6 +90,12 @@
 };
 
 enum {
+	NOTIFY_TYPE_NO_UPDATE,
+	NOTIFY_TYPE_SUSPEND,
+	NOTIFY_TYPE_UPDATE,
+};
+
+enum {
 	MDP_RGB_565,      /* RGB 565 planer */
 	MDP_XRGB_8888,    /* RGB 888 padded */
 	MDP_Y_CBCR_H2V2,  /* Y and CbCr, pseudo planer w/ Cb is in MSB */
@@ -607,6 +613,7 @@
 #define MDSS_AD_MODE_AUTO_STR	0x1
 #define MDSS_AD_MODE_TARG_STR	0x3
 #define MDSS_AD_MODE_MAN_STR	0x7
+#define MDSS_AD_MODE_CALIB	0xF
 
 #define MDP_PP_AD_INIT	0x10
 #define MDP_PP_AD_CFG	0x20
@@ -634,6 +641,8 @@
 	uint32_t *bl_lin_inv;
 };
 
+#define MDSS_AD_BL_CTRL_MODE_EN 1
+#define MDSS_AD_BL_CTRL_MODE_DIS 0
 struct mdss_ad_cfg {
 	uint32_t mode;
 	uint32_t al_calib_lut[33];
@@ -646,6 +655,7 @@
 	uint8_t strength_limit;
 	uint8_t t_filter_recursion;
 	uint16_t stab_itr;
+	uint32_t bl_ctrl_mode;
 };
 
 /* ops uses standard MDP_PP_* flags */
@@ -663,10 +673,12 @@
 	union {
 		uint32_t amb_light;
 		uint32_t strength;
+		uint32_t calib_bl;
 	} in;
 	uint32_t output;
 };
 
+#define MDSS_CALIB_MODE_BL	0x1
 struct mdss_calib_cfg {
 	uint32_t ops;
 	uint32_t calib_mask;
diff --git a/include/linux/netfilter_ipv4/ipt_NATTYPE.h b/include/linux/netfilter_ipv4/ipt_NATTYPE.h
index 88311c9..594b62a 100644
--- a/include/linux/netfilter_ipv4/ipt_NATTYPE.h
+++ b/include/linux/netfilter_ipv4/ipt_NATTYPE.h
@@ -21,7 +21,8 @@
 	u_int16_t type;
 };
 
-extern bool nattype_refresh_timer(unsigned long nattype);
+extern bool nattype_refresh_timer(unsigned long nattype,
+unsigned long timeout_value);
 
 #endif /*_IPT_NATTYPE_H_target*/
 
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index e883ad7..c6da2c3 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1844,9 +1844,11 @@
 
 #define V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL (V4L2_CID_MPEG_MSM_VIDC_BASE + 26)
 enum v4l2_mpeg_vidc_perf_level {
-	V4L2_CID_MPEG_VIDC_PERF_LEVEL_PERFORMANCE		= 0,
-	V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO			= 1,
+	V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL			= 0,
+	V4L2_CID_MPEG_VIDC_PERF_LEVEL_PERFORMANCE		= 1,
+	V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO			= 2,
 };
+
 #define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB		\
 		(V4L2_CID_MPEG_MSM_VIDC_BASE+27)
 #define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE	\
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index 3775ddd..25d528d7 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -161,12 +161,20 @@
 	ENABLE_STREAM_BUF_DIVERT,
 	DISABLE_STREAM_BUF_DIVERT,
 	UPDATE_STREAM_FRAMEDROP_PATTERN,
+	UPDATE_STREAM_AXI_CONFIG,
+};
+
+struct msm_vfe_axi_stream_cfg_update_info {
+	uint32_t stream_handle;
+	uint32_t output_format;
+	enum msm_vfe_frame_skip_pattern skip_pattern;
+	struct msm_vfe_axi_plane_cfg plane_cfg[MAX_PLANES_PER_STREAM];
 };
 
 struct msm_vfe_axi_stream_update_cmd {
-	uint32_t stream_handle;
+	uint32_t num_streams;
 	enum msm_vfe_axi_stream_update_type update_type;
-	enum msm_vfe_frame_skip_pattern skip_pattern;
+	struct msm_vfe_axi_stream_cfg_update_info update_info[MAX_NUM_STREAM];
 };
 
 enum msm_isp_stats_type {
@@ -317,6 +325,7 @@
 	uint32_t session_id;
 	uint32_t stream_id;
 	uint32_t handle;
+	uint32_t output_format;
 	int8_t buf_idx;
 };
 struct msm_isp_stats_event {
@@ -335,6 +344,8 @@
 	 *which use monotonic clock
 	 */
 	struct timeval timestamp;
+	/* Monotonic timestamp since bootup */
+	struct timeval mono_timestamp;
 	/* if pix is a src frame_id is from camif */
 	uint32_t frame_id;
 	union {
@@ -362,6 +373,8 @@
 #define V4L2_PIX_FMT_QGBRG12 v4l2_fourcc('Q', 'G', 'B', '2')
 #define V4L2_PIX_FMT_QGRBG12 v4l2_fourcc('Q', 'G', 'R', '2')
 #define V4L2_PIX_FMT_QRGGB12 v4l2_fourcc('Q', 'R', 'G', '2')
+#define V4L2_PIX_FMT_NV14 v4l2_fourcc('N', 'V', '1', '4')
+#define V4L2_PIX_FMT_NV41 v4l2_fourcc('N', 'V', '4', '1')
 
 #define VIDIOC_MSM_VFE_REG_CFG \
 	_IOWR('V', BASE_VIDIOC_PRIVATE, struct msm_vfe_cfg_cmd2)
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index 909e1b9..f36e4d5 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -314,7 +314,7 @@
 	TP_ARGS(client_name, heap_name, len, mask, flags),
 
 	TP_STRUCT__entry(
-		__field(const char *,	client_name)
+		__array(char,		client_name, 64)
 		__field(const char *,	heap_name)
 		__field(size_t,		len)
 		__field(unsigned int,	mask)
@@ -322,7 +322,7 @@
 	),
 
 	TP_fast_assign(
-		__entry->client_name	= client_name;
+		strlcpy(__entry->client_name, client_name, 64);
 		__entry->heap_name	= heap_name;
 		__entry->len		= len;
 		__entry->mask		= mask;
diff --git a/net/ipv4/netfilter/ipt_NATTYPE.c b/net/ipv4/netfilter/ipt_NATTYPE.c
index 2bb18ca..f181be4 100644
--- a/net/ipv4/netfilter/ipt_NATTYPE.c
+++ b/net/ipv4/netfilter/ipt_NATTYPE.c
@@ -58,6 +58,7 @@
 struct ipt_nattype {
 	struct list_head list;
 	struct timer_list timeout;
+	unsigned long timeout_value;
 	unsigned char is_valid;
 	unsigned short proto;		/* Protocol: TCP or UDP */
 	struct nf_nat_ipv4_range range;	/* LAN side source information */
@@ -102,7 +103,7 @@
  * nattype_refresh_timer()
  *	Refresh the timer for this object.
  */
-bool nattype_refresh_timer(unsigned long nat_type)
+bool nattype_refresh_timer(unsigned long nat_type, unsigned long timeout_value)
 {
 	struct ipt_nattype *nte = (struct ipt_nattype *)nat_type;
 	if (!nte)
@@ -113,7 +114,8 @@
 		return false;
 	}
 	if (del_timer(&nte->timeout)) {
-		nte->timeout.expires = jiffies + NATTYPE_TIMEOUT * HZ;
+		nte->timeout_value = timeout_value - jiffies;
+		nte->timeout.expires = timeout_value;
 		add_timer(&nte->timeout);
 		spin_unlock_bh(&nattype_lock);
 		return true;
@@ -222,7 +224,8 @@
  * nattype_compare
  *	Compare two entries, return true if relevant fields are the same.
  */
-static bool nattype_compare(struct ipt_nattype *n1, struct ipt_nattype *n2)
+static bool nattype_compare(struct ipt_nattype *n1, struct ipt_nattype *n2,
+		const struct ipt_nattype_info *info)
 {
 	/*
 	 * Protocol compare.
@@ -261,19 +264,15 @@
 	}
 
 	/*
-	 * Destination compare
+	 * Destination Comapre for Address Restricted Cone NAT.
 	 */
-	if (n1->dest_addr != n2->dest_addr) {
+	if ((info->type == TYPE_ADDRESS_RESTRICTED) &&
+		(n1->dest_addr != n2->dest_addr)) {
 		DEBUGP("nattype_compare: dest_addr mismatch: %pI4:%pI4\n",
-				&n1->dest_addr, &n2->dest_addr);
+			&n1->dest_addr, &n2->dest_addr);
 		return false;
 	}
 
-	if (n1->dest_port != n2->dest_port) {
-		DEBUGP("nattype_compare: dest_port mismatch: %d:%d\n",
-				ntohs(n1->dest_port), ntohs(n2->dest_port));
-		return false;
-	}
 	return true;
 }
 
@@ -316,6 +315,15 @@
 		}
 
 		/*
+		 * Refresh the timer, if we fail, break
+		 * out and forward fail as though we never
+		 * found the entry.
+		 */
+		if (!nattype_refresh_timer((unsigned long)nte,
+				jiffies + nte->timeout_value))
+			break;
+
+		/*
 		 * Expand the ingress conntrack to include the reply as source
 		 */
 		DEBUGP("Expand ingress conntrack=%p, type=%d, src[%pI4:%d]\n",
@@ -344,11 +352,21 @@
 	enum ip_conntrack_info ctinfo;
 	const struct ipt_nattype_info *info = par->targinfo;
 	uint16_t nat_port;
+	enum ip_conntrack_dir dir;
+
 
 	if (par->hooknum != NF_INET_FORWARD)
 		return XT_CONTINUE;
 
 	/*
+	 * Egress packet, create a new rule in our list.  If conntrack does
+	 * not have an entry, skip this packet.
+	 */
+	ct = nf_ct_get(skb, &ctinfo);
+	if (!ct)
+		return XT_CONTINUE;
+
+	/*
 	 * Ingress packet, refresh the timer if we find an entry.
 	 */
 	if (info->mode == MODE_FORWARD_IN) {
@@ -366,7 +384,8 @@
 			 * out and forward fail as though we never
 			 * found the entry.
 			 */
-			if (!nattype_refresh_timer((unsigned long)nte))
+			if (!nattype_refresh_timer((unsigned long)nte,
+					ct->timeout.expires))
 				break;
 			/*
 			 * The entry is found and refreshed, the
@@ -382,15 +401,9 @@
 		return XT_CONTINUE;
 	}
 
-	/*
-	 * Egress packet, create a new rule in our list.  If conntrack does
-	 * not have an entry, skip this packet.
-	 */
-	ct = nf_ct_get(skb, &ctinfo);
-	if (!ct || (ctinfo == IP_CT_NEW && ctinfo == IP_CT_RELATED))
-		return XT_CONTINUE;
+	dir = CTINFO2DIR(ctinfo);
 
-	nat_port = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all;
+	nat_port = ct->tuplehash[!dir].tuple.dst.u.all;
 
 	/*
 	 * Allocate a new entry
@@ -439,7 +452,7 @@
 	 */
 	spin_lock_bh(&nattype_lock);
 	list_for_each_entry(nte2, &nattype_list, list) {
-		if (!nattype_compare(nte, nte2))
+		if (!nattype_compare(nte, nte2, info))
 			continue;
 		spin_unlock_bh(&nattype_lock);
 		/*
@@ -447,7 +460,9 @@
 		 * entry as this one is timed out and will be removed
 		 * from the list shortly.
 		 */
-		if (!nattype_refresh_timer((unsigned long)nte2))
+		nte2->timeout_value = ct->timeout.expires - jiffies;
+		if (!nattype_refresh_timer((unsigned long)nte2,
+				ct->timeout.expires))
 			break;
 		/*
 		 * Found and refreshed an existing entry.  Its values
@@ -463,7 +478,8 @@
 	/*
 	 * Add the new entry to the list.
 	 */
-	nte->timeout.expires = jiffies + (NATTYPE_TIMEOUT  * HZ);
+	nte->timeout_value = ct->timeout.expires - jiffies;
+	nte->timeout.expires = ct->timeout.expires;
 	add_timer(&nte->timeout);
 	list_add(&nte->list, &nattype_list);
 	ct->nattype_entry = (unsigned long)nte;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 13925ac..d7eafd5 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1101,7 +1101,7 @@
 
 /* Refresh the NAT type entry. */
 #if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
-	(void)nattype_refresh_timer(ct->nattype_entry);
+	(void)nattype_refresh_timer(ct->nattype_entry, ct->timeout.expires);
 #endif
 
 acct:
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index ca7e835..6239080 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1229,6 +1229,11 @@
 	ct->timeout.expires = jiffies + timeout * HZ;
 	add_timer(&ct->timeout);
 
+/* Refresh the NAT type entry. */
+#if defined(CONFIG_IP_NF_TARGET_NATTYPE_MODULE)
+	(void)nattype_refresh_timer(ct->nattype_entry, ct->timeout.expires);
+#endif
+
 	return 0;
 }
 
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index 75881cf..0ba1ec5 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -1750,6 +1750,7 @@
 	{"IIR1", NULL, "IIR1 INP1 MUX"},
 	{"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
 	{"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
+	{"MIC BIAS Internal1", NULL, "INT_LDO_H"},
 	{"MIC BIAS Internal2", NULL, "INT_LDO_H"},
 	{"MIC BIAS External", NULL, "INT_LDO_H"},
 };
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index 6cdbb8c..8ae6050 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -4325,6 +4325,23 @@
 		snd_soc_write(codec, TAPAN_A_SPKR_DRV_EN, 0xEF);
 }
 
+static void tapan_update_reg_mclk_rate(struct wcd9xxx *wcd9xxx)
+{
+	struct snd_soc_codec *codec;
+
+	codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
+	dev_dbg(codec->dev, "%s: MCLK Rate = %x\n",
+			__func__, wcd9xxx->mclk_rate);
+
+	if (wcd9xxx->mclk_rate == TAPAN_MCLK_CLK_12P288MHZ) {
+		snd_soc_update_bits(codec, TAPAN_A_CHIP_CTL, 0x06, 0x0);
+		snd_soc_update_bits(codec, TAPAN_A_RX_COM_TIMER_DIV, 0x01,
+				0x01);
+	} else if (wcd9xxx->mclk_rate == TAPAN_MCLK_CLK_9P6MHZ) {
+		snd_soc_update_bits(codec, TAPAN_A_CHIP_CTL, 0x06, 0x2);
+	}
+}
+
 static const struct tapan_reg_mask_val tapan_codec_reg_init_val[] = {
 	/* Initialize current threshold to 350MA
 	 * number of wait and run cycles to 4096
@@ -4395,26 +4412,29 @@
 				tapan_codec_reg_init_val[i].mask,
 				tapan_codec_reg_init_val[i].val);
 }
-
-static int tapan_setup_irqs(struct tapan_priv *tapan)
+static void tapan_slim_interface_init_reg(struct snd_soc_codec *codec)
 {
 	int i;
-	int ret = 0;
-	struct snd_soc_codec *codec = tapan->codec;
-
-	ret = wcd9xxx_request_irq(codec->control_data, WCD9XXX_IRQ_SLIMBUS,
-				  tapan_slimbus_irq, "SLIMBUS Slave", tapan);
-	if (ret) {
-		pr_err("%s: Failed to request irq %d\n", __func__,
-		       WCD9XXX_IRQ_SLIMBUS);
-		goto exit;
-	}
 
 	for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
 		wcd9xxx_interface_reg_write(codec->control_data,
 					    TAPAN_SLIM_PGD_PORT_INT_EN0 + i,
 					    0xFF);
-exit:
+}
+
+static int tapan_setup_irqs(struct tapan_priv *tapan)
+{
+	int ret = 0;
+	struct snd_soc_codec *codec = tapan->codec;
+
+	ret = wcd9xxx_request_irq(codec->control_data, WCD9XXX_IRQ_SLIMBUS,
+				  tapan_slimbus_irq, "SLIMBUS Slave", tapan);
+	if (ret)
+		pr_err("%s: Failed to request irq %d\n", __func__,
+		       WCD9XXX_IRQ_SLIMBUS);
+	else
+		tapan_slim_interface_init_reg(codec);
+
 	return ret;
 }
 
@@ -4432,9 +4452,74 @@
 }
 EXPORT_SYMBOL_GPL(tapan_hs_detect);
 
+static int tapan_post_reset_cb(struct wcd9xxx *wcd9xxx)
+{
+	int ret = 0;
+	int rco_clk_rate;
+	struct snd_soc_codec *codec;
+	struct tapan_priv *tapan;
+
+	codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
+	tapan = snd_soc_codec_get_drvdata(codec);
+	mutex_lock(&codec->mutex);
+	WCD9XXX_BCL_LOCK(&tapan->resmgr);
+
+	if (codec->reg_def_copy) {
+		pr_debug("%s: Update ASOC cache", __func__);
+		kfree(codec->reg_cache);
+		codec->reg_cache = kmemdup(codec->reg_def_copy,
+						codec->reg_size, GFP_KERNEL);
+		if (!codec->reg_cache) {
+			pr_err("%s: Cache update failed!\n", __func__);
+			WCD9XXX_BCL_UNLOCK(&tapan->resmgr);
+			mutex_unlock(&codec->mutex);
+			return -ENOMEM;
+		}
+	}
+
+	wcd9xxx_resmgr_post_ssr(&tapan->resmgr);
+	if (spkr_drv_wrnd == 1)
+		snd_soc_update_bits(codec, TAPAN_A_SPKR_DRV_EN, 0x80, 0x80);
+	WCD9XXX_BCL_UNLOCK(&tapan->resmgr);
+
+	tapan_update_reg_defaults(codec);
+	tapan_update_reg_mclk_rate(wcd9xxx);
+	tapan_codec_init_reg(codec);
+	ret = tapan_handle_pdata(tapan);
+	if (IS_ERR_VALUE(ret))
+		pr_err("%s: bad pdata\n", __func__);
+
+	tapan_slim_interface_init_reg(codec);
+
+	wcd9xxx_mbhc_deinit(&tapan->mbhc);
+
+	if (TAPAN_IS_1_0(wcd9xxx->version))
+		rco_clk_rate = TAPAN_MCLK_CLK_12P288MHZ;
+	else
+		rco_clk_rate = TAPAN_MCLK_CLK_9P6MHZ;
+
+	ret = wcd9xxx_mbhc_init(&tapan->mbhc, &tapan->resmgr, codec, NULL,
+				WCD9XXX_MBHC_VERSION_TAPAN,
+				rco_clk_rate);
+	if (ret)
+		pr_err("%s: mbhc init failed %d\n", __func__, ret);
+	else
+		wcd9xxx_mbhc_start(&tapan->mbhc, tapan->mbhc.mbhc_cfg);
+	mutex_unlock(&codec->mutex);
+	return ret;
+}
+
 static struct wcd9xxx_reg_address tapan_reg_address = {
 };
 
+static int wcd9xxx_ssr_register(struct wcd9xxx *control,
+		int (*post_reset_cb)(struct wcd9xxx *wcd9xxx), void *priv)
+{
+	control->post_reset = post_reset_cb;
+	control->ssr_priv = priv;
+	return 0;
+}
+
 static int tapan_codec_probe(struct snd_soc_codec *codec)
 {
 	struct wcd9xxx *control;
@@ -4449,6 +4534,8 @@
 	codec->control_data = dev_get_drvdata(codec->dev->parent);
 	control = codec->control_data;
 
+	wcd9xxx_ssr_register(control, tapan_post_reset_cb, (void *)codec);
+
 	dev_info(codec->dev, "%s()\n", __func__);
 
 	tapan = kzalloc(sizeof(struct tapan_priv), GFP_KERNEL);
@@ -4502,17 +4589,7 @@
 	tapan->aux_l_gain = 0x1F;
 	tapan->aux_r_gain = 0x1F;
 	tapan_update_reg_defaults(codec);
-
-	dev_dbg(codec->dev, "%s: MCLK Rate = %x\n",
-			__func__, wcd9xxx->mclk_rate);
-
-	if (wcd9xxx->mclk_rate == TAPAN_MCLK_CLK_12P288MHZ) {
-		snd_soc_update_bits(codec, TAPAN_A_CHIP_CTL, 0x06, 0x0);
-		snd_soc_update_bits(codec, TAPAN_A_RX_COM_TIMER_DIV, 0x01,
-				0x01);
-	} else if (wcd9xxx->mclk_rate == TAPAN_MCLK_CLK_9P6MHZ) {
-		snd_soc_update_bits(codec, TAPAN_A_CHIP_CTL, 0x06, 0x2);
-	}
+	tapan_update_reg_mclk_rate(wcd9xxx);
 	tapan_codec_init_reg(codec);
 	ret = tapan_handle_pdata(tapan);
 	if (IS_ERR_VALUE(ret)) {
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 887a324..e853061 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -94,9 +94,6 @@
 
 #define WCD9XXX_USLEEP_RANGE_MARGIN_US 1000
 
-#define WCD9XXX_IRQ_MBHC_JACK_SWITCH_TAIKO 28
-#define WCD9XXX_IRQ_MBHC_JACK_SWITCH_TAPAN 21
-
 static bool detect_use_vddio_switch = true;
 
 struct wcd9xxx_mbhc_detect {
@@ -1838,12 +1835,12 @@
 /* called only from interrupt which is under codec_resource_lock acquisition */
 static void wcd9xxx_hs_remove_irq_noswch(struct wcd9xxx_mbhc *mbhc)
 {
-	short bias_value;
+	s16 dce;
+	unsigned long timeout;
 	bool removed = true;
 	struct snd_soc_codec *codec = mbhc->codec;
 	const struct wcd9xxx_mbhc_general_cfg *generic =
 		WCD9XXX_MBHC_CAL_GENERAL_PTR(mbhc->mbhc_cfg->calibration);
-	int min_us = FAKE_REMOVAL_MIN_PERIOD_MS * 1000;
 
 	pr_debug("%s: enter\n", __func__);
 	if (mbhc->current_plug != PLUG_TYPE_HEADSET) {
@@ -1855,23 +1852,21 @@
 	}
 
 	usleep_range(generic->t_shutdown_plug_rem,
-			generic->t_shutdown_plug_rem);
+		     generic->t_shutdown_plug_rem);
 
+	timeout = jiffies + msecs_to_jiffies(FAKE_REMOVAL_MIN_PERIOD_MS);
 	do {
-		bias_value = wcd9xxx_codec_sta_dce(mbhc, 1,  true);
-		pr_debug("%s: DCE %d,%d, %d us left\n", __func__, bias_value,
-			 wcd9xxx_codec_sta_dce_v(mbhc, 1, bias_value), min_us);
-		if (bias_value <
+		dce = wcd9xxx_codec_sta_dce(mbhc, 1,  true);
+		pr_debug("%s: DCE 0x%x,%d\n", __func__, dce,
+			 wcd9xxx_codec_sta_dce_v(mbhc, 1, dce));
+		if (dce <
 		    wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_INS_H)) {
-			pr_debug("%s: checking false removal\n", __func__);
-			msleep(500);
-			removed = !wcd9xxx_hs_remove_settle(mbhc);
-			pr_debug("%s: headset %sactually removed\n", __func__,
-				 removed ? "" : "not ");
+			removed = false;
 			break;
 		}
-		min_us -= mbhc->mbhc_data.t_dce;
-	} while (min_us > 0);
+	} while (!time_after(jiffies, timeout));
+	pr_debug("%s: headset %sactually removed\n", __func__,
+		  removed ? "" : "not ");
 
 	if (removed) {
 		if (mbhc->mbhc_cfg->detect_extn_cable) {
@@ -3117,10 +3112,10 @@
 
 		switch (mbhc->mbhc_version) {
 		case WCD9XXX_MBHC_VERSION_TAIKO:
-			jack_irq = WCD9XXX_IRQ_MBHC_JACK_SWITCH_TAIKO;
+			jack_irq = WCD9320_IRQ_MBHC_JACK_SWITCH;
 			break;
 		case WCD9XXX_MBHC_VERSION_TAPAN:
-			jack_irq = WCD9XXX_IRQ_MBHC_JACK_SWITCH_TAPAN;
+			jack_irq = WCD9306_IRQ_MBHC_JACK_SWITCH;
 			break;
 		default:
 			return -EINVAL;
@@ -3802,7 +3797,18 @@
 	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_REMOVAL, mbhc);
 	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_INSERTION, mbhc);
 
-	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_JACK_SWITCH, mbhc);
+	switch (mbhc->mbhc_version) {
+	case WCD9XXX_MBHC_VERSION_TAIKO:
+		wcd9xxx_free_irq(cdata, WCD9320_IRQ_MBHC_JACK_SWITCH, mbhc);
+		break;
+	case WCD9XXX_MBHC_VERSION_TAPAN:
+		wcd9xxx_free_irq(cdata, WCD9306_IRQ_MBHC_JACK_SWITCH, mbhc);
+		break;
+	default:
+		pr_err("%s: irq free failed! Invalid MBHC version %d\n",
+			__func__, mbhc->mbhc_version);
+	}
+
 	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_HPH_PA_OCPL_FAULT, mbhc);
 	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_HPH_PA_OCPR_FAULT, mbhc);
 
diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
index 1d3779f..9990ae8 100644
--- a/sound/soc/msm/msm8226.c
+++ b/sound/soc/msm/msm8226.c
@@ -147,7 +147,6 @@
 		if (clk_users != 1)
 			goto exit;
 		if (codec_clk) {
-			clk_set_rate(codec_clk, TAPAN_EXT_CLK_RATE);
 			clk_prepare_enable(codec_clk);
 			tapan_mclk_enable(codec, 1, dapm);
 		} else {
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index c25eb86..9fc0adb 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -639,7 +639,6 @@
 			goto exit;
 
 		if (codec_clk) {
-			clk_set_rate(codec_clk, TAIKO_EXT_CLK_RATE);
 			clk_prepare_enable(codec_clk);
 			taiko_mclk_enable(codec, 1, dapm);
 		} else {
@@ -2097,6 +2096,58 @@
 		 /* this dainlink has playback support */
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
 	},
+	/* HDMI Hostless */
+	{
+		.name = "HDMI_RX_HOSTLESS",
+		.stream_name = "HDMI_RX_HOSTLESS",
+		.cpu_dai_name = "HDMI_HOSTLESS",
+		.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,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{
+		.name = LPASS_BE_SLIMBUS_4_TX,
+		.stream_name = "Slimbus4 Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.16393",
+		.platform_name = "msm-pcm-hostless",
+		.codec_name = "taiko_codec",
+		.codec_dai_name	= "taiko_vifeedback",
+		.be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
+		.be_hw_params_fixup = msm_slim_4_tx_be_hw_params_fixup,
+		.ops = &msm8974_be_ops,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+	},
+	/* Ultrasound RX Back End DAI Link */
+	{
+		.name = "SLIMBUS_2 Hostless Playback",
+		.stream_name = "SLIMBUS_2 Hostless Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.16388",
+		.platform_name = "msm-pcm-hostless",
+		.codec_name = "taiko_codec",
+		.codec_dai_name = "taiko_rx2",
+		.ignore_suspend = 1,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ops = &msm8974_slimbus_2_be_ops,
+	},
+	/* Ultrasound TX Back End DAI Link */
+	{
+		.name = "SLIMBUS_2 Hostless Capture",
+		.stream_name = "SLIMBUS_2 Hostless Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.16389",
+		.platform_name = "msm-pcm-hostless",
+		.codec_name = "taiko_codec",
+		.codec_dai_name = "taiko_tx2",
+		.ignore_suspend = 1,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ops = &msm8974_slimbus_2_be_ops,
+	},
 	/* Backend BT/FM DAI Links */
 	{
 		.name = LPASS_BE_INT_BT_SCO_RX,
@@ -2177,21 +2228,6 @@
 		.be_hw_params_fixup = msm_proxy_tx_be_hw_params_fixup,
 		.ignore_suspend = 1,
 	},
-	/* HDMI Hostless */
-	{
-		.name = "HDMI_RX_HOSTLESS",
-		.stream_name = "HDMI_RX_HOSTLESS",
-		.cpu_dai_name = "HDMI_HOSTLESS",
-		.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,
-		.codec_dai_name = "snd-soc-dummy-dai",
-		.codec_name = "snd-soc-dummy",
-	},
 	/* Primary AUX PCM Backend DAI Links */
 	{
 		.name = LPASS_BE_AUXPCM_RX,
@@ -2351,19 +2387,6 @@
 		.ignore_pmdown_time = 1,
 		.ignore_suspend = 1,
 	},
-	{
-		.name = LPASS_BE_SLIMBUS_4_TX,
-		.stream_name = "Slimbus4 Capture",
-		.cpu_dai_name = "msm-dai-q6-dev.16393",
-		.platform_name = "msm-pcm-hostless",
-		.codec_name = "taiko_codec",
-		.codec_dai_name	= "taiko_vifeedback",
-		.be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
-		.be_hw_params_fixup = msm_slim_4_tx_be_hw_params_fixup,
-		.ops = &msm8974_be_ops,
-		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
-		.ignore_suspend = 1,
-	},
 	/* Incall Record Uplink BACK END DAI Link */
 	{
 		.name = LPASS_BE_INCALL_RECORD_TX,
@@ -2416,30 +2439,6 @@
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
 		.ignore_suspend = 1,
 	},
-	/* Ultrasound RX Back End DAI Link */
-	{
-		.name = "SLIMBUS_2 Hostless Playback",
-		.stream_name = "SLIMBUS_2 Hostless Playback",
-		.cpu_dai_name = "msm-dai-q6-dev.16388",
-		.platform_name = "msm-pcm-hostless",
-		.codec_name = "taiko_codec",
-		.codec_dai_name = "taiko_rx2",
-		.ignore_suspend = 1,
-		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
-		.ops = &msm8974_slimbus_2_be_ops,
-	},
-	/* Ultrasound TX Back End DAI Link */
-	{
-		.name = "SLIMBUS_2 Hostless Capture",
-		.stream_name = "SLIMBUS_2 Hostless Capture",
-		.cpu_dai_name = "msm-dai-q6-dev.16389",
-		.platform_name = "msm-pcm-hostless",
-		.codec_name = "taiko_codec",
-		.codec_dai_name = "taiko_tx2",
-		.ignore_suspend = 1,
-		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
-		.ops = &msm8974_slimbus_2_be_ops,
-	},
 };
 
 static struct snd_soc_dai_link msm8974_hdmi_dai_link[] = {
diff --git a/sound/soc/msm/msm8x10.c b/sound/soc/msm/msm8x10.c
index 96f78d9..ce6cfea 100644
--- a/sound/soc/msm/msm8x10.c
+++ b/sound/soc/msm/msm8x10.c
@@ -94,16 +94,6 @@
 static int msm8x10_mclk_event(struct snd_soc_dapm_widget *w,
 			      struct snd_kcontrol *kcontrol, int event);
 
-static const struct snd_soc_dapm_route msm8x10_common_audio_map[] = {
-	{"RX_BIAS", NULL, "MCLK"},
-	{"INT_LDO_H", NULL, "MCLK"},
-	{"MIC BIAS External", NULL, "Handset Mic"},
-	{"MIC BIAS Internal2", NULL, "Headset Mic"},
-	{"AMIC1", NULL, "MIC BIAS External"},
-	{"AMIC2", NULL, "MIC BIAS Internal2"},
-
-};
-
 static const struct snd_soc_dapm_widget msm8x10_dapm_widgets[] = {
 
 	SND_SOC_DAPM_SUPPLY("MCLK",  SND_SOC_NOPM, 0, 0,
@@ -381,9 +371,6 @@
 	snd_soc_dapm_new_controls(dapm, msm8x10_dapm_widgets,
 				ARRAY_SIZE(msm8x10_dapm_widgets));
 
-	snd_soc_dapm_add_routes(dapm, msm8x10_common_audio_map,
-		ARRAY_SIZE(msm8x10_common_audio_map));
-
 	snd_soc_dapm_sync(dapm);
 	ret =  msm_enable_mclk_root(AFE_PORT_ID_SECONDARY_MI2S_RX,
 				    &digital_cdc_clk);
@@ -806,6 +793,10 @@
 	card->dev = &pdev->dev;
 	platform_set_drvdata(pdev, card);
 
+	ret = snd_soc_of_parse_audio_routing(card,
+			"qcom,audio-routing");
+	if (ret)
+		goto err;
 
 	ret = snd_soc_register_card(card);
 	if (ret) {
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 0ae393c..461fca4 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -295,7 +295,7 @@
 	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);
+		ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 		pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
@@ -303,12 +303,12 @@
 		if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
 			break;
 		prtd->cmd_ack = 0;
-		q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
+		ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
 		break;
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		pr_debug("SNDRV_PCM_TRIGGER_PAUSE\n");
-		q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
+		ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
 		atomic_set(&prtd->start, 0);
 		break;
 	default:
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 997946d..4fd90f9 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -618,7 +618,7 @@
 
 static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
 {
-	u16 session_id = 0;
+	u32 session_id = 0;
 
 	pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
 
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
index 5485440..5c97403 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
@@ -67,9 +67,9 @@
 		return false;
 }
 
-static uint16_t get_session_id(struct msm_voice *pvoc)
+static uint32_t get_session_id(struct msm_voice *pvoc)
 {
-	uint16_t session_id = 0;
+	uint32_t session_id = 0;
 
 	if (is_volte(pvoc))
 		session_id = voc_get_session_id(VOLTE_SESSION_NAME);
@@ -175,7 +175,7 @@
 
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct msm_voice *prtd = runtime->private_data;
-	uint16_t session_id = 0;
+	uint32_t session_id = 0;
 	int ret = 0;
 
 	mutex_lock(&prtd->lock);
@@ -201,7 +201,7 @@
 	int ret = 0;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct msm_voice *prtd = runtime->private_data;
-	uint16_t session_id = 0;
+	uint32_t session_id = 0;
 
 	mutex_lock(&prtd->lock);
 
@@ -236,7 +236,7 @@
 	int ret = 0;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct msm_voice *prtd = runtime->private_data;
-	uint16_t session_id = 0;
+	uint32_t session_id = 0;
 
 	pr_debug("%s: cmd = %d\n", __func__, cmd);
 
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 3bb31f9..9882ec7 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -393,11 +393,23 @@
 	if ((this_afe.afe_cal_addr[path].cal_paddr != cal_block.cal_paddr) ||
 		(cal_block.cal_size > this_afe.afe_cal_addr[path].cal_size)) {
 		atomic_set(&this_afe.mem_map_cal_index, path);
-		if (this_afe.afe_cal_addr[path].cal_paddr != 0)
-			afe_cmd_memory_unmap(
+		if (this_afe.afe_cal_addr[path].cal_paddr != 0) {
+			result = afe_cmd_memory_unmap(
 				this_afe.afe_cal_addr[path].cal_paddr);
+			if (result) {
+				pr_err("%s: AFE memory unmap failed\n",
+						__func__);
+				atomic_set(&this_afe.mem_map_cal_index, -1);
+				goto done;
+			}
+		}
 
-		afe_cmd_memory_map(cal_block.cal_paddr, size);
+		result = afe_cmd_memory_map(cal_block.cal_paddr, size);
+		if (result) {
+			pr_err("%s: AFE memory map failed\n", __func__);
+			atomic_set(&this_afe.mem_map_cal_index, -1);
+			goto done;
+		}
 		atomic_set(&this_afe.mem_map_cal_index, -1);
 		this_afe.afe_cal_addr[path].cal_paddr = cal_block.cal_paddr;
 		this_afe.afe_cal_addr[path].cal_size = size;
@@ -1949,6 +1961,7 @@
 	pr_debug("%s: dma_addr_p 0x%x , size %d\n", __func__,
 					dma_addr_p, dma_buf_sz);
 	atomic_set(&this_afe.state, 1);
+	atomic_set(&this_afe.status, 0);
 	this_afe.mmap_handle = 0;
 	ret = apr_send_pkt(this_afe.apr, (uint32_t *) mmap_region_cmd);
 	if (ret < 0) {
@@ -1966,6 +1979,12 @@
 		ret = -EINVAL;
 		goto fail_cmd;
 	}
+	if (atomic_read(&this_afe.status) != 0) {
+		pr_err("%s: Memory map cmd failed\n", __func__);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
+
 	pr_debug("%s: mmap handle 0x%x\n", __func__, this_afe.mmap_handle);
 	kfree(mmap_region_cmd);
 	return 0;
@@ -2120,10 +2139,16 @@
 	/* Todo */
 	index = mregion.hdr.token = IDX_RSVD_2;
 
+	atomic_set(&this_afe.status, 0);
 	ret = afe_apr_send_pkt(&mregion, &this_afe.wait[index]);
 	if (ret)
 		pr_err("%s: AFE memory unmap cmd failed %d\n",
 		       __func__, ret);
+	if (atomic_read(&this_afe.status) != 0) {
+		pr_err("%s: Memory unmap cmd failed\n", __func__);
+		ret = -EINVAL;
+	}
+
 	return ret;
 }
 
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 5136cb9..46d208b 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -408,7 +408,7 @@
 
 	result = wait_event_timeout(ac->cmd_wait,
 			(atomic_read(&ac->cmd_state) == 0), 5*HZ);
-	if (result < 0) {
+	if (!result) {
 		pr_err("%s: Set topologies failed payload = 0x%x\n",
 			__func__, cal_block.cal_paddr);
 		goto done;
@@ -508,16 +508,17 @@
 
 int q6asm_mmap_apr_dereg(void)
 {
-	if (atomic_read(&this_mmap.ref_cnt) <= 0) {
-		pr_err("%s: APR Common Port Already Closed\n", __func__);
-		goto done;
-	}
-	atomic_dec(&this_mmap.ref_cnt);
-	if (atomic_read(&this_mmap.ref_cnt) == 0) {
+	int c;
+
+	c = atomic_sub_return(1, &this_mmap.ref_cnt);
+	if (c == 0) {
 		apr_deregister(this_mmap.apr);
-		pr_debug("%s:APR De-Register common port\n", __func__);
+		pr_debug("%s: APR De-Register common port\n", __func__);
+	} else if (c < 0) {
+		pr_err("%s: APR Common Port Already Closed\n", __func__);
+		atomic_set(&this_mmap.ref_cnt, 0);
 	}
-done:
+
 	return 0;
 }
 
@@ -1716,12 +1717,14 @@
 	run.time_lsw = lsw_ts;
 	run.time_msw = msw_ts;
 
+	/* have to increase first avoid race */
+	atomic_inc(&ac->nowait_cmd_cnt);
 	rc = apr_send_pkt(ac->apr, (uint32_t *) &run);
 	if (rc < 0) {
+		atomic_dec(&ac->nowait_cmd_cnt);
 		pr_err("%s:Commmand run failed[%d]", __func__, rc);
 		return -EINVAL;
 	}
-	atomic_inc(&ac->nowait_cmd_cnt);
 	return 0;
 }
 
@@ -3692,12 +3695,14 @@
 	pr_debug("%s:session[%d]opcode[0x%x] ", __func__,
 						ac->session,
 						hdr.opcode);
+	/* have to increase first avoid race */
+	atomic_inc(&ac->nowait_cmd_cnt);
 	rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr);
 	if (rc < 0) {
+		atomic_dec(&ac->nowait_cmd_cnt);
 		pr_err("%s:Commmand 0x%x failed\n", __func__, hdr.opcode);
 		goto fail_cmd;
 	}
-	atomic_inc(&ac->nowait_cmd_cnt);
 	return 0;
 fail_cmd:
 	return -EINVAL;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 8888e41..2fabca1 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -61,7 +61,7 @@
 static int voice_send_mvm_media_type_cmd(struct voice_data *v);
 static int voice_send_cvs_data_exchange_mode_cmd(struct voice_data *v);
 static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v);
-static int voice_set_packet_exchange_mode_and_config(uint16_t session_id,
+static int voice_set_packet_exchange_mode_and_config(uint32_t session_id,
 						     uint32_t mode);
 
 static int voice_send_cvs_register_cal_cmd(struct voice_data *v);
@@ -85,6 +85,9 @@
 static int voice_send_set_pp_enable_cmd(struct voice_data *v,
 					uint32_t module_id, int enable);
 
+static struct voice_data *voice_get_session_by_idx(int idx);
+static int voice_get_idx_for_session(u32 session_id);
+
 static u16 voice_get_mvm_handle(struct voice_data *v)
 {
 	if (v == NULL) {
@@ -154,7 +157,7 @@
 	v->cvp_handle = cvp_handle;
 }
 
-char *voc_get_session_name(u16 session_id)
+char *voc_get_session_name(u32 session_id)
 {
 	char *session_name = NULL;
 
@@ -169,9 +172,9 @@
 	return session_name;
 }
 
-uint16_t voc_get_session_id(char *name)
+uint32_t voc_get_session_id(char *name)
 {
-	u16 session_id = 0;
+	u32 session_id = 0;
 
 	if (name != NULL) {
 		if (!strncmp(name, "Voice session", 13))
@@ -192,42 +195,103 @@
 	return session_id;
 }
 
-static struct voice_data *voice_get_session(u16 session_id)
+static struct voice_data *voice_get_session(u32 session_id)
 {
 	struct voice_data *v = NULL;
 
-	if ((session_id >= SESSION_ID_BASE) &&
-	    (session_id < SESSION_ID_BASE + MAX_VOC_SESSIONS)) {
-		v = &common.voice[session_id - SESSION_ID_BASE];
+	switch (session_id) {
+	case VOICE_SESSION_VSID:
+		v = &common.voice[VOC_PATH_PASSIVE];
+		break;
+
+	case VOICE2_SESSION_VSID:
+		v = &common.voice[VOC_PATH_VOICE2_PASSIVE];
+		break;
+
+	case VOLTE_SESSION_VSID:
+		v = &common.voice[VOC_PATH_VOLTE_PASSIVE];
+		break;
+
+	case VOIP_SESSION_VSID:
+		v = &common.voice[VOC_PATH_FULL];
+		break;
+
+	case ALL_SESSION_VSID:
+		break;
+
+	default:
+		pr_err("%s: Invalid session_id : %x\n", __func__, session_id);
+
+		break;
 	}
 
-	pr_debug("%s: session_id 0x%x session handle 0x%x\n",
-			 __func__, session_id, (unsigned int)v);
+	pr_debug("%s:session_id 0x%x session handle 0x%x\n",
+		__func__, session_id, (unsigned int)v);
 
 	return v;
 }
 
-static bool is_voice_session(u16 session_id)
+static int voice_get_idx_for_session(u32 session_id)
+{
+	int idx = 0;
+
+	switch (session_id) {
+	case VOICE_SESSION_VSID:
+		idx = VOC_PATH_PASSIVE;
+		break;
+
+	case VOICE2_SESSION_VSID:
+		idx = VOC_PATH_VOICE2_PASSIVE;
+		break;
+
+	case VOLTE_SESSION_VSID:
+		idx = VOC_PATH_VOLTE_PASSIVE;
+		break;
+
+	case VOIP_SESSION_VSID:
+		idx = VOC_PATH_FULL;
+		break;
+
+	case ALL_SESSION_VSID:
+		idx = MAX_VOC_SESSIONS - 1;
+		break;
+
+	default:
+		pr_err("%s: Invalid session_id : %x\n", __func__, session_id);
+
+		break;
+	}
+
+	return idx;
+}
+
+static struct voice_data *voice_get_session_by_idx(int idx)
+{
+	return ((idx < 0 || idx >= MAX_VOC_SESSIONS) ?
+				NULL : &common.voice[idx]);
+}
+
+static bool is_voice_session(u32 session_id)
 {
 	return (session_id == common.voice[VOC_PATH_PASSIVE].session_id);
 }
 
-static bool is_voip_session(u16 session_id)
+static bool is_voip_session(u32 session_id)
 {
 	return (session_id == common.voice[VOC_PATH_FULL].session_id);
 }
 
-static bool is_volte_session(u16 session_id)
+static bool is_volte_session(u32 session_id)
 {
 	return (session_id == common.voice[VOC_PATH_VOLTE_PASSIVE].session_id);
 }
 
-static bool is_voice2_session(u16 session_id)
+static bool is_voice2_session(u32 session_id)
 {
 	return (session_id == common.voice[VOC_PATH_VOICE2_PASSIVE].session_id);
 }
 
-static bool is_other_session_active(u16 session_id)
+static bool is_other_session_active(u32 session_id)
 {
 	int i;
 	bool ret = false;
@@ -247,7 +311,14 @@
 	pr_debug("%s: ret %d\n", __func__, ret);
 
 	return ret;
+}
 
+static void init_session_id(void)
+{
+	common.voice[VOC_PATH_PASSIVE].session_id = VOICE_SESSION_VSID;
+	common.voice[VOC_PATH_VOLTE_PASSIVE].session_id = VOLTE_SESSION_VSID;
+	common.voice[VOC_PATH_VOICE2_PASSIVE].session_id = VOICE2_SESSION_VSID;
+	common.voice[VOC_PATH_FULL].session_id = VOIP_SESSION_VSID;
 }
 
 static int voice_apr_register(void)
@@ -387,7 +458,8 @@
 						APR_HDR_SIZE);
 		pr_debug("%s: send mvm Voice Ctl pkt size = %d\n",
 			__func__, mvm_voice_ctl_cmd.hdr.pkt_size);
-		mvm_voice_ctl_cmd.hdr.src_port = v->session_id;
+		mvm_voice_ctl_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 		mvm_voice_ctl_cmd.hdr.dest_port = mvm_handle;
 		mvm_voice_ctl_cmd.hdr.token = 0;
 		mvm_voice_ctl_cmd.hdr.opcode =
@@ -461,7 +533,8 @@
 						APR_HDR_SIZE);
 			pr_debug("%s: send mvm create session pkt size = %d\n",
 				 __func__, mvm_session_cmd.hdr.pkt_size);
-			mvm_session_cmd.hdr.src_port = v->session_id;
+			mvm_session_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 			mvm_session_cmd.hdr.dest_port = 0;
 			mvm_session_cmd.hdr.token = 0;
 			mvm_session_cmd.hdr.opcode =
@@ -472,7 +545,7 @@
 				sizeof(mvm_session_cmd.mvm_session.name));
 			} else if (is_voice2_session(v->session_id)) {
 				strlcpy(mvm_session_cmd.mvm_session.name,
-				VOICE2_SESSION_VSID,
+				VOICE2_SESSION_VSID_STR,
 				sizeof(mvm_session_cmd.mvm_session.name));
 			} else {
 				strlcpy(mvm_session_cmd.mvm_session.name,
@@ -505,7 +578,8 @@
 					APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(mvm_session_cmd) -
 					APR_HDR_SIZE);
-			mvm_session_cmd.hdr.src_port = v->session_id;
+			mvm_session_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 			mvm_session_cmd.hdr.dest_port = 0;
 			mvm_session_cmd.hdr.token = 0;
 			mvm_session_cmd.hdr.opcode =
@@ -549,7 +623,8 @@
 						APR_PKT_SIZE(APR_HDR_SIZE,
 						sizeof(cvs_session_cmd) -
 						APR_HDR_SIZE);
-			cvs_session_cmd.hdr.src_port = v->session_id;
+			cvs_session_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 			cvs_session_cmd.hdr.dest_port = 0;
 			cvs_session_cmd.hdr.token = 0;
 			cvs_session_cmd.hdr.opcode =
@@ -560,7 +635,7 @@
 				sizeof(cvs_session_cmd.cvs_session.name));
 			} else if (is_voice2_session(v->session_id)) {
 				strlcpy(cvs_session_cmd.cvs_session.name,
-				VOICE2_SESSION_VSID,
+				VOICE2_SESSION_VSID_STR,
 				sizeof(cvs_session_cmd.cvs_session.name));
 			} else {
 			strlcpy(cvs_session_cmd.cvs_session.name,
@@ -598,7 +673,8 @@
 					sizeof(cvs_full_ctl_cmd) -
 					APR_HDR_SIZE);
 
-			cvs_full_ctl_cmd.hdr.src_port = v->session_id;
+			cvs_full_ctl_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 			cvs_full_ctl_cmd.hdr.dest_port = 0;
 			cvs_full_ctl_cmd.hdr.token = 0;
 			cvs_full_ctl_cmd.hdr.opcode =
@@ -645,7 +721,8 @@
 					APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(attach_stream_cmd) -
 					APR_HDR_SIZE);
-			attach_stream_cmd.hdr.src_port = v->session_id;
+			attach_stream_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 			attach_stream_cmd.hdr.dest_port = mvm_handle;
 			attach_stream_cmd.hdr.token = 0;
 			attach_stream_cmd.hdr.opcode =
@@ -710,7 +787,8 @@
 					APR_PKT_VER);
 		detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(detach_stream) - APR_HDR_SIZE);
-		detach_stream.hdr.src_port = v->session_id;
+		detach_stream.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 		detach_stream.hdr.dest_port = mvm_handle;
 		detach_stream.hdr.token = 0;
 		detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM;
@@ -756,7 +834,8 @@
 						      APR_PKT_VER);
 		cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(cvs_destroy) - APR_HDR_SIZE);
-		cvs_destroy.src_port = v->session_id;
+		cvs_destroy.src_port =
+				voice_get_idx_for_session(v->session_id);
 		cvs_destroy.dest_port = cvs_handle;
 		cvs_destroy.token = 0;
 		cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
@@ -805,7 +884,8 @@
 						      APR_PKT_VER);
 		mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					    sizeof(mvm_destroy) - APR_HDR_SIZE);
-		mvm_destroy.src_port = v->session_id;
+		mvm_destroy.src_port =
+				voice_get_idx_for_session(v->session_id);
 		mvm_destroy.dest_port = mvm_handle;
 		mvm_destroy.token = 0;
 		mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
@@ -864,7 +944,8 @@
 						APR_HDR_SIZE);
 		pr_debug("%s: pkt size = %d\n",
 			 __func__, mvm_tty_mode_cmd.hdr.pkt_size);
-		mvm_tty_mode_cmd.hdr.src_port = v->session_id;
+		mvm_tty_mode_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 		mvm_tty_mode_cmd.hdr.dest_port = mvm_handle;
 		mvm_tty_mode_cmd.hdr.token = 0;
 		mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE;
@@ -917,7 +998,7 @@
 	cvs_set_pp_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 						   sizeof(cvs_set_pp_cmd) -
 						   APR_HDR_SIZE);
-	cvs_set_pp_cmd.hdr.src_port = v->session_id;
+	cvs_set_pp_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id);
 	cvs_set_pp_cmd.hdr.dest_port = cvs_handle;
 	cvs_set_pp_cmd.hdr.token = 0;
 	cvs_set_pp_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY;
@@ -975,7 +1056,8 @@
 					      APR_PKT_VER);
 	cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(cvs_set_dtx) - APR_HDR_SIZE);
-	cvs_set_dtx.hdr.src_port = v->session_id;
+	cvs_set_dtx.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvs_set_dtx.hdr.dest_port = cvs_handle;
 	cvs_set_dtx.hdr.token = 0;
 	cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE;
@@ -1028,7 +1110,8 @@
 	mvm_set_cal_media_type.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(mvm_set_cal_media_type) -
 					APR_HDR_SIZE);
-	mvm_set_cal_media_type.hdr.src_port = v->session_id;
+	mvm_set_cal_media_type.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	mvm_set_cal_media_type.hdr.dest_port = mvm_handle;
 	mvm_set_cal_media_type.hdr.token = 0;
 	mvm_set_cal_media_type.hdr.opcode = VSS_IMVM_CMD_SET_CAL_MEDIA_TYPE;
@@ -1084,7 +1167,8 @@
 	cvs_dtmf_rx_detection.hdr.pkt_size =
 				APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_dtmf_rx_detection) - APR_HDR_SIZE);
-	cvs_dtmf_rx_detection.hdr.src_port = v->session_id;
+	cvs_dtmf_rx_detection.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvs_dtmf_rx_detection.hdr.dest_port = cvs_handle;
 	cvs_dtmf_rx_detection.hdr.token = 0;
 	cvs_dtmf_rx_detection.hdr.opcode =
@@ -1130,7 +1214,7 @@
 	}
 }
 
-int voc_enable_dtmf_rx_detection(uint16_t session_id, uint32_t enable)
+int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -1181,7 +1265,8 @@
 	cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 						sizeof(cvs_set_media_cmd) -
 						APR_HDR_SIZE);
-	cvs_set_media_cmd.hdr.src_port = v->session_id;
+	cvs_set_media_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvs_set_media_cmd.hdr.dest_port = cvs_handle;
 	cvs_set_media_cmd.hdr.token = 0;
 	cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE;
@@ -1220,7 +1305,8 @@
 					APR_PKT_VER);
 		cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				      sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE);
-		cvs_set_cdma_rate.hdr.src_port = v->session_id;
+		cvs_set_cdma_rate.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 		cvs_set_cdma_rate.hdr.dest_port = cvs_handle;
 		cvs_set_cdma_rate.hdr.token = 0;
 		cvs_set_cdma_rate.hdr.opcode =
@@ -1257,7 +1343,8 @@
 				APR_PKT_VER);
 		cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				       sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
-		cvs_set_amr_rate.hdr.src_port = v->session_id;
+		cvs_set_amr_rate.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 		cvs_set_amr_rate.hdr.dest_port = cvs_handle;
 		cvs_set_amr_rate.hdr.token = 0;
 		cvs_set_amr_rate.hdr.opcode =
@@ -1298,7 +1385,8 @@
 		cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 						sizeof(cvs_set_amrwb_rate) -
 						APR_HDR_SIZE);
-		cvs_set_amrwb_rate.hdr.src_port = v->session_id;
+		cvs_set_amrwb_rate.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 		cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
 		cvs_set_amrwb_rate.hdr.token = 0;
 		cvs_set_amrwb_rate.hdr.opcode =
@@ -1370,7 +1458,8 @@
 				sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE);
 	pr_debug("send mvm_start_voice_cmd pkt size = %d\n",
 				mvm_start_voice_cmd.pkt_size);
-	mvm_start_voice_cmd.src_port = v->session_id;
+	mvm_start_voice_cmd.src_port =
+				voice_get_idx_for_session(v->session_id);
 	mvm_start_voice_cmd.dest_port = mvm_handle;
 	mvm_start_voice_cmd.token = 0;
 	mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE;
@@ -1420,7 +1509,8 @@
 				sizeof(cvp_disable_cmd) - APR_HDR_SIZE);
 	pr_debug("cvp_disable_cmd pkt size = %d, cvp_handle=%d\n",
 		cvp_disable_cmd.pkt_size, cvp_handle);
-	cvp_disable_cmd.src_port = v->session_id;
+	cvp_disable_cmd.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_disable_cmd.dest_port = cvp_handle;
 	cvp_disable_cmd.token = 0;
 	cvp_disable_cmd.opcode = VSS_IVOCPROC_CMD_DISABLE;
@@ -1499,7 +1589,8 @@
 				sizeof(cvp_setdev_cmd) - APR_HDR_SIZE);
 	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.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_setdev_cmd.hdr.dest_port = cvp_handle;
 	cvp_setdev_cmd.hdr.token = 0;
 	cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE_V2;
@@ -1565,7 +1656,8 @@
 				sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE);
 	pr_debug("send mvm_stop_voice_cmd pkt size = %d\n",
 				mvm_stop_voice_cmd.pkt_size);
-	mvm_stop_voice_cmd.src_port = v->session_id;
+	mvm_stop_voice_cmd.src_port =
+				voice_get_idx_for_session(v->session_id);
 	mvm_stop_voice_cmd.dest_port = mvm_handle;
 	mvm_stop_voice_cmd.token = 0;
 	mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE;
@@ -1625,7 +1717,8 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
-	cvs_reg_cal_cmd.hdr.src_port = v->session_id;
+	cvs_reg_cal_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvs_reg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v);
 	cvs_reg_cal_cmd.hdr.token = 0;
 	cvs_reg_cal_cmd.hdr.opcode =
@@ -1690,7 +1783,8 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
-	cvs_dereg_cal_cmd.hdr.src_port = v->session_id;
+	cvs_dereg_cal_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvs_dereg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v);
 	cvs_dereg_cal_cmd.hdr.token = 0;
 	cvs_dereg_cal_cmd.hdr.opcode =
@@ -1755,7 +1849,8 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_reg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_reg_dev_cfg_cmd) - APR_HDR_SIZE);
-	cvp_reg_dev_cfg_cmd.hdr.src_port = v->session_id;
+	cvp_reg_dev_cfg_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_reg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v);
 	cvp_reg_dev_cfg_cmd.hdr.token = 0;
 	cvp_reg_dev_cfg_cmd.hdr.opcode =
@@ -1817,7 +1912,8 @@
 					APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_dereg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_dereg_dev_cfg_cmd) - APR_HDR_SIZE);
-	cvp_dereg_dev_cfg_cmd.hdr.src_port = v->session_id;
+	cvp_dereg_dev_cfg_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_dereg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v);
 	cvp_dereg_dev_cfg_cmd.hdr.token = 0;
 	cvp_dereg_dev_cfg_cmd.hdr.opcode =
@@ -1883,7 +1979,8 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
-	cvp_reg_cal_cmd.hdr.src_port = v->session_id;
+	cvp_reg_cal_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_reg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
 	cvp_reg_cal_cmd.hdr.token = 0;
 	cvp_reg_cal_cmd.hdr.opcode =
@@ -1948,7 +2045,8 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
-	cvp_dereg_cal_cmd.hdr.src_port = v->session_id;
+	cvp_dereg_cal_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_dereg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
 	cvp_dereg_cal_cmd.hdr.token = 0;
 	cvp_dereg_cal_cmd.hdr.opcode =
@@ -2012,7 +2110,8 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_reg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_reg_vol_cal_cmd) - APR_HDR_SIZE);
-	cvp_reg_vol_cal_cmd.hdr.src_port = v->session_id;
+	cvp_reg_vol_cal_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_reg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
 	cvp_reg_vol_cal_cmd.hdr.token = 0;
 	cvp_reg_vol_cal_cmd.hdr.opcode =
@@ -2081,7 +2180,8 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	cvp_dereg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvp_dereg_vol_cal_cmd) - APR_HDR_SIZE);
-	cvp_dereg_vol_cal_cmd.hdr.src_port = v->session_id;
+	cvp_dereg_vol_cal_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_dereg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
 	cvp_dereg_vol_cal_cmd.hdr.token = 0;
 	cvp_dereg_vol_cal_cmd.hdr.opcode =
@@ -2162,7 +2262,8 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	mvm_map_phys_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(mvm_map_phys_cmd) - APR_HDR_SIZE);
-	mvm_map_phys_cmd.hdr.src_port = v->session_id;
+	mvm_map_phys_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	mvm_map_phys_cmd.hdr.dest_port = voice_get_mvm_handle(v);
 	mvm_map_phys_cmd.hdr.token = token;
 	mvm_map_phys_cmd.hdr.opcode = VSS_IMEMORY_CMD_MAP_PHYSICAL;
@@ -2267,7 +2368,8 @@
 				sizeof(cvp_session_cmd) - APR_HDR_SIZE);
 	pr_debug(" send create cvp session, pkt size = %d\n",
 		cvp_session_cmd.hdr.pkt_size);
-	cvp_session_cmd.hdr.src_port = v->session_id;
+	cvp_session_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_session_cmd.hdr.dest_port = 0;
 	cvp_session_cmd.hdr.token = 0;
 	cvp_session_cmd.hdr.opcode =
@@ -2398,7 +2500,8 @@
 				sizeof(cvp_enable_cmd) - APR_HDR_SIZE);
 	pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n",
 		cvp_enable_cmd.pkt_size, cvp_handle);
-	cvp_enable_cmd.src_port = v->session_id;
+	cvp_enable_cmd.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_enable_cmd.dest_port = cvp_handle;
 	cvp_enable_cmd.token = 0;
 	cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE;
@@ -2446,7 +2549,8 @@
 						APR_PKT_VER);
 	mvm_set_cal_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(mvm_set_cal_network) - APR_HDR_SIZE);
-	mvm_set_cal_network.hdr.src_port = v->session_id;
+	mvm_set_cal_network.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	mvm_set_cal_network.hdr.dest_port = mvm_handle;
 	mvm_set_cal_network.hdr.token = 0;
 	mvm_set_cal_network.hdr.opcode = VSS_IMVM_CMD_SET_CAL_NETWORK;
@@ -2505,7 +2609,8 @@
 						APR_PKT_VER);
 	mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(mvm_set_network) - APR_HDR_SIZE);
-	mvm_set_network.hdr.src_port = v->session_id;
+	mvm_set_network.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	mvm_set_network.hdr.dest_port = mvm_handle;
 	mvm_set_network.hdr.token = 0;
 	mvm_set_network.hdr.opcode = VSS_ICOMMON_CMD_SET_NETWORK;
@@ -2535,7 +2640,8 @@
 	mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 						sizeof(mvm_set_voice_timing) -
 						APR_HDR_SIZE);
-	mvm_set_voice_timing.hdr.src_port = v->session_id;
+	mvm_set_voice_timing.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	mvm_set_voice_timing.hdr.dest_port = mvm_handle;
 	mvm_set_voice_timing.hdr.token = 0;
 	mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
@@ -2593,7 +2699,8 @@
 				sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE);
 	pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n",
 		mvm_a_vocproc_cmd.hdr.pkt_size);
-	mvm_a_vocproc_cmd.hdr.src_port = v->session_id;
+	mvm_a_vocproc_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle;
 	mvm_a_vocproc_cmd.hdr.token = 0;
 	mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC;
@@ -2662,7 +2769,8 @@
 				sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE);
 	pr_debug("mvm_d_vocproc_cmd  pkt size = %d\n",
 		mvm_d_vocproc_cmd.hdr.pkt_size);
-	mvm_d_vocproc_cmd.hdr.src_port = v->session_id;
+	mvm_d_vocproc_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle;
 	mvm_d_vocproc_cmd.hdr.token = 0;
 	mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC;
@@ -2696,7 +2804,8 @@
 				sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE);
 	pr_debug("cvp_destroy_session_cmd pkt size = %d\n",
 		cvp_destroy_session_cmd.pkt_size);
-	cvp_destroy_session_cmd.src_port = v->session_id;
+	cvp_destroy_session_cmd.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_destroy_session_cmd.dest_port = cvp_handle;
 	cvp_destroy_session_cmd.token = 0;
 	cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION;
@@ -2748,7 +2857,8 @@
 						APR_PKT_VER);
 	mem_unmap.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(mem_unmap) - APR_HDR_SIZE);
-	mem_unmap.hdr.src_port = v->session_id;
+	mem_unmap.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	mem_unmap.hdr.dest_port = mvm_handle;
 	mem_unmap.hdr.token = 0;
 	mem_unmap.hdr.opcode = VSS_IMEMORY_CMD_UNMAP;
@@ -2809,7 +2919,8 @@
 	packet_exchange_config_pkt.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(packet_exchange_config_pkt) -
 					 APR_HDR_SIZE);
-	packet_exchange_config_pkt.hdr.src_port = v->session_id;
+	packet_exchange_config_pkt.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	packet_exchange_config_pkt.hdr.dest_port = cvs_handle;
 	packet_exchange_config_pkt.hdr.token = 0;
 	packet_exchange_config_pkt.hdr.opcode =
@@ -2869,7 +2980,8 @@
 						APR_PKT_VER);
 	data_exchange_pkt.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(data_exchange_pkt) - APR_HDR_SIZE);
-	data_exchange_pkt.hdr.src_port = v->session_id;
+	data_exchange_pkt.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	data_exchange_pkt.hdr.dest_port = cvs_handle;
 	data_exchange_pkt.hdr.token = 0;
 	data_exchange_pkt.hdr.opcode = VSS_ISTREAM_CMD_SET_PACKET_EXCHANGE_MODE;
@@ -2916,7 +3028,8 @@
 						APR_PKT_VER);
 	cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
-	cvs_mute_cmd.hdr.src_port = v->session_id;
+	cvs_mute_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvs_mute_cmd.hdr.dest_port = voice_get_cvs_handle(v);
 	cvs_mute_cmd.hdr.token = 0;
 	cvs_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
@@ -2969,7 +3082,8 @@
 						APR_PKT_VER);
 	cvp_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(cvp_mute_cmd) - APR_HDR_SIZE);
-	cvp_mute_cmd.hdr.src_port = v->session_id;
+	cvp_mute_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_mute_cmd.hdr.dest_port = voice_get_cvp_handle(v);
 	cvp_mute_cmd.hdr.token = 0;
 	cvp_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
@@ -3023,7 +3137,8 @@
 						APR_PKT_VER);
 	cvp_vol_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(cvp_vol_cmd) - APR_HDR_SIZE);
-	cvp_vol_cmd.hdr.src_port = v->session_id;
+	cvp_vol_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 	cvp_vol_cmd.hdr.dest_port = cvp_handle;
 	cvp_vol_cmd.hdr.token = 0;
 	cvp_vol_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX;
@@ -3072,7 +3187,8 @@
 					APR_PKT_VER);
 		cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				  sizeof(cvs_start_record) - APR_HDR_SIZE);
-		cvs_start_record.hdr.src_port = v->session_id;
+		cvs_start_record.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 		cvs_start_record.hdr.dest_port = cvs_handle;
 		cvs_start_record.hdr.token = 0;
 		cvs_start_record.hdr.opcode = VSS_IRECORD_CMD_START;
@@ -3157,7 +3273,8 @@
 				  APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 		cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				  sizeof(cvs_stop_record) - APR_HDR_SIZE);
-		cvs_stop_record.src_port = v->session_id;
+		cvs_stop_record.src_port =
+				voice_get_idx_for_session(v->session_id);
 		cvs_stop_record.dest_port = cvs_handle;
 		cvs_stop_record.token = 0;
 		cvs_stop_record.opcode = VSS_IRECORD_CMD_STOP;
@@ -3328,7 +3445,8 @@
 					APR_PKT_VER);
 		cvs_start_playback.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_start_playback) - APR_HDR_SIZE);
-		cvs_start_playback.hdr.src_port = v->session_id;
+		cvs_start_playback.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 		cvs_start_playback.hdr.dest_port = cvs_handle;
 		cvs_start_playback.hdr.token = 0;
 		cvs_start_playback.hdr.opcode = VSS_IPLAYBACK_CMD_START;
@@ -3392,7 +3510,8 @@
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 		cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(cvs_stop_playback) - APR_HDR_SIZE);
-		cvs_stop_playback.src_port = v->session_id;
+		cvs_stop_playback.src_port =
+				voice_get_idx_for_session(v->session_id);
 		cvs_stop_playback.dest_port = cvs_handle;
 		cvs_stop_playback.token = 0;
 
@@ -3463,7 +3582,7 @@
 	return ret;
 }
 
-int voc_disable_cvp(uint16_t session_id)
+int voc_disable_cvp(uint32_t session_id)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3497,7 +3616,7 @@
 	return ret;
 }
 
-int voc_enable_cvp(uint16_t session_id)
+int voc_enable_cvp(uint32_t session_id)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3572,7 +3691,7 @@
 	return ret;
 }
 
-static int voice_set_packet_exchange_mode_and_config(uint16_t session_id,
+static int voice_set_packet_exchange_mode_and_config(uint32_t session_id,
 						 uint32_t mode)
 {
 	struct voice_data *v = voice_get_session(session_id);
@@ -3604,7 +3723,7 @@
 	return -EINVAL;
 }
 
-int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute)
+int voc_set_tx_mute(uint32_t session_id, uint32_t dir, uint32_t mute)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3629,7 +3748,7 @@
 	return ret;
 }
 
-int voc_set_rx_device_mute(uint16_t session_id, uint32_t mute)
+int voc_set_rx_device_mute(uint32_t session_id, uint32_t mute)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3654,7 +3773,7 @@
 	return ret;
 }
 
-int voc_get_rx_device_mute(uint16_t session_id)
+int voc_get_rx_device_mute(uint32_t session_id)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3674,7 +3793,7 @@
 	return ret;
 }
 
-int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode)
+int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3694,7 +3813,7 @@
 	return ret;
 }
 
-uint8_t voc_get_tty_mode(uint16_t session_id)
+uint8_t voc_get_tty_mode(uint32_t session_id)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3714,7 +3833,7 @@
 	return ret;
 }
 
-int voc_set_pp_enable(uint16_t session_id, uint32_t module_id, uint32_t enable)
+int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3741,7 +3860,7 @@
 	return ret;
 }
 
-int voc_get_pp_enable(uint16_t session_id, uint32_t module_id)
+int voc_get_pp_enable(uint32_t session_id, uint32_t module_id)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3760,7 +3879,7 @@
 	return ret;
 }
 
-int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t vol_idx)
+int voc_set_rx_vol_index(uint32_t session_id, uint32_t dir, uint32_t vol_idx)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3785,7 +3904,7 @@
 	return ret;
 }
 
-int voc_set_rxtx_port(uint16_t session_id, uint32_t port_id, uint32_t dev_type)
+int voc_set_rxtx_port(uint32_t session_id, uint32_t port_id, uint32_t dev_type)
 {
 	struct voice_data *v = voice_get_session(session_id);
 
@@ -3809,7 +3928,7 @@
 	return 0;
 }
 
-int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set)
+int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set)
 {
 	struct voice_data *v = voice_get_session(session_id);
 
@@ -3833,7 +3952,7 @@
 	return 0;
 }
 
-uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir)
+uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3856,7 +3975,7 @@
 	return ret;
 }
 
-int voc_end_voice_call(uint16_t session_id)
+int voc_end_voice_call(uint32_t session_id)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3885,7 +4004,7 @@
 	return ret;
 }
 
-int voc_standby_voice_call(uint16_t session_id)
+int voc_standby_voice_call(uint32_t session_id)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	struct apr_hdr mvm_standby_voice_cmd;
@@ -3914,7 +4033,8 @@
 			sizeof(mvm_standby_voice_cmd) - APR_HDR_SIZE);
 		pr_debug("send mvm_standby_voice_cmd pkt size = %d\n",
 			 mvm_standby_voice_cmd.pkt_size);
-		mvm_standby_voice_cmd.src_port = v->session_id;
+		mvm_standby_voice_cmd.src_port =
+				voice_get_idx_for_session(v->session_id);
 		mvm_standby_voice_cmd.dest_port = mvm_handle;
 		mvm_standby_voice_cmd.token = 0;
 		mvm_standby_voice_cmd.opcode = VSS_IMVM_CMD_STANDBY_VOICE;
@@ -3932,7 +4052,7 @@
 	return ret;
 }
 
-int voc_set_lch(uint16_t session_id, enum voice_lch_mode lch_mode)
+int voc_set_lch(uint32_t session_id, enum voice_lch_mode lch_mode)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3975,7 +4095,7 @@
 	return ret;
 }
 
-int voc_resume_voice_call(uint16_t session_id)
+int voc_resume_voice_call(uint32_t session_id)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -3991,7 +4111,7 @@
 	return -EINVAL;
 }
 
-int voc_start_voice_call(uint16_t session_id)
+int voc_start_voice_call(uint32_t session_id)
 {
 	struct voice_data *v = voice_get_session(session_id);
 	int ret = 0;
@@ -4112,7 +4232,7 @@
 	struct common_data *c = NULL;
 	struct voice_data *v = NULL;
 	int i = 0;
-	uint16_t session_id = 0;
+	uint32_t session_id = 0;
 
 	if ((data == NULL) || (priv == NULL)) {
 		pr_err("%s: data or priv is NULL\n", __func__);
@@ -4158,7 +4278,7 @@
 
 	pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port);
 
-	v = voice_get_session(data->dest_port);
+	v = voice_get_session_by_idx(data->dest_port);
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
 
@@ -4250,7 +4370,7 @@
 	struct common_data *c = NULL;
 	struct voice_data *v = NULL;
 	int i = 0;
-	uint16_t session_id = 0;
+	uint32_t session_id = 0;
 
 	if ((data == NULL) || (priv == NULL)) {
 		pr_err("%s: data or priv is NULL\n", __func__);
@@ -4295,7 +4415,7 @@
 		return 0;
 	}
 
-	v = voice_get_session(data->dest_port);
+	v = voice_get_session_by_idx(data->dest_port);
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
 
@@ -4397,7 +4517,8 @@
 			APR_PKT_SIZE(APR_HDR_SIZE,
 			sizeof(send_enc_buf_consumed_cmd) - APR_HDR_SIZE);
 
-		send_enc_buf_consumed_cmd.hdr.src_port = v->session_id;
+		send_enc_buf_consumed_cmd.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 		send_enc_buf_consumed_cmd.hdr.dest_port = cvs_handle;
 		send_enc_buf_consumed_cmd.hdr.token = 0;
 		send_enc_buf_consumed_cmd.hdr.opcode =
@@ -4443,7 +4564,8 @@
 		send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(send_dec_buf) - APR_HDR_SIZE);
 
-		send_dec_buf.hdr.src_port = v->session_id;
+		send_dec_buf.hdr.src_port =
+				voice_get_idx_for_session(v->session_id);
 		send_dec_buf.hdr.dest_port = cvs_handle;
 		send_dec_buf.hdr.token = 0;
 		send_dec_buf.hdr.opcode =
@@ -4524,7 +4646,7 @@
 	struct common_data *c = NULL;
 	struct voice_data *v = NULL;
 	int i = 0;
-	uint16_t session_id = 0;
+	uint32_t session_id = 0;
 
 	if ((data == NULL) || (priv == NULL)) {
 		pr_err("%s: data or priv is NULL\n", __func__);
@@ -4565,7 +4687,7 @@
 		return 0;
 	}
 
-	v = voice_get_session(data->dest_port);
+	v = voice_get_session_by_idx(data->dest_port);
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
 
@@ -4778,8 +4900,10 @@
 
 	mutex_init(&common.common_lock);
 
+	/* Initialize session id with vsid */
+	init_session_id();
+
 	for (i = 0; i < MAX_VOC_SESSIONS; i++) {
-		common.voice[i].session_id = SESSION_ID_BASE + i;
 
 		/* initialize dev_rx and dev_tx */
 		common.voice[i].dev_rx.volume = common.default_vol_val;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index 386634b..5a16115 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -1258,7 +1258,7 @@
 
 	struct voice_dev_route_state voc_route_state;
 
-	u16 session_id;
+	u32 session_id;
 
 	struct incall_rec_info rec_info;
 
@@ -1274,7 +1274,6 @@
 };
 
 #define MAX_VOC_SESSIONS 4
-#define SESSION_ID_BASE 0xFFF0
 
 struct common_data {
 	/* these default values are for all devices */
@@ -1337,34 +1336,39 @@
 #define VOLTE_SESSION_NAME  "VoLTE session"
 #define VOICE2_SESSION_NAME "Voice2 session"
 
-#define VOICE2_SESSION_VSID "10DC1000"
+#define VOICE2_SESSION_VSID_STR "10DC1000"
+#define VOICE_SESSION_VSID  0x10C01000
+#define VOICE2_SESSION_VSID 0x10DC1000
+#define VOLTE_SESSION_VSID  0x10C02000
+#define VOIP_SESSION_VSID   0x10004000
+#define ALL_SESSION_VSID    0xFFFFFFFF
 
 /* called  by alsa driver */
-int voc_set_pp_enable(uint16_t session_id, uint32_t module_id,
+int voc_set_pp_enable(uint32_t session_id, uint32_t module_id,
 		      uint32_t enable);
-int voc_get_pp_enable(uint16_t session_id, uint32_t module_id);
-uint8_t voc_get_tty_mode(uint16_t session_id);
-int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode);
-int voc_start_voice_call(uint16_t session_id);
-int voc_end_voice_call(uint16_t session_id);
-int voc_standby_voice_call(uint16_t session_id);
-int voc_resume_voice_call(uint16_t session_id);
-int voc_set_lch(uint16_t session_id, enum voice_lch_mode lch_mode);
-int voc_set_rxtx_port(uint16_t session_id,
+int voc_get_pp_enable(uint32_t session_id, uint32_t module_id);
+uint8_t voc_get_tty_mode(uint32_t session_id);
+int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode);
+int voc_start_voice_call(uint32_t session_id);
+int voc_end_voice_call(uint32_t session_id);
+int voc_standby_voice_call(uint32_t session_id);
+int voc_resume_voice_call(uint32_t session_id);
+int voc_set_lch(uint32_t session_id, enum voice_lch_mode lch_mode);
+int voc_set_rxtx_port(uint32_t session_id,
 		      uint32_t dev_port_id,
 		      uint32_t dev_type);
-int voc_set_rx_vol_index(uint16_t session_id, uint32_t dir, uint32_t voc_idx);
-int voc_set_tx_mute(uint16_t session_id, uint32_t dir, uint32_t mute);
-int voc_set_rx_device_mute(uint16_t session_id, uint32_t mute);
-int voc_get_rx_device_mute(uint16_t session_id);
-int voc_disable_cvp(uint16_t session_id);
-int voc_enable_cvp(uint16_t session_id);
-int voc_set_route_flag(uint16_t session_id, uint8_t path_dir, uint8_t set);
-uint8_t voc_get_route_flag(uint16_t session_id, uint8_t path_dir);
-int voc_enable_dtmf_rx_detection(uint16_t session_id, uint32_t enable);
+int voc_set_rx_vol_index(uint32_t session_id, uint32_t dir, uint32_t voc_idx);
+int voc_set_tx_mute(uint32_t session_id, uint32_t dir, uint32_t mute);
+int voc_set_rx_device_mute(uint32_t session_id, uint32_t mute);
+int voc_get_rx_device_mute(uint32_t session_id);
+int voc_disable_cvp(uint32_t session_id);
+int voc_enable_cvp(uint32_t session_id);
+int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set);
+uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir);
+int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable);
 void voc_disable_dtmf_det_on_active_sessions(void);
 
-uint16_t voc_get_session_id(char *name);
+uint32_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);