Merge "ASoC: msm: q6: move ocmem enable request from trigger to open"
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
new file mode 100644
index 0000000..6508329
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -0,0 +1,78 @@
+* ARM CPUs binding description
+
+The device tree allows to describe the layout of CPUs in a system through
+the "cpus" node, which in turn contains a number of subnodes (ie "cpu")
+defining properties for every cpu.
+
+Bindings for CPU nodes follow the ePAPR standard, available from:
+
+http://devicetree.org
+
+For the ARM architecture every CPU node must contain the following properties:
+
+- device_type:	must be "cpu"
+- reg:		property matching the CPU MPIDR[23:0] register bits
+		reg[31:24] bits must be set to 0
+- compatible:	should be one of:
+		"arm,arm1020"
+		"arm,arm1020e"
+		"arm,arm1022"
+		"arm,arm1026"
+		"arm,arm720"
+		"arm,arm740"
+		"arm,arm7tdmi"
+		"arm,arm920"
+		"arm,arm922"
+		"arm,arm925"
+		"arm,arm926"
+		"arm,arm940"
+		"arm,arm946"
+		"arm,arm9tdmi"
+		"arm,cortex-a5"
+		"arm,cortex-a7"
+		"arm,cortex-a8"
+		"arm,cortex-a9"
+		"arm,cortex-a15"
+		"arm,arm1136"
+		"arm,arm1156"
+		"arm,arm1176"
+		"arm,arm11mpcore"
+		"faraday,fa526"
+		"intel,sa110"
+		"intel,sa1100"
+		"marvell,feroceon"
+		"marvell,mohawk"
+		"marvell,xsc3"
+		"marvell,xscale"
+		"qcom,krait"
+
+Example:
+
+	cpus {
+		#size-cells = <0>;
+		#address-cells = <1>;
+
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x0>;
+		};
+
+		CPU1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x1>;
+		};
+
+		CPU2: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x100>;
+		};
+
+		CPU3: cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x101>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
index 23498e5..6ef2b77 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
@@ -24,6 +24,8 @@
 
 Optional properties
 
+- qcom,freq-control-mask: The cpu mask that will be used to determine if a
+			core can be used for freq control.
 - qcom,core-limit-temp: Threshold temperature to start shutting down cores
 			in degC
 - qcom,core-temp-hysterisis: Degrees C below which the cores will be brought
@@ -77,6 +79,7 @@
 		qcom,limit-temp = <60>;
 		qcom,temp-hysteresis = <10>;
 		qcom,freq-step = <2>;
+		qcom,freq-control-mask = <0xf>
 		qcom,core-limit-temp = <90>;
 		qcom,core-temp-hysterisis = <10>;
 		qcom,core-control-mask = <7>;
diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt
index 436dfc7..052feeb 100644
--- a/Documentation/devicetree/bindings/gpu/adreno.txt
+++ b/Documentation/devicetree/bindings/gpu/adreno.txt
@@ -72,6 +72,20 @@
 			   This is used to override faulty hardware readings.
 - qcom,strtstp-sleepwake:  Boolean. Enables use of GPU SLUMBER instead of SLEEP for power savings
 
+The following properties are optional as collecting data via coresight might
+not be supported for every chipset. The documentation for coresight
+properties can be found in:
+Documentation/devicetree/bindings/coresight/coresight.txt
+
+- coresight-id           Unique integer identifier for the bus.
+- coresight-name         Unique descriptive name of the bus.
+- coresight-nr-inports   Number of input ports on the bus.
+- coresight-outports     List of output port numbers on the bus.
+- coresight-child-list   List of phandles pointing to the children of this
+                         component.
+- coresight-child-ports  List of input port numbers of the children.
+
+
 Example of A330 GPU in MSM8974:
 
 / {
diff --git a/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt b/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
index 706ffe6..c7c6415 100644
--- a/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
+++ b/Documentation/devicetree/bindings/iommu/msm_iommu_v0.txt
@@ -13,6 +13,7 @@
 - qcom,iommu-pmu-event-classes: List of event classes supported.
 - qcom,needs-alt-core-clk : boolean to enable the secondary core clock for
   access to the IOMMU configuration registers
+- Bus scaling properties: See msm_bus.txt
 
 - List of sub nodes, one for each of the translation context banks supported.
     Required properties for each sub-node:
diff --git a/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt b/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
index 56f4767..ed45979 100644
--- a/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
+++ b/Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt
@@ -21,6 +21,7 @@
 - qcom,iommu-pmu-ngroups: Number of Performance Monitor Unit (PMU) groups.
 - qcom,iommu-pmu-ncounters: Number of PMU counters per group.
 - qcom,iommu-pmu-event-classes: List of event classes supported.
+- Bus scaling properties: See msm_bus.txt
 
 - List of sub nodes, one for each of the translation context banks supported.
   Each sub node has the following required properties:
diff --git a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
index 8ce31d9..b0d6b4d 100644
--- a/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt
@@ -40,6 +40,8 @@
   DATA GPIO PAD.
 - qcom,phy-sof-workaround : If present then HSIC PHY has h/w BUGs related to
   SOFs. Software workarounds are required for the same.
+- hsic,consider-ipa-handshake: If present then hsic low power mode is
+  depend on suitable handshake with the IPA peer.
 
 - Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for
   below optional properties:
@@ -71,6 +73,7 @@
 		hsic,ignore-cal-pad-config;
 		hsic,strobe-pad-offset = <0x2050>;
 		hsic,data-pad-offset = <0x2054>;
+		hsic,consider-ipa-handshake;
 
 		qcom,msm-bus,name = "hsic";
 		qcom,msm-bus,num-cases = <2>;
diff --git a/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt b/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
index c130b26..6df1efe 100644
--- a/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
+++ b/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
@@ -21,6 +21,10 @@
 - qcom,has_48mhz_xo: boolean flag to determine the usage of 24MHz XO from RF
 - qcom,has_pronto_hw: boolean flag to determine the revId of the WLAN subsystem
 
+Optional properties:
+- qcom,has_autodetect_xo: boolean flag to determine whether Iris XO auto detect
+should be performed during boot up.
+
 Example:
 
     qcom,wcnss-wlan@fb000000 {
diff --git a/arch/arm/boot/dts/apq8074-dragonboard.dtsi b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
index ea626c8..5700b8d 100644
--- a/arch/arm/boot/dts/apq8074-dragonboard.dtsi
+++ b/arch/arm/boot/dts/apq8074-dragonboard.dtsi
@@ -92,6 +92,7 @@
 	};
 
 	i2c@f9923000 {
+		status = "ok";
 		atmel_mxt_ts@4a {
 			compatible = "atmel,mxt-ts";
 			reg = <0x4a>;
diff --git a/arch/arm/boot/dts/apq8074-v1.dtsi b/arch/arm/boot/dts/apq8074-v1.dtsi
new file mode 100644
index 0000000..c4e7b7c
--- /dev/null
+++ b/arch/arm/boot/dts/apq8074-v1.dtsi
@@ -0,0 +1,48 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm8974.dtsi file.
+ */
+
+/include/ "msm8974-v1.dtsi"
+
+&soc {
+	qcom,qseecom@a700000 {
+		compatible = "qcom,qseecom";
+		reg = <0x0a700000 0x500000>;
+		reg-names = "secapp-region";
+		qcom,disk-encrypt-pipe-pair = <2>;
+		qcom,hlos-ce-hw-instance = <1>;
+		qcom,qsee-ce-hw-instance = <0>;
+		qcom,msm-bus,name = "qseecom-noc";
+		qcom,msm-bus,num-cases = <4>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<55 512 0 0>,
+				<55 512 3936000 393600>,
+				<55 512 3936000 393600>,
+				<55 512 3936000 393600>;
+	};
+};
+
+&memory_hole {
+	qcom,memblock-remove = <0x0a700000 0x5800000>; /* Address and size of the hole */
+};
+
+&qseecom {
+	status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/apq8084-smp2p.dtsi b/arch/arm/boot/dts/apq8084-smp2p.dtsi
new file mode 100644
index 0000000..b1d21ff
--- /dev/null
+++ b/arch/arm/boot/dts/apq8084-smp2p.dtsi
@@ -0,0 +1,82 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+&soc {
+	qcom,smp2p-adsp {
+		compatible = "qcom,smp2p";
+		reg = <0xf9011008 0x4>;
+		qcom,remote-pid = <2>;
+		qcom,irq-bitmask = <0x400>;
+		interrupts = <0 158 1>;
+	};
+
+	smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <7>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_7_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_7_in";
+		gpios = <&smp2pgpio_smp2p_7_in 0 0>;
+	};
+
+	smp2pgpio_smp2p_7_out: qcom,smp2pgpio-smp2p-7-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <7>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_7_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_7_out";
+		gpios = <&smp2pgpio_smp2p_7_out 0 0>;
+	};
+
+	smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <2>;
+		qcom,is-inbound;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_2_in {
+		compatible = "qcom,smp2pgpio_test_smp2p_2_in";
+		gpios = <&smp2pgpio_smp2p_2_in 0 0>;
+	};
+
+	smp2pgpio_smp2p_2_out: qcom,smp2pgpio-smp2p-2-out {
+		compatible = "qcom,smp2pgpio";
+		qcom,entry-name = "smp2p";
+		qcom,remote-pid = <2>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	qcom,smp2pgpio_test_smp2p_2_out {
+		compatible = "qcom,smp2pgpio_test_smp2p_2_out";
+		gpios = <&smp2pgpio_smp2p_2_out 0 0>;
+	};
+};
diff --git a/arch/arm/boot/dts/apq8084.dtsi b/arch/arm/boot/dts/apq8084.dtsi
index 7a1bbef..c74e59d 100644
--- a/arch/arm/boot/dts/apq8084.dtsi
+++ b/arch/arm/boot/dts/apq8084.dtsi
@@ -20,6 +20,7 @@
 };
 
 /include/ "apq8084-ion.dtsi"
+/include/ "apq8084-smp2p.dtsi"
 
 &soc {
 	#address-cells = <1>;
@@ -201,6 +202,51 @@
 		};
 
 	};
+
+	memory_hole: qcom,msm-mem-hole {
+		compatible = "qcom,msm-mem-hole";
+		qcom,memblock-remove = <0x0dc00000 0x2000000>; /* Address and Size of Hole */
+	};
+
+	qcom,ipc-spinlock@fd484000 {
+		compatible = "qcom,ipc-spinlock-sfpb";
+		reg = <0xfd484000 0x400>;
+		qcom,num-locks = <8>;
+	};
+
+	qcom,smem@fa00000 {
+		compatible = "qcom,smem";
+		reg = <0xfa00000 0x200000>,
+			<0xf9011000 0x1000>,
+			<0xfc428000 0x4000>;
+		reg-names = "smem", "irq-reg-base", "aux-mem1";
+
+		qcom,smd-adsp {
+			compatible = "qcom,smd";
+			qcom,smd-edge = <1>;
+			qcom,smd-irq-offset = <0x8>;
+			qcom,smd-irq-bitmask = <0x100>;
+			qcom,pil-string = "adsp";
+			interrupts = <0 156 1>;
+		};
+
+		qcom,smsm-adsp {
+			compatible = "qcom,smsm";
+			qcom,smsm-edge = <1>;
+			qcom,smsm-irq-offset = <0x8>;
+			qcom,smsm-irq-bitmask = <0x200>;
+			interrupts = <0 157 1>;
+		};
+
+		qcom,smd-rpm {
+			compatible = "qcom,smd";
+			qcom,smd-edge = <15>;
+			qcom,smd-irq-offset = <0x8>;
+			qcom,smd-irq-bitmask = <0x1>;
+			interrupts = <0 168 1>;
+			qcom,irq-no-suspend;
+		};
+	};
 };
 
 /include/ "msm-pma8084.dtsi"
diff --git a/arch/arm/boot/dts/msm-iommu-v0.dtsi b/arch/arm/boot/dts/msm-iommu-v0.dtsi
index 35829a7..65075e5 100644
--- a/arch/arm/boot/dts/msm-iommu-v0.dtsi
+++ b/arch/arm/boot/dts/msm-iommu-v0.dtsi
@@ -27,6 +27,13 @@
 						0x10
 						0x12
 						0x80>;
+		qcom,msm-bus,name = "lpass_ebi";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<11 512 0 0>,
+				<11 512 0 1000>;
 		status = "disabled";
 
 		lpass_q6_fw: qcom,iommu-ctx@fd000000 {
@@ -78,6 +85,14 @@
 						0x10
 						0x12
 						0x80>;
+		qcom,msm-bus,name = "copss_ebi";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<88 512 0 0>,
+				<88 512 0 1000>;
+
 		status = "disabled";
 
 		qcom,iommu-ctx@fd010000 {
@@ -161,6 +176,13 @@
 						0x10
 						0x12
 						0x80>;
+		qcom,msm-bus,name = "mdpe_ebi";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<92 512 0 0>,
+				<92 512 0 1000>;
 		status = "disabled";
 
 		qcom,iommu-ctx@fd860000 {
@@ -196,6 +218,13 @@
 						0x10
 						0x12
 						0x80>;
+		qcom,msm-bus,name = "mdps_ebi";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<22 512 0 0>,
+				<22 512 0 1000>;
 		status = "disabled";
 
 		qcom,iommu-ctx@fd870000 {
@@ -232,6 +261,13 @@
 						0x10
 						0x12
 						0x80>;
+		qcom,msm-bus,name = "gfx_ebi";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<26 512 0 0>,
+				<26 512 0 1000>;
 		status = "disabled";
 
 		qcom,iommu-ctx@fd880000 {
@@ -277,6 +313,13 @@
 						0x10
 						0x12
 						0x80>;
+		qcom,msm-bus,name = "vfe_ebi";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<29 512 0 0>,
+				<29 512 0 1000>;
 		status = "disabled";
 
 		qcom,iommu-ctx@fd890000 {
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 9d77312..753b5b9 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -547,6 +547,7 @@
 
 		gpios = <&msmgpio 40 0>, <&msmgpio 41 0>, <&msmgpio 42 0>, <&msmgpio 43 0>, <&msmgpio 44 0>;
 		qcom,has_pronto_hw;
+		qcom,has_autodetect_xo;
 	};
 
 	qcom,msm-adsp-sensors {
@@ -869,6 +870,7 @@
 		qcom,limit-temp = <60>;
 		qcom,temp-hysteresis = <10>;
 		qcom,freq-step = <2>;
+		qcom,freq-control-mask = <0xf>;
 	};
 
 	spi_0: spi@f9923000 { /* BLSP1 QUP1 */
diff --git a/arch/arm/boot/dts/msm8610-cdp.dts b/arch/arm/boot/dts/msm8610-cdp.dts
index d3fc917..d7fe3cf 100644
--- a/arch/arm/boot/dts/msm8610-cdp.dts
+++ b/arch/arm/boot/dts/msm8610-cdp.dts
@@ -229,6 +229,7 @@
 
 	vdd-io-supply = <&pm8110_l6>;
 	qcom,vdd-io-always-on;
+	qcom,vdd-io-lpm-sup;
 	qcom,vdd-io-voltage-level = <1800000 1800000>;
 	qcom,vdd-io-current-level = <200 60000>;
 
@@ -250,8 +251,6 @@
 	qcom,vdd-current-level = <15000 400000>;
 
 	vdd-io-supply = <&pm8110_l21>;
-	qcom,vdd-io-always-on;
-	qcom,vdd-io-lpm-sup;
 	qcom,vdd-io-voltage-level = <1800000 2950000>;
 	qcom,vdd-io-current-level = <200 50000>;
 
diff --git a/arch/arm/boot/dts/msm8610-mtp.dts b/arch/arm/boot/dts/msm8610-mtp.dts
index e1fe66a..e7fe9ca 100644
--- a/arch/arm/boot/dts/msm8610-mtp.dts
+++ b/arch/arm/boot/dts/msm8610-mtp.dts
@@ -229,6 +229,7 @@
 
 	vdd-io-supply = <&pm8110_l6>;
 	qcom,vdd-io-always-on;
+	qcom,vdd-io-lpm-sup;
 	qcom,vdd-io-voltage-level = <1800000 1800000>;
 	qcom,vdd-io-current-level = <200 60000>;
 
@@ -250,8 +251,6 @@
 	qcom,vdd-current-level = <15000 400000>;
 
 	vdd-io-supply = <&pm8110_l21>;
-	qcom,vdd-io-always-on;
-	qcom,vdd-io-lpm-sup;
 	qcom,vdd-io-voltage-level = <1800000 2950000>;
 	qcom,vdd-io-current-level = <200 50000>;
 
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 9dbd71d..ca3e7ca 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -736,6 +736,7 @@
 		qcom,limit-temp = <60>;
 		qcom,temp-hysteresis = <10>;
 		qcom,freq-step = <2>;
+		qcom,freq-control-mask = <0xf>;
 	};
 
 	qcom,ipc-spinlock@fd484000 {
@@ -812,6 +813,43 @@
 		compatible = "qcom,tz-log";
 		reg = <0x0fe805720 0x1000>;
 	};
+
+	qcom,qcrypto@fd404000 {
+		compatible = "qcom,qcrypto";
+                reg  =  <0xfd400000 0x20000>,
+                        <0xfd404000 0x8000>;
+		reg-names = "crypto-base","crypto-bam-base";
+		interrupts = <0 207 0>;
+		qcom,bam-pipe-pair = <2>;
+		qcom,ce-hw-instance = <1>;
+		qcom,ce-hw-shared;
+		qcom,msm-bus,name = "qcrypto-noc";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<55 512 0 0>,
+				<55 512 393600 3936000>;
+	};
+
+        qcom,qcedev@fd400000 {
+		compatible = "qcom,qcedev";
+		reg  =  <0xfd400000 0x20000>,
+			<0xfd404000 0x8000>;
+		reg-names = "crypto-base","crypto-bam-base";
+		interrupts = <0 207 0>;
+		qcom,bam-pipe-pair = <1>;
+		qcom,ce-hw-instance = <1>;
+		qcom,ce-hw-shared;
+		qcom,msm-bus,name = "qcedev-noc";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<55 512 0 0>,
+				<55 512 393600 3936000>;
+	};
+
 };
 
 &gdsc_vfe {
diff --git a/arch/arm/boot/dts/msm8974-gpu.dtsi b/arch/arm/boot/dts/msm8974-gpu.dtsi
index 669097e..5172a5a 100644
--- a/arch/arm/boot/dts/msm8974-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpu.dtsi
@@ -51,6 +51,14 @@
 		/* IOMMU Data */
 		iommu = <&kgsl_iommu>;
 
+		/* Trace bus */
+		coresight-id = <67>;
+		coresight-name = "coresight-gfx";
+		coresight-nr-inports = <0>;
+		coresight-outports = <0>;
+		coresight-child-list = <&funnel_mmss>;
+		coresight-child-ports = <7>;
+
 		qcom,gpu-pwrlevels {
 			#address-cells = <1>;
 			#size-cells = <0>;
diff --git a/arch/arm/boot/dts/msm8974-leds.dtsi b/arch/arm/boot/dts/msm8974-leds.dtsi
index b39cc21..c4780b0 100644
--- a/arch/arm/boot/dts/msm8974-leds.dtsi
+++ b/arch/arm/boot/dts/msm8974-leds.dtsi
@@ -65,10 +65,10 @@
 			pm8941_flash0: qcom,flash_0 {
 				qcom,max-current = <1000>;
 				qcom,default-state = "off";
-				qcom,headroom = <0>;
+				qcom,headroom = <3>;
 				qcom,duration = <1280>;
 				qcom,clamp-curr = <200>;
-				qcom,startup-dly = <1>;
+				qcom,startup-dly = <3>;
 				qcom,safety-timer;
 				label = "flash";
 				linux,default-trigger =
@@ -81,10 +81,10 @@
 			pm8941_flash1: qcom,flash_1 {
 				qcom,max-current = <1000>;
 				qcom,default-state = "off";
-				qcom,headroom = <0>;
+				qcom,headroom = <3>;
 				qcom,duration = <1280>;
 				qcom,clamp-curr = <200>;
-				qcom,startup-dly = <1>;
+				qcom,startup-dly = <3>;
 				qcom,safety-timer;
 				linux,default-trigger =
 					"flash1_trigger";
diff --git a/arch/arm/boot/dts/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974-v2.dtsi
index b37a509..63a31dc 100644
--- a/arch/arm/boot/dts/msm8974-v2.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -81,7 +81,8 @@
 		<783360 465000000>,
 		<489600 266670000>,
 		<244800 133330000>;
-	qcom,reg-presets = <0x80070 0x11FFF>,
+	qcom,reg-presets = <0x80004 0x1>,
+		<0x80070 0x11FFF>,
 		<0x80074 0xA4>,
 		<0x800A8 0x1FFF>,
 		<0x80124 0x3>,
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index a4a3efe..44ebe67 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -26,6 +26,35 @@
 		sdhc4 = &sdhc_4; /* SDC4 SDIO slot */
 	};
 
+	cpus {
+		#size-cells = <0>;
+		#address-cells = <1>;
+
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			compatible = "qcom,krait";
+			reg = <0x0>;
+		};
+
+		CPU1: cpu@1 {
+			device_type = "cpu";
+			compatible = "qcom,krait";
+			reg = <0x1>;
+		};
+
+		CPU2: cpu@2 {
+			device_type = "cpu";
+			compatible = "qcom,krait";
+			reg = <0x2>;
+		};
+
+		CPU3: cpu@3 {
+			device_type = "cpu";
+			compatible = "qcom,krait";
+			reg = <0x3>;
+		};
+	};
+
 	memory {
 		secure_mem: secure_region {
 			linux,contiguous-region;
@@ -1419,6 +1448,7 @@
 		qcom,limit-temp = <60>;
 		qcom,temp-hysteresis = <10>;
 		qcom,freq-step = <2>;
+		qcom,freq-control-mask = <0xf>;
 		qcom,core-limit-temp = <80>;
 		qcom,core-temp-hysteresis = <10>;
 		qcom,core-control-mask = <0xe>;
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 6e258b5..ca09370 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -190,6 +190,7 @@
 				<85 512 40000 640000>;
 		qcom,pool-64-bit-align;
 		qcom,enable-hbm;
+		hsic,consider-ipa-handshake;
 	};
 
 	qcom,usbbam@f9a44000 {
diff --git a/arch/arm/configs/apq8084_defconfig b/arch/arm/configs/apq8084_defconfig
index a1fa53c..c0084bf 100644
--- a/arch/arm/configs/apq8084_defconfig
+++ b/arch/arm/configs/apq8084_defconfig
@@ -43,6 +43,8 @@
 # CONFIG_MSM_PROC_COMM is not set
 CONFIG_MSM_SMD=y
 CONFIG_MSM_SMD_PKG4=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
 CONFIG_MSM_IPC_LOGGING=y
 CONFIG_MSM_IPC_ROUTER=y
 CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
index 07a15d9..7bf54ce 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -291,6 +291,10 @@
 CONFIG_SND=y
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_MSM8226=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_GADGET_DEBUG_FS=y
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index ef56fec..368078e 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -297,6 +297,10 @@
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_MSM8226=y
 CONFIG_SND_SOC_MSM8X10=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_GADGET_DEBUG_FS=y
@@ -310,6 +314,7 @@
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
 CONFIG_MMC_TEST=m
+CONFIG_MMC_BLOCK_TEST=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_MSM=y
@@ -361,4 +366,5 @@
 # CONFIG_CRYPTO_HW is not set
 CONFIG_CRC_CCITT=y
 CONFIG_QPNP_VIBRATOR=y
-CONFIG_QSEECOM=y
\ No newline at end of file
+CONFIG_QSEECOM=y
+CONFIG_IOSCHED_TEST=y
\ No newline at end of file
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index e4497e1..7bb3629 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -294,6 +294,10 @@
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_MSM8226=y
 CONFIG_SND_SOC_MSM8X10=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
 CONFIG_USB_GADGET_DEBUG_FS=y
@@ -307,6 +311,7 @@
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
 CONFIG_MMC_TEST=m
+CONFIG_MMC_BLOCK_TEST=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_MSM=y
@@ -384,3 +389,4 @@
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=y
 CONFIG_CRYPTO_DEV_QCEDEV=m
+CONFIG_IOSCHED_TEST=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 2a1215d..ba246e5 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -108,12 +108,15 @@
 CONFIG_NF_CT_NETLINK=y
 CONFIG_NETFILTER_XT_MARK=y
 CONFIG_NETFILTER_XT_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
 CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
 CONFIG_NETFILTER_XT_MATCH_DSCP=y
 CONFIG_NETFILTER_XT_MATCH_ESP=y
 CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
 CONFIG_IP_SET=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 91d32c4..108a68f 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -304,6 +304,8 @@
 	select ARM_HAS_SG_CHAIN
 	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
 	select ARCH_WANT_KMAP_ATOMIC_FLUSH
+	select MEMORY_HOLE_CARVEOUT
+	select DONT_MAP_HOLE_AFTER_MEMBANK0
 
 config ARCH_MPQ8092
 	bool "MPQ8092"
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 4f4bfbc..fa3344d 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -317,6 +317,7 @@
 obj-$(CONFIG_ARCH_MSM9625) += clock-local2.o clock-pll.o clock-9625.o clock-rpm.o clock-voter.o acpuclock-9625.o acpuclock-cortex.o
 obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o acpuclock-8930ab.o
 obj-$(CONFIG_ARCH_MPQ8092) += board-8092.o board-8092-gpiomux.o
+obj-$(CONFIG_ARCH_MPQ8092) += clock-8092.o
 obj-$(CONFIG_ARCH_MSM8226) += board-8226.o board-8226-gpiomux.o
 obj-$(CONFIG_ARCH_MSM8226) += clock-local2.o clock-pll.o clock-8226.o clock-rpm.o clock-voter.o clock-mdss-8226.o
 obj-$(CONFIG_ARCH_MSM8226) += acpuclock-8226.o acpuclock-cortex.o
diff --git a/arch/arm/mach-msm/board-8084.c b/arch/arm/mach-msm/board-8084.c
index 500c302..67c05ba 100644
--- a/arch/arm/mach-msm/board-8084.c
+++ b/arch/arm/mach-msm/board-8084.c
@@ -31,6 +31,7 @@
 #include "clock.h"
 #include "devices.h"
 #include "platsmp.h"
+#include "modem_notifier.h"
 
 static struct memtype_reserve apq8084_reserve_table[] __initdata = {
 	[MEMTYPE_SMI] = {
@@ -82,6 +83,7 @@
  */
 void __init apq8084_add_drivers(void)
 {
+	msm_init_modem_notifier_list();
 	msm_smd_init();
 	msm_clock_init(&msm8084_clock_init_data);
 }
diff --git a/arch/arm/mach-msm/board-8092.c b/arch/arm/mach-msm/board-8092.c
index cd95bf3..ab5cc3a 100644
--- a/arch/arm/mach-msm/board-8092.c
+++ b/arch/arm/mach-msm/board-8092.c
@@ -35,21 +35,6 @@
 #include "clock.h"
 #include "platsmp.h"
 
-static struct clk_lookup msm_clocks_dummy[] = {
-	CLK_DUMMY("core_clk",   BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
-	CLK_DUMMY("iface_clk",  BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
-	CLK_DUMMY("core_clk",	SDC1_CLK,	"msm_sdcc.1", OFF),
-	CLK_DUMMY("iface_clk",	SDC1_P_CLK,	"msm_sdcc.1", OFF),
-	CLK_DUMMY("core_clk",	SDC2_CLK,	"msm_sdcc.2", OFF),
-	CLK_DUMMY("iface_clk",	SDC2_P_CLK,	"msm_sdcc.2", OFF),
-
-};
-
-struct clock_init_data mpq8092_clock_init_data __initdata = {
-	.table = msm_clocks_dummy,
-	.size = ARRAY_SIZE(msm_clocks_dummy),
-};
-
 static struct memtype_reserve mpq8092_reserve_table[] __initdata = {
 	[MEMTYPE_SMI] = {
 	},
diff --git a/arch/arm/mach-msm/clock-8084.c b/arch/arm/mach-msm/clock-8084.c
index 424b694..b7f9fd7 100644
--- a/arch/arm/mach-msm/clock-8084.c
+++ b/arch/arm/mach-msm/clock-8084.c
@@ -325,7 +325,9 @@
 	CLK_DUMMY("",	mmss_mmssnoc_ahb_clk.c,	"", OFF),
 	CLK_DUMMY("",	mmss_mmssnoc_axi_clk.c,	"", OFF),
 	CLK_DUMMY("",	mmss_s0_axi_clk.c,	"", OFF),
-	CLK_DUMMY("",	ocmemcx_ocmemnoc_clk.c,	"", OFF),
+	CLK_DUMMY("core_clk",  ocmemgx_core_clk.c, "fdd00000.qcom,ocmem", OFF),
+	CLK_DUMMY("iface_clk",	ocmemcx_ocmemnoc_clk.c,
+						"fdd00000.qcom,ocmem", OFF),
 	CLK_DUMMY("",	oxili_ocmemgx_clk.c,	"", OFF),
 	CLK_DUMMY("",	oxili_gfx3d_clk.c,	"", OFF),
 	CLK_DUMMY("",	oxili_rbbmtimer_clk.c,	"", OFF),
diff --git a/arch/arm/mach-msm/clock-8092.c b/arch/arm/mach-msm/clock-8092.c
new file mode 100644
index 0000000..a8520e6
--- /dev/null
+++ b/arch/arm/mach-msm/clock-8092.c
@@ -0,0 +1,323 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/rpm-regulator-smd.h>
+#include <mach/socinfo.h>
+#include <mach/rpm-smd.h>
+
+#include "clock-local2.h"
+#include "clock-pll.h"
+#include "clock-rpm.h"
+#include "clock-voter.h"
+#include "clock.h"
+
+/*
+ * Drivers need to fill in the clock names and device names for the clocks
+ * they need to control.
+ */
+static struct clk_lookup msm_clocks_8092[] = {
+	CLK_DUMMY("core_clk",   BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
+	CLK_DUMMY("iface_clk",  BLSP1_UART_CLK, "msm_serial_hsl.0", OFF),
+	CLK_DUMMY("core_clk",	SDC1_CLK,	"msm_sdcc.1", OFF),
+	CLK_DUMMY("iface_clk",	SDC1_P_CLK,	"msm_sdcc.1", OFF),
+	CLK_DUMMY("core_clk",	SDC2_CLK,	"msm_sdcc.2", OFF),
+	CLK_DUMMY("iface_clk",	SDC2_P_CLK,	"msm_sdcc.2", OFF),
+	CLK_DUMMY("",	usb30_master_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	tsif_ref_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	ce1_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	ce2_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	ce3_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	geni_ser_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	gmac_125m_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	gmac_core_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	gmac_sys_25m_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	gp1_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	gp2_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	gp3_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	pcie_aux_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	pcie_pipe_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	pdm2_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	pwm_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	sata_asic0_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	sata_pmalive_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	sata_rx_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	sata_rx_oob_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	sdcc1_apps_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	sdcc2_apps_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	usb30_mock_utmi_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	usb_hs_system_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	usb_hs2_system_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	usb_hsic_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	usb_hsic_io_cal_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	usb_hsic_system_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	gcc_bam_dma_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_bcss_cfg_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_bimc_gfx_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_bimc_kpss_axi_mstr_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_bimc_sysnoc_axi_mstr_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup1_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup1_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup2_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup2_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup3_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup3_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup4_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup4_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup5_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup5_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup6_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_qup6_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_uart1_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_uart2_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_uart3_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_uart4_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_uart5_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp1_uart6_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup1_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup1_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup2_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup2_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup3_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup3_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup4_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup4_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup5_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup5_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup6_i2c_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_qup6_spi_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_uart1_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_uart2_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_uart3_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_uart4_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_uart5_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_blsp2_uart6_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_boot_rom_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_ce1_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_ce1_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_ce1_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_ce2_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_ce2_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_ce2_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_ce3_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_ce3_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_ce3_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_xo_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_xo_div4_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_geni_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_geni_ser_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_gmac_125m_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_gmac_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_gmac_cfg_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_gmac_core_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_gmac_rx_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_gmac_sys_25m_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_gmac_sys_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_gp1_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_gp2_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_gp3_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_klm_core_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_klm_s_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_lpass_q6_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sys_noc_lpass_mport_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sys_noc_lpass_sway_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_mmss_a5ss_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_mmss_bimc_gfx_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_pcie_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_pcie_axi_mstr_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_pcie_cfg_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_pcie_pipe_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_pcie_sleep_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_pdm2_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_pdm_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_prng_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_pwm_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_pwm_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sata_asic0_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sata_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sata_cfg_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sata_pmalive_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sata_rx_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sata_rx_oob_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sdcc1_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sdcc1_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sdcc2_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sdcc2_apps_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_spss_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_sys_noc_usb3_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb2a_phy_sleep_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb2b_phy_sleep_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb2c_phy_sleep_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb30_master_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb30_mock_utmi_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb30_sleep_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb_hs_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb_hs_system_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb_hs2_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb_hs2_system_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb_hsic_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb_hsic_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb_hsic_io_cal_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_usb_hsic_system_clk.c,	"", OFF),
+	/* MMSS Clock Dummy */
+	CLK_DUMMY("",	axi_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	mmpll0_pll_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	mmpll1_pll_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	mmpll2_pll_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	mmpll3_pll_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	mmpll6_pll_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	vcodec0_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	extpclk_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	lvds_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	mdp_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	vbyone_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	gfx3d_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	vp_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	jpeg2_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	hdmi_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	vbyone_symbol_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	mmss_spdm_axi_div_clk.c,	"", OFF),
+	CLK_DUMMY("",	mmss_spdm_gfx3d_div_clk.c,	"", OFF),
+	CLK_DUMMY("",	mmss_spdm_jpeg2_div_clk.c,	"", OFF),
+	CLK_DUMMY("",	mmss_spdm_mdp_div_clk.c,	"", OFF),
+	CLK_DUMMY("",	mmss_spdm_vcodec0_div_clk.c,	"", OFF),
+	CLK_DUMMY("",	afe_pixel_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	cfg_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	hdmi_bus_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	hdmi_rx_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	md_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	ttl_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	vafe_ext_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	vcap_vp_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	gproc_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	hdmc_frcf_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	kproc_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	maple_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	preproc_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	sdmc_frcs_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	sdme_frcf_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	sdme_vproc_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	vdp_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	vpu_bus_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	vpu_frc_xin_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	vpu_vdp_xin_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	avsync_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	avsync_extpclk_clk.c,	"", OFF),
+	CLK_DUMMY("",	avsync_lvds_clk.c,	"", OFF),
+	CLK_DUMMY("",	avsync_vbyone_clk.c,	"", OFF),
+	CLK_DUMMY("",	avsync_vp_clk.c,	"", OFF),
+	CLK_DUMMY("",	camss_jpeg_jpeg2_clk.c,	"", OFF),
+	CLK_DUMMY("",	camss_jpeg_jpeg_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	camss_jpeg_jpeg_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	camss_micro_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	camss_top_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	mdss_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	mdss_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	mdss_extpclk_clk.c,	"", OFF),
+	CLK_DUMMY("",	mdss_hdmi_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	mdss_hdmi_clk.c,	"", OFF),
+	CLK_DUMMY("",	mdss_lvds_clk.c,	"", OFF),
+	CLK_DUMMY("",	mdss_mdp_clk.c,	"", OFF),
+	CLK_DUMMY("",	mdss_mdp_lut_clk.c,	"", OFF),
+	CLK_DUMMY("",	mdss_vbyone_clk.c,	"", OFF),
+	CLK_DUMMY("",	mdss_vbyone_symbol_clk.c,	"", OFF),
+	CLK_DUMMY("",	mmss_misc_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	mmss_mmssnoc_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	mmss_mmssnoc_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	mmss_s0_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	ocmemcx_ocmemnoc_clk.c,	"", OFF),
+	CLK_DUMMY("",	oxili_ocmemgx_clk.c,	"", OFF),
+	CLK_DUMMY("",	oxili_gfx3d_clk.c,	"", OFF),
+	CLK_DUMMY("",	oxilicx_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcss_mmss_ifdemod_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_afe_pixel_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_audio_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_cfg_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_hdmi_bus_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_hdmi_rx_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_md_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_ttl_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_ttl_debug_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_vafe_ext_clk.c,	"", OFF),
+	CLK_DUMMY("",	vcap_vp_clk.c,	"", OFF),
+	CLK_DUMMY("",	venus0_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	venus0_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	venus0_core0_vcodec_clk.c,	"", OFF),
+	CLK_DUMMY("",	venus0_core1_vcodec_clk.c,	"", OFF),
+	CLK_DUMMY("",	venus0_ocmemnoc_clk.c,	"", OFF),
+	CLK_DUMMY("",	venus0_vcodec0_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_bus_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_cxo_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_frc_xin_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_gproc_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_hdmc_frcf_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_kproc_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_maple_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_preproc_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_sdmc_frcs_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_sdme_frcf_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_sdme_frcs_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_sdme_vproc_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_sleep_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_vdp_clk.c,	"", OFF),
+	CLK_DUMMY("",	vpu_vdp_xin_clk.c,	"", OFF),
+	/* BCSS broadcast */
+	CLK_DUMMY("",	bcc_dem_core_b_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	adc_01_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	bcc_adc_0_in_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_dem_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_klm_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_lnb_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_tsc_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_tspp2_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_vbif_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_bcss_ahb_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_dem_atv_rxfe_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_dem_atv_rxfe_resamp_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_dem_core_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	bcc_dem_core_div2_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	bcc_dem_core_x2_b_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	bcc_dem_core_x2_pre_cgf_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_tsc_ci_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_tsc_cicam_ts_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	bcc_tsc_par_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_tsc_ser_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	bcc_tspp2_clk_src.c,	"", OFF),
+	CLK_DUMMY("",	dig_dem_core_b_div2_clk.c,	"", OFF),
+	CLK_DUMMY("",	atv_x5_pre_cgc_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_albacore_cvbs_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_atv_x1_clk.c,	"", OFF),
+	CLK_DUMMY("",	nidaq_out_clk.c,	"", OFF),
+	CLK_DUMMY("",	gcc_bcss_axi_clk.c,	"", OFF),
+	CLK_DUMMY("",	bcc_lnb_core_clk.c,	"", OFF),
+};
+
+struct clock_init_data mpq8092_clock_init_data __initdata = {
+	.table = msm_clocks_8092,
+	.size = ARRAY_SIZE(msm_clocks_8092),
+};
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index f3de05a..1f0d328 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -3271,7 +3271,8 @@
 	CLK_LOOKUP("byte_clk", mdss_byte0_clk.c, "fd922800.qcom,mdss_dsi"),
 	CLK_LOOKUP("core_clk", mdss_esc0_clk.c, "fd922800.qcom,mdss_dsi"),
 	CLK_LOOKUP("pixel_clk", mdss_pclk0_clk.c, "fd922800.qcom,mdss_dsi"),
-	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdss_dsi_clk_ctrl"),
+	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd922800.qcom,mdss_dsi"),
+	CLK_LOOKUP("bus_clk", mdss_axi_clk.c, "fd922800.qcom,mdss_dsi"),
 
 	CLK_LOOKUP("core_clk", mdss_mdp_clk.c, "fd900000.qcom,mdss_mdp"),
 	CLK_LOOKUP("lut_clk", mdss_mdp_lut_clk.c, "fd900000.qcom,mdss_mdp"),
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index 340f1ef..1034516 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -509,7 +509,6 @@
 
 static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc_clk.c, LONG_MAX);
 static DEFINE_CLK_VOTER(pnoc_iommu_clk, &pnoc_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(pnoc_qseecom_clk, &pnoc_clk.c, LONG_MAX);
 
 static DEFINE_CLK_MEASURE(apc0_m_clk);
 static DEFINE_CLK_MEASURE(apc1_m_clk);
@@ -1546,6 +1545,7 @@
 	F_END,
 };
 
+static struct branch_clk mmss_mmssnoc_axi_clk;
 static struct rcg_clk axi_clk_src = {
 	.cmd_rcgr_reg = AXI_CMD_RCGR,
 	.set_rate = set_rate_hid,
@@ -1557,6 +1557,7 @@
 		.ops = &clk_ops_rcg,
 		VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
 		CLK_INIT(axi_clk_src.c),
+		.depends = &mmss_mmssnoc_axi_clk.c
 	},
 };
 
@@ -2320,7 +2321,6 @@
 	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
-		.parent = &axi_clk_src.c,
 		.dbg_name = "mmss_mmssnoc_axi_clk",
 		.ops = &clk_ops_branch,
 		CLK_INIT(mmss_mmssnoc_axi_clk.c),
@@ -2336,7 +2336,6 @@
 		.dbg_name = "mmss_s0_axi_clk",
 		.ops = &clk_ops_branch,
 		CLK_INIT(mmss_s0_axi_clk.c),
-		.depends = &mmss_mmssnoc_axi_clk.c,
 	},
 };
 
@@ -2764,7 +2763,6 @@
 	CLK_LOOKUP("core_clk",  gcc_blsp1_uart2_apps_clk.c, "f991e000.serial"),
 
 	CLK_LOOKUP("dfab_clk", pnoc_sps_clk.c, "msm_sps"),
-	CLK_LOOKUP("bus_clk",  pnoc_qseecom_clk.c, "qseecom"),
 
 	CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
 	CLK_LOOKUP("bus_clk", pnoc_clk.c, ""),
@@ -3232,10 +3230,6 @@
 	/* Maintain the max nominal frequency on the MMSSNOC AHB bus. */
 	clk_set_rate(&mmssnoc_ahb_a_clk.c,  40000000);
 	clk_prepare_enable(&mmssnoc_ahb_a_clk.c);
-
-	/* TODO: Remove this once the bus driver is in place */
-	clk_set_rate(&axi_clk_src.c, 200000000);
-	clk_prepare_enable(&mmss_s0_axi_clk.c);
 }
 
 struct clock_init_data msm8610_clock_init_data __initdata = {
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 4a16b42..dabab9f 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -4212,6 +4212,7 @@
 
 static struct branch_clk venus0_vcodec0_clk = {
 	.cbcr_reg = VENUS0_VCODEC0_CBCR,
+	.bcr_reg = VENUS0_BCR,
 	.has_sibling = 0,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
@@ -4891,6 +4892,10 @@
 	CLK_LOOKUP("byte_clk", mdss_byte1_clk.c, "fd922e00.qcom,mdss_dsi"),
 	CLK_LOOKUP("core_clk", mdss_esc0_clk.c, "fd922800.qcom,mdss_dsi"),
 	CLK_LOOKUP("core_clk", mdss_esc1_clk.c, "fd922e00.qcom,mdss_dsi"),
+	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd922800.qcom,mdss_dsi"),
+	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd922e00.qcom,mdss_dsi"),
+	CLK_LOOKUP("bus_clk", mdss_axi_clk.c, "fd922800.qcom,mdss_dsi"),
+	CLK_LOOKUP("bus_clk", mdss_axi_clk.c, "fd922e00.qcom,mdss_dsi"),
 	CLK_LOOKUP("pixel_clk", mdss_pclk0_clk.c, "fd922800.qcom,mdss_dsi"),
 	CLK_LOOKUP("pixel_clk", mdss_pclk1_clk.c, "fd922e00.qcom,mdss_dsi"),
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd922100.qcom,hdmi_tx"),
@@ -5097,7 +5102,6 @@
 	CLK_LOOKUP("core_clk", camss_vfe_vfe_axi_clk.c, "fda44000.qcom,iommu"),
 	CLK_LOOKUP("alt_core_clk", camss_top_ahb_clk.c, "fda44000.qcom,iommu"),
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdp.0"),
-	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdss_dsi_clk_ctrl"),
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd923400.qcom,mdss_edp"),
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd928000.qcom,iommu"),
 	CLK_LOOKUP("core_clk", mdss_axi_clk.c, "fd928000.qcom,iommu"),
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index e67d973..fff517a 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -559,11 +559,8 @@
 {
 	struct branch_clk *branch = to_branch_clk(c);
 
-	if (!branch->bcr_reg) {
-		WARN("clk_reset called on an unsupported clock (%s)\n",
-			c->dbg_name);
+	if (!branch->bcr_reg)
 		return -EPERM;
-	}
 	return __branch_clk_reset(BCR_REG(branch), action);
 }
 
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index 674ef77..2a65d2f 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -54,6 +54,7 @@
 extern struct clock_init_data msm8226_clock_init_data;
 extern struct clock_init_data msm8226_rumi_clock_init_data;
 extern struct clock_init_data msm8084_clock_init_data;
+extern struct clock_init_data mpq8092_clock_init_data;
 
 int msm_clock_init(struct clock_init_data *data);
 int find_vdd_level(struct clk *clk, unsigned long rate);
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index bf89321..483d8b3 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -1270,6 +1270,7 @@
 	LPASS_SCSS_GP_HIGH_IRQ,
 	SPS_MTI_31,
 	A2_BAM_IRQ,
+	USB1_HS_BAM_IRQ,
 };
 
 struct msm_mpm_device_data msm9615_mpm_dev_data __initdata = {
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index 23d204a..decf9bb 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -98,6 +98,7 @@
  * @halt_enabled: Set to 1 if IOMMU halt is supported in the IOMMU, 0 otherwise.
  * @asid:         List of ASID and their usage count (index is ASID value).
  * @ctx_attach_count: Count of how many context are attached.
+ * @bus_client  : Bus client needed to vote for bus bandwidth.
  *
  * A msm_iommu_drvdata holds the global driver data about a single piece
  * of an IOMMU hardware instance.
@@ -121,12 +122,14 @@
 	int halt_enabled;
 	int *asid;
 	unsigned int ctx_attach_count;
+	unsigned int bus_client;
 };
 
 /**
  * struct iommu_access_ops - Callbacks for accessing IOMMU
  * @iommu_power_on:     Turn on power to unit
  * @iommu_power_off:    Turn off power to unit
+ * @iommu_bus_vote:     Vote for bus bandwidth
  * @iommu_clk_on:       Turn on clks to unit
  * @iommu_clk_off:      Turn off clks to unit
  * @iommu_lock_initialize: Initialize the remote lock
@@ -136,6 +139,8 @@
 struct iommu_access_ops {
 	int (*iommu_power_on)(struct msm_iommu_drvdata *);
 	void (*iommu_power_off)(struct msm_iommu_drvdata *);
+	int (*iommu_bus_vote)(struct msm_iommu_drvdata *drvdata,
+			      unsigned int vote);
 	int (*iommu_clk_on)(struct msm_iommu_drvdata *);
 	void (*iommu_clk_off)(struct msm_iommu_drvdata *);
 	void * (*iommu_lock_initialize)(void);
diff --git a/arch/arm/mach-msm/include/mach/kgsl.h b/arch/arm/mach-msm/include/mach/kgsl.h
index 349dbe7..2216183 100644
--- a/arch/arm/mach-msm/include/mach/kgsl.h
+++ b/arch/arm/mach-msm/include/mach/kgsl.h
@@ -89,6 +89,8 @@
 	struct kgsl_device_iommu_data *iommu_data;
 	int iommu_count;
 	struct msm_dcvs_core_info *core_info;
+	struct coresight_device *csdev;
+	struct coresight_platform_data *coresight_pdata;
 	unsigned int chipid;
 };
 
diff --git a/arch/arm/mach-msm/include/mach/ocmem_priv.h b/arch/arm/mach-msm/include/mach/ocmem_priv.h
index 8539dcc..6f83c53 100644
--- a/arch/arm/mach-msm/include/mach/ocmem_priv.h
+++ b/arch/arm/mach-msm/include/mach/ocmem_priv.h
@@ -42,7 +42,7 @@
 struct ocmem_zone;
 
 struct ocmem_zone_ops {
-	unsigned long (*allocate) (struct ocmem_zone *, unsigned long);
+	int (*allocate) (struct ocmem_zone *, unsigned long, unsigned long *);
 	int (*free) (struct ocmem_zone *, unsigned long, unsigned long);
 };
 
@@ -197,9 +197,9 @@
 int zone_active(int);
 unsigned long offset_to_phys(unsigned long);
 unsigned long phys_to_offset(unsigned long);
-unsigned long allocate_head(struct ocmem_zone *, unsigned long);
+int allocate_head(struct ocmem_zone *, unsigned long, unsigned long *);
 int free_head(struct ocmem_zone *, unsigned long, unsigned long);
-unsigned long allocate_tail(struct ocmem_zone *, unsigned long);
+int allocate_tail(struct ocmem_zone *, unsigned long, unsigned long *);
 int free_tail(struct ocmem_zone *, unsigned long, unsigned long);
 
 int ocmem_notifier_init(void);
diff --git a/arch/arm/mach-msm/include/mach/usb_bam.h b/arch/arm/mach-msm/include/mach/usb_bam.h
index 5ecc63b..bc76f56 100644
--- a/arch/arm/mach-msm/include/mach/usb_bam.h
+++ b/arch/arm/mach-msm/include/mach/usb_bam.h
@@ -126,6 +126,7 @@
 	struct sps_mem_buffer desc_mem_buf;
 	struct usb_bam_event_info event;
 	bool enabled;
+	bool suspended;
 	int ipa_clnt_hdl;
 	void *priv;
 	int (*activity_notify)(void *priv);
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index f4ac37e..12f5a8e 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -570,12 +570,14 @@
 			goto out;
 		}
 		ctx = msm_iommu_get_ctx(name);
-		if (!ctx) {
-			pr_err("Unable to find context %s\n", name);
-			ret_val = -EINVAL;
+		if (IS_ERR(ctx)) {
+			ret_val = PTR_ERR(ctx);
 			goto out;
 		}
-		iommu_group_add_device(group, ctx);
+
+		ret_val = iommu_group_add_device(group, ctx);
+		if (ret_val)
+			goto out;
 	}
 out:
 	return ret_val;
@@ -590,7 +592,7 @@
 	struct msm_iova_layout l;
 	struct msm_iova_partition *part = 0;
 	struct iommu_domain *domain = 0;
-	unsigned int *addr_array;
+	unsigned int *addr_array = 0;
 	unsigned int array_size;
 	int domain_no;
 	int secure_domain;
@@ -661,11 +663,46 @@
 	iommu_group_set_iommudata(group, domain, NULL);
 
 free_mem:
+	kfree(addr_array);
 	kfree(part);
 out:
 	return ret_val;
 }
 
+static int __msm_group_get_domain(struct device *dev, void *data)
+{
+	struct msm_iommu_data_entry *list_entry;
+	struct list_head *dev_list = data;
+	int ret_val = 0;
+
+	list_entry = kmalloc(sizeof(*list_entry), GFP_KERNEL);
+	if (list_entry) {
+		list_entry->data = dev;
+		list_add(&list_entry->list, dev_list);
+	} else {
+		ret_val = -ENOMEM;
+	}
+
+	return ret_val;
+}
+
+static void __msm_iommu_group_remove_device(struct iommu_group *grp)
+{
+	struct msm_iommu_data_entry *tmp;
+	struct msm_iommu_data_entry *list_entry;
+	struct list_head dev_list;
+
+	INIT_LIST_HEAD(&dev_list);
+	iommu_group_for_each_dev(grp, &dev_list, __msm_group_get_domain);
+
+	list_for_each_entry_safe(list_entry, tmp, &dev_list, list) {
+		iommu_group_remove_device(list_entry->data);
+		list_del(&list_entry->list);
+		kfree(list_entry);
+	}
+}
+
+
 static int iommu_domain_parse_dt(const struct device_node *dt_node)
 {
 	struct device_node *node;
@@ -674,13 +711,30 @@
 	int ret_val = 0;
 	struct iommu_group *group = 0;
 	const char *name;
+	struct msm_iommu_data_entry *grp_list_entry;
+	struct msm_iommu_data_entry *tmp;
+	struct list_head iommu_group_list;
+	INIT_LIST_HEAD(&iommu_group_list);
 
 	for_each_child_of_node(dt_node, node) {
 		group = iommu_group_alloc();
 		if (IS_ERR(group)) {
 			ret_val = PTR_ERR(group);
-			goto out;
+			group = 0;
+			goto free_group;
 		}
+
+		/* This is only needed to clean up memory if something fails */
+		grp_list_entry = kmalloc(sizeof(*grp_list_entry),
+					   GFP_KERNEL);
+		if (grp_list_entry) {
+			grp_list_entry->data = group;
+			list_add(&grp_list_entry->list, &iommu_group_list);
+		} else {
+			ret_val = -ENOMEM;
+			goto free_group;
+		}
+
 		if (of_property_read_string(node, "label", &name)) {
 			ret_val = -EINVAL;
 			goto free_group;
@@ -696,7 +750,6 @@
 
 		ret_val = find_and_add_contexts(group, node, num_contexts);
 		if (ret_val) {
-			ret_val = -EINVAL;
 			goto free_group;
 		}
 		ret_val = create_and_add_domain(group, node, name);
@@ -704,9 +757,33 @@
 			ret_val = -EINVAL;
 			goto free_group;
 		}
+
+		/* Remove reference to the group that is taken when the group
+		 * is allocated. This will ensure that when all the devices in
+		 * the group are removed the group will be released.
+		 */
+		iommu_group_put(group);
 	}
+
+	list_for_each_entry_safe(grp_list_entry, tmp, &iommu_group_list, list) {
+		list_del(&grp_list_entry->list);
+		kfree(grp_list_entry);
+	}
+	goto out;
+
 free_group:
-	/* No iommu_group_free() function */
+	list_for_each_entry_safe(grp_list_entry, tmp, &iommu_group_list, list) {
+		struct iommu_domain *d;
+
+		d = iommu_group_get_iommudata(grp_list_entry->data);
+		if (d)
+			msm_unregister_domain(d);
+
+		__msm_iommu_group_remove_device(grp_list_entry->data);
+		list_del(&grp_list_entry->list);
+		kfree(grp_list_entry);
+	}
+	iommu_group_put(group);
 out:
 	return ret_val;
 }
diff --git a/arch/arm/mach-msm/ipc_logging.c b/arch/arm/mach-msm/ipc_logging.c
index 1260a1a..280f237 100644
--- a/arch/arm/mach-msm/ipc_logging.c
+++ b/arch/arm/mach-msm/ipc_logging.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -32,7 +32,7 @@
 #include "ipc_logging.h"
 
 static LIST_HEAD(ipc_log_context_list);
-DEFINE_SPINLOCK(ipc_log_context_list_lock);
+DEFINE_RWLOCK(ipc_log_context_list_lock);
 static atomic_t next_log_id = ATOMIC_INIT(0);
 
 static struct ipc_log_page *get_first_page(struct ipc_log_context *ilctxt)
@@ -140,7 +140,7 @@
 		return;
 	}
 
-	spin_lock_irqsave(&ipc_log_context_list_lock, flags);
+	read_lock_irqsave(&ipc_log_context_list_lock, flags);
 	spin_lock(&ilctxt->ipc_log_context_lock);
 	while (ilctxt->write_avail < ectxt->offset)
 		msg_read(ilctxt, NULL);
@@ -165,7 +165,7 @@
 	ilctxt->write_avail -= ectxt->offset;
 	complete(&ilctxt->read_avail);
 	spin_unlock(&ilctxt->ipc_log_context_lock);
-	spin_unlock_irqrestore(&ipc_log_context_list_lock, flags);
+	read_unlock_irqrestore(&ipc_log_context_list_lock, flags);
 }
 EXPORT_SYMBOL(ipc_log_write);
 
@@ -471,13 +471,13 @@
 	if (!df_info)
 		return -ENOSPC;
 
-	spin_lock_irqsave(&ipc_log_context_list_lock, flags);
+	read_lock_irqsave(&ipc_log_context_list_lock, flags);
 	spin_lock(&ilctxt->ipc_log_context_lock);
 	df_info->type = type;
 	df_info->dfunc = dfunc;
 	list_add_tail(&df_info->list, &ilctxt->dfunc_info_list);
 	spin_unlock(&ilctxt->ipc_log_context_lock);
-	spin_unlock_irqrestore(&ipc_log_context_list_lock, flags);
+	read_unlock_irqrestore(&ipc_log_context_list_lock, flags);
 	return 0;
 }
 EXPORT_SYMBOL(add_deserialization_func);
@@ -528,9 +528,9 @@
 
 	create_ctx_debugfs(ctxt, mod_name);
 
-	spin_lock_irqsave(&ipc_log_context_list_lock, flags);
+	write_lock_irqsave(&ipc_log_context_list_lock, flags);
 	list_add_tail(&ctxt->list, &ipc_log_context_list);
-	spin_unlock_irqrestore(&ipc_log_context_list_lock, flags);
+	write_unlock_irqrestore(&ipc_log_context_list_lock, flags);
 	return (void *)ctxt;
 
 release_ipc_log_context:
diff --git a/arch/arm/mach-msm/ipc_logging.h b/arch/arm/mach-msm/ipc_logging.h
index 0eb82a5..36b4171 100644
--- a/arch/arm/mach-msm/ipc_logging.h
+++ b/arch/arm/mach-msm/ipc_logging.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -65,7 +65,7 @@
 #define IS_MSG_TYPE(x) (((x) > TSV_TYPE_MSG_START) && \
 			((x) < TSV_TYPE_MSG_END))
 
-extern spinlock_t ipc_log_context_list_lock;
+extern rwlock_t ipc_log_context_list_lock;
 
 extern int msg_read(struct ipc_log_context *ilctxt,
 		    struct encode_context *ectxt);
diff --git a/arch/arm/mach-msm/ipc_logging_debug.c b/arch/arm/mach-msm/ipc_logging_debug.c
index ff947ef..246fb99 100644
--- a/arch/arm/mach-msm/ipc_logging_debug.c
+++ b/arch/arm/mach-msm/ipc_logging_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -62,7 +62,7 @@
 	dctxt.output_format = OUTPUT_DEBUGFS;
 	dctxt.buff = buff;
 	dctxt.size = size;
-	spin_lock_irqsave(&ipc_log_context_list_lock, flags);
+	read_lock_irqsave(&ipc_log_context_list_lock, flags);
 	spin_lock(&ilctxt->ipc_log_context_lock);
 	while (dctxt.size >= MAX_MSG_DECODED_SIZE &&
 	       !is_ilctxt_empty(ilctxt)) {
@@ -70,19 +70,19 @@
 		deserialize_func = get_deserialization_func(ilctxt,
 							ectxt.hdr.type);
 		spin_unlock(&ilctxt->ipc_log_context_lock);
-		spin_unlock_irqrestore(&ipc_log_context_list_lock, flags);
+		read_unlock_irqrestore(&ipc_log_context_list_lock, flags);
 		if (deserialize_func)
 			deserialize_func(&ectxt, &dctxt);
 		else
 			pr_err("%s: unknown message 0x%x\n",
 				__func__, ectxt.hdr.type);
-		spin_lock_irqsave(&ipc_log_context_list_lock, flags);
+		read_lock_irqsave(&ipc_log_context_list_lock, flags);
 		spin_lock(&ilctxt->ipc_log_context_lock);
 	}
 	if ((size - dctxt.size) == 0)
 		init_completion(&ilctxt->read_avail);
 	spin_unlock(&ilctxt->ipc_log_context_lock);
-	spin_unlock_irqrestore(&ipc_log_context_list_lock, flags);
+	read_unlock_irqrestore(&ipc_log_context_list_lock, flags);
 	return size - dctxt.size;
 }
 
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index c620419..f95ef3b 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -476,23 +476,44 @@
 	kfree(skb_head);
 }
 
+static int post_pkt_to_port(struct msm_ipc_port *port_ptr,
+			    struct rr_packet *pkt, int clone)
+{
+	struct rr_packet *temp_pkt = pkt;
+
+	if (unlikely(!port_ptr || !pkt))
+		return -EINVAL;
+
+	if (clone) {
+		temp_pkt = clone_pkt(pkt);
+		if (!temp_pkt) {
+			pr_err("%s: Error cloning packet for port %08x:%08x\n",
+				__func__, port_ptr->this_port.node_id,
+				port_ptr->this_port.port_id);
+			return -ENOMEM;
+		}
+	}
+
+	mutex_lock(&port_ptr->port_rx_q_lock);
+	wake_lock(&port_ptr->port_rx_wake_lock);
+	list_add_tail(&temp_pkt->list, &port_ptr->port_rx_q);
+	wake_up(&port_ptr->port_rx_wait_q);
+	if (port_ptr->notify)
+		port_ptr->notify(MSM_IPC_ROUTER_READ_CB, port_ptr->priv);
+	mutex_unlock(&port_ptr->port_rx_q_lock);
+	return 0;
+}
+
 static int post_control_ports(struct rr_packet *pkt)
 {
 	struct msm_ipc_port *port_ptr;
-	struct rr_packet *cloned_pkt;
 
 	if (!pkt)
 		return -EINVAL;
 
 	mutex_lock(&control_ports_lock);
-	list_for_each_entry(port_ptr, &control_ports, list) {
-		mutex_lock(&port_ptr->port_rx_q_lock);
-		cloned_pkt = clone_pkt(pkt);
-		wake_lock(&port_ptr->port_rx_wake_lock);
-		list_add_tail(&cloned_pkt->list, &port_ptr->port_rx_q);
-		wake_up(&port_ptr->port_rx_wait_q);
-		mutex_unlock(&port_ptr->port_rx_q_lock);
-	}
+	list_for_each_entry(port_ptr, &control_ports, list)
+		post_pkt_to_port(port_ptr, pkt, 1);
 	mutex_unlock(&control_ports_lock);
 	return 0;
 }
@@ -736,27 +757,14 @@
 {
 	struct msm_ipc_resume_tx_port *rtx_port, *tmp_rtx_port;
 	struct msm_ipc_port *local_port;
-	struct rr_packet *cloned_pkt;
 
 	list_for_each_entry_safe(rtx_port, tmp_rtx_port,
 				&rport_ptr->resume_tx_port_list, list) {
 		mutex_lock(&local_ports_lock);
 		local_port =
 			msm_ipc_router_lookup_local_port(rtx_port->port_id);
-		if (local_port) {
-			cloned_pkt = clone_pkt(pkt);
-			if (cloned_pkt) {
-				mutex_lock(&local_port->port_rx_q_lock);
-				list_add_tail(&cloned_pkt->list,
-						&local_port->port_rx_q);
-				wake_up(&local_port->port_rx_wait_q);
-				mutex_unlock(&local_port->port_rx_q_lock);
-			} else {
-				pr_err("%s: Clone_pkt failed for %08x:%08x\n",
-					__func__, local_port->this_port.node_id,
-					local_port->this_port.port_id);
-			}
-		}
+		if (local_port)
+			post_pkt_to_port(local_port, pkt, 1);
 		mutex_unlock(&local_ports_lock);
 		list_del(&rtx_port->list);
 		kfree(rtx_port);
@@ -1646,16 +1654,157 @@
 	return rc;
 }
 
+static int process_resume_tx_msg(union rr_control_msg *msg,
+				 struct rr_packet *pkt)
+{
+	struct msm_ipc_router_remote_port *rport_ptr;
+
+	RR("o RESUME_TX id=%d:%08x\n", msg->cli.node_id, msg->cli.port_id);
+
+	rport_ptr = msm_ipc_router_lookup_remote_port(msg->cli.node_id,
+						      msg->cli.port_id);
+	if (!rport_ptr) {
+		pr_err("%s: Unable to resume client\n", __func__);
+		return -ENODEV;
+	}
+	mutex_lock(&rport_ptr->quota_lock);
+	rport_ptr->tx_quota_cnt = 0;
+	post_resume_tx(rport_ptr, pkt);
+	mutex_unlock(&rport_ptr->quota_lock);
+	return 0;
+}
+
+static int process_new_server_msg(struct msm_ipc_router_xprt_info *xprt_info,
+			union rr_control_msg *msg, struct rr_packet *pkt)
+{
+	struct msm_ipc_routing_table_entry *rt_entry;
+	struct msm_ipc_server *server;
+	struct msm_ipc_router_remote_port *rport_ptr;
+
+	if (msg->srv.instance == 0) {
+		pr_err("%s: Server %08x create rejected, version = 0\n",
+			__func__, msg->srv.service);
+		return -EINVAL;
+	}
+
+	RR("o NEW_SERVER id=%d:%08x service=%08x:%08x\n", msg->srv.node_id,
+	    msg->srv.port_id, msg->srv.service, msg->srv.instance);
+	/*
+	 * Find the entry from Routing Table corresponding to Node ID.
+	 * Under SSR, an entry will be found. When the subsystem hosting
+	 * service is not adjacent, an entry will not be found and hence
+	 * allocate an entry. Update the entry with the Node ID that it
+	 * corresponds to and the XPRT through which it can be reached.
+	 */
+	mutex_lock(&routing_table_lock);
+	rt_entry = lookup_routing_table(msg->srv.node_id);
+	if (!rt_entry) {
+		rt_entry = alloc_routing_table_entry(msg->srv.node_id);
+		if (!rt_entry) {
+			mutex_unlock(&routing_table_lock);
+			pr_err("%s: rt_entry allocation failed\n", __func__);
+			return -ENOMEM;
+		}
+		mutex_lock(&rt_entry->lock);
+		rt_entry->neighbor_node_id = xprt_info->remote_node_id;
+		rt_entry->xprt_info = xprt_info;
+		mutex_unlock(&rt_entry->lock);
+		add_routing_table_entry(rt_entry);
+	}
+	mutex_unlock(&routing_table_lock);
+
+	/*
+	 * If the service does not exist already in the database, create and
+	 * store the service info. Create a remote port structure in which
+	 * the service is hosted and cache the security rule for the service
+	 * in that remote port structure.
+	 */
+	mutex_lock(&server_list_lock);
+	server = msm_ipc_router_lookup_server(msg->srv.service,
+			msg->srv.instance, msg->srv.node_id, msg->srv.port_id);
+	if (!server) {
+		server = msm_ipc_router_create_server(
+				msg->srv.service, msg->srv.instance,
+				msg->srv.node_id, msg->srv.port_id, xprt_info);
+		if (!server) {
+			mutex_unlock(&server_list_lock);
+			pr_err("%s: Server Create failed\n", __func__);
+			return -ENOMEM;
+		}
+
+		if (!msm_ipc_router_lookup_remote_port(
+				msg->srv.node_id, msg->srv.port_id)) {
+			rport_ptr = msm_ipc_router_create_remote_port(
+					msg->srv.node_id, msg->srv.port_id);
+			if (!rport_ptr) {
+				mutex_unlock(&server_list_lock);
+				return -ENOMEM;
+			}
+			rport_ptr->sec_rule = msm_ipc_get_security_rule(
+						msg->srv.service,
+						msg->srv.instance);
+		}
+	}
+	mutex_unlock(&server_list_lock);
+
+	/*
+	 * Relay the new server message to other subsystems that do not belong
+	 * to the cluster from which this message is received. Notify the
+	 * local clients waiting for this service.
+	 */
+	relay_msg(xprt_info, pkt);
+	post_control_ports(pkt);
+	return 0;
+}
+
+static int process_rmv_server_msg(struct msm_ipc_router_xprt_info *xprt_info,
+			union rr_control_msg *msg, struct rr_packet *pkt)
+{
+	struct msm_ipc_server *server;
+
+	RR("o REMOVE_SERVER service=%08x:%d\n",
+	    msg->srv.service, msg->srv.instance);
+	mutex_lock(&server_list_lock);
+	server = msm_ipc_router_lookup_server(msg->srv.service,
+			msg->srv.instance, msg->srv.node_id, msg->srv.port_id);
+	if (server) {
+		msm_ipc_router_destroy_server(server, msg->srv.node_id,
+					      msg->srv.port_id);
+		/*
+		 * Relay the new server message to other subsystems that do not
+		 * belong to the cluster from which this message is received.
+		 * Notify the local clients communicating with the service.
+		 */
+		relay_msg(xprt_info, pkt);
+		post_control_ports(pkt);
+	}
+	mutex_unlock(&server_list_lock);
+	return 0;
+}
+
+static int process_rmv_client_msg(struct msm_ipc_router_xprt_info *xprt_info,
+			union rr_control_msg *msg, struct rr_packet *pkt)
+{
+	struct msm_ipc_router_remote_port *rport_ptr;
+
+	RR("o REMOVE_CLIENT id=%d:%08x\n", msg->cli.node_id, msg->cli.port_id);
+	rport_ptr = msm_ipc_router_lookup_remote_port(msg->cli.node_id,
+						      msg->cli.port_id);
+	if (rport_ptr)
+		msm_ipc_router_destroy_remote_port(rport_ptr);
+
+	relay_msg(xprt_info, pkt);
+	post_control_ports(pkt);
+	return 0;
+}
+
 static int process_control_msg(struct msm_ipc_router_xprt_info *xprt_info,
 			       struct rr_packet *pkt)
 {
 	union rr_control_msg *msg;
-	struct msm_ipc_router_remote_port *rport_ptr;
 	int rc = 0;
 	struct sk_buff *temp_ptr;
 	struct rr_header *hdr;
-	struct msm_ipc_server *server;
-	struct msm_ipc_routing_table_entry *rt_entry;
 
 	if (pkt->length != (IPC_ROUTER_HDR_SIZE + sizeof(*msg))) {
 		pr_err("%s: r2r msg size %d != %d\n", __func__, pkt->length,
@@ -1679,115 +1828,17 @@
 	case IPC_ROUTER_CTRL_CMD_HELLO:
 		rc = process_hello_msg(xprt_info, hdr);
 		break;
-
 	case IPC_ROUTER_CTRL_CMD_RESUME_TX:
-		RR("o RESUME_TX id=%d:%08x\n",
-		   msg->cli.node_id, msg->cli.port_id);
-
-		rport_ptr = msm_ipc_router_lookup_remote_port(msg->cli.node_id,
-							msg->cli.port_id);
-		if (!rport_ptr) {
-			pr_err("%s: Unable to resume client\n", __func__);
-			break;
-		}
-		mutex_lock(&rport_ptr->quota_lock);
-		rport_ptr->tx_quota_cnt = 0;
-		post_resume_tx(rport_ptr, pkt);
-		mutex_unlock(&rport_ptr->quota_lock);
+		rc = process_resume_tx_msg(msg, pkt);
 		break;
-
 	case IPC_ROUTER_CTRL_CMD_NEW_SERVER:
-		if (msg->srv.instance == 0) {
-			pr_err(
-			"rpcrouter: Server create rejected, version = 0, "
-			"service = %08x\n", msg->srv.service);
-			break;
-		}
-
-		RR("o NEW_SERVER id=%d:%08x service=%08x:%08x\n",
-		   msg->srv.node_id, msg->srv.port_id,
-		   msg->srv.service, msg->srv.instance);
-
-		mutex_lock(&routing_table_lock);
-		rt_entry = lookup_routing_table(msg->srv.node_id);
-		if (!rt_entry) {
-			rt_entry = alloc_routing_table_entry(msg->srv.node_id);
-			if (!rt_entry) {
-				mutex_unlock(&routing_table_lock);
-				pr_err("%s: rt_entry allocation failed\n",
-					__func__);
-				return -ENOMEM;
-			}
-			mutex_lock(&rt_entry->lock);
-			rt_entry->neighbor_node_id = xprt_info->remote_node_id;
-			rt_entry->xprt_info = xprt_info;
-			mutex_unlock(&rt_entry->lock);
-			add_routing_table_entry(rt_entry);
-		}
-		mutex_unlock(&routing_table_lock);
-
-		mutex_lock(&server_list_lock);
-		server = msm_ipc_router_lookup_server(msg->srv.service,
-						      msg->srv.instance,
-						      msg->srv.node_id,
-						      msg->srv.port_id);
-		if (!server) {
-			server = msm_ipc_router_create_server(
-				msg->srv.service, msg->srv.instance,
-				msg->srv.node_id, msg->srv.port_id, xprt_info);
-			if (!server) {
-				mutex_unlock(&server_list_lock);
-				pr_err("%s: Server Create failed\n", __func__);
-				return -ENOMEM;
-			}
-
-			if (!msm_ipc_router_lookup_remote_port(
-					msg->srv.node_id, msg->srv.port_id)) {
-				rport_ptr = msm_ipc_router_create_remote_port(
-					msg->srv.node_id, msg->srv.port_id);
-				if (!rport_ptr)
-					pr_err("%s: Remote port create "
-					       "failed\n", __func__);
-				else
-					rport_ptr->sec_rule =
-						msm_ipc_get_security_rule(
-						msg->srv.service,
-						msg->srv.instance);
-			}
-			wake_up(&newserver_wait);
-		}
-		mutex_unlock(&server_list_lock);
-
-		relay_msg(xprt_info, pkt);
-		post_control_ports(pkt);
+		rc = process_new_server_msg(xprt_info, msg, pkt);
 		break;
 	case IPC_ROUTER_CTRL_CMD_REMOVE_SERVER:
-		RR("o REMOVE_SERVER service=%08x:%d\n",
-		   msg->srv.service, msg->srv.instance);
-		mutex_lock(&server_list_lock);
-		server = msm_ipc_router_lookup_server(msg->srv.service,
-						      msg->srv.instance,
-						      msg->srv.node_id,
-						      msg->srv.port_id);
-		if (server) {
-			msm_ipc_router_destroy_server(server,
-						      msg->srv.node_id,
-						      msg->srv.port_id);
-			relay_msg(xprt_info, pkt);
-			post_control_ports(pkt);
-		}
-		mutex_unlock(&server_list_lock);
+		rc = process_rmv_server_msg(xprt_info, msg, pkt);
 		break;
 	case IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT:
-		RR("o REMOVE_CLIENT id=%d:%08x\n",
-		    msg->cli.node_id, msg->cli.port_id);
-		rport_ptr = msm_ipc_router_lookup_remote_port(msg->cli.node_id,
-							msg->cli.port_id);
-		if (rport_ptr)
-			msm_ipc_router_destroy_remote_port(rport_ptr);
-
-		relay_msg(xprt_info, pkt);
-		post_control_ports(pkt);
+		rc = process_rmv_client_msg(xprt_info, msg, pkt);
 		break;
 	case IPC_ROUTER_CTRL_CMD_PING:
 		/* No action needed for ping messages received */
@@ -1901,14 +1952,7 @@
 			}
 		}
 
-		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,
-					 port_ptr->priv);
-		mutex_unlock(&port_ptr->port_rx_q_lock);
+		post_pkt_to_port(port_ptr, pkt, 0);
 		mutex_unlock(&local_ports_lock);
 
 process_done:
@@ -2082,12 +2126,8 @@
 		return -ENODEV;
 	}
 
-	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);
 	ret_len = pkt->length;
-	wake_up(&port_ptr->port_rx_wait_q);
-	mutex_unlock(&port_ptr->port_rx_q_lock);
+	post_pkt_to_port(port_ptr, pkt, 0);
 	update_comm_mode_info(&src->mode_info, NULL);
 	mutex_unlock(&local_ports_lock);
 
diff --git a/arch/arm/mach-msm/ocmem_allocator.c b/arch/arm/mach-msm/ocmem_allocator.c
index 203bb60..a0ff9f9 100644
--- a/arch/arm/mach-msm/ocmem_allocator.c
+++ b/arch/arm/mach-msm/ocmem_allocator.c
@@ -36,24 +36,22 @@
 	reserve:    Enable libgenpool to simulate tail allocations
 */
 
-unsigned long allocate_head(struct ocmem_zone *z, unsigned long size)
+int allocate_head(struct ocmem_zone *z, unsigned long size,
+							unsigned long *offset)
 {
+	*offset  = gen_pool_alloc(z->z_pool, size);
 
-	unsigned long offset;
-
-	offset  = gen_pool_alloc(z->z_pool, size);
-
-	if (!offset)
+	if (!(*offset))
 		return -ENOMEM;
 
 	z->z_head += size;
 	z->z_free -= size;
-	return offset;
+	return 0;
 }
 
-unsigned long allocate_tail(struct ocmem_zone *z, unsigned long size)
+int allocate_tail(struct ocmem_zone *z, unsigned long size,
+							unsigned long *offset)
 {
-	unsigned long offset;
 	unsigned long reserve;
 	unsigned long head;
 
@@ -63,17 +61,17 @@
 	reserve = z->z_tail - z->z_head - size;
 	if (reserve) {
 		head = gen_pool_alloc(z->z_pool, reserve);
-		offset = gen_pool_alloc(z->z_pool, size);
+		*offset = gen_pool_alloc(z->z_pool, size);
 		gen_pool_free(z->z_pool, head, reserve);
 	} else
-		offset = gen_pool_alloc(z->z_pool, size);
+		*offset = gen_pool_alloc(z->z_pool, size);
 
-	if (!offset)
+	if (!(*offset))
 		return -ENOMEM;
 
 	z->z_tail -= size;
 	z->z_free -= size;
-	return offset;
+	return 0;
 }
 
 int free_head(struct ocmem_zone *z, unsigned long offset,
diff --git a/arch/arm/mach-msm/ocmem_sched.c b/arch/arm/mach-msm/ocmem_sched.c
index a14b960..21c4e1e 100644
--- a/arch/arm/mach-msm/ocmem_sched.c
+++ b/arch/arm/mach-msm/ocmem_sched.c
@@ -724,6 +724,7 @@
 	bool retry;
 	struct ocmem_region *spanned_r = NULL;
 	struct ocmem_region *overlap_r = NULL;
+	int rc = 0;
 
 	struct ocmem_req *matched_req = NULL;
 	struct ocmem_region *matched_region = NULL;
@@ -767,9 +768,10 @@
 	if (overlap_r == NULL) {
 		/* no conflicting regions, schedule this region */
 		zone->z_ops->free(zone, curr_start, curr_sz);
-		alloc_addr = zone->z_ops->allocate(zone, curr_sz + growth_sz);
+		rc = zone->z_ops->allocate(zone, curr_sz + growth_sz,
+								&alloc_addr);
 
-		if (alloc_addr < 0) {
+		if (rc) {
 			pr_err("ocmem: zone allocation operation failed\n");
 			goto internal_error;
 		}
@@ -933,6 +935,7 @@
 	struct ocmem_region *matched_region = NULL;
 	struct ocmem_region *region = NULL;
 	unsigned long alloc_addr = 0x0;
+	int rc =  0;
 
 	struct ocmem_zone *zone = get_zone(owner);
 
@@ -957,9 +960,9 @@
 		goto internal_error;
 	}
 
-	alloc_addr = zone->z_ops->allocate(zone, new_sz);
+	rc = zone->z_ops->allocate(zone, new_sz, &alloc_addr);
 
-	if (alloc_addr < 0) {
+	if (rc) {
 		pr_err("Zone Allocation operation failed\n");
 		goto internal_error;
 	}
@@ -1032,6 +1035,7 @@
 	enum client_prio prio = req->prio;
 	unsigned long alloc_addr = 0x0;
 	bool retry;
+	int rc = 0;
 
 	struct ocmem_region *spanned_r = NULL;
 	struct ocmem_region *overlap_r = NULL;
@@ -1078,9 +1082,9 @@
 
 	if (overlap_r == NULL) {
 		/* no conflicting regions, schedule this region */
-		alloc_addr = zone->z_ops->allocate(zone, sz);
+		rc = zone->z_ops->allocate(zone, sz, &alloc_addr);
 
-		if (alloc_addr < 0) {
+		if (rc) {
 			pr_err("Zone Allocation operation failed\n");
 			goto internal_error;
 		}
diff --git a/arch/arm/mach-msm/spm-regulator.c b/arch/arm/mach-msm/spm-regulator.c
index 00817c0..244a779 100644
--- a/arch/arm/mach-msm/spm-regulator.c
+++ b/arch/arm/mach-msm/spm-regulator.c
@@ -42,17 +42,40 @@
 static const struct voltage_range fts2_range0 = {0, 350000, 1275000,  5000};
 static const struct voltage_range fts2_range1 = {0, 700000, 2040000, 10000};
 
-/* Specifies the PMIC internal slew rate in uV/us. */
-#define QPNP_FTS2_SLEW_RATE		6000
-
 #define QPNP_FTS2_REG_TYPE		0x04
 #define QPNP_FTS2_REG_SUBTYPE		0x05
 #define QPNP_FTS2_REG_VOLTAGE_RANGE	0x40
 #define QPNP_FTS2_REG_VOLTAGE_SETPOINT	0x41
+#define QPNP_FTS2_REG_MODE		0x45
+#define QPNP_FTS2_REG_STEP_CTRL		0x61
 
 #define QPNP_FTS2_TYPE			0x1C
 #define QPNP_FTS2_SUBTYPE		0x08
 
+#define QPNP_FTS2_MODE_PWM		0x80
+#define QPNP_FTS2_MODE_AUTO		0x40
+
+#define QPNP_FTS2_STEP_CTRL_STEP_MASK	0x18
+#define QPNP_FTS2_STEP_CTRL_STEP_SHIFT	3
+#define QPNP_FTS2_STEP_CTRL_DELAY_MASK	0x07
+#define QPNP_FTS2_STEP_CTRL_DELAY_SHIFT	0
+
+/* Clock rate in kHz of the FTS2 regulator reference clock. */
+#define QPNP_FTS2_CLOCK_RATE		19200
+
+/* Time to delay in us to ensure that a mode change has completed. */
+#define QPNP_FTS2_MODE_CHANGE_DELAY	50
+
+/* Minimum time in us that it takes to complete a single SPMI write. */
+#define QPNP_SPMI_WRITE_MIN_DELAY	8
+
+/*
+ * The ratio QPNP_FTS2_STEP_MARGIN_NUM/QPNP_FTS2_STEP_MARGIN_DEN is use to
+ * adjust the step rate in order to account for oscillator variance.
+ */
+#define QPNP_FTS2_STEP_MARGIN_NUM	4
+#define QPNP_FTS2_STEP_MARGIN_DEN	5
+
 struct spm_vreg {
 	struct regulator_desc		rdesc;
 	struct regulator_dev		*rdev;
@@ -64,8 +87,23 @@
 	unsigned			last_set_vlevel;
 	bool				online;
 	u16				spmi_base_addr;
+	u8				init_mode;
+	int				step_rate;
 };
 
+static int qpnp_fts2_set_mode(struct spm_vreg *vreg, u8 mode)
+{
+	int rc;
+
+	rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
+		vreg->spmi_base_addr + QPNP_FTS2_REG_MODE, &mode, 1);
+	if (rc)
+		dev_err(&vreg->spmi_dev->dev, "%s: could not write to mode register, rc=%d\n",
+			__func__, rc);
+
+	return rc;
+}
+
 static int _spm_regulator_set_voltage(struct regulator_dev *rdev)
 {
 	struct spm_vreg *vreg = rdev_get_drvdata(rdev);
@@ -74,6 +112,14 @@
 	if (vreg->vlevel == vreg->last_set_vlevel)
 		return 0;
 
+	if (!(vreg->init_mode & QPNP_FTS2_MODE_PWM)
+	    && vreg->uV > vreg->last_set_uV) {
+		/* Switch to PWM mode so that voltage ramping is fast. */
+		rc = qpnp_fts2_set_mode(vreg, QPNP_FTS2_MODE_PWM);
+		if (rc)
+			return rc;
+	}
+
 	rc = msm_spm_apcs_set_vdd(vreg->vlevel);
 	if (rc) {
 		pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->rdesc.name, rc);
@@ -81,10 +127,21 @@
 	}
 
 	if (vreg->uV > vreg->last_set_uV) {
-		/* Wait for voltage to stabalize. */
+		/* Wait for voltage stepping to complete. */
 		udelay(DIV_ROUND_UP(vreg->uV - vreg->last_set_uV,
-					QPNP_FTS2_SLEW_RATE));
+					vreg->step_rate));
 	}
+
+	if (!(vreg->init_mode & QPNP_FTS2_MODE_PWM)
+	    && vreg->uV > vreg->last_set_uV) {
+		/* Wait for mode transition to complete. */
+		udelay(QPNP_FTS2_MODE_CHANGE_DELAY - QPNP_SPMI_WRITE_MIN_DELAY);
+		/* Switch to AUTO mode so that power consumption is lowered. */
+		rc = qpnp_fts2_set_mode(vreg, QPNP_FTS2_MODE_AUTO);
+		if (rc)
+			return rc;
+	}
+
 	vreg->last_set_uV = vreg->uV;
 	vreg->last_set_vlevel = vreg->vlevel;
 
@@ -254,6 +311,51 @@
 	return rc;
 }
 
+static int qpnp_fts2_init_mode(struct spm_vreg *vreg)
+{
+	int rc;
+
+	rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
+		vreg->spmi_base_addr + QPNP_FTS2_REG_MODE, &vreg->init_mode, 1);
+	if (rc)
+		dev_err(&vreg->spmi_dev->dev, "%s: could not read mode register, rc=%d\n",
+			__func__, rc);
+
+	return rc;
+}
+
+static int qpnp_fts2_init_step_rate(struct spm_vreg *vreg)
+{
+	int rc;
+	u8 reg = 0;
+	int step, delay;
+
+	rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
+		vreg->spmi_base_addr + QPNP_FTS2_REG_STEP_CTRL, &reg, 1);
+	if (rc) {
+		dev_err(&vreg->spmi_dev->dev, "%s: could not read stepping control register, rc=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	step = (reg & QPNP_FTS2_STEP_CTRL_STEP_MASK)
+		>> QPNP_FTS2_STEP_CTRL_STEP_SHIFT;
+	delay = (reg & QPNP_FTS2_STEP_CTRL_DELAY_MASK)
+		>> QPNP_FTS2_STEP_CTRL_DELAY_SHIFT;
+
+	/* step_rate has units of uV/us. */
+	vreg->step_rate = QPNP_FTS2_CLOCK_RATE * vreg->range->step_uV
+				* (1 << step);
+	vreg->step_rate /= 1000 * (8 << delay);
+	vreg->step_rate = vreg->step_rate * QPNP_FTS2_STEP_MARGIN_NUM
+				/ QPNP_FTS2_STEP_MARGIN_DEN;
+
+	/* Ensure that the stepping rate is greater than 0. */
+	vreg->step_rate = max(vreg->step_rate, 1);
+
+	return rc;
+}
+
 static int __devinit spm_regulator_probe(struct spmi_device *spmi)
 {
 	struct device_node *node = spmi->dev.of_node;
@@ -299,6 +401,14 @@
 	if (rc)
 		return rc;
 
+	rc = qpnp_fts2_init_mode(vreg);
+	if (rc)
+		return rc;
+
+	rc = qpnp_fts2_init_step_rate(vreg);
+	if (rc)
+		return rc;
+
 	init_data = of_get_regulator_init_data(&spmi->dev, node);
 	if (!init_data) {
 		dev_err(&spmi->dev, "%s: unable to allocate memory\n",
@@ -334,8 +444,12 @@
 
 	dev_set_drvdata(&spmi->dev, vreg);
 
-	pr_info("name=%s, range=%d\n", vreg->rdesc.name,
-		(vreg->range == &fts2_range0) ? 0 : 1);
+	pr_info("name=%s, range=%s, voltage=%d uV, mode=%s, step rate=%d uV/us\n",
+		vreg->rdesc.name, vreg->range == &fts2_range0 ? "LV" : "MV",
+		vreg->uV,
+		vreg->init_mode & QPNP_FTS2_MODE_PWM ? "PWM" :
+		    (vreg->init_mode & QPNP_FTS2_MODE_AUTO ? "AUTO" : "PFM"),
+		vreg->step_rate);
 
 	return rc;
 }
diff --git a/block/blk-core.c b/block/blk-core.c
index 2b6595c..153240e 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1086,7 +1086,7 @@
 		 * urgent requests. We want to be able to track this
 		 * down.
 		 */
-		pr_err("%s(): requeueing an URGENT request", __func__);
+		pr_debug("%s(): requeueing an URGENT request", __func__);
 		WARN_ON(!q->dispatched_urgent);
 		q->dispatched_urgent = false;
 	}
@@ -1123,7 +1123,7 @@
 		 * urgent requests. We want to be able to track this
 		 * down.
 		 */
-		pr_err("%s(): reinserting an URGENT request", __func__);
+		pr_debug("%s(): reinserting an URGENT request", __func__);
 		WARN_ON(!q->dispatched_urgent);
 		q->dispatched_urgent = false;
 	}
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index f76d41a..9c2c8b1 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -689,9 +689,15 @@
 					 int len, int type)
 {
 	driver->pkt_length = len;
-	if (entry.process_id != NON_APPS_PROC && type != MODEM_DATA) {
-		diag_update_pkt_buffer(buf);
-		diag_update_sleeping_process(entry.process_id, PKT_TYPE);
+
+	/* If the process_id corresponds to an apps process */
+	if (entry.process_id != NON_APPS_PROC) {
+		/* If the message is to be sent to the apps process */
+		if (type != MODEM_DATA) {
+			diag_update_pkt_buffer(buf);
+			diag_update_sleeping_process(entry.process_id,
+							PKT_TYPE);
+		}
 	} else {
 		if (len > 0) {
 			if (entry.client_id < NUM_SMD_DATA_CHANNELS) {
diff --git a/drivers/crypto/msm/qce.h b/drivers/crypto/msm/qce.h
index 51a74b6..cf75e93 100644
--- a/drivers/crypto/msm/qce.h
+++ b/drivers/crypto/msm/qce.h
@@ -32,6 +32,8 @@
 #define SHA256_DIGESTSIZE		32
 #define SHA1_DIGESTSIZE			20
 
+#define AES_CE_BLOCK_SIZE		16
+
 /* key size in bytes */
 #define HMAC_KEY_SIZE			(SHA1_DIGESTSIZE)    /* hmac-sha1 */
 #define SHA_HMAC_KEY_SIZE		64
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 2b70d3f..a3a662a 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -1504,6 +1504,45 @@
 }
 #endif
 
+
+static void _qce_dump_descr_fifos_fail(struct qce_device *pce_dev)
+{
+	int i, j, ents;
+	struct sps_iovec *iovec = pce_dev->ce_sps.in_transfer.iovec;
+	uint32_t cmd_flags = SPS_IOVEC_FLAG_CMD;
+
+	printk(KERN_INFO "==============================================\n");
+	printk(KERN_INFO "CONSUMER (TX/IN/DEST) PIPE DESCRIPTOR\n");
+	printk(KERN_INFO "==============================================\n");
+	for (i = 0; i <  pce_dev->ce_sps.in_transfer.iovec_count; i++) {
+		printk(KERN_INFO " [%d] addr=0x%x  size=0x%x  flags=0x%x\n", i,
+					iovec->addr, iovec->size, iovec->flags);
+		if (iovec->flags & cmd_flags) {
+			struct sps_command_element *pced;
+
+			pced = (struct sps_command_element *)
+					(GET_VIRT_ADDR(iovec->addr));
+			ents = iovec->size/(sizeof(struct sps_command_element));
+			for (j = 0; j < ents; j++) {
+				printk(KERN_INFO "      [%d] [0x%x] 0x%x\n", j,
+					pced->addr, pced->data);
+				pced++;
+			}
+		}
+		iovec++;
+	}
+
+	printk(KERN_INFO "==============================================\n");
+	printk(KERN_INFO "PRODUCER (RX/OUT/SRC) PIPE DESCRIPTOR\n");
+	printk(KERN_INFO "==============================================\n");
+	iovec = pce_dev->ce_sps.out_transfer.iovec;
+	for (i = 0; i <  pce_dev->ce_sps.out_transfer.iovec_count; i++) {
+		printk(KERN_INFO " [%d] addr=0x%x  size=0x%x  flags=0x%x\n", i,
+				iovec->addr, iovec->size, iovec->flags);
+		iovec++;
+	}
+}
+
 static void _qce_sps_iovec_count_init(struct qce_device *pce_dev)
 {
 	pce_dev->ce_sps.in_transfer.iovec_count = 0;
@@ -1602,6 +1641,7 @@
 	if (rc) {
 		pr_err("sps_xfr() fail (consumer pipe=0x%x) rc = %d,",
 				(u32)pce_dev->ce_sps.consumer.pipe, rc);
+		_qce_dump_descr_fifos_fail(pce_dev);
 		return rc;
 	}
 	rc = sps_transfer(pce_dev->ce_sps.producer.pipe,
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index a09bb42..9870648 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1650,6 +1650,10 @@
 								 __func__);
 			goto error;
 		}
+		if (req->byteoffset >= AES_CE_BLOCK_SIZE) {
+			pr_err("%s: Invalid byte offset\n", __func__);
+			goto error;
+		}
 	}
 	/* Ensure zer ivlen for ECB  mode  */
 	if (req->ivlen > 0) {
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index bc9bddd..b1c1c5d 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -42,6 +42,7 @@
  */
 struct ion_iommu_priv_data {
 	struct page **pages;
+	unsigned int pages_uses_vmalloc;
 	int nrpages;
 	unsigned long size;
 };
@@ -118,6 +119,7 @@
 		unsigned int npages_to_vmap, total_pages, num_large_pages = 0;
 		unsigned long size_remaining = PAGE_ALIGN(size);
 		unsigned int max_order = ION_IS_CACHED(flags) ? 0 : orders[0];
+		unsigned int page_tbl_size;
 
 		data = kmalloc(sizeof(*data), GFP_KERNEL);
 		if (!data)
@@ -139,8 +141,24 @@
 
 		data->size = PFN_ALIGN(size);
 		data->nrpages = data->size >> PAGE_SHIFT;
-		data->pages = kzalloc(sizeof(struct page *)*data->nrpages,
-				GFP_KERNEL);
+		data->pages_uses_vmalloc = 0;
+		page_tbl_size = sizeof(struct page *) * data->nrpages;
+
+		if (page_tbl_size > SZ_8K) {
+			/*
+			 * Do fallback to ensure we have a balance between
+			 * performance and availability.
+			 */
+			data->pages = kmalloc(page_tbl_size,
+					      __GFP_COMP | __GFP_NORETRY |
+					      __GFP_NO_KSWAPD | __GFP_NOWARN);
+			if (!data->pages) {
+				data->pages = vmalloc(page_tbl_size);
+				data->pages_uses_vmalloc = 1;
+			}
+		} else {
+			data->pages = kmalloc(page_tbl_size, GFP_KERNEL);
+		}
 		if (!data->pages) {
 			ret = -ENOMEM;
 			goto err_free_data;
@@ -222,7 +240,10 @@
 	kfree(buffer->sg_table);
 	buffer->sg_table = 0;
 err1:
-	kfree(data->pages);
+	if (data->pages_uses_vmalloc)
+		vfree(data->pages);
+	else
+		kfree(data->pages);
 err_free_data:
 	kfree(data);
 
@@ -253,7 +274,10 @@
 	sg_free_table(table);
 	kfree(table);
 	table = 0;
-	kfree(data->pages);
+	if (data->pages_uses_vmalloc)
+		vfree(data->pages);
+	else
+		kfree(data->pages);
 	kfree(data);
 }
 
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index 3441afa..fc66328 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -25,6 +25,7 @@
 	adreno_drawctxt.o \
 	adreno_postmortem.o \
 	adreno_snapshot.o \
+	adreno_coresight.o \
 	adreno_a2xx.o \
 	adreno_a2xx_trace.o \
 	adreno_a2xx_snapshot.o \
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 5f435f3..0c398c4 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -165,8 +165,16 @@
 #define A3XX_RBBM_PERFCTR_PWR_0_HI 0x0EB
 #define A3XX_RBBM_PERFCTR_PWR_1_LO 0x0EC
 #define A3XX_RBBM_PERFCTR_PWR_1_HI 0x0ED
-#define A3XX_RBBM_DEBUG_BUS_CTL             0x111
-#define A3XX_RBBM_DEBUG_BUS_DATA_STATUS     0x112
+#define A3XX_RBBM_DEBUG_BUS_CTL 0x111
+#define A3XX_RBBM_DEBUG_BUS_DATA_STATUS 0x112
+#define A3XX_RBBM_DEBUG_BUS_STB_CTL0 0x11B
+#define A3XX_RBBM_DEBUG_BUS_STB_CTL1 0x11C
+#define A3XX_RBBM_INT_TRACE_BUS_CTL 0x11D
+#define A3XX_RBBM_EXT_TRACE_BUS_CTL 0x11E
+#define A3XX_RBBM_EXT_TRACE_STOP_CNT 0x11F
+#define A3XX_RBBM_EXT_TRACE_START_CNT 0x120
+#define A3XX_RBBM_EXT_TRACE_PERIOD_CNT 0x121
+#define A3XX_RBBM_EXT_TRACE_CMD 0x122
 
 /* Following two are same as on A2XX, just in a different place */
 #define A3XX_CP_PFP_UCODE_ADDR 0x1C9
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index a4f60f9..aad2882 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -18,6 +18,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/delay.h>
+#include <linux/of_coresight.h>
 
 #include <mach/socinfo.h>
 #include <mach/msm_bus_board.h>
@@ -1522,6 +1523,9 @@
 	if (ret)
 		goto err;
 
+	pdata->coresight_pdata = of_get_coresight_platform_data(&pdev->dev,
+			pdev->dev.of_node);
+
 	pdev->dev.platform_data = pdata;
 	return 0;
 
@@ -1595,6 +1599,7 @@
 adreno_probe(struct platform_device *pdev)
 {
 	struct kgsl_device *device;
+	struct kgsl_device_platform_data *pdata = NULL;
 	struct adreno_device *adreno_dev;
 	int status = -EINVAL;
 	bool is_dt;
@@ -1625,6 +1630,10 @@
 	kgsl_pwrscale_attach_policy(device, ADRENO_DEFAULT_PWRSCALE_POLICY);
 
 	device->flags &= ~KGSL_FLAGS_SOFT_RESET;
+	pdata = kgsl_device_get_drvdata(device);
+
+	adreno_coresight_init(pdev);
+
 	return 0;
 
 error_close_rb:
@@ -1643,6 +1652,8 @@
 	device = (struct kgsl_device *)pdev->id_entry->driver_data;
 	adreno_dev = ADRENO_DEVICE(device);
 
+	adreno_coresight_remove(pdev);
+
 	kgsl_pwrscale_detach_policy(device);
 	kgsl_pwrscale_close(device);
 
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index fa892b9..77b654b 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -80,6 +80,15 @@
 	ADRENO_REV_A305B = 335,
 };
 
+enum coresight_debug_reg {
+	DEBUG_BUS_CTL,
+	TRACE_STOP_CNT,
+	TRACE_START_CNT,
+	TRACE_PERIOD_CNT,
+	TRACE_CMD,
+	TRACE_BUS_CTL,
+};
+
 struct adreno_gpudev;
 
 struct adreno_device {
@@ -187,6 +196,10 @@
 	uint64_t (*perfcounter_read)(struct adreno_device *adreno_dev,
 		unsigned int group, unsigned int counter,
 		unsigned int offset);
+	int (*coresight_enable) (struct kgsl_device *device);
+	void (*coresight_disable) (struct kgsl_device *device);
+	void (*coresight_config_debug_reg) (struct kgsl_device *device,
+			int debug_reg, unsigned int val);
 };
 
 /*
@@ -269,6 +282,10 @@
 extern unsigned int ft_detect_regs[];
 extern const unsigned int ft_detect_regs_count;
 
+int adreno_coresight_enable(struct coresight_device *csdev);
+void adreno_coresight_disable(struct coresight_device *csdev);
+void adreno_coresight_remove(struct platform_device *pdev);
+int adreno_coresight_init(struct platform_device *pdev);
 
 int adreno_idle(struct kgsl_device *device);
 void adreno_regread(struct kgsl_device *device, unsigned int offsetwords,
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index a4b3121..1cdc87a 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -3235,6 +3235,108 @@
 	adreno_dev->gpu_cycles = 0;
 }
 
+/**
+ * a3xx_coresight_enable() - Enables debugging through coresight
+ * debug bus for adreno a3xx devices.
+ * @device: Pointer to GPU device structure
+ */
+int a3xx_coresight_enable(struct kgsl_device *device)
+{
+	mutex_lock(&device->mutex);
+	if (!kgsl_active_count_get(device)) {
+		adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_CTL, 0x0001093F);
+		adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_STB_CTL0,
+				0x00000000);
+		adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_STB_CTL1,
+				0xFFFFFFFE);
+		adreno_regwrite(device, A3XX_RBBM_INT_TRACE_BUS_CTL,
+				0x00201111);
+		adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_BUS_CTL,
+				0x89100010);
+		adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_STOP_CNT,
+				0x00017fff);
+		adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_START_CNT,
+				0x0001000f);
+		adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_PERIOD_CNT ,
+				0x0001ffff);
+		adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_CMD,
+				0x00000001);
+		kgsl_active_count_put(device);
+	}
+	mutex_unlock(&device->mutex);
+	return 0;
+}
+
+/**
+ * a3xx_coresight_disable() - Disables debugging through coresight
+ * debug bus for adreno a3xx devices.
+ * @device: Pointer to GPU device structure
+ */
+void a3xx_coresight_disable(struct kgsl_device *device)
+{
+	mutex_lock(&device->mutex);
+	if (!kgsl_active_count_get(device)) {
+		adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_CTL, 0x0);
+		adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_STB_CTL0, 0x0);
+		adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_STB_CTL1, 0x0);
+		adreno_regwrite(device, A3XX_RBBM_INT_TRACE_BUS_CTL, 0x0);
+		adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_BUS_CTL, 0x0);
+		adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_STOP_CNT, 0x0);
+		adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_START_CNT, 0x0);
+		adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_PERIOD_CNT , 0x0);
+		adreno_regwrite(device, A3XX_RBBM_EXT_TRACE_CMD, 0x0);
+		kgsl_active_count_put(device);
+	}
+	mutex_unlock(&device->mutex);
+}
+
+static void a3xx_coresight_write_reg(struct kgsl_device *device,
+		unsigned int wordoffset, unsigned int val)
+{
+	mutex_lock(&device->mutex);
+	if (!kgsl_active_count_get(device)) {
+		adreno_regwrite(device, wordoffset, val);
+		kgsl_active_count_put(device);
+	}
+	mutex_unlock(&device->mutex);
+}
+
+void a3xx_coresight_config_debug_reg(struct kgsl_device *device,
+		int debug_reg, unsigned int val)
+{
+	switch (debug_reg) {
+
+	case DEBUG_BUS_CTL:
+		a3xx_coresight_write_reg(device, A3XX_RBBM_DEBUG_BUS_CTL, val);
+		break;
+
+	case TRACE_STOP_CNT:
+		a3xx_coresight_write_reg(device, A3XX_RBBM_EXT_TRACE_STOP_CNT,
+				val);
+		break;
+
+	case TRACE_START_CNT:
+		a3xx_coresight_write_reg(device, A3XX_RBBM_EXT_TRACE_START_CNT,
+				val);
+		break;
+
+	case TRACE_PERIOD_CNT:
+		a3xx_coresight_write_reg(device, A3XX_RBBM_EXT_TRACE_PERIOD_CNT,
+				val);
+		break;
+
+	case TRACE_CMD:
+		a3xx_coresight_write_reg(device, A3XX_RBBM_EXT_TRACE_CMD, val);
+		break;
+
+	case TRACE_BUS_CTL:
+		a3xx_coresight_write_reg(device, A3XX_RBBM_EXT_TRACE_BUS_CTL,
+				val);
+		break;
+	}
+
+}
+
 /*
  * Define the available perfcounter groups - these get used by
  * adreno_perfcounter_get and adreno_perfcounter_put
@@ -3381,4 +3483,7 @@
 	.snapshot = a3xx_snapshot,
 	.perfcounter_enable = a3xx_perfcounter_enable,
 	.perfcounter_read = a3xx_perfcounter_read,
+	.coresight_enable = a3xx_coresight_enable,
+	.coresight_disable = a3xx_coresight_disable,
+	.coresight_config_debug_reg = a3xx_coresight_config_debug_reg,
 };
diff --git a/drivers/gpu/msm/adreno_coresight.c b/drivers/gpu/msm/adreno_coresight.c
new file mode 100644
index 0000000..e18568d
--- /dev/null
+++ b/drivers/gpu/msm/adreno_coresight.c
@@ -0,0 +1,219 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/of_coresight.h>
+#include <linux/coresight.h>
+#include <linux/memory_alloc.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include "kgsl.h"
+#include "kgsl_device.h"
+#include "adreno.h"
+
+struct coresight_attr {
+	struct device_attribute attr;
+	int regname;
+};
+
+#define CORESIGHT_CREATE_REG_ATTR(_attrname, _regname) \
+	struct coresight_attr coresight_attr_##_attrname = \
+	{ __ATTR(_attrname, S_IRUGO | S_IWUSR, gfx_show_reg, gfx_store_reg),\
+		_regname}
+
+/**
+ * adreno_coresight_enable() - Generic function to enable coresight debugging
+ * @csdev: Pointer to coresight's device struct
+ *
+ * This is a generic function to enable coresight debug bus on adreno
+ * devices. This should be used in all cases of enabling
+ * coresight debug bus for adreno devices. This function in turn calls
+ * the adreno device specific function through gpudev hook.
+ * This function is registered as the coresight enable function
+ * with coresight driver. It should only be called through coresight driver
+ * as that would ensure that the necessary setup required to be done
+ * on coresight driver's part is also done.
+ */
+int adreno_coresight_enable(struct coresight_device *csdev)
+{
+	struct kgsl_device *device = dev_get_drvdata(csdev->dev.parent);
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+	/* Check if coresight compatible device, return error otherwise */
+	if (adreno_dev->gpudev->coresight_enable)
+		return adreno_dev->gpudev->coresight_enable(device);
+	else
+		return -ENODEV;
+}
+
+/**
+ * adreno_coresight_disable() - Generic function to disable coresight debugging
+ * @csdev: Pointer to coresight's device struct
+ *
+ * This is a generic function to disable coresight debug bus on adreno
+ * devices. This should be used in all cases of disabling
+ * coresight debug bus for adreno devices. This function in turn calls
+ * the adreno device specific function through the gpudev hook.
+ * This function is registered as the coresight disable function
+ * with coresight driver. It should only be called through coresight driver
+ * as that would ensure that the necessary setup required to be done on
+ * coresight driver's part is also done.
+ */
+void adreno_coresight_disable(struct coresight_device *csdev)
+{
+	struct kgsl_device *device = dev_get_drvdata(csdev->dev.parent);
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+	/* Check if coresight compatible device, bail otherwise */
+	if (adreno_dev->gpudev->coresight_disable)
+		return adreno_dev->gpudev->coresight_disable(device);
+}
+
+static const struct coresight_ops_source adreno_coresight_ops_source = {
+	.enable = adreno_coresight_enable,
+	.disable = adreno_coresight_disable,
+};
+
+static const struct coresight_ops adreno_coresight_cs_ops = {
+	.source_ops = &adreno_coresight_ops_source,
+};
+
+void adreno_coresight_remove(struct platform_device *pdev)
+{
+	struct kgsl_device_platform_data *pdata = pdev->dev.platform_data;
+	coresight_unregister(pdata->csdev);
+}
+
+static ssize_t coresight_read_reg(struct kgsl_device *device,
+		unsigned int offset, char *buf)
+{
+	unsigned int regval = 0;
+
+	mutex_lock(&device->mutex);
+	if (!kgsl_active_count_get(device)) {
+		adreno_regread(device, offset, &regval);
+		kgsl_active_count_put(device);
+	}
+	mutex_unlock(&device->mutex);
+	return snprintf(buf, PAGE_SIZE, "0x%X", regval);
+}
+
+static inline unsigned int coresight_convert_reg(const char *buf)
+{
+	long regval = 0;
+	int rv = 0;
+
+	rv = kstrtoul(buf, 16, &regval);
+	if (!rv)
+		return (unsigned int)regval;
+	else
+		return rv;
+}
+
+static ssize_t gfx_show_reg(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct kgsl_device *device = dev_get_drvdata(dev->parent);
+	struct coresight_attr *csight_attr = container_of(attr,
+			struct coresight_attr, attr);
+	return coresight_read_reg(device, csight_attr->regname, buf);
+}
+
+static ssize_t gfx_store_reg(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t size)
+{
+	struct kgsl_device *device = dev_get_drvdata(dev->parent);
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+	struct coresight_attr *csight_attr = container_of(attr,
+			struct coresight_attr, attr);
+	unsigned int regval = 0;
+
+	regval = coresight_convert_reg(buf);
+
+	if (adreno_dev->gpudev->coresight_config_debug_reg)
+		adreno_dev->gpudev->coresight_config_debug_reg(device,
+				csight_attr->regname, regval);
+	return size;
+}
+
+CORESIGHT_CREATE_REG_ATTR(config_debug_bus, DEBUG_BUS_CTL);
+CORESIGHT_CREATE_REG_ATTR(config_trace_stop_cnt, TRACE_STOP_CNT);
+CORESIGHT_CREATE_REG_ATTR(config_trace_start_cnt, TRACE_START_CNT);
+CORESIGHT_CREATE_REG_ATTR(config_trace_period_cnt, TRACE_PERIOD_CNT);
+CORESIGHT_CREATE_REG_ATTR(config_trace_cmd, TRACE_CMD);
+CORESIGHT_CREATE_REG_ATTR(config_trace_bus_ctl, TRACE_BUS_CTL);
+
+static struct attribute *gfx_attrs[] = {
+	&coresight_attr_config_debug_bus.attr.attr,
+	&coresight_attr_config_trace_start_cnt.attr.attr,
+	&coresight_attr_config_trace_stop_cnt.attr.attr,
+	&coresight_attr_config_trace_period_cnt.attr.attr,
+	&coresight_attr_config_trace_cmd.attr.attr,
+	&coresight_attr_config_trace_bus_ctl.attr.attr,
+	NULL,
+};
+
+static struct attribute_group gfx_attr_grp = {
+	.attrs = gfx_attrs,
+};
+
+static const struct attribute_group *gfx_attr_grps[] = {
+	&gfx_attr_grp,
+	NULL,
+};
+
+int adreno_coresight_init(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct kgsl_device_platform_data *pdata = pdev->dev.platform_data;
+	struct device *dev = &pdev->dev;
+	struct coresight_desc *desc;
+
+	if (IS_ERR_OR_NULL(pdata->coresight_pdata))
+		return -ENODATA;
+
+
+	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+
+
+	desc->type = CORESIGHT_DEV_TYPE_SOURCE;
+	desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_BUS;
+	desc->ops = &adreno_coresight_cs_ops;
+	desc->pdata = pdata->coresight_pdata;
+	desc->dev = &pdev->dev;
+	desc->owner = THIS_MODULE;
+	desc->groups = gfx_attr_grps;
+	pdata->csdev = coresight_register(desc);
+	if (IS_ERR(pdata->csdev)) {
+		ret = PTR_ERR(pdata->csdev);
+		goto err;
+	}
+
+	return 0;
+
+err:
+	devm_kfree(dev, desc);
+	return ret;
+}
+
diff --git a/drivers/iommu/msm_iommu-v0.c b/drivers/iommu/msm_iommu-v0.c
index 06f4a0f..10fa5b1 100644
--- a/drivers/iommu/msm_iommu-v0.c
+++ b/drivers/iommu/msm_iommu-v0.c
@@ -32,6 +32,7 @@
 #include <mach/msm_iommu_priv.h>
 #include <mach/iommu.h>
 #include <mach/msm_smem.h>
+#include <mach/msm_bus.h>
 
 #define MRC(reg, processor, op1, crn, crm, op2)				\
 __asm__ __volatile__ (							\
@@ -135,6 +136,20 @@
 	return msm_iommu_remote_lock.lock;
 }
 
+static int apply_bus_vote(struct msm_iommu_drvdata *drvdata, unsigned int vote)
+{
+	int ret = 0;
+
+	if (drvdata->bus_client) {
+		ret = msm_bus_scale_client_update_request(drvdata->bus_client,
+							  vote);
+		if (ret)
+			pr_err("%s: Failed to vote for bus: %d\n", __func__,
+				vote);
+	}
+	return ret;
+}
+
 static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
 {
 	int ret;
@@ -202,6 +217,7 @@
 struct iommu_access_ops iommu_access_ops_v0 = {
 	.iommu_power_on = __enable_regulators,
 	.iommu_power_off = __disable_regulators,
+	.iommu_bus_vote = apply_bus_vote,
 	.iommu_clk_on = __enable_clocks,
 	.iommu_clk_off = __disable_clocks,
 	.iommu_lock_initialize = _iommu_lock_initialize,
@@ -506,6 +522,11 @@
 			goto unlock;
 		}
 
+	ret = apply_bus_vote(iommu_drvdata, 1);
+
+	if (ret)
+		goto unlock;
+
 	ret = __enable_clocks(iommu_drvdata);
 	if (ret)
 		goto unlock;
@@ -572,6 +593,9 @@
 	msm_iommu_remote_spin_unlock();
 
 	__disable_clocks(iommu_drvdata);
+
+	apply_bus_vote(iommu_drvdata, 0);
+
 	list_del_init(&ctx_drvdata->attached_elm);
 	ctx_drvdata->attached_domain = NULL;
 unlock:
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index 8e68beb..f90bf6c 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -32,6 +32,7 @@
 #include <mach/iommu.h>
 #include <mach/msm_iommu_priv.h>
 #include <mach/iommu_perfmon.h>
+#include <mach/msm_bus.h>
 #include "msm_iommu_pagetable.h"
 
 /* bitmap of the page sizes currently supported */
@@ -62,6 +63,20 @@
 	regulator_disable(drvdata->gdsc);
 }
 
+static int apply_bus_vote(struct msm_iommu_drvdata *drvdata, unsigned int vote)
+{
+	int ret = 0;
+
+	if (drvdata->bus_client) {
+		ret = msm_bus_scale_client_update_request(drvdata->bus_client,
+							  vote);
+		if (ret)
+			pr_err("%s: Failed to vote for bus: %d\n", __func__,
+				vote);
+	}
+	return ret;
+}
+
 static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
 {
 	int ret;
@@ -116,6 +131,7 @@
 struct iommu_access_ops iommu_access_ops_v1 = {
 	.iommu_power_on = __enable_regulators,
 	.iommu_power_off = __disable_regulators,
+	.iommu_bus_vote = apply_bus_vote,
 	.iommu_clk_on = __enable_clocks,
 	.iommu_clk_off = __disable_clocks,
 	.iommu_lock_acquire = _iommu_lock_acquire,
@@ -513,6 +529,10 @@
 	if (ret)
 		goto fail;
 
+	ret = apply_bus_vote(iommu_drvdata, 1);
+	if (ret)
+		goto fail;
+
 	ret = __enable_clocks(iommu_drvdata);
 	if (ret) {
 		__disable_regulators(iommu_drvdata);
@@ -602,6 +622,8 @@
 
 	__disable_clocks(iommu_drvdata);
 
+	apply_bus_vote(iommu_drvdata, 0);
+
 	__disable_regulators(iommu_drvdata);
 
 	list_del_init(&ctx_drvdata->attached_elm);
diff --git a/drivers/iommu/msm_iommu_dev-v0.c b/drivers/iommu/msm_iommu_dev-v0.c
index 059216e..4ee65d8 100644
--- a/drivers/iommu/msm_iommu_dev-v0.c
+++ b/drivers/iommu/msm_iommu_dev-v0.c
@@ -30,10 +30,13 @@
 #include <mach/iommu_perfmon.h>
 #include <mach/iommu_hw-v0.h>
 #include <mach/iommu.h>
+#include <mach/msm_bus.h>
 
 static DEFINE_MUTEX(iommu_list_lock);
 static LIST_HEAD(iommu_list);
 
+static struct of_device_id msm_iommu_v0_ctx_match_table[];
+
 void msm_iommu_add_drv(struct msm_iommu_drvdata *drv)
 {
 	mutex_lock(&iommu_list_lock);
@@ -77,10 +80,13 @@
 	}
 	mutex_unlock(&iommu_list_lock);
 
-	if (!dev || !dev_get_drvdata(dev))
-		pr_err("Could not find context <%s>\n", ctx_name);
 	put_device(dev);
 
+	if (!dev || !dev_get_drvdata(dev)) {
+		pr_debug("Could not find context <%s>\n", ctx_name);
+		dev = ERR_PTR(-EPROBE_DEFER);
+	}
+
 	return dev;
 }
 EXPORT_SYMBOL(msm_iommu_get_ctx);
@@ -128,74 +134,24 @@
 	mb();
 }
 
-static int msm_iommu_parse_dt(struct platform_device *pdev,
-				struct msm_iommu_drvdata *drvdata,
-				int *needs_alt_core_clk)
-{
-#ifdef CONFIG_OF_DEVICE
-	struct device_node *child;
-	struct resource *r;
-	u32 glb_offset = 0;
-	int ret;
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!r) {
-		pr_err("%s: Missing property reg\n", __func__);
-		return -EINVAL;
-	}
-	drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
-	if (!drvdata->base) {
-		pr_err("%s: Unable to ioremap %pr\n", __func__, r);
-		return -ENOMEM;
-	}
-	drvdata->glb_base = drvdata->base;
-
-	if (!of_property_read_u32(pdev->dev.of_node, "qcom,glb-offset",
-			&glb_offset)) {
-		drvdata->glb_base += glb_offset;
-	} else {
-		pr_err("%s: Missing property qcom,glb-offset\n", __func__);
-		return -EINVAL;
-	}
-
-	for_each_child_of_node(pdev->dev.of_node, child) {
-		drvdata->ncb++;
-		if (!of_platform_device_create(child, NULL, &pdev->dev))
-			pr_err("Failed to create %s device\n", child->name);
-	}
-
-	ret = of_property_read_string(pdev->dev.of_node, "label",
-			&drvdata->name);
-	if (ret) {
-		pr_err("%s: Missing property label\n", __func__);
-		return -EINVAL;
-	}
-
-	*needs_alt_core_clk = of_property_read_bool(pdev->dev.of_node,
-						   "qcom,needs-alt-core-clk");
-
-	drvdata->sec_id = -1;
-	drvdata->ttbr_split = 0;
-#endif
-	return 0;
-}
-
 static int __get_clocks(struct platform_device *pdev,
 			struct msm_iommu_drvdata *drvdata,
 			int needs_alt_core_clk)
 {
 	int ret = 0;
 
-	drvdata->pclk = clk_get(&pdev->dev, "iface_clk");
+	drvdata->pclk = devm_clk_get(&pdev->dev, "iface_clk");
 	if (IS_ERR(drvdata->pclk)) {
 		ret = PTR_ERR(drvdata->pclk);
 		drvdata->pclk = NULL;
-		pr_err("Unable to get %s clock for %s IOMMU device\n",
-			dev_name(&pdev->dev), drvdata->name);
+		if (ret != -EPROBE_DEFER) {
+			pr_err("Unable to get %s clock for %s IOMMU device\n",
+				dev_name(&pdev->dev), drvdata->name);
+		}
 		goto fail;
 	}
 
-	drvdata->clk = clk_get(&pdev->dev, "core_clk");
+	drvdata->clk = devm_clk_get(&pdev->dev, "core_clk");
 
 	if (!IS_ERR(drvdata->clk)) {
 		if (clk_get_rate(drvdata->clk) == 0) {
@@ -208,8 +164,10 @@
 
 	if (needs_alt_core_clk) {
 		drvdata->aclk = devm_clk_get(&pdev->dev, "alt_core_clk");
-		if (IS_ERR(drvdata->aclk))
-			return PTR_ERR(drvdata->aclk);
+		if (IS_ERR(drvdata->aclk)) {
+			ret = PTR_ERR(drvdata->aclk);
+			goto fail;
+		}
 	}
 
 	if (drvdata->aclk && clk_get_rate(drvdata->aclk) == 0) {
@@ -222,15 +180,127 @@
 	return ret;
 }
 
-static void __put_clocks(struct msm_iommu_drvdata *drvdata)
+#ifdef CONFIG_OF_DEVICE
+
+static int __get_bus_vote_client(struct platform_device *pdev,
+				  struct msm_iommu_drvdata *drvdata)
 {
-	if (drvdata->aclk)
-		clk_put(drvdata->aclk);
-	if (drvdata->clk)
-		clk_put(drvdata->clk);
-	clk_put(drvdata->pclk);
+	int ret = 0;
+	struct msm_bus_scale_pdata *bs_table;
+	const char *dummy;
+
+	/* Check whether bus scaling has been specified for this node */
+	ret = of_property_read_string(pdev->dev.of_node, "qcom,msm-bus,name",
+				      &dummy);
+	if (ret)
+		return 0;
+
+	bs_table = msm_bus_cl_get_pdata(pdev);
+
+	if (bs_table) {
+		drvdata->bus_client = msm_bus_scale_register_client(bs_table);
+		if (IS_ERR(&drvdata->bus_client)) {
+			pr_err("%s(): Bus client register failed.\n", __func__);
+			ret = -EINVAL;
+		}
+	}
+	return ret;
 }
 
+static void __put_bus_vote_client(struct msm_iommu_drvdata *drvdata)
+{
+	msm_bus_scale_unregister_client(drvdata->bus_client);
+	drvdata->bus_client = 0;
+}
+
+static int msm_iommu_parse_dt(struct platform_device *pdev,
+				struct msm_iommu_drvdata *drvdata)
+{
+	struct device_node *child;
+	struct resource *r;
+	u32 glb_offset = 0;
+	int ret = 0;
+	int needs_alt_core_clk;
+
+	ret = __get_bus_vote_client(pdev, drvdata);
+
+	if (ret)
+		goto fail;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		pr_err("%s: Missing property reg\n", __func__);
+		ret = -EINVAL;
+		goto fail;
+	}
+	drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
+	if (!drvdata->base) {
+		pr_err("%s: Unable to ioremap %pr\n", __func__, r);
+		ret = -ENOMEM;
+		goto fail;
+	}
+	drvdata->glb_base = drvdata->base;
+
+	if (!of_property_read_u32(pdev->dev.of_node, "qcom,glb-offset",
+			&glb_offset)) {
+		drvdata->glb_base += glb_offset;
+	} else {
+		pr_err("%s: Missing property qcom,glb-offset\n", __func__);
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	for_each_child_of_node(pdev->dev.of_node, child)
+		drvdata->ncb++;
+
+	ret = of_property_read_string(pdev->dev.of_node, "label",
+			&drvdata->name);
+	if (ret) {
+		pr_err("%s: Missing property label\n", __func__);
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	needs_alt_core_clk = of_property_read_bool(pdev->dev.of_node,
+						   "qcom,needs-alt-core-clk");
+
+	ret = __get_clocks(pdev, drvdata, needs_alt_core_clk);
+
+	if (ret)
+		goto fail;
+
+	drvdata->sec_id = -1;
+	drvdata->ttbr_split = 0;
+
+	ret = of_platform_populate(pdev->dev.of_node,
+				   msm_iommu_v0_ctx_match_table,
+				   NULL, &pdev->dev);
+	if (ret) {
+		pr_err("Failed to create iommu context device\n");
+		goto fail;
+	}
+
+	return ret;
+
+fail:
+	__put_bus_vote_client(drvdata);
+	return ret;
+}
+
+#else
+static int msm_iommu_parse_dt(struct platform_device *pdev,
+				struct msm_iommu_drvdata *drvdata)
+{
+	return 0;
+}
+
+static void __put_bus_vote_client(struct msm_iommu_drvdata *drvdata)
+{
+
+}
+
+#endif
+
 /*
  * Do a basic check of the IOMMU by performing an ATS operation
  * on context bank 0.
@@ -322,23 +392,27 @@
 	struct msm_iommu_drvdata *drvdata;
 	struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
 	int ret;
-	int needs_alt_core_clk = 0;
 
 	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
 
 	if (!drvdata) {
 		ret = -ENOMEM;
-		goto fail;
+		goto fail_mem;
 	}
 
 	if (pdev->dev.of_node) {
-		ret = msm_iommu_parse_dt(pdev, drvdata, &needs_alt_core_clk);
+		ret = msm_iommu_parse_dt(pdev, drvdata);
 		if (ret)
 			goto fail;
 	} else if (pdev->dev.platform_data) {
 		struct resource *r, *r2;
 		resource_size_t	len;
 
+		ret = __get_clocks(pdev, drvdata, 0);
+
+		if (ret)
+			goto fail;
+
 		r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 						"physbase");
 
@@ -349,7 +423,8 @@
 
 		len = resource_size(r);
 
-		r2 = request_mem_region(r->start, len, r->name);
+		r2 = devm_request_mem_region(&pdev->dev, r->start,
+					     len, r->name);
 		if (!r2) {
 			pr_err("Could not request memory region: %pr\n", r);
 			ret = -EBUSY;
@@ -379,11 +454,6 @@
 
 	drvdata->dev = &pdev->dev;
 
-	ret = __get_clocks(pdev, drvdata, needs_alt_core_clk);
-
-	if (ret)
-		goto fail;
-
 	iommu_access_ops_v0.iommu_clk_on(drvdata);
 
 	msm_iommu_reset(drvdata->base, drvdata->glb_base, drvdata->ncb);
@@ -392,14 +462,14 @@
 	if (ret)
 		goto fail_clk;
 
+	iommu_access_ops_v0.iommu_clk_off(drvdata);
+
 	pr_info("device %s mapped at %p, with %d ctx banks\n",
 		drvdata->name, drvdata->base, drvdata->ncb);
 
 	msm_iommu_add_drv(drvdata);
 	platform_set_drvdata(pdev, drvdata);
 
-	iommu_access_ops_v0.iommu_clk_off(drvdata);
-
 	pmon_info = msm_iommu_pm_alloc(&pdev->dev);
 	if (pmon_info != NULL) {
 		ret = msm_iommu_pmon_parse_dt(pdev, pmon_info);
@@ -428,8 +498,9 @@
 
 fail_clk:
 	iommu_access_ops_v0.iommu_clk_off(drvdata);
-	__put_clocks(drvdata);
 fail:
+	__put_bus_vote_client(drvdata);
+fail_mem:
 	return ret;
 }
 
@@ -437,12 +508,13 @@
 {
 	struct msm_iommu_drvdata *drv = NULL;
 
+	msm_iommu_pm_iommu_unregister(&pdev->dev);
+	msm_iommu_pm_free(&pdev->dev);
+
 	drv = platform_get_drvdata(pdev);
 	if (drv) {
+		__put_bus_vote_client(drv);
 		msm_iommu_remove_drv(drv);
-		if (drv->clk)
-			clk_put(drv->clk);
-		clk_put(drv->pclk);
 		platform_set_drvdata(pdev, NULL);
 	}
 	return 0;
@@ -458,26 +530,28 @@
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq > 0) {
-		ret = request_threaded_irq(irq, NULL,
+		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
 				msm_iommu_fault_handler,
 				IRQF_ONESHOT | IRQF_SHARED,
 				"msm_iommu_nonsecure_irq", ctx_drvdata);
 		if (ret) {
 			pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
-			return ret;
+			goto out;
 		}
 	}
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!r) {
 		pr_err("Could not find reg property for context bank\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	ret = of_address_to_resource(pdev->dev.parent->of_node, 0, &rp);
 	if (ret) {
 		pr_err("of_address_to_resource failed\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	/* Calculate the context bank number using the base addresses. CB0
@@ -488,29 +562,34 @@
 	if (of_property_read_string(pdev->dev.of_node, "label",
 					&ctx_drvdata->name)) {
 		pr_err("Could not find label property\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-ctx-mids",
 			     &nmid_array_size)) {
 		pr_err("Could not find iommu-ctx-mids property\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 	if (nmid_array_size >= sizeof(ctx_drvdata->sids)) {
 		pr_err("Too many mids defined - array size: %u, mids size: %u\n",
 			nmid_array_size, sizeof(ctx_drvdata->sids));
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 	nmid = nmid_array_size / sizeof(*ctx_drvdata->sids);
 
 	if (of_property_read_u32_array(pdev->dev.of_node, "qcom,iommu-ctx-mids",
 				       ctx_drvdata->sids, nmid)) {
 		pr_err("Could not find iommu-ctx-mids property\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 	ctx_drvdata->nsid = nmid;
 
-	return 0;
+out:
+	return ret;
 }
 
 static void __program_m2v_tables(struct msm_iommu_drvdata *drvdata,
@@ -560,7 +639,7 @@
 	drvdata = dev_get_drvdata(pdev->dev.parent);
 
 	if (!drvdata) {
-		ret = -ENODEV;
+		ret = -EPROBE_DEFER;
 		goto fail;
 	}
 
@@ -578,8 +657,10 @@
 
 	if (pdev->dev.of_node) {
 		ret = msm_iommu_ctx_parse_dt(pdev, ctx_drvdata);
-		if (ret)
+		if (ret) {
+			platform_set_drvdata(pdev, NULL);
 			goto fail;
+		}
 	} else if (pdev->dev.platform_data) {
 		struct msm_iommu_ctx_dev *c = pdev->dev.platform_data;
 
@@ -601,7 +682,8 @@
 			goto fail;
 		}
 
-		ret = request_threaded_irq(irq, NULL, msm_iommu_fault_handler,
+		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+					msm_iommu_fault_handler,
 					IRQF_ONESHOT | IRQF_SHARED,
 					"msm_iommu_nonsecure_irq", ctx_drvdata);
 
@@ -647,15 +729,15 @@
 	.remove		= __devexit_p(msm_iommu_remove),
 };
 
-static struct of_device_id msm_iommu_ctx_match_table[] = {
-	{ .name = "qcom,iommu-ctx", },
+static struct of_device_id msm_iommu_v0_ctx_match_table[] = {
+	{ .compatible = "qcom,msm-smmu-v0-ctx", },
 	{}
 };
 
 static struct platform_driver msm_iommu_ctx_driver = {
 	.driver = {
 		.name	= "msm_iommu_ctx",
-		.of_match_table = msm_iommu_ctx_match_table,
+		.of_match_table = msm_iommu_v0_ctx_match_table,
 	},
 	.probe		= msm_iommu_ctx_probe,
 	.remove		= __devexit_p(msm_iommu_ctx_remove),
diff --git a/drivers/iommu/msm_iommu_dev-v1.c b/drivers/iommu/msm_iommu_dev-v1.c
index 418a086..c0e05f4 100644
--- a/drivers/iommu/msm_iommu_dev-v1.c
+++ b/drivers/iommu/msm_iommu_dev-v1.c
@@ -28,6 +28,9 @@
 #include <mach/iommu_hw-v1.h>
 #include <mach/iommu.h>
 #include <mach/iommu_perfmon.h>
+#include <mach/msm_bus.h>
+
+static struct of_device_id msm_iommu_v1_ctx_match_table[];
 
 static int msm_iommu_parse_bfb_settings(struct platform_device *pdev,
 				    struct msm_iommu_drvdata *drvdata)
@@ -84,6 +87,36 @@
 	return 0;
 }
 
+static int __get_bus_vote_client(struct platform_device *pdev,
+				  struct msm_iommu_drvdata *drvdata)
+{
+	int ret = 0;
+	struct msm_bus_scale_pdata *bs_table;
+	const char *dummy;
+
+	/* Check whether bus scaling has been specified for this node */
+	ret = of_property_read_string(pdev->dev.of_node, "qcom,msm-bus,name",
+				      &dummy);
+	if (ret)
+		return 0;
+
+	bs_table = msm_bus_cl_get_pdata(pdev);
+
+	if (bs_table) {
+		drvdata->bus_client = msm_bus_scale_register_client(bs_table);
+		if (IS_ERR(&drvdata->bus_client)) {
+			pr_err("%s(): Bus client register failed.\n", __func__);
+			ret = -EINVAL;
+		}
+	}
+	return ret;
+}
+
+static void __put_bus_vote_client(struct msm_iommu_drvdata *drvdata)
+{
+	msm_bus_scale_unregister_client(drvdata->bus_client);
+}
+
 static int msm_iommu_parse_dt(struct platform_device *pdev,
 				struct msm_iommu_drvdata *drvdata)
 {
@@ -92,17 +125,18 @@
 	struct resource *r;
 
 	drvdata->dev = &pdev->dev;
-	msm_iommu_add_drv(drvdata);
+
+	ret = __get_bus_vote_client(pdev, drvdata);
+
+	if (ret)
+		goto fail;
 
 	ret = msm_iommu_parse_bfb_settings(pdev, drvdata);
 	if (ret)
 		goto fail;
 
-	for_each_child_of_node(pdev->dev.of_node, child) {
+	for_each_child_of_node(pdev->dev.of_node, child)
 		drvdata->ncb++;
-		if (!of_platform_device_create(child, NULL, &pdev->dev))
-			pr_err("Failed to create %s device\n", child->name);
-	}
 
 	drvdata->asid = devm_kzalloc(&pdev->dev, drvdata->ncb * sizeof(int),
 				     GFP_KERNEL);
@@ -137,8 +171,15 @@
 	drvdata->halt_enabled = of_property_read_bool(pdev->dev.of_node,
 						      "qcom,iommu-enable-halt");
 
-	return 0;
+	ret = of_platform_populate(pdev->dev.of_node,
+				   msm_iommu_v1_ctx_match_table,
+				   NULL, &pdev->dev);
+	if (ret)
+		pr_err("Failed to create iommu context device\n");
+
+	msm_iommu_add_drv(drvdata);
 fail:
+	__put_bus_vote_client(drvdata);
 	return ret;
 }
 
@@ -224,7 +265,7 @@
 
 	drvdata->gdsc = devm_regulator_get(&pdev->dev, "vdd");
 	if (IS_ERR(drvdata->gdsc))
-		return -EINVAL;
+		return PTR_ERR(drvdata->gdsc);
 
 	drvdata->alt_gdsc = devm_regulator_get(&pdev->dev, "qcom,alt-vdd");
 	if (IS_ERR(drvdata->alt_gdsc))
@@ -301,10 +342,8 @@
 
 	drv = platform_get_drvdata(pdev);
 	if (drv) {
+		__put_bus_vote_client(drv);
 		msm_iommu_remove_drv(drv);
-		if (drv->clk)
-			clk_put(drv->clk);
-		clk_put(drv->pclk);
 		platform_set_drvdata(pdev, NULL);
 	}
 	return 0;
@@ -314,7 +353,7 @@
 				struct msm_iommu_ctx_drvdata *ctx_drvdata)
 {
 	struct resource *r, rp;
-	int irq, ret;
+	int irq = 0, ret = 0;
 	u32 nsid;
 
 	ctx_drvdata->secure_context = of_property_read_bool(pdev->dev.of_node,
@@ -323,25 +362,27 @@
 	if (!ctx_drvdata->secure_context) {
 		irq = platform_get_irq(pdev, 0);
 		if (irq > 0) {
-			ret = request_threaded_irq(irq, NULL,
+			ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
 					msm_iommu_fault_handler_v2,
 					IRQF_ONESHOT | IRQF_SHARED,
 					"msm_iommu_nonsecure_irq", pdev);
 			if (ret) {
 				pr_err("Request IRQ %d failed with ret=%d\n",
 					irq, ret);
-				return ret;
+				goto out;
 			}
 		}
 	}
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!r)
-		return -EINVAL;
+	if (!r) {
+		ret = -EINVAL;
+		goto out;
+	}
 
 	ret = of_address_to_resource(pdev->dev.parent->of_node, 0, &rp);
 	if (ret)
-		return -EINVAL;
+		goto out;
 
 	/* Calculate the context bank number using the base addresses. The
 	 * first 8 pages belong to the global address space which is followed
@@ -354,21 +395,26 @@
 					&ctx_drvdata->name))
 		ctx_drvdata->name = dev_name(&pdev->dev);
 
-	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-ctx-sids", &nsid))
-		return -EINVAL;
-
-	if (nsid >= sizeof(ctx_drvdata->sids))
-		return -EINVAL;
+	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-ctx-sids", &nsid)) {
+		ret = -EINVAL;
+		goto out;
+	}
+	if (nsid >= sizeof(ctx_drvdata->sids)) {
+		ret = -EINVAL;
+		goto out;
+	}
 
 	if (of_property_read_u32_array(pdev->dev.of_node, "qcom,iommu-ctx-sids",
 				       ctx_drvdata->sids,
 				       nsid / sizeof(*ctx_drvdata->sids))) {
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 	ctx_drvdata->nsid = nsid;
 
 	ctx_drvdata->asid = -1;
-	return 0;
+out:
+	return ret;
 }
 
 static int __devinit msm_iommu_ctx_probe(struct platform_device *pdev)
@@ -386,12 +432,14 @@
 
 	ctx_drvdata->pdev = pdev;
 	INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
-	platform_set_drvdata(pdev, ctx_drvdata);
 
 	ret = msm_iommu_ctx_parse_dt(pdev, ctx_drvdata);
-	if (!ret)
+	if (!ret) {
+		platform_set_drvdata(pdev, ctx_drvdata);
+
 		dev_info(&pdev->dev, "context %s using bank %d\n",
 			 ctx_drvdata->name, ctx_drvdata->num);
+	}
 
 	return ret;
 }
@@ -416,15 +464,15 @@
 	.remove		= __devexit_p(msm_iommu_remove),
 };
 
-static struct of_device_id msm_iommu_ctx_match_table[] = {
-	{ .name = "qcom,iommu-ctx", },
+static struct of_device_id msm_iommu_v1_ctx_match_table[] = {
+	{ .compatible = "qcom,msm-smmu-v1-ctx", },
 	{}
 };
 
 static struct platform_driver msm_iommu_ctx_driver = {
 	.driver = {
 		.name	= "msm_iommu_ctx_v1",
-		.of_match_table = msm_iommu_ctx_match_table,
+		.of_match_table = msm_iommu_v1_ctx_match_table,
 	},
 	.probe		= msm_iommu_ctx_probe,
 	.remove		= __devexit_p(msm_iommu_ctx_remove),
diff --git a/drivers/iommu/msm_iommu_perfmon.c b/drivers/iommu/msm_iommu_perfmon.c
index a11d794..958c6ca 100644
--- a/drivers/iommu/msm_iommu_perfmon.c
+++ b/drivers/iommu/msm_iommu_perfmon.c
@@ -257,6 +257,7 @@
 					dev_get_drvdata(iommu->iommu_dev);
 
 	iommu->ops->iommu_power_on(iommu_drvdata);
+	iommu->ops->iommu_bus_vote(iommu_drvdata, 1);
 	iommu->ops->iommu_clk_on(iommu_drvdata);
 
 	/* Reset counters in HW */
@@ -311,6 +312,7 @@
 
 	iommu->ops->iommu_lock_release();
 	iommu->ops->iommu_clk_off(iommu_drvdata);
+	iommu->ops->iommu_bus_vote(iommu_drvdata, 0);
 	iommu->ops->iommu_power_off(iommu_drvdata);
 
 	pr_info("%s: TLB performance monitoring turned OFF\n",
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index 0233e18..0f238b2 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -1631,7 +1631,7 @@
 	if (!rc)
 		led->flash_cfg->headroom = (u8) val;
 	else if (rc == -EINVAL)
-		led->flash_cfg->headroom = HEADROOM_300mV;
+		led->flash_cfg->headroom = HEADROOM_500mV;
 	else
 		return rc;
 
@@ -1656,7 +1656,7 @@
 	if (!rc)
 		led->flash_cfg->startup_dly = (u8) val;
 	else if (rc == -EINVAL)
-		led->flash_cfg->startup_dly = DELAY_32us;
+		led->flash_cfg->startup_dly = DELAY_128us;
 	else
 		return rc;
 
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 8caa9dd..b8c3c44 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -1577,9 +1577,11 @@
 
 		if (pktsize == 192) {
 			if (leadingbytes)
-				memcpy(timestamp, &buf[p], TIMESTAMP_LEN);
+				memcpy(timestamp, &demux->tsbuf[p],
+					TIMESTAMP_LEN);
 			else
-				memcpy(timestamp, &buf[188], TIMESTAMP_LEN);
+				memcpy(timestamp, &demux->tsbuf[188],
+					TIMESTAMP_LEN);
 		} else {
 			memset(timestamp, 0, TIMESTAMP_LEN);
 		}
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
index 4579cee..08fa7dd 100644
--- a/drivers/media/platform/msm/camera_v2/camera/camera.c
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -539,7 +539,6 @@
 		rc = msm_create_session(pvdev->vdev->num, pvdev->vdev);
 		if (rc < 0)
 			goto session_fail;
-
 		rc = msm_create_command_ack_q(pvdev->vdev->num, 0);
 		if (rc < 0)
 			goto command_ack_q_fail;
@@ -611,6 +610,7 @@
 
 		/* Donot wait, imaging server may have crashed */
 		msm_post_event(&event, -1);
+		msm_delete_command_ack_q(pvdev->vdev->num, 0);
 
 		/* This should take care of both normal close
 		 * and application crashes */
@@ -622,7 +622,6 @@
 
 		/* Donot wait, imaging server may have crashed */
 		msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
-
 		msm_delete_command_ack_q(pvdev->vdev->num,
 			sp->stream_id);
 
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
index b31b3f1..ff9c9b8 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
@@ -121,6 +121,7 @@
 	vfe_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 	vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE;
 	vfe_dev->subdev.sd.entity.name = pdev->name;
+	vfe_dev->subdev.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x2;
 	rc = msm_sd_register(&vfe_dev->subdev);
 	if (rc != 0) {
 		pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index dd8db03..ee205c0 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -389,6 +389,11 @@
 		rc = msm_isp_update_axi_stream(vfe_dev, arg);
 		mutex_unlock(&vfe_dev->core_mutex);
 		break;
+	case MSM_SD_SHUTDOWN:
+		while (vfe_dev->vfe_open_cnt != 0)
+			msm_isp_close_node(sd, NULL);
+		break;
+
 	default:
 		pr_err("%s: Invalid ISP command\n", __func__);
 		rc = -EINVAL;
@@ -912,11 +917,10 @@
 
 	rc = vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev);
 	if (rc <= 0)
-		pr_err("%s: halt timeout\n", __func__);
+		pr_err("%s: halt timeout rc=%ld\n", __func__, rc);
 
 	vfe_dev->buf_mgr->ops->buf_mgr_deinit(vfe_dev->buf_mgr);
 	vfe_dev->hw_info->vfe_ops.core_ops.release_hw(vfe_dev);
-
 	vfe_dev->vfe_open_cnt--;
 	mutex_unlock(&vfe_dev->core_mutex);
 	mutex_unlock(&vfe_dev->realtime_mutex);
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index a95eda7..dc1bcc3 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -91,7 +91,6 @@
 	BUG_ON(!ispif);
 
 	memset(ispif->sof_count, 0, sizeof(ispif->sof_count));
-
 	for (i = 0; i < ispif->vfe_info.num_vfe; i++) {
 
 		msm_camera_io_w(1 << PIX0_LINE_BUF_EN_BIT,
@@ -105,9 +104,13 @@
 			ISPIF_VFE_m_IRQ_CLEAR_1(i));
 		msm_camera_io_w(0xFFFFFFFF, ispif->base +
 			ISPIF_VFE_m_IRQ_CLEAR_2(i));
+
 		msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INPUT_SEL(i));
-		msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
-		msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
+
+		msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
+			ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
+		msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
+			ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
 
 		msm_camera_io_w(0, ispif->base +
 			ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
@@ -905,6 +908,12 @@
 	switch (cmd) {
 	case VIDIOC_MSM_ISPIF_CFG:
 		return msm_ispif_cmd(sd, arg);
+	case MSM_SD_SHUTDOWN: {
+		struct ispif_device *ispif =
+			(struct ispif_device *)v4l2_get_subdevdata(sd);
+		msm_ispif_release(ispif);
+		return 0;
+	}
 	default:
 		pr_err("%s: invalid cmd 0x%x received\n", __func__, cmd);
 		return -ENOIOCTLCMD;
@@ -986,6 +995,7 @@
 	ispif->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 	ispif->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ISPIF;
 	ispif->msm_sd.sd.entity.name = pdev->name;
+	ispif->msm_sd.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x1;
 	rc = msm_sd_register(&ispif->msm_sd);
 	if (rc) {
 		pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
index c805c3d..3cc21a7 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
@@ -91,4 +91,6 @@
 
 #define ISPIF_IRQ_GLOBAL_CLEAR_CMD               0x1
 
+#define ISPIF_STOP_INTF_IMMEDIATELY              0xAAAAAAAA
+
 #endif /* __MSM_ISPIF_HWREG_V2_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index be9f613..5581723 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -31,6 +31,7 @@
 #include "msm_sd.h"
 
 static struct v4l2_device *msm_v4l2_dev;
+static struct list_head    ordered_sd_list;
 
 static struct msm_queue_head *msm_session_q;
 
@@ -301,6 +302,20 @@
 	return rc;
 }
 
+static void msm_add_sd_in_position(struct msm_sd_subdev *msm_subdev,
+	struct list_head *sd_list)
+{
+	struct msm_sd_subdev *temp_sd;
+
+	list_for_each_entry(temp_sd, sd_list, list) {
+		if (msm_subdev->close_seq < temp_sd->close_seq) {
+			list_add_tail(&msm_subdev->list, &temp_sd->list);
+			return;
+		}
+	}
+	list_add_tail(&msm_subdev->list, sd_list);
+}
+
 int msm_sd_register(struct msm_sd_subdev *msm_subdev)
 {
 	if (WARN_ON(!msm_subdev))
@@ -309,6 +324,7 @@
 	if (WARN_ON(!msm_v4l2_dev) || WARN_ON(!msm_v4l2_dev->dev))
 		return -EIO;
 
+	msm_add_sd_in_position(msm_subdev, &ordered_sd_list);
 	return __msm_sd_register_subdev(&msm_subdev->sd);
 }
 
@@ -397,66 +413,40 @@
 
 	spin_lock_irqsave(&(session->command_ack_q.lock), flags);
 	list_del_init(&cmd_ack->list);
+	kzfree(cmd_ack);
 	session->command_ack_q.len--;
 	spin_unlock_irqrestore(&(session->command_ack_q.lock), flags);
 }
 
-static inline int __msm_v4l2_subdev_shutdown(struct v4l2_subdev *sd)
-{
-	return 0;
-}
-
-static void msm_sd_try_shutdown(void)
-{
-	unsigned long flags;
-	struct v4l2_subdev *sd;
-
-	/* release all subdev's resource */
-	spin_lock_irqsave(&msm_v4l2_dev->lock, flags);
-	if (!list_empty(&msm_v4l2_dev->subdevs)) {
-		list_for_each_entry(sd, &msm_v4l2_dev->subdevs, list)
-			__msm_v4l2_subdev_shutdown(sd);
-	}
-	spin_unlock_irqrestore(&msm_v4l2_dev->lock, flags);
-}
-
-static inline int __msm_sd_close_session_streams(struct v4l2_subdev *sd,
+static inline int __msm_sd_close_subdevs(struct msm_sd_subdev *msm_sd,
 	struct msm_sd_close_ioctl *sd_close)
 {
+	struct v4l2_subdev *sd;
+	sd = &msm_sd->sd;
+	pr_debug("%s: Shutting down subdev %s", __func__, sd->name);
+
+	v4l2_subdev_call(sd, core, ioctl, MSM_SD_SHUTDOWN, sd_close);
+	v4l2_subdev_call(sd, core, s_power, 0);
+
 	return 0;
 }
 
 static inline int __msm_destroy_session_streams(void *d1, void *d2)
 {
 	struct msm_stream *stream = d1;
-	struct msm_sd_close_ioctl *sd_close = d2;
-	struct v4l2_subdev *sd;
-	unsigned long flags;
 
-	sd_close->stream = stream->stream_id;
-
-	spin_lock_irqsave(&msm_v4l2_dev->lock, flags);
-	if (!list_empty(&msm_v4l2_dev->subdevs))
-		list_for_each_entry(sd, &msm_v4l2_dev->subdevs, list)
-			__msm_sd_close_session_streams(sd, sd_close);
-	spin_unlock_irqrestore(&msm_v4l2_dev->lock, flags);
 	INIT_LIST_HEAD(&stream->queued_list);
 	return 0;
 }
 
 static void msm_destroy_session_streams(struct msm_session *session)
 {
-	struct msm_sd_close_ioctl sd_close;
 
-	/* to ensure error handling purpose, it needs to detach all subdevs
-	 * which are being connected to streams */
 	if (!session)
 		return;
 
-	sd_close.session = session->session_id;
-
 	msm_queue_traverse_action(&session->stream_q, struct msm_stream, list,
-		__msm_destroy_session_streams, &sd_close);
+		__msm_destroy_session_streams, NULL);
 
 	msm_queue_drain(&session->stream_q, struct msm_stream, list);
 }
@@ -694,16 +684,13 @@
 	struct msm_v4l2_event_data *event_data =
 		(struct msm_v4l2_event_data *)&event.u.data[0];
 	struct msm_session *session = d1;
-	mutex_lock(&session->lock);
+
 	event.type = MSM_CAMERA_V4L2_EVENT_TYPE;
 	event.id   = MSM_CAMERA_MSM_NOTIFY;
 	event_data->command = MSM_CAMERA_PRIV_SHUTDOWN;
 
 	v4l2_event_queue(session->event_q.vdev, &event);
 
-	msm_destroy_session_streams(session);
-	msm_remove_session_cmd_ack_q(session);
-	mutex_unlock(&session->lock);
 	return 0;
 }
 
@@ -712,22 +699,23 @@
 	int rc = 0;
 	unsigned long flags;
 	struct msm_video_device *pvdev = video_drvdata(filep);
+	struct msm_sd_close_ioctl sd_close;
+	struct msm_sd_subdev *msm_sd;
 
-	/* 1st thing 1st, send v4l2_event to HAL immediately,
-	 * to ensure error handling purpose, it needs to detach all subdevs
-	 * which are being connected to streams */
+	/*stop all hardware blocks immediately*/
+	if (!list_empty(&msm_v4l2_dev->subdevs))
+		list_for_each_entry(msm_sd, &ordered_sd_list, list)
+			__msm_sd_close_subdevs(msm_sd, &sd_close);
+
+	/* send v4l2_event to HAL next*/
 	msm_queue_traverse_action(msm_session_q, struct msm_session, list,
 		__msm_close_destry_session_notify_apps, NULL);
 
-	msm_queue_drain(msm_session_q, struct msm_session, list);
-
 	spin_lock_irqsave(&msm_eventq_lock, flags);
 	msm_eventq = NULL;
 	spin_unlock_irqrestore(&msm_eventq_lock, flags);
 	v4l2_fh_release(filep);
 
-	msm_sd_try_shutdown();
-
 	spin_lock_irqsave(&msm_pid_lock, flags);
 	put_pid(msm_pid);
 	msm_pid = NULL;
@@ -754,7 +742,6 @@
 	int rc;
 	unsigned long flags;
 	struct msm_video_device *pvdev = video_drvdata(filep);
-
 	BUG_ON(!pvdev);
 
 	/* !!! only ONE open is allowed !!! */
@@ -990,7 +977,7 @@
 	msm_init_queue(msm_session_q);
 	spin_lock_init(&msm_eventq_lock);
 	spin_lock_init(&msm_pid_lock);
-
+	INIT_LIST_HEAD(&ordered_sd_list);
 	goto probe_end;
 
 v4l2_fail:
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
index b0ff832..895f452 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -161,6 +161,7 @@
 	msm_buf_mngr_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 	msm_buf_mngr_dev->subdev.sd.entity.group_id =
 		MSM_CAMERA_SUBDEV_BUF_MNGR;
+	msm_buf_mngr_dev->subdev.close_seq = MSM_SD_CLOSE_4TH_CATEGORY;
 	rc = msm_sd_register(&msm_buf_mngr_dev->subdev);
 	if (rc != 0) {
 		pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
diff --git a/drivers/media/platform/msm/camera_v2/msm_sd.h b/drivers/media/platform/msm/camera_v2/msm_sd.h
index 958e030..7c1519d 100644
--- a/drivers/media/platform/msm/camera_v2/msm_sd.h
+++ b/drivers/media/platform/msm/camera_v2/msm_sd.h
@@ -50,10 +50,12 @@
 #define MSM_SD_CLOSE_1ST_CATEGORY  0x00010000
 #define MSM_SD_CLOSE_2ND_CATEGORY  0x00020000
 #define MSM_SD_CLOSE_3RD_CATEGORY  0x00030000
+#define MSM_SD_CLOSE_4TH_CATEGORY  0x00040000
 
 struct msm_sd_subdev {
 	struct v4l2_subdev sd;
 	int close_seq;
+	struct list_head list;
 };
 
 struct msm_sd_req_sd {
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 5a174f5..4dd3f3d 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -43,6 +43,9 @@
 
 #define CONFIG_MSM_CPP_DBG 0
 
+/* dump the frame command before writing to the hardware */
+#define  MSM_CPP_DUMP_FRM_CMD 0
+
 #if CONFIG_MSM_CPP_DBG
 #define CPP_DBG(fmt, args...) pr_err(fmt, ##args)
 #else
@@ -208,7 +211,6 @@
 		pr_err("ION import failed\n");
 		goto QUEUE_BUFF_ERROR1;
 	}
-
 	rc = ion_map_iommu(cpp_dev->client, buff->map_info.ion_handle,
 		cpp_dev->domain_num, 0, SZ_4K, 0,
 		(unsigned long *)&buff->map_info.phy_addr,
@@ -237,6 +239,7 @@
 static void msm_cpp_dequeue_buffer_info(struct cpp_device *cpp_dev,
 	struct msm_cpp_buffer_map_list_t *buff)
 {
+
 	ion_unmap_iommu(cpp_dev->client, buff->map_info.ion_handle,
 		cpp_dev->domain_num, 0);
 	ion_free(cpp_dev->client, buff->map_info.ion_handle);
@@ -390,6 +393,8 @@
 			pr_err("Queue not free sessionid: %d, streamid: %d\n",
 				cpp_dev->buff_queue[i].session_id,
 				cpp_dev->buff_queue[i].stream_id);
+			msm_cpp_dequeue_buff_info_list
+				(cpp_dev, &cpp_dev->buff_queue[i]);
 			msm_cpp_free_buff_queue_entry(cpp_dev,
 				cpp_dev->buff_queue[i].session_id,
 				cpp_dev->buff_queue[i].stream_id);
@@ -821,9 +826,16 @@
 {
 	uint32_t i;
 	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+
 	mutex_lock(&cpp_dev->mutex);
+
+	if (cpp_dev->cpp_open_cnt == 0) {
+		mutex_unlock(&cpp_dev->mutex);
+		return 0;
+	}
+
 	for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
-		if (cpp_dev->cpp_subscribe_list[i].vfh == &fh->vfh) {
+		if (cpp_dev->cpp_subscribe_list[i].active == 1) {
 			cpp_dev->cpp_subscribe_list[i].active = 0;
 			cpp_dev->cpp_subscribe_list[i].vfh = NULL;
 			break;
@@ -835,7 +847,6 @@
 		return -ENODEV;
 	}
 
-	CPP_DBG("close %d %p\n", i, &fh->vfh);
 	cpp_dev->cpp_open_cnt--;
 	if (cpp_dev->cpp_open_cnt == 0) {
 		msm_camera_io_w(0x0, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL);
@@ -843,6 +854,7 @@
 		cpp_release_hardware(cpp_dev);
 		cpp_dev->state = CPP_STATE_OFF;
 	}
+
 	mutex_unlock(&cpp_dev->mutex);
 	return 0;
 }
@@ -888,8 +900,7 @@
 		event_qcmd->command = processed_frame;
 		CPP_DBG("fid %d\n", processed_frame->frame_id);
 		msm_enqueue(&cpp_dev->eventData_q, &event_qcmd->list_eventdata);
-
-		if (!processed_frame->output_buffer_info.processed_divert) {
+		if (!processed_frame->output_buffer_info[0].processed_divert) {
 			memset(&buff_mgr_info, 0 ,
 				sizeof(struct msm_buf_mngr_info));
 			buff_mgr_info.session_id =
@@ -899,7 +910,7 @@
 			buff_mgr_info.frame_id = processed_frame->frame_id;
 			buff_mgr_info.timestamp = processed_frame->timestamp;
 			buff_mgr_info.index =
-				processed_frame->output_buffer_info.index;
+				processed_frame->output_buffer_info[0].index;
 			rc = msm_cpp_buffer_ops(cpp_dev,
 				VIDIOC_MSM_BUF_MNGR_BUF_DONE,
 				&buff_mgr_info);
@@ -908,6 +919,28 @@
 				rc = -EINVAL;
 			}
 		}
+
+		if (processed_frame->duplicate_output  &&
+			!processed_frame->
+				output_buffer_info[1].processed_divert) {
+			memset(&buff_mgr_info, 0 ,
+				sizeof(struct msm_buf_mngr_info));
+			buff_mgr_info.session_id =
+			((processed_frame->duplicate_identity >> 16) & 0xFFFF);
+			buff_mgr_info.stream_id =
+				(processed_frame->duplicate_identity & 0xFFFF);
+			buff_mgr_info.frame_id = processed_frame->frame_id;
+			buff_mgr_info.timestamp = processed_frame->timestamp;
+			buff_mgr_info.index =
+				processed_frame->output_buffer_info[1].index;
+			rc = msm_cpp_buffer_ops(cpp_dev,
+				VIDIOC_MSM_BUF_MNGR_BUF_DONE,
+					&buff_mgr_info);
+			if (rc < 0) {
+				pr_err("error putting buffer\n");
+				rc = -EINVAL;
+			}
+		}
 		v4l2_evt.id = processed_frame->inst_id;
 		v4l2_evt.type = V4L2_EVENT_CPP_FRAME_DONE;
 		v4l2_event_queue(cpp_dev->msm_sd.sd.devnode, &v4l2_evt);
@@ -915,6 +948,23 @@
 	return rc;
 }
 
+#if MSM_CPP_DUMP_FRM_CMD
+static int msm_cpp_dump_frame_cmd(uint32_t *cmd, int32_t len)
+{
+	int i;
+	pr_err("%s: -------- cpp frame cmd msg start --------", __func__);
+	for (i = 0; i < len; i++)
+		pr_err("%s: msg[%03d] = 0x%08x", __func__, i, cmd[i]);
+	pr_err("%s: --------- cpp frame cmd msg end ---------", __func__);
+	return 0;
+}
+#else
+static int msm_cpp_dump_frame_cmd(uint32_t *cmd, int32_t len)
+{
+	return 0;
+}
+#endif
+
 static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev,
 	struct msm_queue_cmd *frame_qcmd)
 {
@@ -927,6 +977,8 @@
 		msm_enqueue(&cpp_dev->processing_q,
 					&frame_qcmd->list_frame);
 		msm_cpp_write(0x6, cpp_dev->base);
+		msm_cpp_dump_frame_cmd(process_frame->cpp_cmd_msg,
+				process_frame->msg_len);
 		for (i = 0; i < process_frame->msg_len; i++)
 			msm_cpp_write(process_frame->cpp_cmd_msg[i],
 				cpp_dev->base);
@@ -951,7 +1003,7 @@
 	struct msm_cpp_frame_info_t *new_frame =
 		kzalloc(sizeof(struct msm_cpp_frame_info_t), GFP_KERNEL);
 	uint32_t *cpp_frame_msg;
-	unsigned long in_phyaddr, out_phyaddr;
+	unsigned long in_phyaddr, out_phyaddr0, out_phyaddr1;
 	uint16_t num_stripes = 0;
 	struct msm_buf_mngr_info buff_mgr_info;
 	struct msm_cpp_frame_info_t *u_frame_info =
@@ -1001,7 +1053,7 @@
 		goto ERROR2;
 	}
 
-	memset(&new_frame->output_buffer_info, 0,
+	memset(&new_frame->output_buffer_info[0], 0,
 		sizeof(struct msm_cpp_buffer_info_t));
 	memset(&buff_mgr_info, 0, sizeof(struct msm_buf_mngr_info));
 	buff_mgr_info.session_id = ((new_frame->identity >> 16) & 0xFFFF);
@@ -1013,17 +1065,49 @@
 		pr_debug("error getting buffer rc:%d\n", rc);
 		goto ERROR2;
 	}
-
-	new_frame->output_buffer_info.index = buff_mgr_info.index;
-	out_phyaddr = msm_cpp_fetch_buffer_info(cpp_dev,
-		&new_frame->output_buffer_info,
+	new_frame->output_buffer_info[0].index = buff_mgr_info.index;
+	out_phyaddr0 = msm_cpp_fetch_buffer_info(cpp_dev,
+		&new_frame->output_buffer_info[0],
 		((new_frame->identity >> 16) & 0xFFFF),
 		(new_frame->identity & 0xFFFF));
-	if (!out_phyaddr) {
+	if (!out_phyaddr0) {
 		pr_err("error gettting output physical address\n");
 		rc = -EINVAL;
 		goto ERROR3;
 	}
+	out_phyaddr1 = out_phyaddr0;
+
+	/* get buffer for duplicate output */
+	if (new_frame->duplicate_output) {
+		CPP_DBG("duplication enabled, dup_id=0x%x",
+			new_frame->duplicate_identity);
+		memset(&new_frame->output_buffer_info[1], 0,
+			sizeof(struct msm_cpp_buffer_info_t));
+		memset(&buff_mgr_info, 0, sizeof(struct msm_buf_mngr_info));
+		buff_mgr_info.session_id =
+			((new_frame->duplicate_identity >> 16) & 0xFFFF);
+		buff_mgr_info.stream_id =
+			(new_frame->duplicate_identity & 0xFFFF);
+		rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_GET_BUF,
+			&buff_mgr_info);
+		if (rc < 0) {
+			rc = -EAGAIN;
+			pr_err("error getting buffer rc:%d\n", rc);
+			goto ERROR2;
+		}
+		new_frame->output_buffer_info[1].index = buff_mgr_info.index;
+		out_phyaddr1 = msm_cpp_fetch_buffer_info(cpp_dev,
+			&new_frame->output_buffer_info[1],
+			((new_frame->duplicate_identity >> 16) & 0xFFFF),
+			(new_frame->duplicate_identity & 0xFFFF));
+		if (!out_phyaddr1) {
+			pr_err("error gettting output physical address\n");
+			rc = -EINVAL;
+			goto ERROR3;
+		}
+		/* set duplicate enable bit */
+		cpp_frame_msg[5] |= 0x1;
+	}
 
 	num_stripes = ((cpp_frame_msg[12] >> 20) & 0x3FF) +
 		((cpp_frame_msg[12] >> 10) & 0x3FF) +
@@ -1031,10 +1115,10 @@
 
 	for (i = 0; i < num_stripes; i++) {
 		cpp_frame_msg[133 + i * 27] += (uint32_t) in_phyaddr;
-		cpp_frame_msg[139 + i * 27] += (uint32_t) out_phyaddr;
-		cpp_frame_msg[140 + i * 27] += (uint32_t) out_phyaddr;
-		cpp_frame_msg[141 + i * 27] += (uint32_t) out_phyaddr;
-		cpp_frame_msg[142 + i * 27] += (uint32_t) out_phyaddr;
+		cpp_frame_msg[139 + i * 27] += (uint32_t) out_phyaddr0;
+		cpp_frame_msg[140 + i * 27] += (uint32_t) out_phyaddr1;
+		cpp_frame_msg[141 + i * 27] += (uint32_t) out_phyaddr0;
+		cpp_frame_msg[142 + i * 27] += (uint32_t) out_phyaddr1;
 	}
 
 	frame_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
@@ -1245,6 +1329,13 @@
 		kfree(event_qcmd);
 		break;
 	}
+	case MSM_SD_SHUTDOWN: {
+		mutex_unlock(&cpp_dev->mutex);
+		while (cpp_dev->cpp_open_cnt != 0)
+			cpp_close_node(sd, NULL);
+		rc = 0;
+		break;
+	}
 	}
 	mutex_unlock(&cpp_dev->mutex);
 	CPP_DBG("X\n");
@@ -1446,6 +1537,7 @@
 	cpp_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 	cpp_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CPP;
 	cpp_dev->msm_sd.sd.entity.name = pdev->name;
+	cpp_dev->msm_sd.close_seq = MSM_SD_CLOSE_3RD_CATEGORY;
 	msm_sd_register(&cpp_dev->msm_sd);
 	msm_cpp_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner;
 	msm_cpp_v4l2_subdev_fops.open = v4l2_subdev_fops.open;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index e1b978f..b115738 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -629,6 +629,9 @@
 		return msm_actuator_get_subdev_id(a_ctrl, argp);
 	case VIDIOC_MSM_ACTUATOR_CFG:
 		return msm_actuator_config(a_ctrl, argp);
+	case MSM_SD_SHUTDOWN:
+		msm_actuator_close(sd, NULL);
+		return 0;
 	default:
 		return -ENOIOCTLCMD;
 	}
@@ -710,6 +713,7 @@
 	media_entity_init(&act_ctrl_t->msm_sd.sd.entity, 0, NULL, 0);
 	act_ctrl_t->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 	act_ctrl_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
+	act_ctrl_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
 	msm_sd_register(&act_ctrl_t->msm_sd);
 	CDBG("succeeded\n");
 	CDBG("Exit\n");
@@ -780,6 +784,7 @@
 	media_entity_init(&msm_actuator_t->msm_sd.sd.entity, 0, NULL, 0);
 	msm_actuator_t->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 	msm_actuator_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
+	msm_actuator_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
 	msm_sd_register(&msm_actuator_t->msm_sd);
 	CDBG("Exit\n");
 	return rc;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index 3409b3e..f3da41c 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -773,6 +773,12 @@
 	case VIDIOC_MSM_CCI_CFG:
 		rc = msm_cci_config(sd, arg);
 		break;
+	case MSM_SD_SHUTDOWN: {
+		struct msm_camera_cci_ctrl ctrl_cmd;
+		ctrl_cmd.cmd = MSM_CCI_RELEASE;
+		rc = msm_cci_config(sd, &ctrl_cmd);
+		break;
+	}
 	default:
 		rc = -ENOIOCTLCMD;
 	}
@@ -1007,6 +1013,7 @@
 		goto cci_release_mem;
 	}
 	disable_irq(new_cci_dev->irq->start);
+	new_cci_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x6;
 	msm_sd_register(&new_cci_dev->msm_sd);
 	new_cci_dev->pdev = pdev;
 	msm_cci_init_cci_params(new_cci_dev);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
index 33eaa69..4db6855 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
@@ -460,6 +460,7 @@
 		rc = msm_csid_cmd(csid_dev, arg);
 		break;
 	case VIDIOC_MSM_CSID_RELEASE:
+	case MSM_SD_SHUTDOWN:
 		rc = msm_csid_release(csid_dev);
 		break;
 	default:
@@ -552,6 +553,7 @@
 	media_entity_init(&new_csid_dev->msm_sd.sd.entity, 0, NULL, 0);
 	new_csid_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 	new_csid_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CSID;
+	new_csid_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x5;
 	msm_sd_register(&new_csid_dev->msm_sd);
 
 	rc = request_irq(new_csid_dev->irq->start, msm_csid_irq,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
index 7d3a1fc..429d151 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
@@ -570,6 +570,7 @@
 		rc = msm_csiphy_cmd(csiphy_dev, arg);
 		break;
 	case VIDIOC_MSM_CSIPHY_RELEASE:
+	case MSM_SD_SHUTDOWN:
 		rc = msm_csiphy_release(csiphy_dev, arg);
 		break;
 	default:
@@ -665,7 +666,7 @@
 	media_entity_init(&new_csiphy_dev->msm_sd.sd.entity, 0, NULL, 0);
 	new_csiphy_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 	new_csiphy_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CSIPHY;
-
+	new_csiphy_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x4;
 	msm_sd_register(&new_csiphy_dev->msm_sd);
 	new_csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
 	return 0;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
index 9119a13..044fd31 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
@@ -81,6 +81,7 @@
 	media_entity_init(&fctrl->msm_sd.sd.entity, 0, NULL, 0);
 	fctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 	fctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_LED_FLASH;
+	fctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1;
 	msm_sd_register(&fctrl->msm_sd);
 
 	CDBG("probe success\n");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
index 27d3d40..d56a5252 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
@@ -1050,6 +1050,7 @@
 	struct msm_sensor_power_setting_array *power_setting_array = NULL;
 	struct msm_sensor_power_setting *power_setting = NULL;
 	struct msm_camera_sensor_board_info *data = s_ctrl->sensordata;
+	s_ctrl->stop_setting_valid = 0;
 
 	CDBG("%s:%d\n", __func__, __LINE__);
 	power_setting_array = &s_ctrl->power_setting_array;
@@ -1149,9 +1150,13 @@
 
 static void msm_sensor_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
 {
-	s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table(
-		s_ctrl->sensor_i2c_client, &s_ctrl->stop_setting);
-	kfree(s_ctrl->stop_setting.reg_setting);
+	mutex_lock(s_ctrl->msm_sensor_mutex);
+	if (s_ctrl->sensor_state == MSM_SENSOR_POWER_UP) {
+		s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table(
+			s_ctrl->sensor_i2c_client, &s_ctrl->stop_setting);
+		kfree(s_ctrl->stop_setting.reg_setting);
+	}
+	mutex_unlock(s_ctrl->msm_sensor_mutex);
 	return;
 }
 
@@ -1168,6 +1173,7 @@
 	case VIDIOC_MSM_SENSOR_CFG:
 		return s_ctrl->func_tbl->sensor_config(s_ctrl, argp);
 	case VIDIOC_MSM_SENSOR_RELEASE:
+	case MSM_SD_SHUTDOWN:
 		msm_sensor_stop_stream(s_ctrl);
 		return 0;
 	default:
@@ -1282,6 +1288,13 @@
 		struct msm_camera_i2c_reg_setting conf_array;
 		struct msm_camera_i2c_reg_array *reg_setting = NULL;
 
+		if (s_ctrl->sensor_state != MSM_SENSOR_POWER_UP) {
+			pr_err("%s:%d failed: invalid state %d\n", __func__,
+				__LINE__, s_ctrl->sensor_state);
+			rc = -EFAULT;
+			break;
+		}
+
 		if (copy_from_user(&conf_array,
 			(void *)cdata->cfg.setting,
 			sizeof(struct msm_camera_i2c_reg_setting))) {
@@ -1316,6 +1329,13 @@
 		struct msm_camera_i2c_seq_reg_setting conf_array;
 		struct msm_camera_i2c_seq_reg_array *reg_setting = NULL;
 
+		if (s_ctrl->sensor_state != MSM_SENSOR_POWER_UP) {
+			pr_err("%s:%d failed: invalid state %d\n", __func__,
+				__LINE__, s_ctrl->sensor_state);
+			rc = -EFAULT;
+			break;
+		}
+
 		if (copy_from_user(&conf_array,
 			(void *)cdata->cfg.setting,
 			sizeof(struct msm_camera_i2c_seq_reg_setting))) {
@@ -1350,23 +1370,54 @@
 	}
 
 	case CFG_POWER_UP:
-		if (s_ctrl->sensordata->misc_regulator)
-			msm_sensor_misc_regulator(s_ctrl, 1);
-
-		if (s_ctrl->func_tbl->sensor_power_up)
-			rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
-		else
+		if (s_ctrl->sensor_state != MSM_SENSOR_POWER_DOWN) {
+			pr_err("%s:%d failed: invalid state %d\n", __func__,
+				__LINE__, s_ctrl->sensor_state);
 			rc = -EFAULT;
+			break;
+		}
+		if (s_ctrl->func_tbl->sensor_power_up) {
+			if (s_ctrl->sensordata->misc_regulator)
+				msm_sensor_misc_regulator(s_ctrl, 1);
+
+			rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+			if (rc < 0) {
+				pr_err("%s:%d failed rc %ld\n", __func__,
+					__LINE__, rc);
+				break;
+			}
+			s_ctrl->sensor_state = MSM_SENSOR_POWER_UP;
+			pr_err("%s:%d sensor state %d\n", __func__, __LINE__,
+				s_ctrl->sensor_state);
+		} else {
+			rc = -EFAULT;
+		}
 		break;
 
 	case CFG_POWER_DOWN:
-		if (s_ctrl->sensordata->misc_regulator)
-			msm_sensor_misc_regulator(s_ctrl, 0);
-		if (s_ctrl->func_tbl->sensor_power_down)
+		if (s_ctrl->sensor_state != MSM_SENSOR_POWER_UP) {
+			pr_err("%s:%d failed: invalid state %d\n", __func__,
+				__LINE__, s_ctrl->sensor_state);
+			rc = -EFAULT;
+			break;
+		}
+		if (s_ctrl->func_tbl->sensor_power_down) {
+			if (s_ctrl->sensordata->misc_regulator)
+				msm_sensor_misc_regulator(s_ctrl, 0);
+
 			rc = s_ctrl->func_tbl->sensor_power_down(
 				s_ctrl);
-		else
+			if (rc < 0) {
+				pr_err("%s:%d failed rc %ld\n", __func__,
+					__LINE__, rc);
+				break;
+			}
+			s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
+			pr_err("%s:%d sensor state %d\n", __func__, __LINE__,
+				s_ctrl->sensor_state);
+		} else {
 			rc = -EFAULT;
+		}
 		break;
 
 	case CFG_SET_STOP_STREAM_SETTING: {
@@ -1380,6 +1431,7 @@
 			rc = -EFAULT;
 			break;
 		}
+		s_ctrl->stop_setting_valid = 1;
 
 		reg_setting = stop_setting->reg_setting;
 		stop_setting->reg_setting = kzalloc(stop_setting->size *
@@ -1417,8 +1469,10 @@
 	int rc = 0;
 	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
 	mutex_lock(s_ctrl->msm_sensor_mutex);
-	if (!on)
-		rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+	if (!on && s_ctrl->sensor_state == MSM_SENSOR_POWER_UP) {
+		s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+		s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN;
+	}
 	if (s_ctrl->free_power_setting == true) {
 		kfree(s_ctrl->power_setting_array.power_setting);
 		s_ctrl->free_power_setting = false;
@@ -1558,6 +1612,7 @@
 	rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id);
 	CDBG("%s rc %d session_id %d\n", __func__, rc, session_id);
 	s_ctrl->sensordata->sensor_info->session_id = session_id;
+	s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
 	msm_sd_register(&s_ctrl->msm_sd);
 	CDBG("%s:%d\n", __func__, __LINE__);
 
@@ -1649,6 +1704,7 @@
 		&session_id);
 	CDBG("%s rc %d session_id %d\n", __func__, rc, session_id);
 	s_ctrl->sensordata->sensor_info->session_id = session_id;
+	s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
 	msm_sd_register(&s_ctrl->msm_sd);
 	CDBG("%s:%d\n", __func__, __LINE__);
 
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
index a1128a6..fe11a56 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h
@@ -37,6 +37,11 @@
 
 struct msm_sensor_ctrl_t;
 
+enum msm_sensor_state_t {
+	MSM_SENSOR_POWER_DOWN,
+	MSM_SENSOR_POWER_UP,
+};
+
 struct msm_sensor_fn_t {
 	int (*sensor_config) (struct msm_sensor_ctrl_t *, void __user *);
 	int (*sensor_power_down)
@@ -62,10 +67,12 @@
 	struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
 	struct msm_sensor_fn_t *func_tbl;
 	struct msm_camera_i2c_reg_setting stop_setting;
+	bool stop_setting_valid;
 	bool free_power_setting;
 	struct msm_cam_clk_info *clk_info;
 	uint16_t clk_info_size;
 	void *misc_regulator;
+	enum msm_sensor_state_t sensor_state;
 };
 
 int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 20cb08d..c3cfe76 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -787,11 +787,10 @@
 
 		if (*num_buffers > VIDEO_MAX_FRAME) {
 			dprintk(VIDC_ERR,
-					"Failed : No of slices requested = %d"\
-					" Max supported slices = %d",
-					*num_buffers, VIDEO_MAX_FRAME);
-			rc = -EINVAL;
-			break;
+				"Changing buffers requested, from %d to max"\
+				" supported (%d) best effort encoding\n",
+				*num_buffers, VIDEO_MAX_FRAME);
+			*num_buffers = VIDEO_MAX_FRAME;
 		}
 		ctrl = v4l2_ctrl_find(&inst->ctrl_handler,
 				V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA);
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index 0c5534c..ea7032b 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -1001,9 +1001,15 @@
 			FMDBG("Search list has %d stations\n",
 						radio->registers[XFRCTRL+1]);
 			radio->xfr_bytes_left = radio->registers[XFRCTRL+1]*2;
-			if (radio->xfr_bytes_left > 14) {
+			if (!radio->registers[XFRCTRL+1]) {
 				copy_from_xfr(radio, TAVARUA_BUF_SRCH_LIST,
-							XFR_REG_NUM);
+									1);
+				tavarua_q_event(radio,
+						TAVARUA_EVT_NEW_SRCH_LIST);
+				radio->xfr_in_progress = 0;
+			} else if (radio->xfr_bytes_left > 14) {
+				copy_from_xfr(radio, TAVARUA_BUF_SRCH_LIST,
+							RX_STATIONS0_LEN);
 				request_read_xfr(radio,	RX_STATIONS_1);
 			} else if (radio->xfr_bytes_left) {
 				FMDBG("In else RX_STATIONS_0\n");
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index d8a5669..9bc77be 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -278,63 +278,24 @@
 	svc->sb_virt = (char *) ion_map_kernel(qseecom.ion_clnt, svc->ihandle);
 	svc->sb_phys = pa;
 
-	if (qseecom.qseos_version == QSEOS_VERSION_14) {
-		req.qsee_cmd_id = QSEOS_REGISTER_LISTENER;
-		req.listener_id = svc->svc.listener_id;
-		req.sb_len = svc->sb_length;
-		req.sb_ptr = (void *)svc->sb_phys;
+	req.qsee_cmd_id = QSEOS_REGISTER_LISTENER;
+	req.listener_id = svc->svc.listener_id;
+	req.sb_len = svc->sb_length;
+	req.sb_ptr = (void *)svc->sb_phys;
 
-		resp.result = QSEOS_RESULT_INCOMPLETE;
+	resp.result = QSEOS_RESULT_INCOMPLETE;
 
-		ret = scm_call(SCM_SVC_TZSCHEDULER, 1,  &req,
+	ret = scm_call(SCM_SVC_TZSCHEDULER, 1,  &req,
 					sizeof(req), &resp, sizeof(resp));
-		if (ret) {
-			pr_err("qseecom_scm_call failed with err: %d\n", ret);
-			return -EINVAL;
-		}
+	if (ret) {
+		pr_err("qseecom_scm_call failed with err: %d\n", ret);
+		return -EINVAL;
+	}
 
-		if (resp.result != QSEOS_RESULT_SUCCESS) {
-			pr_err("Error SB registration req: resp.result = %d\n",
-					resp.result);
-			return -EPERM;
-		}
-	} else {
-		struct qseecom_command cmd;
-		struct qseecom_response resp;
-		struct qse_pr_init_sb_req_s sb_init_req;
-		struct qse_pr_init_sb_rsp_s sb_init_rsp;
-
-		svc->sb_reg_req = kzalloc((sizeof(sb_init_req) +
-					sizeof(sb_init_rsp)), GFP_KERNEL);
-
-		sb_init_req.pr_cmd = TZ_SCHED_CMD_ID_REGISTER_LISTENER;
-		sb_init_req.listener_id = svc->svc.listener_id;
-		sb_init_req.sb_len = svc->sb_length;
-		sb_init_req.sb_ptr = svc->sb_phys;
-
-		memcpy(svc->sb_reg_req, &sb_init_req, sizeof(sb_init_req));
-
-		/* It will always be a new cmd from this method */
-		cmd.cmd_type = TZ_SCHED_CMD_NEW;
-		cmd.sb_in_cmd_addr = (u8 *)(virt_to_phys(svc->sb_reg_req));
-		cmd.sb_in_cmd_len = sizeof(sb_init_req);
-
-		resp.cmd_status = TZ_SCHED_STATUS_INCOMPLETE;
-
-		ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &cmd, sizeof(cmd)
-				, &resp, sizeof(resp));
-
-		if (ret) {
-			pr_err("qseecom_scm_call failed with err: %d\n", ret);
-			return -EINVAL;
-		}
-
-		if (resp.cmd_status != TZ_SCHED_STATUS_COMPLETE) {
-			pr_err("SB registration fail resp.cmd_status %d\n",
-							resp.cmd_status);
-			return -EINVAL;
-		}
-		memset(svc->sb_virt, 0, svc->sb_length);
+	if (resp.result != QSEOS_RESULT_SUCCESS) {
+		pr_err("Error SB registration req: resp.result = %d\n",
+			resp.result);
+		return -EPERM;
 	}
 	return 0;
 }
@@ -396,56 +357,24 @@
 	struct qseecom_command_scm_resp resp;
 	struct ion_handle *ihandle = NULL;		/* Retrieve phy addr */
 
-	if (qseecom.qseos_version == QSEOS_VERSION_14) {
-		req.qsee_cmd_id = QSEOS_DEREGISTER_LISTENER;
-		req.listener_id = data->listener.id;
-		resp.result = QSEOS_RESULT_INCOMPLETE;
+	req.qsee_cmd_id = QSEOS_DEREGISTER_LISTENER;
+	req.listener_id = data->listener.id;
+	resp.result = QSEOS_RESULT_INCOMPLETE;
 
-		ret = scm_call(SCM_SVC_TZSCHEDULER, 1,  &req,
+	ret = scm_call(SCM_SVC_TZSCHEDULER, 1,  &req,
 					sizeof(req), &resp, sizeof(resp));
-		if (ret) {
-			pr_err("scm_call() failed with err: %d (lstnr id=%d)\n",
-					ret, data->listener.id);
-			return ret;
-		}
-
-		if (resp.result != QSEOS_RESULT_SUCCESS) {
-			pr_err("Failed resp.result=%d,(lstnr id=%d)\n",
-					resp.result, data->listener.id);
-			return -EPERM;
-		}
-	} else {
-		struct qse_pr_init_sb_req_s sb_init_req;
-		struct qseecom_command cmd;
-		struct qseecom_response resp;
-		struct qseecom_registered_listener_list *svc;
-
-		svc = __qseecom_find_svc(data->listener.id);
-		sb_init_req.pr_cmd = TZ_SCHED_CMD_ID_REGISTER_LISTENER;
-		sb_init_req.listener_id = data->listener.id;
-		sb_init_req.sb_len = 0;
-		sb_init_req.sb_ptr = 0;
-
-		memcpy(svc->sb_reg_req, &sb_init_req, sizeof(sb_init_req));
-
-		/* It will always be a new cmd from this method */
-		cmd.cmd_type = TZ_SCHED_CMD_NEW;
-		cmd.sb_in_cmd_addr = (u8 *)(virt_to_phys(svc->sb_reg_req));
-		cmd.sb_in_cmd_len = sizeof(sb_init_req);
-		resp.cmd_status = TZ_SCHED_STATUS_INCOMPLETE;
-
-		ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &cmd, sizeof(cmd),
-					&resp, sizeof(resp));
-		if (ret) {
-			pr_err("qseecom_scm_call failed with err: %d\n", ret);
-			return ret;
-		}
-		kzfree(svc->sb_reg_req);
-		if (resp.cmd_status != TZ_SCHED_STATUS_COMPLETE) {
-			pr_err("Error with SB initialization\n");
-			return -EPERM;
-		}
+	if (ret) {
+		pr_err("scm_call() failed with err: %d (lstnr id=%d)\n",
+				ret, data->listener.id);
+		return ret;
 	}
+
+	if (resp.result != QSEOS_RESULT_SUCCESS) {
+		pr_err("Failed resp.result=%d,(lstnr id=%d)\n",
+				resp.result, data->listener.id);
+		return -EPERM;
+	}
+
 	data->abort = 1;
 	spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags);
 	list_for_each_entry(ptr_svc, &qseecom.registered_listener_list_head,
@@ -830,8 +759,7 @@
 	bool unload = false;
 	bool found_app = false;
 
-	if ((qseecom.qseos_version == QSEOS_VERSION_14) &&
-				(data->client.app_id > 0)) {
+	if (data->client.app_id > 0) {
 		spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
 		list_for_each_entry(ptr_app, &qseecom.registered_app_list_head,
 								list) {
@@ -857,7 +785,7 @@
 		}
 	}
 
-	if ((unload) && (qseecom.qseos_version == QSEOS_VERSION_14)) {
+	if (unload) {
 		struct qseecom_unload_app_ireq req;
 
 		__qseecom_cleanup_app(data);
@@ -890,19 +818,6 @@
 			}
 		}
 	}
-
-	if (qseecom.qseos_version == QSEOS_VERSION_13) {
-		data->abort = 1;
-		wake_up_all(&qseecom.send_resp_wq);
-		while (atomic_read(&data->ioctl_count) > 0) {
-			if (wait_event_freezable(data->abort_wq,
-					atomic_read(&data->ioctl_count) <= 0)) {
-				pr_err("Interrupted from abort\n");
-				ret = -ERESTARTSYS;
-				break;
-			}
-		}
-	}
 	qseecom_unmap_ion_allocated_memory(data);
 	data->released = true;
 	return ret;
@@ -914,98 +829,6 @@
 	return data->client.sb_phys + (virt - data->client.user_virt_sb_base);
 }
 
-static int __qseecom_send_cmd_legacy(struct qseecom_dev_handle *data,
-				struct qseecom_send_cmd_req *req)
-{
-	int ret = 0;
-	unsigned long flags;
-	u32 reqd_len_sb_in = 0;
-	struct qseecom_command cmd;
-	struct qseecom_response resp;
-
-
-	if (req->cmd_req_buf == NULL || req->resp_buf == NULL) {
-		pr_err("cmd buffer or response buffer is null\n");
-		return -EINVAL;
-	}
-
-	if (req->cmd_req_len <= 0 ||
-		req->resp_len <= 0 ||
-		req->cmd_req_len > data->client.sb_length ||
-		req->resp_len > data->client.sb_length) {
-		pr_err("cmd buffer length or "
-				"response buffer length not valid\n");
-		return -EINVAL;
-	}
-
-	reqd_len_sb_in = req->cmd_req_len + req->resp_len;
-	if (reqd_len_sb_in > data->client.sb_length) {
-		pr_debug("Not enough memory to fit cmd_buf and "
-			"resp_buf. Required: %u, Available: %u\n",
-				reqd_len_sb_in, data->client.sb_length);
-		return -ENOMEM;
-	}
-	cmd.cmd_type = TZ_SCHED_CMD_NEW;
-	cmd.sb_in_cmd_addr = (u8 *) data->client.sb_phys;
-	cmd.sb_in_cmd_len = req->cmd_req_len;
-
-	resp.cmd_status = TZ_SCHED_STATUS_INCOMPLETE;
-	resp.sb_in_rsp_addr = (u8 *)data->client.sb_phys + req->cmd_req_len;
-	resp.sb_in_rsp_len = req->resp_len;
-
-	ret = scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *)&cmd,
-					sizeof(cmd), &resp, sizeof(resp));
-
-	if (ret) {
-		pr_err("qseecom_scm_call_legacy failed with err: %d\n", ret);
-		return ret;
-	}
-
-	while (resp.cmd_status != TZ_SCHED_STATUS_COMPLETE) {
-		/*
-		 * If cmd is incomplete, get the callback cmd out from SB out
-		 * and put it on the list
-		 */
-		struct qseecom_registered_listener_list *ptr_svc = NULL;
-		/*
-		 * We don't know which service can handle the command. so we
-		 * wake up all blocking services and let them figure out if
-		 * they can handle the given command.
-		 */
-		spin_lock_irqsave(&qseecom.registered_listener_list_lock,
-					flags);
-		list_for_each_entry(ptr_svc,
-				&qseecom.registered_listener_list_head, list) {
-				ptr_svc->rcv_req_flag = 1;
-				wake_up_interruptible(&ptr_svc->rcv_req_wq);
-		}
-		spin_unlock_irqrestore(&qseecom.registered_listener_list_lock,
-				flags);
-
-		pr_debug("waking up rcv_req_wq and "
-				"waiting for send_resp_wq\n");
-		if (wait_event_freezable(qseecom.send_resp_wq,
-				__qseecom_listener_has_sent_rsp(data))) {
-			pr_warning("qseecom Interrupted: exiting send_cmd loop\n");
-			return -ERESTARTSYS;
-		}
-
-		if (data->abort) {
-			pr_err("Aborting driver\n");
-			return -ENODEV;
-		}
-		qseecom.send_resp_flag = 0;
-		cmd.cmd_type = TZ_SCHED_CMD_PENDING;
-		ret = scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *)&cmd,
-					sizeof(cmd), &resp, sizeof(resp));
-		if (ret) {
-			pr_err("qseecom_scm_call failed with err: %d\n", ret);
-			return ret;
-		}
-	}
-	return ret;
-}
-
 int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr,
 		struct qseecom_send_svc_cmd_req *req_ptr,
 		struct qseecom_client_send_service_ireq *send_svc_ireq_ptr)
@@ -1171,10 +994,8 @@
 		pr_err("copy_from_user failed\n");
 		return ret;
 	}
-	if (qseecom.qseos_version == QSEOS_VERSION_14)
-		ret = __qseecom_send_cmd(data, &req);
-	else
-		ret = __qseecom_send_cmd_legacy(data, &req);
+	ret = __qseecom_send_cmd(data, &req);
+
 	if (ret)
 		return ret;
 
@@ -1289,12 +1110,9 @@
 	ret = __qseecom_update_with_phy_addr(&req);
 	if (ret)
 		return ret;
-	if (qseecom.qseos_version == QSEOS_VERSION_14)
-		ret = __qseecom_send_cmd(data, &send_cmd_req);
-	else
-		ret = __qseecom_send_cmd_legacy(data, &send_cmd_req);
-	__qseecom_send_cmd_req_clean_up(&req);
 
+	ret = __qseecom_send_cmd(data, &send_cmd_req);
+	__qseecom_send_cmd_req_clean_up(&req);
 	if (ret)
 		return ret;
 
@@ -1333,12 +1151,7 @@
 			return -ENODEV;
 		}
 		this_lstnr->rcv_req_flag = 0;
-		if (qseecom.qseos_version == QSEOS_VERSION_13) {
-			if (*((uint32_t *)this_lstnr->sb_virt) != 0)
-				break;
-		} else {
-			break;
-		}
+		break;
 	}
 	return ret;
 }
@@ -1636,11 +1449,6 @@
 	uint32_t len;
 	ion_phys_addr_t pa;
 
-	if (qseecom.qseos_version == QSEOS_VERSION_13) {
-		pr_err("This functionality is UNSUPPORTED in version 1.3\n");
-		return -EINVAL;
-	}
-
 	*handle = kzalloc(sizeof(struct qseecom_handle), GFP_KERNEL);
 	if (!(*handle)) {
 		pr_err("failed to allocate memory for kernel client handle\n");
@@ -1791,10 +1599,6 @@
 	unsigned long flags = 0;
 	bool found_handle = false;
 
-	if (qseecom.qseos_version == QSEOS_VERSION_13) {
-		pr_err("This functionality is UNSUPPORTED in version 1.3\n");
-		return -EINVAL;
-	}
 	if ((handle == NULL)  || (*handle == NULL)) {
 		pr_err("Handle is not initialized\n");
 		return -EINVAL;
@@ -1835,11 +1639,6 @@
 	struct qseecom_send_cmd_req req = {0, 0, 0, 0};
 	struct qseecom_dev_handle *data;
 
-	if (qseecom.qseos_version == QSEOS_VERSION_13) {
-		pr_err("This functionality is UNSUPPORTED in version 1.3\n");
-		return -EINVAL;
-	}
-
 	if (handle == NULL) {
 		pr_err("Handle is not initialized\n");
 		return -EINVAL;
@@ -2868,11 +2667,6 @@
 	}
 	case QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ: {
 		data->released = true;
-		if (qseecom.qseos_version == QSEOS_VERSION_13) {
-			pr_err("Loading External elf image unsupported in rev 0x13\n");
-			ret = -EINVAL;
-			break;
-		}
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_load_external_elf(data, argp);
@@ -2884,11 +2678,6 @@
 	}
 	case QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ: {
 		data->released = true;
-		if (qseecom.qseos_version == QSEOS_VERSION_13) {
-			pr_err("Unloading External elf image unsupported in rev 0x13\n");
-			ret = -EINVAL;
-			break;
-		}
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_unload_external_elf(data);
@@ -2992,23 +2781,7 @@
 	data->released = false;
 	init_waitqueue_head(&data->abort_wq);
 	atomic_set(&data->ioctl_count, 0);
-	if (qseecom.qseos_version == QSEOS_VERSION_13) {
-		int pil_error;
-		mutex_lock(&pil_access_lock);
-		if (pil_ref_cnt == 0) {
-			pil = subsystem_get("tzapps");
-			if (IS_ERR(pil)) {
-				pr_err("Playready PIL image load failed\n");
-				pil_error = PTR_ERR(pil);
-				pil = NULL;
-				pr_debug("tzapps image load FAILED\n");
-				mutex_unlock(&pil_access_lock);
-				return pil_error;
-			}
-		}
-		pil_ref_cnt++;
-		mutex_unlock(&pil_access_lock);
-	}
+
 	return ret;
 }
 
@@ -3046,13 +2819,6 @@
 	if (data->perf_enabled == true)
 		qsee_disable_clock_vote(data, CLK_DFAB);
 
-	if (qseecom.qseos_version == QSEOS_VERSION_13) {
-		mutex_lock(&pil_access_lock);
-		if (pil_ref_cnt == 1)
-			subsystem_put(pil);
-		pil_ref_cnt--;
-		mutex_unlock(&pil_access_lock);
-	}
 	kfree(data);
 
 	return ret;
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 89730b0..d850782 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -2137,7 +2137,7 @@
 	int ret = 0, dead = 0;
 	u32 vdd_max_current;
 	u16 host_version;
-	u32 pwr;
+	u32 pwr, irq_status, irq_ctl;
 
 	pr_debug("%s: Enter %s\n", dev_name(&pdev->dev), __func__);
 	msm_host = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_msm_host),
@@ -2265,6 +2265,27 @@
 	writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE));
 
 	/*
+	 * CORE_SW_RST above may trigger power irq if previous status of PWRCTL
+	 * was either BUS_ON or IO_HIGH_V. So before we enable the power irq
+	 * interrupt in GIC (by registering the interrupt handler), we need to
+	 * ensure that any pending power irq interrupt status is acknowledged
+	 * otherwise power irq interrupt handler would be fired prematurely.
+	 */
+	irq_status = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS);
+	writel_relaxed(irq_status, (msm_host->core_mem + CORE_PWRCTL_CLEAR));
+	irq_ctl = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_CTL);
+	if (irq_status & (CORE_PWRCTL_BUS_ON | CORE_PWRCTL_BUS_OFF))
+		irq_ctl |= CORE_PWRCTL_BUS_SUCCESS;
+	if (irq_status & (CORE_PWRCTL_IO_HIGH | CORE_PWRCTL_IO_LOW))
+		irq_ctl |= CORE_PWRCTL_IO_SUCCESS;
+	writel_relaxed(irq_ctl, (msm_host->core_mem + CORE_PWRCTL_CTL));
+	/*
+	 * Ensure that above writes are propogated before interrupt enablement
+	 * in GIC.
+	 */
+	mb();
+
+	/*
 	 * Following are the deviations from SDHC spec v3.0 -
 	 * 1. Card detection is handled using separate GPIO.
 	 * 2. Bus power control is handled by interacting with PMIC.
diff --git a/drivers/net/wireless/wcnss/wcnss_vreg.c b/drivers/net/wireless/wcnss/wcnss_vreg.c
index 59a6b68..c02daa4 100644
--- a/drivers/net/wireless/wcnss/wcnss_vreg.c
+++ b/drivers/net/wireless/wcnss/wcnss_vreg.c
@@ -31,6 +31,7 @@
 static LIST_HEAD(power_on_lock_list);
 static DEFINE_MUTEX(list_lock);
 static DEFINE_SEMAPHORE(wcnss_power_on_lock);
+static int auto_detect;
 
 #define MSM_RIVA_PHYS           0x03204000
 #define MSM_PRONTO_PHYS         0xfb21b000
@@ -42,11 +43,17 @@
 #define PRONTO_SPARE_OFFSET     0x1088
 #define NVBIN_DLND_BIT          BIT(25)
 
+#define PRONTO_IRIS_REG_READ_OFFSET       0x1134
+#define PRONTO_IRIS_REG_CHIP_ID           0x04
+
 #define WCNSS_PMU_CFG_IRIS_XO_CFG          BIT(3)
 #define WCNSS_PMU_CFG_IRIS_XO_EN           BIT(4)
 #define WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP   BIT(5)
 #define WCNSS_PMU_CFG_IRIS_XO_CFG_STS      BIT(6) /* 1: in progress, 0: done */
 
+#define WCNSS_PMU_CFG_IRIS_XO_READ         BIT(9)
+#define WCNSS_PMU_CFG_IRIS_XO_READ_STS     BIT(10)
+
 #define WCNSS_PMU_CFG_IRIS_XO_MODE         0x6
 #define WCNSS_PMU_CFG_IRIS_XO_MODE_48      (3 << 1)
 
@@ -56,6 +63,8 @@
 #define VREG_OPTIMUM_MODE_MASK      0x0004
 #define VREG_ENABLE_MASK            0x0008
 
+#define WCNSS_INVALID_IRIS_REG      0xbaadbaad
+
 struct vregs_info {
 	const char * const name;
 	int state;
@@ -110,10 +119,38 @@
 	struct list_head list;
 };
 
+enum {
+	WCNSS_XO_48MHZ = 1,
+	WCNSS_XO_19MHZ,
+	WCNSS_XO_INVALID,
+};
+
+enum {
+	IRIS_3660, /* also 3660A and 3680 */
+	IRIS_3620
+};
+
+
+int xo_auto_detect(u32 reg)
+{
+	reg >>= 30;
+
+	switch (reg) {
+	case IRIS_3660:
+		return WCNSS_XO_48MHZ;
+
+	case IRIS_3620:
+		return WCNSS_XO_19MHZ;
+
+	default:
+		return WCNSS_XO_INVALID;
+	}
+}
 
 static int configure_iris_xo(struct device *dev, bool use_48mhz_xo, int on)
 {
 	u32 reg = 0;
+	u32 iris_reg = WCNSS_INVALID_IRIS_REG;
 	int rc = 0;
 	int size = 0;
 	int pmu_offset = 0;
@@ -121,6 +158,7 @@
 	unsigned long wcnss_phys_addr;
 	void __iomem *pmu_conf_reg;
 	void __iomem *spare_reg;
+	void __iomem *iris_read_reg;
 	struct clk *clk;
 	struct clk *clk_rf = NULL;
 
@@ -136,14 +174,6 @@
 			return PTR_ERR(clk);
 		}
 
-		if (!use_48mhz_xo) {
-			clk_rf = clk_get(dev, "rf_clk");
-			if (IS_ERR(clk_rf)) {
-				pr_err("Couldn't get rf_clk\n");
-				clk_put(clk);
-				return PTR_ERR(clk_rf);
-			}
-		}
 	} else {
 		wcnss_phys_addr = MSM_RIVA_PHYS;
 		pmu_offset = RIVA_PMU_OFFSET;
@@ -187,10 +217,44 @@
 				WCNSS_PMU_CFG_IRIS_XO_EN;
 		writel_relaxed(reg, pmu_conf_reg);
 
+		if (wcnss_xo_auto_detect_enabled()) {
+			iris_read_reg = msm_wcnss_base +
+				PRONTO_IRIS_REG_READ_OFFSET;
+			iris_reg = readl_relaxed(iris_read_reg);
+		}
+
+		if (iris_reg != WCNSS_INVALID_IRIS_REG) {
+			iris_reg &= 0xffff;
+			iris_reg |= PRONTO_IRIS_REG_CHIP_ID;
+			writel_relaxed(iris_reg, iris_read_reg);
+
+			/* Iris read */
+			reg = readl_relaxed(pmu_conf_reg);
+			reg |= WCNSS_PMU_CFG_IRIS_XO_READ;
+			writel_relaxed(reg, pmu_conf_reg);
+
+			/* Wait for PMU_CFG.iris_reg_read_sts */
+			while (readl_relaxed(pmu_conf_reg) &
+					WCNSS_PMU_CFG_IRIS_XO_READ_STS)
+				cpu_relax();
+
+			iris_reg = readl_relaxed(iris_read_reg);
+			auto_detect = xo_auto_detect(iris_reg);
+
+			/* Reset iris read bit */
+			reg &= ~WCNSS_PMU_CFG_IRIS_XO_READ;
+
+		} else if (wcnss_xo_auto_detect_enabled())
+			/* Default to 48 MHZ */
+			auto_detect = WCNSS_XO_48MHZ;
+		else
+			auto_detect = WCNSS_XO_INVALID;
+
 		/* Clear XO_MODE[b2:b1] bits. Clear implies 19.2 MHz TCXO */
 		reg &= ~(WCNSS_PMU_CFG_IRIS_XO_MODE);
 
-		if (use_48mhz_xo)
+		if ((use_48mhz_xo && auto_detect == WCNSS_XO_INVALID)
+				|| auto_detect ==  WCNSS_XO_48MHZ)
 			reg |= WCNSS_PMU_CFG_IRIS_XO_MODE_48;
 
 		writel_relaxed(reg, pmu_conf_reg);
@@ -210,30 +274,41 @@
 		writel_relaxed(reg, pmu_conf_reg);
 		clk_disable_unprepare(clk);
 
-		if (!use_48mhz_xo) {
+		if ((!use_48mhz_xo && auto_detect == WCNSS_XO_INVALID)
+				|| auto_detect ==  WCNSS_XO_19MHZ) {
+
+			clk_rf = clk_get(dev, "rf_clk");
+			if (IS_ERR(clk_rf)) {
+				pr_err("Couldn't get rf_clk\n");
+				goto fail;
+			}
+
 			rc = clk_prepare_enable(clk_rf);
 			if (rc) {
 				pr_err("clk_rf enable failed\n");
 				goto fail;
 			}
 		}
-	}  else if (clk_rf != NULL && !use_48mhz_xo)
-			clk_disable_unprepare(clk_rf);
+
+	}  else if ((!use_48mhz_xo && auto_detect == WCNSS_XO_INVALID)
+			|| auto_detect ==  WCNSS_XO_19MHZ) {
+		clk_rf = clk_get(dev, "rf_clk");
+		if (IS_ERR(clk_rf)) {
+			pr_err("Couldn't get rf_clk\n");
+			goto fail;
+		}
+		clk_disable_unprepare(clk_rf);
+	}
+
 	/* Add some delay for XO to settle */
 	msleep(20);
 
+fail:
 	clk_put(clk);
 
-	if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
-		if (!use_48mhz_xo)
-			clk_put(clk_rf);
-	}
-
-	return rc;
-fail:
 	if (clk_rf != NULL)
 		clk_put(clk_rf);
-	clk_put(clk);
+
 	return rc;
 }
 
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index c30f46f..a75687b 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -56,6 +56,10 @@
 module_param(has_calibrated_data, int, S_IWUSR | S_IRUGO);
 MODULE_PARM_DESC(has_calibrated_data, "whether calibrated data file available");
 
+static int has_autodetect_xo = WCNSS_CONFIG_UNSPECIFIED;
+module_param(has_autodetect_xo, int, S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(has_autodetect_xo, "Perform auto detect to configure IRIS XO");
+
 static int do_not_cancel_vote = WCNSS_CONFIG_UNSPECIFIED;
 module_param(do_not_cancel_vote, int, S_IWUSR | S_IRUGO);
 MODULE_PARM_DESC(do_not_cancel_vote, "Do not cancel votes for wcnss");
@@ -873,6 +877,11 @@
 module_param_call(enable_wcnss_suspend_notify, enable_wcnss_suspend_notify_set,
 		param_get_int, &enable_wcnss_suspend_notify, S_IRUGO | S_IWUSR);
 
+int wcnss_xo_auto_detect_enabled(void)
+{
+	return (has_autodetect_xo == 1 ? 1 : 0);
+}
+
 
 void wcnss_suspend_notify(void)
 {
@@ -1507,6 +1516,11 @@
 	penv->wcnss_hw_type = (has_pronto_hw) ? WCNSS_PRONTO_HW : WCNSS_RIVA_HW;
 	penv->wlan_config.use_48mhz_xo = has_48mhz_xo;
 
+	if (WCNSS_CONFIG_UNSPECIFIED == has_autodetect_xo && has_pronto_hw) {
+		has_autodetect_xo = of_property_read_bool(pdev->dev.of_node,
+									"qcom,has_autodetect_xo");
+	}
+
 	penv->thermal_mitigation = 0;
 	strlcpy(penv->wcnss_version, "INVALID", WCNSS_VERSION_LEN);
 
diff --git a/drivers/platform/msm/qpnp-power-on.c b/drivers/platform/msm/qpnp-power-on.c
index a85e31c..9e3bab3 100644
--- a/drivers/platform/msm/qpnp-power-on.c
+++ b/drivers/platform/msm/qpnp-power-on.c
@@ -23,6 +23,9 @@
 #include <linux/input.h>
 #include <linux/log2.h>
 
+/* Common PNP defines */
+#define QPNP_PON_REVISION2(base)		(base + 0x01)
+
 /* PON common register addresses */
 #define QPNP_PON_RT_STS(base)			(base + 0x10)
 #define QPNP_PON_PULL_CTL(base)			(base + 0x70)
@@ -38,6 +41,7 @@
 #define QPNP_PON_RESIN_S2_TIMER(base)		(base + 0x45)
 #define QPNP_PON_RESIN_S2_CNTL(base)		(base + 0x46)
 #define QPNP_PON_PS_HOLD_RST_CTL(base)		(base + 0x5A)
+#define QPNP_PON_PS_HOLD_RST_CTL2(base)		(base + 0x5B)
 
 #define QPNP_PON_WARM_RESET_TFT			BIT(4)
 
@@ -140,17 +144,31 @@
 int qpnp_pon_system_pwr_off(bool reset)
 {
 	int rc;
+	u8 reg;
+	u16 rst_en_reg;
 	struct qpnp_pon *pon = sys_reset_dev;
 
 	if (!pon)
 		return -ENODEV;
 
-	rc = qpnp_pon_masked_write(pon, QPNP_PON_PS_HOLD_RST_CTL(pon->base),
-							QPNP_PON_RESET_EN, 0);
+	rc = spmi_ext_register_readl(pon->spmi->ctrl, pon->spmi->sid,
+			QPNP_PON_REVISION2(pon->base), &reg, 1);
+	if (rc) {
+		dev_err(&pon->spmi->dev,
+			"Unable to read addr=%x, rc(%d)\n",
+			QPNP_PON_REVISION2(pon->base), rc);
+		return rc;
+	}
+
+	if (reg == 0x00)
+		rst_en_reg = QPNP_PON_PS_HOLD_RST_CTL(pon->base);
+	else
+		rst_en_reg = QPNP_PON_PS_HOLD_RST_CTL2(pon->base);
+
+	rc = qpnp_pon_masked_write(pon, rst_en_reg, QPNP_PON_RESET_EN, 0);
 	if (rc)
 		dev_err(&pon->spmi->dev,
-			"Unable to write to addr=%x, rc(%d)\n",
-				QPNP_PON_PS_HOLD_RST_CTL(pon->base), rc);
+			"Unable to write to addr=%x, rc(%d)\n", rst_en_reg, rc);
 
 	/*
 	 * We need 10 sleep clock cycles here. But since the clock is
@@ -167,13 +185,11 @@
 			"Unable to write to addr=%x, rc(%d)\n",
 				QPNP_PON_PS_HOLD_RST_CTL(pon->base), rc);
 
-	rc = qpnp_pon_masked_write(pon, QPNP_PON_PS_HOLD_RST_CTL(pon->base),
-							QPNP_PON_RESET_EN,
-							QPNP_PON_RESET_EN);
+	rc = qpnp_pon_masked_write(pon, rst_en_reg, QPNP_PON_RESET_EN,
+						    QPNP_PON_RESET_EN);
 	if (rc)
 		dev_err(&pon->spmi->dev,
-			"Unable to write to addr=%x, rc(%d)\n",
-				QPNP_PON_PS_HOLD_RST_CTL(pon->base), rc);
+			"Unable to write to addr=%x, rc(%d)\n", rst_en_reg, rc);
 
 	return rc;
 }
diff --git a/drivers/platform/msm/qpnp-pwm.c b/drivers/platform/msm/qpnp-pwm.c
index 442d18f..be62408 100644
--- a/drivers/platform/msm/qpnp-pwm.c
+++ b/drivers/platform/msm/qpnp-pwm.c
@@ -914,7 +914,7 @@
 
 static inline int qpnp_enable_pwm_mode(struct qpnp_pwm_config *pwm_conf)
 {
-	if (pwm_conf->channel_id >= QPNP_GPLED_LPG_CHANNEL_RANGE_START ||
+	if (pwm_conf->channel_id >= QPNP_GPLED_LPG_CHANNEL_RANGE_START &&
 		pwm_conf->channel_id <= QPNP_GPLED_LPG_CHANNEL_RANGE_END)
 		return QPNP_ENABLE_PWM_MODE_GPLED_CHANNEL;
 	return QPNP_ENABLE_PWM_MODE;
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index 23c346a..81d80e6 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -1583,10 +1583,7 @@
 	for (i = 0; i < transfer->iovec_count; i++) {
 		u32 flags = iovec->flags;
 
-		if (iovec->addr == 0) {
-			SPS_ERR("sps:%s:iovec address is invalid.\n", __func__);
-			return SPS_ERROR;
-		} else if (iovec->size > SPS_IOVEC_MAX_SIZE) {
+		if (iovec->size > SPS_IOVEC_MAX_SIZE) {
 			SPS_ERR("sps:%s:iovec size is invalid.\n", __func__);
 			return SPS_ERROR;
 		}
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index fc85dba..af5442a 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -133,11 +133,11 @@
 	enum ipa_rm_event cur_prod_state[MAX_BAMS];
 	enum ipa_rm_event cur_cons_state[MAX_BAMS];
 
-	int lpm_wait_handshake;
+	bool lpm_wait_handshake[MAX_BAMS];
 	int connect_complete;
 	bool lpm_wait_pipes;
 	int bus_suspend;
-	bool in_lpm;
+	bool in_lpm[MAX_BAMS];
 
 	int (*wake_cb)(void *);
 	void *wake_param;
@@ -169,8 +169,31 @@
 static struct usb_bam_pipe_connect *usb_bam_connections;
 static struct usb_bam_ctx_type ctx;
 
+static struct device *hsic_host_dev;
+
 static int __usb_bam_register_wake_cb(u8 idx, int (*callback)(void *user),
 	void *param, bool trigger_cb_per_pipe);
+static void wait_for_prod_release(enum usb_bam cur_bam);
+static void wait_for_cons_release(enum usb_bam cur_bam);
+
+void msm_bam_set_hsic_host_dev(struct device *dev)
+{
+	if (dev) {
+		/* Hold the device until allowing lpm */
+		info.in_lpm[HSIC_BAM] = false;
+		pr_debug("%s: Getting hsic device %x\n", __func__,
+			(int)dev);
+		pm_runtime_get(dev);
+	} else if (hsic_host_dev) {
+		pr_debug("%s: Putting hsic device %x\n", __func__,
+			(int)hsic_host_dev);
+		/* Just free previous device*/
+		info.in_lpm[HSIC_BAM] = true;
+		pm_runtime_put(hsic_host_dev);
+	}
+
+	hsic_host_dev = dev;
+}
 
 static int get_bam_type_from_core_name(const char *name)
 {
@@ -209,6 +232,8 @@
 	struct sps_pipe *pipe = NULL;
 	int i;
 
+	pr_debug("%s: enter\n", __func__);
+
 	/*
 	 * Since we configure global incativity timer for all pipes
 	 * and not per each pipe, it is enough to use some pipe
@@ -217,14 +242,15 @@
 	 */
 	for (i = 0; i < ctx.max_connections; i++) {
 		pipe_connect = &usb_bam_connections[i];
-		if (pipe_connect->bam_type == bam) {
+		if (pipe_connect->bam_type == bam &&
+		    pipe_connect->enabled) {
 			pipe = ctx.usb_bam_sps.sps_pipes[i];
 			break;
 		}
 	}
 
 	if (!pipe) {
-		pr_err("%s: Bam %s has no pipes\n", __func__,
+		pr_warning("%s: Bam %s has no connected pipes\n", __func__,
 			bam_enable_strings[bam]);
 		return;
 	}
@@ -540,16 +566,6 @@
 		goto error;
 	}
 
-	spin_lock(&usb_bam_lock);
-
-	/* Set global inactivity timer upon first pipe connection */
-	if (ctx.pipes_enabled_per_bam[pipe_connect->bam_type] == 0 &&
-		ctx.inactivity_timer_ms[pipe_connect->bam_type] &&
-		pipe_connect->inactivity_notify)
-		usb_bam_set_inactivity_timer(pipe_connect->bam_type);
-
-	spin_unlock(&usb_bam_lock);
-
 	return 0;
 
 error:
@@ -622,7 +638,7 @@
 	BUG_ON(trans == NULL);
 		pr_debug("%s: Going to LPM\n", __func__);
 	spin_lock(&usb_bam_ipa_handshake_info_lock);
-	info.lpm_wait_handshake = false;
+	info.lpm_wait_handshake[HSUSB_BAM] = false;
 		info.lpm_wait_pipes = 0;
 	if (disconnect)
 		pm_runtime_put_noidle(trans->dev);
@@ -813,8 +829,40 @@
 	return;
 }
 
+static void usb_bam_resume_hsic_host(void)
+{
+	int i;
+	struct usb_bam_pipe_connect *pipe_iter;
+
+	spin_lock(&usb_bam_lock);
+
+	/* Exit from "full suspend" in case of hsic host */
+	if (hsic_host_dev && info.in_lpm[HSIC_BAM]) {
+		pr_debug("%s: Getting hsic device %x\n", __func__,
+			(int)hsic_host_dev);
+		pm_runtime_get(hsic_host_dev);
+		info.in_lpm[HSIC_BAM] = false;
+
+		for (i = 0; i < ctx.max_connections; i++) {
+			pipe_iter = &usb_bam_connections[i];
+			if (pipe_iter->bam_type == HSIC_BAM &&
+			    pipe_iter->enabled &&
+			    pipe_iter->suspended) {
+				spin_unlock(&usb_bam_lock);
+				ipa_resume(pipe_iter->ipa_clnt_hdl);
+				pipe_iter->suspended = false;
+				spin_lock(&usb_bam_lock);
+			}
+		}
+	}
+
+	spin_unlock(&usb_bam_lock);
+}
+
 static int cons_request_resource(enum usb_bam cur_bam)
 {
+	int ret = -EINPROGRESS;
+
 	pr_debug("%s: Request %s_CONS resource\n",
 			__func__, bam_enable_strings[cur_bam]);
 
@@ -823,29 +871,44 @@
 	complete_all(&info.cons_avail[cur_bam]);
 
 	spin_lock(&usb_bam_lock);
-	if (ctx.pipes_enabled_per_bam[cur_bam] && info.connect_complete &&
-				!info.bus_suspend && !info.prod_stopped) {
-		spin_unlock(&usb_bam_lock);
-		spin_unlock(&usb_bam_ipa_handshake_info_lock);
-		pr_debug("%s: ACK on cons_request", __func__);
-		return 0;
+
+	switch (cur_bam) {
+	case HSUSB_BAM:
+		if (ctx.pipes_enabled_per_bam[HSUSB_BAM] &&
+		    info.connect_complete &&
+			!info.cons_stopped && !info.prod_stopped) {
+			pr_debug("%s: ACK on cons_request", __func__);
+			ret = 0;
+		} else if (ctx.pipes_enabled_per_bam[HSUSB_BAM] &&
+				   info.connect_complete && info.bus_suspend) {
+			info.bus_suspend = 0;
+			if (info.wake_cb)
+				info.wake_cb(info.wake_param);
+		}
+
+		break;
+	case HSIC_BAM:
+			usb_bam_resume_hsic_host();
+
+			/*
+			 * Return sucess if there are pipes connected
+			 * and not in lpm
+			 */
+			if (ctx.pipes_enabled_per_bam[cur_bam] &&
+			    !info.in_lpm[cur_bam])
+				ret = 0;
+		break;
+	case SSUSB_BAM:
+	default:
+		break;
 	}
 
-	/* A2 wakeup from LPM */
-	if (cur_bam == HSUSB_BAM && ctx.pipes_enabled_per_bam[cur_bam] &&
-		info.connect_complete && info.bus_suspend) {
-		info.bus_suspend = 0;
-		spin_unlock(&usb_bam_lock);
-		spin_unlock(&usb_bam_ipa_handshake_info_lock);
-		if (info.wake_cb)
-			info.wake_cb(info.wake_param);
-	} else {
-		spin_unlock(&usb_bam_lock);
-		spin_unlock(&usb_bam_ipa_handshake_info_lock);
-	}
+	spin_unlock(&usb_bam_ipa_handshake_info_lock);
+	spin_unlock(&usb_bam_lock);
 
-	pr_debug("%s: EINPROGRESS on cons_request", __func__);
-	return -EINPROGRESS;
+	if (ret == -EINPROGRESS)
+		pr_debug("%s: EINPROGRESS on cons_request", __func__);
+	return ret;
 }
 
 static int usb_cons_request_resource(void)
@@ -934,7 +997,7 @@
 	}
 }
 
-static void wait_for_prod_granted(enum usb_bam cur_bam)
+static void wait_for_prod_granted(enum usb_bam cur_bam, bool start_cons)
 {
 	int ret;
 
@@ -948,7 +1011,8 @@
 			__func__);
 
 	init_completion(&info.prod_avail[cur_bam]);
-	init_completion(&info.cons_avail[cur_bam]);
+	if (start_cons)
+		init_completion(&info.cons_avail[cur_bam]);
 
 	ret = ipa_rm_request_resource(ipa_rm_resource_prod[cur_bam]);
 	if (!ret) {
@@ -1129,7 +1193,7 @@
 	}
 
 	spin_lock(&usb_bam_ipa_handshake_info_lock);
-	info.lpm_wait_handshake = true;
+	info.lpm_wait_handshake[HSUSB_BAM] = true;
 	spin_unlock(&usb_bam_ipa_handshake_info_lock);
 
 	wait_for_prod_release(HSUSB_BAM);
@@ -1156,10 +1220,10 @@
 		mutex_unlock(&info.suspend_resume_mutex);
 		return;
 	}
-	info.lpm_wait_handshake = true;
+	info.lpm_wait_handshake[HSUSB_BAM] = true;
 	spin_unlock(&usb_bam_ipa_handshake_info_lock);
 
-	wait_for_prod_granted(HSUSB_BAM);
+	wait_for_prod_granted(HSUSB_BAM, true);
 	wait_for_cons_granted(HSUSB_BAM);
 	if (info.cons_stopped) {
 		ipa_resume_pipes();
@@ -1213,13 +1277,115 @@
 	if (cur_bam != HSUSB_BAM)
 		return;
 
-	info.in_lpm = false;
+	info.in_lpm[HSUSB_BAM] = false;
 	spin_lock(&usb_bam_ipa_handshake_info_lock);
 	info.bus_suspend = 0;
 	spin_unlock(&usb_bam_ipa_handshake_info_lock);
 	queue_work(ctx.usb_bam_wq, &info.resume_work);
 }
 
+void msm_bam_wait_for_hsic_prod_granted(void)
+{
+	ctx.is_bam_inactivity[HSIC_BAM] = false;
+
+	/* Get back to resume state including wakeup ipa */
+	usb_bam_resume_hsic_host();
+
+	/* Ensure getting the producer resource */
+	wait_for_prod_granted(HSIC_BAM, false);
+}
+
+void msm_bam_hsic_notify_on_resume(void)
+{
+	/*
+	 * This function is called to notify the usb bam driver
+	 * that the hsic core and hsic bam hw are fully resumed
+	 * and clocked on. Therefore we can now set the inactivity
+	 * timer to the hsic bam hw.
+	 */
+	if (ctx.inactivity_timer_ms[HSIC_BAM])
+		usb_bam_set_inactivity_timer(HSIC_BAM);
+}
+
+bool msm_bam_hsic_lpm_ok(void)
+{
+	int i;
+	struct usb_bam_pipe_connect *pipe_iter;
+
+	if (hsic_host_dev) {
+
+		pr_debug("%s: Starting hsic full suspend sequence\n",
+			__func__);
+
+		info.lpm_wait_handshake[HSIC_BAM] = true;
+
+		wait_for_prod_release(HSIC_BAM);
+		pr_debug("%s: complete wait on hsic producer s=%d\n",
+			__func__, info.cur_prod_state[HSIC_BAM]);
+
+		wait_for_cons_release(HSIC_BAM);
+		pr_debug("%s: complete wait on hsic consumer s=%d\n",
+			__func__, info.cur_cons_state[HSIC_BAM]);
+
+		info.lpm_wait_handshake[HSIC_BAM] = false;
+
+		/*
+		 * Start low power mode by releasing the device
+		 * only in case that indeed the resources were released
+		 * and we are still in inactivity state (wake event
+		 * have not been occured while we were waiting to the
+		 * resources release)
+		 */
+		spin_lock(&usb_bam_lock);
+
+		pr_debug("%s: goto lpm?, inactivity=%d\n",
+			__func__, ctx.is_bam_inactivity[HSIC_BAM]);
+
+		if (info.cur_cons_state[HSIC_BAM] ==
+			IPA_RM_RESOURCE_RELEASED &&
+		    info.cur_prod_state[HSIC_BAM] ==
+			IPA_RM_RESOURCE_RELEASED &&
+		    ctx.is_bam_inactivity[HSIC_BAM] && info.in_lpm[HSIC_BAM]) {
+
+			/* HSIC host will go now to lpm */
+			pr_debug("%s: vote for suspend hsic %x\n",
+				__func__, (int)hsic_host_dev);
+
+			for (i = 0; i < ctx.max_connections; i++) {
+				pipe_iter =
+					&usb_bam_connections[i];
+				if (pipe_iter->bam_type == HSIC_BAM &&
+				    pipe_iter->enabled &&
+				    !pipe_iter->suspended) {
+					spin_unlock(&usb_bam_lock);
+					ipa_suspend(
+					   pipe_iter->ipa_clnt_hdl);
+					pipe_iter->suspended = true;
+					spin_lock(&usb_bam_lock);
+				}
+			}
+
+			spin_unlock(&usb_bam_lock);
+			return true;
+		}
+
+		/* We not allow lpm, therefore renew our vote here */
+		if (info.in_lpm[HSIC_BAM]) {
+			pr_debug("%s: Getting hsic device %x\n", __func__,
+			(int)hsic_host_dev);
+			pm_runtime_get(hsic_host_dev);
+			info.in_lpm[HSIC_BAM] = false;
+			spin_unlock(&usb_bam_lock);
+			wait_for_prod_granted(HSIC_BAM, false);
+		} else
+			spin_unlock(&usb_bam_lock);
+
+		return false;
+	}
+
+	return true;
+}
+
 int usb_bam_connect_ipa(struct usb_bam_connect_ipa_params *ipa_params)
 {
 	u8 idx;
@@ -1255,52 +1421,77 @@
 	}
 
 	pr_debug("%s: enter", __func__);
-	mutex_lock(&info.suspend_resume_mutex);
 
-	spin_lock(&usb_bam_lock);
-	if (ctx.pipes_enabled_per_bam[cur_bam] == 0) {
-		spin_unlock(&usb_bam_lock);
-		if (cur_bam == HSUSB_BAM) {
+	if (cur_bam == HSUSB_BAM) {
+		mutex_lock(&info.suspend_resume_mutex);
+
+		spin_lock(&usb_bam_lock);
+		if (ctx.pipes_enabled_per_bam[HSUSB_BAM] == 0) {
+			spin_unlock(&usb_bam_lock);
 			spin_lock(&usb_bam_ipa_handshake_info_lock);
-			info.lpm_wait_handshake = 1;
+			info.lpm_wait_handshake[HSUSB_BAM] = true;
 			info.connect_complete = 0;
 			info.lpm_wait_pipes = 1;
 			info.bus_suspend = 0;
 			info.cons_stopped = 0;
 			info.prod_stopped = 0;
 			spin_unlock(&usb_bam_ipa_handshake_info_lock);
-		}
-		usb_bam_resume_core(cur_bam);
-	} else
-		spin_unlock(&usb_bam_lock);
+			usb_bam_resume_core(cur_bam);
+		} else
+			spin_unlock(&usb_bam_lock);
+	}
 
 	 /* Check if BAM requires RESET before connect and reset first pipe */
 	 spin_lock(&usb_bam_lock);
 	 if ((pdata->reset_on_connect[cur_bam] == true) &&
-		 (ctx.pipes_enabled_per_bam[cur_bam] == 0))
-			sps_device_reset(ctx.h_bam[cur_bam]);
+	     (ctx.pipes_enabled_per_bam[cur_bam] == 0)) {
+		spin_unlock(&usb_bam_lock);
+		sps_device_reset(ctx.h_bam[cur_bam]);
+
+		/* On re-connect assume out from lpm for HSIC BAM */
+		if (cur_bam == HSIC_BAM && hsic_host_dev &&
+		    info.in_lpm[HSIC_BAM]) {
+			pr_debug("%s: Getting hsic device %x\n",
+					__func__, (int)hsic_host_dev);
+			pm_runtime_get(hsic_host_dev);
+		}
+
+		/* On re-connect assume out from lpm for all BAMs */
+		info.in_lpm[cur_bam] = false;
+	 } else
 		spin_unlock(&usb_bam_lock);
 
 	if (ipa_params->dir == USB_TO_PEER_PERIPHERAL) {
 		pr_debug("%s: Starting connect sequence\n", __func__);
-		wait_for_prod_granted(cur_bam);
+		wait_for_prod_granted(cur_bam, true);
 	}
 
 	ret = connect_pipe_ipa(idx, ipa_params);
 	if (ret) {
 		pr_err("%s: pipe connection failure\n", __func__);
-		mutex_unlock(&info.suspend_resume_mutex);
+		if (cur_bam == HSUSB_BAM)
+			mutex_unlock(&info.suspend_resume_mutex);
 		return ret;
 	}
 
 	spin_lock(&usb_bam_lock);
 	pipe_connect->enabled = 1;
+	pipe_connect->suspended = 0;
+
+	/* Set global inactivity timer upon first pipe connection */
+	if (ctx.pipes_enabled_per_bam[pipe_connect->bam_type] == 0 &&
+		ctx.inactivity_timer_ms[pipe_connect->bam_type] &&
+		pipe_connect->inactivity_notify)
+		usb_bam_set_inactivity_timer(pipe_connect->bam_type);
+
 	ctx.pipes_enabled_per_bam[cur_bam] += 1;
 	spin_unlock(&usb_bam_lock);
 	if (ipa_params->dir == PEER_PERIPHERAL_TO_USB && cur_bam == HSUSB_BAM)
 		wait_for_cons_granted(cur_bam);
 
-	mutex_unlock(&info.suspend_resume_mutex);
+	if (cur_bam == HSUSB_BAM)
+		mutex_unlock(&info.suspend_resume_mutex);
+
 	pr_debug("%s: done", __func__);
 
 	return 0;
@@ -1337,7 +1528,7 @@
 		container_of(w, struct usb_bam_event_info, event_w);
 	struct usb_bam_pipe_connect *pipe_connect =
 		container_of(event_info, struct usb_bam_pipe_connect, event);
-	struct usb_bam_pipe_connect *pipe_connect_iter;
+	struct usb_bam_pipe_connect *pipe_iter;
 	int (*callback)(void *priv);
 	void *param = NULL;
 
@@ -1347,8 +1538,33 @@
 
 		pr_debug("%s recieved USB_BAM_EVENT_WAKEUP\n", __func__);
 
+		/*
+		 * Make sure the PROD resource is granted before
+		 * wakeup hsic host class driver (done by the callback below)
+		 */
+		if (pipe_connect->peer_bam == IPA_P_BAM &&
+		    pipe_connect->bam_type == HSIC_BAM &&
+		    info.cur_prod_state[HSIC_BAM] != IPA_RM_RESOURCE_GRANTED) {
+			wait_for_prod_granted(HSIC_BAM, false);
+		}
+
+		/*
+		 * Check if need to resume the hsic host.
+		 * On one hand, since we got the wakeup interrupt
+		 * the hsic bam clocks are already enabled, so no need
+		 * to actualluy resume the hardware... However, we still need
+		 * to update the usb bam driver state (to set in_lpm=false),
+		 * and to wake ipa (ipa_resume) and to hold again the hsic host
+		 * device again to avoid it going to low poer mode next time
+		 * until we complete releasing the hsic consumer and producer
+		 * resources against the ipa resource manager.
+		 */
+		if (pipe_connect->bam_type == HSIC_BAM)
+			usb_bam_resume_hsic_host();
+
 		/* Notify about wakeup / activity of the bam */
-		event_info->callback(event_info->param);
+		if (event_info->callback)
+			event_info->callback(event_info->param);
 
 		/*
 		 * Reset inactivity timer counter if this pipe's bam
@@ -1359,12 +1575,14 @@
 			usb_bam_set_inactivity_timer(pipe_connect->bam_type);
 		spin_unlock(&usb_bam_lock);
 
-		/* A2 wakeup not from LPM (CONS was up) */
-		wait_for_prod_granted(pipe_connect->bam_type);
-		if (info.start) {
-			pr_debug("%s: Enqueue PROD transfer", __func__);
-			info.start(info.start_stop_param,
-					USB_TO_PEER_PERIPHERAL);
+		if (pipe_connect->bam_type == HSUSB_BAM) {
+			/* A2 wakeup not from LPM (CONS was up) */
+			wait_for_prod_granted(pipe_connect->bam_type, true);
+			if (info.start) {
+				pr_debug("%s: Enqueue PROD transfer", __func__);
+				info.start(info.start_stop_param,
+						USB_TO_PEER_PERIPHERAL);
+			}
 		}
 
 		break;
@@ -1389,21 +1607,34 @@
 		 */
 		spin_lock(&usb_bam_lock);
 		for (i = 0; i < ctx.max_connections; i++) {
-			pipe_connect_iter = &usb_bam_connections[i];
-			if (pipe_connect_iter->bam_type ==
+			pipe_iter = &usb_bam_connections[i];
+			if (pipe_iter->bam_type ==
 				pipe_connect->bam_type &&
-			    pipe_connect_iter->dir ==
+			    pipe_iter->dir ==
 				PEER_PERIPHERAL_TO_USB &&
-				pipe_connect_iter->enabled) {
+				pipe_iter->enabled) {
+				pr_debug("%s: Register wakeup on pipe %x\n",
+					__func__, (int)pipe_iter);
 				__usb_bam_register_wake_cb(i,
-					pipe_connect_iter->activity_notify,
-					pipe_connect_iter->priv,
+					pipe_iter->activity_notify,
+					pipe_iter->priv,
 					false);
 			}
 		}
 		spin_unlock(&usb_bam_lock);
 
-		/* Notify about the inactivity */
+		/*
+		 * Allow to go to lpm for now. Actual state will be checked
+		 * in msm_bam_hsic_lpm_ok() just before going to lpm.
+		 */
+		if (hsic_host_dev) {
+			pr_debug("%s: Putting hsic device %x\n", __func__,
+			(int)hsic_host_dev);
+			pm_runtime_put(hsic_host_dev);
+			info.in_lpm[HSIC_BAM] = true;
+		}
+
+		/* Notify about the inactivity to the USB class driver */
 		if (callback)
 			callback(param);
 
@@ -1422,13 +1653,14 @@
 		container_of(event_info,
 			     struct usb_bam_pipe_connect,
 			     event);
+	enum usb_bam bam = pipe_connect->bam_type;
 
 	spin_lock(&usb_bam_lock);
 
 	if (event_info->type == USB_BAM_EVENT_WAKEUP_PIPE)
 		queue_work(ctx.usb_bam_wq, &event_info->event_w);
 	else if (event_info->type == USB_BAM_EVENT_WAKEUP &&
-			ctx.is_bam_inactivity[pipe_connect->bam_type]) {
+			ctx.is_bam_inactivity[bam]) {
 
 		/*
 		 * Sps wake event is per pipe, so usb_bam_wake_cb is
@@ -1437,7 +1669,23 @@
 		 * Therefore, the first pipe that awaked will be considered
 		 * as global bam wake event.
 		 */
-		ctx.is_bam_inactivity[pipe_connect->bam_type] = false;
+		ctx.is_bam_inactivity[bam] = false;
+
+		/*
+		 * In case that this wakeup event occured while we are
+		 * waiting to release of the resurces in order to get into
+		 * low power mode, just cancle the waiting.
+		 */
+		if (info.lpm_wait_handshake[bam]) {
+			pr_debug("%s: cancel waiting for lpm\n", __func__);
+			if (info.cur_prod_state[bam] !=
+			    IPA_RM_RESOURCE_RELEASED)
+				complete_all(&info.prod_released[bam]);
+			if (info.cur_cons_state[bam] !=
+			    IPA_RM_RESOURCE_RELEASED)
+				complete_all(&info.cons_released[bam]);
+		}
+
 		queue_work(ctx.usb_bam_wq, &event_info->event_w);
 	}
 
@@ -1687,6 +1935,10 @@
 		idx = ipa_params->dst_idx;
 		pipe_connect = &usb_bam_connections[idx];
 
+		pipe_connect->activity_notify = NULL;
+		pipe_connect->inactivity_notify = NULL;
+		pipe_connect->priv = NULL;
+
 		/* Do the release handshake with the A2 via RM */
 		cur_bam = pipe_connect->bam_type;
 		info.lpm_wait_pipes = 1;
@@ -1716,6 +1968,11 @@
 	if (ipa_params->cons_clnt_hdl) {
 		idx = ipa_params->src_idx;
 		pipe_connect = &usb_bam_connections[idx];
+
+		pipe_connect->activity_notify = NULL;
+		pipe_connect->inactivity_notify = NULL;
+		pipe_connect->priv = NULL;
+
 		cur_bam = pipe_connect->bam_type;
 		wait_for_cons_release(cur_bam);
 		/* close IPA -> USB pipe */
@@ -1839,9 +2096,11 @@
 
 			/*
 			 * Notify inactivity once, Since it is global
-			 * for all pipes on bam.
+			 * for all pipes on bam. Notify only if we have
+			 * connected pipes.
 			 */
-			if (pipe_connect->bam_type == bam) {
+			if (pipe_connect->bam_type == bam &&
+			    pipe_connect->enabled) {
 				event_info = &pipe_connect->event;
 				event_info->type = USB_BAM_EVENT_INACTIVITY;
 				event_info->param = pipe_connect->priv;
@@ -2073,6 +2332,7 @@
 	props.num_pipes = pdata->usb_bam_num_pipes;
 	props.callback = usb_bam_sps_events;
 	props.user = bam_enable_strings[bam_idx];
+	props.options = SPS_BAM_OPT_IRQ_WAKEUP;
 
 	/*
 	* HSUSB and HSIC Cores don't support RESET ACK signal to BAMs
@@ -2190,7 +2450,8 @@
 			/* Apply new timer setting if bam has running pipes */
 			if (ctx.inactivity_timer_ms[bam] != timer_d) {
 				ctx.inactivity_timer_ms[bam] = timer_d;
-				if (ctx.pipes_enabled_per_bam[bam] > 0)
+				if (ctx.pipes_enabled_per_bam[bam] > 0 &&
+				    !info.in_lpm[bam])
 					usb_bam_set_inactivity_timer(bam);
 			}
 
@@ -2263,6 +2524,7 @@
 		complete(&info.prod_released[i]);
 		info.cur_prod_state[i] = IPA_RM_RESOURCE_RELEASED;
 		info.cur_cons_state[i] = IPA_RM_RESOURCE_RELEASED;
+		info.lpm_wait_handshake[i] = false;
 	}
 
 	INIT_WORK(&info.resume_work, usb_bam_finish_resume);
@@ -2360,12 +2622,12 @@
 bool msm_bam_lpm_ok(void)
 {
 	spin_lock(&usb_bam_ipa_handshake_info_lock);
-	if (info.lpm_wait_handshake || info.lpm_wait_pipes) {
+	if (info.lpm_wait_handshake[HSUSB_BAM] || info.lpm_wait_pipes) {
 		spin_unlock(&usb_bam_ipa_handshake_info_lock);
 		pr_err("%s: Scheduling LPM for later\n", __func__);
 		return 0;
 	} else {
-		info.in_lpm = 1;
+		info.in_lpm[HSUSB_BAM] = true;
 		spin_unlock(&usb_bam_ipa_handshake_info_lock);
 		pr_err("%s: Going to LPM now\n", __func__);
 		return 1;
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 624a42f..24825ea 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -1153,7 +1153,6 @@
 get_prop_capacity(struct qpnp_chg_chip *chip)
 {
 	union power_supply_propval ret = {0,};
-	bool usb_online, dc_online;
 
 	if (chip->use_default_batt_values || !get_prop_batt_present(chip))
 		return DEFAULT_CAPACITY;
@@ -1162,11 +1161,8 @@
 		chip->bms_psy->get_property(chip->bms_psy,
 			  POWER_SUPPLY_PROP_CAPACITY, &ret);
 		if (ret.intval == 0) {
-			usb_online = chip->usb_psy->get_property(chip->usb_psy,
-					  POWER_SUPPLY_PROP_ONLINE, &ret);
-			dc_online = chip->dc_psy.get_property(&chip->dc_psy,
-					  POWER_SUPPLY_PROP_ONLINE, &ret);
-			if (!usb_online && !dc_online)
+			if (!qpnp_chg_is_usb_chg_plugged_in(chip)
+				&& !qpnp_chg_is_usb_chg_plugged_in(chip))
 				pr_warn_ratelimited("Battery 0, CHG absent\n");
 		}
 		return ret.intval;
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c8fdc6b..b7762e1 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -725,8 +725,7 @@
 	bool sdev_lookup = true;
 
 	if (!hba || !query || !response) {
-		dev_err(hba->dev,
-			"%s: NULL pointer hba = %p, query = %p response = %p\n",
+		pr_err("%s: NULL pointer hba = %p, query = %p response = %p\n",
 			__func__, hba, query, response);
 		return -EINVAL;
 	}
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 814817b..ab59864 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -596,7 +596,14 @@
 		pr_info("%s: Max frequency reset for cpu%d\n",
 				KBUILD_MODNAME, cpu);
 
-	ret = cpufreq_update_policy(cpu);
+	if (cpu_online(cpu)) {
+		struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+		if (!policy)
+			return ret;
+		ret = cpufreq_driver_target(policy, policy->cur,
+				CPUFREQ_RELATION_H);
+		cpufreq_cpu_put(policy);
+	}
 
 	return ret;
 }
@@ -748,14 +755,56 @@
 	return ret;
 }
 
+static void __cpuinit do_freq_control(long temp)
+{
+	int ret = 0;
+	int cpu = 0;
+	uint32_t max_freq = limited_max_freq;
+
+	if (temp >= msm_thermal_info.limit_temp_degC) {
+		if (limit_idx == limit_idx_low)
+			return;
+
+		limit_idx -= msm_thermal_info.freq_step;
+		if (limit_idx < limit_idx_low)
+			limit_idx = limit_idx_low;
+		max_freq = table[limit_idx].frequency;
+	} else if (temp < msm_thermal_info.limit_temp_degC -
+		 msm_thermal_info.temp_hysteresis_degC) {
+		if (limit_idx == limit_idx_high)
+			return;
+
+		limit_idx += msm_thermal_info.freq_step;
+		if (limit_idx >= limit_idx_high) {
+			limit_idx = limit_idx_high;
+			max_freq = MSM_CPUFREQ_NO_LIMIT;
+		} else
+			max_freq = table[limit_idx].frequency;
+	}
+
+	if (max_freq == limited_max_freq)
+		return;
+
+	/* Update new limits */
+	for_each_possible_cpu(cpu) {
+		if (!(msm_thermal_info.freq_control_mask & BIT(cpu)))
+			continue;
+		ret = update_cpu_max_freq(cpu, max_freq);
+		if (ret)
+			pr_debug(
+			"%s: Unable to limit cpu%d max freq to %d\n",
+					KBUILD_MODNAME, cpu, max_freq);
+	}
+
+}
+
 static void __cpuinit check_temp(struct work_struct *work)
 {
 	static int limit_init;
 	struct tsens_device tsens_dev;
 	long temp = 0;
-	uint32_t max_freq = limited_max_freq;
-	int cpu = 0;
 	int ret = 0;
+
 	tsens_dev.sensor_num = msm_thermal_info.sensor_id;
 	ret = tsens_get_temp(&tsens_dev, &temp);
 	if (ret) {
@@ -775,38 +824,7 @@
 	do_core_control(temp);
 	do_vdd_restriction();
 	do_psm();
-
-	if (temp >= msm_thermal_info.limit_temp_degC) {
-		if (limit_idx == limit_idx_low)
-			goto reschedule;
-
-		limit_idx -= msm_thermal_info.freq_step;
-		if (limit_idx < limit_idx_low)
-			limit_idx = limit_idx_low;
-		max_freq = table[limit_idx].frequency;
-	} else if (temp < msm_thermal_info.limit_temp_degC -
-		 msm_thermal_info.temp_hysteresis_degC) {
-		if (limit_idx == limit_idx_high)
-			goto reschedule;
-
-		limit_idx += msm_thermal_info.freq_step;
-		if (limit_idx >= limit_idx_high) {
-			limit_idx = limit_idx_high;
-			max_freq = MSM_CPUFREQ_NO_LIMIT;
-		} else
-			max_freq = table[limit_idx].frequency;
-	}
-	if (max_freq == limited_max_freq)
-		goto reschedule;
-
-	/* Update new limits */
-	for_each_possible_cpu(cpu) {
-		ret = update_cpu_max_freq(cpu, max_freq);
-		if (ret)
-			pr_debug(
-			"%s: Unable to limit cpu%d max freq to %d\n",
-					KBUILD_MODNAME, cpu, max_freq);
-	}
+	do_freq_control(temp);
 
 reschedule:
 	if (enabled)
@@ -1599,6 +1617,9 @@
 	if (ret)
 		goto fail;
 
+	key = "qcom,freq-control-mask";
+	ret = of_property_read_u32(node, key, &data.freq_control_mask);
+
 	key = "qcom,core-limit-temp";
 	ret = of_property_read_u32(node, key, &data.core_limit_temp_degC);
 
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 80e9e87..678627a 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -3793,9 +3793,7 @@
 	pm_runtime_no_callbacks(&udc->gadget.dev);
 	pm_runtime_enable(&udc->gadget.dev);
 
-	retval = register_trace_usb_daytona_invalid_access(dump_usb_info,
-								NULL);
-	if (retval)
+	if (register_trace_usb_daytona_invalid_access(dump_usb_info, NULL))
 		pr_err("Registering trace failed\n");
 
 	_udc = udc;
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 87a3fd5..2f35315 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -728,12 +728,18 @@
 			rc = -EINTR;
 			break;
 		}
-		if (common->thread_wakeup_needed)
+		spin_lock_irq(&common->lock);
+		if (common->thread_wakeup_needed) {
+			spin_unlock_irq(&common->lock);
 			break;
+		}
+		spin_unlock_irq(&common->lock);
 		schedule();
 	}
 	__set_current_state(TASK_RUNNING);
+	spin_lock_irq(&common->lock);
 	common->thread_wakeup_needed = 0;
+	spin_unlock_irq(&common->lock);
 	return rc;
 }
 
@@ -796,12 +802,17 @@
 			     curlun->file_length - file_offset);
 
 		/* Wait for the next buffer to become available */
+		spin_lock_irq(&common->lock);
 		bh = common->next_buffhd_to_fill;
 		while (bh->state != BUF_STATE_EMPTY) {
+			spin_unlock_irq(&common->lock);
 			rc = sleep_thread(common);
 			if (rc)
 				return rc;
+
+			spin_lock_irq(&common->lock);
 		}
+		spin_unlock_irq(&common->lock);
 
 		/*
 		 * If we were asked to read past the end of file,
@@ -813,8 +824,10 @@
 			curlun->sense_data_info =
 					file_offset >> curlun->blkbits;
 			curlun->info_valid = 1;
+			spin_lock_irq(&common->lock);
 			bh->inreq->length = 0;
 			bh->state = BUF_STATE_FULL;
+			spin_unlock_irq(&common->lock);
 			break;
 		}
 
@@ -854,8 +867,10 @@
 		 * equal to the buffer size, which is divisible by the
 		 * bulk-in maxpacket size.
 		 */
+		spin_lock_irq(&common->lock);
 		bh->inreq->length = nread;
 		bh->state = BUF_STATE_FULL;
+		spin_unlock_irq(&common->lock);
 
 		/* If an error occurred, report it and its position */
 		if (nread < amount) {
@@ -1814,12 +1829,17 @@
 	u32			sd, sdinfo = 0;
 
 	/* Wait for the next buffer to become available */
+	spin_lock_irq(&common->lock);
 	bh = common->next_buffhd_to_fill;
 	while (bh->state != BUF_STATE_EMPTY) {
+		spin_unlock_irq(&common->lock);
 		rc = sleep_thread(common);
 		if (rc)
 			return rc;
+
+		spin_lock_irq(&common->lock);
 	}
+	spin_unlock_irq(&common->lock);
 
 	if (curlun) {
 		sd = curlun->sense_data;
@@ -2029,13 +2049,19 @@
 	dump_cdb(common);
 
 	/* Wait for the next buffer to become available for data or status */
+	spin_lock_irq(&common->lock);
 	bh = common->next_buffhd_to_fill;
 	common->next_buffhd_to_drain = bh;
 	while (bh->state != BUF_STATE_EMPTY) {
+		spin_unlock_irq(&common->lock);
 		rc = sleep_thread(common);
 		if (rc)
 			return rc;
+
+		spin_lock_irq(&common->lock);
 	}
+	spin_unlock_irq(&common->lock);
+
 	common->phase_error = 0;
 	common->short_packet_received = 0;
 
@@ -2376,12 +2402,17 @@
 	int			rc = 0;
 
 	/* Wait for the next buffer to become available */
+	spin_lock_irq(&common->lock);
 	bh = common->next_buffhd_to_fill;
 	while (bh->state != BUF_STATE_EMPTY) {
+		spin_unlock_irq(&common->lock);
 		rc = sleep_thread(common);
 		if (rc)
 			return rc;
+
+		spin_lock_irq(&common->lock);
 	}
+	spin_unlock_irq(&common->lock);
 
 	/* Queue a request to read a Bulk-only CBW */
 	set_bulk_out_req_length(common, bh, US_BULK_CB_WRAP_LEN);
@@ -2396,14 +2427,23 @@
 	 */
 
 	/* Wait for the CBW to arrive */
+	spin_lock_irq(&common->lock);
 	while (bh->state != BUF_STATE_FULL) {
+		spin_unlock_irq(&common->lock);
 		rc = sleep_thread(common);
 		if (rc)
 			return rc;
+
+		spin_lock_irq(&common->lock);
 	}
+	spin_unlock_irq(&common->lock);
+
 	smp_rmb();
 	rc = fsg_is_set(common) ? received_cbw(common->fsg, bh) : -EIO;
+
+	spin_lock_irq(&common->lock);
 	bh->state = BUF_STATE_EMPTY;
+	spin_unlock_irq(&common->lock);
 
 	return rc;
 }
@@ -2586,10 +2626,13 @@
 		/* Wait until everything is idle */
 		for (;;) {
 			int num_active = 0;
+			spin_lock_irq(&common->lock);
 			for (i = 0; i < fsg_num_buffers; ++i) {
 				bh = &common->buffhds[i];
 				num_active += bh->inreq_busy + bh->outreq_busy;
 			}
+			spin_unlock_irq(&common->lock);
+
 			if (num_active == 0)
 				break;
 			if (sleep_thread(common))
diff --git a/drivers/usb/gadget/f_qc_ecm.c b/drivers/usb/gadget/f_qc_ecm.c
index 5e68296..4f9cbf1 100644
--- a/drivers/usb/gadget/f_qc_ecm.c
+++ b/drivers/usb/gadget/f_qc_ecm.c
@@ -389,6 +389,7 @@
 		IPA_P_BAM : A2_P_BAM;
 
 	ecm_qc_bam_port.cdev = cdev;
+	ecm_qc_bam_port.func = &dev->port.func;
 	ecm_qc_bam_port.in = dev->port.in_ep;
 	ecm_qc_bam_port.out = dev->port.out_ep;
 
diff --git a/drivers/usb/gadget/f_qc_rndis.c b/drivers/usb/gadget/f_qc_rndis.c
index baea664..267cf53 100644
--- a/drivers/usb/gadget/f_qc_rndis.c
+++ b/drivers/usb/gadget/f_qc_rndis.c
@@ -426,6 +426,7 @@
 	struct usb_gadget *gadget = cdev->gadget;
 
 	dev->bam_port.cdev = cdev;
+	dev->bam_port.func = &dev->port.func;
 	dev->bam_port.in = dev->port.in_ep;
 	dev->bam_port.out = dev->port.out_ep;
 
diff --git a/drivers/usb/gadget/u_bam_data.c b/drivers/usb/gadget/u_bam_data.c
index 081a09c..c638164 100644
--- a/drivers/usb/gadget/u_bam_data.c
+++ b/drivers/usb/gadget/u_bam_data.c
@@ -178,6 +178,15 @@
 reenable_eps:
 	/* Re-Enable the relevant EPs, if EPs were originally enabled */
 	if (reenable_eps) {
+		if (config_ep_by_speed(port->port_usb->cdev->gadget,
+			port->port_usb->func, port->port_usb->in) ||
+		    config_ep_by_speed(port->port_usb->cdev->gadget,
+			port->port_usb->func, port->port_usb->out)) {
+			pr_err("%s: config_ep_by_speed failed", __func__);
+				port->port_usb->in->desc = NULL;
+				port->port_usb->out->desc = NULL;
+				return -EINVAL;
+		}
 		ret = usb_ep_enable(port->port_usb->in);
 		if (ret) {
 			pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
diff --git a/drivers/usb/gadget/u_bam_data.h b/drivers/usb/gadget/u_bam_data.h
index 486191b5..5ce678d 100644
--- a/drivers/usb/gadget/u_bam_data.h
+++ b/drivers/usb/gadget/u_bam_data.h
@@ -23,6 +23,7 @@
 
 struct data_port {
 	struct usb_composite_dev	*cdev;
+	struct usb_function		*func;
 	struct usb_ep			*in;
 	struct usb_ep			*out;
 };
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index d1d0f91..0ea9778 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -752,6 +752,19 @@
 		return -EBUSY;
 	}
 
+	if (pdata->consider_ipa_handshake) {
+		dev_dbg(mehci->dev, "%s:Wait for resources release\n",
+			__func__);
+		if (!msm_bam_hsic_lpm_ok()) {
+			dev_dbg(mehci->dev, "%s:Prod+Cons not released\n",
+			__func__);
+			enable_irq(hcd->irq);
+			return -EBUSY;
+		}
+		dev_dbg(mehci->dev, "%s:Prod+Cons resources released\n",
+			__func__);
+	}
+
 	/*
 	 * PHY may take some time or even fail to enter into low power
 	 * mode (LPM). Hence poll for 500 msec and reset the PHY and link
@@ -829,7 +842,7 @@
 
 	wake_unlock(&mehci->wlock);
 
-	dev_dbg(mehci->dev, "HSIC-USB in low power mode\n");
+	dev_info(mehci->dev, "HSIC-USB in low power mode\n");
 
 	return 0;
 }
@@ -848,6 +861,14 @@
 		return 0;
 	}
 
+	if (pdata->consider_ipa_handshake) {
+		dev_dbg(mehci->dev, "%s:Wait for producer resource\n",
+			__func__);
+		msm_bam_wait_for_hsic_prod_granted();
+		dev_dbg(mehci->dev, "%s:Producer resource obtained\n",
+			__func__);
+	}
+
 	/* Handles race with Async interrupt */
 	disable_irq(hcd->irq);
 
@@ -933,7 +954,13 @@
 	}
 
 	enable_irq(hcd->irq);
-	dev_dbg(mehci->dev, "HSIC-USB exited from low power mode\n");
+	dev_info(mehci->dev, "HSIC-USB exited from low power mode\n");
+
+	if (pdata->consider_ipa_handshake) {
+		dev_dbg(mehci->dev, "%s:Notify usb bam on resume complete\n",
+			__func__);
+		msm_bam_hsic_notify_on_resume();
+	}
 
 	return 0;
 }
@@ -1853,6 +1880,8 @@
 				"qcom,enable-hbm");
 	pdata->disable_park_mode = (of_property_read_bool(node,
 				"qcom,disable-park-mode"));
+	pdata->consider_ipa_handshake = (of_property_read_bool(node,
+				"hsic,consider-ipa-handshake"));
 
 	return pdata;
 }
@@ -2092,6 +2121,8 @@
 	if (mehci->enable_hbm)
 		hbm_init(hcd, pdata->disable_park_mode);
 
+	msm_bam_set_hsic_host_dev(&pdev->dev);
+
 	return 0;
 
 destroy_wq:
@@ -2115,6 +2146,8 @@
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 	struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
 
+	msm_bam_set_hsic_host_dev(NULL);
+
 	/* If the device was removed no need to call pm_runtime_disable */
 	if (pdev->dev.power.power_state.event != PM_EVENT_INVALID)
 		pm_runtime_disable(&pdev->dev);
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index c663170..db3cecc 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -418,6 +418,9 @@
 
 	/* disable DSI phy */
 	mdss_dsi_phy_enable(ctrl_pdata->ctrl_base, 0);
+
+	mdss_dsi_disable_bus_clocks(ctrl_pdata);
+
 	ret = mdss_dsi_panel_power_on(pdata, 0);
 	if (ret) {
 		pr_err("%s: Panel power off failed\n", __func__);
@@ -502,6 +505,14 @@
 
 	pdata->panel_info.panel_power_on = 1;
 
+	ret = mdss_dsi_enable_bus_clocks(ctrl_pdata);
+	if (ret) {
+		pr_err("%s: failed to enable bus clocks. rc=%d\n", __func__,
+			ret);
+		mdss_dsi_panel_power_on(pdata, 0);
+		return ret;
+	}
+
 	mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base));
 	mdss_dsi_phy_init(pdata);
 
@@ -1094,6 +1105,11 @@
 	 * register in mdp driver
 	 */
 
+	ctrl_pdata->pclk_rate = dsi_pclk_rate;
+	ctrl_pdata->byte_clk_rate = panel_data->panel_info.clk_rate / 8;
+	pr_debug("%s: pclk=%d, bclk=%d\n", __func__,
+			ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate);
+
 	cont_splash_enabled = of_property_read_bool(pdev->dev.of_node,
 			"qcom,cont-splash-enabled");
 	if (!cont_splash_enabled) {
@@ -1112,15 +1128,18 @@
 			pr_err("%s: Panel power on failed\n", __func__);
 			return rc;
 		}
-	}
 
-	ctrl_pdata->pclk_rate = dsi_pclk_rate;
-	ctrl_pdata->byte_clk_rate = panel_data->panel_info.clk_rate / 8;
-	pr_debug("%s: pclk=%d, bclk=%d\n", __func__,
-			ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate);
+		rc = mdss_dsi_enable_bus_clocks(ctrl_pdata);
+		if (rc) {
+			pr_err("%s: failed to enable bus clocks. rc=%d\n",
+				__func__, rc);
+			rc = mdss_dsi_panel_power_on(
+				&(ctrl_pdata->panel_data), 0);
+			return rc;
+		}
 
-	if (ctrl_pdata->panel_data.panel_info.cont_splash_enabled)
 		mdss_dsi_clk_ctrl(ctrl_pdata, 1);
+	}
 
 	rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data));
 	if (rc) {
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index 602ed9e..c78c5cf 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -327,6 +327,8 @@
 	unsigned char *ctrl_base;
 	int reg_size;
 	u32 clk_cnt;
+	struct clk *ahb_clk;
+	struct clk *axi_clk;
 	struct clk *byte_clk;
 	struct clk *esc_clk;
 	struct clk *pixel_clk;
@@ -409,6 +411,8 @@
 void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
 void mdss_dsi_prepare_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
 void mdss_dsi_unprepare_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+int mdss_dsi_enable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+void mdss_dsi_disable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
 void mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable);
 void mdss_dsi_phy_enable(unsigned char *ctrl_base, int on);
 void mdss_dsi_phy_init(struct mdss_panel_data *pdata);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index ab91320..fe10189 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -614,6 +614,37 @@
 	}
 } /* hdmi_tx_set_audio_switch_node */
 
+static int hdmi_tx_config_avmute(struct hdmi_tx_ctrl *hdmi_ctrl, int set)
+{
+	struct dss_io_data *io;
+
+	if (!hdmi_ctrl) {
+		DEV_ERR("%s: invalid input\n", __func__);
+		return -EINVAL;
+	}
+
+	io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+	if (!io->base) {
+		DEV_ERR("%s: Core io is not initialized\n", __func__);
+		return -EINVAL;
+	}
+
+	if (set)
+		DSS_REG_W(io, HDMI_GC,
+			DSS_REG_R(io, HDMI_GC) | BIT(0));
+	else
+		DSS_REG_W(io, HDMI_GC,
+			DSS_REG_R(io, HDMI_GC) & ~BIT(0));
+
+	/* Enable AV Mute tranmission here */
+	DSS_REG_W(io, HDMI_VBI_PKT_CTRL,
+		DSS_REG_R(io, HDMI_VBI_PKT_CTRL) | (BIT(4) & BIT(5)));
+
+	DEV_DBG("%s: AVMUTE %s\n", __func__, set ? "set" : "cleared");
+
+	return 0;
+} /* hdmi_tx_config_avmute */
+
 void hdmi_tx_hdcp_cb(void *ptr, enum hdmi_hdcp_state status)
 {
 	int rc = 0;
@@ -629,13 +660,25 @@
 
 	switch (status) {
 	case HDCP_STATE_AUTHENTICATED:
-		if (hdmi_ctrl->hpd_state)
+		if (hdmi_ctrl->hpd_state) {
+			/* Clear AV Mute */
+			rc = hdmi_tx_config_avmute(hdmi_ctrl, 0);
+			if (rc)
+				DEV_ERR("%s: Failed to clear av mute. rc=%d\n",
+					__func__, rc);
 			hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1, false);
+		}
 		break;
 	case HDCP_STATE_AUTH_FAIL:
 		hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0, false);
 
 		if (hdmi_ctrl->hpd_state) {
+			/* Set AV Mute */
+			rc = hdmi_tx_config_avmute(hdmi_ctrl, 1);
+			if (rc)
+				DEV_ERR("%s: Failed to set av mute. rc=%d\n",
+					__func__, rc);
+
 			DEV_DBG("%s: Reauthenticating\n", __func__);
 			rc = hdmi_hdcp_reauthenticate(
 				hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP]);
@@ -2743,6 +2786,12 @@
 
 	case MDSS_EVENT_PANEL_ON:
 		if (hdmi_ctrl->hdcp_feature_on && hdmi_ctrl->present_hdcp) {
+			/* Set AV Mute before starting authentication */
+			rc = hdmi_tx_config_avmute(hdmi_ctrl, 1);
+			if (rc)
+				DEV_ERR("%s: Failed to set av mute. rc=%d\n",
+					__func__, rc);
+
 			DEV_DBG("%s: Starting HDCP authentication\n", __func__);
 			rc = hdmi_hdcp_authenticate(
 				hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP]);
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index e346082..4b763aa 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1505,7 +1505,6 @@
 	mdss_mdp_pp_setup_locked(ctl);
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, ctl->flush_bits);
 	if (sctl) {
-		mdss_mdp_pp_setup_locked(sctl);
 		mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_FLUSH,
 			sctl->flush_bits);
 	}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index fcc1c1a..9d28265 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -888,14 +888,19 @@
 	return ret;
 }
 
-static int pp_mixer_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
+static int pp_mixer_setup(u32 disp_num,
 		struct mdss_mdp_mixer *mixer)
 {
 	u32 flags, offset, dspp_num, opmode = 0;
 	struct mdp_pgc_lut_data *pgc_config;
 	struct pp_sts_type *pp_sts;
+	struct mdss_mdp_ctl *ctl;
 	dspp_num = mixer->num;
 
+	if (!mixer || !mixer->ctl)
+		return -EINVAL;
+	ctl = mixer->ctl;
+
 	/* no corresponding dspp */
 	if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
 		(dspp_num >= MDSS_MDP_MAX_DSPP))
@@ -1003,8 +1008,7 @@
 	return ret;
 }
 
-static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
-				struct mdss_mdp_mixer *mixer)
+static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
 {
 	u32 flags, base, offset, dspp_num, opmode = 0;
 	struct mdp_dither_cfg_data *dither_cfg;
@@ -1014,12 +1018,12 @@
 	char __iomem *basel;
 	int i, ret = 0;
 	struct mdss_data_type *mdata;
+	struct mdss_mdp_ctl *ctl;
 
-	mdata = ctl->mdata;
-
-	if (!mixer || !ctl || !mdata)
+	if (!mixer || !mixer->ctl || !mixer->ctl->mdata)
 		return -EINVAL;
-
+	ctl = mixer->ctl;
+	mdata = ctl->mdata;
 	dspp_num = mixer->num;
 	/* no corresponding dspp */
 	if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
@@ -1174,12 +1178,12 @@
 
 	mutex_lock(&mdss_pp_mutex);
 	if (ctl->mixer_left) {
-		pp_mixer_setup(disp_num, ctl, ctl->mixer_left);
-		pp_dspp_setup(disp_num, ctl, ctl->mixer_left);
+		pp_mixer_setup(disp_num, ctl->mixer_left);
+		pp_dspp_setup(disp_num, ctl->mixer_left);
 	}
 	if (ctl->mixer_right) {
-		pp_mixer_setup(disp_num, ctl, ctl->mixer_right);
-		pp_dspp_setup(disp_num, ctl, ctl->mixer_right);
+		pp_mixer_setup(disp_num, ctl->mixer_right);
+		pp_dspp_setup(disp_num, ctl->mixer_right);
 	}
 	/* clear dirty flag */
 	if (disp_num < MDSS_BLOCK_DISP_NUM)
diff --git a/drivers/video/msm/mdss/mhl_msc.c b/drivers/video/msm/mdss/mhl_msc.c
index 08d0693..15811bb 100644
--- a/drivers/video/msm/mdss/mhl_msc.c
+++ b/drivers/video/msm/mdss/mhl_msc.c
@@ -201,6 +201,22 @@
 	return 0;
 }
 
+int mhl_msc_clear(struct mhl_tx_ctrl *mhl_ctrl)
+{
+	if (!mhl_ctrl)
+		return -EFAULT;
+
+	memset(mhl_ctrl->devcap, 0, 16);
+	mhl_ctrl->devcap_state = 0;
+	mhl_ctrl->path_en_state = 0;
+	mhl_ctrl->status[0] = 0;
+	mhl_ctrl->status[1] = 0;
+	mhl_ctrl->scrpd_busy = 0;
+	mhl_ctrl->wr_burst_pending = 0;
+
+	return 0;
+}
+
 int mhl_msc_command_done(struct mhl_tx_ctrl *mhl_ctrl,
 			 struct msc_command_struct *req)
 {
@@ -541,7 +557,7 @@
 		 * connected device bits
 		 * changed and DEVCAP READY
 		 */
-		if (((value ^ mhl_ctrl->devcap_state) &
+		if (((value ^ mhl_ctrl->status[offset]) &
 		     MHL_STATUS_DCAP_RDY)) {
 			if (value & MHL_STATUS_DCAP_RDY) {
 				mhl_ctrl->devcap_state = 0;
@@ -563,7 +579,7 @@
 		 * bit set
 		 */
 		tmds_en = mhl_check_tmds_enabled(mhl_ctrl);
-		if ((value ^ mhl_ctrl->path_en_state)
+		if ((value ^ mhl_ctrl->status[offset])
 		    & MHL_STATUS_PATH_ENABLED) {
 			if (value & MHL_STATUS_PATH_ENABLED) {
 				if (tmds_en &&
@@ -593,7 +609,7 @@
 		}
 		break;
 	}
-	mhl_ctrl->path_en_state = value;
+	mhl_ctrl->status[offset] = value;
 	return 0;
 }
 
diff --git a/drivers/video/msm/mdss/mhl_msc.h b/drivers/video/msm/mdss/mhl_msc.h
index 8a1fd39..3137f17 100644
--- a/drivers/video/msm/mdss/mhl_msc.h
+++ b/drivers/video/msm/mdss/mhl_msc.h
@@ -25,6 +25,8 @@
 
 /******************************************************************/
 /* the below APIs are implemented by the MSC functionality */
+int mhl_msc_clear(struct mhl_tx_ctrl *mhl_ctrl);
+
 int mhl_msc_command_done(struct mhl_tx_ctrl *mhl_ctrl,
 			 struct msc_command_struct *req);
 
diff --git a/drivers/video/msm/mdss/mhl_sii8334.c b/drivers/video/msm/mdss/mhl_sii8334.c
index 3c11317..a1053fb 100644
--- a/drivers/video/msm/mdss/mhl_sii8334.c
+++ b/drivers/video/msm/mdss/mhl_sii8334.c
@@ -867,6 +867,7 @@
 	/* disabling Tx termination */
 	MHL_SII_REG_NAME_WR(REG_MHLTX_CTL1, 0xD0);
 	switch_mode(mhl_ctrl, POWER_STATE_D3, true);
+	mhl_msc_clear(mhl_ctrl);
 }
 
 static int  mhl_msm_read_rgnd_int(struct mhl_tx_ctrl *mhl_ctrl)
diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c
index 12bc5e0..d4eb716 100644
--- a/drivers/video/msm/mdss/msm_mdss_io_8974.c
+++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c
@@ -32,6 +32,7 @@
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata)
 {
 	struct device *dev = NULL;
+	int rc = 0;
 
 	if (!pdev) {
 		pr_err("%s: Invalid pdev\n", __func__);
@@ -39,32 +40,53 @@
 	}
 
 	dev = &pdev->dev;
+	ctrl_pdata->ahb_clk = clk_get(dev, "iface_clk");
+	if (IS_ERR(ctrl_pdata->ahb_clk)) {
+		rc = PTR_ERR(ctrl_pdata->ahb_clk);
+		pr_err("%s: Unable to get mdss ahb clk. rc=%d\n",
+			__func__, rc);
+		goto mdss_dsi_clk_err;
+	}
+
+	ctrl_pdata->axi_clk = clk_get(dev, "bus_clk");
+	if (IS_ERR(ctrl_pdata->axi_clk)) {
+		rc = PTR_ERR(ctrl_pdata->axi_clk);
+		pr_err("%s: Unable to get axi bus clk. rc=%d\n",
+			__func__, rc);
+		goto mdss_dsi_clk_err;
+	}
+
 	ctrl_pdata->byte_clk = clk_get(dev, "byte_clk");
 	if (IS_ERR(ctrl_pdata->byte_clk)) {
-		pr_err("can't find dsi_byte_clk\n");
+		rc = PTR_ERR(ctrl_pdata->byte_clk);
+		pr_err("%s: can't find dsi_byte_clk. rc=%d\n",
+			__func__, rc);
 		ctrl_pdata->byte_clk = NULL;
 		goto mdss_dsi_clk_err;
 	}
 
 	ctrl_pdata->pixel_clk = clk_get(dev, "pixel_clk");
 	if (IS_ERR(ctrl_pdata->pixel_clk)) {
-		pr_err("can't find dsi_pixel_clk\n");
+		rc = PTR_ERR(ctrl_pdata->pixel_clk);
+		pr_err("%s: can't find dsi_pixel_clk. rc=%d\n",
+			__func__, rc);
 		ctrl_pdata->pixel_clk = NULL;
 		goto mdss_dsi_clk_err;
 	}
 
 	ctrl_pdata->esc_clk = clk_get(dev, "core_clk");
 	if (IS_ERR(ctrl_pdata->esc_clk)) {
-		pr_err("can't find dsi_esc_clk\n");
+		rc = PTR_ERR(ctrl_pdata->esc_clk);
+		pr_err("%s: can't find dsi_esc_clk. rc=%d\n",
+			__func__, rc);
 		ctrl_pdata->esc_clk = NULL;
 		goto mdss_dsi_clk_err;
 	}
 
-	return 0;
-
 mdss_dsi_clk_err:
-	mdss_dsi_clk_deinit(ctrl_pdata);
-	return -EPERM;
+	if (rc)
+		mdss_dsi_clk_deinit(ctrl_pdata);
+	return rc;
 }
 
 void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata  *ctrl_pdata)
@@ -75,6 +97,10 @@
 		clk_put(ctrl_pdata->esc_clk);
 	if (ctrl_pdata->pixel_clk)
 		clk_put(ctrl_pdata->pixel_clk);
+	if (ctrl_pdata->axi_clk)
+		clk_put(ctrl_pdata->axi_clk);
+	if (ctrl_pdata->ahb_clk)
+		clk_put(ctrl_pdata->ahb_clk);
 }
 
 #define PREF_DIV_RATIO 27
@@ -156,6 +182,33 @@
 	return 0;
 }
 
+int mdss_dsi_enable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+{
+	int rc = 0;
+
+	rc = clk_prepare_enable(ctrl_pdata->ahb_clk);
+	if (rc) {
+		pr_err("%s: failed to enable ahb clock. rc=%d\n", __func__, rc);
+		goto error;
+	}
+
+	rc = clk_prepare_enable(ctrl_pdata->axi_clk);
+	if (rc) {
+		pr_err("%s: failed to enable ahb clock. rc=%d\n", __func__, rc);
+		clk_disable_unprepare(ctrl_pdata->ahb_clk);
+		goto error;
+	}
+
+error:
+	return rc;
+}
+
+void mdss_dsi_disable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+{
+	clk_disable_unprepare(ctrl_pdata->axi_clk);
+	clk_disable_unprepare(ctrl_pdata->ahb_clk);
+}
+
 void mdss_dsi_prepare_clocks(struct mdss_dsi_ctrl_pdata  *ctrl_pdata)
 {
 	clk_prepare(ctrl_pdata->byte_clk);
diff --git a/include/linux/mhl_8334.h b/include/linux/mhl_8334.h
index a66a411..f04bf80 100644
--- a/include/linux/mhl_8334.h
+++ b/include/linux/mhl_8334.h
@@ -146,6 +146,7 @@
 	struct completion msc_cmd_done;
 	uint8_t devcap[16];
 	uint8_t devcap_state;
+	uint8_t status[2];
 	uint8_t path_en_state;
 	void *hdmi_mhl_ops;
 	struct work_struct mhl_msc_send_work;
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index f14cc52..2c1fa11 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -20,6 +20,7 @@
 	int32_t limit_temp_degC;
 	int32_t temp_hysteresis_degC;
 	uint32_t freq_step;
+	uint32_t freq_control_mask;
 	int32_t core_limit_temp_degC;
 	int32_t core_temp_hysteresis_degC;
 	uint32_t core_control_mask;
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 4ae3b79..209062b 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -424,6 +424,7 @@
 	bool pool_64_bit_align;
 	bool enable_hbm;
 	bool disable_park_mode;
+	bool consider_ipa_handshake;
 };
 
 struct msm_usb_host_platform_data {
@@ -465,8 +466,16 @@
 };
 #ifdef CONFIG_USB_BAM
 bool msm_bam_lpm_ok(void);
+void msm_bam_set_hsic_host_dev(struct device *dev);
+void msm_bam_wait_for_hsic_prod_granted(void);
+bool msm_bam_hsic_lpm_ok(void);
+void msm_bam_hsic_notify_on_resume(void);
 #else
 static inline bool msm_bam_lpm_ok(void) { return true; }
+static inline void msm_bam_set_hsic_host_dev(struct device *dev) {}
+static inline void msm_bam_wait_for_hsic_prod_granted(void) {}
+static inline bool msm_bam_hsic_lpm_ok(void) { return true; }
+static inline void msm_bam_hsic_notify_on_resume(void) {}
 #endif
 #ifdef CONFIG_USB_CI13XXX_MSM
 void msm_hw_bam_disable(bool bam_disable);
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 4711ec8..2a53114 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -68,6 +68,7 @@
 void wcnss_pronto_log_debug_regs(void);
 int wcnss_device_ready(void);
 void wcnss_riva_dump_pmic_regs(void);
+int wcnss_xo_auto_detect_enabled(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/msmb_pproc.h b/include/media/msmb_pproc.h
index aead2d2..6cd4995 100644
--- a/include/media/msmb_pproc.h
+++ b/include/media/msmb_pproc.h
@@ -112,9 +112,10 @@
 	struct timeval in_time, out_time;
 	void *cookie;
 	int32_t *status;
-
+	int32_t duplicate_output;
+	uint32_t duplicate_identity;
 	struct msm_cpp_buffer_info_t input_buffer_info;
-	struct msm_cpp_buffer_info_t output_buffer_info;
+	struct msm_cpp_buffer_info_t output_buffer_info[2];
 };
 
 struct cpp_hw_info {
diff --git a/include/media/tavarua.h b/include/media/tavarua.h
index 881b851..fea09dd 100644
--- a/include/media/tavarua.h
+++ b/include/media/tavarua.h
@@ -18,6 +18,7 @@
 #define BYTES_PER_BLOCK             (3)
 #define MAX_PS_LENGTH              (96)
 #define MAX_RT_LENGTH              (64)
+#define RX_STATIONS0_LEN           (15)
 
 #define XFRDAT0                    (0x20)
 #define XFRDAT1                    (0x21)
diff --git a/include/sound/Kbuild b/include/sound/Kbuild
index edadaa9..60847b0 100644
--- a/include/sound/Kbuild
+++ b/include/sound/Kbuild
@@ -12,3 +12,4 @@
 header-y += compress_params.h
 header-y += compress_offload.h
 header-y += lsm_params.h
+header-y += voice_params.h
diff --git a/include/sound/voice_params.h b/include/sound/voice_params.h
new file mode 100644
index 0000000..43e3b9d
--- /dev/null
+++ b/include/sound/voice_params.h
@@ -0,0 +1,14 @@
+#ifndef __VOICE_PARAMS_H__
+#define __VOICE_PARAMS_H__
+
+#include <linux/types.h>
+#include <sound/asound.h>
+
+enum voice_lch_mode {
+	VOICE_LCH_START = 1,
+	VOICE_LCH_STOP
+};
+
+#define SNDRV_VOICE_IOCTL_LCH _IOW('U', 0x00, enum voice_lch_mode)
+
+#endif
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 8946dce..ab96baf 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -3108,7 +3108,7 @@
 		}
 		release_firmware(fw);
 		break;
-	case SND_SOC_DAPM_POST_PMD:
+	case SND_SOC_DAPM_PRE_PMD:
 		msleep(40);
 		snd_soc_update_bits(codec, TAIKO_A_CDC_ANC1_B1_CTL, 0x01, 0x00);
 		snd_soc_update_bits(codec, TAIKO_A_CDC_ANC2_B1_CTL, 0x02, 0x00);
@@ -3209,8 +3209,6 @@
 			snd_soc_update_bits(codec,
 					TAIKO_A_RX_HPH_CNP_EN, 0x30, 0x00);
 			msleep(40);
-		}
-		if (w->shift == 5) {
 			snd_soc_update_bits(codec,
 					TAIKO_A_TX_7_MBHC_EN, 0x80, 00);
 			ret |= taiko_codec_enable_anc(w, kcontrol, event);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
index 25bb72f..5485440 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c
@@ -281,6 +281,58 @@
 	return ret;
 }
 
+static int msm_pcm_ioctl(struct snd_pcm_substream *substream,
+			 unsigned int cmd, void *arg)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct msm_voice *prtd = runtime->private_data;
+	uint16_t session_id = get_session_id(prtd);
+	enum voice_lch_mode lch_mode;
+	int ret = 0;
+
+	switch (cmd) {
+	case SNDRV_VOICE_IOCTL_LCH:
+		if (copy_from_user(&lch_mode, (void *)arg,
+				   sizeof(enum voice_lch_mode))) {
+			pr_err("%s: Copy from user failed, size %d\n", __func__,
+			       sizeof(enum voice_lch_mode));
+
+			ret = -EFAULT;
+			break;
+		}
+
+		pr_debug("%s: %s lch_mode:%d\n",
+			 __func__, substream->pcm->id, lch_mode);
+
+		switch (lch_mode) {
+		case VOICE_LCH_START:
+		case VOICE_LCH_STOP:
+			ret = voc_set_lch(session_id, lch_mode);
+			break;
+
+		default:
+			pr_err("%s: Invalid LCH MODE %d\n", __func__, lch_mode);
+
+			ret = -EFAULT;
+		}
+
+		break;
+	default:
+		pr_debug("%s: Falling into default snd_lib_ioctl cmd 0x%x\n",
+			 __func__, cmd);
+
+		ret = snd_pcm_lib_ioctl(substream, cmd, arg);
+		break;
+	}
+
+	if (!ret)
+		pr_debug("%s: ret %d\n", __func__, ret);
+	else
+		pr_err("%s: cmd 0x%x failed %d\n", __func__, cmd, ret);
+
+	return ret;
+}
+
 static int msm_voice_volume_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -476,29 +528,6 @@
 
 	return 0;
 }
-static int msm_voice_widevoice_put(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol)
-{
-	int wv_enable = ucontrol->value.integer.value[0];
-
-	pr_debug("%s: wv enable=%d\n", __func__, wv_enable);
-
-	voc_set_widevoice_enable(voc_get_session_id(VOICE_SESSION_NAME),
-				 wv_enable);
-	voc_set_widevoice_enable(voc_get_session_id(VOICE2_SESSION_NAME),
-				 wv_enable);
-
-	return 0;
-}
-
-static int msm_voice_widevoice_get(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol)
-{
-	ucontrol->value.integer.value[0] =
-	       voc_get_widevoice_enable(voc_get_session_id(VOICE_SESSION_NAME));
-	return 0;
-}
-
 
 static int msm_voice_slowtalk_put(struct snd_kcontrol *kcontrol,
 			struct snd_ctl_elem_value *ucontrol)
@@ -524,30 +553,6 @@
 	return 0;
 }
 
-static int msm_voice_fens_put(struct snd_kcontrol *kcontrol,
-			struct snd_ctl_elem_value *ucontrol)
-{
-	int fens_enable = ucontrol->value.integer.value[0];
-
-	pr_debug("%s: fens enable=%d\n", __func__, fens_enable);
-
-	voc_set_pp_enable(voc_get_session_id(VOICE_SESSION_NAME),
-			  MODULE_ID_VOICE_MODULE_FENS, fens_enable);
-	voc_set_pp_enable(voc_get_session_id(VOICE2_SESSION_NAME),
-			  MODULE_ID_VOICE_MODULE_FENS, fens_enable);
-
-	return 0;
-}
-
-static int msm_voice_fens_get(struct snd_kcontrol *kcontrol,
-			struct snd_ctl_elem_value *ucontrol)
-{
-	ucontrol->value.integer.value[0] =
-		voc_get_pp_enable(voc_get_session_id(VOICE_SESSION_NAME),
-				MODULE_ID_VOICE_MODULE_FENS);
-	return 0;
-}
-
 static struct snd_kcontrol_new msm_voice_controls[] = {
 	SOC_SINGLE_EXT("Voice Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
 				msm_voice_rx_device_mute_get,
@@ -558,12 +563,8 @@
 				msm_voice_volume_get, msm_voice_volume_put),
 	SOC_ENUM_EXT("TTY Mode", msm_tty_mode_enum[0], msm_voice_tty_mode_get,
 				msm_voice_tty_mode_put),
-	SOC_SINGLE_EXT("Widevoice Enable", SND_SOC_NOPM, 0, 1, 0,
-			msm_voice_widevoice_get, msm_voice_widevoice_put),
 	SOC_SINGLE_EXT("Slowtalk Enable", SND_SOC_NOPM, 0, 1, 0,
 				msm_voice_slowtalk_get, msm_voice_slowtalk_put),
-	SOC_SINGLE_EXT("FENS Enable", SND_SOC_NOPM, 0, 1, 0,
-				msm_voice_fens_get, msm_voice_fens_put),
 	SOC_SINGLE_EXT("VoLTE Rx Device Mute", SND_SOC_NOPM, 0, 1, 0,
 			msm_volte_rx_device_mute_get,
 			msm_volte_rx_device_mute_put),
@@ -581,11 +582,12 @@
 };
 
 static struct snd_pcm_ops msm_pcm_ops = {
-	.open           = msm_pcm_open,
-	.hw_params	= msm_pcm_hw_params,
-	.close          = msm_pcm_close,
-	.prepare        = msm_pcm_prepare,
-	.trigger	= msm_pcm_trigger,
+	.open			= msm_pcm_open,
+	.hw_params		= msm_pcm_hw_params,
+	.close			= msm_pcm_close,
+	.prepare		= msm_pcm_prepare,
+	.trigger		= msm_pcm_trigger,
+	.ioctl			= msm_pcm_ioctl,
 };
 
 
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 5f89e4a..60999fa 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -82,7 +82,6 @@
 static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv);
 static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv);
 
-static int voice_send_set_widevoice_enable_cmd(struct voice_data *v);
 static int voice_send_set_pp_enable_cmd(struct voice_data *v,
 					uint32_t module_id, int enable);
 
@@ -841,56 +840,6 @@
 	return -EINVAL;
 }
 
-static int voice_send_set_widevoice_enable_cmd(struct voice_data *v)
-{
-	struct mvm_set_widevoice_enable_cmd mvm_set_wv_cmd;
-	int ret = 0;
-	void *apr_mvm;
-	u16 mvm_handle;
-
-	if (v == NULL) {
-		pr_err("%s: v is NULL\n", __func__);
-		return -EINVAL;
-	}
-	apr_mvm = common.apr_q6_mvm;
-
-	if (!apr_mvm) {
-		pr_err("%s: apr_mvm is NULL.\n", __func__);
-		return -EINVAL;
-	}
-	mvm_handle = voice_get_mvm_handle(v);
-
-	mvm_set_wv_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
-						     APR_HDR_LEN(APR_HDR_SIZE),
-						     APR_PKT_VER);
-	mvm_set_wv_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
-						   sizeof(mvm_set_wv_cmd) -
-						   APR_HDR_SIZE);
-	mvm_set_wv_cmd.hdr.src_port = v->session_id;
-	mvm_set_wv_cmd.hdr.dest_port = mvm_handle;
-	mvm_set_wv_cmd.hdr.token = 0;
-	mvm_set_wv_cmd.hdr.opcode = VSS_IWIDEVOICE_CMD_SET_WIDEVOICE;
-
-	mvm_set_wv_cmd.vss_set_wv.enable = v->wv_enable;
-
-	v->mvm_state = CMD_STATUS_FAIL;
-	ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_wv_cmd);
-	if (ret < 0) {
-		pr_err("Fail: sending mvm set widevoice enable,\n");
-		goto fail;
-	}
-	ret = wait_event_timeout(v->mvm_wait,
-				 (v->mvm_state == CMD_STATUS_SUCCESS),
-				 msecs_to_jiffies(TIMEOUT_MS));
-	if (!ret) {
-		pr_err("%s: wait_event timeout\n", __func__);
-		goto fail;
-	}
-	return 0;
-fail:
-	return -EINVAL;
-}
-
 static int voice_send_set_pp_enable_cmd(struct voice_data *v,
 					uint32_t module_id, int enable)
 {
@@ -1444,6 +1393,34 @@
 	return -EINVAL;
 }
 
+static void voc_get_tx_rx_topology(struct voice_data *v,
+				   uint32_t *tx_topology_id,
+				   uint32_t *rx_topology_id)
+{
+	uint32_t tx_id = 0;
+	uint32_t rx_id = 0;
+
+	if (v->lch_mode == VOICE_LCH_START) {
+		pr_debug("%s: Setting TX and RX topology to NONE for LCH\n",
+			 __func__);
+
+		tx_id = VSS_IVOCPROC_TOPOLOGY_ID_NONE;
+		rx_id = VSS_IVOCPROC_TOPOLOGY_ID_NONE;
+	} else {
+		/* Use default topology if invalid value in ACDB */
+		tx_id = get_voice_tx_topology();
+		if (tx_id == 0)
+			tx_id = VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
+
+		rx_id = get_voice_rx_topology();
+		if (rx_id == 0)
+			rx_id = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
+	}
+
+	*tx_topology_id = tx_id;
+	*rx_topology_id = rx_id;
+}
+
 static int voice_send_set_device_cmd(struct voice_data *v)
 {
 	struct cvp_set_device_cmd  cvp_setdev_cmd;
@@ -1474,26 +1451,22 @@
 	cvp_setdev_cmd.hdr.src_port = v->session_id;
 	cvp_setdev_cmd.hdr.dest_port = cvp_handle;
 	cvp_setdev_cmd.hdr.token = 0;
-	cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE;
+	cvp_setdev_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_DEVICE_V2;
 
-	/* Use default topology if invalid value in ACDB */
-	cvp_setdev_cmd.cvp_set_device.tx_topology_id =
-				get_voice_tx_topology();
-	if (cvp_setdev_cmd.cvp_set_device.tx_topology_id == 0)
-		cvp_setdev_cmd.cvp_set_device.tx_topology_id =
-				VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
+	voc_get_tx_rx_topology(v,
+			&cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id,
+			&cvp_setdev_cmd.cvp_set_device_v2.rx_topology_id);
 
-	cvp_setdev_cmd.cvp_set_device.rx_topology_id =
-				get_voice_rx_topology();
-	if (cvp_setdev_cmd.cvp_set_device.rx_topology_id == 0)
-		cvp_setdev_cmd.cvp_set_device.rx_topology_id =
-				VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
-	cvp_setdev_cmd.cvp_set_device.tx_port_id = v->dev_tx.port_id;
-	cvp_setdev_cmd.cvp_set_device.rx_port_id = v->dev_rx.port_id;
+	cvp_setdev_cmd.cvp_set_device_v2.tx_port_id = v->dev_tx.port_id;
+	cvp_setdev_cmd.cvp_set_device_v2.rx_port_id = v->dev_rx.port_id;
+	cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
+				    VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
+	cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
+				    VSS_IVOCPROC_PORT_ID_NONE;
 	pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
-		cvp_setdev_cmd.cvp_set_device.tx_topology_id,
-		cvp_setdev_cmd.cvp_set_device.tx_port_id,
-		cvp_setdev_cmd.cvp_set_device.rx_port_id);
+		cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id,
+		cvp_setdev_cmd.cvp_set_device_v2.tx_port_id,
+		cvp_setdev_cmd.cvp_set_device_v2.rx_port_id);
 
 	v->cvp_state = CMD_STATUS_FAIL;
 	ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd);
@@ -2249,18 +2222,9 @@
 	cvp_session_cmd.hdr.opcode =
 			VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V2;
 
-	/* Use default topology if invalid value in ACDB */
-	cvp_session_cmd.cvp_session.tx_topology_id =
-				get_voice_tx_topology();
-	if (cvp_session_cmd.cvp_session.tx_topology_id == 0)
-		cvp_session_cmd.cvp_session.tx_topology_id =
-			VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS;
-
-	cvp_session_cmd.cvp_session.rx_topology_id =
-				get_voice_rx_topology();
-	if (cvp_session_cmd.cvp_session.rx_topology_id == 0)
-		cvp_session_cmd.cvp_session.rx_topology_id =
-			VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
+	voc_get_tx_rx_topology(v,
+			&cvp_session_cmd.cvp_session.tx_topology_id,
+			&cvp_session_cmd.cvp_session.rx_topology_id);
 
 	cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/
 	cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id;
@@ -2329,20 +2293,11 @@
 		voice_send_netid_timing_cmd(v);
 	}
 
-	/* enable widevoice if wv_enable is set */
-	if (v->wv_enable)
-		voice_send_set_widevoice_enable_cmd(v);
-
 	/* enable slowtalk if st_enable is set */
 	if (v->st_enable)
 		voice_send_set_pp_enable_cmd(v,
 					     MODULE_ID_VOICE_MODULE_ST,
 					     v->st_enable);
-
-	voice_send_set_pp_enable_cmd(v,
-				     MODULE_ID_VOICE_MODULE_FENS,
-				     v->fens_enable);
-
 	/* Start in-call music delivery if this feature is enabled */
 	if (v->music_info.play_enable)
 		voice_cvs_start_playback(v);
@@ -2645,6 +2600,9 @@
 	if (v->dtmf_rx_detect_en)
 		voice_send_dtmf_rx_detection_cmd(v, 0);
 
+	/* reset LCH mode */
+	v->lch_mode = 0;
+
 	/* detach VOCPROC and wait for response from mvm */
 	mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 						APR_HDR_LEN(APR_HDR_SIZE),
@@ -2884,7 +2842,7 @@
 	return -EINVAL;
 }
 
-static int voice_send_mute_cmd(struct voice_data *v)
+static int voice_send_stream_mute_cmd(struct voice_data *v)
 {
 	struct cvs_set_mute_cmd cvs_mute_cmd;
 	int ret = 0;
@@ -2912,7 +2870,7 @@
 	cvs_mute_cmd.hdr.token = 0;
 	cvs_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
 	cvs_mute_cmd.cvs_set_mute.direction = VSS_IVOLUME_DIRECTION_TX;
-	cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
+	cvs_mute_cmd.cvs_set_mute.mute_flag = v->stream_tx.stream_mute;
 	cvs_mute_cmd.cvs_set_mute.ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
 
 	v->cvs_state = CMD_STATUS_FAIL;
@@ -2937,7 +2895,8 @@
 	return -EINVAL;
 }
 
-static int voice_send_rx_device_mute_cmd(struct voice_data *v)
+static int voice_send_device_mute_cmd(struct voice_data *v, uint16_t direction,
+				      uint16_t mute_flag)
 {
 	struct cvp_set_mute_cmd cvp_mute_cmd;
 	int ret = 0;
@@ -2963,8 +2922,8 @@
 	cvp_mute_cmd.hdr.dest_port = voice_get_cvp_handle(v);
 	cvp_mute_cmd.hdr.token = 0;
 	cvp_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
-	cvp_mute_cmd.cvp_set_mute.direction = VSS_IVOLUME_DIRECTION_RX;
-	cvp_mute_cmd.cvp_set_mute.mute_flag = v->dev_rx.mute;
+	cvp_mute_cmd.cvp_set_mute.direction = direction;
+	cvp_mute_cmd.cvp_set_mute.mute_flag = mute_flag;
 	cvp_mute_cmd.cvp_set_mute.ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
 
 	v->cvp_state = CMD_STATUS_FAIL;
@@ -3493,7 +3452,7 @@
 	int ret = 0;
 
 	if (v == NULL) {
-		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+		pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);
 
 		return -EINVAL;
 	}
@@ -3503,7 +3462,7 @@
 	if (v->voc_state == VOC_CHANGE) {
 		ret = voice_send_set_device_cmd(v);
 		if (ret < 0) {
-			pr_err("%s:  set device failed\n", __func__);
+			pr_err("%s:  Set device failed\n", __func__);
 			goto fail;
 		}
 
@@ -3511,31 +3470,45 @@
 		voice_send_cvp_register_cal_cmd(v);
 		voice_send_cvp_register_vol_cal_cmd(v);
 
+		if (v->lch_mode == VOICE_LCH_START) {
+			pr_debug("%s: TX and RX mute ON\n", __func__);
+
+			voice_send_device_mute_cmd(v,
+						   VSS_IVOLUME_DIRECTION_TX,
+						   VSS_IVOLUME_MUTE_ON);
+			voice_send_device_mute_cmd(v,
+						   VSS_IVOLUME_DIRECTION_RX,
+						   VSS_IVOLUME_MUTE_ON);
+		} else if (v->lch_mode == VOICE_LCH_STOP) {
+			pr_debug("%s: TX and RX mute OFF\n", __func__);
+
+			voice_send_device_mute_cmd(v,
+						   VSS_IVOLUME_DIRECTION_TX,
+						   VSS_IVOLUME_MUTE_OFF);
+			voice_send_device_mute_cmd(v,
+						   VSS_IVOLUME_DIRECTION_RX,
+						   VSS_IVOLUME_MUTE_OFF);
+			/* Reset lch mode when VOICE_LCH_STOP is recieved */
+			v->lch_mode = 0;
+		} else {
+			pr_debug("%s: Mute commands not sent for lch_mode=%d\n",
+				 __func__, v->lch_mode);
+		}
+
 		ret = voice_send_enable_vocproc_cmd(v);
 		if (ret < 0) {
-			pr_err("%s: enable vocproc failed %d\n", __func__, ret);
+			pr_err("%s: Enable vocproc failed %d\n", __func__, ret);
+
 			goto fail;
 		}
 
 		/* Send tty mode if tty device is used */
 		voice_send_tty_mode_cmd(v);
-
-		/* enable widevoice if wv_enable is set */
-		if (v->wv_enable)
-			voice_send_set_widevoice_enable_cmd(v);
-
 		/* enable slowtalk */
 		if (v->st_enable)
 			voice_send_set_pp_enable_cmd(v,
 					     MODULE_ID_VOICE_MODULE_ST,
 					     v->st_enable);
-
-		/* enable FENS */
-		if (v->fens_enable)
-			voice_send_set_pp_enable_cmd(v,
-					     MODULE_ID_VOICE_MODULE_FENS,
-					     v->fens_enable);
-
 		rtac_add_voice(voice_get_cvs_handle(v),
 			voice_get_cvp_handle(v),
 			v->dev_rx.port_id, v->dev_tx.port_id,
@@ -3593,12 +3566,12 @@
 
 	mutex_lock(&v->lock);
 
-	v->dev_tx.mute = mute;
+	v->stream_tx.stream_mute = mute;
 
 	if ((v->voc_state == VOC_RUN) ||
 	    (v->voc_state == VOC_CHANGE) ||
 	    (v->voc_state == VOC_STANDBY))
-		ret = voice_send_mute_cmd(v);
+		ret = voice_send_stream_mute_cmd(v);
 
 	mutex_unlock(&v->lock);
 
@@ -3618,10 +3591,12 @@
 
 	mutex_lock(&v->lock);
 
-	v->dev_rx.mute = mute;
+	v->dev_rx.dev_mute = mute;
 
 	if (v->voc_state == VOC_RUN)
-		ret = voice_send_rx_device_mute_cmd(v);
+		ret = voice_send_device_mute_cmd(v,
+						 VSS_IVOLUME_DIRECTION_RX,
+						 v->dev_rx.dev_mute);
 
 	mutex_unlock(&v->lock);
 
@@ -3641,7 +3616,7 @@
 
 	mutex_lock(&v->lock);
 
-	ret = v->dev_rx.mute;
+	ret = v->dev_rx.dev_mute;
 
 	mutex_unlock(&v->lock);
 
@@ -3688,51 +3663,6 @@
 	return ret;
 }
 
-int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable)
-{
-	struct voice_data *v = voice_get_session(session_id);
-	u16 mvm_handle;
-	int ret = 0;
-
-	if (v == NULL) {
-		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
-
-		return -EINVAL;
-	}
-
-	mutex_lock(&v->lock);
-
-	v->wv_enable = wv_enable;
-
-	mvm_handle = voice_get_mvm_handle(v);
-	if (mvm_handle != 0)
-		voice_send_set_widevoice_enable_cmd(v);
-
-	mutex_unlock(&v->lock);
-
-	return ret;
-}
-
-uint32_t voc_get_widevoice_enable(uint16_t session_id)
-{
-	struct voice_data *v = voice_get_session(session_id);
-	int ret = 0;
-
-	if (v == NULL) {
-		pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
-
-		return -EINVAL;
-	}
-
-	mutex_lock(&v->lock);
-
-	ret = v->wv_enable;
-
-	mutex_unlock(&v->lock);
-
-	return ret;
-}
-
 int voc_set_pp_enable(uint16_t session_id, uint32_t module_id, uint32_t enable)
 {
 	struct voice_data *v = voice_get_session(session_id);
@@ -3747,18 +3677,12 @@
 	mutex_lock(&v->lock);
 	if (module_id == MODULE_ID_VOICE_MODULE_ST)
 		v->st_enable = enable;
-	else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
-		v->fens_enable = enable;
 
 	if (v->voc_state == VOC_RUN) {
 		if (module_id == MODULE_ID_VOICE_MODULE_ST)
 			ret = voice_send_set_pp_enable_cmd(v,
 						MODULE_ID_VOICE_MODULE_ST,
 						enable);
-		else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
-			ret = voice_send_set_pp_enable_cmd(v,
-						MODULE_ID_VOICE_MODULE_FENS,
-						enable);
 	}
 
 	mutex_unlock(&v->lock);
@@ -3780,9 +3704,6 @@
 	mutex_lock(&v->lock);
 	if (module_id == MODULE_ID_VOICE_MODULE_ST)
 		ret = v->st_enable;
-	else if (module_id == MODULE_ID_VOICE_MODULE_FENS)
-		ret = v->fens_enable;
-
 	mutex_unlock(&v->lock);
 
 	return ret;
@@ -3960,6 +3881,49 @@
 	return ret;
 }
 
+int voc_set_lch(uint16_t session_id, enum voice_lch_mode lch_mode)
+{
+	struct voice_data *v = voice_get_session(session_id);
+	int ret = 0;
+
+	if (v == NULL) {
+		pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);
+
+		ret = -EINVAL;
+		goto done;
+	}
+
+	mutex_lock(&v->lock);
+	if (v->lch_mode == lch_mode) {
+		pr_debug("%s: Session %d already in LCH mode %d\n",
+				 __func__, session_id, lch_mode);
+
+		mutex_unlock(&v->lock);
+		goto done;
+	}
+
+	v->lch_mode = lch_mode;
+	mutex_unlock(&v->lock);
+
+	ret = voc_disable_cvp(session_id);
+	if (ret < 0) {
+		pr_err("%s: voc_disable_cvp failed ret=%d\n", __func__, ret);
+
+		goto done;
+	}
+
+	/* Mute and topology_none will be set as part of voc_enable_cvp() */
+	ret = voc_enable_cvp(session_id);
+	if (ret < 0) {
+		pr_err("%s: voc_enable_cvp failed ret=%d\n", __func__, ret);
+
+		goto done;
+	}
+
+done:
+	return ret;
+}
+
 int voc_resume_voice_call(uint16_t session_id)
 {
 	struct voice_data *v = voice_get_session(session_id);
@@ -4181,7 +4145,6 @@
 			case VSS_IMVM_CMD_DETACH_STREAM:
 			case VSS_ICOMMON_CMD_SET_NETWORK:
 			case VSS_ICOMMON_CMD_SET_VOICE_TIMING:
-			case VSS_IWIDEVOICE_CMD_SET_WIDEVOICE:
 			case VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL:
 			case VSS_IMVM_CMD_SET_CAL_NETWORK:
 			case VSS_IMVM_CMD_SET_CAL_MEDIA_TYPE:
@@ -4580,7 +4543,7 @@
 				v->cvp_state = CMD_STATUS_SUCCESS;
 				wake_up(&v->cvp_wait);
 				break;
-			case VSS_IVOCPROC_CMD_SET_DEVICE:
+			case VSS_IVOCPROC_CMD_SET_DEVICE_V2:
 			case VSS_IVOCPROC_CMD_SET_RX_VOLUME_INDEX:
 			case VSS_IVOCPROC_CMD_ENABLE:
 			case VSS_IVOCPROC_CMD_DISABLE:
@@ -4769,13 +4732,16 @@
 
 		/* initialize dev_rx and dev_tx */
 		common.voice[i].dev_rx.volume = common.default_vol_val;
-		common.voice[i].dev_rx.mute =  0;
-		common.voice[i].dev_tx.mute = common.default_mute_val;
+		common.voice[i].dev_rx.dev_mute =  0;
+		common.voice[i].dev_tx.dev_mute =  0;
+		common.voice[i].stream_rx.stream_mute = common.default_mute_val;
+		common.voice[i].stream_tx.stream_mute = common.default_mute_val;
 
 		common.voice[i].dev_tx.port_id = 0x100B;
 		common.voice[i].dev_rx.port_id = 0x100A;
 		common.voice[i].sidetone_gain = 0x512;
 		common.voice[i].dtmf_rx_detect_en = 0;
+		common.voice[i].lch_mode = 0;
 
 		common.voice[i].voc_state = VOC_INIT;
 
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index ef5c6e3..386634b 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -14,6 +14,7 @@
 
 #include <mach/qdsp6v2/apr.h>
 #include <linux/msm_ion.h>
+#include <sound/voice_params.h>
 
 #define MAX_VOC_PKT_SIZE 642
 #define SESSION_NAME_LEN 20
@@ -41,11 +42,15 @@
 	void *cb_handle;
 };
 
-/* Device information payload structure */
+/* Stream information payload structure */
+struct stream_data {
+	uint32_t stream_mute;
+};
 
+/* Device information payload structure */
 struct device_data {
 	uint32_t volume; /* in index */
-	uint32_t mute;
+	uint32_t dev_mute;
 	uint32_t sample;
 	uint32_t enabled;
 	uint32_t dev_id;
@@ -194,9 +199,6 @@
 #define VSS_ICOMMON_CMD_SET_VOICE_TIMING		0x000111E0
 /* Set the voice timing parameters. */
 
-#define VSS_IWIDEVOICE_CMD_SET_WIDEVOICE                0x00011243
-/* Enable/disable WideVoice */
-
 #define VSS_IMEMORY_CMD_MAP_PHYSICAL			0x00011334
 #define VSS_IMEMORY_RSP_MAP				0x00011336
 #define VSS_IMEMORY_CMD_UNMAP				0x00011337
@@ -291,14 +293,6 @@
 	/* Set to TRUE to enable modem state machine control */
 } __packed;
 
-struct vss_iwidevoice_cmd_set_widevoice_t {
-	uint32_t enable;
-	/* WideVoice enable/disable; possible values:
-	* - 0 -- WideVoice disabled
-	* - 1 -- WideVoice enabled
-	*/
-} __packed;
-
 struct mvm_attach_vocproc_cmd {
 	struct apr_hdr hdr;
 	struct vss_istream_cmd_attach_vocproc_t mvm_attach_cvp_handle;
@@ -344,11 +338,6 @@
 	struct vss_icommon_cmd_set_voice_timing_t timing;
 } __packed;
 
-struct mvm_set_widevoice_enable_cmd {
-	struct apr_hdr hdr;
-	struct vss_iwidevoice_cmd_set_widevoice_t vss_set_wv;
-} __packed;
-
 struct vss_imemory_table_descriptor_t {
 	uint64_t mem_address;
 	/*
@@ -484,7 +473,6 @@
 #define VSS_ISTREAM_CMD_SET_ENC_DTX_MODE		0x0001101D
 /* Set encoder DTX mode. */
 
-#define MODULE_ID_VOICE_MODULE_FENS			0x00010EEB
 #define MODULE_ID_VOICE_MODULE_ST			0x00010EE3
 #define VOICE_PARAM_MOD_ENABLE				0x00010E00
 #define MOD_ENABLE_PARAM_LEN				4
@@ -904,7 +892,7 @@
 
 #define APRV2_IBASIC_CMD_DESTROY_SESSION		0x0001003C
 
-#define VSS_IVOCPROC_CMD_SET_DEVICE			0x000100C4
+#define VSS_IVOCPROC_CMD_SET_DEVICE_V2			0x000112C6
 
 #define VSS_IVOCPROC_CMD_SET_VP3_DATA			0x000110EB
 
@@ -1042,8 +1030,8 @@
 	 */
 } __packed;
 
-struct vss_ivocproc_cmd_set_device_t {
-	uint32_t tx_port_id;
+struct vss_ivocproc_cmd_set_device_v2_t {
+	uint16_t tx_port_id;
 	/*
 	 * TX device port ID which vocproc will connect to.
 	 * VSS_IVOCPROC_PORT_ID_NONE means vocproc will not connect to any port.
@@ -1054,7 +1042,7 @@
 	 * VSS_IVOCPROC_TOPOLOGY_ID_NONE means vocproc does not contain any
 	 * pre/post-processing blocks and is pass-through.
 	 */
-	int32_t rx_port_id;
+	uint16_t rx_port_id;
 	/*
 	 * RX device port ID which vocproc will connect to.
 	 * VSS_IVOCPROC_PORT_ID_NONE means vocproc will not connect to any port.
@@ -1065,6 +1053,15 @@
 	 * VSS_IVOCPROC_TOPOLOGY_ID_NONE means vocproc does not contain any
 	 * pre/post-processing blocks and is pass-through.
 	 */
+	uint32_t vocproc_mode;
+	/* Vocproc mode. The supported values:
+	 * VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING - 0x00010F7C
+	 * VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING - 0x00010F7D
+	 */
+	uint16_t ec_ref_port_id;
+	/* Port ID to which the vocproc connects for receiving
+	 * echo
+	 */
 } __packed;
 
 struct vss_ivocproc_cmd_register_device_config_t {
@@ -1128,7 +1125,7 @@
 
 struct cvp_set_device_cmd {
 	struct apr_hdr hdr;
-	struct vss_ivocproc_cmd_set_device_t cvp_set_device;
+	struct vss_ivocproc_cmd_set_device_v2_t cvp_set_device_v2;
 } __packed;
 
 struct cvp_set_vp3_data_cmd {
@@ -1230,10 +1227,14 @@
 	wait_queue_head_t cvs_wait;
 	wait_queue_head_t cvp_wait;
 
-	/* cache the values related to Rx and Tx */
+	/* Cache the values related to Rx and Tx devices */
 	struct device_data dev_rx;
 	struct device_data dev_tx;
 
+	/* Cache the values related to Rx and Tx streams */
+	struct stream_data stream_rx;
+	struct stream_data stream_tx;
+
 	u32 mvm_state;
 	u32 cvs_state;
 	u32 cvp_state;
@@ -1249,14 +1250,11 @@
 
 	uint16_t sidetone_gain;
 	uint8_t tty_mode;
-	/* widevoice enable value */
-	uint8_t wv_enable;
 	/* slowtalk enable value */
 	uint32_t st_enable;
-	/* FENC enable value */
-	uint32_t fens_enable;
-
 	uint32_t dtmf_rx_detect_en;
+	/* Local Call Hold mode */
+	uint8_t lch_mode;
 
 	struct voice_dev_route_state voc_route_state;
 
@@ -1345,14 +1343,13 @@
 int voc_set_pp_enable(uint16_t session_id, uint32_t module_id,
 		      uint32_t enable);
 int voc_get_pp_enable(uint16_t session_id, uint32_t module_id);
-int voc_set_widevoice_enable(uint16_t session_id, uint32_t wv_enable);
-uint32_t voc_get_widevoice_enable(uint16_t session_id);
 uint8_t voc_get_tty_mode(uint16_t session_id);
 int voc_set_tty_mode(uint16_t session_id, uint8_t tty_mode);
 int voc_start_voice_call(uint16_t session_id);
 int voc_end_voice_call(uint16_t session_id);
 int voc_standby_voice_call(uint16_t session_id);
 int voc_resume_voice_call(uint16_t session_id);
+int voc_set_lch(uint16_t session_id, enum voice_lch_mode lch_mode);
 int voc_set_rxtx_port(uint16_t session_id,
 		      uint32_t dev_port_id,
 		      uint32_t dev_type);