Merge "common: DMA-mapping: Add strongly ordered memory attribute"
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp.txt b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
index ef77e1e..d7290e0 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
@@ -4,9 +4,7 @@
 controlling LEDs that are part of PMIC on Qualcomm reference
 platforms. The PMIC is connected to Host processor via
 SPMI bus. This driver supports various LED modules such as
-WLED (white LED), RGB LED and flash LED. The first version of
-the driver supports WLED and other features are added in the
-next versions.
+WLED (white LED), RGB LED and flash LED.
 
 Required Properties:
 - compatible	: should be "qcom,leds-qpnp"
@@ -48,27 +46,60 @@
 - linux,default-trigger: trigger the led from external modules such as display
 - qcom,default-state:  default state of the led, should be "on" or "off"
 
+RGB Led is a tri-colored led, Red, Blue & Green.
+
+Required properties for RGB led:
+- qcom,mode: mode the led should operate in, options 0 = PWM, 1 = LPG
+- qcom,pwm-channel: pwm channel the led will operate on
+- qcom,pwm-us: time the pwm device will modulate at (us)
+
+Required properties for LPG mode only:
+- qcom,duty-ms: duty cycle time the led will operate at (ms)
+- qcom,duty-pcts: array of values for duty cycle to go through
+- qcom,start-idx: starting point duty-pcts array
+
+Optional properties for RGB led:
+- linux,default-trigger: trigger the led from external modules such as display
+- qcom,default-state:  default state of the led, should be "on" or "off"
+
 Example:
 
-	qcom,leds@d800 {
-			compatible = "qcom,leds-qpnp";
-			status = "okay";
-			qcom,wled_0 {
-				linux,default-trigger = "bkl-trigger"
-				label = "wled";
-				qcom,cs-out-en;
-				qcom,op-fdbck;
-				qcom,default-state "off";
-				qcom,max-current = <25>;
-				qcom,ctrl-delay-us = <0>;
-				qcom,boost-curr-lim = <3>;
-				qcom,cp-sel = <0>;
-				qcom,switch-freq = <2>;
-				qcom,ovp-val = <2>;
-				qcom,num-strings = <1>;
-				qcom,id = <0>;
-				linux,name = "led:wled_backlight";
-			};
+	qcom,leds@d000 {
+		status = "okay";
+		qcom,rgb_pwm {
+			label = "rgb";
+			linux,name = "led:rgb_red";
+			qcom,mode = <0>;
+			qcom,pwm-channel = <6>;
+			qcom,pwm-us = <1000>;
+			qcom,duty-ms = <20>;
+			qcom,start-idx = <1>;
+			qcom,idx-len = <10>;
+			qcom,duty-pcts = [00 19 32 4B 64
+					 64 4B 32 19 00];
+			qcom,max-current = <12>;
+			qcom,default-state = "off";
+			qcom,id = <3>;
+			linux,default-trigger =
+				"battery-charging";
+		};
+
+		qcom,rgb_lpg {
+			label = "rgb";
+			linux,name = "led:rgb_blue";
+			qcom,mode = <1>;
+			qcom,pwm-channel = <4>;
+			qcom,pwm-us = <1000>;
+			qcom,duty-ms = <20>;
+			qcom,start-idx = <1>;
+			qcom,idx-len = <10>;
+			qcom,duty-pcts = [00 19 32 4B 64
+					 64 4B 32 19 00];
+			qcom,max-current = <12>;
+			qcom,default-state = "off";
+			qcom,id = <5>;
+			linux,default-trigger = "none";
+		};
 	};
 
 	qcom,leds@d300 {
@@ -90,3 +121,24 @@
 				qcom,id = <1>;
 			};
 	};
+
+	qcom,leds@d800 {
+			compatible = "qcom,leds-qpnp";
+			status = "okay";
+			qcom,wled_0 {
+				linux,default-trigger = "bkl-trigger"
+				label = "wled";
+				qcom,cs-out-en;
+				qcom,op-fdbck;
+				qcom,default-state "off";
+				qcom,max-current = <25>;
+				qcom,ctrl-delay-us = <0>;
+				qcom,boost-curr-lim = <3>;
+				qcom,cp-sel = <0>;
+				qcom,switch-freq = <2>;
+				qcom,ovp-val = <2>;
+				qcom,num-strings = <1>;
+				qcom,id = <0>;
+				linux,name = "led:wled_backlight";
+			};
+	};
diff --git a/Documentation/devicetree/bindings/mmc/msm_sdcc.txt b/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
index aac998f..a981eed 100644
--- a/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
+++ b/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
@@ -10,7 +10,8 @@
   "reg-names" examples are "core_mem", "dml_mem" and "bam_mem"
   - interrupts : should contain SDCC core interrupt.
   - interrupt-names : indicates interrupts passed to driver (via interrupts property) by name.
-  "interrupt-names" examples are "core_irq", "bam_irq" and "status_irq"
+  "core_irq" is mandatory, "bam_irq" is mandatory only when BAM DMA engine is used,
+  "status_irq" and "sdiowakeup_irq" are optional.
   - qcom,sdcc-clk-rates : specifies supported SDCC clock frequencies, Units - Hz.
   - qcom,sdcc-sup-voltages: specifies supported voltage ranges for card. Should always be
 			specified in pairs (min, max), Units - mV.
@@ -28,6 +29,8 @@
 	- qcom,sdcc-bus-speed-mode - specifies supported bus speed modes by host.
 	- qcom,sdcc-current-limit - specifies max. current the host can drive.
 	- qcom,sdcc-xpc - specifies if the host can supply more than 150mA for SDXC cards.
+	- qcom,dat1-mpm-int - specifies MPM interrupt number corresponding to DAT1 line of SDCC
+					(used only if slot has dedicated DAT1 MSM pin (not GPIO))
 
 In the following, <supply> can be vdd (flash core voltage) or vdd-io (I/O voltage).
 	- qcom,sdcc-<supply>-always_on - specifies whether supply should be kept "on" always.
diff --git a/Documentation/devicetree/bindings/regulator/krait-regulator.txt b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
new file mode 100644
index 0000000..fddae80
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
@@ -0,0 +1,27 @@
+Krait Voltage regulators
+
+Required properties:
+- compatible:			Must be "qcom,krait-regulator"
+- reg:				Specifies the address and size for this regulator device
+- qcom,headroom-voltage:	The minimum required voltage drop between the input
+			 	voltage and the output voltage for the LDO to be
+			 	operational, in microvolts
+- qcom,retention-voltage:	The value for retention voltage in microvolts
+- qcom,ldo-default-voltage:	The default value for LDO voltage in microvolts
+- qcom,ldo-threshold-voltage:	The voltage value above which LDO is nonfunctional
+
+Any property defined as part of the core regulator
+binding, defined in regulator.txt, can also be used.
+
+Example:
+	krait0_vreg: regulator@f9088000 {
+		compatible = "qcom,krait-regulator";
+		regulator-name = "krait0";
+		reg = <0xf9088000 0x1000>;
+		regulator-min-microvolt = <500000>;
+		regulator-max-microvolt = <1100000>;
+		qcom,headroom-voltage = <150000>;
+		qcom,retention-voltage = <745000>;
+		qcom,ldo-default-voltage = <745000>;
+		qcom,ldo-threshold-voltage = <750000>;
+	};
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 186a58d..7bff0f2 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -81,13 +81,16 @@
 - compatible: should be "qcom,android-usb"
 
 Optional properties :
-- reg  : offset and length of memory region that is used by driver to
+- reg  : offset and length of memory region that is used by device to
   update USB PID and serial numbers used by bootloader in DLOAD mode.
+- qcom,android-usb-swfi-latency : value to be used by device to vote
+  for DMA latency in microsecs.
 
 Example Android USB device node :
 	android_usb@fc42b0c8 {
 		compatible = "qcom,android-usb";
 		reg = <0xfc42b0c8 0xc8>;
+		qcom,android-usb-swfi-latency = <1>;
 	};
 
 
diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
index 99274d5..57d776f 100644
--- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
@@ -28,8 +28,10 @@
 - interrupt-names : Optional interrupt resource entries are:
     "hs_phy_irq" : Interrupt from HSPHY for asynchronous events in LPM.
 	This is not used if wakeup events are received externally (e.g. PMIC)
-- qcom,dwc-usb3-msm-otg-capability: If present then depends on PMIC
-  for VBUS notifications, otherwise depends on PHY.
+- qcom,otg-capability: If present then depend on PMIC for VBUS notifications,
+  otherwise depend on PHY.
+- qcom,charging-disabled: If present then battery charging using USB
+  is disabled.
 
 Example MSM USB3.0 controller device node :
 	usb@f9200000 {
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 341b49b..21d8c8c 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -993,6 +993,24 @@
 			status = "disabled";
 		};
 
+		qcom,leds@d000 {
+			compatible = "qcom,leds-qpnp";
+			reg = <0xd000 0x100>;
+			label = "rgb";
+		};
+
+		qcom,leds@d100 {
+			compatible = "qcom,leds-qpnp";
+			reg = <0xd100 0x100>;
+			label = "rgb";
+		};
+
+		qcom,leds@d200 {
+			compatible = "qcom,leds-qpnp";
+			reg = <0xd200 0x100>;
+			label = "rgb";
+		};
+
 		qcom,leds@d300 {
 			compatible = "qcom,leds-qpnp";
 			reg = <0xd300 0x100>;
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index f4be0dc..6553fc0 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -172,7 +172,7 @@
 };
 
 &usb3 {
-	qcom,dwc-usb3-msm-otg-capability;
+	qcom,otg-capability;
 };
 
 &pm8941_chg {
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index de9e98c..495d3fb 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -456,6 +456,10 @@
 		reg = <0xf9088000 0x1000>;
 		regulator-min-microvolt = <500000>;
 		regulator-max-microvolt = <1100000>;
+		qcom,headroom-voltage = <150000>;
+		qcom,retention-voltage = <745000>;
+		qcom,ldo-default-voltage = <745000>;
+		qcom,ldo-threshold-voltage = <750000>;
 	};
 
 	krait1_vreg: regulator@f9098000 {
@@ -464,6 +468,10 @@
 		reg = <0xf9098000 0x1000>;
 		regulator-min-microvolt = <500000>;
 		regulator-max-microvolt = <1100000>;
+		qcom,headroom-voltage = <150000>;
+		qcom,retention-voltage = <745000>;
+		qcom,ldo-default-voltage = <745000>;
+		qcom,ldo-threshold-voltage = <750000>;
 	};
 
 	krait2_vreg: regulator@f90a8000 {
@@ -472,6 +480,10 @@
 		reg = <0xf90a8000 0x1000>;
 		regulator-min-microvolt = <500000>;
 		regulator-max-microvolt = <1100000>;
+		qcom,headroom-voltage = <150000>;
+		qcom,retention-voltage = <745000>;
+		qcom,ldo-default-voltage = <745000>;
+		qcom,ldo-threshold-voltage = <750000>;
 	};
 
 	krait3_vreg: regulator@f90b8000 {
@@ -480,6 +492,10 @@
 		reg = <0xf90b8000 0x1000>;
 		regulator-min-microvolt = <500000>;
 		regulator-max-microvolt = <1100000>;
+		qcom,headroom-voltage = <150000>;
+		qcom,retention-voltage = <745000>;
+		qcom,ldo-default-voltage = <745000>;
+		qcom,ldo-threshold-voltage = <750000>;
 	};
 
 	spi_eth_vreg: spi_eth_phy_vreg {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 18f14a2..83e1141 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -122,6 +122,7 @@
 	android_usb@fc42b0c8 {
 		compatible = "qcom,android-usb";
 		reg = <0xfc42b0c8 0xc8>;
+		qcom,android-usb-swfi-latency = <1>;
 	};
 
 	sdcc1: qcom,sdcc@f9824000 {
@@ -168,6 +169,7 @@
 				<78 512 106496 212992>, /* 208 MB/s */
 				<78 512 2147483647 4294967295>; /* Max. bandwidth */
 		qcom,bus-bw-vectors-bps = <0 13631488 27262976 54525952 109051904 218103808 4294967295>;
+		qcom,dat1-mpm-int = <42>;
 	};
 
 	sdcc2: qcom,sdcc@f98a4000 {
@@ -214,6 +216,7 @@
 				<81 512 106496 212992>, /* 208 MB/s */
 				<81 512 2147483647 4294967295>; /* Max. bandwidth */
 		qcom,bus-bw-vectors-bps = <0 13631488 27262976 54525952 109051904 218103808 4294967295>;
+		qcom,dat1-mpm-int = <44>;
 	};
 
 	sdcc3: qcom,sdcc@f9864000 {
@@ -223,8 +226,15 @@
 			<0xf9864800 0x100>,
 			<0xf9844000 0x7000>;
 		reg-names = "core_mem", "dml_mem", "bam_mem";
-		interrupts = <0 127 0>, <0 223 0>;
-		interrupt-names = "core_irq", "bam_irq";
+		#address-cells = <0>;
+		interrupt-parent = <&sdcc3>;
+		interrupts = <0 1 2>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0xffffffff>;
+		interrupt-map = <0 &intc 0 127 0
+				1 &intc 0 223 0
+				2 &msmgpio 37 0x8>;
+		interrupt-names = "core_irq", "bam_irq", "sdiowakeup_irq";
 
 		gpios = <&msmgpio 40 0>, /* CLK */
 			<&msmgpio 39 0>, /* CMD */
@@ -261,8 +271,15 @@
 			<0xf98e4800 0x100>,
 			<0xf98c4000 0x7000>;
 		reg-names = "core_mem", "dml_mem", "bam_mem";
-		interrupts = <0 129 0>, <0 226 0>;
-		interrupt-names = "core_irq", "bam_irq";
+		#address-cells = <0>;
+		interrupt-parent = <&sdcc4>;
+		interrupts = <0 1 2>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0xffffffff>;
+		interrupt-map = <0 &intc 0 129 0
+				1 &intc 0 226 0
+				2 &msmgpio 95 0x8>;
+		interrupt-names = "core_irq", "bam_irq", "sdiowakeup_irq";
 
 		gpios = <&msmgpio 93 0>, /* CLK */
 			<&msmgpio 91 0>, /* CMD */
diff --git a/arch/arm/boot/dts/msm9625-coresight.dtsi b/arch/arm/boot/dts/msm9625-coresight.dtsi
new file mode 100644
index 0000000..f01fe63
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-coresight.dtsi
@@ -0,0 +1,118 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This 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.
+ */
+
+/ {
+	tmc_etr: tmc@fc322000 {
+		compatible = "arm,coresight-tmc";
+		reg = <0xfc322000 0x1000>,
+		      <0xfc37c000 0x3000>;
+
+		qcom,memory-reservation-type = "EBI1";
+		qcom,memory-reservation-size = <0x100000>; /* 1M EBI1 buffer */
+
+		coresight-id = <0>;
+		coresight-name = "coresight-tmc-etr";
+		coresight-nr-inports = <1>;
+	};
+
+	tpiu: tpiu@fc318000 {
+		compatible = "arm,coresight-tpiu";
+		reg = <0xfc318000 0x1000>;
+
+		coresight-id = <1>;
+		coresight-name = "coresight-tpiu";
+		coresight-nr-inports = <1>;
+	};
+
+	replicator: replicator@fc31c000 {
+		compatible = "qcom,coresight-replicator";
+		reg = <0xfc31c000 0x1000>;
+
+		coresight-id = <2>;
+		coresight-name = "coresight-replicator";
+		coresight-nr-inports = <1>;
+		coresight-outports = <0 1>;
+		coresight-child-list = <&tmc_etr &tpiu>;
+		coresight-child-ports = <0 0>;
+	};
+
+	tmc_etf: tmc@fc307000 {
+		compatible = "arm,coresight-tmc";
+		reg = <0xfc307000 0x1000>;
+
+		coresight-id = <3>;
+		coresight-name = "coresight-tmc-etf";
+		coresight-nr-inports = <1>;
+		coresight-outports = <0>;
+		coresight-child-list = <&replicator>;
+		coresight-child-ports = <0>;
+		coresight-default-sink;
+	};
+
+	funnel_merg: funnel@fc31b000 {
+		compatible = "arm,coresight-funnel";
+		reg = <0xfc31b000 0x1000>;
+
+		coresight-id = <4>;
+		coresight-name = "coresight-funnel-merg";
+		coresight-nr-inports = <2>;
+		coresight-outports = <0>;
+		coresight-child-list = <&tmc_etf>;
+		coresight-child-ports = <0>;
+	};
+
+	funnel_in0: funnel@fc319000 {
+		compatible = "arm,coresight-funnel";
+		reg = <0xfc319000 0x1000>;
+
+		coresight-id = <5>;
+		coresight-name = "coresight-funnel-in0";
+		coresight-nr-inports = <8>;
+		coresight-outports = <0>;
+		coresight-child-list = <&funnel_merg>;
+		coresight-child-ports = <0>;
+	};
+
+	funnel_in1: funnel@fc31a000 {
+		compatible = "arm,coresight-funnel";
+		reg = <0xfc31a000 0x1000>;
+
+		coresight-id = <6>;
+		coresight-name = "coresight-funnel-in1";
+		coresight-nr-inports = <8>;
+		coresight-outports = <0>;
+		coresight-child-list = <&funnel_merg>;
+		coresight-child-ports = <1>;
+	};
+
+	stm: stm@fc321000 {
+		compatible = "arm,coresight-stm";
+		reg = <0xfc321000 0x1000>,
+		      <0xfa280000 0x180000>;
+
+		coresight-id = <7>;
+		coresight-name = "coresight-stm";
+		coresight-nr-inports = <0>;
+		coresight-outports = <0>;
+		coresight-child-list = <&funnel_in1>;
+		coresight-child-ports = <7>;
+	};
+
+	csr: csr@fc302000 {
+		compatible = "qcom,coresight-csr";
+		reg = <0xfc302000 0x1000>;
+
+		coresight-id = <8>;
+		coresight-name = "coresight-csr";
+		coresight-nr-inports = <0>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 7b01020..3d2515d 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -13,6 +13,7 @@
 /include/ "skeleton.dtsi"
 /include/ "msm9625-ion.dtsi"
 /include/ "msm9625-pm.dtsi"
+/include/ "msm9625-coresight.dtsi"
 
 / {
 	model = "Qualcomm MSM 9625";
@@ -141,7 +142,6 @@
 		/* 190,ee0_krait_hlos_spmi_periph_irq */
 		/* 187,channel_0_krait_hlos_trans_done_irq */
 		interrupts = <0 190 0 0 187 0>;
-		qcom,not-wakeup;
 		qcom,pmic-arb-ee = <0>;
 		qcom,pmic-arb-channel = <0>;
 		qcom,pmic-arb-ppid-map = <0x02400000>, /* TEMP_ALARM */
@@ -241,7 +241,6 @@
 		compatible = "qcom,bam_dmux";
 		reg = <0xfc834000 0x7000>;
 		interrupts = <0 29 1>;
-		qcom,satellite-mode;
 	};
 
 	qcom,acpuclk@f9010000 {
@@ -258,6 +257,16 @@
 		reg = <0xfc400404 0x4>;
 		regulator-name = "gdsc_usb_hsic";
 	};
+
+	tsens@fc4a8000 {
+		compatible = "qcom,msm-tsens";
+		reg = <0xfc4a8000 0x2000>,
+		      <0xfc4b8000 0x1000>;
+		reg-names = "tsens_physical", "tsens_eeprom_physical";
+		interrupts = <0 184 0>;
+		qcom,sensors = <5>;
+		qcom,slope = <3200 3200 3200 3200 3200>;
+	};
 };
 
 /include/ "msm-pm8019-rpm-regulator.dtsi"
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 76650e0..8e948c2 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -42,6 +42,7 @@
 # CONFIG_MSM_SMD_NMEA is not set
 # CONFIG_MSM_SMD_QMI is not set
 CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
 # CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
 CONFIG_MSM_RMT_STORAGE_CLIENT=y
 # CONFIG_MSM_HW3D is not set
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 8ab57de..d403cec 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -42,6 +42,7 @@
 # CONFIG_MSM_SMD_NMEA is not set
 # CONFIG_MSM_SMD_QMI is not set
 CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
 # CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
 CONFIG_MSM_RMT_STORAGE_CLIENT=y
 # CONFIG_MSM_HW3D is not set
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 2ee3f3b..828484a 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -295,7 +295,6 @@
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_SX150X=y
 CONFIG_POWER_SUPPLY=y
-# CONFIG_BATTERY_MSM is not set
 CONFIG_BATTERY_MSM8X60=y
 CONFIG_PM8058_CHARGER=y
 CONFIG_ISL9519_CHARGER=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 25c5207..28d7b12 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -295,7 +295,6 @@
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_SX150X=y
 CONFIG_POWER_SUPPLY=y
-# CONFIG_BATTERY_MSM is not set
 CONFIG_BATTERY_MSM8X60=y
 CONFIG_PM8058_CHARGER=y
 CONFIG_ISL9519_CHARGER=y
diff --git a/arch/arm/configs/msm8910_defconfig b/arch/arm/configs/msm8910_defconfig
index 7e4e7705..fe6a7da 100644
--- a/arch/arm/configs/msm8910_defconfig
+++ b/arch/arm/configs/msm8910_defconfig
@@ -34,15 +34,16 @@
 CONFIG_EFI_PARTITION=y
 CONFIG_ARCH_MSM=y
 CONFIG_ARCH_MSM8910=y
+CONFIG_ARCH_MSM8226=y
 # CONFIG_MSM_STACKED_MEMORY is not set
 CONFIG_CPU_HAS_L2_PMU=y
 # CONFIG_MSM_FIQ_SUPPORT is not set
 # CONFIG_MSM_PROC_COMM is not set
 CONFIG_MSM_SMD=y
+# CONFIG_MSM_HW3D is not set
 CONFIG_MSM_DIRECT_SCLK_ACCESS=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
-CONFIG_SMP=y
 # CONFIG_SMP_ON_UP is not set
 CONFIG_ARM_ARCH_TIMER=y
 CONFIG_HOTPLUG_CPU=y
@@ -92,7 +93,6 @@
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_GPIO=m
-CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIAL_MSM_HSL=y
 CONFIG_SERIAL_MSM_HSL_CONSOLE=y
 CONFIG_DIAG_CHAR=y
@@ -104,7 +104,6 @@
 CONFIG_REGULATOR_STUB=y
 CONFIG_FB=y
 CONFIG_FB_VIRTUAL=y
-# CONFIG_MSM_HW3D is not set
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
@@ -122,7 +121,6 @@
 CONFIG_MMC_BLOCK_MINORS=32
 CONFIG_MMC_TEST=m
 CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SPS_SUPPORT=y
 CONFIG_STAGING=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
@@ -152,19 +150,11 @@
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_KEYS=y
-CONFIG_CRYPTO_AUTHENC=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_DEFLATE=y
 # CONFIG_CRYPTO_HW is not set
 CONFIG_CRC_CCITT=y
-CONFIG_CRC16=y
 CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index ec00b68..a613932 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -315,7 +315,6 @@
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_SX150X=y
 CONFIG_POWER_SUPPLY=y
-# CONFIG_BATTERY_MSM is not set
 CONFIG_ISL9519_CHARGER=y
 CONFIG_SMB349_CHARGER=y
 CONFIG_PM8921_CHARGER=y
@@ -356,6 +355,7 @@
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
 CONFIG_MSM_CAMERA_FLASH_TPS61310=y
 CONFIG_OV2720=y
+CONFIG_IMX135=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_ACTUATOR=y
 CONFIG_MSM_EEPROM=y
@@ -367,14 +367,12 @@
 CONFIG_S5K3L1YX=y
 CONFIG_IMX091=y
 CONFIG_MSM_WFD=y
-CONFIG_IMX135=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
 # CONFIG_DVB_FE_CUSTOMISE is not set
 CONFIG_DVB_MPQ=m
 CONFIG_DVB_MPQ_DEMUX=m
 CONFIG_DVB_MPQ_VIDEO=m
-CONFIG_DVB_MPQ_TSPP1=y
 CONFIG_ION=y
 CONFIG_ION_MSM=y
 CONFIG_MSM_KGSL=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 33f7987..0d63836 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -320,7 +320,6 @@
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_SX150X=y
 CONFIG_POWER_SUPPLY=y
-# CONFIG_BATTERY_MSM is not set
 CONFIG_ISL9519_CHARGER=y
 CONFIG_SMB349_CHARGER=y
 CONFIG_PM8921_CHARGER=y
@@ -360,6 +359,7 @@
 CONFIG_IMX074_ACT=y
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
 CONFIG_OV2720=y
+CONFIG_IMX135=y
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_ACTUATOR=y
 CONFIG_MSM_EEPROM=y
@@ -371,14 +371,12 @@
 CONFIG_S5K3L1YX=y
 CONFIG_IMX091=y
 CONFIG_MSM_WFD=y
-CONFIG_IMX135=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
 # CONFIG_DVB_FE_CUSTOMISE is not set
 CONFIG_DVB_MPQ=m
 CONFIG_DVB_MPQ_DEMUX=m
 CONFIG_DVB_MPQ_VIDEO=m
-CONFIG_DVB_MPQ_TSPP1=y
 CONFIG_ION=y
 CONFIG_ION_MSM=y
 CONFIG_MSM_KGSL=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 156e348..7bfe3fe 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -53,7 +53,6 @@
 CONFIG_MSM_SYSMON_COMM=y
 CONFIG_MSM_PIL_LPASS_QDSP6V5=y
 CONFIG_MSM_PIL_MSS_QDSP6V5=y
-CONFIG_MSM_PIL_MBA=y
 CONFIG_MSM_PIL_VENUS=y
 CONFIG_MSM_PIL_PRONTO=y
 CONFIG_MSM_TZ_LOG=y
@@ -75,7 +74,6 @@
 CONFIG_STRICT_MEMORY_RWX=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
-CONFIG_SMP=y
 # CONFIG_SMP_ON_UP is not set
 CONFIG_ARM_ARCH_TIMER=y
 CONFIG_PREEMPT=y
@@ -239,8 +237,8 @@
 CONFIG_MSM_RMNET_BAM=y
 CONFIG_SLIP=y
 CONFIG_SLIP_COMPRESSED=y
-CONFIG_USB_USBNET=y
 CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_USB_USBNET=y
 CONFIG_WCNSS_CORE=y
 CONFIG_WCNSS_CORE_PRONTO=y
 CONFIG_INPUT_EVDEV=y
@@ -273,10 +271,11 @@
 CONFIG_POWER_SUPPLY=y
 CONFIG_BATTERY_BQ28400=y
 CONFIG_QPNP_CHARGER=y
+CONFIG_BATTERY_BCL=y
 CONFIG_QPNP_BMS=y
+CONFIG_SENSORS_EPM_ADC=y
 CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
 CONFIG_SENSORS_QPNP_ADC_CURRENT=y
-CONFIG_SENSORS_EPM_ADC=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8974=y
 CONFIG_THERMAL_QPNP=y
@@ -411,4 +410,3 @@
 CONFIG_CRYPTO_DEV_QCE=m
 CONFIG_CRYPTO_DEV_QCEDEV=m
 CONFIG_CRC_CCITT=y
-CONFIG_BATTERY_BCL=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index aef30fb..af832cb 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -51,7 +51,6 @@
 CONFIG_MSM_SYSMON_COMM=y
 CONFIG_MSM_PIL_LPASS_QDSP6V5=y
 CONFIG_MSM_PIL_MSS_QDSP6V5=y
-CONFIG_MSM_PIL_MBA=y
 CONFIG_MSM_PIL_VENUS=y
 CONFIG_MSM_PIL_PRONTO=y
 CONFIG_MSM_TZ_LOG=y
@@ -240,8 +239,8 @@
 CONFIG_MSM_RMNET_BAM=y
 CONFIG_SLIP=y
 CONFIG_SLIP_COMPRESSED=y
-CONFIG_USB_USBNET=y
 CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_USB_USBNET=y
 CONFIG_WCNSS_CORE=y
 CONFIG_WCNSS_CORE_PRONTO=y
 CONFIG_INPUT_EVDEV=y
@@ -272,13 +271,14 @@
 CONFIG_GPIO_QPNP_PIN=y
 CONFIG_GPIO_QPNP_PIN_DEBUG=y
 CONFIG_POWER_SUPPLY=y
-CONFIG_BATTERY_BQ28400=y
 CONFIG_SMB350_CHARGER=y
+CONFIG_BATTERY_BQ28400=y
 CONFIG_QPNP_CHARGER=y
+CONFIG_BATTERY_BCL=y
 CONFIG_QPNP_BMS=y
+CONFIG_SENSORS_EPM_ADC=y
 CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
 CONFIG_SENSORS_QPNP_ADC_CURRENT=y
-CONFIG_SENSORS_EPM_ADC=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8974=y
 CONFIG_THERMAL_QPNP=y
@@ -427,4 +427,3 @@
 CONFIG_CRYPTO_DEV_QCE=m
 CONFIG_CRYPTO_DEV_QCEDEV=m
 CONFIG_CRC_CCITT=y
-CONFIG_BATTERY_BCL=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 81b853d..a052609 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -199,7 +199,6 @@
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_POWER_SUPPLY=y
-# CONFIG_BATTERY_MSM is not set
 CONFIG_SENSORS_PM8XXX_ADC=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8960=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 783be1b..6297ef5 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -21,6 +21,7 @@
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_PANIC_TIMEOUT=5
 CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
 CONFIG_PROFILING=y
@@ -43,6 +44,7 @@
 CONFIG_MSM_RPM_REGULATOR_SMD=y
 CONFIG_MSM_DIRECT_SCLK_ACCESS=y
 CONFIG_MSM_WATCHDOG_V2=y
+CONFIG_MSM_DLOAD_MODE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_ARM_ARCH_TIMER=y
@@ -51,12 +53,12 @@
 CONFIG_HIGHMEM=y
 CONFIG_VMALLOC_RESERVE=0x19000000
 CONFIG_USE_OF=y
-CONFIG_CPU_IDLE=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
@@ -66,15 +68,6 @@
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IPV6=y
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_HTB=y
-CONFIG_NET_SCH_PRIO=y
-CONFIG_NET_CLS_FW=y
-# CONFIG_WIRELESS is not set
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_OF_PARTS=y
-CONFIG_MTD_BLOCK=y
 CONFIG_NETFILTER=y
 CONFIG_NETFILTER_DEBUG=y
 CONFIG_NETFILTER_NETLINK_QUEUE=y
@@ -86,14 +79,16 @@
 CONFIG_NF_CONNTRACK_PPTP=y
 CONFIG_NF_CONNTRACK_SIP=y
 CONFIG_NF_CONNTRACK_TFTP=y
-CONFIG_NETFILTER_XT_MARK=y
-CONFIG_NETFILTER_XT_CONNMARK=y
-CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_CLS_FW=y
+CONFIG_CFG80211=m
+CONFIG_NL80211_TESTMODE=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_BLOCK=y
 # CONFIG_MTD_MSM_NAND is not set
 CONFIG_MTD_MSM_QPIC_NAND=y
 CONFIG_BLK_DEV_LOOP=y
@@ -104,13 +99,6 @@
 # CONFIG_NET_VENDOR_CIRRUS is not set
 # CONFIG_NET_VENDOR_FARADAY is not set
 # CONFIG_NET_VENDOR_INTEL is not set
-CONFIG_WIRELESS=y
-CONFIG_CFG80211=m
-CONFIG_NL80211_TESTMODE=y
-CONFIG_ATH_COMMON=m
-CONFIG_ATH6KL=m
-CONFIG_ATH6KL_SDIO=m
-CONFIG_ATH6KL_DEBUG=y
 CONFIG_KS8851=y
 # CONFIG_NET_VENDOR_MICROCHIP is not set
 # CONFIG_MSM_RMNET is not set
@@ -123,6 +111,7 @@
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_GPIO=m
@@ -141,15 +130,16 @@
 CONFIG_SPMI=y
 CONFIG_SPMI_MSM_PMIC_ARB=y
 CONFIG_MSM_QPNP_INT=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_QPNP_PIN=y
 CONFIG_GPIO_QPNP_PIN_DEBUG=y
 CONFIG_POWER_SUPPLY=y
-CONFIG_HWMON=y
 CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_TSENS8974=y
 CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_QPNP=y
 CONFIG_ION=y
 CONFIG_ION_MSM=y
@@ -210,5 +200,3 @@
 # CONFIG_CRYPTO_HW is not set
 CONFIG_CRC_CCITT=y
 CONFIG_LIBCRC32C=y
-CONFIG_PANIC_TIMEOUT=5
-CONFIG_MSM_DLOAD_MODE=y
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
index d341ea9..e7de62e 100644
--- a/arch/arm/include/asm/mach/mmc.h
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -149,7 +149,7 @@
 	int status_gpio;
 	/* Indicates the polarity of the GPIO line when card is inserted */
 	bool is_status_gpio_active_low;
-        unsigned int sdiowakeup_irq;
+	int sdiowakeup_irq;
         unsigned long irq_flags;
         unsigned long mmc_bus_width;
         int (*wpswitch) (struct device *);
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 7a443ec..176696c 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -279,30 +279,6 @@
 	select SPARSE_IRQ
 	select MSM_NOPM
 
-config ARCH_MSM8226
-	bool "MSM8226"
-	select ARCH_MSM_KRAITMP
-	select GPIO_MSM_V3
-	select ARM_GIC
-	select CPU_V7
-	select MSM_SCM if SMP
-	select MSM_GPIOMUX
-	select MULTI_IRQ_HANDLER
-	select MSM_MULTIMEDIA_USE_ION
-	select MSM_PIL
-	select MSM_SPM_V2
-	select MSM_L2_SPM
-	select MSM_PM8X60 if PM
-	select MAY_HAVE_SPARSE_IRQ
-	select SPARSE_IRQ
-	select MSM_RPM_SMD
-	select REGULATOR
-	select MSM_QDSP6_APRV2
-	select MSM_QDSP6V2_CODECS
-	select MSM_AUDIO_QDSP6V2 if SND_SOC
-	select MSM_RPM_REGULATOR_SMD
-	select ARM_HAS_SG_CHAIN
-
 config ARCH_FSM9XXX
 	bool "FSM9XXX"
 	select ARCH_MSM_SCORPION
@@ -387,6 +363,20 @@
 	select MSM_GPIOMUX
 	select MSM_NATIVE_RESTART
 	select MSM_RESTART_V2
+
+config ARCH_MSM8226
+	bool "MSM8226"
+	select ARM_GIC
+	select GIC_SECURE
+	select SMP
+	select ARCH_MSM_CORTEXMP
+	select CPU_V7
+	select MSM_SCM if SMP
+	select MAY_HAVE_SPARSE_IRQ
+	select SPARSE_IRQ
+	select MULTI_IRQ_HANDLER
+	select GPIO_MSM_V3
+	select MSM_GPIOMUX
 endmenu
 
 choice
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index b9a16fa..403c32c 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -299,7 +299,7 @@
 obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o
 obj-$(CONFIG_ARCH_MPQ8092) += board-8092.o board-8092-gpiomux.o
 obj-$(CONFIG_ARCH_MSM8226) += board-8226.o board-8226-gpiomux.o
-obj-$(CONFIG_ARCH_MSM8910) += board-8910.o
+obj-$(CONFIG_ARCH_MSM8910) += board-8910.o board-8910-gpiomux.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-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index c973bd5..a358bba 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -395,7 +395,6 @@
 #define CHG_TERM_MA		100
 static struct pm8921_charger_platform_data
 apq8064_pm8921_chg_pdata __devinitdata = {
-	.safety_time		= 180,
 	.update_time		= 60000,
 	.max_voltage		= MAX_VOLTAGE_MV,
 	.min_voltage		= 3200,
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index c6bcb6b..4ea9d8e 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1257,29 +1257,20 @@
  * clock is running at 100KHz and voltage levels are at 3.3
  * and 5 volts
  */
-static int enable_100KHz_ls(int enable)
+static int enable_100KHz_ls(int enable, int gpio)
 {
-	int ret = 0;
-	if (enable) {
-		ret = gpio_request(SX150X_GPIO(1, 10),
-					"cs8427_100KHZ_ENABLE");
-		if (ret) {
-			pr_err("%s: Failed to request gpio %d\n", __func__,
-				SX150X_GPIO(1, 10));
-			return ret;
-		}
-		gpio_direction_output(SX150X_GPIO(1, 10), 1);
-	} else {
-		gpio_direction_output(SX150X_GPIO(1, 10), 0);
-		gpio_free(SX150X_GPIO(1, 10));
-	}
-	return ret;
+	if (enable)
+		gpio_direction_output(gpio, 1);
+	else
+		gpio_direction_output(gpio, 0);
+	return 0;
 }
 
 static struct cs8427_platform_data cs8427_i2c_platform_data = {
 	.irq = SX150X_GPIO(1, 4),
 	.reset_gpio = SX150X_GPIO(1, 6),
 	.enable = enable_100KHz_ls,
+	.ls_gpio = SX150X_GPIO(1, 10),
 };
 
 static struct i2c_board_info cs8427_device_info[] __initdata = {
@@ -2703,7 +2694,7 @@
 };
 
 static struct msm_spi_platform_data mpq8064_qup_spi_gsbi6_pdata = {
-	.max_clock_speed = 1100000,
+	.max_clock_speed = 10800000,
 };
 
 static struct ci_bridge_platform_data mpq8064_ci_bridge_pdata = {
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index 33f18a2..980f312 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -50,7 +50,7 @@
 	CLK_DUMMY("core_clk",	HSUSB_CORE_CLK, "f9a55000.usb", OFF),
 };
 
-struct clock_init_data msm_dummy_clock_init_data __initdata = {
+static struct clock_init_data msm_dummy_clock_init_data __initdata = {
 	.table = msm_clocks_dummy,
 	.size = ARRAY_SIZE(msm_clocks_dummy),
 };
@@ -66,7 +66,6 @@
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
-
 static const char *msm8226_dt_match[] __initconst = {
 	"qcom,msm8226",
 	NULL
diff --git a/arch/arm/mach-msm/board-8910-gpiomux.c b/arch/arm/mach-msm/board-8910-gpiomux.c
new file mode 100644
index 0000000..a67f916
--- /dev/null
+++ b/arch/arm/mach-msm/board-8910-gpiomux.c
@@ -0,0 +1,29 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This 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/init.h>
+#include <linux/ioport.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+
+void __init msm8910_init_gpiomux(void)
+{
+	int rc;
+
+	rc = msm_gpiomux_init(NR_GPIO_IRQS);
+	if (rc) {
+		pr_err(KERN_ERR "msm_8910_init_gpiomux failed %d\n", rc);
+		return;
+	}
+}
diff --git a/arch/arm/mach-msm/board-8910.c b/arch/arm/mach-msm/board-8910.c
index b79ee0b..b031dac 100644
--- a/arch/arm/mach-msm/board-8910.c
+++ b/arch/arm/mach-msm/board-8910.c
@@ -54,7 +54,7 @@
 	CLK_DUMMY("bus_clk",	NULL,		"msm_sdcc.2", OFF),
 };
 
-struct clock_init_data msm_dummy_clock_init_data __initdata = {
+static struct clock_init_data msm_dummy_clock_init_data __initdata = {
 	.table = msm_clocks_dummy,
 	.size = ARRAY_SIZE(msm_clocks_dummy),
 };
@@ -71,6 +71,7 @@
 {
 	struct of_dev_auxdata *adata = msm8910_auxdata_lookup;
 
+	msm8910_init_gpiomux();
 	msm_clock_init(&msm_dummy_clock_init_data);
 
 	if (socinfo_init() < 0)
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index 0c7666b..d35a907 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -315,7 +315,6 @@
 #define MAX_VOLTAGE_MV		4200
 #define CHG_TERM_MA		100
 static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
-	.safety_time		= 180,
 	.update_time		= 60000,
 	.max_voltage		= MAX_VOLTAGE_MV,
 	.min_voltage		= 3200,
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index 9efedb1..1a3d90d 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -396,7 +396,6 @@
 #define MAX_VOLTAGE_MV		4200
 #define CHG_TERM_MA		100
 static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
-	.safety_time		= 180,
 	.update_time		= 60000,
 	.max_voltage		= MAX_VOLTAGE_MV,
 	.min_voltage		= 3200,
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index 5c7eebe..a41fc06 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -108,6 +108,8 @@
 			"msm_sdcc.2", NULL),
 	OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF9864000, \
 			"msm_sdcc.3", NULL),
+	OF_DEV_AUXDATA("qcom,msm-tsens", 0xFC4A8000, \
+			"msm-tsens", NULL),
 	{}
 };
 
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index ff4776a..b2bf546 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -587,6 +587,7 @@
 void msm_map_msm8226_io(void);
 void msm8226_init_irq(void);
 void msm8226_init_gpiomux(void);
+void msm8910_init_gpiomux(void);
 void msm_map_msm8910_io(void);
 void msm8910_init_irq(void);
 
diff --git a/arch/arm/mach-msm/include/mach/irqs-8226.h b/arch/arm/mach-msm/include/mach/irqs-8226.h
index fad7b90..7e174b9 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8226.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8226.h
@@ -24,15 +24,12 @@
 #define GIC_PPI_START 16
 #define GIC_SPI_START 32
 
-#define AVS_SVICINT				(GIC_PPI_START + 6)
-#define AVS_SVICINTSWDONE			(GIC_PPI_START + 7)
 #define INT_ARMQC_PERFMON			(GIC_PPI_START + 10)
 /* PPI 15 is unused */
 
 #define APCC_QGICL2PERFMONIRPTREQ	(GIC_SPI_START + 1)
 #define SC_SICL2PERFMONIRPTREQ		APCC_QGICL2PERFMONIRPTREQ
 #define TLMM_MSM_SUMMARY_IRQ		(GIC_SPI_START + 208)
-#define SPS_BAM_DMA_IRQ			(GIC_SPI_START + 105)
 
 #define NR_MSM_IRQS 256
 #define NR_GPIO_IRQS 146
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h b/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
index 08bc981..c03b513 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
@@ -45,7 +45,4 @@
 #define MSM_DEBUG_UART_PHYS	0xF991E000
 #endif
 
-#define MSM8226_DBG_IMEM_PHYS	0xFE805000
-#define MSM8226_DBG_IMEM_SIZE	SZ_4K
-
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_ipc_router.h b/arch/arm/mach-msm/include/mach/msm_ipc_router.h
new file mode 100644
index 0000000..45a7e19
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_ipc_router.h
@@ -0,0 +1,181 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MSM_IPC_ROUTER_H
+#define _MSM_IPC_ROUTER_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/wakelock.h>
+#include <linux/msm_ipc.h>
+
+#define MAX_WAKELOCK_NAME_SZ 32
+
+/**
+ * enum msm_ipc_router_event - Events that will be generated by IPC Router
+ */
+enum msm_ipc_router_event {
+	MSM_IPC_ROUTER_READ_CB = 0,
+	MSM_IPC_ROUTER_WRITE_DONE,
+};
+
+struct msm_ipc_port {
+	struct list_head list;
+
+	struct msm_ipc_port_addr this_port;
+	struct msm_ipc_port_name port_name;
+	uint32_t type;
+	unsigned flags;
+	spinlock_t port_lock;
+
+	struct list_head incomplete;
+	struct mutex incomplete_lock;
+
+	struct list_head port_rx_q;
+	struct mutex port_rx_q_lock;
+	char rx_wakelock_name[MAX_WAKELOCK_NAME_SZ];
+	struct wake_lock port_rx_wake_lock;
+	wait_queue_head_t port_rx_wait_q;
+
+	int restart_state;
+	spinlock_t restart_lock;
+	wait_queue_head_t restart_wait;
+
+	void *endpoint;
+	void (*notify)(unsigned event, void *priv);
+
+	uint32_t num_tx;
+	uint32_t num_rx;
+	unsigned long num_tx_bytes;
+	unsigned long num_rx_bytes;
+	void *priv;
+};
+
+#ifdef CONFIG_MSM_IPC_ROUTER
+/**
+ * msm_ipc_router_create_port() - Create a IPC Router port/endpoint
+ * @notify: Callback function to notify any event on the port.
+ * @priv: Private info to be passed while the notification is generated.
+ *
+ * @return: Pointer to the port on success, NULL on error.
+ */
+struct msm_ipc_port *msm_ipc_router_create_port(
+	void (*notify)(unsigned event, void *priv),
+	void *priv);
+
+/**
+ * msm_ipc_router_lookup_server_name() - Resolve server address
+ * @srv_name: Name<service:instance> of the server to be resolved.
+ * @srv_info: Buffer to hold the resolved address.
+ * @num_entries_in_array: Number of server info the buffer can hold.
+ * @lookup_mask: Mask to specify the range of instances to be resolved.
+ *
+ * @return: Number of server addresses resolved on success, < 0 on error.
+ */
+int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name,
+				      struct msm_ipc_server_info *srv_info,
+				      int num_entries_in_array,
+				      uint32_t lookup_mask);
+
+/**
+ * msm_ipc_router_send_msg() - Send a message/packet
+ * @src: Sender's address/port.
+ * @dest: Destination address.
+ * @data: Pointer to the data to be sent.
+ * @data_len: Length of the data to be sent.
+ *
+ * @return: 0 on success, < 0 on error.
+ */
+int msm_ipc_router_send_msg(struct msm_ipc_port *src,
+			    struct msm_ipc_addr *dest,
+			    void *data, unsigned int data_len);
+
+/**
+ * msm_ipc_router_get_curr_pkt_size() - Get the packet size of the first
+ *                                      packet in the rx queue
+ * @port_ptr: Port which owns the rx queue.
+ *
+ * @return: Returns the size of the first packet, if available.
+ *          0 if no packets available, < 0 on error.
+ */
+int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr);
+
+/**
+ * msm_ipc_router_read_msg() - Read a message/packet
+ * @port_ptr: Receiver's port/address.
+ * @data: Pointer containing the address of the received data.
+ * @src: Address of the sender/source.
+ * @len: Length of the data being read.
+ *
+ * @return: 0 on success, < 0 on error.
+ */
+int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr,
+			    struct msm_ipc_addr *src,
+			    unsigned char **data,
+			    unsigned int *len);
+
+/**
+ * msm_ipc_router_close_port() - Close the port
+ * @port_ptr: Pointer to the port to be closed.
+ *
+ * @return: 0 on success, < 0 on error.
+ */
+int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr);
+
+#else
+
+struct msm_ipc_port *msm_ipc_router_create_port(
+	void (*notify)(unsigned event, void *priv),
+	void *priv)
+{
+	return NULL;
+}
+
+int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name,
+				      struct msm_ipc_server_info *srv_info,
+				      int num_entries_in_array,
+				      uint32_t lookup_mask)
+{
+	return -ENODEV;
+}
+
+int msm_ipc_router_send_msg(struct msm_ipc_port *src,
+			    struct msm_ipc_addr *dest,
+			    void *data, unsigned int data_len)
+{
+	return -ENODEV;
+}
+
+int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr)
+{
+	return -ENODEV;
+}
+
+int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr,
+			    struct msm_ipc_addr *src,
+			    unsigned char **data,
+			    unsigned int *len)
+{
+	return -ENODEV;
+}
+
+int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr)
+{
+	return -ENODEV;
+}
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index ae908e1..52bb8ef 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -519,7 +519,6 @@
 	MSM_CHIP_DEVICE(APCS_GCC, MSM8226),
 	MSM_CHIP_DEVICE(TLMM, MSM8226),
 	MSM_CHIP_DEVICE(IMEM, MSM8226),
-	MSM_CHIP_DEVICE(DBG_IMEM, MSM8226),
 	{
 		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
 		.length =   MSM_SHARED_RAM_SIZE,
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index ac33836..8f1d197 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -33,6 +33,7 @@
 
 #include <mach/smem_log.h>
 #include <mach/subsystem_notif.h>
+#include <mach/msm_ipc_router.h>
 
 #include "ipc_router.h"
 #include "modem_notifier.h"
@@ -111,11 +112,14 @@
 struct msm_ipc_server {
 	struct list_head list;
 	struct msm_ipc_port_name name;
+	char pdev_name[32];
+	int next_pdev_id;
 	struct list_head server_port_list;
 };
 
 struct msm_ipc_server_port {
 	struct list_head list;
+	struct platform_device pdev;
 	struct msm_ipc_port_addr server_addr;
 	struct msm_ipc_router_xprt_info *xprt_info;
 };
@@ -366,6 +370,102 @@
 	return;
 }
 
+static struct sk_buff_head *msm_ipc_router_buf_to_skb(void *buf,
+						unsigned int buf_len)
+{
+	struct sk_buff_head *skb_head;
+	struct sk_buff *skb;
+	int first = 1, offset = 0;
+	int skb_size, data_size;
+	void *data;
+
+	skb_head = kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);
+	if (!skb_head) {
+		pr_err("%s: Couldnot allocate skb_head\n", __func__);
+		return NULL;
+	}
+	skb_queue_head_init(skb_head);
+
+	data_size = buf_len;
+	while (offset != buf_len) {
+		skb_size = data_size;
+		if (first)
+			skb_size += IPC_ROUTER_HDR_SIZE;
+
+		skb = alloc_skb(skb_size, GFP_KERNEL);
+		if (!skb) {
+			if (skb_size <= (PAGE_SIZE/2)) {
+				pr_err("%s: cannot allocate skb\n", __func__);
+				goto buf_to_skb_error;
+			}
+			data_size = data_size / 2;
+			continue;
+		}
+
+		if (first) {
+			skb_reserve(skb, IPC_ROUTER_HDR_SIZE);
+			first = 0;
+		}
+
+		data = skb_put(skb, data_size);
+		memcpy(skb->data, buf + offset, data_size);
+		skb_queue_tail(skb_head, skb);
+		offset += data_size;
+		data_size = buf_len - offset;
+	}
+	return skb_head;
+
+buf_to_skb_error:
+	while (!skb_queue_empty(skb_head)) {
+		skb = skb_dequeue(skb_head);
+		kfree_skb(skb);
+	}
+	kfree(skb_head);
+	return NULL;
+}
+
+static void *msm_ipc_router_skb_to_buf(struct sk_buff_head *skb_head,
+				       unsigned int len)
+{
+	struct sk_buff *temp;
+	int offset = 0, buf_len = 0, copy_len;
+	void *buf;
+
+	if (!skb_head) {
+		pr_err("%s: NULL skb_head\n", __func__);
+		return NULL;
+	}
+
+	temp = skb_peek(skb_head);
+	buf_len = len;
+	buf = kmalloc(buf_len, GFP_KERNEL);
+	if (!buf) {
+		pr_err("%s: cannot allocate buf\n", __func__);
+		return NULL;
+	}
+	skb_queue_walk(skb_head, temp) {
+		copy_len = buf_len < temp->len ? buf_len : temp->len;
+		memcpy(buf + offset, temp->data, copy_len);
+		offset += copy_len;
+		buf_len -= copy_len;
+	}
+	return buf;
+}
+
+static void msm_ipc_router_free_skb(struct sk_buff_head *skb_head)
+{
+	struct sk_buff *temp_skb;
+
+	if (!skb_head)
+		return;
+
+	while (!skb_queue_empty(skb_head)) {
+		temp_skb = skb_dequeue(skb_head);
+		kfree_skb(temp_skb);
+	}
+	kfree(skb_head);
+}
+
 static int post_control_ports(struct rr_packet *pkt)
 {
 	struct msm_ipc_port *port_ptr;
@@ -437,8 +537,7 @@
 }
 
 struct msm_ipc_port *msm_ipc_router_create_raw_port(void *endpoint,
-		void (*notify)(unsigned event, void *data,
-			       void *addr, void *priv),
+		void (*notify)(unsigned event, void *priv),
 		void *priv)
 {
 	struct msm_ipc_port *port_ptr;
@@ -628,6 +727,10 @@
 	return NULL;
 }
 
+static void dummy_release(struct device *dev)
+{
+}
+
 /**
  * msm_ipc_router_create_server() - Add server info to hash table
  * @service: Service ID of the server info to be created.
@@ -660,7 +763,7 @@
 			goto create_srv_port;
 	}
 
-	server = kmalloc(sizeof(struct msm_ipc_server), GFP_KERNEL);
+	server = kzalloc(sizeof(struct msm_ipc_server), GFP_KERNEL);
 	if (!server) {
 		pr_err("%s: Server allocation failed\n", __func__);
 		return NULL;
@@ -669,9 +772,12 @@
 	server->name.instance = instance;
 	INIT_LIST_HEAD(&server->server_port_list);
 	list_add_tail(&server->list, &server_list[key]);
+	scnprintf(server->pdev_name, sizeof(server->pdev_name),
+		  "QMI%08x:%08x", service, instance);
+	server->next_pdev_id = 1;
 
 create_srv_port:
-	server_port = kmalloc(sizeof(struct msm_ipc_server_port), GFP_KERNEL);
+	server_port = kzalloc(sizeof(struct msm_ipc_server_port), GFP_KERNEL);
 	if (!server_port) {
 		if (list_empty(&server->server_port_list)) {
 			list_del(&server->list);
@@ -685,6 +791,11 @@
 	server_port->xprt_info = xprt_info;
 	list_add_tail(&server_port->list, &server->server_port_list);
 
+	server_port->pdev.name = server->pdev_name;
+	server_port->pdev.id = server->next_pdev_id++;
+	server_port->pdev.dev.release = dummy_release;
+	platform_device_register(&server_port->pdev);
+
 	return server;
 }
 
@@ -714,6 +825,7 @@
 			break;
 	}
 	if (server_port) {
+		platform_device_unregister(&server_port->pdev);
 		list_del(&server_port->list);
 		kfree(server_port);
 	}
@@ -1079,6 +1191,7 @@
 				ctl.srv.port_id = svr_port->server_addr.port_id;
 				relay_ctl_msg(xprt_info, &ctl);
 				broadcast_ctl_msg_locally(&ctl);
+				platform_device_unregister(&svr_port->pdev);
 				list_del(&svr_port->list);
 				kfree(svr_port);
 			}
@@ -1432,7 +1545,6 @@
 	struct rr_packet *pkt = NULL;
 	struct msm_ipc_port *port_ptr;
 	struct sk_buff *head_skb;
-	struct msm_ipc_port_addr *src_addr;
 	struct msm_ipc_router_remote_port *rport_ptr;
 	uint32_t resume_tx, resume_tx_node_id, resume_tx_port_id;
 
@@ -1527,30 +1639,15 @@
 			}
 		}
 
-		if (!port_ptr->notify) {
-			mutex_lock(&port_ptr->port_rx_q_lock);
-			wake_lock(&port_ptr->port_rx_wake_lock);
-			list_add_tail(&pkt->list, &port_ptr->port_rx_q);
-			wake_up(&port_ptr->port_rx_wait_q);
-			mutex_unlock(&port_ptr->port_rx_q_lock);
-			mutex_unlock(&local_ports_lock);
-		} else {
-			mutex_lock(&port_ptr->port_rx_q_lock);
-			src_addr = kmalloc(sizeof(struct msm_ipc_port_addr),
-					   GFP_KERNEL);
-			if (src_addr) {
-				src_addr->node_id = hdr->src_node_id;
-				src_addr->port_id = hdr->src_port_id;
-			}
-			skb_pull(head_skb, IPC_ROUTER_HDR_SIZE);
-			mutex_unlock(&local_ports_lock);
+		mutex_lock(&port_ptr->port_rx_q_lock);
+		wake_lock(&port_ptr->port_rx_wake_lock);
+		list_add_tail(&pkt->list, &port_ptr->port_rx_q);
+		wake_up(&port_ptr->port_rx_wait_q);
+		if (port_ptr->notify)
 			port_ptr->notify(MSM_IPC_ROUTER_READ_CB,
-				pkt->pkt_fragment_q, src_addr, port_ptr->priv);
-			mutex_unlock(&port_ptr->port_rx_q_lock);
-			pkt->pkt_fragment_q = NULL;
-			src_addr = NULL;
-			release_pkt(pkt);
-		}
+					 port_ptr->priv);
+		mutex_unlock(&port_ptr->port_rx_q_lock);
+		mutex_unlock(&local_ports_lock);
 
 process_done:
 		if (resume_tx) {
@@ -1904,6 +2001,28 @@
 	return ret;
 }
 
+int msm_ipc_router_send_msg(struct msm_ipc_port *src,
+			    struct msm_ipc_addr *dest,
+			    void *data, unsigned int data_len)
+{
+	struct sk_buff_head *out_skb_head;
+	int ret;
+
+	out_skb_head = msm_ipc_router_buf_to_skb(data, data_len);
+	if (!out_skb_head) {
+		pr_err("%s: SKB conversion failed\n", __func__);
+		return -EFAULT;
+	}
+
+	ret = msm_ipc_router_send_to(src, out_skb_head, dest);
+	if (ret < 0) {
+		pr_err("%s: msm_ipc_router_send_to failed - ret: %d\n",
+			__func__, ret);
+		msm_ipc_router_free_skb(out_skb_head);
+	}
+	return 0;
+}
+
 int msm_ipc_router_read(struct msm_ipc_port *port_ptr,
 			struct sk_buff_head **data,
 			size_t buf_len)
@@ -1939,7 +2058,7 @@
 int msm_ipc_router_recv_from(struct msm_ipc_port *port_ptr,
 			     struct sk_buff_head **data,
 			     struct msm_ipc_addr *src,
-			     unsigned long timeout)
+			     long timeout)
 {
 	int ret, data_len, align_size;
 	struct sk_buff *temp_skb;
@@ -1996,11 +2115,42 @@
 	return data_len;
 }
 
+int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr,
+			    struct msm_ipc_addr *src,
+			    unsigned char **data,
+			    unsigned int *len)
+{
+	struct sk_buff_head *in_skb_head;
+	int ret;
+
+	ret = msm_ipc_router_recv_from(port_ptr, &in_skb_head, src, -1);
+	if (ret < 0) {
+		pr_err("%s: msm_ipc_router_recv_from failed - ret: %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	*data = msm_ipc_router_skb_to_buf(in_skb_head, ret);
+	if (!(*data))
+		pr_err("%s: Buf conversion failed\n", __func__);
+
+	*len = ret;
+	msm_ipc_router_free_skb(in_skb_head);
+	return 0;
+}
+
 struct msm_ipc_port *msm_ipc_router_create_port(
-	void (*notify)(unsigned event, void *data, void *addr, void *priv),
+	void (*notify)(unsigned event, void *priv),
 	void *priv)
 {
 	struct msm_ipc_port *port_ptr;
+	int ret;
+
+	ret = wait_for_completion_interruptible(&msm_ipc_local_router_up);
+	if (ret < 0) {
+		pr_err("%s: Error waiting for local router\n", __func__);
+		return NULL;
+	}
 
 	port_ptr = msm_ipc_router_create_raw_port(NULL, notify, priv);
 	if (!port_ptr)
diff --git a/arch/arm/mach-msm/ipc_router.h b/arch/arm/mach-msm/ipc_router.h
index 07bc5e0..39038f2 100644
--- a/arch/arm/mach-msm/ipc_router.h
+++ b/arch/arm/mach-msm/ipc_router.h
@@ -18,22 +18,18 @@
 #include <linux/errno.h>
 #include <linux/mm.h>
 #include <linux/list.h>
-#include <linux/cdev.h>
 #include <linux/platform_device.h>
-#include <linux/wakelock.h>
 #include <linux/msm_ipc.h>
 
 #include <net/sock.h>
 
 /* definitions for the R2R wire protcol */
 #define IPC_ROUTER_VERSION			1
-#define IPC_ROUTER_PROCESSORS_MAX		4
 
 #define IPC_ROUTER_CLIENT_BCAST_ID		0xffffffff
 #define IPC_ROUTER_ADDRESS			0xfffffffe
 
 #define IPC_ROUTER_NID_LOCAL			1
-#define IPC_ROUTER_NID_REMOTE			0
 
 #define IPC_ROUTER_CTRL_CMD_DATA		1
 #define IPC_ROUTER_CTRL_CMD_HELLO		2
@@ -51,18 +47,11 @@
 #define IPC_ROUTER_XPRT_EVENT_OPEN  2
 #define IPC_ROUTER_XPRT_EVENT_CLOSE 3
 
-#define NUM_NODES 2
-
 #define IPC_ROUTER_INFINITY -1
 #define DEFAULT_RCV_TIMEO IPC_ROUTER_INFINITY
 
 #define ALIGN_SIZE(x) ((4 - ((x) & 3)) & 3)
 
-enum {
-	MSM_IPC_ROUTER_READ_CB = 0,
-	MSM_IPC_ROUTER_WRITE_DONE,
-};
-
 union rr_control_msg {
 	uint32_t cmd;
 	struct {
@@ -92,10 +81,6 @@
 
 #define IPC_ROUTER_HDR_SIZE sizeof(struct rr_header)
 #define MAX_IPC_PKT_SIZE 66000
-/* internals */
-
-#define IPC_ROUTER_MAX_REMOTE_SERVERS		100
-#define MAX_WAKELOCK_NAME_SZ 32
 
 struct rr_packet {
 	struct list_head list;
@@ -103,50 +88,12 @@
 	uint32_t length;
 };
 
-struct msm_ipc_port {
-	struct list_head list;
-
-	struct msm_ipc_port_addr this_port;
-	struct msm_ipc_port_name port_name;
-	uint32_t type;
-	unsigned flags;
-	spinlock_t port_lock;
-
-	struct list_head incomplete;
-	struct mutex incomplete_lock;
-
-	struct list_head port_rx_q;
-	struct mutex port_rx_q_lock;
-	char rx_wakelock_name[MAX_WAKELOCK_NAME_SZ];
-	struct wake_lock port_rx_wake_lock;
-	wait_queue_head_t port_rx_wait_q;
-
-	int restart_state;
-	spinlock_t restart_lock;
-	wait_queue_head_t restart_wait;
-
-	void *endpoint;
-	void (*notify)(unsigned event, void *data, void *addr, void *priv);
-
-	uint32_t num_tx;
-	uint32_t num_rx;
-	unsigned long num_tx_bytes;
-	unsigned long num_rx_bytes;
-	void *priv;
-};
-
 struct msm_ipc_sock {
 	struct sock sk;
 	struct msm_ipc_port *port;
 	void *default_pil;
 };
 
-enum write_data_type {
-	HEADER = 1,
-	PACKMARK,
-	PAYLOAD,
-};
-
 struct msm_ipc_router_xprt {
 	char *name;
 	uint32_t link_id;
@@ -161,8 +108,6 @@
 	int (*close)(struct msm_ipc_router_xprt *xprt);
 };
 
-extern struct completion msm_ipc_remote_router_up;
-
 void msm_ipc_router_xprt_notify(struct msm_ipc_router_xprt *xprt,
 				unsigned event,
 				void *data);
@@ -173,8 +118,7 @@
 
 
 struct msm_ipc_port *msm_ipc_router_create_raw_port(void *endpoint,
-		void (*notify)(unsigned event, void *data,
-			       void *addr, void *priv),
+		void (*notify)(unsigned event, void *priv),
 		void *priv);
 int msm_ipc_router_send_to(struct msm_ipc_port *src,
 			   struct sk_buff_head *data,
@@ -182,27 +126,16 @@
 int msm_ipc_router_read(struct msm_ipc_port *port_ptr,
 			struct sk_buff_head **data,
 			size_t buf_len);
-int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr);
 int msm_ipc_router_bind_control_port(struct msm_ipc_port *port_ptr);
-int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name,
-				      struct msm_ipc_server_info *srv_info,
-				      int num_entries_in_array,
-				      uint32_t lookup_mask);
-int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr);
 
-struct msm_ipc_port *msm_ipc_router_create_port(
-	void (*notify)(unsigned event, void *data,
-		       void *addr, void *priv),
-	void *priv);
 int msm_ipc_router_recv_from(struct msm_ipc_port *port_ptr,
 		      struct sk_buff_head **data,
 		      struct msm_ipc_addr *src_addr,
-		      unsigned long timeout);
+		      long timeout);
 int msm_ipc_router_register_server(struct msm_ipc_port *server_port,
 			    struct msm_ipc_addr *name);
 int msm_ipc_router_unregister_server(struct msm_ipc_port *server_port);
 
-
 int msm_ipc_router_init_sockets(void);
 void msm_ipc_router_exit_sockets(void);
 
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index d3917f1..3a6abbd 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -30,6 +30,8 @@
 
 #include <net/sock.h>
 
+#include <mach/msm_ipc_router.h>
+
 #include "ipc_router.h"
 
 #define msm_ipc_sk(sk) ((struct msm_ipc_sock *)(sk))
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index aa9b344..a568b52 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -56,16 +56,10 @@
  *           |_________________|
  */
 
-#define V_RETENTION			600000
-#define V_LDO_HEADROOM			150000
-
 #define PMIC_VOLTAGE_MIN		350000
 #define PMIC_VOLTAGE_MAX		1355000
 #define LV_RANGE_STEP			5000
 
-/* use LDO for core voltage below LDO_THRESH */
-#define CORE_VOLTAGE_LDO_THRESH		750000
-
 #define LOAD_PER_PHASE			3200000
 
 #define CORE_VOLTAGE_MIN		900000
@@ -161,6 +155,10 @@
 	int				load_uA;
 	enum krait_supply_mode		mode;
 	void __iomem			*reg_base;
+	int				ldo_default_uV;
+	int				retention_uV;
+	int				headroom_uV;
+	int				ldo_threshold_uV;
 };
 
 static u32 version;
@@ -200,11 +198,22 @@
 	return uV;
 }
 
-static int set_krait_ldo_uv(struct krait_power_vreg *kvreg)
+static int set_krait_retention_uv(struct krait_power_vreg *kvreg, int uV)
 {
 	uint32_t reg_val;
 
-	reg_val = kvreg->uV - KRAIT_LDO_VOLTAGE_OFFSET / KRAIT_LDO_STEP;
+	reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
+	krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_RET_MASK,
+						reg_val << VREF_RET_POS);
+
+	return 0;
+}
+
+static int set_krait_ldo_uv(struct krait_power_vreg *kvreg, int uV)
+{
+	uint32_t reg_val;
+
+	reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
 	krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_LDO_MASK,
 						reg_val << VREF_LDO_BIT_POS);
 
@@ -252,7 +261,7 @@
 	if (kvreg->mode == LDO_MODE)
 		switch_to_using_hs(kvreg);
 
-	set_krait_ldo_uv(kvreg);
+	set_krait_ldo_uv(kvreg, kvreg->uV);
 
 	/*
 	 * enable ldo - note that both LDO and BHS are are supplying voltage to
@@ -310,8 +319,8 @@
 	int rc = 0;
 
 	list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
-		if (kvreg->uV > CORE_VOLTAGE_LDO_THRESH
-			 || kvreg->uV > vmax - V_LDO_HEADROOM) {
+		if (kvreg->uV > kvreg->ldo_threshold_uV
+			 || kvreg->uV > vmax - kvreg->headroom_uV) {
 			rc = switch_to_using_hs(kvreg);
 			if (rc < 0) {
 				pr_err("could not switch %s to hs rc = %d\n",
@@ -510,7 +519,7 @@
 	 * switch to LDO mode. Hence round the voltage as per the LDO
 	 * resolution
 	 */
-	if (min_uV < CORE_VOLTAGE_LDO_THRESH) {
+	if (min_uV < kvreg->ldo_threshold_uV) {
 		if (min_uV < KRAIT_LDO_VOLTAGE_MIN)
 			min_uV = KRAIT_LDO_VOLTAGE_MIN;
 		min_uV = ROUND_UP_VOLTAGE(min_uV, KRAIT_LDO_STEP);
@@ -638,6 +647,9 @@
 	/* BHS has six different segments, turn them all on */
 	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
 		BHS_SEG_EN_MASK, BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS);
+
+	set_krait_retention_uv(kvreg, kvreg->retention_uV);
+	set_krait_ldo_uv(kvreg, kvreg->ldo_default_uV);
 }
 
 static void glb_init(struct platform_device *pdev)
@@ -649,12 +661,31 @@
 	pr_debug("version= 0x%x\n", version);
 }
 
+static int is_between(int left, int right, int value)
+{
+	if (left >= right && left >= value && value >= right)
+		return 1;
+	if (left <= right && left <= value && value <= right)
+		return 1;
+	return 0;
+}
+
+#define LDO_HDROOM_MIN		50000
+#define LDO_HDROOM_MAX		250000
+
+#define LDO_UV_MIN		465000
+#define LDO_UV_MAX		750000
+
+#define LDO_TH_MIN		600000
+#define LDO_TH_MAX		800000
+
 static int __devinit krait_power_probe(struct platform_device *pdev)
 {
 	struct krait_power_vreg *kvreg;
 	struct resource *res;
 	struct regulator_init_data *init_data = pdev->dev.platform_data;
 	int rc = 0;
+	int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
 
 	/* Initialize the pmic gang if it hasn't been initialized already */
 	if (the_gang == NULL) {
@@ -679,6 +710,57 @@
 			|= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE
 			| REGULATOR_MODE_FAST;
 		init_data->constraints.input_uV = init_data->constraints.max_uV;
+		rc = of_property_read_u32(pdev->dev.of_node,
+					"qcom,headroom-voltage",
+					&headroom_uV);
+		if (rc < 0) {
+			pr_err("headroom-voltage missing rc=%d\n", rc);
+			return rc;
+		}
+		if (!is_between(LDO_HDROOM_MIN, LDO_HDROOM_MAX, headroom_uV)) {
+			pr_err("bad headroom-voltage = %d specified\n",
+					headroom_uV);
+			return -EINVAL;
+		}
+
+		rc = of_property_read_u32(pdev->dev.of_node,
+					"qcom,retention-voltage",
+					&retention_uV);
+		if (rc < 0) {
+			pr_err("retention-voltage missing rc=%d\n", rc);
+			return rc;
+		}
+		if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV)) {
+			pr_err("bad retention-voltage = %d specified\n",
+					retention_uV);
+			return -EINVAL;
+		}
+
+		rc = of_property_read_u32(pdev->dev.of_node,
+					"qcom,ldo-default-voltage",
+					&ldo_default_uV);
+		if (rc < 0) {
+			pr_err("ldo-default-voltage missing rc=%d\n", rc);
+			return rc;
+		}
+		if (!is_between(LDO_UV_MIN, LDO_UV_MAX, ldo_default_uV)) {
+			pr_err("bad ldo-default-voltage = %d specified\n",
+					ldo_default_uV);
+			return -EINVAL;
+		}
+
+		rc = of_property_read_u32(pdev->dev.of_node,
+					"qcom,ldo-threshold-voltage",
+					&ldo_threshold_uV);
+		if (rc < 0) {
+			pr_err("ldo-threshold-voltage missing rc=%d\n", rc);
+			return rc;
+		}
+		if (!is_between(LDO_TH_MIN, LDO_TH_MAX, ldo_threshold_uV)) {
+			pr_err("bad ldo-threshold-voltage = %d specified\n",
+					ldo_threshold_uV);
+			return -EINVAL;
+		}
 	}
 
 	if (!init_data) {
@@ -708,15 +790,19 @@
 	kvreg->reg_base = devm_ioremap(&pdev->dev,
 				res->start, resource_size(res));
 
-	kvreg->pvreg	  = the_gang;
-	kvreg->name	  = init_data->constraints.name;
-	kvreg->desc.name  = kvreg->name;
-	kvreg->desc.ops   = &krait_power_ops;
-	kvreg->desc.type  = REGULATOR_VOLTAGE;
-	kvreg->desc.owner = THIS_MODULE;
-	kvreg->uV	  = CORE_VOLTAGE_MIN;
-	kvreg->mode	  = HS_MODE;
-	kvreg->desc.ops   = &krait_power_ops;
+	kvreg->pvreg		= the_gang;
+	kvreg->name		= init_data->constraints.name;
+	kvreg->desc.name	= kvreg->name;
+	kvreg->desc.ops		= &krait_power_ops;
+	kvreg->desc.type	= REGULATOR_VOLTAGE;
+	kvreg->desc.owner	= THIS_MODULE;
+	kvreg->uV		= CORE_VOLTAGE_MIN;
+	kvreg->mode		= HS_MODE;
+	kvreg->desc.ops		= &krait_power_ops;
+	kvreg->headroom_uV	= headroom_uV;
+	kvreg->retention_uV	= retention_uV;
+	kvreg->ldo_default_uV	= ldo_default_uV;
+	kvreg->ldo_threshold_uV = ldo_threshold_uV;
 
 	platform_set_drvdata(pdev, kvreg);
 
diff --git a/arch/arm/mach-msm/wdog_debug.c b/arch/arm/mach-msm/wdog_debug.c
index 08dd9ce..8b39d26 100644
--- a/arch/arm/mach-msm/wdog_debug.c
+++ b/arch/arm/mach-msm/wdog_debug.c
@@ -43,6 +43,11 @@
 	value = readl_relaxed(wdog_data->base + GCC_WDOG_DEBUG_OFFSET);
 	value &= ~BIT(WDOG_DEBUG_EN);
 	writel_relaxed(value, wdog_data->base + GCC_WDOG_DEBUG_OFFSET);
+
+	/* Ensure the WDOG_DEBUG_EN status has changed */
+	while (readl_relaxed(wdog_data->base + GCC_WDOG_DEBUG_OFFSET) &
+		BIT(WDOG_DEBUG_EN))
+			;
 }
 EXPORT_SYMBOL(msm_disable_wdog_debug);
 
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index b5d38d5..8994d6d 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -571,7 +571,6 @@
 	pm_callback_t callback = NULL;
 	char *info = NULL;
 	int error = 0;
-	bool put = false;
 
 	TRACE_DEVICE(dev);
 	TRACE_RESUME(0);
@@ -589,7 +588,6 @@
 		goto Unlock;
 
 	pm_runtime_enable(dev);
-	put = true;
 
 	if (dev->pm_domain) {
 		info = "power domain ";
@@ -642,9 +640,6 @@
 
 	TRACE_RESUME(error);
 
-	if (put)
-		pm_runtime_put_sync(dev);
-
 	return error;
 }
 
@@ -779,6 +774,8 @@
 	}
 
 	device_unlock(dev);
+
+	pm_runtime_put_sync(dev);
 }
 
 /**
@@ -1064,12 +1061,16 @@
 	if (async_error)
 		return 0;
 
-	pm_runtime_get_noresume(dev);
+	/*
+	 * If a device configured to wake up the system from sleep states
+	 * has been suspended at run time and there's a resume request pending
+	 * for it, this is equivalent to the device signaling wakeup, so the
+	 * system suspend operation should be aborted.
+	 */
 	if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
 		pm_wakeup_event(dev, 0);
 
 	if (pm_wakeup_pending()) {
-		pm_runtime_put_sync(dev);
 		async_error = -EBUSY;
 		return 0;
 	}
@@ -1142,12 +1143,10 @@
 
 	complete_all(&dev->power.completion);
 
-	if (error) {
-		pm_runtime_put_sync(dev);
+	if (error)
 		async_error = error;
-	} else if (dev->power.is_suspended) {
+	else if (dev->power.is_suspended)
 		__pm_runtime_disable(dev, false);
-	}
 
 	return error;
 }
@@ -1240,6 +1239,14 @@
 	char *info = NULL;
 	int error = 0;
 
+	/*
+	 * If a device's parent goes into runtime suspend at the wrong time,
+	 * it won't be possible to resume the device.  To prevent this we
+	 * block runtime suspend here, during the prepare phase, and allow
+	 * it again during the complete phase.
+	 */
+	pm_runtime_get_noresume(dev);
+
 	device_lock(dev);
 
 	dev->power.wakeup_path = device_may_wakeup(dev);
diff --git a/drivers/coresight/coresight-etm.c b/drivers/coresight/coresight-etm.c
index e2a16ad..f3fe70f 100644
--- a/drivers/coresight/coresight-etm.c
+++ b/drivers/coresight/coresight-etm.c
@@ -363,6 +363,7 @@
 	 */
 	etm_set_pwrup(drvdata);
 	etm_clr_pwrdwn(drvdata);
+	etm_clr_pwrup(drvdata);
 
 	ETM_LOCK(drvdata);
 }
@@ -373,10 +374,8 @@
 
 	ETM_UNLOCK(drvdata);
 
-	if (!drvdata->enable) {
+	if (!drvdata->enable)
 		etm_set_pwrdwn(drvdata);
-		etm_clr_pwrup(drvdata);
-	}
 
 	ETM_LOCK(drvdata);
 }
@@ -400,6 +399,7 @@
 	 * for trace enable.
 	 */
 	etm_clr_pwrdwn(drvdata);
+	etm_clr_pwrup(drvdata);
 	etm_set_prog(drvdata);
 
 	etmcr = etm_readl(drvdata, ETMCR);
@@ -495,10 +495,8 @@
 	/* program trace enable to low by using always false event */
 	etm_writel(drvdata, 0x6F | BIT(14), ETMTEEVR);
 
-	if (!drvdata->pcsave_enable) {
+	if (!drvdata->pcsave_enable)
 		etm_set_pwrdwn(drvdata);
-		etm_clr_pwrup(drvdata);
-	}
 	ETM_LOCK(drvdata);
 
 	dev_dbg(drvdata->dev, "cpu: %d disable smp call done\n", drvdata->cpu);
@@ -1688,6 +1686,7 @@
 	 * certain registers might be ignored.
 	 */
 	etm_clr_pwrdwn(drvdata);
+	etm_clr_pwrup(drvdata);
 	/* Set prog bit. It will be set from reset but this is included to
 	 * ensure it is set
 	 */
@@ -1705,7 +1704,6 @@
 	drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
 
 	etm_set_pwrdwn(drvdata);
-	etm_clr_pwrup(drvdata);
 	ETM_LOCK(drvdata);
 }
 
diff --git a/drivers/crypto/msm/qce40.c b/drivers/crypto/msm/qce40.c
index 7a229a5..de060cc 100644
--- a/drivers/crypto/msm/qce40.c
+++ b/drivers/crypto/msm/qce40.c
@@ -1844,6 +1844,8 @@
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
 	*cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
@@ -1860,6 +1862,8 @@
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
 	*cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
@@ -1877,6 +1881,8 @@
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
 	*cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
@@ -1894,6 +1900,8 @@
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
 	*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
 	*cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 1312448..4361263 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -487,7 +487,10 @@
 		pce->data = auth_cfg;
 
 		pce = cmdlistinfo->auth_seg_size;
-		pce->data = totallen_in;
+		if (creq->dir == QCE_ENCRYPT)
+			pce->data = totallen_in;
+		else
+			pce->data = totallen_in - creq->authsize;
 		pce = cmdlistinfo->auth_seg_start;
 		pce->data = 0;
 	}
@@ -503,7 +506,8 @@
 		encr_cfg |= (CRYPTO_ENCR_MODE_XTS << CRYPTO_ENCR_MODE);
 		break;
 	case QCE_MODE_CCM:
-		encr_cfg |= (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE);
+		encr_cfg |= (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE) |
+				(CRYPTO_LAST_CCM_XFR << CRYPTO_LAST_CCM);
 		break;
 	case QCE_MODE_CTR:
 	default:
@@ -1930,7 +1934,9 @@
 		auth_cfg &= ~(1 << CRYPTO_USE_HW_KEY_AUTH);
 		encr_cfg = (CRYPTO_ENCR_KEY_SZ_AES256 << CRYPTO_ENCR_KEY_SZ) |
 			(CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG) |
-			((CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE));
+			(CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE) |
+			(CRYPTO_LAST_CCM_XFR << CRYPTO_LAST_CCM);
+
 		key_reg = 8;
 	}
 	qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_CONFIG_REG,
@@ -2161,8 +2167,10 @@
 	struct qce_cmdlist_info *cmdlistinfo = NULL;
 	struct qce_cmdlist_info *auth_cmdlistinfo = NULL;
 
-	if (q_req->mode != QCE_MODE_CCM)
+	if (q_req->mode != QCE_MODE_CCM) {
 		ivsize = crypto_aead_ivsize(aead);
+		auth_cmdlistinfo = &pce_dev->ce_sps.cmdlistptr.aead_sha1_hmac;
+	}
 
 	ce_burst_size = pce_dev->ce_sps.ce_burst_size;
 	if (q_req->dir == QCE_ENCRYPT) {
@@ -2770,13 +2778,11 @@
 	ce_support->aes_xts = true;
 	ce_support->ota = false;
 	ce_support->bam = true;
-	if (pce_dev->ce_sps.minor_version) {
+	ce_support->aes_ccm = true;
+	if (pce_dev->ce_sps.minor_version)
 		ce_support->aligned_only = false;
-		ce_support->aes_ccm = true;
-	} else {
+	else
 		ce_support->aligned_only = true;
-		ce_support->aes_ccm = false;
-	}
 	return 0;
 }
 EXPORT_SYMBOL(qce_hw_support);
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 7fc5cab..10f83f3 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -919,7 +919,7 @@
 
 			for (sg = areq->dst; bytes != nbytes; sg++) {
 				memcpy(sg_virt(sg),
-				((char *)rctx->data + rctx->assoclen + bytes),
+				((char *)rctx->data + areq->assoclen + bytes),
 								sg->length);
 				bytes += sg->length;
 			}
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index e5a790f..0d5e409 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -28,6 +28,14 @@
 
 #define GSL_RB_NOP_SIZEDWORDS				2
 
+/*
+ * CP DEBUG settings for all cores:
+ * DYNAMIC_CLK_DISABLE [27] - turn off the dynamic clock control
+ * PROG_END_PTR_ENABLE [25] - Allow 128 bit writes to the VBIF
+ */
+
+#define CP_DEBUG_DEFAULT ((1 << 27) | (1 << 25))
+
 void adreno_ringbuffer_submit(struct adreno_ringbuffer *rb)
 {
 	BUG_ON(rb->wptr == 0);
@@ -231,7 +239,7 @@
 	KGSL_DRV_INFO(device, "loading pm4 ucode version: %d\n",
 		adreno_dev->pm4_fw[0]);
 
-	adreno_regwrite(device, REG_CP_DEBUG, 0x02000000);
+	adreno_regwrite(device, REG_CP_DEBUG, CP_DEBUG_DEFAULT);
 	adreno_regwrite(device, REG_CP_ME_RAM_WADDR, 0);
 	for (i = 1; i < adreno_dev->pm4_fw_size; i++)
 		adreno_regwrite(device, REG_CP_ME_RAM_DATA,
@@ -537,6 +545,9 @@
 	if (adreno_is_a3xx(adreno_dev))
 		total_sizedwords += 7;
 
+	if (adreno_is_a2xx(adreno_dev))
+		total_sizedwords += 2; /* CP_WAIT_FOR_IDLE */
+
 	total_sizedwords += 2; /* scratchpad ts for recovery */
 	if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS &&
 			!(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
@@ -602,6 +613,16 @@
 	}
 	timestamp = rb->timestamp[context_id];
 
+	/* HW Workaround for MMU Page fault
+	* due to memory getting free early before
+	* GPU completes it.
+	*/
+	if (adreno_is_a2xx(adreno_dev)) {
+		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+			cp_type3_packet(CP_WAIT_FOR_IDLE, 1));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x00);
+	}
+
 	/* scratchpad ts for recovery */
 	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type0_packet(REG_CP_TIMESTAMP, 1));
 	GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index ba122bb..d658217 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -21,6 +21,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
 #include <linux/spmi.h>
+#include <linux/qpnp/pwm.h>
 
 #define WLED_MOD_EN_REG(base, n)	(base + 0x60 + n*0x10)
 #define WLED_IDAC_DLY_REG(base, n)	(WLED_MOD_EN_REG(base, n) + 0x01)
@@ -127,6 +128,21 @@
 
 #define LED_TRIGGER_DEFAULT		"none"
 
+#define RGB_LED_SRC_SEL(base)		(base + 0x45)
+#define RGB_LED_EN_CTL(base)		(base + 0x46)
+#define RGB_LED_ATC_CTL(base)		(base + 0x47)
+
+#define RGB_MAX_LEVEL			LED_FULL
+#define RGB_LED_ENABLE_RED		0x80
+#define RGB_LED_ENABLE_GREEN		0x40
+#define RGB_LED_ENABLE_BLUE		0x20
+#define RGB_LED_SOURCE_VPH_PWR		0x01
+#define RGB_LED_ENABLE_MASK		0xE0
+#define RGB_LED_SRC_MASK		0x03
+#define QPNP_LED_PWM_FLAGS	(PM_PWM_LUT_LOOP | PM_PWM_LUT_RAMP_UP)
+#define	PWM_LUT_MAX_SIZE		63
+#define RGB_LED_DISABLE			0x00
+
 /**
  * enum qpnp_leds - QPNP supported led ids
  * @QPNP_ID_WLED - White led backlight
@@ -135,6 +151,9 @@
 	QPNP_ID_WLED = 0,
 	QPNP_ID_FLASH1_LED0,
 	QPNP_ID_FLASH1_LED1,
+	QPNP_ID_RGB_RED,
+	QPNP_ID_RGB_GREEN,
+	QPNP_ID_RGB_BLUE,
 	QPNP_ID_MAX,
 };
 
@@ -180,6 +199,11 @@
 	DELAY_128us,
 };
 
+enum rgb_mode {
+	RGB_MODE_PWM = 0,
+	RGB_MODE_LPG,
+};
+
 static u8 wled_debug_regs[] = {
 	/* common registers */
 	0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4f,
@@ -197,7 +221,9 @@
 	0x4f, 0x46, 0x47,
 };
 
-
+static u8 rgb_pwm_debug_regs[] = {
+	0x45, 0x46, 0x47,
+};
 /**
  *  wled_config_data - wled configuration data
  *  @num_strings - number of wled strings supported
@@ -248,6 +274,24 @@
 };
 
 /**
+ *  rgb_config_data - rgb configuration data
+ *  @lut_params - lut parameters to be used by pwm driver
+ *  @pwm_device - pwm device
+ *  @pwm_channel - pwm channel to be configured for led
+ *  @pwm_period_us - period for pwm, in us
+ *  @mode - mode the led operates in
+ */
+struct rgb_config_data {
+	struct lut_params	lut_params;
+	struct pwm_device	*pwm_dev;
+	int			pwm_channel;
+	u32			pwm_period_us;
+	struct pwm_duty_cycles	*duty_cycles;
+	u8	mode;
+	u8	enable;
+};
+
+/**
  * struct qpnp_led_data - internal led data structure
  * @led_classdev - led class device
  * @id - led index
@@ -268,6 +312,7 @@
 	spinlock_t		lock;
 	struct wled_config_data *wled_cfg;
 	struct flash_config_data	*flash_cfg;
+	struct rgb_config_data	*rgb_cfg;
 	int			max_current;
 	bool			default_on;
 };
@@ -458,6 +503,51 @@
 		}
 	}
 
+	qpnp_dump_regs(led, flash_debug_regs, ARRAY_SIZE(flash_debug_regs));
+
+	return 0;
+}
+
+static int qpnp_rgb_set(struct qpnp_led_data *led)
+{
+	int duty_us;
+	int rc;
+
+	if (led->cdev.brightness) {
+		if (led->rgb_cfg->mode == RGB_MODE_PWM) {
+			duty_us = (led->rgb_cfg->pwm_period_us *
+				led->cdev.brightness) / LED_FULL;
+			rc = pwm_config(led->rgb_cfg->pwm_dev, duty_us,
+					led->rgb_cfg->pwm_period_us);
+			if (rc < 0) {
+				dev_err(&led->spmi_dev->dev, "Failed to " \
+					"configure pwm for new values\n");
+				return rc;
+			}
+		}
+		rc = qpnp_led_masked_write(led,
+			RGB_LED_EN_CTL(led->base),
+			led->rgb_cfg->enable, led->rgb_cfg->enable);
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"Failed to write led enable reg\n");
+			return rc;
+		}
+		rc = pwm_enable(led->rgb_cfg->pwm_dev);
+	} else {
+		pwm_disable(led->rgb_cfg->pwm_dev);
+		rc = qpnp_led_masked_write(led,
+			RGB_LED_EN_CTL(led->base),
+			led->rgb_cfg->enable, RGB_LED_DISABLE);
+		if (rc) {
+			dev_err(&led->spmi_dev->dev,
+				"Failed to write led enable reg\n");
+			return rc;
+		}
+	}
+
+	qpnp_dump_regs(led, rgb_pwm_debug_regs, ARRAY_SIZE(rgb_pwm_debug_regs));
+
 	return 0;
 }
 
@@ -490,6 +580,14 @@
 			dev_err(&led->spmi_dev->dev,
 				"FLASH set brightness failed (%d)\n", rc);
 		break;
+	case QPNP_ID_RGB_RED:
+	case QPNP_ID_RGB_GREEN:
+	case QPNP_ID_RGB_BLUE:
+		rc = qpnp_rgb_set(led);
+		if (rc < 0)
+			dev_err(&led->spmi_dev->dev,
+				"RGB set brightness failed (%d)\n", rc);
+		break;
 	default:
 		dev_err(&led->spmi_dev->dev, "Invalid LED(%d)\n", led->id);
 		break;
@@ -507,6 +605,11 @@
 	case QPNP_ID_FLASH1_LED1:
 		led->cdev.max_brightness = led->max_current;
 		break;
+	case QPNP_ID_RGB_RED:
+	case QPNP_ID_RGB_GREEN:
+	case QPNP_ID_RGB_BLUE:
+		led->cdev.max_brightness = RGB_MAX_LEVEL;
+		break;
 	default:
 		dev_err(&led->spmi_dev->dev, "Invalid LED(%d)\n", led->id);
 		return -EINVAL;
@@ -769,6 +872,74 @@
 	return 0;
 }
 
+static int __devinit qpnp_rgb_init(struct qpnp_led_data *led)
+{
+	int rc, start_idx, idx_len;
+
+	rc = qpnp_led_masked_write(led, RGB_LED_SRC_SEL(led->base),
+		RGB_LED_SRC_MASK, RGB_LED_SOURCE_VPH_PWR);
+	if (rc) {
+		dev_err(&led->spmi_dev->dev,
+			"Failed to write led source select register\n");
+		return rc;
+	}
+
+	if (led->rgb_cfg->pwm_channel != -1) {
+		led->rgb_cfg->pwm_dev =
+			pwm_request(led->rgb_cfg->pwm_channel,
+						led->cdev.name);
+
+		if (IS_ERR_OR_NULL(led->rgb_cfg->pwm_dev)) {
+			dev_err(&led->spmi_dev->dev,
+				"could not acquire PWM Channel %d, " \
+				"error %ld\n",
+				led->rgb_cfg->pwm_channel,
+				PTR_ERR(led->rgb_cfg->pwm_dev));
+			led->rgb_cfg->pwm_dev = NULL;
+			return -ENODEV;
+		}
+
+		if (led->rgb_cfg->mode == RGB_MODE_LPG) {
+			start_idx =
+			led->rgb_cfg->duty_cycles->start_idx;
+			idx_len =
+			led->rgb_cfg->duty_cycles->num_duty_pcts;
+
+			if (idx_len >= PWM_LUT_MAX_SIZE &&
+					start_idx) {
+				dev_err(&led->spmi_dev->dev,
+					"Wrong LUT size or index\n");
+				return -EINVAL;
+			}
+			if ((start_idx + idx_len) >
+					PWM_LUT_MAX_SIZE) {
+				dev_err(&led->spmi_dev->dev,
+					"Exceed LUT limit\n");
+				return -EINVAL;
+			}
+			rc = pwm_lut_config(led->rgb_cfg->pwm_dev,
+				led->rgb_cfg->pwm_period_us,
+				led->rgb_cfg->duty_cycles->duty_pcts,
+				led->rgb_cfg->lut_params);
+			if (rc < 0) {
+				dev_err(&led->spmi_dev->dev, "Failed to " \
+					"configure pwm LUT\n");
+				return rc;
+			}
+		}
+	} else {
+		dev_err(&led->spmi_dev->dev,
+			"Invalid PWM channel\n");
+		return -EINVAL;
+	}
+
+	/* Initialize led for use in auto trickle charging mode */
+	rc = qpnp_led_masked_write(led, RGB_LED_ATC_CTL(led->base),
+		led->rgb_cfg->enable, led->rgb_cfg->enable);
+
+	return 0;
+}
+
 static int __devinit qpnp_led_initialize(struct qpnp_led_data *led)
 {
 	int rc;
@@ -787,12 +958,20 @@
 			dev_err(&led->spmi_dev->dev,
 				"FLASH initialize failed(%d)\n", rc);
 		break;
+	case QPNP_ID_RGB_RED:
+	case QPNP_ID_RGB_GREEN:
+	case QPNP_ID_RGB_BLUE:
+		rc = qpnp_rgb_init(led);
+		if (rc)
+			dev_err(&led->spmi_dev->dev,
+				"RGB initialize failed(%d)\n", rc);
+		break;
 	default:
 		dev_err(&led->spmi_dev->dev, "Invalid LED(%d)\n", led->id);
-		rc = -EINVAL;
+		return -EINVAL;
 	}
 
-	return rc;
+	return 0;
 }
 
 static int __devinit qpnp_get_common_configs(struct qpnp_led_data *led,
@@ -965,6 +1144,120 @@
 	return 0;
 }
 
+static int __devinit qpnp_get_config_rgb(struct qpnp_led_data *led,
+				struct device_node *node)
+{
+	struct property *prop;
+	int rc, i;
+	u32 val;
+	u8 *temp_cfg;
+
+	led->rgb_cfg = devm_kzalloc(&led->spmi_dev->dev,
+				sizeof(struct rgb_config_data), GFP_KERNEL);
+	if (!led->rgb_cfg) {
+		dev_err(&led->spmi_dev->dev, "Unable to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	if (led->id == QPNP_ID_RGB_RED)
+		led->rgb_cfg->enable = RGB_LED_ENABLE_RED;
+	else if (led->id == QPNP_ID_RGB_GREEN)
+		led->rgb_cfg->enable = RGB_LED_ENABLE_GREEN;
+	else if (led->id == QPNP_ID_RGB_BLUE)
+		led->rgb_cfg->enable = RGB_LED_ENABLE_BLUE;
+	else
+		return -EINVAL;
+
+	rc = of_property_read_u32(node, "qcom,mode", &val);
+	if (!rc)
+		led->rgb_cfg->mode = (u8) val;
+	else
+		return rc;
+
+	rc = of_property_read_u32(node, "qcom,pwm-channel", &val);
+	if (!rc)
+		led->rgb_cfg->pwm_channel = (u8) val;
+	else
+		return rc;
+
+	rc = of_property_read_u32(node, "qcom,pwm-us", &val);
+	if (!rc)
+		led->rgb_cfg->pwm_period_us = val;
+	else
+		return rc;
+
+	if (led->rgb_cfg->mode == RGB_MODE_LPG) {
+		led->rgb_cfg->duty_cycles =
+			devm_kzalloc(&led->spmi_dev->dev,
+			sizeof(struct pwm_duty_cycles), GFP_KERNEL);
+		if (!led->rgb_cfg->duty_cycles) {
+			dev_err(&led->spmi_dev->dev,
+				"Unable to allocate memory\n");
+			return -ENOMEM;
+		}
+
+		rc = of_property_read_u32(node, "qcom,duty-ms", &val);
+		if (!rc)
+			led->rgb_cfg->duty_cycles->duty_ms = (u8) val;
+		else
+			return rc;
+
+		prop = of_find_property(node, "qcom,duty-pcts",
+			&led->rgb_cfg->duty_cycles->num_duty_pcts);
+		if (!prop) {
+			dev_err(&led->spmi_dev->dev, "Looking up property " \
+				"node qcom,duty-pcts failed\n");
+			return -ENODEV;
+		} else if (!led->rgb_cfg->duty_cycles->num_duty_pcts) {
+			dev_err(&led->spmi_dev->dev, "Invalid length of " \
+				"duty pcts\n");
+			return -EINVAL;
+		}
+
+		led->rgb_cfg->duty_cycles->duty_pcts =
+			devm_kzalloc(&led->spmi_dev->dev,
+			sizeof(int) * led->rgb_cfg->duty_cycles->num_duty_pcts,
+			GFP_KERNEL);
+		if (!led->rgb_cfg->duty_cycles->duty_pcts) {
+			dev_err(&led->spmi_dev->dev,
+				"Unable to allocate memory\n");
+			return -ENOMEM;
+		}
+
+		temp_cfg = devm_kzalloc(&led->spmi_dev->dev,
+				led->rgb_cfg->duty_cycles->num_duty_pcts *
+				sizeof(u8), GFP_KERNEL);
+		if (!temp_cfg) {
+			dev_err(&led->spmi_dev->dev, "Failed to allocate " \
+				"memory for duty pcts\n");
+			return -ENOMEM;
+		}
+
+		memcpy(temp_cfg, prop->value,
+			led->rgb_cfg->duty_cycles->num_duty_pcts);
+
+		for (i = 0; i < led->rgb_cfg->duty_cycles->num_duty_pcts; i++)
+			led->rgb_cfg->duty_cycles->duty_pcts[i] =
+				(int) temp_cfg[i];
+
+		rc = of_property_read_u32(node, "qcom,start-idx", &val);
+		if (!rc) {
+			led->rgb_cfg->lut_params.start_idx = (u8) val;
+			led->rgb_cfg->duty_cycles->start_idx = (u8) val;
+		} else
+			return rc;
+
+		led->rgb_cfg->lut_params.idx_len =
+			led->rgb_cfg->duty_cycles->num_duty_pcts;
+		led->rgb_cfg->lut_params.lut_pause_hi = 0;
+		led->rgb_cfg->lut_params.lut_pause_lo = 0;
+		led->rgb_cfg->lut_params.ramp_step_ms = 255;
+		led->rgb_cfg->lut_params.flags = QPNP_LED_PWM_FLAGS;
+	}
+
+	return 0;
+}
+
 static int __devinit qpnp_leds_probe(struct spmi_device *spmi)
 {
 	struct qpnp_led_data *led;
@@ -1060,6 +1353,13 @@
 					"Unable to read flash config data\n");
 				return rc;
 			}
+		} else if (strncmp(led_label, "rgb", sizeof("rgb")) == 0) {
+			rc = qpnp_get_config_rgb(led, temp);
+			if (rc < 0) {
+				dev_err(&led->spmi_dev->dev,
+					"Unable to read rgb config data\n");
+				return rc;
+			}
 		} else {
 			dev_err(&led->spmi_dev->dev, "No LED matching label\n");
 			return -EINVAL;
diff --git a/drivers/media/video/msm_wfd/enc-mfc-subdev.c b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
index 6db2ad1..d839be3 100644
--- a/drivers/media/video/msm_wfd/enc-mfc-subdev.c
+++ b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
@@ -194,6 +194,9 @@
 			break;
 		}
 
+		if (frame_data->flags & VCD_FRAME_FLAG_CODECCONFIG)
+			vbuf->v4l2_buf.flags |= V4L2_QCOM_BUF_FLAG_CODECCONFIG;
+
 		vbuf->v4l2_buf.timestamp =
 			ns_to_timeval(frame_data->time_stamp * NSEC_PER_USEC);
 
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
index 2b73b11..9afc3df 100644
--- a/drivers/media/video/vcap_v4l2.c
+++ b/drivers/media/video/vcap_v4l2.c
@@ -569,6 +569,17 @@
 }
 
 /* VC Videobuf operations */
+static void wait_prepare(struct vb2_queue *q)
+{
+	struct vcap_client_data *c_data = vb2_get_drv_priv(q);
+	mutex_unlock(&c_data->mutex);
+}
+
+static void wait_finish(struct vb2_queue *q)
+{
+	struct vcap_client_data *c_data = vb2_get_drv_priv(q);
+	mutex_lock(&c_data->mutex);
+}
 
 static int capture_queue_setup(struct vb2_queue *vq,
 			       const struct v4l2_format *fmt,
@@ -651,6 +662,8 @@
 
 static struct vb2_ops capture_video_qops = {
 	.queue_setup		= capture_queue_setup,
+	.wait_finish		= wait_finish,
+	.wait_prepare		= wait_prepare,
 	.buf_init			= capture_buffer_init,
 	.buf_prepare		= capture_buffer_prepare,
 	.buf_queue			= capture_buffer_queue,
@@ -749,6 +762,8 @@
 
 static struct vb2_ops vp_in_video_qops = {
 	.queue_setup		= vp_in_queue_setup,
+	.wait_finish		= wait_finish,
+	.wait_prepare		= wait_prepare,
 	.buf_init			= vp_in_buffer_init,
 	.buf_prepare		= vp_in_buffer_prepare,
 	.buf_queue			= vp_in_buffer_queue,
@@ -847,6 +862,8 @@
 
 static struct vb2_ops vp_out_video_qops = {
 	.queue_setup		= vp_out_queue_setup,
+	.wait_finish		= wait_finish,
+	.wait_prepare		= wait_prepare,
 	.buf_init			= vp_out_buffer_init,
 	.buf_prepare		= vp_out_buffer_prepare,
 	.buf_queue			= vp_out_buffer_queue,
@@ -1072,7 +1089,9 @@
 		rc = get_phys_addr(c_data->dev, &c_data->vc_vidq, p);
 		if (rc < 0)
 			return rc;
+		mutex_lock(&c_data->mutex);
 		rc = vb2_qbuf(&c_data->vc_vidq, p);
+		mutex_unlock(&c_data->mutex);
 		if (rc < 0)
 			free_ion_handle(c_data, &c_data->vc_vidq, p);
 		return rc;
@@ -1082,7 +1101,9 @@
 		rc = get_phys_addr(c_data->dev, &c_data->vp_in_vidq, p);
 		if (rc < 0)
 			return rc;
+		mutex_lock(&c_data->mutex);
 		rc = vb2_qbuf(&c_data->vp_in_vidq, p);
+		mutex_unlock(&c_data->mutex);
 		if (rc < 0)
 			free_ion_handle(c_data, &c_data->vp_in_vidq, p);
 		return rc;
@@ -1090,7 +1111,9 @@
 		rc = get_phys_addr(c_data->dev, &c_data->vp_out_vidq, p);
 		if (rc < 0)
 			return rc;
+		mutex_lock(&c_data->mutex);
 		rc = vb2_qbuf(&c_data->vp_out_vidq, p);
+		mutex_unlock(&c_data->mutex);
 		if (rc < 0)
 			free_ion_handle(c_data, &c_data->vp_out_vidq, p);
 		return rc;
@@ -1114,21 +1137,27 @@
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 		if (c_data->op_mode == VC_AND_VP_VCAP_OP)
 			return -EINVAL;
+		mutex_lock(&c_data->mutex);
 		rc = vb2_dqbuf(&c_data->vc_vidq, p, file->f_flags & O_NONBLOCK);
+		mutex_unlock(&c_data->mutex);
 		if (rc < 0)
 			return rc;
 		return free_ion_handle(c_data, &c_data->vc_vidq, p);
 	case V4L2_BUF_TYPE_INTERLACED_IN_DECODER:
 		if (c_data->op_mode == VC_AND_VP_VCAP_OP)
 			return -EINVAL;
+		mutex_lock(&c_data->mutex);
 		rc = vb2_dqbuf(&c_data->vp_in_vidq, p, file->f_flags &
 				O_NONBLOCK);
+		mutex_unlock(&c_data->mutex);
 		if (rc < 0)
 			return rc;
 		return free_ion_handle(c_data, &c_data->vp_in_vidq, p);
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		mutex_lock(&c_data->mutex);
 		rc = vb2_dqbuf(&c_data->vp_out_vidq, p, file->f_flags &
 				O_NONBLOCK);
+		mutex_unlock(&c_data->mutex);
 		if (rc < 0)
 			return rc;
 		return free_ion_handle(c_data, &c_data->vp_out_vidq, p);
@@ -1488,8 +1517,10 @@
 		dev->vc_resource = 0;
 		mutex_unlock(&dev->dev_mutex);
 		c_data->streaming = 0;
+		mutex_lock(&c_data->mutex);
 		rc = vb2_streamoff(&c_data->vc_vidq,
 				V4L2_BUF_TYPE_VIDEO_CAPTURE);
+		mutex_unlock(&c_data->mutex);
 		if (rc >= 0)
 			atomic_set(&c_data->dev->vc_enabled, 0);
 		return rc;
@@ -1515,14 +1546,18 @@
 			return rc;
 		c_data->streaming = 0;
 
+		mutex_unlock(&dev->dev_mutex);
 		/* These stream on calls should not fail */
 		rc = vb2_streamoff(&c_data->vp_in_vidq,
 				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
-		if (rc < 0)
+		if (rc < 0) {
+			mutex_unlock(&c_data->mutex);
 			return rc;
+		}
 
 		rc = vb2_streamoff(&c_data->vp_out_vidq,
 				V4L2_BUF_TYPE_VIDEO_OUTPUT);
+		mutex_unlock(&c_data->mutex);
 		if (rc < 0)
 			return rc;
 
@@ -1557,20 +1592,26 @@
 		if (rc < 0)
 			return rc;
 
-		/* These stream on calls should not fail */
 		c_data->streaming = 0;
+		mutex_lock(&c_data->mutex);
+		/* These stream on calls should not fail */
 		rc = vb2_streamoff(&c_data->vc_vidq,
 				V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		if (rc < 0)
+		if (rc < 0) {
+			mutex_unlock(&c_data->mutex);
 			return rc;
+		}
 
 		rc = vb2_streamoff(&c_data->vp_in_vidq,
 				V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
-		if (rc < 0)
+		if (rc < 0) {
+			mutex_unlock(&c_data->mutex);
 			return rc;
+		}
 
 		rc = vb2_streamoff(&c_data->vp_out_vidq,
 				V4L2_BUF_TYPE_VIDEO_OUTPUT);
+		mutex_unlock(&c_data->mutex);
 		if (rc < 0)
 			return rc;
 
@@ -1716,6 +1757,7 @@
 	c_data->dev = dev;
 
 	spin_lock_init(&c_data->cap_slock);
+	mutex_init(&c_data->mutex);
 
 	/* initialize vc queue */
 	q = &c_data->vc_vidq;
@@ -1799,6 +1841,7 @@
 vp_in_q_failed:
 	vb2_queue_release(&c_data->vc_vidq);
 vc_q_failed:
+	mutex_destroy(&c_data->mutex);
 	kfree(c_data);
 	return ret;
 }
@@ -1833,6 +1876,7 @@
 		c_data->dev->vc_client = NULL;
 	if (c_data->dev->vp_client == c_data)
 		c_data->dev->vp_client = NULL;
+	mutex_destroy(&c_data->mutex);
 	kfree(c_data);
 	return 0;
 }
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index e71c95d..27123bc 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -51,6 +51,9 @@
 
 #define QSEOS_CHECK_VERSION_CMD		0x00001803
 
+#define QSEE_CE_CLK_100MHZ		100000000
+#define QSEE_CE_CLK_50MHZ		50000000
+
 enum qseecom_command_scm_resp_type {
 	QSEOS_APP_ID = 0xEE01,
 	QSEOS_LISTENER_ID
@@ -247,8 +250,6 @@
 /* Function proto types */
 static int qsee_vote_for_clock(int32_t);
 static void qsee_disable_clock_vote(int32_t);
-static int __qseecom_init_clk(void);
-static void __qseecom_disable_clk(void);
 
 static int __qseecom_is_svc_unique(struct qseecom_dev_handle *data,
 		struct qseecom_register_listener_req *svc)
@@ -1718,9 +1719,13 @@
 			if (qsee_sfpb_bw_count > 0)
 				ret = msm_bus_scale_client_update_request(
 						qsee_perf_client, 3);
-			else
+			else {
+				if (ce_core_src_clk != NULL)
+					clk_set_rate(ce_core_src_clk,
+							QSEE_CE_CLK_100MHZ);
 				ret = msm_bus_scale_client_update_request(
 						qsee_perf_client, 1);
+			}
 			if (ret)
 				pr_err("DFAB Bandwidth req failed (%d)\n",
 								ret);
@@ -1737,9 +1742,13 @@
 			if (qsee_bw_count > 0)
 				ret = msm_bus_scale_client_update_request(
 						qsee_perf_client, 3);
-			else
+			else {
+				if (ce_core_src_clk != NULL)
+					clk_set_rate(ce_core_src_clk,
+							QSEE_CE_CLK_100MHZ);
 				ret = msm_bus_scale_client_update_request(
 						qsee_perf_client, 2);
+			}
 
 			if (ret)
 				pr_err("SFPB Bandwidth req failed (%d)\n",
@@ -1778,9 +1787,13 @@
 			if (qsee_sfpb_bw_count > 0)
 				ret = msm_bus_scale_client_update_request(
 						qsee_perf_client, 2);
-			else
+			else {
 				ret = msm_bus_scale_client_update_request(
 						qsee_perf_client, 0);
+				if (ce_core_src_clk != NULL)
+					clk_set_rate(ce_core_src_clk,
+							QSEE_CE_CLK_50MHZ);
+			}
 			if (ret)
 				pr_err("SFPB Bandwidth req fail (%d)\n",
 								ret);
@@ -1798,9 +1811,13 @@
 			if (qsee_bw_count > 0)
 				ret = msm_bus_scale_client_update_request(
 						qsee_perf_client, 1);
-			else
+			else {
 				ret = msm_bus_scale_client_update_request(
 						qsee_perf_client, 0);
+				if (ce_core_src_clk != NULL)
+					clk_set_rate(ce_core_src_clk,
+							QSEE_CE_CLK_50MHZ);
+			}
 			if (ret)
 				pr_err("SFPB Bandwidth req fail (%d)\n",
 								ret);
@@ -2261,7 +2278,47 @@
 		.release = qseecom_release
 };
 
-static int __qseecom_init_clk()
+static int __qseecom_enable_clk(void)
+{
+	int rc = 0;
+
+	/* Enable CE core clk */
+	rc = clk_prepare_enable(ce_core_clk);
+	if (rc) {
+		pr_err("Unable to enable/prepare CE core clk\n");
+		return -EIO;
+	} else {
+		/* Enable CE clk */
+		rc = clk_prepare_enable(ce_clk);
+		if (rc) {
+			pr_err("Unable to enable/prepare CE iface clk\n");
+			clk_disable_unprepare(ce_core_clk);
+			return -EIO;
+		} else {
+			/* Enable AXI clk */
+			rc = clk_prepare_enable(ce_bus_clk);
+			if (rc) {
+				pr_err("Unable to enable/prepare CE iface clk\n");
+				clk_disable_unprepare(ce_core_clk);
+				clk_disable_unprepare(ce_clk);
+				return -EIO;
+			}
+		}
+	}
+	return rc;
+}
+
+static void __qseecom_disable_clk(void)
+{
+	if (ce_clk != NULL)
+		clk_disable_unprepare(ce_clk);
+	if (ce_core_clk != NULL)
+		clk_disable_unprepare(ce_core_clk);
+	if (ce_bus_clk != NULL)
+		clk_disable_unprepare(ce_bus_clk);
+}
+
+static int __qseecom_init_clk(void)
 {
 	int rc = 0;
 	struct device *pdev;
@@ -2270,14 +2327,12 @@
 	/* Get CE3 src core clk. */
 	ce_core_src_clk = clk_get(pdev, "core_clk_src");
 	if (!IS_ERR(ce_core_src_clk)) {
-		ce_core_src_clk = ce_core_src_clk;
-
-		/* Set the core src clk @100Mhz */
-		rc = clk_set_rate(ce_core_src_clk, 100000000);
+		/* Set the core src clk @50Mhz */
+		rc = clk_set_rate(ce_core_src_clk, QSEE_CE_CLK_50MHZ);
 		if (rc) {
 			clk_put(ce_core_src_clk);
 			pr_err("Unable to set the core src clk @100Mhz.\n");
-			goto err_clk;
+			return -EIO;
 		}
 	} else {
 		pr_warn("Unable to get CE core src clk, set to NULL\n");
@@ -2291,7 +2346,7 @@
 		pr_err("Unable to get CE core clk\n");
 		if (ce_core_src_clk != NULL)
 			clk_put(ce_core_src_clk);
-		goto err_clk;
+		return -EIO;
 	}
 
 	/* Get CE Interface clk */
@@ -2302,7 +2357,7 @@
 		if (ce_core_src_clk != NULL)
 			clk_put(ce_core_src_clk);
 		clk_put(ce_core_clk);
-		goto err_clk;
+		return -EIO;
 	}
 
 	/* Get CE AXI clk */
@@ -2314,78 +2369,35 @@
 			clk_put(ce_core_src_clk);
 		clk_put(ce_core_clk);
 		clk_put(ce_clk);
-		goto err_clk;
+		return -EIO;
 	}
-
-	/* Enable CE core clk */
-	rc = clk_prepare_enable(ce_core_clk);
-	if (rc) {
-		pr_err("Unable to enable/prepare CE core clk\n");
-		if (ce_core_src_clk != NULL)
-			clk_put(ce_core_src_clk);
-		clk_put(ce_core_clk);
-		clk_put(ce_clk);
-		goto err_clk;
-	} else {
-		/* Enable CE clk */
-		rc = clk_prepare_enable(ce_clk);
-		if (rc) {
-			pr_err("Unable to enable/prepare CE iface clk\n");
-			clk_disable_unprepare(ce_core_clk);
-			if (ce_core_src_clk != NULL)
-				clk_put(ce_core_src_clk);
-			clk_put(ce_core_clk);
-			clk_put(ce_clk);
-			goto err_clk;
-		} else {
-			/* Enable AXI clk */
-			rc = clk_prepare_enable(ce_bus_clk);
-			if (rc) {
-				pr_err("Unable to enable/prepare CE iface clk\n");
-				clk_disable_unprepare(ce_core_clk);
-				clk_disable_unprepare(ce_clk);
-				if (ce_core_src_clk != NULL)
-					clk_put(ce_core_src_clk);
-				clk_put(ce_core_clk);
-				clk_put(ce_clk);
-				goto err_clk;
-			}
-		}
-	}
-	return rc;
-
-err_clk:
-	if (rc)
-		pr_err("Unable to init CE clks, rc = %d\n", rc);
-	clk_disable_unprepare(ce_clk);
-	clk_disable_unprepare(ce_core_clk);
-	clk_disable_unprepare(ce_bus_clk);
-	if (ce_core_src_clk != NULL)
-		clk_put(ce_core_src_clk);
-	clk_put(ce_clk);
-	clk_put(ce_core_clk);
-	clk_put(ce_bus_clk);
 	return rc;
 }
 
-
-
-static void __qseecom_disable_clk()
+static void __qseecom_deinit_clk(void)
 {
-	clk_disable_unprepare(ce_clk);
-	clk_disable_unprepare(ce_core_clk);
-	clk_disable_unprepare(ce_bus_clk);
-	if (ce_core_src_clk != NULL)
+	if (ce_clk != NULL) {
+		clk_put(ce_clk);
+		ce_clk = NULL;
+	}
+	if (ce_core_clk != NULL) {
+		clk_put(ce_core_clk);
+		ce_clk = NULL;
+	}
+	if (ce_bus_clk != NULL) {
+		clk_put(ce_bus_clk);
+		ce_clk = NULL;
+	}
+	if (ce_core_src_clk != NULL) {
 		clk_put(ce_core_src_clk);
-	clk_put(ce_clk);
-	clk_put(ce_core_clk);
-	clk_put(ce_bus_clk);
+		ce_core_src_clk = NULL;
+	}
 }
 
 static int __devinit qseecom_probe(struct platform_device *pdev)
 {
 	int rc;
-	int ret;
+	int ret = 0;
 	struct device *class_dev;
 	char qsee_not_legacy = 0;
 	struct msm_bus_scale_pdata *qseecom_platform_support = NULL;
@@ -2393,6 +2405,12 @@
 
 	qsee_bw_count = 0;
 	qsee_perf_client = 0;
+	qsee_sfpb_bw_count = 0;
+
+	ce_core_clk = NULL;
+	ce_clk = NULL;
+	ce_core_src_clk = NULL;
+	ce_bus_clk = NULL;
 
 	rc = alloc_chrdev_region(&qseecom_device_no, 0, 1, QSEECOM_DEV);
 	if (rc < 0) {
@@ -2471,6 +2489,11 @@
 		ret = __qseecom_init_clk();
 		if (ret)
 			goto err;
+		ret = __qseecom_enable_clk();
+		if (ret) {
+			__qseecom_deinit_clk();
+			goto err;
+		}
 		qseecom_platform_support = (struct msm_bus_scale_pdata *)
 						msm_bus_cl_get_pdata(pdev);
 	} else {
@@ -2550,6 +2573,14 @@
 	}
 	if (qseecom.qseos_version  > QSEEE_VERSION_00)
 		qseecom_unload_commonlib_image();
+
+	if (qsee_perf_client)
+		msm_bus_scale_client_update_request(qsee_perf_client, 0);
+	/* register client for bus scaling */
+	if (pdev->dev.of_node) {
+		__qseecom_disable_clk();
+		__qseecom_deinit_clk();
+	}
 	return ret;
 };
 
@@ -2577,9 +2608,6 @@
 
 static void __devexit qseecom_exit(void)
 {
-
-	__qseecom_disable_clk();
-
 	device_destroy(driver_class, qseecom_device_no);
 	class_destroy(driver_class);
 	unregister_chrdev_region(qseecom_device_no, 1);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 47fd9b9..5183f2a 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -479,11 +479,11 @@
 				else
 					card->ext_csd.bkops_en = 1;
 			}
-			if (!card->ext_csd.bkops_en)
-				pr_info("%s: BKOPS_EN bit is not set\n",
-					mmc_hostname(card->host));
 		}
 
+		pr_info("%s: BKOPS_EN bit = %d\n",
+			mmc_hostname(card->host), card->ext_csd.bkops_en);
+
 		/* check whether the eMMC card supports HPI */
 		if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) {
 			card->ext_csd.hpi = 1;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 6cb492d..a752357 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -5656,6 +5656,8 @@
 		pdata->nonremovable = true;
 	if (of_get_property(np, "qcom,sdcc-disable_cmd23", NULL))
 		pdata->disable_cmd23 = true;
+	of_property_read_u32(np, "qcom,dat1-mpm-int",
+					&pdata->mpm_sdiowakeup_int);
 
 	return pdata;
 err:
@@ -5985,6 +5987,14 @@
 	disable_irq(core_irqres->start);
 	host->sdcc_irq_disabled = 1;
 
+	if (!plat->sdiowakeup_irq) {
+		/* Check if registered as IORESOURCE_IRQ */
+		plat->sdiowakeup_irq =
+			platform_get_irq_byname(pdev, "sdiowakeup_irq");
+		if (plat->sdiowakeup_irq < 0)
+			plat->sdiowakeup_irq = 0;
+	}
+
 	if (plat->sdiowakeup_irq) {
 		wake_lock_init(&host->sdio_wlock, WAKE_LOCK_SUSPEND,
 				mmc_hostname(mmc));
diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c
index 7ed8ffa..f87b3b9 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.c
+++ b/drivers/net/usb/rmnet_usb_ctrl.c
@@ -339,8 +339,10 @@
 
 int rmnet_usb_ctrl_suspend(struct rmnet_ctrl_dev *dev)
 {
-	if (!flush_work_sync(&dev->get_encap_work))
-		usb_kill_anchored_urbs(&dev->rx_submitted);
+	if (work_busy(&dev->get_encap_work))
+		return -EBUSY;
+
+	usb_kill_anchored_urbs(&dev->rx_submitted);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index b9459dd..3167b3a 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/clk.h>
 
 #include <mach/msm_smd.h>
 #include <mach/msm_iomap.h>
@@ -45,6 +46,14 @@
 module_param(has_48mhz_xo, int, S_IWUSR | S_IRUGO);
 MODULE_PARM_DESC(has_48mhz_xo, "Is an external 48 MHz XO present");
 
+static DEFINE_SPINLOCK(reg_spinlock);
+
+#define MSM_RIVA_PHYS			0x03204000
+#define MSM_PRONTO_PHYS			0xfb21b000
+
+#define RIVA_SPARE_OFFSET		0x0b4
+#define RIVA_SUSPEND_BIT		BIT(24)
+
 #define WCNSS_CTRL_CHANNEL			"WCNSS_CTRL"
 #define WCNSS_MAX_FRAME_SIZE		500
 #define WCNSS_VERSION_LEN			30
@@ -91,6 +100,7 @@
 	struct work_struct wcnssctrl_version_work;
 	struct work_struct wcnssctrl_rx_work;
 	struct wake_lock wcnss_wake_lock;
+	void __iomem *msm_wcnss_base;
 } *penv = NULL;
 
 static ssize_t wcnss_serial_number_show(struct device *dev,
@@ -489,6 +499,87 @@
 }
 EXPORT_SYMBOL(wcnss_get_serial_number);
 
+static int enable_wcnss_suspend_notify;
+
+static int enable_wcnss_suspend_notify_set(const char *val,
+				struct kernel_param *kp)
+{
+	int ret;
+
+	ret = param_set_int(val, kp);
+	if (ret)
+		return ret;
+
+	if (enable_wcnss_suspend_notify)
+		pr_debug("Suspend notification activated for wcnss\n");
+
+	return 0;
+}
+module_param_call(enable_wcnss_suspend_notify, enable_wcnss_suspend_notify_set,
+		param_get_int, &enable_wcnss_suspend_notify, S_IRUGO | S_IWUSR);
+
+
+void wcnss_suspend_notify(void)
+{
+	void __iomem *pmu_spare_reg;
+	u32 reg = 0;
+	unsigned long flags;
+	struct clk *cxo = clk_get(&penv->pdev->dev, "cxo");
+	int rc = 0;
+
+	if (!enable_wcnss_suspend_notify)
+		return;
+
+	if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
+		return;
+
+	/* For Riva */
+	rc = clk_prepare_enable(cxo);
+	if (rc) {
+		pr_err("cxo enable failed\n");
+		return;
+	}
+	pmu_spare_reg = penv->msm_wcnss_base + RIVA_SPARE_OFFSET;
+	spin_lock_irqsave(&reg_spinlock, flags);
+	reg = readl_relaxed(pmu_spare_reg);
+	reg |= RIVA_SUSPEND_BIT;
+	writel_relaxed(reg, pmu_spare_reg);
+	spin_unlock_irqrestore(&reg_spinlock, flags);
+	clk_disable_unprepare(cxo);
+}
+EXPORT_SYMBOL(wcnss_suspend_notify);
+
+void wcnss_resume_notify(void)
+{
+	void __iomem *pmu_spare_reg;
+	u32 reg = 0;
+	unsigned long flags;
+	struct clk *cxo = clk_get(&penv->pdev->dev, "cxo");
+	int rc = 0;
+
+	if (!enable_wcnss_suspend_notify)
+		return;
+
+	if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
+		return;
+
+	/* For Riva */
+	pmu_spare_reg = penv->msm_wcnss_base + RIVA_SPARE_OFFSET;
+
+	rc = clk_prepare_enable(cxo);
+	if (rc) {
+		pr_err("cxo enable failed\n");
+		return;
+	}
+	spin_lock_irqsave(&reg_spinlock, flags);
+	reg = readl_relaxed(pmu_spare_reg);
+	reg &= ~RIVA_SUSPEND_BIT;
+	writel_relaxed(reg, pmu_spare_reg);
+	spin_unlock_irqrestore(&reg_spinlock, flags);
+	clk_disable_unprepare(cxo);
+}
+EXPORT_SYMBOL(wcnss_resume_notify);
+
 static int wcnss_wlan_suspend(struct device *dev)
 {
 	if (penv && dev && (dev == &penv->pdev->dev) &&
@@ -612,6 +703,8 @@
 {
 	int ret;
 	struct qcom_wcnss_opts *pdata;
+	unsigned long wcnss_phys_addr;
+	int size = 0;
 	int has_pronto_hw = of_property_read_bool(pdev->dev.of_node,
 									"qcom,has_pronto_hw");
 
@@ -692,8 +785,25 @@
 
 	wake_lock_init(&penv->wcnss_wake_lock, WAKE_LOCK_SUSPEND, "wcnss");
 
+	if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
+		size = 0x3000;
+		wcnss_phys_addr = MSM_PRONTO_PHYS;
+	} else {
+		wcnss_phys_addr = MSM_RIVA_PHYS;
+		size = SZ_256;
+	}
+
+	penv->msm_wcnss_base = ioremap(wcnss_phys_addr, size);
+	if (!penv->msm_wcnss_base) {
+		ret = -ENOMEM;
+		pr_err("%s: ioremap wcnss physical failed\n", __func__);
+		goto fail_wake;
+	}
+
 	return 0;
 
+fail_wake:
+	wake_lock_destroy(&penv->wcnss_wake_lock);
 fail_res:
 	if (penv->pil)
 		subsystem_put(penv->pil);
@@ -702,7 +812,7 @@
 				WCNSS_WLAN_SWITCH_OFF);
 fail_power:
 	if (has_pronto_hw)
-		ret = wcnss_pronto_gpios_config(&pdev->dev, false);
+		wcnss_pronto_gpios_config(&pdev->dev, false);
 	else
 		wcnss_gpios_config(penv->gpios_5wire, false);
 fail_gpio_res:
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 6b54b23..9a18a97 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -617,21 +617,6 @@
 	int error = 0;
 
 	/*
-	 * If a PCI device configured to wake up the system from sleep states
-	 * has been suspended at run time and there's a resume request pending
-	 * for it, this is equivalent to the device signaling wakeup, so the
-	 * system suspend operation should be aborted.
-	 */
-	pm_runtime_get_noresume(dev);
-	if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
-		pm_wakeup_event(dev, 0);
-
-	if (pm_wakeup_pending()) {
-		pm_runtime_put_sync(dev);
-		return -EBUSY;
-	}
-
-	/*
 	 * PCI devices suspended at run time need to be resumed at this
 	 * point, because in general it is necessary to reconfigure them for
 	 * system suspend.  Namely, if the device is supposed to wake up the
@@ -654,8 +639,6 @@
 
 	if (drv && drv->pm && drv->pm->complete)
 		drv->pm->complete(dev);
-
-	pm_runtime_put_sync(dev);
 }
 
 #else /* !CONFIG_PM_SLEEP */
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 60eee64..81be519 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -1911,7 +1911,8 @@
 	}
 
 	/* last_soc < soc  ... scale and catch up */
-	if (last_soc != -EINVAL && last_soc < soc && soc != 100)
+	if (last_soc != -EINVAL && last_soc < soc && soc != 100
+				&& chip->catch_up_time_us != 0)
 		soc = scale_soc_while_chg(chip, delta_time_us, soc, last_soc);
 
 	last_soc = soc;
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 8a36d6c..cb6b23e 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -87,6 +87,7 @@
 #define EOC_CHECK_PERIOD_MS	10000
 /* check for USB unplug every 200 msecs */
 #define UNPLUG_CHECK_WAIT_PERIOD_MS 200
+#define USB_TRIM_ENTRIES 16
 
 enum chg_fsm_state {
 	FSM_STATE_OFF_0 = 0,
@@ -209,7 +210,6 @@
  * @dc_present:			present status of dc
  * @usb_charger_current:	usb current to charge the battery with used when
  *				the usb path is enabled or charging is resumed
- * @safety_time:		max time for which charging will happen
  * @update_time:		how frequently the userland needs to be updated
  * @max_voltage_mv:		the max volts the batt should be charged up to
  * @min_voltage_mv:		the min battery voltage before turning the FETon
@@ -230,12 +230,12 @@
 	unsigned int			usb_charger_current;
 	unsigned int			max_bat_chg_current;
 	unsigned int			pmic_chg_irq[PM_CHG_MAX_INTS];
-	unsigned int			safety_time;
 	unsigned int			ttrkl_time;
 	unsigned int			update_time;
 	unsigned int			max_voltage_mv;
 	unsigned int			min_voltage_mv;
 	unsigned int			uvd_voltage_mv;
+	unsigned int			safe_current_ma;
 	unsigned int			alarm_low_mv;
 	unsigned int			alarm_high_mv;
 	int				cool_temp_dc;
@@ -259,6 +259,7 @@
 	struct power_supply		batt_psy;
 	struct dentry			*dent;
 	struct bms_notify		bms_notify;
+	int				*usb_trim_table;
 	bool				keep_btm_on_suspend;
 	bool				ext_charging;
 	bool				ext_charge_done;
@@ -709,6 +710,46 @@
 	u8	value;
 };
 
+/* USB Trim tables */
+static int usb_trim_8038_table[USB_TRIM_ENTRIES] = {
+	0x0,
+	0x0,
+	-0x9,
+	0x0,
+	-0xD,
+	0x0,
+	-0x10,
+	-0x11,
+	0x0,
+	0x0,
+	-0x25,
+	0x0,
+	-0x28,
+	0x0,
+	-0x32,
+	0x0
+};
+
+static int usb_trim_8917_table[USB_TRIM_ENTRIES] = {
+	0x0,
+	0x0,
+	0xA,
+	0xC,
+	0x10,
+	0x10,
+	0x13,
+	0x14,
+	0x13,
+	0x16,
+	0x1A,
+	0x1D,
+	0x1D,
+	0x21,
+	0x24,
+	0x26
+};
+
+/* Maximum USB  setting table */
 static struct usb_ma_limit_entry usb_ma_table[] = {
 	{100, 0x0},
 	{200, 0x1},
@@ -728,18 +769,92 @@
 	{1600, 0xF},
 };
 
+#define REG_SBI_CONFIG		0x04F
+#define PAGE3_ENABLE_MASK	0x6
+#define USB_OVP_TRIM_MASK	0x3F
+#define USB_OVP_TRIM_MIN	0x00
+#define REG_USB_OVP_TRIM_ORIG_LSB	0x10A
+#define REG_USB_OVP_TRIM_ORIG_MSB	0x09C
+static int pm_chg_usb_trim(struct pm8921_chg_chip *chip, int index)
+{
+	u8 temp, sbi_config, msb, lsb;
+	s8 trim;
+	int rc = 0;
+	static u8 usb_trim_reg_orig = 0xFF;
+
+	/* No trim data for PM8921 */
+	if (!chip->usb_trim_table)
+		return 0;
+
+	if (usb_trim_reg_orig == 0xFF) {
+		rc = pm8xxx_readb(chip->dev->parent,
+				REG_USB_OVP_TRIM_ORIG_MSB, &msb);
+		if (rc) {
+			pr_err("error = %d reading sbi config reg\n", rc);
+			return rc;
+		}
+
+		rc = pm8xxx_readb(chip->dev->parent,
+				REG_USB_OVP_TRIM_ORIG_LSB, &lsb);
+		if (rc) {
+			pr_err("error = %d reading sbi config reg\n", rc);
+			return rc;
+		}
+
+		msb = msb >> 5;
+		lsb = lsb >> 5;
+		usb_trim_reg_orig = msb << 3 | lsb;
+	}
+
+	/* use the original trim value */
+	trim = usb_trim_reg_orig;
+
+	trim += chip->usb_trim_table[index];
+	if (trim < 0)
+		trim = 0;
+
+	pr_err("trim_orig %d write 0x%x index=%d value 0x%x to USB_OVP_TRIM\n",
+		usb_trim_reg_orig, trim, index, chip->usb_trim_table[index]);
+
+	rc = pm8xxx_readb(chip->dev->parent, REG_SBI_CONFIG, &sbi_config);
+	if (rc) {
+		pr_err("error = %d reading sbi config reg\n", rc);
+		return rc;
+	}
+
+	temp = sbi_config | PAGE3_ENABLE_MASK;
+	rc = pm8xxx_writeb(chip->dev->parent, REG_SBI_CONFIG, temp);
+	if (rc) {
+		pr_err("error = %d writing sbi config reg\n", rc);
+		return rc;
+	}
+
+	rc = pm_chg_masked_write(chip, USB_OVP_TRIM, USB_OVP_TRIM_MASK, trim);
+	if (rc) {
+		pr_err("error = %d writing USB_OVP_TRIM\n", rc);
+		return rc;
+	}
+
+	rc = pm8xxx_writeb(chip->dev->parent, REG_SBI_CONFIG, sbi_config);
+	if (rc) {
+		pr_err("error = %d writing sbi config reg\n", rc);
+		return rc;
+	}
+	return rc;
+}
+
 #define PM8921_CHG_IUSB_MASK 0x1C
 #define PM8921_CHG_IUSB_SHIFT 2
 #define PM8921_CHG_IUSB_MAX  7
 #define PM8921_CHG_IUSB_MIN  0
 #define PM8917_IUSB_FINE_RES BIT(0)
-static int pm_chg_iusbmax_set(struct pm8921_chg_chip *chip, int reg_val)
+static int pm_chg_iusbmax_set(struct pm8921_chg_chip *chip, int index)
 {
-	u8 temp, fineres;
+	u8 temp, fineres, reg_val;
 	int rc;
 
-	fineres = PM8917_IUSB_FINE_RES & usb_ma_table[reg_val].value;
-	reg_val = usb_ma_table[reg_val].value >> 1;
+	reg_val = usb_ma_table[index].value >> 1;
+	fineres = PM8917_IUSB_FINE_RES & usb_ma_table[index].value;
 
 	if (reg_val < PM8921_CHG_IUSB_MIN || reg_val > PM8921_CHG_IUSB_MAX) {
 		pr_err("bad mA=%d asked to set\n", reg_val);
@@ -764,17 +879,25 @@
 		if (fineres) {
 			rc = pm_chg_masked_write(chip, IUSB_FINE_RES,
 				PM8917_IUSB_FINE_RES, fineres);
-			if (rc)
+			if (rc) {
 				pr_err("Failed to write ISUB_FINE_RES rc=%d\n",
 					rc);
+				return rc;
+			}
 		}
 	} else {
 		rc = pm_chg_masked_write(chip, PBL_ACCESS2,
 			PM8921_CHG_IUSB_MASK, temp);
-		if (rc)
+		if (rc) {
 			pr_err("Failed to write PBL_ACCESS2 rc=%d\n", rc);
+			return rc;
+		}
 	}
 
+	rc = pm_chg_usb_trim(chip, index);
+	if (rc)
+			pr_err("unable to set usb trim rc = %d\n", rc);
+
 	return rc;
 }
 
@@ -1717,9 +1840,8 @@
 		if (i < 0)
 			i = 0;
 		rc = pm_chg_iusbmax_set(the_chip, i);
-		if (rc) {
+		if (rc)
 			pr_err("unable to set iusb to %d rc = %d\n", i, rc);
-		}
 	}
 }
 
@@ -2691,8 +2813,8 @@
 			goto check_again_later;
 		}
 	}
-
-	if (active_path & USB_ACTIVE_BIT) {
+	/* AICL only for usb wall charger */
+	if ((active_path & USB_ACTIVE_BIT) && usb_target_ma > 0) {
 		reg_loop = pm_chg_get_regulation_loop(chip);
 		pr_debug("reg_loop=0x%x usb_ma = %d\n", reg_loop, usb_ma);
 		if ((reg_loop & VIN_ACTIVE_BIT) &&
@@ -2737,7 +2859,9 @@
 		unplug_ovp_fet_open(chip);
 	}
 
+	/* AICL only for usb wall charger */
 	if (!(reg_loop & VIN_ACTIVE_BIT) && (active_path & USB_ACTIVE_BIT)
+		&& usb_target_ma > 0
 		&& !charging_disabled) {
 		/* only increase iusb_max if vin loop not active */
 		if (usb_ma < usb_target_ma) {
@@ -3551,6 +3675,12 @@
 			chip->dc_present,
 			get_prop_batt_present(chip),
 			fsm_state);
+
+	/* Determine which USB trim column to use */
+	if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8917)
+		chip->usb_trim_table = usb_trim_8917_table;
+	else if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8038)
+		chip->usb_trim_table = usb_trim_8038_table;
 }
 
 struct pm_chg_irq_init_data {
@@ -3757,11 +3887,15 @@
 #define CHG_BAT_TEMP_DIS_BIT	BIT(2)
 #define SAFE_CURRENT_MA		1500
 #define PM_SUB_REV		0x001
+#define MIN_CHARGE_CURRENT_MA	350
+#define DEFAULT_SAFETY_MINUTES	500
 static int __devinit pm8921_chg_hw_init(struct pm8921_chg_chip *chip)
 {
 	int rc;
 	int vdd_safe;
 	u8 subrev;
+	int fcc_uah;
+	int safety_time = DEFAULT_SAFETY_MINUTES;
 
 	/* forcing 19p2mhz before accessing any charger registers */
 	pm8921_chg_force_19p2mhz_clk(chip);
@@ -3802,7 +3936,11 @@
 						chip->max_voltage_mv, rc);
 		return rc;
 	}
-	rc = pm_chg_ibatsafe_set(chip, SAFE_CURRENT_MA);
+
+	if (chip->safe_current_ma == 0)
+		chip->safe_current_ma = SAFE_CURRENT_MA;
+
+	rc = pm_chg_ibatsafe_set(chip, chip->safe_current_ma);
 	if (rc) {
 		pr_err("Failed to set max voltage to %d rc=%d\n",
 						SAFE_CURRENT_MA, rc);
@@ -3830,20 +3968,26 @@
 		return rc;
 	}
 
-	if (chip->safety_time != 0) {
-		rc = pm_chg_tchg_max_set(chip, chip->safety_time);
-		if (rc) {
-			pr_err("Failed to set max time to %d minutes rc=%d\n",
-							chip->safety_time, rc);
-			return rc;
-		}
+	fcc_uah = pm8921_bms_get_fcc();
+	if (fcc_uah > 0) {
+		safety_time = div_s64((s64)fcc_uah * 60,
+						1000 * MIN_CHARGE_CURRENT_MA);
+		/* add 20 minutes of buffer time */
+		safety_time += 20;
+	}
+
+	rc = pm_chg_tchg_max_set(chip, safety_time);
+	if (rc) {
+		pr_err("Failed to set max time to %d minutes rc=%d\n",
+						safety_time, rc);
+		return rc;
 	}
 
 	if (chip->ttrkl_time != 0) {
 		rc = pm_chg_ttrkl_max_set(chip, chip->ttrkl_time);
 		if (rc) {
 			pr_err("Failed to set trkl time to %d minutes rc=%d\n",
-							chip->safety_time, rc);
+							chip->ttrkl_time, rc);
 			return rc;
 		}
 	}
@@ -4249,13 +4393,13 @@
 	}
 
 	chip->dev = &pdev->dev;
-	chip->safety_time = pdata->safety_time;
 	chip->ttrkl_time = pdata->ttrkl_time;
 	chip->update_time = pdata->update_time;
 	chip->max_voltage_mv = pdata->max_voltage;
 	chip->alarm_low_mv = pdata->alarm_low_mv;
 	chip->alarm_high_mv = pdata->alarm_high_mv;
 	chip->min_voltage_mv = pdata->min_voltage;
+	chip->safe_current_ma = pdata->safe_current_ma;
 	chip->uvd_voltage_mv = pdata->uvd_thresh_voltage;
 	chip->resume_voltage_delta = pdata->resume_voltage_delta;
 	chip->resume_charge_percent = pdata->resume_charge_percent;
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 7efe40d..9c69f47 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -619,6 +619,7 @@
 		u16 chh[40];
 		struct slim_ch prop;
 		u32 exp;
+		u16 *grph = NULL;
 		u8 coeff, cc;
 		u8 prrate = buf[6];
 		if (len <= 8)
@@ -639,6 +640,9 @@
 					return ret;
 				if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
 					sat->satch[j].req_def++;
+				/* First channel in group from satellite */
+				if (i == 8)
+					grph = &sat->satch[j].chanh;
 				continue;
 			}
 			if (sat->nsatch >= MSM_MAX_SATCH)
@@ -650,6 +654,8 @@
 			sat->satch[j].chanh = chh[i - 8];
 			if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
 				sat->satch[j].req_def++;
+			if (i == 8)
+				grph = &sat->satch[j].chanh;
 			sat->nsatch++;
 		}
 		prop.dataf = (enum slim_ch_dataf)((buf[3] & 0xE0) >> 5);
@@ -670,10 +676,12 @@
 					true, &chh[0]);
 		else
 			ret = slim_define_ch(&sat->satcl, &prop,
-					&chh[0], 1, false, NULL);
+					chh, 1, true, &chh[0]);
 		dev_dbg(dev->dev, "define sat grp returned:%d", ret);
 		if (ret)
 			return ret;
+		else if (grph)
+			*grph = chh[0];
 
 		/* part of group so activating 1 will take care of rest */
 		if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
@@ -806,6 +814,8 @@
 						slim_control_ch(&sat->satcl,
 							sat->satch[i].chanh,
 							SLIM_CH_REMOVE, true);
+						slim_dealloc_ch(&sat->satcl,
+							sat->satch[i].chanh);
 						sat->satch[i].reconf = false;
 					}
 				}
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 1e79dce..d5d6e0c 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -26,6 +26,7 @@
 #define SLIM_HDL_TO_PORT(hdl)	((u32)(hdl) & 0xFF)
 
 #define SLIM_HDL_TO_CHIDX(hdl)	((u16)(hdl) & 0xFF)
+#define SLIM_GRP_TO_NCHAN(hdl)	((u16)(hdl >> 8) & 0xFF)
 
 #define SLIM_SLAVE_PORT(p, la)	(((la)<<16) | (p))
 #define SLIM_MGR_PORT(p)	((0xFF << 16) | (p))
@@ -767,6 +768,7 @@
 	list_for_each_entry(sbdev, &ctrl->devs, dev_list) {
 		if (memcmp(sbdev->e_addr, e_addr, 6) == 0) {
 			struct slim_driver *sbdrv;
+			sbdev->laddr = *laddr;
 			if (sbdev->dev.driver) {
 				sbdrv = to_slim_driver(sbdev->dev.driver);
 				if (sbdrv->device_up)
@@ -1845,7 +1847,7 @@
 	}
 
 	if (grp)
-		*grph = chanh[0];
+		*grph = ((nchan << 8) | SLIM_HDL_TO_CHIDX(chanh[0]));
 	for (i = 0; i < nchan; i++) {
 		u8 chan = SLIM_HDL_TO_CHIDX(chanh[i]);
 		struct slim_ich *slc = &ctrl->chans[chan];
@@ -2868,6 +2870,7 @@
 	int ret = 0;
 	/* Get rid of the group flag in MSB if any */
 	u8 chan = SLIM_HDL_TO_CHIDX(chanh);
+	u8 nchan = 0;
 	struct slim_ich *slc = &ctrl->chans[chan];
 	if (!(slc->nextgrp & SLIM_START_GRP))
 		return -EINVAL;
@@ -2928,9 +2931,10 @@
 			}
 		}
 
-		if (!(slc->nextgrp & SLIM_END_GRP))
+		nchan++;
+		if (nchan < SLIM_GRP_TO_NCHAN(chanh))
 			chan = SLIM_HDL_TO_CHIDX(slc->nextgrp);
-	} while (!(slc->nextgrp & SLIM_END_GRP));
+	} while (nchan < SLIM_GRP_TO_NCHAN(chanh));
 	mutex_unlock(&ctrl->m_ctrl);
 	if (!ret && commit == true)
 		ret = slim_reconfigure_now(sb);
diff --git a/drivers/thermal/msm8974-tsens.c b/drivers/thermal/msm8974-tsens.c
index 8e13fbf..4cb93b8 100644
--- a/drivers/thermal/msm8974-tsens.c
+++ b/drivers/thermal/msm8974-tsens.c
@@ -558,6 +558,7 @@
 	int tsens9_point2 = 0, tsens10_point2 = 0;
 	int tsens_base2_data = 0, tsens_calibration_mode = 0, temp = 0;
 	uint32_t calib_data[6], calib_redun_sel, calib_data_backup[4];
+	uint32_t calib_tsens_point1_data[11], calib_tsens_point2_data[11];
 
 	if (tmdev->calibration_less_mode)
 		goto calibration_less_mode;
@@ -619,45 +620,46 @@
 			tsens10_point1 = (calib_data_backup[2] &
 				TSENS10_POINT1_MASK_BACKUP) >>
 				TSENS10_POINT1_BACKUP_SHIFT;
-	} else if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
-		pr_debug("backup two point calibrationless mode\n");
-		tsens_base2_data = (calib_data_backup[2] &
+		} else
+			goto calibration_less_mode;
+
+		if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
+			pr_debug("backup two point calibrationless mode\n");
+			tsens_base2_data = (calib_data_backup[2] &
 				TSENS_BASE2_BACKUP_MASK) >>
 				TSENS_POINT2_BASE_BACKUP_SHIFT;
-		tsens0_point2 = (calib_data_backup[2] &
+			tsens0_point2 = (calib_data_backup[2] &
 					TSENS0_POINT2_BACKUP_MASK) >>
 					TSENS0_POINT2_BACKUP_SHIFT;
-		tsens1_point2 = (calib_data_backup[3] &
+			tsens1_point2 = (calib_data_backup[3] &
 					TSENS1_POINT2_BACKUP_MASK);
-		tsens2_point2 = (calib_data_backup[3] &
+			tsens2_point2 = (calib_data_backup[3] &
 					TSENS2_POINT2_BACKUP_MASK) >>
 					TSENS2_POINT2_BACKUP_SHIFT;
-		tsens3_point2 = (calib_data_backup[3] &
+			tsens3_point2 = (calib_data_backup[3] &
 					TSENS3_POINT2_BACKUP_MASK) >>
 					TSENS3_POINT2_BACKUP_SHIFT;
-		tsens4_point2 = (calib_data_backup[3] &
+			tsens4_point2 = (calib_data_backup[3] &
 					TSENS4_POINT2_BACKUP_MASK) >>
 					TSENS4_POINT2_BACKUP_SHIFT;
-		tsens5_point2 = (calib_data[4] & TSENS5_POINT2_BACKUP_MASK) >>
-						TSENS5_POINT2_BACKUP_SHIFT;
-		tsens6_point2 = (calib_data[5] & TSENS6_POINT2_BACKUP_MASK);
-		tsens7_point2 = (calib_data[5] & TSENS7_POINT2_BACKUP_MASK) >>
-						TSENS7_POINT2_BACKUP_SHIFT;
-		tsens8_point2 = (calib_data[5] & TSENS8_POINT2_BACKUP_MASK) >>
-						TSENS8_POINT2_BACKUP_SHIFT;
-		tsens9_point2 = (calib_data[5] & TSENS9_POINT2_BACKUP_MASK) >>
-						TSENS9_POINT2_BACKUP_SHIFT;
-		tsens10_point2 = (calib_data[5] & TSENS10_POINT2_BACKUP_MASK)
-						>> TSENS10_POINT2_BACKUP_SHIFT;
-	} else {
-		pr_debug("TSENS:backup is calibrationless mode\n");
-		for (i = 0; i < tmdev->tsens_num_sensor; i++) {
-			tmdev->sensor[i].calib_data_point2 = 780;
-			tmdev->sensor[i].calib_data_point1 = 492;
+			tsens5_point2 = (calib_data[4] &
+					TSENS5_POINT2_BACKUP_MASK) >>
+					TSENS5_POINT2_BACKUP_SHIFT;
+			tsens6_point2 = (calib_data[5] &
+					TSENS6_POINT2_BACKUP_MASK);
+			tsens7_point2 = (calib_data[5] &
+					TSENS7_POINT2_BACKUP_MASK) >>
+					TSENS7_POINT2_BACKUP_SHIFT;
+			tsens8_point2 = (calib_data[5] &
+					TSENS8_POINT2_BACKUP_MASK) >>
+					TSENS8_POINT2_BACKUP_SHIFT;
+			tsens9_point2 = (calib_data[5] &
+					TSENS9_POINT2_BACKUP_MASK) >>
+					TSENS9_POINT2_BACKUP_SHIFT;
+			tsens10_point2 = (calib_data[5] &
+					TSENS10_POINT2_BACKUP_MASK)
+					>> TSENS10_POINT2_BACKUP_SHIFT;
 		}
-		tsens_calibration_mode = 0;
-		goto compute_intercept_slope;
-	}
 	} else {
 		tsens_calibration_mode = (calib_data[1] & TSENS_CAL_SEL_0_1)
 			>> TSENS_CAL_SEL_SHIFT;
@@ -690,7 +692,10 @@
 			tsens9_point1 = (calib_data[2] & TSENS9_POINT1_MASK);
 			tsens10_point1 = (calib_data[2] & TSENS10_POINT1_MASK)
 							>> TSENS10_POINT1_SHIFT;
-		} else if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
+		} else
+			goto calibration_less_mode;
+
+		if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
 			pr_debug("TSENS is two point calibrationless mode\n");
 			tsens_base2_data = (calib_data[2] & TSENS_BASE2_MASK) >>
 						TSENS_POINT2_BASE_SHIFT;
@@ -714,120 +719,145 @@
 						TSENS9_POINT2_SHIFT;
 			tsens10_point2 = (calib_data[4] & TSENS10_POINT2_MASK)
 						>> TSENS10_POINT2_SHIFT;
-		} else {
+		}
+
+		if (tsens_calibration_mode == 0) {
 calibration_less_mode:
 			pr_debug("TSENS is calibrationless mode\n");
 			for (i = 0; i < tmdev->tsens_num_sensor; i++)
-				tmdev->sensor[i].calib_data_point2 = 780;
-			tmdev->sensor[0].calib_data_point1 = 502;
-			tmdev->sensor[1].calib_data_point1 = 509;
-			tmdev->sensor[2].calib_data_point1 = 503;
-			tmdev->sensor[3].calib_data_point1 = 509;
-			tmdev->sensor[4].calib_data_point1 = 505;
-			tmdev->sensor[5].calib_data_point1 = 509;
-			tmdev->sensor[6].calib_data_point1 = 507;
-			tmdev->sensor[7].calib_data_point1 = 510;
-			tmdev->sensor[8].calib_data_point1 = 508;
-			tmdev->sensor[9].calib_data_point1 = 509;
-			tmdev->sensor[10].calib_data_point1 = 508;
+				calib_tsens_point2_data[i] = 780;
+			calib_tsens_point1_data[0] = 502;
+			calib_tsens_point1_data[1] = 509;
+			calib_tsens_point1_data[2] = 503;
+			calib_tsens_point1_data[3] = 509;
+			calib_tsens_point1_data[4] = 505;
+			calib_tsens_point1_data[5] = 509;
+			calib_tsens_point1_data[6] = 507;
+			calib_tsens_point1_data[7] = 510;
+			calib_tsens_point1_data[8] = 508;
+			calib_tsens_point1_data[9] = 509;
+			calib_tsens_point1_data[10] = 508;
 			goto compute_intercept_slope;
 		}
 	}
 
 	if (tsens_calibration_mode == TSENS_ONE_POINT_CALIB) {
 		pr_debug("old one point calibration calculation\n");
-		tmdev->sensor[0].calib_data_point1 =
-		(((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens0_point1;
-		tmdev->sensor[1].calib_data_point1 =
-		(((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens1_point1;
-		tmdev->sensor[2].calib_data_point1 =
-		(((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens2_point1;
-		tmdev->sensor[3].calib_data_point1 =
-		(((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens3_point1;
-		tmdev->sensor[4].calib_data_point1 =
-		(((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens4_point1;
-		tmdev->sensor[5].calib_data_point1 =
-		(((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens5_point1;
-		tmdev->sensor[6].calib_data_point1 =
-		(((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens6_point1;
-		tmdev->sensor[7].calib_data_point1 =
-		(((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens7_point1;
-		tmdev->sensor[8].calib_data_point1 =
-		(((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens8_point1;
-		tmdev->sensor[9].calib_data_point1 =
-		(((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens9_point1;
-		tmdev->sensor[10].calib_data_point1 =
-		(((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens10_point1;
+		calib_tsens_point1_data[0] =
+			(((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+							+ tsens0_point1;
+		calib_tsens_point1_data[1] =
+			(((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+							+ tsens1_point1;
+		calib_tsens_point1_data[2] =
+			(((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+							+ tsens2_point1;
+		calib_tsens_point1_data[3] =
+			(((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+							+ tsens3_point1;
+		calib_tsens_point1_data[4] =
+			(((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+							+ tsens4_point1;
+		calib_tsens_point1_data[5] =
+			(((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+							+ tsens5_point1;
+		calib_tsens_point1_data[6] =
+			(((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+							+ tsens6_point1;
+		calib_tsens_point1_data[7] =
+			(((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+							+ tsens7_point1;
+		calib_tsens_point1_data[8] =
+			(((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+							+ tsens8_point1;
+		calib_tsens_point1_data[9] =
+			(((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+							+ tsens9_point1;
+		calib_tsens_point1_data[10] =
+			(((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+							+ tsens10_point1;
 	}
 
 	if ((tsens_calibration_mode == TSENS_ONE_POINT_CALIB_OPTION_2) ||
 			(tsens_calibration_mode == TSENS_TWO_POINT_CALIB)) {
 		pr_debug("one and two point calibration calculation\n");
-
-		tmdev->sensor[0].calib_data_point1 =
-		((((tsens_base1_data) + tsens0_point1) << 2) |
+		calib_tsens_point1_data[0] =
+			((((tsens_base1_data) + tsens0_point1) << 2) |
 						TSENS_BIT_APPEND);
-		tmdev->sensor[1].calib_data_point1 =
-		((((tsens_base1_data) + tsens1_point1) << 2) |
+		calib_tsens_point1_data[1] =
+			((((tsens_base1_data) + tsens1_point1) << 2) |
 						TSENS_BIT_APPEND);
-		tmdev->sensor[2].calib_data_point1 =
-		((((tsens_base1_data) + tsens2_point1) << 2) |
+		calib_tsens_point1_data[2] =
+			((((tsens_base1_data) + tsens2_point1) << 2) |
 						TSENS_BIT_APPEND);
-		tmdev->sensor[3].calib_data_point1 =
-		((((tsens_base1_data) + tsens3_point1) << 2) |
+		calib_tsens_point1_data[3] =
+			((((tsens_base1_data) + tsens3_point1) << 2) |
 						TSENS_BIT_APPEND);
-		tmdev->sensor[4].calib_data_point1 =
-		((((tsens_base1_data) + tsens4_point1) << 2) |
+		calib_tsens_point1_data[4] =
+			((((tsens_base1_data) + tsens4_point1) << 2) |
 						TSENS_BIT_APPEND);
-		tmdev->sensor[5].calib_data_point1 =
-		((((tsens_base1_data) + tsens5_point1) << 2) |
+		calib_tsens_point1_data[5] =
+			((((tsens_base1_data) + tsens5_point1) << 2) |
 						TSENS_BIT_APPEND);
-		tmdev->sensor[6].calib_data_point1 =
-		((((tsens_base1_data) + tsens6_point1) << 2) |
+		calib_tsens_point1_data[6] =
+			((((tsens_base1_data) + tsens6_point1) << 2) |
 						TSENS_BIT_APPEND);
-		tmdev->sensor[7].calib_data_point1 =
-		((((tsens_base1_data) + tsens7_point1) << 2) |
+		calib_tsens_point1_data[7] =
+			((((tsens_base1_data) + tsens7_point1) << 2) |
 						TSENS_BIT_APPEND);
-		tmdev->sensor[8].calib_data_point1 =
-		((((tsens_base1_data) + tsens8_point1) << 2) |
+		calib_tsens_point1_data[8] =
+			((((tsens_base1_data) + tsens8_point1) << 2) |
 						TSENS_BIT_APPEND);
-		tmdev->sensor[9].calib_data_point1 =
-		((((tsens_base1_data) + tsens9_point1) << 2) |
+		calib_tsens_point1_data[9] =
+			((((tsens_base1_data) + tsens9_point1) << 2) |
 						TSENS_BIT_APPEND);
-		tmdev->sensor[10].calib_data_point1 =
-		((((tsens_base1_data) + tsens10_point1) << 2) |
+		calib_tsens_point1_data[10] =
+			((((tsens_base1_data) + tsens10_point1) << 2) |
 						TSENS_BIT_APPEND);
 	}
 
 	if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
 		pr_debug("two point calibration calculation\n");
-		tmdev->sensor[0].calib_data_point2 =
-		(((tsens_base2_data + tsens0_point2) << 2) | TSENS_BIT_APPEND);
-		tmdev->sensor[1].calib_data_point2 =
-		(((tsens_base2_data + tsens1_point2) << 2) | TSENS_BIT_APPEND);
-		tmdev->sensor[2].calib_data_point2 =
-		(((tsens_base2_data + tsens2_point2) << 2) | TSENS_BIT_APPEND);
-		tmdev->sensor[3].calib_data_point2 =
-		(((tsens_base2_data + tsens3_point2) << 2) | TSENS_BIT_APPEND);
-		tmdev->sensor[4].calib_data_point2 =
-		(((tsens_base2_data + tsens4_point2) << 2) | TSENS_BIT_APPEND);
-		tmdev->sensor[5].calib_data_point2 =
-		(((tsens_base2_data + tsens5_point2) << 2) | TSENS_BIT_APPEND);
-		tmdev->sensor[6].calib_data_point2 =
-		(((tsens_base2_data + tsens6_point2) << 2) | TSENS_BIT_APPEND);
-		tmdev->sensor[7].calib_data_point2 =
-		(((tsens_base2_data + tsens7_point2) << 2) | TSENS_BIT_APPEND);
-		tmdev->sensor[8].calib_data_point2 =
-		(((tsens_base2_data + tsens8_point2) << 2) | TSENS_BIT_APPEND);
-		tmdev->sensor[9].calib_data_point2 =
-		(((tsens_base2_data + tsens9_point2) << 2) | TSENS_BIT_APPEND);
-		tmdev->sensor[10].calib_data_point2 =
-		(((tsens_base2_data + tsens10_point2) << 2) | TSENS_BIT_APPEND);
+		calib_tsens_point2_data[0] =
+			(((tsens_base2_data + tsens0_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[1] =
+			(((tsens_base2_data + tsens1_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[2] =
+			(((tsens_base2_data + tsens2_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[3] =
+			(((tsens_base2_data + tsens3_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[4] =
+			(((tsens_base2_data + tsens4_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[5] =
+			(((tsens_base2_data + tsens5_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[6] =
+			(((tsens_base2_data + tsens6_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[7] =
+			(((tsens_base2_data + tsens7_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[8] =
+			(((tsens_base2_data + tsens8_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[9] =
+			(((tsens_base2_data + tsens9_point2) << 2) |
+					TSENS_BIT_APPEND);
+		calib_tsens_point2_data[10] =
+			(((tsens_base2_data + tsens10_point2) << 2) |
+					TSENS_BIT_APPEND);
 	}
 
 compute_intercept_slope:
 	for (i = 0; i < tmdev->tsens_num_sensor; i++) {
 		int32_t num = 0, den = 0;
+		tmdev->sensor[i].calib_data_point2 = calib_tsens_point2_data[i];
+		tmdev->sensor[i].calib_data_point1 = calib_tsens_point1_data[i];
 		if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
 			num = TSENS_CAL_DEGC_POINT2 - TSENS_CAL_DEGC_POINT2;
 			den = tmdev->sensor[i].calib_data_point2 -
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 98eb0a0..4073fc8 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1262,6 +1262,17 @@
 	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG,
 						0xC00000, 0x800000);
 
+	/* Sequence to put SSPHY in low power state:
+	 * 1. Clear REF_SS_PHY_EN in SS_PHY_CTRL_REG
+	 * 2. Clear REF_USE_PAD in SS_PHY_CTRL_REG
+	 * 3. Set TEST_POWERED_DOWN in SS_PHY_CTRL_REG to enable PHY retention
+	 * 4. Disable SSPHY ref clk
+	 */
+	dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 8), 0x0);
+	dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 28), 0x0);
+	dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 26),
+								(1 << 26));
+
 	usleep_range(1000, 1200);
 	clk_disable_unprepare(mdwc->ref_clk);
 
@@ -1346,14 +1357,26 @@
 
 	dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0),
 	      dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)) | 0xF0000000);
-	/* 20usec delay required before de-asserting PHY RESET */
-	udelay(20);
+	/* 10usec delay required before de-asserting PHY RESET */
+	udelay(10);
 	dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0),
 	      dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)) & 0x7FFFFFFF);
 
 	/* Bring PHY out of suspend */
 	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0xC00000, 0x0);
 
+	/* Assert SS PHY RESET */
+	dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 7),
+								(1 << 7));
+	dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 28),
+								(1 << 28));
+	dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 8),
+								(1 << 8));
+	dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 26), 0x0);
+	/* 10usec delay required before de-asserting SS PHY RESET */
+	udelay(10);
+	dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 7), 0x0);
+
 	atomic_set(&mdwc->in_lpm, 0);
 
 	/* match disable_irq call from isr */
@@ -1745,7 +1768,9 @@
 	}
 
 	msm->ext_xceiv.otg_capability = of_property_read_bool(node,
-				"qcom,dwc-usb3-msm-otg-capability");
+				"qcom,otg-capability");
+	msm->charger.charging_disabled = of_property_read_bool(node,
+				"qcom,charging-disabled");
 
 	if (!msm->ext_xceiv.otg_capability) {
 		/* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index 41dd144..7b672c4 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -393,11 +393,14 @@
 	struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg);
 
 
-	if (!dotg->psy) {
-		dev_err(phy->dev, "no usb power supply registered\n");
+	if (!dotg->psy || !dotg->charger) {
+		dev_err(phy->dev, "no usb power supply/charger registered\n");
 		return 0;
 	}
 
+	if (dotg->charger->charging_disabled)
+		return 0;
+
 	if (dotg->charger->chg_type == DWC3_SDP_CHARGER)
 		power_supply_type = POWER_SUPPLY_TYPE_USB;
 	else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
diff --git a/drivers/usb/dwc3/dwc3_otg.h b/drivers/usb/dwc3/dwc3_otg.h
index 4384888..c93ce5f 100644
--- a/drivers/usb/dwc3/dwc3_otg.h
+++ b/drivers/usb/dwc3/dwc3_otg.h
@@ -70,6 +70,7 @@
 struct dwc3_charger {
 	enum dwc3_chg_type	chg_type;
 	unsigned		max_power;
+	bool			charging_disabled;
 
 	/* start/stop charger detection, provided by external charger module */
 	void	(*start_detection)(struct dwc3_charger *charger, bool start);
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 5fb2370..b773d1a 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -24,6 +24,7 @@
 #include <linux/utsname.h>
 #include <linux/platform_device.h>
 #include <linux/pm_qos.h>
+#include <linux/of.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/composite.h>
@@ -2409,11 +2410,26 @@
 
 static int __devinit android_probe(struct platform_device *pdev)
 {
-	struct android_usb_platform_data *pdata = pdev->dev.platform_data;
+	struct android_usb_platform_data *pdata;
 	struct android_dev *android_dev;
 	struct resource *res;
 	int ret = 0;
 
+	if (pdev->dev.of_node) {
+		dev_dbg(&pdev->dev, "device tree enabled\n");
+		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+		if (!pdata) {
+			pr_err("unable to allocate platform data\n");
+			return -ENOMEM;
+		}
+
+		of_property_read_u32(pdev->dev.of_node,
+				"qcom,android-usb-swfi-latency",
+				&pdata->swfi_latency);
+	} else {
+		pdata = pdev->dev.platform_data;
+	}
+
 	if (!android_class) {
 		android_class = class_create(THIS_MODULE, "android_usb");
 		if (IS_ERR(android_class))
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 92cbe6f..d10c692 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -3068,10 +3068,9 @@
 {
 	static bool init;
 	struct msm_otg *motg = the_msm_otg;
-	struct usb_otg *otg = motg->phy.otg;
 
-	/* In A Host Mode, ignore received BSV interrupts */
-	if (otg->phy->state >= OTG_STATE_A_IDLE)
+	/* Ignore received BSV interrupts, if ID pin is GND */
+	if (!test_bit(ID, &motg->inputs))
 		return;
 
 	if (online) {
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 25da094..985d0b0 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -2528,8 +2528,6 @@
 #if defined(CONFIG_FB_MSM_MIPI_DSI) && defined(CONFIG_FB_MSM_MDP40)
 	struct mipi_panel_info *mipi;
 #endif
-	static int contSplash_update_done;
-	char *cp;
 	unsigned int mdp_r = 0;
 
 	if ((pdev->id == 0) && (pdev->num_resources > 0)) {
@@ -2613,57 +2611,6 @@
 	mfd->pdev = msm_fb_dev;
 	mfd->mdp_rev = mdp_rev;
 
-	if (mdp_pdata) {
-		if (mdp_pdata->cont_splash_enabled) {
-			mfd->cont_splash_done = 0;
-
-			if (!contSplash_update_done) {
-				uint32 bpp = 3;
-				/*read panel wxh and calculate splash screen
-				size*/
-				mdp_pdata->splash_screen_size =
-						inpdw(MDP_BASE + 0x90004);
-				mdp_pdata->splash_screen_size =
-				(((mdp_pdata->splash_screen_size >> 16) &
-					0x00000FFF) * (
-					mdp_pdata->splash_screen_size &
-					0x00000FFF)) * bpp;
-
-				mdp_pdata->splash_screen_addr =
-						inpdw(MDP_BASE + 0x90008);
-
-				mfd->copy_splash_buf = dma_alloc_coherent(NULL,
-					mdp_pdata->splash_screen_size,
-					(dma_addr_t *) &(mfd->copy_splash_phys),
-					GFP_KERNEL);
-
-				if (!mfd->copy_splash_buf) {
-					pr_err("DMA ALLOC FAILED for SPLASH\n");
-					return -ENOMEM;
-				}
-				cp = (char *)ioremap(
-						mdp_pdata->splash_screen_addr,
-						mdp_pdata->splash_screen_size);
-				if (!cp) {
-					pr_err("IOREMAP FAILED for SPLASH\n");
-					return -ENOMEM;
-				}
-				memcpy(mfd->copy_splash_buf, cp,
-					mdp_pdata->splash_screen_size);
-
-				MDP_OUTP(MDP_BASE + 0x90008,
-						mfd->copy_splash_phys);
-
-				if (mfd->panel.type == MIPI_VIDEO_PANEL ||
-				    mfd->panel.type == LCDC_PANEL)
-					mdp_pipe_ctrl(MDP_CMD_BLOCK,
-						MDP_BLOCK_POWER_ON, FALSE);
-				contSplash_update_done = 1;
-			}
-		} else
-			mfd->cont_splash_done = 1;
-	}
-
 	mfd->ov0_wb_buf = MDP_ALLOC(sizeof(struct mdp_buf_type));
 	mfd->ov1_wb_buf = MDP_ALLOC(sizeof(struct mdp_buf_type));
 	memset((void *)mfd->ov0_wb_buf, 0, sizeof(struct mdp_buf_type));
@@ -2694,6 +2641,53 @@
 		rc = -ENOMEM;
 		goto mdp_probe_err;
 	}
+
+	if (mdp_pdata) {
+		if (mdp_pdata->cont_splash_enabled &&
+				 mfd->panel_info.pdest == DISPLAY_1) {
+			char *cp;
+			uint32 bpp = 3;
+			/*read panel wxh and calculate splash screen
+			  size*/
+			mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+			mdp_pdata->splash_screen_size =
+				inpdw(MDP_BASE + 0x90004);
+			mdp_pdata->splash_screen_size =
+				(((mdp_pdata->splash_screen_size >> 16) &
+				  0x00000FFF) * (
+					  mdp_pdata->splash_screen_size &
+					  0x00000FFF)) * bpp;
+
+			mdp_pdata->splash_screen_addr =
+				inpdw(MDP_BASE + 0x90008);
+
+			mfd->copy_splash_buf = dma_alloc_coherent(NULL,
+					mdp_pdata->splash_screen_size,
+					(dma_addr_t *) &(mfd->copy_splash_phys),
+					GFP_KERNEL);
+
+			if (!mfd->copy_splash_buf) {
+				pr_err("DMA ALLOC FAILED for SPLASH\n");
+				return -ENOMEM;
+			}
+			cp = (char *)ioremap(
+					mdp_pdata->splash_screen_addr,
+					mdp_pdata->splash_screen_size);
+			if (!cp) {
+				pr_err("IOREMAP FAILED for SPLASH\n");
+				return -ENOMEM;
+			}
+			memcpy(mfd->copy_splash_buf, cp,
+					mdp_pdata->splash_screen_size);
+
+			MDP_OUTP(MDP_BASE + 0x90008,
+					mfd->copy_splash_phys);
+		}
+
+		mfd->cont_splash_done = (1 - mdp_pdata->cont_splash_enabled);
+	}
+
 	/* data chain */
 	pdata = msm_fb_dev->dev.platform_data;
 	pdata->on = mdp_on;
@@ -2993,7 +2987,7 @@
 	}
 
 	/* req bus bandwidth immediately */
-	if (!(mfd->cont_splash_done))
+	if (!(mfd->cont_splash_done) && (mfd->panel_info.pdest == DISPLAY_1))
 		mdp_bus_scale_update_request(5);
 
 #endif
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index d53240f..a8f853d 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/iopoll.h>
 #include <linux/of_address.h>
 #include <linux/of_gpio.h>
 #include <linux/types.h>
@@ -37,6 +38,9 @@
 #define SW_RESET BIT(2)
 #define SW_RESET_PLL BIT(0)
 
+#define HPD_DISCONNECT_POLARITY 0
+#define HPD_CONNECT_POLARITY    1
+
 #define IFRAME_CHECKSUM_32(d)			\
 	((d & 0xff) + ((d >> 8) & 0xff) +	\
 	((d >> 16) & 0xff) + ((d >> 24) & 0xff))
@@ -457,86 +461,8 @@
 	return status;
 } /* hdmi_tx_read_sink_info */
 
-static void hdmi_tx_hpd_state_work(struct work_struct *work)
-{
-	u32 hpd_state = false;
-	struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
-	struct dss_io_data *io = NULL;
-
-	hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, hpd_state_work);
-	if (!hdmi_ctrl || !hdmi_ctrl->hpd_initialized) {
-		DEV_DBG("%s: invalid input\n", __func__);
-		return;
-	}
-
-	io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
-	if (!io->base) {
-		DEV_ERR("%s: Core io is not initialized\n", __func__);
-		return;
-	}
-
-	DEV_DBG("%s: Got HPD interrupt\n", __func__);
-
-	hpd_state = (DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(1)) >> 1;
-	mutex_lock(&hdmi_ctrl->mutex);
-	if ((hdmi_ctrl->hpd_prev_state != hdmi_ctrl->hpd_state) ||
-		(hdmi_ctrl->hpd_state != hpd_state)) {
-
-		hdmi_ctrl->hpd_state = hpd_state;
-		hdmi_ctrl->hpd_prev_state = hdmi_ctrl->hpd_state;
-		hdmi_ctrl->hpd_stable = 0;
-
-		DEV_DBG("%s: state not stable yet, wait again (%d|%d|%d)\n",
-			__func__, hdmi_ctrl->hpd_prev_state,
-			hdmi_ctrl->hpd_state, hpd_state);
-
-		mutex_unlock(&hdmi_ctrl->mutex);
-
-		mod_timer(&hdmi_ctrl->hpd_state_timer, jiffies + HZ/2);
-
-		return;
-	}
-
-	if (hdmi_ctrl->hpd_stable) {
-		mutex_unlock(&hdmi_ctrl->mutex);
-		DEV_DBG("%s: no more timer, depending on IRQ now\n",
-			__func__);
-		return;
-	}
-
-	hdmi_ctrl->hpd_stable = 1;
-
-	/*
-	 *todo: Revisit cable chg detected condition when HPD support is ready
-	 */
-	hdmi_ctrl->hpd_cable_chg_detected = false;
-	mutex_unlock(&hdmi_ctrl->mutex);
-
-	if (hpd_state) {
-		/* todo: what if EDID read fails? */
-		hdmi_tx_read_sink_info(hdmi_ctrl);
-		DEV_INFO("HDMI HPD: sense CONNECTED: send ONLINE\n");
-		kobject_uevent(hdmi_ctrl->kobj, KOBJ_ONLINE);
-		switch_set_state(&hdmi_ctrl->sdev, 1);
-		DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
-			hdmi_ctrl->sdev.state);
-	} else {
-		DEV_INFO("HDMI HPD: sense DISCONNECTED: send OFFLINE\n");
-		kobject_uevent(hdmi_ctrl->kobj, KOBJ_OFFLINE);
-		switch_set_state(&hdmi_ctrl->sdev, 0);
-		DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
-			hdmi_ctrl->sdev.state);
-	}
-
-	/* Set IRQ for HPD */
-	DSS_REG_W(io, HDMI_HPD_INT_CTRL, 4 | (hpd_state ? 0 : 2));
-} /* hdmi_tx_hpd_state_work */
-
 static void hdmi_tx_hpd_int_work(struct work_struct *work)
 {
-	u32 hpd_int_status;
-	u32 hpd_int_ctrl;
-	u32 cable_detected;
 	struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
 	struct dss_io_data *io = NULL;
 
@@ -552,23 +478,24 @@
 		return;
 	}
 
-	/* Process HPD Interrupt */
-	hpd_int_status = DSS_REG_R(io, HDMI_HPD_INT_STATUS);
-	hpd_int_ctrl = DSS_REG_R(io, HDMI_HPD_INT_CTRL);
+	DEV_DBG("%s: Got HPD interrupt\n", __func__);
 
-	DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(2));
-
-	cable_detected = hpd_int_status & BIT(1);
-	mutex_lock(&hdmi_ctrl->mutex);
-	hdmi_ctrl->hpd_cable_chg_detected = true;
-	hdmi_ctrl->hpd_prev_state = cable_detected ? 0 : 1;
-	hdmi_ctrl->hpd_stable = 0;
-	mutex_unlock(&hdmi_ctrl->mutex);
-
-	mod_timer(&hdmi_ctrl->hpd_state_timer, jiffies + HZ/2);
-
-	DEV_DBG("%s: HPD<Ctrl=%04x, State=%04x>\n", __func__, hpd_int_ctrl,
-		hpd_int_status);
+	hdmi_ctrl->hpd_state =
+		(DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(1)) >> 1;
+	if (hdmi_ctrl->hpd_state) {
+		hdmi_tx_read_sink_info(hdmi_ctrl);
+		DEV_INFO("HDMI HPD: sense CONNECTED: send ONLINE\n");
+		kobject_uevent(hdmi_ctrl->kobj, KOBJ_ONLINE);
+		switch_set_state(&hdmi_ctrl->sdev, 1);
+		DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
+			hdmi_ctrl->sdev.state);
+	} else {
+		DEV_INFO("HDMI HPD: sense DISCONNECTED: send OFFLINE\n");
+		kobject_uevent(hdmi_ctrl->kobj, KOBJ_OFFLINE);
+		switch_set_state(&hdmi_ctrl->sdev, 0);
+		DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
+			hdmi_ctrl->sdev.state);
+	}
 } /* hdmi_tx_hpd_int_work */
 
 static int hdmi_tx_check_capability(struct dss_io_data *io)
@@ -1009,17 +936,6 @@
 	DSS_REG_W(io, HDMI_GEN_PKT_CTRL, packet_control);
 } /* hdmi_tx_set_spd_infoframe */
 
-/* todo: revisit when new HPD debouncing logic is avialble */
-static void hdmi_tx_hpd_state_timer(unsigned long data)
-{
-	struct hdmi_tx_ctrl *hdmi_ctrl = (struct hdmi_tx_ctrl *)data;
-
-	if (hdmi_ctrl)
-		queue_work(hdmi_ctrl->workq, &hdmi_ctrl->hpd_state_work);
-	else
-		DEV_ERR("%s: invalid input\n", __func__);
-} /* hdmi_tx_hpd_state_timer */
-
 static void hdmi_tx_set_mode(struct hdmi_tx_ctrl *hdmi_ctrl, u32 power_on)
 {
 	u32 reg_val = 0;
@@ -1560,7 +1476,8 @@
 	}
 	DSS_REG_W(io, HDMI_INFOFRAME_CTRL0, audio_info_ctrl_reg);
 
-	dss_reg_dump(io->base, io->len, "HDMI-AUDIO-ON: ", REG_DUMP);
+	dss_reg_dump(io->base, io->len,
+		enabled ? "HDMI-AUDIO-ON: " : "HDMI-AUDIO-OFF: ", REG_DUMP);
 
 	return 0;
 } /* hdmi_tx_audio_info_setup */
@@ -1603,8 +1520,7 @@
 
 static void hdmi_tx_audio_off(struct hdmi_tx_ctrl *hdmi_ctrl)
 {
-	int i;
-	u32 audio_pkt_ctrl, audio_cfg;
+	u32 i, status, max_reads, timeout_us, timeout_sec = 15;
 	struct dss_io_data *io = NULL;
 
 	if (!hdmi_ctrl) {
@@ -1618,15 +1534,26 @@
 		return;
 	}
 
-	/* Number of wait iterations */
-	i = 10;
-	do {
-		audio_pkt_ctrl = DSS_REG_R_ND(io, HDMI_AUDIO_PKT_CTRL);
-		audio_cfg = DSS_REG_R_ND(io, HDMI_AUDIO_CFG);
-		DEV_DBG("%s: i=%d, AUDIO PACKET=%08x, AUDIO CFG=%08x",
-			__func__, i, audio_pkt_ctrl, audio_cfg);
-		msleep(20);
-	} while (((audio_pkt_ctrl & BIT(0)) || (audio_cfg & BIT(0))) && i--);
+	/* Check if audio engine is turned off by QDSP or not */
+	/* send off notification after every 1 sec for 15 seconds */
+	for (i = 0; i < timeout_sec; i++) {
+		max_reads = 500;
+		timeout_us = 1000 * 2;
+
+		if (readl_poll_timeout_noirq((io->base + HDMI_AUDIO_CFG),
+			status, ((status & BIT(0)) == 0),
+			max_reads, timeout_us)) {
+
+			DEV_ERR("%s: audio still on after %d sec. try again\n",
+				__func__, i+1);
+
+			switch_set_state(&hdmi_ctrl->audio_sdev, 0);
+			continue;
+		}
+		break;
+	}
+	if (i == timeout_sec)
+		DEV_ERR("%s: Error: cannot turn off audio engine\n", __func__);
 
 	if (hdmi_tx_audio_info_setup(hdmi_ctrl, false, 0, 0, 0, false))
 		DEV_ERR("%s: hdmi_tx_audio_info_setup failed.\n", __func__);
@@ -1678,9 +1605,6 @@
 	/* todo: CONFIG_FB_MSM_HDMI_3D */
 	hdmi_tx_set_spd_infoframe(hdmi_ctrl);
 
-	/* Set IRQ for HPD */
-	DSS_REG_W(io, HDMI_HPD_INT_CTRL, 4 | (hdmi_ctrl->hpd_state ? 0 : 2));
-
 	/* todo: HDCP/CEC */
 
 	DEV_INFO("%s: HDMI Core: Initialized\n", __func__);
@@ -1688,17 +1612,51 @@
 	return rc;
 } /* hdmi_tx_start */
 
-static int hdmi_tx_power_off(struct mdss_panel_data *panel_data)
+static void hdmi_tx_hpd_polarity_setup(struct hdmi_tx_ctrl *hdmi_ctrl,
+	bool polarity)
 {
-	struct hdmi_tx_ctrl *hdmi_ctrl =
-		hdmi_tx_get_drvdata_from_panel_data(panel_data);
+	struct dss_io_data *io = NULL;
 
 	if (!hdmi_ctrl) {
 		DEV_ERR("%s: invalid input\n", __func__);
-		return -EINVAL;
+		return;
+	}
+	io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+	if (!io->base) {
+		DEV_ERR("%s: core io is not initialized\n", __func__);
+		return;
 	}
 
-	DEV_INFO("%s: HDMI Core: OFF\n", __func__);
+	if (polarity)
+		DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(2) | BIT(1));
+	else
+		DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(2));
+
+	if ((DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(1)) == polarity) {
+		u32 reg_val = DSS_REG_R(io, HDMI_HPD_CTRL);
+
+		/* Toggle HPD circuit to trigger HPD sense */
+		DSS_REG_W(io, HDMI_HPD_CTRL, reg_val & ~BIT(28));
+		DSS_REG_W(io, HDMI_HPD_CTRL, reg_val | BIT(28));
+	}
+} /* hdmi_tx_hpd_polarity_setup */
+
+static void hdmi_tx_power_off_work(struct work_struct *work)
+{
+	struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
+	struct dss_io_data *io = NULL;
+
+	hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, power_off_work);
+	if (!hdmi_ctrl) {
+		DEV_DBG("%s: invalid input\n", __func__);
+		return;
+	}
+
+	io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+	if (!io->base) {
+		DEV_ERR("%s: Core io is not initialized\n", __func__);
+		return;
+	}
 
 	if (!hdmi_tx_is_dvi_mode(hdmi_ctrl)) {
 		switch_set_state(&hdmi_ctrl->audio_sdev, 0);
@@ -1709,9 +1667,35 @@
 	}
 
 	hdmi_tx_powerdown_phy(hdmi_ctrl);
-	hdmi_ctrl->panel_power_on = false;
 	hdmi_tx_core_off(hdmi_ctrl);
 
+	mutex_lock(&hdmi_ctrl->mutex);
+	hdmi_ctrl->panel_power_on = false;
+	mutex_unlock(&hdmi_ctrl->mutex);
+
+	hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_CONNECT_POLARITY);
+
+	DEV_INFO("%s: HDMI Core: OFF\n", __func__);
+} /* hdmi_tx_power_off_work */
+
+static int hdmi_tx_power_off(struct mdss_panel_data *panel_data)
+{
+	struct hdmi_tx_ctrl *hdmi_ctrl =
+		hdmi_tx_get_drvdata_from_panel_data(panel_data);
+
+	if (!hdmi_ctrl || !hdmi_ctrl->panel_power_on) {
+		DEV_ERR("%s: invalid input\n", __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * Queue work item to handle power down sequence.
+	 * This is needed since we need to wait for the audio engine
+	 * to shutdown first before we shutdown the HDMI core.
+	 */
+	DEV_DBG("%s: Queuing work to power off HDMI core\n", __func__);
+	queue_work(hdmi_ctrl->workq, &hdmi_ctrl->power_off_work);
+
 	return 0;
 } /* hdmi_tx_power_off */
 
@@ -1732,6 +1716,15 @@
 		return -EINVAL;
 	}
 
+	if (!hdmi_ctrl->hpd_initialized) {
+		DEV_ERR("%s: HDMI on is not possible w/o cable detection.\n",
+			__func__);
+		return -EPERM;
+	}
+
+	/* If a power down is already underway, wait for it to finish */
+	flush_work_sync(&hdmi_ctrl->power_off_work);
+
 	DEV_INFO("power: ON (%dx%d %ld)\n", hdmi_ctrl->xres, hdmi_ctrl->yres,
 		hdmi_ctrl->pixel_clk);
 
@@ -1772,6 +1765,8 @@
 		hdmi_tx_is_controller_on(hdmi_ctrl) ? "ON" : "OFF" ,
 		hdmi_tx_is_dvi_mode(hdmi_ctrl) ? "ON" : "OFF");
 
+	hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_DISCONNECT_POLARITY);
+
 	return 0;
 } /* hdmi_tx_power_on */
 
@@ -1789,8 +1784,6 @@
 		return;
 	}
 
-	DEV_DBG("%s: (timer, 5V, IRQ off)\n", __func__);
-	del_timer_sync(&hdmi_ctrl->hpd_state_timer);
 	mdss_disable_irq(&hdmi_tx_hw);
 
 	hdmi_tx_set_mode(hdmi_ctrl, false);
@@ -1838,28 +1831,18 @@
 
 		DSS_REG_W(io, HDMI_USEC_REFTIMER, 0x0001001B);
 
-		/* set timeout to 4.1ms (max) for hardware debounce */
-		reg_val = DSS_REG_R(io, HDMI_HPD_CTRL) | 0x1FFF;
-
-		/* Toggle HPD circuit to trigger HPD sense */
-		DSS_REG_W(io, HDMI_HPD_CTRL,
-			~(1 << 28) & reg_val);
-		DSS_REG_W(io, HDMI_HPD_CTRL, (1 << 28) | reg_val);
+		mdss_enable_irq(&hdmi_tx_hw);
 
 		hdmi_ctrl->hpd_initialized = true;
 
-		/* Check HPD State */
-		mdss_enable_irq(&hdmi_tx_hw);
-	}
+		/* set timeout to 4.1ms (max) for hardware debounce */
+		reg_val = DSS_REG_R(io, HDMI_HPD_CTRL) | 0x1FFF;
 
-	/* Set HPD state machine: ensure at least 2 readouts */
-	mutex_lock(&hdmi_ctrl->mutex);
-	hdmi_ctrl->hpd_stable = 0;
-	hdmi_ctrl->hpd_prev_state = true;
-	hdmi_ctrl->hpd_state = false;
-	hdmi_ctrl->hpd_cable_chg_detected = true;
-	mutex_unlock(&hdmi_ctrl->mutex);
-	mod_timer(&hdmi_ctrl->hpd_state_timer, jiffies + HZ/2);
+		/* Turn on HPD HW circuit */
+		DSS_REG_W(io, HDMI_HPD_CTRL, reg_val | BIT(28));
+
+		hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_CONNECT_POLARITY);
+	}
 
 	return rc;
 } /* hdmi_tx_hpd_on */
@@ -1905,10 +1888,10 @@
 
 	if (DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(0)) {
 		/*
-		 * Turn off HPD irq and clear all interrupts,
-		 * worker will turn IRQ back on
+		 * Ack the current hpd interrupt and stop listening to
+		 * new hpd interrupt.
 		 */
-		DSS_REG_W(io, HDMI_HPD_INT_CTRL, ~BIT(2) | BIT(0));
+		DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(0));
 		queue_work(hdmi_ctrl->workq, &hdmi_ctrl->hpd_int_work);
 	}
 
@@ -1930,7 +1913,6 @@
 
 	switch_dev_unregister(&hdmi_ctrl->audio_sdev);
 	switch_dev_unregister(&hdmi_ctrl->sdev);
-	del_timer_sync(&hdmi_ctrl->hpd_state_timer);
 	if (hdmi_ctrl->workq)
 		destroy_workqueue(hdmi_ctrl->workq);
 	mutex_destroy(&hdmi_ctrl->mutex);
@@ -1971,12 +1953,10 @@
 	hdmi_ctrl->ddc_ctrl.io = &pdata->io[HDMI_TX_CORE_IO];
 	init_completion(&hdmi_ctrl->ddc_ctrl.ddc_sw_done);
 
-	INIT_WORK(&hdmi_ctrl->hpd_state_work, hdmi_tx_hpd_state_work);
+	hdmi_ctrl->hpd_state = false;
 	INIT_WORK(&hdmi_ctrl->hpd_int_work, hdmi_tx_hpd_int_work);
-	init_timer(&hdmi_ctrl->hpd_state_timer);
-	hdmi_ctrl->hpd_state_timer.function = hdmi_tx_hpd_state_timer;
-	hdmi_ctrl->hpd_state_timer.data = (u32)hdmi_ctrl;
-	hdmi_ctrl->hpd_state_timer.expires = 0xffffffffL;
+
+	INIT_WORK(&hdmi_ctrl->power_off_work, hdmi_tx_power_off_work);
 
 	hdmi_ctrl->audio_sample_rate = HDMI_SAMPLE_RATE_48KHZ;
 
@@ -1984,7 +1964,7 @@
 	if (switch_dev_register(&hdmi_ctrl->sdev) < 0) {
 		DEV_ERR("%s: Hdmi switch registration failed\n", __func__);
 		rc = -ENODEV;
-		goto fail_switch_dev;
+		goto fail_create_workq;
 	}
 
 	hdmi_ctrl->audio_sdev.name = "hdmi_audio";
@@ -1999,8 +1979,6 @@
 
 fail_audio_switch_dev:
 	switch_dev_unregister(&hdmi_ctrl->sdev);
-fail_switch_dev:
-	del_timer_sync(&hdmi_ctrl->hpd_state_timer);
 fail_create_workq:
 	if (hdmi_ctrl->workq)
 		destroy_workqueue(hdmi_ctrl->workq);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.h b/drivers/video/msm/mdss/mdss_hdmi_tx.h
index 437f681..3e9fd3c 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.h
@@ -53,14 +53,11 @@
 	u32 panel_power_on;
 
 	u32 hpd_initialized;
-	int hpd_stable;
-	u32 hpd_prev_state;
-	u32 hpd_cable_chg_detected;
 	u32 hpd_state;
 	u32 hpd_feature_on;
-	struct work_struct hpd_state_work;
 	struct work_struct hpd_int_work;
-	struct timer_list hpd_state_timer;
+
+	struct work_struct power_off_work;
 
 	unsigned long pixel_clk;
 	u32 xres;
diff --git a/drivers/video/msm/mdss/mdss_io_util.c b/drivers/video/msm/mdss/mdss_io_util.c
index 5778525..0a14056 100644
--- a/drivers/video/msm/mdss/mdss_io_util.c
+++ b/drivers/video/msm/mdss/mdss_io_util.c
@@ -136,7 +136,7 @@
 			curr_vreg = &in_vreg[i];
 			curr_vreg->vreg = regulator_get(dev,
 				curr_vreg->vreg_name);
-			rc = IS_ERR(curr_vreg->vreg);
+			rc = PTR_RET(curr_vreg->vreg);
 			if (rc) {
 				DEV_ERR("%pS->%s: %s get failed. rc=%d\n",
 					 __builtin_return_address(0), __func__,
@@ -215,7 +215,7 @@
 	int i = 0, rc = 0;
 	if (enable) {
 		for (i = 0; i < num_vreg; i++) {
-			rc = IS_ERR(in_vreg[i].vreg);
+			rc = PTR_RET(in_vreg[i].vreg);
 			if (rc) {
 				DEV_ERR("%pS->%s: %s regulator error. rc=%d\n",
 					__builtin_return_address(0), __func__,
@@ -286,7 +286,7 @@
 
 	for (i = 0; i < num_clk; i++) {
 		clk_arry[i].clk = clk_get(dev, clk_arry[i].clk_name);
-		rc = IS_ERR(clk_arry[i].clk);
+		rc = PTR_RET(clk_arry[i].clk);
 		if (rc) {
 			DEV_ERR("%pS->%s: '%s' get failed. rc=%d\n",
 				__builtin_return_address(0), __func__,
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index c2d107a..11b0831 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -226,7 +226,7 @@
 		mdss_res->irq_mask &= ~ndx_bit;
 		if (mdss_res->irq_mask == 0) {
 			mdss_res->irq_ena = false;
-			disable_irq(mdss_res->irq);
+			disable_irq_nosync(mdss_res->irq);
 		}
 	}
 	spin_unlock_irqrestore(&mdss_lock, irq_flags);
@@ -292,7 +292,7 @@
 		msm_bus_scale_unregister_client(mdata->bus_hdl);
 }
 
-int mdss_mdp_bus_scale_set_quota(u32 ab_quota, u32 ib_quota)
+int mdss_mdp_bus_scale_set_quota(u64 ab_quota, u64 ib_quota)
 {
 	static int current_bus_idx;
 	int bus_idx;
@@ -310,6 +310,10 @@
 
 		bus_idx = (current_bus_idx % (num_cases - 1)) + 1;
 
+		/* aligning to avoid performing updates for small changes */
+		ab_quota = ALIGN(ab_quota, SZ_64M);
+		ib_quota = ALIGN(ib_quota, SZ_64M);
+
 		vect = mdp_bus_scale_table.usecase[current_bus_idx].vectors;
 		if ((ab_quota == vect->ab) && (ib_quota == vect->ib)) {
 			pr_debug("skip bus scaling, no change in vectors\n");
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 33028cb..808babb 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -276,7 +276,7 @@
 int mdss_mdp_set_intr_callback(u32 intr_type, u32 intf_num,
 			       void (*fnc_ptr)(void *), void *arg);
 
-int mdss_mdp_bus_scale_set_quota(u32 ab_quota, u32 ib_quota);
+int mdss_mdp_bus_scale_set_quota(u64 ab_quota, u64 ib_quota);
 void mdss_mdp_set_clk_rate(unsigned long min_clk_rate);
 unsigned long mdss_mdp_get_clk_rate(u32 clk_idx);
 int mdss_mdp_vsync_clk_enable(int enable);
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 73b8c60..3db13f5 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -20,8 +20,10 @@
 #include "mdss_fb.h"
 #include "mdss_mdp.h"
 
+/* truncate at 1k */
+#define MDSS_MDP_BUS_FACTOR_SHIFT 10
 /* 1.5 bus fudge factor */
-#define MDSS_MDP_BUS_FUDGE_FACTOR(val) ALIGN((((val) * 3) / 2), SZ_16M)
+#define MDSS_MDP_BUS_FUDGE_FACTOR(val) (((val) / 2) * 3)
 /* 1.25 clock fudge factor */
 #define MDSS_MDP_CLK_FUDGE_FACTOR(val) (((val) * 5) / 4)
 
@@ -44,7 +46,7 @@
 	struct mdss_mdp_ctl *ctl;
 	int cnum;
 	unsigned long clk_rate = 0;
-	u32 bus_ab_quota = 0, bus_ib_quota = 0;
+	u64 bus_ab_quota = 0, bus_ib_quota = 0;
 
 	if (!flags) {
 		pr_err("nothing to update\n");
@@ -63,7 +65,9 @@
 		}
 	}
 	if (flags & MDSS_MDP_PERF_UPDATE_BUS) {
+		bus_ab_quota = bus_ab_quota << MDSS_MDP_BUS_FACTOR_SHIFT;
 		bus_ib_quota = MDSS_MDP_BUS_FUDGE_FACTOR(bus_ib_quota);
+		bus_ib_quota <<= MDSS_MDP_BUS_FACTOR_SHIFT;
 		mdss_mdp_bus_scale_set_quota(bus_ab_quota, bus_ib_quota);
 	}
 	if (flags & MDSS_MDP_PERF_UPDATE_CLK) {
@@ -116,6 +120,7 @@
 		if (is_writeback) {
 			/* perf for bus writeback */
 			*bus_ab_quota = fps * mixer->width * mixer->height * 3;
+			*bus_ab_quota >>= MDSS_MDP_BUS_FACTOR_SHIFT;
 			*bus_ib_quota = *bus_ab_quota;
 		}
 	}
@@ -148,13 +153,13 @@
 		if (mixer->rotator_mode)
 			rate /= 4; /* block mode fetch at 4 pix/clk */
 
-		*bus_ab_quota += quota;
-		*bus_ib_quota += ib_quota;
-		if (rate > *clk_rate)
-			*clk_rate = rate;
-
 		pr_debug("mixer=%d pnum=%d clk_rate=%u bus ab=%u ib=%u\n",
 			 mixer->num, pipe->num, rate, quota, ib_quota);
+
+		*bus_ab_quota += quota >> MDSS_MDP_BUS_FACTOR_SHIFT;
+		*bus_ib_quota += ib_quota >> MDSS_MDP_BUS_FACTOR_SHIFT;
+		if (rate > *clk_rate)
+			*clk_rate = rate;
 	}
 
 	pr_debug("final mixer=%d clk_rate=%u bus ab=%u ib=%u\n", mixer->num,
@@ -564,6 +569,17 @@
 		goto start_fail;
 	}
 
+	/* request bus bandwidth for panel commands */
+	ctl->clk_rate = MDP_CLK_DEFAULT_RATE;
+	ctl->bus_ib_quota = SZ_1M;
+	mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
+
+	ret = pdata->on(pdata);
+	if (ret) {
+		pr_err("panel power on failed ctl=%d\n", ctl->num);
+		goto panel_fail;
+	}
+
 	pr_debug("ctl_num=%d\n", ctl->num);
 
 	mixer = ctl->mixer_left;
@@ -591,17 +607,16 @@
 		MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OUT_SIZE, outsize);
 		mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_PACK_3D, 0);
 	}
-
-	/* request bus bandwidth for panel commands */
-	ctl->clk_rate = MDP_CLK_DEFAULT_RATE;
-	ctl->bus_ib_quota = SZ_1M;
-	mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
-
-	ret = pdata->on(pdata);
-
+panel_fail:
+	if (ret && ctl->stop_fnc)
+		ctl->stop_fnc(ctl);
 start_fail:
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 	mutex_unlock(&ctl->lock);
+	if (ret) {
+		mdss_mdp_ctl_destroy(mfd);
+		mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
+	}
 
 	return ret;
 }
diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
index a58010e..cc19555 100644
--- a/drivers/video/msm/mipi_dsi.c
+++ b/drivers/video/msm/mipi_dsi.c
@@ -446,9 +446,6 @@
 	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
 		return -ENOMEM;
 
-	if (!mfd->cont_splash_done)
-		cont_splash_clk_ctrl(1);
-
 	mdp_dev = platform_device_alloc("mdp", pdev->id);
 	if (!mdp_dev)
 		return -ENOMEM;
@@ -584,6 +581,9 @@
 
 	pdev_list[pdev_list_cnt++] = pdev;
 
+	if (!mfd->cont_splash_done)
+		cont_splash_clk_ctrl(1);
+
 return 0;
 
 mipi_dsi_probe_err:
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f581c8f..37b1fdc 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -486,7 +486,7 @@
 		  __attribute__((section("__trace_printk_fmt"))) =	\
 			__builtin_constant_p(fmt) ? fmt : NULL;		\
 									\
-		__trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args);	\
+		__trace_printk(_THIS_IP_, trace_printk_fmt, ##args);	\
 	} else								\
 		__trace_printk(_THIS_IP_, fmt, ##args);		\
 } while (0)
diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h
index 130fb54..4ad55f4 100644
--- a/include/linux/mfd/pm8xxx/pm8921-charger.h
+++ b/include/linux/mfd/pm8xxx/pm8921-charger.h
@@ -58,7 +58,6 @@
 
 /**
  * struct pm8921_charger_platform_data -
- * @safety_time:	max charging time in minutes incl. fast and trkl
  *			valid range 4 to 512 min. PON default 120 min
  * @ttrkl_time:		max trckl charging time in minutes
  *			valid range 1 to 64 mins. PON default 15 min
@@ -70,6 +69,9 @@
  *			trickle to fast. This is also the minimum voltage the
  *			system operates at
  * @uvd_thresh_voltage:	the USB falling UVD threshold (mV) (PM8917 only)
+ * @safe_current_ma:	The upper limit of current allowed to be pushed in
+ *			battery. This ends up writing in a one time
+ *			programmable register.
  * @resume_voltage_delta:	the (mV) drop to wait for before resume charging
  *				after the battery has been fully charged
  * @resume_charge_percent:	the % SOC the charger will drop to after the
@@ -127,12 +129,12 @@
  */
 struct pm8921_charger_platform_data {
 	struct pm8xxx_charger_core_data	charger_cdata;
-	unsigned int			safety_time;
 	unsigned int			ttrkl_time;
 	unsigned int			update_time;
 	unsigned int			max_voltage;
 	unsigned int			min_voltage;
 	unsigned int			uvd_thresh_voltage;
+	unsigned int			safe_current_ma;
 	unsigned int			alarm_low_mv;
 	unsigned int			alarm_high_mv;
 	unsigned int			resume_voltage_delta;
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 7a194ca..6d2eee4 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -31,6 +31,8 @@
 };
 
 #define WCNSS_WLAN_IRQ_INVALID -1
+#define HAVE_WCNSS_SUSPEND_RESUME_NOTIFY 1
+#define HAVE_WCNSS_RESET_INTR 1
 
 struct device *wcnss_wlan_get_device(void);
 struct resource *wcnss_wlan_get_memory_map(struct device *dev);
@@ -59,6 +61,8 @@
 void *wcnss_prealloc_get(unsigned int size);
 int wcnss_prealloc_put(void *ptr);
 void wcnss_reset_intr(void);
+void wcnss_suspend_notify(void);
+void wcnss_resume_notify(void);
 
 #define wcnss_wlan_get_drvdata(dev) dev_get_drvdata(dev)
 #define wcnss_wlan_set_drvdata(dev, data) dev_set_drvdata((dev), (data))
diff --git a/include/media/vcap_v4l2.h b/include/media/vcap_v4l2.h
index 55d67bf..2d3b5c5 100644
--- a/include/media/vcap_v4l2.h
+++ b/include/media/vcap_v4l2.h
@@ -254,6 +254,8 @@
 	uint32_t				hold_vc;
 	uint32_t				hold_vp;
 
+	/* Mutex ensures only one thread is dq buffer or turning streamoff */
+	struct mutex			mutex;
 	spinlock_t				cap_slock;
 	bool					streaming;
 
diff --git a/include/sound/cs8427.h b/include/sound/cs8427.h
index 2004ec3..a1e988d 100644
--- a/include/sound/cs8427.h
+++ b/include/sound/cs8427.h
@@ -209,7 +209,8 @@
 	int irq_base;
 	int num_irqs;
 	int reset_gpio;
-	int (*enable) (int enable);
+	int (*enable) (int enable, int gpio);
+	int ls_gpio;
 };
 
 struct snd_pcm_substream;
diff --git a/sound/soc/codecs/cs8427.c b/sound/soc/codecs/cs8427.c
index 23870a4..6e08742 100644
--- a/sound/soc/codecs/cs8427.c
+++ b/sound/soc/codecs/cs8427.c
@@ -110,7 +110,7 @@
 	 * with CS8427 chip
 	 */
 	if (pdata->enable) {
-		err = pdata->enable(1);
+		err = pdata->enable(1, pdata->ls_gpio);
 		if (err < 0) {
 			dev_err(&chip->client->dev,
 				"failed to enable the level shifter\n");
@@ -124,7 +124,7 @@
 	 * with CS8427 chip
 	 */
 	if (pdata->enable) {
-		err = pdata->enable(0);
+		err = pdata->enable(0, pdata->ls_gpio);
 		if (err < 0) {
 			dev_err(&chip->client->dev,
 				"failed to disable the level shifter\n");
@@ -192,7 +192,7 @@
 	 * with CS8427 chip
 	 */
 	if (pdata->enable) {
-		err = pdata->enable(1);
+		err = pdata->enable(1, pdata->ls_gpio);
 		if (err < 0) {
 			dev_err(&chip->client->dev,
 				"failed to enable the level shifter\n");
@@ -207,7 +207,7 @@
 	 * with CS8427 chip
 	 */
 	if (pdata->enable) {
-		err = pdata->enable(0);
+		err = pdata->enable(0, pdata->ls_gpio);
 		if (err < 0) {
 			dev_err(&chip->client->dev,
 				"failed to disable the level shifter\n");
@@ -239,7 +239,7 @@
 	 * with CS8427 chip
 	 */
 	if (pdata->enable) {
-		err = pdata->enable(1);
+		err = pdata->enable(1, pdata->ls_gpio);
 		if (err < 0) {
 			dev_err(&chip->client->dev,
 				"failed to enable the level shifter\n");
@@ -262,7 +262,7 @@
 	 * with CS8427 chip
 	 */
 	if (pdata->enable) {
-		err = pdata->enable(0);
+		err = pdata->enable(0, pdata->ls_gpio);
 		if (err < 0) {
 			dev_err(&chip->client->dev,
 				"failed to disable the level shifter\n");
@@ -734,6 +734,16 @@
 	struct cs8427_platform_data *pdata = chip->client->dev.platform_data;
 	int ret = 0;
 
+	if (pdata->enable) {
+		ret = gpio_request(pdata->ls_gpio, "cs8427 ls");
+		if (ret < 0) {
+			dev_err(&chip->client->dev,
+				 "failed to request the gpio %d\n",
+					pdata->reset_gpio);
+			return ret;
+		}
+	}
+
 	ret = gpio_request(pdata->reset_gpio, "cs8427 reset");
 	if (ret < 0) {
 		dev_err(&chip->client->dev,
@@ -928,8 +938,10 @@
 	}
 	pdata = chip->client->dev.platform_data;
 	gpio_free(pdata->reset_gpio);
-	if (pdata->enable)
-		pdata->enable(0);
+	if (pdata->enable) {
+		pdata->enable(0, pdata->ls_gpio);
+		gpio_free(pdata->ls_gpio);
+	}
 	kfree(chip);
 	return 0;
 }
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 127a2c3..6ac4562 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -875,6 +875,7 @@
 	pr_debug("%s\n", __func__);
 	atomic_set(&prtd->pending_buffer, 0);
 	q6asm_cmd(prtd->audio_client, CMD_CLOSE);
+	compressed_audio.prtd = NULL;
 	q6asm_audio_client_buf_free_contiguous(dir,
 				prtd->audio_client);
 	if (compr->info.codec_param.codec.id ==
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 7b52956..cde5b02 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -486,6 +486,7 @@
 	struct audio_buffer *buf;
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 	int len;
+	unsigned int bufsz_4k_aligned;
 #endif
 
 	if (!(ac) || ((dir != IN) && (dir != OUT)))
@@ -526,8 +527,15 @@
 						mutex_unlock(&ac->cmd_lock);
 						goto fail;
 					}
+					bufsz_4k_aligned = (bufsz + 4095) &
+								(~4095);
+					pr_debug("%s: bufsz_4k_aligned %d"\
+						"bufsz = %d\n",
+						__func__, bufsz_4k_aligned,
+						bufsz);
 					buf[cnt].handle = ion_alloc
-						(buf[cnt].client, bufsz, SZ_4K,
+						(buf[cnt].client,
+						bufsz_4k_aligned, SZ_4K,
 						(0x1 << ION_AUDIO_HEAP_ID), 0);
 					if (IS_ERR_OR_NULL((void *)
 						buf[cnt].handle)) {
@@ -757,6 +765,7 @@
 {
 	uint32_t token;
 	uint32_t *payload = data->payload;
+	struct audio_client *ac;
 
 	if (data->opcode == RESET_EVENTS) {
 		pr_debug("%s: Reset event is received: %d %d apr[%p]\n",
@@ -776,6 +785,8 @@
 
 	if (data->opcode == APR_BASIC_RSP_RESULT) {
 		token = data->token;
+		ac = (struct audio_client *)data->token;
+		pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
 		switch (payload[0]) {
 		case ASM_SESSION_CMD_MEMORY_MAP:
 		case ASM_SESSION_CMD_MEMORY_UNMAP:
@@ -783,9 +794,15 @@
 		case ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS:
 			pr_debug("%s:command[0x%x]success [0x%x]\n",
 					__func__, payload[0], payload[1]);
-			if (atomic_read(&this_mmap.cmd_state)) {
-				atomic_set(&this_mmap.cmd_state, 0);
-				wake_up(&this_mmap.cmd_wait);
+			if (atomic_read(&ac->cmd_state)) {
+				atomic_set(&ac->cmd_state, 0);
+				if (payload[1] != ADSP_EOK) {
+					pr_err("payload[1]:%d error case\n",
+						payload[1]);
+					atomic_set(&ac->cmd_response, 1);
+				} else
+					atomic_set(&ac->cmd_response, 0);
+				wake_up(&ac->cmd_wait);
 			}
 			break;
 		default:
@@ -1327,14 +1344,16 @@
 static void q6asm_add_mmaphdr(struct apr_hdr *hdr, uint32_t pkt_size,
 							uint32_t cmd_flg)
 {
+	struct audio_client *ac;
 	pr_debug("%s:pkt size=%d cmd_flg=%d\n", __func__, pkt_size, cmd_flg);
+	ac = (struct audio_client *)hdr->token;
+	pr_debug("%s: audio_client = %x\n", __func__, (uint32_t)ac);
 	hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	hdr->src_port = 0;
 	hdr->dest_port = 0;
 	if (cmd_flg) {
-		hdr->token = 0;
-		atomic_set(&this_mmap.cmd_state, 1);
+		atomic_set(&ac->cmd_state, 1);
 	}
 	hdr->pkt_size  = pkt_size;
 	return;
@@ -2813,6 +2832,8 @@
 	mem_map.mempool_id = 0; /* EBI */
 	mem_map.reserved = 0;
 
+	pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
+	mem_map.hdr.token = (uint32_t)ac;
 	q6asm_add_mmaphdr(&mem_map.hdr,
 			sizeof(struct asm_stream_cmd_memory_map), TRUE);
 
@@ -2827,14 +2848,20 @@
 		goto fail_cmd;
 	}
 
-	rc = wait_event_timeout(this_mmap.cmd_wait,
-		(atomic_read(&this_mmap.cmd_state) == 0), 5 * HZ);
+	rc = wait_event_timeout(ac->cmd_wait,
+		(atomic_read(&ac->cmd_state) == 0), 5*HZ);
 	if (!rc) {
 		pr_err("timeout. waited for memory_map\n");
 		rc = -EINVAL;
 		goto fail_cmd;
 	}
+	if (atomic_read(&ac->cmd_response)) {
+		pr_err("%s: ASM_SESSION_CMD_MEMORY_MAP cmd failed\n", __func__);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
 	rc = 0;
+
 fail_cmd:
 	return rc;
 }
@@ -2850,6 +2877,8 @@
 	}
 	pr_debug("%s: Session[%d]\n", __func__, ac->session);
 
+	pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
+	mem_unmap.hdr.token = (uint32_t)ac;
 	q6asm_add_mmaphdr(&mem_unmap.hdr,
 			sizeof(struct asm_stream_cmd_memory_unmap), TRUE);
 	mem_unmap.hdr.opcode = ASM_SESSION_CMD_MEMORY_UNMAP;
@@ -2863,14 +2892,21 @@
 		goto fail_cmd;
 	}
 
-	rc = wait_event_timeout(this_mmap.cmd_wait,
-			(atomic_read(&this_mmap.cmd_state) == 0), 5 * HZ);
+	rc = wait_event_timeout(ac->cmd_wait,
+		(atomic_read(&ac->cmd_state) == 0), 5*HZ);
 	if (!rc) {
-		pr_err("timeout. waited for memory_map\n");
+		pr_err("timeout. waited for memory_unmap\n");
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+	if (atomic_read(&ac->cmd_response)) {
+		pr_err("%s: ASM_SESSION_CMD_MEMORY_UNMAP cmd failed\n",
+			__func__);
 		rc = -EINVAL;
 		goto fail_cmd;
 	}
 	rc = 0;
+
 fail_cmd:
 	return rc;
 }
@@ -2959,6 +2995,8 @@
 	}
 	mmap_regions = (struct asm_stream_cmd_memory_map_regions *)
 							mmap_region_cmd;
+	mmap_regions->hdr.token = (uint32_t)ac;
+	pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
 	q6asm_add_mmaphdr(&mmap_regions->hdr, cmd_size, TRUE);
 	mmap_regions->hdr.opcode = ASM_SESSION_CMD_MEMORY_MAP_REGIONS;
 	mmap_regions->mempool_id = 0;
@@ -2984,14 +3022,21 @@
 		goto fail_cmd;
 	}
 
-	rc = wait_event_timeout(this_mmap.cmd_wait,
-			(atomic_read(&this_mmap.cmd_state) == 0), 5*HZ);
+	rc = wait_event_timeout(ac->cmd_wait,
+		(atomic_read(&ac->cmd_state) == 0), 5*HZ);
 	if (!rc) {
-		pr_err("timeout. waited for memory_map\n");
+		pr_err("timeout. waited for map_regions\n");
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+	if (atomic_read(&ac->cmd_response)) {
+		pr_err("%s: ASM_SESSION_CMD_MEMORY_MAP_REGIONS cmd failed\n",
+			__func__);
 		rc = -EINVAL;
 		goto fail_cmd;
 	}
 	rc = 0;
+
 fail_cmd:
 	kfree(mmap_region_cmd);
 	return rc;
@@ -3027,6 +3072,8 @@
 	}
 	unmap_regions = (struct asm_stream_cmd_memory_unmap_regions *)
 							unmap_region_cmd;
+	unmap_regions->hdr.token = (uint32_t)ac;
+	pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
 	q6asm_add_mmaphdr(&unmap_regions->hdr, cmd_size, TRUE);
 	unmap_regions->hdr.opcode = ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS;
 	unmap_regions->nregions = bufcnt & 0x00ff;
@@ -3048,10 +3095,17 @@
 		goto fail_cmd;
 	}
 
-	rc = wait_event_timeout(this_mmap.cmd_wait,
-			(atomic_read(&this_mmap.cmd_state) == 0), 5*HZ);
+	rc = wait_event_timeout(ac->cmd_wait,
+		(atomic_read(&ac->cmd_state) == 0), 5*HZ);
 	if (!rc) {
-		pr_err("timeout. waited for memory_unmap\n");
+		pr_err("timeout. waited for unmap_regions\n");
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+	if (atomic_read(&ac->cmd_response)) {
+		pr_err("%s: ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS cmd failed\n",
+			__func__);
+		rc = -EINVAL;
 		goto fail_cmd;
 	}
 	rc = 0;
diff --git a/sound/soc/msm/qdsp6v2/audio_ocmem.c b/sound/soc/msm/qdsp6v2/audio_ocmem.c
index d38bcbb..9e08be3 100644
--- a/sound/soc/msm/qdsp6v2/audio_ocmem.c
+++ b/sound/soc/msm/qdsp6v2/audio_ocmem.c
@@ -30,6 +30,11 @@
 
 #define AUDIO_OCMEM_BUF_SIZE (512 * SZ_1K)
 
+static int enable_ocmem_audio_voice;
+module_param(enable_ocmem_audio_voice, int,
+			S_IRUGO | S_IWUSR | S_IWGRP);
+MODULE_PARM_DESC(enable_ocmem_audio_voice, "control OCMEM usage for audio/voice");
+
 enum {
 	OCMEM_STATE_DEFAULT = 0,
 	OCMEM_STATE_ALLOC = 1,
@@ -71,6 +76,7 @@
 	spinlock_t audio_lock;
 	struct workqueue_struct *audio_ocmem_workqueue;
 	struct workqueue_struct *voice_ocmem_workqueue;
+	bool ocmem_en;
 };
 
 static struct audio_ocmem_prv audio_ocmem_lcl;
@@ -416,21 +422,31 @@
 
 	struct voice_ocmem_workdata *workdata = NULL;
 
-	if (audio_ocmem_lcl.voice_ocmem_workqueue == NULL) {
-		pr_err("%s: voice ocmem workqueue is NULL\n", __func__);
-		return -EINVAL;
+	if (enable) {
+		if (enable_ocmem_audio_voice)
+			audio_ocmem_lcl.ocmem_en = true;
+		else
+			audio_ocmem_lcl.ocmem_en = false;
 	}
-	workdata = kzalloc(sizeof(struct voice_ocmem_workdata),
-						GFP_ATOMIC);
-	if (workdata == NULL) {
-		pr_err("%s: mem failure\n", __func__);
-		return -ENOMEM;
-	}
-	workdata->id = cid;
-	workdata->en = enable;
+	if (audio_ocmem_lcl.ocmem_en) {
+		if (audio_ocmem_lcl.voice_ocmem_workqueue == NULL) {
+			pr_err("%s: voice ocmem workqueue is NULL\n",
+								__func__);
+			return -EINVAL;
+		}
+		workdata = kzalloc(sizeof(struct voice_ocmem_workdata),
+							GFP_ATOMIC);
+		if (workdata == NULL) {
+			pr_err("%s: mem failure\n", __func__);
+			return -ENOMEM;
+		}
+		workdata->id = cid;
+		workdata->en = enable;
 
-	INIT_WORK(&workdata->work, voice_ocmem_process_workdata);
-	queue_work(audio_ocmem_lcl.voice_ocmem_workqueue, &workdata->work);
+		INIT_WORK(&workdata->work, voice_ocmem_process_workdata);
+		queue_work(audio_ocmem_lcl.voice_ocmem_workqueue,
+							&workdata->work);
+	}
 
 	return 0;
 }
@@ -510,24 +526,35 @@
 {
 	struct audio_ocmem_workdata *workdata = NULL;
 
-	if (audio_ocmem_lcl.audio_ocmem_workqueue == NULL) {
-		pr_err("%s: audio ocmem workqueue is NULL\n", __func__);
-		return -EINVAL;
+	if (enable) {
+		if (enable_ocmem_audio_voice)
+			audio_ocmem_lcl.ocmem_en = true;
+		else
+			audio_ocmem_lcl.ocmem_en = false;
 	}
-	workdata = kzalloc(sizeof(struct audio_ocmem_workdata),
+
+	if (audio_ocmem_lcl.ocmem_en) {
+		if (audio_ocmem_lcl.audio_ocmem_workqueue == NULL) {
+			pr_err("%s: audio ocmem workqueue is NULL\n",
+								__func__);
+			return -EINVAL;
+		}
+		workdata = kzalloc(sizeof(struct audio_ocmem_workdata),
 							GFP_ATOMIC);
-	if (workdata == NULL) {
-		pr_err("%s: mem failure\n", __func__);
-		return -ENOMEM;
+		if (workdata == NULL) {
+			pr_err("%s: mem failure\n", __func__);
+			return -ENOMEM;
+		}
+		workdata->id = id;
+		workdata->en = enable;
+
+		/* if previous work waiting for ocmem - signal it to exit */
+		atomic_set(&audio_ocmem_lcl.audio_exit, 1);
+
+		INIT_WORK(&workdata->work, audio_ocmem_process_workdata);
+		queue_work(audio_ocmem_lcl.audio_ocmem_workqueue,
+							&workdata->work);
 	}
-	workdata->id = id;
-	workdata->en = enable;
-
-	/* if previous work waiting for ocmem - signal it to exit */
-	atomic_set(&audio_ocmem_lcl.audio_exit, 1);
-
-	INIT_WORK(&workdata->work, audio_ocmem_process_workdata);
-	queue_work(audio_ocmem_lcl.audio_ocmem_workqueue, &workdata->work);
 
 	return 0;
 }
@@ -584,6 +611,7 @@
 	atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_DEFAULT);
 	atomic_set(&audio_ocmem_lcl.audio_exit, 0);
 	spin_lock_init(&audio_ocmem_lcl.audio_lock);
+	audio_ocmem_lcl.ocmem_en = false;
 
 	/* populate platform data */
 	ret = audio_ocmem_platform_data_populate(pdev);