Merge "genalloc: Correct nbytes calculation on long boundary"
diff --git a/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt b/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
index 0d3d3f7..1b881f0 100644
--- a/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
+++ b/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
@@ -22,16 +22,13 @@
 				should be 1 for SVS corner
 - regulator-max-microvolt:	Maximum corner value as max constraint, which
 				should be 4 for SUPER_TURBO or 3 for TURBO
-- qcom,pvs-init-voltage:  	A list of integers whose length is equal to 2
-				to the power of qcom,pvs-fuse[num-of-bits]. The
-				location or 0-based index of an element in the
-				list corresponds to the bin number. The value of
-				each integer corresponds to the initial voltage
-				of the PVS bin in turbo mode in microvolts.
-- qcom,pvs-corner-ceiling-slow:	Ceiling voltages of all corners for APC_PVS_SLOW
-- qcom,pvs-corner-ceiling-nom:	Ceiling voltages of all corners for APC_PVS_NOM
-- qcom,pvs-corner-ceiling-fast:	Ceiling voltages of all corners for APC_PVS_FAST
-				The ceiling voltages for each of above three
+- qcom,pvs-voltage-table: 	Array of triples in which each triple indicates the initial voltage
+				of the PVS bin in SVS, NOM and Turbo corner in microvolts.
+				The location or 0-based index of an triple in the
+				list corresponds to the bin number.
+- qcom,cpr-voltage-ceiling:	Ceiling voltages of SVS, NOM and TURBO corners respectively
+- qcom,cpr-voltage-floor:	Floor voltages of SVS, NOM and TURBO corners respectively
+				The ceiling voltages for each of above two
 				properties may look like this:
 				  0 (SVS voltage):		1050000 uV
 				  1 (NORMAL voltage):		1150000 uV
@@ -243,23 +240,47 @@
 		interrupts = <0 15 0>;
 		regulator-name = "apc_corner";
 		regulator-min-microvolt = <1>;
-		regulator-max-microvolt = <3>;
+		regulator-max-microvolt = <12>;
 
 		qcom,pvs-fuse = <22 6 5 1>;
 		qcom,pvs-fuse-redun-sel = <22 24 3 2 1>;
 		qcom,pvs-fuse-redun = <22 27 5 1>;
 
-		qcom,pvs-init-voltage = <1330000 1330000 1330000 1320000
-						1310000 1300000 1290000 1280000
-						1270000 1260000 1250000 1240000
-						1230000 1220000 1210000 1200000
-						1190000 1180000 1170000 1160000
-						1150000 1140000 1140000 1140000
-						1140000 1140000 1140000 1140000
-						1140000 1140000 1140000 1140000>;
-		qcom,pvs-corner-ceiling-slow = <1050000 1160000 1275000>;
-		qcom,pvs-corner-ceiling-nom  =  <975000 1075000 1200000>;
-		qcom,pvs-corner-ceiling-fast =  <900000 1000000 1140000>;
+		qcom,pvs-voltage-table =
+			<1050000 1150000 1350000>,
+			<1050000 1150000 1340000>,
+			<1050000 1150000 1330000>,
+			<1050000 1150000 1320000>,
+			<1050000 1150000 1310000>,
+			<1050000 1150000 1300000>,
+			<1050000 1150000 1290000>,
+			<1050000 1150000 1280000>,
+			<1050000 1150000 1270000>,
+			<1050000 1140000 1260000>,
+			<1050000 1130000 1250000>,
+			<1050000 1120000 1240000>,
+			<1050000 1110000 1230000>,
+			<1050000 1100000 1220000>,
+			<1050000 1090000 1210000>,
+			<1050000 1080000 1200000>,
+			<1050000 1070000 1190000>,
+			<1050000 1060000 1180000>,
+			<1050000 1050000 1170000>,
+			<1050000 1050000 1160000>,
+			<1050000 1050000 1150000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>;
+		qcom,cpr-voltage-ceiling = <1050000 1150000 1280000>;
+		qcom,cpr-voltage-floor = <1050000 1050000 1100000>;
 		vdd-apc-supply = <&pm8226_s2>;
 		vdd-apc-optional-prim-supply = <&ncp6335d>;
 		vdd-apc-optional-sec-supply = <&fan53555>;
diff --git a/Documentation/devicetree/bindings/arm/msm/ext-buck-control.txt b/Documentation/devicetree/bindings/arm/msm/ext-buck-control.txt
new file mode 100644
index 0000000..37c0995
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/ext-buck-control.txt
@@ -0,0 +1,26 @@
+* MSM EXT BUCK REGULATOR CONTROL
+
+External buck regulator is used to power up the APC rail.
+This buck can be turn-on & turn-off by toggling a gpio
+line which is connected to buck enable pin. This driver
+control the external regulator behaviour with the help
+of RPM by sending the sleep and active sets when APPS
+decide to enter into low power state with RPM assisted.
+
+The required properties for EXT BUCK CONTROL are:
+
+- compatible: "qcom,ext-buck-control"
+
+The optional properties are:
+- qcom,gpio-num: Indicates the GPIO number which will turn-on and turn-off
+		 the external buck.
+- qcom,settling-time-us: Indicates the settling time for the external buck to
+			 get turn-on or turn-off. Settling time is calculated
+			 in terms of QTIMER(19.2MHz) and the value is in us.
+
+Example:
+	qcom,ext-buck-control {
+		compatible = "qcom,ext-buck-control";
+		qcom,gpio-num = <50>;
+		qcom,settling-time-us = <2580>;
+};
diff --git a/Documentation/devicetree/bindings/arm/msm/ext-buck-support.txt b/Documentation/devicetree/bindings/arm/msm/ext-buck-support.txt
deleted file mode 100644
index d7de2b7..0000000
--- a/Documentation/devicetree/bindings/arm/msm/ext-buck-support.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-* MSM EXT BUCK SUPPORT
-
-EXT BUCK SUPPORT driver is for supporting the external buck controlled by RPM.
-This driver sends active and sleep set votes when handshaking with rpm for
-supporting external buck by toggling a gpio to trun-on and turn-off external
-buck.
-
-The required properties for EXT BUCK SUPPORT are:
-
-- compatible: "qcom,ext-buck-support"
-
-The optional properties are:
-- qcom,gpio-num: Indicates the GPIO number which will turn-on and turn-off
-		 the external buck.
-- qcom,settling-time: Indicates the settling time for the external buck to
-		      get turn-on or turn-off. Settling time is calculated
-		      in terms of QTIMER(19.2MHz).
-
-Example:
-	qcom,ext-buck-support {
-		compatible = "qcom,ext-buck-support";
-		qcom,gpio-num = <50>;
-		qcom,settling-time = <2580>;
-	};
diff --git a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
index d0c2b7d..ba61a2f 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
@@ -52,6 +52,12 @@
  - goodix,cfg-data5	: Touch screen controller config data group 5. Ask vendor
 				to provide that.
  - goodix,fw-name	: Touch screen controller firmware file name.
+ - goodix,slide-wakeup	: To specify slide-wakeup property is enabled or not.
+ - goodix,dbl-clk-wakeup	: To specify dbl-clk-wakeup property is enabled or not.
+ - goodix,change-x2y	: To specify change-x2y property is enabled or not.
+ - goodix,driver-send-cfg	: To specify driver-send-cfg property is enabled or not.
+ - goodix,have-touch-key	: To specify have-touch-key property is enabled or not.
+ - goodix,with-pen	: To specify with-pen property is enabled or not.
 Example:
 i2c@f9927000 {
 		goodix@5d {
@@ -87,5 +93,7 @@
 				FF FF FF FF FF FF FF 22 22 22
 				22 22 22 FF 07 01];
 			goodix,fw_name = "gtp_fw.bin";
+			goodix,have-touch-key;
+			goodix,driver-send-cfg;
 		};
 };
diff --git a/Documentation/devicetree/bindings/media/video/msm-eeprom.txt b/Documentation/devicetree/bindings/media/video/msm-eeprom.txt
index 6ed130c..6aa0a16 100644
--- a/Documentation/devicetree/bindings/media/video/msm-eeprom.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-eeprom.txt
@@ -57,6 +57,7 @@
 - qcom,pageen%d : number %d page enable reg size, start address, address type,
     data, data type, delay in ms. size 0 stand for not used.
 - cam_vdig-supply : should contain regulator to be used for the digital vdd.
+- qcom,saddr%d : property should specify the slave address for block (%d).
 
 Optional properties -EEPROM Camera Multimodule
 - qcom,mm-data-support - Camera Multimodule data capability flag.
@@ -82,6 +83,7 @@
         qcom,pageen1 = <1 0x0202 2 0x01 1 10>;
         qcom,poll1 = <0 0x0 2 0 1 1>;
         qcom,mem1 = <32 0x3000 2 0 1 0>;
+        qcom,saddr1 = <0x62>;
 
 	qcom,mm-data-support;
 	qcom,mm-data-compressed;
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index 50381a2..87ecc64 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -106,6 +106,10 @@
 - qcom,vbatdet-maxerr-mv		This property in mV is a hystersis value for the charge
 					resume voltage property qcom,vbatdet-delta-mv. If this
 					property is not defined it defaults to 50 mV.
+- qcom,parallel-ovp-mode		When this option is enabled, it allows charging through both
+					DC and USB OVP FETs. Please note that this should only
+					be enabled in board designs with PM8941 which have DC_IN
+					and USB_IN connected via a short.
 
 Sub node required structure:
 - A qcom,chg node must be a child of an SPMI node that has specified
diff --git a/Documentation/devicetree/bindings/slimbus/slim-msm-ctrl.txt b/Documentation/devicetree/bindings/slimbus/slim-msm-ctrl.txt
index 64f2ddd..e199e55 100644
--- a/Documentation/devicetree/bindings/slimbus/slim-msm-ctrl.txt
+++ b/Documentation/devicetree/bindings/slimbus/slim-msm-ctrl.txt
@@ -54,7 +54,11 @@
 		 are to be used, so that application processor can query
 		 logical address of the ported generic device to be used.
 		 Other than PC, fields of EA are same across platforms.
-
+ -qcom,slim-mdm: This value indicates presence of slimbus component on
+		 external mdm. This property enables the slimbus driver to
+		 receive subsytem restart notification from mdm and follow
+		 appropriate steps to ensure communication on the bus can be
+		 resumed after mdm-restart.
 Example:
 	slim@fe12f000 {
 		cell-index = <1>;
diff --git a/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
index e4e05d1..415a3ef 100644
--- a/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
+++ b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
@@ -26,6 +26,12 @@
 		to set temperature thresholds and receive notification when the temperature
 		crosses a set threshold, read temperature and enable/set trip types supported
 		by the thermal framework.
+- qcom,meas-interval-timer-idx: If present select from the following timer index to choose
+		a preset configurable measurement interval timer value. The driver defaults
+		to timer 1 with a measurement interval of 1 second if the property is not present.
+		0 : Select Timer 1 for a measurement polling interval of 1 second.
+		1 : Select Timer 2 for a measurement polling interval of 500ms.
+		2 : Select Timer 3 for a measurement polling interval of 4 seconds.
 
 Client required property:
 - qcom,<consumer name>-adc_tm : The phandle to the corresponding adc_tm device.
diff --git a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
index 24f21b4..6562607 100644
--- a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
@@ -131,15 +131,24 @@
 
 Required properties :
 - compatible : should be "qcom,hsic-smsc-hub"
-- smsc,model-id : should be either <3503> or <4604> depending on hub model
-- smsc,<gpio-name>-gpio : handle to the GPIO node, see "gpios property"
-  in Documentation/devicetree/bindings/gpio/gpio.txt.
-  Required "gpio-name" is "reset" and optionally - "refclk", "int".
-- <supply-name>-supply: handle to the regulator device tree node
-  Required "supply-name" is "hub_init" and optionally - "hub_vbus".
+- smsc,model-id : should be <3502>/<3503>/<4604> depending on hub model. It
+  will be 0 for standalone HSIC controller configuration.
+- smsc,reset-gpio: this output gpio is used to assert/de-assert the hub reset
 - Sub node for "MSM HSIC EHCI controller".
   Sub node has the required properties mentioned above.
 
+Optional properties :
+- smsc,int-gpio: this input gpio indicate HUB suspend status and signal remote
+  wakeup interrupt
+- smsc,refclk-gpio: this gpio is used to supply the reference clock
+- smsc,xo-clk-gio: this output gpio is used to control the external XO clock
+  which is supplied to the hub as a reference clock
+- hub-vbus-supply: this regulator is used to supply the power to
+  downstream ports
+- hub-int-supply: this regulator is used to bias the interrupt gpio
+- ext-hub-vddio-supply: this regulator is used to supply the power to one of
+  the hub's VDD.
+
 Example SMSC HSIC HUB :
 	hsic_hub {
 		compatible = "qcom,hsic-smsc-hub";
@@ -148,8 +157,8 @@
 		smsc,reset-gpio = <&pm8941_gpios 8 0x00>;
 		smsc,refclk-gpio = <&pm8941_gpios 16 0x00>;
 		smsc,int-gpio = <&msmgpio 50 0x00>;
-		hub_int-supply = <&pm8941_l10>;
-		hub_vbus-supply = <&pm8941_mvs1>;
+		hub-int-supply = <&pm8941_l10>;
+		hub-vbus-supply = <&pm8941_mvs1>;
 
 		hsic@f9a00000 {
 			compatible = "qcom,hsic-host";
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 623a23c..7d3d435 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -93,6 +93,8 @@
 	enable this feature without proper bus voting.
 -qcom,disable-retention-with-vdd-min: If present dont allow phy retention but allow
 	vdd min.
+- qcom,usbin-vadc: Corresponding vadc device's phandle to read usbin voltage using VADC.
+	This will be used to get value of usb power supply's VOLTAGE_NOW property.
 
 Example HSUSB OTG controller device node :
 	usb@f9690000 {
@@ -120,6 +122,7 @@
 		qcom,disable-retention-with-vdd-min;
 		qcom,hsusb-otg-dpsehv-int = <49>;
 		qcom,hsusb-otg-dmsehv-int = <58>;
+		qcom,usbin-vadc = <&pm8226_vadc>;
 		qcom,msm_bus,name = "usb2";
 		qcom,msm_bus,num_cases = <2>;
 		qcom,msm_bus,active_only = <0>;
diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
index a7a646d..bfa9abe 100644
--- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
@@ -58,6 +58,8 @@
 		for TX fifo allocation in QDSS composition
 - qcom,dwc-ssphy-deemphasis-value: This property if present represents ss phy
   deemphasis value to be used for overriding into SSPHY register.
+- qcom,usbin-vadc: Corresponding vadc device's phandle to read usbin voltage using VADC.
+	This will be used to get value of usb power supply's VOLTAGE_NOW property,
 
 Sub nodes:
 - Sub node for "DWC3- USB3 controller".
@@ -85,6 +87,7 @@
 		qcom,dwc-usb3-msm-tx-fifo-size = <29696>;
 		qcom,dwc-usb3-msm-qdss-tx-fifo-size = <16384>;
 		qcom,dwc-ssphy-deemphasis-value = <26>;
+		qcom,usbin-vadc = <&pm8941_vadc>;
 
 		qcom,msm_bus,name = "usb3";
 		qcom,msm_bus,num_cases = <2>;
diff --git a/arch/arm/boot/dts/apq8074-dragonboard.dtsi b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
index c7e24d9..8c76a6d 100644
--- a/arch/arm/boot/dts/apq8074-dragonboard.dtsi
+++ b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
@@ -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
@@ -74,7 +74,7 @@
 		/* Dragonboard has an always-on VBUS supply for HSIC hub,
 		 * providing a dummy regulator for the hub driver
 		 */
-		hub_vbus-supply = <&vph_pwr_vreg>;
+		hub-vbus-supply = <&vph_pwr_vreg>;
 
 		hsic_host: hsic@f9a00000 {
 			compatible = "qcom,hsic-host";
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index 9dde30e..41897da 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -363,6 +363,7 @@
 			interrupt-names = "eoc-int-en-set";
 			qcom,adc-bit-resolution = <15>;
 			qcom,adc-vdd-reference = <1800>;
+			qcom,vadc-poll-eoc;
 
 			chan@8 {
 				label = "die_temp";
@@ -421,6 +422,7 @@
 			qcom,adc-bit-resolution = <16>;
 			qcom,adc-vdd-reference = <1800>;
 			qcom,iadc-vadc = <&pm8226_vadc>;
+			qcom,iadc-poll-eoc;
 			qcom,use-default-rds-trim = <0>;
 
 			chan@0 {
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index e678388..94a4e83 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -875,6 +875,7 @@
 			qcom,hw-settle-time = <2>;
 			qcom,fast-avg-setup = <3>;
 			qcom,btm-channel-number = <0x68>;
+			qcom,meas-interval-timer-idx = <2>;
 		};
 
 		chan@8 {
diff --git a/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi b/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
index a99df65..3734273 100644
--- a/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
@@ -120,6 +120,7 @@
 
 		qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
 		qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
+		qcom,cdc-us-euro-gpios = <&msmgpio 69 0>;
 	};
 
 	sound-9302 {
@@ -137,6 +138,7 @@
 
 		qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
 		qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
+		qcom,cdc-us-euro-gpios = <&msmgpio 69 0>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8226-720p-mtp.dtsi b/arch/arm/boot/dts/msm8226-720p-mtp.dtsi
index 7f4f8fc..b4d9139 100644
--- a/arch/arm/boot/dts/msm8226-720p-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-720p-mtp.dtsi
@@ -110,6 +110,7 @@
 
 		qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
 		qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
+		qcom,cdc-us-euro-gpios = <&msmgpio 69 0>;
 	};
 
 	sound-9302 {
@@ -127,6 +128,7 @@
 
 		qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
 		qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
+		qcom,cdc-us-euro-gpios = <&msmgpio 69 0>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8226-gpu.dtsi b/arch/arm/boot/dts/msm8226-gpu.dtsi
index 590f733..fd20d8c 100644
--- a/arch/arm/boot/dts/msm8226-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8226-gpu.dtsi
@@ -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
@@ -34,9 +34,9 @@
 		qcom,msm-bus,num-paths = <2>;
 		qcom,msm-bus,vectors-KBps =
 			<26 512 0 0>, <89 604 0 0>,
-			<26 512 0 1600000>, <89 604 0 3200000>,
-			<26 512 0 3200000>, <89 604 0 5120000>,
-			<26 512 0 4256000>, <89 604 0 6400000>;
+			<26 512 800000 1600000>, <89 604 0 3200000>,
+			<26 512 1600000 3200000>, <89 604 0 5120000>,
+			<26 512 2128000 4256000>, <89 604 0 6400000>;
 
 
 		/* GDSC oxili regulators */
diff --git a/arch/arm/boot/dts/msm8226-mdss.dtsi b/arch/arm/boot/dts/msm8226-mdss.dtsi
index 8a98d5c..375c5df 100644
--- a/arch/arm/boot/dts/msm8226-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8226-mdss.dtsi
@@ -59,7 +59,7 @@
 		qcom,mdss-intf-off = <0x00000000 0x00021300>;
 		qcom,mdss-rot-block-size = <64>;
 		qcom,mdss-rotator-ot-limit = <2>;
-		qcom,mdss-smp-mb-per-pipe = <4>;
+		qcom,mdss-smp-mb-per-pipe = <3>;
 		vdd-cx-supply = <&pm8226_s1_corner>;
 
 		qcom,vbif-settings = <0x004 0x00000001>,
diff --git a/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi b/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
index c3fcedb..42de953 100755
--- a/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
+++ b/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
@@ -125,6 +125,8 @@
 				FF FF FF FF FF FF FF FF FF FF
 				FF FF FF FF 3E 01];
 			goodix,fw_name = "gtp_fw.bin";
+			goodix,have-touch-key;
+			goodix,driver-send-cfg;
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index a76c4df..5e890d3 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -19,7 +19,7 @@
 			regulator-name = "8226_s2";
 			reg = <0x1700 0x100>;
 			regulator-min-microvolt = <900000>;
-			regulator-max-microvolt = <1275000>;
+			regulator-max-microvolt = <1350000>;
 			qcom,mode = "auto";
 		};
 	};
@@ -35,23 +35,46 @@
 		reg-names = "rbcpr", "rbcpr_clk", "efuse_addr";
 		interrupts = <0 15 0>;
 		regulator-name = "apc_corner";
-		regulator-min-microvolt = <1>;
-		regulator-max-microvolt = <14>;
 
 		qcom,pvs-fuse-redun-sel = <22 24 3 2 0>;
 		qcom,pvs-fuse = <22 6 5 0>;
 		qcom,pvs-fuse-redun = <22 27 5 0>;
 
-		qcom,pvs-init-voltage = <1275000 1275000 1275000 1275000 1275000
-					1275000 1260000 1245000 1230000 1215000
-					1200000 1185000 1170000 1155000 1140000
-					1140000 1140000 1140000 1140000 1140000
-					1150000 1140000 1140000 1140000 1140000
-					1140000 1140000 1140000 1275000 1275000
-					1275000 1275000>;
-		qcom,pvs-corner-ceiling-slow = <1050000 1150000 1275000>;
-		qcom,pvs-corner-ceiling-nom  = <1050000 1075000 1200000>;
-		qcom,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
+		qcom,pvs-voltage-table =
+			<1050000 1150000 1350000>,
+			<1050000 1150000 1340000>,
+			<1050000 1150000 1330000>,
+			<1050000 1150000 1320000>,
+			<1050000 1150000 1310000>,
+			<1050000 1150000 1300000>,
+			<1050000 1150000 1290000>,
+			<1050000 1150000 1280000>,
+			<1050000 1150000 1270000>,
+			<1050000 1140000 1260000>,
+			<1050000 1130000 1250000>,
+			<1050000 1120000 1240000>,
+			<1050000 1110000 1230000>,
+			<1050000 1100000 1220000>,
+			<1050000 1090000 1210000>,
+			<1050000 1080000 1200000>,
+			<1050000 1070000 1190000>,
+			<1050000 1060000 1180000>,
+			<1050000 1050000 1170000>,
+			<1050000 1050000 1160000>,
+			<1050000 1050000 1150000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>,
+			<1050000 1050000 1140000>;
+		qcom,cpr-voltage-ceiling = <1050000 1150000 1280000>;
+		qcom,cpr-voltage-floor = <1050000 1050000 1100000>;
 		vdd-apc-supply = <&pm8226_s2>;
 
 		vdd-mx-supply = <&pm8226_l3_ao>;
@@ -63,14 +86,12 @@
 		qcom,cpr-timer-cons-up = <0>;
 		qcom,cpr-timer-cons-down = <2>;
 		qcom,cpr-irq-line = <0>;
-		qcom,cpr-step-quotient = <15>;
-		qcom,cpr-up-threshold = <0>;
-		qcom,cpr-down-threshold = <10>;
+		qcom,cpr-step-quotient = <30>;
 		qcom,cpr-idle-clocks = <0>;
 		qcom,cpr-gcnt-time = <1>;
 		qcom,vdd-apc-step-up-limit = <1>;
 		qcom,vdd-apc-step-down-limit = <1>;
-		qcom,cpr-apc-volt-step = <5000>;
+		qcom,cpr-apc-volt-step = <10000>;
 
 		qcom,cpr-fuse-redun-sel = <138 57 1 1 0>;
 		qcom,cpr-fuse-row = <138 0>;
@@ -91,15 +112,6 @@
 		qcom,cpr-uplift-max-volt = <1350000>;
 		qcom,cpr-uplift-speed-bin = <1>;
 		qcom,speed-bin-fuse-sel = <22 0 3 0>;
-		qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3 3 3 3 3 3>;
-		qcom,cpr-quot-adjust-table =
-					<1 5 450>,
-					<1 6 375>,
-					<1 7 300>,
-					<1 8 225>,
-					<1 9 187>,
-					<1 10 150>,
-					<1 11 75>;
 	};
 };
 
@@ -198,7 +210,7 @@
 		pm8226_l3: regulator-l3 {
 			regulator-name = "8226_l3";
 			regulator-min-microvolt = <750000>;
-			regulator-max-microvolt = <1275000>;
+			regulator-max-microvolt = <1337500>;
 			status = "okay";
 		};
 		pm8226_l3_ao: regulator-3-ao {
@@ -206,7 +218,7 @@
 			regulator-name = "8226_l3_ao";
 			qcom,set = <1>;
 			regulator-min-microvolt = <750000>;
-			regulator-max-microvolt = <1275000>;
+			regulator-max-microvolt = <1337500>;
 			status = "okay";
 		};
 		pm8226_l3_so: regulator-l3-so {
@@ -214,7 +226,7 @@
 			regulator-name = "8226_l3_so";
 			qcom,set = <2>;
 			regulator-min-microvolt = <750000>;
-			regulator-max-microvolt = <1275000>;
+			regulator-max-microvolt = <1337500>;
 			qcom,init-voltage = <750000>;
 			status = "okay";
 		};
diff --git a/arch/arm/boot/dts/msm8226-v1-pm.dtsi b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
index 6e79e8a..d59fab3 100644
--- a/arch/arm/boot/dts/msm8226-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
@@ -226,6 +226,9 @@
 			<0xff 191>, /* lpass_irq_out_apcs(3) */
 			<0xff 192>, /* lpass_irq_out_apcs(4) */
 			<0xff 194>, /* lpass_irq_out_apcs(6) */
+			<0xff 195>, /* SLIMbus  slimbus_core_ee1_irq */
+			<0xff 196>, /* BAM-Lite - SlimBus */
+			<0xff 198>, /* coresight-tmc-etr interrupt */
 			<0xff 200>, /* rpm_ipc(4) */
 			<0xff 201>, /* rpm_ipc(5) */
 			<0xff 202>, /* rpm_ipc(6) */
diff --git a/arch/arm/boot/dts/msm8226-v1.dtsi b/arch/arm/boot/dts/msm8226-v1.dtsi
index 7f2048f..b9455fb 100644
--- a/arch/arm/boot/dts/msm8226-v1.dtsi
+++ b/arch/arm/boot/dts/msm8226-v1.dtsi
@@ -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
@@ -65,3 +65,63 @@
 	qcom,retain-periph;
 	qcom,retain-mem;
 };
+
+&pm8226_s2 {
+	regulator-max-microvolt = <1275000>;
+};
+
+&pm8226_l3 {
+	regulator-max-microvolt = <1287500>;
+};
+
+&pm8226_l3_ao {
+	regulator-max-microvolt = <1287500>;
+};
+
+&pm8226_l3_so {
+	regulator-max-microvolt = <1287500>;
+};
+
+&apc_vreg_corner {
+	regulator-min-microvolt = <1>;
+	regulator-max-microvolt = <3>;
+	qcom,pvs-voltage-table =
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>,
+		<1050000 1150000 1275000>;
+	qcom,cpr-voltage-ceiling = <1050000 1150000 1275000>;
+	qcom,cpr-voltage-floor = <1050000 1050000 1100000>;
+	qcom,cpr-step-quotient = <15>;
+	qcom,cpr-apc-volt-step = <5000>;
+	qcom,cpr-up-threshold = <0>;
+	qcom,cpr-down-threshold = <10>;
+};
diff --git a/arch/arm/boot/dts/msm8226-v2-pm.dtsi b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
index 7753562..bc8fe5d 100644
--- a/arch/arm/boot/dts/msm8226-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
@@ -238,6 +238,9 @@
 			<0xff 191>, /* lpass_irq_out_apcs(3) */
 			<0xff 192>, /* lpass_irq_out_apcs(4) */
 			<0xff 194>, /* lpass_irq_out_apcs(6) */
+			<0xff 195>, /* SLIMbus  slimbus_core_ee1_irq */
+			<0xff 196>, /* BAM-Lite - SlimBus */
+			<0xff 198>, /* coresight-tmc-etr interrupt */
 			<0xff 200>, /* rpm_ipc(4) */
 			<0xff 201>, /* rpm_ipc(5) */
 			<0xff 202>, /* rpm_ipc(6) */
diff --git a/arch/arm/boot/dts/msm8226-v2.dtsi b/arch/arm/boot/dts/msm8226-v2.dtsi
index 5a670c2..6215740 100644
--- a/arch/arm/boot/dts/msm8226-v2.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2.dtsi
@@ -31,41 +31,20 @@
 		      <223 0x20000>;
 };
 
-&pm8226_l3 {
-	regulator-min-microvolt = <750000>;
-	regulator-max-microvolt = <1337500>;
-};
-
-&pm8226_l3_ao {
-	regulator-min-microvolt = <750000>;
-	regulator-max-microvolt = <1337500>;
-};
-
-&pm8226_l3_so {
-	regulator-min-microvolt = <750000>;
-	regulator-max-microvolt = <1337500>;
-};
-
-&pm8226_s2 {
-	regulator-min-microvolt = <900000>;
-	regulator-max-microvolt = <1330000>;
-};
-
 &apc_vreg_corner {
-	qcom,pvs-init-voltage = <1330000 1330000 1330000 1320000 1310000
-					1300000 1290000 1280000 1270000 1260000
-					1250000 1240000 1230000 1220000 1210000
-					1200000 1190000 1180000 1170000 1160000
-					1150000 1140000 1140000 1140000 1140000
-					1140000 1140000 1140000 1140000 1140000
-					1140000 1140000>;
-	qcom,pvs-corner-ceiling-slow = <1050000 1150000 1280000>;
-	qcom,pvs-corner-ceiling-nom  = <1050000 1080000 1200000>;
-	qcom,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
-	qcom,cpr-step-quotient = <30>;
+	regulator-min-microvolt = <1>;
+	regulator-max-microvolt = <14>;
 	qcom,cpr-up-threshold = <0>;
 	qcom,cpr-down-threshold = <5>;
-	qcom,cpr-apc-volt-step = <10000>;
+	qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3 3 3 3 3 3>;
+	qcom,cpr-quot-adjust-table =
+				<1 5 450>,
+				<1 6 375>,
+				<1 7 300>,
+				<1 8 225>,
+				<1 9 187>,
+				<1 10 150>,
+				<1 11 75>;
 };
 
 &msm_gpu {
@@ -78,6 +57,11 @@
 		reg =	<0xf9011050 0x8>,
 			<0xfc4b80b0 0x8>;
 		reg-names = "rcg-base", "efuse";
+		qcom,speed0-bin-v0 =
+			<         0 0>,
+			< 384000000 2>,
+			< 787200000 4>,
+			<1190400000 7>;
 		qcom,speed0-bin-v2 =
 			<         0 0>,
 			< 384000000 2>,
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index e7d8a4d..9113259 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -282,8 +282,9 @@
 		qcom,hsusb-otg-phy-type = <2>;
 		qcom,hsusb-otg-mode = <1>;
 		qcom,hsusb-otg-otg-control = <2>;
+		qcom,hsusb-otg-disable-reset;
 		qcom,dp-manual-pullup;
-		qcom,ahb-async-bridge-bypass;
+		qcom,usbin-vadc = <&pm8226_vadc>;
 
 		qcom,msm-bus,name = "usb";
 		qcom,msm-bus,num-cases = <3>;
@@ -486,6 +487,10 @@
 		compatible = "qcom,msm-lsm-client";
 	};
 
+	qti,msm-pcm-loopback {
+		compatible = "qti,msm-pcm-loopback";
+	};
+
 	qcom,msm-dai-q6 {
 		compatible = "qcom,msm-dai-q6";
 		qcom,msm-dai-q6-sb-0-rx {
@@ -1013,9 +1018,9 @@
 		clock-names = "clk-4", "clk-5";
 		qcom,speed0-bin-v0 =
 			<         0 0>,
-			< 384000000 2>,
-			< 787200000 4>,
-			<1190400000 7>;
+			< 384000000 1>,
+			< 787200000 2>,
+			<1190400000 3>;
 
 		cpu-vdd-supply = <&apc_vreg_corner>;
 	};
@@ -1508,6 +1513,7 @@
 		qcom,hw-settle-time = <2>;
 		qcom,fast-avg-setup = <3>;
 		qcom,btm-channel-number = <0x48>;
+		qcom,meas-interval-timer-idx = <2>;
 	};
 
 	chan@8 {
diff --git a/arch/arm/boot/dts/msm8610-bus.dtsi b/arch/arm/boot/dts/msm8610-bus.dtsi
index 54c698c..d26d660 100644
--- a/arch/arm/boot/dts/msm8610-bus.dtsi
+++ b/arch/arm/boot/dts/msm8610-bus.dtsi
@@ -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
@@ -41,8 +41,8 @@
 			qcom,qport = <0>;
 			qcom,ws = <10000>;
 			qcom,mas-hw-id = <8>;
-			qcom,prio1 = <2>;
-			qcom,prio0 = <2>;
+			qcom,prio1 = <3>;
+			qcom,prio0 = <3>;
 		};
 
 		mas-vfe {
diff --git a/arch/arm/boot/dts/msm8610-qrd-skuab.dtsi b/arch/arm/boot/dts/msm8610-qrd-skuab.dtsi
index c7fa9db..1554575 100644
--- a/arch/arm/boot/dts/msm8610-qrd-skuab.dtsi
+++ b/arch/arm/boot/dts/msm8610-qrd-skuab.dtsi
@@ -88,6 +88,8 @@
 				00 FF FF FF FF FF FF FF 00 00
 				00 FF FF FF FF FF FF FF FF FF
 				F8 FF FF FF E4 01];
+			goodix,have-touch-key;
+			goodix,driver-send-cfg;
 		};
 	};
 	gen-vkeys {
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index 30c557d..6639668 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -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
@@ -42,16 +42,41 @@
 		qcom,pvs-fuse = <23 6 5 1>;
 		qcom,pvs-fuse-redun = <61 47 5 1>;
 
-		qcom,pvs-init-voltage = <1275000 1275000 1275000 1275000 1275000
-					1275000 1275000 1275000 1275000 1275000
-					1275000 1275000 1275000 1275000 1275000
-					1275000 1275000 1275000 1275000 1275000
-					1275000 1275000 1275000 1275000 1275000
-					1275000 1275000 1275000 1275000 1275000
-					1275000 1275000>;
-		qcom,pvs-corner-ceiling-slow = <1050000 1150000 1275000>;
-		qcom,pvs-corner-ceiling-nom  = <1050000 1075000 1275000>;
-		qcom,pvs-corner-ceiling-fast = <1050000 1050000 1275000>;
+		qcom,pvs-voltage-table =
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>,
+			<1050000 1150000 1275000>;
+		qcom,cpr-voltage-ceiling = <1050000 1150000 1275000>;
+		qcom,cpr-voltage-floor = <1050000 1050000 1275000>;
 		vdd-apc-supply = <&pm8110_s2>;
 
 		vdd-mx-supply = <&pm8110_l3_ao>;
diff --git a/arch/arm/boot/dts/msm8610-v1-pm.dtsi b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
index 5fb406b..dc1dc8b 100644
--- a/arch/arm/boot/dts/msm8610-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
@@ -227,6 +227,7 @@
 			<0xff 191>, /* lpass_irq_out_apcs(3) */
 			<0xff 192>, /* lpass_irq_out_apcs(4) */
 			<0xff 194>, /* lpass_irq_out_apcs(6) */
+			<0xff 198>, /* QDSS - u_qdss */
 			<0xff 200>, /* rpm_ipc(4) */
 			<0xff 201>, /* rpm_ipc(5) */
 			<0xff 202>, /* rpm_ipc(6) */
diff --git a/arch/arm/boot/dts/msm8610-v1.dtsi b/arch/arm/boot/dts/msm8610-v1.dtsi
index 9d8c411..8965e93 100644
--- a/arch/arm/boot/dts/msm8610-v1.dtsi
+++ b/arch/arm/boot/dts/msm8610-v1.dtsi
@@ -20,6 +20,7 @@
 /include/ "msm8610-v1-pm.dtsi"
 
 / {
-	qcom,msm-id = <147 0>, <165 0>, <161 0>, <162 0>,
-			<163 0>, <164 0>, <166 0>;
+	qcom,msm-id = <147 1000>, <165 1000>, <161 1000>, <162 1000>,
+			<163 1000>, <164 1000>, <166 1000>, <225 1000>,
+			<226 1000>;
 };
diff --git a/arch/arm/boot/dts/msm8610-v2-pm.dtsi b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
index 331e344..2859744 100644
--- a/arch/arm/boot/dts/msm8610-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
@@ -239,6 +239,7 @@
 			<0xff 191>, /* lpass_irq_out_apcs(3) */
 			<0xff 192>, /* lpass_irq_out_apcs(4) */
 			<0xff 194>, /* lpass_irq_out_apcs(6) */
+			<0xff 198>, /* QDSS - u_qdss */
 			<0xff 200>, /* rpm_ipc(4) */
 			<0xff 201>, /* rpm_ipc(5) */
 			<0xff 202>, /* rpm_ipc(6) */
diff --git a/arch/arm/boot/dts/msm8610-v2.dtsi b/arch/arm/boot/dts/msm8610-v2.dtsi
index a1f466a..221598d 100644
--- a/arch/arm/boot/dts/msm8610-v2.dtsi
+++ b/arch/arm/boot/dts/msm8610-v2.dtsi
@@ -21,5 +21,6 @@
 
 / {
 	qcom,msm-id = <147 0x10001>, <165 0x10001>, <161 0x10001>, <162 0x10001>,
-				  <163 0x10001>, <164 0x10001>, <166 0x10001>;
+				  <163 0x10001>, <164 0x10001>, <166 0x10001>,
+				  <225 0x10001>, <226 0x10001>;
 };
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 61fa6bc..f152ceb 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -1168,6 +1168,7 @@
 		qcom,hw-settle-time = <2>;
 		qcom,fast-avg-setup = <3>;
 		qcom,btm-channel-number = <0x48>;
+		qcom,meas-interval-timer-idx = <2>;
 	};
 
 	chan@8 {
diff --git a/arch/arm/boot/dts/msm8926-v2-ext-buck.dtsi b/arch/arm/boot/dts/msm8926-v2-ext-buck.dtsi
index e5e496e..8a95116 100644
--- a/arch/arm/boot/dts/msm8926-v2-ext-buck.dtsi
+++ b/arch/arm/boot/dts/msm8926-v2-ext-buck.dtsi
@@ -52,5 +52,36 @@
 };
 
 &soc {
+	qcom,spm@f9012000 {
+		compatible = "qcom,spm-v2";
+		qcom,saw2-spm-cmd-pc-no-rpm = [00 32 10 e0 d0 6b c0 42 f0
+				03 50 4e 02 02 c0 d0 12 e0 6b 02 32
+				50 f0 0f];
+		qcom,saw2-spm-cmd-pc = [00 32 10 e0 d0 6b c0 42 f0
+				07 50 4e 02 02 c0 d0 12 e0 6b 02 32
+				50 f0 0f];
+	};
+
+	qcom,lpm-levels {
+		qcom,system-modes {
+			compatible = "qcom,system-modes";
+			qcom,system-modes@2 {
+				qcom,l2 = "l2_cache_pc";
+				qcom,latency-us = <13200>;
+				qcom,ss-power = <315>;
+				qcom,energy-overhead = <1027150>;
+				qcom,time-overhead = <2400>;
+				qcom,min-cpu-mode= "pc";
+				qcom,sync-cpus;
+				qcom,send-rpm-sleep-set;
+			};
+		};
+	};
+
+	qcom,ext-buck-control {
+		compatible = "qcom,ext-buck-control";
+		qcom,gpio-num = <50>;
+		qcom,settling-time-us = <9600>;
+	};
 
 };
diff --git a/arch/arm/boot/dts/msm8926-v2.dtsi b/arch/arm/boot/dts/msm8926-v2.dtsi
index 9d0c6db..1322573 100644
--- a/arch/arm/boot/dts/msm8926-v2.dtsi
+++ b/arch/arm/boot/dts/msm8926-v2.dtsi
@@ -80,6 +80,13 @@
 
 &apc_vreg_corner {
 	/delete-property/ qcom,cpr-enable;
+	/delete-property/ qcom,cpr-fuse-cond-min-volt-sel;
+	/delete-property/ qcom,cpr-cond-min-voltage;
+	/delete-property/ qcom,cpr-fuse-uplift-sel;
+	/delete-property/ qcom,cpr-uplift-voltage;
+	/delete-property/ qcom,cpr-uplift-quotient;
+	/delete-property/ qcom,cpr-uplift-max-volt;
+	/delete-property/ qcom,cpr-uplift-speed-bin;
 	qcom,vdd-mx-vmax = <1287500>;
 	qcom,vdd-mx-vmin-method = <4>;
 	qcom,vdd-mx-corner-map = <1050000 1150000 1280000>;
diff --git a/arch/arm/boot/dts/msm8926.dtsi b/arch/arm/boot/dts/msm8926.dtsi
index c274d9f..8a0e5c4 100644
--- a/arch/arm/boot/dts/msm8926.dtsi
+++ b/arch/arm/boot/dts/msm8926.dtsi
@@ -39,6 +39,11 @@
 		reg =	<0xf9011050 0x8>,
 			<0xfc4b80b0 0x8>;
 		reg-names = "rcg-base", "efuse";
+		qcom,speed0-bin-v0 =
+			<         0 0>,
+			< 384000000 2>,
+			< 787200000 4>,
+			<1190400000 7>;
 		qcom,speed0-bin-v1 =
 			<         0 0>,
 			< 384000000 2>,
@@ -127,41 +132,20 @@
 	};
 };
 
-&pm8226_l3 {
-	regulator-min-microvolt = <750000>;
-	regulator-max-microvolt = <1350000>;
-};
-
-&pm8226_l3_ao {
-	regulator-min-microvolt = <750000>;
-	regulator-max-microvolt = <1350000>;
-};
-
-&pm8226_l3_so {
-	regulator-min-microvolt = <750000>;
-	regulator-max-microvolt = <1350000>;
-};
-
-&pm8226_s2 {
-	regulator-min-microvolt = <900000>;
-	regulator-max-microvolt = <1350000>;
-};
-
 &apc_vreg_corner {
-	qcom,pvs-init-voltage = <1350000 1340000 1330000 1320000 1310000
-					1300000 1290000 1280000 1270000 1260000
-					1250000 1240000 1230000 1220000 1210000
-					1200000 1190000 1180000 1170000 1160000
-					1150000 1140000 1140000 1140000 1140000
-					1140000 1140000 1140000 1140000 1140000
-					1140000 1140000>;
-	qcom,pvs-corner-ceiling-slow = <1050000 1150000 1280000>;
-	qcom,pvs-corner-ceiling-nom  = <1050000 1080000 1200000>;
-	qcom,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
-	qcom,cpr-step-quotient = <30>;
 	qcom,cpr-up-threshold = <0>;
 	qcom,cpr-down-threshold = <2>;
-	qcom,cpr-apc-volt-step = <10000>;
+	regulator-min-microvolt = <1>;
+	regulator-max-microvolt = <14>;
+	qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3 3 3 3 3 3>;
+	qcom,cpr-quot-adjust-table =
+				<1 5 450>,
+				<1 6 375>,
+				<1 7 300>,
+				<1 8 225>,
+				<1 9 187>,
+				<1 10 150>,
+				<1 11 75>;
 	qcom,cpr-quotient-adjustment = <0 72 72>;
 };
 
@@ -186,3 +170,9 @@
 	hsic,strobe-gpio = <&msmgpio 119 0x00>;
 	hsic,data-gpio = <&msmgpio 120 0x00>;
 };
+
+&usb_otg {
+	/delete-property/ qcom,hsusb-otg-disable-reset;
+	qcom,ahb-async-bridge-bypass;
+};
+
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 9b9202e..5cf98d6 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -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
@@ -288,7 +288,7 @@
 	rpm-regulator-ldoa11 {
 		status = "okay";
 		pm8941_l11: regulator-l11 {
-			regulator-min-microvolt = <1300000>;
+			regulator-min-microvolt = <1225000>;
 			regulator-max-microvolt = <1350000>;
 			qcom,init-voltage = <1300000>;
 			status = "okay";
diff --git a/arch/arm/boot/dts/msm8974-v1.dtsi b/arch/arm/boot/dts/msm8974-v1.dtsi
index 556e912..6146454 100644
--- a/arch/arm/boot/dts/msm8974-v1.dtsi
+++ b/arch/arm/boot/dts/msm8974-v1.dtsi
@@ -149,6 +149,10 @@
 	qcom,hsusb-otg-pnoc-errata-fix;
 };
 
+&usb3 {
+	qcom,usbin-vadc = <&pm8941_vadc>;
+};
+
 &gdsc_venus {
 	qcom,skip-logic-collapse;
 	qcom,retain-periph;
diff --git a/arch/arm/boot/dts/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974-v2.dtsi
index 5607257..7e102fe 100644
--- a/arch/arm/boot/dts/msm8974-v2.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -49,6 +49,10 @@
 	};
 };
 
+&usb3 {
+	qcom,usbin-vadc = <&pm8941_vadc>;
+};
+
 /* GPU overrides */
 &msm_gpu {
 	/* Updated chip ID */
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-cdp.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-cdp.dts
index b6a6fcb..5a01945 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-cdp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-cdp.dts
@@ -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
@@ -20,3 +20,8 @@
 	compatible = "qcom,msm8974-cdp", "qcom,msm8974", "qcom,cdp";
 	qcom,board-id = <1 0>;
 };
+
+&sdhc_1 {
+	qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+	qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid-hbtp.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid-hbtp.dts
index f4f7968..6ba8b5e 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid-hbtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid-hbtp.dts
@@ -40,3 +40,8 @@
 	 */
 	status = "disabled";
 };
+
+&sdhc_1 {
+	qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+	qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid.dts
index be298d1..010a4ad 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid.dts
@@ -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
@@ -20,3 +20,8 @@
 	compatible = "qcom,msm8974-fluid", "qcom,msm8974", "qcom,fluid";
 	qcom,board-id = <3 0>;
 };
+
+&sdhc_1 {
+	qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+	qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-liquid.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-liquid.dts
index 49c3df0..0192f56 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-liquid.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-liquid.dts
@@ -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
@@ -20,3 +20,8 @@
 	compatible = "qcom,msm8974-liquid", "qcom,msm8974", "qcom,liquid";
 	qcom,board-id = <9 0>;
 };
+
+&sdhc_1 {
+	qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+	qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
index d4bb37b..f80551e 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
@@ -22,5 +22,7 @@
 };
 
 &sdhc_1 {
+	qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+	qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
 	qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
 };
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pm8941-cdp.dts b/arch/arm/boot/dts/msm8974pro-ac-pm8941-cdp.dts
index 3e0feda..08ef393 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pm8941-cdp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ac-pm8941-cdp.dts
@@ -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
@@ -20,3 +20,8 @@
 	compatible = "qcom,msm8974-cdp", "qcom,msm8974", "qcom,cdp";
 	qcom,board-id = <1 0>;
 };
+
+&sdhc_1 {
+	qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+	qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pm8941-liquid.dts b/arch/arm/boot/dts/msm8974pro-ac-pm8941-liquid.dts
index 7b88abe..8118e48 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pm8941-liquid.dts
+++ b/arch/arm/boot/dts/msm8974pro-ac-pm8941-liquid.dts
@@ -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
@@ -20,3 +20,8 @@
 	compatible = "qcom,msm8974-liquid", "qcom,msm8974", "qcom,liquid";
 	qcom,board-id = <9 0>;
 };
+
+&sdhc_1 {
+	qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+	qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pm8941-mtp.dts b/arch/arm/boot/dts/msm8974pro-ac-pm8941-mtp.dts
index f79d361..76d0121 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pm8941-mtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ac-pm8941-mtp.dts
@@ -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
@@ -22,9 +22,6 @@
 };
 
 &sdhc_1 {
-	qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000 384000000>;
-	qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
-
 	qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
 	qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
 };
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
index cdcfecb..694049a 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ac-pm8941.dtsi
@@ -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
@@ -18,7 +18,3 @@
 		      <213 0x10000>,
 		      <216 0x10000>;
 };
-
-&sdhc_1 {
-	reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>;
-};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pma8084-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-ac-pma8084-pm8941.dtsi
index dc438bb..bc7ecd2 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pma8084-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ac-pma8084-pm8941.dtsi
@@ -102,6 +102,7 @@
 	vbus_dwc3-supply = <&pm8941_mvs1>;
 	qcom,misc-ref = <&pm8941_misc>;
 	dwc_usb3-adc_tm = <&pm8941_adc_tm>;
+	qcom,usbin-vadc = <&pm8941_vadc>;
 	interrupt-map-mask = <0x0 0xffffffff>;
 	interrupt-map = <0x0 0 &intc 0 133 0
 			0x0 1 &spmi_bus 0x0 0x2 0x9 0x0>;
diff --git a/arch/arm/boot/dts/msm8974pro-ac-pma8084.dtsi b/arch/arm/boot/dts/msm8974pro-ac-pma8084.dtsi
index 4b7ed1d..46fae99 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-pma8084.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ac-pma8084.dtsi
@@ -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
@@ -18,7 +18,3 @@
 		      <213 0x10000>,
 		      <216 0x10000>;
 };
-
-&sdhc_1 {
-	reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>;
-};
diff --git a/arch/arm/boot/dts/msm8974pro-pm.dtsi b/arch/arm/boot/dts/msm8974pro-pm.dtsi
index 34ae372..aca8f20 100644
--- a/arch/arm/boot/dts/msm8974pro-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm.dtsi
@@ -376,4 +376,12 @@
 		reg = <0xfc000000 0x1a0000>;
 		qcom,start-offset = <0x190010>;
 	};
+
+	qcom,rpm-master-stats@fc428150 {
+		compatible = "qcom,rpm-master-stats";
+		reg = <0xfc428150 0x3200>;
+		qcom,masters = "APSS", "MPSS", "LPSS", "PRONTO";
+		qcom,master-stats-version = <2>;
+		qcom,master-offset = <2560>;
+	};
 };
diff --git a/arch/arm/boot/dts/msm8974pro-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
index 8b13c9f..decd444 100644
--- a/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
@@ -64,6 +64,10 @@
 	qcom,init-smps-mode = <0>;	/* Allow AUTO mode for VDD_CX. */
 };
 
+&usb3 {
+	qcom,usbin-vadc = <&pm8941_vadc>;
+};
+
 &krait_regulator_pmic {
 	status = "ok";
 
diff --git a/arch/arm/boot/dts/msm8974pro-pma8084-mtp.dtsi b/arch/arm/boot/dts/msm8974pro-pma8084-mtp.dtsi
old mode 100755
new mode 100644
index 552c559..680674d
--- a/arch/arm/boot/dts/msm8974pro-pma8084-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pma8084-mtp.dtsi
@@ -137,9 +137,6 @@
 	vdd-supply = <&pma8084_l20>;
 	vdd-io-supply = <&pma8084_s4>;
 
-	qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000 384000000>;
-	qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
-
 	qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
 	qcom,pad-pull-off = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
 };
diff --git a/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi b/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
index 79d7412..78e2167 100644
--- a/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
@@ -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
@@ -267,7 +267,7 @@
 	rpm-regulator-ldoa11 {
 		status = "okay";
 		pma8084_l11: regulator-l11 {
-			regulator-min-microvolt = <1300000>;
+			regulator-min-microvolt = <1225000>;
 			regulator-max-microvolt = <1300000>;
 			qcom,init-voltage = <1300000>;
 			status = "okay";
diff --git a/arch/arm/boot/dts/msm8974pro.dtsi b/arch/arm/boot/dts/msm8974pro.dtsi
old mode 100755
new mode 100644
index f9cdb6e..a72ebb2
--- a/arch/arm/boot/dts/msm8974pro.dtsi
+++ b/arch/arm/boot/dts/msm8974pro.dtsi
@@ -1755,3 +1755,10 @@
 &gdsc_venus {
 	qcom,skip-logic-collapse;
 };
+
+&sdhc_1 {
+	reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>;
+
+	qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000 384000000>;
+	qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
+};
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index f1c285d..e72e5ff 100755
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -276,6 +276,7 @@
 CONFIG_MD=y
 CONFIG_BLK_DEV_DM=y
 CONFIG_DM_CRYPT=y
+CONFIG_DM_REQ_CRYPT=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
 CONFIG_TUN=y
@@ -540,8 +541,9 @@
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_XTS=y
 CONFIG_NFC_QNCI=y
-CONFIG_CRYPTO_DEV_QCRYPTO=m
+CONFIG_CRYPTO_DEV_QCRYPTO=y
 CONFIG_CRYPTO_DEV_QCE=y
 CONFIG_CRYPTO_DEV_QCEDEV=y
 CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index bd49b1f..3be4085 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/bug.h>
 
 #include <linux/atomic.h>
 #include <asm/cacheflush.h>
@@ -765,6 +766,7 @@
 asmlinkage void __div0(void)
 {
 	printk("Division by zero in kernel.\n");
+	BUG_ON(PANIC_CORRUPTION);
 	dump_stack();
 }
 EXPORT_SYMBOL(__div0);
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index f2d65fe..b8444c1 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -339,7 +339,6 @@
 	select MSM_GPIOMUX
 	select MULTI_IRQ_HANDLER
 	select PM_DEVFREQ
-	select MSM_DEVFREQ_CPUBW
 	select MSM_PIL
 	select MSM_NATIVE_RESTART
 	select MSM_RESTART_V2
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index fae2378..1c07e7d 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -297,7 +297,7 @@
 obj-$(CONFIG_ARCH_MSM8610) += clock-dsi-8610.o
 obj-$(CONFIG_ARCH_MSMKRYPTON) += clock-local2.o clock-pll.o clock-krypton.o clock-rpm.o clock-voter.o
 
-obj-$(CONFIG_MSM_PM) += msm-pm.o pm-data.o ext-buck-support.o
+obj-$(CONFIG_MSM_PM) += msm-pm.o pm-data.o ext-buck-control.o
 
 obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire.o board-sapphire-gpio.o
 obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire-keypad.o board-sapphire-panel.o
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index 3539ad3..1c1fbe3 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -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
@@ -75,6 +75,11 @@
 	return MEMTYPE_EBI1;
 }
 
+static struct of_dev_auxdata msm_hsic_host_adata[] = {
+	OF_DEV_AUXDATA("qcom,hsic-host", 0xF9A00000, "msm_hsic_host", NULL),
+	{}
+};
+
 static struct of_dev_auxdata msm8226_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF9824000, \
 			"msm_sdcc.1", NULL),
@@ -89,6 +94,8 @@
 	OF_DEV_AUXDATA("qcom,sdhci-msm", 0xF9864900, \
 			"msm_sdcc.3", NULL),
 	OF_DEV_AUXDATA("qcom,hsic-host", 0xF9A00000, "msm_hsic_host", NULL),
+	OF_DEV_AUXDATA("qcom,hsic-smsc-hub", 0, "msm_smsc_hub",
+			msm_hsic_host_adata),
 
 	{}
 };
diff --git a/arch/arm/mach-msm/clock-a7.c b/arch/arm/mach-msm/clock-a7.c
index d09e4b6..a610a23 100644
--- a/arch/arm/mach-msm/clock-a7.c
+++ b/arch/arm/mach-msm/clock-a7.c
@@ -97,9 +97,7 @@
 
 static int cortex_enable(struct mux_div_clk *md)
 {
-	u32 src_sel = parent_to_src_sel(md->parents, md->num_parents,
-							md->c.parent);
-	return cortex_set_config(md, src_sel, md->data.div);
+	return cortex_set_config(md, md->src_sel, md->data.div);
 }
 
 static void cortex_disable(struct mux_div_clk *md)
diff --git a/arch/arm/mach-msm/cpr-regulator.c b/arch/arm/mach-msm/cpr-regulator.c
index c245079..b940cb4 100644
--- a/arch/arm/mach-msm/cpr-regulator.c
+++ b/arch/arm/mach-msm/cpr-regulator.c
@@ -117,7 +117,6 @@
 #define CPR_INT_DEFAULT	(CPR_INT_UP | CPR_INT_DOWN)
 
 #define CPR_NUM_RING_OSC	8
-#define CPR_NUM_SAVE_REGS	10
 
 /* RBCPR Clock Control Register */
 #define RBCPR_CLK_SEL_MASK	BIT(0)
@@ -166,11 +165,9 @@
 	void __iomem	*efuse_base;
 
 	/* Process voltage parameters */
-	u32		pvs_init_v[CPR_PVS_EFUSE_BINS_MAX];
-	u32		pvs_corner_v[NUM_APC_PVS][CPR_FUSE_CORNER_MAX];
+	u32		pvs_corner_v[CPR_FUSE_CORNER_MAX];
 	/* Process voltage variables */
 	u32		pvs_bin;
-	u32		process;
 	u32		speed_bin;
 	/* APC voltage regulator */
 	struct regulator	*vdd_apc;
@@ -203,9 +200,6 @@
 	int		*save_ctl;
 	int		*save_irq;
 
-	u32		save_regs[CPR_NUM_SAVE_REGS];
-	u32		save_reg_val[CPR_NUM_SAVE_REGS];
-
 	/* Config parameters */
 	bool		enable;
 	u32		ref_clk_khz;
@@ -224,6 +218,8 @@
 	int		*corner_map;
 	u32		num_corners;
 	int		*quot_adjust;
+
+	bool		is_cpr_suspended;
 };
 
 #define CPR_DEBUG_MASK_IRQ	BIT(0)
@@ -348,6 +344,22 @@
 	u32 val;
 	int fuse_corner = cpr_vreg->corner_map[corner];
 
+	if (cpr_vreg->is_cpr_suspended)
+		return;
+
+	/* Program Consecutive Up & Down */
+	val = ((cpr_vreg->timer_cons_down & RBIF_TIMER_ADJ_CONS_DOWN_MASK)
+			<< RBIF_TIMER_ADJ_CONS_DOWN_SHIFT) |
+		(cpr_vreg->timer_cons_up & RBIF_TIMER_ADJ_CONS_UP_MASK);
+	cpr_masked_write(cpr_vreg, REG_RBIF_TIMER_ADJUST,
+			RBIF_TIMER_ADJ_CONS_UP_MASK |
+			RBIF_TIMER_ADJ_CONS_DOWN_MASK, val);
+	cpr_masked_write(cpr_vreg, REG_RBCPR_CTL,
+			RBCPR_CTL_SW_AUTO_CONT_NACK_DN_EN |
+			RBCPR_CTL_SW_AUTO_CONT_ACK_EN,
+			cpr_vreg->save_ctl[corner]);
+	cpr_irq_set(cpr_vreg, cpr_vreg->save_irq[corner]);
+
 	if (cpr_is_allowed(cpr_vreg) &&
 	    (cpr_vreg->ceiling_volt[fuse_corner] >
 		cpr_vreg->floor_volt[fuse_corner]))
@@ -359,31 +371,21 @@
 
 static void cpr_ctl_disable(struct cpr_regulator *cpr_vreg)
 {
+	if (cpr_vreg->is_cpr_suspended)
+		return;
+
+	cpr_irq_set(cpr_vreg, 0);
+	cpr_ctl_modify(cpr_vreg, RBCPR_CTL_SW_AUTO_CONT_NACK_DN_EN |
+			RBCPR_CTL_SW_AUTO_CONT_ACK_EN, 0);
+	cpr_masked_write(cpr_vreg, REG_RBIF_TIMER_ADJUST,
+			RBIF_TIMER_ADJ_CONS_UP_MASK |
+			RBIF_TIMER_ADJ_CONS_DOWN_MASK, 0);
+	cpr_irq_clr(cpr_vreg);
+	cpr_write(cpr_vreg, REG_RBIF_CONT_ACK_CMD, 1);
+	cpr_write(cpr_vreg, REG_RBIF_CONT_NACK_CMD, 1);
 	cpr_ctl_modify(cpr_vreg, RBCPR_CTL_LOOP_EN, 0);
 }
 
-static void cpr_regs_save(struct cpr_regulator *cpr_vreg)
-{
-	int i, offset;
-
-	for (i = 0; i < CPR_NUM_SAVE_REGS; i++) {
-		offset = cpr_vreg->save_regs[i];
-		cpr_vreg->save_reg_val[i] = cpr_read(cpr_vreg, offset);
-	}
-}
-
-static void cpr_regs_restore(struct cpr_regulator *cpr_vreg)
-{
-	int i, offset;
-	u32 val;
-
-	for (i = 0; i < CPR_NUM_SAVE_REGS; i++) {
-		offset = cpr_vreg->save_regs[i];
-		val = cpr_vreg->save_reg_val[i];
-		cpr_write(cpr_vreg, offset, val);
-	}
-}
-
 static void cpr_corner_save(struct cpr_regulator *cpr_vreg, int corner)
 {
 	cpr_vreg->save_ctl[corner] = cpr_read(cpr_vreg, REG_RBCPR_CTL);
@@ -495,8 +497,7 @@
 		vdd_mx = cpr_vreg->ceiling_volt[fuse_corner];
 		break;
 	case VDD_MX_VMIN_APC_SLOW_CORNER_CEILING:
-		vdd_mx = cpr_vreg->pvs_corner_v[APC_PVS_SLOW]
-						[CPR_FUSE_CORNER_TURBO];
+		vdd_mx = cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_TURBO];
 		break;
 	case VDD_MX_VMIN_MX_VMAX:
 		vdd_mx = cpr_vreg->vdd_mx_vmax;
@@ -842,8 +843,7 @@
 		cpr_ctl_disable(cpr_vreg);
 		new_volt = cpr_vreg->last_volt[corner];
 	} else {
-		new_volt = cpr_vreg->pvs_corner_v
-				[cpr_vreg->process][fuse_corner];
+		new_volt = cpr_vreg->pvs_corner_v[fuse_corner];
 	}
 
 	cpr_debug("[corner:%d, fuse_corner:%d] = %d uV\n", corner, fuse_corner,
@@ -892,12 +892,16 @@
 {
 	cpr_debug("suspend\n");
 
+	mutex_lock(&cpr_vreg->cpr_mutex);
+
 	cpr_ctl_disable(cpr_vreg);
 	disable_irq(cpr_vreg->cpr_irq);
 
 	cpr_irq_clr(cpr_vreg);
-	cpr_regs_save(cpr_vreg);
 
+	cpr_vreg->is_cpr_suspended = true;
+
+	mutex_unlock(&cpr_vreg->cpr_mutex);
 	return 0;
 }
 
@@ -906,12 +910,15 @@
 {
 	cpr_debug("resume\n");
 
-	cpr_regs_restore(cpr_vreg);
+	mutex_lock(&cpr_vreg->cpr_mutex);
+
+	cpr_vreg->is_cpr_suspended = false;
 	cpr_irq_clr(cpr_vreg);
 
 	enable_irq(cpr_vreg->cpr_irq);
 	cpr_ctl_enable(cpr_vreg, cpr_vreg->corner);
 
+	mutex_unlock(&cpr_vreg->cpr_mutex);
 	return 0;
 }
 
@@ -1008,21 +1015,6 @@
 	val |= RBCPR_CTL_SW_AUTO_CONT_ACK_EN;
 	cpr_write(cpr_vreg, REG_RBCPR_CTL, val);
 
-	/* Registers to save & restore for suspend */
-	cpr_vreg->save_regs[0] = REG_RBCPR_TIMER_INTERVAL;
-	cpr_vreg->save_regs[1] = REG_RBCPR_STEP_QUOT;
-	cpr_vreg->save_regs[2] = REG_RBIF_TIMER_ADJUST;
-	cpr_vreg->save_regs[3] = REG_RBIF_LIMIT;
-	cpr_vreg->save_regs[4] = REG_RBIF_SW_VLEVEL;
-	cpr_vreg->save_regs[5] = REG_RBIF_IRQ_EN(cpr_vreg->irq_line);
-	cpr_vreg->save_regs[6] = REG_RBCPR_CTL;
-	cpr_vreg->save_regs[7] = REG_RBCPR_GCNT_TARGET
-		(cpr_vreg->cpr_fuse_ro_sel[CPR_FUSE_CORNER_SVS]);
-	cpr_vreg->save_regs[8] = REG_RBCPR_GCNT_TARGET
-		(cpr_vreg->cpr_fuse_ro_sel[CPR_FUSE_CORNER_NORMAL]);
-	cpr_vreg->save_regs[9] = REG_RBCPR_GCNT_TARGET
-		(cpr_vreg->cpr_fuse_ro_sel[CPR_FUSE_CORNER_TURBO]);
-
 	cpr_irq_set(cpr_vreg, CPR_INT_DEFAULT);
 
 	val = cpr_read(cpr_vreg, REG_RBCPR_VERSION);
@@ -1067,7 +1059,7 @@
 {
 	u32 uplift_voltage;
 	u32 uplift_max_volt = 0;
-	int rc, i;
+	int rc;
 
 	rc = of_property_read_u32(of_node,
 		"qcom,cpr-uplift-voltage", &uplift_voltage);
@@ -1082,11 +1074,9 @@
 		return rc;
 	}
 
-	for (i = 0; i < CPR_PVS_EFUSE_BINS_MAX; i++) {
-		cpr_vreg->pvs_init_v[i] += uplift_voltage;
-		if (cpr_vreg->pvs_init_v[i] > uplift_max_volt)
-			cpr_vreg->pvs_init_v[i] = uplift_max_volt;
-	}
+	cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO] += uplift_voltage;
+	if (cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO] > uplift_max_volt)
+		cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO] = uplift_max_volt;
 
 	return rc;
 }
@@ -1096,11 +1086,11 @@
 {
 	struct device_node *of_node = pdev->dev.of_node;
 	u64 efuse_bits;
-	int rc, process;
+	int rc, i, stripe_size;
 	u32 pvs_fuse[4], pvs_fuse_redun_sel[5];
-	u32 init_v;
 	bool redundant;
 	size_t pvs_bins;
+	u32 *tmp;
 
 	rc = of_property_read_u32_array(of_node, "qcom,pvs-fuse-redun-sel",
 					pvs_fuse_redun_sel, 5);
@@ -1135,13 +1125,26 @@
 
 	pvs_bins = 1 << pvs_fuse[2];
 
-	rc = of_property_read_u32_array(of_node, "qcom,pvs-init-voltage",
-					cpr_vreg->pvs_init_v, pvs_bins);
+	stripe_size = CPR_FUSE_CORNER_MAX - 1;
+	tmp = kzalloc(sizeof(u32) * pvs_bins * stripe_size, GFP_KERNEL);
+	if (!tmp) {
+		pr_err("memory alloc failed\n");
+		return -ENOMEM;
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,pvs-voltage-table",
+					tmp, pvs_bins * stripe_size);
 	if (rc < 0) {
-		pr_err("pvs-init-voltage missing: rc=%d\n", rc);
+		pr_err("pvs-voltage-table missing: rc=%d\n", rc);
+		kfree(tmp);
 		return rc;
 	}
 
+	for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_MAX; i++)
+		cpr_vreg->pvs_corner_v[i] = tmp[cpr_vreg->pvs_bin *
+						stripe_size + i - 1];
+	kfree(tmp);
+
 	if (cpr_vreg->flags & FLAGS_UPLIFT_QUOT_VOLT) {
 		rc = cpr_voltage_uplift_wa_inc_volt(cpr_vreg, of_node);
 		if (rc < 0) {
@@ -1150,30 +1153,31 @@
 		}
 	}
 
-	init_v = cpr_vreg->pvs_init_v[cpr_vreg->pvs_bin];
-	for (process = NUM_APC_PVS - 1; process > APC_PVS_NO; process--) {
-		if (init_v <= cpr_vreg->pvs_corner_v
-			[process][CPR_FUSE_CORNER_TURBO])
-			break;
-	}
+	if (cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO] >
+		cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_TURBO])
+		cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_TURBO] =
+			cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO];
 
-	if (process == APC_PVS_NO) {
-		process = APC_PVS_SLOW;
-		cpr_vreg->pvs_corner_v[process][CPR_FUSE_CORNER_TURBO] = init_v;
-		cpr_vreg->ceiling_max = init_v;
-	} else if (process == APC_PVS_FAST &&
-		init_v < cpr_vreg->pvs_corner_v
-			[APC_PVS_FAST][CPR_FUSE_CORNER_SVS]) {
-		process = APC_PVS_SLOW;
-	}
+	for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_TURBO; i++)
+		if (cpr_vreg->pvs_corner_v[i] > cpr_vreg->ceiling_volt[i])
+			cpr_vreg->pvs_corner_v[i] = cpr_vreg->ceiling_volt[i];
+		else if (cpr_vreg->pvs_corner_v[i] < cpr_vreg->floor_volt[i])
+			cpr_vreg->pvs_corner_v[i] = cpr_vreg->floor_volt[i];
 
-	pr_info("[row:%d] = 0x%llX, n_bits=%d, bin=%d (%d)",
-		pvs_fuse[0], efuse_bits, pvs_fuse[2],
-		cpr_vreg->pvs_bin, process);
-	pr_info("pvs initial turbo voltage_= from %u to %u\n",
-		init_v, cpr_vreg->pvs_corner_v[process][CPR_FUSE_CORNER_TURBO]);
+	cpr_vreg->ceiling_max = cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_TURBO];
 
-	cpr_vreg->process = process;
+	pr_info("pvs voltage: [%d %d %d] uV\n",
+			cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_SVS],
+			cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_NORMAL],
+			cpr_vreg->pvs_corner_v[CPR_FUSE_CORNER_TURBO]);
+	pr_info("ceiling voltage: [%d %d %d] uV\n",
+			cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_SVS],
+			cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_NORMAL],
+			cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_TURBO]);
+	pr_info("floor voltage: [%d %d %d] uV\n",
+			cpr_vreg->floor_volt[CPR_FUSE_CORNER_SVS],
+			cpr_vreg->floor_volt[CPR_FUSE_CORNER_NORMAL],
+			cpr_vreg->floor_volt[CPR_FUSE_CORNER_TURBO]);
 
 	return 0;
 }
@@ -1571,17 +1575,9 @@
 	if (!cpr_vreg->last_volt)
 		return -EINVAL;
 
-	/* Construct CPR voltage limits */
-	for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_MAX; i++) {
-		cpr_vreg->floor_volt[i] =
-			cpr_vreg->pvs_corner_v[APC_PVS_FAST][i];
-		cpr_vreg->ceiling_volt[i] =
-			cpr_vreg->pvs_corner_v[APC_PVS_SLOW][i];
-	}
-
 	for (i = 1; i < size; i++) {
 		cpr_vreg->last_volt[i] = cpr_vreg->pvs_corner_v
-				[cpr_vreg->process][cpr_vreg->corner_map[i]];
+						[cpr_vreg->corner_map[i]];
 	}
 
 	return 0;
@@ -1818,33 +1814,22 @@
 					struct cpr_regulator *cpr_vreg)
 {
 	struct device_node *of_node = pdev->dev.of_node;
-	int rc, i, j;
+	int rc, i;
 	u32 min_uv = 0;
 
-	rc = of_property_read_u32_array(of_node,
-		"qcom,pvs-corner-ceiling-slow",
-		&cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_FUSE_CORNER_SVS],
-		CPR_FUSE_CORNER_MAX - CPR_FUSE_CORNER_SVS);
+	rc = of_property_read_u32_array(of_node, "qcom,cpr-voltage-ceiling",
+		&cpr_vreg->ceiling_volt[CPR_FUSE_CORNER_SVS],
+		CPR_FUSE_CORNER_MAX - 1);
 	if (rc < 0) {
-		pr_err("pvs-corner-ceiling-slow missing: rc=%d\n", rc);
+		pr_err("cpr-voltage-ceiling missing: rc=%d\n", rc);
 		return rc;
 	}
 
-	rc = of_property_read_u32_array(of_node,
-		"qcom,pvs-corner-ceiling-nom",
-		&cpr_vreg->pvs_corner_v[APC_PVS_NOM][CPR_FUSE_CORNER_SVS],
-		CPR_FUSE_CORNER_MAX - CPR_FUSE_CORNER_SVS);
+	rc = of_property_read_u32_array(of_node, "qcom,cpr-voltage-floor",
+		&cpr_vreg->floor_volt[CPR_FUSE_CORNER_SVS],
+		CPR_FUSE_CORNER_MAX - 1);
 	if (rc < 0) {
-		pr_err("pvs-corner-ceiling-norm missing: rc=%d\n", rc);
-		return rc;
-	}
-
-	rc = of_property_read_u32_array(of_node,
-		"qcom,pvs-corner-ceiling-fast",
-		&cpr_vreg->pvs_corner_v[APC_PVS_FAST][CPR_FUSE_CORNER_SVS],
-		CPR_FUSE_CORNER_MAX - CPR_FUSE_CORNER_SVS);
-	if (rc < 0) {
-		pr_err("pvs-corner-ceiling-fast missing: rc=%d\n", rc);
+		pr_err("cpr-voltage-floor missing: rc=%d\n", rc);
 		return rc;
 	}
 
@@ -1858,22 +1843,13 @@
 	if (cpr_vreg->flags & FLAGS_SET_MIN_VOLTAGE) {
 		of_property_read_u32(of_node, "qcom,cpr-cond-min-voltage",
 					&min_uv);
-		for (i = APC_PVS_SLOW; i < NUM_APC_PVS; i++)
-			for (j = CPR_FUSE_CORNER_SVS; j < CPR_FUSE_CORNER_MAX;
-				j++)
-				if (cpr_vreg->pvs_corner_v[i][j] < min_uv)
-					cpr_vreg->pvs_corner_v[i][j] = min_uv;
-	}
-
-	/* Set ceiling max and use it for APC_PVS_NO */
-	cpr_vreg->ceiling_max =
-		cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_FUSE_CORNER_TURBO];
-
-	for (i = APC_PVS_SLOW; i < NUM_APC_PVS; i++) {
-		pr_info("[%d] [%d %d %d] uV\n", i,
-			cpr_vreg->pvs_corner_v[i][CPR_FUSE_CORNER_SVS],
-			cpr_vreg->pvs_corner_v[i][CPR_FUSE_CORNER_NORMAL],
-			cpr_vreg->pvs_corner_v[i][CPR_FUSE_CORNER_TURBO]);
+		for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_MAX; i++)
+			if (cpr_vreg->ceiling_volt[i] < min_uv) {
+				cpr_vreg->ceiling_volt[i] = min_uv;
+				cpr_vreg->floor_volt[i] = min_uv;
+			} else if (cpr_vreg->floor_volt[i] < min_uv) {
+				cpr_vreg->floor_volt[i] = min_uv;
+			}
 	}
 
 	return 0;
diff --git a/arch/arm/mach-msm/dfe-fsm9xxx.c b/arch/arm/mach-msm/dfe-fsm9xxx.c
index 66272d2..3470710 100644
--- a/arch/arm/mach-msm/dfe-fsm9xxx.c
+++ b/arch/arm/mach-msm/dfe-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -50,6 +50,8 @@
 					HH_IRQ_FIFO_SIZE) == \
 					(pdev)->irq_fifo_head)
 
+#define UINT32_MAX  (0xFFFFFFFFU)
+
 static struct hh_dev_node_info {
 	spinlock_t hh_lock;
 	char irq_fifo[HH_IRQ_FIFO_SIZE];
@@ -220,8 +222,9 @@
 				return -EFAULT;
 			if (!HH_OFFSET_VALID(param.offset))
 				return -EINVAL;
-			if (param.num == 0)
-				break;
+			if ((param.num == 0) ||
+			(param.num >= (UINT32_MAX / sizeof(unsigned int))))
+				return -EINVAL;
 			req_sz = sizeof(unsigned int) * param.num;
 
 			if (pdfi->array_num < param.num) {
@@ -270,8 +273,10 @@
 
 			if (copy_from_user(&param, argp, sizeof param))
 				return -EFAULT;
-			if (param.num == 0)
-				break;
+			if ((param.num == 0) ||
+			(param.num >= (UINT32_MAX  /
+			sizeof(struct dfe_command_entry))))
+				return -EINVAL;
 			req_sz = sizeof(struct dfe_command_entry) * param.num;
 
 			if (pdfi->cmd_num < param.num) {
diff --git a/arch/arm/mach-msm/ext-buck-support.c b/arch/arm/mach-msm/ext-buck-control.c
similarity index 88%
rename from arch/arm/mach-msm/ext-buck-support.c
rename to arch/arm/mach-msm/ext-buck-control.c
index 11f9e31..e0c349a 100644
--- a/arch/arm/mach-msm/ext-buck-support.c
+++ b/arch/arm/mach-msm/ext-buck-control.c
@@ -75,38 +75,40 @@
 {
 	char *key = NULL;
 	int gpio_num;
-	int settling_time;
+	int settling_time_us;
 	int ret = 0;
 
 	key = "qcom,gpio-num";
 	ret = of_property_read_u32(pdev->dev.of_node, key, &gpio_num);
 	if (ret) {
-		pr_debug("%s: Cannot read %s from dt", __func__, key);
+		pr_err("%s: Cannot read %s from dt (ret:%d)\n",
+						__func__, key, ret);
 		return ret;
 	}
 
-	key = "qcom,settling-time";
+	key = "qcom,settling-time-us";
 	ret = of_property_read_u32(pdev->dev.of_node, key,
-					&settling_time);
+					&settling_time_us);
 	if (ret) {
-		pr_debug("%s: Cannot read %s from dt", __func__, key);
+		pr_err("%s: Cannot read %s from dt (ret:%d)\n",
+						__func__, key, ret);
 		return ret;
 	}
 
-	ret = msm_send_ext_buck_votes(gpio_num, settling_time);
+	ret = msm_send_ext_buck_votes(gpio_num, settling_time_us);
 
 	return ret;
 }
 
 static struct of_device_id msm_ext_buck_table[] = {
-	{.compatible = "qcom,ext-buck-support"},
+	{.compatible = "qcom,ext-buck-control"},
 	{},
 };
 
 static struct platform_driver msm_ext_buck_driver = {
 	.probe = msm_ext_buck_probe,
 	.driver = {
-		.name = "ext-buck-support",
+		.name = "ext-buck-control",
 		.owner = THIS_MODULE,
 		.of_match_table = msm_ext_buck_table,
 	},
diff --git a/arch/arm/mach-msm/include/mach/camera2.h b/arch/arm/mach-msm/include/mach/camera2.h
index 0ce5213..7024045 100644
--- a/arch/arm/mach-msm/include/mach/camera2.h
+++ b/arch/arm/mach-msm/include/mach/camera2.h
@@ -119,11 +119,16 @@
 	uint32_t delay;
 };
 
+struct eeprom_slave_add_t {
+	uint32_t addr;
+};
+
 struct msm_eeprom_memory_map_t {
 	struct eeprom_map_t page;
 	struct eeprom_map_t pageen;
 	struct eeprom_map_t poll;
 	struct eeprom_map_t mem;
+	struct eeprom_slave_add_t saddr;
 };
 
 struct msm_eeprom_memory_block_t {
diff --git a/arch/arm/mach-msm/include/mach/msm_qmi_interface.h b/arch/arm/mach-msm/include/mach/msm_qmi_interface.h
index 1641e8c..4bcb0e7 100644
--- a/arch/arm/mach-msm/include/mach/msm_qmi_interface.h
+++ b/arch/arm/mach-msm/include/mach/msm_qmi_interface.h
@@ -172,37 +172,44 @@
  * qmi_connect_to_service() - Connect the QMI handle with a QMI service
  * @handle: QMI handle to be connected with the QMI service.
  * @service_id: Service id to identify the QMI service.
- * @instance_id: Instance id to identify the instance of the QMI service.
+ * @service_vers: Version to identify the compatibility.
+ * @service_ins: Instance id to identify the instance of the QMI service.
  *
  * @return: 0 on success, < 0 on error.
  */
 int qmi_connect_to_service(struct qmi_handle *handle,
-			   uint32_t service_id, uint32_t instance_id);
+			   uint32_t service_id,
+			   uint32_t service_vers,
+			   uint32_t service_ins);
 
 /**
  * qmi_svc_event_notifier_register() - Register a notifier block to receive
  *                                     events regarding a QMI service
  * @service_id: Service ID to identify the QMI service.
- * @instance_id: Instance ID to identify the instance of the QMI service.
+ * @service_vers: Version to identify the compatibility.
+ * @service_ins: Instance ID to identify the instance of the QMI service.
  * @nb: Notifier block used to receive the event.
  *
  * @return: 0 if successfully registered, < 0 on error.
  */
 int qmi_svc_event_notifier_register(uint32_t service_id,
-				    uint32_t instance_id,
+				    uint32_t service_vers,
+				    uint32_t service_ins,
 				    struct notifier_block *nb);
 
 /**
  * qmi_svc_event_notifier_unregister() - Unregister service event
  *                                       notifier block
  * @service_id: Service ID to identify the QMI service.
- * @instance_id: Instance ID to identify the instance of the QMI service.
+ * @service_vers: Version to identify the compatibility.
+ * @service_ins: Instance ID to identify the instance of the QMI service.
  * @nb: Notifier block registered to receive the events.
  *
  * @return: 0 if successfully registered, < 0 on error.
  */
 int qmi_svc_event_notifier_unregister(uint32_t service_id,
-				      uint32_t instance_id,
+				      uint32_t service_vers,
+				      uint32_t service_ins,
 				      struct notifier_block *nb);
 #else
 
@@ -260,20 +267,23 @@
 
 static inline int qmi_connect_to_service(struct qmi_handle *handle,
 					 uint32_t service_id,
-					 uint32_t instance_id)
+					 uint32_t service_vers,
+					 uint32_t service_ins)
 {
 	return -ENODEV;
 }
 
 static inline int qmi_svc_event_notifier_register(uint32_t service_id,
-						  uint32_t instance_id,
+						  uint32_t service_vers,
+						  uint32_t service_ins,
 						  struct notifier_block *nb)
 {
 	return -ENODEV;
 }
 
 static inline int qmi_svc_event_notifier_unregister(uint32_t service_id,
-						    uint32_t instance_id,
+						    uint32_t service_vers,
+						    uint32_t service_ins,
 						    struct notifier_block *nb)
 {
 	return -ENODEV;
diff --git a/arch/arm/mach-msm/include/mach/usbdiag.h b/arch/arm/mach-msm/include/mach/usbdiag.h
index 15f4783..7457993 100644
--- a/arch/arm/mach-msm/include/mach/usbdiag.h
+++ b/arch/arm/mach-msm/include/mach/usbdiag.h
@@ -1,6 +1,6 @@
 /* include/asm-arm/arch-msm/usbdiag.h
  *
- * Copyright (c) 2008-2010, 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2008-2010, 2012-2013,The Linux Foundation. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
@@ -54,7 +54,6 @@
 		void (*notify)(void *, unsigned, struct diag_request *));
 void usb_diag_close(struct usb_diag_ch *ch);
 int usb_diag_alloc_req(struct usb_diag_ch *ch, int n_write, int n_read);
-void usb_diag_free_req(struct usb_diag_ch *ch);
 int usb_diag_read(struct usb_diag_ch *ch, struct diag_request *d_req);
 int usb_diag_write(struct usb_diag_ch *ch, struct diag_request *d_req);
 #else
@@ -71,9 +70,6 @@
 {
 	return -ENODEV;
 }
-static inline void usb_diag_free_req(struct usb_diag_ch *ch)
-{
-}
 static inline
 int usb_diag_read(struct usb_diag_ch *ch, struct diag_request *d_req)
 {
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index 2370bec..7128017 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -754,7 +754,7 @@
 	do_div(time, 1000);
 	dev->last_residency = (int)time;
 	local_irq_enable();
-	return index;
+	return idx;
 }
 
 static int lpm_suspend_enter(suspend_state_t state)
diff --git a/arch/arm/mach-msm/mpm-of.c b/arch/arm/mach-msm/mpm-of.c
index 5b351b4..1fbd077 100644
--- a/arch/arm/mach-msm/mpm-of.c
+++ b/arch/arm/mach-msm/mpm-of.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-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
@@ -32,6 +32,7 @@
 #include <linux/power_supply.h>
 #include <linux/regulator/consumer.h>
 #include <linux/workqueue.h>
+#include <linux/mutex.h>
 #include <asm/hardware/gic.h>
 #include <asm/arch_timer.h>
 #include <mach/gpio.h>
@@ -567,6 +568,9 @@
 }
 static void msm_mpm_sys_low_power_modes(bool allow)
 {
+	static DEFINE_MUTEX(enable_xo_mutex);
+
+	mutex_lock(&enable_xo_mutex);
 	if (allow) {
 		if (xo_enabled) {
 			clk_disable_unprepare(xo_clk);
@@ -582,6 +586,7 @@
 			xo_enabled = true;
 		}
 	}
+	mutex_unlock(&enable_xo_mutex);
 }
 
 void msm_mpm_suspend_prepare(void)
diff --git a/arch/arm/mach-msm/msm-pm.c b/arch/arm/mach-msm/msm-pm.c
index 865cd0a..f9a9343 100644
--- a/arch/arm/mach-msm/msm-pm.c
+++ b/arch/arm/mach-msm/msm-pm.c
@@ -39,6 +39,7 @@
 #include "scm-boot.h"
 #include "spm.h"
 #include "pm-boot.h"
+#include "clock.h"
 
 #define CREATE_TRACE_POINTS
 #include <mach/trace_msm_low_power.h>
@@ -452,8 +453,8 @@
 	if (!msm_pc_debug_counters)
 		return;
 
-	cnt = readl_relaxed(msm_pc_debug_counters + cpu * 4 + offset * 4);
-	writel_relaxed(++cnt, msm_pc_debug_counters + cpu * 4 + offset * 4);
+	cnt = readl_relaxed(msm_pc_debug_counters + cpu * 4 * MSM_PC_NUM_COUNTERS + offset * 4);
+	writel_relaxed(++cnt, msm_pc_debug_counters + cpu * 4 * MSM_PC_NUM_COUNTERS + offset * 4);
 	mb();
 }
 
@@ -641,6 +642,14 @@
 	if (MSM_PM_DEBUG_POWER_COLLAPSE & msm_pm_debug_mask)
 		pr_info("CPU%u: %s: pre power down\n", cpu, __func__);
 
+	/* This spews a lot of messages when a core is hotplugged. This
+	 * information is most useful from last core going down during
+	 * power collapse
+	 */
+	if ((!from_idle && cpu_online(cpu))
+			|| (MSM_PM_DEBUG_IDLE_CLK & msm_pm_debug_mask))
+		clock_debug_print_enabled();
+
 	avsdscr = avs_get_avsdscr();
 	avscsr = avs_get_avscsr();
 	avs_set_avscsr(0); /* Disable AVS */
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
index a76c29b..5747f79 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
@@ -1932,13 +1932,9 @@
 	ports = hop->node_info->num_sports;
 	MSM_BUS_DBG("BIMC: ID: %d, Sports: %d\n", hop->node_info->priv_id,
 		ports);
-	if (ports)
-		bw = INTERLEAVED_BW(fab_pdata, add_bw, ports);
-	else
-		return;
 
 	for (i = 0; i < ports; i++) {
-		sel_cd->slv[hop->node_info->slavep[i]].bw += bw;
+		sel_cd->slv[hop->node_info->slavep[i]].bw += add_bw;
 		sel_cd->slv[hop->node_info->slavep[i]].hw_id =
 			hop->node_info->slv_hw_id;
 		MSM_BUS_DBG("BIMC: Update slave_bw: ID: %d -> %llu\n",
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_noc.c b/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
index 479826e..988d720 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
@@ -586,14 +586,8 @@
 
 skip_mas_bw:
 	ports = hop->node_info->num_sports;
-	if (ports == 0) {
-		MSM_BUS_DBG("\nDIVIDE BY 0, hop: %d\n",
-			hop->node_info->priv_id);
-		return;
-	}
-	bw = INTERLEAVED_BW(fab_pdata, add_bw, ports);
 	for (i = 0; i < ports; i++) {
-		sel_cd->slv[hop->node_info->slavep[i]].bw += bw;
+		sel_cd->slv[hop->node_info->slavep[i]].bw += add_bw;
 		sel_cd->slv[hop->node_info->slavep[i]].hw_id =
 			hop->node_info->slv_hw_id;
 		MSM_BUS_DBG("NOC: Update slave_bw for ID: %d -> %llu\n",
diff --git a/arch/arm/mach-msm/msm_qmi_interface.c b/arch/arm/mach-msm/msm_qmi_interface.c
index e2ff0f4..7c5adc1 100644
--- a/arch/arm/mach-msm/msm_qmi_interface.c
+++ b/arch/arm/mach-msm/msm_qmi_interface.c
@@ -33,6 +33,9 @@
 
 #include "msm_qmi_interface_priv.h"
 
+#define BUILD_INSTANCE_ID(vers, ins) (((vers) & 0xFF) | (((ins) & 0xFF) << 8))
+#define LOOKUP_MASK 0xFFFFFFFF
+
 static LIST_HEAD(svc_event_nb_list);
 static DEFINE_MUTEX(svc_event_nb_list_lock);
 static DEFINE_MUTEX(msm_qmi_init_lock);
@@ -625,12 +628,15 @@
 EXPORT_SYMBOL(qmi_recv_msg);
 
 int qmi_connect_to_service(struct qmi_handle *handle,
-			   uint32_t service_id, uint32_t instance_id)
+			   uint32_t service_id,
+			   uint32_t service_vers,
+			   uint32_t service_ins)
 {
 	struct msm_ipc_port_name svc_name;
 	struct msm_ipc_server_info svc_info;
 	struct msm_ipc_addr *svc_dest_addr;
 	int rc;
+	uint32_t instance_id;
 
 	if (!handle)
 		return -EINVAL;
@@ -642,12 +648,15 @@
 		return -ENOMEM;
 	}
 
+	instance_id = BUILD_INSTANCE_ID(service_vers, service_ins);
 	svc_name.service = service_id;
 	svc_name.instance = instance_id;
 
-	rc = msm_ipc_router_lookup_server_name(&svc_name, &svc_info, 1, 0xFF);
+	rc = msm_ipc_router_lookup_server_name(&svc_name, &svc_info,
+						1, LOOKUP_MASK);
 	if (rc <= 0) {
-		pr_err("%s: Server not found\n", __func__);
+		pr_err("%s: Server %08x:%08x not found\n",
+			__func__, service_id, instance_id);
 		return -ENODEV;
 	}
 	svc_dest_addr->addrtype = MSM_IPC_ADDR_ID;
@@ -780,13 +789,16 @@
 }
 
 int qmi_svc_event_notifier_register(uint32_t service_id,
-				    uint32_t instance_id,
+				    uint32_t service_vers,
+				    uint32_t service_ins,
 				    struct notifier_block *nb)
 {
 	struct svc_event_nb *temp;
 	unsigned long flags;
 	int ret;
+	uint32_t instance_id;
 
+	instance_id = BUILD_INSTANCE_ID(service_vers, service_ins);
 	temp = find_and_add_svc_event_nb(service_id, instance_id);
 	if (!temp)
 		return -EFAULT;
@@ -810,13 +822,16 @@
 EXPORT_SYMBOL(qmi_svc_event_notifier_register);
 
 int qmi_svc_event_notifier_unregister(uint32_t service_id,
-				      uint32_t instance_id,
+				      uint32_t service_vers,
+				      uint32_t service_ins,
 				      struct notifier_block *nb)
 {
 	int ret;
 	struct svc_event_nb *temp;
 	unsigned long flags;
+	uint32_t instance_id;
 
+	instance_id = BUILD_INSTANCE_ID(service_vers, service_ins);
 	mutex_lock(&svc_event_nb_list_lock);
 	temp = find_svc_event_nb(service_id, instance_id);
 	if (!temp) {
diff --git a/arch/arm/mach-msm/pm-stats.c b/arch/arm/mach-msm/pm-stats.c
index c4e52be..5614ddd 100644
--- a/arch/arm/mach-msm/pm-stats.c
+++ b/arch/arm/mach-msm/pm-stats.c
@@ -225,6 +225,14 @@
 			stats[i].total_time = 0;
 		}
 	}
+	memset(suspend_stats.bucket,
+		0, sizeof(suspend_stats.bucket));
+	memset(suspend_stats.min_time,
+		0, sizeof(suspend_stats.min_time));
+	memset(suspend_stats.max_time,
+		0, sizeof(suspend_stats.max_time));
+	suspend_stats.count = 0;
+	suspend_stats.total_time = 0;
 
 	spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
 	return count;
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index e7cec58..9f50547 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -393,6 +393,8 @@
 	[164] = MSM_CPU_8610,
 	[165] = MSM_CPU_8610,
 	[166] = MSM_CPU_8610,
+	[225] = MSM_CPU_8610,
+	[226] = MSM_CPU_8610,
 
 	/* 8064AB IDs */
 	[153] = MSM_CPU_8064AB,
diff --git a/block/blk-core.c b/block/blk-core.c
index 00eab3b..7afd6cf 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1221,8 +1221,9 @@
 
 	elv_completed_request(q, req);
 
-	/* this is a bio leak */
-	WARN_ON(req->bio != NULL);
+	/* this is a bio leak if the bio is not tagged with BIO_DONTFREE */
+	WARN_ON(req->bio && !bio_flagged(req->bio, BIO_DONTFREE));
+
 
 	/*
 	 * Request may not have originated from ll_rw_blk. if not,
@@ -2274,6 +2275,15 @@
 	blk_account_io_completion(req, nr_bytes);
 
 	total_bytes = bio_nbytes = 0;
+
+	/*
+	 * Check for this if flagged, Req based dm needs to perform
+	 * post processing, hence dont end bios or request.DM
+	 * layer takes care.
+	 */
+	if (bio_flagged(req->bio, BIO_DONTFREE))
+		return false;
+
 	while ((bio = req->bio) != NULL) {
 		int nbytes;
 
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 028f045..8cc7515 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1870,7 +1870,6 @@
 	printk(KERN_DEBUG "diag: USB disconnected\n");
 	driver->usb_connected = 0;
 	driver->debug_flag = 1;
-	usb_diag_free_req(driver->legacy_ch);
 	if (driver->logging_mode == USB_MODE) {
 		for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++) {
 			driver->smd_data[i].in_busy_1 = 1;
@@ -2625,8 +2624,6 @@
 		diag_smd_destructor(&driver->smd_data[i]);
 
 #ifdef CONFIG_DIAG_OVER_USB
-	if (driver->usb_connected)
-		usb_diag_free_req(driver->legacy_ch);
 	usb_diag_close(driver->legacy_ch);
 #endif
 	platform_driver_unregister(&msm_smd_ch1_driver);
diff --git a/drivers/char/diag/diagfwd_bridge.c b/drivers/char/diag/diagfwd_bridge.c
index 143959b..142d15a 100644
--- a/drivers/char/diag/diagfwd_bridge.c
+++ b/drivers/char/diag/diagfwd_bridge.c
@@ -133,7 +133,6 @@
 			/* If the usb cable is being disconnected */
 			if (process_cable) {
 				diag_bridge[i].usb_connected = 0;
-				usb_diag_free_req(diag_bridge[i].ch);
 			}
 
 			if (i == SMUX) {
@@ -383,8 +382,6 @@
 	for (i = 0; i < MAX_BRIDGES; i++) {
 		if (diag_bridge[i].enabled) {
 #ifdef CONFIG_DIAG_OVER_USB
-			if (diag_bridge[i].usb_connected)
-				usb_diag_free_req(diag_bridge[i].ch);
 			usb_diag_close(diag_bridge[i].ch);
 #endif
 			kfree(diag_bridge[i].usb_buf_out);
diff --git a/drivers/char/diag/diagfwd_sdio.c b/drivers/char/diag/diagfwd_sdio.c
index 7d4e0d5..ef56a1b 100644
--- a/drivers/char/diag/diagfwd_sdio.c
+++ b/drivers/char/diag/diagfwd_sdio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011, 2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -131,7 +131,6 @@
 
 int diagfwd_disconnect_sdio(void)
 {
-	usb_diag_free_req(driver->mdm_ch);
 	if (driver->sdio_ch && (driver->logging_mode == USB_MODE)) {
 		driver->in_busy_sdio = 1;
 		diag_sdio_close();
@@ -280,10 +279,6 @@
 
 void diagfwd_sdio_exit(void)
 {
-#ifdef CONFIG_DIAG_OVER_USB
-	if (driver->usb_connected)
-		usb_diag_free_req(driver->mdm_ch);
-#endif
 	platform_driver_unregister(&msm_sdio_ch_driver);
 #ifdef CONFIG_DIAG_OVER_USB
 	usb_diag_close(driver->mdm_ch);
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 9e49b3e..e13fb5f 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -125,14 +125,20 @@
 	cur_time = jiffies;
 	devfreq->time_in_state[lev] +=
 			 cur_time - devfreq->last_stat_updated;
-	if (freq != devfreq->previous_freq) {
-		prev_lev = devfreq_get_freq_level(devfreq,
-						devfreq->previous_freq);
+	devfreq->last_stat_updated = cur_time;
+
+	if (freq == devfreq->previous_freq)
+		return 0;
+
+	prev_lev = devfreq_get_freq_level(devfreq, devfreq->previous_freq);
+	if (prev_lev < 0)
+		return 0;
+
+	if (lev != prev_lev) {
 		devfreq->trans_table[(prev_lev *
 				devfreq->profile->max_state) + lev]++;
 		devfreq->total_trans++;
 	}
-	devfreq->last_stat_updated = cur_time;
 
 	return 0;
 }
diff --git a/drivers/gpu/ion/ion_heap.c b/drivers/gpu/ion/ion_heap.c
index 6261d89..aa2551a 100644
--- a/drivers/gpu/ion/ion_heap.c
+++ b/drivers/gpu/ion/ion_heap.c
@@ -141,9 +141,11 @@
 		if (!ptr)
 			return -ENOMEM;
 
-		memset(ptr, 0, npages_to_vmap * PAGE_SIZE);
 		/*
-		 * invalidate the cache to pick up the zeroing
+		 * We have to invalidate the cache here because there
+		 * might be dirty lines to these physical pages (which
+		 * we don't care about) that could get written out at
+		 * any moment.
 		 */
 		for (k = 0; k < npages_to_vmap; k++) {
 			void *p = kmap_atomic(pages[i + k]);
@@ -154,6 +156,7 @@
 			outer_inv_range(phys, phys + PAGE_SIZE);
 			kunmap_atomic(p);
 		}
+		memset(ptr, 0, npages_to_vmap * PAGE_SIZE);
 		vunmap(ptr);
 	}
 
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index be1a89c..cfdd5f4 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_system_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-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
@@ -34,7 +34,7 @@
 					    __GFP_NO_KSWAPD) & ~__GFP_WAIT;
 static unsigned int low_order_gfp_flags  = (GFP_HIGHUSER | __GFP_ZERO |
 					 __GFP_NOWARN);
-static const unsigned int orders[] = {8, 4, 0};
+static const unsigned int orders[] = {9, 8, 4, 0};
 static const int num_orders = ARRAY_SIZE(orders);
 static int order_to_index(unsigned int order)
 {
@@ -362,7 +362,7 @@
 		struct ion_page_pool *pool;
 		gfp_t gfp_flags = low_order_gfp_flags;
 
-		if (orders[i] > 4)
+		if (orders[i])
 			gfp_flags = high_order_gfp_flags;
 		pool = ion_page_pool_create(gfp_flags, orders[i]);
 		if (!pool)
diff --git a/drivers/gpu/msm/adreno_profile.c b/drivers/gpu/msm/adreno_profile.c
index 079e120..26c8b69 100644
--- a/drivers/gpu/msm/adreno_profile.c
+++ b/drivers/gpu/msm/adreno_profile.c
@@ -1074,9 +1074,6 @@
 	 */
 	transfer_results(device, shared_buf_tail);
 
-	/* check for any cleanup */
-	check_close_profile(profile);
-
 	return 1;
 }
 
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 9aae497..7bbbc35 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -1197,6 +1197,8 @@
 					pwrlevel.level = constraint;
 		}
 
+		device->pwrctrl.constraint.expires = jiffies +
+			device->pwrctrl.interval_timeout;
 	}
 
 }
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 7d009ce..5f63cb6 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -723,4 +723,23 @@
 	return ret;
 }
 
+/**
+ * kgsl_sysfs_store() - parse a string from a sysfs store function
+ * @buf: Incoming string to parse
+ * @ptr: Pointer to an unsigned int to store the value
+ */
+static inline int kgsl_sysfs_store(const char *buf, unsigned int *ptr)
+{
+	unsigned int val;
+	int rc;
+
+	rc = kstrtou32(buf, 0, &val);
+	if (rc)
+		return rc;
+
+	if (ptr)
+		*ptr = val;
+
+	return 0;
+}
 #endif  /* __KGSL_DEVICE_H */
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index c00e978..9353b2e 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -220,19 +220,18 @@
 {
 	struct kgsl_device *device = kgsl_device_from_dev(dev);
 	struct kgsl_pwrctrl *pwr;
-	int ret, level;
+	int ret;
+	unsigned int level = 0;
 
 	if (device == NULL)
 		return 0;
 
 	pwr = &device->pwrctrl;
 
-	ret = sscanf(buf, "%d", &level);
-	if (ret != 1)
-		return count;
+	ret = kgsl_sysfs_store(buf, &level);
 
-	if (level < 0)
-		return count;
+	if (ret)
+		return ret;
 
 	mutex_lock(&device->mutex);
 
@@ -274,20 +273,17 @@
 {
 	struct kgsl_device *device = kgsl_device_from_dev(dev);
 	struct kgsl_pwrctrl *pwr;
-	int ret, level, max_level;
+	int ret, max_level;
+	unsigned int level = 0;
 
 	if (device == NULL)
 		return 0;
 
 	pwr = &device->pwrctrl;
 
-	ret = sscanf(buf, "%d", &level);
-	if (ret != 1)
-		return count;
-
-	/* If the use specifies a negative number, then don't change anything */
-	if (level < 0)
-		return count;
+	ret = kgsl_sysfs_store(buf, &level);
+	if (ret)
+		return ret;
 
 	mutex_lock(&device->mutex);
 
@@ -329,20 +325,17 @@
 					 const char *buf, size_t count)
 {	struct kgsl_device *device = kgsl_device_from_dev(dev);
 	struct kgsl_pwrctrl *pwr;
-	int ret, level, min_level;
+	int ret, min_level;
+	unsigned int level = 0;
 
 	if (device == NULL)
 		return 0;
 
 	pwr = &device->pwrctrl;
 
-	ret = sscanf(buf, "%d", &level);
-	if (ret != 1)
-		return count;
-
-	/* Don't do anything on obviously incorrect values */
-	if (level < 0)
-		return count;
+	ret = kgsl_sysfs_store(buf, &level);
+	if (ret)
+		return ret;
 
 	mutex_lock(&device->mutex);
 	if (level > pwr->num_pwrlevels - 2)
@@ -413,7 +406,7 @@
 {
 	struct kgsl_device *device = kgsl_device_from_dev(dev);
 	struct kgsl_pwrctrl *pwr;
-	unsigned long val;
+	unsigned int val = 0;
 	int ret, level;
 
 	if (device == NULL)
@@ -421,9 +414,9 @@
 
 	pwr = &device->pwrctrl;
 
-	ret = sscanf(buf, "%ld", &val);
-	if (ret != 1)
-		return count;
+	ret = kgsl_sysfs_store(buf, &val);
+	if (ret)
+		return ret;
 
 	mutex_lock(&device->mutex);
 	level = _get_nearest_pwrlevel(pwr, val);
@@ -465,7 +458,7 @@
 {
 	struct kgsl_device *device = kgsl_device_from_dev(dev);
 	struct kgsl_pwrctrl *pwr;
-	unsigned long val;
+	unsigned int val = 0;
 	int ret, level;
 
 	if (device == NULL)
@@ -473,9 +466,9 @@
 
 	pwr = &device->pwrctrl;
 
-	ret = sscanf(buf, "%ld", &val);
-	if (ret != 1)
-		return count;
+	ret = kgsl_sysfs_store(buf, &val);
+	if (ret)
+		return ret;
 
 	mutex_lock(&device->mutex);
 	level = _get_nearest_pwrlevel(pwr, val);
@@ -502,22 +495,19 @@
 					struct device_attribute *attr,
 					const char *buf, size_t count)
 {
-	char temp[20];
-	unsigned long val;
+	unsigned int val = 0;
 	struct kgsl_device *device = kgsl_device_from_dev(dev);
 	struct kgsl_pwrctrl *pwr;
 	const long div = 1000/HZ;
-	int rc;
+	int ret;
 
 	if (device == NULL)
 		return 0;
 	pwr = &device->pwrctrl;
 
-	snprintf(temp, sizeof(temp), "%.*s",
-			 (int)min(count, sizeof(temp) - 1), buf);
-	rc = strict_strtoul(temp, 0, &val);
-	if (rc)
-		return rc;
+	ret = kgsl_sysfs_store(buf, &val);
+	if (ret)
+		return ret;
 
 	mutex_lock(&device->mutex);
 
@@ -547,19 +537,16 @@
 					struct device_attribute *attr,
 					const char *buf, size_t count)
 {
-	char temp[20];
-	unsigned long val;
+	unsigned int val = 0;
 	struct kgsl_device *device = kgsl_device_from_dev(dev);
-	int rc;
+	int ret;
 
 	if (device == NULL)
 		return 0;
 
-	snprintf(temp, sizeof(temp), "%.*s",
-			(int)min(count, sizeof(temp) - 1), buf);
-	rc = kstrtoul(temp, 0, &val);
-	if (rc)
-		return rc;
+	ret = kgsl_sysfs_store(buf, &val);
+	if (ret)
+		return ret;
 
 	mutex_lock(&device->mutex);
 	device->pwrctrl.pm_qos_latency = val;
@@ -694,19 +681,16 @@
 					const char *buf, size_t count,
 					int flag)
 {
-	char temp[20];
-	unsigned long val;
+	unsigned int val = 0;
 	struct kgsl_device *device = kgsl_device_from_dev(dev);
-	int rc;
+	int ret;
 
 	if (device == NULL)
 		return 0;
 
-	snprintf(temp, sizeof(temp), "%.*s",
-			(int)min(count, sizeof(temp) - 1), buf);
-	rc = kstrtoul(temp, 0, &val);
-	if (rc)
-		return rc;
+	ret = kgsl_sysfs_store(buf, &val);
+	if (ret)
+		return ret;
 
 	mutex_lock(&device->mutex);
 	__force_on(device, flag, val);
@@ -772,19 +756,16 @@
 					struct device_attribute *attr,
 					const char *buf, size_t count)
 {
-	char temp[20];
-	unsigned long val;
+	unsigned int val = 0;
 	struct kgsl_device *device = kgsl_device_from_dev(dev);
-	int rc;
+	int ret;
 
 	if (device == NULL)
 		return 0;
 
-	snprintf(temp, sizeof(temp), "%.*s",
-			(int)min(count, sizeof(temp) - 1), buf);
-	rc = kstrtoul(temp, 0, &val);
-	if (rc)
-		return rc;
+	ret = kgsl_sysfs_store(buf, &val);
+	if (ret)
+		return ret;
 
 	mutex_lock(&device->mutex);
 	device->pwrctrl.bus_control = val ? true : false;
@@ -1569,7 +1550,10 @@
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
 	/* Order pwrrail/clk sequence based upon platform */
 	kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_ON);
-	kgsl_pwrctrl_pwrlevel_change(device, pwr->active_pwrlevel);
+
+	if (pwr->constraint.type == KGSL_CONSTRAINT_NONE)
+		kgsl_pwrctrl_pwrlevel_change(device, pwr->active_pwrlevel);
+
 	kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON, KGSL_STATE_ACTIVE);
 	kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON);
 }
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index c811b78..31c5229 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -51,6 +51,7 @@
 			unsigned int level;
 		} pwrlevel;
 	} hint;
+	unsigned long expires;
 };
 
 /**
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index acee4d4..0bb13a4 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -227,12 +227,25 @@
 			kgsl_pwrctrl_buslevel_update(device, true);
 	}
 
-	kgsl_pwrctrl_pwrlevel_change(device, level);
+	/*
+	 * The power constraints need an entire interval to do their magic, so
+	 * skip changing the powerlevel if the time hasn't expired yet  and the
+	 * new level is less than the constraint
+	 */
+	if ((pwr->constraint.type != KGSL_CONSTRAINT_NONE) &&
+		(!time_after(jiffies, pwr->constraint.expires)) &&
+		(level >= pwr->constraint.hint.pwrlevel.level))
+			*freq = cur_freq;
+	else {
+		/* Change the power level */
+		kgsl_pwrctrl_pwrlevel_change(device, level);
 
-	/*Invalidate the constraint set */
-	pwr->constraint.type = KGSL_CONSTRAINT_NONE;
+		/*Invalidate the constraint set */
+		pwr->constraint.type = KGSL_CONSTRAINT_NONE;
+		pwr->constraint.expires = 0;
 
-	*freq = kgsl_pwrctrl_active_freq(pwr);
+		*freq = kgsl_pwrctrl_active_freq(pwr);
+	}
 
 	mutex_unlock(&device->mutex);
 	return 0;
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c
index 91d787f..0d75869 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.c
@@ -77,12 +77,6 @@
 #define GTP_MAX_TOUCH		5
 #define GTP_ESD_CHECK_CIRCLE_MS	2000
 
-#if GTP_HAVE_TOUCH_KEY
-static const u16 touch_key_array[] = {KEY_MENU, KEY_HOMEPAGE, KEY_BACK};
-#define GTP_MAX_KEY_NUM  (sizeof(touch_key_array)/sizeof(touch_key_array[0]))
-
-#endif
-
 static void gtp_int_sync(struct goodix_ts_data *ts, int ms);
 static int gtp_i2c_test(struct i2c_client *client);
 static int goodix_power_off(struct goodix_ts_data *ts);
@@ -105,15 +99,14 @@
 static int gtp_init_ext_watchdog(struct i2c_client *client);
 #endif
 
-#if GTP_SLIDE_WAKEUP
-enum doze_status {
+enum doze {
 	DOZE_DISABLED = 0,
 	DOZE_ENABLED = 1,
 	DOZE_WAKEUP = 2,
 };
-static enum doze_status = DOZE_DISABLED;
+static enum doze doze_status = DOZE_DISABLED;
 static s8 gtp_enter_doze(struct goodix_ts_data *ts);
-#endif
+
 bool init_done;
 static u8 chip_gt9xxs;  /* true if ic is gt9xxs, like gt915s */
 u8 grp_cfg_version;
@@ -163,11 +156,11 @@
 		dev_err(&client->dev, "I2C retry: %d\n", retries + 1);
 	}
 	if (retries == GTP_I2C_RETRY_5) {
-#if GTP_SLIDE_WAKEUP
-		/* reset chip would quit doze mode */
-		if (DOZE_ENABLED == doze_status)
-			return ret;
-#endif
+		if (ts->pdata->slide_wakeup)
+			/* reset chip would quit doze mode */
+			if (DOZE_ENABLED == doze_status)
+				return ret;
+
 		if (init_done)
 			gtp_reset_guitar(ts, 10);
 		else
@@ -209,10 +202,10 @@
 		dev_err(&client->dev, "I2C retry: %d\n", retries + 1);
 	}
 	if ((retries == GTP_I2C_RETRY_5)) {
-#if GTP_SLIDE_WAKEUP
-		if (DOZE_ENABLED == doze_status)
-			return ret;
-#endif
+		if (ts->pdata->slide_wakeup)
+			if (DOZE_ENABLED == doze_status)
+				return ret;
+
 		if (init_done)
 			gtp_reset_guitar(ts, 10);
 		else
@@ -278,24 +271,25 @@
 *********************************************************/
 int gtp_send_cfg(struct goodix_ts_data *ts)
 {
-	int ret;
-#if GTP_DRIVER_SEND_CFG
-	int retry = 0;
+	int ret = 0;
+	int retry;
 
-	if (ts->fixed_cfg) {
-		dev_dbg(&ts->client->dev,
-			"Ic fixed config, no config sent!");
-		ret = 2;
-	} else {
-		for (retry = 0; retry < GTP_I2C_RETRY_5; retry++) {
-			ret = gtp_i2c_write(ts->client,
-				ts->config_data,
-				GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH);
-			if (ret > 0)
-				break;
+	if (ts->pdata->driver_send_cfg) {
+		if (ts->fixed_cfg) {
+			dev_dbg(&ts->client->dev,
+				"Ic fixed config, no config sent!");
+			ret = 2;
+		} else {
+			for (retry = 0; retry < GTP_I2C_RETRY_5; retry++) {
+				ret = gtp_i2c_write(ts->client,
+					ts->config_data,
+					GTP_CONFIG_MAX_LENGTH +
+						GTP_ADDR_LENGTH);
+				if (ret > 0)
+					break;
+			}
 		}
 	}
-#endif
 
 	return ret;
 }
@@ -355,9 +349,8 @@
 static void gtp_touch_down(struct goodix_ts_data *ts, int id, int x, int y,
 		int w)
 {
-#if GTP_CHANGE_X2Y
-	swap(x, y);
-#endif
+	if (ts->pdata->change_x2y)
+		swap(x, y);
 
 	input_mt_slot(ts->input_dev, id);
 	input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
@@ -402,9 +395,7 @@
 	u8 finger = 0;
 	static u16 pre_touch;
 	static u8 pre_key;
-#if GTP_WITH_PEN
 	static u8 pre_pen;
-#endif
 	u8 key_value = 0;
 	u8 *coor_data = NULL;
 	s32 input_x = 0;
@@ -414,10 +405,7 @@
 	s32 i = 0;
 	int ret = -1;
 	struct goodix_ts_data *ts = NULL;
-
-#if GTP_SLIDE_WAKEUP
 	u8 doze_buf[3] = {0x81, 0x4B};
-#endif
 
 	ts = container_of(work, struct goodix_ts_data, work);
 #ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE
@@ -425,55 +413,59 @@
 		return;
 #endif
 
-#if GTP_SLIDE_WAKEUP
-	if (DOZE_ENABLED == doze_status) {
-		ret = gtp_i2c_read(ts->client, doze_buf, 3);
-		if (ret > 0) {
-			if (doze_buf[2] == 0xAA) {
-				dev_dbg(&ts->client->dev,
-					"Slide(0xAA) To Light up the screen!");
-				doze_status = DOZE_WAKEUP;
-				input_report_key(
-					ts->input_dev, KEY_POWER, 1);
-				input_sync(ts->input_dev);
-				input_report_key(
-					ts->input_dev, KEY_POWER, 0);
-				input_sync(ts->input_dev);
-				/* clear 0x814B */
-				doze_buf[2] = 0x00;
-				gtp_i2c_write(ts->client, doze_buf, 3);
-			} else if (doze_buf[2] == 0xBB) {
-				dev_dbg(&ts->client->dev,
-					"Slide(0xBB) To Light up the screen!");
-				doze_status = DOZE_WAKEUP;
-				input_report_key(ts->input_dev, KEY_POWER, 1);
-				input_sync(ts->input_dev);
-				input_report_key(ts->input_dev, KEY_POWER, 0);
-				input_sync(ts->input_dev);
-				/* clear 0x814B*/
-				doze_buf[2] = 0x00;
-				gtp_i2c_write(ts->client, doze_buf, 3);
-			} else if (0xC0 == (doze_buf[2] & 0xC0)) {
-				dev_dbg(&ts->client->dev,
-					"double click to light up the screen!");
-				doze_status = DOZE_WAKEUP;
-				input_report_key(ts->input_dev, KEY_POWER, 1);
-				input_sync(ts->input_dev);
-				input_report_key(ts->input_dev, KEY_POWER, 0);
-				input_sync(ts->input_dev);
-				/* clear 0x814B */
-				doze_buf[2] = 0x00;
-				gtp_i2c_write(ts->client, doze_buf, 3);
-			} else {
-				gtp_enter_doze(ts);
+	if (ts->pdata->slide_wakeup) {
+		if (DOZE_ENABLED == doze_status) {
+			ret = gtp_i2c_read(ts->client, doze_buf, 3);
+			if (ret > 0) {
+				if (doze_buf[2] == 0xAA) {
+					dev_dbg(&ts->client->dev,
+						"Slide(0xAA) To Light up the screen!");
+					doze_status = DOZE_WAKEUP;
+					input_report_key(
+						ts->input_dev, KEY_POWER, 1);
+					input_sync(ts->input_dev);
+					input_report_key(
+						ts->input_dev, KEY_POWER, 0);
+					input_sync(ts->input_dev);
+					/* clear 0x814B */
+					doze_buf[2] = 0x00;
+					gtp_i2c_write(ts->client, doze_buf, 3);
+				} else if (doze_buf[2] == 0xBB) {
+					dev_dbg(&ts->client->dev,
+						"Slide(0xBB) To Light up the screen!");
+					doze_status = DOZE_WAKEUP;
+					input_report_key(ts->input_dev,
+								KEY_POWER, 1);
+					input_sync(ts->input_dev);
+					input_report_key(ts->input_dev,
+								KEY_POWER, 0);
+					input_sync(ts->input_dev);
+					/* clear 0x814B*/
+					doze_buf[2] = 0x00;
+					gtp_i2c_write(ts->client, doze_buf, 3);
+				} else if (0xC0 == (doze_buf[2] & 0xC0)) {
+					dev_dbg(&ts->client->dev,
+						"double click to light up the screen!");
+					doze_status = DOZE_WAKEUP;
+					input_report_key(ts->input_dev,
+								KEY_POWER, 1);
+					input_sync(ts->input_dev);
+					input_report_key(ts->input_dev,
+								KEY_POWER, 0);
+					input_sync(ts->input_dev);
+					/* clear 0x814B */
+					doze_buf[2] = 0x00;
+					gtp_i2c_write(ts->client, doze_buf, 3);
+				} else {
+					gtp_enter_doze(ts);
+				}
 			}
-		}
-		if (ts->use_irq)
-			gtp_irq_enable(ts);
+			if (ts->use_irq)
+				gtp_irq_enable(ts);
 
-		return;
+			return;
+		}
 	}
-#endif
 
 	ret = gtp_i2c_read(ts->client, point_data, 12);
 	if (ret < 0) {
@@ -514,15 +506,16 @@
 
 	pre_key = key_value;
 
-#if GTP_WITH_PEN
-	if (pre_pen && (touch_num == 0)) {
-		dev_dbg(&ts->client->dev, "Pen touch UP(Slot)!");
-		input_report_key(ts->input_dev, BTN_TOOL_PEN, 0);
-		input_mt_slot(ts->input_dev, 5);
-		input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
-		pre_pen = 0;
+	if (ts->pdata->with_pen) {
+		if (pre_pen && (touch_num == 0)) {
+			dev_dbg(&ts->client->dev, "Pen touch UP(Slot)!");
+			input_report_key(ts->input_dev, BTN_TOOL_PEN, 0);
+			input_mt_slot(ts->input_dev, 5);
+			input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
+			pre_pen = 0;
+		}
 	}
-#endif
+
 	if (pre_touch || touch_num) {
 		s32 pos = 0;
 		u16 touch_index = 0;
@@ -530,45 +523,45 @@
 		coor_data = &point_data[3];
 		if (touch_num) {
 			id = coor_data[pos] & 0x0F;
-#if GTP_WITH_PEN
-			id = coor_data[pos];
-			if (id == 128) {
-				dev_dbg(&ts->client->dev,
-						"Pen touch DOWN(Slot)!");
-				input_x  = coor_data[pos + 1]
-					| (coor_data[pos + 2] << 8);
-				input_y  = coor_data[pos + 3]
-					| (coor_data[pos + 4] << 8);
-				input_w  = coor_data[pos + 5]
-					| (coor_data[pos + 6] << 8);
+			if (ts->pdata->with_pen) {
+				id = coor_data[pos];
+				if (id == 128) {
+					dev_dbg(&ts->client->dev,
+							"Pen touch DOWN(Slot)!");
+					input_x  = coor_data[pos + 1]
+						| (coor_data[pos + 2] << 8);
+					input_y  = coor_data[pos + 3]
+						| (coor_data[pos + 4] << 8);
+					input_w  = coor_data[pos + 5]
+						| (coor_data[pos + 6] << 8);
 
-				input_report_key(ts->input_dev,
-					BTN_TOOL_PEN, 1);
-				input_mt_slot(ts->input_dev, 5);
-				input_report_abs(ts->input_dev,
-					ABS_MT_TRACKING_ID, 5);
-				input_report_abs(ts->input_dev,
-					ABS_MT_POSITION_X, input_x);
-				input_report_abs(ts->input_dev,
-					ABS_MT_POSITION_Y, input_y);
-				input_report_abs(ts->input_dev,
-					ABS_MT_TOUCH_MAJOR, input_w);
-				dev_dbg(&ts->client->dev,
-					"Pen/Stylus: (%d, %d)[%d]",
-					input_x, input_y, input_w);
-				pre_pen = 1;
-				pre_touch = 0;
+					input_report_key(ts->input_dev,
+						BTN_TOOL_PEN, 1);
+					input_mt_slot(ts->input_dev, 5);
+					input_report_abs(ts->input_dev,
+						ABS_MT_TRACKING_ID, 5);
+					input_report_abs(ts->input_dev,
+						ABS_MT_POSITION_X, input_x);
+					input_report_abs(ts->input_dev,
+						ABS_MT_POSITION_Y, input_y);
+					input_report_abs(ts->input_dev,
+						ABS_MT_TOUCH_MAJOR, input_w);
+					dev_dbg(&ts->client->dev,
+						"Pen/Stylus: (%d, %d)[%d]",
+						input_x, input_y, input_w);
+					pre_pen = 1;
+					pre_touch = 0;
+				}
 			}
-#endif
 
 			touch_index |= (0x01<<id);
 		}
 
 		for (i = 0; i < GTP_MAX_TOUCH; i++) {
-#if GTP_WITH_PEN
-			if (pre_pen == 1)
-				break;
-#endif
+			if (ts->pdata->with_pen)
+				if (pre_pen == 1)
+					break;
+
 			if (touch_index & (0x01<<i)) {
 				input_x = coor_data[pos + 1] |
 						coor_data[pos + 2] << 8;
@@ -673,7 +666,6 @@
 }
 
 #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_FB)
-#if GTP_SLIDE_WAKEUP
 /*******************************************************
 Function:
 	Enter doze mode for sliding wakeup.
@@ -690,9 +682,9 @@
 		(u8)(GTP_REG_SLEEP >> 8),
 		(u8)GTP_REG_SLEEP, 8};
 
-#if GTP_DBL_CLK_WAKEUP
-	i2c_control_buf[2] = 0x09;
-#endif
+	if (ts->pdata->dbl_clk_wakeup)
+		i2c_control_buf[2] = 0x09;
+
 	gtp_irq_disable(ts);
 
 	while (retry++ < GTP_I2C_RETRY_3) {
@@ -721,7 +713,6 @@
 	gtp_irq_enable(ts);
 	return ret;
 }
-#else
 /**
  * gtp_enter_sleep - Enter sleep mode
  * @ts: driver private data
@@ -767,7 +758,6 @@
 		return ret;
 	}
 }
-#endif /* !GTP_SLIDE_WAKEUP */
 
 /*******************************************************
 Function:
@@ -813,33 +803,33 @@
 				"Wakeup sleep send config success.");
 	} else {
 err_retry:
-#if GTP_SLIDE_WAKEUP
-		/* wakeup not by slide */
-		if (DOZE_WAKEUP != doze_status)
-			gtp_reset_guitar(ts, 10);
-		else
-			/* wakeup by slide */
-			doze_status = DOZE_DISABLED;
-#else
-		if (chip_gt9xxs == 1) {
-			gtp_reset_guitar(ts, 10);
+		if (ts->pdata->slide_wakeup) { /* wakeup not by slide */
+			if (DOZE_WAKEUP != doze_status)
+				gtp_reset_guitar(ts, 10);
+			else
+				/* wakeup by slide */
+				doze_status = DOZE_DISABLED;
 		} else {
-			ret = gpio_direction_output(ts->pdata->irq_gpio, 1);
-			usleep(5000);
+			if (chip_gt9xxs == 1) {
+				gtp_reset_guitar(ts, 10);
+			} else {
+				ret = gpio_direction_output(
+						ts->pdata->irq_gpio, 1);
+				usleep(5000);
+			}
 		}
-#endif
 		ret = gtp_i2c_test(ts->client);
 		if (ret == 2) {
 			dev_dbg(&ts->client->dev, "GTP wakeup sleep.");
-#if (!GTP_SLIDE_WAKEUP)
-			if (chip_gt9xxs == 0) {
-				gtp_int_sync(ts, 25);
-				msleep(20);
+			if (!ts->pdata->slide_wakeup) {
+				if (chip_gt9xxs == 0) {
+					gtp_int_sync(ts, 25);
+					msleep(20);
 #if GTP_ESD_PROTECT
-				gtp_init_ext_watchdog(ts->client);
+					gtp_init_ext_watchdog(ts->client);
 #endif
+				}
 			}
-#endif
 			return ret;
 		}
 		gtp_reset_guitar(ts, 20);
@@ -863,123 +853,126 @@
 static int gtp_init_panel(struct goodix_ts_data *ts)
 {
 	struct i2c_client *client = ts->client;
-	unsigned char *config_data;
+	unsigned char *config_data = NULL;
 	int ret = -EIO;
-
-#if GTP_DRIVER_SEND_CFG
 	int i;
 	u8 check_sum = 0;
 	u8 opr_buf[16];
 	u8 sensor_id = 0;
 
-	for (i = 0; i < GOODIX_MAX_CFG_GROUP; i++)
-		dev_dbg(&client->dev, "Config Groups(%d) Lengths: %d",
-			i, ts->pdata->config_data_len[i]);
+	if (ts->pdata->driver_send_cfg) {
+		for (i = 0; i < GOODIX_MAX_CFG_GROUP; i++)
+			dev_dbg(&client->dev, "Config Groups(%d) Lengths: %d",
+				i, ts->pdata->config_data_len[i]);
 
-	ret = gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1);
-	if (SUCCESS == ret) {
-		if (opr_buf[0] != 0xBE) {
-			ts->fw_error = 1;
+		ret = gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1);
+		if (SUCCESS == ret) {
+			if (opr_buf[0] != 0xBE) {
+				ts->fw_error = 1;
+				dev_err(&client->dev,
+					"Firmware error, no config sent!");
+				return -EINVAL;
+			}
+		}
+
+		for (i = 1; i < GOODIX_MAX_CFG_GROUP; i++) {
+			if (ts->pdata->config_data_len[i])
+				break;
+		}
+
+		if (i == GOODIX_MAX_CFG_GROUP) {
+			sensor_id = 0;
+		} else {
+			ret = gtp_i2c_read_dbl_check(ts->client,
+					GTP_REG_SENSOR_ID, &sensor_id, 1);
+			if (SUCCESS == ret) {
+				if (sensor_id >= GOODIX_MAX_CFG_GROUP) {
+					dev_err(&client->dev,
+						"Invalid sensor_id(0x%02X), No Config Sent!",
+						sensor_id);
+					return -EINVAL;
+				}
+			} else {
+				dev_err(&client->dev,
+					"Failed to get sensor_id, No config sent!");
+				return -EINVAL;
+			}
+		}
+
+		dev_info(&client->dev, "Sensor ID selected: %d", sensor_id);
+
+		if (ts->pdata->config_data_len[sensor_id] <
+			GTP_CONFIG_MIN_LENGTH ||
+			!ts->pdata->config_data[sensor_id]) {
 			dev_err(&client->dev,
-				"Firmware error, no config sent!");
+					"Sensor_ID(%d) matches with NULL or invalid config group!\n",
+					sensor_id);
 			return -EINVAL;
 		}
-	}
 
-	for (i = 1; i < GOODIX_MAX_CFG_GROUP; i++) {
-		if (ts->pdata->config_data_len[i])
-			break;
-	}
-	if (i == GOODIX_MAX_CFG_GROUP) {
-		sensor_id = 0;
-	} else {
-		ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_SENSOR_ID,
-			&sensor_id, 1);
-		if (SUCCESS == ret) {
-			if (sensor_id >= GOODIX_MAX_CFG_GROUP) {
-				dev_err(&client->dev,
-					"Invalid sensor_id(0x%02X), No Config Sent!",
-					sensor_id);
-				return -EINVAL;
+		ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA,
+			&opr_buf[0], 1);
+		if (ret == SUCCESS) {
+			if (opr_buf[0] < 90) {
+				/* backup group config version */
+				grp_cfg_version =
+				ts->pdata->
+					config_data[sensor_id][GTP_ADDR_LENGTH];
+				ts->pdata->
+					config_data[sensor_id][GTP_ADDR_LENGTH]
+						= 0x00;
+				ts->fixed_cfg = 0;
+			} else {
+				/* treated as fixed config, not send config */
+				dev_warn(&client->dev,
+					"Ic fixed config with config version(%d, 0x%02X)",
+					opr_buf[0], opr_buf[0]);
+				ts->fixed_cfg = 1;
 			}
 		} else {
 			dev_err(&client->dev,
-				"Failed to get sensor_id, No config sent!");
+				"Failed to get ic config version!No config sent!");
 			return -EINVAL;
 		}
-	}
 
-	dev_info(&client->dev, "Sensor ID selected: %d", sensor_id);
-
-	if (ts->pdata->config_data_len[sensor_id] < GTP_CONFIG_MIN_LENGTH ||
-		!ts->pdata->config_data[sensor_id]) {
-		dev_err(&client->dev,
-				"Sensor_ID(%d) matches with NULL or invalid config group!\n",
-				sensor_id);
-		return -EINVAL;
-	}
-
-	ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA,
-		&opr_buf[0], 1);
-	if (ret == SUCCESS) {
-		if (opr_buf[0] < 90) {
-			/* backup group config version */
-			grp_cfg_version =
-			ts->pdata->config_data[sensor_id][GTP_ADDR_LENGTH];
-			ts->pdata->config_data[sensor_id][GTP_ADDR_LENGTH] =
-				0x00;
-			ts->fixed_cfg = 0;
-		} else {
-			/* treated as fixed config, not send config */
-			dev_warn(&client->dev,
-				"Ic fixed config with config version(%d, 0x%02X)",
-				opr_buf[0], opr_buf[0]);
-			ts->fixed_cfg = 1;
-		}
-	} else {
-		dev_err(&client->dev,
-			"Failed to get ic config version!No config sent!");
-		return -EINVAL;
-	}
-
-	config_data = ts->pdata->config_data[sensor_id];
-	ts->config_data = ts->pdata->config_data[sensor_id];
-	ts->gtp_cfg_len = ts->pdata->config_data_len[sensor_id];
+		config_data = ts->pdata->config_data[sensor_id];
+		ts->config_data = ts->pdata->config_data[sensor_id];
+		ts->gtp_cfg_len = ts->pdata->config_data_len[sensor_id];
 
 #if GTP_CUSTOM_CFG
-	config_data[RESOLUTION_LOC] =
-	(unsigned char)(GTP_MAX_WIDTH && 0xFF);
-	config_data[RESOLUTION_LOC + 1] =
-	(unsigned char)(GTP_MAX_WIDTH >> 8);
-	config_data[RESOLUTION_LOC + 2] =
-	(unsigned char)(GTP_MAX_HEIGHT && 0xFF);
-	config_data[RESOLUTION_LOC + 3] =
-	(unsigned char)(GTP_MAX_HEIGHT >> 8);
+		config_data[RESOLUTION_LOC] =
+		(unsigned char)(GTP_MAX_WIDTH && 0xFF);
+		config_data[RESOLUTION_LOC + 1] =
+		(unsigned char)(GTP_MAX_WIDTH >> 8);
+		config_data[RESOLUTION_LOC + 2] =
+		(unsigned char)(GTP_MAX_HEIGHT && 0xFF);
+		config_data[RESOLUTION_LOC + 3] =
+		(unsigned char)(GTP_MAX_HEIGHT >> 8);
 
-	if (GTP_INT_TRIGGER == 0)
-		config_data[TRIGGER_LOC] &= 0xfe;
-	else if (GTP_INT_TRIGGER == 1)
-		config_data[TRIGGER_LOC] |= 0x01;
+		if (GTP_INT_TRIGGER == 0)
+			config_data[TRIGGER_LOC] &= 0xfe;
+		else if (GTP_INT_TRIGGER == 1)
+			config_data[TRIGGER_LOC] |= 0x01;
 #endif  /* !GTP_CUSTOM_CFG */
 
-	check_sum = 0;
-	for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++)
-		check_sum += config_data[i];
+		check_sum = 0;
+		for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++)
+			check_sum += config_data[i];
 
-	config_data[ts->gtp_cfg_len] = (~check_sum) + 1;
+		config_data[ts->gtp_cfg_len] = (~check_sum) + 1;
 
-#else /* DRIVER NOT SEND CONFIG */
-	ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH;
-	ret = gtp_i2c_read(ts->client, config_data,
+	} else { /* DRIVER NOT SEND CONFIG */
+		ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH;
+		ret = gtp_i2c_read(ts->client, config_data,
 			ts->gtp_cfg_len + GTP_ADDR_LENGTH);
-	if (ret < 0) {
-		dev_err(&client->dev,
+		if (ret < 0) {
+			dev_err(&client->dev,
 				"Read Config Failed, Using DEFAULT Resolution & INT Trigger!\n");
-		ts->abs_x_max = GTP_MAX_WIDTH;
-		ts->abs_y_max = GTP_MAX_HEIGHT;
-		ts->int_trigger_type = GTP_INT_TRIGGER;
-	}
-#endif /* !DRIVER NOT SEND CONFIG */
+			ts->abs_x_max = GTP_MAX_WIDTH;
+			ts->abs_y_max = GTP_MAX_HEIGHT;
+			ts->int_trigger_type = GTP_INT_TRIGGER;
+		}
+	} /* !DRIVER NOT SEND CONFIG */
 
 	if ((ts->abs_x_max == 0) && (ts->abs_y_max == 0)) {
 		ts->abs_x_max = (config_data[RESOLUTION_LOC + 1] << 8)
@@ -1213,9 +1206,7 @@
 {
 	int ret;
 	char phys[PHY_BUF_SIZE];
-#if GTP_HAVE_TOUCH_KEY
 	int index = 0;
-#endif
 
 	ts->input_dev = input_allocate_device();
 	if (ts->input_dev == NULL) {
@@ -1230,27 +1221,24 @@
 	__set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
 	input_mt_init_slots(ts->input_dev, 10);/* in case of "out of memory" */
 
-
-	for (index = 0; index < ts->pdata->num_button; index++) {
-		input_set_capability(ts->input_dev,
+	if (ts->pdata->have_touch_key) {
+		for (index = 0; index < ts->pdata->num_button; index++) {
+			input_set_capability(ts->input_dev,
 				EV_KEY, ts->pdata->button_map[index]);
+		}
 	}
 
+	if (ts->pdata->slide_wakeup)
+		input_set_capability(ts->input_dev, EV_KEY, KEY_POWER);
 
-#if GTP_SLIDE_WAKEUP
-	input_set_capability(ts->input_dev, EV_KEY, KEY_POWER);
-#endif
+	if (ts->pdata->with_pen) {  /* pen support */
+		__set_bit(BTN_TOOL_PEN, ts->input_dev->keybit);
+		__set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
+		__set_bit(INPUT_PROP_POINTER, ts->input_dev->propbit);
+	}
 
-#if GTP_WITH_PEN
-	/* pen support */
-	__set_bit(BTN_TOOL_PEN, ts->input_dev->keybit);
-	__set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
-	__set_bit(INPUT_PROP_POINTER, ts->input_dev->propbit);
-#endif
-
-#if GTP_CHANGE_X2Y
-	swap(ts->abs_x_max, ts->abs_y_max);
-#endif
+	if (ts->pdata->change_x2y)
+		swap(ts->abs_x_max, ts->abs_y_max);
 
 	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
 				0, ts->abs_x_max, 0, 0);
@@ -1850,6 +1838,25 @@
 
 	pdata->enable_power_off = of_property_read_bool(np,
 						"goodix,enable-power-off");
+
+	pdata->have_touch_key = of_property_read_bool(np,
+						"goodix,have-touch-key");
+
+	pdata->driver_send_cfg = of_property_read_bool(np,
+						"goodix,driver-send-cfg");
+
+	pdata->change_x2y = of_property_read_bool(np,
+						"goodix,change-x2y");
+
+	pdata->with_pen = of_property_read_bool(np,
+						"goodix,with-pen");
+
+	pdata->slide_wakeup = of_property_read_bool(np,
+						"goodix,slide-wakeup");
+
+	pdata->dbl_clk_wakeup = of_property_read_bool(np,
+						"goodix,dbl_clk_wakeup");
+
 	/* reset, irq gpio info */
 	pdata->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios",
 				0, &pdata->reset_gpio_flags);
@@ -2113,8 +2120,6 @@
 #endif
 	if (ts->use_irq)
 		free_irq(client->irq, ts);
-	else
-		hrtimer_cancel(&ts->timer);
 	cancel_work_sync(&ts->work);
 	flush_workqueue(ts->goodix_wq);
 	destroy_workqueue(ts->goodix_wq);
@@ -2178,8 +2183,6 @@
 	if (ts) {
 		if (ts->use_irq)
 			free_irq(client->irq, ts);
-		else
-			hrtimer_cancel(&ts->timer);
 
 		cancel_work_sync(&ts->work);
 		flush_workqueue(ts->goodix_wq);
@@ -2237,23 +2240,21 @@
 	gtp_esd_switch(ts->client, SWITCH_OFF);
 #endif
 
-#if GTP_SLIDE_WAKEUP
-	ret = gtp_enter_doze(ts);
-#else
-	if (ts->use_irq)
-		gtp_irq_disable(ts);
-	else
-		hrtimer_cancel(&ts->timer);
+	if (ts->pdata->slide_wakeup) {
+		ret = gtp_enter_doze(ts);
+	} else {
+		if (ts->use_irq)
+			gtp_irq_disable(ts);
 
-	for (i = 0; i < GTP_MAX_TOUCH; i++)
-		gtp_touch_up(ts, i);
+		for (i = 0; i < GTP_MAX_TOUCH; i++)
+			gtp_touch_up(ts, i);
 
-	input_sync(ts->input_dev);
+		input_sync(ts->input_dev);
 
-	ret = gtp_enter_sleep(ts);
-#endif
-	if (ret < 0)
-		dev_err(&ts->client->dev, "GTP early suspend failed.\n");
+		ret = gtp_enter_sleep(ts);
+		if (ret < 0)
+			dev_err(&ts->client->dev, "GTP early suspend failed.\n");
+	}
 	/* to avoid waking up while not sleeping,
 	 * delay 48 + 10ms to ensure reliability
 	 */
@@ -2285,18 +2286,14 @@
 	mutex_lock(&ts->lock);
 	ret = gtp_wakeup_sleep(ts);
 
-#if GTP_SLIDE_WAKEUP
-	doze_status = DOZE_DISABLED;
-#endif
+	if (ts->pdata->slide_wakeup)
+		doze_status = DOZE_DISABLED;
 
 	if (ret <= 0)
 		dev_err(&ts->client->dev, "GTP resume failed.\n");
 
 	if (ts->use_irq)
 		gtp_irq_enable(ts);
-	else
-		hrtimer_start(&ts->timer,
-			ktime_set(1, 0), HRTIMER_MODE_REL);
 
 #if GTP_ESD_PROTECT
 	gtp_esd_switch(ts->client, SWITCH_ON);
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.h b/drivers/input/touchscreen/gt9xx/gt9xx.h
index 0ba6895..3cedf26 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.h
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.h
@@ -63,6 +63,12 @@
 	u8 *config_data[GOODIX_MAX_CFG_GROUP];
 	u32 button_map[MAX_BUTTONS];
 	u8 num_button;
+	bool have_touch_key;
+	bool driver_send_cfg;
+	bool change_x2y;
+	bool with_pen;
+	bool slide_wakeup;
+	bool dbl_clk_wakeup;
 };
 struct goodix_ts_data {
 	spinlock_t irq_lock;
@@ -111,16 +117,7 @@
 
 /***************************PART1:ON/OFF define*******************************/
 #define GTP_CUSTOM_CFG			0
-#define GTP_CHANGE_X2Y			0
-#define GTP_DRIVER_SEND_CFG		1
-#define GTP_HAVE_TOUCH_KEY		1
 #define GTP_ESD_PROTECT			0
-#define GTP_WITH_PEN			0
-
-/* This cannot work when enable-power-off is on */
-#define GTP_SLIDE_WAKEUP		0
-/* double-click wakeup, function together with GTP_SLIDE_WAKEUP */
-#define GTP_DBL_CLK_WAKEUP		0
 
 #define GTP_IRQ_TAB            {\
 				IRQ_TYPE_EDGE_RISING,\
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index 9208599..d87520f 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -619,7 +619,7 @@
 		for (i = 0; i < num_wled_strings; i++) {
 			rc = qpnp_led_masked_write(led,
 				WLED_FULL_SCALE_REG(led->base, i),
-				WLED_MAX_CURR_MASK, led->max_current);
+				WLED_MAX_CURR_MASK, (u8)led->max_current);
 			if (rc) {
 				dev_err(&led->spmi_dev->dev,
 					"Write max current failure (%d)\n",
@@ -689,7 +689,8 @@
 
 static int qpnp_mpp_set(struct qpnp_led_data *led)
 {
-	int rc, val;
+	int rc;
+	u8 val;
 	int duty_us;
 
 	if (led->cdev.brightness) {
@@ -1604,7 +1605,7 @@
 
 		rc = qpnp_led_masked_write(led,
 			WLED_FULL_SCALE_REG(led->base, i), WLED_MAX_CURR_MASK,
-			led->max_current);
+			(u8)led->max_current);
 		if (rc) {
 			dev_err(&led->spmi_dev->dev,
 				"WLED max current reg write failed(%d)\n", rc);
@@ -2445,8 +2446,8 @@
 
 static int __devinit qpnp_mpp_init(struct qpnp_led_data *led)
 {
-	int rc, val;
-
+	int rc;
+	u8 val;
 
 	if (led->max_current < LED_MPP_CURRENT_MIN ||
 		led->max_current > LED_MPP_CURRENT_MAX) {
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 10f122a..67df573 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -237,6 +237,23 @@
 
 	  If unsure, say N.
 
+config DM_REQ_CRYPT
+	tristate "Crypt target support"
+	depends on BLK_DEV_DM
+	select XTS
+	select CRYPTO_XTS
+	---help---
+	  This request based device-mapper target allows you to create a device that
+	  transparently encrypts the data on it. You'll need to activate
+	  the ciphers you're going to use in the cryptoapi configuration.
+          The DM REQ CRYPT operates on requests (bigger payloads) to utilize 
+          crypto hardware better.	  
+
+	  To compile this code as a module, choose M here: the module will
+	  be called dm-req-crypt.
+
+	  If unsure, say N.
+	  
 config DM_SNAPSHOT
        tristate "Snapshot target"
        depends on BLK_DEV_DM
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index 8b2e0df..7b16079 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -43,7 +43,7 @@
 obj-$(CONFIG_DM_RAID)	+= dm-raid.o
 obj-$(CONFIG_DM_THIN_PROVISIONING)	+= dm-thin-pool.o
 obj-$(CONFIG_DM_VERITY)		+= dm-verity.o
-
+obj-$(CONFIG_DM_REQ_CRYPT)		+= dm-req-crypt.o
 ifeq ($(CONFIG_DM_UEVENT),y)
 dm-mod-objs			+= dm-uevent.o
 endif
diff --git a/drivers/md/dm-req-crypt.c b/drivers/md/dm-req-crypt.c
new file mode 100644
index 0000000..16141b5
--- /dev/null
+++ b/drivers/md/dm-req-crypt.c
@@ -0,0 +1,752 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/completion.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/bio.h>
+#include <linux/blkdev.h>
+#include <linux/mempool.h>
+#include <linux/slab.h>
+#include <linux/crypto.h>
+#include <linux/workqueue.h>
+#include <linux/backing-dev.h>
+#include <linux/atomic.h>
+#include <linux/scatterlist.h>
+#include <crypto/scatterwalk.h>
+#include <asm/page.h>
+#include <asm/unaligned.h>
+#include <crypto/hash.h>
+#include <crypto/md5.h>
+#include <crypto/algapi.h>
+#include <mach/qcrypto.h>
+
+#include <linux/device-mapper.h>
+
+
+#define DM_MSG_PREFIX "req-crypt"
+
+#define MAX_SG_LIST	1024
+#define REQ_DM_512_KB (512*1024)
+#define MAX_ENCRYPTION_BUFFERS 1
+#define MIN_IOS 16
+#define MIN_POOL_PAGES 32
+#define KEY_SIZE_XTS 32
+#define AES_XTS_IV_LEN 16
+
+#define DM_REQ_CRYPT_ERROR -1
+
+struct req_crypt_result {
+	struct completion completion;
+	int err;
+};
+
+struct dm_dev *dev;
+static struct kmem_cache *_req_crypt_io_pool;
+sector_t start_sector_orig;
+struct workqueue_struct *req_crypt_queue;
+mempool_t *req_io_pool;
+mempool_t *req_page_pool;
+struct crypto_ablkcipher *tfm;
+
+struct req_dm_crypt_io {
+	struct work_struct work;
+	struct request *cloned_request;
+	int error;
+	atomic_t pending;
+	struct timespec start_time;
+};
+
+static void req_crypt_cipher_complete
+		(struct crypto_async_request *req, int err);
+
+
+static void req_crypt_inc_pending(struct req_dm_crypt_io *io)
+{
+	atomic_inc(&io->pending);
+}
+
+static void req_crypt_dec_pending_encrypt(struct req_dm_crypt_io *io)
+{
+	int error = 0;
+	struct request *clone = NULL;
+
+	if (io) {
+		error = io->error;
+		if (io->cloned_request) {
+			clone = io->cloned_request;
+		} else {
+			DMERR("%s io->cloned_request is NULL\n",
+								__func__);
+			/*
+			 * If Clone is NULL we cannot do anything,
+			 * this should never happen
+			 */
+			BUG();
+		}
+	} else {
+		DMERR("%s io is NULL\n", __func__);
+		/*
+		 * If Clone is NULL we cannot do anything,
+		 * this should never happen
+		 */
+		BUG();
+	}
+
+	atomic_dec(&io->pending);
+
+	if (error < 0)
+		dm_kill_unmapped_request(clone, error);
+	else
+		dm_dispatch_request(clone);
+}
+
+static void req_crypt_dec_pending_decrypt(struct req_dm_crypt_io *io)
+{
+	int error = 0;
+	struct request *clone = NULL;
+
+	if (io) {
+		error = io->error;
+		if (io->cloned_request) {
+			clone = io->cloned_request;
+		} else {
+			DMERR("%s io->cloned_request is NULL\n",
+								__func__);
+			/*
+			 * If Clone is NULL we cannot do anything,
+			 * this should never happen
+			 */
+			BUG();
+		}
+	} else {
+		DMERR("%s io is NULL\n",
+							__func__);
+		/*
+		 * If Clone is NULL we cannot do anything,
+		 * this should never happen
+		 */
+		BUG();
+	}
+
+	/* Should never get here if io or Clone is NULL */
+	dm_end_request(clone, error);
+	atomic_dec(&io->pending);
+	mempool_free(io, req_io_pool);
+}
+
+/*
+ * The callback that will be called by the worker queue to perform Decryption
+ * for reads and use the dm function to complete the bios and requests.
+ */
+static void req_cryptd_crypt_read_convert(struct req_dm_crypt_io *io)
+{
+	struct request *clone = NULL;
+	int error = 0;
+	int total_sg_len = 0, rc = 0, total_bytes_in_req = 0;
+	struct ablkcipher_request *req = NULL;
+	struct req_crypt_result result;
+	struct scatterlist *req_sg_read = NULL;
+	int err = 0;
+	struct req_iterator iter2;
+	struct bio_vec *bvec = NULL;
+	u8 IV[AES_XTS_IV_LEN];
+
+	if (io) {
+		error = io->error;
+		if (io->cloned_request) {
+			clone = io->cloned_request;
+		} else {
+			DMERR("%s io->cloned_request is NULL\n",
+								__func__);
+			error = DM_REQ_CRYPT_ERROR;
+			goto submit_request;
+		}
+	} else {
+		DMERR("%s io is NULL\n",
+							__func__);
+		error = DM_REQ_CRYPT_ERROR;
+		goto submit_request;
+	}
+
+	req_crypt_inc_pending(io);
+
+	if (error != 0) {
+		err = error;
+		goto submit_request;
+	}
+
+	req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
+	if (!req) {
+		DMERR("%s ablkcipher request allocation failed\n", __func__);
+		err = DM_REQ_CRYPT_ERROR;
+		goto ablkcipher_req_alloc_failure;
+	}
+
+	ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+					req_crypt_cipher_complete, &result);
+	init_completion(&result.completion);
+	qcrypto_cipher_set_flag(req,
+		QCRYPTO_CTX_USE_PIPE_KEY | QCRYPTO_CTX_XTS_DU_SIZE_512B);
+	crypto_ablkcipher_clear_flags(tfm, ~0);
+	crypto_ablkcipher_setkey(tfm, NULL, KEY_SIZE_XTS);
+
+	req_sg_read = kzalloc(sizeof(struct scatterlist) *
+			MAX_SG_LIST, GFP_KERNEL);
+	if (!req_sg_read) {
+		DMERR("%s req_sg_read allocation failed\n",
+						__func__);
+		err = DM_REQ_CRYPT_ERROR;
+		goto ablkcipher_req_alloc_failure;
+	}
+
+	total_sg_len = blk_rq_map_sg(clone->q, clone, req_sg_read);
+	if ((total_sg_len <= 0) || (total_sg_len > MAX_SG_LIST)) {
+		DMERR("%s Request Error%d", __func__, total_sg_len);
+		err = DM_REQ_CRYPT_ERROR;
+		goto ablkcipher_req_alloc_failure;
+	}
+
+
+	/* total bytes to copy */
+	bvec = NULL;
+	rq_for_each_segment(bvec, clone, iter2) {
+		total_bytes_in_req = total_bytes_in_req + bvec->bv_len;
+	}
+
+	memset(IV, 0, AES_XTS_IV_LEN);
+	memcpy(IV, &clone->__sector, sizeof(sector_t));
+
+	ablkcipher_request_set_crypt(req, req_sg_read, req_sg_read,
+			total_bytes_in_req, (void *) IV);
+
+	rc = crypto_ablkcipher_decrypt(req);
+
+	switch (rc) {
+	case 0:
+		break;
+
+	case -EBUSY:
+		/*
+		 * Lets make this synchronous request by waiting on
+		 * in progress as well
+		 */
+	case -EINPROGRESS:
+		wait_for_completion_io(&result.completion);
+		if (result.err) {
+			DMERR("%s error = %d encrypting the request\n",
+				 __func__, result.err);
+			err = DM_REQ_CRYPT_ERROR;
+		}
+		break;
+
+	default:
+		err = DM_REQ_CRYPT_ERROR;
+		break;
+	}
+
+ablkcipher_req_alloc_failure:
+
+	if (req)
+		ablkcipher_request_free(req);
+
+	kfree(req_sg_read);
+
+submit_request:
+	io->error = err;
+	req_crypt_dec_pending_decrypt(io);
+}
+
+/*
+ * The callback that will be called by the worker queue to perform Encryption
+ * for writes and submit the request using the elevelator.
+ */
+static void req_cryptd_crypt_write_convert(struct req_dm_crypt_io *io)
+{
+	struct request *clone = NULL;
+	struct bio *bio_src = NULL;
+	unsigned int total_sg_len_req_in = 0, total_sg_len_req_out = 0,
+		total_bytes_in_req = 0, error = DM_MAPIO_REMAPPED, rc = 0;
+	struct req_iterator iter;
+	struct ablkcipher_request *req = NULL;
+	struct req_crypt_result result;
+	struct bio_vec *bvec = NULL;
+	struct scatterlist *req_sg_in = NULL;
+	struct scatterlist *req_sg_out = NULL;
+	int copy_bio_sector_to_req = 0;
+	gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
+	struct page *page = NULL;
+	u8 IV[AES_XTS_IV_LEN];
+	int remaining_size = 0;
+
+	if (io) {
+		if (io->cloned_request) {
+			clone = io->cloned_request;
+		} else {
+			DMERR("%s io->cloned_request is NULL\n",
+								__func__);
+			error = DM_REQ_CRYPT_ERROR;
+			goto submit_request;
+		}
+	} else {
+		DMERR("%s io is NULL\n",
+							__func__);
+		error = DM_REQ_CRYPT_ERROR;
+		goto submit_request;
+	}
+
+	req_crypt_inc_pending(io);
+
+	req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
+	if (!req) {
+		DMERR("%s ablkcipher request allocation failed\n",
+					__func__);
+		error = DM_REQ_CRYPT_ERROR;
+		goto ablkcipher_req_alloc_failure;
+	}
+
+	ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+				req_crypt_cipher_complete, &result);
+
+	init_completion(&result.completion);
+	qcrypto_cipher_set_flag(req,
+		QCRYPTO_CTX_USE_PIPE_KEY | QCRYPTO_CTX_XTS_DU_SIZE_512B);
+	crypto_ablkcipher_clear_flags(tfm, ~0);
+	crypto_ablkcipher_setkey(tfm, NULL, KEY_SIZE_XTS);
+
+	req_sg_in = kzalloc(sizeof(struct scatterlist) * MAX_SG_LIST,
+			GFP_KERNEL);
+	if (!req_sg_in) {
+		DMERR("%s req_sg_in allocation failed\n",
+					__func__);
+		error = DM_REQ_CRYPT_ERROR;
+		goto ablkcipher_req_alloc_failure;
+	}
+
+	req_sg_out = kzalloc(sizeof(struct scatterlist) * MAX_SG_LIST,
+			GFP_KERNEL);
+	if (!req_sg_out) {
+		DMERR("%s req_sg_out allocation failed\n",
+					__func__);
+		error = DM_REQ_CRYPT_ERROR;
+		goto ablkcipher_req_alloc_failure;
+	}
+
+	total_sg_len_req_in = blk_rq_map_sg(clone->q, clone, req_sg_in);
+	if ((total_sg_len_req_in <= 0) ||
+			(total_sg_len_req_in > MAX_SG_LIST)) {
+		DMERR("%s Request Error%d", __func__, total_sg_len_req_in);
+		error = DM_REQ_CRYPT_ERROR;
+		goto ablkcipher_req_alloc_failure;
+	}
+
+
+	rq_for_each_segment(bvec, clone, iter) {
+try_again:
+		if (bvec->bv_len > remaining_size) {
+			page = NULL;
+		page = mempool_alloc(req_page_pool, gfp_mask);
+		if (!page) {
+			DMERR("%s Crypt page alloc failed", __func__);
+			congestion_wait(BLK_RW_ASYNC, HZ/100);
+			goto try_again;
+			}
+			bvec->bv_page = page;
+			bvec->bv_offset = 0;
+			total_bytes_in_req = total_bytes_in_req + bvec->bv_len;
+			remaining_size = PAGE_SIZE -  bvec->bv_len;
+			if (remaining_size < 0)
+				BUG();
+		} else {
+			bvec->bv_page = page;
+			bvec->bv_offset = PAGE_SIZE - remaining_size;
+			remaining_size = remaining_size -  bvec->bv_len;
+			total_bytes_in_req = total_bytes_in_req + bvec->bv_len;
+		}
+	}
+
+	total_sg_len_req_out = blk_rq_map_sg(clone->q, clone, req_sg_out);
+	if ((total_sg_len_req_out <= 0) ||
+			(total_sg_len_req_out > MAX_SG_LIST)) {
+		DMERR("%s Request Error %d", __func__, total_sg_len_req_out);
+		error = DM_REQ_CRYPT_ERROR;
+		goto ablkcipher_req_alloc_failure;
+	}
+
+	memset(IV, 0, AES_XTS_IV_LEN);
+	memcpy(IV, &clone->__sector, sizeof(sector_t));
+
+	ablkcipher_request_set_crypt(req, req_sg_in, req_sg_out,
+			total_bytes_in_req, (void *) IV);
+
+	rc = crypto_ablkcipher_encrypt(req);
+
+	switch (rc) {
+	case 0:
+		break;
+
+	case -EBUSY:
+		/*
+		 * Lets make this synchronous request by waiting on
+		 * in progress as well
+		 */
+	case -EINPROGRESS:
+		wait_for_completion_interruptible(&result.completion);
+		if (result.err) {
+			DMERR("%s error = %d encrypting the request\n",
+				 __func__, result.err);
+			error = DM_REQ_CRYPT_ERROR;
+			goto ablkcipher_req_alloc_failure;
+		}
+		break;
+
+	default:
+		error = DM_REQ_CRYPT_ERROR;
+		goto ablkcipher_req_alloc_failure;
+	}
+
+	__rq_for_each_bio(bio_src, clone) {
+		if (copy_bio_sector_to_req == 0) {
+			clone->buffer = bio_data(bio_src);
+			copy_bio_sector_to_req++;
+		}
+		blk_queue_bounce(clone->q, &bio_src);
+	}
+
+
+ablkcipher_req_alloc_failure:
+	if (req)
+		ablkcipher_request_free(req);
+
+
+	kfree(req_sg_in);
+
+	kfree(req_sg_out);
+
+submit_request:
+	io->error = error;
+	req_crypt_dec_pending_encrypt(io);
+}
+
+/* Queue callback function that will get triggered */
+static void req_cryptd_crypt(struct work_struct *work)
+{
+	struct req_dm_crypt_io *io =
+			container_of(work, struct req_dm_crypt_io, work);
+
+	if (rq_data_dir(io->cloned_request) == WRITE)
+		req_cryptd_crypt_write_convert(io);
+	else if (rq_data_dir(io->cloned_request) == READ)
+		req_cryptd_crypt_read_convert(io);
+	else
+		DMERR("%s received non-write request for Clone %u\n",
+				__func__, (unsigned int)io->cloned_request);
+}
+
+static void req_cryptd_queue_crypt(struct req_dm_crypt_io *io)
+{
+	INIT_WORK(&io->work, req_cryptd_crypt);
+	queue_work(req_crypt_queue, &io->work);
+}
+
+/*
+ * Cipher complete callback, this is triggered by the Linux crypto api once
+ * the operation is done. This signals the waiting thread that the crypto
+ * operation is complete.
+ */
+static void req_crypt_cipher_complete(struct crypto_async_request *req, int err)
+{
+	struct req_crypt_result *res = req->data;
+
+	if (err == -EINPROGRESS)
+		return;
+
+	res->err = err;
+	complete(&res->completion);
+}
+
+/*
+ * If bio->bi_dev is a partition, remap the location
+ */
+static inline void req_crypt_blk_partition_remap(struct bio *bio)
+{
+	struct block_device *bdev = bio->bi_bdev;
+
+	if (bio_sectors(bio) && bdev != bdev->bd_contains) {
+		struct hd_struct *p = bdev->bd_part;
+
+		bio->bi_sector += p->start_sect;
+		bio->bi_bdev = bdev->bd_contains;
+	}
+}
+
+/*
+ * The endio function is called from ksoftirqd context (atomic).
+ * For write operations the new pages created form the mempool
+ * is freed and returned.  * For read operations, decryption is
+ * required, since this is called in a atomic  * context, the
+ * request is sent to a worker queue to complete decryptiona and
+ * free the request once done.
+ */
+static int req_crypt_endio(struct dm_target *ti, struct request *clone,
+			    int error, union map_info *map_context)
+{
+	int err = 0;
+	struct req_iterator iter1;
+	struct bio_vec *bvec = NULL;
+	struct req_dm_crypt_io *req_io = map_context->ptr;
+
+	/* If it is a write request, do nothing just return. */
+	bvec = NULL;
+	if (rq_data_dir(clone) == WRITE) {
+		rq_for_each_segment(bvec, clone, iter1) {
+			if (bvec->bv_offset == 0) {
+				mempool_free(bvec->bv_page, req_page_pool);
+				bvec->bv_page = NULL;
+			} else
+				bvec->bv_page = NULL;
+		}
+		mempool_free(req_io, req_io_pool);
+		goto submit_request;
+	} else if (rq_data_dir(clone) == READ) {
+		req_io->error = error;
+		req_cryptd_queue_crypt(req_io);
+		err = DM_ENDIO_INCOMPLETE;
+		goto submit_request;
+	}
+
+submit_request:
+	return err;
+}
+
+/*
+ * This function is called with interrupts disabled
+ * The function remaps the clone for the underlying device.
+ * If it is a write request, it calls into the worker queue to
+ * encrypt the data
+ * and submit the request directly using the elevator
+ * For a read request no pre-processing is required the request
+ * is returned to dm once mapping is done
+ */
+
+static int req_crypt_map(struct dm_target *ti, struct request *clone,
+			 union map_info *map_context)
+{
+	struct req_dm_crypt_io *req_io = NULL;
+	int error = DM_MAPIO_REMAPPED, copy_bio_sector_to_req = 0;
+	struct bio *bio_src = NULL;
+
+	req_io = mempool_alloc(req_io_pool, GFP_NOWAIT);
+	if (!req_io) {
+		DMERR("%s req_io allocation failed\n", __func__);
+		error = DM_REQ_CRYPT_ERROR;
+		goto submit_request;
+	}
+
+	/* Save the clone in the req_io, the callback to the worker
+	 * queue will get the req_io
+	 */
+	req_io->cloned_request = clone;
+	map_context->ptr = req_io;
+	atomic_set(&req_io->pending, 0);
+
+	/* Get the queue of the underlying original device */
+	clone->q = bdev_get_queue(dev->bdev);
+	clone->rq_disk = dev->bdev->bd_disk;
+
+	__rq_for_each_bio(bio_src, clone) {
+		bio_src->bi_bdev = dev->bdev;
+		/* Currently the way req-dm works is that once the underlying
+		 * device driver completes the request by calling into the
+		 * block layer. The block layer completes the bios (clones) and
+		 * then the cloned request. This is undesirable for req-dm-crypt
+		 * hence added a flag BIO_DONTFREE, this flag will ensure that
+		 * blk layer does not complete the cloned bios before completing
+		 * the request. When the crypt endio is called, post-processsing
+		 * is done and then the dm layer will complete the bios (clones)
+		 * and free them.
+		 */
+		bio_src->bi_flags |= 1 << BIO_DONTFREE;
+
+		/*
+		 * If this device has partitions, remap block n
+		 * of partition p to block n+start(p) of the disk.
+		 */
+		req_crypt_blk_partition_remap(bio_src);
+		if (copy_bio_sector_to_req == 0) {
+			clone->__sector = bio_src->bi_sector;
+			clone->buffer = bio_data(bio_src);
+			copy_bio_sector_to_req++;
+		}
+		blk_queue_bounce(clone->q, &bio_src);
+	}
+
+	if (rq_data_dir(clone) == READ) {
+		error = DM_MAPIO_REMAPPED;
+		goto submit_request;
+	} else if (rq_data_dir(clone) == WRITE) {
+		req_cryptd_queue_crypt(req_io);
+		error = DM_MAPIO_SUBMITTED;
+		goto submit_request;
+	} else {
+		error = DM_REQ_CRYPT_ERROR;
+		DMERR("%s Unknown request\n", __func__);
+	}
+
+submit_request:
+	return error;
+
+}
+
+static int req_crypt_status(struct dm_target *ti, status_type_t type,
+			char *result, unsigned maxlen)
+{
+	return 0;
+}
+
+static void req_crypt_dtr(struct dm_target *ti)
+{
+	if (req_crypt_queue)
+		destroy_workqueue(req_crypt_queue);
+	if (req_io_pool)
+		mempool_destroy(req_io_pool);
+	if (req_page_pool)
+		mempool_destroy(req_page_pool);
+	if (tfm)
+		crypto_free_ablkcipher(tfm);
+}
+
+
+/*
+ * Construct an encryption mapping:
+ * <cipher> <key> <iv_offset> <dev_path> <start>
+ */
+static int req_crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+{
+	unsigned long long tmpll;
+	char dummy;
+
+	if (dm_get_device(ti, argv[3], dm_table_get_mode(ti->table), &dev)) {
+		DMERR(" %s Device Lookup failed\n", __func__);
+		return DM_REQ_CRYPT_ERROR;
+	}
+
+	if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1) {
+		DMERR("%s Invalid device sector\n", __func__);
+		return DM_REQ_CRYPT_ERROR;
+	}
+	start_sector_orig = tmpll;
+
+	req_crypt_queue = alloc_workqueue("req_cryptd",
+					  WQ_HIGHPRI |
+					  WQ_CPU_INTENSIVE|
+					  WQ_MEM_RECLAIM,
+					  1);
+	if (!req_crypt_queue) {
+		DMERR("%s req_crypt_queue not allocated\n", __func__);
+		return DM_REQ_CRYPT_ERROR;
+	}
+
+	/* Allocate the crypto alloc blk cipher and keep the handle */
+	tfm = crypto_alloc_ablkcipher("qcom-xts(aes)", 0, 0);
+	if (IS_ERR(tfm)) {
+		DMERR("%s ablkcipher tfm allocation failed : error = %lu\n",
+					 __func__, PTR_ERR(tfm));
+		return DM_REQ_CRYPT_ERROR;
+	}
+
+	req_io_pool = mempool_create_slab_pool(MIN_IOS, _req_crypt_io_pool);
+	if (!req_io_pool) {
+		DMERR("%s req_io_pool not allocated\n", __func__);
+		return DM_REQ_CRYPT_ERROR;
+	}
+
+	req_page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0);
+	if (!req_page_pool) {
+		DMERR("%s req_page_pool not allocated\n", __func__);
+		return DM_REQ_CRYPT_ERROR;
+	}
+
+	return 0;
+}
+
+static void req_crypt_postsuspend(struct dm_target *ti)
+{
+}
+
+static int req_crypt_preresume(struct dm_target *ti)
+{
+	return 0;
+}
+
+static void req_crypt_resume(struct dm_target *ti)
+{
+}
+
+/* Message interface
+ *	key set <key>
+ *	key wipe
+ */
+static int req_crypt_message(struct dm_target *ti, unsigned argc, char **argv)
+{
+	return 0;
+}
+
+static int req_crypt_iterate_devices(struct dm_target *ti,
+				 iterate_devices_callout_fn fn, void *data)
+{
+	return fn(ti, dev, start_sector_orig, ti->len, data);
+}
+
+static struct target_type req_crypt_target = {
+	.name   = "req-crypt",
+	.version = {1, 0, 0},
+	.module = THIS_MODULE,
+	.ctr    = req_crypt_ctr,
+	.dtr    = req_crypt_dtr,
+	.map_rq = req_crypt_map,
+	.rq_end_io = req_crypt_endio,
+	.status = req_crypt_status,
+	.postsuspend = req_crypt_postsuspend,
+	.preresume = req_crypt_preresume,
+	.resume = req_crypt_resume,
+	.message = req_crypt_message,
+	.iterate_devices = req_crypt_iterate_devices,
+};
+
+static int __init req_dm_crypt_init(void)
+{
+	int r;
+
+	_req_crypt_io_pool = KMEM_CACHE(req_dm_crypt_io, 0);
+	if (!_req_crypt_io_pool)
+		return -ENOMEM;
+
+	r = dm_register_target(&req_crypt_target);
+	if (r < 0)
+		DMERR("register failed %d", r);
+
+	return r;
+}
+
+static void __exit req_dm_crypt_exit(void)
+{
+	kmem_cache_destroy(_req_crypt_io_pool);
+	dm_unregister_target(&req_crypt_target);
+}
+
+module_init(req_dm_crypt_init);
+module_exit(req_dm_crypt_exit);
+
+MODULE_DESCRIPTION(DM_NAME " target for request based transparent encryption / decryption");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index e24143c..5d240d1 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -775,7 +775,7 @@
  * Complete the clone and the original request.
  * Must be called without queue lock.
  */
-static void dm_end_request(struct request *clone, int error)
+void dm_end_request(struct request *clone, int error)
 {
 	int rw = rq_data_dir(clone);
 	struct dm_rq_target_io *tio = clone->end_io_data;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index a85f853..f9855c0 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -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
@@ -188,7 +188,6 @@
 					mapped_info->handle,
 					buf_mgr->iommu_domain_num, 0);
 				ion_free(buf_mgr->client, mapped_info->handle);
-
 				list_del_init(&buf_pending->list);
 				kfree(buf_pending);
 				break;
@@ -309,6 +308,9 @@
 	struct msm_isp_buffer *temp_buf_info;
 	struct msm_isp_bufq *bufq = NULL;
 	struct vb2_buffer *vb2_buf = NULL;
+	struct buffer_cmd *buf_pending = NULL;
+	struct msm_isp_buffer_mapped_info *mped_info_tmp1;
+	struct msm_isp_buffer_mapped_info *mped_info_tmp2;
 	bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
 	if (!bufq) {
 		pr_err("%s: Invalid bufq\n", __func__);
@@ -348,9 +350,22 @@
 		list_for_each_entry(temp_buf_info, &bufq->head, list) {
 			if (temp_buf_info->state ==
 					MSM_ISP_BUFFER_STATE_QUEUED) {
-				/* found one buf */
-				list_del_init(&temp_buf_info->list);
-				*buf_info = temp_buf_info;
+
+				list_for_each_entry(buf_pending, &buf_mgr->buffer_q, list) {
+					if (!buf_pending)
+						break;
+					mped_info_tmp1 = buf_pending->mapped_info;
+					mped_info_tmp2 = &temp_buf_info->mapped_info[0];
+
+					if (mped_info_tmp1 == mped_info_tmp2
+						&& (mped_info_tmp1->len == mped_info_tmp2->len)
+						&& (mped_info_tmp1->paddr == mped_info_tmp2->paddr)) {
+						/* found one buf */
+						list_del_init(&temp_buf_info->list);
+						*buf_info = temp_buf_info;
+						break;
+					}
+				}
 				break;
 			}
 		}
@@ -359,9 +374,22 @@
 			bufq->session_id, bufq->stream_id);
 		if (vb2_buf) {
 			if (vb2_buf->v4l2_buf.index < bufq->num_bufs) {
-				*buf_info =
-					&bufq->bufs[vb2_buf->v4l2_buf.index];
-				(*buf_info)->vb2_buf = vb2_buf;
+
+				list_for_each_entry(buf_pending, &buf_mgr->buffer_q, list) {
+					if (!buf_pending)
+						break;
+					mped_info_tmp1 = buf_pending->mapped_info;
+					mped_info_tmp2 =
+						&bufq->bufs[vb2_buf->v4l2_buf.index].mapped_info[0];
+
+					if (mped_info_tmp1 == mped_info_tmp2
+						&& (mped_info_tmp1->len == mped_info_tmp2->len)
+						&& (mped_info_tmp1->paddr == mped_info_tmp2->paddr)) {
+						*buf_info = &bufq->bufs[vb2_buf->v4l2_buf.index];
+						(*buf_info)->vb2_buf = vb2_buf;
+						break;
+					}
+				}
 			} else {
 				pr_err("%s: Incorrect buf index %d\n",
 					__func__, vb2_buf->v4l2_buf.index);
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 ef8b996..7805930 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
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -127,31 +127,63 @@
 }
 
 static int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
-	uint16_t size, enum msm_actuator_data_type type,
-	struct reg_settings_t *settings)
+	uint16_t size, struct reg_settings_t *settings)
 {
 	int32_t rc = -EFAULT;
 	int32_t i = 0;
 	CDBG("Enter\n");
 
 	for (i = 0; i < size; i++) {
-		switch (type) {
-		case MSM_ACTUATOR_BYTE_DATA:
-			rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write(
-				&a_ctrl->i2c_client,
-				settings[i].reg_addr,
-				settings[i].reg_data, MSM_CAMERA_I2C_BYTE_DATA);
-			break;
-		case MSM_ACTUATOR_WORD_DATA:
-			rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write(
-				&a_ctrl->i2c_client,
-				settings[i].reg_addr,
-				settings[i].reg_data, MSM_CAMERA_I2C_WORD_DATA);
-			break;
-		default:
-			pr_err("Unsupport data type: %d\n", type);
-			break;
+		switch (settings[i].i2c_operation) {
+		case MSM_ACT_WRITE: {
+			switch (settings[i].data_type) {
+			case MSM_ACTUATOR_BYTE_DATA:
+				rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write(
+					&a_ctrl->i2c_client,
+					settings[i].reg_addr,
+					settings[i].reg_data,
+					MSM_CAMERA_I2C_BYTE_DATA);
+				break;
+			case MSM_ACTUATOR_WORD_DATA:
+				rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write(
+					&a_ctrl->i2c_client,
+					settings[i].reg_addr,
+					settings[i].reg_data,
+					MSM_CAMERA_I2C_WORD_DATA);
+				break;
+			default:
+				pr_err("Unsupport data type: %d\n",
+					settings[i].i2c_operation);
+				break;
+			}
 		}
+		case MSM_ACT_POLL: {
+			switch (settings[i].data_type) {
+			case MSM_ACTUATOR_BYTE_DATA:
+				rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_poll(
+					&a_ctrl->i2c_client,
+					settings[i].reg_addr,
+					settings[i].reg_data,
+					MSM_CAMERA_I2C_BYTE_DATA);
+				break;
+			case MSM_ACTUATOR_WORD_DATA:
+				rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_poll(
+					&a_ctrl->i2c_client,
+					settings[i].reg_addr,
+					settings[i].reg_data,
+					MSM_CAMERA_I2C_WORD_DATA);
+				break;
+			default:
+				pr_err("Unsupport data type: %d\n",
+					settings[i].i2c_operation);
+				break;
+			}
+		}
+		}
+
+		if (0 != settings[i].delay)
+			msleep(settings[i].delay);
+
 		if (rc < 0)
 			break;
 	}
@@ -544,7 +576,6 @@
 			}
 			rc = a_ctrl->func_tbl->actuator_init_focus(a_ctrl,
 				set_info->actuator_params.init_setting_size,
-				a_ctrl->i2c_data_type,
 				init_settings);
 			kfree(init_settings);
 			if (rc < 0) {
@@ -644,6 +675,7 @@
 	.i2c_write_table_w_microdelay =
 		msm_camera_cci_i2c_write_table_w_microdelay,
 	.i2c_util = msm_sensor_cci_i2c_util,
+	.i2c_poll =  msm_camera_cci_i2c_poll,
 };
 
 static struct msm_camera_i2c_fn_t msm_sensor_qup_func_tbl = {
@@ -654,6 +686,7 @@
 	.i2c_write_seq_table = msm_camera_qup_i2c_write_seq_table,
 	.i2c_write_table_w_microdelay =
 		msm_camera_qup_i2c_write_table_w_microdelay,
+	.i2c_poll = msm_camera_qup_i2c_poll,
 };
 
 static int msm_actuator_open(struct v4l2_subdev *sd,
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 7ec9a49..772b12e 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
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -31,7 +31,7 @@
 	int32_t (*actuator_init_step_table)(struct msm_actuator_ctrl_t *,
 		struct msm_actuator_set_info_t *);
 	int32_t (*actuator_init_focus)(struct msm_actuator_ctrl_t *,
-		uint16_t, enum msm_actuator_data_type, struct reg_settings_t *);
+		uint16_t, struct reg_settings_t *);
 	int32_t (*actuator_set_default_focus) (struct msm_actuator_ctrl_t *,
 			struct msm_actuator_move_params_t *);
 	int32_t (*actuator_move_focus) (struct msm_actuator_ctrl_t *,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
index 5c0e6d5..7649a40 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
@@ -284,13 +284,23 @@
 	int j;
 	struct msm_eeprom_memory_map_t *emap = block->map;
 	uint8_t *memptr = block->mapdata;
+	struct msm_eeprom_board_info *eb_info = NULL;
 
 	if (!e_ctrl) {
 		pr_err("%s e_ctrl is NULL", __func__);
 		return -EINVAL;
 	}
 
+	eb_info = e_ctrl->eboard_info;
 	for (j = 0; j < block->num_map; j++) {
+		if (emap[j].saddr.addr) {
+			eb_info->i2c_slaveaddr = emap[j].saddr.addr;
+			e_ctrl->i2c_client.cci_client->sid =
+					eb_info->i2c_slaveaddr >> 1;
+			pr_err("qcom,slave-addr = 0x%X\n",
+				eb_info->i2c_slaveaddr);
+		}
+
 		if (emap[j].page.valid_size) {
 			e_ctrl->i2c_client.addr_type = emap[j].page.addr_t;
 			rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_write(
@@ -405,6 +415,12 @@
 			goto ERROR;
 		}
 
+		snprintf(property, PROPERTY_MAXSIZE, "qcom,saddr%d", i);
+		rc = of_property_read_u32_array(of, property,
+			(uint32_t *) &map[i].saddr.addr, 1);
+		if (rc < 0)
+			CDBG("%s: saddr not needed - block %d\n", __func__, i);
+
 		snprintf(property, PROPERTY_MAXSIZE, "qcom,mem%d", i);
 		rc = of_property_read_u32_array(of, property,
 				(uint32_t *) &map[i].mem, count);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/gc0339.c b/drivers/media/platform/msm/camera_v2/sensor/gc0339.c
index e233b8d..36f3b61 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/gc0339.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/gc0339.c
@@ -407,6 +407,10 @@
 		for (i = 0; i < SUB_MODULE_MAX; i++)
 			cdata->cfg.sensor_info.subdev_id[i] =
 				s_ctrl->sensordata->sensor_info->subdev_id[i];
+		cdata->cfg.sensor_info.is_mount_angle_valid =
+			s_ctrl->sensordata->sensor_info->is_mount_angle_valid;
+		cdata->cfg.sensor_info.sensor_mount_angle =
+			s_ctrl->sensordata->sensor_info->sensor_mount_angle;
 		CDBG("%s:%d sensor name %s\n", __func__, __LINE__,
 			cdata->cfg.sensor_info.sensor_name);
 		CDBG("%s:%d session id %d\n", __func__, __LINE__,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/hi256.c b/drivers/media/platform/msm/camera_v2/sensor/hi256.c
index 2b1024e..c7e0cb5 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/hi256.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/hi256.c
@@ -1781,6 +1781,10 @@
 		for (i = 0; i < SUB_MODULE_MAX; i++)
 			cdata->cfg.sensor_info.subdev_id[i] =
 				s_ctrl->sensordata->sensor_info->subdev_id[i];
+		cdata->cfg.sensor_info.is_mount_angle_valid =
+			s_ctrl->sensordata->sensor_info->is_mount_angle_valid;
+		cdata->cfg.sensor_info.sensor_mount_angle =
+			s_ctrl->sensordata->sensor_info->sensor_mount_angle;
 		CDBG("%s:%d sensor name %s\n", __func__, __LINE__,
 			cdata->cfg.sensor_info.sensor_name);
 		CDBG("%s:%d session id %d\n", __func__, __LINE__,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
index 1fb113d..cc301ae 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
@@ -356,7 +356,8 @@
 	struct msm_sensor_power_setting *ps;
 
 	struct msm_sensor_power_setting *power_setting;
-	uint16_t *power_setting_size;
+	uint16_t *power_setting_size, size = 0;
+	bool need_reverse = 0;
 
 	if (!power_info)
 		return -EINVAL;
@@ -508,6 +509,39 @@
 			i, ps[i].delay);
 	}
 	kfree(array);
+
+	size = *power_setting_size;
+
+	if (NULL != ps && 0 != size)
+		need_reverse = 1;
+
+	power_info->power_down_setting =
+		kzalloc(sizeof(*ps) * size, GFP_KERNEL);
+
+	if (!power_info->power_down_setting) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+	memcpy(power_info->power_down_setting,
+		ps, sizeof(*ps) * size);
+
+	power_info->power_down_setting_size = size;
+
+	if (need_reverse) {
+		int c, end = size - 1;
+		struct msm_sensor_power_setting power_down_setting_t;
+		for (c = 0; c < size/2; c++) {
+			power_down_setting_t =
+				power_info->power_down_setting[c];
+			power_info->power_down_setting[c] =
+				power_info->power_down_setting[end];
+			power_info->power_down_setting[end] =
+				power_down_setting_t;
+			end--;
+		}
+	}
 	return rc;
 ERROR2:
 	kfree(array);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
index 763c131..1bceb51 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -117,4 +117,8 @@
 	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
 	enum msm_camera_i2c_data_type data_type);
 
+int32_t msm_camera_qup_i2c_poll(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type);
+
 #endif
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 71ad080..ea7d670 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -21,7 +21,7 @@
 
 #define MSM_VDEC_DVC_NAME "msm_vdec_8974"
 #define MIN_NUM_OUTPUT_BUFFERS 4
-#define MAX_NUM_OUTPUT_BUFFERS 6
+#define MAX_NUM_OUTPUT_BUFFERS VIDEO_MAX_FRAME
 #define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8080
 
 #define TZ_DYNAMIC_BUFFER_FEATURE_ID 12
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 2c808ff..fe0a42d 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -683,7 +683,8 @@
 				return -EINVAL;
 			}
 		} else
-			dprintk(VIDC_ERR, "%s: WARN: NULL handle", __func__);
+			dprintk(VIDC_DBG, "%s: NULL handle for plane %d\n",
+					__func__, i);
 	}
 	return 0;
 }
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 95afa2a..70114de 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -390,7 +390,8 @@
 		&inst->completions[SESSION_MSG_INDEX(cmd)],
 		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
 	if (!rc) {
-		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
+		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n",
+				SESSION_MSG_INDEX(cmd));
 		msm_comm_recover_from_session_error(inst);
 		rc = -EIO;
 	} else {
@@ -1472,7 +1473,8 @@
 		&core->completions[SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)],
 		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
 	if (!rc) {
-		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
+		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n",
+				SYS_MSG_INDEX(RELEASE_RESOURCE_DONE));
 		rc = -EIO;
 	}
 release_ocmem_failed:
@@ -1494,7 +1496,8 @@
 		&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)],
 		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
 	if (!rc) {
-		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
+		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n",
+				SYS_MSG_INDEX(SYS_INIT_DONE));
 		rc = -EIO;
 		goto exit;
 	} else {
@@ -2574,7 +2577,8 @@
 		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
 	if (!rc) {
 		dprintk(VIDC_ERR,
-			"Wait interrupted or timeout: %d\n", rc);
+			"Wait interrupted or timeout: %d\n",
+			SESSION_MSG_INDEX(SESSION_PROPERTY_INFO));
 		inst->state = MSM_VIDC_CORE_INVALID;
 		msm_comm_recover_from_session_error(inst);
 		rc = -EIO;
@@ -3316,10 +3320,24 @@
 
 	rc = msm_vidc_load_supported(inst);
 	if (!rc && inst->capability.capability_set) {
-		rc = call_hfi_op(hdev, capability_check,
-			inst->fmts[OUTPUT_PORT]->fourcc,
-			inst->prop.width[CAPTURE_PORT], &capability->width.max,
-			&capability->height.max);
+		if (inst->prop.width[CAPTURE_PORT] < capability->width.min ||
+			inst->prop.height[CAPTURE_PORT] <
+			capability->height.min) {
+			dprintk(VIDC_ERR,
+				"Unsupported WxH = (%u)x(%u), min supported is - (%u)x(%u)\n",
+				inst->prop.width[CAPTURE_PORT],
+				inst->prop.height[CAPTURE_PORT],
+				capability->width.min,
+				capability->height.min);
+			rc = -ENOTSUPP;
+		}
+		if (!rc) {
+			rc = call_hfi_op(hdev, capability_check,
+				inst->fmts[OUTPUT_PORT]->fourcc,
+				inst->prop.width[CAPTURE_PORT],
+				&capability->width.max,
+				&capability->height.max);
+		}
 
 		if (!rc && (inst->prop.height[CAPTURE_PORT]
 			* inst->prop.width[CAPTURE_PORT] >
@@ -3337,7 +3355,6 @@
 		inst->state = MSM_VIDC_CORE_INVALID;
 		mutex_unlock(&inst->sync_lock);
 		msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
-		wake_up(&inst->kernel_event_queue);
 	}
 	return rc;
 }
@@ -3388,7 +3405,7 @@
 		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
 	if (!rc) {
 		dprintk(VIDC_ERR, "%s: Wait interrupted or timeout: %d\n",
-			__func__, rc);
+			__func__, SESSION_MSG_INDEX(SESSION_ABORT_DONE));
 		msm_comm_generate_sys_error(inst);
 	} else
 		change_inst_state(inst, MSM_VIDC_CLOSE_DONE);
diff --git a/drivers/misc/smsc_hub.c b/drivers/misc/smsc_hub.c
index 6f98dc7..e89451a 100644
--- a/drivers/misc/smsc_hub.c
+++ b/drivers/misc/smsc_hub.c
@@ -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
@@ -36,6 +36,7 @@
 	struct clk		*ref_clk;
 	struct regulator	*hsic_hub_reg;
 	struct regulator	*int_pad_reg, *hub_vbus_reg;
+	bool enabled;
 };
 static struct hsic_hub *smsc_hub;
 static struct platform_driver smsc_hub_driver;
@@ -191,6 +192,14 @@
 {
 	int ret;
 
+	/*
+	 * xo_clk_gpio controls an external xo clock which feeds
+	 * the hub reference clock. When this gpio is present,
+	 * assume that no other clocks are required.
+	 */
+	if (hub->pdata->xo_clk_gpio)
+		return 0;
+
 	if (!init) {
 		if (!IS_ERR(hub->ref_clk))
 			clk_disable_unprepare(hub->ref_clk);
@@ -257,6 +266,15 @@
 			dev_err(hub->dev, "gpio request failed (CLK GPIO)\n");
 	}
 
+	if (pdata->xo_clk_gpio) {
+		ret = devm_gpio_request(hub->dev, pdata->xo_clk_gpio,
+							 "HSIC_HUB_XO_CLK");
+		if (ret < 0) {
+			dev_err(hub->dev, "gpio request failed(XO CLK GPIO)\n");
+			return ret;
+		}
+	}
+
 	if (pdata->int_gpio) {
 		ret = devm_gpio_request(hub->dev, pdata->int_gpio,
 							 "HSIC_HUB_INT");
@@ -266,7 +284,7 @@
 		}
 
 		/* Enable LDO if required for external pull-up */
-		smsc_hub->int_pad_reg = devm_regulator_get(hub->dev, "hub_int");
+		smsc_hub->int_pad_reg = devm_regulator_get(hub->dev, "hub-int");
 		if (IS_ERR(smsc_hub->int_pad_reg)) {
 			dev_dbg(hub->dev, "unable to get ext hub_int reg\n");
 		} else {
@@ -298,6 +316,9 @@
 {
 	int ret;
 
+	if (!of_get_property(hub->dev->of_node, "ext-hub-vddio-supply", NULL))
+		return 0;
+
 	if (!init) {
 		if (!IS_ERR(smsc_hub->hsic_hub_reg)) {
 			regulator_disable(smsc_hub->hsic_hub_reg);
@@ -308,7 +329,7 @@
 		return 0;
 	}
 
-	smsc_hub->hsic_hub_reg = devm_regulator_get(hub->dev, "EXT_HUB_VDDIO");
+	smsc_hub->hsic_hub_reg = devm_regulator_get(hub->dev, "ext-hub-vddio");
 	if (IS_ERR(smsc_hub->hsic_hub_reg)) {
 		dev_dbg(hub->dev, "unable to get ext hub vddcx\n");
 	} else {
@@ -345,6 +366,124 @@
 
 	return ret;
 }
+
+static int smsc_hub_enable(struct hsic_hub *hub)
+{
+	struct smsc_hub_platform_data *pdata = hub->pdata;
+	struct of_dev_auxdata *hsic_host_auxdata = dev_get_platdata(hub->dev);
+	struct device_node *node = hub->dev->of_node;
+	int ret;
+
+	ret = gpio_direction_output(pdata->xo_clk_gpio, 1);
+	if (ret < 0) {
+		dev_err(hub->dev, "fail to enable xo clk\n");
+		return ret;
+	}
+
+	ret = gpio_direction_output(pdata->hub_reset, 0);
+	if (ret < 0) {
+		dev_err(hub->dev, "fail to assert reset\n");
+		goto disable_xo;
+	}
+	udelay(5);
+	ret = gpio_direction_output(pdata->hub_reset, 1);
+	if (ret < 0) {
+		dev_err(hub->dev, "fail to de-assert reset\n");
+		goto disable_xo;
+	}
+
+	ret = of_platform_populate(node, NULL, hsic_host_auxdata,
+			hub->dev);
+	if (ret < 0) {
+		dev_err(smsc_hub->dev, "fail to add child with %d\n",
+				ret);
+		goto reset;
+	}
+
+	pm_runtime_allow(hub->dev);
+
+	return 0;
+
+reset:
+	gpio_direction_output(pdata->hub_reset, 0);
+disable_xo:
+	gpio_direction_output(pdata->xo_clk_gpio, 0);
+
+	return ret;
+}
+
+static int sms_hub_remove_child(struct device *dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	/*
+	 * Runtime PM is disabled before the driver's remove method
+	 * is called.  So resume the device before unregistering
+	 * the device. Don't worry about the PM usage counter as
+	 * the device will be freed.
+	 */
+	pm_runtime_get_sync(dev);
+	of_device_unregister(pdev);
+
+	return 0;
+}
+
+static int smsc_hub_disable(struct hsic_hub *hub)
+{
+	struct smsc_hub_platform_data *pdata = hub->pdata;
+
+	pm_runtime_forbid(hub->dev);
+	device_for_each_child(hub->dev, NULL, sms_hub_remove_child);
+	gpio_direction_output(pdata->hub_reset, 0);
+	gpio_direction_output(pdata->xo_clk_gpio, 0);
+
+	return 0;
+}
+
+static ssize_t smsc_hub_enable_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", smsc_hub->enabled ?
+						"enabled" : "disabled");
+}
+
+static ssize_t smsc_hub_enable_store(struct device *dev,
+		struct device_attribute *attr, const char
+		*buf, size_t size)
+{
+
+	bool enable;
+	int val;
+	int ret = size;
+
+	if (sscanf(buf, "%d", &val) == 1) {
+		enable = !!val;
+	} else {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (smsc_hub->enabled == enable)
+		goto out;
+
+	if (enable)
+		ret = smsc_hub_enable(smsc_hub);
+	else
+		ret = smsc_hub_disable(smsc_hub);
+
+	pr_debug("smsc hub %s status %d\n", enable ?
+			"Enable" : "Disable", ret);
+	if (!ret) {
+		ret = size;
+		smsc_hub->enabled = enable;
+	}
+out:
+	return ret;
+}
+
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, smsc_hub_enable_show,
+			smsc_hub_enable_store);
+
 struct smsc_hub_platform_data *msm_hub_dt_to_pdata(
 				struct platform_device *pdev)
 {
@@ -365,6 +504,8 @@
 		return ERR_PTR(rc);
 	} else {
 		pdata->model_id = temp_val;
+		if (pdata->model_id == 0)
+			return pdata;
 	}
 
 	pdata->hub_reset = of_get_named_gpio(node, "smsc,reset-gpio", 0);
@@ -379,6 +520,10 @@
 	if (pdata->int_gpio < 0)
 		pdata->int_gpio = 0;
 
+	pdata->xo_clk_gpio = of_get_named_gpio(node, "smsc,xo-clk-gpio", 0);
+	if (pdata->xo_clk_gpio < 0)
+		pdata->xo_clk_gpio = 0;
+
 	return pdata;
 }
 
@@ -406,6 +551,12 @@
 		return -ENODEV;
 	}
 
+	if (pdata->model_id == 0) {
+		dev_dbg(&pdev->dev, "standalone HSIC config enabled\n");
+		return of_platform_populate(node, NULL,
+				hsic_host_auxdata, &pdev->dev);
+	}
+
 	if (!pdata->hub_reset)
 		return -EINVAL;
 
@@ -416,11 +567,14 @@
 	smsc_hub->dev = &pdev->dev;
 	smsc_hub->pdata = pdata;
 
-	smsc_hub->hub_vbus_reg = devm_regulator_get(&pdev->dev, "hub_vbus");
-	ret = PTR_ERR(smsc_hub->hub_vbus_reg);
-	if (ret == -EPROBE_DEFER) {
-		dev_dbg(&pdev->dev, "failed to get hub_vbus\n");
-		return ret;
+	if (of_get_property(pdev->dev.of_node, "hub-vbus-supply", NULL)) {
+		smsc_hub->hub_vbus_reg = devm_regulator_get(&pdev->dev,
+				"hub-vbus");
+		ret = PTR_ERR(smsc_hub->hub_vbus_reg);
+		if (ret == -EPROBE_DEFER) {
+			dev_dbg(&pdev->dev, "failed to get hub_vbus\n");
+			return ret;
+		}
 	}
 
 	ret = msm_hsic_hub_init_vdd(smsc_hub, 1);
@@ -439,6 +593,16 @@
 		goto uninit_clock;
 	}
 
+	if (pdata->model_id == SMSC3502_ID) {
+		ret = device_create_file(&pdev->dev, &dev_attr_enable);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "fail to create sysfs file\n");
+			goto uninit_gpio;
+		}
+		pm_runtime_forbid(&pdev->dev);
+		goto done;
+	}
+
 	gpio_direction_output(pdata->hub_reset, 0);
 	/*
 	 * Hub reset should be asserted for minimum 2microsec
@@ -447,7 +611,7 @@
 	udelay(5);
 	gpio_direction_output(pdata->hub_reset, 1);
 
-	if (!IS_ERR(smsc_hub->hub_vbus_reg)) {
+	if (!IS_ERR_OR_NULL(smsc_hub->hub_vbus_reg)) {
 		ret = regulator_enable(smsc_hub->hub_vbus_reg);
 		if (ret) {
 			dev_err(&pdev->dev, "unable to enable hub_vbus\n");
@@ -501,10 +665,13 @@
 		goto uninit_gpio;
 	}
 
+	smsc_hub->enabled = true;
+
 	if (!smsc_hub->client)
 		dev_err(&pdev->dev,
 			"failed to connect to smsc_hub through I2C\n");
 
+done:
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 
@@ -524,7 +691,12 @@
 {
 	const struct smsc_hub_platform_data *pdata;
 
+	if (!smsc_hub)
+		return 0;
+
 	pdata = smsc_hub->pdata;
+	if (pdata->model_id == SMSC3502_ID)
+		device_remove_file(&pdev->dev, &dev_attr_enable);
 	if (smsc_hub->client) {
 		i2c_unregister_device(smsc_hub->client);
 		smsc_hub->client = NULL;
@@ -532,7 +704,7 @@
 	}
 	pm_runtime_disable(&pdev->dev);
 
-	if (!IS_ERR(smsc_hub->hub_vbus_reg))
+	if (!IS_ERR_OR_NULL(smsc_hub->hub_vbus_reg))
 		regulator_disable(smsc_hub->hub_vbus_reg);
 	msm_hsic_hub_init_gpio(smsc_hub, 0);
 	msm_hsic_hub_init_clock(smsc_hub, 0);
@@ -553,13 +725,19 @@
 {
 	int ret = 0;
 
+	if (!smsc_hub || !smsc_hub->enabled)
+		return 0;
+
 	if (smsc_hub->xo_handle) {
 		ret = msm_xo_mode_vote(smsc_hub->xo_handle, MSM_XO_MODE_OFF);
 		if (ret) {
 			pr_err("%s: failed to devote for TCXO\n"
 				"D1 buffer%d\n", __func__, ret);
 		}
+	} else if (smsc_hub->pdata->xo_clk_gpio) {
+		gpio_direction_output(smsc_hub->pdata->xo_clk_gpio, 0);
 	}
+
 	return ret;
 }
 
@@ -567,13 +745,19 @@
 {
 	int ret = 0;
 
+	if (!smsc_hub || !smsc_hub->enabled)
+		return 0;
+
 	if (smsc_hub->xo_handle) {
 		ret = msm_xo_mode_vote(smsc_hub->xo_handle, MSM_XO_MODE_ON);
 		if (ret) {
 			pr_err("%s: failed to vote for TCXO\n"
 				"D1 buffer%d\n", __func__, ret);
 		}
+	} else if (smsc_hub->pdata->xo_clk_gpio) {
+		gpio_direction_output(smsc_hub->pdata->xo_clk_gpio, 1);
 	}
+
 	return ret;
 }
 #endif
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 6add807..9c6bef6 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -198,9 +198,13 @@
 {
 	int ret;
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
-	struct mmc_card *card = md->queue.card;
+	struct mmc_card *card;
 	int locked = 0;
 
+	if (!md)
+		return -EINVAL;
+
+	card = md->queue.card;
 	if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PERM_WP_EN)
 		locked = 2;
 	else if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_EN)
@@ -226,6 +230,8 @@
 		return count;
 
 	md = mmc_blk_get(dev_to_disk(dev));
+	if (!md)
+		return -EINVAL;
 	card = md->queue.card;
 
 	mmc_rpm_hold(card->host, &card->dev);
@@ -265,6 +271,9 @@
 	int ret;
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
 
+	if (!md)
+		return -EINVAL;
+
 	ret = snprintf(buf, PAGE_SIZE, "%d",
 		       get_disk_ro(dev_to_disk(dev)) ^
 		       md->read_only);
@@ -279,6 +288,10 @@
 	char *end;
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
 	unsigned long set = simple_strtoul(buf, &end, 0);
+
+	if (!md)
+		return -EINVAL;
+
 	if (end == buf) {
 		ret = -EINVAL;
 		goto out;
@@ -299,6 +312,8 @@
 	int num_wr_reqs_to_start_packing;
 	int ret;
 
+	if (!md)
+		return -EINVAL;
 	num_wr_reqs_to_start_packing = md->queue.num_wr_reqs_to_start_packing;
 
 	ret = snprintf(buf, PAGE_SIZE, "%d\n", num_wr_reqs_to_start_packing);
@@ -314,9 +329,13 @@
 {
 	int value;
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
-	struct mmc_card *card = md->queue.card;
+	struct mmc_card *card;
 	int ret = count;
 
+	if (!md)
+		return -EINVAL;
+
+	card = md->queue.card;
 	if (!card) {
 		ret = -EINVAL;
 		goto exit;
@@ -348,9 +367,13 @@
 				  struct device_attribute *attr, char *buf)
 {
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
-	struct mmc_card *card = md->queue.card;
+	struct mmc_card *card;
 	int ret;
 
+	if (!md)
+		return -EINVAL;
+
+	card = md->queue.card;
 	if (!card)
 		ret = -EINVAL;
 	else
@@ -368,10 +391,14 @@
 {
 	int value;
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
-	struct mmc_card *card = md->queue.card;
+	struct mmc_card *card;
 	unsigned int card_size;
 	int ret = count;
 
+	if (!md)
+		return -EINVAL;
+
+	card = md->queue.card;
 	if (!card) {
 		ret = -EINVAL;
 		goto exit;
@@ -409,6 +436,8 @@
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
 	int ret;
 
+	if (!md)
+		return -EINVAL;
 	ret = snprintf(buf, PAGE_SIZE, "%d\n", md->queue.no_pack_for_random);
 
 	mmc_blk_put(md);
@@ -422,9 +451,13 @@
 {
 	int value;
 	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
-	struct mmc_card *card = md->queue.card;
+	struct mmc_card *card;
 	int ret = count;
 
+	if (!md)
+		return -EINVAL;
+
+	card = md->queue.card;
 	if (!card) {
 		ret = -EINVAL;
 		goto exit;
@@ -772,7 +805,7 @@
 	/* make sure this is a rpmb partition */
 	if ((!md) || (!(md->area_type & MMC_BLK_DATA_AREA_RPMB))) {
 		err = -EINVAL;
-		goto cmd_done;
+		return err;
 	}
 
 	idata = mmc_blk_ioctl_rpmb_copy_from_user(ic_ptr);
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 3648d88..d4d7c18 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -851,6 +851,7 @@
 	   ((*rocr & 0x41000000) == 0x41000000)) {
 		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, true);
 		if (err) {
+			mmc_power_cycle(host);
 			ocr &= ~SD_OCR_S18R;
 			goto try_again;
 		}
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 2559ff9..a0d9a24 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -130,6 +130,7 @@
 struct bms_irq {
 	unsigned int	irq;
 	unsigned long	disabled;
+	bool		ready;
 };
 
 struct bms_wakeup_source {
@@ -393,7 +394,7 @@
 
 static void enable_bms_irq(struct bms_irq *irq)
 {
-	if (__test_and_clear_bit(0, &irq->disabled)) {
+	if (irq->ready && __test_and_clear_bit(0, &irq->disabled)) {
 		enable_irq(irq->irq);
 		pr_debug("enabled irq %d\n", irq->irq);
 	}
@@ -401,7 +402,7 @@
 
 static void disable_bms_irq(struct bms_irq *irq)
 {
-	if (!__test_and_set_bit(0, &irq->disabled)) {
+	if (irq->ready && !__test_and_set_bit(0, &irq->disabled)) {
 		disable_irq(irq->irq);
 		pr_debug("disabled irq %d\n", irq->irq);
 	}
@@ -409,7 +410,7 @@
 
 static void disable_bms_irq_nosync(struct bms_irq *irq)
 {
-	if (!__test_and_set_bit(0, &irq->disabled)) {
+	if (irq->ready && !__test_and_set_bit(0, &irq->disabled)) {
 		disable_irq_nosync(irq->irq);
 		pr_debug("disabled irq %d\n", irq->irq);
 	}
@@ -605,12 +606,14 @@
 	temp_current = div_s64((vsense_uv * 1000000LL),
 				(int)chip->r_sense_uohm);
 
+	*result_ua = temp_current;
 	rc = qpnp_iadc_comp_result(chip->iadc_dev, &temp_current);
 	if (rc)
 		pr_debug("error compensation failed: %d\n", rc);
 
+	pr_debug("%d uA err compensated ibat=%llduA\n",
+			*result_ua, temp_current);
 	*result_ua = temp_current;
-	pr_debug("err compensated ibat=%duA\n", *result_ua);
 	return 0;
 }
 
@@ -3884,6 +3887,7 @@
 		pr_err("Unable to request " #irq_name " irq: %d\n", rc);\
 		return -ENXIO;						\
 	}								\
+	chip->irq_name##_irq.ready = true;				\
 } while (0)
 
 static int bms_request_irqs(struct qpnp_bms_chip *chip)
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 3561788..2dc77e6 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -114,6 +114,9 @@
 #define USB_OCP_CLR				0x53
 #define BAT_IF_TEMP_STATUS			0x09
 #define BOOST_ILIM				0x78
+#define USB_SPARE				0xDF
+#define DC_COMP_OVR1				0xE9
+#define CHGR_COMP_OVR1				0xEE
 
 #define REG_OFFSET_PERP_SUBTYPE			0x05
 
@@ -318,6 +321,8 @@
 	bool				ibat_calibration_enabled;
 	bool				aicl_settled;
 	bool				use_external_rsense;
+	bool				fastchg_on;
+	bool				parallel_ovp_mode;
 	unsigned int			bpd_detection;
 	unsigned int			max_bat_chg_current;
 	unsigned int			warm_bat_chg_ma;
@@ -384,6 +389,8 @@
 	bool				power_stage_workaround_enable;
 };
 
+static void
+qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip);
 
 static struct of_device_id qpnp_charger_match_table[] = {
 	{ .compatible = QPNP_CHARGER_DEV_NAME, },
@@ -904,21 +911,21 @@
 	return rc;
 }
 
-#define QPNP_CHG_VINMIN_MIN_MV		4200
+#define QPNP_CHG_VINMIN_MIN_MV		4000
 #define QPNP_CHG_VINMIN_HIGH_MIN_MV	5600
 #define QPNP_CHG_VINMIN_HIGH_MIN_VAL	0x2B
 #define QPNP_CHG_VINMIN_MAX_MV		9600
 #define QPNP_CHG_VINMIN_STEP_MV		50
 #define QPNP_CHG_VINMIN_STEP_HIGH_MV	200
 #define QPNP_CHG_VINMIN_MASK		0x3F
-#define QPNP_CHG_VINMIN_MIN_VAL	0x10
+#define QPNP_CHG_VINMIN_MIN_VAL	0x0C
 static int
 qpnp_chg_vinmin_set(struct qpnp_chg_chip *chip, int voltage)
 {
 	u8 temp;
 
-	if (voltage < QPNP_CHG_VINMIN_MIN_MV
-			|| voltage > QPNP_CHG_VINMIN_MAX_MV) {
+	if ((voltage < QPNP_CHG_VINMIN_MIN_MV)
+			|| (voltage > QPNP_CHG_VINMIN_MAX_MV)) {
 		pr_err("bad mV=%d asked to set\n", voltage);
 		return -EINVAL;
 	}
@@ -1010,10 +1017,68 @@
 	return iusbmax_ma;
 }
 
+#define ILIMIT_OVR_0	0x02
+static int
+override_dcin_ilimit(struct qpnp_chg_chip *chip, bool override)
+{
+	int rc;
+
+	pr_debug("override %d\n", override);
+	rc = qpnp_chg_masked_write(chip,
+			chip->dc_chgpth_base + SEC_ACCESS,
+			0xA5,
+			0xA5, 1);
+	rc |= qpnp_chg_masked_write(chip,
+			chip->dc_chgpth_base + DC_COMP_OVR1,
+			0xFF,
+			override ? ILIMIT_OVR_0 : 0, 1);
+	if (rc) {
+		pr_err("Failed to override dc ilimit rc = %d\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+#define DUAL_PATH_EN	BIT(7)
+static int
+switch_parallel_ovp_mode(struct qpnp_chg_chip *chip, bool enable)
+{
+	int rc = 0;
+
+	if (!chip->usb_chgpth_base || !chip->dc_chgpth_base)
+		return rc;
+
+	pr_debug("enable %d\n", enable);
+	rc = override_dcin_ilimit(chip, 1);
+	udelay(10);
+
+	/* enable/disable dual path mode */
+	rc = qpnp_chg_masked_write(chip,
+			chip->usb_chgpth_base + SEC_ACCESS,
+			0xA5,
+			0xA5, 1);
+	rc |= qpnp_chg_masked_write(chip,
+			chip->usb_chgpth_base + USB_SPARE,
+			0xFF,
+			enable ? DUAL_PATH_EN : 0, 1);
+	if (rc) {
+		pr_err("Failed to turn on usb ovp rc = %d\n", rc);
+		return rc;
+	}
+
+	rc = override_dcin_ilimit(chip, 0);
+	return rc;
+}
+
 #define USB_SUSPEND_BIT	BIT(0)
 static int
 qpnp_chg_usb_suspend_enable(struct qpnp_chg_chip *chip, int enable)
 {
+	/* Turn off DC OVP FET when going into USB suspend */
+	if (chip->parallel_ovp_mode && enable)
+		switch_parallel_ovp_mode(chip, 0);
+
 	return qpnp_chg_masked_write(chip,
 			chip->usb_chgpth_base + CHGR_USB_USB_SUSP,
 			USB_SUSPEND_BIT,
@@ -1779,43 +1844,96 @@
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t
-qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
+static int qpnp_chg_is_fastchg_on(struct qpnp_chg_chip *chip)
 {
-	struct qpnp_chg_chip *chip = _chip;
 	u8 chgr_sts;
 	int rc;
 
 	qpnp_chg_irq_wake_disable(&chip->chg_fastchg);
 
 	rc = qpnp_chg_read(chip, &chgr_sts, INT_RT_STS(chip->chgr_base), 1);
-	if (rc)
-		pr_err("failed to read interrupt sts %d\n", rc);
+	if (rc) {
+		pr_err("failed to read interrupt status %d\n", rc);
+		return rc;
+	}
+	pr_debug("chgr_sts 0x%x\n", chgr_sts);
+	return (chgr_sts & FAST_CHG_ON_IRQ) ? 1 : 0;
+}
 
-	pr_debug("FAST_CHG IRQ triggered\n");
-	chip->chg_done = false;
-	if (chip->bat_if_base) {
-		pr_debug("psy changed batt_psy\n");
-		power_supply_changed(&chip->batt_psy);
+#define VBATDET_BYPASS	0x01
+static int
+bypass_vbatdet_comp(struct qpnp_chg_chip *chip, bool bypass)
+{
+	int rc;
+
+	pr_debug("bypass %d\n", bypass);
+		rc = qpnp_chg_masked_write(chip,
+			chip->chgr_base + SEC_ACCESS,
+			0xA5,
+			0xA5, 1);
+	rc |= qpnp_chg_masked_write(chip,
+			chip->chgr_base + CHGR_COMP_OVR1,
+			0xFF,
+			bypass ? VBATDET_BYPASS : 0, 1);
+	if (rc) {
+		pr_err("Failed to bypass vbatdet comp rc = %d\n", rc);
+		return rc;
 	}
 
-	pr_debug("psy changed usb_psy\n");
-	power_supply_changed(chip->usb_psy);
+	return rc;
+}
 
-	if (chip->dc_chgpth_base) {
-		pr_debug("psy changed dc_psy\n");
-		power_supply_changed(&chip->dc_psy);
-	}
+static irqreturn_t
+qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
+{
+	struct qpnp_chg_chip *chip = _chip;
+	bool fastchg_on = false;
 
-	if (chip->resuming_charging) {
-		chip->resuming_charging = false;
-		qpnp_chg_set_appropriate_vbatdet(chip);
-	}
+	fastchg_on = qpnp_chg_is_fastchg_on(chip);
 
-	if (!chip->charging_disabled) {
-		schedule_delayed_work(&chip->eoc_work,
-			msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
-		pm_stay_awake(chip->dev);
+	pr_debug("FAST_CHG IRQ triggered, fastchg_on: %d\n", fastchg_on);
+
+	if (chip->fastchg_on ^ fastchg_on) {
+		chip->fastchg_on = fastchg_on;
+		if (chip->bat_if_base) {
+			pr_debug("psy changed batt_psy\n");
+			power_supply_changed(&chip->batt_psy);
+		}
+
+		pr_debug("psy changed usb_psy\n");
+		power_supply_changed(chip->usb_psy);
+
+		if (chip->dc_chgpth_base) {
+			pr_debug("psy changed dc_psy\n");
+			power_supply_changed(&chip->dc_psy);
+		}
+
+		if (fastchg_on) {
+			chip->chg_done = false;
+			bypass_vbatdet_comp(chip, 1);
+			if (chip->bat_is_warm || chip->bat_is_cool) {
+				qpnp_chg_set_appropriate_vddmax(chip);
+				qpnp_chg_set_appropriate_battery_current(chip);
+			}
+
+			if (chip->resuming_charging) {
+				chip->resuming_charging = false;
+				qpnp_chg_set_appropriate_vbatdet(chip);
+			}
+
+			if (!chip->charging_disabled) {
+				schedule_delayed_work(&chip->eoc_work,
+					msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
+				pm_stay_awake(chip->dev);
+			}
+			if (chip->parallel_ovp_mode)
+				switch_parallel_ovp_mode(chip, 1);
+		} else {
+			if (chip->parallel_ovp_mode)
+				switch_parallel_ovp_mode(chip, 0);
+			if (!chip->bat_is_warm && !chip->bat_is_cool)
+				bypass_vbatdet_comp(chip, 0);
+		}
 	}
 
 	qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
@@ -1931,6 +2049,9 @@
 	if (qpnp_chg_is_otg_en_set(chip))
 		return 0;
 
+	if (chip->parallel_ovp_mode)
+		switch_parallel_ovp_mode(chip, 0);
+
 	if (chip->type == SMBBP) {
 		rc = qpnp_chg_masked_write(chip,
 				chip->boost_base + BOOST_ILIM,
@@ -2340,7 +2461,7 @@
 		pr_debug("Unable to read batt temperature rc=%d\n", rc);
 		return 0;
 	}
-	pr_debug("get_bat_temp %d %lld\n",
+	pr_debug("get_bat_temp %d, %lld\n",
 		results.adc_code, results.physical);
 
 	return (int)results.physical;
@@ -2682,6 +2803,25 @@
 	return 0;
 }
 
+static void
+qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip)
+{
+	unsigned int chg_current = chip->max_bat_chg_current;
+
+	if (chip->bat_is_cool)
+		chg_current = min(chg_current, chip->cool_bat_chg_ma);
+
+	if (chip->bat_is_warm)
+		chg_current = min(chg_current, chip->warm_bat_chg_ma);
+
+	if (chip->therm_lvl_sel != 0 && chip->thermal_mitigation)
+		chg_current = min(chg_current,
+			chip->thermal_mitigation[chip->therm_lvl_sel]);
+
+	pr_debug("setting %d mA\n", chg_current);
+	qpnp_chg_ibatmax_set(chip, chg_current);
+}
+
 static int
 qpnp_chg_vddsafe_set(struct qpnp_chg_chip *chip, int voltage)
 {
@@ -2890,25 +3030,6 @@
 }
 
 static void
-qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip)
-{
-	unsigned int chg_current = chip->max_bat_chg_current;
-
-	if (chip->bat_is_cool)
-		chg_current = min(chg_current, chip->cool_bat_chg_ma);
-
-	if (chip->bat_is_warm)
-		chg_current = min(chg_current, chip->warm_bat_chg_ma);
-
-	if (chip->therm_lvl_sel != 0 && chip->thermal_mitigation)
-		chg_current = min(chg_current,
-			chip->thermal_mitigation[chip->therm_lvl_sel]);
-
-	pr_debug("setting %d mA\n", chg_current);
-	qpnp_chg_ibatmax_set(chip, chg_current);
-}
-
-static void
 qpnp_batt_system_temp_level_set(struct qpnp_chg_chip *chip, int lvl_sel)
 {
 	if (lvl_sel >= 0 && lvl_sel < chip->thermal_levels) {
@@ -3482,9 +3603,6 @@
 		chip->bat_is_cool = bat_cool;
 		chip->bat_is_warm = bat_warm;
 
-		if (bat_cool || bat_warm)
-			chip->resuming_charging = false;
-
 		/**
 		 * set appropriate voltages and currents.
 		 *
@@ -3492,9 +3610,25 @@
 		 * driver will not resume with SoC. Only vbatdet is used to
 		 * determine resume of charging.
 		 */
-		qpnp_chg_set_appropriate_vddmax(chip);
-		qpnp_chg_set_appropriate_battery_current(chip);
-		qpnp_chg_set_appropriate_vbatdet(chip);
+		if (bat_cool || bat_warm) {
+			chip->resuming_charging = false;
+			qpnp_chg_set_appropriate_vbatdet(chip);
+
+			/* To avoid ARB, only vbatdet is configured in
+			 * warm/cold zones. Once vbat < vbatdet the
+			 * appropriate vddmax/ibatmax adjustments will
+			 * be made in the fast charge interrupt. */
+			bypass_vbatdet_comp(chip, 1);
+			qpnp_chg_charge_en(chip, !chip->charging_disabled);
+			qpnp_chg_charge_en(chip, chip->charging_disabled);
+			qpnp_chg_charge_en(chip, !chip->charging_disabled);
+		} else {
+			bypass_vbatdet_comp(chip, 0);
+			/* restore normal parameters */
+			qpnp_chg_set_appropriate_vbatdet(chip);
+			qpnp_chg_set_appropriate_vddmax(chip);
+			qpnp_chg_set_appropriate_battery_current(chip);
+		}
 	}
 
 	pr_debug("warm %d, cool %d, low = %d deciDegC, high = %d deciDegC\n",
@@ -3977,7 +4111,8 @@
 
 			rc |= devm_request_irq(chip->dev, chip->chg_fastchg.irq,
 					qpnp_chg_chgr_chg_fastchg_irq_handler,
-					IRQF_TRIGGER_RISING,
+					IRQF_TRIGGER_RISING |
+					IRQF_TRIGGER_FALLING,
 					"fast-chg-on", chip);
 			if (rc < 0) {
 				pr_err("Can't request %d fast-chg-on: %d\n",
@@ -4623,6 +4758,9 @@
 	chip->ibat_calibration_enabled =
 			of_property_read_bool(chip->spmi->dev.of_node,
 					"qcom,ibat-calibration-enabled");
+	chip->parallel_ovp_mode =
+			of_property_read_bool(chip->spmi->dev.of_node,
+					"qcom,parallel-ovp-mode");
 
 	of_get_property(chip->spmi->dev.of_node, "qcom,thermal-mitigation",
 		&(chip->thermal_levels));
diff --git a/drivers/rtc/qpnp-rtc.c b/drivers/rtc/qpnp-rtc.c
index bfbae78..d64b577 100644
--- a/drivers/rtc/qpnp-rtc.c
+++ b/drivers/rtc/qpnp-rtc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-13, 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
@@ -102,6 +102,7 @@
 	int rc;
 	unsigned long secs, irq_flags;
 	u8 value[4], reg = 0, alarm_enabled = 0, ctrl_reg;
+	u8 rtc_disabled = 0, rtc_ctrl_reg;
 	struct qpnp_rtc *rtc_dd = dev_get_drvdata(dev);
 
 	rtc_tm_to_time(tm, &secs);
@@ -152,6 +153,22 @@
 	 * write operation
 	 */
 
+	/* Disable RTC H/w before writing on RTC register*/
+	rtc_ctrl_reg = rtc_dd->rtc_ctrl_reg;
+	if (rtc_ctrl_reg & BIT_RTC_ENABLE) {
+		rtc_disabled = 1;
+		rtc_ctrl_reg &= ~BIT_RTC_ENABLE;
+		rc = qpnp_write_wrapper(rtc_dd, &rtc_ctrl_reg,
+				rtc_dd->rtc_base + REG_OFFSET_RTC_CTRL, 1);
+		if (rc) {
+			dev_err(dev,
+				"Disabling of RTC control reg failed"
+					" with error:%d\n", rc);
+			goto rtc_rw_fail;
+		}
+		rtc_dd->rtc_ctrl_reg = rtc_ctrl_reg;
+	}
+
 	/* Clear WDATA[0] */
 	reg = 0x0;
 	rc = qpnp_write_wrapper(rtc_dd, &reg,
@@ -177,6 +194,20 @@
 		goto rtc_rw_fail;
 	}
 
+	/* Enable RTC H/w after writing on RTC register*/
+	if (rtc_disabled) {
+		rtc_ctrl_reg |= BIT_RTC_ENABLE;
+		rc = qpnp_write_wrapper(rtc_dd, &rtc_ctrl_reg,
+				rtc_dd->rtc_base + REG_OFFSET_RTC_CTRL, 1);
+		if (rc) {
+			dev_err(dev,
+				"Enabling of RTC control reg failed"
+					" with error:%d\n", rc);
+			goto rtc_rw_fail;
+		}
+		rtc_dd->rtc_ctrl_reg = rtc_ctrl_reg;
+	}
+
 	if (alarm_enabled) {
 		ctrl_reg |= BIT_RTC_ALARM_ENABLE;
 		rc = qpnp_write_wrapper(rtc_dd, &ctrl_reg,
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 6e7a815..c662a2b 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -345,10 +345,12 @@
 	 */
 	if (!(txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG))
 		msgv = msm_slim_get_ctrl(dev);
+	if (msgv >= 0)
+		dev->state = MSM_CTRL_AWAKE;
 	mutex_lock(&dev->tx_lock);
 	if (dev->state == MSM_CTRL_ASLEEP ||
 		((!(txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG)) &&
-		dev->state == MSM_CTRL_SLEEPING)) {
+		dev->state == MSM_CTRL_IDLE)) {
 		dev_err(dev->dev, "runtime or system PM suspended state");
 		mutex_unlock(&dev->tx_lock);
 		if (msgv >= 0)
@@ -1452,6 +1454,10 @@
 #ifdef CONFIG_PM_RUNTIME
 static int msm_slim_runtime_idle(struct device *device)
 {
+	struct platform_device *pdev = to_platform_device(device);
+	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
+	if (dev->state == MSM_CTRL_AWAKE)
+		dev->state = MSM_CTRL_IDLE;
 	dev_dbg(device, "pm_runtime: idle...\n");
 	pm_request_autosuspend(device);
 	return -EAGAIN;
@@ -1470,7 +1476,6 @@
 	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
 	int ret;
 	dev_dbg(device, "pm_runtime: suspending...\n");
-	dev->state = MSM_CTRL_SLEEPING;
 	ret = slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED);
 	if (ret) {
 		dev_err(device, "clk pause not entered:%d", ret);
@@ -1500,10 +1505,12 @@
 
 static int msm_slim_suspend(struct device *dev)
 {
-	int ret = 0;
-	if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
-		struct platform_device *pdev = to_platform_device(dev);
-		struct msm_slim_ctrl *cdev = platform_get_drvdata(pdev);
+	int ret = -EBUSY;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_slim_ctrl *cdev = platform_get_drvdata(pdev);
+	if (!pm_runtime_enabled(dev) ||
+		(!pm_runtime_suspended(dev) &&
+			cdev->state == MSM_CTRL_IDLE)) {
 		dev_dbg(dev, "system suspend");
 		ret = msm_slim_runtime_suspend(dev);
 		if (!ret) {
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index e65c8cf..f858822 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -83,6 +83,7 @@
 };
 
 static int ngd_slim_runtime_resume(struct device *device);
+static int ngd_slim_power_up(struct msm_slim_ctrl *dev);
 
 static irqreturn_t ngd_slim_interrupt(int irq, void *d)
 {
@@ -91,25 +92,25 @@
 	u32 stat = readl_relaxed(ngd + NGD_INT_STAT);
 	u32 pstat;
 
-	if (stat & NGD_INT_TX_MSG_SENT) {
+	if ((stat & NGD_INT_MSG_BUF_CONTE) ||
+		(stat & NGD_INT_MSG_TX_INVAL) || (stat & NGD_INT_DEV_ERR) ||
+		(stat & NGD_INT_TX_NACKED_2)) {
+		writel_relaxed(stat, ngd + NGD_INT_CLR);
+		dev->err = -EIO;
+
+		dev_err(dev->dev, "NGD interrupt error:0x%x, err:%d", stat,
+								dev->err);
+		/* Guarantee that error interrupts are cleared */
+		mb();
+		if (dev->wr_comp)
+			complete(dev->wr_comp);
+
+	} else if (stat & NGD_INT_TX_MSG_SENT) {
 		writel_relaxed(NGD_INT_TX_MSG_SENT, ngd + NGD_INT_CLR);
 		/* Make sure interrupt is cleared */
 		mb();
 		if (dev->wr_comp)
 			complete(dev->wr_comp);
-	} else if ((stat & NGD_INT_MSG_BUF_CONTE) ||
-		(stat & NGD_INT_MSG_TX_INVAL) || (stat & NGD_INT_DEV_ERR) ||
-		(stat & NGD_INT_TX_NACKED_2)) {
-		dev_err(dev->dev, "NGD interrupt error:0x%x", stat);
-		writel_relaxed(stat, ngd + NGD_INT_CLR);
-		/* Guarantee that error interrupts are cleared */
-		mb();
-		if (((stat & NGD_INT_TX_NACKED_2) ||
-			(stat & NGD_INT_MSG_TX_INVAL))) {
-			dev->err = -EIO;
-		if (dev->wr_comp)
-			complete(dev->wr_comp);
-		}
 	}
 	if (stat & NGD_INT_RX_MSG_RCVD) {
 		u32 rx_buf[10];
@@ -180,6 +181,41 @@
 	return 0;
 }
 
+static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code,
+				void *_cmd)
+{
+	struct msm_slim_mdm *mdm = container_of(n, struct msm_slim_mdm, nb);
+	struct msm_slim_ctrl *dev = container_of(mdm, struct msm_slim_ctrl,
+						mdm);
+	int ret;
+
+	switch (code) {
+	case SUBSYS_BEFORE_SHUTDOWN:
+		/* make sure runtime-pm doesn't suspend during modem SSR */
+		pm_runtime_get_noresume(dev->dev);
+		break;
+	case SUBSYS_AFTER_POWERUP:
+		ret = msm_slim_qmi_check_framer_request(dev);
+		dev_err(dev->dev,
+			"%s:SLIM %lu external_modem SSR notify cb, ret %d",
+			__func__, code, ret);
+		/*
+		 * Next codec transaction will reinit the HW
+		 * if it was suspended
+		 */
+		if (pm_runtime_suspended(dev->dev) ||
+			dev->state >= MSM_CTRL_ASLEEP) {
+			break;
+		} else {
+			ngd_slim_power_up(dev);
+			msm_slim_put_ctrl(dev);
+		}
+	default:
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
 static int ngd_get_tid(struct slim_controller *ctrl, struct slim_msg_txn *txn,
 				u8 *tid, struct completion *done)
 {
@@ -243,7 +279,7 @@
 	}
 	if ((txn->mc == (SLIM_MSG_CLK_PAUSE_SEQ_FLG |
 			SLIM_MSG_MC_RECONFIGURE_NOW)) &&
-			dev->state <= MSM_CTRL_SLEEPING) {
+			dev->state <= MSM_CTRL_IDLE) {
 		msm_slim_disconnect_endp(dev, &dev->rx_msgq,
 					&dev->use_rx_msgqs);
 		msm_slim_disconnect_endp(dev, &dev->tx_msgq,
@@ -305,7 +341,20 @@
 			if (!timeout && dev->state == MSM_CTRL_DOWN)
 				return -ETIMEDOUT;
 		}
-		msm_slim_get_ctrl(dev);
+		ret = msm_slim_get_ctrl(dev);
+		/*
+		 * Runtime-pm's callbacks are not called until runtime-pm's
+		 * error status is cleared
+		 * Setting runtime status to suspended clears the error
+		 * It also makes HW status cosistent with what SW has it here
+		 */
+		if (ret == -ENETRESET && dev->state == MSM_CTRL_DOWN) {
+			pm_runtime_set_suspended(dev->dev);
+			msm_slim_put_ctrl(dev);
+			return -EREMOTEIO;
+		} else if (ret >= 0) {
+			dev->state = MSM_CTRL_AWAKE;
+		}
 	}
 	mutex_lock(&dev->tx_lock);
 
@@ -507,17 +556,12 @@
 			ret = -ETIMEDOUT;
 		else
 			ret = txn->ec;
-	} else if (ret == -EREMOTEIO &&
-			(txn->mc == SLIM_USR_MC_CHAN_CTRL ||
-			 txn->mc == SLIM_USR_MC_DISCONNECT_PORT)) {
-		/* HW restarting, channel/port removal should succeed */
-		return 0;
 	}
 
 	if (ret) {
-		pr_err("master msg:0x%x,tid:%d ret:%d", txn->mc,
+		if (ret != -EREMOTEIO || txn->mc != SLIM_USR_MC_CHAN_CTRL)
+			pr_err("master msg:0x%x,tid:%d ret:%d", txn->mc,
 				txn->tid, ret);
-		WARN(1, "timeout during xfer and wait");
 		mutex_lock(&ctrl->m_ctrl);
 		ctrl->txnt[txn->tid] = NULL;
 		mutex_unlock(&ctrl->m_ctrl);
@@ -642,7 +686,10 @@
 		txn.mc = SLIM_USR_MC_CHAN_CTRL;
 		txn.rl = txn.len + 4;
 		ret = ngd_xferandwait_ack(ctrl, &txn);
-		if (ret)
+		/* HW restarting, channel removal should succeed */
+		if (ret == -EREMOTEIO)
+			return 0;
+		else if (ret)
 			return ret;
 
 		txn.mc = SLIM_USR_MC_RECONFIG_NOW;
@@ -758,6 +805,7 @@
 		ret = ngd_xfer_msg(&dev->ctrl, &txn);
 		if (!ret) {
 			enum msm_ctrl_state prev_state = dev->state;
+			pr_info("SLIM SAT: capability exchange successful");
 			dev->state = MSM_CTRL_AWAKE;
 			if (prev_state >= MSM_CTRL_ASLEEP)
 				complete(&dev->reconf);
@@ -829,7 +877,7 @@
 static int ngd_slim_power_up(struct msm_slim_ctrl *dev)
 {
 	void __iomem *ngd;
-	int timeout, ret;
+	int timeout, ret = 0;
 	enum msm_ctrl_state cur_state = dev->state;
 	u32 laddr;
 	u32 ngd_int = (NGD_INT_TX_NACKED_2 |
@@ -844,10 +892,13 @@
 			pr_err("slimbus QMI init timed out");
 	}
 
-	ret = msm_slim_qmi_power_request(dev, true);
-	if (ret) {
-		pr_err("SLIM QMI power request failed:%d", ret);
-		return ret;
+	/* No need to vote if contorller is not in low power mode */
+	if (cur_state == MSM_CTRL_DOWN || cur_state == MSM_CTRL_ASLEEP) {
+		ret = msm_slim_qmi_power_request(dev, true);
+		if (ret) {
+			pr_err("SLIM QMI power request failed:%d", ret);
+			return ret;
+		}
 	}
 	if (!dev->ver) {
 		dev->ver = readl_relaxed(dev->base);
@@ -858,14 +909,35 @@
 	laddr = readl_relaxed(ngd + NGD_STATUS);
 	if (laddr & NGD_LADDR) {
 		/*
+		 * external MDM restart case where ADSP itself was active framer
+		 * For example, modem restarted when playback was active
+		 */
+		if (cur_state == MSM_CTRL_AWAKE) {
+			pr_err("SLIM MDM restart: ADSP active framer:NO OP");
+			return 0;
+		}
+		/*
 		 * ADSP power collapse case, where HW wasn't reset.
 		 * Reconnect BAM pipes if disconnected
 		 */
 		ngd_slim_setup_msg_path(dev);
 		return 0;
-	} else if (cur_state != MSM_CTRL_DOWN) {
-		pr_info("ADSP P.C. CTRL state:%d NGD not enumerated:0x%x",
+	} else if (cur_state == MSM_CTRL_ASLEEP) {
+		pr_debug("ADSP P.C. CTRL state:%d NGD not enumerated:0x%x",
 					dev->state, laddr);
+	} else if (cur_state == MSM_CTRL_IDLE || cur_state == MSM_CTRL_AWAKE) {
+		/*
+		 * external MDM SSR when only voice call is in progress.
+		 * ADSP will reset slimbus HW. disconnect BAM pipes so that
+		 * they can be connected after capability message is received.
+		 * Set device state to ASLEEP to be synchronous with the HW
+		 */
+		pr_err("SLIM MDM restart: MDM active framer: reinit HW");
+		dev->state = MSM_CTRL_ASLEEP;
+		msm_slim_disconnect_endp(dev, &dev->rx_msgq,
+					&dev->use_rx_msgqs);
+		msm_slim_disconnect_endp(dev, &dev->tx_msgq,
+					&dev->use_tx_msgqs);
 	}
 	/* ADSP SSR scenario, need to disconnect pipe before connecting */
 	if (dev->use_rx_msgqs == MSM_MSGQ_DOWN) {
@@ -896,7 +968,7 @@
 
 	timeout = wait_for_completion_timeout(&dev->reconf, HZ);
 	if (!timeout) {
-		pr_err("failed to received master capability");
+		pr_err("Failed to receive master capability");
 		return -ETIMEDOUT;
 	}
 	if (cur_state == MSM_CTRL_DOWN)
@@ -999,11 +1071,13 @@
 		container_of(work, struct msm_slim_ctrl, slave_notify);
 	struct slim_controller *ctrl = &dev->ctrl;
 	struct slim_device *sbdev;
+	struct list_head *pos, *next;
 	int i;
 	slim_framer_booted(ctrl);
 	mutex_lock(&ctrl->m_ctrl);
-	list_for_each_entry(sbdev, &ctrl->devs, dev_list) {
+	list_for_each_safe(pos, next, &ctrl->devs) {
 		int ret = 0;
+		sbdev = list_entry(pos, struct slim_device, dev_list);
 		mutex_unlock(&ctrl->m_ctrl);
 		for (i = 0; i < LADDR_RETRY; i++) {
 			ret = slim_get_logical_addr(sbdev, sbdev->e_addr,
@@ -1058,6 +1132,7 @@
 	struct resource		*irq, *bam_irq;
 	enum apr_subsys_state q6_state;
 	bool			rxreg_access = false;
+	bool			slim_mdm = false;
 
 	q6_state = apr_get_q6_state();
 	if (q6_state == APR_SUBSYS_DOWN) {
@@ -1126,6 +1201,8 @@
 					&dev->pdata.apps_pipes);
 		of_property_read_u32(pdev->dev.of_node, "qcom,ea-pc",
 					&dev->pdata.eapc);
+		slim_mdm = of_property_read_bool(pdev->dev.of_node,
+					"qcom,slim-mdm");
 	} else {
 		dev->ctrl.nr = pdev->id;
 	}
@@ -1195,12 +1272,23 @@
 	pm_runtime_set_suspended(dev->dev);
 	pm_runtime_enable(dev->dev);
 
+	if (slim_mdm) {
+		dev->mdm.nb.notifier_call = mdm_ssr_notify_cb;
+		dev->mdm.ssr = subsys_notif_register_notifier("external_modem",
+							&dev->mdm.nb);
+		if (IS_ERR_OR_NULL(dev->mdm.ssr))
+			dev_err(dev->dev,
+				"subsys_notif_register_notifier failed %p",
+				dev->mdm.ssr);
+	}
+
 	INIT_WORK(&dev->slave_notify, ngd_laddr_lookup);
 	INIT_WORK(&dev->qmi.ssr_down, ngd_adsp_down);
 	INIT_WORK(&dev->qmi.ssr_up, ngd_adsp_up);
 	dev->qmi.nb.notifier_call = ngd_qmi_available;
 	pm_runtime_get_noresume(dev->dev);
 	ret = qmi_svc_event_notifier_register(SLIMBUS_QMI_SVC_ID,
+				SLIMBUS_QMI_SVC_V1,
 				SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
 	if (ret) {
 		pr_err("Slimbus QMI service registration failed:%d", ret);
@@ -1228,6 +1316,7 @@
 
 err_thread_create_failed:
 	qmi_svc_event_notifier_unregister(SLIMBUS_QMI_SVC_ID,
+				SLIMBUS_QMI_SVC_V1,
 				SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
 qmi_register_failed:
 	free_irq(dev->irq, dev);
@@ -1247,8 +1336,11 @@
 	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
 	ngd_slim_enable(dev, false);
 	qmi_svc_event_notifier_unregister(SLIMBUS_QMI_SVC_ID,
+				SLIMBUS_QMI_SVC_V1,
 				SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
 	pm_runtime_disable(&pdev->dev);
+	if (!IS_ERR_OR_NULL(dev->mdm.ssr))
+		subsys_notif_unregister_notifier(dev->mdm.ssr, &dev->mdm.nb);
 	free_irq(dev->irq, dev);
 	slim_del_controller(&dev->ctrl);
 	kthread_stop(dev->rx_msgq_thread);
@@ -1261,6 +1353,10 @@
 #ifdef CONFIG_PM_RUNTIME
 static int ngd_slim_runtime_idle(struct device *device)
 {
+	struct platform_device *pdev = to_platform_device(device);
+	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
+	if (dev->state == MSM_CTRL_AWAKE)
+		dev->state = MSM_CTRL_IDLE;
 	dev_dbg(device, "pm_runtime: idle...\n");
 	pm_request_autosuspend(device);
 	return -EAGAIN;
@@ -1280,8 +1376,11 @@
 	if (dev->state >= MSM_CTRL_ASLEEP)
 		ret = slim_ctrl_clk_pause(&dev->ctrl, true, 0);
 	if (ret) {
-		dev_err(device, "clk pause not exited:%d", ret);
-		dev->state = MSM_CTRL_ASLEEP;
+		/* Did SSR cause this clock pause failure */
+		if (dev->state != MSM_CTRL_DOWN)
+			dev->state = MSM_CTRL_ASLEEP;
+		else
+			dev_err(device, "HW wakeup attempt during SSR");
 	} else {
 		dev->state = MSM_CTRL_AWAKE;
 	}
@@ -1294,7 +1393,6 @@
 	struct platform_device *pdev = to_platform_device(device);
 	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
 	int ret = 0;
-	dev->state = MSM_CTRL_SLEEPING;
 	ret = slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED);
 	if (ret) {
 		if (ret != -EBUSY)
@@ -1309,7 +1407,11 @@
 static int ngd_slim_suspend(struct device *dev)
 {
 	int ret = -EBUSY;
-	if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_slim_ctrl *cdev = platform_get_drvdata(pdev);
+	if (!pm_runtime_enabled(dev) ||
+		(!pm_runtime_suspended(dev) &&
+			cdev->state == MSM_CTRL_IDLE)) {
 		dev_dbg(dev, "system suspend");
 		ret = ngd_slim_runtime_suspend(dev);
 		/*
diff --git a/drivers/slimbus/slim-msm.c b/drivers/slimbus/slim-msm.c
index 37bc883..5d30e54 100644
--- a/drivers/slimbus/slim-msm.c
+++ b/drivers/slimbus/slim-msm.c
@@ -69,7 +69,7 @@
 	if (ref <= 0)
 		dev_err(dev->dev, "reference count mismatch:%d", ref);
 	else
-		pm_runtime_put(dev->dev);
+		pm_runtime_put_sync(dev->dev);
 #endif
 }
 
@@ -392,7 +392,7 @@
 	struct sps_pipe *pipe = endpoint->sps;
 	int ix = (buf - (u8 *)mem->base) / SLIM_MSGQ_BUF_LEN;
 
-	u32 phys_addr = mem->phys_base + (SLIM_MSGQ_BUF_LEN * ix);
+	phys_addr_t phys_addr = mem->phys_base + (SLIM_MSGQ_BUF_LEN * ix);
 
 	for (ret = 0; ret < ((len + 3) >> 2); ret++)
 		pr_debug("BAM TX buf[%d]:0x%x", ret, ((u32 *)buf)[ret]);
@@ -425,7 +425,7 @@
 	}
 
 	/* Calculate buffer index */
-	dev->tx_idx = (iovec.addr - mem->phys_base) / SLIM_MSGQ_BUF_LEN;
+	dev->tx_idx = ((int)(iovec.addr - mem->phys_base)) / SLIM_MSGQ_BUF_LEN;
 
 	return (u32 *)((u8 *)mem->base + (dev->tx_idx * SLIM_MSGQ_BUF_LEN));
 }
@@ -500,9 +500,9 @@
 
 	/* Rx message queue buffers are 4 bytes in length */
 	u8 *virt_addr = mem->base + (4 * ix);
-	u32 phys_addr = mem->phys_base + (4 * ix);
+	phys_addr_t phys_addr = mem->phys_base + (4 * ix);
 
-	pr_debug("index:%d, phys:0x%x, virt:0x%p\n", ix, phys_addr, virt_addr);
+	pr_debug("index:%d, virt:0x%p\n", ix, virt_addr);
 
 	ret = sps_transfer_one(pipe, phys_addr, 4, virt_addr, flags);
 	if (ret)
@@ -884,11 +884,14 @@
 #define SLIMBUS_QMI_SELECT_INSTANCE_RESP_V01 0x0020
 #define SLIMBUS_QMI_POWER_REQ_V01 0x0021
 #define SLIMBUS_QMI_POWER_RESP_V01 0x0021
+#define SLIMBUS_QMI_CHECK_FRAMER_STATUS_REQ 0x0022
+#define SLIMBUS_QMI_CHECK_FRAMER_STATUS_RESP 0x0022
 
 #define SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN 7
 #define SLIMBUS_QMI_POWER_RESP_MAX_MSG_LEN 7
 #define SLIMBUS_QMI_SELECT_INSTANCE_REQ_MAX_MSG_LEN 14
 #define SLIMBUS_QMI_SELECT_INSTANCE_RESP_MAX_MSG_LEN 7
+#define SLIMBUS_QMI_CHECK_FRAMER_STAT_RESP_MAX_MSG_LEN 7
 
 enum slimbus_mode_enum_type_v01 {
 	/* To force a 32 bit signed enum. Do not change or use*/
@@ -936,6 +939,13 @@
 	struct qmi_response_type_v01 resp;
 };
 
+struct slimbus_chkfrm_resp_msg {
+	/* Mandatory */
+	/* Result Code */
+	struct qmi_response_type_v01 resp;
+};
+
+
 static struct elem_info slimbus_select_inst_req_msg_v01_ei[] = {
 	{
 		.data_type = QMI_UNSIGNED_4_BYTE,
@@ -1042,6 +1052,27 @@
 	},
 };
 
+static struct elem_info slimbus_chkfrm_resp_msg_v01_ei[] = {
+	{
+		.data_type = QMI_STRUCT,
+		.elem_len  = 1,
+		.elem_size = sizeof(struct qmi_response_type_v01),
+		.is_array  = NO_ARRAY,
+		.tlv_type  = 0x02,
+		.offset    = offsetof(struct slimbus_chkfrm_resp_msg, resp),
+		.ei_array  = get_qmi_response_type_v01_ei(),
+	},
+	{
+		.data_type = QMI_EOTI,
+		.elem_len  = 0,
+		.elem_size = 0,
+		.is_array  = NO_ARRAY,
+		.tlv_type  = 0x00,
+		.offset    = 0,
+		.ei_array  = NULL,
+	},
+};
+
 static void msm_slim_qmi_recv_msg(struct kthread_work *work)
 {
 	int rc;
@@ -1174,6 +1205,7 @@
 	}
 
 	rc = qmi_connect_to_service(handle, SLIMBUS_QMI_SVC_ID,
+						SLIMBUS_QMI_SVC_V1,
 						SLIMBUS_QMI_INS_ID);
 	if (rc < 0) {
 		pr_err("%s: QMI server not found\n", __func__);
@@ -1231,3 +1263,32 @@
 
 	return msm_slim_qmi_send_power_request(dev, &req);
 }
+
+int msm_slim_qmi_check_framer_request(struct msm_slim_ctrl *dev)
+{
+	struct slimbus_chkfrm_resp_msg resp = { { 0, 0 } };
+	struct msg_desc req_desc, resp_desc;
+	int rc;
+
+	req_desc.msg_id = SLIMBUS_QMI_CHECK_FRAMER_STATUS_REQ;
+	req_desc.max_msg_len = 0;
+	req_desc.ei_array = NULL;
+
+	resp_desc.msg_id = SLIMBUS_QMI_CHECK_FRAMER_STATUS_RESP;
+	resp_desc.max_msg_len = SLIMBUS_QMI_CHECK_FRAMER_STAT_RESP_MAX_MSG_LEN;
+	resp_desc.ei_array = slimbus_chkfrm_resp_msg_v01_ei;
+
+	rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, NULL, 0,
+					&resp_desc, &resp, sizeof(resp), 5000);
+	if (rc < 0) {
+		dev_err(dev->dev, "%s: QMI send req failed %d\n", __func__, rc);
+		return rc;
+	}
+	/* Check the response */
+	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
+		dev_err(dev->dev, "%s: QMI request failed 0x%x (%s)\n",
+			__func__, resp.resp.result, get_qmi_error(&resp.resp));
+		return -EREMOTEIO;
+	}
+	return 0;
+}
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
index b5c41ed..5ffa300 100644
--- a/drivers/slimbus/slim-msm.h
+++ b/drivers/slimbus/slim-msm.h
@@ -16,6 +16,7 @@
 #include <linux/irq.h>
 #include <linux/kthread.h>
 #include <mach/msm_qmi_interface.h>
+#include <mach/subsystem_notif.h>
 
 /* Per spec.max 40 bytes per received message */
 #define SLIM_MSGQ_BUF_LEN	40
@@ -82,7 +83,8 @@
 
 /* Slimbus QMI service */
 #define SLIMBUS_QMI_SVC_ID 0x0301
-#define SLIMBUS_QMI_INS_ID 1
+#define SLIMBUS_QMI_SVC_V1 1
+#define SLIMBUS_QMI_INS_ID 0
 
 #define PGD_THIS_EE(r, v) ((v) ? PGD_THIS_EE_V2(r) : PGD_THIS_EE_V1(r))
 #define PGD_PORT(r, p, v) ((v) ? PGD_PORT_V2(r, p) : PGD_PORT_V1(r, p))
@@ -168,7 +170,7 @@
 
 enum msm_ctrl_state {
 	MSM_CTRL_AWAKE,
-	MSM_CTRL_SLEEPING,
+	MSM_CTRL_IDLE,
 	MSM_CTRL_ASLEEP,
 	MSM_CTRL_DOWN,
 };
@@ -205,6 +207,11 @@
 	struct work_struct		ssr_up;
 };
 
+struct msm_slim_mdm {
+	struct notifier_block nb;
+	void *ssr;
+};
+
 struct msm_slim_pdata {
 	u32 apps_pipes;
 	u32 eapc;
@@ -253,6 +260,7 @@
 	struct work_struct	slave_notify;
 	struct msm_slim_qmi	qmi;
 	struct msm_slim_pdata	pdata;
+	struct msm_slim_mdm	mdm;
 };
 
 struct msm_sat_chan {
@@ -317,4 +325,5 @@
 void msm_slim_qmi_exit(struct msm_slim_ctrl *dev);
 int msm_slim_qmi_init(struct msm_slim_ctrl *dev, bool apps_is_master);
 int msm_slim_qmi_power_request(struct msm_slim_ctrl *dev, bool active);
+int msm_slim_qmi_check_framer_request(struct msm_slim_ctrl *dev);
 #endif
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 96fe2a8..caf7a87 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -288,37 +288,29 @@
 
 static void slim_report(struct work_struct *work)
 {
-	u8 laddr;
-	int ret, i;
 	struct slim_driver *sbdrv;
 	struct slim_device *sbdev =
 			container_of(work, struct slim_device, wd);
-	struct slim_controller *ctrl = sbdev->ctrl;
 	if (!sbdev->dev.driver)
 		return;
 	/* check if device-up or down needs to be called */
-	mutex_lock(&ctrl->m_ctrl);
-	/* address no longer valid, means device reported absent */
-	for (i = 0; i < ctrl->num_dev; i++) {
-		if (sbdev->laddr == ctrl->addrt[i].laddr &&
-			ctrl->addrt[i].valid == false &&
-			sbdev->notified)
-			break;
-	}
-	mutex_unlock(&ctrl->m_ctrl);
+	if ((!sbdev->reported && !sbdev->notified) ||
+			(sbdev->reported && sbdev->notified))
+		return;
+
 	sbdrv = to_slim_driver(sbdev->dev.driver);
-	if (i < ctrl->num_dev) {
+	/*
+	 * address no longer valid, means device reported absent, whereas
+	 * address valid, means device reported present
+	 */
+	if (sbdev->notified && !sbdev->reported) {
 		sbdev->notified = false;
 		if (sbdrv->device_down)
 			sbdrv->device_down(sbdev);
-		return;
-	}
-	if (sbdev->notified || !sbdrv)
-		return;
-	ret = slim_get_logical_addr(sbdev, sbdev->e_addr, 6, &laddr);
-	if (!ret) {
+	} else if (!sbdev->notified && sbdev->reported) {
 		sbdev->notified = true;
-		sbdrv->device_up(sbdev);
+		if (sbdrv->device_up)
+			sbdrv->device_up(sbdev);
 	}
 }
 
@@ -643,6 +635,7 @@
 			ctrl->addrt[i].valid = false;
 	}
 	mutex_unlock(&ctrl->m_ctrl);
+	sbdev->reported = false;
 	queue_work(ctrl->wq, &sbdev->wd);
 }
 EXPORT_SYMBOL(slim_report_absent);
@@ -696,9 +689,12 @@
 
 	mutex_lock(&ctrl->m_ctrl);
 	txn = ctrl->txnt[tid];
-	if (txn == NULL) {
-		dev_err(&ctrl->dev, "Got response to invalid TID:%d, len:%d",
+	if (txn == NULL || txn->rbuf == NULL) {
+		if (txn == NULL)
+			dev_err(&ctrl->dev, "Got response to invalid TID:%d, len:%d",
 				tid, len);
+		else
+			dev_err(&ctrl->dev, "Invalid client buffer passed\n");
 		mutex_unlock(&ctrl->m_ctrl);
 		return;
 	}
@@ -801,6 +797,8 @@
 	u8 i = 0;
 	bool exists = false;
 	struct slim_device *sbdev;
+	struct list_head *pos, *next;
+
 	mutex_lock(&ctrl->m_ctrl);
 	/* already assigned */
 	if (ctrl_getlogical_addr(ctrl, e_addr, e_len, &i) == 0) {
@@ -850,10 +848,12 @@
 	pr_info("slimbus:%d laddr:0x%x, EAPC:0x%x:0x%x", ctrl->nr, *laddr,
 				e_addr[1], e_addr[2]);
 	mutex_lock(&ctrl->m_ctrl);
-	list_for_each_entry(sbdev, &ctrl->devs, dev_list) {
+	list_for_each_safe(pos, next, &ctrl->devs) {
+		sbdev = list_entry(pos, struct slim_device, dev_list);
 		if (memcmp(sbdev->e_addr, e_addr, 6) == 0) {
 			struct slim_driver *sbdrv;
 			sbdev->laddr = *laddr;
+			sbdev->reported = true;
 			if (sbdev->dev.driver) {
 				sbdrv = to_slim_driver(sbdev->dev.driver);
 				if (sbdrv->device_up)
@@ -1553,7 +1553,8 @@
 	for (j = *len - 1; j > i; j--)
 		arr[j] = arr[j - 1];
 	arr[i] = slc;
-	ctrl->sched.usedslots += sl;
+	if (!ctrl->allocbw)
+		ctrl->sched.usedslots += sl;
 
 	return;
 }
@@ -2659,7 +2660,8 @@
 				u32 sl = slc->seglen << slc->rootexp;
 				if (slc->coeff == SLIM_COEFF_3)
 					sl *= 3;
-				ctrl->sched.usedslots -= sl;
+				if (!ctrl->allocbw)
+					ctrl->sched.usedslots -= sl;
 				slim_remove_ch(ctrl, slc);
 				slc->state = SLIM_CH_DEFINED;
 			}
@@ -2680,7 +2682,8 @@
 		if (revert || slc->def > 0) {
 			if (slc->coeff == SLIM_COEFF_3)
 				sl *= 3;
-			ctrl->sched.usedslots += sl;
+			if (!ctrl->allocbw)
+				ctrl->sched.usedslots += sl;
 			if (revert)
 				slc->def++;
 			slc->state = SLIM_CH_ACTIVE;
@@ -2774,7 +2777,8 @@
 		u32 sl = slc->seglen << slc->rootexp;
 		if (slc->coeff == SLIM_COEFF_3)
 			sl *= 3;
-		ctrl->sched.usedslots -= sl;
+		if (!ctrl->allocbw)
+			ctrl->sched.usedslots -= sl;
 		slc->state = SLIM_CH_PENDING_REMOVAL;
 	}
 	list_for_each_entry(pch, &sb->mark_suspend, pending) {
@@ -3036,7 +3040,7 @@
 					pch = list_entry(pos,
 						struct slim_pending_ch,
 						pending);
-					if (pch->chan == slc->chan) {
+					if (pch->chan == chan) {
 						list_del(&pch->pending);
 						kfree(pch);
 						add_mark_removal = false;
@@ -3129,8 +3133,15 @@
 		 */
 		if (ctrl->clk_state == SLIM_CLK_PAUSED && ctrl->wakeup)
 			ret = ctrl->wakeup(ctrl);
+		/*
+		 * If wakeup fails, make sure that next attempt can succeed.
+		 * Since we already consumed pause_comp, complete it so
+		 * that next wakeup isn't blocked forever
+		 */
 		if (!ret)
 			ctrl->clk_state = SLIM_CLK_ACTIVE;
+		else
+			complete(&ctrl->pause_comp);
 		mutex_unlock(&ctrl->m_ctrl);
 		return ret;
 	} else {
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 891eb2f..73513ec 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -1769,6 +1769,18 @@
 	int ret = 0;
 	uint32_t cpu;
 
+	for_each_possible_cpu(cpu) {
+		cpus[cpu].cpu = cpu;
+		cpus[cpu].offline = 0;
+		cpus[cpu].user_offline = 0;
+		cpus[cpu].hotplug_thresh_clear = false;
+		cpus[cpu].max_freq = false;
+		cpus[cpu].user_max_freq = UINT_MAX;
+		cpus[cpu].user_min_freq = 0;
+		cpus[cpu].limited_max_freq = UINT_MAX;
+		cpus[cpu].limited_min_freq = 0;
+		cpus[cpu].freq_thresh_clear = false;
+	}
 	BUG_ON(!pdata);
 	tsens_get_max_sensor_num(&max_tsens_num);
 	memcpy(&msm_thermal_info, pdata, sizeof(struct msm_thermal_data));
@@ -1779,10 +1791,6 @@
 		return -EINVAL;
 
 	enabled = 1;
-	for_each_possible_cpu(cpu) {
-		cpus[cpu].limited_max_freq = UINT_MAX;
-		cpus[cpu].limited_min_freq = 0;
-	}
 	ret = cpufreq_register_notifier(&msm_thermal_cpufreq_notifier,
 			CPUFREQ_POLICY_NOTIFIER);
 	if (ret)
@@ -2433,10 +2441,6 @@
 	}
 
 	for_each_possible_cpu(cpu) {
-		cpus[cpu].cpu = cpu;
-		cpus[cpu].offline = 0;
-		cpus[cpu].user_offline = 0;
-		cpus[cpu].hotplug_thresh_clear = false;
 		ret = of_property_read_string_index(node, key, cpu,
 				&cpus[cpu].sensor_type);
 		if (ret)
@@ -2470,7 +2474,6 @@
 {
 	char *key = NULL;
 	int ret = 0;
-	uint32_t cpu;
 
 	key = "qcom,freq-mitigation-temp";
 	ret = of_property_read_u32(node, key, &data->freq_mitig_temp_degc);
@@ -2494,14 +2497,6 @@
 		goto PROBE_FREQ_EXIT;
 
 	freq_mitigation_enabled = 1;
-	for_each_possible_cpu(cpu) {
-		cpus[cpu].max_freq = false;
-		cpus[cpu].user_max_freq = UINT_MAX;
-		cpus[cpu].user_min_freq = 0;
-		cpus[cpu].limited_max_freq = UINT_MAX;
-		cpus[cpu].limited_min_freq = 0;
-		cpus[cpu].freq_thresh_clear = false;
-	}
 
 PROBE_FREQ_EXIT:
 	if (ret) {
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index efb87a9..eb647fa 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -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
@@ -471,16 +471,30 @@
 		struct qpnp_adc_tm_chip *chip, uint32_t btm_chan,
 		struct qpnp_vadc_chan_properties *chan_prop)
 {
-	int rc;
-	u8 meas_interval_timer2 = 0;
+	int rc, chan_idx = 0, i = 0;
+	bool chan_found = false;
+	u8 meas_interval_timer2 = 0, timer_interval_store = 0;
 	uint32_t btm_chan_idx = 0;
 
-	/* Configure kernel clients to timer1 */
-	switch (chan_prop->timer_select) {
+	while (i < chip->max_channels_available) {
+		if (chip->sensor[i].btm_channel_num == btm_chan) {
+			chan_idx = i;
+			chan_found = true;
+			i++;
+		} else
+			i++;
+	}
+
+	if (!chan_found) {
+		pr_err("Channel not found\n");
+		return -EINVAL;
+	}
+
+	switch (chip->sensor[chan_idx].timer_select) {
 	case ADC_MEAS_TIMER_SELECT1:
 		rc = qpnp_adc_tm_write_reg(chip,
 				QPNP_ADC_TM_MEAS_INTERVAL_CTL,
-				chan_prop->meas_interval1);
+				chip->sensor[chan_idx].meas_interval);
 		if (rc < 0) {
 			pr_err("timer1 configure failed\n");
 			return rc;
@@ -495,9 +509,10 @@
 			pr_err("timer2 configure read failed\n");
 			return rc;
 		}
-		meas_interval_timer2 |=
-			(chan_prop->meas_interval2 <<
-			QPNP_ADC_TM_MEAS_INTERVAL_CTL2_SHIFT);
+		timer_interval_store = chip->sensor[chan_idx].meas_interval;
+		timer_interval_store <<= QPNP_ADC_TM_MEAS_INTERVAL_CTL2_SHIFT;
+		timer_interval_store &= QPNP_ADC_TM_MEAS_INTERVAL_CTL2_MASK;
+		meas_interval_timer2 |= timer_interval_store;
 		rc = qpnp_adc_tm_write_reg(chip,
 			QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
 			meas_interval_timer2);
@@ -514,8 +529,9 @@
 			pr_err("timer3 read failed\n");
 			return rc;
 		}
-		chan_prop->meas_interval2 = ADC_MEAS3_INTERVAL_1S;
-		meas_interval_timer2 |= chan_prop->meas_interval2;
+		timer_interval_store = chip->sensor[chan_idx].meas_interval;
+		timer_interval_store &= QPNP_ADC_TM_MEAS_INTERVAL_CTL3_MASK;
+		meas_interval_timer2 |= timer_interval_store;
 		rc = qpnp_adc_tm_write_reg(chip,
 			QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
 			meas_interval_timer2);
@@ -535,7 +551,18 @@
 		pr_err("Invalid btm channel idx\n");
 		return rc;
 	}
-	adc_tm_data[btm_chan_idx].meas_interval_ctl = chan_prop->timer_select;
+	rc = qpnp_adc_tm_write_reg(chip,
+			adc_tm_data[btm_chan_idx].meas_interval_ctl,
+				chip->sensor[chan_idx].timer_select);
+	if (rc < 0) {
+		pr_err("TM channel timer configure failed\n");
+		return rc;
+	}
+
+	pr_debug("timer select:%d, timer_value_within_select:%d, channel:%x\n",
+			chip->sensor[chan_idx].timer_select,
+			chip->sensor[chan_idx].meas_interval,
+			btm_chan);
 
 	return rc;
 }
@@ -954,10 +981,6 @@
 			chip->adc->adc_channels[channel].fast_avg_setup;
 		chip->adc->amux_prop->mode_sel =
 			ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
-		chip->adc->amux_prop->chan_prop->timer_select =
-					ADC_MEAS_TIMER_SELECT1;
-		chip->adc->amux_prop->chan_prop->meas_interval1 =
-						ADC_MEAS1_INTERVAL_1S;
 		chip->adc->amux_prop->chan_prop->low_thr = adc_tm->low_thr;
 		chip->adc->amux_prop->chan_prop->high_thr = adc_tm->high_thr;
 		chip->adc->amux_prop->chan_prop->tm_channel_select =
@@ -1673,8 +1696,6 @@
 			chip->adc->adc_channels[dt_index].fast_avg_setup;
 	chip->adc->amux_prop->mode_sel =
 		ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
-	chip->adc->amux_prop->chan_prop->meas_interval1 =
-						ADC_MEAS1_INTERVAL_1S;
 	adc_tm_rscale_fn[scale_type].chan(chip->vadc_dev, param,
 			&chip->adc->amux_prop->chan_prop->low_thr,
 			&chip->adc->amux_prop->chan_prop->high_thr);
@@ -1682,8 +1703,6 @@
 				chip->adc->amux_prop->chan_prop);
 	chip->adc->amux_prop->chan_prop->tm_channel_select =
 				chip->sensor[dt_index].btm_channel_num;
-	chip->adc->amux_prop->chan_prop->timer_select =
-					ADC_MEAS_TIMER_SELECT1;
 	chip->adc->amux_prop->chan_prop->state_request =
 					param->state_request;
 	rc = qpnp_adc_tm_configure(chip, chip->adc->amux_prop);
@@ -1880,7 +1899,7 @@
 
 	for_each_child_of_node(node, child) {
 		char name[25];
-		int btm_channel_num;
+		int btm_channel_num, timer_select = 0;
 
 		rc = of_property_read_u32(child,
 				"qcom,btm-channel-number", &btm_channel_num);
@@ -1888,6 +1907,28 @@
 			pr_err("Invalid btm channel number\n");
 			goto fail;
 		}
+		rc = of_property_read_u32(child,
+				"qcom,meas-interval-timer-idx", &timer_select);
+		if (rc) {
+			pr_debug("Default to timer1 with interval of 1 sec\n");
+			chip->sensor[sen_idx].timer_select =
+							ADC_MEAS_TIMER_SELECT1;
+			chip->sensor[sen_idx].meas_interval =
+							ADC_MEAS1_INTERVAL_1S;
+		} else {
+			if (timer_select >= ADC_MEAS_TIMER_NUM) {
+				pr_err("Invalid timer selection number\n");
+				goto fail;
+			}
+			chip->sensor[sen_idx].timer_select = timer_select;
+			if (timer_select == ADC_MEAS_TIMER_SELECT2)
+				chip->sensor[sen_idx].meas_interval =
+						ADC_MEAS2_INTERVAL_500MS;
+			if (timer_select == ADC_MEAS_TIMER_SELECT3)
+				chip->sensor[sen_idx].meas_interval =
+						ADC_MEAS3_INTERVAL_4S;
+		}
+
 		chip->sensor[sen_idx].btm_channel_num = btm_channel_num;
 		chip->sensor[sen_idx].vadc_channel_num =
 				chip->adc->adc_channels[sen_idx].channel_num;
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 066419f..517ec05 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -3070,6 +3070,7 @@
 	int core_irqres, bam_irqres, wakeup_irqres;
 	struct msm_serial_hs_platform_data *pdata = pdev->dev.platform_data;
 	const struct of_device_id *match;
+	unsigned long data;
 
 	if (pdev->dev.of_node) {
 		dev_dbg(&pdev->dev, "device tree enabled\n");
@@ -3325,6 +3326,17 @@
 	 */
 	mb();
 
+	/*
+	* Set RX_BREAK_ZERO_CHAR_OFF and RX_ERROR_CHAR_OFF
+	* so any rx_break and character having parity of framing
+	* error don't enter inside UART RX FIFO.
+	*/
+	data = msm_hs_read(uport, UART_DM_MR2);
+	data |= (UARTDM_MR2_RX_BREAK_ZERO_CHAR_OFF |
+			UARTDM_MR2_RX_ERROR_CHAR_OFF);
+	msm_hs_write(uport, UART_DM_MR2, data);
+	mb();
+
 	msm_uport->clk_state = MSM_HS_CLK_PORT_OFF;
 	hrtimer_init(&msm_uport->clk_off_timer, CLOCK_MONOTONIC,
 		     HRTIMER_MODE_REL);
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 667a8a2..0e371d5 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -217,6 +217,7 @@
 	struct qpnp_adc_tm_chip *adc_tm_dev;
 	struct delayed_work	init_adc_work;
 	bool			id_adc_detect;
+	struct qpnp_vadc_chip	*vadc_dev;
 	u8			dcd_retries;
 	u32			bus_perf_client;
 	struct msm_bus_scale_pdata	*bus_scale_table;
@@ -2258,6 +2259,27 @@
 	return IRQ_HANDLED;
 }
 
+static int
+get_prop_usbin_voltage_now(struct dwc3_msm *mdwc)
+{
+	int rc = 0;
+	struct qpnp_vadc_result results;
+
+	if (IS_ERR_OR_NULL(mdwc->vadc_dev)) {
+		mdwc->vadc_dev = qpnp_get_vadc(mdwc->dev, "usbin");
+		if (IS_ERR(mdwc->vadc_dev))
+			return PTR_ERR(mdwc->vadc_dev);
+	}
+
+	rc = qpnp_vadc_read(mdwc->vadc_dev, USBIN, &results);
+	if (rc) {
+		pr_err("Unable to read usbin rc=%d\n", rc);
+		return 0;
+	} else {
+		return results.physical;
+	}
+}
+
 static int dwc3_msm_power_get_property_usb(struct power_supply *psy,
 				  enum power_supply_property psp,
 				  union power_supply_propval *val)
@@ -2283,6 +2305,9 @@
 	case POWER_SUPPLY_PROP_TYPE:
 		val->intval = psy->type;
 		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		val->intval = get_prop_usbin_voltage_now(mdwc);
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -2391,6 +2416,7 @@
 	POWER_SUPPLY_PROP_CURRENT_MAX,
 	POWER_SUPPLY_PROP_TYPE,
 	POWER_SUPPLY_PROP_SCOPE,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
 static void dwc3_init_adc_work(struct work_struct *w);
@@ -2635,6 +2661,30 @@
 			pm_runtime_put(mdwc->dev);
 		}
 		break;
+	case MSM_USB_EXT_CHG_VOLTAGE_INFO:
+		if (get_user(val, (int __user *)arg)) {
+			pr_err("%s: get_user failed\n\n", __func__);
+			ret = -EFAULT;
+			break;
+		}
+
+		if (val == USB_REQUEST_5V)
+			pr_debug("%s:voting 5V voltage request\n", __func__);
+		else if (val == USB_REQUEST_9V)
+			pr_debug("%s:voting 9V voltage request\n", __func__);
+		break;
+	case MSM_USB_EXT_CHG_RESULT:
+		if (get_user(val, (int __user *)arg)) {
+			pr_err("%s: get_user failed\n\n", __func__);
+			ret = -EFAULT;
+			break;
+		}
+
+		if (!val)
+			pr_debug("%s:voltage request successful\n", __func__);
+		else
+			pr_debug("%s:voltage request failed\n", __func__);
+		break;
 	default:
 		ret = -EINVAL;
 	}
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index effe0fd..e218130 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -354,28 +354,6 @@
 }
 
 /**
- * usb_diag_free_req() - Free USB requests
- * @ch: Channel handler
- *
- * This function free read and write USB requests for the interface
- * associated with this channel.
- *
- */
-void usb_diag_free_req(struct usb_diag_ch *ch)
-{
-	struct diag_context *ctxt = ch->priv_usb;
-	unsigned long flags;
-
-	if (ctxt) {
-		spin_lock_irqsave(&ctxt->lock, flags);
-		free_reqs(ctxt);
-		spin_unlock_irqrestore(&ctxt->lock, flags);
-	}
-
-}
-EXPORT_SYMBOL(usb_diag_free_req);
-
-/**
  * usb_diag_alloc_req() - Allocate USB requests
  * @ch: Channel handler
  * @n_write: Number of requests for Tx
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 3fa508c..15a9ab0 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -41,6 +41,7 @@
 #include <linux/mfd/pm8xxx/pm8921-charger.h>
 #include <linux/mfd/pm8xxx/misc.h>
 #include <linux/mhl_8334.h>
+#include <linux/qpnp/qpnp-adc.h>
 
 #include <mach/scm.h>
 #include <mach/clk.h>
@@ -3645,6 +3646,27 @@
 	return count;
 }
 
+static int
+otg_get_prop_usbin_voltage_now(struct msm_otg *motg)
+{
+	int rc = 0;
+	struct qpnp_vadc_result results;
+
+	if (IS_ERR_OR_NULL(motg->vadc_dev)) {
+		motg->vadc_dev = qpnp_get_vadc(motg->phy.dev, "usbin");
+		if (IS_ERR(motg->vadc_dev))
+			return PTR_ERR(motg->vadc_dev);
+	}
+
+	rc = qpnp_vadc_read(motg->vadc_dev, USBIN, &results);
+	if (rc) {
+		pr_err("Unable to read usbin rc=%d\n", rc);
+		return 0;
+	} else {
+		return results.physical;
+	}
+}
+
 static int otg_power_get_property_usb(struct power_supply *psy,
 				  enum power_supply_property psp,
 				  union power_supply_propval *val)
@@ -3674,6 +3696,9 @@
 	case POWER_SUPPLY_PROP_HEALTH:
 		val->intval = motg->usbin_health;
 		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		val->intval = otg_get_prop_usbin_voltage_now(motg);
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -3744,6 +3769,7 @@
 	POWER_SUPPLY_PROP_CURRENT_MAX,
 	POWER_SUPPLY_PROP_SCOPE,
 	POWER_SUPPLY_PROP_TYPE,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
 const struct file_operations msm_otg_bus_fops = {
@@ -4027,6 +4053,30 @@
 			pm_runtime_put(motg->phy.dev);
 		}
 		break;
+	case MSM_USB_EXT_CHG_VOLTAGE_INFO:
+		if (get_user(val, (int __user *)arg)) {
+			pr_err("%s: get_user failed\n\n", __func__);
+			ret = -EFAULT;
+			break;
+		}
+
+		if (val == USB_REQUEST_5V)
+			pr_debug("%s:voting 5V voltage request\n", __func__);
+		else if (val == USB_REQUEST_9V)
+			pr_debug("%s:voting 9V voltage request\n", __func__);
+		break;
+	case MSM_USB_EXT_CHG_RESULT:
+		if (get_user(val, (int __user *)arg)) {
+			pr_err("%s: get_user failed\n\n", __func__);
+			ret = -EFAULT;
+			break;
+		}
+
+		if (!val)
+			pr_debug("%s:voltage request successful\n", __func__);
+		else
+			pr_debug("%s:voltage request failed\n", __func__);
+		break;
 	default:
 		ret = -EINVAL;
 	}
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 0cf1093..9f608b8 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -1849,7 +1849,8 @@
 static int mdp3_continuous_splash_on(struct mdss_panel_data *pdata)
 {
 	struct mdss_panel_info *panel_info = &pdata->panel_info;
-	int ab, ib, rc;
+	u64 ab, ib;
+	int rc;
 
 	pr_debug("mdp3__continuous_splash_on\n");
 
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index e4d8d0f..b324130 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -343,8 +343,8 @@
 	int rc = 0;
 	if (status) {
 		struct mdss_panel_info *panel_info = mfd->panel_info;
-		int ab = 0;
-		int ib = 0;
+		u64 ab = 0;
+		u64 ib = 0;
 		ab = panel_info->xres * panel_info->yres * 4;
 		ab *= panel_info->mipi.frame_rate;
 		ib = (ab * 3) / 2;
@@ -792,16 +792,16 @@
 	if (panel && panel->set_backlight)
 		panel->set_backlight(panel, 0);
 
+	rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
+	if (rc)
+		pr_err("fail to turn off panel\n");
+
 	rc = mdp3_dma->stop(mdp3_dma, mdp3_session->intf);
 	if (rc) {
 		pr_err("fail to stop the MDP3 dma\n");
 		goto reset_error;
 	}
 
-	rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
-	if (rc)
-		pr_err("fail to turn off panel\n");
-
 	rc = mdp3_put_mdp_dsi_clk();
 	if (rc) {
 		pr_err("fail to release mdp clocks\n");
@@ -1608,6 +1608,43 @@
 	return rc;
 }
 
+static int mdp3_overlay_prepare(struct msm_fb_data_type *mfd,
+		struct mdp_overlay_list __user *user_ovlist)
+{
+	struct mdp_overlay_list ovlist;
+	struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
+	struct mdp_overlay *req;
+	int rc;
+
+	if (!mdp3_session)
+		return -ENODEV;
+
+	req = &mdp3_session->req_overlay;
+
+	if (copy_from_user(&ovlist, user_ovlist, sizeof(ovlist)))
+		return -EFAULT;
+
+	if (ovlist.num_overlays != 1) {
+		pr_err("OV_PREPARE failed: only 1 overlay allowed\n");
+		return -EINVAL;
+	}
+
+	if (copy_from_user(req, ovlist.overlay_list[0], sizeof(*req)))
+		return -EFAULT;
+
+	rc = mdp3_overlay_set(mfd, req);
+	if (!IS_ERR_VALUE(rc)) {
+		if (copy_to_user(ovlist.overlay_list[0], req, sizeof(*req)))
+			return -EFAULT;
+	}
+
+	if (put_user(IS_ERR_VALUE(rc) ? 0 : 1,
+			&user_ovlist->processed_overlays))
+		return -EFAULT;
+
+	return rc;
+}
+
 static int mdp3_ctrl_ioctl_handler(struct msm_fb_data_type *mfd,
 					u32 cmd, void __user *argp)
 {
@@ -1707,6 +1744,9 @@
 		if (rc)
 			pr_err("OVERLAY_PLAY failed (%d)\n", rc);
 		break;
+	case MSMFB_OVERLAY_PREPARE:
+		rc = mdp3_overlay_prepare(mfd, argp);
+		break;
 	default:
 		break;
 	}
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index eeb697b..e1786a6 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -1090,6 +1090,7 @@
 	SPRINT("dma_pipes=%d\n", mdata->ndma_pipes);
 	SPRINT("smp_count=%d\n", mdata->smp_mb_cnt);
 	SPRINT("smp_size=%d\n", mdata->smp_mb_size);
+	SPRINT("smp_mb_per_pipe=%d\n", mdata->smp_mb_per_pipe);
 	SPRINT("max_downscale_ratio=%d\n", MAX_DOWNSCALE_RATIO);
 	SPRINT("max_upscale_ratio=%d\n", MAX_UPSCALE_RATIO);
 	if (mdata->max_bw_low)
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 9d200b9..3afb27e 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -319,6 +319,7 @@
 	uint32_t bl_bright_shift;
 	uint32_t bl_lin[AD_BL_LIN_LEN];
 	uint32_t bl_lin_inv[AD_BL_LIN_LEN];
+	uint32_t bl_att_lut[AD_BL_ATT_LUT_LEN];
 };
 
 struct pp_sts_type {
@@ -528,6 +529,9 @@
 int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff);
 int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl);
 int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg);
+int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl,
+		struct mdss_mdp_pipe **left_plist, int left_cnt,
+		struct mdss_mdp_pipe **right_plist, int right_cnt);
 int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe,
 	struct mdss_mdp_perf_params *perf, struct mdss_mdp_img_rect *roi);
 int mdss_mdp_ctl_notify(struct mdss_mdp_ctl *ctl, int event);
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 18b6338..b445afa 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -427,7 +427,8 @@
 }
 
 static void mdss_mdp_perf_calc_mixer(struct mdss_mdp_mixer *mixer,
-		struct mdss_mdp_perf_params *perf)
+		struct mdss_mdp_perf_params *perf,
+		struct mdss_mdp_pipe **pipe_list, int num_pipes)
 {
 	struct mdss_mdp_pipe *pipe;
 	struct mdss_panel_info *pinfo = NULL;
@@ -436,10 +437,12 @@
 	int i;
 	u32 max_clk_rate = 0;
 	u64 bw_overlap_max = 0;
-	u64 bw_overlap[MDSS_MDP_MAX_STAGE];
-	u32 v_region[MDSS_MDP_MAX_STAGE * 2];
+	u64 bw_overlap[MDSS_MDP_MAX_STAGE] = { 0 };
+	u32 v_region[MDSS_MDP_MAX_STAGE * 2] = { 0 };
 	u32 prefill_bytes = 0;
 
+	BUG_ON(num_pipes > MDSS_MDP_MAX_STAGE);
+
 	memset(perf, 0, sizeof(*perf));
 
 	if (!mixer->rotator_mode) {
@@ -466,9 +469,9 @@
 	memset(bw_overlap, 0, sizeof(u64) * MDSS_MDP_MAX_STAGE);
 	memset(v_region, 0, sizeof(u32) * MDSS_MDP_MAX_STAGE * 2);
 
-	for (i = 0; i < MDSS_MDP_MAX_STAGE; i++) {
+	for (i = 0; i < num_pipes; i++) {
 		struct mdss_mdp_perf_params tmp;
-		pipe = mixer->stage_pipe[i];
+		pipe = pipe_list[i];
 		if (pipe == NULL)
 			continue;
 
@@ -488,8 +491,8 @@
 	 * data for each region and sum them up, then the worst case
 	 * of all regions is ib request.
 	 */
-	sort(v_region, MDSS_MDP_MAX_STAGE * 2, sizeof(u32), cmpu32, NULL);
-	for (i = 1; i < MDSS_MDP_MAX_STAGE * 2; i++) {
+	sort(v_region, num_pipes * 2, sizeof(u32), cmpu32, NULL);
+	for (i = 1; i < num_pipes * 2; i++) {
 		int j;
 		u64 bw_max_region = 0;
 		u32 y0, y1;
@@ -498,10 +501,10 @@
 			continue;
 		y0 = (v_region[i-1]) ? v_region[i-1] + 1 : 0;
 		y1 = v_region[i];
-		for (j = 0; j < MDSS_MDP_MAX_STAGE; j++) {
+		for (j = 0; j < num_pipes; j++) {
 			if (!bw_overlap[j])
 				continue;
-			pipe = mixer->stage_pipe[j];
+			pipe = pipe_list[j];
 			if (mdss_mdp_perf_is_overlap(y0, y1, pipe->dst.y,
 				(pipe->dst.y + pipe->dst.h)))
 				bw_max_region += bw_overlap[j];
@@ -566,22 +569,26 @@
 	return vbp_max;
 }
 
-static void mdss_mdp_perf_calc_ctl(struct mdss_mdp_ctl *ctl,
-		struct mdss_mdp_perf_params *perf)
+static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl,
+		struct mdss_mdp_perf_params *perf,
+		struct mdss_mdp_pipe **left_plist, int left_cnt,
+		struct mdss_mdp_pipe **right_plist, int right_cnt)
 {
 	struct mdss_mdp_perf_params tmp;
 
 	memset(perf, 0, sizeof(*perf));
 
-	if (ctl->mixer_left) {
-		mdss_mdp_perf_calc_mixer(ctl->mixer_left, &tmp);
+	if (left_cnt && ctl->mixer_left) {
+		mdss_mdp_perf_calc_mixer(ctl->mixer_left, &tmp,
+				left_plist, left_cnt);
 		perf->bw_overlap += tmp.bw_overlap;
 		perf->prefill_bytes += tmp.prefill_bytes;
 		perf->mdp_clk_rate = tmp.mdp_clk_rate;
 	}
 
-	if (ctl->mixer_right) {
-		mdss_mdp_perf_calc_mixer(ctl->mixer_right, &tmp);
+	if (right_cnt && ctl->mixer_right) {
+		mdss_mdp_perf_calc_mixer(ctl->mixer_right, &tmp,
+				right_plist, right_cnt);
 		perf->bw_overlap += tmp.bw_overlap;
 		perf->prefill_bytes += tmp.prefill_bytes;
 		if (tmp.mdp_clk_rate > perf->mdp_clk_rate)
@@ -618,6 +625,47 @@
 
 	if (ctl->is_video_mode)
 		perf->bw_ctl = IB_FUDGE_FACTOR(perf->bw_ctl);
+}
+
+int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl,
+		struct mdss_mdp_pipe **left_plist, int left_cnt,
+		struct mdss_mdp_pipe **right_plist, int right_cnt)
+{
+	struct mdss_data_type *mdata = ctl->mdata;
+	struct mdss_mdp_perf_params perf;
+	u32 bw, threshold;
+
+	/* we only need bandwidth check on real-time clients (interfaces) */
+	if (ctl->intf_type == MDSS_MDP_NO_INTF)
+		return 0;
+
+	__mdss_mdp_perf_calc_ctl_helper(ctl, &perf,
+			left_plist, left_cnt, right_plist, right_cnt);
+
+	/* convert bandwidth to kb */
+	bw = DIV_ROUND_UP_ULL(perf.bw_ctl, 1000);
+	pr_debug("calculated bandwidth=%uk\n", bw);
+
+	threshold = ctl->is_video_mode ? mdata->max_bw_low : mdata->max_bw_high;
+	if (bw > threshold) {
+		pr_debug("exceeds bandwidth: %ukb > %ukb\n", bw, threshold);
+		return -E2BIG;
+	}
+
+	return 0;
+}
+
+static void mdss_mdp_perf_calc_ctl(struct mdss_mdp_ctl *ctl,
+		struct mdss_mdp_perf_params *perf)
+{
+	struct mdss_mdp_pipe **left_plist, **right_plist;
+
+	left_plist = ctl->mixer_left ? ctl->mixer_left->stage_pipe : NULL;
+	right_plist = ctl->mixer_right ? ctl->mixer_right->stage_pipe : NULL;
+
+	__mdss_mdp_perf_calc_ctl_helper(ctl, perf,
+			left_plist, (left_plist ? MDSS_MDP_MAX_STAGE : 0),
+			right_plist, (right_plist ? MDSS_MDP_MAX_STAGE : 0));
 
 	pr_debug("ctl=%d clk_rate=%u\n", ctl->num, perf->mdp_clk_rate);
 	pr_debug("bw_overlap=%llu bw_prefill=%llu prefill_byptes=%d\n",
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index baea509..5d6ecdc 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -156,6 +156,9 @@
 			pr_err("Invalid decimation factors horz=%d vert=%d\n",
 					req->horz_deci, req->vert_deci);
 			return -EINVAL;
+		} else if (req->flags & MDP_BWC_EN) {
+			pr_err("Decimation can't be enabled with BWC\n");
+			return -EINVAL;
 		}
 	}
 
@@ -272,7 +275,8 @@
 		 * requirement by applying vertical decimation and reduce
 		 * mdp clock requirement
 		 */
-		if (mdata->has_decimation && (pipe->vert_deci < MAX_DECIMATION))
+		if (mdata->has_decimation && (pipe->vert_deci < MAX_DECIMATION)
+			&& !pipe->bwc_mode)
 			pipe->vert_deci++;
 		else
 			return -EPERM;
@@ -1100,7 +1104,7 @@
 	struct mdss_mdp_pipe *pipe;
 	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
 	u32 pipe_ndx, unset_ndx = 0;
-	int i;
+	int i, destroy_pipe;
 
 	for (i = 0; unset_ndx != ndx && i < MDSS_MDP_MAX_SSPP; i++) {
 		pipe_ndx = BIT(i);
@@ -1111,16 +1115,22 @@
 				pr_warn("unknown pipe ndx=%x\n", pipe_ndx);
 				continue;
 			}
+
 			mutex_lock(&mfd->lock);
 			pipe->pid = 0;
+			destroy_pipe = pipe->play_cnt == 0;
+
 			if (!list_empty(&pipe->used_list)) {
 				list_del_init(&pipe->used_list);
-				list_add(&pipe->cleanup_list,
-					&mdp5_data->pipes_cleanup);
+				if (!destroy_pipe)
+					list_add(&pipe->cleanup_list,
+						&mdp5_data->pipes_cleanup);
 			}
 			mutex_unlock(&mfd->lock);
 			mdss_mdp_mixer_pipe_unstage(pipe);
 			mdss_mdp_pipe_unmap(pipe);
+			if (destroy_pipe)
+				mdss_mdp_pipe_destroy(pipe);
 		}
 	}
 	return 0;
@@ -2211,6 +2221,10 @@
 		caps->features |= MDP_BWC_EN;
 	if (mdata->has_decimation)
 		caps->features |= MDP_DECIMATION_EN;
+
+	caps->max_smp_cnt = mdss_res->smp_mb_cnt;
+	caps->smp_per_pipe = mdata->smp_mb_per_pipe;
+
 	return 0;
 }
 
@@ -2249,6 +2263,98 @@
 	return ret;
 }
 
+static int __handle_overlay_prepare(struct msm_fb_data_type *mfd,
+		struct mdp_overlay_list *ovlist,
+		struct mdp_overlay *overlays)
+{
+	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
+	struct mdss_mdp_pipe *pipe;
+	struct mdp_overlay *req;
+	int ret = 0;
+	int i;
+	u32 new_reqs = 0;
+
+	ret = mutex_lock_interruptible(&mdp5_data->ov_lock);
+	if (ret)
+		return ret;
+
+	if (!mfd->panel_power_on) {
+		mutex_unlock(&mdp5_data->ov_lock);
+		return -EPERM;
+	}
+
+	pr_debug("prepare fb%d num_overlays=%d\n", mfd->index,
+			ovlist->num_overlays);
+
+	for (i = 0; i < ovlist->num_overlays; i++) {
+		req = overlays + i;
+
+		req->z_order += MDSS_MDP_STAGE_0;
+		ret = mdss_mdp_overlay_pipe_setup(mfd, req, &pipe);
+		req->z_order -= MDSS_MDP_STAGE_0;
+
+		if (IS_ERR_VALUE(ret))
+			goto validate_exit;
+
+		/* keep track of the new overlays to unset in case of errors */
+		if (pipe->play_cnt == 0)
+			new_reqs |= pipe->ndx;
+	}
+
+validate_exit:
+	if (IS_ERR_VALUE(ret))
+		mdss_mdp_overlay_release(mfd, new_reqs);
+	mutex_unlock(&mdp5_data->ov_lock);
+
+	ovlist->processed_overlays = i;
+
+	return ret;
+}
+
+static int __handle_ioctl_overlay_prepare(struct msm_fb_data_type *mfd,
+		void __user *argp)
+{
+	struct mdp_overlay_list ovlist;
+	struct mdp_overlay *overlays;
+	int i, ret;
+
+	if (copy_from_user(&ovlist, argp, sizeof(ovlist)))
+		return -EFAULT;
+
+	overlays = kmalloc(ovlist.num_overlays * sizeof(*overlays), GFP_KERNEL);
+	if (!overlays) {
+		pr_err("Unable to allocate memory for overlays\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < ovlist.num_overlays; i++) {
+		if (copy_from_user(overlays + i, ovlist.overlay_list[i],
+				sizeof(struct mdp_overlay))) {
+			ret = -EFAULT;
+			goto validate_exit;
+		}
+	}
+
+	ret = __handle_overlay_prepare(mfd, &ovlist, overlays);
+	if (!IS_ERR_VALUE(ret)) {
+		for (i = 0; i < ovlist.num_overlays; i++) {
+			if (copy_to_user(ovlist.overlay_list[i], overlays + i,
+					sizeof(struct mdp_overlay))) {
+				ret = -EFAULT;
+				goto validate_exit;
+			}
+		}
+	}
+
+	if (copy_to_user(argp, &ovlist, sizeof(ovlist)))
+		ret = -EFAULT;
+
+validate_exit:
+	kfree(overlays);
+
+	return ret;
+}
+
 static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
 					  u32 cmd, void __user *argp)
 {
@@ -2372,6 +2478,9 @@
 		if (!ret)
 			ret = copy_to_user(argp, &metadata, sizeof(metadata));
 		break;
+	case MSMFB_OVERLAY_PREPARE:
+		ret = __handle_ioctl_overlay_prepare(mfd, argp);
+		break;
 	default:
 		if (mfd->panel.type == WRITEBACK_PANEL)
 			ret = mdss_mdp_wb_ioctl_handler(mfd, cmd, argp);
@@ -2460,10 +2569,10 @@
 	}
 
 	if (!mfd->panel_info->cont_splash_enabled &&
-		(mfd->panel_info->type != DTV_PANEL) &&
-		(mfd->panel_info->type != WRITEBACK_PANEL)) {
+		(mfd->panel_info->type != DTV_PANEL)) {
 		rc = mdss_mdp_overlay_start(mfd);
-		if (!IS_ERR_VALUE(rc))
+		if (!IS_ERR_VALUE(rc) &&
+			(mfd->panel_info->type != WRITEBACK_PANEL))
 			rc = mdss_mdp_overlay_kickoff(mfd, NULL);
 	} else {
 		rc = mdss_mdp_ctl_setup(mdp5_data->ctl);
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 4999103..b6f9b17 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -209,7 +209,7 @@
 	u32 num_blks = 0, reserved = 0;
 	struct mdss_mdp_plane_sizes ps;
 	int i;
-	int rc = 0, rot_mode = 0;
+	int rc = 0, rot_mode = 0, wb_mixer = 0;
 	u32 nlines, format;
 	u16 width;
 
@@ -295,6 +295,9 @@
 	else
 		nlines = pipe->bwc_mode ? 1 : 2;
 
+	if (pipe->mixer->type == MDSS_MDP_MIXER_TYPE_WRITEBACK)
+		wb_mixer = 1;
+
 	mutex_lock(&mdss_mdp_smp_lock);
 	for (i = (MAX_PLANES - 1); i >= ps.num_planes; i--) {
 		if (bitmap_weight(pipe->smp_map[i].allocated, SMP_MB_CNT)) {
@@ -306,7 +309,7 @@
 	}
 
 	for (i = 0; i < ps.num_planes; i++) {
-		if (rot_mode) {
+		if (rot_mode || wb_mixer) {
 			num_blks = 1;
 		} else {
 			num_blks = DIV_ROUND_UP(ps.ystride[i] * nlines,
@@ -672,16 +675,20 @@
 	pr_debug("ndx=%x pnum=%d ref_cnt=%d\n", pipe->ndx, pipe->num,
 			atomic_read(&pipe->ref_cnt));
 
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
-	mdss_mdp_pipe_sspp_term(pipe);
-	mdss_mdp_smp_free(pipe);
+	if (pipe->play_cnt) {
+		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+		mdss_mdp_pipe_sspp_term(pipe);
+		mdss_mdp_smp_free(pipe);
+		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+	} else {
+		mdss_mdp_smp_unreserve(pipe);
+	}
+
 	pipe->flags = 0;
 	pipe->bwc_mode = 0;
 	pipe->mfd = NULL;
 	memset(&pipe->scale, 0, sizeof(struct mdp_scale_data));
 
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
-
 	return 0;
 }
 
@@ -815,6 +822,7 @@
 		pipe->src_fmt->bpp);
 
 	pipe->is_handed_off = true;
+	pipe->play_cnt = 1;
 	atomic_inc(&pipe->ref_cnt);
 
 error:
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 9b6d130..5c9ad9c 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -396,6 +396,7 @@
 				struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode);
 static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd);
 static void pp_ad_cfg_lut(char __iomem *addr, u32 *data);
+static u32 pp_ad_attenuate_bl(u32 bl, struct mdss_ad_info *ad);
 static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num);
 static inline bool pp_sts_is_enabled(u32 sts, int side);
 static inline void pp_sts_set_split_bits(u32 *sts, u32 bits);
@@ -1589,7 +1590,7 @@
 	if (mdata->nad_cfgs == 0)
 		valid_mixers = false;
 	for (i = 0; i < mixer_cnt && valid_mixers; i++) {
-		if (mixer_id[i] > mdata->nad_cfgs)
+		if (mixer_id[i] >= mdata->nad_cfgs)
 			valid_mixers = false;
 	}
 	if (valid_mixers && (mixer_cnt <= mdata->nmax_concurrent_ad_hw)) {
@@ -1648,6 +1649,7 @@
 			if (ad->state & PP_AD_STATE_BL_LIN) {
 				bl = ad->bl_lin[bl >> ad->bl_bright_shift];
 				bl = bl << ad->bl_bright_shift;
+				bl = pp_ad_attenuate_bl(bl, ad);
 			}
 			ad->bl_data = bl;
 			pp_ad_input_write(&mdata->ad_off[dspp_num], ad);
@@ -3781,7 +3783,7 @@
 {
 	struct mdss_ad_info *ad;
 	struct msm_fb_data_type *bl_mfd;
-	int lin_ret = -1, inv_ret = -1, ret = 0;
+	int lin_ret = -1, inv_ret = -1, att_ret = -1, ret = 0;
 	u32 ratio_temp, shift = 0, last_ops;
 
 	ret = mdss_mdp_get_ad(mfd, &ad);
@@ -3830,6 +3832,23 @@
 		} else
 			ad->state |= PP_AD_STATE_BL_LIN;
 
+		if ((init_cfg->params.init.bl_att_len == AD_BL_ATT_LUT_LEN) &&
+			(init_cfg->params.init.bl_att_lut)) {
+			att_ret = copy_from_user(&ad->bl_att_lut,
+				init_cfg->params.init.bl_att_lut,
+				init_cfg->params.init.bl_att_len *
+				sizeof(uint32_t));
+			if (att_ret)
+				ret = -ENOMEM;
+		} else {
+			ret = -EINVAL;
+		}
+		if (ret) {
+			ad->state &= ~PP_AD_STATE_BL_LIN;
+			goto ad_config_exit;
+		} else
+			ad->state |= PP_AD_STATE_BL_LIN;
+
 		ad->sts |= PP_AD_STS_DIRTY_INIT;
 	} else if (init_cfg->ops & MDP_PP_AD_CFG) {
 		memcpy(&ad->cfg, &init_cfg->params.cfg,
@@ -4256,6 +4275,7 @@
 			if (ad->state & PP_AD_STATE_BL_LIN) {
 				bl = ad->bl_lin[bl >> ad->bl_bright_shift];
 				bl = bl << ad->bl_bright_shift;
+				bl = pp_ad_attenuate_bl(bl, ad);
 			}
 			ad->bl_data = bl;
 		}
@@ -4330,6 +4350,8 @@
 								AD_BL_LIN_LEN);
 			memset(&ad->bl_lin_inv, 0, sizeof(uint32_t) *
 								AD_BL_LIN_LEN);
+			memset(&ad->bl_att_lut, 0, sizeof(uint32_t) *
+				AD_BL_ATT_LUT_LEN);
 			memset(&ad->init, 0, sizeof(struct mdss_ad_init));
 			memset(&ad->cfg, 0, sizeof(struct mdss_ad_cfg));
 			mutex_lock(&bl_mfd->bl_lock);
@@ -4391,7 +4413,7 @@
 	ctl = mfd_to_ctl(ad->mfd);
 	mdata = mfd_to_mdata(ad->mfd);
 
-	if (!mdata || ad->calc_hw_num > mdata->nad_cfgs) {
+	if (!mdata || ad->calc_hw_num >= mdata->nad_cfgs) {
 		mutex_unlock(&ad->lock);
 		return;
 	}
@@ -4474,6 +4496,30 @@
 			addr + ((PP_AD_LUT_LEN - 1) * 2));
 }
 
+static u32 pp_ad_attenuate_bl(u32 bl, struct mdss_ad_info *ad)
+{
+	u32 shift = 0, ratio_temp = 0;
+	u32 n, lut_interval, bl_att, out;
+
+	ratio_temp = ad->cfg.backlight_max / (AD_BL_ATT_LUT_LEN - 1);
+	while (ratio_temp > 0) {
+		ratio_temp = ratio_temp >> 1;
+		shift++;
+	}
+	n = bl >> shift;
+	lut_interval = (ad->cfg.backlight_max + 1) / (AD_BL_ATT_LUT_LEN - 1);
+	bl_att = ad->bl_att_lut[n] + (bl - lut_interval * n) *
+			(ad->bl_att_lut[n + 1] - ad->bl_att_lut[n]) /
+			lut_interval;
+	if (ad->init.alpha_base)
+		out = (ad->init.alpha * bl_att +
+			(ad->init.alpha_base - ad->init.alpha) * bl) /
+			ad->init.alpha_base;
+	else
+		out = bl;
+	return out;
+}
+
 int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets)
 {
 	u32 i;
diff --git a/drivers/video/msm/mdss/mhl_sii8334.c b/drivers/video/msm/mdss/mhl_sii8334.c
index 0f84b2d..c5d5366 100644
--- a/drivers/video/msm/mdss/mhl_sii8334.c
+++ b/drivers/video/msm/mdss/mhl_sii8334.c
@@ -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
@@ -194,6 +194,7 @@
 static void mhl_init_reg_settings(struct mhl_tx_ctrl *mhl_ctrl,
 				  bool mhl_disc_en);
 static int mhl_gpio_config(struct mhl_tx_ctrl *mhl_ctrl, int on);
+static int mhl_vreg_config(struct mhl_tx_ctrl *mhl_ctrl, uint8_t on);
 
 int mhl_i2c_reg_read(struct i2c_client *client,
 			    uint8_t slave_addr_index, uint8_t reg_offset)
@@ -385,15 +386,69 @@
 	return 0;
 }
 
+static int mhl_sii_config(struct mhl_tx_ctrl *mhl_ctrl, bool on)
+{
+	int rc = 0;
+	struct i2c_client *client = NULL;
+
+	if (!mhl_ctrl) {
+		pr_err("%s: ctrl is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	client = mhl_ctrl->i2c_handle;
+
+	if (on) {
+		rc = mhl_vreg_config(mhl_ctrl, 1);
+		if (rc) {
+			pr_err("%s: vreg init failed [%d]\n",
+				__func__, rc);
+			return -ENODEV;
+		}
+
+		rc = mhl_gpio_config(mhl_ctrl, 1);
+		if (rc) {
+			pr_err("%s: gpio init failed [%d]\n",
+				__func__, rc);
+			return -ENODEV;
+		}
+
+		rc = request_threaded_irq(mhl_ctrl->i2c_handle->irq, NULL,
+			&mhl_tx_isr, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+			client->dev.driver->name, mhl_ctrl);
+		if (rc) {
+			pr_err("%s: request_threaded_irq failed, status: %d\n",
+			       __func__, rc);
+			return -ENODEV;
+		} else {
+			mhl_ctrl->irq_req_done = true;
+		}
+	} else {
+		free_irq(mhl_ctrl->i2c_handle->irq, mhl_ctrl);
+		mhl_gpio_config(mhl_ctrl, 0);
+		mhl_vreg_config(mhl_ctrl, 0);
+		mhl_ctrl->irq_req_done = false;
+	}
+
+	return rc;
+}
+
+static void mhl_sii_disc_intr_work(struct work_struct *work)
+{
+	struct mhl_tx_ctrl *mhl_ctrl = NULL;
+
+	mhl_ctrl = container_of(work, struct mhl_tx_ctrl, mhl_intr_work);
+
+	mhl_sii_config(mhl_ctrl, false);
+}
+
 /*  USB_HANDSHAKING FUNCTIONS */
 static int mhl_sii_device_discovery(void *data, int id,
 			     void (*usb_notify_cb)(void *, int), void *ctx)
 {
 	int rc;
 	struct mhl_tx_ctrl *mhl_ctrl = data;
-	struct i2c_client *client = mhl_ctrl->i2c_handle;
 	unsigned long flags;
-	int discovery_retry = 5;
 
 	if (id) {
 		/* When MHL cable is disconnected we get a sii8334
@@ -413,18 +468,14 @@
 		mhl_ctrl->notify_usb_online = usb_notify_cb;
 		mhl_ctrl->notify_ctx = ctx;
 	}
-again:
+
+	flush_work(&mhl_ctrl->mhl_intr_work);
+
 	if (!mhl_ctrl->irq_req_done) {
-		rc = request_threaded_irq(mhl_ctrl->i2c_handle->irq, NULL,
-			&mhl_tx_isr, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-			client->dev.driver->name, mhl_ctrl);
+		rc = mhl_sii_config(mhl_ctrl, true);
 		if (rc) {
-			pr_debug("request_threaded_irq failed, status: %d\n",
-			       rc);
-			return -EINVAL;
-		} else {
-			pr_debug("request_threaded_irq succeeded\n");
-			mhl_ctrl->irq_req_done = true;
+			pr_err("%s: Failed to config vreg/gpio\n", __func__);
+			return rc;
 		}
 
 		/* wait for i2c interrupt line to be activated */
@@ -448,23 +499,9 @@
 		if (mhl_sii_wait_for_rgnd(mhl_ctrl)) {
 			pr_err("%s: discovery timeout\n", __func__);
 
-			free_irq(mhl_ctrl->i2c_handle->irq, mhl_ctrl);
-			mhl_gpio_config(mhl_ctrl, 0);
-			mhl_ctrl->irq_req_done = false;
+			mhl_sii_config(mhl_ctrl, false);
 
-			msleep(100);
-
-			mhl_gpio_config(mhl_ctrl, 1);
-			if (discovery_retry--) {
-				pr_debug("%s: retrying discovery\n", __func__);
-				goto again;
-			} else {
-				pr_err("%s: discovery failed, ret to USB\n",
-					__func__);
-				if (mhl_ctrl->notify_usb_online)
-					mhl_ctrl->notify_usb_online(
-						mhl_ctrl->notify_ctx, 0);
-			}
+			return -EAGAIN;
 		}
 	} else {
 		if (mhl_ctrl->cur_state == POWER_STATE_D3) {
@@ -1059,13 +1096,8 @@
 		mhl_msm_connection(mhl_ctrl);
 	} else if (status & BIT3) {
 		pr_debug("%s: uUSB-a type dev detct\n", __func__);
-
-		/* Short RGND */
-		MHL_SII_REG_NAME_MOD(REG_DISC_STAT2, BIT0 | BIT1, 0x00);
-		mhl_msm_disconnection(mhl_ctrl);
 		power_supply_changed(&mhl_ctrl->mhl_psy);
-		if (mhl_ctrl->notify_usb_online)
-			mhl_ctrl->notify_usb_online(mhl_ctrl->notify_ctx, 0);
+		mhl_drive_hpd(mhl_ctrl, HPD_DOWN);
 		return 0;
 	}
 
@@ -1081,6 +1113,9 @@
 		power_supply_changed(&mhl_ctrl->mhl_psy);
 		if (mhl_ctrl->notify_usb_online)
 			mhl_ctrl->notify_usb_online(mhl_ctrl->notify_ctx, 0);
+
+		queue_work(mhl_ctrl->mhl_workq, &mhl_ctrl->mhl_intr_work);
+
 		return 0;
 	}
 
@@ -1495,6 +1530,27 @@
 	int rc = -EINVAL;
 
 	pr_debug("%s\n", __func__);
+
+	if (!enable) {
+		regulator_disable(reg_8941_vdda);
+		regulator_put(reg_8941_vdda);
+		reg_8941_vdda = NULL;
+
+		regulator_disable(reg_8941_smps3a);
+		regulator_put(reg_8941_smps3a);
+		reg_8941_smps3a = NULL;
+
+		regulator_disable(reg_8941_l02);
+		regulator_put(reg_8941_l02);
+		reg_8941_l02 = NULL;
+
+		regulator_disable(reg_8941_l24);
+		regulator_put(reg_8941_l24);
+		reg_8941_l24 = NULL;
+
+		return 0;
+	}
+
 	if (!reg_8941_l24) {
 		reg_8941_l24 = regulator_get(&client->dev,
 			"avcc_18");
@@ -1736,26 +1792,6 @@
 	}
 
 	/*
-	 * Regulator init
-	 */
-	rc = mhl_vreg_config(mhl_ctrl, 1);
-	if (rc) {
-		pr_err("%s: vreg init failed [%d]\n",
-			__func__, rc);
-		goto failed_probe;
-	}
-
-	/*
-	 * GPIO init
-	 */
-	rc = mhl_gpio_config(mhl_ctrl, 1);
-	if (rc) {
-		pr_err("%s: gpio init failed [%d]\n",
-			__func__, rc);
-		goto failed_probe;
-	}
-
-	/*
 	 * Other initializations
 	 * such tx specific
 	 */
@@ -1767,6 +1803,9 @@
 	spin_lock_init(&mhl_ctrl->lock);
 	mhl_ctrl->msc_send_workqueue = create_singlethread_workqueue
 		("mhl_msc_cmd_queue");
+	mhl_ctrl->mhl_workq = create_singlethread_workqueue("mhl_workq");
+
+	INIT_WORK(&mhl_ctrl->mhl_intr_work, mhl_sii_disc_intr_work);
 
 	mhl_ctrl->input = input_allocate_device();
 	if (mhl_ctrl->input) {
@@ -1894,9 +1933,7 @@
 failed_probe_pwr:
 	power_supply_unregister(&mhl_ctrl->mhl_psy);
 failed_probe:
-	free_irq(mhl_ctrl->i2c_handle->irq, mhl_ctrl);
-	mhl_gpio_config(mhl_ctrl, 0);
-	mhl_vreg_config(mhl_ctrl, 0);
+	mhl_sii_config(mhl_ctrl, false);
 	/* do not deep-free */
 	if (mhl_info)
 		devm_kfree(&client->dev, mhl_info);
@@ -1923,9 +1960,10 @@
 		return -EINVAL;
 	}
 
-	free_irq(mhl_ctrl->i2c_handle->irq, mhl_ctrl);
-	mhl_gpio_config(mhl_ctrl, 0);
-	mhl_vreg_config(mhl_ctrl, 0);
+	mhl_sii_config(mhl_ctrl, false);
+
+	destroy_workqueue(mhl_ctrl->mhl_workq);
+
 	if (mhl_ctrl->mhl_info)
 		devm_kfree(&client->dev, mhl_ctrl->mhl_info);
 	if (mhl_ctrl->pdata)
@@ -1949,17 +1987,19 @@
 
 	pr_debug("%s\n", __func__);
 
-	if (!mhl_ctrl)
+	if (!mhl_ctrl) {
+		pr_err("%s: invalid ctrl data\n", __func__);
 		return 0;
-
-	free_irq(mhl_ctrl->i2c_handle->irq, mhl_ctrl);
-	mhl_ctrl->irq_req_done = false;
+	}
 
 	if (mhl_ctrl->mhl_mode)	{
 		mhl_ctrl->mhl_mode = 0;
+
 		power_supply_changed(&mhl_ctrl->mhl_psy);
 		if (mhl_ctrl->notify_usb_online)
 			mhl_ctrl->notify_usb_online(mhl_ctrl->notify_ctx, 0);
+
+		mhl_sii_config(mhl_ctrl, false);
 	}
 
 	return 0;
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
old mode 100644
new mode 100755
index ec27b00..276a48f
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -42,7 +42,9 @@
 #define ERR(x...) pr_err(x)
 
 #define VID_DEC_NAME "msm_vidc_dec"
-
+#ifdef KW_TAINT_ANALYSIS	51
+	extern void * get_tainted_stuff();
+#endif
 static char *node_name[2] = {"", "_sec"};
 static struct vid_dec_dev *vid_dec_device_p;
 static dev_t vid_dec_dev_num;
@@ -1736,7 +1738,11 @@
 	unsigned long kernel_vaddr, phy_addr, len;
 	unsigned long ker_vaddr;
 	u32 result = true;
+	#ifdef KW_TAINT_ANALYSIS
+    void __user *arg = (void __user *) get_tainted_stuff();
+	#else
 	void __user *arg = (void __user *)u_arg;
+	#endif
 	int rc = 0;
 	size_t ion_len;
 
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
old mode 100644
new mode 100755
index 823626a..ee9c48b
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -45,7 +45,9 @@
 
 #define INFO(x...) printk(KERN_INFO x)
 #define ERR(x...) printk(KERN_ERR x)
-
+#ifdef KW_TAINT_ANALYSIS
+	extern void * get_tainted_stuff();
+#endif
 static struct vid_enc_dev *vid_enc_device_p;
 static dev_t vid_enc_dev_num;
 static struct class *vid_enc_class;
@@ -840,7 +842,11 @@
 {
 	struct video_client_ctx *client_ctx = NULL;
 	struct venc_ioctl_msg venc_msg;
+	#ifdef KW_TAINT_ANALYSIS
+	void __user *arg = (void __user *)get_tainted_stuff();;
+	#else
 	void __user *arg = (void __user *)u_arg;
+	#endif
 	u32 result = true;
 	int result_read = -1;
 
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 341f753..8db494d 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -329,10 +329,14 @@
 /* fat/misc.c */
 extern __printf(3, 4) __cold
 void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...);
-#define fat_fs_error(sb, fmt, args...)		\
-	__fat_fs_error(sb, 1, fmt , ## args)
 #define fat_fs_error_ratelimit(sb, fmt, args...) \
 	__fat_fs_error(sb, __ratelimit(&MSDOS_SB(sb)->ratelimit), fmt , ## args)
+/*
+ * If removable devices with a fat fs are removed without a unmount, further
+ * accesses to the device by applications causes a large number of error prints
+ * & in some cases leads to watchdog bark.
+ */
+#define fat_fs_error(sb, fmt, args...)	fat_fs_error_ratelimit(sb, fmt, ## args)
 __printf(3, 4) __cold
 void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...);
 extern int fat_clusters_flush(struct super_block *sb);
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index ac750ea..3f62354 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -95,6 +95,12 @@
 #define BIO_FS_INTEGRITY 9	/* fs owns integrity data, not block layer */
 #define BIO_QUIET	10	/* Make BIO Quiet */
 #define BIO_MAPPED_INTEGRITY 11/* integrity metadata has been remapped */
+/*
+ * Added for Req based dm which need to perform post processing. This flag
+ * ensures blk_update_request does not free the bios or request, this is done
+ * at the dm level
+ */
+#define BIO_DONTFREE 12
 #define bio_flagged(bio, flag)	((bio)->bi_flags & (1 << (flag)))
 
 /*
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 98f34b8..546871b 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -510,5 +510,6 @@
 void dm_requeue_unmapped_request(struct request *rq);
 void dm_kill_unmapped_request(struct request *rq, int error);
 int dm_underlying_device_busy(struct request_queue *q);
+void dm_end_request(struct request *clone, int error);
 
 #endif	/* _LINUX_DEVICE_MAPPER_H */
diff --git a/include/linux/mhl_8334.h b/include/linux/mhl_8334.h
index 71dec42..42ee81e 100644
--- a/include/linux/mhl_8334.h
+++ b/include/linux/mhl_8334.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
@@ -155,6 +155,8 @@
 	struct list_head list_cmd;
 	struct input_dev *input;
 	struct workqueue_struct *msc_send_workqueue;
+	struct workqueue_struct *mhl_workq;
+	struct work_struct mhl_intr_work;
 	u16 *rcp_key_code_tbl;
 	size_t rcp_key_code_tbl_len;
 	struct scrpd_struct scrpd;
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 45975f9..e332368 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -79,7 +79,8 @@
 #define MSMFB_WRITEBACK_SET_MIRRORING_HINT _IOW(MSMFB_IOCTL_MAGIC, 167, \
 						unsigned int)
 #define MSMFB_ASYNC_BLIT              _IOW(MSMFB_IOCTL_MAGIC, 168, unsigned int)
-
+#define MSMFB_OVERLAY_PREPARE		_IOWR(MSMFB_IOCTL_MAGIC, 169, \
+						struct mdp_overlay_list)
 #define FB_TYPE_3D_PANEL 0x10101010
 #define MDP_IMGTYPE2_START 0x10000
 #define MSMFB_DRIVER_VERSION	0xF9E8D701
@@ -811,6 +812,7 @@
 
 #define MDSS_MAX_BL_BRIGHTNESS 255
 #define AD_BL_LIN_LEN 256
+#define AD_BL_ATT_LUT_LEN 33
 
 #define MDSS_AD_MODE_AUTO_BL	0x0
 #define MDSS_AD_MODE_AUTO_STR	0x1
@@ -839,9 +841,13 @@
 	uint16_t frame_h;
 	uint8_t logo_v;
 	uint8_t logo_h;
+	uint32_t alpha;
+	uint32_t alpha_base;
 	uint32_t bl_lin_len;
+	uint32_t bl_att_len;
 	uint32_t *bl_lin;
 	uint32_t *bl_lin_inv;
+	uint32_t *bl_att_lut;
 };
 
 #define MDSS_AD_BL_CTRL_MODE_EN 1
@@ -965,6 +971,8 @@
 	uint8_t rgb_pipes;
 	uint8_t vig_pipes;
 	uint8_t dma_pipes;
+	uint8_t max_smp_cnt;
+	uint8_t smp_per_pipe;
 	uint32_t features;
 };
 
@@ -1010,6 +1018,24 @@
 	struct mdp_rect roi;
 };
 
+/**
+* struct mdp_overlay_list - argument for ioctl MSMFB_OVERLAY_PREPARE
+* @num_overlays:	Number of overlay layers as part of the frame.
+* @overlay_list:	Pointer to a list of overlay structures identifying
+*			the layers as part of the frame
+* @flags:		Flags can be used to extend behavior.
+* @processed_overlays:	Output parameter indicating how many pipes were
+*			successful. If there are no errors this number should
+*			match num_overlays. Otherwise it will indicate the last
+*			successful index for overlay that couldn't be set.
+*/
+struct mdp_overlay_list {
+	uint32_t num_overlays;
+	struct mdp_overlay **overlay_list;
+	uint32_t flags;
+	uint32_t processed_overlays;
+};
+
 struct mdp_page_protection {
 	uint32_t page_protection;
 };
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 7be6cd2..d797797 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -615,6 +615,28 @@
  * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can
  *	return back to normal.
  *
+ * @NL80211_CMD_GET_COALESCE: Get currently supported coalesce rules.
+ * @NL80211_CMD_SET_COALESCE: Configure coalesce rules or clear existing rules.
+ *
+ * @NL80211_CMD_CHANNEL_SWITCH: Perform a channel switch by announcing the
+ *	the new channel information (Channel Switch Announcement - CSA)
+ *	in the beacon for some time (as defined in the
+ *	%NL80211_ATTR_CH_SWITCH_COUNT parameter) and then change to the
+ *	new channel. Userspace provides the new channel information (using
+ *	%NL80211_ATTR_WIPHY_FREQ and the attributes determining channel
+ *	width). %NL80211_ATTR_CH_SWITCH_BLOCK_TX may be supplied to inform
+ *	other station that transmission must be blocked until the channel
+ *	switch is complete.
+ *
+ * @NL80211_CMD_VENDOR: Vendor-specified command/event. The command is specified
+ *	by the %NL80211_ATTR_VENDOR_ID attribute and a sub-command in
+ *	%NL80211_ATTR_VENDOR_SUBCMD. Parameter(s) can be transported in
+ *	%NL80211_ATTR_VENDOR_DATA.
+ *	For feature advertisement, the %NL80211_ATTR_VENDOR_DATA attribute is
+ *	used in the wiphy data as a nested attribute containing descriptions
+ *	(&struct nl80211_vendor_cmd_info) of the supported vendor commands.
+ *	This may also be sent as an event with the same attributes.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -778,6 +800,13 @@
 	NL80211_CMD_CRIT_PROTOCOL_START,
 	NL80211_CMD_CRIT_PROTOCOL_STOP,
 
+	NL80211_CMD_GET_COALESCE,
+	NL80211_CMD_SET_COALESCE,
+
+	NL80211_CMD_CHANNEL_SWITCH,
+
+	NL80211_CMD_VENDOR,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -1402,6 +1431,21 @@
  * @NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES: array of supported
  *      supported operating classes.
  *
+ * @NL80211_ATTR_HANDLE_DFS: A flag indicating whether user space
+ *	controls DFS operation in IBSS mode. If the flag is included in
+ *	%NL80211_CMD_JOIN_IBSS request, the driver will allow use of DFS
+ *	channels and reports radar events to userspace. Userspace is required
+ *	to react to radar events, e.g. initiate a channel switch or leave the
+ *	IBSS network.
+ *
+ * @NL80211_ATTR_VENDOR_ID: The vendor ID, either a 24-bit OUI or, if
+ *	%NL80211_VENDOR_ID_IS_LINUX is set, a special Linux ID (not used yet)
+ * @NL80211_ATTR_VENDOR_SUBCMD: vendor sub-command
+ * @NL80211_ATTR_VENDOR_DATA: data for the vendor command, if any; this
+ *	attribute is also used for vendor command feature advertisement
+ * @NL80211_ATTR_VENDOR_EVENTS: used for event list advertising in the wiphy
+ *	info, containing a nested array of possible events
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1715,6 +1759,20 @@
 	NL80211_ATTR_STA_SUPPORTED_CHANNELS,
 
 	NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
+
+	NL80211_ATTR_HANDLE_DFS,
+
+	NL80211_ATTR_SUPPORT_5_MHZ,
+	NL80211_ATTR_SUPPORT_10_MHZ,
+
+	NL80211_ATTR_OPMODE_NOTIF,
+
+	NL80211_ATTR_VENDOR_ID,
+	NL80211_ATTR_VENDOR_SUBCMD,
+	NL80211_ATTR_VENDOR_DATA,
+
+	NL80211_ATTR_VENDOR_EVENTS,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -3178,4 +3236,24 @@
 /* maximum duration for critical protocol measures */
 #define NL80211_CRIT_PROTO_MAX_DURATION		5000 /* msec */
 
+/*
+ * If this flag is unset, the lower 24 bits are an OUI, if set
+ * a Linux nl80211 vendor ID is used (no such IDs are allocated
+ * yet, so that's not valid so far)
+ */
+#define NL80211_VENDOR_ID_IS_LINUX	0x80000000
+
+/**
+ * struct nl80211_vendor_cmd_info - vendor command data
+ * @vendor_id: If the %NL80211_VENDOR_ID_IS_LINUX flag is clear, then the
+ *	value is a 24-bit OUI; if it is set then a separately allocated ID
+ *	may be used, but no such IDs are allocated yet. New IDs should be
+ *	added to this file when needed.
+ * @subcmd: sub-command ID for the command
+ */
+struct nl80211_vendor_cmd_info {
+	__u32 vendor_id;
+	__u32 subcmd;
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/include/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index 2b47b88..13eb461 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -574,12 +574,10 @@
 /**
  * enum qpnp_adc_meas_timer_select - Selects the timer for which
  *	the appropriate polling frequency is set.
- * %ADC_MEAS_TIMER_SELECT1 - Select this timer if the client is USB_ID.
- * %ADC_MEAS_TIMER_SELECT2 - Select this timer if the client is batt_therm.
- * %ADC_MEAS_TIMER_SELECT3 - The timer is added only for completion. It is
- *	not used by kernel space clients and user space clients cannot set
- *	the polling frequency. The driver will set a appropriate polling
- *	frequency to measure the user space clients from qpnp_adc_meas_timer_3.
+ * %ADC_MEAS_TIMER_SELECT1 - Select this timer for measurement polling interval
+ *				for 1 second.
+ * %ADC_MEAS_TIMER_SELECT2 - Select this timer for 500ms measurement interval.
+ * %ADC_MEAS_TIMER_SELECT3 - Select this timer for 5 second interval.
  */
 enum qpnp_adc_meas_timer_select {
 	ADC_MEAS_TIMER_SELECT1 = 0,
diff --git a/include/linux/regulator/cpr-regulator.h b/include/linux/regulator/cpr-regulator.h
index e6a8f58..9d06a8c 100644
--- a/include/linux/regulator/cpr-regulator.h
+++ b/include/linux/regulator/cpr-regulator.h
@@ -18,9 +18,6 @@
 
 #define CPR_REGULATOR_DRIVER_NAME	"qcom,cpr-regulator"
 
-#define CPR_PVS_EFUSE_BITS_MAX		5
-#define CPR_PVS_EFUSE_BINS_MAX		(1 << CPR_PVS_EFUSE_BITS_MAX)
-
 /**
  * enum cpr_fuse_corner_enum - CPR fuse corner enum values
  * %CPR_FUSE_CORNER_SVS:		Lowest voltage for APC
@@ -70,21 +67,6 @@
 };
 
 /**
- * enum pvs_process_enum - PVS process enum values
- * %APC_PVS_NO:		No PVS
- * %APC_PVS_SLOW:	Slow PVS process
- * %APC_PVS_NOM:	Nominal PVS process
- * %APC_PVS_FAST:	Fast PVS process
- */
-enum apc_pvs_process_enum {
-	APC_PVS_NO,
-	APC_PVS_SLOW,
-	APC_PVS_NOM,
-	APC_PVS_FAST,
-	NUM_APC_PVS,
-};
-
-/**
  * enum vdd_mx_vmin_method - Method to determine vmin for vdd-mx
  * %VDD_MX_VMIN_APC:			Equal to APC voltage
  * %VDD_MX_VMIN_APC_CORNER_CEILING:	Equal to PVS corner ceiling voltage
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index 67f4d8c..56a3a5f 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -634,6 +634,10 @@
  *  @driver: Device's driver. Pointer to access routines.
  *  @ctrl: Slimbus controller managing the bus hosting this device.
  *  @laddr: 1-byte Logical address of this device.
+ *  @reported: Flag to indicate whether this device reported present. The flag
+ *	is set when device reports present, and is reset when it reports
+ *	absent. This flag alongwith notified flag below is used to call
+ *	device_up, or device_down callbacks for driver of this device.
  *  @mark_define: List of channels pending definition/activation.
  *  @mark_suspend: List of channels pending suspend.
  *  @mark_removal: List of channels pending removal.
@@ -657,6 +661,7 @@
 	struct slim_driver	*driver;
 	struct slim_controller	*ctrl;
 	u8			laddr;
+	bool			reported;
 	struct list_head	mark_define;
 	struct list_head	mark_suspend;
 	struct list_head	mark_removal;
diff --git a/include/linux/smsc_hub.h b/include/linux/smsc_hub.h
index 9c0afc0..c87f21b 100644
--- a/include/linux/smsc_hub.h
+++ b/include/linux/smsc_hub.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 software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -14,6 +14,7 @@
 #ifndef __LINUX_SMSC3503_H__
 #define __LINUX_SMSC3503_H__
 
+#define SMSC3502_ID	3502
 #define SMSC3503_ID	3503
 #define SMSC4604_ID	4604
 #define SMSC3503_I2C_ADDR	0x08
@@ -52,6 +53,7 @@
 	int hub_reset;
 	int refclk_gpio;
 	int int_gpio;
+	int xo_clk_gpio;
 };
 
 #endif
diff --git a/include/linux/usb/msm_ext_chg.h b/include/linux/usb/msm_ext_chg.h
index dcc786d..596ab49 100644
--- a/include/linux/usb/msm_ext_chg.h
+++ b/include/linux/usb/msm_ext_chg.h
@@ -6,6 +6,8 @@
 #define USB_CHG_BLOCK_ULPI	1
 #define USB_CHG_BLOCK_QSCRATCH	2
 
+#define USB_REQUEST_5V		1
+#define USB_REQUEST_9V		2
 /**
  * struct msm_usb_chg_info - MSM USB charger block details.
  * @chg_block_type: The type of charger block. QSCRATCH/ULPI.
@@ -28,4 +30,10 @@
 /* Vote against USB hardware low power mode */
 #define MSM_USB_EXT_CHG_BLOCK_LPM _IOW('M', 1, int)
 
+/* To tell kernel about voltage being voted */
+#define MSM_USB_EXT_CHG_VOLTAGE_INFO _IOW('M', 2, int)
+
+/* To tell kernel about voltage request result */
+#define MSM_USB_EXT_CHG_RESULT _IOW('M', 3, int)
+
 #endif /* __LINUX_USB_MSM_EXT_CHG_H */
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 862a0cc..d16448a 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -464,6 +464,7 @@
 	struct completion ext_chg_wait;
 	int ui_enabled;
 	bool pm_done;
+	struct qpnp_vadc_chip	*vadc_dev;
 };
 
 struct ci13xxx_platform_data {
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index e301d8f..a88a71d 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -494,9 +494,18 @@
 	MSM_ACTUATOR_WORD_ADDR,
 };
 
+enum msm_actuator_i2c_operation {
+	MSM_ACT_WRITE = 0,
+	MSM_ACT_POLL,
+};
+
 struct reg_settings_t {
 	uint16_t reg_addr;
+	enum msm_actuator_addr_type addr_type;
 	uint16_t reg_data;
+	enum msm_actuator_data_type data_type;
+	enum msm_actuator_i2c_operation i2c_operation;
+	uint32_t delay;
 };
 
 struct region_params_t {
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 77084ed..9f0d486 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2046,6 +2046,34 @@
 };
 
 /**
+ * enum wiphy_vendor_command_flags - validation flags for vendor commands
+ * @WIPHY_VENDOR_CMD_NEED_WDEV: vendor command requires wdev
+ * @WIPHY_VENDOR_CMD_NEED_NETDEV: vendor command requires netdev
+ * @WIPHY_VENDOR_CMD_NEED_RUNNING: interface/wdev must be up & running
+ *	(must be combined with %_WDEV or %_NETDEV)
+ */
+enum wiphy_vendor_command_flags {
+	WIPHY_VENDOR_CMD_NEED_WDEV = BIT(0),
+	WIPHY_VENDOR_CMD_NEED_NETDEV = BIT(1),
+	WIPHY_VENDOR_CMD_NEED_RUNNING = BIT(2),
+};
+
+/**
+ * struct wiphy_vendor_command - vendor command definition
+ * @info: vendor command identifying information, as used in nl80211
+ * @flags: flags, see &enum wiphy_vendor_command_flags
+ * @doit: callback for the operation, note that wdev is %NULL if the
+ *	flags didn't ask for a wdev and non-%NULL otherwise; the data
+ *	pointer may be %NULL if userspace provided no data at all
+ */
+struct wiphy_vendor_command {
+	struct nl80211_vendor_cmd_info info;
+	u32 flags;
+	int (*doit)(struct wiphy *wiphy, struct wireless_dev *wdev,
+		    void *data, int data_len);
+};
+
+/**
  * struct wiphy - wireless hardware description
  * @reg_notifier: the driver's regulatory notification callback,
  *	note that if your driver uses wiphy_apply_custom_regulatory()
@@ -2144,6 +2172,11 @@
  *	supports for ACL.
  * @country_ie_pref: country IE processing preferences specified
  *	by enum nl80211_country_ie_pref
+ *
+ * @vendor_commands: array of vendor commands supported by the hardware
+ * @n_vendor_commands: number of vendor commands
+ * @vendor_events: array of vendor events supported by the hardware
+ * @n_vendor_events: number of vendor events
  */
 struct wiphy {
 	/* assign these fields before you register the wiphy */
@@ -2248,6 +2281,10 @@
 	const struct iw_handler_def *wext;
 #endif
 
+	const struct wiphy_vendor_command *vendor_commands;
+	const struct nl80211_vendor_cmd_info *vendor_events;
+	int n_vendor_commands, n_vendor_events;
+
 	char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
 };
 
@@ -3128,6 +3165,121 @@
  */
 void wiphy_rfkill_stop_polling(struct wiphy *wiphy);
 
+/**
+ * DOC: Vendor commands
+ *
+ * Occasionally, there are special protocol or firmware features that
+ * can't be implemented very openly. For this and similar cases, the
+ * vendor command functionality allows implementing the features with
+ * (typically closed-source) userspace and firmware, using nl80211 as
+ * the configuration mechanism.
+ *
+ * A driver supporting vendor commands must register them as an array
+ * in struct wiphy, with handlers for each one, each command has an
+ * OUI and sub command ID to identify it.
+ *
+ * Note that this feature should not be (ab)used to implement protocol
+ * features that could openly be shared across drivers. In particular,
+ * it must never be required to use vendor commands to implement any
+ * "normal" functionality that higher-level userspace like connection
+ * managers etc. need.
+ */
+
+struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
+					   enum nl80211_commands cmd,
+					   enum nl80211_attrs attr,
+					   int approxlen);
+
+struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
+					   enum nl80211_commands cmd,
+					   enum nl80211_attrs attr,
+					   int vendor_event_idx,
+					   int approxlen, gfp_t gfp);
+
+void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp);
+
+/**
+ * cfg80211_vendor_cmd_alloc_reply_skb - allocate vendor command reply
+ * @wiphy: the wiphy
+ * @approxlen: an upper bound of the length of the data that will
+ *	be put into the skb
+ *
+ * This function allocates and pre-fills an skb for a reply to
+ * a vendor command. Since it is intended for a reply, calling
+ * it outside of a vendor command's doit() operation is invalid.
+ *
+ * The returned skb is pre-filled with some identifying data in
+ * a way that any data that is put into the skb (with skb_put(),
+ * nla_put() or similar) will end up being within the
+ * %NL80211_ATTR_VENDOR_DATA attribute, so all that needs to be done
+ * with the skb is adding data for the corresponding userspace tool
+ * which can then read that data out of the testdata attribute. You
+ * must not modify the skb in any other way.
+ *
+ * When done, call cfg80211_vendor_cmd_reply() with the skb and return
+ * its error code as the result of the doit() operation.
+ *
+ * Return: An allocated and pre-filled skb. %NULL if any errors happen.
+ */
+static inline struct sk_buff *
+cfg80211_vendor_cmd_alloc_reply_skb(struct wiphy *wiphy, int approxlen)
+{
+	return __cfg80211_alloc_reply_skb(wiphy, NL80211_CMD_TESTMODE,
+					  NL80211_ATTR_TESTDATA, approxlen);
+}
+
+/**
+ * cfg80211_vendor_cmd_reply - send the reply skb
+ * @skb: The skb, must have been allocated with
+ *	cfg80211_vendor_cmd_alloc_reply_skb()
+ *
+ * Since calling this function will usually be the last thing
+ * before returning from the vendor command doit() you should
+ * return the error code.  Note that this function consumes the
+ * skb regardless of the return value.
+ *
+ * Return: An error code or 0 on success.
+ */
+int cfg80211_vendor_cmd_reply(struct sk_buff *skb);
+
+/**
+ * cfg80211_vendor_event_alloc - allocate vendor-specific event skb
+ * @wiphy: the wiphy
+ * @event_idx: index of the vendor event in the wiphy's vendor_events
+ * @approxlen: an upper bound of the length of the data that will
+ *	be put into the skb
+ * @gfp: allocation flags
+ *
+ * This function allocates and pre-fills an skb for an event on the
+ * vendor-specific multicast group.
+ *
+ * When done filling the skb, call cfg80211_vendor_event() with the
+ * skb to send the event.
+ *
+ * Return: An allocated and pre-filled skb. %NULL if any errors happen.
+ */
+static inline struct sk_buff *
+cfg80211_vendor_event_alloc(struct wiphy *wiphy, int approxlen,
+			    int event_idx, gfp_t gfp)
+{
+	return __cfg80211_alloc_event_skb(wiphy, NL80211_CMD_VENDOR,
+					  NL80211_ATTR_VENDOR_DATA,
+					  event_idx, approxlen, gfp);
+}
+
+/**
+ * cfg80211_vendor_event - send the event
+ * @skb: The skb, must have been allocated with cfg80211_vendor_event_alloc()
+ * @gfp: allocation flags
+ *
+ * This function sends the given @skb, which must have been allocated
+ * by cfg80211_vendor_event_alloc(), as an event. It always consumes it.
+ */
+static inline void cfg80211_vendor_event(struct sk_buff *skb, gfp_t gfp)
+{
+	__cfg80211_send_event_skb(skb, gfp);
+}
+
 #ifdef CONFIG_NL80211_TESTMODE
 /**
  * DOC: Test mode
@@ -3161,8 +3313,12 @@
  * When done, call cfg80211_testmode_reply() with the skb and return
  * its error code as the result of the @testmode_cmd operation.
  */
-struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,
-						  int approxlen);
+static inline struct sk_buff *
+cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy, int approxlen)
+{
+	return __cfg80211_alloc_reply_skb(wiphy, NL80211_CMD_TESTMODE,
+					  NL80211_ATTR_TESTDATA, approxlen);
+}
 
 /**
  * cfg80211_testmode_reply - send the reply skb
@@ -3175,7 +3331,10 @@
  * Note that this function consumes the skb regardless of the
  * return value.
  */
-int cfg80211_testmode_reply(struct sk_buff *skb);
+static inline int cfg80211_testmode_reply(struct sk_buff *skb)
+{
+	return cfg80211_vendor_cmd_reply(skb);
+}
 
 /**
  * cfg80211_testmode_alloc_event_skb - allocate testmode event
@@ -3196,8 +3355,13 @@
  * When done filling the skb, call cfg80211_testmode_event() with the
  * skb to send the event.
  */
-struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy,
-						  int approxlen, gfp_t gfp);
+static inline struct sk_buff *
+cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, int approxlen, gfp_t gfp)
+{
+	return __cfg80211_alloc_event_skb(wiphy, NL80211_CMD_TESTMODE,
+					  NL80211_ATTR_TESTDATA, -1,
+					  approxlen, gfp);
+}
 
 /**
  * cfg80211_testmode_event - send the event
@@ -3209,7 +3373,10 @@
  * by cfg80211_testmode_alloc_event_skb(), as an event. It always
  * consumes it.
  */
-void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp);
+static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
+{
+	__cfg80211_send_event_skb(skb, gfp);
+}
 
 #define CFG80211_TESTMODE_CMD(cmd)	.testmode_cmd = (cmd),
 #define CFG80211_TESTMODE_DUMP(cmd)	.testmode_dump = (cmd),
diff --git a/include/sound/q6lsm.h b/include/sound/q6lsm.h
index 34eba81..8f06f20c 100644
--- a/include/sound/q6lsm.h
+++ b/include/sound/q6lsm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -47,6 +47,8 @@
 	uint16_t	user_sensitivity;
 	uint16_t	kw_sensitivity;
 	bool		started;
+	dma_addr_t	lsm_cal_phy_addr;
+	uint32_t	lsm_cal_size;
 };
 
 struct lsm_stream_cmd_open_tx {
@@ -123,10 +125,9 @@
 int q6lsm_open(struct lsm_client *client);
 int q6lsm_start(struct lsm_client *client, bool wait);
 int q6lsm_stop(struct lsm_client *client, bool wait);
-int q6lsm_snd_model_buf_alloc(struct lsm_client *client, uint32_t len);
+int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len);
 int q6lsm_snd_model_buf_free(struct lsm_client *client);
 int q6lsm_close(struct lsm_client *client);
-int q6lsm_unmap_cal_blocks(void);
 int q6lsm_register_sound_model(struct lsm_client *client,
 			       enum lsm_detection_mode mode, u16 minkeyword,
 			       u16 minuser, bool detectfailure);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 036faee..2e85324 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -69,9 +69,7 @@
 
 	struct mutex sched_scan_mtx;
 
-#ifdef CONFIG_NL80211_TESTMODE
-	struct genl_info *testmode_info;
-#endif
+	struct genl_info *cur_cmd_info;
 
 	struct work_struct conn_work;
 	struct work_struct event_work;
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 0e44fa8..c27f165 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -295,6 +295,12 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
+country ET: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
+
 country FI: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5170 - 5250 @ 80), (N/A, 20)
@@ -410,7 +416,7 @@
 
 country ID:
 	# ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf
-	(2402 - 2482 @ 40), (N/A, 20)
+	(2402 - 2482 @ 20), (N/A, 20)
 	(5735 - 5815 @ 20), (N/A, 23)
 
 country IE: DFS-ETSI
@@ -485,6 +491,13 @@
 	(5250 - 5330 @ 80), (N/A, 20), DFS
 	(5490 - 5710 @ 80), (N/A, 27), DFS
 
+country KY:
+        (2402 - 2472 @ 40), (N/A, 27)
+	(5170 - 5250 @ 80), (3, 17)
+	(5250 - 5330 @ 80), (3, 24), DFS
+	(5490 - 5710 @ 80), (3, 24), DFS
+	(5735 - 5835 @ 80), (3, 30)
+
 country KP:
 	(2402 - 2482 @ 20), (N/A, 20)
 	(5170 - 5330 @ 20), (6, 20)
@@ -825,6 +838,12 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
+country SR: DFS-ETSI
+	(2400 - 2483.5 @ 40), (N/A, 100 mW)
+	(5150 - 5250 @ 80), (N/A, 100 mW), NO-OUTDOOR
+	(5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
+	(5470 - 5725 @ 80), (N/A, 500 mW), DFS
+
 country SV:
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5170 - 5250 @ 20), (3, 17)
@@ -947,6 +966,12 @@
 	(5470 - 5725 @ 80), (6, 24), DFS
 	(5725 - 5850 @ 80), (6, 30)
 
+country WS: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 20), (3, 17)
+	(5250 - 5330 @ 80), (3, 24), DFS
+	(5490 - 5710 @ 80), (3, 24), DFS
+
 country YE:
 	(2402 - 2482 @ 40), (N/A, 20)
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a251231..e90ef68 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -225,6 +225,18 @@
 	[NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
 	[NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
 	[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
+	[NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
+	[NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
+	[NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
+	[NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 },
+	[NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 },
+	[NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
+	[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
+	[NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
+	[NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
+	[NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
+	[NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
+	[NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
 };
 
 /* policy for the key attributes */
@@ -1076,6 +1088,39 @@
 		NLA_PUT_U32(msg, NL80211_ATTR_MAC_ACL_MAX,
 			    dev->wiphy.max_acl_mac_addrs);
 
+	if (dev->wiphy.n_vendor_commands) {
+		const struct nl80211_vendor_cmd_info *info;
+		struct nlattr *nested;
+
+		nested = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+		if (!nested)
+			goto nla_put_failure;
+
+		for (i = 0; i < dev->wiphy.n_vendor_commands; i++) {
+			info = &dev->wiphy.vendor_commands[i].info;
+			if (nla_put(msg, i + 1, sizeof(*info), info))
+				goto nla_put_failure;
+			}
+			nla_nest_end(msg, nested);
+	}
+
+	if (dev->wiphy.n_vendor_events) {
+		const struct nl80211_vendor_cmd_info *info;
+		struct nlattr *nested;
+
+		nested = nla_nest_start(msg,
+			NL80211_ATTR_VENDOR_EVENTS);
+		if (!nested)
+			goto nla_put_failure;
+
+		for (i = 0; i < dev->wiphy.n_vendor_events; i++) {
+			info = &dev->wiphy.vendor_events[i];
+			if (nla_put(msg, i + 1, sizeof(*info), info))
+				goto nla_put_failure;
+		}
+		nla_nest_end(msg, nested);
+	}
+
 	return genlmsg_end(msg, hdr);
 
  nla_put_failure:
@@ -5211,6 +5256,57 @@
 	return cfg80211_leave_ibss(rdev, dev, false);
 }
 
+static struct sk_buff *
+__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
+			    int approxlen, u32 portid, u32 seq,
+			    enum nl80211_commands cmd,
+			    enum nl80211_attrs attr,
+			    const struct nl80211_vendor_cmd_info *info,
+			    gfp_t gfp)
+{
+	struct sk_buff *skb;
+	void *hdr;
+	struct nlattr *data;
+
+	skb = nlmsg_new(approxlen + 100, gfp);
+	if (!skb)
+		return NULL;
+
+	hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
+	if (!hdr) {
+		kfree_skb(skb);
+		return NULL;
+	}
+
+	if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
+		goto nla_put_failure;
+
+	if (info) {
+		if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
+				info->vendor_id))
+			goto nla_put_failure;
+		if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
+				info->subcmd))
+			goto nla_put_failure;
+	}
+
+	data = nla_nest_start(skb, attr);
+
+	((void **)skb->cb)[0] = rdev;
+	((void **)skb->cb)[1] = hdr;
+	((void **)skb->cb)[2] = data;
+
+	return skb;
+
+ nla_put_failure:
+	kfree_skb(skb);
+	return NULL;
+}
+
+static struct genl_multicast_group nl80211_vendor_mcgrp = {
+	.name = "vendor",
+};
+
 #ifdef CONFIG_NL80211_TESTMODE
 static struct genl_multicast_group nl80211_testmode_mcgrp = {
 	.name = "testmode",
@@ -5226,11 +5322,11 @@
 
 	err = -EOPNOTSUPP;
 	if (rdev->ops->testmode_cmd) {
-		rdev->testmode_info = info;
+		rdev->cur_cmd_info = info;
 		err = rdev->ops->testmode_cmd(&rdev->wiphy,
 				nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
 				nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
-		rdev->testmode_info = NULL;
+		rdev->cur_cmd_info = NULL;
 	}
 
 	return err;
@@ -5335,89 +5431,53 @@
 	return err;
 }
 
-static struct sk_buff *
-__cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev,
-			      int approxlen, u32 pid, u32 seq, gfp_t gfp)
-{
-	struct sk_buff *skb;
-	void *hdr;
-	struct nlattr *data;
-
-	skb = nlmsg_new(approxlen + 100, gfp);
-	if (!skb)
-		return NULL;
-
-	hdr = nl80211hdr_put(skb, pid, seq, 0, NL80211_CMD_TESTMODE);
-	if (!hdr) {
-		kfree_skb(skb);
-		return NULL;
-	}
-
-	NLA_PUT_U32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
-	data = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
-
-	((void **)skb->cb)[0] = rdev;
-	((void **)skb->cb)[1] = hdr;
-	((void **)skb->cb)[2] = data;
-
-	return skb;
-
- nla_put_failure:
-	kfree_skb(skb);
-	return NULL;
-}
-
-struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,
-						  int approxlen)
+struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
+					   enum nl80211_commands cmd,
+					   enum nl80211_attrs attr,
+					   int vendor_event_idx,
+					   int approxlen, gfp_t gfp)
 {
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	const struct nl80211_vendor_cmd_info *info;
 
-	if (WARN_ON(!rdev->testmode_info))
+	switch (cmd) {
+	case NL80211_CMD_TESTMODE:
+		if (WARN_ON(vendor_event_idx != -1))
+			return NULL;
+		info = NULL;
+		break;
+	case NL80211_CMD_VENDOR:
+		if (WARN_ON(vendor_event_idx < 0 ||
+			    vendor_event_idx >= wiphy->n_vendor_events))
+			return NULL;
+		info = &wiphy->vendor_events[vendor_event_idx];
+		break;
+	default:
+		WARN_ON(1);
 		return NULL;
-
-	return __cfg80211_testmode_alloc_skb(rdev, approxlen,
-				rdev->testmode_info->snd_pid,
-				rdev->testmode_info->snd_seq,
-				GFP_KERNEL);
+	}
+	return __cfg80211_alloc_vendor_skb(rdev, approxlen, 0, 0,
+					   cmd, attr, info, gfp);
 }
-EXPORT_SYMBOL(cfg80211_testmode_alloc_reply_skb);
+EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
 
-int cfg80211_testmode_reply(struct sk_buff *skb)
+void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
 {
 	struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
 	void *hdr = ((void **)skb->cb)[1];
 	struct nlattr *data = ((void **)skb->cb)[2];
 
-	if (WARN_ON(!rdev->testmode_info)) {
-		kfree_skb(skb);
-		return -EINVAL;
-	}
-
 	nla_nest_end(skb, data);
 	genlmsg_end(skb, hdr);
-	return genlmsg_reply(skb, rdev->testmode_info);
+
+	if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
+		genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), skb, 0,
+			nl80211_vendor_mcgrp.id, gfp);
+	else
+		genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), skb, 0,
+			nl80211_testmode_mcgrp.id, gfp);
 }
-EXPORT_SYMBOL(cfg80211_testmode_reply);
-
-struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy,
-						  int approxlen, gfp_t gfp)
-{
-	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-
-	return __cfg80211_testmode_alloc_skb(rdev, approxlen, 0, 0, gfp);
-}
-EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb);
-
-void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
-{
-	void *hdr = ((void **)skb->cb)[1];
-	struct nlattr *data = ((void **)skb->cb)[2];
-
-	nla_nest_end(skb, data);
-	genlmsg_end(skb, hdr);
-	genlmsg_multicast(skb, 0, nl80211_testmode_mcgrp.id, gfp);
-}
-EXPORT_SYMBOL(cfg80211_testmode_event);
+EXPORT_SYMBOL(__cfg80211_send_event_skb);
 #endif
 
 static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
@@ -6635,6 +6695,105 @@
 	return rdev->ops->update_ft_ies(&rdev->wiphy, dev, &ft_params);
 }
 
+static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct net_device *dev = info->user_ptr[1];
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int i, err;
+	u32 vid, subcmd;
+
+	if (!rdev->wiphy.vendor_commands)
+		return -EOPNOTSUPP;
+
+	if (IS_ERR(wdev)) {
+		err = PTR_ERR(wdev);
+		if (err != -EINVAL)
+			return err;
+		wdev = NULL;
+	} else if (wdev->wiphy != &rdev->wiphy) {
+		return -EINVAL;
+	}
+
+	if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
+	    !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
+		return -EINVAL;
+
+	vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
+	subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
+	for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
+		const struct wiphy_vendor_command *vcmd;
+		void *data = NULL;
+		int len = 0;
+
+		vcmd = &rdev->wiphy.vendor_commands[i];
+
+		if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
+			continue;
+
+		if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
+				   WIPHY_VENDOR_CMD_NEED_NETDEV)) {
+			if (!wdev)
+				return -EINVAL;
+			if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
+			    !wdev->netdev)
+				return -EINVAL;
+
+			if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
+				if (wdev->netdev &&
+				    !netif_running(wdev->netdev))
+					return -ENETDOWN;
+			}
+		} else {
+			wdev = NULL;
+		}
+
+		if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
+			data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
+			len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
+		}
+
+		return rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
+							   data, len);
+	}
+
+	return -EOPNOTSUPP;
+}
+
+struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
+					   enum nl80211_commands cmd,
+					   enum nl80211_attrs attr,
+					   int approxlen)
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+	if (WARN_ON(!rdev->cur_cmd_info))
+		return NULL;
+
+	return __cfg80211_alloc_vendor_skb(rdev, approxlen,
+					   0,
+					   0,
+					   cmd, attr, NULL, GFP_KERNEL);
+}
+EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
+
+int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
+{
+	struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
+	void *hdr = ((void **)skb->cb)[1];
+	struct nlattr *data = ((void **)skb->cb)[2];
+
+	if (WARN_ON(!rdev->cur_cmd_info)) {
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+
+	nla_nest_end(skb, data);
+	genlmsg_end(skb, hdr);
+	return genlmsg_reply(skb, rdev->cur_cmd_info);
+}
+EXPORT_SYMBOL(cfg80211_vendor_cmd_reply);
+
 #define NL80211_FLAG_NEED_WIPHY		0x01
 #define NL80211_FLAG_NEED_NETDEV	0x02
 #define NL80211_FLAG_NEED_RTNL		0x04
@@ -7239,7 +7398,14 @@
 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
-
+	{
+		.cmd = NL80211_CMD_VENDOR,
+		.doit = nl80211_vendor_cmd,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_WIPHY |
+				  NL80211_FLAG_NEED_RTNL,
+	},
 };
 
 static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -8562,6 +8728,9 @@
 	if (err)
 		goto err_out;
 #endif
+	err = genl_register_mc_group(&nl80211_fam, &nl80211_vendor_mcgrp);
+	if (err)
+		goto err_out;
 
 	err = netlink_register_notifier(&nl80211_netlink_notifier);
 	if (err)
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
old mode 100644
new mode 100755
index af648e0..120e0dc
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -19,7 +19,9 @@
 #include <net/netlink.h>
 #include <net/wext.h>
 #include <net/net_namespace.h>
-
+#ifdef KW_TAINT_ANALYSIS
+       extern void * get_tainted_stuff();
+#endif
 typedef int (*wext_ioctl_func)(struct net_device *, struct iwreq *,
 			       unsigned int, struct iw_request_info *,
 			       iw_handler);
@@ -1006,8 +1008,13 @@
 
 
 int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
-		      void __user *arg)
+		      void __user *arg_actual)
 {
+	#ifdef KW_TAINT_ANALYSIS
+	void __user *arg = (void __user *)get_tainted_stuff();
+	#else	
+	void __user *arg = (void __user *)arg_actual;
+	#endif
 	struct iw_request_info info = { .cmd = cmd, .flags = 0 };
 	int ret;
 
@@ -1056,7 +1063,11 @@
 int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
 			     unsigned long arg)
 {
+	#ifdef KW_TAINT_ANALYSIS
+	void __user *argp = (void __user *)get_tainted_stuff();
+	#else
 	void __user *argp = (void __user *)arg;
+	#endif	
 	struct iw_request_info info;
 	struct iwreq iwr;
 	char *colon;
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
old mode 100644
new mode 100755
index a306bc6..c143046
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -59,7 +59,9 @@
 
 #include <net/x25.h>
 #include <net/compat.h>
-
+#ifdef KW_TAINT_ANALYSIS
+   extern void * get_tainted_stuff();
+#endif
 int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20;
 int sysctl_x25_call_request_timeout    = X25_DEFAULT_T21;
 int sysctl_x25_reset_request_timeout   = X25_DEFAULT_T22;
@@ -1625,7 +1627,7 @@
 
 #ifdef CONFIG_COMPAT
 static int compat_x25_subscr_ioctl(unsigned int cmd,
-		struct compat_x25_subscrip_struct __user *x25_subscr32)
+		struct compat_x25_subscrip_struct __user *x25_subscr32_actual)
 {
 	struct compat_x25_subscrip_struct x25_subscr;
 	struct x25_neigh *nb;
@@ -1633,6 +1635,11 @@
 	int rc = -EINVAL;
 
 	rc = -EFAULT;
+	#ifdef KW_TAINT_ANALYSIS
+	struct compat_x25_subscrip_struct __user *x25_subscr32 = (struct compat_x25_subscrip_struct __user *)get_tainted_stuff();
+	#else
+	struct compat_x25_subscrip_struct __user *x25_subscr32 = x25_subscr32_actual;
+	#endif
 	if (copy_from_user(&x25_subscr, x25_subscr32, sizeof(*x25_subscr32)))
 		goto out;
 
@@ -1675,7 +1682,11 @@
 static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
 				unsigned long arg)
 {
+	#ifdef KW_TAINT_ANALYSIS
+	void __user *argp = (void __user *)get_tainted_stuff();
+	#else
 	void __user *argp = compat_ptr(arg);
+	#endif	
 	struct sock *sk = sock->sk;
 
 	int rc = -ENOIOCTLCMD;
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c
old mode 100644
new mode 100755
index 4acacf3..c82fcc2
--- a/net/x25/x25_link.c
+++ b/net/x25/x25_link.c
@@ -31,6 +31,9 @@
 #include <linux/init.h>
 #include <net/x25.h>
 
+#ifdef KW_TAINT_ANALYSIS
+   extern void * get_tainted_stuff();
+#endif
 LIST_HEAD(x25_neigh_list);
 DEFINE_RWLOCK(x25_neigh_list_lock);
 
@@ -338,13 +341,17 @@
 /*
  *	Handle the ioctls that control the subscription functions.
  */
-int x25_subscr_ioctl(unsigned int cmd, void __user *arg)
+int x25_subscr_ioctl(unsigned int cmd, void __user *arg_actual)
 {
 	struct x25_subscrip_struct x25_subscr;
 	struct x25_neigh *nb;
 	struct net_device *dev;
 	int rc = -EINVAL;
-
+	#ifdef KW_TAINT_ANALYSIS
+	void __user *arg = (void __user *)get_tainted_stuff();
+	#else
+	void __user *arg = arg_actual;
+	#endif
 	if (cmd != SIOCX25GSUBSCRIP && cmd != SIOCX25SSUBSCRIP)
 		goto out;
 
diff --git a/net/x25/x25_route.c b/net/x25/x25_route.c
old mode 100644
new mode 100755
index cf63662..7a1778a
--- a/net/x25/x25_route.c
+++ b/net/x25/x25_route.c
@@ -21,7 +21,9 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <net/x25.h>
-
+#ifdef KW_TAINT_ANALYSIS
+   extern void * get_tainted_stuff();
+#endif
 LIST_HEAD(x25_route_list);
 DEFINE_RWLOCK(x25_route_list_lock);
 
@@ -179,12 +181,16 @@
 /*
  *	Handle the ioctls that control the routing functions.
  */
-int x25_route_ioctl(unsigned int cmd, void __user *arg)
+int x25_route_ioctl(unsigned int cmd, void __user *arg_actual)
 {
 	struct x25_route_struct rt;
 	struct net_device *dev;
 	int rc = -EINVAL;
-
+	#ifdef KW_TAINT_ANALYSIS
+	void __user *arg = (void __user *)get_tainted_stuff();
+	#else
+	void __user *arg = arg_actual;
+	#endif
 	if (cmd != SIOCADDRT && cmd != SIOCDELRT)
 		goto out;
 
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index e3c9ad3..dd50020 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -5523,7 +5523,8 @@
 				mux_wait_us + WCD9XXX_USLEEP_RANGE_MARGIN_US);
 		break;
 	case PA_DISABLE:
-		wcd9xxx_enable_static_pa(mbhc, false);
+		if (!mbhc->hph_pa_dac_state)
+			wcd9xxx_enable_static_pa(mbhc, false);
 		wcd9xxx_restore_registers(codec, &tapan->reg_save_restore);
 		break;
 	}
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index cf33a9d..5dedec8 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -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
@@ -5147,6 +5147,24 @@
 	return 0;
 }
 
+static int taiko_codec_iir_mux_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	pr_debug("%s: event = %d\n", __func__, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		snd_soc_write(codec, w->reg, snd_soc_read(codec, w->reg));
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_write(codec, w->reg, snd_soc_read(codec, w->reg));
+		break;
+	}
+	return 0;
+}
+
 static int taiko_codec_dsm_mux_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
@@ -5645,10 +5663,16 @@
 		SND_SOC_DAPM_POST_PMD),
 
 	/* Sidetone */
-	SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
+	SND_SOC_DAPM_MUX_E("IIR1 INP1 MUX", TAIKO_A_CDC_IIR1_GAIN_B1_CTL, 0, 0,
+		&iir1_inp1_mux,  taiko_codec_iir_mux_event,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
 	SND_SOC_DAPM_MIXER("IIR1", TAIKO_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
 
-	SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux),
+	SND_SOC_DAPM_MUX_E("IIR2 INP1 MUX", TAIKO_A_CDC_IIR2_GAIN_B1_CTL, 0, 0,
+		&iir2_inp1_mux,  taiko_codec_iir_mux_event,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
 	SND_SOC_DAPM_MIXER("IIR2", TAIKO_A_CDC_CLK_SD_CTL, 1, 0, NULL, 0),
 
 	/* AUX PGA */
@@ -6513,7 +6537,8 @@
 		/* Clean up starts */
 		/* Turn off PA ramp generator */
 		snd_soc_write(codec, WCD9XXX_A_CDC_PA_RAMP_B1_CTL, 0x0);
-		wcd9xxx_enable_static_pa(mbhc, false);
+		if (!mbhc->hph_pa_dac_state)
+			wcd9xxx_enable_static_pa(mbhc, false);
 		wcd9xxx_restore_registers(codec, &taiko->reg_save_restore);
 		break;
 	}
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 12348f8..2b43ab6 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -689,20 +689,6 @@
 		.name = "DTMF_RX_HOSTLESS",
 	},
 	{
-		.capture = {
-			.stream_name = "Listen Audio Service Capture",
-			.aif_name = "LSM_UL_HL",
-			.rates = SNDRV_PCM_RATE_16000,
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
-			.channels_min = 1,
-			.channels_max = 1,
-			.rate_min = 16000,
-			.rate_max = 16000,
-		},
-		.ops = &msm_fe_dai_ops,
-		.name = "LSM",
-	},
-	{
 		.playback = {
 			.stream_name = "VoLTE Stub Playback",
 			.aif_name = "VOLTE_STUB_DL",
@@ -801,6 +787,118 @@
 		.ops = &msm_fe_dai_ops,
 		.name = "QCHAT",
 	},
+	{
+		.capture = {
+			.stream_name = "Listen 1 Audio Service Capture",
+			.aif_name = "LSM1_UL_HL",
+			.rates = SNDRV_PCM_RATE_16000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 1,
+			.rate_min = 16000,
+			.rate_max = 16000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "LSM1",
+	},
+	{
+		.capture = {
+			.stream_name = "Listen 2 Audio Service Capture",
+			.aif_name = "LSM2_UL_HL",
+			.rates = SNDRV_PCM_RATE_16000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 1,
+			.rate_min = 16000,
+			.rate_max = 16000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "LSM2",
+	},
+	{
+		.capture = {
+			.stream_name = "Listen 3 Audio Service Capture",
+			.aif_name = "LSM3_UL_HL",
+			.rates = SNDRV_PCM_RATE_16000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 1,
+			.rate_min = 16000,
+			.rate_max = 16000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "LSM3",
+	},
+	{
+		.capture = {
+			.stream_name = "Listen 4 Audio Service Capture",
+			.aif_name = "LSM4_UL_HL",
+			.rates = SNDRV_PCM_RATE_16000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 1,
+			.rate_min = 16000,
+			.rate_max = 16000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "LSM4",
+	},
+	{
+		.capture = {
+			.stream_name = "Listen 5 Audio Service Capture",
+			.aif_name = "LSM5_UL_HL",
+			.rates = SNDRV_PCM_RATE_16000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 1,
+			.rate_min = 16000,
+			.rate_max = 16000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "LSM5",
+	},
+	{
+		.capture = {
+			.stream_name = "Listen 6 Audio Service Capture",
+			.aif_name = "LSM6_UL_HL",
+			.rates = SNDRV_PCM_RATE_16000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 1,
+			.rate_min = 16000,
+			.rate_max = 16000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "LSM6",
+	},
+	{
+		.capture = {
+			.stream_name = "Listen 7 Audio Service Capture",
+			.aif_name = "LSM7_UL_HL",
+			.rates = SNDRV_PCM_RATE_16000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 1,
+			.rate_min = 16000,
+			.rate_max = 16000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "LSM7",
+	},
+	{
+		.capture = {
+			.stream_name = "Listen 8 Audio Service Capture",
+			.aif_name = "LSM8_UL_HL",
+			.rates = SNDRV_PCM_RATE_16000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 1,
+			.rate_min = 16000,
+			.rate_max = 16000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "LSM8",
+	},
 };
 
 static __devinit int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
index be0cb7f..b512bb5 100644
--- a/sound/soc/msm/msm8226.c
+++ b/sound/soc/msm/msm8226.c
@@ -1410,9 +1410,9 @@
 	},
 	/* LSM FE */
 	{
-		.name = "Listen Audio Service",
-		.stream_name = "Listen Audio Service",
-		.cpu_dai_name = "LSM",
+		.name = "Listen 1 Audio Service",
+		.stream_name = "Listen 1 Audio Service",
+		.cpu_dai_name = "LSM1",
 		.platform_name = "msm-lsm-client",
 		.dynamic = 1,
 		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
@@ -1439,6 +1439,142 @@
 		 /* this dainlink has playback support */
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
 	},
+	{
+		.name = "Listen 2 Audio Service",
+		.stream_name = "Listen 2 Audio Service",
+		.cpu_dai_name = "LSM2",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM2,
+	},
+	{
+		.name = "Listen 3 Audio Service",
+		.stream_name = "Listen 3 Audio Service",
+		.cpu_dai_name = "LSM3",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM3,
+	},
+	{
+		.name = "Listen 4 Audio Service",
+		.stream_name = "Listen 4 Audio Service",
+		.cpu_dai_name = "LSM4",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM4,
+	},
+	{
+		.name = "Listen 5 Audio Service",
+		.stream_name = "Listen 5 Audio Service",
+		.cpu_dai_name = "LSM5",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM5,
+	},
+	{
+		.name = "Listen 6 Audio Service",
+		.stream_name = "Listen 6 Audio Service",
+		.cpu_dai_name = "LSM6",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM6,
+	},
+	{
+		.name = "Listen 7 Audio Service",
+		.stream_name = "Listen 7 Audio Service",
+		.cpu_dai_name = "LSM7",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM7,
+	},
+	{
+		.name = "Listen 8 Audio Service",
+		.stream_name = "Listen 8 Audio Service",
+		.cpu_dai_name = "LSM8",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM8,
+	},
+	{
+		.name = "INT_HFP_BT Hostless",
+		.stream_name = "INT_HFP_BT Hostless",
+		.cpu_dai_name   = "INT_HFP_BT_HOSTLESS",
+		.platform_name  = "msm-pcm-hostless",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		/* this dai link has playback support */
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{
+		.name = "MSM8226 HFP TX",
+		.stream_name = "MultiMedia6",
+		.cpu_dai_name = "MultiMedia6",
+		.platform_name  = "msm-pcm-loopback",
+		.dynamic = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST},
+		.ignore_suspend = 1,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		/* this dai link has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA6,
+	},
 	/* Backend BT/FM DAI Links */
 	{
 		.name = LPASS_BE_INT_BT_SCO_RX,
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 0eea842..ca5e217 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -2117,9 +2117,9 @@
 	},
 	/* LSM FE */
 	{
-		.name = "Listen Audio Service",
-		.stream_name = "Listen Audio Service",
-		.cpu_dai_name = "LSM",
+		.name = "Listen 1 Audio Service",
+		.stream_name = "Listen 1 Audio Service",
+		.cpu_dai_name = "LSM1",
 		.platform_name = "msm-lsm-client",
 		.dynamic = 1,
 		.trigger = { SND_SOC_DPCM_TRIGGER_POST,
@@ -2256,6 +2256,111 @@
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA6,
 	},
 	{
+		.name = "Listen 2 Audio Service",
+		.stream_name = "Listen 2 Audio Service",
+		.cpu_dai_name = "LSM2",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = { SND_SOC_DPCM_TRIGGER_POST,
+			     SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM2,
+	},
+	{
+		.name = "Listen 3 Audio Service",
+		.stream_name = "Listen 3 Audio Service",
+		.cpu_dai_name = "LSM3",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = { SND_SOC_DPCM_TRIGGER_POST,
+			     SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM3,
+	},
+	{
+		.name = "Listen 4 Audio Service",
+		.stream_name = "Listen 4 Audio Service",
+		.cpu_dai_name = "LSM4",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = { SND_SOC_DPCM_TRIGGER_POST,
+			     SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM4,
+	},
+	{
+		.name = "Listen 5 Audio Service",
+		.stream_name = "Listen 5 Audio Service",
+		.cpu_dai_name = "LSM5",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = { SND_SOC_DPCM_TRIGGER_POST,
+			     SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM5,
+	},
+	{
+		.name = "Listen 6 Audio Service",
+		.stream_name = "Listen 6 Audio Service",
+		.cpu_dai_name = "LSM6",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = { SND_SOC_DPCM_TRIGGER_POST,
+			     SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM6,
+	},
+	{
+		.name = "Listen 7 Audio Service",
+		.stream_name = "Listen 7 Audio Service",
+		.cpu_dai_name = "LSM7",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = { SND_SOC_DPCM_TRIGGER_POST,
+			     SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM7,
+	},
+	{
+		.name = "Listen 8 Audio Service",
+		.stream_name = "Listen 8 Audio Service",
+		.cpu_dai_name = "LSM8",
+		.platform_name = "msm-lsm-client",
+		.dynamic = 1,
+		.trigger = { SND_SOC_DPCM_TRIGGER_POST,
+			     SND_SOC_DPCM_TRIGGER_POST },
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.be_id = MSM_FRONTEND_DAI_LSM8,
+	},
+	{
 		.name = LPASS_BE_SLIMBUS_4_TX,
 		.stream_name = "Slimbus4 Capture",
 		.cpu_dai_name = "msm-dai-q6-dev.16393",
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.c b/sound/soc/msm/qdsp6v2/audio_acdb.c
index 4e04bef..df15c59 100644
--- a/sound/soc/msm/qdsp6v2/audio_acdb.c
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-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
@@ -1151,13 +1151,6 @@
 		result = result2;
 	}
 
-	result2 = q6lsm_unmap_cal_blocks();
-	if (result2 < 0) {
-		pr_err("%s: lsm_unmap_cal_blocks failed, err = %d\n",
-			__func__, result2);
-		result = result2;
-	}
-
 	result2 = q6asm_unmap_cal_blocks();
 	if (result2 < 0) {
 		pr_err("%s: asm_unmap_cal_blocks failed, err = %d\n",
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 41ef3e3..143508f 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -472,11 +472,12 @@
 			COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
 	prtd->compr_cap.max_fragments =
 			COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
-	prtd->compr_cap.num_codecs = 4;
+	prtd->compr_cap.num_codecs = 5;
 	prtd->compr_cap.codecs[0] = SND_AUDIOCODEC_MP3;
 	prtd->compr_cap.codecs[1] = SND_AUDIOCODEC_AAC;
 	prtd->compr_cap.codecs[2] = SND_AUDIOCODEC_AC3;
 	prtd->compr_cap.codecs[3] = SND_AUDIOCODEC_EAC3;
+	prtd->compr_cap.codecs[4] = SND_AUDIOCODEC_PCM;
 }
 
 static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
@@ -486,8 +487,22 @@
 	struct msm_compr_audio *prtd = runtime->private_data;
 	struct asm_aac_cfg aac_cfg;
 	int ret = 0;
+	uint16_t bit_width = 16;
 
 	switch (prtd->codec) {
+	case FORMAT_LINEAR_PCM:
+		pr_debug("SND_AUDIOCODEC_PCM\n");
+		if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE)
+			bit_width = 24;
+		ret = q6asm_media_format_block_pcm_format_support(
+							prtd->audio_client,
+							prtd->sample_rate,
+							prtd->num_channels,
+							bit_width);
+		if (ret < 0)
+			pr_err("%s: CMD Format block failed\n", __func__);
+
+		break;
 	case FORMAT_MP3:
 		/* no media format block needed */
 		break;
@@ -744,6 +759,7 @@
 
 	if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0) &&
 	    (prtd->gapless_state.stream_opened[stream_index])) {
+		prtd->gapless_state.stream_opened[stream_index] = 0;
 		spin_unlock_irqrestore(&prtd->lock, flags);
 		pr_debug(" close stream %d", NEXT_STREAM_ID(stream_id));
 		q6asm_stream_cmd(ac, CMD_CLOSE, NEXT_STREAM_ID(stream_id));
@@ -753,6 +769,7 @@
 	stream_index = STREAM_ARRAY_INDEX(stream_id);
 	if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0) &&
 	    (prtd->gapless_state.stream_opened[stream_index])) {
+		prtd->gapless_state.stream_opened[stream_index] = 0;
 		spin_unlock_irqrestore(&prtd->lock, flags);
 		pr_debug("close stream %d", stream_id);
 		q6asm_stream_cmd(ac, CMD_CLOSE, stream_id);
@@ -826,6 +843,12 @@
 	pr_debug("%s: sample_rate %d\n", __func__, prtd->sample_rate);
 
 	switch (params->codec.id) {
+	case SND_AUDIOCODEC_PCM: {
+		pr_debug("SND_AUDIOCODEC_PCM\n");
+		prtd->codec = FORMAT_LINEAR_PCM;
+		break;
+	}
+
 	case SND_AUDIOCODEC_MP3: {
 		pr_debug("SND_AUDIOCODEC_MP3\n");
 		prtd->codec = FORMAT_MP3;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 2c001fa..e72502c 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-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
@@ -59,6 +59,7 @@
 #define INVALID_SESSION -1
 #define SESSION_TYPE_RX 0
 #define SESSION_TYPE_TX 1
+#define MAX_LSM_SESSIONS 8
 
 #define EC_PORT_ID_PRIMARY_MI2S_TX    1
 #define EC_PORT_ID_SECONDARY_MI2S_TX  2
@@ -153,12 +154,12 @@
  * If new back-end is defined, add new back-end DAI ID at the end of enum
  */
 
-
+#define SRS_TRUMEDIA_INDEX 2
 union srs_trumedia_params_u {
 	struct srs_trumedia_params srs_params;
 	unsigned short int raw_params[1];
 };
-static union srs_trumedia_params_u msm_srs_trumedia_params[2];
+static union srs_trumedia_params_u msm_srs_trumedia_params[SRS_TRUMEDIA_INDEX];
 static int srs_port_id = -1;
 
 static void srs_send_params(int port_id, unsigned int techs,
@@ -1186,7 +1187,7 @@
 			SRS_PARAM_OFFSET_MASK) >> 16);
 	value = (unsigned short)(ucontrol->value.integer.value[0] &
 			SRS_PARAM_VALUE_MASK);
-	if (offset < max) {
+	if ((offset < max) && (index < SRS_TRUMEDIA_INDEX)) {
 		msm_srs_trumedia_params[index].raw_params[offset] = value;
 		pr_debug("SRS %s: index set... (max %d, requested %d, val %d, paramblockidx %d)",
 			__func__, max, offset, value, index);
@@ -1475,7 +1476,7 @@
 		msm_route_ext_ec_ref = AFE_PORT_INVALID;
 		break;
 	}
-	if (voc_set_ext_ec_ref(msm_route_ext_ec_ref, state)) {
+	if (!voc_set_ext_ec_ref(msm_route_ext_ec_ref, state)) {
 		mutex_unlock(&routing_lock);
 		snd_soc_dapm_mux_update_power(widget, kcontrol, 1, mux, e);
 	} else {
@@ -2612,11 +2613,45 @@
 
 static const struct soc_enum lsm_mux_enum =
 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mad_audio_mux_text), mad_audio_mux_text);
-static const struct snd_kcontrol_new lsm_mux =
+
+static const struct snd_kcontrol_new lsm1_mux =
 	SOC_DAPM_ENUM_EXT("LSM1 MUX", lsm_mux_enum,
 			  msm_routing_lsm_mux_get,
 			  msm_routing_lsm_mux_put);
 
+static const struct snd_kcontrol_new lsm2_mux =
+	SOC_DAPM_ENUM_EXT("LSM2 MUX", lsm_mux_enum,
+			  msm_routing_lsm_mux_get,
+			  msm_routing_lsm_mux_put);
+static const struct snd_kcontrol_new lsm3_mux =
+	SOC_DAPM_ENUM_EXT("LSM3 MUX", lsm_mux_enum,
+			  msm_routing_lsm_mux_get,
+			  msm_routing_lsm_mux_put);
+
+static const struct snd_kcontrol_new lsm4_mux =
+	SOC_DAPM_ENUM_EXT("LSM4 MUX", lsm_mux_enum,
+			  msm_routing_lsm_mux_get,
+			  msm_routing_lsm_mux_put);
+static const struct snd_kcontrol_new lsm5_mux =
+	SOC_DAPM_ENUM_EXT("LSM5 MUX", lsm_mux_enum,
+			  msm_routing_lsm_mux_get,
+			  msm_routing_lsm_mux_put);
+
+static const struct snd_kcontrol_new lsm6_mux =
+	SOC_DAPM_ENUM_EXT("LSM6 MUX", lsm_mux_enum,
+			  msm_routing_lsm_mux_get,
+			  msm_routing_lsm_mux_put);
+static const struct snd_kcontrol_new lsm7_mux =
+	SOC_DAPM_ENUM_EXT("LSM7 MUX", lsm_mux_enum,
+			  msm_routing_lsm_mux_get,
+			  msm_routing_lsm_mux_put);
+
+static const struct snd_kcontrol_new lsm8_mux =
+	SOC_DAPM_ENUM_EXT("LSM8 MUX", lsm_mux_enum,
+			  msm_routing_lsm_mux_get,
+			  msm_routing_lsm_mux_put);
+
+
 static const char * const lsm_func_text[] = {
 	"None", "AUDIO", "BEACON", "ULTRASOUND", "SWAUDIO",
 };
@@ -3163,7 +3198,21 @@
 	SND_SOC_DAPM_AIF_IN("DTMF_DL_HL", "DTMF_RX_HOSTLESS Playback",
 		0, 0, 0, 0),
 	/* LSM */
-	SND_SOC_DAPM_AIF_OUT("LSM_UL_HL", "Listen Audio Service Capture",
+	SND_SOC_DAPM_AIF_OUT("LSM1_UL_HL", "Listen 1 Audio Service Capture",
+			     0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("LSM2_UL_HL", "Listen 2 Audio Service Capture",
+			     0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("LSM3_UL_HL", "Listen 3 Audio Service Capture",
+				 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("LSM4_UL_HL", "Listen 4 Audio Service Capture",
+						 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("LSM5_UL_HL", "Listen 5 Audio Service Capture",
+				 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("LSM6_UL_HL", "Listen 6 Audio Service Capture",
+				 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("LSM7_UL_HL", "Listen 7 Audio Service Capture",
+				 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("LSM8_UL_HL", "Listen 8 Audio Service Capture",
 			     0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("QCHAT_DL", "QCHAT Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("QCHAT_UL", "QCHAT Capture", 0, 0, 0, 0),
@@ -3251,7 +3300,14 @@
 				&pcm_rx_switch_mixer_controls),
 
 	/* Mux Definitions */
-	SND_SOC_DAPM_MUX("LSM1 MUX", SND_SOC_NOPM, 0, 0, &lsm_mux),
+	SND_SOC_DAPM_MUX("LSM1 MUX", SND_SOC_NOPM, 0, 0, &lsm1_mux),
+	SND_SOC_DAPM_MUX("LSM2 MUX", SND_SOC_NOPM, 0, 0, &lsm2_mux),
+	SND_SOC_DAPM_MUX("LSM3 MUX", SND_SOC_NOPM, 0, 0, &lsm3_mux),
+	SND_SOC_DAPM_MUX("LSM4 MUX", SND_SOC_NOPM, 0, 0, &lsm4_mux),
+	SND_SOC_DAPM_MUX("LSM5 MUX", SND_SOC_NOPM, 0, 0, &lsm5_mux),
+	SND_SOC_DAPM_MUX("LSM6 MUX", SND_SOC_NOPM, 0, 0, &lsm6_mux),
+	SND_SOC_DAPM_MUX("LSM7 MUX", SND_SOC_NOPM, 0, 0, &lsm7_mux),
+	SND_SOC_DAPM_MUX("LSM8 MUX", SND_SOC_NOPM, 0, 0, &lsm8_mux),
 	SND_SOC_DAPM_MUX("SLIM_0_RX AANC MUX", SND_SOC_NOPM, 0, 0,
 			aanc_slim_0_rx_mux),
 
@@ -3781,7 +3837,62 @@
 	{"LSM1 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
 	{"LSM1 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
 	{"LSM1 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
-	{"LSM_UL_HL", NULL, "LSM1 MUX"},
+	{"LSM1_UL_HL", NULL, "LSM1 MUX"},
+
+	{"LSM2 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+	{"LSM2 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+	{"LSM2 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+	{"LSM2 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+	{"LSM2 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+	{"LSM2_UL_HL", NULL, "LSM2 MUX"},
+
+
+	{"LSM3 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+	{"LSM3 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+	{"LSM3 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+	{"LSM3 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+	{"LSM3 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+	{"LSM3_UL_HL", NULL, "LSM3 MUX"},
+
+
+	{"LSM4 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+	{"LSM4 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+	{"LSM4 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+	{"LSM4 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+	{"LSM4 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+	{"LSM4_UL_HL", NULL, "LSM4 MUX"},
+
+	{"LSM5 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+	{"LSM5 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+	{"LSM5 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+	{"LSM5 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+	{"LSM5 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+	{"LSM5_UL_HL", NULL, "LSM5 MUX"},
+
+	{"LSM6 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+	{"LSM6 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+	{"LSM6 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+	{"LSM6 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+	{"LSM6 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+	{"LSM6_UL_HL", NULL, "LSM6 MUX"},
+
+
+	{"LSM7 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+	{"LSM7 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+	{"LSM7 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+	{"LSM7 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+	{"LSM7 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+	{"LSM7_UL_HL", NULL, "LSM7 MUX"},
+
+
+	{"LSM8 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+	{"LSM8 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+	{"LSM8 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+	{"LSM8 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+	{"LSM8 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+	{"LSM8_UL_HL", NULL, "LSM8 MUX"},
+
+
 
 	{"QCHAT_Tx Mixer", "PRI_TX_QCHAT", "PRI_I2S_TX"},
 	{"QCHAT_Tx Mixer", "SLIM_0_TX_QCHAT", "SLIMBUS_0_TX"},
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index 54f5e4a..f2b0436 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-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
@@ -79,9 +79,16 @@
 	MSM_FRONTEND_DAI_VOICE_STUB,
 	MSM_FRONTEND_DAI_VOLTE,
 	MSM_FRONTEND_DAI_DTMF_RX,
-	MSM_FRONTEND_DAI_LSM1,
 	MSM_FRONTEND_DAI_VOICE2,
 	MSM_FRONTEND_DAI_QCHAT,
+	MSM_FRONTEND_DAI_LSM1,
+	MSM_FRONTEND_DAI_LSM2,
+	MSM_FRONTEND_DAI_LSM3,
+	MSM_FRONTEND_DAI_LSM4,
+	MSM_FRONTEND_DAI_LSM5,
+	MSM_FRONTEND_DAI_LSM6,
+	MSM_FRONTEND_DAI_LSM7,
+	MSM_FRONTEND_DAI_LSM8,
 	MSM_FRONTEND_DAI_MAX,
 };
 
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 3dac1f9..74b79dd 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -133,6 +133,10 @@
 static ssize_t audio_output_latency_dbgfs_read(struct file *file,
 				char __user *buf, size_t count, loff_t *ppos)
 {
+	if (out_buffer == NULL) {
+		pr_err("%s: out_buffer is null\n", __func__);
+		return 0;
+	}
 	snprintf(out_buffer, OUT_BUFFER_SIZE, "%ld,%ld,%ld,%ld,%ld,%ld,",\
 		out_cold_tv.tv_sec, out_cold_tv.tv_usec, out_warm_tv.tv_sec,\
 		out_warm_tv.tv_usec, out_cont_tv.tv_sec, out_cont_tv.tv_usec);
@@ -178,6 +182,10 @@
 static ssize_t audio_input_latency_dbgfs_read(struct file *file,
 				char __user *buf, size_t count, loff_t *ppos)
 {
+	if (in_buffer == NULL) {
+		pr_err("%s: in_buffer is null\n", __func__);
+		return 0;
+	}
 	snprintf(in_buffer, IN_BUFFER_SIZE, "%ld,%ld,",\
 				in_cont_tv.tv_sec, in_cont_tv.tv_usec);
 	return  simple_read_from_buffer(buf, IN_BUFFER_SIZE, ppos,
@@ -293,17 +301,38 @@
 static void config_debug_fs_init(void)
 {
 	out_buffer = kmalloc(OUT_BUFFER_SIZE, GFP_KERNEL);
+	if (out_buffer == NULL) {
+		pr_err("%s: kmalloc() for out_buffer failed\n", __func__);
+		goto outbuf_fail;
+	}
+	in_buffer = kmalloc(IN_BUFFER_SIZE, GFP_KERNEL);
+	if (in_buffer == NULL) {
+		pr_err("%s: kmalloc() for in_buffer failed\n", __func__);
+		goto inbuf_fail;
+	}
 	out_dentry = debugfs_create_file("audio_out_latency_measurement_node",\
 				S_IRUGO | S_IWUSR | S_IWGRP,\
 				NULL, NULL, &audio_output_latency_debug_fops);
-	if (IS_ERR(out_dentry))
-		pr_err("debugfs_create_file failed\n");
-	in_buffer = kmalloc(IN_BUFFER_SIZE, GFP_KERNEL);
+	if (IS_ERR(out_dentry)) {
+		pr_err("%s: debugfs_create_file failed\n", __func__);
+		goto file_fail;
+	}
 	in_dentry = debugfs_create_file("audio_in_latency_measurement_node",\
 				S_IRUGO | S_IWUSR | S_IWGRP,\
 				NULL, NULL, &audio_input_latency_debug_fops);
-	if (IS_ERR(in_dentry))
-		pr_err("debugfs_create_file failed\n");
+	if (IS_ERR(in_dentry)) {
+		pr_err("%s: debugfs_create_file failed\n", __func__);
+		goto file_fail;
+	}
+	return;
+file_fail:
+	kfree(in_buffer);
+inbuf_fail:
+	kfree(out_buffer);
+outbuf_fail:
+	in_buffer = NULL;
+	out_buffer = NULL;
+	return;
 }
 #else
 static void config_debug_fs_write(struct audio_buffer *ab)
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
index e9352df..496a5ef 100644
--- a/sound/soc/msm/qdsp6v2/q6core.c
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -41,6 +41,11 @@
 	uint32_t nseg;
 	int i, j;
 
+	if (data == NULL) {
+		pr_err("%s: data argument is null\n", __func__);
+		return -EINVAL;
+	}
+
 	pr_debug("core msg: payload len = %u, apr resp opcode = 0x%X\n",
 		data->payload_size, data->opcode);
 
diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c
index 9227b23..a88b733 100644
--- a/sound/soc/msm/qdsp6v2/q6lsm.c
+++ b/sound/soc/msm/qdsp6v2/q6lsm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -35,6 +35,7 @@
 
 #define APR_TIMEOUT	(5 * HZ)
 #define LSM_CAL_SIZE	4096
+#define LSM_ALIGN_BOUNDARY 512
 
 enum {
 	CMD_STATE_CLEARED = 0,
@@ -48,13 +49,11 @@
 	LSM_CONTROL_SESSION = 0x0F,
 };
 
+#define CHECK_SESSION(x) (x < LSM_MIN_SESSION_ID || x > LSM_MAX_SESSION_ID)
 struct lsm_common {
 	void *apr;
 	atomic_t apr_users;
-	uint32_t lsm_cal_addr;
-	uint32_t lsm_cal_size;
-	uint32_t mmap_handle_for_cal;
-	struct lsm_client	common_client;
+	struct lsm_client	common_client[LSM_MAX_SESSION_ID + 1];
 	struct mutex apr_lock;
 };
 
@@ -93,9 +92,9 @@
 	}
 
 	payload = data->payload;
-	pr_debug("%s: Session %d opcode 0x%x token 0x%x payload size %d\n",
-		__func__, client->session,
-		data->opcode, data->token, data->payload_size);
+	pr_debug("%s: Session %d opcode 0x%x token 0x%x payload size %d\n"
+			 "payload [0] = %x\n", __func__, client->session,
+		data->opcode, data->token, data->payload_size, payload[0]);
 
 	if (data->opcode == APR_BASIC_RSP_RESULT) {
 		token = data->token;
@@ -150,13 +149,13 @@
 		}
 	}
 	spin_unlock_irqrestore(&lsm_session_lock, flags);
+	pr_debug("%s: Alloc Session %d", __func__, n);
 	return ret;
 }
 
 static void q6lsm_session_free(struct lsm_client *client)
 {
 	unsigned long flags;
-
 	pr_debug("%s: Freeing session ID %d\n", __func__, client->session);
 	spin_lock_irqsave(&lsm_session_lock, flags);
 	lsm_session[client->session] = LSM_INVALID_SESSION_ID;
@@ -207,13 +206,18 @@
 		kfree(client);
 		return NULL;
 	}
-
-	pr_debug("%s: New client session %d\n", __func__, client->session);
 	client->session = n;
 	client->cb = cb;
 	client->priv = priv;
+	pr_debug("%s:Client session %d\n", __func__, client->session);
+	if (CHECK_SESSION(client->session)) {
+		kfree(client);
+		return NULL;
+	}
+	pr_debug("%s:Client Session %d\n", __func__, client->session);
 	client->apr = apr_register("ADSP", "LSM", q6lsm_callback,
-				   ((client->session) << 8 | 0x0001), client);
+				   ((client->session) << 8 | client->session),
+				   client);
 
 	if (client->apr == NULL) {
 		pr_err("%s: Registration with APR failed\n", __func__);
@@ -239,9 +243,12 @@
 
 void q6lsm_client_free(struct lsm_client *client)
 {
-	if (!client || !client->session)
+	if (!client)
 		return;
-
+	if (CHECK_SESSION(client->session)) {
+		pr_err("%s: Invalid Session %d", __func__, client->session);
+		return;
+	}
 	apr_deregister(client->apr);
 	client->mmap_apr = NULL;
 	q6lsm_session_free(client);
@@ -308,8 +315,8 @@
 	hdr->src_domain = APR_DOMAIN_APPS;
 	hdr->dest_svc = APR_SVC_LSM;
 	hdr->dest_domain = APR_DOMAIN_ADSP;
-	hdr->src_port = ((client->session << 8) & 0xFF00) | 0x01;
-	hdr->dest_port = ((client->session << 8) & 0xFF00) | 0x01;
+	hdr->src_port = ((client->session << 8) & 0xFF00) | client->session;
+	hdr->dest_port = ((client->session << 8) & 0xFF00) | client->session;
 	hdr->pkt_size = pkt_size;
 	if (cmd_flg)
 		hdr->token = client->session;
@@ -331,7 +338,7 @@
 	if (rc)
 		pr_err("%s: Open failed opcode 0x%x, rc %d\n",
 		       __func__, open.hdr.opcode, rc);
-
+	pr_debug("%s: leave %d\n", __func__, rc);
 	return rc;
 }
 
@@ -429,15 +436,15 @@
 
 	q6lsm_add_hdr(client, &cmd.hdr, sizeof(cmd), true);
 	cmd.hdr.opcode = LSM_SESSION_CMD_REGISTER_SOUND_MODEL;
-	cmd.model_addr_lsw = client->sound_model.phys;
-	cmd.model_addr_msw = 0;
+	cmd.model_addr_lsw = lower_32_bits(client->sound_model.phys);
+	cmd.model_addr_msw = upper_32_bits(client->sound_model.phys);
 	cmd.model_size = client->sound_model.size;
 	/* read updated mem_map_handle by q6lsm_mmapcallback */
 	rmb();
 	cmd.mem_map_handle = client->sound_model.mem_map_handle;
 
-	pr_debug("%s: lsw %x, size %d, handle %x\n", __func__,
-		 cmd.model_addr_lsw, cmd.model_size, cmd.mem_map_handle);
+	pr_debug("%s: addr %pa, size %d, handle %x\n", __func__,
+		&client->sound_model.phys, cmd.model_size, cmd.mem_map_handle);
 	rc = q6lsm_apr_send_pkt(client, client->apr, &cmd, true, NULL);
 	if (rc)
 		pr_err("%s: Failed cmd op[0x%x]rc[%d]\n", __func__,
@@ -458,6 +465,8 @@
 		return -EINVAL;
 	}
 	pr_debug("%s: session[%d]", __func__, client->session);
+	if (CHECK_SESSION(client->session))
+		return -EINVAL;
 
 	memset(&cmd, 0, sizeof(cmd));
 	q6lsm_add_hdr(client, &cmd.hdr, sizeof(cmd.hdr), false);
@@ -492,7 +501,7 @@
 }
 
 static int q6lsm_memory_map_regions(struct lsm_client *client,
-				    uint32_t dma_addr_p, uint32_t dma_buf_sz,
+				    dma_addr_t dma_addr_p, uint32_t dma_buf_sz,
 				    uint32_t *mmap_p)
 {
 	struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL;
@@ -502,9 +511,11 @@
 	int rc;
 	int cmd_size = 0;
 
-	pr_debug("%s: dma_addr_p 0x%x, dma_buf_sz %d, mmap_p 0x%p, session %d\n",
-		 __func__, dma_addr_p, dma_buf_sz, mmap_p, client->session);
-
+	pr_debug("%s: dma_addr_p 0x%pa, dma_buf_sz %d, mmap_p 0x%p, session %d\n",
+		__func__, &dma_addr_p, dma_buf_sz, mmap_p,
+		client->session);
+	if (CHECK_SESSION(client->session))
+		return -EINVAL;
 	cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions) +
 		   sizeof(struct avs_shared_map_region_payload);
 
@@ -524,8 +535,8 @@
 		   sizeof(struct avs_cmd_shared_mem_map_regions));
 	mregions = (struct avs_shared_map_region_payload *)payload;
 
-	mregions->shm_addr_lsw = dma_addr_p;
-	mregions->shm_addr_msw = 0;
+	mregions->shm_addr_lsw = lower_32_bits(dma_addr_p);
+	mregions->shm_addr_msw = upper_32_bits(dma_addr_p);
 	mregions->mem_size_bytes = dma_buf_sz;
 
 	rc = q6lsm_apr_send_pkt(client, client->mmap_apr, mmap_region_cmd,
@@ -545,7 +556,8 @@
 	struct avs_cmd_shared_mem_unmap_regions unmap;
 	int rc = 0;
 	int cmd_size = 0;
-
+	if (CHECK_SESSION(client->session))
+		return -EINVAL;
 	cmd_size = sizeof(struct avs_cmd_shared_mem_unmap_regions);
 	q6lsm_add_mmaphdr(client, &unmap.hdr, cmd_size,
 			  true, (client->session << 8));
@@ -569,107 +581,35 @@
 	struct lsm_cmd_set_params params;
 	struct acdb_cal_block lsm_cal;
 
-	pr_debug("%s: enter\n", __func__);
-
+	pr_debug("%s: Session %d\n", __func__, client->session);
+	if (CHECK_SESSION(client->session))
+		return -EINVAL;
 	memset(&lsm_cal, 0, sizeof(lsm_cal));
 	get_lsm_cal(&lsm_cal);
-	if (!lsm_cal.cal_size) {
-		pr_err("%s: Could not get LSM calibration data\n", __func__);
-		rc = -EINVAL;
-		goto bail;
-	}
-
 	/* Cache mmap address, only map once or if new addr */
-	if ((lsm_common.lsm_cal_addr != lsm_cal.cal_paddr) ||
-	    (lsm_cal.cal_size > lsm_common.lsm_cal_size)) {
-		if (lsm_common.lsm_cal_addr != 0) {
-			rc = q6lsm_memory_unmap_regions(client,
-						lsm_common.mmap_handle_for_cal);
-			if (rc)
-				pr_warn("%s: Unmapping %x failed, %d\n",
-					__func__, lsm_common.lsm_cal_addr, rc);
-		}
-
-		rc = q6lsm_memory_map_regions(client, lsm_cal.cal_paddr,
-					      LSM_CAL_SIZE,
-					      &lsm_common.mmap_handle_for_cal);
-		if (rc < 0) {
-			pr_err("%s: Calibration data memory map failed, %d\n",
-			       __func__, rc);
-			goto bail;
-		}
-		lsm_common.lsm_cal_addr = lsm_cal.cal_paddr;
-		lsm_common.lsm_cal_size = LSM_CAL_SIZE;
-		lsm_common.common_client.session = client->session;
-	}
-
+	lsm_common.common_client[client->session].session = client->session;
 	q6lsm_add_hdr(client, &params.hdr, sizeof(params), true);
 	params.hdr.opcode = LSM_SESSION_CMD_SET_PARAMS;
-	params.data_payload_addr_lsw = lsm_cal.cal_paddr;
-	params.data_payload_addr_msw = 0;
-	/* read updated mem_map_handle by q6lsm_mmapcallback */
-	rmb();
-	params.mem_map_handle = lsm_common.mmap_handle_for_cal;
+	params.data_payload_addr_lsw = lower_32_bits(client->lsm_cal_phy_addr);
+	params.data_payload_addr_msw = upper_32_bits(client->lsm_cal_phy_addr);
+	params.mem_map_handle = client->sound_model.mem_map_handle;
 	params.data_payload_size = lsm_cal.cal_size;
-
+	pr_debug("%s: Cal Size = %x", __func__, client->lsm_cal_size);
 	rc = q6lsm_apr_send_pkt(client, client->apr, &params, true, NULL);
 	if (rc)
 		pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
 		       __func__, params.hdr.opcode, rc);
-bail:
 	return rc;
 }
 
-int q6lsm_unmap_cal_blocks(void)
-{
-	int	result = 0;
-	int	result2 = 0;
-
-	if (lsm_common.mmap_handle_for_cal == 0)
-		goto done;
-
-	if (lsm_common.common_client.mmap_apr == NULL) {
-		lsm_common.common_client.mmap_apr = q6lsm_mmap_apr_reg();
-		if (lsm_common.common_client.mmap_apr == NULL) {
-			pr_err("%s: q6lsm_mmap_apr_reg failed\n",
-				__func__);
-			result = -EPERM;
-			goto done;
-		}
-	}
-
-	result2 = q6lsm_memory_unmap_regions(
-		&lsm_common.common_client,
-		lsm_common.mmap_handle_for_cal);
-	if (result2 < 0) {
-		pr_err("%s: unmap failed, err %d\n",
-			__func__, result2);
-		result = result2;
-	} else {
-		lsm_common.mmap_handle_for_cal = 0;
-	}
-
-	result2 = q6lsm_mmap_apr_dereg();
-	if (result2 < 0) {
-		pr_err("%s: q6lsm_mmap_apr_dereg failed, err %d\n",
-			__func__, result2);
-		result = result2;
-	} else {
-		lsm_common.common_client.mmap_apr = NULL;
-	}
-
-	lsm_common.lsm_cal_addr = 0;
-	lsm_common.lsm_cal_size = 0;
-
-done:
-	return result;
-}
-
 int q6lsm_snd_model_buf_free(struct lsm_client *client)
 {
 	int rc;
 
 	pr_debug("%s: Session id %d\n", __func__, client->session);
+	if (CHECK_SESSION(client->session))
+		return -EINVAL;
+
 	mutex_lock(&client->cmd_lock);
 	rc = q6lsm_memory_unmap_regions(client,
 					client->sound_model.mem_map_handle);
@@ -678,12 +618,16 @@
 
 	if (client->sound_model.data) {
 		ion_unmap_kernel(client->sound_model.client,
-				 client->sound_model.handle);
+						 client->sound_model.handle);
 		ion_free(client->sound_model.client,
-			 client->sound_model.handle);
+				 client->sound_model.handle);
 		ion_client_destroy(client->sound_model.client);
+		client->sound_model.client = NULL;
+		client->sound_model.handle = NULL;
 		client->sound_model.data = NULL;
 		client->sound_model.phys = 0;
+		client->lsm_cal_phy_addr = 0;
+		client->lsm_cal_size = 0;
 	}
 	mutex_unlock(&client->cmd_lock);
 	return rc;
@@ -695,7 +639,7 @@
 	struct lsm_client *client = NULL;
 
 	if (session_id == LSM_CONTROL_SESSION) {
-		client = &lsm_common.common_client;
+		client = &lsm_common.common_client[session_id];
 		goto done;
 	}
 
@@ -724,19 +668,19 @@
 	struct lsm_client *client = NULL;
 
 	if (data->opcode == RESET_EVENTS) {
-		pr_debug("%s: SSR event received 0x%x, event 0x%x, proc 0x%x\n",
-			 __func__, data->opcode, data->reset_event,
-			 data->reset_proc);
-		lsm_common.lsm_cal_addr = 0;
+		sid = (data->token >> 8) & 0x0F;
+		pr_debug("%s: SSR event received 0x%x, event 0x%x,\n"
+			 "proc 0x%x SID 0x%x\n", __func__, data->opcode,
+			 data->reset_event, data->reset_proc, sid);
+		lsm_common.common_client[sid].lsm_cal_phy_addr = 0;
 		return 0;
 	}
 
 	command = payload[0];
 	retcode = payload[1];
-	pr_debug("%s: opcode 0x%x command 0x%x return code 0x%x\n", __func__,
-		 data->opcode, command, retcode);
-
 	sid = (data->token >> 8) & 0x0F;
+	pr_debug("%s: opcode 0x%x command 0x%x return code 0x%x SID 0x%x\n",
+		 __func__, data->opcode, command, retcode, sid);
 	client = q6lsm_get_lsm_client(sid);
 	if (!client) {
 		pr_debug("%s: Session %d already freed\n", __func__, sid);
@@ -774,15 +718,31 @@
 	return 0;
 }
 
-int q6lsm_snd_model_buf_alloc(struct lsm_client *client, uint32_t len)
+int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len)
 {
 	int rc = -EINVAL;
+	struct acdb_cal_block lsm_cal;
+	size_t pad_zero = 0, total_mem = 0;
 
-	if (!client)
+	if (!client || len <= LSM_ALIGN_BOUNDARY)
 		return rc;
-
+	memset(&lsm_cal, 0, sizeof(lsm_cal));
 	mutex_lock(&client->cmd_lock);
+	get_lsm_cal(&lsm_cal);
+	pr_debug("%s:Snd Model len = %d cal size %d", __func__,
+			 len, lsm_cal.cal_size);
+	if (!lsm_cal.cal_paddr) {
+		pr_err("%s: No LSM calibration set for session", __func__);
+		mutex_unlock(&client->cmd_lock);
+		return -EINVAL;
+	}
 	if (!client->sound_model.data) {
+		client->sound_model.size = len;
+		pad_zero = (LSM_ALIGN_BOUNDARY -
+			   (len % LSM_ALIGN_BOUNDARY));
+		total_mem = pad_zero + len + lsm_cal.cal_size;
+		pr_debug("%s: Pad zeros sound model %d Total mem %d\n",
+				 __func__, pad_zero, total_mem);
 		client->sound_model.client =
 		    msm_ion_client_create(UINT_MAX, "lsm_client");
 		if (IS_ERR_OR_NULL(client->sound_model.client)) {
@@ -791,8 +751,8 @@
 			goto fail;
 		}
 		client->sound_model.handle =
-			ion_alloc(client->sound_model.client,
-				  len, SZ_4K, (0x1 << ION_AUDIO_HEAP_ID), 0);
+		ion_alloc(client->sound_model.client,
+			  total_mem, SZ_4K, (0x1 << ION_AUDIO_HEAP_ID), 0);
 		if (IS_ERR_OR_NULL(client->sound_model.handle)) {
 			pr_err("%s: ION memory allocation for AUDIO failed\n",
 			       __func__);
@@ -817,7 +777,13 @@
 			goto fail;
 		}
 		memset(client->sound_model.data, 0, len);
-		client->sound_model.size = len;
+		client->lsm_cal_phy_addr = (pad_zero +
+					    client->sound_model.phys +
+					    client->sound_model.size);
+		client->lsm_cal_size = lsm_cal.cal_size;
+		memcpy((client->sound_model.data + pad_zero +
+			client->sound_model.size),
+			(uint32_t *)lsm_cal.cal_kvaddr, len);
 	} else {
 		rc = -EBUSY;
 		goto fail;
@@ -825,7 +791,7 @@
 	mutex_unlock(&client->cmd_lock);
 
 	rc = q6lsm_memory_map_regions(client, client->sound_model.phys,
-				      client->sound_model.size,
+				      len,
 				      &client->sound_model.mem_map_handle);
 	if (rc < 0) {
 		pr_err("%s:CMD Memory_map_regions failed\n", __func__);
@@ -882,16 +848,18 @@
 
 static int __init q6lsm_init(void)
 {
+	int i = 0;
 	pr_debug("%s\n", __func__);
 	spin_lock_init(&lsm_session_lock);
 	spin_lock_init(&mmap_lock);
 	mutex_init(&lsm_common.apr_lock);
-
-	lsm_common.common_client.session = LSM_CONTROL_SESSION;
-	init_waitqueue_head(&lsm_common.common_client.cmd_wait);
-	mutex_init(&lsm_common.common_client.cmd_lock);
-	atomic_set(&lsm_common.common_client.cmd_state, CMD_STATE_CLEARED);
-
+	for (; i <= LSM_MAX_SESSION_ID; i++) {
+		lsm_common.common_client[i].session = LSM_CONTROL_SESSION;
+		init_waitqueue_head(&lsm_common.common_client[i].cmd_wait);
+		mutex_init(&lsm_common.common_client[i].cmd_lock);
+		atomic_set(&lsm_common.common_client[i].cmd_state,
+			   CMD_STATE_CLEARED);
+	}
 	return 0;
 }