Merge "ARM: dts: msm: enable HSIC interrupt as wake up capable for 8926"
diff --git a/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt b/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
index f57d928..917ea75 100644
--- a/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
+++ b/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
@@ -20,6 +20,7 @@
 		"pc_no_xo_shutdown" - Power Collapse with no XO shutdown
 - qcom,l2: The state of L2 cache. Values are:
 		"l2_cache_pc" - L2 cache in power collapse
+		"l2_cache_pc_no_rpm" - L2 cache in power collapse. This mode wouldn't inform the RPM
 		"l2_cache_retenetion" - L2 cache in retention
 		"l2_cache_gdhs" - L2 cache in GDHS
 		"l2_cache_active" - L2 cache in active mode
diff --git a/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt b/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
index c7c6415..cf21158 100644
--- a/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
+++ b/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
@@ -14,6 +14,7 @@
 - qcom,needs-alt-core-clk : boolean to enable the secondary core clock for
   access to the IOMMU configuration registers
 - Bus scaling properties: See msm_bus.txt
+- qcom,msm-enable-remote-spinlock : boolean to enable use of remote spinlock
 
 - List of sub nodes, one for each of the translation context banks supported.
     Required properties for each sub-node:
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index 7ed6ff9..81448d2 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -88,6 +88,9 @@
 					necessary software workarounds.
 - qcom,ovp-monitor-en			The ovp is enabled on hw by default. If this flag is
 					set, the charger ovp status is monitored in software.
+- qcom,ext-ovp-present			Indicates if an external OVP exists which reduces the
+					overall input resistance of the charge path.
+
 Sub node required structure:
 - A qcom,chg node must be a child of an SPMI node that has specified
 	the spmi-dev-container property. Each subnode reflects
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index aa37edc..adcf168 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -222,7 +222,8 @@
 	default DRAM_BASE if REMAP_VECTORS_TO_RAM
 	default 0x00000000
 	help
-	  The base address of exception vectors.
+	  The base address of exception vectors.  This must be two pages
+	  in size.
 
 config ARM_PATCH_PHYS_VIRT
 	bool "Patch physical to virtual translations at runtime" if EMBEDDED
diff --git a/arch/arm/boot/dts/msm-iommu-v0.dtsi b/arch/arm/boot/dts/msm-iommu-v0.dtsi
index 8ab9985..8891935 100644
--- a/arch/arm/boot/dts/msm-iommu-v0.dtsi
+++ b/arch/arm/boot/dts/msm-iommu-v0.dtsi
@@ -33,6 +33,7 @@
 		qcom,msm-bus,vectors-KBps =
 				<11 512 0 0>,
 				<11 512 0 1000>;
+		qcom,msm-enable-remote-spinlock;
 		status = "disabled";
 
 		lpass_q6_fw: qcom,iommu-ctx@fd000000 {
diff --git a/arch/arm/boot/dts/msm-pm8110.dtsi b/arch/arm/boot/dts/msm-pm8110.dtsi
index 6969940..8523524 100644
--- a/arch/arm/boot/dts/msm-pm8110.dtsi
+++ b/arch/arm/boot/dts/msm-pm8110.dtsi
@@ -113,7 +113,7 @@
 							"vdd-loop";
 			};
 
-			qcom,bat-if@1200 {
+			pm8110_chg_batif: qcom,bat-if@1200 {
 				status = "disabled";
 				reg = <0x1200 0x100>;
 				interrupts =	<0x0 0x12 0x0>,
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index ba1bf08..5e0abea 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -131,7 +131,7 @@
 							"vdd-loop";
 			};
 
-			qcom,bat-if@1200 {
+			pm8226_chg_batif: qcom,bat-if@1200 {
 				status = "disabled";
 				reg = <0x1200 0x100>;
 				interrupts =	<0x0 0x12 0x0>,
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 98d2f5e..8a239cc 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -250,7 +250,7 @@
 						"vdd-loop";
 		};
 
-		qcom,bat-if@1200 {
+		pm8941_chg_batif: qcom,bat-if@1200 {
 			status = "disabled";
 			reg = <0x1200 0x100>;
 			interrupts =	<0x0 0x12 0x0>,
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index 838592c..23a2158 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -491,6 +491,10 @@
 	otg-parent-supply = <&pm8226_chg_boost>;
 };
 
+&pm8226_chg_batif {
+	regulator-name = "batfet";
+};
+
 &pm8226_chg_otg {
 	regulator-name = "8226_smbbp_otg";
 };
diff --git a/arch/arm/boot/dts/msm8226-v1-pm.dtsi b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
index 1530074..02feec8 100644
--- a/arch/arm/boot/dts/msm8226-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
@@ -99,6 +99,9 @@
 		qcom,saw2-spm-cmd-pc = [00 32 b0 10 e0 d0 6b c0 42 f0
 				11 07 01 b0 50 4e 02 02 c0 d0 12 e0 6b 02 32
 				50 f0 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
+		qcom,saw2-spm-cmd-pc-no-rpm = [00 32 b0 10 e0 d0 6b c0 42 f0
+				11 03 01 b0 50 4e 02 02 c0 d0 12 e0 6b 02 32
+				50 f0 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
 		qcom,L2-spm-is-apcs-master;
 	};
 
@@ -113,8 +116,8 @@
 			qcom,mode = "wfi";
 			qcom,l2 = "l2_cache_active";
 			qcom,latency-us = <1>;
-			qcom,ss-power = <784>;
-			qcom,energy-overhead = <190000>;
+			qcom,ss-power = <530>;
+			qcom,energy-overhead = <52800>;
 			qcom,time-overhead = <100>;
 		};
 
@@ -122,30 +125,30 @@
 			reg = <0x1>;
 			qcom,mode = "standalone_pc";
 			qcom,l2 = "l2_cache_active";
-			qcom,latency-us = <3000>;
-			qcom,ss-power = <725>;
-			qcom,energy-overhead = <99500>;
-			qcom,time-overhead = <3130>;
+			qcom,latency-us = <500>;
+			qcom,ss-power = <410>;
+			qcom,energy-overhead = <603400>;
+			qcom,time-overhead = <1200>;
 		};
 
 		qcom,lpm-level@2 {
 			reg = <0x2>;
 			qcom,mode = "pc";
-			qcom,l2 = "l2_cache_retention";
-			qcom,latency-us = <20000>;
-			qcom,ss-power = <138>;
-			qcom,energy-overhead = <1208400>;
-			qcom,time-overhead = <9200>;
+			qcom,l2 = "l2_cache_pc_no_rpm";
+			qcom,latency-us = <1000>;
+			qcom,ss-power = <315>;
+			qcom,energy-overhead = <1027150>;
+			qcom,time-overhead = <2400>;
 		};
 
 		qcom,lpm-level@3 {
 			reg = <0x3>;
 			qcom,mode = "pc";
 			qcom,l2 = "l2_cache_pc";
-			qcom,latency-us = <30000>;
-			qcom,ss-power = <110>;
-			qcom,energy-overhead = <1250300>;
-			qcom,time-overhead = <9500>;
+			qcom,latency-us = <11000>;
+			qcom,ss-power = <315>;
+			qcom,energy-overhead = <1027150>;
+			qcom,time-overhead = <2400>;
 		};
 	};
 
diff --git a/arch/arm/boot/dts/msm8226-v2-pm.dtsi b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
index 9104cba..31d5a8f 100644
--- a/arch/arm/boot/dts/msm8226-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
@@ -98,6 +98,9 @@
 		qcom,saw2-spm-cmd-ret = [00 03 00 0f];
 		qcom,saw2-spm-cmd-gdhs = [00 20 32 6b c0 e0 d0 42 07 50
 				4e 02 02 d0 e0 c0 22 6b 02 32 50 0f];
+		qcom,saw2-spm-cmd-pc-no-rpm = [00 32 b0 10 e0 d0 6b c0 42 f0
+				11 03 01 b0 50 4e 02 02 c0 d0 12 e0 6b 02 32
+				50 f0 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
 		qcom,saw2-spm-cmd-pc = [00 32 b0 10 e0 d0 6b c0 42 f0
 				11 07 01 b0 50 4e 02 02 c0 d0 12 e0 6b 02 32
 				50 f0 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
@@ -115,8 +118,8 @@
 			qcom,mode = "wfi";
 			qcom,l2 = "l2_cache_active";
 			qcom,latency-us = <1>;
-			qcom,ss-power = <784>;
-			qcom,energy-overhead = <190000>;
+			qcom,ss-power = <530>;
+			qcom,energy-overhead = <52800>;
 			qcom,time-overhead = <100>;
 		};
 
@@ -124,30 +127,40 @@
 			reg = <0x1>;
 			qcom,mode = "standalone_pc";
 			qcom,l2 = "l2_cache_active";
-			qcom,latency-us = <3000>;
-			qcom,ss-power = <725>;
-			qcom,energy-overhead = <99500>;
-			qcom,time-overhead = <3130>;
+			qcom,latency-us = <500>;
+			qcom,ss-power = <410>;
+			qcom,energy-overhead = <603400>;
+			qcom,time-overhead = <1200>;
 		};
 
 		qcom,lpm-level@2 {
 			reg = <0x2>;
 			qcom,mode = "pc";
 			qcom,l2 = "l2_cache_gdhs";
-			qcom,latency-us = <20000>;
-			qcom,ss-power = <138>;
-			qcom,energy-overhead = <1208400>;
-			qcom,time-overhead = <9200>;
+			qcom,latency-us = <10700>;
+			qcom,ss-power = <372>;
+			qcom,energy-overhead = <738750>;
+			qcom,time-overhead = <1410>;
 		};
 
 		qcom,lpm-level@3 {
 			reg = <0x3>;
 			qcom,mode = "pc";
+			qcom,l2 = "l2_cache_pc_no_rpm";
+			qcom,latency-us = <1000>;
+			qcom,ss-power = <315>;
+			qcom,energy-overhead = <1027150>;
+			qcom,time-overhead = <2400>;
+		};
+
+		qcom,lpm-level@4 {
+			reg = <0x4>;
+			qcom,mode = "pc";
 			qcom,l2 = "l2_cache_pc";
-			qcom,latency-us = <30000>;
-			qcom,ss-power = <110>;
-			qcom,energy-overhead = <1250300>;
-			qcom,time-overhead = <9500>;
+			qcom,latency-us = <11000>;
+			qcom,ss-power = <315>;
+			qcom,energy-overhead = <1027150>;
+			qcom,time-overhead = <2400>;
 		};
 	};
 
diff --git a/arch/arm/boot/dts/msm8610-bus.dtsi b/arch/arm/boot/dts/msm8610-bus.dtsi
index 6b72e66..c6e81d8 100644
--- a/arch/arm/boot/dts/msm8610-bus.dtsi
+++ b/arch/arm/boot/dts/msm8610-bus.dtsi
@@ -56,8 +56,8 @@
 			qcom,ws = <10000>;
 			qcom,qport = <2>;
 			qcom,mas-hw-id = <11>;
-			qcom,prio1 = <2>;
-			qcom,prio0 = <2>;
+			qcom,prio1 = <3>;
+			qcom,prio0 = <3>;
 		};
 
 		mas-mdpe {
@@ -71,8 +71,8 @@
 			qcom,ws = <10000>;
 			qcom,qport = <7>;
 			qcom,mas-hw-id = <11>;
-			qcom,prio1 = <2>;
-			qcom,prio0 = <2>;
+			qcom,prio1 = <1>;
+			qcom,prio0 = <1>;
 		};
 
 		fab-bimc {
@@ -913,7 +913,7 @@
 		qcom,fabclk-dual = "mem_clk";
 		qcom,fabclk-active = "mem_a_clk";
 		qcom,ntieredslaves = <0>;
-		qcom,qos-freq = <4800>;
+		qcom,qos-freq = <19200>;
 		qcom,hw-sel = "BIMC";
 		qcom,rpm-en;
 
@@ -930,13 +930,19 @@
 			qcom,masterp = <0>;
 			qcom,tier = <2>;
 			qcom,hw-sel = "BIMC";
-			qcom,mode = "Fixed";
+			qcom,mode = "Limiter";
 			qcom,qport = <0>;
 			qcom,ws = <10000>;
 			qcom,mas-hw-id = <0>;
 			qcom,prio-rd = <0>;
 			qcom,prio-wr = <0>;
 			qcom,prio-lvl = <0>;
+			qcom,mode-thresh = "Fixed";
+			qcom,thresh = <800000>;
+			qcom,dual-conf;
+			qcom,bimc,bw = <300000>;
+			qcom,bimc,gp = <5>;
+			qcom,bimc,thmp = <50>;
 		};
 
 		mas-mss-proc {
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index eb69678..f97d991 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -391,3 +391,7 @@
 		};
 	};
 };
+
+&pm8110_chg_batif {
+	regulator-name = "batfet";
+};
diff --git a/arch/arm/boot/dts/msm8610-v1-pm.dtsi b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
index 4a2de1c..e560447 100644
--- a/arch/arm/boot/dts/msm8610-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
@@ -113,8 +113,8 @@
 			qcom,mode = "wfi";
 			qcom,l2 = "l2_cache_active";
 			qcom,latency-us = <1>;
-			qcom,ss-power = <784>;
-			qcom,energy-overhead = <190000>;
+			qcom,ss-power = <530>;
+			qcom,energy-overhead = <52800>;
 			qcom,time-overhead = <100>;
 		};
 
@@ -122,30 +122,30 @@
 			reg = <0x1>;
 			qcom,mode = "standalone_pc";
 			qcom,l2 = "l2_cache_active";
-			qcom,latency-us = <3000>;
-			qcom,ss-power = <725>;
-			qcom,energy-overhead = <99500>;
-			qcom,time-overhead = <3130>;
+			qcom,latency-us = <500>;
+			qcom,ss-power = <410>;
+			qcom,energy-overhead = <603400>;
+			qcom,time-overhead = <1200>;
 		};
 
 		qcom,lpm-level@2 {
 			reg = <0x2>;
 			qcom,mode = "pc";
 			qcom,l2 = "l2_cache_retention";
-			qcom,latency-us = <20000>;
-			qcom,ss-power = <138>;
-			qcom,energy-overhead = <1208400>;
-			qcom,time-overhead = <9200>;
+			qcom,latency-us = <520>;
+			qcom,ss-power = <460>;
+			qcom,energy-overhead = <704900>;
+			qcom,time-overhead = <1300>;
 		};
 
 		qcom,lpm-level@3 {
 			reg = <0x3>;
 			qcom,mode = "pc";
 			qcom,l2 = "l2_cache_pc";
-			qcom,latency-us = <30000>;
-			qcom,ss-power = <110>;
-			qcom,energy-overhead = <1250300>;
-			qcom,time-overhead = <9500>;
+			qcom,latency-us = <11700>;
+			qcom,ss-power = <315>;
+			qcom,energy-overhead = <1027150>;
+			qcom,time-overhead = <2400>;
 		};
 	};
 
diff --git a/arch/arm/boot/dts/msm8610-v2-pm.dtsi b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
index 079f0b1..72509c1 100644
--- a/arch/arm/boot/dts/msm8610-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
@@ -115,8 +115,8 @@
 			qcom,mode = "wfi";
 			qcom,l2 = "l2_cache_active";
 			qcom,latency-us = <1>;
-			qcom,ss-power = <784>;
-			qcom,energy-overhead = <190000>;
+			qcom,ss-power = <530>;
+			qcom,energy-overhead = <52800>;
 			qcom,time-overhead = <100>;
 		};
 
@@ -124,30 +124,30 @@
 			reg = <0x1>;
 			qcom,mode = "standalone_pc";
 			qcom,l2 = "l2_cache_active";
-			qcom,latency-us = <3000>;
-			qcom,ss-power = <725>;
-			qcom,energy-overhead = <99500>;
-			qcom,time-overhead = <3130>;
+			qcom,latency-us = <500>;
+			qcom,ss-power = <410>;
+			qcom,energy-overhead = <603400>;
+			qcom,time-overhead = <1200>;
 		};
 
 		qcom,lpm-level@2 {
 			reg = <0x2>;
 			qcom,mode = "pc";
 			qcom,l2 = "l2_cache_gdhs";
-			qcom,latency-us = <20000>;
-			qcom,ss-power = <138>;
-			qcom,energy-overhead = <1208400>;
-			qcom,time-overhead = <9200>;
+			qcom,latency-us = <10700>;
+			qcom,ss-power = <325>;
+			qcom,energy-overhead = <441250>;
+			qcom,time-overhead = <1020>;
 		};
 
 		qcom,lpm-level@3 {
 			reg = <0x3>;
 			qcom,mode = "pc";
 			qcom,l2 = "l2_cache_pc";
-			qcom,latency-us = <30000>;
-			qcom,ss-power = <110>;
-			qcom,energy-overhead = <1250300>;
-			qcom,time-overhead = <9500>;
+			qcom,latency-us = <11700>;
+			qcom,ss-power = <315>;
+			qcom,energy-overhead = <1027150>;
+			qcom,time-overhead = <2400>;
 		};
 	};
 
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
index 9cbd45c..c84dfe5 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-fluid.dtsi
@@ -78,6 +78,7 @@
 		qcom,mount-angle = <270>;
 		qcom,sensor-name = "imx135";
 		qcom,actuator-src = <&actuator1>;
+		qcom,led-flash-src = <&led_flash0>;
 		cam_vdig-supply = <&pm8941_l3>;
 		cam_vana-supply = <&pm8941_l17>;
 		cam_vio-supply = <&pm8941_lvs3>;
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
index 68af4a6..02d2288 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
@@ -78,6 +78,7 @@
 		qcom,mount-angle = <90>;
 		qcom,sensor-name = "imx135";
 		qcom,actuator-src = <&actuator1>;
+		qcom,led-flash-src = <&led_flash0>;
 		cam_vdig-supply = <&pm8941_l3>;
 		cam_vana-supply = <&pm8941_l17>;
 		cam_vio-supply = <&pm8941_lvs3>;
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index a88a709..344c26f 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -560,6 +560,10 @@
 	regulator-name = "8941_smbb_boost";
 };
 
+&pm8941_chg_batif  {
+	regulator-name = "batfet";
+};
+
 &pm8941_chg_otg {
 	regulator-name = "8941_smbb_otg";
 };
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
index cc4b6ed..811b2ef 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
@@ -90,6 +90,10 @@
 	regulator-name = "8941_smbb_boost";
 };
 
+&pm8941_chg_batif {
+	regulator-name = "batfet";
+};
+
 &pm8941_chg_otg {
 	regulator-name = "8941_smbb_otg";
 };
diff --git a/arch/arm/boot/dts/msm8974pro-ion.dtsi b/arch/arm/boot/dts/msm8974pro-ion.dtsi
index 7faee21..4c427bf 100644
--- a/arch/arm/boot/dts/msm8974pro-ion.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ion.dtsi
@@ -17,7 +17,7 @@
 			compatible = "qcom,msm-ion-reserve";
 			reg = <23>;
 			qcom,heap-align = <0x1000>;
-			qcom,memory-fixed = <0x05400000 0x2700000>;
+			qcom,memory-fixed = <0x05a00000 0x2100000>;
 		};
 
 		qcom,ion-heap@26 { /* MODEM HEAP */
diff --git a/arch/arm/boot/dts/msm8974pro.dtsi b/arch/arm/boot/dts/msm8974pro.dtsi
index 86f0058..f45d75e 100644
--- a/arch/arm/boot/dts/msm8974pro.dtsi
+++ b/arch/arm/boot/dts/msm8974pro.dtsi
@@ -46,6 +46,8 @@
 	/* Updated chip ID */
 	qcom,chipid = <0x03030002>;
 
+	qcom,initial-pwrlevel = <6>;
+
 	/* Updated bus bandwidth requirements */
 	qcom,msm-bus,vectors-KBps =
 		/* Off */
@@ -69,41 +71,69 @@
 
                qcom,gpu-pwrlevel@0 {
                        reg = <0>;
-                       qcom,gpu-freq = <550000000>;
+                       qcom,gpu-freq = <578000000>;
                        qcom,bus-freq = <5>;
                        qcom,io-fraction = <33>;
                };
 
-               qcom,gpu-pwrlevel@1 {
-                       reg = <1>;
-                       qcom,gpu-freq = <320000000>;
+		qcom,gpu-pwrlevel@1 {
+			reg = <1>;
+			qcom,gpu-freq = <462400000>;
+			qcom,bus-freq = <4>;
+			qcom,io-fraction = <33>;
+		};
+
+		qcom,gpu-pwrlevel@2 {
+			reg = <2>;
+			qcom,gpu-freq = <462400000>;
+			qcom,bus-freq = <3>;
+			qcom,io-fraction = <66>;
+		};
+
+		qcom,gpu-pwrlevel@3 {
+			reg = <3>;
+			qcom,gpu-freq = <389000000>;
+			qcom,bus-freq = <4>;
+			qcom,io-fraction = <66>;
+		};
+
+		qcom,gpu-pwrlevel@4 {
+			reg = <4>;
+			qcom,gpu-freq = <389000000>;
+			qcom,bus-freq = <3>;
+			qcom,io-fraction = <66>;
+		};
+
+               qcom,gpu-pwrlevel@5 {
+                       reg = <5>;
+                       qcom,gpu-freq = <330000000>;
                        qcom,bus-freq = <4>;
                        qcom,io-fraction = <66>;
                };
 
-               qcom,gpu-pwrlevel@2 {
-                       reg = <2>;
-                       qcom,gpu-freq = <320000000>;
+               qcom,gpu-pwrlevel@6 {
+                       reg = <6>;
+                       qcom,gpu-freq = <330000000>;
                        qcom,bus-freq = <3>;
                        qcom,io-fraction = <66>;
                };
 
-               qcom,gpu-pwrlevel@3 {
-                       reg = <3>;
+               qcom,gpu-pwrlevel@7 {
+                       reg = <7>;
                        qcom,gpu-freq = <200000000>;
                        qcom,bus-freq = <2>;
                        qcom,io-fraction = <100>;
                };
 
-               qcom,gpu-pwrlevel@4 {
-                       reg = <4>;
+               qcom,gpu-pwrlevel@8 {
+                       reg = <8>;
                        qcom,gpu-freq = <200000000>;
                        qcom,bus-freq = <1>;
                        qcom,io-fraction = <100>;
                };
 
-               qcom,gpu-pwrlevel@5 {
-                       reg = <5>;
+               qcom,gpu-pwrlevel@9 {
+                       reg = <9>;
                        qcom,gpu-freq = <27000000>;
                        qcom,bus-freq = <0>;
                        qcom,io-fraction = <0>;
@@ -203,5 +233,6 @@
 };
 
 &memory_hole {
-	qcom,memblock-remove = <0x05400000 0xab00000>; /* Address and size of the hole */
+	qcom,memblock-remove = <0x05a00000 0x7800000
+				0x0fa00000 0x500000>; /* Address and size of the hole */
 };
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 329fcec..fb05a08 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -340,6 +340,7 @@
 CONFIG_MT9M114=y
 CONFIG_OV2720=y
 CONFIG_IMX135=y
+CONFIG_IMX132=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_EEPROM=y
 CONFIG_MSM_CPP=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 812faf6..b26a028 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -348,6 +348,7 @@
 CONFIG_MT9M114=y
 CONFIG_OV2720=y
 CONFIG_IMX135=y
+CONFIG_IMX132=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_EEPROM=y
 CONFIG_MSM_CPP=y
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 38050b1..56211f2 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -130,4 +130,10 @@
 extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
 
+#ifdef CONFIG_MMU
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+int arch_setup_additional_pages(struct linux_binprm *, int);
+#endif
+
 #endif
diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h
index febe495..15cb035 100644
--- a/arch/arm/include/asm/mach/irq.h
+++ b/arch/arm/include/asm/mach/irq.h
@@ -17,7 +17,7 @@
 /*
  * This is internal.  Do not use it.
  */
-extern void init_FIQ(void);
+extern void init_FIQ(int);
 extern int show_fiq_list(struct seq_file *, int);
 
 #ifdef CONFIG_MULTI_IRQ_HANDLER
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index b8e580a..cf0c81f 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -9,6 +9,7 @@
 	raw_spinlock_t id_lock;
 #endif
 	unsigned int kvm_seq;
+	unsigned long	sigpage;
 } mm_context_t;
 
 #ifdef CONFIG_CPU_HAS_ASID
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index afc1ca7..673205e 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -151,7 +151,9 @@
 #define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, const void *from);
 
+#ifdef CONFIG_KUSER_HELPERS
 #define __HAVE_ARCH_GATE_AREA 1
+#endif
 
 #ifdef CONFIG_ARM_LPAE
 #include <asm/pgtable-3level-types.h>
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 67d6443..2eb0c2c 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -58,7 +58,7 @@
 	struct cpu_context_save	cpu_context;	/* cpu context */
 	__u32			syscall;	/* syscall number */
 	__u8			used_cp[16];	/* thread used copro */
-	unsigned long		tp_value;
+	unsigned long		tp_value[2];	/* TLS registers */
 	struct crunch_state	crunchstate;
 	union fp_state		fpstate __attribute__((aligned(8)));
 	union vfp_state		vfpstate;
diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
index 73409e6..83259b8 100644
--- a/arch/arm/include/asm/tls.h
+++ b/arch/arm/include/asm/tls.h
@@ -2,27 +2,30 @@
 #define __ASMARM_TLS_H
 
 #ifdef __ASSEMBLY__
-	.macro set_tls_none, tp, tmp1, tmp2
+#include <asm/asm-offsets.h>
+	.macro switch_tls_none, base, tp, tpuser, tmp1, tmp2
 	.endm
 
-	.macro set_tls_v6k, tp, tmp1, tmp2
+	.macro switch_tls_v6k, base, tp, tpuser, tmp1, tmp2
+	mrc	p15, 0, \tmp2, c13, c0, 2	@ get the user r/w register
 	mcr	p15, 0, \tp, c13, c0, 3		@ set TLS register
-	mov	\tmp1, #0
-	mcr	p15, 0, \tmp1, c13, c0, 2	@ clear user r/w TLS register
+	mcr	p15, 0, \tpuser, c13, c0, 2	@ and the user r/w register
+	str	\tmp2, [\base, #TI_TP_VALUE + 4] @ save it
 	.endm
 
-	.macro set_tls_v6, tp, tmp1, tmp2
+	.macro switch_tls_v6, base, tp, tpuser, tmp1, tmp2
 	ldr	\tmp1, =elf_hwcap
 	ldr	\tmp1, [\tmp1, #0]
 	mov	\tmp2, #0xffff0fff
 	tst	\tmp1, #HWCAP_TLS		@ hardware TLS available?
-	mcrne	p15, 0, \tp, c13, c0, 3		@ yes, set TLS register
-	movne	\tmp1, #0
-	mcrne	p15, 0, \tmp1, c13, c0, 2	@ clear user r/w TLS register
 	streq	\tp, [\tmp2, #-15]		@ set TLS value at 0xffff0ff0
+	mrcne	p15, 0, \tmp2, c13, c0, 2	@ get the user r/w register
+	mcrne	p15, 0, \tp, c13, c0, 3		@ yes, set TLS register
+	mcrne	p15, 0, \tpuser, c13, c0, 2	@ set user r/w register
+	strne	\tmp2, [\base, #TI_TP_VALUE + 4] @ save it
 	.endm
 
-	.macro set_tls_software, tp, tmp1, tmp2
+	.macro switch_tls_software, base, tp, tpuser, tmp1, tmp2
 	mov	\tmp1, #0xffff0fff
 	str	\tp, [\tmp1, #-15]		@ set TLS value at 0xffff0ff0
 	.endm
@@ -31,19 +34,30 @@
 #ifdef CONFIG_TLS_REG_EMUL
 #define tls_emu		1
 #define has_tls_reg		1
-#define set_tls		set_tls_none
+#define switch_tls	switch_tls_none
 #elif defined(CONFIG_CPU_V6)
 #define tls_emu		0
 #define has_tls_reg		(elf_hwcap & HWCAP_TLS)
-#define set_tls		set_tls_v6
+#define switch_tls	switch_tls_v6
 #elif defined(CONFIG_CPU_32v6K)
 #define tls_emu		0
 #define has_tls_reg		1
-#define set_tls		set_tls_v6k
+#define switch_tls	switch_tls_v6k
 #else
 #define tls_emu		0
 #define has_tls_reg		0
-#define set_tls		set_tls_software
+#define switch_tls	switch_tls_software
 #endif
 
+#ifndef __ASSEMBLY__
+static inline unsigned long get_tpuser(void)
+{
+	unsigned long reg = 0;
+
+	if (has_tls_reg && !tls_emu)
+		__asm__("mrc p15, 0, %0, c13, c0, 2" : "=r" (reg));
+
+	return reg;
+}
+#endif
 #endif	/* __ASMARM_TLS_H */
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 9f52940..317400a 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -698,15 +698,16 @@
  UNWIND(.fnstart	)
  UNWIND(.cantunwind	)
 	add	ip, r1, #TI_CPU_SAVE
-	ldr	r3, [r2, #TI_TP_VALUE]
  ARM(	stmia	ip!, {r4 - sl, fp, sp, lr} )	@ Store most regs on stack
  THUMB(	stmia	ip!, {r4 - sl, fp}	   )	@ Store most regs on stack
  THUMB(	str	sp, [ip], #4		   )
  THUMB(	str	lr, [ip], #4		   )
+	ldr	r4, [r2, #TI_TP_VALUE]
+	ldr	r5, [r2, #TI_TP_VALUE + 4]
 #ifdef CONFIG_CPU_USE_DOMAINS
 	ldr	r6, [r2, #TI_CPU_DOMAIN]
 #endif
-	set_tls	r3, r4, r5
+	switch_tls r1, r4, r5, r3, r7
 #if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
 	ldr	r7, [r2, #TI_TASK]
 	ldr	r8, =__stack_chk_guard
@@ -754,6 +755,18 @@
 #endif
 	.endm
 
+	.macro	kuser_pad, sym, size
+	.if	(. - \sym) & 3
+	.rept	4 - (. - \sym) & 3
+	.byte	0
+	.endr
+	.endif
+	.rept	(\size - (. - \sym)) / 4
+	.word	0xe7fddef1
+	.endr
+	.endm
+
+#ifdef CONFIG_KUSER_HELPERS
 	.align	5
 	.globl	__kuser_helper_start
 __kuser_helper_start:
@@ -935,18 +948,13 @@
 #error "incoherent kernel configuration"
 #endif
 
-	/* pad to next slot */
-	.rept	(16 - (. - __kuser_cmpxchg64)/4)
-	.word	0
-	.endr
-
-	.align	5
+	kuser_pad __kuser_cmpxchg64, 64
 
 __kuser_memory_barrier:				@ 0xffff0fa0
 	smp_dmb	arm
 	usr_ret	lr
 
-	.align	5
+	kuser_pad __kuser_memory_barrier, 32
 
 __kuser_cmpxchg:				@ 0xffff0fc0
 
@@ -1019,13 +1027,14 @@
 
 #endif
 
-	.align	5
+	kuser_pad __kuser_cmpxchg, 32
 
 __kuser_get_tls:				@ 0xffff0fe0
 	ldr	r0, [pc, #(16 - 8)]	@ read TLS, set in kuser_get_tls_init
 	usr_ret	lr
 	mrc	p15, 0, r0, c13, c0, 3	@ 0xffff0fe8 hardware TLS code
-	.rep	4
+	kuser_pad __kuser_get_tls, 16
+	.rep	3
 	.word	0			@ 0xffff0ff0 software TLS value, then
 	.endr				@ pad up to __kuser_helper_version
 
@@ -1035,14 +1044,16 @@
 	.globl	__kuser_helper_end
 __kuser_helper_end:
 
+#endif
+
  THUMB(	.thumb	)
 
 /*
  * Vector stubs.
  *
- * This code is copied to 0xffff0200 so we can use branches in the
- * vectors, rather than ldr's.  Note that this code must not
- * exceed 0x300 bytes.
+ * This code is copied to 0xffff1000 so we can use branches in the
+ * vectors, rather than ldr's.  Note that this code must not exceed
+ * a page size.
  *
  * Common stub entry macro:
  *   Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
@@ -1101,8 +1112,17 @@
 1:
 	.endm
 
-	.globl	__stubs_start
+	.section .stubs, "ax", %progbits
 __stubs_start:
+	@ This must be the first word
+	.word	vector_swi
+
+vector_rst:
+ ARM(	swi	SYS_ERROR0	)
+ THUMB(	svc	#0		)
+ THUMB(	nop			)
+	b	vector_und
+
 /*
  * Interrupt dispatcher
  */
@@ -1197,6 +1217,16 @@
 	.align	5
 
 /*=============================================================================
+ * Address exception handler
+ *-----------------------------------------------------------------------------
+ * These aren't too critical.
+ * (they're not supposed to happen, and won't happen in 32-bit data mode).
+ */
+
+vector_addrexcptn:
+	b	vector_addrexcptn
+
+/*=============================================================================
  * Undefined FIQs
  *-----------------------------------------------------------------------------
  * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
@@ -1209,47 +1239,22 @@
 vector_fiq:
 	subs	pc, lr, #4
 
-/*=============================================================================
- * Address exception handler
- *-----------------------------------------------------------------------------
- * These aren't too critical.
- * (they're not supposed to happen, and won't happen in 32-bit data mode).
- */
-
-vector_addrexcptn:
-	b	vector_addrexcptn
-
-/*
- * We group all the following data together to optimise
- * for CPUs with separate I & D caches.
- */
-	.align	5
-
-.LCvswi:
-	.word	vector_swi
 .krait_fixup:
 	.word	msm_krait_need_wfe_fixup
 
-	.globl	__stubs_end
-__stubs_end:
+	.globl	vector_fiq_offset
+	.equ	vector_fiq_offset, vector_fiq
 
-	.equ	stubs_offset, __vectors_start + 0x200 - __stubs_start
-
-	.globl	__vectors_start
+	.section .vectors, "ax", %progbits
 __vectors_start:
- ARM(	swi	SYS_ERROR0	)
- THUMB(	svc	#0		)
- THUMB(	nop			)
-	W(b)	vector_und + stubs_offset
-	W(ldr)	pc, .LCvswi + stubs_offset
-	W(b)	vector_pabt + stubs_offset
-	W(b)	vector_dabt + stubs_offset
-	W(b)	vector_addrexcptn + stubs_offset
-	W(b)	vector_irq + stubs_offset
-	W(b)	vector_fiq + stubs_offset
-
-	.globl	__vectors_end
-__vectors_end:
+	W(b)	vector_rst
+	W(b)	vector_und
+	W(ldr)	pc, __vectors_start + 0x1000
+	W(b)	vector_pabt
+	W(b)	vector_dabt
+	W(b)	vector_addrexcptn
+	W(b)	vector_irq
+	W(b)	vector_fiq
 
 	.data
 
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index ca852c5..f9f16ef 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -48,6 +48,11 @@
 #include <asm/irq.h>
 #include <asm/traps.h>
 
+#define FIQ_OFFSET ({					\
+		extern void *vector_fiq_offset;		\
+		(unsigned)&vector_fiq_offset;		\
+	})
+
 static unsigned long no_fiq_insn;
 
 /* Default reacquire function
@@ -80,14 +85,14 @@
 
 void set_fiq_handler(void *start, unsigned int length)
 {
-#if defined(CONFIG_CPU_USE_DOMAINS)
-	memcpy((void *)0xffff001c, start, length);
-#else
-	memcpy(vectors_page + 0x1c, start, length);
-#endif
-	flush_icache_range(0xffff001c, 0xffff001c + length);
-	if (!vectors_high())
-		flush_icache_range(0x1c, 0x1c + length);
+	void *base = vectors_page;
+	unsigned offset = FIQ_OFFSET;
+
+	memcpy(base + offset, start, length);
+	if (!cache_is_vipt_nonaliasing())
+		flush_icache_range((unsigned long)base + offset, offset +
+				   length);
+	flush_icache_range(0xffff0000 + offset, 0xffff0000 + offset + length);
 }
 
 int claim_fiq(struct fiq_handler *f)
@@ -123,14 +128,16 @@
 	while (current_fiq->fiq_op(current_fiq->dev_id, 0));
 }
 
+static int fiq_start;
+
 void enable_fiq(int fiq)
 {
-	enable_irq(fiq + FIQ_START);
+	enable_irq(fiq + fiq_start);
 }
 
 void disable_fiq(int fiq)
 {
-	disable_irq(fiq + FIQ_START);
+	disable_irq(fiq + fiq_start);
 }
 
 void fiq_set_type(int fiq, unsigned int type)
@@ -147,7 +154,9 @@
 EXPORT_SYMBOL(disable_fiq);
 EXPORT_SYMBOL(fiq_set_type);
 
-void __init init_FIQ(void)
+void __init init_FIQ(int start)
 {
-	no_fiq_insn = *(unsigned long *)0xffff001c;
+	unsigned offset = FIQ_OFFSET;
+	no_fiq_insn = *(unsigned long *)(0xffff0000 + offset);
+	fiq_start = start;
 }
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 0241da1..2a3ab6e 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -116,7 +116,12 @@
 static int
 armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
 {
-	int mapping = (*event_map)[config];
+	int mapping;
+
+	if (config >= PERF_COUNT_HW_MAX)
+		return -EINVAL;
+
+	mapping = (*event_map)[config];
 	return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
 }
 
@@ -341,6 +346,9 @@
 	struct hw_perf_event fake_event = event->hw;
 	struct pmu *leader_pmu = event->group_leader->pmu;
 
+	if (is_software_event(event))
+		return 1;
+
 	if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF)
 		return 1;
 
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index fe97ff2..c5fa883 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -38,6 +38,7 @@
 #include <asm/thread_notify.h>
 #include <asm/stacktrace.h>
 #include <asm/mach/time.h>
+#include <asm/tls.h>
 
 #ifdef CONFIG_CC_STACKPROTECTOR
 #include <linux/stackprotector.h>
@@ -534,7 +535,8 @@
 	clear_ptrace_hw_breakpoint(p);
 
 	if (clone_flags & CLONE_SETTLS)
-		thread->tp_value = regs->ARM_r3;
+		thread->tp_value[0] = childregs->ARM_r3;
+	thread->tp_value[1] = get_tpuser();
 
 	thread_notify(THREAD_NOTIFY_COPY, thread);
 
@@ -650,10 +652,11 @@
 }
 
 #ifdef CONFIG_MMU
+#ifdef CONFIG_KUSER_HELPERS
 /*
  * The vectors page is always readable from user space for the
- * atomic helpers and the signal restart code. Insert it into the
- * gate_vma so that it is visible through ptrace and /proc/<pid>/mem.
+ * atomic helpers. Insert it into the gate_vma so that it is visible
+ * through ptrace and /proc/<pid>/mem.
  */
 static struct vm_area_struct gate_vma;
 
@@ -682,14 +685,53 @@
 {
 	return in_gate_area(NULL, addr);
 }
+#define is_gate_vma(vma)	((vma) == &gate_vma)
+#else
+#define is_gate_vma(vma)	0
+#endif
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
-	if (vma == &gate_vma)
+	if (is_gate_vma(vma))
 		return "[vectors]";
+	else if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage)
+		return "[sigpage]";
 	else if (vma == get_user_timers_vma(NULL))
 		return "[timers]";
 	else
 		return NULL;
 }
+
+static struct page *signal_page;
+extern struct page *get_signal_page(void);
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long addr;
+	int ret;
+
+	if (!signal_page)
+		signal_page = get_signal_page();
+	if (!signal_page)
+		return -ENOMEM;
+
+	down_write(&mm->mmap_sem);
+	addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
+	if (IS_ERR_VALUE(addr)) {
+		ret = addr;
+		goto up_fail;
+	}
+
+	ret = install_special_mapping(mm, addr, PAGE_SIZE,
+		VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+		&signal_page);
+
+	if (ret == 0)
+		mm->context.sigpage = addr;
+
+ up_fail:
+	up_write(&mm->mmap_sem);
+	return ret;
+}
 #endif
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 9650c14..c6c6be7 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -844,7 +844,7 @@
 #endif
 
 		case PTRACE_GET_THREAD_AREA:
-			ret = put_user(task_thread_info(child)->tp_value,
+			ret = put_user(task_thread_info(child)->tp_value[0],
 				       datap);
 			break;
 
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index d68d1b6..e000e5e 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/errno.h>
+#include <linux/random.h>
 #include <linux/signal.h>
 #include <linux/personality.h>
 #include <linux/freezer.h>
@@ -16,10 +17,10 @@
 
 #include <asm/elf.h>
 #include <asm/cacheflush.h>
+#include <asm/traps.h>
 #include <asm/ucontext.h>
 #include <asm/unistd.h>
 #include <asm/vfp.h>
-
 #include "signal.h"
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -44,7 +45,7 @@
 #define SWI_THUMB_SIGRETURN	(0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
 #define SWI_THUMB_RT_SIGRETURN	(0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
 
-const unsigned long sigreturn_codes[7] = {
+static const unsigned long sigreturn_codes[7] = {
 	MOV_R7_NR_SIGRETURN,    SWI_SYS_SIGRETURN,    SWI_THUMB_SIGRETURN,
 	MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
 };
@@ -112,6 +113,8 @@
 	return ret;
 }
 
+static unsigned long signal_return_offset;
+
 #ifdef CONFIG_CRUNCH
 static int preserve_crunch_context(struct crunch_sigframe __user *frame)
 {
@@ -460,13 +463,20 @@
 		    __put_user(sigreturn_codes[idx+1], rc+1))
 			return 1;
 
+#ifdef CONFIG_MMU
 		if (cpsr & MODE32_BIT) {
+			struct mm_struct *mm = current->mm;
+
 			/*
-			 * 32-bit code can use the new high-page
-			 * signal return code support.
+			 * 32-bit code can use the signal return page
+			 * except when the MPU has protected the vectors
+			 * page from PL0
 			 */
-			retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
-		} else {
+			retcode = mm->context.sigpage + signal_return_offset +
+				  (idx << 2) + thumb;
+		} else
+#endif
+		{
 			/*
 			 * Ensure that the instruction cache sees
 			 * the return code written onto the stack.
@@ -739,3 +749,33 @@
 			key_replace_session_keyring();
 	}
 }
+
+struct page *get_signal_page(void)
+{
+	unsigned long ptr;
+	unsigned offset;
+	struct page *page;
+	void *addr;
+
+	page = alloc_pages(GFP_KERNEL, 0);
+
+	if (!page)
+		return NULL;
+
+	addr = page_address(page);
+
+	/* Give the signal return code some randomness */
+	offset = 0x200 + (get_random_int() & 0x7fc);
+	signal_return_offset = offset;
+
+	/*
+	 * Copy signal return handlers into the vector page, and
+	 * set sigreturn to be a pointer to these.
+	 */
+	memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));
+
+	ptr = (unsigned long)addr + offset;
+	flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
+
+	return page;
+}
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
index 6fcfe83..a0dcf5f 100644
--- a/arch/arm/kernel/signal.h
+++ b/arch/arm/kernel/signal.h
@@ -10,5 +10,4 @@
 #define KERN_SIGRETURN_CODE	(CONFIG_VECTORS_BASE + 0x00000500)
 #define KERN_RESTART_CODE	(KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
 
-extern const unsigned long sigreturn_codes[7];
 extern const unsigned long syscall_restart_code[2];
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 1e9504b..bd49b1f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -35,8 +35,6 @@
 #include <asm/tls.h>
 #include <asm/system_misc.h>
 
-#include "signal.h"
-
 #include <trace/events/exception.h>
 
 static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
@@ -566,7 +564,7 @@
 		return regs->ARM_r0;
 
 	case NR(set_tls):
-		thread->tp_value = regs->ARM_r0;
+		thread->tp_value[0] = regs->ARM_r0;
 		if (tls_emu)
 			return 0;
 		if (has_tls_reg) {
@@ -684,7 +682,7 @@
 	int reg = (instr >> 12) & 15;
 	if (reg == 15)
 		return 1;
-	regs->uregs[reg] = current_thread_info()->tp_value;
+	regs->uregs[reg] = current_thread_info()->tp_value[0];
 	regs->ARM_pc += 4;
 	return 0;
 }
@@ -785,49 +783,55 @@
 	return;
 }
 
-static void __init kuser_get_tls_init(unsigned long vectors)
+#ifdef CONFIG_KUSER_HELPERS
+static void __init kuser_init(void *vectors)
 {
+	extern char __kuser_helper_start[], __kuser_helper_end[];
+	int kuser_sz = __kuser_helper_end - __kuser_helper_start;
+
+	memcpy(vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
+
 	/*
 	 * vectors + 0xfe0 = __kuser_get_tls
 	 * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8
 	 */
 	if (tls_emu || has_tls_reg)
-		memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4);
+		memcpy(vectors + 0xfe0, vectors + 0xfe8, 4);
 }
+#else
+static void __init kuser_init(void *vectors)
+{
+}
+#endif
 
 void __init early_trap_init(void *vectors_base)
 {
 	unsigned long vectors = (unsigned long)vectors_base;
 	extern char __stubs_start[], __stubs_end[];
 	extern char __vectors_start[], __vectors_end[];
-	extern char __kuser_helper_start[], __kuser_helper_end[];
-	int kuser_sz = __kuser_helper_end - __kuser_helper_start;
+	unsigned i;
 
 	vectors_page = vectors_base;
 
 	/*
+	 * Poison the vectors page with an undefined instruction.  This
+	 * instruction is chosen to be undefined for both ARM and Thumb
+	 * ISAs.  The Thumb version is an undefined instruction with a
+	 * branch back to the undefined instruction.
+	 */
+	for (i = 0; i < PAGE_SIZE / sizeof(u32); i++)
+		((u32 *)vectors_base)[i] = 0xe7fddef1;
+
+	/*
 	 * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
 	 * into the vector page, mapped at 0xffff0000, and ensure these
 	 * are visible to the instruction stream.
 	 */
 	memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
-	memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
-	memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
+	memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
 
-	/*
-	 * Do processor specific fixups for the kuser helpers
-	 */
-	kuser_get_tls_init(vectors);
+	kuser_init(vectors_base);
 
-	/*
-	 * Copy signal return handlers into the vector page, and
-	 * set sigreturn to be a pointer to these.
-	 */
-	memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
-	       sigreturn_codes, sizeof(sigreturn_codes));
-	memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
-	       syscall_restart_code, sizeof(syscall_restart_code));
-
-	flush_icache_range(vectors, vectors + PAGE_SIZE);
+	flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
 	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
 }
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 0bf55ae..68c312b 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -151,6 +151,23 @@
 #endif
 	__init_begin = .;
 #endif
+	/*
+	 * The vectors and stubs are relocatable code, and the
+	 * only thing that matters is their relative offsets
+	 */
+	__vectors_start = .;
+	.vectors 0 : AT(__vectors_start) {
+		*(.vectors)
+	}
+	. = __vectors_start + SIZEOF(.vectors);
+	__vectors_end = .;
+
+	__stubs_start = .;
+	.stubs 0x1000 : AT(__stubs_start) {
+		*(.stubs)
+	}
+	. = __stubs_start + SIZEOF(.stubs);
+	__stubs_end = .;
 
 	INIT_TEXT_SECTION(8)
 	.exit.text : {
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 696ddf9..87c2f8c 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -473,6 +473,7 @@
 	select MSM_JTAG_MM if CORESIGHT_ETM
 	select MSM_CPR_REGULATOR
 	select MSM_RPM_LOG
+	select MSM_IOMMU_SYNC
 	select MSM_RPM_STATS_LOG
 
 config ARCH_MSM8226
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index d7277ce..993ce58 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -322,6 +322,7 @@
 #define CAMSS_VFE_VFE_AXI_CBCR                             (0x36BC)
 #define CAMSS_CSI_VFE0_BCR                                 (0x3700)
 #define CAMSS_CSI_VFE0_CBCR                                (0x3704)
+#define CAMSS_MICRO_BCR                                    (0x3490)
 #define OXILI_GFX3D_CBCR                                   (0x4028)
 #define OXILICX_BCR                                        (0x4030)
 #define OXILICX_AXI_CBCR                                   (0x4038)
@@ -2367,6 +2368,7 @@
 static struct branch_clk camss_micro_ahb_clk = {
 	.cbcr_reg = CAMSS_MICRO_AHB_CBCR,
 	.has_sibling = 1,
+	.bcr_reg = CAMSS_MICRO_BCR,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
 		.dbg_name = "camss_micro_ahb_clk",
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 9ae3340..32a2617 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -3909,6 +3909,7 @@
 static struct branch_clk camss_micro_ahb_clk = {
 	.cbcr_reg = CAMSS_MICRO_AHB_CBCR,
 	.has_sibling = 1,
+	.bcr_reg = CAMSS_MICRO_BCR,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
 		.dbg_name = "camss_micro_ahb_clk",
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 7cfbd93..c4db727 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -101,6 +101,7 @@
  * @asid:         List of ASID and their usage count (index is ASID value).
  * @ctx_attach_count: Count of how many context are attached.
  * @bus_client  : Bus client needed to vote for bus bandwidth.
+ * @needs_rem_spinlock  : 1 if remote spinlock is needed, 0 otherwise
  *
  * A msm_iommu_drvdata holds the global driver data about a single piece
  * of an IOMMU hardware instance.
@@ -125,6 +126,7 @@
 	int *asid;
 	unsigned int ctx_attach_count;
 	unsigned int bus_client;
+	int needs_rem_spinlock;
 };
 
 /**
@@ -146,8 +148,8 @@
 	int (*iommu_clk_on)(struct msm_iommu_drvdata *);
 	void (*iommu_clk_off)(struct msm_iommu_drvdata *);
 	void * (*iommu_lock_initialize)(void);
-	void (*iommu_lock_acquire)(void);
-	void (*iommu_lock_release)(void);
+	void (*iommu_lock_acquire)(unsigned int need_extra_lock);
+	void (*iommu_lock_release)(unsigned int need_extra_lock);
 };
 
 void msm_iommu_add_drv(struct msm_iommu_drvdata *drv);
@@ -277,32 +279,21 @@
 }
 #endif
 
-#ifdef CONFIG_MSM_IOMMU_GPU_SYNC
-void msm_iommu_remote_p0_spin_lock(void);
-void msm_iommu_remote_p0_spin_unlock(void);
+#ifdef CONFIG_MSM_IOMMU_SYNC
+void msm_iommu_remote_p0_spin_lock(unsigned int need_lock);
+void msm_iommu_remote_p0_spin_unlock(unsigned int need_lock);
 
 #define msm_iommu_remote_lock_init() _msm_iommu_remote_spin_lock_init()
-#define msm_iommu_remote_spin_lock() msm_iommu_remote_p0_spin_lock()
-#define msm_iommu_remote_spin_unlock() msm_iommu_remote_p0_spin_unlock()
+#define msm_iommu_remote_spin_lock(need_lock) \
+				msm_iommu_remote_p0_spin_lock(need_lock)
+#define msm_iommu_remote_spin_unlock(need_lock) \
+				msm_iommu_remote_p0_spin_unlock(need_lock)
 #else
 #define msm_iommu_remote_lock_init()
-#define msm_iommu_remote_spin_lock()
-#define msm_iommu_remote_spin_unlock()
+#define msm_iommu_remote_spin_lock(need_lock)
+#define msm_iommu_remote_spin_unlock(need_lock)
 #endif
 
-/* Allows kgsl iommu driver to acquire lock */
-#define msm_iommu_lock() \
-	do { \
-		msm_iommu_mutex_lock(); \
-		msm_iommu_remote_spin_lock(); \
-	} while (0)
-
-#define msm_iommu_unlock() \
-	do { \
-		msm_iommu_remote_spin_unlock(); \
-		msm_iommu_mutex_unlock(); \
-	} while (0)
-
 #ifdef CONFIG_MSM_IOMMU
 /*
  * Look up an IOMMU context device by its context name. NULL if none found.
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index 180d277..249a334 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -191,6 +191,9 @@
 	case MSM_SPM_L2_MODE_GDHS:
 		msm_pm_set_l2_flush_flag(MSM_SCM_L2_GDHS);
 		break;
+	case MSM_SPM_L2_MODE_PC_NO_RPM:
+		msm_pm_set_l2_flush_flag(MSM_SCM_L2_OFF);
+		break;
 	case MSM_SPM_L2_MODE_RETENTION:
 	case MSM_SPM_L2_MODE_DISABLED:
 		break;
@@ -448,6 +451,7 @@
 	int i;
 	struct lpm_lookup_table l2_mode_lookup[] = {
 		{MSM_SPM_L2_MODE_POWER_COLLAPSE, "l2_cache_pc"},
+		{MSM_SPM_L2_MODE_PC_NO_RPM, "l2_cache_pc_no_rpm"},
 		{MSM_SPM_L2_MODE_GDHS, "l2_cache_gdhs"},
 		{MSM_SPM_L2_MODE_RETENTION, "l2_cache_retention"},
 		{MSM_SPM_L2_MODE_DISABLED, "l2_cache_active"}
diff --git a/arch/arm/mach-msm/ocmem_core.c b/arch/arm/mach-msm/ocmem_core.c
index 153864d..c186a5e 100644
--- a/arch/arm/mach-msm/ocmem_core.c
+++ b/arch/arm/mach-msm/ocmem_core.c
@@ -43,6 +43,8 @@
 	unsigned int num_macros;
 	struct ocmem_hw_macro *macro;
 	struct msm_rpm_request *rpm_req;
+	unsigned long macro_size;
+	unsigned long region_size;
 	unsigned r_state;
 };
 
@@ -69,6 +71,9 @@
 #define NUM_MACROS_MASK (0x3F << 8)
 #define NUM_MACROS_SHIFT (8)
 
+#define LAST_REGN_HALFSIZE_MASK (0x1 << 16)
+#define LAST_REGN_HALFSIZE_SHIFT (16)
+
 #define INTERLEAVING_MASK (0x1 << 17)
 #define INTERLEAVING_SHIFT (17)
 
@@ -198,7 +203,13 @@
 
 	return state;
 }
+
 #ifndef CONFIG_MSM_OCMEM_POWER_DISABLE
+static struct ocmem_hw_region *get_ocmem_region(unsigned region_num)
+{
+	return &region_ctrl[region_num];
+}
+
 static int commit_region_staging(unsigned region_num, unsigned start_m,
 				unsigned new_state)
 {
@@ -933,6 +944,7 @@
 	unsigned start_m = num_banks;
 	unsigned end_m = num_banks;
 	unsigned long region_offset = 0;
+	struct ocmem_hw_region *region;
 	int rc = 0;
 
 	if (offset < 0)
@@ -966,6 +978,7 @@
 
 	for (i = region_start; i <= region_end; i++) {
 
+		region = get_ocmem_region(i);
 		curr_state = read_region_state(i);
 
 		switch (curr_state) {
@@ -981,14 +994,14 @@
 			break;
 		}
 
-		if (len >= region_size) {
+		if (len >= region->region_size) {
 			pr_debug("switch: entire region (%d)\n", i);
 			start_m = 0;
 			end_m = num_banks;
 		} else {
-			region_offset = offset - (i * region_size);
-			start_m = region_offset / macro_size;
-			end_m = (region_offset + len - 1) / macro_size;
+			region_offset = offset - (i * region->region_size);
+			start_m = region_offset / region->macro_size;
+			end_m = (region_offset + len - 1) / region->macro_size;
 			pr_debug("switch: macro (%u to %u)\n", start_m, end_m);
 		}
 
@@ -1002,7 +1015,7 @@
 		aggregate_region_state(i);
 		if (rpm_power_control)
 			commit_region_state(i);
-		len -= region_size;
+		len -= region->region_size;
 
 		/* If we voted ON/retain the banks must never be OFF */
 		if (new_state != REGION_DEFAULT_OFF) {
@@ -1123,6 +1136,7 @@
 	struct device   *dev = &pdev->dev;
 	struct ocmem_plat_data *pdata = NULL;
 	unsigned hw_ver;
+	bool last_region_halfsize;
 	bool interleaved;
 	unsigned i, j, k;
 	unsigned rsc_type = 0;
@@ -1146,6 +1160,9 @@
 		goto hw_not_supported;
 	}
 
+	last_region_halfsize = (hw_ver & LAST_REGN_HALFSIZE_MASK) >>
+					LAST_REGN_HALFSIZE_SHIFT;
+
 	interleaved = (hw_ver & INTERLEAVING_MASK) >> INTERLEAVING_SHIFT;
 
 	num_regions = pdata->nr_regions;
@@ -1179,6 +1196,14 @@
 		region->r_state = REGION_DEFAULT_OFF;
 		region->num_macros = num_banks;
 
+		if (last_region_halfsize && i == (num_regions - 1)) {
+			region->macro_size = macro_size / 2;
+			region->region_size = region_size / 2;
+		} else {
+			region->macro_size = macro_size;
+			region->region_size = region_size;
+		}
+
 		region->macro = devm_kzalloc(dev,
 					sizeof(struct ocmem_hw_macro) *
 						num_banks, GFP_KERNEL);
diff --git a/arch/arm/mach-msm/spm.h b/arch/arm/mach-msm/spm.h
index 3207011..1769402 100644
--- a/arch/arm/mach-msm/spm.h
+++ b/arch/arm/mach-msm/spm.h
@@ -24,6 +24,7 @@
 	MSM_SPM_L2_MODE_DISABLED = MSM_SPM_MODE_DISABLED,
 	MSM_SPM_L2_MODE_RETENTION,
 	MSM_SPM_L2_MODE_GDHS,
+	MSM_SPM_L2_MODE_PC_NO_RPM,
 	MSM_SPM_L2_MODE_POWER_COLLAPSE,
 };
 
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 3ac1348..19b0b80 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -397,6 +397,7 @@
 	struct mode_of of_l2_modes[] = {
 		{"qcom,saw2-spm-cmd-ret", MSM_SPM_L2_MODE_RETENTION, 1},
 		{"qcom,saw2-spm-cmd-gdhs", MSM_SPM_L2_MODE_GDHS, 1},
+		{"qcom,saw2-spm-cmd-pc-no-rpm", MSM_SPM_L2_MODE_PC_NO_RPM, 1},
 		{"qcom,saw2-spm-cmd-pc", MSM_SPM_L2_MODE_POWER_COLLAPSE, 1},
 	};
 
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
index cf0e669..3e4fa84 100644
--- a/arch/arm/mach-rpc/irq.c
+++ b/arch/arm/mach-rpc/irq.c
@@ -163,6 +163,6 @@
 		}
 	}
 
-	init_FIQ();
+	init_FIQ(FIQ_START);
 }
 
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 194c5f6..7b9f754 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -436,24 +436,28 @@
 	select TLS_REG_EMUL if SMP || !MMU
 	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
 	select CPU_USE_DOMAINS if MMU
+	select NEED_KUSER_HELPERS
 
 config CPU_32v4
 	bool
 	select TLS_REG_EMUL if SMP || !MMU
 	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
 	select CPU_USE_DOMAINS if MMU
+	select NEED_KUSER_HELPERS
 
 config CPU_32v4T
 	bool
 	select TLS_REG_EMUL if SMP || !MMU
 	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
 	select CPU_USE_DOMAINS if MMU
+	select NEED_KUSER_HELPERS
 
 config CPU_32v5
 	bool
 	select TLS_REG_EMUL if SMP || !MMU
 	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
 	select CPU_USE_DOMAINS if MMU
+	select NEED_KUSER_HELPERS
 
 config CPU_32v6
 	bool
@@ -792,6 +796,7 @@
 
 config TLS_REG_EMUL
 	bool
+	select NEED_KUSER_HELPERS
 	help
 	  An SMP system using a pre-ARMv6 processor (there are apparently
 	  a few prototypes like that in existence) and therefore access to
@@ -799,11 +804,43 @@
 
 config NEEDS_SYSCALL_FOR_CMPXCHG
 	bool
+	select NEED_KUSER_HELPERS
 	help
 	  SMP on a pre-ARMv6 processor?  Well OK then.
 	  Forget about fast user space cmpxchg support.
 	  It is just not possible.
 
+config NEED_KUSER_HELPERS
+	bool
+
+config KUSER_HELPERS
+	bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS
+	default y
+	help
+	  Warning: disabling this option may break user programs.
+
+	  Provide kuser helpers in the vector page.  The kernel provides
+	  helper code to userspace in read only form at a fixed location
+	  in the high vector page to allow userspace to be independent of
+	  the CPU type fitted to the system.  This permits binaries to be
+	  run on ARMv4 through to ARMv7 without modification.
+
+	  See Documentation/arm/kernel_user_helpers.txt for details.
+
+	  However, the fixed address nature of these helpers can be used
+	  by ROP (return orientated programming) authors when creating
+	  exploits.
+
+	  If all of the binaries and libraries which run on your platform
+	  are built specifically for your platform, and make no use of
+	  these helpers, then you can turn this option off to hinder
+	  such exploits. However, in that case, if a binary or library
+	  relying on those helpers is run, it will receive a SIGILL signal,
+	  which will terminate the program.
+
+	  Say N here only if you are absolutely certain that you do not
+	  need these helpers; otherwise, the safe option is to say Y.
+
 config DMA_CACHE_RWFO
 	bool "Enable read/write for ownership DMA cache maintenance"
 	depends on CPU_V6K && SMP
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 509f59d..a1a2e51 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1203,7 +1203,7 @@
 	/*
 	 * Allocate the vector page early.
 	 */
-	vectors = early_alloc(PAGE_SIZE);
+	vectors = early_alloc(PAGE_SIZE * 2);
 
 	early_trap_init(vectors);
 
@@ -1248,15 +1248,27 @@
 	map.pfn = __phys_to_pfn(virt_to_phys(vectors));
 	map.virtual = 0xffff0000;
 	map.length = PAGE_SIZE;
+#ifdef CONFIG_KUSER_HELPERS
 	map.type = MT_HIGH_VECTORS;
+#else
+	map.type = MT_LOW_VECTORS;
+#endif
 	create_mapping(&map);
 
 	if (!vectors_high()) {
 		map.virtual = 0;
+		map.length = PAGE_SIZE * 2;
 		map.type = MT_LOW_VECTORS;
 		create_mapping(&map);
 	}
 
+	/* Now create a kernel read-only mapping */
+	map.pfn += 1;
+	map.virtual = 0xffff0000 + PAGE_SIZE;
+	map.length = PAGE_SIZE;
+	map.type = MT_LOW_VECTORS;
+	create_mapping(&map);
+
 	/*
 	 * Ask the machine support to map in the statically mapped devices.
 	 */
@@ -1485,7 +1497,7 @@
 		vm->addr = (void *)(vaddr & PAGE_MASK);
 		vm->size = PAGE_ALIGN(length + (vaddr & ~PAGE_MASK));
 		vm->phys_addr = __pfn_to_phys(pfn);
-		vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
+		vm->flags = VM_LOWMEM | VM_ARM_STATIC_MAPPING;
 		vm->flags |= VM_ARM_MTYPE(type);
 		vm->caller = map_lowmem;
 		vm_area_add_early(vm++);
diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c
index 689f81f..9091f03 100644
--- a/arch/arm/plat-mxc/avic.c
+++ b/arch/arm/plat-mxc/avic.c
@@ -199,7 +199,7 @@
 
 #ifdef CONFIG_FIQ
 	/* Initialize FIQ */
-	init_FIQ();
+	init_FIQ(FIQ_START);
 #endif
 
 	printk(KERN_INFO "MXC IRQ initialized\n");
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
index 98308ec..5cebccf 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/plat-mxc/tzic.c
@@ -180,7 +180,7 @@
 
 #ifdef CONFIG_FIQ
 	/* Initialize FIQ */
-	init_FIQ();
+	init_FIQ(FIQ_START);
 #endif
 
 	pr_info("TrustZone Interrupt Controller (TZIC) initialized\n");
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index bc42c04..fe57bbb 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -533,7 +533,7 @@
 	int i;
 
 #ifdef CONFIG_FIQ
-	init_FIQ();
+	init_FIQ(FIQ_START);
 #endif
 
 	irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
diff --git a/drivers/base/sync.c b/drivers/base/sync.c
index abde6d9..645a698 100644
--- a/drivers/base/sync.c
+++ b/drivers/base/sync.c
@@ -92,14 +92,14 @@
 void sync_timeline_destroy(struct sync_timeline *obj)
 {
 	obj->destroyed = true;
+	smp_wmb();
 
 	/*
-	 * If this is not the last reference, signal any children
-	 * that their parent is going away.
+	 * signal any children that their parent is going away.
 	 */
+	sync_timeline_signal(obj);
 
-	if (!kref_put(&obj->kref, sync_timeline_free))
-		sync_timeline_signal(obj);
+	kref_put(&obj->kref, sync_timeline_free);
 }
 EXPORT_SYMBOL(sync_timeline_destroy);
 
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index 7409ccb..81a90fe 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1661,6 +1661,9 @@
 static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req,
 						struct qcedev_control *podev)
 {
+	uint32_t total = 0;
+	uint32_t i;
+
 	if (req->use_pmem) {
 		pr_err("%s: Use of PMEM is not supported\n", __func__);
 		goto error;
@@ -1712,7 +1715,22 @@
 			goto error;
 		}
 	}
-
+	/* Check for sum of all dst length is equal to data_len  */
+	for (i = 0; (i < QCEDEV_MAX_BUFFERS) && (total < req->data_len); i++)
+		total += req->vbuf.dst[i].len;
+	if (total != req->data_len) {
+		pr_err("%s: Total (i=%d) dst(%d) buf size != data_len (%d)\n",
+			__func__, i, total, req->data_len);
+		goto error;
+	}
+	/* Check for sum of all src length is equal to data_len  */
+	for (i = 0, total = 0; i < req->entries; i++)
+		total += req->vbuf.src[i].len;
+	if (total != req->data_len) {
+		pr_err("%s: Total src(%d) buf size != data_len (%d)\n",
+			__func__, total, req->data_len);
+		goto error;
+	}
 	return 0;
 error:
 	return -EINVAL;
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index ecda5a7..a06ebbf 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -72,16 +72,18 @@
 
 static struct iommu_access_ops *iommu_access_ops;
 
-static void _iommu_lock(void)
+static void _iommu_lock(struct kgsl_iommu const *iommu)
 {
 	if (iommu_access_ops && iommu_access_ops->iommu_lock_acquire)
-		iommu_access_ops->iommu_lock_acquire();
+		iommu_access_ops->iommu_lock_acquire(
+						iommu->sync_lock_initialized);
 }
 
-static void _iommu_unlock(void)
+static void _iommu_unlock(struct kgsl_iommu const *iommu)
 {
 	if (iommu_access_ops && iommu_access_ops->iommu_lock_release)
-		iommu_access_ops->iommu_lock_release();
+		iommu_access_ops->iommu_lock_release(
+						iommu->sync_lock_initialized);
 }
 
 struct remote_iommu_petersons_spinlock kgsl_iommu_sync_lock_vars;
@@ -906,6 +908,8 @@
 	return 0;
 }
 
+#ifdef CONFIG_MSM_IOMMU_GPU_SYNC
+
 /*
  * kgsl_get_sync_lock - Init Sync Lock between GPU and CPU
  * @mmu - Pointer to mmu device
@@ -973,6 +977,12 @@
 
 	return status;
 }
+#else
+static int kgsl_iommu_init_sync_lock(struct kgsl_mmu *mmu)
+{
+	return 0;
+}
+#endif
 
 /*
  * kgsl_iommu_sync_lock - Acquire Sync Lock between GPU and CPU
@@ -1643,7 +1653,7 @@
 	 * changing pagetables we can use this lsb value of the pagetable w/o
 	 * having to read it again
 	 */
-	_iommu_lock();
+	_iommu_lock(iommu);
 	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++) {
@@ -1682,7 +1692,7 @@
 		}
 	}
 	kgsl_iommu_lock_rb_in_tlb(mmu);
-	_iommu_unlock();
+	_iommu_unlock(iommu);
 
 	/* For complete CFF */
 	kgsl_cffdump_setmem(mmu->device, mmu->setstate_memory.gpuaddr +
@@ -1788,12 +1798,12 @@
 			for (j = 0; j < iommu_unit->dev_count; j++) {
 				if (iommu_unit->dev[j].fault) {
 					kgsl_iommu_enable_clk(mmu, j);
-					_iommu_lock();
+					_iommu_lock(iommu);
 					KGSL_IOMMU_SET_CTX_REG(iommu,
 						iommu_unit,
 						iommu_unit->dev[j].ctx_id,
 						RESUME, 1);
-					_iommu_unlock();
+					_iommu_unlock(iommu);
 					iommu_unit->dev[j].fault = 0;
 				}
 			}
@@ -1912,7 +1922,7 @@
 		kgsl_idle(mmu->device);
 
 	/* Acquire GPU-CPU sync Lock here */
-	_iommu_lock();
+	_iommu_lock(iommu);
 
 	if (flags & KGSL_MMUFLAGS_PTUPDATE) {
 		if (!msm_soc_version_supports_iommu_v0())
@@ -1979,7 +1989,7 @@
 	}
 
 	/* Release GPU-CPU sync Lock here */
-	_iommu_unlock();
+	_iommu_unlock(iommu);
 
 	/* Disable smmu clock */
 	kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
diff --git a/drivers/input/misc/cm36283.c b/drivers/input/misc/cm36283.c
index d850a0e..17127a8 100644
--- a/drivers/input/misc/cm36283.c
+++ b/drivers/input/misc/cm36283.c
@@ -40,8 +40,6 @@
 #include <asm/mach-types.h>
 #include <asm/setup.h>
 
-#define D(x...) pr_info(x)
-
 #define I2C_RETRY_COUNT 10
 
 #define NEAR_DELAY_TIME ((100 * HZ) / 1000)
@@ -65,8 +63,6 @@
 #define CM36283_PS_MAX_POLL_DELAY	1000
 #define CM36283_PS_DEFAULT_POLL_DELAY	100
 
-static int record_init_fail = 0;
-
 static const int als_range[] = {
 	[CM36283_ALS_IT0] = 6554,
 	[CM36283_ALS_IT1] = 3277,
@@ -156,9 +152,8 @@
 static int I2C_RxData(uint16_t slaveAddr, uint8_t cmd, uint8_t *rxData, int length)
 {
 	uint8_t loop_i;
-	int val;
 	struct cm36283_info *lpi = lp_info;
-  uint8_t subaddr[1];
+	uint8_t subaddr[1];
 
 	struct i2c_msg msgs[] = {
 		{
@@ -174,24 +169,21 @@
 		 .buf = rxData,
 		 },		 
 	};
-  subaddr[0] = cmd;
+
+	subaddr[0] = cmd;
 
 	for (loop_i = 0; loop_i < I2C_RETRY_COUNT; loop_i++) {
 
 		if (i2c_transfer(lp_info->i2c_client->adapter, msgs, 2) > 0)
 			break;
 
-		val = gpio_get_value(lpi->intr_pin);
-		/*check intr GPIO when i2c error*/
-		if (loop_i == 0 || loop_i == I2C_RETRY_COUNT -1)
-			D("[PS][CM36283 error] %s, i2c err, slaveAddr 0x%x ISR gpio %d  = %d, record_init_fail %d \n",
-				__func__, slaveAddr, lpi->intr_pin, val, record_init_fail);
-
+		dev_err(&lpi->i2c_client->dev, "%s: I2C error(%d). Retrying.\n",
+				__func__, cmd);
 		msleep(10);
 	}
 	if (loop_i >= I2C_RETRY_COUNT) {
-		printk(KERN_ERR "[PS_ERR][CM36283 error] %s retry over %d\n",
-			__func__, I2C_RETRY_COUNT);
+		dev_err(&lpi->i2c_client->dev, "%s: Retry count exceeds %d.",
+				__func__, I2C_RETRY_COUNT);
 		return -EIO;
 	}
 
@@ -201,8 +193,8 @@
 static int I2C_TxData(uint16_t slaveAddr, uint8_t *txData, int length)
 {
 	uint8_t loop_i;
-	int val;
 	struct cm36283_info *lpi = lp_info;
+
 	struct i2c_msg msg[] = {
 		{
 		 .addr = slaveAddr,
@@ -216,18 +208,13 @@
 		if (i2c_transfer(lp_info->i2c_client->adapter, msg, 1) > 0)
 			break;
 
-		val = gpio_get_value(lpi->intr_pin);
-		/*check intr GPIO when i2c error*/
-		if (loop_i == 0 || loop_i == I2C_RETRY_COUNT -1)
-			D("[PS][CM36283 error] %s, i2c err, slaveAddr 0x%x, value 0x%x, ISR gpio%d  = %d, record_init_fail %d\n",
-				__func__, slaveAddr, txData[0], lpi->intr_pin, val, record_init_fail);
-
+		pr_err("%s: I2C error. Retrying...\n", __func__);
 		msleep(10);
 	}
 
 	if (loop_i >= I2C_RETRY_COUNT) {
-		printk(KERN_ERR "[PS_ERR][CM36283 error] %s retry over %d\n",
-			__func__, I2C_RETRY_COUNT);
+		dev_err(&lpi->i2c_client->dev, "%s: Retry count exceeds %d.",
+				__func__, I2C_RETRY_COUNT);
 		return -EIO;
 	}
 
@@ -244,18 +231,12 @@
 
 	ret = I2C_RxData(slaveAddr, cmd, buffer, 2);
 	if (ret < 0) {
-		pr_err(
-			"[PS_ERR][CM3218 error]%s: I2C_RxData fail [0x%x, 0x%x]\n",
-			__func__, slaveAddr, cmd);
+		pr_err("%s: I2C RxData fail(%d).\n", __func__, cmd);
 		return ret;
 	}
 
 	*pdata = (buffer[1]<<8)|buffer[0];
-#if 0
-	/* Debug use */
-	printk(KERN_DEBUG "[CM3218] %s: I2C_RxData[0x%x, 0x%x] = 0x%x\n",
-		__func__, slaveAddr, cmd, *pdata);
-#endif
+
 	return ret;
 }
 
@@ -263,19 +244,14 @@
 {
 	char buffer[3];
 	int ret = 0;
-#if 0
-	/* Debug use */
-	printk(KERN_DEBUG
-	"[CM3218] %s: _cm36283_I2C_Write_Word[0x%x, 0x%x, 0x%x]\n",
-		__func__, SlaveAddress, cmd, data);
-#endif
+
 	buffer[0] = cmd;
 	buffer[1] = (uint8_t)(data&0xff);
 	buffer[2] = (uint8_t)((data&0xff00)>>8);	
 	
 	ret = I2C_TxData(SlaveAddress, buffer, 3);
 	if (ret < 0) {
-		pr_err("[PS_ERR][CM3218 error]%s: I2C_TxData fail\n", __func__);
+		pr_err("%s: I2C_TxData failed.\n", __func__);
 		return -EIO;
 	}
 
@@ -285,7 +261,7 @@
 static int get_ls_adc_value(uint16_t *als_step, bool resume)
 {
 	struct cm36283_info *lpi = lp_info;
-	uint32_t tmpResult;
+	uint32_t tmp;
 	int ret = 0;
 
 	if (als_step == NULL)
@@ -294,22 +270,20 @@
 	/* Read ALS data: */
 	ret = _cm36283_I2C_Read_Word(lpi->slave_addr, ALS_DATA, als_step);
 	if (ret < 0) {
-		pr_err(
-			"[LS][CM3218 error]%s: _cm36283_I2C_Read_Word fail\n",
-			__func__);
+		dev_err(&lpi->i2c_client->dev, "%s: I2C read word failed.\n",
+				__func__);
 		return -EIO;
 	}
 
-  if (!lpi->ls_calibrate) {
-		tmpResult = (uint32_t)(*als_step) * lpi->als_gadc / lpi->als_kadc;
-		if (tmpResult > 0xFFFF)
+	if (!lpi->ls_calibrate) {
+		tmp = (uint32_t)(*als_step) * lpi->als_gadc / lpi->als_kadc;
+		if (tmp > 0xFFFF)
 			*als_step = 0xFFFF;
 		else
-		  *als_step = tmpResult;  			
+			*als_step = tmp;
 	}
 
-	D("[LS][CM3218] %s: raw adc = 0x%X, ls_calibrate = %d\n",
-		__func__, *als_step, lpi->ls_calibrate);
+	dev_dbg(&lpi->i2c_client->dev, "raw adc = 0x%x\n", *als_step);
 
 	return ret;
 }
@@ -335,18 +309,10 @@
 
 	ret = _cm36283_I2C_Read_Word(lpi->slave_addr, PS_DATA, data);
 	
+	if (ret < 0)
+		return ret;
+
 	(*data) &= 0xFF;
-	
-	if (ret < 0) {
-		pr_err(
-			"[PS][CM36283 error]%s: _cm36283_I2C_Read_Word fail\n",
-			__func__);
-		return -EIO;
-	} else {
-		pr_err(
-			"[PS][CM36283 OK]%s: _cm36283_I2C_Read_Word OK 0x%x\n",
-			__func__, *data);
-	}
 
 	return ret;
 }
@@ -383,16 +349,16 @@
 			msleep(10);
 			wait_count++;
 			if (wait_count > 12) {
-				pr_err("[PS_ERR][CM36283 error]%s: interrupt GPIO low,"
-					" get_ps_adc_value\n", __func__);
+				dev_err(&lpi->i2c_client->dev, "%s: interrupt GPIO low\n",
+					       __func__);
 				return -EIO;
 			}
 		}
 
 		ret = get_ps_adc_value(&value[i]);
 		if (ret < 0) {
-			pr_err("[PS_ERR][CM36283 error]%s: get_ps_adc_value\n",
-				__func__);
+			dev_err(&lpi->i2c_client->dev,
+					"%s: error get ps value\n", __func__);
 			return -EIO;
 		}
 
@@ -402,10 +368,8 @@
 		wait_count = 0;
 	}
 
-	/*D("Sta_ps: Before sort, value[0, 1, 2] = [0x%x, 0x%x, 0x%x]",
-		value[0], value[1], value[2]);*/
 	mid_val = mid_value(value, 3);
-	D("Sta_ps: After sort, value[0, 1, 2] = [0x%x, 0x%x, 0x%x]",
+	dev_dbg(&lpi->i2c_client->dev, "Sta_ps: After sort, value[0, 1, 2] = [0x%x, 0x%x, 0x%x]",
 		value[0], value[1], value[2]);
 	*ps_adc = (mid_val & 0xFF);
 
@@ -531,14 +495,16 @@
 
 static void psensor_initial_cmd(struct cm36283_info *lpi)
 {
-	/*must disable p-sensor interrupt befrore IST create*//*disable ALS func*/		
-  lpi->ps_conf1_val |= CM36283_PS_SD;
-  lpi->ps_conf1_val &= CM36283_PS_INT_MASK;  
-  _cm36283_I2C_Write_Word(lpi->slave_addr, PS_CONF1, lpi->ps_conf1_val);   
-  _cm36283_I2C_Write_Word(lpi->slave_addr, PS_CONF3, lpi->ps_conf3_val);
-  _cm36283_I2C_Write_Word(lpi->slave_addr, PS_THD, (lpi->ps_close_thd_set <<8)| lpi->ps_away_thd_set);
+	/*must disable p-sensor interrupt befrore IST create*/
+	lpi->ps_conf1_val |= CM36283_PS_SD;
+	lpi->ps_conf1_val &= CM36283_PS_INT_MASK;
+	_cm36283_I2C_Write_Word(lpi->slave_addr, PS_CONF1, lpi->ps_conf1_val);
+	_cm36283_I2C_Write_Word(lpi->slave_addr, PS_CONF3, lpi->ps_conf3_val);
+	_cm36283_I2C_Write_Word(lpi->slave_addr, PS_THD,
+			(lpi->ps_close_thd_set << 8) | lpi->ps_away_thd_set);
 
-	D("[PS][CM36283] %s, finish\n", __func__);	
+	dev_dbg(&lpi->i2c_client->dev,
+			"%s:send psensor initial command finished\n", __func__);
 }
 
 static int psensor_enable(struct cm36283_info *lpi)
@@ -547,10 +513,10 @@
 	unsigned int delay;
 	
 	mutex_lock(&ps_enable_mutex);
-	D("[PS][CM36283] %s\n", __func__);
+	dev_dbg(&lpi->i2c_client->dev, "psensor enable!\n");
 
 	if (lpi->ps_enable) {
-		D("[PS][CM36283] %s: already enabled\n", __func__);
+		dev_err(&lpi->i2c_client->dev, "already enabled\n");
 		ret = 0;
 	} else {
 		ret = control_and_report(lpi, CONTROL_PS, 1, 0);
@@ -573,10 +539,10 @@
 		cancel_delayed_work_sync(&lpi->pdwork);
 
 	mutex_lock(&ps_disable_mutex);
-	D("[PS][CM36283] %s\n", __func__);
+	dev_dbg(&lpi->i2c_client->dev, "psensor disable!\n");
 
 	if (lpi->ps_enable == 0) {
-		D("[PS][CM36283] %s: already disabled\n", __func__);
+		dev_err(&lpi->i2c_client->dev, "already disabled\n");
 		ret = 0;
 	} else {
 		ret = control_and_report(lpi, CONTROL_PS, 0, 0);
@@ -590,7 +556,7 @@
 {
 	struct cm36283_info *lpi = lp_info;
 
-	D("[PS][CM36283] %s\n", __func__);
+	dev_dbg(&lpi->i2c_client->dev, "psensor open!");
 
 	if (lpi->psensor_opened)
 		return -EBUSY;
@@ -604,7 +570,7 @@
 {
 	struct cm36283_info *lpi = lp_info;
 
-	D("[PS][CM36283] %s\n", __func__);
+	dev_dbg(&lpi->i2c_client->dev, "psensor release!");
 
 	lpi->psensor_opened = 0;
 
@@ -618,7 +584,7 @@
 	int val;
 	struct cm36283_info *lpi = lp_info;
 
-	D("[PS][CM36283] %s cmd %d\n", __func__, _IOC_NR(cmd));
+	dev_dbg(&lpi->i2c_client->dev, "%s cmd %d\n", __func__, _IOC_NR(cmd));
 
 	switch (cmd) {
 	case CAPELLA_CM3602_IOCTL_ENABLE:
@@ -633,7 +599,7 @@
 		return put_user(lpi->ps_enable, (unsigned long __user *)arg);
 		break;
 	default:
-		pr_err("[PS][CM36283 error]%s: invalid cmd %d\n",
+		dev_err(&lpi->i2c_client->dev, "%s: invalid cmd %d\n",
 			__func__, _IOC_NR(cmd));
 		return -EINVAL;
 	}
@@ -655,18 +621,19 @@
 void lightsensor_set_kvalue(struct cm36283_info *lpi)
 {
 	if (!lpi) {
-		pr_err("[LS][CM36283 error]%s: ls_info is empty\n", __func__);
+		pr_err("%s: ls_info is empty\n", __func__);
 		return;
 	}
 
-	D("[LS][CM36283] %s: ALS calibrated als_kadc=0x%x\n",
+	dev_dbg(&lpi->i2c_client->dev, "%s: ALS calibrated als_kadc=0x%x\n",
 			__func__, als_kadc);
 
 	if (als_kadc >> 16 == ALS_CALIBRATED)
 		lpi->als_kadc = als_kadc & 0xFFFF;
 	else {
 		lpi->als_kadc = 0;
-		D("[LS][CM36283] %s: no ALS calibrated\n", __func__);
+		dev_dbg(&lpi->i2c_client->dev, "%s: no ALS calibrated\n",
+				__func__);
 	}
 
 	if (lpi->als_kadc && lpi->golden_adc > 0) {
@@ -677,25 +644,26 @@
 		lpi->als_kadc = 1;
 		lpi->als_gadc = 1;
 	}
-	D("[LS][CM36283] %s: als_kadc=0x%x, als_gadc=0x%x\n",
+	dev_dbg(&lpi->i2c_client->dev, "%s: als_kadc=0x%x, als_gadc=0x%x\n",
 		__func__, lpi->als_kadc, lpi->als_gadc);
 }
 
 
 static int lightsensor_update_table(struct cm36283_info *lpi)
 {
-	uint32_t tmpData[10];
+	uint32_t tmp_data[10];
 	int i;
 	for (i = 0; i < 10; i++) {
-		tmpData[i] = (uint32_t)(*(lpi->adc_table + i))
-				* lpi->als_kadc / lpi->als_gadc ;
-		if( tmpData[i] <= 0xFFFF ){
-      lpi->cali_table[i] = (uint16_t) tmpData[i];		
-    } else {
-      lpi->cali_table[i] = 0xFFFF;    
-    }         
-		D("[LS][CM36283] %s: Calibrated adc_table: data[%d], %x\n",
-			__func__, i, lpi->cali_table[i]);
+		tmp_data[i] = (uint32_t)(*(lpi->adc_table + i))
+			* lpi->als_kadc / lpi->als_gadc;
+
+		if (tmp_data[i] <= 0xFFFF)
+			lpi->cali_table[i] = (uint16_t) tmp_data[i];
+		else
+			lpi->cali_table[i] = 0xFFFF;
+
+		dev_dbg(&lpi->i2c_client->dev, "%s: Calibrated adc_table: data[%d], %x\n",
+				__func__, i, lpi->cali_table[i]);
 	}
 
 	return 0;
@@ -708,10 +676,10 @@
 	unsigned int delay;
 	
 	mutex_lock(&als_enable_mutex);
-	D("[LS][CM36283] %s\n", __func__);
 
 	if (lpi->als_enable) {
-		D("[LS][CM36283] %s: already enabled\n", __func__);
+		dev_err(&lpi->i2c_client->dev, "%s: already enabled\n",
+			       __func__);
 		ret = 0;
 	} else {
 		ret = control_and_report(lpi, CONTROL_ALS, 1, 0);
@@ -731,13 +699,13 @@
 {
 	int ret = -EIO;
 	mutex_lock(&als_disable_mutex);
-	D("[LS][CM36283] %s\n", __func__);
+	dev_dbg(&lpi->i2c_client->dev, "disable lightsensor\n");
 
 	if (lpi->polling)
 		cancel_delayed_work_sync(&lpi->ldwork);
 
 	if ( lpi->als_enable == 0 ) {
-		D("[LS][CM36283] %s: already disabled\n", __func__);
+		dev_err(&lpi->i2c_client->dev, "already disabled\n");
 		ret = 0;
 	} else {
 		ret = control_and_report(lpi, CONTROL_ALS, 0, 0);
@@ -752,9 +720,10 @@
 	struct cm36283_info *lpi = lp_info;
 	int rc = 0;
 
-	D("[LS][CM36283] %s\n", __func__);
+	dev_dbg(&lpi->i2c_client->dev, "%s\n", __func__);
 	if (lpi->lightsensor_opened) {
-		pr_err("[LS][CM36283 error]%s: already opened\n", __func__);
+		dev_err(&lpi->i2c_client->dev, "%s: already opened\n",
+				__func__);
 		rc = -EBUSY;
 	}
 	lpi->lightsensor_opened = 1;
@@ -765,7 +734,7 @@
 {
 	struct cm36283_info *lpi = lp_info;
 
-	D("[LS][CM36283] %s\n", __func__);
+	dev_dbg(&lpi->i2c_client->dev, "%s\n", __func__);
 	lpi->lightsensor_opened = 0;
 	return 0;
 }
@@ -776,22 +745,16 @@
 	int rc, val;
 	struct cm36283_info *lpi = lp_info;
 
-	/*D("[CM36283] %s cmd %d\n", __func__, _IOC_NR(cmd));*/
-
 	switch (cmd) {
 	case LIGHTSENSOR_IOCTL_ENABLE:
 		if (get_user(val, (unsigned long __user *)arg)) {
 			rc = -EFAULT;
 			break;
 		}
-		D("[LS][CM36283] %s LIGHTSENSOR_IOCTL_ENABLE, value = %d\n",
-			__func__, val);
 		rc = val ? lightsensor_enable(lpi) : lightsensor_disable(lpi);
 		break;
 	case LIGHTSENSOR_IOCTL_GET_ENABLED:
 		val = lpi->als_enable;
-		D("[LS][CM36283] %s LIGHTSENSOR_IOCTL_GET_ENABLED, enabled %d\n",
-			__func__, val);
 		rc = put_user(val, (unsigned long __user *)arg);
 		break;
 	default:
@@ -850,29 +813,28 @@
 		&& ps_en != 10 && ps_en != 13 && ps_en != 16)
 		return -EINVAL;
 
-	if (ps_en) {
-		D("[PS][CM36283] %s: ps_en=%d\n",
+	dev_dbg(&lpi->i2c_client->dev, "%s: ps_en=%d\n",
 			__func__, ps_en);
-		psensor_enable(lpi);
-	} else
-		psensor_disable(lpi);
 
-	D("[PS][CM36283] %s\n", __func__);
+	if (ps_en)
+		psensor_enable(lpi);
+	else
+		psensor_disable(lpi);
 
 	return count;
 }
 
 static DEVICE_ATTR(ps_adc, 0664, ps_adc_show, ps_enable_store);
 
-unsigned PS_cmd_test_value;
 static ssize_t ps_parameters_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
 	int ret;
 	struct cm36283_info *lpi = lp_info;
 
-	ret = sprintf(buf, "PS_close_thd_set = 0x%x, PS_away_thd_set = 0x%x, PS_cmd_cmd:value = 0x%x\n",
-		lpi->ps_close_thd_set, lpi->ps_away_thd_set, PS_cmd_test_value);
+	ret = snprintf(buf, PAGE_SIZE,
+			"PS_close_thd_set = 0x%x, PS_away_thd_set = 0x%x\n",
+			lpi->ps_close_thd_set, lpi->ps_away_thd_set);
 
 	return ret;
 }
@@ -885,19 +847,23 @@
 	struct cm36283_info *lpi = lp_info;
 	char *token[10];
 	int i;
+	unsigned long tmp;
 
-	printk(KERN_INFO "[PS][CM36283] %s\n", buf);
 	for (i = 0; i < 3; i++)
 		token[i] = strsep((char **)&buf, " ");
 
-	lpi->ps_close_thd_set = simple_strtoul(token[0], NULL, 16);
-	lpi->ps_away_thd_set = simple_strtoul(token[1], NULL, 16);	
-	PS_cmd_test_value = simple_strtoul(token[2], NULL, 16);
-	printk(KERN_INFO
-		"[PS][CM36283]Set PS_close_thd_set = 0x%x, PS_away_thd_set = 0x%x, PS_cmd_cmd:value = 0x%x\n",
-		lpi->ps_close_thd_set, lpi->ps_away_thd_set, PS_cmd_test_value);
+	if (kstrtoul(token[0], 16, &tmp))
+		return -EINVAL;
+	lpi->ps_close_thd_set = tmp;
 
-	D("[PS][CM36283] %s\n", __func__);
+	if (kstrtoul(token[1], 16, &tmp))
+		return -EINVAL;
+	lpi->ps_away_thd_set = tmp;
+
+	dev_dbg(&lpi->i2c_client->dev, "ps_close_thd_set:0x%x\n",
+			lpi->ps_close_thd_set);
+	dev_dbg(&lpi->i2c_client->dev, "ps_away_thd_set:0x%x\n",
+			lpi->ps_away_thd_set);
 
 	return count;
 }
@@ -920,14 +886,14 @@
 	struct cm36283_info *lpi = lp_info;
 
 	sscanf(buf, "0x%x 0x%x", &code1, &code2);
+	dev_dbg(&lpi->i2c_client->dev, "PS_CONF1:0x%x PS_CONF3:0x%x\n",
+			code1, code2);
 
-	D("[PS]%s: store value PS conf1 reg = 0x%x PS conf3 reg = 0x%x\n", __func__, code1, code2);
+	lpi->ps_conf1_val = code1;
+	lpi->ps_conf3_val = code2;
 
-  lpi->ps_conf1_val = code1;
-  lpi->ps_conf3_val = code2;
-
-	_cm36283_I2C_Write_Word(lpi->slave_addr, PS_CONF3, lpi->ps_conf3_val );  
-	_cm36283_I2C_Write_Word(lpi->slave_addr, PS_CONF1, lpi->ps_conf1_val );
+	_cm36283_I2C_Write_Word(lpi->slave_addr, PS_CONF3, lpi->ps_conf3_val);
+	_cm36283_I2C_Write_Word(lpi->slave_addr, PS_CONF1, lpi->ps_conf1_val);
 
 	return count;
 }
@@ -950,12 +916,13 @@
 
 	sscanf(buf, "0x%x", &code);
 
-	D("[PS]%s: store value = 0x%x\n", __func__, code);
-
 	lpi->ps_away_thd_set = code &0xFF;
-	lpi->ps_close_thd_set = (code &0xFF00)>>8;	
+	lpi->ps_close_thd_set = (code & 0xFF00)>>8;
 
-	D("[PS]%s: ps_close_thd_set = 0x%x, ps_away_thd_set = 0x%x\n", __func__, lpi->ps_close_thd_set, lpi->ps_away_thd_set);
+	dev_dbg(&lpi->i2c_client->dev, "ps_away_thd_set:0x%x\n",
+			lpi->ps_away_thd_set);
+	dev_dbg(&lpi->i2c_client->dev, "ps_close_thd_set:0x%x\n",
+			lpi->ps_close_thd_set);
 
 	return count;
 }
@@ -977,12 +944,9 @@
 				const char *buf, size_t count)
 {
 	int code;
-//	struct cm36283_info *lpi = lp_info;
 
 	sscanf(buf, "0x%x", &code);
 
-	D("[PS]%s: store value = 0x%x\n", __func__, code);
-
 	return count;
 }
 static DEVICE_ATTR(ps_hw, 0664, ps_hw_show, ps_hw_store);
@@ -993,8 +957,6 @@
 	int ret;
 	struct cm36283_info *lpi = lp_info;
 
-	D("[LS][CM36283] %s: ADC = 0x%04X, Level = %d \n",
-		__func__, lpi->current_adc, lpi->current_level);
 	ret = sprintf(buf, "ADC[0x%04X] => level %d\n",
 		lpi->current_adc, lpi->current_level);
 
@@ -1038,12 +1000,14 @@
 		ret = lightsensor_disable(lpi);
 	}
 
-	D("[LS][CM36283] %s: lpi->als_enable = %d, lpi->ls_calibrate = %d, ls_auto=%d\n",
-		__func__, lpi->als_enable, lpi->ls_calibrate, ls_auto);
+	dev_dbg(&lpi->i2c_client->dev, "als_enable:0x%x\n",
+			lpi->als_enable);
+	dev_dbg(&lpi->i2c_client->dev, "ls_calibrate:0x%x\n",
+			lpi->ls_calibrate);
+	dev_dbg(&lpi->i2c_client->dev, "ls_auto:0x%x\n", ls_auto);
 
 	if (ret < 0)
-		pr_err(
-		"[LS][CM36283 error]%s: set auto light sensor fail\n",
+		dev_err(&lpi->i2c_client->dev, "%s: set auto light sensor fail\n",
 		__func__);
 
 	return count;
@@ -1074,17 +1038,18 @@
 	sscanf(buf, "%d", &kadc_temp);
 
 	mutex_lock(&als_get_adc_mutex);
-  if(kadc_temp != 0) {
+	if (kadc_temp != 0) {
 		lpi->als_kadc = kadc_temp;
-		if(  lpi->als_gadc != 0){
-  		if (lightsensor_update_table(lpi) < 0)
-				printk(KERN_ERR "[LS][CM36283 error] %s: update ls table fail\n", __func__);
-  	} else {
-			printk(KERN_INFO "[LS]%s: als_gadc =0x%x wait to be set\n",
-					__func__, lpi->als_gadc);
-  	}		
+		if (lpi->als_gadc != 0) {
+			if (lightsensor_update_table(lpi) < 0)
+				dev_err(&lpi->i2c_client->dev, "%s: update ls table fail\n",
+						__func__);
+			else
+				dev_dbg(&lpi->i2c_client->dev, "%s: als_gadc =0x%x wait to be set\n",
+						__func__, lpi->als_gadc);
+		}
 	} else {
-		printk(KERN_INFO "[LS]%s: als_kadc can't be set to zero\n",
+		dev_err(&lpi->i2c_client->dev, "%s: als_kadc can't be set to zero\n",
 				__func__);
 	}
 				
@@ -1115,18 +1080,18 @@
 	sscanf(buf, "%d", &gadc_temp);
 	
 	mutex_lock(&als_get_adc_mutex);
-  if(gadc_temp != 0) {
+	if (gadc_temp != 0) {
 		lpi->als_gadc = gadc_temp;
-		if(  lpi->als_kadc != 0){
-  		if (lightsensor_update_table(lpi) < 0)
-				printk(KERN_ERR "[LS][CM36283 error] %s: update ls table fail\n", __func__);
-  	} else {
-			printk(KERN_INFO "[LS]%s: als_kadc =0x%x wait to be set\n",
-					__func__, lpi->als_kadc);
-  	}		
+		if (lpi->als_kadc != 0) {
+			if (lightsensor_update_table(lpi) < 0)
+				dev_err(&lpi->i2c_client->dev, "%s: update ls table fail\n",
+						__func__);
+		} else {
+			dev_dbg(&lpi->i2c_client->dev, "als_kadc =0x%x wait to be set\n",
+					lpi->als_kadc);
+		}
 	} else {
-		printk(KERN_INFO "[LS]%s: als_gadc can't be set to zero\n",
-				__func__);
+		dev_err(&lpi->i2c_client->dev, "als_gadc can't be set to zero\n");
 	}
 	mutex_unlock(&als_get_adc_mutex);
 	return count;
@@ -1161,29 +1126,24 @@
 	uint16_t tempdata[10];
 	int i;
 
-	printk(KERN_INFO "[LS][CM36283]%s\n", buf);
 	for (i = 0; i < 10; i++) {
 		token[i] = strsep((char **)&buf, " ");
 		tempdata[i] = simple_strtoul(token[i], NULL, 16);
 		if (tempdata[i] < 1 || tempdata[i] > 0xffff) {
-			printk(KERN_ERR
-			"[LS][CM36283 error] adc_table[%d] =  0x%x Err\n",
+			dev_err(&lpi->i2c_client->dev,
+			"adc_table[%d] =  0x%x error\n",
 			i, tempdata[i]);
 			return count;
 		}
 	}
 	mutex_lock(&als_get_adc_mutex);
-	for (i = 0; i < 10; i++) {
+	for (i = 0; i < 10; i++)
 		lpi->adc_table[i] = tempdata[i];
-		printk(KERN_INFO
-		"[LS][CM36283]Set lpi->adc_table[%d] =  0x%x\n",
-		i, *(lp_info->adc_table + i));
-	}
+
 	if (lightsensor_update_table(lpi) < 0)
-		printk(KERN_ERR "[LS][CM36283 error] %s: update ls table fail\n",
+		dev_err(&lpi->i2c_client->dev, "%s: update ls table fail\n",
 		__func__);
 	mutex_unlock(&als_get_adc_mutex);
-	D("[LS][CM36283] %s\n", __func__);
 
 	return count;
 }
@@ -1206,8 +1166,9 @@
 	sscanf(buf, "0x%x", &value);
 
 	lpi->ls_cmd = value;
-	printk(KERN_INFO "[LS]set ALS_CONF = %x\n", lpi->ls_cmd);
-	
+
+	dev_dbg(&lpi->i2c_client->dev, "ALS_CONF:0x%x\n", lpi->ls_cmd);
+
 	_cm36283_I2C_Write_Word(lpi->slave_addr, ALS_CONF, lpi->ls_cmd);
 	return count;
 }
@@ -1285,7 +1246,6 @@
 	fLevel=value;
 	input_report_abs(lpi->ls_input_dev, ABS_MISC, fLevel);
 	input_sync(lpi->ls_input_dev);
-	printk(KERN_INFO "[LS]set fLevel = %d\n", fLevel);
 
 	msleep(1000);
 	fLevel=-1;
@@ -1381,7 +1341,8 @@
 	uint16_t idReg;
 
 	val = gpio_get_value(lpi->intr_pin);
-	D("[PS][CM36283] %s, INTERRUPT GPIO val = %d\n", __func__, val);
+	dev_dbg(&lpi->i2c_client->dev, "%s, INTERRUPT GPIO val = %d\n",
+		       __func__, val);
 
 	ret = _cm36283_I2C_Read_Word(lpi->slave_addr, ID_REG, &idReg);
 
@@ -1545,15 +1506,10 @@
 	struct cm36283_info *lpi;
 	struct cm36283_platform_data *pdata;
 
-	D("[PS][CM36283] %s\n", __func__);
-
-
 	lpi = kzalloc(sizeof(struct cm36283_info), GFP_KERNEL);
 	if (!lpi)
 		return -ENOMEM;
 
-	/*D("[CM36283] %s: client->irq = %d\n", __func__, client->irq);*/
-
 	lpi->i2c_client = client;
 
 	if (client->dev.of_node) {
@@ -1605,7 +1561,7 @@
 	
 	lpi->record_clear_int_fail=0;
 	
-	D("[PS][CM36283] %s: ls_cmd 0x%x\n",
+	dev_dbg(&lpi->i2c_client->dev, "[PS][CM36283] %s: ls_cmd 0x%x\n",
 		__func__, lpi->ls_cmd);
 	
 	if (pdata->ls_cmd == 0) {
@@ -1777,7 +1733,7 @@
 	mutex_init(&wq_lock);
 	INIT_DELAYED_WORK(&lpi->ldwork, lsensor_delay_work_handler);
 	INIT_DELAYED_WORK(&lpi->pdwork, psensor_delay_work_handler);
-	D("[PS][CM36283] %s: Probe success!\n", __func__);
+	dev_dbg(&lpi->i2c_client->dev, "%s: Probe success!\n", __func__);
 
 	return ret;
 
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 6324dff..8e70129 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -45,10 +45,22 @@
 
 	  If unsure, say N here.
 
+# MSM IOMMU sync lock support
+config MSM_IOMMU_SYNC
+	bool "MSM IOMMU Sync Lock Support"
+	depends on (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8930 || ARCH_MSM8610) && MSM_IOMMU_V0
+	help
+	  Say Y here if you want the IOMMU to grab a remote spinlock to ensure
+	  synchronization between IOMMU accesses by CPU and other exectution
+	  environments in the SoC.
+
+	  If unsure, say N here.
+
 # 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_V0 && MSM_REMOTE_SPINLOCK_SFPB
+	depends on (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8930) && MSM_IOMMU_V0
+	select  MSM_IOMMU_SYNC
 	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
diff --git a/drivers/iommu/msm_iommu-v0.c b/drivers/iommu/msm_iommu-v0.c
index 49bfdb8..99d071b 100644
--- a/drivers/iommu/msm_iommu-v0.c
+++ b/drivers/iommu/msm_iommu-v0.c
@@ -83,7 +83,7 @@
 
 static struct msm_iommu_remote_lock msm_iommu_remote_lock;
 
-#ifdef CONFIG_MSM_IOMMU_GPU_SYNC
+#ifdef CONFIG_MSM_IOMMU_SYNC
 static void _msm_iommu_remote_spin_lock_init(void)
 {
 	msm_iommu_remote_lock.lock = smem_alloc(SMEM_SPINLOCK_ARRAY, 32);
@@ -91,8 +91,11 @@
 			sizeof(*msm_iommu_remote_lock.lock));
 }
 
-void msm_iommu_remote_p0_spin_lock(void)
+void msm_iommu_remote_p0_spin_lock(unsigned int need_lock)
 {
+	if (!need_lock)
+		return;
+
 	msm_iommu_remote_lock.lock->flag[PROC_APPS] = 1;
 	msm_iommu_remote_lock.lock->turn = 1;
 
@@ -103,8 +106,11 @@
 		cpu_relax();
 }
 
-void msm_iommu_remote_p0_spin_unlock(void)
+void msm_iommu_remote_p0_spin_unlock(unsigned int need_lock)
 {
+	if (!need_lock)
+		return;
+
 	smp_mb();
 
 	msm_iommu_remote_lock.lock->flag[PROC_APPS] = 0;
@@ -200,14 +206,16 @@
 	return msm_iommu_lock_initialize();
 }
 
-static void _iommu_lock_acquire(void)
+static void _iommu_lock_acquire(unsigned int need_extra_lock)
 {
-	msm_iommu_lock();
+	msm_iommu_mutex_lock();
+	msm_iommu_remote_spin_lock(need_extra_lock);
 }
 
-static void _iommu_lock_release(void)
+static void _iommu_lock_release(unsigned int need_extra_lock)
 {
-	msm_iommu_unlock();
+	msm_iommu_remote_spin_unlock(need_extra_lock);
+	msm_iommu_mutex_unlock();
 }
 
 struct iommu_access_ops iommu_access_ops_v0 = {
@@ -241,7 +249,7 @@
 		if (ret)
 			goto fail;
 
-		msm_iommu_remote_spin_lock();
+		msm_iommu_remote_spin_lock(iommu_drvdata->needs_rem_spinlock);
 
 		asid = GET_CONTEXTIDR_ASID(iommu_drvdata->base,
 					   ctx_drvdata->num);
@@ -250,7 +258,7 @@
 			   asid | (va & TLBIVA_VA));
 		mb();
 
-		msm_iommu_remote_spin_unlock();
+		msm_iommu_remote_spin_unlock(iommu_drvdata->needs_rem_spinlock);
 
 		__disable_clocks(iommu_drvdata);
 	}
@@ -278,7 +286,7 @@
 		if (ret)
 			goto fail;
 
-		msm_iommu_remote_spin_lock();
+		msm_iommu_remote_spin_lock(iommu_drvdata->needs_rem_spinlock);
 
 		asid = GET_CONTEXTIDR_ASID(iommu_drvdata->base,
 					   ctx_drvdata->num);
@@ -286,7 +294,7 @@
 		SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num, asid);
 		mb();
 
-		msm_iommu_remote_spin_unlock();
+		msm_iommu_remote_spin_unlock(iommu_drvdata->needs_rem_spinlock);
 
 		__disable_clocks(iommu_drvdata);
 	}
@@ -318,13 +326,16 @@
 	mb();
 }
 
-static void __program_context(void __iomem *base, void __iomem *glb_base,
+static void __program_context(struct msm_iommu_drvdata *iommu_drvdata,
 			      int ctx, int ncb, phys_addr_t pgtable,
 			      int redirect, int ttbr_split)
 {
+	void __iomem *base = iommu_drvdata->base;
+	void __iomem *glb_base = iommu_drvdata->glb_base;
 	unsigned int prrr, nmrr;
 	int i, j, found;
-	msm_iommu_remote_spin_lock();
+
+	msm_iommu_remote_spin_lock(iommu_drvdata->needs_rem_spinlock);
 
 	__reset_context(base, glb_base, ctx);
 
@@ -416,7 +427,7 @@
 	SET_M(base, ctx, 1);
 	mb();
 
-	msm_iommu_remote_spin_unlock();
+	msm_iommu_remote_spin_unlock(iommu_drvdata->needs_rem_spinlock);
 }
 
 static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
@@ -526,7 +537,7 @@
 	if (ret)
 		goto unlock;
 
-	__program_context(iommu_drvdata->base, iommu_drvdata->glb_base,
+	__program_context(iommu_drvdata,
 			  ctx_drvdata->num, iommu_drvdata->ncb,
 			  __pa(priv->pt.fl_table), priv->pt.redirect,
 			  iommu_drvdata->ttbr_split);
@@ -577,7 +588,7 @@
 	if (ret)
 		goto unlock;
 
-	msm_iommu_remote_spin_lock();
+	msm_iommu_remote_spin_lock(iommu_drvdata->needs_rem_spinlock);
 
 	SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num,
 		    GET_CONTEXTIDR_ASID(iommu_drvdata->base, ctx_drvdata->num));
@@ -585,7 +596,7 @@
 	__reset_context(iommu_drvdata->base, iommu_drvdata->glb_base,
 			ctx_drvdata->num);
 
-	msm_iommu_remote_spin_unlock();
+	msm_iommu_remote_spin_unlock(iommu_drvdata->needs_rem_spinlock);
 
 	__disable_clocks(iommu_drvdata);
 
@@ -1246,7 +1257,7 @@
 	if (ret)
 		goto fail;
 
-	msm_iommu_remote_spin_lock();
+	msm_iommu_remote_spin_lock(iommu_drvdata->needs_rem_spinlock);
 
 	SET_V2PPR(base, ctx, va & V2Pxx_VA);
 
@@ -1262,7 +1273,7 @@
 	if (GET_FAULT(base, ctx))
 		ret = 0;
 
-	msm_iommu_remote_spin_unlock();
+	msm_iommu_remote_spin_unlock(iommu_drvdata->needs_rem_spinlock);
 
 	__disable_clocks(iommu_drvdata);
 fail:
@@ -1324,7 +1335,7 @@
 	if (ret)
 		goto fail;
 
-	msm_iommu_remote_spin_lock();
+	msm_iommu_remote_spin_lock(drvdata->needs_rem_spinlock);
 
 	fsr = GET_FSR(base, num);
 
@@ -1357,7 +1368,7 @@
 	} else
 		ret = IRQ_NONE;
 
-	msm_iommu_remote_spin_unlock();
+	msm_iommu_remote_spin_unlock(drvdata->needs_rem_spinlock);
 
 	__disable_clocks(drvdata);
 fail:
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index b9c4cae..c81aa0ac 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -123,12 +123,12 @@
 	clk_disable_unprepare(drvdata->pclk);
 }
 
-static void _iommu_lock_acquire(void)
+static void _iommu_lock_acquire(unsigned int need_extra_lock)
 {
 	mutex_lock(&msm_iommu_lock);
 }
 
-static void _iommu_lock_release(void)
+static void _iommu_lock_release(unsigned int need_extra_lock)
 {
 	mutex_unlock(&msm_iommu_lock);
 }
diff --git a/drivers/iommu/msm_iommu_dev-v0.c b/drivers/iommu/msm_iommu_dev-v0.c
index 2d0fba2..9382e52 100644
--- a/drivers/iommu/msm_iommu_dev-v0.c
+++ b/drivers/iommu/msm_iommu_dev-v0.c
@@ -216,6 +216,12 @@
 	drvdata->sec_id = -1;
 	drvdata->ttbr_split = 0;
 
+	drvdata->needs_rem_spinlock = of_property_read_bool(pdev->dev.of_node,
+					"qcom,msm-enable-remote-spinlock");
+
+	if (drvdata->needs_rem_spinlock)
+		pr_info("%s enabled remote spinlock\n", drvdata->name);
+
 	ret = of_platform_populate(pdev->dev.of_node,
 				   msm_iommu_v0_ctx_match_table,
 				   NULL, &pdev->dev);
diff --git a/drivers/iommu/msm_iommu_perfmon-v0.c b/drivers/iommu/msm_iommu_perfmon-v0.c
index 1073623..b08a9ec 100644
--- a/drivers/iommu/msm_iommu_perfmon-v0.c
+++ b/drivers/iommu/msm_iommu_perfmon-v0.c
@@ -176,9 +176,9 @@
 		goto out;
 	}
 
-	iommu->ops->iommu_lock_acquire();
+	iommu->ops->iommu_lock_acquire(1);
 	iommu_pm_check_for_overflow(pmon);
-	iommu->ops->iommu_lock_release();
+	iommu->ops->iommu_lock_release(1);
 
 	mutex_unlock(&pmon->lock);
 
diff --git a/drivers/iommu/msm_iommu_perfmon-v1.c b/drivers/iommu/msm_iommu_perfmon-v1.c
index 7d6dd34..2b55184 100644
--- a/drivers/iommu/msm_iommu_perfmon-v1.c
+++ b/drivers/iommu/msm_iommu_perfmon-v1.c
@@ -151,9 +151,9 @@
 		goto out;
 	}
 
-	iommu->ops->iommu_lock_acquire();
+	iommu->ops->iommu_lock_acquire(0);
 	iommu_pm_check_for_overflow(pmon);
-	iommu->ops->iommu_lock_release();
+	iommu->ops->iommu_lock_release(0);
 
 	mutex_unlock(&pmon->lock);
 
diff --git a/drivers/iommu/msm_iommu_perfmon.c b/drivers/iommu/msm_iommu_perfmon.c
index 958c6ca..503d4ab 100644
--- a/drivers/iommu/msm_iommu_perfmon.c
+++ b/drivers/iommu/msm_iommu_perfmon.c
@@ -188,11 +188,11 @@
 
 	if (event_class == MSM_IOMMU_PMU_NO_EVENT_CLASS) {
 		if (iommu->hw_ops->is_hw_access_OK(pmon)) {
-			iommu->ops->iommu_lock_acquire();
+			iommu->ops->iommu_lock_acquire(1);
 			iommu->hw_ops->counter_disable(iommu, counter);
 			iommu->hw_ops->ovfl_int_disable(iommu, counter);
 			iommu->hw_ops->set_event_class(pmon, count_no, 0);
-			iommu->ops->iommu_lock_release();
+			iommu->ops->iommu_lock_release(1);
 		}
 		counter->overflow_count = 0;
 		counter->value = 0;
@@ -200,12 +200,12 @@
 		counter->overflow_count = 0;
 		counter->value = 0;
 		if (iommu->hw_ops->is_hw_access_OK(pmon)) {
-			iommu->ops->iommu_lock_acquire();
+			iommu->ops->iommu_lock_acquire(1);
 			iommu->hw_ops->set_event_class(pmon, count_no,
 					event_class);
 			iommu->hw_ops->ovfl_int_enable(iommu, counter);
 			iommu->hw_ops->counter_enable(iommu, counter);
-			iommu->ops->iommu_lock_release();
+			iommu->ops->iommu_lock_release(1);
 		}
 	}
 }
@@ -261,9 +261,9 @@
 	iommu->ops->iommu_clk_on(iommu_drvdata);
 
 	/* Reset counters in HW */
-	iommu->ops->iommu_lock_acquire();
+	iommu->ops->iommu_lock_acquire(1);
 	iommu->hw_ops->reset_counters(&pmon->iommu);
-	iommu->ops->iommu_lock_release();
+	iommu->ops->iommu_lock_release(1);
 
 	/* Reset SW counters */
 	iommu_pm_reset_counts(pmon);
@@ -272,7 +272,7 @@
 
 	iommu_pm_set_all_counters(pmon);
 
-	iommu->ops->iommu_lock_acquire();
+	iommu->ops->iommu_lock_acquire(1);
 
 	/* enable all counter group */
 	for (i = 0; i < pmon->num_groups; ++i)
@@ -280,7 +280,7 @@
 
 	/* enable global counters */
 	iommu->hw_ops->enable_pm(iommu);
-	iommu->ops->iommu_lock_release();
+	iommu->ops->iommu_lock_release(1);
 
 	pr_info("%s: TLB performance monitoring turned ON\n",
 		pmon->iommu.iommu_name);
@@ -295,7 +295,7 @@
 
 	pmon->enabled = 0;
 
-	iommu->ops->iommu_lock_acquire();
+	iommu->ops->iommu_lock_acquire(1);
 
 	/* disable global counters */
 	iommu->hw_ops->disable_pm(iommu);
@@ -310,7 +310,7 @@
 	/* Update cached copy of counters before turning off power */
 	iommu_pm_read_all_counters(pmon);
 
-	iommu->ops->iommu_lock_release();
+	iommu->ops->iommu_lock_release(1);
 	iommu->ops->iommu_clk_off(iommu_drvdata);
 	iommu->ops->iommu_bus_vote(iommu_drvdata, 0);
 	iommu->ops->iommu_power_off(iommu_drvdata);
@@ -341,9 +341,9 @@
 	mutex_lock(&pmon->lock);
 
 	if (iommu->hw_ops->is_hw_access_OK(pmon)) {
-		iommu->ops->iommu_lock_acquire();
+		iommu->ops->iommu_lock_acquire(1);
 		counter->value = iommu->hw_ops->read_counter(counter);
-		iommu->ops->iommu_lock_release();
+		iommu->ops->iommu_lock_release(1);
 	}
 	full_count = (unsigned long long) counter->value +
 		     ((unsigned long long)counter->overflow_count *
@@ -448,9 +448,9 @@
 		rv = kstrtoul(buf, 10, &cmd);
 		if (!rv && (cmd == 1)) {
 			if (iommu->hw_ops->is_hw_access_OK(pmon)) {
-				iommu->ops->iommu_lock_acquire();
+				iommu->ops->iommu_lock_acquire(1);
 				iommu->hw_ops->reset_counters(&pmon->iommu);
-				iommu->ops->iommu_lock_release();
+				iommu->ops->iommu_lock_release(1);
 			}
 			iommu_pm_reset_counts(pmon);
 			pr_info("TLB performance counters reset\n");
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index 474efdf..5a1806e 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -194,7 +194,7 @@
 	struct msm_scm_fault_regs_dump *regs;
 	int tmp, ret = IRQ_HANDLED;
 
-	iommu_access_ops->iommu_lock_acquire();
+	iommu_access_ops->iommu_lock_acquire(0);
 
 	BUG_ON(!pdev);
 
@@ -266,7 +266,7 @@
 free_regs:
 	kfree(regs);
 lock_release:
-	iommu_access_ops->iommu_lock_release();
+	iommu_access_ops->iommu_lock_release(0);
 	return ret;
 }
 
@@ -510,12 +510,12 @@
 {
 	struct msm_iommu_priv *priv;
 
-	iommu_access_ops->iommu_lock_acquire();
+	iommu_access_ops->iommu_lock_acquire(0);
 	priv = domain->priv;
 	domain->priv = NULL;
 
 	kfree(priv);
-	iommu_access_ops->iommu_lock_release();
+	iommu_access_ops->iommu_lock_release(0);
 }
 
 static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
@@ -526,7 +526,7 @@
 	struct msm_iommu_ctx_drvdata *tmp_drvdata;
 	int ret = 0;
 
-	iommu_access_ops->iommu_lock_acquire();
+	iommu_access_ops->iommu_lock_acquire(0);
 
 	priv = domain->priv;
 	if (!priv || !dev) {
@@ -581,12 +581,12 @@
 	ctx_drvdata->attached_domain = domain;
 	++iommu_drvdata->ctx_attach_count;
 
-	iommu_access_ops->iommu_lock_release();
+	iommu_access_ops->iommu_lock_release(0);
 
 	msm_iommu_attached(dev->parent);
 	return ret;
 fail:
-	iommu_access_ops->iommu_lock_release();
+	iommu_access_ops->iommu_lock_release(0);
 	return ret;
 }
 
@@ -598,7 +598,7 @@
 
 	msm_iommu_detached(dev->parent);
 
-	iommu_access_ops->iommu_lock_acquire();
+	iommu_access_ops->iommu_lock_acquire(0);
 	if (!dev)
 		goto fail;
 
@@ -614,7 +614,7 @@
 	BUG_ON(iommu_drvdata->ctx_attach_count == 0);
 	--iommu_drvdata->ctx_attach_count;
 fail:
-	iommu_access_ops->iommu_lock_release();
+	iommu_access_ops->iommu_lock_release(0);
 }
 
 static int get_drvdata(struct iommu_domain *domain,
@@ -644,7 +644,7 @@
 	struct msm_iommu_ctx_drvdata *ctx_drvdata;
 	int ret = 0;
 
-	iommu_access_ops->iommu_lock_acquire();
+	iommu_access_ops->iommu_lock_acquire(0);
 
 	ret = get_drvdata(domain, &iommu_drvdata, &ctx_drvdata);
 	if (ret)
@@ -655,7 +655,7 @@
 					va, pa, len);
 	iommu_access_ops->iommu_clk_off(iommu_drvdata);
 fail:
-	iommu_access_ops->iommu_lock_release();
+	iommu_access_ops->iommu_lock_release(0);
 	return ret;
 }
 
@@ -666,7 +666,7 @@
 	struct msm_iommu_ctx_drvdata *ctx_drvdata;
 	int ret = -ENODEV;
 
-	iommu_access_ops->iommu_lock_acquire();
+	iommu_access_ops->iommu_lock_acquire(0);
 
 	ret = get_drvdata(domain, &iommu_drvdata, &ctx_drvdata);
 	if (ret)
@@ -677,7 +677,7 @@
 					va, len);
 	iommu_access_ops->iommu_clk_off(iommu_drvdata);
 fail:
-	iommu_access_ops->iommu_lock_release();
+	iommu_access_ops->iommu_lock_release(0);
 
 	/* the IOMMU API requires us to return how many bytes were unmapped */
 	len = ret ? 0 : len;
@@ -692,7 +692,7 @@
 	struct msm_iommu_drvdata *iommu_drvdata;
 	struct msm_iommu_ctx_drvdata *ctx_drvdata;
 
-	iommu_access_ops->iommu_lock_acquire();
+	iommu_access_ops->iommu_lock_acquire(0);
 
 	ret = get_drvdata(domain, &iommu_drvdata, &ctx_drvdata);
 	if (ret)
@@ -702,7 +702,7 @@
 						va, sg, len);
 	iommu_access_ops->iommu_clk_off(iommu_drvdata);
 fail:
-	iommu_access_ops->iommu_lock_release();
+	iommu_access_ops->iommu_lock_release(0);
 	return ret;
 }
 
@@ -714,7 +714,7 @@
 	struct msm_iommu_ctx_drvdata *ctx_drvdata;
 	int ret;
 
-	iommu_access_ops->iommu_lock_acquire();
+	iommu_access_ops->iommu_lock_acquire(0);
 
 	ret = get_drvdata(domain, &iommu_drvdata, &ctx_drvdata);
 	if (ret)
@@ -725,7 +725,7 @@
 	iommu_access_ops->iommu_clk_off(iommu_drvdata);
 
 fail:
-	iommu_access_ops->iommu_lock_release();
+	iommu_access_ops->iommu_lock_release(0);
 	return 0;
 }
 
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index c1f48f5..8b8d23b 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -27,6 +27,7 @@
 #include <linux/timer.h>
 #include <linux/kernel.h>
 #include <linux/workqueue.h>
+#include <mach/clk.h>
 #include <mach/iommu_domains.h>
 #include <mach/iommu.h>
 #include <mach/vreg.h>
@@ -48,6 +49,7 @@
 #define CONFIG_MSM_CPP_DBG 0
 
 #define CPP_CMD_TIMEOUT_MS 300
+#define MSM_MICRO_IFACE_CLK_IDX 7
 
 struct msm_cpp_timer_data_t {
 	struct cpp_device *cpp_dev;
@@ -646,6 +648,38 @@
 		}
 	}
 
+	cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX] =
+		clk_get(&cpp_dev->pdev->dev,
+		cpp_clk_info[MSM_MICRO_IFACE_CLK_IDX].clk_name);
+	if (IS_ERR(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX])) {
+		pr_err("%s get failed\n",
+			cpp_clk_info[MSM_MICRO_IFACE_CLK_IDX].clk_name);
+		rc = PTR_ERR(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX]);
+		goto remap_failed;
+	}
+
+	rc = clk_reset(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX],
+		CLK_RESET_ASSERT);
+	if (rc) {
+		pr_err("%s:micro_iface_clk assert failed\n", __func__);
+		clk_put(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX]);
+		goto remap_failed;
+	}
+
+	usleep_range(10000, 12000);
+
+	rc = clk_reset(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX],
+		CLK_RESET_DEASSERT);
+	  if (rc) {
+		pr_err("%s:micro_iface_clk assert failed\n", __func__);
+		clk_put(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX]);
+		goto remap_failed;
+	}
+
+	usleep_range(1000, 1200);
+
+	clk_put(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX]);
+
 	rc = msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
 			cpp_dev->cpp_clk, ARRAY_SIZE(cpp_clk_info), 1);
 	if (rc < 0) {
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index 2b6118a..3f89d8b 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -180,7 +180,19 @@
 	cmd_done.device_id = device_id;
 	cmd_done.session_id = ((struct hal_session *) pkt->session_id)->
 		session_id;
-	callback(SESSION_ERROR, &cmd_done);
+	dprintk(VIDC_INFO, "Received : SESSION_ERROR with event id : %d\n",
+		pkt->event_data1);
+	switch (pkt->event_data1) {
+	case HFI_ERR_SESSION_INVALID_SCALE_FACTOR:
+	case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE:
+	case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
+		dprintk(VIDC_INFO, "Non Fatal : HFI_EVENT_SESSION_ERROR\n");
+		break;
+	default:
+		dprintk(VIDC_ERR, "HFI_EVENT_SESSION_ERROR\n");
+		callback(SESSION_ERROR, &cmd_done);
+		break;
+	}
 }
 static void hfi_process_event_notify(
 		msm_vidc_callback callback, u32 device_id,
@@ -204,7 +216,7 @@
 		hfi_process_sys_error(callback, device_id);
 		break;
 	case HFI_EVENT_SESSION_ERROR:
-		dprintk(VIDC_ERR, "HFI_EVENT_SESSION_ERROR");
+		dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR");
 		if (!validate_session_pkt(sessions, sess, session_lock))
 			hfi_process_session_error(callback, device_id, pkt);
 		break;
@@ -532,6 +544,39 @@
 			num_properties--;
 			break;
 		}
+		case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE_SUPPORTED:
+		{
+			struct hfi_buffer_alloc_mode_supported *prop =
+				(struct hfi_buffer_alloc_mode_supported *)
+				(data_ptr + next_offset);
+			int i;
+			if (prop->buffer_type == HFI_BUFFER_OUTPUT ||
+				prop->buffer_type == HFI_BUFFER_OUTPUT2) {
+				sess_init_done->alloc_mode_out = 0;
+				for (i = 0; i < prop->num_entries; i++) {
+					switch (prop->rg_data[i]) {
+					case HFI_BUFFER_MODE_STATIC:
+						sess_init_done->alloc_mode_out
+						|= HAL_BUFFER_MODE_STATIC;
+						break;
+					case HFI_BUFFER_MODE_DYNAMIC:
+						sess_init_done->alloc_mode_out
+						|= HAL_BUFFER_MODE_DYNAMIC;
+						break;
+					}
+					if (i >= 32) {
+						dprintk(VIDC_ERR,
+						"%s - num_entries: %d from f/w seems suspect\n",
+						__func__, prop->num_entries);
+						break;
+					}
+				}
+			}
+			next_offset += sizeof(*prop) -
+				sizeof(u32) + prop->num_entries * sizeof(u32);
+			num_properties--;
+			break;
+		}
 		default:
 			dprintk(VIDC_DBG,
 				"%s default case - 0x%x", __func__, prop_id);
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 08881aa..4ca66db 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -818,7 +818,6 @@
 		return -EINVAL;
 	}
 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		struct hal_frame_size frame_sz;
 
 		fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
 			ARRAY_SIZE(vdec_formats), f->fmt.pix_mp.pixelformat,
@@ -831,13 +830,6 @@
 			goto err_invalid_fmt;
 		}
 		inst->fmts[fmt->type] = fmt;
-		frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
-		frame_sz.width = inst->prop.width;
-		frame_sz.height = inst->prop.height;
-		dprintk(VIDC_DBG, "width = %d, height = %d\n",
-				frame_sz.width, frame_sz.height);
-		ret = msm_comm_try_set_prop(inst,
-			HAL_PARAM_FRAME_SIZE, &frame_sz);
 		ret = ret || msm_comm_try_get_bufreqs(inst);
 		if (ret) {
 			for (i = 0; i < fmt->num_planes; ++i) {
@@ -1299,6 +1291,8 @@
 	inst->capability.height.max = DEFAULT_HEIGHT;
 	inst->capability.width.min = MIN_SUPPORTED_WIDTH;
 	inst->capability.width.max = DEFAULT_WIDTH;
+	inst->capability.buffer_mode[OUTPUT_PORT] = HAL_BUFFER_MODE_STATIC;
+	inst->capability.buffer_mode[CAPTURE_PORT] = HAL_BUFFER_MODE_STATIC;
 	inst->prop.fps = 30;
 	return rc;
 }
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index fdc851c..0e0328a 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -430,6 +430,8 @@
 			inst->capability.frame_rate =
 				session_init_done->frame_rate;
 			inst->capability.capability_set = true;
+			inst->capability.buffer_mode[CAPTURE_PORT] =
+				session_init_done->alloc_mode_out;
 		} else {
 			dprintk(VIDC_ERR,
 				"Session init response from FW : 0x%x",
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 15f4e3f..0a078bd 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -178,6 +178,7 @@
 	struct hal_capability_supported height;
 	struct hal_capability_supported frame_rate;
 	u32 capability_set;
+	enum buffer_mode_type buffer_mode[MAX_PORT_NUM];
 };
 
 struct msm_vidc_core {
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h
index 5059273..af58e22 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi.h
@@ -60,6 +60,7 @@
 
 #define HFI_BUFFER_MODE_STATIC (HFI_OX_BASE + 0x1)
 #define HFI_BUFFER_MODE_RING (HFI_OX_BASE + 0x2)
+#define HFI_BUFFER_MODE_DYNAMIC (HFI_OX_BASE + 0x3)
 
 #define HFI_FLUSH_INPUT (HFI_OX_BASE + 0x1)
 #define HFI_FLUSH_OUTPUT (HFI_OX_BASE + 0x2)
@@ -137,6 +138,8 @@
 	(HFI_PROPERTY_PARAM_OX_START + 0x008)
 #define HFI_PROPERTY_PARAM_S3D_FRAME_PACKING_EXTRADATA	\
 	(HFI_PROPERTY_PARAM_OX_START + 0x009)
+#define  HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE_SUPPORTED	\
+	(HFI_PROPERTY_PARAM_OX_START + 0x00A)
 
 #define HFI_PROPERTY_CONFIG_OX_START					\
 	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x02000)
@@ -278,6 +281,12 @@
 	u32 format;
 };
 
+struct hfi_buffer_alloc_mode_supported {
+	u32 buffer_type;
+	u32 num_entries;
+	u32 rg_data[1];
+};
+
 struct hfi_mb_error_map {
 	u32 error_map_size;
 	u8 rg_error_map[1];
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index b600d64..e5d6040 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -868,8 +868,9 @@
 };
 
 enum buffer_mode_type {
-	HAL_BUFFER_MODE_STATIC = 0x00000000,
-	HAL_BUFFER_MODE_RING,
+	HAL_BUFFER_MODE_STATIC = 0x001,
+	HAL_BUFFER_MODE_RING = 0x010,
+	HAL_BUFFER_MODE_DYNAMIC = 0x100,
 };
 
 struct hal_buffer_alloc_mode {
@@ -1014,10 +1015,9 @@
 	struct hal_uncompressed_format_supported uncomp_format;
 	struct hal_interlace_format_supported HAL_format;
 	struct hal_nal_stream_format_supported nal_stream_format;
-/*	struct hal_profile_level_supported profile_level;
-	// allocate and released memory for above. */
 	struct hal_intra_refresh intra_refresh;
 	struct hal_seq_header_info seq_hdr_info;
+	enum buffer_mode_type alloc_mode_out;
 };
 
 struct buffer_requirements {
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index b5c431e..050a98d 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -64,7 +64,12 @@
 
 #define HFI_ERR_SESSION_STREAM_CORRUPT		(HFI_COMMON_BASE + 0x100B)
 #define HFI_ERR_SESSION_ENC_OVERFLOW		(HFI_COMMON_BASE + 0x100C)
-#define  HFI_ERR_SESSION_UNSUPPORTED_STREAM	(HFI_COMMON_BASE + 0x100D)
+#define HFI_ERR_SESSION_UNSUPPORTED_STREAM	(HFI_COMMON_BASE + 0x100D)
+#define HFI_ERR_SESSION_CMDSIZE			(HFI_COMMON_BASE + 0x100E)
+#define HFI_ERR_SESSION_UNSUPPORT_CMD		(HFI_COMMON_BASE + 0x100F)
+#define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE	(HFI_COMMON_BASE + 0x1010)
+#define HFI_ERR_SESSION_BUFFERCOUNT_TOOSMALL	(HFI_COMMON_BASE + 0x1011)
+#define HFI_ERR_SESSION_INVALID_SCALE_FACTOR	(HFI_COMMON_BASE + 0x1012)
 
 #define HFI_EVENT_SYS_ERROR				(HFI_COMMON_BASE + 0x1)
 #define HFI_EVENT_SESSION_ERROR			(HFI_COMMON_BASE + 0x2)
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 317c6a9..d8abc6d 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -1451,23 +1451,23 @@
 		dev_err(dev, "Looking up %s property in node %s failed",
 			"qcom,cdc-dmic-sample-rate",
 			dev->of_node->full_name);
-		dmic_sample_rate = TAIKO_DMIC_SAMPLE_RATE_UNDEFINED;
+		dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED;
 	}
-	if (pdata->mclk_rate == TAIKO_MCLK_CLK_9P6HZ) {
-		if ((dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_2P4MHZ) &&
-		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_3P2MHZ) &&
-		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_4P8MHZ) &&
-		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_UNDEFINED)) {
+	if (pdata->mclk_rate == WCD9XXX_MCLK_CLK_9P6HZ) {
+		if ((dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ) &&
+		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ) &&
+		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ) &&
+		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED)) {
 			dev_err(dev, "Invalid dmic rate %d for mclk %d\n",
 				dmic_sample_rate, pdata->mclk_rate);
 			ret = -EINVAL;
 			goto err;
 		}
-	} else if (pdata->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ) {
-		if ((dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_3P072MHZ) &&
-		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_4P096MHZ) &&
-		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_6P144MHZ) &&
-		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_UNDEFINED)) {
+	} else if (pdata->mclk_rate == WCD9XXX_MCLK_CLK_12P288MHZ) {
+		if ((dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ) &&
+		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ) &&
+		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ) &&
+		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED)) {
 			dev_err(dev, "Invalid dmic rate %d for mclk %d\n",
 				dmic_sample_rate, pdata->mclk_rate);
 			ret = -EINVAL;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 7cc1c9f..a30607c 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -434,6 +434,12 @@
 	if (copy_from_user(&req, (void __user *)argp, sizeof(req)))
 		return -EFAULT;
 
+	if ((req.ifd_data_fd <= 0) || (req.virt_sb_base == 0) ||
+					(req.sb_len == 0)) {
+		pr_err("Inavlid input(s)ion_fd(%d), sb_len(%d), vaddr(0x%x)\n",
+			req.ifd_data_fd, req.sb_len, req.virt_sb_base);
+		return -EFAULT;
+	}
 	/* Get the handle of the shared fd */
 	data->client.ihandle = ion_import_dma_buf(qseecom.ion_clnt,
 						req.ifd_data_fd);
@@ -615,6 +621,7 @@
 	if (ret)
 		pr_warning("Unable to vote for SFPB clock");
 	req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND;
+	load_img_req.img_name[MAX_APP_NAME_SIZE-1] = '\0';
 	memcpy(req.app_name, load_img_req.img_name, MAX_APP_NAME_SIZE);
 
 	ret = __qseecom_check_app_exists(req);
@@ -963,9 +970,22 @@
 		pr_err("cmd buffer or response buffer is null\n");
 		return -EINVAL;
 	}
+	if (((uint32_t)req->cmd_req_buf < data->client.user_virt_sb_base) ||
+		((uint32_t)req->cmd_req_buf >= (data->client.user_virt_sb_base +
+					data->client.sb_length))) {
+		pr_err("cmd buffer address not within shared bufffer\n");
+		return -EINVAL;
+	}
 
-	if (req->cmd_req_len <= 0 ||
-		req->resp_len <= 0 ||
+
+	if (((uint32_t)req->resp_buf < data->client.user_virt_sb_base)  ||
+		((uint32_t)req->resp_buf >= (data->client.user_virt_sb_base +
+					data->client.sb_length))){
+		pr_err("response buffer address not within shared bufffer\n");
+		return -EINVAL;
+	}
+
+	if ((req->cmd_req_len == 0) || (req->resp_len == 0) ||
 		req->cmd_req_len > data->client.sb_length ||
 		req->resp_len > data->client.sb_length) {
 		pr_err("cmd buffer length or "
@@ -1203,6 +1223,7 @@
 					void __user *argp)
 {
 	int ret = 0;
+	int i;
 	struct qseecom_send_modfd_cmd_req req;
 	struct qseecom_send_cmd_req send_cmd_req;
 
@@ -1216,6 +1237,14 @@
 	send_cmd_req.resp_buf = req.resp_buf;
 	send_cmd_req.resp_len = req.resp_len;
 
+	/* validate offsets */
+	for (i = 0; i < MAX_ION_FD; i++) {
+		if (req.ifd_data[i].cmd_buf_offset >= req.cmd_req_len) {
+			pr_err("Invalid offset %d = 0x%x\n",
+				i, req.ifd_data[i].cmd_buf_offset);
+			return -EINVAL;
+		}
+	}
 	ret = __qseecom_update_cmd_buf(&req, false, data, false);
 	if (ret)
 		return ret;
@@ -1806,11 +1835,20 @@
 						void __user *argp)
 {
 	struct qseecom_send_modfd_listener_resp resp;
+	int i;
 
 	if (copy_from_user(&resp, argp, sizeof(resp))) {
 		pr_err("copy_from_user failed");
 		return -EINVAL;
 	}
+	/* validate offsets */
+	for (i = 0; i < MAX_ION_FD; i++) {
+		if (resp.ifd_data[i].cmd_buf_offset >= resp.resp_len) {
+			pr_err("Invalid offset %d = 0x%x\n",
+				i, resp.ifd_data[i].cmd_buf_offset);
+			return -EINVAL;
+		}
+	}
 	__qseecom_update_cmd_buf(&resp, false, data, true);
 	qseecom.send_resp_flag = 1;
 	wake_up_interruptible(&qseecom.send_resp_wq);
@@ -2259,6 +2297,7 @@
 	}
 
 	req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND;
+	query_req.app_name[MAX_APP_NAME_SIZE-1] = '\0';
 	memcpy(req.app_name, query_req.app_name, MAX_APP_NAME_SIZE);
 
 	ret = __qseecom_check_app_exists(req);
@@ -2680,6 +2719,12 @@
 
 	switch (cmd) {
 	case QSEECOM_IOCTL_REGISTER_LISTENER_REQ: {
+		if (data->type != QSEECOM_GENERIC) {
+			pr_err("reg lstnr req: invalid handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
 		pr_debug("ioctl register_listener_req()\n");
 		atomic_inc(&data->ioctl_count);
 		data->type = QSEECOM_LISTENER_SERVICE;
@@ -2691,6 +2736,13 @@
 		break;
 	}
 	case QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ: {
+		if ((data->listener.id == 0) ||
+			(data->type != QSEECOM_LISTENER_SERVICE)) {
+			pr_err("unreg lstnr req: invalid handle (%d) lid(%d)\n",
+						data->type, data->listener.id);
+			ret = -EINVAL;
+			break;
+		}
 		pr_debug("ioctl unregister_listener_req()\n");
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_unregister_listener(data);
@@ -2701,6 +2753,13 @@
 		break;
 	}
 	case QSEECOM_IOCTL_SEND_CMD_REQ: {
+		if ((data->client.app_id == 0) ||
+			(data->type != QSEECOM_CLIENT_APP)) {
+			pr_err("send cmd req: invalid handle (%d) app_id(%d)\n",
+					data->type, data->client.app_id);
+			ret = -EINVAL;
+			break;
+		}
 		/* Only one client allowed here at a time */
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
@@ -2713,6 +2772,13 @@
 		break;
 	}
 	case QSEECOM_IOCTL_SEND_MODFD_CMD_REQ: {
+		if ((data->client.app_id == 0) ||
+			(data->type != QSEECOM_CLIENT_APP)) {
+			pr_err("send mdfd cmd: invalid handle (%d) appid(%d)\n",
+					data->type, data->client.app_id);
+			ret = -EINVAL;
+			break;
+		}
 		/* Only one client allowed here at a time */
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
@@ -2725,6 +2791,13 @@
 		break;
 	}
 	case QSEECOM_IOCTL_RECEIVE_REQ: {
+		if ((data->listener.id == 0) ||
+			(data->type != QSEECOM_LISTENER_SERVICE)) {
+			pr_err("receive req: invalid handle (%d), lid(%d)\n",
+						data->type, data->listener.id);
+			ret = -EINVAL;
+			break;
+		}
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_receive_req(data);
 		atomic_dec(&data->ioctl_count);
@@ -2734,6 +2807,13 @@
 		break;
 	}
 	case QSEECOM_IOCTL_SEND_RESP_REQ: {
+		if ((data->listener.id == 0) ||
+			(data->type != QSEECOM_LISTENER_SERVICE)) {
+			pr_err("send resp req: invalid handle (%d), lid(%d)\n",
+						data->type, data->listener.id);
+			ret = -EINVAL;
+			break;
+		}
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_send_resp();
 		atomic_dec(&data->ioctl_count);
@@ -2743,7 +2823,14 @@
 		break;
 	}
 	case QSEECOM_IOCTL_SET_MEM_PARAM_REQ: {
-		data->type = QSEECOM_CLIENT_APP;
+		if ((data->type != QSEECOM_CLIENT_APP) &&
+			(data->type != QSEECOM_GENERIC) &&
+			(data->type != QSEECOM_SECURE_SERVICE)) {
+			pr_err("set mem param req: invalid handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
 		pr_debug("SET_MEM_PARAM: qseecom addr = 0x%x\n", (u32)data);
 		ret = qseecom_set_client_mem_param(data, argp);
 		if (ret)
@@ -2752,6 +2839,13 @@
 		break;
 	}
 	case QSEECOM_IOCTL_LOAD_APP_REQ: {
+		if ((data->type != QSEECOM_GENERIC) &&
+			(data->type != QSEECOM_CLIENT_APP)) {
+			pr_err("load app req: invalid handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
 		data->type = QSEECOM_CLIENT_APP;
 		pr_debug("LOAD_APP_REQ: qseecom_addr = 0x%x\n", (u32)data);
 		mutex_lock(&app_access_lock);
@@ -2772,6 +2866,13 @@
 		break;
 	}
 	case QSEECOM_IOCTL_UNLOAD_APP_REQ: {
+		if ((data->client.app_id == 0) ||
+			(data->type != QSEECOM_CLIENT_APP)) {
+			pr_err("unload app req:invalid handle(%d) app_id(%d)\n",
+					data->type, data->client.app_id);
+			ret = -EINVAL;
+			break;
+		}
 		pr_debug("UNLOAD_APP: qseecom_addr = 0x%x\n", (u32)data);
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
@@ -2791,6 +2892,20 @@
 		break;
 	}
 	case QSEECOM_IOCTL_PERF_ENABLE_REQ:{
+		if ((data->type != QSEECOM_GENERIC) &&
+			(data->type != QSEECOM_CLIENT_APP)) {
+			pr_err("perf enable req: invalid handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
+		if ((data->type == QSEECOM_CLIENT_APP) &&
+			(data->client.app_id == 0)) {
+			pr_err("perf enable req:invalid handle(%d) appid(%d)\n",
+					data->type, data->client.app_id);
+			ret = -EINVAL;
+			break;
+		}
 		atomic_inc(&data->ioctl_count);
 		ret = qsee_vote_for_clock(data, CLK_DFAB);
 		if (ret)
@@ -2802,13 +2917,33 @@
 		break;
 	}
 	case QSEECOM_IOCTL_PERF_DISABLE_REQ:{
+		if ((data->type != QSEECOM_SECURE_SERVICE) &&
+			(data->type != QSEECOM_CLIENT_APP)) {
+			pr_err("perf disable req: invalid handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
+		if ((data->type == QSEECOM_CLIENT_APP) &&
+			(data->client.app_id == 0)) {
+			pr_err("perf disable: invalid handle (%d)app_id(%d)\n",
+					data->type, data->client.app_id);
+			ret = -EINVAL;
+			break;
+		}
 		atomic_inc(&data->ioctl_count);
-		qsee_disable_clock_vote(data, CLK_DFAB);
-		qsee_disable_clock_vote(data, CLK_SFPB);
+			qsee_disable_clock_vote(data, CLK_DFAB);
+			qsee_disable_clock_vote(data, CLK_SFPB);
 		atomic_dec(&data->ioctl_count);
 		break;
 	}
 	case QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ: {
+		if (data->type != QSEECOM_GENERIC) {
+			pr_err("load ext elf req: invalid client handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
 		data->type = QSEECOM_UNAVAILABLE_CLIENT_APP;
 		data->released = true;
 		mutex_lock(&app_access_lock);
@@ -2821,6 +2956,12 @@
 		break;
 	}
 	case QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ: {
+		if (data->type != QSEECOM_UNAVAILABLE_CLIENT_APP) {
+			pr_err("unload ext elf req: invalid handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
 		data->released = true;
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
@@ -2842,9 +2983,15 @@
 		break;
 	}
 	case QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ: {
+		if (data->type != QSEECOM_GENERIC) {
+			pr_err("send cmd svc req: invalid handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
 		data->type = QSEECOM_SECURE_SERVICE;
 		if (qseecom.qsee_version < QSEE_VERSION_03) {
-			pr_err("SEND_CMD_SERVICE_REQ: Invalid qsee version %u\n",
+			pr_err("SEND_CMD_SERVICE_REQ: Invalid qsee ver %u\n",
 				qseecom.qsee_version);
 			return -EINVAL;
 		}
@@ -2856,8 +3003,14 @@
 		break;
 	}
 	case QSEECOM_IOCTL_CREATE_KEY_REQ: {
+		if (data->type != QSEECOM_GENERIC) {
+			pr_err("create key req: invalid handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
 		if (qseecom.qsee_version < QSEE_VERSION_05) {
-			pr_err("Create Key feature not supported in qsee version %u\n",
+			pr_err("Create Key feature unsupported: qsee ver %u\n",
 				qseecom.qsee_version);
 			return -EINVAL;
 		}
@@ -2873,8 +3026,14 @@
 		break;
 	}
 	case QSEECOM_IOCTL_WIPE_KEY_REQ: {
+		if (data->type != QSEECOM_GENERIC) {
+			pr_err("wipe key req: invalid handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
 		if (qseecom.qsee_version < QSEE_VERSION_05) {
-			pr_err("Wipe Key feature not supported in qsee version %u\n",
+			pr_err("Wipe Key feature unsupported in qsee ver %u\n",
 				qseecom.qsee_version);
 			return -EINVAL;
 		}
@@ -2889,6 +3048,12 @@
 		break;
 	}
 	case QSEECOM_IOCTL_SAVE_PARTITION_HASH_REQ: {
+		if (data->type != QSEECOM_GENERIC) {
+			pr_err("save part hash req: invalid handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
 		data->released = true;
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
@@ -2898,6 +3063,12 @@
 		break;
 	}
 	case QSEECOM_IOCTL_IS_ES_ACTIVATED_REQ: {
+		if (data->type != QSEECOM_GENERIC) {
+			pr_err("ES activated req: invalid handle (%d)\n",
+								data->type);
+			ret = -EINVAL;
+			break;
+		}
 		data->released = true;
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
@@ -2907,6 +3078,13 @@
 		break;
 	}
 	case QSEECOM_IOCTL_SEND_MODFD_RESP: {
+		if ((data->listener.id == 0) ||
+			(data->type != QSEECOM_LISTENER_SERVICE)) {
+			pr_err("receive req: invalid handle (%d), lid(%d)\n",
+						data->type, data->listener.id);
+			ret = -EINVAL;
+			break;
+		}
 		/* Only one client allowed here at a time */
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_send_modfd_resp(data, argp);
@@ -2917,6 +3095,13 @@
 		break;
 	}
 	case QSEECOM_IOCTL_UNPROTECT_BUF: {
+		if ((data->listener.id == 0) ||
+			(data->type != QSEECOM_LISTENER_SERVICE)) {
+			pr_err("receive req: invalid handle (%d), lid(%d)\n",
+						data->type, data->listener.id);
+			ret = -EINVAL;
+			break;
+		}
 		/* Only one client allowed here at a time */
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_unprotect_buffer(argp);
@@ -2927,6 +3112,7 @@
 		break;
 	}
 	default:
+		pr_err("Invalid IOCTL: %d\n", cmd);
 		return -EINVAL;
 	}
 	return ret;
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 02fd276..319a24d 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -150,6 +150,7 @@
 	POWER_SUPPLY_ATTR(input_voltage_regulation),
 	POWER_SUPPLY_ATTR(current_max),
 	POWER_SUPPLY_ATTR(input_current_max),
+	POWER_SUPPLY_ATTR(input_current_trim),
 	POWER_SUPPLY_ATTR(current_now),
 	POWER_SUPPLY_ATTR(current_avg),
 	POWER_SUPPLY_ATTR(power_now),
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 61d4bf2..ad39e88 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -2687,7 +2687,8 @@
 		return;
 	}
 
-	temp = kzalloc(sizeof(struct single_row_lut), GFP_KERNEL);
+	temp = devm_kzalloc(chip->dev, sizeof(struct single_row_lut),
+			GFP_KERNEL);
 	if (!temp) {
 		pr_err("Cannot allocate memory for adjusted fcc table\n");
 		return;
@@ -2705,7 +2706,7 @@
 
 	old = chip->adjusted_fcc_temp_lut;
 	chip->adjusted_fcc_temp_lut = temp;
-	kfree(old);
+	devm_kfree(chip->dev, old);
 }
 
 static int read_fcc_data_from_backup(struct qpnp_bms_chip *chip)
@@ -3442,7 +3443,7 @@
 static int set_battery_data(struct qpnp_bms_chip *chip)
 {
 	int64_t battery_id;
-	int rc, dt_data = false;
+	int rc = 0, dt_data = false;
 	struct bms_battery_data *batt_data;
 	struct device_node *node;
 
@@ -3466,41 +3467,52 @@
 
 		node = of_find_node_by_name(chip->spmi->dev.of_node,
 				"qcom,battery-data");
-		if (node) {
-			batt_data = kzalloc(sizeof(struct bms_battery_data),
-					GFP_KERNEL);
-			batt_data->fcc_temp_lut = kzalloc(
-					sizeof(struct single_row_lut),
-					GFP_KERNEL);
-			batt_data->pc_temp_ocv_lut = kzalloc(
-					sizeof(struct pc_temp_ocv_lut),
-					GFP_KERNEL);
-			batt_data->rbatt_sf_lut = kzalloc(
-					sizeof(struct sf_lut), GFP_KERNEL);
+		if (!node) {
+			pr_warn("No available batterydata, using palladium 1500\n");
+			batt_data = &palladium_1500_data;
+			goto assign_data;
+		}
+		batt_data = devm_kzalloc(chip->dev,
+				sizeof(struct bms_battery_data), GFP_KERNEL);
+		if (!batt_data) {
+			pr_err("Could not alloc battery data\n");
+			batt_data = &palladium_1500_data;
+			goto assign_data;
+		}
+		batt_data->fcc_temp_lut = devm_kzalloc(chip->dev,
+				sizeof(struct single_row_lut),
+				GFP_KERNEL);
+		batt_data->pc_temp_ocv_lut = devm_kzalloc(chip->dev,
+				sizeof(struct pc_temp_ocv_lut),
+				GFP_KERNEL);
+		batt_data->rbatt_sf_lut = devm_kzalloc(chip->dev,
+				sizeof(struct sf_lut),
+				GFP_KERNEL);
 
-			batt_data->max_voltage_uv = -1;
-			batt_data->cutoff_uv = -1;
-			batt_data->iterm_ua = -1;
+		batt_data->max_voltage_uv = -1;
+		batt_data->cutoff_uv = -1;
+		batt_data->iterm_ua = -1;
 
-			rc = of_batterydata_read_data(node,
-					batt_data, battery_id);
-			if (rc) {
-				pr_err("battery data load failed, using palladium 1500\n");
-				kfree(batt_data->fcc_temp_lut);
-				kfree(batt_data->pc_temp_ocv_lut);
-				kfree(batt_data->rbatt_sf_lut);
-				kfree(batt_data);
-				batt_data = &palladium_1500_data;
-			} else {
-				dt_data = true;
-			}
+		/*
+		 * if the alloced luts are 0s, of_batterydata_read_data ignores
+		 * them.
+		 */
+		rc = of_batterydata_read_data(node, batt_data, battery_id);
+		if (rc == 0 && batt_data->fcc_temp_lut
+				&& batt_data->pc_temp_ocv_lut
+				&& batt_data->rbatt_sf_lut) {
+			dt_data = true;
 		} else {
-			pr_warn("invalid battid, palladium 1500 assumed batt_id %llx\n",
-					battery_id);
+			pr_err("battery data load failed, using palladium 1500\n");
+			devm_kfree(chip->dev, batt_data->fcc_temp_lut);
+			devm_kfree(chip->dev, batt_data->pc_temp_ocv_lut);
+			devm_kfree(chip->dev, batt_data->rbatt_sf_lut);
+			devm_kfree(chip->dev, batt_data);
 			batt_data = &palladium_1500_data;
 		}
 	}
 
+assign_data:
 	chip->fcc_mah = batt_data->fcc;
 	chip->fcc_temp_lut = batt_data->fcc_temp_lut;
 	chip->fcc_sf_lut = batt_data->fcc_sf_lut;
@@ -3519,13 +3531,20 @@
 	if (batt_data->iterm_ua >= 0 && dt_data)
 		chip->chg_term_ua = batt_data->iterm_ua;
 
-	if (dt_data)
-		kfree(batt_data);
-
 	if (chip->pc_temp_ocv_lut == NULL) {
-		pr_err("temp ocv lut table is NULL\n");
+		pr_err("temp ocv lut table has not been loaded\n");
+		if (dt_data) {
+			devm_kfree(chip->dev, batt_data->fcc_temp_lut);
+			devm_kfree(chip->dev, batt_data->pc_temp_ocv_lut);
+			devm_kfree(chip->dev, batt_data->rbatt_sf_lut);
+			devm_kfree(chip->dev, batt_data);
+		}
 		return -EINVAL;
 	}
+
+	if (dt_data)
+		devm_kfree(chip->dev, batt_data);
+
 	return 0;
 }
 
@@ -3642,6 +3661,8 @@
 		chip->fcc_learning_samples = devm_kzalloc(&chip->spmi->dev,
 				(sizeof(struct fcc_sample) *
 				chip->min_fcc_learning_samples), GFP_KERNEL);
+		if (chip->fcc_learning_samples == NULL)
+			return -ENOMEM;
 		pr_debug("min-fcc-soc=%d, min-fcc-pc=%d, min-fcc-cycles=%d\n",
 			chip->min_fcc_learning_soc, chip->min_fcc_ocv_pc,
 			chip->min_fcc_learning_samples);
@@ -3981,7 +4002,8 @@
 	bool warm_reset;
 	int rc, vbatt;
 
-	chip = kzalloc(sizeof *chip, GFP_KERNEL);
+	chip = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_bms_chip),
+			GFP_KERNEL);
 
 	if (chip == NULL) {
 		pr_err("kzalloc() failed.\n");
@@ -4172,17 +4194,12 @@
 	wake_lock_destroy(&chip->cv_wake_lock);
 error_resource:
 error_read:
-	kfree(chip);
 	return rc;
 }
 
-static int __devexit
-qpnp_bms_remove(struct spmi_device *spmi)
+static int qpnp_bms_remove(struct spmi_device *spmi)
 {
-	struct qpnp_bms_chip *chip = dev_get_drvdata(&spmi->dev);
-
 	dev_set_drvdata(&spmi->dev, NULL);
-	kfree(chip);
 	return 0;
 }
 
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 8e42912..04ca7f8 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -82,11 +82,13 @@
 #define CHGR_USB_USB_SUSP			0x47
 #define CHGR_USB_USB_OTG_CTL			0x48
 #define CHGR_USB_ENUM_T_STOP			0x4E
+#define CHGR_USB_TRIM				0xF1
 #define CHGR_CHG_TEMP_THRESH			0x66
 #define CHGR_BAT_IF_PRES_STATUS			0x08
 #define CHGR_STATUS				0x09
 #define CHGR_BAT_IF_VCP				0x42
 #define CHGR_BAT_IF_BATFET_CTRL1		0x90
+#define CHGR_BAT_IF_BATFET_CTRL4		0x93
 #define CHGR_BAT_IF_SPARE			0xDF
 #define CHGR_MISC_BOOT_DONE			0x42
 #define CHGR_BUCK_PSTG_CTRL			0x73
@@ -353,10 +355,13 @@
 	struct qpnp_chg_regulator	otg_vreg;
 	struct qpnp_chg_regulator	boost_vreg;
 	struct qpnp_chg_regulator	batfet_vreg;
+	bool				batfet_ext_en;
+	struct work_struct		batfet_lcl_work;
 	struct qpnp_vadc_chip		*vadc_dev;
 	struct qpnp_adc_tm_chip		*adc_tm_dev;
 	struct mutex			jeita_configure_lock;
 	spinlock_t			usbin_health_monitor_lock;
+	struct mutex			batfet_vreg_lock;
 	struct alarm			reduce_power_stage_alarm;
 	struct work_struct		reduce_power_stage_work;
 	bool				power_stage_workaround_running;
@@ -742,6 +747,48 @@
 }
 
 static int
+qpnp_chg_iusb_trim_get(struct qpnp_chg_chip *chip)
+{
+	int rc = 0;
+	u8 trim_reg;
+
+	rc = qpnp_chg_read(chip, &trim_reg,
+			chip->usb_chgpth_base + CHGR_USB_TRIM, 1);
+	if (rc) {
+		pr_err("failed to read USB_TRIM rc=%d\n", rc);
+		return 0;
+	}
+
+	return trim_reg;
+}
+
+static int
+qpnp_chg_iusb_trim_set(struct qpnp_chg_chip *chip, int trim)
+{
+	int rc = 0;
+
+	rc = qpnp_chg_masked_write(chip,
+		chip->usb_chgpth_base + SEC_ACCESS,
+		0xFF,
+		0xA5, 1);
+	if (rc) {
+		pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = qpnp_chg_masked_write(chip,
+		chip->usb_chgpth_base + CHGR_USB_TRIM,
+		0xFF,
+		trim, 1);
+	if (rc) {
+		pr_err("failed to write USB TRIM rc=%d\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+static int
 qpnp_chg_iusbmax_set(struct qpnp_chg_chip *chip, int mA)
 {
 	int rc = 0;
@@ -1273,6 +1320,31 @@
 	return IRQ_HANDLED;
 }
 
+#define BATFET_LPM_MASK		0xC0
+#define BATFET_LPM		0x40
+#define BATFET_NO_LPM		0x00
+static int
+qpnp_chg_regulator_batfet_set(struct qpnp_chg_chip *chip, bool enable)
+{
+	int rc = 0;
+
+	if (chip->charging_disabled || !chip->bat_if_base)
+		return rc;
+
+	if (chip->type == SMBB)
+		rc = qpnp_chg_masked_write(chip,
+			chip->bat_if_base + CHGR_BAT_IF_SPARE,
+			BATFET_LPM_MASK,
+			enable ? BATFET_NO_LPM : BATFET_LPM, 1);
+	else
+		rc = qpnp_chg_masked_write(chip,
+			chip->bat_if_base + CHGR_BAT_IF_BATFET_CTRL4,
+			BATFET_LPM_MASK,
+			enable ? BATFET_NO_LPM : BATFET_LPM, 1);
+
+	return rc;
+}
+
 #define ENUM_T_STOP_BIT		BIT(0)
 static irqreturn_t
 qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
@@ -1316,10 +1388,9 @@
 			if (!qpnp_chg_is_dc_chg_plugged_in(chip)) {
 				chip->delta_vddmax_mv = 0;
 				qpnp_chg_set_appropriate_vddmax(chip);
+				chip->chg_done = false;
 			}
 			qpnp_chg_usb_suspend_enable(chip, 1);
-			if (!qpnp_chg_is_dc_chg_plugged_in(chip))
-				chip->chg_done = false;
 			chip->prev_usb_max_ma = -EINVAL;
 		} else {
 			/* when OVP clamped usbin, and then decrease
@@ -1353,6 +1424,7 @@
 		}
 
 		power_supply_set_present(chip->usb_psy, chip->usb_present);
+		schedule_work(&chip->batfet_lcl_work);
 	}
 
 	return IRQ_HANDLED;
@@ -1430,6 +1502,7 @@
 		power_supply_changed(&chip->dc_psy);
 		pr_debug("psy changed batt_psy\n");
 		power_supply_changed(&chip->batt_psy);
+		schedule_work(&chip->batfet_lcl_work);
 	}
 
 	return IRQ_HANDLED;
@@ -1544,6 +1617,7 @@
 	case POWER_SUPPLY_PROP_CHARGING_ENABLED:
 	case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
 	case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX:
+	case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM:
 	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
 	case POWER_SUPPLY_PROP_COOL_TEMP:
 	case POWER_SUPPLY_PROP_WARM_TEMP:
@@ -1654,6 +1728,7 @@
 	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_INPUT_CURRENT_MAX,
+	POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM,
 	POWER_SUPPLY_PROP_VOLTAGE_MIN,
 	POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION,
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
@@ -1676,7 +1751,11 @@
 static int charger_monitor;
 module_param(charger_monitor, int, 0644);
 
+static int ext_ovp_present;
+module_param(ext_ovp_present, int, 0444);
+
 #define USB_WALL_THRESHOLD_MA	500
+#define OVP_USB_WALL_THRESHOLD_MA	200
 static int
 qpnp_power_get_property_mains(struct power_supply *psy,
 				  enum power_supply_property psp,
@@ -2018,8 +2097,12 @@
 			if (((ret.intval / 1000) > USB_WALL_THRESHOLD_MA)
 					&& (charger_monitor ||
 					!chip->charger_monitor_checked)) {
-				qpnp_chg_iusbmax_set(chip,
+				if (!ext_ovp_present)
+					qpnp_chg_iusbmax_set(chip,
 						USB_WALL_THRESHOLD_MA);
+				else
+					qpnp_chg_iusbmax_set(chip,
+						OVP_USB_WALL_THRESHOLD_MA);
 			} else {
 				qpnp_chg_iusbmax_set(chip, ret.intval / 1000);
 			}
@@ -2111,6 +2194,9 @@
 	case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX:
 		val->intval = qpnp_chg_usb_iusbmax_get(chip) * 1000;
 		break;
+	case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM:
+		val->intval = qpnp_chg_iusb_trim_get(chip);
+		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
 		val->intval = qpnp_chg_vinmin_get(chip) * 1000;
 		break;
@@ -2551,20 +2637,50 @@
 	.list_voltage		= qpnp_chg_regulator_boost_list_voltage,
 };
 
-#define BATFET_LPM_MASK		0xC0
-#define BATFET_LPM		0x40
-#define BATFET_NO_LPM		0x00
+static int
+qpnp_chg_bat_if_batfet_reg_enabled(struct qpnp_chg_chip *chip)
+{
+	int rc = 0;
+	u8 reg = 0;
+
+	if (!chip->bat_if_base)
+		return rc;
+
+	if (chip->type == SMBB)
+		rc = qpnp_chg_read(chip, &reg,
+				chip->bat_if_base + CHGR_BAT_IF_SPARE, 1);
+	else
+		rc = qpnp_chg_read(chip, &reg,
+			chip->bat_if_base + CHGR_BAT_IF_BATFET_CTRL4, 1);
+
+	if (rc) {
+		pr_err("failed to read batt_if rc=%d\n", rc);
+		return rc;
+	}
+
+	if ((reg & BATFET_LPM_MASK) == BATFET_NO_LPM)
+		return 1;
+
+	return 0;
+}
+
 static int
 qpnp_chg_regulator_batfet_enable(struct regulator_dev *rdev)
 {
 	struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
-	int rc;
+	int rc = 0;
 
-	rc = qpnp_chg_masked_write(chip,
-			chip->bat_if_base + CHGR_BAT_IF_SPARE,
-			BATFET_LPM_MASK, BATFET_NO_LPM, 1);
-	if (rc)
-		pr_err("failed to write to batt_if rc=%d\n", rc);
+	mutex_lock(&chip->batfet_vreg_lock);
+	/* Only enable if not already enabled */
+	if (!qpnp_chg_bat_if_batfet_reg_enabled(chip)) {
+		rc = qpnp_chg_regulator_batfet_set(chip, 1);
+		if (rc)
+			pr_err("failed to write to batt_if rc=%d\n", rc);
+	}
+
+	chip->batfet_ext_en = true;
+	mutex_unlock(&chip->batfet_vreg_lock);
+
 	return rc;
 }
 
@@ -2572,13 +2688,20 @@
 qpnp_chg_regulator_batfet_disable(struct regulator_dev *rdev)
 {
 	struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
-	int rc;
+	int rc = 0;
 
-	rc = qpnp_chg_masked_write(chip,
-			chip->bat_if_base + CHGR_BAT_IF_SPARE,
-			BATFET_LPM_MASK, BATFET_LPM, 1);
-	if (rc)
-		pr_err("failed to write to batt_if rc=%d\n", rc);
+	mutex_lock(&chip->batfet_vreg_lock);
+	/* Don't allow disable if charger connected */
+	if (!qpnp_chg_is_usb_chg_plugged_in(chip) &&
+			!qpnp_chg_is_dc_chg_plugged_in(chip)) {
+		rc = qpnp_chg_regulator_batfet_set(chip, 0);
+		if (rc)
+			pr_err("failed to write to batt_if rc=%d\n", rc);
+	}
+
+	chip->batfet_ext_en = false;
+	mutex_unlock(&chip->batfet_vreg_lock);
+
 	return rc;
 }
 
@@ -2586,20 +2709,8 @@
 qpnp_chg_regulator_batfet_is_enabled(struct regulator_dev *rdev)
 {
 	struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
-	int rc;
-	u8 reg;
 
-	rc = qpnp_chg_read(chip, &reg,
-				chip->bat_if_base + CHGR_BAT_IF_SPARE, 1);
-	if (rc) {
-		pr_err("failed to read batt_if rc=%d\n", rc);
-		return rc;
-	}
-
-	if (reg && BATFET_LPM_MASK == BATFET_NO_LPM)
-		return 1;
-
-	return 0;
+	return chip->batfet_ext_en;
 }
 
 static struct regulator_ops qpnp_chg_batfet_vreg_ops = {
@@ -3088,6 +3199,25 @@
 }
 
 static void
+qpnp_chg_batfet_lcl_work(struct work_struct *work)
+{
+	struct qpnp_chg_chip *chip = container_of(work,
+				struct qpnp_chg_chip, batfet_lcl_work);
+
+	mutex_lock(&chip->batfet_vreg_lock);
+	if (qpnp_chg_is_usb_chg_plugged_in(chip) ||
+			qpnp_chg_is_dc_chg_plugged_in(chip)) {
+		qpnp_chg_regulator_batfet_set(chip, 1);
+		pr_debug("disabled ULPM\n");
+	} else if (!chip->batfet_ext_en && !qpnp_chg_is_usb_chg_plugged_in(chip)
+			&& !qpnp_chg_is_dc_chg_plugged_in(chip)) {
+		qpnp_chg_regulator_batfet_set(chip, 0);
+		pr_debug("enabled ULPM\n");
+	}
+	mutex_unlock(&chip->batfet_vreg_lock);
+}
+
+static void
 qpnp_chg_reduce_power_stage_work(struct work_struct *work)
 {
 	struct qpnp_chg_chip *chip = container_of(work,
@@ -3172,6 +3302,9 @@
 	case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX:
 		qpnp_chg_iusbmax_set(chip, val->intval / 1000);
 		break;
+	case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM:
+		qpnp_chg_iusb_trim_set(chip, val->intval);
+		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
 		qpnp_chg_vinmin_set(chip, val->intval / 1000);
 		break;
@@ -3894,6 +4027,9 @@
 	chip->btc_disabled = of_property_read_bool(chip->spmi->dev.of_node,
 					"qcom,btc-disabled");
 
+	ext_ovp_present = of_property_read_bool(chip->spmi->dev.of_node,
+					"qcom,ext-ovp-present");
+
 	/* Get the charging-disabled property */
 	chip->charging_disabled = of_property_read_bool(chip->spmi->dev.of_node,
 					"qcom,charging-disabled");
@@ -3973,6 +4109,9 @@
 			qpnp_chg_reduce_power_stage_callback);
 	INIT_WORK(&chip->reduce_power_stage_work,
 			qpnp_chg_reduce_power_stage_work);
+	mutex_init(&chip->batfet_vreg_lock);
+	INIT_WORK(&chip->batfet_lcl_work,
+			qpnp_chg_batfet_lcl_work);
 
 	/* Get all device tree properties */
 	rc = qpnp_charger_read_dt_props(chip);
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index 08bff9a..9c909bf 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -481,12 +481,13 @@
 			pr_err("fail to start the MDP display interface\n");
 			goto on_error;
 		}
+	} else {
+		mdp3_session->first_commit = true;
 	}
 
 on_error:
 	if (!rc)
 		mdp3_session->status = 1;
-
 	mutex_unlock(&mdp3_session->lock);
 	return rc;
 }
@@ -557,6 +558,56 @@
 	return 0;
 }
 
+static int mdp3_ctrl_reset_cmd(struct msm_fb_data_type *mfd)
+{
+	int rc = 0;
+	struct mdp3_session_data *mdp3_session;
+	struct mdp3_dma *mdp3_dma;
+	struct mdss_panel_data *panel;
+	struct mdp3_vsync_notification vsync_client;
+
+	pr_debug("mdp3_ctrl_reset_cmd\n");
+	mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
+	if (!mdp3_session || !mdp3_session->panel || !mdp3_session->dma ||
+		!mdp3_session->intf) {
+		pr_err("mdp3_ctrl_reset no device");
+		return -ENODEV;
+	}
+
+	panel = mdp3_session->panel;
+	mdp3_dma = mdp3_session->dma;
+	mutex_lock(&mdp3_session->lock);
+
+	vsync_client = mdp3_dma->vsync_client;
+
+	rc = mdp3_dma->stop(mdp3_dma, mdp3_session->intf);
+	if (rc) {
+		pr_err("fail to stop the MDP3 dma\n");
+		goto reset_error;
+	}
+
+	rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P);
+	if (rc) {
+		pr_err("fail to attach dma iommu\n");
+		goto reset_error;
+	}
+
+	mdp3_ctrl_intf_init(mfd, mdp3_session->intf);
+	mdp3_ctrl_dma_init(mfd, mdp3_dma);
+
+	if (vsync_client.handler)
+		mdp3_dma->vsync_enable(mdp3_dma, &vsync_client);
+
+	if (mfd->fbi->screen_base)
+		rc = mdp3_dma->start(mdp3_dma, mdp3_session->intf);
+	else
+		mdp3_session->first_commit = true;
+
+reset_error:
+	mutex_unlock(&mdp3_session->lock);
+	return rc;
+}
+
 static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd)
 {
 	int rc = 0;
@@ -573,11 +624,18 @@
 		return -ENODEV;
 	}
 
+	if (mfd->panel.type == MIPI_CMD_PANEL) {
+		rc = mdp3_ctrl_reset_cmd(mfd);
+		return rc;
+	}
+
 	panel = mdp3_session->panel;
 	mdp3_dma = mdp3_session->dma;
 	mutex_lock(&mdp3_session->lock);
 
 	vsync_client = mdp3_dma->vsync_client;
+	if (panel && panel->set_backlight)
+		panel->set_backlight(panel, 0);
 
 	rc = mdp3_dma->stop(mdp3_dma, mdp3_session->intf);
 	if (rc) {
@@ -633,6 +691,8 @@
 
 	if (mfd->fbi->screen_base)
 		rc = mdp3_dma->start(mdp3_dma, mdp3_session->intf);
+	else
+		mdp3_session->first_commit = true;
 
 reset_error:
 	mutex_unlock(&mdp3_session->lock);
@@ -747,7 +807,10 @@
 {
 	struct mdp3_session_data *mdp3_session;
 	struct mdp3_img_data *data;
+	struct mdss_panel_info *panel_info = mfd->panel_info;
 	int rc = 0;
+	bool reset_done = false;
+	struct mdss_panel_data *panel;
 
 	if (!mfd || !mfd->mdp.private1)
 		return -EINVAL;
@@ -756,9 +819,16 @@
 	if (!mdp3_session || !mdp3_session->dma)
 		return -EINVAL;
 
+	if (mdp3_bufq_count(&mdp3_session->bufq_in) == 0) {
+		pr_debug("no buffer in queue yet\n");
+		return -EPERM;
+	}
+
+	panel = mdp3_session->panel;
 	if (!mdp3_iommu_is_attached(MDP3_CLIENT_DMA_P)) {
 		pr_debug("continuous splash screen, IOMMU not attached\n");
 		mdp3_ctrl_reset(mfd);
+		reset_done = true;
 	}
 	mdp3_release_splash_memory();
 
@@ -782,6 +852,15 @@
 		data = mdp3_bufq_pop(&mdp3_session->bufq_out);
 		mdp3_put_img(data, MDP3_CLIENT_DMA_P);
 	}
+
+	if (mdp3_session->first_commit) {
+		/*wait for one frame time to ensure frame is sent to panel*/
+		msleep(1000 / panel_info->mipi.frame_rate);
+		mdp3_session->first_commit = false;
+	}
+	if (reset_done && (panel && panel->set_backlight))
+		panel->set_backlight(panel, panel->panel_info.bl_max);
+
 	mutex_unlock(&mdp3_session->lock);
 
 	mdss_fb_update_notify_update(mfd);
@@ -795,6 +874,7 @@
 	struct mdp3_session_data *mdp3_session;
 	u32 offset;
 	int bpp;
+	struct mdss_panel_info *panel_info = mfd->panel_info;
 
 	pr_debug("mdp3_ctrl_pan_display\n");
 	if (!mfd || !mfd->mdp.private1)
@@ -837,6 +917,13 @@
 		pr_debug("mdp3_ctrl_pan_display no memory, stop interface");
 		mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
 	}
+
+	if (mdp3_session->first_commit) {
+		/*wait for one frame time to ensure frame is sent to panel*/
+		msleep(1000 / panel_info->mipi.frame_rate);
+		mdp3_session->first_commit = false;
+	}
+
 pan_error:
 	mutex_unlock(&mdp3_session->lock);
 }
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.h b/drivers/video/msm/mdss/mdp3_ctrl.h
index eb32797..7c4f6ac 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.h
+++ b/drivers/video/msm/mdss/mdp3_ctrl.h
@@ -51,6 +51,7 @@
 	struct mutex histo_lock;
 	int lut_sel;
 	int cc_vect_sel;
+	bool first_commit;
 };
 
 int mdp3_ctrl_init(struct msm_fb_data_type *mfd);
diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
index 1b1ddf1..8f6168a 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.c
+++ b/drivers/video/msm/mdss/mdp3_ppp.c
@@ -54,6 +54,7 @@
 	[MDP_YCRYCB_H2V1] = true,
 	[MDP_Y_CBCR_H2V1] = true,
 	[MDP_Y_CRCB_H2V1] = true,
+	[MDP_BGRX_8888] = true,
 };
 
 #define MAX_LIST_WINDOW 16
@@ -554,8 +555,9 @@
 			tmp_v =
 				(MDP_SCALE_Q_FACTOR * blit_op->dst.roi.height) /
 				MDP_MAX_X_SCALE_FACTOR +
-				(MDP_SCALE_Q_FACTOR * blit_op->dst.roi.height) %
-				MDP_MAX_X_SCALE_FACTOR ? 1 : 0;
+				((MDP_SCALE_Q_FACTOR *
+				blit_op->dst.roi.height) %
+				MDP_MAX_X_SCALE_FACTOR ? 1 : 0);
 
 			/* move x location as roi width gets bigger */
 			blit_op->src.roi.x -= tmp_v - blit_op->src.roi.width;
@@ -565,8 +567,9 @@
 			tmp_v =
 				(MDP_SCALE_Q_FACTOR * blit_op->dst.roi.height) /
 				MDP_MIN_X_SCALE_FACTOR +
-				(MDP_SCALE_Q_FACTOR * blit_op->dst.roi.height) %
-				MDP_MIN_X_SCALE_FACTOR ? 1 : 0;
+				((MDP_SCALE_Q_FACTOR *
+				blit_op->dst.roi.height) %
+				MDP_MIN_X_SCALE_FACTOR ? 1 : 0);
 
 			/*
 			 * we don't move x location for continuity of
diff --git a/drivers/video/msm/mdss/mdp3_ppp_data.c b/drivers/video/msm/mdss/mdp3_ppp_data.c
index ba2a369..e562ad3 100644
--- a/drivers/video/msm/mdss/mdp3_ppp_data.c
+++ b/drivers/video/msm/mdss/mdp3_ppp_data.c
@@ -36,6 +36,7 @@
 	[MDP_YCRYCB_H2V1] = MDP_YCRYCB_H2V1_SRC_REG,
 	[MDP_Y_CBCR_H2V1] = MDP_Y_CRCB_H2V1_SRC_REG,
 	[MDP_Y_CRCB_H2V1] = MDP_Y_CRCB_H2V1_SRC_REG,
+	[MDP_BGRX_8888] = MDP_RGBX_8888_SRC_REG,
 };
 
 const uint32_t out_cfg_lut[MDP_IMGTYPE_LIMIT] = {
@@ -55,6 +56,7 @@
 	[MDP_YCRYCB_H2V1] = MDP_YCRYCB_H2V1_DST_REG,
 	[MDP_Y_CBCR_H2V1] = MDP_Y_CRCB_H2V1_DST_REG,
 	[MDP_Y_CRCB_H2V1] = MDP_Y_CRCB_H2V1_DST_REG,
+	[MDP_BGRX_8888] = MDP_RGBX_8888_DST_REG,
 };
 
 const uint32_t pack_patt_lut[MDP_IMGTYPE_LIMIT] = {
@@ -62,8 +64,8 @@
 	[MDP_BGR_565] = PPP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8),
 	[MDP_RGB_888] = PPP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8),
 	[MDP_BGR_888] = PPP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8),
-	[MDP_BGRA_8888] = PPP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R,
-		CLR_G, CLR_B, 8),
+	[MDP_BGRA_8888] = PPP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B,
+		CLR_G, CLR_R, 8),
 	[MDP_RGBA_8888] = PPP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R,
 		CLR_G, CLR_B, 8),
 	[MDP_ARGB_8888] = PPP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R,
@@ -82,6 +84,8 @@
 		CLR_CR, CLR_Y, CLR_CB, 8),
 	[MDP_Y_CBCR_H2V1] = PPP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8),
 	[MDP_Y_CRCB_H2V1] = PPP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8),
+	[MDP_BGRX_8888] = PPP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B,
+		CLR_G, CLR_R, 8),
 };
 
 const uint32_t dst_op_reg[MDP_IMGTYPE_LIMIT] = {
@@ -121,6 +125,7 @@
 	[MDP_Y_CRCB_H2V1] = 1,
 	[MDP_Y_CRCB_H2V2] = 1,
 	[MDP_YCRYCB_H2V1] = 2,
+	[MDP_BGRX_8888] = 4,
 };
 
 const bool per_pixel_alpha[MDP_IMGTYPE_LIMIT] = {
diff --git a/drivers/video/msm/mdss/mdp3_ppp_hwio.c b/drivers/video/msm/mdss/mdp3_ppp_hwio.c
index a051037..eb01d00 100644
--- a/drivers/video/msm/mdss/mdp3_ppp_hwio.c
+++ b/drivers/video/msm/mdss/mdp3_ppp_hwio.c
@@ -354,6 +354,7 @@
 	case MDP_ARGB_8888:
 	case MDP_XRGB_8888:
 	case MDP_RGBX_8888:
+	case MDP_BGRX_8888:
 		rgb = true;
 	default:
 		break;
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 8addec3..02458bd 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -591,9 +591,6 @@
 	},
 };
 
-static int unset_bl_level, bl_updated;
-static int bl_level_old;
-
 static void mdss_fb_scale_bl(struct msm_fb_data_type *mfd, u32 *bl_lvl)
 {
 	u32 temp = *bl_lvl;
@@ -615,11 +612,11 @@
 		 * scaling fraction (x/1024)
 		 */
 		temp = (temp * mfd->bl_scale) / 1024;
-
-		/*if less than minimum level, use min level*/
-		if (temp < mfd->bl_min_lvl)
-			temp = mfd->bl_min_lvl;
 	}
+	/*if less than minimum level, use min level*/
+	else if ((temp < mfd->bl_min_lvl) && (0 != temp))
+		temp = mfd->bl_min_lvl;
+
 	pr_debug("output = %d", temp);
 
 	(*bl_lvl) = temp;
@@ -632,11 +629,15 @@
 	int (*update_ad_input)(struct msm_fb_data_type *mfd);
 	u32 temp = bkl_lvl;
 
-	if ((!mfd->panel_power_on || !bl_updated) && !IS_CALIB_MODE_BL(mfd)) {
-		unset_bl_level = bkl_lvl;
-		return;
+	if (((!mfd->panel_power_on && mfd->dcm_state != DCM_ENTER)
+		|| !mfd->bl_updated) && !IS_CALIB_MODE_BL(mfd)) {
+			if (bkl_lvl < mfd->bl_min_lvl)
+				mfd->unset_bl_level = mfd->bl_min_lvl;
+			else
+				mfd->unset_bl_level = bkl_lvl;
+			return;
 	} else {
-		unset_bl_level = 0;
+		mfd->unset_bl_level = 0;
 	}
 
 	pdata = dev_get_platdata(&mfd->pdev->dev);
@@ -652,13 +653,13 @@
 		 * as well as setting bl_level to bkl_lvl even though the
 		 * backlight has been set to the scaled value.
 		 */
-		if (bl_level_old == temp) {
+		if (mfd->bl_level_old == temp) {
 			mfd->bl_level = bkl_lvl;
 			return;
 		}
 		pdata->set_backlight(pdata, temp);
 		mfd->bl_level = bkl_lvl;
-		bl_level_old = temp;
+		mfd->bl_level_old = temp;
 
 		if (mfd->mdp.update_ad_input) {
 			update_ad_input = mfd->mdp.update_ad_input;
@@ -674,15 +675,15 @@
 {
 	struct mdss_panel_data *pdata;
 
-	if (unset_bl_level && !bl_updated) {
+	if (mfd->unset_bl_level && !mfd->bl_updated) {
 		pdata = dev_get_platdata(&mfd->pdev->dev);
 		if ((pdata) && (pdata->set_backlight)) {
 			mutex_lock(&mfd->bl_lock);
-			mfd->bl_level = unset_bl_level;
+			mfd->bl_level = mfd->unset_bl_level;
 			pdata->set_backlight(pdata, mfd->bl_level);
-			bl_level_old = unset_bl_level;
+			mfd->bl_level_old = mfd->unset_bl_level;
 			mutex_unlock(&mfd->bl_lock);
-			bl_updated = 1;
+			mfd->bl_updated = 1;
 		}
 	}
 }
@@ -729,7 +730,7 @@
 			mfd->op_enable = false;
 			curr_pwr_state = mfd->panel_power_on;
 			mfd->panel_power_on = false;
-			bl_updated = 0;
+			mfd->bl_updated = 0;
 
 			ret = mfd->mdp.off_fnc(mfd);
 			if (ret)
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index 1400bdd..256789d 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -140,6 +140,9 @@
 	u32 bl_level;
 	u32 bl_scale;
 	u32 bl_min_lvl;
+	u32 unset_bl_level;
+	u32 bl_updated;
+	u32 bl_level_old;
 	struct mutex bl_lock;
 	struct mutex lock;
 
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 64d0bca..563a4a6 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -295,6 +295,9 @@
 				struct mdp_pgc_lut_data *config);
 static void pp_update_hist_lut(char __iomem *base,
 				struct mdp_hist_lut_data *cfg);
+static int pp_gm_has_invalid_lut_size(struct mdp_gamut_cfg_data *config);
+static void pp_gamut_config(struct mdp_gamut_cfg_data *gamut_cfg,
+				u32 base, struct pp_sts_type *pp_sts);
 static void pp_pa_config(unsigned long flags, u32 base,
 				struct pp_sts_type *pp_sts,
 				struct mdp_pa_cfg *pa_config);
@@ -2038,10 +2041,32 @@
 	return 0;
 }
 
+static int pp_gm_has_invalid_lut_size(struct mdp_gamut_cfg_data *config)
+{
+	if (config->tbl_size[0] != GAMUT_T0_SIZE)
+		return -EINVAL;
+	if (config->tbl_size[1] != GAMUT_T1_SIZE)
+		return -EINVAL;
+	if (config->tbl_size[2] != GAMUT_T2_SIZE)
+		return -EINVAL;
+	if (config->tbl_size[3] != GAMUT_T3_SIZE)
+		return -EINVAL;
+	if (config->tbl_size[4] != GAMUT_T4_SIZE)
+		return -EINVAL;
+	if (config->tbl_size[5] != GAMUT_T5_SIZE)
+		return -EINVAL;
+	if (config->tbl_size[6] != GAMUT_T6_SIZE)
+		return -EINVAL;
+	if (config->tbl_size[7] != GAMUT_T7_SIZE)
+		return -EINVAL;
+
+	return 0;
+}
+
 int mdss_mdp_gamut_config(struct mdp_gamut_cfg_data *config,
 					u32 *copyback)
 {
-	int i, j, size_total = 0, ret = 0;
+	int i, j, ret = 0;
 	u32 offset, disp_num, dspp_num = 0;
 	uint16_t *tbl_off;
 	struct mdp_gamut_cfg_data local_cfg;
@@ -2053,9 +2078,8 @@
 	if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(config->block >= MDP_BLOCK_MAX))
 		return -EINVAL;
-	for (i = 0; i < MDP_GAMUT_TABLE_NUM; i++)
-		size_total += config->tbl_size[i];
-	if (size_total != GAMUT_TOTAL_TABLE_SIZE)
+
+	if (pp_gm_has_invalid_lut_size(config))
 		return -EINVAL;
 
 	mutex_lock(&mdss_pp_mutex);
@@ -3486,12 +3510,22 @@
 int mdss_mdp_calib_config_buffer(struct mdp_calib_config_buffer *cfg,
 						u32 *copyback)
 {
-	int ret = -1;
-	int counter = cfg->size / (sizeof(uint32_t) * 2);
+	int ret = -1, counter;
 	uint32_t *buff = NULL, *buff_org = NULL;
 	void *ptr;
 	int i = 0;
 
+	if (!cfg) {
+		pr_err("Invalid buffer pointer");
+		return ret;
+	}
+
+	if (cfg->size == 0) {
+		pr_err("Invalid buffer size");
+		return ret;
+	}
+
+	counter = cfg->size / (sizeof(uint32_t) * 2);
 	buff_org = buff = kzalloc(cfg->size, GFP_KERNEL);
 	if (buff == NULL) {
 		pr_err("Allocation failed");
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index fbe89e1..eba0157 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -206,6 +206,7 @@
 #define CLOCK_SOURCE_WATCHDOG			0x10
 #define CLOCK_SOURCE_VALID_FOR_HRES		0x20
 #define CLOCK_SOURCE_UNSTABLE			0x40
+#define CLOCK_SOURCE_SUSPEND_NONSTOP		0x80
 
 /* simplify initialization of mask field */
 #define CLOCKSOURCE_MASK(bits) (cycle_t)((bits) < 64 ? ((1ULL<<(bits))-1) : -1)
diff --git a/include/linux/mfd/wcd9xxx/pdata.h b/include/linux/mfd/wcd9xxx/pdata.h
index b7ba6fb..ffbd732 100644
--- a/include/linux/mfd/wcd9xxx/pdata.h
+++ b/include/linux/mfd/wcd9xxx/pdata.h
@@ -69,20 +69,20 @@
 #define TABLA_DCYCLE_3839 0xE
 #define TABLA_DCYCLE_4095 0xF
 
-#define TAIKO_MCLK_CLK_12P288MHZ 12288000
-#define TAIKO_MCLK_CLK_9P6HZ 9600000
+#define WCD9XXX_MCLK_CLK_12P288MHZ 12288000
+#define WCD9XXX_MCLK_CLK_9P6HZ 9600000
 
 /* Only valid for 9.6 MHz mclk */
-#define TAIKO_DMIC_SAMPLE_RATE_2P4MHZ 2400000
-#define TAIKO_DMIC_SAMPLE_RATE_3P2MHZ 3200000
-#define TAIKO_DMIC_SAMPLE_RATE_4P8MHZ 4800000
+#define WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ 2400000
+#define WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ 3200000
+#define WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ 4800000
 
 /* Only valid for 12.288 MHz mclk */
-#define TAIKO_DMIC_SAMPLE_RATE_3P072MHZ 3072000
-#define TAIKO_DMIC_SAMPLE_RATE_4P096MHZ 4096000
-#define TAIKO_DMIC_SAMPLE_RATE_6P144MHZ 6144000
+#define WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ 3072000
+#define WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ 4096000
+#define WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ 6144000
 
-#define TAIKO_DMIC_SAMPLE_RATE_UNDEFINED 0
+#define WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED 0
 
 struct wcd9xxx_amic {
 	/*legacy mode, txfe_enable and txfe_buff take 7 input
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 48268f0..a5fa304 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -302,16 +302,16 @@
  * On nommu, vmalloc/vfree wrap through kmalloc/kfree directly, so there
  * is no special casing required.
  */
+
+#ifdef CONFIG_MMU
+extern int is_vmalloc_addr(const void *x);
+#else
 static inline int is_vmalloc_addr(const void *x)
 {
-#ifdef CONFIG_MMU
-	unsigned long addr = (unsigned long)x;
-
-	return addr >= VMALLOC_START && addr < VMALLOC_END;
-#else
 	return 0;
-#endif
 }
+#endif
+
 #ifdef CONFIG_MMU
 extern int is_vmalloc_or_module_addr(const void *x);
 #else
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 4923521..93af04d 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -103,6 +103,7 @@
 	POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION,
 	POWER_SUPPLY_PROP_CURRENT_MAX,
 	POWER_SUPPLY_PROP_INPUT_CURRENT_MAX,
+	POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_CURRENT_AVG,
 	POWER_SUPPLY_PROP_POWER_NOW,
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 663bc05..7675a5c 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -14,6 +14,7 @@
 #define VM_USERMAP	0x00000008	/* suitable for remap_vmalloc_range */
 #define VM_VPAGES	0x00000010	/* buffer for pages was vmalloc'ed */
 #define VM_UNLIST	0x00000020	/* vm_struct is not listed in vmlist */
+#define VM_LOWMEM	0x00000040	/* Tracking of direct mapped lowmem */
 /* bits [20..32] reserved for arch specific ioremap internals */
 
 /*
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index a2ab2ab..e174693 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -184,6 +184,36 @@
 	return ret;
 }
 
+#ifdef ENABLE_VMALLOC_SAVING
+int is_vmalloc_addr(const void *x)
+{
+	struct rb_node *n;
+	struct vmap_area *va;
+	int ret = 0;
+
+	spin_lock(&vmap_area_lock);
+
+	for (n = rb_first(vmap_area_root); n; rb_next(n)) {
+		va = rb_entry(n, struct vmap_area, rb_node);
+		if (x >= va->va_start && x < va->va_end) {
+			ret = 1;
+			break;
+		}
+	}
+
+	spin_unlock(&vmap_area_lock);
+	return ret;
+}
+#else
+int is_vmalloc_addr(const void *x)
+{
+	unsigned long addr = (unsigned long)x;
+
+	return addr >= VMALLOC_START && addr < VMALLOC_END;
+}
+#endif
+EXPORT_SYMBOL(is_vmalloc_addr);
+
 int is_vmalloc_or_module_addr(const void *x)
 {
 	/*
@@ -2643,6 +2673,9 @@
 	if (v->flags & VM_VPAGES)
 		seq_printf(m, " vpages");
 
+	if (v->flags & VM_LOWMEM)
+		seq_printf(m, " lowmem");
+
 	show_numa_info(m, v);
 	seq_putc(m, '\n');
 	return 0;
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index 2955eee..4c20bb9 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -2519,8 +2519,10 @@
 	/* Enable pulldown to reduce leakage */
 	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_MICB_1_CTL, 0x82),
 	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_TX_COM_BIAS, 0xE0),
+	/* Keep the same default gain settings for TX paths */
 	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_TX_1_EN, 0x32),
 	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_TX_2_EN, 0x32),
+	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_TX_3_EN, 0x30),
 
 	/* ClassG fine tuning setting for 16 ohm HPH */
 	MSM8X10_WCD_REG_VAL(MSM8X10_WCD_A_CDC_CLSG_FREQ_THRESH_B1_CTL, 0x05),
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index 577c1ed..17ed0d3 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -4600,6 +4600,9 @@
 	u8 flag = pdata->amic_settings.use_pdata;
 	u8 i = 0, j = 0;
 	u8 val_txfe = 0, value = 0;
+	u8 dmic_sample_rate_value = 0;
+	u8 dmic_b1_ctl_value = 0;
+	u8 anc_ctl_value = 0;
 
 	if (!pdata) {
 		dev_err(codec->dev, "%s: NULL pdata\n", __func__);
@@ -4693,6 +4696,78 @@
 		 0x00 : 0x10);
 	snd_soc_update_bits(codec, TAPAN_A_MICB_3_CTL, 0x10, value);
 
+	/* Set the DMIC sample rate */
+	if (pdata->mclk_rate == TAPAN_MCLK_CLK_9P6MHZ) {
+		switch (pdata->dmic_sample_rate) {
+		case WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
+			break;
+		case WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
+			break;
+		case WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ:
+		case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
+			break;
+		default:
+			dev_err(codec->dev,
+				"%s Invalid sample rate %d for mclk %d\n",
+				__func__, pdata->dmic_sample_rate,
+				pdata->mclk_rate);
+			rc = -EINVAL;
+			goto done;
+		}
+	} else if (pdata->mclk_rate == TAPAN_MCLK_CLK_12P288MHZ) {
+		switch (pdata->dmic_sample_rate) {
+		case WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
+			break;
+		case WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
+			break;
+		case WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ:
+		case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
+			break;
+		default:
+			dev_err(codec->dev,
+				"%s Invalid sample rate %d for mclk %d\n",
+				__func__, pdata->dmic_sample_rate,
+				pdata->mclk_rate);
+			rc = -EINVAL;
+			goto done;
+		}
+	} else {
+		dev_err(codec->dev, "%s MCLK is not set!\n", __func__);
+		rc = -EINVAL;
+		goto done;
+	}
+
+	snd_soc_update_bits(codec, TAPAN_A_CDC_TX1_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAPAN_A_CDC_TX2_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAPAN_A_CDC_TX3_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAPAN_A_CDC_TX4_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_DMIC_B1_CTL,
+		0xEE, dmic_b1_ctl_value);
+	snd_soc_update_bits(codec, TAPAN_A_CDC_ANC1_B2_CTL,
+		0x1, anc_ctl_value);
+
 done:
 	return rc;
 }
@@ -4886,15 +4961,6 @@
 	{TAPAN_A_CDC_TX3_MUX_CTL, 0x8, 0x0},
 	{TAPAN_A_CDC_TX4_MUX_CTL, 0x8, 0x0},
 
-	/* config Decimator for DMIC CLK_MODE_1(3.2Mhz@9.6Mhz mclk) */
-	{TAPAN_A_CDC_TX1_DMIC_CTL, 0x7, 0x1},
-	{TAPAN_A_CDC_TX2_DMIC_CTL, 0x7, 0x1},
-	{TAPAN_A_CDC_TX3_DMIC_CTL, 0x7, 0x1},
-	{TAPAN_A_CDC_TX4_DMIC_CTL, 0x7, 0x1},
-
-	/* config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) */
-	{TAPAN_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},
-
 	/* Compander zone selection */
 	{TAPAN_A_CDC_COMP0_B4_CTL, 0x3F, 0x37},
 	{TAPAN_A_CDC_COMP1_B4_CTL, 0x3F, 0x37},
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 4ce9b4a..2beda38 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -248,21 +248,6 @@
 
 #define TAIKO_I2S_MASTER_MODE_MASK 0x08
 
-#define TAIKO_DMIC_SAMPLE_RATE_DIV_2	0x0
-#define TAIKO_DMIC_SAMPLE_RATE_DIV_3	0x1
-#define TAIKO_DMIC_SAMPLE_RATE_DIV_4	0x2
-
-#define TAIKO_DMIC_B1_CTL_DIV_2 0x00
-#define TAIKO_DMIC_B1_CTL_DIV_3 0x22
-#define TAIKO_DMIC_B1_CTL_DIV_4 0x44
-
-#define TAIKO_DMIC_B2_CTL_DIV_2 0x00
-#define TAIKO_DMIC_B2_CTL_DIV_3 0x02
-#define TAIKO_DMIC_B2_CTL_DIV_4 0x04
-
-#define TAIKO_ANC_DMIC_X2_ON	0x1
-#define TAIKO_ANC_DMIC_X2_OFF	0x0
-
 #define TAIKO_SLIM_CLOSE_TIMEOUT 1000
 #define TAIKO_SLIM_IRQ_OVERFLOW (1 << 0)
 #define TAIKO_SLIM_IRQ_UNDERFLOW (1 << 1)
@@ -5741,24 +5726,24 @@
 	/* Set the DMIC sample rate */
 	if (pdata->mclk_rate == TAIKO_MCLK_CLK_9P6MHZ) {
 		switch (pdata->dmic_sample_rate) {
-		case TAIKO_DMIC_SAMPLE_RATE_2P4MHZ:
-			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_4;
-			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_4;
-			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_4;
-			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
+		case WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
+			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_4;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
 			break;
-		case TAIKO_DMIC_SAMPLE_RATE_4P8MHZ:
-			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_2;
-			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_2;
-			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_2;
-			anc_ctl_value = TAIKO_ANC_DMIC_X2_ON;
+		case WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
+			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_2;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
 			break;
-		case TAIKO_DMIC_SAMPLE_RATE_3P2MHZ:
-		case TAIKO_DMIC_SAMPLE_RATE_UNDEFINED:
-			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_3;
-			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_3;
-			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_3;
-			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
+		case WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ:
+		case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
+			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_3;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
 			break;
 		default:
 			pr_err("%s Invalid sample rate %d for mclk %d\n",
@@ -5769,24 +5754,24 @@
 		}
 	} else if (pdata->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ) {
 		switch (pdata->dmic_sample_rate) {
-		case TAIKO_DMIC_SAMPLE_RATE_3P072MHZ:
-			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_4;
-			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_4;
-			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_4;
-			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
+		case WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
+			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_4;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
 			break;
-		case TAIKO_DMIC_SAMPLE_RATE_6P144MHZ:
-			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_2;
-			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_2;
-			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_2;
-			anc_ctl_value = TAIKO_ANC_DMIC_X2_ON;
+		case WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
+			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_2;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
 			break;
-		case TAIKO_DMIC_SAMPLE_RATE_4P096MHZ:
-		case TAIKO_DMIC_SAMPLE_RATE_UNDEFINED:
-			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_3;
-			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_3;
-			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_3;
-			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
+		case WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ:
+		case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
+			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
+			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
+			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_3;
+			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
 			break;
 		default:
 			pr_err("%s Invalid sample rate %d for mclk %d\n",
diff --git a/sound/soc/codecs/wcd9xxx-common.h b/sound/soc/codecs/wcd9xxx-common.h
index e63d36a..0239c86 100644
--- a/sound/soc/codecs/wcd9xxx-common.h
+++ b/sound/soc/codecs/wcd9xxx-common.h
@@ -37,6 +37,21 @@
 #define	WCD9XXX_CLSH_STATE_LO (0x01 << 3)
 #define NUM_CLSH_STATES ((0x01 << 4) - 1)
 
+#define WCD9XXX_DMIC_SAMPLE_RATE_DIV_2    0x0
+#define WCD9XXX_DMIC_SAMPLE_RATE_DIV_3    0x1
+#define WCD9XXX_DMIC_SAMPLE_RATE_DIV_4    0x2
+
+#define WCD9XXX_DMIC_B1_CTL_DIV_2 0x00
+#define WCD9XXX_DMIC_B1_CTL_DIV_3 0x22
+#define WCD9XXX_DMIC_B1_CTL_DIV_4 0x44
+
+#define WCD9XXX_DMIC_B2_CTL_DIV_2 0x00
+#define WCD9XXX_DMIC_B2_CTL_DIV_3 0x02
+#define WCD9XXX_DMIC_B2_CTL_DIV_4 0x04
+
+#define WCD9XXX_ANC_DMIC_X2_ON    0x1
+#define WCD9XXX_ANC_DMIC_X2_OFF   0x0
+
 /* Derived State: Bits 1 and 2 should be set for Headphone stereo */
 #define WCD9XXX_CLSH_STATE_HPH_ST (WCD9XXX_CLSH_STATE_HPHL | \
 						WCD9XXX_CLSH_STATE_HPHR)