Merge "msm: mdss: decouple clk ctrl and bw ctrl"
diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt
index d62d0c6..019b476 100644
--- a/Documentation/DMA-attributes.txt
+++ b/Documentation/DMA-attributes.txt
@@ -76,3 +76,28 @@
 buffering, no pre-fetching). This has severe performance penalties and
 should not be used for general purpose DMA allocations. It should only
 be used if one of the restrictions on strongly ordered memory is required.
+
+DMA_ATTR_SKIP_CPU_SYNC
+----------------------
+
+By default dma_map_{single,page,sg} functions family transfer a given
+buffer from CPU domain to device domain. Some advanced use cases might
+require sharing a buffer between more than one device. This requires
+having a mapping created separately for each device and is usually
+performed by calling dma_map_{single,page,sg} function more than once
+for the given buffer with device pointer to each device taking part in
+the buffer sharing. The first call transfers a buffer from 'CPU' domain
+to 'device' domain, what synchronizes CPU caches for the given region
+(usually it means that the cache has been flushed or invalidated
+depending on the dma direction). However, next calls to
+dma_map_{single,page,sg}() for other devices will perform exactly the
+same sychronization operation on the CPU cache. CPU cache sychronization
+might be a time consuming operation, especially if the buffers are
+large, so it is highly recommended to avoid it if possible.
+DMA_ATTR_SKIP_CPU_SYNC allows platform code to skip synchronization of
+the CPU cache for the given buffer assuming that it has been already
+transferred to 'device' domain. This attribute can be also used for
+dma_unmap_{single,page,sg} functions family to force buffer to stay in
+device domain after releasing a mapping for it. Use this attribute with
+care!
+
diff --git a/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt b/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
index 3e6d060..9bc44f5 100644
--- a/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
+++ b/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
@@ -58,43 +58,6 @@
 		    1 : 1K
 		    2 : 2K
 		    3 : 4K
-- qcom,pre-div-channel-scaling : Pre-div used for the channel before the signal
-				 is being measured.
-- qcom,calibration-type : Calibration point values vary with temperature.
-			  For improved accuracy fresh gain and offset point values
-			  can be used for calibration. Reading fresh values for ever
-			  read affects the reading time. Application can use the historic
-			  values used from the trim register values.
-			  Select from the following strings.
-			  "absolute" : Uses TRIM gain and offset values for calibration.
-			  "ratiometric" : Calculate the gain and offset calibration value when an ADC
-			  	    request is issued.
-- qcom,scale-function : Scaling fuction used to convert raw ADC code to units specific to
-			a given channel.
-			Select from the following unsigned int.
-			0 : Default scaling to convert raw adc code to voltage.
-			1 : Conversion to temperature based on btm parameters.
-			2 : Returns result in milli degree's Centigrade.
-			3 : Returns current across 0.1 ohm resistor.
-			4 : Returns XO thermistor voltage in degree's Centigrade.
-- qcom,hw-settle-time : Settling period for the channel before ADC read.
-			Select from the following unsigned int.
-			0 : 0us
-			1 : 100us
-			2 : 200us
-			3 : 300us
-			4 : 400us
-			5 : 500us
-			6 : 600us
-			7 : 700us
-			8 : 800us
-			9 : 900us
-			0xa : 1ms
-			0xb : 2ms
-			0xc : 4ms
-			0xd : 6ms
-			0xe : 8ms
-			0xf : 10ms
 - qcom,fast-avg-setup : Average number of samples to be used for measurement. Fast averaging
 			provides the option to obtain a single measurement from the ADC that
 			is an average of multiple samples. The value selected is 2^(value)
@@ -130,10 +93,6 @@
                                 label = "rsense";
                                 reg = <0>;
                                 qcom,decimation = <0>;
-                                qcom,pre-div-channel-scaling = <20>;
-                                qcom,calibration-type = "fresh";
-                                qcom,scale-function = <0>;
-                                qcom,hw-settle-time = <0>;
                                 qcom,fast-avg-setup = <0>;
                         };
 	};
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp.txt b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
index 1aca300..ac447d7 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
@@ -48,6 +48,7 @@
 - qcom,torch-enable: set flash led to torch mode functionality and triggers software workaround for torch if hardware does not support
 - flash-boost-supply: SMBB regulator for LED flash mode
 - torch-boost-supply: SMBB regulator for LED torch mode
+- flash-wa-supply: SMBB regulator for flash workarounds.
 
 RGB Led is a tri-colored led, Red, Blue & Green.
 
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index ff89757..c21d8fe 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -210,6 +210,10 @@
 			qcom,batfet:
 			 - regulator-name:	A string used as a descriptive name
 						for the batfet regulator.
+
+			qcom,chgr:
+			- regulator-name:	A string used as a descriptive name
+						for the flash workarounds regulator.
 Example:
 	pm8941-chg {
 		spmi-dev-container;
diff --git a/arch/arm/boot/dts/msm-pm8110.dtsi b/arch/arm/boot/dts/msm-pm8110.dtsi
index 5ccecfa..cd81a3f 100644
--- a/arch/arm/boot/dts/msm-pm8110.dtsi
+++ b/arch/arm/boot/dts/msm-pm8110.dtsi
@@ -275,10 +275,6 @@
 				label = "internal_rsense";
 				reg = <0>;
 				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
 				qcom,fast-avg-setup = <0>;
 			};
 		};
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index 6e1b985..7a66f6a 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -91,7 +91,7 @@
 			qcom,cool-bat-mv = <4100>;
 			qcom,ibatmax-cool-ma = <350>;
 
-			qcom,chgr@1000 {
+			pm8226_chg_chgr: qcom,chgr@1000 {
 				status = "disabled";
 				reg = <0x1000 0x100>;
 				interrupts =	<0x0 0x10 0x0>,
@@ -435,20 +435,12 @@
 				label = "internal_rsense";
 				reg = <0>;
 				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
 				qcom,fast-avg-setup = <0>;
 			};
 			chan@1 {
 				label = "external_rsense";
 				reg = <1>;
 				qcom,decimation = <0>;
-				qcom,pre-div-channel-scaling = <1>;
-				qcom,calibration-type = "absolute";
-				qcom,scale-function = <0>;
-				qcom,hw-settle-time = <0>;
 				qcom,fast-avg-setup = <0>;
 			};
 		};
@@ -852,6 +844,7 @@
 			reg = <0xd300 0x100>;
 			label = "flash";
 			flash-boost-supply = <&pm8226_chg_boost>;
+			flash-wa-supply = <&pm8226_chg_chgr>;
 			pm8226_flash0: qcom,flash_0 {
 				qcom,max-current = <1000>;
 				qcom,default-state = "off";
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index d8046c5..f77fc3c 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -835,10 +835,6 @@
 			label = "internal_rsense";
 			reg = <0>;
 			qcom,decimation = <0>;
-			qcom,pre-div-channel-scaling = <1>;
-			qcom,calibration-type = "absolute";
-			qcom,scale-function = <0>;
-			qcom,hw-settle-time = <0>;
 			qcom,fast-avg-setup = <0>;
 		};
 	};
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
index 05a3f07..a227802 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
@@ -38,124 +38,6 @@
 		qcom,cci-master = <0>;
 	};
 
-	qcom,camera@6f {
-		compatible = "qcom,ov8825";
-		reg = <0x6f>;
-		qcom,slave-id = <0x6c 0x300a 0x8825>;
-		qcom,csiphy-sd-index = <0>;
-		qcom,csid-sd-index = <0>;
-		qcom,actuator-src = <&actuator0>;
-		qcom,led-flash-src = <&led_flash0>;
-		qcom,mount-angle = <180>;
-		qcom,sensor-name = "ov8825";
-		cam_vdig-supply = <&pm8226_l5>;
-		cam_vana-supply = <&pm8226_l19>;
-		cam_vio-supply = <&pm8226_lvs1>;
-		cam_vaf-supply = <&pm8226_l15>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
-							 "cam_vaf";
-		qcom,cam-vreg-type = <0 1 0 0>;
-		qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
-		qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
-		qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
-		qcom,gpio-no-mux = <0>;
-		gpios = <&msmgpio 26 0>,
-			<&msmgpio 37 0>,
-			<&msmgpio 36 0>;
-		qcom,gpio-reset = <1>;
-		qcom,gpio-standby = <2>;
-		qcom,gpio-req-tbl-num = <0 1 2>;
-		qcom,gpio-req-tbl-flags = <1 0 0>;
-		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
-			"CAM_RESET1",
-			"CAM_STANDBY";
-		qcom,csi-lane-assign = <0x4320>;
-		qcom,csi-lane-mask = <0x1f>;
-		qcom,sensor-position = <0>;
-		qcom,sensor-mode = <1>;
-		qcom,cci-master = <0>;
-	};
-
-    qcom,camera@20 {
-		compatible = "qcom,imx135";
-		reg = <0x20>;
-		qcom,slave-id = <0x20 0x0016 0x0135>;
-		qcom,csiphy-sd-index = <0>;
-		qcom,csid-sd-index = <0>;
-		qcom,actuator-src = <&actuator1>;
-		qcom,mount-angle = <90>;
-		qcom,sensor-name = "imx135";
-		cam_vdig-supply = <&pm8226_l5>;
-		cam_vana-supply = <&pm8226_l19>;
-		cam_vio-supply = <&pm8226_lvs1>;
-		cam_vaf-supply = <&pm8226_l15>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
-				     "cam_vaf";
-		qcom,cam-vreg-type = <0 1 0 0>;
-		qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
-		qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
-		qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
-		qcom,gpio-no-mux = <0>;
-		gpios = <&msmgpio 26 0>,
-			<&msmgpio 37 0>,
-			<&msmgpio 36 0>;
-		qcom,gpio-reset = <1>;
-		qcom,gpio-standby = <2>;
-		qcom,gpio-req-tbl-num = <0 1 2>;
-		qcom,gpio-req-tbl-flags = <1 0 0>;
-		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
-			"CAM_RESET1",
-			"CAM_STANDBY";
-		qcom,gpio-set-tbl-num = <1 1>;
-		qcom,gpio-set-tbl-flags = <0 2>;
-		qcom,gpio-set-tbl-delay = <1000 30000>;
-		qcom,csi-lane-assign = <0x4320>;
-		qcom,csi-lane-mask = <0x1F>;
-		qcom,sensor-position = <0>;
-		qcom,sensor-mode = <0>;
-	        qcom,sensor-type = <0>;
-		qcom,cci-master = <0>;
-		status = "ok";
-	};
-
-	qcom,camera@6d {
-		compatible = "qcom,ov9724";
-		reg = <0x6d>;
-		qcom,slave-id = <0x20 0x0 0x9724>;
-		qcom,csiphy-sd-index = <1>;
-		qcom,csid-sd-index = <1>;
-		qcom,mount-angle = <0>;
-		qcom,sensor-name = "ov9724";
-		cam_vdig-supply = <&pm8226_l5>;
-		cam_vana-supply = <&pm8226_l19>;
-		cam_vio-supply = <&pm8226_lvs1>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
-		qcom,cam-vreg-type = <0 1 0>;
-		qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
-		qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
-		qcom,cam-vreg-op-mode = <200000 0 80000>;
-		qcom,gpio-no-mux = <0>;
-		gpios = <&msmgpio 26 0>,
-				<&msmgpio 28 0>,
-				<&msmgpio 35 0>;
-		qcom,gpio-reset = <1>;
-		qcom,gpio-standby = <2>;
-		qcom,gpio-req-tbl-num = <0 1 2>;
-		qcom,gpio-req-tbl-flags = <1 0 0>;
-		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
-				"CAM_RESET",
-				"CAM_STANDBY";
-		qcom,gpio-set-tbl-num = <1 1>;
-		qcom,gpio-set-tbl-flags = <0 2>;
-		qcom,gpio-set-tbl-delay = <1000 4000>;
-		qcom,csi-lane-assign = <0x4320>;
-		qcom,csi-lane-mask = <0x3>;
-		qcom,sensor-position = <1>;
-		qcom,sensor-mode = <1>;
-		qcom,cci-master = <0>;
-		status = "ok";
-	};
-
 	qcom,camera@90 {
 		compatible = "qcom,mt9m114";
 		reg = <0x90 0x0>;
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
index a6af2c2..6b305a5 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
@@ -31,81 +31,6 @@
 		qcom,cci-master = <0>;
 	};
 
-	qcom,camera@6f {
-		compatible = "qcom,ov8825";
-		reg = <0x6f>;
-		qcom,slave-id = <0x6c 0x300a 0x8825>;
-		qcom,csiphy-sd-index = <0>;
-		qcom,csid-sd-index = <0>;
-		qcom,actuator-src = <&actuator0>;
-		qcom,led-flash-src = <&led_flash0>;
-		qcom,mount-angle = <270>;
-		qcom,sensor-name = "ov8825";
-		cam_vdig-supply = <&pm8226_l5>;
-		cam_vana-supply = <&pm8226_l19>;
-		cam_vio-supply = <&pm8226_lvs1>;
-		cam_vaf-supply = <&pm8226_l15>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
-							 "cam_vaf";
-		qcom,cam-vreg-type = <0 1 0 0>;
-		qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
-		qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
-		qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
-		qcom,gpio-no-mux = <0>;
-		gpios = <&msmgpio 26 0>,
-			<&msmgpio 37 0>,
-			<&msmgpio 35 0>;
-		qcom,gpio-reset = <1>;
-		qcom,gpio-standby = <2>;
-		qcom,gpio-req-tbl-num = <0 1 2>;
-		qcom,gpio-req-tbl-flags = <1 0 0>;
-		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
-			"CAM_RESET1",
-			"CAM_STANDBY";
-		qcom,csi-lane-assign = <0x4320>;
-		qcom,csi-lane-mask = <0x1f>;
-		qcom,sensor-position = <0>;
-		qcom,sensor-mode = <1>;
-		qcom,cci-master = <0>;
-	};
-
-	qcom,camera@6d {
-		compatible = "qcom,ov9724";
-		reg = <0x6d>;
-		qcom,slave-id = <0x20 0x0 0x9724>;
-		qcom,csiphy-sd-index = <1>;
-		qcom,csid-sd-index = <1>;
-		qcom,mount-angle = <270>;
-		qcom,sensor-name = "ov9724";
-		cam_vdig-supply = <&pm8226_l5>;
-		cam_vana-supply = <&pm8226_l19>;
-		cam_vio-supply = <&pm8226_lvs1>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
-		qcom,cam-vreg-type = <0 1 0>;
-		qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
-		qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
-		qcom,cam-vreg-op-mode = <200000 0 80000>;
-		qcom,gpio-no-mux = <0>;
-		gpios = <&msmgpio 26 0>,
-				<&msmgpio 28 0>,
-				<&msmgpio 36 0>;
-		qcom,gpio-reset = <1>;
-		qcom,gpio-standby = <2>;
-		qcom,gpio-req-tbl-num = <0 1 2>;
-		qcom,gpio-req-tbl-flags = <1 0 0>;
-		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
-				"CAM_RESET",
-				"CAM_STANDBY";
-		qcom,gpio-set-tbl-num = <1 1>;
-		qcom,gpio-set-tbl-flags = <0 2>;
-		qcom,gpio-set-tbl-delay = <1000 4000>;
-		qcom,csi-lane-assign = <0x4320>;
-		qcom,csi-lane-mask = <0x3>;
-		qcom,sensor-position = <1>;
-		qcom,sensor-mode = <1>;
-		qcom,cci-master = <0>;
-		status = "ok";
-	};
 	qcom,camera@0 {
 		cell-index = <0>;
 		compatible = "qcom,camera";
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
index dab92ff..4115959 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
@@ -104,45 +104,6 @@
 		qcom,cam-power-seq-delay = <1 1 5 5 10>;
 	};
 
-	qcom,camera@6f {
-		compatible = "qcom,ov8825";
-		reg = <0x6f>;
-		qcom,slave-id = <0x6c 0x300a 0x8825>;
-		qcom,csiphy-sd-index = <0>;
-		qcom,csid-sd-index = <0>;
-		qcom,actuator-src = <&actuator0>;
-		qcom,led-flash-src = <&led_flash0>;
-		qcom,eeprom-src = <&eeprom0>;
-		qcom,mount-angle = <90>;
-		qcom,sensor-name = "ov8825";
-		cam_vdig-supply = <&pm8226_l5>;
-		cam_vana-supply = <&pm8226_l19>;
-		cam_vio-supply = <&pm8226_lvs1>;
-		cam_vaf-supply = <&pm8226_l15>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
-							 "cam_vaf";
-		qcom,cam-vreg-type = <0 1 0 0>;
-		qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
-		qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
-		qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
-		qcom,gpio-no-mux = <0>;
-		gpios = <&msmgpio 26 0>,
-			<&msmgpio 37 0>,
-			<&msmgpio 36 0>;
-		qcom,gpio-reset = <1>;
-		qcom,gpio-standby = <2>;
-		qcom,gpio-req-tbl-num = <0 1 2>;
-		qcom,gpio-req-tbl-flags = <1 0 0>;
-		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
-			"CAM_RESET1",
-			"CAM_STANDBY";
-		qcom,csi-lane-assign = <0x4320>;
-		qcom,csi-lane-mask = <0x1f>;
-		qcom,sensor-position = <0>;
-		qcom,sensor-mode = <1>;
-		qcom,cci-master = <0>;
-	};
-
 	actuator1: qcom,actuator@18 {
 		cell-index = <4>;
 		reg = <0x18>;
@@ -252,89 +213,6 @@
 		qcom,cam-power-seq-delay = <1 1 10 10 10 5>;
 	};
 
-	qcom,camera@6c {
-		compatible = "qcom,ov12830";
-		reg = <0x6c>;
-		qcom,slave-id = <0x20 0x300a 0xc830>;
-		qcom,csiphy-sd-index = <0>;
-		qcom,csid-sd-index = <0>;
-		qcom,actuator-src = <&actuator1>;
-		qcom,led-flash-src = <&led_flash0>;
-		qcom,eeprom-src = <&eeprom1>;
-		qcom,mount-angle = <90>;
-		qcom,sensor-name = "skuf_ov12830_p12v01c";
-		cam_vdig-supply = <&pm8226_l5>;
-		cam_vana-supply = <&pm8226_l19>;
-		cam_vio-supply = <&pm8226_lvs1>;
-		cam_vaf-supply = <&pm8226_l15>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
-                             "cam_vaf";
-		qcom,cam-vreg-type = <0 1 0 0>;
-		qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
-		qcom,cam-vreg-max-voltage = <1200000 0  2850000 2800000>;
-		qcom,cam-vreg-op-mode = <120000 0 0 80000 100000>;
-		qcom,gpio-no-mux = <0>;
-		gpios = <&msmgpio 26 0>,
-			<&msmgpio 37 0>,
-			<&msmgpio 36 0>,
-			<&msmgpio 22 0>,
-			<&msmgpio 34 0>;
-		qcom,gpio-reset = <1>;
-		qcom,gpio-standby = <2>;
-		qcom,gpio-vdig = <3>;
-		qcom,gpio-af-pwdm = <4>;
-		qcom,gpio-req-tbl-num = <0 1 2 3 4>;
-		qcom,gpio-req-tbl-flags = <1 0 0 0 0>;
-		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
-			"CAM_RESET1",
-			"CAM_STANDBY",
-			"CAM_VDIG",
-			"CAM_AF_PWDM";
-		qcom,csi-lane-assign = <0x4320>;
-		qcom,csi-lane-mask = <0x1f>;
-		qcom,sensor-position = <0>;
-		qcom,sensor-mode = <1>;
-		qcom,cci-master = <0>;
-	};
-
-	qcom,camera@6d {
-		compatible = "qcom,ov9724";
-		reg = <0x6d>;
-		qcom,slave-id = <0x20 0x0 0x9724>;
-		qcom,csiphy-sd-index = <1>;
-		qcom,csid-sd-index = <1>;
-		qcom,mount-angle = <270>;
-		qcom,sensor-name = "ov9724";
-		cam_vdig-supply = <&pm8226_l5>;
-		cam_vana-supply = <&pm8226_l19>;
-		cam_vio-supply = <&pm8226_lvs1>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
-		qcom,cam-vreg-type = <0 1 0>;
-		qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
-		qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
-		qcom,cam-vreg-op-mode = <200000 0 80000>;
-		qcom,gpio-no-mux = <0>;
-		gpios = <&msmgpio 26 0>,
-				<&msmgpio 28 0>,
-				<&msmgpio 35 0>;
-		qcom,gpio-reset = <1>;
-		qcom,gpio-standby = <2>;
-		qcom,gpio-req-tbl-num = <0 1 2>;
-		qcom,gpio-req-tbl-flags = <1 0 0>;
-		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
-				"CAM_RESET",
-				"CAM_STANDBY";
-		qcom,gpio-set-tbl-num = <1 1>;
-		qcom,gpio-set-tbl-flags = <0 2>;
-		qcom,gpio-set-tbl-delay = <1000 4000>;
-		qcom,csi-lane-assign = <0x4320>;
-		qcom,csi-lane-mask = <0x3>;
-		qcom,sensor-position = <1>;
-		qcom,sensor-mode = <1>;
-		qcom,cci-master = <0>;
-		status = "ok";
-	};
-
 	eeprom2: qcom,eeprom@6b{
 		cell-index = <2>;
 		reg = <0x6b 0x0>;
@@ -401,47 +279,6 @@
 		qcom,cam-power-seq-delay = <1 1 10 10 10 5>;
 	};
 
-	qcom,camera@6a {
-		compatible = "ovti,ov5648";
-		reg = <0x6a>;
-		qcom,slave-id = <0x6c 0x300a 0x5648>;
-		qcom,csiphy-sd-index = <1>;
-		qcom,csid-sd-index = <1>;
-		qcom,eeprom-src = <&eeprom2>;
-		qcom,mount-angle = <270>;
-		qcom,sensor-name = "skuf_ov5648_p5v23c";
-		cam_vdig-supply = <&pm8226_l5>;
-		cam_vana-supply = <&pm8226_l19>;
-		cam_vio-supply = <&pm8226_lvs1>;
-		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
-		qcom,cam-vreg-type = <0 1 0>;
-		qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
-		qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
-		qcom,cam-vreg-op-mode = <200000 0 80000>;
-		qcom,gpio-no-mux = <0>;
-		gpios = <&msmgpio 26 0>,
-				<&msmgpio 28 0>,
-				<&msmgpio 35 0>,
-				<&msmgpio 21 0>;
-		qcom,gpio-reset = <1>;
-		qcom,gpio-standby = <2>;
-		qcom,gpio-vdig = <3>;
-		qcom,gpio-req-tbl-num = <0 1 2 3>;
-		qcom,gpio-req-tbl-flags = <1 0 0 0>;
-		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
-				"CAM_RESET",
-				"CAM_STANDBY",
-				"CAM_VDIG";
-		qcom,gpio-set-tbl-num = <1 1>;
-		qcom,gpio-set-tbl-flags = <0 2>;
-		qcom,gpio-set-tbl-delay = <1000 4000>;
-		qcom,csi-lane-assign = <0x4320>;
-		qcom,csi-lane-mask = <0x3>;
-		qcom,sensor-position = <1>;
-		qcom,sensor-mode = <1>;
-		qcom,cci-master = <0>;
-		status = "ok";
-	};
 	qcom,camera@0 {
 		cell-index = <0>;
 		compatible = "qcom,camera";
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index 78e1a63..6ac7189 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -528,3 +528,7 @@
 &pm8226_chg_otg {
 	regulator-name = "8226_smbbp_otg";
 };
+
+&pm8226_chg_chgr {
+	regulator-name = "flash_wa";
+};
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index 5bdd10a..b996d29 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1,6 +1,6 @@
 /* Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -1242,7 +1242,7 @@
 	}
 	case AUDIO_ASYNC_READ: {
 		mutex_lock(&audio->read_lock);
-		if ((audio->feedback) && (audio->enabled))
+		if (audio->feedback)
 			rc = audio_aio_buf_add(audio, 0,
 					(void __user *)arg);
 		else
diff --git a/arch/arm/mach-msm/rpm_log.c b/arch/arm/mach-msm/rpm_log.c
index 1809cea..3cc012e 100755
--- a/arch/arm/mach-msm/rpm_log.c
+++ b/arch/arm/mach-msm/rpm_log.c
@@ -227,9 +227,10 @@
 						&(buf->read_idx));
 	}
 
-	if ((file->f_flags & O_NONBLOCK) && buf->len == 0)
+	if ((file->f_flags & O_NONBLOCK) && buf->len == 0) {
 		mutex_unlock(&buf->mutex);
 		return -EAGAIN;
+	}
 
 	/* loop until new messages arrive */
 	while (buf->len == 0) {
diff --git a/arch/arm/mach-msm/rpm_rbcpr_stats_v2.c b/arch/arm/mach-msm/rpm_rbcpr_stats_v2.c
index 8f0ccd4..bfa2570 100644
--- a/arch/arm/mach-msm/rpm_rbcpr_stats_v2.c
+++ b/arch/arm/mach-msm/rpm_rbcpr_stats_v2.c
@@ -42,9 +42,12 @@
 
 enum {
 	CORNER_OFF,
-	CORNER_SVS,
+	CORNER_RETENTION,
+	CORNER_SVS_KRAIT,
+	CORNER_SVS_SOC,
 	CORNER_NOMINAL,
 	CORNER_TURBO,
+	CORNER_SUPER_TURBO,
 	CORNER_MAX,
 };
 
@@ -54,7 +57,7 @@
 };
 
 struct rbcpr_corners_data_type {
-	uint32_t efuse_adjustment;
+	int32_t efuse_adjustment;
 	uint32_t programmed_voltage;
 	uint32_t isr_count;
 	uint32_t min_count;
@@ -62,10 +65,12 @@
 	struct rbcpr_recmnd_data_type rbcpr_recmnd[RBCPR_NUM_RECMNDS];
 };
 
-struct rbcpr_rail_stats_type {
+struct rbcpr_rail_stats_header_type {
 	uint32_t num_corners;
 	uint32_t num_latest_recommends;
-	struct rbcpr_corners_data_type rbcpr_corners[RBCPR_NUM_CORNERS];
+};
+
+struct rbcpr_rail_stats_footer_type {
 	uint32_t current_corner;
 	uint32_t railway_voltage;
 	uint32_t off_corner;
@@ -75,7 +80,6 @@
 struct rbcpr_stats_type {
 	uint32_t num_rails;
 	uint32_t status;
-	struct rbcpr_rail_stats_type *rbcpr_rail;
 };
 
 struct rbcpr_data_type {
@@ -91,106 +95,158 @@
 
 static char *rbcpr_corner_string[] = {
 	[CORNER_OFF] = "CORNERS_OFF",
-	[CORNER_SVS] = "SVS",
+	[CORNER_RETENTION] = "RETENTION",
+	[CORNER_SVS_KRAIT] = "SVS",
+	[CORNER_SVS_SOC] = "SVS_SOC",
 	[CORNER_NOMINAL] = "NOMINAL",
 	[CORNER_TURBO] = "TURBO",
+	[CORNER_SUPER_TURBO] = "SUPER_TURBO",
 };
+
 #define CORNER_STRING(a)	\
 	((a >= CORNER_MAX) ? "INVALID Corner" : rbcpr_corner_string[a])
 
 static struct rbcpr_data_type *rbcpr_data;
-static struct rbcpr_stats_type *rbcpr_stats;
 
-static void msm_rpmrbcpr_read_rpm_data(void)
+static void msm_rpmrbcpr_print_stats_header(
+		struct rbcpr_stats_type *rbcpr_stats, char *buf,
+						uint32_t *pos)
 {
-	uint32_t start_offset;
-	uint32_t stats_size;
-
-	start_offset = offsetof(struct rbcpr_stats_type, rbcpr_rail);
-	stats_size =
-		rbcpr_stats->num_rails * sizeof(struct rbcpr_rail_stats_type);
-
-	if (stats_size > RBCPR_STATS_MAX_SIZE) {
-		pr_err("%s: Max copy size exceeded. stats size %d max %d",
-			__func__, stats_size, RBCPR_STATS_MAX_SIZE);
-		return;
-	}
-
-	memcpy_fromio(rbcpr_stats->rbcpr_rail,
-		(rbcpr_data->start + start_offset), stats_size);
-}
-
-static uint32_t msm_rpmrbcpr_print_data(void)
-{
-	uint32_t pos = 0;
-	uint32_t i, j, k;
-	struct rbcpr_rail_stats_type *rail;
-	struct rbcpr_corners_data_type *corner;
-	struct rbcpr_recmnd_data_type *rbcpr_recmnd;
-	char *buf = rbcpr_data->buf;
-
-	pos += PRINT(buf, pos, ":RBCPR STATS\n");
-	pos += PRINT(buf, pos, "(%s: %d)", FIELD(rbcpr_stats->num_rails),
+	*pos += PRINT(buf, *pos, "\n:RBCPR STATS  ");
+	*pos += PRINT(buf, *pos, "(%s: %d)", FIELD(rbcpr_stats->num_rails),
 				rbcpr_stats->num_rails);
-	pos += PRINT(buf, pos, "(%s: %d)\n", FIELD(rbcpr_stats->status),
+	*pos += PRINT(buf, *pos, "(%s: %d)", FIELD(rbcpr_stats->status),
 				rbcpr_stats->status);
-
-
-	for (i = 0; i < rbcpr_stats->num_rails; i++) {
-		rail = &rbcpr_stats->rbcpr_rail[i];
-		pos += PRINT(buf, pos, ":%s Rail Data\n", rbcpr_rail_labels[i]);
-		pos += PRINT(buf, pos, "(%s: %s)",
-			FIELD(rail->current_corner),
-			CORNER_STRING(rail->current_corner));
-		pos += PRINT(buf, pos, "(%s: %d)",
-			FIELD(rail->railway_voltage), rail->railway_voltage);
-		pos += PRINT(buf, pos, "(%s: %d)",
-			FIELD(rail->off_corner), rail->off_corner);
-		pos += PRINT(buf, pos, "(%s: %d)\n",
-			FIELD(rail->margin), rail->margin);
-
-		for (j = 0; j < RBCPR_NUM_CORNERS; j++) {
-			pos += PRINT(buf, pos, "\t\tCorner Data:%s ",
-							CORNER_STRING(j + 1));
-			corner = &rail->rbcpr_corners[j];
-			pos += PRINT(buf, pos, "(%s: %d)",
-				FIELD(corner->efuse_adjustment),
-						corner->efuse_adjustment);
-			pos += PRINT(buf, pos, "(%s: %d)",
-				FIELD(corner->programmed_voltage),
-						corner->programmed_voltage);
-			pos += PRINT(buf, pos, "(%s: %d)",
-				FIELD(corner->isr_count), corner->isr_count);
-			pos += PRINT(buf, pos, "(%s: %d)",
-				FIELD(corner->min_count), corner->min_count);
-			pos += PRINT(buf, pos, "(%s: %d)\n",
-				FIELD(corner->max_count), corner->max_count);
-
-
-			for (k = 0; k < RBCPR_NUM_RECMNDS; k++) {
-				rbcpr_recmnd = &corner->rbcpr_recmnd[k];
-				pos += PRINT(buf, pos,
-					"\t\t\t\tVoltage History[%d] ", k);
-				pos += PRINT(buf, pos, " (%s: %d) ",
-					FIELD(rbcpr_recmd->microvolts),
-						rbcpr_recmnd->microvolts);
-				pos += PRINT(buf, pos, " (%s: %lld)\n",
-					FIELD(rbcpr_recmd->timestamp),
-						rbcpr_recmnd->timestamp);
-			}
-		}
-	}
-
-	return pos;
 }
 
-
-static int msm_rpmrbcpr_file_read(struct file *file, char __user *bufu,
-					size_t count, loff_t *ppos)
+static void msm_rpmrbcpr_print_rail_header(
+		struct rbcpr_rail_stats_header_type *rail_header, char *buf,
+							uint32_t *pos)
 {
-	struct rbcpr_data_type *pdata = file->private_data;
+	*pos += PRINT(buf, *pos, "(%s: %d)", FIELD(rail_header->num_corners),
+				rail_header->num_corners);
+	*pos += PRINT(buf, *pos, "(%s: %d)",
+			FIELD(rail_header->num_latest_recommends),
+			rail_header->num_latest_recommends);
+}
+
+static void msm_rpmrbcpr_print_corner_recmnds(
+		struct rbcpr_recmnd_data_type *rbcpr_recmnd, char *buf,
+							uint32_t *pos)
+{
+	*pos += PRINT(buf, *pos, "\n\t\t\t :(%s: %d) ",
+						FIELD(rbcpr_recmd->microvolts),
+						rbcpr_recmnd->microvolts);
+	*pos += PRINT(buf, *pos, " (%s: %lld)", FIELD(rbcpr_recmd->timestamp),
+						rbcpr_recmnd->timestamp);
+}
+
+static void msm_rpmrbcpr_print_corner_data(
+		struct rbcpr_corners_data_type *corner, char *buf,
+			uint32_t num_corners, uint32_t *pos)
+{
+	int i;
+
+	*pos += PRINT(buf, *pos, "(%s: %d)",
+			FIELD(corner->efuse_adjustment),
+					corner->efuse_adjustment);
+	*pos += PRINT(buf, *pos, "(%s: %d)",
+			FIELD(corner->programmed_voltage),
+					corner->programmed_voltage);
+	*pos += PRINT(buf, *pos, "(%s: %d)",
+			FIELD(corner->isr_count), corner->isr_count);
+	*pos += PRINT(buf, *pos, "(%s: %d)",
+			FIELD(corner->min_count), corner->min_count);
+	*pos += PRINT(buf, *pos, "(%s: %d)\n",
+			FIELD(corner->max_count), corner->max_count);
+	*pos += PRINT(buf, *pos, "\t\t\t:Latest Recommends");
+	for (i = 0; i < num_corners; i++)
+		msm_rpmrbcpr_print_corner_recmnds(&corner->rbcpr_recmnd[i], buf,
+						pos);
+}
+
+static void msm_rpmrbcpr_print_rail_footer(
+		struct rbcpr_rail_stats_footer_type *rail, char *buf,
+							uint32_t *pos)
+{
+	*pos += PRINT(buf, *pos, "(%s: %s)", FIELD(rail->current_corner),
+			CORNER_STRING(rail->current_corner));
+	*pos += PRINT(buf, *pos, "(%s: %d)",
+			FIELD(rail->railway_voltage), rail->railway_voltage);
+	*pos += PRINT(buf, *pos, "(%s: %d)",
+			FIELD(rail->off_corner), rail->off_corner);
+	*pos += PRINT(buf, *pos, "(%s: %d)\n",
+			FIELD(rail->margin), rail->margin);
+}
+
+static uint32_t msm_rpmrbcpr_read_rpm_data(void)
+{
+	uint32_t read_offset = 0;
+	static struct rbcpr_stats_type rbcpr_stats_header;
+	uint32_t buffer_offset = 0;
+	char *buf = rbcpr_data->buf;
+	int i, j;
+
+	memcpy_fromio(&rbcpr_stats_header, rbcpr_data->start,
+					sizeof(rbcpr_stats_header));
+	read_offset += sizeof(rbcpr_stats_header);
+	msm_rpmrbcpr_print_stats_header(&rbcpr_stats_header, buf,
+							&buffer_offset);
+
+	for (i = 0; i < rbcpr_stats_header.num_rails; i++) {
+		static struct rbcpr_rail_stats_header_type rail_header;
+		static struct rbcpr_rail_stats_footer_type rail_footer;
+
+		memcpy_fromio(&rail_header, (rbcpr_data->start + read_offset),
+					sizeof(rail_header));
+		read_offset += sizeof(rail_header);
+		buffer_offset += PRINT(buf, buffer_offset, "\n:%s Rail Data ",
+							rbcpr_rail_labels[i]);
+		msm_rpmrbcpr_print_rail_header(&rail_header, buf,
+							&buffer_offset);
+
+		for (j = 0; j < rail_header.num_corners; j++) {
+			static struct rbcpr_corners_data_type corner;
+			uint32_t corner_index;
+
+			memcpy_fromio(&corner,
+					(rbcpr_data->start + read_offset),
+					sizeof(corner));
+			read_offset += sizeof(corner);
+
+			/*
+			 * RPM doesn't include corner type in the data for the
+			 * corner. For now add this hack to know which corners
+			 * are used based on number of corners for the rail.
+			 */
+			corner_index = j + 3;
+			if (rail_header.num_corners == 3 && j == 2)
+				corner_index++;
+
+			buffer_offset += PRINT(buf, buffer_offset,
+				"\n\t\t:Corner Data: %s ",
+					CORNER_STRING(corner_index));
+			msm_rpmrbcpr_print_corner_data(&corner, buf,
+				rail_header.num_latest_recommends,
+				&buffer_offset);
+		}
+		buffer_offset += PRINT(buf, buffer_offset,
+				"\n\t\t");
+		memcpy_fromio(&rail_footer, (rbcpr_data->start + read_offset),
+					sizeof(rail_footer));
+		read_offset += sizeof(rail_footer);
+		msm_rpmrbcpr_print_rail_footer(&rail_footer, buf,
+							&buffer_offset);
+	}
+	return buffer_offset;
+}
+
+static int msm_rpmrbcpr_file_read(struct seq_file *m, void *data)
+{
+	struct rbcpr_data_type *pdata = m->private;
 	int ret = 0;
-	int status_counter;
+	int curr_status_counter;
+	static int prev_status_counter;
 	static DEFINE_MUTEX(rbcpr_lock);
 
 	mutex_lock(&rbcpr_lock);
@@ -200,27 +256,17 @@
 		goto exit_rpmrbcpr_file_read;
 	}
 
-	if (!bufu || count < 0) {
-		pr_err("%s count %d ", __func__, count);
-		ret = -EINVAL;
-		goto exit_rpmrbcpr_file_read;
+	/* Read RPM stats */
+	curr_status_counter = readl_relaxed(pdata->start +
+		offsetof(struct rbcpr_stats_type, status));
+	if (curr_status_counter != prev_status_counter) {
+		pdata->len = msm_rpmrbcpr_read_rpm_data();
+		pdata->len = 0;
+		prev_status_counter = curr_status_counter;
 	}
 
-	if (*ppos > pdata->len || !*ppos) {
-		/* Read RPM stats */
-		status_counter = readl_relaxed(pdata->start +
-			offsetof(struct rbcpr_stats_type, status));
-		if (status_counter != rbcpr_stats->status) {
-			msm_rpmrbcpr_read_rpm_data();
-			rbcpr_stats->status = status_counter;
-		}
-		pdata->len = msm_rpmrbcpr_print_data();
-		*ppos = 0;
-	}
+	seq_printf(m, "%s", pdata->buf);
 
-	/* copy to user data*/
-	ret = simple_read_from_buffer(bufu, count, ppos, pdata->buf,
-					pdata->len);
 exit_rpmrbcpr_file_read:
 	mutex_unlock(&rbcpr_lock);
 	return ret;
@@ -228,77 +274,31 @@
 
 static int msm_rpmrbcpr_file_open(struct inode *inode, struct file *file)
 {
-	file->private_data = rbcpr_data;
-
 	if (!rbcpr_data->start)
 		return -ENODEV;
-
-	return 0;
-}
-
-static int msm_rpmrbcpr_file_close(struct inode *inode, struct file *file)
-{
-	return 0;
+	return single_open(file, msm_rpmrbcpr_file_read, inode->i_private);
 }
 
 static const struct file_operations msm_rpmrbcpr_fops = {
-	.owner    = THIS_MODULE,
-	.open     = msm_rpmrbcpr_file_open,
-	.read     = msm_rpmrbcpr_file_read,
-	.release  = msm_rpmrbcpr_file_close,
-	.llseek   = no_llseek,
+	.open		= msm_rpmrbcpr_file_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
 };
 
-static int msm_rpmrbcpr_memalloc(struct platform_device *pdev)
+static int msm_rpmrbcpr_validate(struct platform_device *pdev)
 {
-	void *addr = NULL;
 	int ret = 0;
-	uint32_t num_latest_recommends = 0;
-	uint32_t num_corners = 0;
+	uint32_t num_rails;
 
-	rbcpr_stats->num_rails = readl_relaxed(rbcpr_data->start);
+	num_rails = readl_relaxed(rbcpr_data->start);
 
-	if (rbcpr_stats->num_rails > RBCPR_MAX_RAILS) {
+	if (num_rails > RBCPR_MAX_RAILS) {
 		pr_err("%s: Invalid number of RPM RBCPR rails %d",
-				__func__, rbcpr_stats->num_rails);
-		rbcpr_stats->num_rails = 0;
+				__func__, num_rails);
 		ret = -EFAULT;
-		goto rbcpr_memalloc_fail;
 	}
 
-	rbcpr_stats->rbcpr_rail =
-		devm_kzalloc(&pdev->dev,
-			sizeof(struct rbcpr_rail_stats_type) *
-			rbcpr_stats->num_rails, GFP_KERNEL);
-
-	if (!rbcpr_stats->rbcpr_rail) {
-		ret = -ENOMEM;
-		goto rbcpr_memalloc_fail;
-	}
-
-	addr = rbcpr_data->start + offsetof(struct rbcpr_stats_type,
-								rbcpr_rail);
-
-	/* Each rail has the same number of corners and number of latest
-	   recommended values. Read these from the first rail and check them
-	   to make sure the values are valid. (RPM doesn't 0 initialize this
-	   memory region, so its possible we end up with bogus values if the
-	   rbcpr driver is not initialized.).
-	*/
-	num_corners = readl_relaxed(addr);
-	num_latest_recommends = readl_relaxed(addr +
-				offsetof(struct rbcpr_rail_stats_type,
-						num_latest_recommends));
-
-	if ((num_latest_recommends != RBCPR_NUM_RECMNDS)
-		|| (num_corners != RBCPR_NUM_CORNERS)) {
-		pr_err("%s: Invalid num corners %d, num recmnds %d",
-			__func__, num_corners, num_latest_recommends);
-		ret = -EFAULT;
-		goto rbcpr_memalloc_fail;
-	}
-
-rbcpr_memalloc_fail:
 	return ret;
 }
 
@@ -318,15 +318,6 @@
 	if (!rbcpr_data)
 		return -ENOMEM;
 
-	rbcpr_stats = devm_kzalloc(&pdev->dev,
-				sizeof(struct rbcpr_stats_type), GFP_KERNEL);
-
-	if (!rbcpr_stats) {
-		pr_err("%s: Failed to allocate memory for RBCPR stats",
-						__func__);
-		return -ENOMEM;
-	}
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 	if (!res) {
@@ -371,13 +362,13 @@
 		goto rbcpr_probe_fail;
 	}
 
-	ret = msm_rpmrbcpr_memalloc(pdev);
+	ret = msm_rpmrbcpr_validate(pdev);
 
 	if (ret)
 		goto rbcpr_probe_fail;
 
 	dent = debugfs_create_file("rpm_rbcpr", S_IRUGO, NULL,
-			pdev->dev.platform_data, &msm_rpmrbcpr_fops);
+			rbcpr_data, &msm_rpmrbcpr_fops);
 
 	if (!dent) {
 		pr_err("%s: error debugfs_create_file failed\n", __func__);
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7ad6401..f055aa7 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -164,7 +164,8 @@
 	return mask;
 }
 
-static void __dma_clear_buffer(struct page *page, size_t size)
+static void __dma_clear_buffer(struct page *page, size_t size,
+					struct dma_attrs *attrs)
 {
 	/*
 	 * Ensure that the allocated pages are zeroed, and that any data
@@ -173,7 +174,8 @@
 	if (!PageHighMem(page)) {
 		void *ptr = page_address(page);
 		if (ptr) {
-			memset(ptr, 0, size);
+			if (!dma_get_attr(DMA_ATTR_SKIP_ZEROING, attrs))
+				memset(ptr, 0, size);
 			dmac_flush_range(ptr, ptr + size);
 			outer_flush_range(__pa(ptr), __pa(ptr) + size);
 		}
@@ -182,7 +184,8 @@
 		phys_addr_t end = base + size;
 		while (size > 0) {
 			void *ptr = kmap_atomic(page);
-			memset(ptr, 0, PAGE_SIZE);
+			if (!dma_get_attr(DMA_ATTR_SKIP_ZEROING, attrs))
+				memset(ptr, 0, PAGE_SIZE);
 			dmac_flush_range(ptr, ptr + PAGE_SIZE);
 			kunmap_atomic(ptr);
 			page++;
@@ -212,7 +215,7 @@
 	for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
 		__free_page(p);
 
-	__dma_clear_buffer(page, size);
+	__dma_clear_buffer(page, size, NULL);
 
 	return page;
 }
@@ -523,8 +526,12 @@
 	if (!page)
 		return NULL;
 
-	if (!dma_get_attr(DMA_ATTR_SKIP_ZEROING, attrs))
-		__dma_clear_buffer(page, size);
+	/*
+	 * skip completely if we neither need to zero nor sync.
+	 */
+	if (!(dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs) &&
+	      dma_get_attr(DMA_ATTR_SKIP_ZEROING, attrs)))
+		__dma_clear_buffer(page, size, attrs);
 
 	if (!PageHighMem(page)) {
 		__dma_remap(page, size, prot, no_kernel_mapping);
@@ -1020,7 +1027,7 @@
 		while (--j)
 			pages[i + j] = pages[i] + j;
 
-		__dma_clear_buffer(pages[i], PAGE_SIZE << order);
+		__dma_clear_buffer(pages[i], PAGE_SIZE << order, NULL);
 		i += 1 << order;
 		count -= 1 << order;
 	}
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index c8ea471..8f3760c 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -390,7 +390,7 @@
 
 static int kgsl_page_alloc_vmflags(struct kgsl_memdesc *memdesc)
 {
-	return VM_RESERVED | VM_DONTEXPAND;
+	return VM_RESERVED | VM_DONTEXPAND | VM_DONTCOPY;
 }
 
 static void kgsl_page_alloc_free(struct kgsl_memdesc *memdesc)
@@ -412,7 +412,7 @@
 
 static int kgsl_contiguous_vmflags(struct kgsl_memdesc *memdesc)
 {
-	return VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
+	return VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTCOPY;
 }
 
 /*
diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
index 96b058b..5847b4b 100644
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.c
@@ -1128,7 +1128,7 @@
 
 	for_each_child_of_node(node, child) {
 		int channel_num, scaling, post_scaling, hw_settle_time;
-		int fast_avg_setup, calib_type, rc;
+		int fast_avg_setup, calib_type = 0, rc;
 		const char *calibration_param, *channel_name;
 
 		channel_name = of_get_property(child,
@@ -1149,23 +1149,40 @@
 			pr_err("Invalid channel decimation property\n");
 			return -EINVAL;
 		}
-		rc = of_property_read_u32(child,
-				"qcom,pre-div-channel-scaling", &scaling);
-		if (rc) {
-			pr_err("Invalid channel scaling property\n");
-			return -EINVAL;
-		}
-		rc = of_property_read_u32(child,
-				"qcom,scale-function", &post_scaling);
-		if (rc) {
-			pr_err("Invalid channel post scaling property\n");
-			return -EINVAL;
-		}
-		rc = of_property_read_u32(child,
+		if (!of_device_is_compatible(node, "qcom,qpnp-iadc")) {
+			rc = of_property_read_u32(child,
 				"qcom,hw-settle-time", &hw_settle_time);
-		if (rc) {
-			pr_err("Invalid channel hw settle time property\n");
-			return -EINVAL;
+			if (rc) {
+				pr_err("Invalid channel hw settle time property\n");
+				return -EINVAL;
+			}
+			rc = of_property_read_u32(child,
+				"qcom,pre-div-channel-scaling", &scaling);
+			if (rc) {
+				pr_err("Invalid channel scaling property\n");
+				return -EINVAL;
+			}
+			rc = of_property_read_u32(child,
+				"qcom,scale-function", &post_scaling);
+			if (rc) {
+				pr_err("Invalid channel post scaling property\n");
+				return -EINVAL;
+			}
+			rc = of_property_read_string(child,
+				"qcom,calibration-type", &calibration_param);
+			if (rc) {
+				pr_err("Invalid calibration type\n");
+				return -EINVAL;
+			}
+			if (!strcmp(calibration_param, "absolute"))
+				calib_type = CALIB_ABSOLUTE;
+			else if (!strcmp(calibration_param, "ratiometric"))
+				calib_type = CALIB_RATIOMETRIC;
+			else {
+				pr_err("%s: Invalid calibration property\n",
+						__func__);
+				return -EINVAL;
+			}
 		}
 		rc = of_property_read_u32(child,
 				"qcom,fast-avg-setup", &fast_avg_setup);
@@ -1173,29 +1190,17 @@
 			pr_err("Invalid channel fast average setup\n");
 			return -EINVAL;
 		}
-		rc = of_property_read_string(child, "qcom,calibration-type",
-							&calibration_param);
-		if (rc) {
-			pr_err("Invalid calibration type\n");
-			return -EINVAL;
-		}
-		if (!strncmp(calibration_param, "absolute", 8))
-			calib_type = CALIB_ABSOLUTE;
-		else if (!strncmp(calibration_param, "ratiometric", 11))
-			calib_type = CALIB_RATIOMETRIC;
-		else {
-			pr_err("%s: Invalid calibration property\n", __func__);
-			return -EINVAL;
-		}
 		/* Individual channel properties */
 		adc_channel_list[i].name = (char *)channel_name;
 		adc_channel_list[i].channel_num = channel_num;
-		adc_channel_list[i].chan_path_prescaling = scaling;
 		adc_channel_list[i].adc_decimation = decimation;
-		adc_channel_list[i].adc_scale_fn = post_scaling;
-		adc_channel_list[i].hw_settle_time = hw_settle_time;
 		adc_channel_list[i].fast_avg_setup = fast_avg_setup;
-		adc_channel_list[i].calib_type = calib_type;
+		if (!of_device_is_compatible(node, "qcom,qpnp-iadc")) {
+			adc_channel_list[i].chan_path_prescaling = scaling;
+			adc_channel_list[i].adc_scale_fn = post_scaling;
+			adc_channel_list[i].hw_settle_time = hw_settle_time;
+			adc_channel_list[i].calib_type = calib_type;
+		}
 		i++;
 	}
 
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index dddbbd0..1354907 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -70,7 +70,6 @@
 #define QPNP_ADC_DEC_RATIO_SEL_MASK			0xc
 #define QPNP_ADC_DIG_DEC_RATIO_SEL_SHIFT		2
 
-#define QPNP_HW_SETTLE_DELAY				0x51
 #define QPNP_CONV_REQ					0x52
 #define QPNP_CONV_REQ_SET				BIT(7)
 #define QPNP_CONV_SEQ_CTL				0x54
@@ -163,6 +162,7 @@
 	bool					iadc_poll_eoc;
 	u16					batt_id_trim_cnst_rds;
 	int					rds_trim_default_type;
+	int					max_channels_available;
 	bool					rds_trim_default_check;
 	int32_t					rsense_workaround_value;
 	struct sensor_device_attribute		sens_attr[0];
@@ -802,13 +802,6 @@
 		return rc;
 	}
 
-	rc = qpnp_iadc_write_reg(iadc, QPNP_HW_SETTLE_DELAY,
-				iadc->adc->amux_prop->hw_settle_time);
-	if (rc < 0) {
-		pr_err("qpnp adc configure error for hw settling time setup\n");
-		return rc;
-	}
-
 	rc = qpnp_iadc_write_reg(iadc, QPNP_FAST_AVG_CTL,
 					iadc->adc->amux_prop->fast_avg_setup);
 	if (rc < 0) {
@@ -927,6 +920,9 @@
 		pm_stay_awake(iadc->dev);
 	}
 
+	iadc->adc->amux_prop->decimation = DECIMATION_TYPE1;
+	iadc->adc->amux_prop->fast_avg_setup = ADC_FAST_AVG_SAMPLE_1;
+
 	rc = qpnp_iadc_configure(iadc, GAIN_CALIBRATION_17P857MV,
 						&raw_data, mode_sel);
 	if (rc < 0) {
@@ -1170,6 +1166,7 @@
 	int32_t rsense_u_ohms = 0;
 	int64_t result_current;
 	uint16_t raw_data;
+	int dt_index = 0;
 
 	if (qpnp_iadc_is_valid(iadc) < 0)
 		return -EPROBE_DEFER;
@@ -1187,6 +1184,22 @@
 
 	mutex_lock(&iadc->adc->adc_lock);
 
+	while (((enum qpnp_iadc_channels)
+		iadc->adc->adc_channels[dt_index].channel_num
+		!= channel) && (dt_index < iadc->max_channels_available))
+		dt_index++;
+
+	if (dt_index >= iadc->max_channels_available) {
+		pr_err("not a valid IADC channel\n");
+		rc = -EINVAL;
+		goto fail;
+	}
+
+	iadc->adc->amux_prop->decimation =
+			iadc->adc->adc_channels[dt_index].adc_decimation;
+	iadc->adc->amux_prop->fast_avg_setup =
+			iadc->adc->adc_channels[dt_index].fast_avg_setup;
+
 	if (iadc->iadc_poll_eoc) {
 		pr_debug("acquiring iadc eoc wakelock\n");
 		pm_stay_awake(iadc->dev);
@@ -1289,6 +1302,7 @@
 	enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result)
 {
 	int rc = 0, mode_sel = 0, num = 0, rsense_n_ohms = 0, sign = 0;
+	int dt_index = 0;
 	uint16_t raw_data;
 	int32_t rsense_u_ohms = 0;
 	int64_t result_current;
@@ -1316,6 +1330,22 @@
 		goto fail;
 	}
 
+	while (((enum qpnp_iadc_channels)
+		iadc->adc->adc_channels[dt_index].channel_num
+		!= i_channel) && (dt_index < iadc->max_channels_available))
+		dt_index++;
+
+	if (dt_index >= iadc->max_channels_available) {
+		pr_err("not a valid IADC channel\n");
+		rc = -EINVAL;
+		goto fail;
+	}
+
+	iadc->adc->amux_prop->decimation =
+			iadc->adc->adc_channels[dt_index].adc_decimation;
+	iadc->adc->amux_prop->fast_avg_setup =
+			iadc->adc->adc_channels[dt_index].fast_avg_setup;
+
 	rc = qpnp_iadc_configure(iadc, i_channel, &raw_data, mode_sel);
 	if (rc < 0) {
 		pr_err("qpnp adc result read failed with %d\n", rc);
@@ -1529,6 +1559,7 @@
 		goto fail;
 	}
 
+	iadc->max_channels_available = count_adc_channel_list;
 	INIT_WORK(&iadc->trigger_completion_work, qpnp_iadc_trigger_completion);
 	INIT_DELAYED_WORK(&iadc->iadc_work, qpnp_iadc_work);
 	rc = qpnp_iadc_comp_info(iadc);
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
old mode 100644
new mode 100755
index 0413472..dd0299e
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -396,6 +396,7 @@
  *  @torch_on - torch status, on or off
  *  @flash_boost_reg - boost regulator for flash
  *  @torch_boost_reg - boost regulator for torch
+ *  @flash_wa_reg - flash regulator for wa
  */
 struct flash_config_data {
 	u8	current_prgm;
@@ -416,6 +417,7 @@
 	bool	torch_on;
 	struct regulator *flash_boost_reg;
 	struct regulator *torch_boost_reg;
+	struct regulator *flash_wa_reg;
 };
 
 /**
@@ -833,6 +835,15 @@
 		for (i = 0; i < led->num_leds; i++) {
 			if (led_array[i].flash_cfg->flash_reg_get) {
 				rc = regulator_enable(
+					led_array[i].flash_cfg->flash_wa_reg);
+				if (rc) {
+					dev_err(&led->spmi_dev->dev,
+						"Flash_wa regulator enable failed(%d)\n",
+								rc);
+					return rc;
+				}
+
+				rc = regulator_enable(
 					led_array[i].flash_cfg->\
 					flash_boost_reg);
 				if (rc) {
@@ -871,6 +882,14 @@
 									rc);
 					return rc;
 				}
+				rc = regulator_disable(
+					led_array[i].flash_cfg->flash_wa_reg);
+				if (rc) {
+					dev_err(&led->spmi_dev->dev,
+						"Flash_wa regulator disable failed(%d)\n",
+								rc);
+					return rc;
+				}
 				led->flash_cfg->flash_on = false;
 			}
 			break;
@@ -2715,6 +2734,21 @@
 	led->flash_cfg->torch_enable =
 		of_property_read_bool(node, "qcom,torch-enable");
 
+	if (of_find_property(of_get_parent(node), "flash-wa-supply",
+					NULL) && (!*reg_set)) {
+		led->flash_cfg->flash_wa_reg =
+			devm_regulator_get(&led->spmi_dev->dev,
+					"flash-wa");
+		if (IS_ERR_OR_NULL(led->flash_cfg->flash_wa_reg)) {
+			rc = PTR_ERR(led->flash_cfg->flash_wa_reg);
+			if (rc != EPROBE_DEFER) {
+				dev_err(&led->spmi_dev->dev,
+						"Falsh wa regulator get failed(%d)\n",
+						rc);
+			}
+		}
+	}
+
 	if (led->id == QPNP_ID_FLASH1_LED0) {
 		led->flash_cfg->enable_module = FLASH_ENABLE_LED_0;
 		led->flash_cfg->current_addr = FLASH_LED_0_CURR(led->base);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index a81c7bb..2567657 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -25,8 +25,8 @@
 static DEFINE_MUTEX(bandwidth_mgr_mutex);
 static struct msm_isp_bandwidth_mgr isp_bandwidth_mgr;
 
-#define MSM_ISP_MIN_AB 450000000
-#define MSM_ISP_MIN_IB 900000000
+#define MSM_ISP_MIN_AB 300000000
+#define MSM_ISP_MIN_IB 450000000
 
 #define VFE40_8974V2_VERSION 0x1001001A
 static struct msm_bus_vectors msm_isp_init_vectors[] = {
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index 7fb312a..79581ce 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -283,6 +283,10 @@
 	int32_t num_steps = move_params->num_steps;
 	struct msm_camera_i2c_reg_setting reg_setting;
 
+	if (a_ctrl->step_position_table == NULL) {
+		pr_err("Step Position Table is NULL");
+		return -EFAULT;
+	}
 	curr_lens_pos = a_ctrl->step_position_table[a_ctrl->curr_step_pos];
 	move_params->curr_lens_pos = curr_lens_pos;
 
@@ -381,7 +385,10 @@
 	for (; data_size > 0; data_size--)
 		max_code_size *= 2;
 
-	kfree(a_ctrl->step_position_table);
+	if ((a_ctrl->actuator_state == ACTUATOR_POWER_UP) &&
+		(a_ctrl->step_position_table != NULL))
+		kfree(a_ctrl->step_position_table);
+
 	a_ctrl->step_position_table = NULL;
 
 	if (set_info->af_tuning_params.total_steps
@@ -392,7 +399,7 @@
 	}
 	/* Fill step position table */
 	a_ctrl->step_position_table =
-		kmalloc(sizeof(uint16_t) *
+		kzalloc(sizeof(uint16_t) *
 		(set_info->af_tuning_params.total_steps + 1), GFP_KERNEL);
 
 	if (a_ctrl->step_position_table == NULL)
@@ -471,10 +478,21 @@
 {
 	int32_t rc = 0;
 	CDBG("Enter\n");
-	if (a_ctrl->vcm_enable) {
-		rc = gpio_direction_output(a_ctrl->vcm_pwd, 0);
-		if (!rc)
-			gpio_free(a_ctrl->vcm_pwd);
+	if (a_ctrl->actuator_state != ACTUATOR_POWER_DOWN) {
+		if (a_ctrl->vcm_enable) {
+			rc = gpio_direction_output(a_ctrl->vcm_pwd, 0);
+			if (!rc)
+				gpio_free(a_ctrl->vcm_pwd);
+		}
+
+		if (a_ctrl->step_position_table != NULL)
+			kfree(a_ctrl->step_position_table);
+		a_ctrl->step_position_table = NULL;
+		if (a_ctrl->i2c_reg_tbl != NULL)
+			kfree(a_ctrl->i2c_reg_tbl);
+		a_ctrl->i2c_reg_tbl = NULL;
+		a_ctrl->i2c_tbl_index = 0;
+		a_ctrl->actuator_state = ACTUATOR_POWER_DOWN;
 	}
 	rc = msm_actuator_vreg_control(a_ctrl, 0);
 	if (rc < 0) {
@@ -592,13 +610,16 @@
 		return -EFAULT;
 	}
 
-	kfree(a_ctrl->i2c_reg_tbl);
+	if ((a_ctrl->actuator_state == ACTUATOR_POWER_UP) &&
+		(a_ctrl->i2c_reg_tbl != NULL))
+		kfree(a_ctrl->i2c_reg_tbl);
 
+	a_ctrl->i2c_reg_tbl = NULL;
 	a_ctrl->i2c_reg_tbl =
-		kmalloc(sizeof(struct msm_camera_i2c_reg_array) *
+		kzalloc(sizeof(struct msm_camera_i2c_reg_array) *
 		(set_info->af_tuning_params.total_steps + 1), GFP_KERNEL);
 	if (!a_ctrl->i2c_reg_tbl) {
-		pr_err("kmalloc fail\n");
+		pr_err("kzalloc fail\n");
 		return -ENOMEM;
 	}
 
@@ -614,7 +635,7 @@
 		set_info->actuator_params.init_setting_size
 		<= MAX_ACTUATOR_REG_TBL_SIZE) {
 		if (a_ctrl->func_tbl->actuator_init_focus) {
-			init_settings = kmalloc(sizeof(struct reg_settings_t) *
+			init_settings = kzalloc(sizeof(struct reg_settings_t) *
 				(set_info->actuator_params.init_setting_size),
 				GFP_KERNEL);
 			if (init_settings == NULL) {
@@ -635,6 +656,7 @@
 				set_info->actuator_params.init_setting_size,
 				init_settings);
 			kfree(init_settings);
+			init_settings = NULL;
 			if (rc < 0) {
 				kfree(a_ctrl->i2c_reg_tbl);
 				pr_err("Error actuator_init_focus\n");
@@ -936,6 +958,7 @@
 	act_ctrl_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
 	act_ctrl_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
 	msm_sd_register(&act_ctrl_t->msm_sd);
+	act_ctrl_t->actuator_state = ACTUATOR_POWER_DOWN;
 	pr_info("msm_actuator_i2c_probe: succeeded\n");
 	CDBG("Exit\n");
 
@@ -1025,6 +1048,7 @@
 	msm_actuator_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
 	msm_actuator_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
 	msm_sd_register(&msm_actuator_t->msm_sd);
+	msm_actuator_t->actuator_state = ACTUATOR_POWER_DOWN;
 	CDBG("Exit\n");
 	return rc;
 }
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h
index b0d9430..2ae1900 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h
@@ -29,6 +29,11 @@
 
 struct msm_actuator_ctrl_t;
 
+enum msm_actuator_state_t {
+	ACTUATOR_POWER_DOWN,
+	ACTUATOR_POWER_UP,
+};
+
 struct msm_actuator_func_tbl {
 	int32_t (*actuator_i2c_write_b_af)(struct msm_actuator_ctrl_t *,
 			uint8_t,
@@ -95,6 +100,7 @@
 	enum cci_i2c_master_t cci_master;
 	uint32_t subdev_id;
 	struct msm_actuator_vreg vreg_cfg;
+	enum msm_actuator_state_t actuator_state;
 };
 
 #endif
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
index 888bbbf..a687779 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,7 @@
 static struct qseecom_handle *sdmx_qseecom_handles[SDMX_MAX_SESSIONS];
 static struct mutex sdmx_lock[SDMX_MAX_SESSIONS];
 
+#define QSEECOM_SBUFF_SIZE	SZ_16K
 #define QSEECOM_ALIGN_SIZE	0x40
 #define QSEECOM_ALIGN_MASK	(QSEECOM_ALIGN_SIZE - 1)
 #define QSEECOM_ALIGN(x)	\
@@ -195,22 +196,27 @@
 struct sdmx_set_log_level_rsp {
 	enum sdmx_status ret;
 };
-static void get_cmd_rsp_buffers(int handle_index,
+static int get_cmd_rsp_buffers(int handle_index,
 	void **cmd,
 	int *cmd_len,
 	void **rsp,
 	int *rsp_len)
 {
-	*cmd = sdmx_qseecom_handles[handle_index]->sbuf;
-
 	if (*cmd_len & QSEECOM_ALIGN_MASK)
 		*cmd_len = QSEECOM_ALIGN(*cmd_len);
 
-	*rsp = sdmx_qseecom_handles[handle_index]->sbuf + *cmd_len;
-
 	if (*rsp_len & QSEECOM_ALIGN_MASK)
 		*rsp_len = QSEECOM_ALIGN(*rsp_len);
 
+	if ((*rsp_len + *cmd_len) > QSEECOM_SBUFF_SIZE) {
+		pr_err("%s: shared buffer too small to hold cmd=%d and rsp=%d\n",
+			__func__, *cmd_len, *rsp_len);
+		return SDMX_STATUS_OUT_OF_MEM;
+	}
+
+	*cmd = sdmx_qseecom_handles[handle_index]->sbuf;
+	*rsp = sdmx_qseecom_handles[handle_index]->sbuf + *cmd_len;
+	return SDMX_SUCCESS;
 }
 
 /*
@@ -237,8 +243,10 @@
 	mutex_lock(&sdmx_lock[session_handle]);
 
 	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
 		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
 
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_GET_VERSION_CMD;
@@ -254,7 +262,7 @@
 
 	ret = rsp->ret;
 	*version = rsp->version;
-
+out:
 	mutex_unlock(&sdmx_lock[session_handle]);
 
 	return ret;
@@ -282,7 +290,8 @@
 		return SDMX_STATUS_GENERAL_FAILURE;
 
 	/* Start the TZ app */
-	res = qseecom_start_app(&qseecom_handle, "securemm", 4096);
+	res = qseecom_start_app(&qseecom_handle, "securemm",
+		QSEECOM_SBUFF_SIZE);
 
 	if (res < 0)
 		return SDMX_STATUS_GENERAL_FAILURE;
@@ -359,8 +368,10 @@
 	mutex_lock(&sdmx_lock[session_handle]);
 
 	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
 		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
 
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_CLOSE_SESSION_CMD;
@@ -385,7 +396,7 @@
 	}
 
 	sdmx_qseecom_handles[session_handle] = NULL;
-
+out:
 	mutex_unlock(&sdmx_lock[session_handle]);
 
 	return ret;
@@ -426,8 +437,10 @@
 	mutex_lock(&sdmx_lock[session_handle]);
 
 	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
 		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
 
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_SET_SESSION_CFG_CMD;
@@ -448,7 +461,7 @@
 	}
 
 	ret = rsp->ret;
-
+out:
 	mutex_unlock(&sdmx_lock[session_handle]);
 
 	return ret;
@@ -503,8 +516,10 @@
 	mutex_lock(&sdmx_lock[session_handle]);
 
 	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
 		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
 
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_ADD_FILTER_CMD;
@@ -537,7 +552,7 @@
 	/* Parse response struct */
 	*filter_handle = rsp->filter_handle;
 	ret = rsp->ret;
-
+out:
 	mutex_unlock(&sdmx_lock[session_handle]);
 
 	return ret;
@@ -569,8 +584,10 @@
 	mutex_lock(&sdmx_lock[session_handle]);
 
 	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
 		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
 
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_REMOVE_FILTER_CMD;
@@ -587,7 +604,7 @@
 	}
 
 	ret = rsp->ret;
-
+out:
 	mutex_unlock(&sdmx_lock[session_handle]);
 
 	return ret;
@@ -623,8 +640,10 @@
 	mutex_lock(&sdmx_lock[session_handle]);
 
 	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
 		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
 
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_SET_KL_IDX_CMD;
@@ -642,7 +661,7 @@
 	}
 
 	ret = rsp->ret;
-
+out:
 	mutex_unlock(&sdmx_lock[session_handle]);
 
 	return ret;
@@ -675,8 +694,10 @@
 	mutex_lock(&sdmx_lock[session_handle]);
 
 	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
 		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
 
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_ADD_RAW_PID_CMD;
@@ -694,7 +715,7 @@
 	}
 
 	ret = rsp->ret;
-
+out:
 	mutex_unlock(&sdmx_lock[session_handle]);
 
 	return ret;
@@ -727,8 +748,10 @@
 	mutex_lock(&sdmx_lock[session_handle]);
 
 	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
 		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
 
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_REMOVE_RAW_PID_CMD;
@@ -746,7 +769,7 @@
 	}
 
 	ret = rsp->ret;
-
+out:
 	mutex_unlock(&sdmx_lock[session_handle]);
 
 	return ret;
@@ -797,8 +820,10 @@
 	mutex_lock(&sdmx_lock[session_handle]);
 
 	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
 		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
 
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_PROCESS_CMD;
@@ -829,7 +854,7 @@
 	memcpy(filter_status, cmd->filters_status,
 		num_filters * sizeof(struct sdmx_filter_status));
 	ret = rsp->ret;
-
+out:
 	mutex_unlock(&sdmx_lock[session_handle]);
 
 	return ret;
@@ -869,8 +894,10 @@
 	mutex_lock(&sdmx_lock[session_handle]);
 
 	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
 		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
 
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_GET_DBG_COUNTERS_CMD;
@@ -892,7 +919,7 @@
 	memcpy(filter_counters, rsp->filter_counters,
 		*num_filters * sizeof(struct sdmx_filter_dbg_counters));
 	ret = rsp->ret;
-
+out:
 	mutex_unlock(&sdmx_lock[session_handle]);
 
 	return ret;
@@ -923,8 +950,10 @@
 	mutex_lock(&sdmx_lock[session_handle]);
 
 	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
 		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
 
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_RESET_DBG_COUNTERS_CMD;
@@ -940,7 +969,7 @@
 	}
 
 	ret = rsp->ret;
-
+out:
 	mutex_unlock(&sdmx_lock[session_handle]);
 
 	return ret;
@@ -965,13 +994,15 @@
 	cmd_len = sizeof(struct sdmx_set_log_level_req);
 	rsp_len = sizeof(struct sdmx_set_log_level_rsp);
 
-	/* Get command and response buffers */
-	get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
-		(void **)&rsp, &rsp_len);
-
 	/* Lock shared memory */
 	mutex_lock(&sdmx_lock[session_handle]);
 
+	/* Get command and response buffers */
+	ret = get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+		(void **)&rsp, &rsp_len);
+	if (ret)
+		goto out;
+
 	/* Populate command struct */
 	cmd->cmd_id = SDMX_SET_LOG_LEVEL_CMD;
 	cmd->session_handle = session_handle;
@@ -985,7 +1016,7 @@
 		return SDMX_STATUS_GENERAL_FAILURE;
 	}
 	ret = rsp->ret;
-
+out:
 	/* Unlock */
 	mutex_unlock(&sdmx_lock[session_handle]);
 	return ret;
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index aaed0e9..5801518 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -327,6 +327,7 @@
 		init_completion(&core->completions[i]);
 	}
 
+	INIT_DELAYED_WORK(&core->fw_unload_work, msm_vidc_fw_unload_handler);
 	return rc;
 }
 
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index bff86a6..30ca194 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -21,8 +21,9 @@
 
 #define MSM_VDEC_DVC_NAME "msm_vdec_8974"
 #define MIN_NUM_OUTPUT_BUFFERS 4
-#define MAX_NUM_OUTPUT_BUFFERS VIDEO_MAX_FRAME
+#define MAX_NUM_OUTPUT_BUFFERS VB2_MAX_FRAME
 #define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8010
+#define MB_SIZE_IN_PIXEL (16 * 16)
 
 #define TZ_DYNAMIC_BUFFER_FEATURE_ID 12
 #define TZ_FEATURE_VERSION(major, minor, patch) \
@@ -316,6 +317,17 @@
 		.default_value = DEFAULT_VIDEO_CONCEAL_COLOR_BLACK,
 		.step = 1,
 	},
+	{
+		.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT,
+		.name = "Buffer size limit",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 0,
+		.maximum = 0x7fffffff,
+		.default_value = 0,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+	},
 };
 
 #define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls)
@@ -327,9 +339,39 @@
 }
 
 static u32 get_frame_size_compressed(int plane,
-					u32 height, u32 width)
+					u32 max_mbs_per_frame, u32 size_per_mb)
 {
-	return (width * height * 3/2)/4;
+	return (max_mbs_per_frame * size_per_mb * 3/2)/2;
+}
+
+static u32 get_frame_size(struct msm_vidc_inst *inst,
+					const struct msm_vidc_format *fmt,
+					int fmt_type, int plane)
+{
+	u32 frame_size = 0;
+	if (fmt_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		frame_size = fmt->get_frame_size(plane,
+					inst->capability.mbs_per_frame.max,
+					MB_SIZE_IN_PIXEL);
+		if (inst->capability.buffer_size_limit &&
+			(inst->capability.buffer_size_limit < frame_size)) {
+			frame_size = inst->capability.buffer_size_limit;
+			dprintk(VIDC_DBG, "input buffer size limited to %d\n",
+				frame_size);
+		} else {
+			dprintk(VIDC_DBG, "set input buffer size to %d\n",
+				frame_size);
+		}
+	} else if (fmt_type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		frame_size = fmt->get_frame_size(plane,
+					inst->capability.height.max,
+					inst->capability.width.max);
+		dprintk(VIDC_DBG, "set output buffer size to %d\n",
+			frame_size);
+	} else {
+		dprintk(VIDC_WARN, "Wrong format type\n");
+	}
+	return frame_size;
 }
 
 struct msm_vidc_format vdec_formats[] = {
@@ -741,11 +783,11 @@
 			for (i = 0; i < fmt->num_planes; ++i) {
 				if (plane_sizes[i] == 0) {
 					f->fmt.pix_mp.plane_fmt[i].sizeimage =
-						fmt->get_frame_size(i,
-						inst->capability.height.max,
-						inst->capability.width.max);
+						get_frame_size(inst, fmt,
+								f->type, i);
 					plane_sizes[i] =
-					f->fmt.pix_mp.plane_fmt[i].sizeimage;
+						f->fmt.pix_mp.plane_fmt[i].
+							sizeimage;
 				} else
 					f->fmt.pix_mp.plane_fmt[i].sizeimage =
 						plane_sizes[i];
@@ -928,9 +970,7 @@
 		if (ret) {
 			for (i = 0; i < fmt->num_planes; ++i) {
 				f->fmt.pix_mp.plane_fmt[i].sizeimage =
-					fmt->get_frame_size(i,
-						inst->capability.height.max,
-						inst->capability.width.max);
+					get_frame_size(inst, fmt, f->type, i);
 			}
 		} else {
 			buff_req_buffer =
@@ -1012,11 +1052,7 @@
 			frame_sz.buffer_type, frame_sz.width,
 			frame_sz.height);
 		msm_comm_try_set_prop(inst, HAL_PARAM_FRAME_SIZE, &frame_sz);
-
-		max_input_size = fmt->get_frame_size(0,
-					inst->capability.height.max,
-					inst->capability.width.max);
-
+		max_input_size = get_frame_size(inst, fmt, f->type, 0);
 		if (f->fmt.pix_mp.plane_fmt[0].sizeimage > max_input_size ||
 			f->fmt.pix_mp.plane_fmt[0].sizeimage == 0) {
 			f->fmt.pix_mp.plane_fmt[0].sizeimage = max_input_size;
@@ -1115,9 +1151,8 @@
 				*num_buffers > MAX_NUM_OUTPUT_BUFFERS)
 			*num_buffers = MIN_NUM_OUTPUT_BUFFERS;
 		for (i = 0; i < *num_planes; i++) {
-			sizes[i] = inst->fmts[OUTPUT_PORT]->get_frame_size(
-					i, inst->capability.height.max,
-					inst->capability.width.max);
+			sizes[i] = get_frame_size(inst,
+					inst->fmts[OUTPUT_PORT], q->type, i);
 		}
 		property_id = HAL_PARAM_BUFFER_COUNT_ACTUAL;
 		new_buf_count.buffer_type = HAL_BUFFER_INPUT;
@@ -1701,6 +1736,13 @@
 		property_val = ctrl->val;
 		pdata = &property_val;
 		break;
+	case V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT:
+	{
+		inst->capability.buffer_size_limit = ctrl->val;
+		dprintk(VIDC_DBG,
+			"Limiting input buffer size to :%u\n", ctrl->val);
+		break;
+	}
 	default:
 		break;
 	}
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 701a8cc..b8c972d 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -931,12 +931,12 @@
 		}
 
 		if (*num_buffers < MIN_NUM_CAPTURE_BUFFERS ||
-				*num_buffers > VIDEO_MAX_FRAME) {
+				*num_buffers > VB2_MAX_FRAME) {
 			int temp = *num_buffers;
 
 			*num_buffers = clamp_val(*num_buffers,
 					MIN_NUM_CAPTURE_BUFFERS,
-					VIDEO_MAX_FRAME);
+					VB2_MAX_FRAME);
 			dprintk(VIDC_INFO,
 				"Changing buffer count on CAPTURE_MPLANE from %d to %d for best effort encoding\n",
 				temp, *num_buffers);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index c5d038f..345bd0e 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -1265,6 +1265,11 @@
 			"Failed to initialize vb2 queue on capture port\n");
 		goto fail_bufq_output;
 	}
+
+	mutex_lock(&core->lock);
+	list_add_tail(&inst->list, &core->instances);
+	mutex_unlock(&core->lock);
+
 	rc = msm_comm_try_state(inst, MSM_VIDC_CORE_INIT);
 	if (rc) {
 		dprintk(VIDC_ERR,
@@ -1276,12 +1281,14 @@
 
 	setup_event_queue(inst, &core->vdev[session_type].vdev);
 
-	mutex_lock(&core->lock);
-	list_add_tail(&inst->list, &core->instances);
-	mutex_unlock(&core->lock);
 	return inst;
 fail_init:
 	vb2_queue_release(&inst->bufq[OUTPUT_PORT].vb2_bufq);
+
+	mutex_lock(&core->lock);
+	list_del(&inst->list);
+	mutex_unlock(&core->lock);
+
 fail_bufq_output:
 	vb2_queue_release(&inst->bufq[CAPTURE_PORT].vb2_bufq);
 fail_bufq_capture:
@@ -1386,6 +1393,9 @@
 	else if (inst->session_type == MSM_VIDC_ENCODER)
 		msm_venc_ctrl_deinit(inst);
 
+	for (i = 0; i < MAX_PORT_NUM; i++)
+		vb2_queue_release(&inst->bufq[i].vb2_bufq);
+
 	cleanup_instance(inst);
 	if (inst->state != MSM_VIDC_CORE_INVALID &&
 		core->state != VIDC_CORE_INVALID)
@@ -1395,8 +1405,6 @@
 	if (rc)
 		dprintk(VIDC_ERR,
 			"Failed to move video instance to uninit state\n");
-	for (i = 0; i < MAX_PORT_NUM; i++)
-		vb2_queue_release(&inst->bufq[i].vb2_bufq);
 
 	msm_smem_delete_client(inst->mem_client);
 	pr_info(VIDC_DBG_TAG "Closed video instance: %p\n", VIDC_INFO, inst);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
old mode 100755
new mode 100644
index 8176b06..a1fba1e
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -14,7 +14,6 @@
 #include <linux/jiffies.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/workqueue.h>
 #include <asm/div64.h>
 #include <mach/subsystem_restart.h>
 
@@ -491,6 +490,8 @@
 			inst->capability.hier_p = session_init_done->hier_p;
 			inst->capability.pixelprocess_capabilities =
 				call_hfi_op(hdev, get_core_capabilities);
+			inst->capability.mbs_per_frame =
+				session_init_done->mbs_per_frame;
 			inst->capability.capability_set = true;
 			inst->capability.buffer_mode[CAPTURE_PORT] =
 				session_init_done->alloc_mode_out;
@@ -1664,6 +1665,7 @@
 			goto fail_load_fw;
 		}
 		core->state = VIDC_CORE_LOADED;
+		dprintk(VIDC_DBG, "Firmware downloaded\n");
 	}
 	mutex_unlock(&core->lock);
 
@@ -1701,7 +1703,6 @@
 
 static int msm_vidc_deinit_core(struct msm_vidc_inst *inst)
 {
-	int rc = 0;
 	struct msm_vidc_core *core;
 	struct hfi_device *hdev;
 
@@ -1725,38 +1726,27 @@
 
 	mutex_lock(&core->lock);
 	if (list_empty(&core->instances)) {
-		if (core->state > VIDC_CORE_INIT) {
-			if (core->resources.has_ocmem) {
-				if (inst->state != MSM_VIDC_CORE_INVALID)
-					msm_comm_unset_ocmem(core);
-				call_hfi_op(hdev, free_ocmem,
-						hdev->hfi_device_data);
-			}
-			dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
-			rc = call_hfi_op(hdev, core_release,
-					hdev->hfi_device_data);
-			if (rc) {
-				dprintk(VIDC_ERR,
-					"Failed to release core, id = %d\n",
-					core->id);
-				goto exit;
-			}
-		}
+		cancel_delayed_work(&core->fw_unload_work);
 
-		core->state = VIDC_CORE_UNINIT;
+		/*
+		* Delay unloading of firmware. This is useful
+		* in avoiding firmware download delays in cases where we
+		* will have a burst of back to back video playback sessions
+		* e.g. thumbnail generation.
+		*/
+		schedule_delayed_work(&core->fw_unload_work,
+			msecs_to_jiffies(core->state == VIDC_CORE_INVALID ?
+					0 : msm_vidc_firmware_unload_delay));
 
-		call_hfi_op(hdev, unload_fw, hdev->hfi_device_data);
-		if (core->resources.has_ocmem)
-			msm_comm_unvote_buses(core, DDR_MEM|OCMEM_MEM);
-		else
-			msm_comm_unvote_buses(core, DDR_MEM);
+		dprintk(VIDC_DBG, "firmware unload delayed by %u ms\n",
+			core->state == VIDC_CORE_INVALID ?
+			0 : msm_vidc_firmware_unload_delay);
 	}
 
 core_already_uninited:
 	change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
-exit:
 	mutex_unlock(&core->lock);
-	return rc;
+	return 0;
 }
 
 int msm_comm_force_cleanup(struct msm_vidc_inst *inst)
@@ -3697,3 +3687,51 @@
 	return msm_smem_get_domain_partition(inst->mem_client, flags,
 			buffer_type, domain_num, partition_num);
 }
+
+void msm_vidc_fw_unload_handler(struct work_struct *work)
+{
+	struct msm_vidc_core *core = NULL;
+	struct hfi_device *hdev = NULL;
+	int rc = 0;
+
+	core = container_of(work, struct msm_vidc_core, fw_unload_work.work);
+	if (!core || !core->device) {
+		dprintk(VIDC_ERR, "%s - invalid work or core handle\n",
+				__func__);
+		return;
+	}
+
+	hdev = core->device;
+
+	mutex_lock(&core->lock);
+	if (list_empty(&core->instances) &&
+		core->state != VIDC_CORE_UNINIT) {
+		if (core->state > VIDC_CORE_INIT) {
+			if (core->resources.has_ocmem) {
+				if (core->state != VIDC_CORE_INVALID)
+					msm_comm_unset_ocmem(core);
+				call_hfi_op(hdev, free_ocmem,
+						hdev->hfi_device_data);
+			}
+			dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
+			rc = call_hfi_op(hdev, core_release,
+					hdev->hfi_device_data);
+			if (rc) {
+				dprintk(VIDC_ERR,
+					"Failed to release core, id = %d\n",
+					core->id);
+				return;
+			}
+		}
+
+		core->state = VIDC_CORE_UNINIT;
+
+		call_hfi_op(hdev, unload_fw, hdev->hfi_device_data);
+		dprintk(VIDC_DBG, "Firmware unloaded\n");
+		if (core->resources.has_ocmem)
+			msm_comm_unvote_buses(core, DDR_MEM|OCMEM_MEM);
+		else
+			msm_comm_unvote_buses(core, DDR_MEM);
+	}
+	mutex_unlock(&core->lock);
+}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
old mode 100755
new mode 100644
index 0ac6fc4..ee91513
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -21,6 +21,7 @@
 int msm_fw_debug_mode = 0x1;
 int msm_fw_low_power_mode = 0x1;
 int msm_vidc_hw_rsp_timeout = 1000;
+u32 msm_vidc_firmware_unload_delay = 15000;
 
 struct debug_buffer {
 	char ptr[MAX_DBG_BUF_SIZE];
@@ -193,6 +194,12 @@
 		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
 		goto failed_create_dir;
 	}
+	if (!debugfs_create_u32("firmware_unload_delay", S_IRUGO | S_IWUSR,
+			parent, &msm_vidc_firmware_unload_delay)) {
+		dprintk(VIDC_ERR,
+			"debugfs_create_file: firmware_unload_delay fail\n");
+		goto failed_create_dir;
+	}
 failed_create_dir:
 	return dir;
 }
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.h b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
index c9ecc6f..f7091cf 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
@@ -54,6 +54,7 @@
 extern int msm_fw_low_power_mode;
 extern int msm_vp8_low_tier;
 extern int msm_vidc_hw_rsp_timeout;
+extern u32 msm_vidc_firmware_unload_delay;
 
 #define dprintk(__level, __fmt, arg...)	\
 	do { \
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 1677e57..e655d71 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 #include <linux/completion.h>
 #include <linux/wait.h>
+#include <linux/workqueue.h>
 #include <mach/msm_bus.h>
 #include <mach/msm_bus_board.h>
 #include <mach/ocmem.h>
@@ -193,8 +194,10 @@
 	struct hal_capability_supported scale_y;
 	struct hal_capability_supported ltr_count;
 	struct hal_capability_supported hier_p;
+	struct hal_capability_supported mbs_per_frame;
 	u32 capability_set;
 	enum buffer_mode_type buffer_mode[MAX_PORT_NUM];
+	u32 buffer_size_limit;
 };
 
 struct msm_vidc_core {
@@ -212,6 +215,7 @@
 	struct msm_vidc_platform_resources resources;
 	u32 enc_codec_supported;
 	u32 dec_codec_supported;
+	struct delayed_work fw_unload_work;
 };
 
 struct msm_vidc_inst {
@@ -310,4 +314,5 @@
 			struct buffer_info *binfo);
 int unmap_and_deregister_buf(struct msm_vidc_inst *inst,
 			struct buffer_info *binfo);
+void msm_vidc_fw_unload_handler(struct work_struct *work);
 #endif
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index a46dc95..529db62 100755
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1073,24 +1073,28 @@
 		return 0;
 	}
 
-	for (i = 0; i <= device->clk_gating_level; i++) {
+	for (i = VCODEC_CLK; i <= device->clk_gating_level; i++) {
 		cl = &device->resources.clock[i];
 		rc = clk_enable(cl->clk);
 		if (rc) {
-			dprintk(VIDC_ERR, "Failed to enable clocks\n");
+			dprintk(VIDC_ERR, "%s: Failed to enable %s clock\n",
+				__func__, cl->name);
 			goto fail_clk_enable;
 		} else {
-			dprintk(VIDC_DBG, "Clock: %s enabled\n", cl->name);
+			dprintk(VIDC_DBG, "%s: Clock: %s enabled\n",
+				__func__, cl->name);
 		}
 	}
 	device->clk_state = ENABLED_PREPARED;
 	++device->clk_cnt;
 	return 0;
 fail_clk_enable:
-	for (i--; i >= 0; i--) {
+	for (i--; i >= VCODEC_CLK; i--) {
 		cl = &device->resources.clock[i];
 		usleep(100);
 		clk_disable(cl->clk);
+		dprintk(VIDC_ERR, "%s: Clock: %s disabled\n",
+			__func__, cl->name);
 	}
 	device->clk_state = DISABLED_PREPARED;
 	return rc;
@@ -1120,10 +1124,12 @@
 	if (rc)
 		dprintk(VIDC_WARN, "Failed to set clock rate to min: %d\n", rc);
 
-	for (i = 0; i <= device->clk_gating_level; i++) {
+	for (i = VCODEC_CLK; i <= device->clk_gating_level; i++) {
 		cl = &device->resources.clock[i];
 		usleep(100);
 		clk_disable(cl->clk);
+		dprintk(VIDC_DBG, "%s: Clock: %s disabled\n",
+			__func__, cl->name);
 	}
 	device->clk_state = DISABLED_PREPARED;
 	--device->clk_cnt;
@@ -3075,7 +3081,7 @@
 			  );
 	}
 
-	for (i = 0; i < VCODEC_MAX_CLKS; i++) {
+	for (i = VCODEC_CLK; i < VCODEC_MAX_CLKS; i++) {
 		if (i == VCODEC_OCMEM_CLK && !res->has_ocmem)
 			continue;
 		cl = &device->resources.clock[i];
@@ -3091,7 +3097,7 @@
 	}
 
 	if (i < VCODEC_MAX_CLKS) {
-		for (--i; i >= 0; i--) {
+		for (--i; i >= VCODEC_CLK; i--) {
 			if (i == VCODEC_OCMEM_CLK && !res->has_ocmem)
 				continue;
 			cl = &device->resources.clock[i];
@@ -3110,7 +3116,7 @@
 		return;
 	}
 
-	for (i = 0; i < VCODEC_MAX_CLKS; i++) {
+	for (i = VCODEC_CLK; i < VCODEC_MAX_CLKS; i++) {
 		if (i == VCODEC_OCMEM_CLK && !device->res->has_ocmem)
 			continue;
 		clk_put(device->resources.clock[i].clk);
@@ -3135,6 +3141,8 @@
 			cl = &device->resources.clock[i];
 			usleep(100);
 			clk_disable(cl->clk);
+			dprintk(VIDC_DBG, "%s: Clock: %s disabled\n",
+				__func__, cl->name);
 		}
 	} else {
 		for (i = device->clk_gating_level + 1;
@@ -3142,6 +3150,8 @@
 			cl = &device->resources.clock[i];
 			usleep(100);
 			clk_disable(cl->clk);
+			dprintk(VIDC_DBG, "%s: Clock: %s disabled\n",
+				__func__, cl->name);
 		}
 	}
 	for (i = VCODEC_CLK; i < VCODEC_MAX_CLKS; i++) {
@@ -3149,6 +3159,8 @@
 			continue;
 		cl = &device->resources.clock[i];
 		clk_unprepare(cl->clk);
+		dprintk(VIDC_DBG, "%s: Clock: %s unprepared\n",
+			__func__, cl->name);
 	}
 	device->clk_state = DISABLED_UNPREPARED;
 	--device->clk_cnt;
@@ -3175,20 +3187,24 @@
 		cl = &device->resources.clock[i];
 		rc = clk_prepare_enable(cl->clk);
 		if (rc) {
-			dprintk(VIDC_ERR, "Failed to enable clocks\n");
+			dprintk(VIDC_ERR, "%s: Failed to enable %s clock\n",
+				__func__, cl->name);
 			goto fail_clk_enable;
 		} else {
-			dprintk(VIDC_DBG, "Clock: %s enabled\n", cl->name);
+			dprintk(VIDC_DBG, "%s: Clock: %s prepare and enabled\n",
+				__func__, cl->name);
 		}
 	}
 	device->clk_state = ENABLED_PREPARED;
 	++device->clk_cnt;
 	return rc;
 fail_clk_enable:
-	for (; i >= 0; i--) {
+	for (; i >= VCODEC_CLK; i--) {
 		cl = &device->resources.clock[i];
 		usleep(100);
 		clk_disable_unprepare(cl->clk);
+		dprintk(VIDC_ERR, "%s: Clock: %s disable and unprepared\n",
+			__func__, cl->name);
 	}
 	device->clk_state = DISABLED_UNPREPARED;
 	return rc;
@@ -3547,7 +3563,7 @@
 			__func__, device);
 		return -EINVAL;
 	}
-	device->clk_gating_level = VCODEC_CLK;
+	device->clk_gating_level = VCODEC_NONE;
 	rc = venus_hfi_iommu_attach(device);
 	if (rc) {
 		dprintk(VIDC_ERR, "Failed to attach iommu");
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.h b/drivers/media/platform/msm/vidc/venus_hfi.h
index 23a51ba..9169355 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.h
+++ b/drivers/media/platform/msm/vidc/venus_hfi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -151,6 +151,7 @@
 };
 
 enum vidc_clocks {
+	VCODEC_NONE,
 	VCODEC_CLK,
 	VCODEC_AHB_CLK,
 	VCODEC_AXI_CLK,
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
index 12897e8..fd5c96b 100644
--- a/drivers/media/video/mem2mem_testdev.c
+++ b/drivers/media/video/mem2mem_testdev.c
@@ -49,7 +49,7 @@
 #define MEM2MEM_NAME		"m2m-testdev"
 
 /* Per queue */
-#define MEM2MEM_DEF_NUM_BUFS	VIDEO_MAX_FRAME
+#define MEM2MEM_DEF_NUM_BUFS	VB2_MAX_FRAME
 /* In bytes, per queue */
 #define MEM2MEM_VID_MEM_LIMIT	(16 * 1024 * 1024)
 
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index 2e3f4b4..851768a 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -197,8 +197,8 @@
 	/* sanitycheck insmod options */
 	if (tsbufs < 2)
 		tsbufs = 2;
-	if (tsbufs > VIDEO_MAX_FRAME)
-		tsbufs = VIDEO_MAX_FRAME;
+	if (tsbufs > VB2_MAX_FRAME)
+		tsbufs = VB2_MAX_FRAME;
 	if (ts_nr_packets < 4)
 		ts_nr_packets = 4;
 	if (ts_nr_packets > 312)
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
index e9aa94b..3702928 100644
--- a/drivers/media/video/saa7134/saa7134-vbi.c
+++ b/drivers/media/video/saa7134/saa7134-vbi.c
@@ -214,8 +214,8 @@
 
 	if (vbibufs < 2)
 		vbibufs = 2;
-	if (vbibufs > VIDEO_MAX_FRAME)
-		vbibufs = VIDEO_MAX_FRAME;
+	if (vbibufs > VB2_MAX_FRAME)
+		vbibufs = VB2_MAX_FRAME;
 	return 0;
 }
 
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 417034e..e63ffda 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -2509,7 +2509,7 @@
 int saa7134_video_init1(struct saa7134_dev *dev)
 {
 	/* sanitycheck insmod options */
-	if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
+	if (gbuffers < 2 || gbuffers > VB2_MAX_FRAME)
 		gbuffers = 2;
 	if (gbufsize < 0 || gbufsize > gbufsize_max)
 		gbufsize = gbufsize_max;
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
index 6cea218..ae544a4 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -536,7 +536,7 @@
 	/*
 	 * Make sure the requested values and current defaults are sane.
 	 */
-	num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME);
+	num_buffers = min_t(unsigned int, req->count, VB2_MAX_FRAME);
 	memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
 	memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
 	q->memory = req->memory;
@@ -644,7 +644,7 @@
 		return -EINVAL;
 	}
 
-	if (q->num_buffers == VIDEO_MAX_FRAME) {
+	if (q->num_buffers == VB2_MAX_FRAME) {
 		dprintk(1, "%s(): maximum number of buffers already allocated\n",
 			__func__);
 		return -ENOBUFS;
@@ -658,7 +658,7 @@
 		q->memory = create->memory;
 	}
 
-	num_buffers = min(create->count, VIDEO_MAX_FRAME - q->num_buffers);
+	num_buffers = min(create->count, VB2_MAX_FRAME - q->num_buffers);
 
 	/*
 	 * Ask the driver, whether the requested number of buffers, planes per
@@ -1774,7 +1774,7 @@
 struct vb2_fileio_data {
 	struct v4l2_requestbuffers req;
 	struct v4l2_buffer b;
-	struct vb2_fileio_buf bufs[VIDEO_MAX_FRAME];
+	struct vb2_fileio_buf bufs[VB2_MAX_FRAME];
 	unsigned int index;
 	unsigned int q_count;
 	unsigned int dq_count;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c1f366e..3b439e8 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -761,9 +761,7 @@
 				EXT_CSD_PWR_CL_52_195 :
 				EXT_CSD_PWR_CL_DDR_52_195;
 		else if (host->ios.clock <= 200000000)
-			index = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
-				EXT_CSD_PWR_CL_200_195 :
-				EXT_CSD_PWR_CL_DDR_200_195;
+			index = EXT_CSD_PWR_CL_200_195;
 		break;
 	case MMC_VDD_27_28:
 	case MMC_VDD_28_29:
@@ -781,9 +779,9 @@
 				EXT_CSD_PWR_CL_52_360 :
 				EXT_CSD_PWR_CL_DDR_52_360;
 		else if (host->ios.clock <= 200000000)
-			index = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
-				EXT_CSD_PWR_CL_200_360 :
-				EXT_CSD_PWR_CL_DDR_200_360;
+			index = (bus_width == EXT_CSD_DDR_BUS_WIDTH_8) ?
+				EXT_CSD_PWR_CL_DDR_200_360 :
+				EXT_CSD_PWR_CL_200_360;
 		break;
 	default:
 		pr_warning("%s: Voltage range not supported "
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 49f639e..04525e1 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -1115,6 +1115,13 @@
 	.remove	= __devexit_p(wcnss_ctrl_remove),
 };
 
+void wcnss_get_monotonic_boottime(struct timespec *ts)
+{
+	get_monotonic_boottime(ts);
+}
+EXPORT_SYMBOL(wcnss_get_monotonic_boottime);
+
+
 struct device *wcnss_wlan_get_device(void)
 {
 	if (penv && penv->pdev && penv->smd_channel_ready)
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 7963ed4..b395783 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -378,6 +378,7 @@
 	struct delayed_work		aicl_check_work;
 	struct work_struct		insertion_ocv_work;
 	struct work_struct		ocp_clear_work;
+	struct qpnp_chg_regulator	flash_wa_vreg;
 	struct qpnp_chg_regulator	otg_vreg;
 	struct qpnp_chg_regulator	boost_vreg;
 	struct qpnp_chg_regulator	batfet_vreg;
@@ -393,9 +394,11 @@
 	struct work_struct		reduce_power_stage_work;
 	bool				power_stage_workaround_running;
 	bool				power_stage_workaround_enable;
+	bool				is_flash_wa_reg_enabled;
 	bool				ext_ovp_ic_gpio_enabled;
 	unsigned int			ext_ovp_isns_gpio;
 	unsigned int			usb_trim_default;
+	u8				chg_temp_thresh_default;
 };
 
 static void
@@ -1709,6 +1712,7 @@
 		return IRQ_HANDLED;
 
 	if (chip->usb_present ^ usb_present) {
+		chip->aicl_settled = false;
 		chip->usb_present = usb_present;
 		if (!usb_present) {
 			/* when a valid charger inserted, and increase the
@@ -1744,7 +1748,6 @@
 			qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100);
 			qpnp_chg_iusb_trim_set(chip, chip->usb_trim_default);
 			chip->prev_usb_max_ma = -EINVAL;
-			chip->aicl_settled = false;
 		} else {
 			/* when OVP clamped usbin, and then decrease
 			 * the charger voltage to lower than the OVP
@@ -3058,7 +3061,12 @@
 {
 	int rc, ibat_max_ma;
 	u8 reg, chgr_sts, ibat_trim, i;
+	bool usb_present = qpnp_chg_is_usb_chg_plugged_in(chip);
 
+	if (!usb_present) {
+		pr_debug("Ignoring AICL settled, since USB is removed\n");
+		return 0;
+	}
 	chip->aicl_settled = true;
 
 	/*
@@ -3212,6 +3220,75 @@
 	}
 }
 
+/*
+ * Increase the SMBB/SMBBP charger overtemp threshold to 150C while firing
+ * the flash (and/or torch for PM8x26) when the bharger is used as the
+ * power source.
+ */
+static int
+qpnp_chg_temp_threshold_set(struct qpnp_chg_chip *chip, u8 value)
+{
+	int rc;
+
+	rc = qpnp_chg_masked_write(chip, chip->chgr_base +
+			CHGR_CHG_TEMP_THRESH ,
+			0xFF, value, 1);
+	if (rc)
+		pr_err("set CHG_TEMP_THRESH_Flash failed, value = %d, rc = %d\n",
+				value, rc);
+
+	return rc;
+}
+
+#define CHG_TEMP_THRESH_FOR_FLASH		0xFD
+#define CHG_TEMP_THRESH_DEFAULT			0x94
+static int
+qpnp_chg_regulator_flash_wa_enable(struct regulator_dev *rdev)
+{
+	struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
+	int rc = 0;
+
+	if (chip->flags & BOOST_FLASH_WA) {
+		rc = qpnp_chg_temp_threshold_set(chip,
+				CHG_TEMP_THRESH_FOR_FLASH);
+		if (rc) {
+			pr_err("set chg temp threshold failed rc = %d\n", rc);
+			return rc;
+		}
+	}
+	chip->is_flash_wa_reg_enabled = true;
+
+	return rc;
+}
+
+static int
+qpnp_chg_regulator_flash_wa_disable(struct regulator_dev *rdev)
+{
+	struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
+	int rc = 0;
+
+	if (chip->flags & BOOST_FLASH_WA) {
+		rc = qpnp_chg_temp_threshold_set(chip,
+				chip->chg_temp_thresh_default);
+		if (rc) {
+			pr_err("set chg temp threshold failed rc = %d\n", rc);
+			return rc;
+		}
+
+	}
+	chip->is_flash_wa_reg_enabled = false;
+
+	return rc;
+}
+
+static int
+qpnp_chg_regulator_flash_wa_is_enabled(struct regulator_dev *rdev)
+{
+	struct qpnp_chg_chip *chip = rdev_get_drvdata(rdev);
+
+	return chip->is_flash_wa_reg_enabled;
+}
+
 /* OTG regulator operations */
 static int
 qpnp_chg_regulator_otg_enable(struct regulator_dev *rdev)
@@ -3458,6 +3535,12 @@
 	return BOOST_MIN_UV + (selector * BOOST_STEP_UV);
 }
 
+static struct regulator_ops qpnp_chg_flash_wa_reg_ops = {
+	.enable			= qpnp_chg_regulator_flash_wa_enable,
+	.disable		= qpnp_chg_regulator_flash_wa_disable,
+	.is_enabled		= qpnp_chg_regulator_flash_wa_is_enabled,
+};
+
 static struct regulator_ops qpnp_chg_otg_reg_ops = {
 	.enable			= qpnp_chg_regulator_otg_enable,
 	.disable		= qpnp_chg_regulator_otg_disable,
@@ -4632,6 +4715,42 @@
 		rc = qpnp_chg_masked_write(chip, chip->chgr_base +
 			CHG_TRICKLE_CLAMP,
 			0xFF, 0x00, 1);
+
+		rc = qpnp_chg_read(chip, &chip->chg_temp_thresh_default,
+				chip->chgr_base + CHGR_CHG_TEMP_THRESH, 1);
+		if (rc) {
+			pr_debug("read CHG_TEMP_THRESH failed, rc = %d\n", rc);
+			chip->chg_temp_thresh_default =
+				CHG_TEMP_THRESH_DEFAULT;
+		}
+
+		init_data = of_get_regulator_init_data(chip->dev,
+						       spmi_resource->of_node);
+		if (!init_data) {
+			pr_err("unable to get regulator init data for flash_wa\n");
+			return -ENOMEM;
+		}
+
+		if (init_data->constraints.name) {
+			rdesc			= &(chip->flash_wa_vreg.rdesc);
+			rdesc->owner		= THIS_MODULE;
+			rdesc->type		= REGULATOR_VOLTAGE;
+			rdesc->ops		= &qpnp_chg_flash_wa_reg_ops;
+			rdesc->name		= init_data->constraints.name;
+
+			init_data->constraints.valid_ops_mask
+				|= REGULATOR_CHANGE_STATUS;
+
+			chip->flash_wa_vreg.rdev =
+				regulator_register(rdesc, chip->dev, init_data,
+						chip, spmi_resource->of_node);
+			if (IS_ERR(chip->flash_wa_vreg.rdev)) {
+				rc = PTR_ERR(chip->flash_wa_vreg.rdev);
+				chip->flash_wa_vreg.rdev = NULL;
+				pr_err("Flash wa failed, rc=%d\n", rc);
+				return rc;
+			}
+		}
 		break;
 	case SMBB_BUCK_SUBTYPE:
 	case SMBBP_BUCK_SUBTYPE:
diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
index 462f1d8..0cb3c08 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.c
+++ b/drivers/video/msm/mdss/mdp3_ppp.c
@@ -401,9 +401,18 @@
 	return 0;
 }
 
-bool mdp3_optimal_bw(int req_cnt)
+bool mdp3_optimal_bw(struct blit_req_list *req)
 {
-	if (req_cnt == 1 && ppp_stat->req_q.count == 1)
+	int i, solid_fill = 0;
+
+	if (!req || (ppp_stat->req_q.count > 1))
+		return false;
+
+	for (i = 0; i < req->count; i++) {
+		if (req->req_list[i].flags & MDP_SOLID_FILL)
+			solid_fill++;
+	}
+	if ((req->count - solid_fill) <= 1)
 		return true;
 	return false;
 }
@@ -1043,7 +1052,7 @@
 	}
 
 	if (!ppp_stat->bw_on) {
-		ppp_stat->bw_optimal = mdp3_optimal_bw(req->count);
+		ppp_stat->bw_optimal = mdp3_optimal_bw(req);
 		mdp3_ppp_turnon(mfd, 1);
 		if (rc < 0) {
 			mutex_unlock(&ppp_stat->config_ppp_mutex);
@@ -1076,7 +1085,7 @@
 		if (ppp_stat->wait_for_pop)
 			complete(&ppp_stat->pop_q_comp);
 		mutex_unlock(&ppp_stat->req_mutex);
-		if (req && (ppp_stat->bw_optimal != mdp3_optimal_bw(req->count))) {
+		if (req && (ppp_stat->bw_optimal != mdp3_optimal_bw(req))) {
 			ppp_stat->bw_optimal = !ppp_stat->bw_optimal;
 			mdp3_ppp_vote_update(mfd);
 		}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index ebda2ee..16d4866 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -985,7 +985,7 @@
 	    (pipe->pp_res.pp_sts.sharp_sts & PP_STS_ENABLE) ||
 	    (chroma_sample == MDSS_MDP_CHROMA_420) ||
 	    (chroma_sample == MDSS_MDP_CHROMA_H1V2) ||
-	    pipe->scale.enable_pxl_ext) {
+	    (pipe->scale.enable_pxl_ext && (src_h != pipe->dst.h))) {
 		pr_debug("scale y - src_h=%d dst_h=%d\n", src_h, pipe->dst.h);
 
 		if ((src_h / MAX_DOWNSCALE_RATIO) > pipe->dst.h) {
@@ -1041,7 +1041,7 @@
 	    (pipe->pp_res.pp_sts.sharp_sts & PP_STS_ENABLE) ||
 	    (chroma_sample == MDSS_MDP_CHROMA_420) ||
 	    (chroma_sample == MDSS_MDP_CHROMA_H2V1) ||
-	    pipe->scale.enable_pxl_ext) {
+	    (pipe->scale.enable_pxl_ext && (src_w != pipe->dst.w))) {
 		pr_debug("scale x - src_w=%d dst_w=%d\n", src_w, pipe->dst.w);
 
 		if ((src_w / MAX_DOWNSCALE_RATIO) > pipe->dst.w) {
diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
index 74f6714..6c847e6 100644
--- a/include/linux/dma-attrs.h
+++ b/include/linux/dma-attrs.h
@@ -18,6 +18,7 @@
 	DMA_ATTR_NO_KERNEL_MAPPING,
 	DMA_ATTR_STRONGLY_ORDERED,
 	DMA_ATTR_SKIP_ZEROING,
+	DMA_ATTR_SKIP_CPU_SYNC,
 	DMA_ATTR_MAX,
 };
 
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index b626915..e13bc45 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -330,8 +330,7 @@
 #define EXT_CSD_POWER_OFF_LONG_TIME	247	/* RO */
 #define EXT_CSD_GENERIC_CMD6_TIME	248	/* RO */
 #define EXT_CSD_CACHE_SIZE		249	/* RO, 4 bytes */
-#define EXT_CSD_PWR_CL_DDR_200_195	253	/* RO */
-#define EXT_CSD_PWR_CL_DDR_200_360	254	/* RO */
+#define EXT_CSD_PWR_CL_DDR_200_360	253	/* RO */
 #define EXT_CSD_TAG_UNIT_SIZE		498	/* RO */
 #define EXT_CSD_DATA_TAG_SUPPORT	499	/* RO */
 #define EXT_CSD_MAX_PACKED_WRITES	500	/* RO */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index f760672..91c5f81 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1948,6 +1948,9 @@
 #define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP \
 		(V4L2_CID_MPEG_MSM_VIDC_BASE + 47)
 
+#define V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT \
+		(V4L2_CID_MPEG_MSM_VIDC_BASE + 48)
+
 /*  Camera class control IDs */
 #define V4L2_CID_CAMERA_CLASS_BASE 	(V4L2_CTRL_CLASS_CAMERA | 0x900)
 #define V4L2_CID_CAMERA_CLASS 		(V4L2_CTRL_CLASS_CAMERA | 1)
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 8836e4a..e6c46d1 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -43,6 +43,7 @@
 #define HAVE_WCNSS_RX_BUFF_COUNT 1
 #define WLAN_MAC_ADDR_SIZE (6)
 
+void wcnss_get_monotonic_boottime(struct timespec *ts);
 struct device *wcnss_wlan_get_device(void);
 struct resource *wcnss_wlan_get_memory_map(struct device *dev);
 int wcnss_wlan_get_dxe_tx_irq(struct device *dev);
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index a15d1f1..b0b6b04 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -17,6 +17,8 @@
 #include <linux/poll.h>
 #include <linux/videodev2.h>
 
+#define VB2_MAX_FRAME  64
+
 struct vb2_alloc_ctx;
 struct vb2_fileio_data;
 
@@ -281,7 +283,7 @@
 
 /* private: internal use only */
 	enum v4l2_memory		memory;
-	struct vb2_buffer		*bufs[VIDEO_MAX_FRAME];
+	struct vb2_buffer		*bufs[VB2_MAX_FRAME];
 	unsigned int			num_buffers;
 
 	struct list_head		queued_list;
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 91591c7..5f8b5c2 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -434,8 +434,8 @@
 
 country IL:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 200 mW), NO-OUTDOOR
-	(5250 - 5350 @ 80), (N/A, 200 mW), NO-OUTDOOR, DFS
+	(5150 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
 
 country IN:
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -636,7 +636,7 @@
 	(5735 - 5835 @ 80), (N/A, 30)
 
 country MX:
-	(2402 - 2472 @ 40), (3, 27)
+	(2402 - 2482 @ 40), (3, 20)
 	(5170 - 5250 @ 80), (3, 17)
 	(5250 - 5330 @ 80), (3, 24), DFS
 	(5490 - 5730 @ 80), (3, 24), DFS
@@ -859,9 +859,10 @@
 	(2402 - 2482 @ 40), (N/A, 20)
 
 country TW:
-	(2402 - 2472 @ 40), (3, 27)
-	(5270 - 5330 @ 40), (6, 17), DFS
-	(5490 - 5730 @ 80), (6, 30), DFS
+	(2402 - 2472 @ 40), (3, 30)
+	(5270 - 5330 @ 40), (6, 17)
+	(5490 - 5590 @ 80), (6, 30), DFS
+	(5650 - 5730 @ 80), (6, 30), DFS
 	(5735 - 5815 @ 80), (6, 30)
 
 country TH:
@@ -988,10 +989,9 @@
 
 country ZA:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5710 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
+	(5170 - 5250 @ 80), (3, 20)
+	(5250 - 5330 @ 80), (3, 20), DFS
+	(5490 - 5710 @ 80), (3, 27), DFS
 
 country ZW:
 	(2402 - 2482 @ 40), (N/A, 20)
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index b2ce700..b35f7fb 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -1149,6 +1149,14 @@
 		40, digital_gain),
 	SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", TAPAN_A_CDC_IIR1_GAIN_B4_CTL, -84,
 		40, digital_gain),
+	SOC_SINGLE_S8_TLV("IIR2 INP1 Volume", TAPAN_A_CDC_IIR2_GAIN_B1_CTL, -84,
+		40, digital_gain),
+	SOC_SINGLE_S8_TLV("IIR2 INP2 Volume", TAPAN_A_CDC_IIR2_GAIN_B2_CTL, -84,
+		40, digital_gain),
+	SOC_SINGLE_S8_TLV("IIR2 INP3 Volume", TAPAN_A_CDC_IIR2_GAIN_B3_CTL, -84,
+		40, digital_gain),
+	SOC_SINGLE_S8_TLV("IIR2 INP4 Volume", TAPAN_A_CDC_IIR2_GAIN_B4_CTL, -84,
+		40, digital_gain),
 
 	SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
 	SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
@@ -1318,7 +1326,7 @@
 	"ZERO", "EAR_HPH_L", "EAR_LINE_1",
 };
 
-static const char * const iir1_inp1_text[] = {
+static const char * const iir_inp_text[] = {
 	"ZERO", "DEC1", "DEC2", "DEC3", "DEC4",
 	"RX1", "RX2", "RX3", "RX4", "RX5"
 };
@@ -1422,7 +1430,28 @@
 	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_ANC_B2_CTL, 0, 3, anc1_fb_mux_text);
 
 static const struct soc_enum iir1_inp1_mux_enum =
-	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_EQ1_B1_CTL, 0, 10, iir1_inp1_text);
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_EQ1_B1_CTL, 0, 10, iir_inp_text);
+
+static const struct soc_enum iir1_inp2_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_EQ1_B2_CTL, 0, 10, iir_inp_text);
+
+static const struct soc_enum iir1_inp3_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_EQ1_B3_CTL, 0, 10, iir_inp_text);
+
+static const struct soc_enum iir1_inp4_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_EQ1_B4_CTL, 0, 10, iir_inp_text);
+
+static const struct soc_enum iir2_inp1_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_EQ2_B1_CTL, 0, 10, iir_inp_text);
+
+static const struct soc_enum iir2_inp2_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_EQ2_B2_CTL, 0, 10, iir_inp_text);
+
+static const struct soc_enum iir2_inp3_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_EQ2_B3_CTL, 0, 10, iir_inp_text);
+
+static const struct soc_enum iir2_inp4_mux_enum =
+	SOC_ENUM_SINGLE(TAPAN_A_CDC_CONN_EQ2_B4_CTL, 0, 10, iir_inp_text);
 
 static const struct snd_kcontrol_new rx_mix1_inp1_mux =
 	SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
@@ -1601,6 +1630,27 @@
 static const struct snd_kcontrol_new iir1_inp1_mux =
 	SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
 
+static const struct snd_kcontrol_new iir1_inp2_mux =
+	SOC_DAPM_ENUM("IIR1 INP2 Mux", iir1_inp2_mux_enum);
+
+static const struct snd_kcontrol_new iir1_inp3_mux =
+	SOC_DAPM_ENUM("IIR1 INP3 Mux", iir1_inp3_mux_enum);
+
+static const struct snd_kcontrol_new iir1_inp4_mux =
+	SOC_DAPM_ENUM("IIR1 INP4 Mux", iir1_inp4_mux_enum);
+
+static const struct snd_kcontrol_new iir2_inp1_mux =
+	SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum);
+
+static const struct snd_kcontrol_new iir2_inp2_mux =
+	SOC_DAPM_ENUM("IIR2 INP2 Mux", iir2_inp2_mux_enum);
+
+static const struct snd_kcontrol_new iir2_inp3_mux =
+	SOC_DAPM_ENUM("IIR2 INP3 Mux", iir2_inp3_mux_enum);
+
+static const struct snd_kcontrol_new iir2_inp4_mux =
+	SOC_DAPM_ENUM("IIR2 INP4 Mux", iir2_inp4_mux_enum);
+
 static const struct snd_kcontrol_new anc1_mux =
 	SOC_DAPM_ENUM("ANC1 MUX Mux", anc1_mux_enum);
 
@@ -3119,12 +3169,14 @@
 	{"RX1 MIX1 INP1", "RX4", "SLIM RX4"},
 	{"RX1 MIX1 INP1", "RX5", "SLIM RX5"},
 	{"RX1 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX1 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX1 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX1 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX1 MIX1 INP2", "RX3", "SLIM RX3"},
 	{"RX1 MIX1 INP2", "RX4", "SLIM RX4"},
 	{"RX1 MIX1 INP2", "RX5", "SLIM RX5"},
 	{"RX1 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX1 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX1 MIX1 INP3", "RX1", "SLIM RX1"},
 	{"RX1 MIX1 INP3", "RX2", "SLIM RX2"},
 	{"RX1 MIX1 INP3", "RX3", "SLIM RX3"},
@@ -3136,30 +3188,39 @@
 	{"RX2 MIX1 INP1", "RX4", "SLIM RX4"},
 	{"RX2 MIX1 INP1", "RX5", "SLIM RX5"},
 	{"RX2 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX2 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX2 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX2 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX2 MIX1 INP2", "RX3", "SLIM RX3"},
 	{"RX2 MIX1 INP2", "RX4", "SLIM RX4"},
 	{"RX2 MIX1 INP2", "RX5", "SLIM RX5"},
 	{"RX2 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX2 MIX1 INP2", "IIR2", "IIR2"},
 	{"RX3 MIX1 INP1", "RX1", "SLIM RX1"},
 	{"RX3 MIX1 INP1", "RX2", "SLIM RX2"},
 	{"RX3 MIX1 INP1", "RX3", "SLIM RX3"},
 	{"RX3 MIX1 INP1", "RX4", "SLIM RX4"},
 	{"RX3 MIX1 INP1", "RX5", "SLIM RX5"},
 	{"RX3 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX3 MIX1 INP1", "IIR2", "IIR2"},
 	{"RX3 MIX1 INP2", "RX1", "SLIM RX1"},
 	{"RX3 MIX1 INP2", "RX2", "SLIM RX2"},
 	{"RX3 MIX1 INP2", "RX3", "SLIM RX3"},
 	{"RX3 MIX1 INP2", "RX4", "SLIM RX4"},
 	{"RX3 MIX1 INP2", "RX5", "SLIM RX5"},
 	{"RX3 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX3 MIX1 INP2", "IIR2", "IIR2"},
 
 	{"RX1 MIX2 INP1", "IIR1", "IIR1"},
 	{"RX1 MIX2 INP2", "IIR1", "IIR1"},
 	{"RX2 MIX2 INP1", "IIR1", "IIR1"},
 	{"RX2 MIX2 INP2", "IIR1", "IIR1"},
 
+	{"RX1 MIX2 INP1", "IIR2", "IIR2"},
+	{"RX1 MIX2 INP2", "IIR2", "IIR2"},
+	{"RX2 MIX2 INP1", "IIR2", "IIR2"},
+	{"RX2 MIX2 INP2", "IIR2", "IIR2"},
+
 	/* Decimator Inputs */
 	{"DEC1 MUX", "ADC1", "ADC1"},
 	{"DEC1 MUX", "ADC2", "ADC2"},
@@ -3190,10 +3251,6 @@
 	{"LINEOUT1_PA_MIXER", "AUX_PGA_L Switch", "AUX_PGA_Left"},
 	{"LINEOUT2_PA_MIXER", "AUX_PGA_R Switch", "AUX_PGA_Right"},
 
-	{"IIR1", NULL, "IIR1 INP1 MUX"},
-	{"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
-	{"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
-
 	{"MIC BIAS1 Internal1", NULL, "LDO_H"},
 	{"MIC BIAS1 Internal2", NULL, "LDO_H"},
 	{"MIC BIAS1 External", NULL, "LDO_H"},
@@ -3202,6 +3259,95 @@
 	{"MIC BIAS2 Internal3", NULL, "LDO_H"},
 	{"MIC BIAS2 External", NULL, "LDO_H"},
 	{DAPM_MICBIAS2_EXTERNAL_STANDALONE, NULL, "LDO_H Standalone"},
+
+	/*sidetone path enable*/
+	{"IIR1", NULL, "IIR1 INP1 MUX"},
+	{"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
+	{"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"},
+	{"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"},
+	{"IIR1 INP1 MUX", "RX1", "SLIM RX1"},
+	{"IIR1 INP1 MUX", "RX2", "SLIM RX2"},
+	{"IIR1 INP1 MUX", "RX3", "SLIM RX3"},
+	{"IIR1 INP1 MUX", "RX4", "SLIM RX4"},
+	{"IIR1 INP1 MUX", "RX5", "SLIM RX5"},
+
+	{"IIR1", NULL, "IIR1 INP2 MUX"},
+	{"IIR1 INP2 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR1 INP2 MUX", "DEC2", "DEC2 MUX"},
+	{"IIR1 INP2 MUX", "DEC3", "DEC3 MUX"},
+	{"IIR1 INP2 MUX", "DEC4", "DEC4 MUX"},
+	{"IIR1 INP2 MUX", "RX1", "SLIM RX1"},
+	{"IIR1 INP2 MUX", "RX2", "SLIM RX2"},
+	{"IIR1 INP2 MUX", "RX3", "SLIM RX3"},
+	{"IIR1 INP2 MUX", "RX4", "SLIM RX4"},
+	{"IIR1 INP2 MUX", "RX5", "SLIM RX5"},
+
+	{"IIR1", NULL, "IIR1 INP3 MUX"},
+	{"IIR1 INP3 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR1 INP3 MUX", "DEC2", "DEC2 MUX"},
+	{"IIR1 INP3 MUX", "DEC3", "DEC3 MUX"},
+	{"IIR1 INP3 MUX", "DEC4", "DEC4 MUX"},
+	{"IIR1 INP3 MUX", "RX1", "SLIM RX1"},
+	{"IIR1 INP3 MUX", "RX2", "SLIM RX2"},
+	{"IIR1 INP3 MUX", "RX3", "SLIM RX3"},
+	{"IIR1 INP3 MUX", "RX4", "SLIM RX4"},
+	{"IIR1 INP3 MUX", "RX5", "SLIM RX5"},
+
+	{"IIR1", NULL, "IIR1 INP4 MUX"},
+	{"IIR1 INP4 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR1 INP4 MUX", "DEC2", "DEC2 MUX"},
+	{"IIR1 INP4 MUX", "DEC3", "DEC3 MUX"},
+	{"IIR1 INP4 MUX", "DEC4", "DEC4 MUX"},
+	{"IIR1 INP4 MUX", "RX1", "SLIM RX1"},
+	{"IIR1 INP4 MUX", "RX2", "SLIM RX2"},
+	{"IIR1 INP4 MUX", "RX3", "SLIM RX3"},
+	{"IIR1 INP4 MUX", "RX4", "SLIM RX4"},
+	{"IIR1 INP4 MUX", "RX5", "SLIM RX5"},
+
+	{"IIR2", NULL, "IIR2 INP1 MUX"},
+	{"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"},
+	{"IIR2 INP1 MUX", "DEC3", "DEC3 MUX"},
+	{"IIR2 INP1 MUX", "DEC4", "DEC4 MUX"},
+	{"IIR2 INP1 MUX", "RX1", "SLIM RX1"},
+	{"IIR2 INP1 MUX", "RX2", "SLIM RX2"},
+	{"IIR2 INP1 MUX", "RX3", "SLIM RX3"},
+	{"IIR2 INP1 MUX", "RX4", "SLIM RX4"},
+	{"IIR2 INP1 MUX", "RX5", "SLIM RX5"},
+
+	{"IIR2", NULL, "IIR2 INP2 MUX"},
+	{"IIR2 INP2 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR2 INP2 MUX", "DEC2", "DEC2 MUX"},
+	{"IIR2 INP2 MUX", "DEC3", "DEC3 MUX"},
+	{"IIR2 INP2 MUX", "DEC4", "DEC4 MUX"},
+	{"IIR2 INP2 MUX", "RX1", "SLIM RX1"},
+	{"IIR2 INP2 MUX", "RX2", "SLIM RX2"},
+	{"IIR2 INP2 MUX", "RX3", "SLIM RX3"},
+	{"IIR2 INP2 MUX", "RX4", "SLIM RX4"},
+	{"IIR2 INP2 MUX", "RX5", "SLIM RX5"},
+
+	{"IIR2", NULL, "IIR2 INP3 MUX"},
+	{"IIR2 INP3 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR2 INP3 MUX", "DEC2", "DEC2 MUX"},
+	{"IIR2 INP3 MUX", "DEC3", "DEC3 MUX"},
+	{"IIR2 INP3 MUX", "DEC4", "DEC4 MUX"},
+	{"IIR2 INP3 MUX", "RX1", "SLIM RX1"},
+	{"IIR2 INP3 MUX", "RX2", "SLIM RX2"},
+	{"IIR2 INP3 MUX", "RX3", "SLIM RX3"},
+	{"IIR2 INP3 MUX", "RX4", "SLIM RX4"},
+	{"IIR2 INP3 MUX", "RX5", "SLIM RX5"},
+
+	{"IIR2", NULL, "IIR2 INP4 MUX"},
+	{"IIR2 INP4 MUX", "DEC1", "DEC1 MUX"},
+	{"IIR2 INP4 MUX", "DEC2", "DEC2 MUX"},
+	{"IIR2 INP4 MUX", "DEC3", "DEC3 MUX"},
+	{"IIR2 INP4 MUX", "DEC4", "DEC4 MUX"},
+	{"IIR2 INP4 MUX", "RX1", "SLIM RX1"},
+	{"IIR2 INP4 MUX", "RX2", "SLIM RX2"},
+	{"IIR2 INP4 MUX", "RX3", "SLIM RX3"},
+	{"IIR2 INP4 MUX", "RX4", "SLIM RX4"},
+	{"IIR2 INP4 MUX", "RX5", "SLIM RX5"},
 };
 
 static const struct snd_soc_dapm_route wcd9302_map[] = {
@@ -4425,6 +4571,23 @@
 	return 0;
 }
 
+static int tapan_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	int value = 0;
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		value = snd_soc_read(codec, TAPAN_A_CDC_IIR1_GAIN_B1_CTL);
+		snd_soc_write(codec, TAPAN_A_CDC_IIR1_GAIN_B1_CTL, value);
+		break;
+	default:
+		pr_err("%s: event = %d not expected\n", __func__, event);
+	}
+	return 0;
+}
+
 static const struct snd_soc_dapm_widget tapan_9306_dapm_widgets[] = {
 	/* RX4 MIX1 mux inputs */
 	SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
@@ -4806,7 +4969,38 @@
 		&iir1_inp1_mux, tapan_codec_iir_mux_event,
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_PGA("IIR1", TAPAN_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
+	SND_SOC_DAPM_PGA_E("IIR1", TAPAN_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0,
+		tapan_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_MUX_E("IIR1 INP2 MUX", TAPAN_A_CDC_IIR1_GAIN_B2_CTL, 0, 0,
+		&iir1_inp2_mux, tapan_codec_iir_mux_event,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("IIR1 INP3 MUX", TAPAN_A_CDC_IIR1_GAIN_B3_CTL, 0, 0,
+		&iir1_inp3_mux, tapan_codec_iir_mux_event,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("IIR1 INP4 MUX", TAPAN_A_CDC_IIR1_GAIN_B4_CTL, 0, 0,
+		&iir1_inp4_mux, tapan_codec_iir_mux_event,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("IIR2 INP1 MUX", TAPAN_A_CDC_IIR2_GAIN_B1_CTL, 0, 0,
+		&iir2_inp1_mux, tapan_codec_iir_mux_event,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("IIR2 INP2 MUX", TAPAN_A_CDC_IIR2_GAIN_B2_CTL, 0, 0,
+		&iir2_inp2_mux, tapan_codec_iir_mux_event,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("IIR2 INP3 MUX", TAPAN_A_CDC_IIR2_GAIN_B3_CTL, 0, 0,
+		&iir2_inp3_mux, tapan_codec_iir_mux_event,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("IIR2 INP4 MUX", TAPAN_A_CDC_IIR2_GAIN_B4_CTL, 0, 0,
+		&iir2_inp4_mux, tapan_codec_iir_mux_event,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_PGA("IIR2", TAPAN_A_CDC_CLK_SD_CTL, 1, 0, NULL, 0),
 
 	/* AUX PGA */
 	SND_SOC_DAPM_ADC_E("AUX_PGA_Left", NULL, TAPAN_A_RX_AUX_SW_CTL, 7, 0,
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index a49866c..09721e1 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -2290,7 +2290,8 @@
 		 * source to VDDIO
 		 */
 		if (mbhc->event_state &
-		(1 << MBHC_EVENT_PA_HPHL | 1 << MBHC_EVENT_PA_HPHR))
+		(1 << MBHC_EVENT_PA_HPHL | 1 << MBHC_EVENT_PA_HPHR |
+		1 << MBHC_EVENT_PRE_TX_1_3_ON))
 			__wcd9xxx_switch_micbias(mbhc, 1, false,
 						 false);
 		wcd9xxx_start_hs_polling(mbhc);
diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
index ff82299..e7b0cf0 100644
--- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c
+++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
@@ -284,8 +284,32 @@
 	unsigned long flags;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct lsm_priv *prtd = runtime->private_data;
+	int ret = 0;
 
 	pr_debug("%s\n", __func__);
+	if (prtd->lsm_client->started) {
+		ret = q6lsm_stop(prtd->lsm_client, true);
+		if (ret)
+			pr_err("%s: session stop failed, err = %d\n",
+				__func__, ret);
+		else
+			pr_debug("%s: LSM client session stopped %d\n",
+				 __func__, ret);
+
+		/*
+		 * Go Ahead and try de-register sound model,
+		 * even if stop failed
+		 */
+		prtd->lsm_client->started = false;
+
+		ret = q6lsm_deregister_sound_model(prtd->lsm_client);
+		if (ret)
+			pr_err("%s: dereg_snd_model failed, err = %d\n",
+				__func__, ret);
+		else
+			pr_debug("%s: dereg_snd_model succesful\n",
+				 __func__);
+	}
 
 	q6lsm_close(prtd->lsm_client);
 	q6lsm_client_free(prtd->lsm_client);
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index fc82215..a7a5d1e 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -2899,8 +2899,9 @@
 			__func__, pcm_afe_instance[port_id & 0x1]);
 		port_id = VIRTUAL_ID_TO_PORTID(port_id);
 		pcm_afe_instance[port_id & 0x1]--;
-		if (!(pcm_afe_instance[port_id & 0x1] == 0 &&
-			proxy_afe_instance[port_id & 0x1] == 0))
+		if ((!(pcm_afe_instance[port_id & 0x1] == 0 &&
+			proxy_afe_instance[port_id & 0x1] == 0)) ||
+			afe_close_done[port_id & 0x1] == true)
 			return 0;
 		else
 			afe_close_done[port_id & 0x1] = true;
@@ -2912,8 +2913,9 @@
 			__func__, proxy_afe_instance[port_id & 0x1]);
 		port_id = VIRTUAL_ID_TO_PORTID(port_id);
 		proxy_afe_instance[port_id & 0x1]--;
-		if (!(pcm_afe_instance[port_id & 0x1] == 0 &&
-			proxy_afe_instance[port_id & 0x1] == 0))
+		if ((!(pcm_afe_instance[port_id & 0x1] == 0 &&
+			proxy_afe_instance[port_id & 0x1] == 0)) ||
+			afe_close_done[port_id & 0x1] == true)
 			return 0;
 		else
 			afe_close_done[port_id & 0x1] = true;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 1ca9b1a..475a0eb 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -655,6 +655,8 @@
 	/* send cmd to create mvm session and wait for response */
 
 	if (!mvm_handle) {
+		memset(mvm_session_cmd.mvm_session.name, 0,
+			sizeof(mvm_session_cmd.mvm_session.name));
 		if (!is_voip_session(v->session_id)) {
 			mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD(
 						APR_MSG_TYPE_SEQ_CMD,
@@ -675,23 +677,23 @@
 			if (is_volte_session(v->session_id)) {
 				strlcpy(mvm_session_cmd.mvm_session.name,
 				"default volte voice",
-				sizeof(mvm_session_cmd.mvm_session.name));
+				strlen("default volte voice")+1);
 			} else if (is_voice2_session(v->session_id)) {
 				strlcpy(mvm_session_cmd.mvm_session.name,
 				VOICE2_SESSION_VSID_STR,
-				sizeof(mvm_session_cmd.mvm_session.name));
+				strlen(VOICE2_SESSION_VSID_STR)+1);
 			} else if (is_qchat_session(v->session_id)) {
 				strlcpy(mvm_session_cmd.mvm_session.name,
 				QCHAT_SESSION_VSID_STR,
-				sizeof(mvm_session_cmd.mvm_session.name));
+				strlen(QCHAT_SESSION_VSID_STR)+1);
 			} else if (is_vowlan_session(v->session_id)) {
 				strlcpy(mvm_session_cmd.mvm_session.name,
 				VOWLAN_SESSION_VSID_STR,
-				sizeof(mvm_session_cmd.mvm_session.name));
+				strlen(VOWLAN_SESSION_VSID_STR)+1);
 			} else {
 				strlcpy(mvm_session_cmd.mvm_session.name,
 				"default modem voice",
-				sizeof(mvm_session_cmd.mvm_session.name));
+				strlen("default modem voice")+1);
 			}
 
 			v->mvm_state = CMD_STATUS_FAIL;
@@ -727,7 +729,7 @@
 				VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION;
 			strlcpy(mvm_session_cmd.mvm_session.name,
 				"default voip",
-				sizeof(mvm_session_cmd.mvm_session.name));
+				strlen("default voip")+1);
 
 			v->mvm_state = CMD_STATUS_FAIL;
 
@@ -750,6 +752,8 @@
 	}
 	/* send cmd to create cvs session */
 	if (!cvs_handle) {
+		memset(cvs_session_cmd.cvs_session.name, 0,
+			sizeof(cvs_session_cmd.cvs_session.name));
 		if (!is_voip_session(v->session_id)) {
 			pr_debug("%s: creating CVS passive session\n",
 				 __func__);
@@ -771,23 +775,23 @@
 			if (is_volte_session(v->session_id)) {
 				strlcpy(cvs_session_cmd.cvs_session.name,
 				"default volte voice",
-				sizeof(cvs_session_cmd.cvs_session.name));
+				strlen("default volte voice")+1);
 			} else if (is_voice2_session(v->session_id)) {
 				strlcpy(cvs_session_cmd.cvs_session.name,
 				VOICE2_SESSION_VSID_STR,
-				sizeof(cvs_session_cmd.cvs_session.name));
+				strlen(VOICE2_SESSION_VSID_STR)+1);
 			} else if (is_qchat_session(v->session_id)) {
 				strlcpy(cvs_session_cmd.cvs_session.name,
 				QCHAT_SESSION_VSID_STR,
-				sizeof(cvs_session_cmd.cvs_session.name));
+				strlen(QCHAT_SESSION_VSID_STR)+1);
 			} else if (is_vowlan_session(v->session_id)) {
 				strlcpy(cvs_session_cmd.cvs_session.name,
 				VOWLAN_SESSION_VSID_STR,
-				sizeof(cvs_session_cmd.cvs_session.name));
+				strlen(VOWLAN_SESSION_VSID_STR)+1);
 			} else {
 			strlcpy(cvs_session_cmd.cvs_session.name,
 				"default modem voice",
-				sizeof(cvs_session_cmd.cvs_session.name));
+				strlen("default modem voice")+1);
 			}
 			v->cvs_state = CMD_STATUS_FAIL;
 
@@ -835,7 +839,7 @@
 					       common.mvs_info.network_type;
 			strlcpy(cvs_full_ctl_cmd.cvs_session.name,
 				"default q6 voice",
-				sizeof(cvs_full_ctl_cmd.cvs_session.name));
+				strlen("default q6 voice")+1);
 
 			v->cvs_state = CMD_STATUS_FAIL;