Merge "coresight: add lpae support for coresight tmc driver"
diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
index cc2506d..6f6f68d 100644
--- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
@@ -12,6 +12,7 @@
 Optional properties:
 - reg : offset and length of the register set for the device.
 - interrupts : should contain the vidc interrupt.
+- vdd-supply : regulator to supply venus.
 - qcom,vidc-cp-map : start and size of device virtual address range for
   secure buffers. Video hardware uses this address range to identify if
   the buffers are secure or non-secure.
@@ -66,6 +67,7 @@
 		compatible = "qcom,msm-vidc";
 		reg = <0xfdc00000 0xff000>;
 		interrupts = <0 44 0>;
+		vdd-supply = <&gdsc_venus>;
 		qcom,vidc-cp-map = <0x1000000 0x40000000>;
 		qcom,vidc-ns-map = <0x40000000 0x40000000>;
 		qcom,load-freq-tbl = <979200 410000000>,
diff --git a/arch/arm/boot/dts/dsi-panel-generic-720p-cmd.dtsi b/arch/arm/boot/dts/dsi-panel-generic-720p-cmd.dtsi
new file mode 100644
index 0000000..23091f0
--- /dev/null
+++ b/arch/arm/boot/dts/dsi-panel-generic-720p-cmd.dtsi
@@ -0,0 +1,80 @@
+/* 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.
+ */
+
+/*---------------------------------------------------------------------------
+ * This file is autogenerated file using gcdb parser. Please do not edit it.
+ * Update input XML file to add a new entry or update variable in this file
+ * VERSION = "1.0"
+ *---------------------------------------------------------------------------*/
+&mdss_mdp {
+	dsi_generic_720p_cmd: qcom,mdss_dsi_generic_720p_cmd {
+		qcom,mdss-dsi-panel-name = "generic 720p cmd mode dsi panel";
+		qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
+		qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
+		qcom,mdss-dsi-panel-destination = "display_1";
+		qcom,mdss-dsi-panel-framerate = <60>;
+		qcom,mdss-dsi-stream = <0>;
+		qcom,mdss-dsi-panel-width = <768>;
+		qcom,mdss-dsi-panel-height = <1280>;
+		qcom,mdss-dsi-h-front-porch = <26>;
+		qcom,mdss-dsi-h-back-porch = <26>;
+		qcom,mdss-dsi-h-pulse-width = <26>;
+		qcom,mdss-dsi-h-sync-skew = <0>;
+		qcom,mdss-dsi-v-back-porch = <2>;
+		qcom,mdss-dsi-v-front-porch = <2>;
+		qcom,mdss-dsi-v-pulse-width = <2>;
+		qcom,mdss-dsi-h-left-border = <0>;
+		qcom,mdss-dsi-h-right-border = <0>;
+		qcom,mdss-dsi-v-top-border = <0>;
+		qcom,mdss-dsi-v-bottom-border = <0>;
+		qcom,mdss-dsi-bpp = <24>;
+		qcom,mdss-dsi-color-order = <0>;
+		qcom,mdss-dsi-underflow-color = <0xff>;
+		qcom,mdss-dsi-border-color = <0>;
+		qcom,mdss-dsi-on-command = [05 01 00 00 78 00 01 11
+				15 01 00 00 0a 00 02 36 00
+				05 01 00 00 0a 00 01 29
+				15 01 00 00 0a 00 02 53 24
+				15 01 00 00 0a 00 02 35 00];
+		qcom,mdss-dsi-off-command = [05 01 00 00 0a 00 01 34
+				 05 01 00 00 78 00 01 10
+				05 01 00 00 78 00 01 28
+				 15 01 00 00 0a 00 02 53 00];
+		qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+		qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+		qcom,mdss-dsi-h-sync-pulse = <0>;
+		qcom,mdss-dsi-traffic-mode = <1>;
+		qcom,mdss-dsi-lane-map = <0>;
+		qcom,mdss-dsi-bllp-eof-power-mode;
+		qcom,mdss-dsi-bllp-power-mode;
+		qcom,mdss-dsi-lane-0-state;
+		qcom,mdss-dsi-lane-1-state;
+		qcom,mdss-dsi-lane-2-state;
+		qcom,mdss-dsi-lane-3-state;
+		qcom,mdss-dsi-te-pin-select = <1>;
+		qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line = <0x2c>;
+		qcom,mdss-dsi-te-v-sync-continues-lines = <0x3c>;
+		qcom,mdss-dsi-te-dcs-command = <1>;
+		qcom,mdss-dsi-te-check-enable;
+		qcom,mdss-dsi-te-using-te-pin;
+		qcom,mdss-dsi-panel-timings = [6e 26 1b 00 35 34 20 28 17 03 04 00];
+		qcom,mdss-dsi-t-clk-post = <0x20>;
+		qcom,mdss-dsi-t-clk-pre = <0x2a>;
+		qcom,mdss-dsi-bl-min-level = <1>;
+		qcom,mdss-dsi-bl-max-level = <255>;
+		qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+		qcom,mdss-dsi-bl-pmic-bank-select = <7>;
+		qcom,mdss-dsi-dma-trigger = <4>;
+		qcom,mdss-dsi-mdp-trigger = <0>;
+		qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226-mdss.dtsi b/arch/arm/boot/dts/msm8226-mdss.dtsi
index 947cc93..2ec7b6c 100644
--- a/arch/arm/boot/dts/msm8226-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8226-mdss.dtsi
@@ -67,7 +67,7 @@
 		vdd-supply = <&pm8226_l15>;
 		vddio-supply = <&pm8226_l8>;
 		vdda-supply = <&pm8226_l4>;
-		qcom,platform-reset-gpio = <&msmgpio 25 1>;
+		qcom,platform-reset-gpio = <&msmgpio 25 0>;
 		qcom,platform-te-gpio = <&msmgpio 24 0>;
 		qcom,platform-strength-ctrl = [ff 06];
 		qcom,platform-bist-ctrl = [00 00 b1 ff 00 00];
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 0ae0fc6..7b944fc 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -33,7 +33,7 @@
 
 		adsp_mem: adsp_region {
 			linux,contiguous-region;
-			reg = <0 0x2000000>;
+			reg = <0 0xc00000>;
 			label = "adsp_mem";
 		};
 
@@ -158,6 +158,7 @@
 		compatible = "qcom,msm-vidc";
 		reg = <0xfdc00000 0xff000>;
 		interrupts = <0 44 0>;
+		vdd-supply = <&gdsc_venus>;
 		qcom,load-freq-tbl = <352800 160000000>,
 			<244800 133330000>,
 			<108000  66700000>;
diff --git a/arch/arm/boot/dts/msm8610-cdp.dtsi b/arch/arm/boot/dts/msm8610-cdp.dtsi
index 8403dfd..cc4d93b 100644
--- a/arch/arm/boot/dts/msm8610-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8610-cdp.dtsi
@@ -121,14 +121,15 @@
 		};
 	};
 
-    sound {
-        qcom,audio-routing =
-            "RX_BIAS", "MCLK",
-            "INT_LDO_H", "MCLK",
-            "MIC BIAS External", "Handset Mic",
-            "MIC BIAS Internal2", "Headset Mic",
-            "AMIC1", "MIC BIAS External",
-            "AMIC2", "MIC BIAS Internal2";
+	sound {
+		qcom,audio-routing =
+			"RX_BIAS", "MCLK",
+			"INT_LDO_H", "MCLK",
+			"MIC BIAS External", "Handset Mic",
+			"MIC BIAS Internal2", "Headset Mic",
+			"AMIC1", "MIC BIAS External",
+			"AMIC2", "MIC BIAS Internal2";
+		qcom,headset-jack-type-NC;
     };
 
 	qcom,dsi_v2_truly_wvga_video {
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 89a7cff..7dcb985 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -944,15 +944,11 @@
 
 &gdsc_vfe {
 	qcom,clock-names = "core_clk", "iface_clk", "bus_clk";
-	qcom,skip-logic-collapse;
-	qcom,retain-periph;
-	qcom,retain-mem;
 	status = "ok";
 };
 
 &gdsc_oxili_cx {
 	qcom,clock-names = "core_clk", "iface_clk", "mem_clk";
-	qcom,skip-logic-collapse;
 	status = "ok";
 };
 
diff --git a/arch/arm/boot/dts/msm8926-cdp.dts b/arch/arm/boot/dts/msm8926-cdp.dts
index 677ca7e..500c7d8 100644
--- a/arch/arm/boot/dts/msm8926-cdp.dts
+++ b/arch/arm/boot/dts/msm8926-cdp.dts
@@ -20,7 +20,9 @@
 	model = "Qualcomm MSM 8926 CDP";
 	compatible = "qcom,msm8926-cdp", "qcom,msm8926", "qcom,cdp";
 	qcom,msm-id = <200 1 0>,
-		      <224 1 0>;
+		      <224 1 0>,
+		      <200 1 0x10001>,
+		      <224 1 0x10001>;
 };
 
 &pm8226_chg {
diff --git a/arch/arm/boot/dts/msm8926-mtp.dts b/arch/arm/boot/dts/msm8926-mtp.dts
index 1c9b7dc..73635bc 100644
--- a/arch/arm/boot/dts/msm8926-mtp.dts
+++ b/arch/arm/boot/dts/msm8926-mtp.dts
@@ -20,5 +20,7 @@
 	model = "Qualcomm MSM 8926 MTP";
 	compatible = "qcom,msm8926-mtp", "qcom,msm8926", "qcom,mtp";
 	qcom,msm-id = <200 8 0>,
-		      <224 8 0>;
+		      <224 8 0>,
+		      <200 8 0x10001>,
+		      <224 8 0x10001>;
 };
diff --git a/arch/arm/boot/dts/msm8926-qrd.dts b/arch/arm/boot/dts/msm8926-qrd.dts
index 6a66e4b..5cae698 100644
--- a/arch/arm/boot/dts/msm8926-qrd.dts
+++ b/arch/arm/boot/dts/msm8926-qrd.dts
@@ -18,5 +18,7 @@
 	model = "Qualcomm MSM 8926 QRD";
 	compatible = "qcom,msm8926-qrd", "qcom,msm8926", "qcom,qrd";
 	qcom,msm-id = <200 11 0>,
-		      <224 11 0>;
+		      <224 11 0>,
+		      <200 11 0x10001>,
+		      <224 11 0x10001>;
 };
diff --git a/arch/arm/boot/dts/msm8926.dtsi b/arch/arm/boot/dts/msm8926.dtsi
index e27e6d1..5893a9b 100644
--- a/arch/arm/boot/dts/msm8926.dtsi
+++ b/arch/arm/boot/dts/msm8926.dtsi
@@ -23,7 +23,9 @@
 	model = "Qualcomm MSM 8926";
 	compatible = "qcom,msm8926";
 	qcom,msm-id = <200 0>,
-		      <224 0>;
+		      <224 0>,
+		      <200 0x10001>,
+		      <224 0x10001>;
 };
 
 &soc {
diff --git a/arch/arm/boot/dts/msm8974-mdss-panels.dtsi b/arch/arm/boot/dts/msm8974-mdss-panels.dtsi
index ab43834..00fc779 100644
--- a/arch/arm/boot/dts/msm8974-mdss-panels.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss-panels.dtsi
@@ -13,3 +13,4 @@
 /include/ "dsi-panel-orise-720p-video.dtsi"
 /include/ "dsi-panel-toshiba-720p-video.dtsi"
 /include/ "dsi-panel-sharp-qhd-video.dtsi"
+/include/ "dsi-panel-generic-720p-cmd.dtsi"
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index 99c15af..24b5860 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -87,9 +87,10 @@
 		vdda-supply = <&pm8941_l2>;
 		qcom,mdss-fb-map = <&mdss_fb0>;
 		qcom,mdss-mdp = <&mdss_mdp>;
-		qcom,platform-reset-gpio = <&pm8941_gpios 19 1>;
-		qcom,platform-enable-gpio = <&msmgpio 58 1>;
+		qcom,platform-reset-gpio = <&pm8941_gpios 19 0>;
+		qcom,platform-enable-gpio = <&msmgpio 58 0>;
 		qcom,platform-reset-sequence = <1 20 0 200 1 20 2>;
+		qcom,platform-te-gpio = <&msmgpio 12 0>;
 		qcom,platform-strength-ctrl = [ff 06];
 		qcom,platform-bist-ctrl = [00 00 b1 ff 00 00];
 		qcom,platform-regulator-settings = [07 09 03 00 20 00 01];
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 1845e17..45aaee9 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -211,6 +211,7 @@
 		compatible = "qcom,msm-vidc";
 		reg = <0xfdc00000 0xff000>;
 		interrupts = <0 44 0>;
+		vdd-supply = <&gdsc_venus>;
 		qcom,hfi = "venus";
 		qcom,has-ocmem;
 		qcom,max-hw-load = <1224450>; /* 4k @ 30 + 1080p @ 30*/
diff --git a/arch/arm/configs/apq8084_defconfig b/arch/arm/configs/apq8084_defconfig
index f4ad0c4..66d66fc 100644
--- a/arch/arm/configs/apq8084_defconfig
+++ b/arch/arm/configs/apq8084_defconfig
@@ -1,6 +1,7 @@
 # CONFIG_ARM_PATCH_PHYS_VIRT is not set
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
+CONFIG_AUDIT=y
 CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -129,6 +130,7 @@
 CONFIG_NETFILTER=y
 CONFIG_NETFILTER_NETLINK_LOG=y
 CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
 CONFIG_NF_CONNTRACK_EVENTS=y
 CONFIG_NF_CT_PROTO_DCCP=y
 CONFIG_NF_CT_PROTO_SCTP=y
@@ -146,9 +148,11 @@
 CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_LOG=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
 CONFIG_NETFILTER_XT_MATCH_COMMENT=y
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
@@ -182,6 +186,7 @@
 CONFIG_IP_NF_TARGET_REJECT=y
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
 CONFIG_IP_NF_ARPTABLES=y
 CONFIG_IP_NF_ARPFILTER=y
 CONFIG_IP_NF_ARP_MANGLE=y
@@ -359,6 +364,7 @@
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
 CONFIG_FUSE_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
@@ -393,6 +399,10 @@
 CONFIG_EARLY_PRINTK=y
 CONFIG_PID_IN_CONTEXTIDR=y
 CONFIG_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=4096
+CONFIG_SECURITY_SELINUX=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_ARC4=y
diff --git a/arch/arm/configs/msm8226-perf_defconfig b/arch/arm/configs/msm8226-perf_defconfig
index 7d96cb1..9535e05 100644
--- a/arch/arm/configs/msm8226-perf_defconfig
+++ b/arch/arm/configs/msm8226-perf_defconfig
@@ -1,6 +1,7 @@
 # CONFIG_ARM_PATCH_PHYS_VIRT is not set
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
+CONFIG_AUDIT=y
 CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -125,6 +126,7 @@
 CONFIG_NETFILTER=y
 CONFIG_NETFILTER_NETLINK_LOG=y
 CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
 CONFIG_NF_CONNTRACK_EVENTS=y
 CONFIG_NF_CT_PROTO_DCCP=y
 CONFIG_NF_CT_PROTO_SCTP=y
@@ -142,10 +144,12 @@
 CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_LOG=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
 CONFIG_NETFILTER_XT_MATCH_COMMENT=y
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
@@ -183,6 +187,7 @@
 CONFIG_IP_NF_TARGET_REDIRECT=y
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
 CONFIG_IP_NF_ARPTABLES=y
 CONFIG_IP_NF_ARPFILTER=y
 CONFIG_IP_NF_ARP_MANGLE=y
@@ -319,6 +324,7 @@
 CONFIG_ION=y
 CONFIG_ION_MSM=y
 CONFIG_MSM_KGSL=y
+CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
 CONFIG_FB=y
 CONFIG_FB_MSM=y
 # CONFIG_FB_MSM_BACKLIGHT is not set
@@ -404,6 +410,7 @@
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
 CONFIG_FUSE_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
@@ -422,6 +429,10 @@
 CONFIG_DEBUG_SET_MODULE_RONX=y
 CONFIG_KEYS=y
 CONFIG_CRYPTO_NULL=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=4096
+CONFIG_SECURITY_SELINUX=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_XCBC=y
diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
index 1d5c492..176a8a2 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -1,6 +1,7 @@
 # CONFIG_ARM_PATCH_PHYS_VIRT is not set
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
+CONFIG_AUDIT=y
 CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -126,6 +127,7 @@
 CONFIG_NETFILTER=y
 CONFIG_NETFILTER_NETLINK_LOG=y
 CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
 CONFIG_NF_CONNTRACK_EVENTS=y
 CONFIG_NF_CT_PROTO_DCCP=y
 CONFIG_NF_CT_PROTO_SCTP=y
@@ -143,10 +145,12 @@
 CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_LOG=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
 CONFIG_NETFILTER_XT_MATCH_COMMENT=y
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
@@ -184,6 +188,7 @@
 CONFIG_IP_NF_TARGET_REDIRECT=y
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
 CONFIG_IP_NF_ARPTABLES=y
 CONFIG_IP_NF_ARPFILTER=y
 CONFIG_IP_NF_ARP_MANGLE=y
@@ -345,6 +350,7 @@
 CONFIG_ION=y
 CONFIG_ION_MSM=y
 CONFIG_MSM_KGSL=y
+CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
 CONFIG_FB=y
 CONFIG_FB_MSM=y
 # CONFIG_FB_MSM_BACKLIGHT is not set
@@ -440,6 +446,7 @@
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
 CONFIG_FUSE_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
@@ -473,6 +480,10 @@
 CONFIG_DEBUG_SET_MODULE_RONX=y
 CONFIG_KEYS=y
 CONFIG_CRYPTO_NULL=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=4096
+CONFIG_SECURITY_SELINUX=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_XCBC=y
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index 03ddb3a..2cf343b 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -2,6 +2,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-perf"
 CONFIG_SYSVIPC=y
+CONFIG_AUDIT=y
 CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -121,6 +122,7 @@
 CONFIG_NETFILTER=y
 CONFIG_NETFILTER_NETLINK_LOG=y
 CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
 CONFIG_NF_CONNTRACK_EVENTS=y
 CONFIG_NF_CT_PROTO_DCCP=y
 CONFIG_NF_CT_PROTO_SCTP=y
@@ -138,9 +140,11 @@
 CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_LOG=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
 CONFIG_NETFILTER_XT_MATCH_COMMENT=y
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
@@ -178,6 +182,7 @@
 CONFIG_IP_NF_TARGET_REDIRECT=y
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
 CONFIG_IP_NF_ARPTABLES=y
 CONFIG_IP_NF_ARPFILTER=y
 CONFIG_IP_NF_ARP_MANGLE=y
@@ -365,6 +370,7 @@
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
 CONFIG_FUSE_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
@@ -381,6 +387,10 @@
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_SET_MODULE_RONX=y
 CONFIG_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=4096
+CONFIG_SECURITY_SELINUX=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_TWOFISH=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index aad3540..91731d0 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -1,6 +1,7 @@
 # CONFIG_ARM_PATCH_PHYS_VIRT is not set
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
+CONFIG_AUDIT=y
 CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -122,6 +123,7 @@
 CONFIG_NETFILTER=y
 CONFIG_NETFILTER_NETLINK_LOG=y
 CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
 CONFIG_NF_CONNTRACK_EVENTS=y
 CONFIG_NF_CT_PROTO_DCCP=y
 CONFIG_NF_CT_PROTO_SCTP=y
@@ -139,9 +141,11 @@
 CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_LOG=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
 CONFIG_NETFILTER_XT_MATCH_COMMENT=y
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
@@ -179,6 +183,7 @@
 CONFIG_IP_NF_TARGET_REDIRECT=y
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
 CONFIG_IP_NF_ARPTABLES=y
 CONFIG_IP_NF_ARPFILTER=y
 CONFIG_IP_NF_ARP_MANGLE=y
@@ -398,6 +403,7 @@
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
 CONFIG_FUSE_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
@@ -428,6 +434,10 @@
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_SET_MODULE_RONX=y
 CONFIG_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=4096
+CONFIG_SECURITY_SELINUX=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_TWOFISH=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 3bc159a..a9e39ed 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -2,6 +2,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-perf"
 CONFIG_SYSVIPC=y
+CONFIG_AUDIT=y
 CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -139,6 +140,7 @@
 CONFIG_NETFILTER=y
 CONFIG_NETFILTER_NETLINK_LOG=y
 CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
 CONFIG_NF_CONNTRACK_EVENTS=y
 CONFIG_NF_CT_PROTO_DCCP=y
 CONFIG_NF_CT_PROTO_SCTP=y
@@ -156,10 +158,12 @@
 CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_LOG=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
 CONFIG_NETFILTER_XT_MATCH_COMMENT=y
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
@@ -197,6 +201,7 @@
 CONFIG_IP_NF_TARGET_REDIRECT=y
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
 CONFIG_IP_NF_ARPTABLES=y
 CONFIG_IP_NF_ARPFILTER=y
 CONFIG_IP_NF_ARP_MANGLE=y
@@ -453,6 +458,7 @@
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
 CONFIG_FUSE_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
@@ -472,6 +478,10 @@
 CONFIG_PID_IN_CONTEXTIDR=y
 CONFIG_DEBUG_SET_MODULE_RONX=y
 CONFIG_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=4096
+CONFIG_SECURITY_SELINUX=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_MD4=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 118fdd4..ee38cc8 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -1,6 +1,7 @@
 # CONFIG_ARM_PATCH_PHYS_VIRT is not set
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
+CONFIG_AUDIT=y
 CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -145,6 +146,7 @@
 CONFIG_NETFILTER=y
 CONFIG_NETFILTER_NETLINK_LOG=y
 CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
 CONFIG_NF_CONNTRACK_EVENTS=y
 CONFIG_NF_CT_PROTO_DCCP=y
 CONFIG_NF_CT_PROTO_SCTP=y
@@ -162,10 +164,12 @@
 CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_LOG=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
 CONFIG_NETFILTER_XT_MATCH_COMMENT=y
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
@@ -203,6 +207,7 @@
 CONFIG_IP_NF_TARGET_REDIRECT=y
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
 CONFIG_IP_NF_ARPTABLES=y
 CONFIG_IP_NF_ARPFILTER=y
 CONFIG_IP_NF_ARP_MANGLE=y
@@ -472,6 +477,7 @@
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
 CONFIG_FUSE_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
@@ -507,6 +513,10 @@
 CONFIG_PID_IN_CONTEXTIDR=y
 CONFIG_DEBUG_SET_MODULE_RONX=y
 CONFIG_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=4096
+CONFIG_SECURITY_SELINUX=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_XCBC=y
 CONFIG_CRYPTO_MD4=y
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index 6165c32..f170b7b 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -1346,6 +1346,11 @@
 		return;
 	}
 
+	pr_err("%s:%d socinfo_get_version %x\n", __func__, __LINE__,
+		socinfo_get_version());
+	if (socinfo_get_version() >= 0x20000)
+		msm_tlmm_misc_reg_write(TLMM_SPARE_REG, 0xf);
+
 #if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
 	if (!(of_board_is_dragonboard() && machine_is_apq8074()))
 		msm_gpiomux_install(msm_eth_configs, \
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index cd6d582..3b80374 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -5077,14 +5077,14 @@
 	CLK_LOOKUP("vsync_clk", mdss_vsync_clk.c, "mdp.0"),
 
 	/* MM sensor clocks */
-	CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6e.qcom,camera"),
-	CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "20.qcom,camera"),
-	CLK_LOOKUP("cam_src_clk", mclk2_clk_src.c, "6c.qcom,camera"),
-	CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "90.qcom,camera"),
-	CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6e.qcom,camera"),
-	CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "20.qcom,camera"),
-	CLK_LOOKUP("cam_clk", camss_mclk2_clk.c, "6c.qcom,camera"),
-	CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "90.qcom,camera"),
+	CLK_LOOKUP("cam_src_clk", mmss_gp0_clk_src.c, "6e.qcom,camera"),
+	CLK_LOOKUP("cam_src_clk", mmss_gp0_clk_src.c, "20.qcom,camera"),
+	CLK_LOOKUP("cam_src_clk", gp1_clk_src.c, "6c.qcom,camera"),
+	CLK_LOOKUP("cam_src_clk", mmss_gp1_clk_src.c, "90.qcom,camera"),
+	CLK_LOOKUP("cam_clk", camss_gp0_clk.c, "6e.qcom,camera"),
+	CLK_LOOKUP("cam_clk", camss_gp0_clk.c, "20.qcom,camera"),
+	CLK_LOOKUP("cam_clk", gcc_gp1_clk.c, "6c.qcom,camera"),
+	CLK_LOOKUP("cam_clk", camss_gp1_clk.c, "90.qcom,camera"),
 	CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, ""),
 	CLK_LOOKUP("cam_clk", camss_mclk2_clk.c, ""),
 	CLK_LOOKUP("cam_clk", camss_mclk3_clk.c, ""),
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index 47332a4..3bb4c57 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -31,8 +31,8 @@
 #define DSS_REG_W(base, offset, data)	REG_W((data), (base) + (offset))
 #define DSS_REG_R(base, offset)		REG_R((base) + (offset))
 
-#define GDSC_PHYS		0xFD8C2304
-#define GDSC_SIZE		0x4
+#define GDSC_PHYS		0xFD8C2300
+#define GDSC_SIZE		0x8
 
 #define DSI_PHY_PHYS		0xFD922A00
 #define DSI_PHY_SIZE		0x000000D4
@@ -163,7 +163,8 @@
 	if (!gdsc_base)
 		return 0;
 
-	return !!(readl_relaxed(gdsc_base) & BIT(31));
+	return (readl_relaxed(gdsc_base + 0x4) & BIT(31)) &&
+		(!(readl_relaxed(gdsc_base) & BIT(0)));
 }
 
 void hdmi_pll_disable(void)
@@ -1140,6 +1141,11 @@
 	int i, rc = 0;
 	struct dsi_pll_vco_clk *vco = to_vco_clk(c);
 
+	if (!mdss_gdsc_enabled()) {
+		pr_err("%s: mdss GDSC is not enabled\n", __func__);
+		return -EPERM;
+	}
+
 	rc = clk_enable(mdss_ahb_clk);
 	if (rc) {
 		pr_err("%s: failed to enable mdss ahb clock. rc=%d\n",
@@ -1167,6 +1173,12 @@
 {
 	int rc = 0;
 
+	if (!mdss_gdsc_enabled()) {
+		pr_warn("%s: mdss GDSC disabled before disabling DSI PLL\n",
+			__func__);
+		return;
+	}
+
 	rc = clk_enable(mdss_ahb_clk);
 	if (rc) {
 		pr_err("%s: failed to enable mdss ahb clock. rc=%d\n",
diff --git a/arch/arm/mach-msm/include/mach/gpiomux.h b/arch/arm/mach-msm/include/mach/gpiomux.h
index 9aae3fb..bd1a4a2 100644
--- a/arch/arm/mach-msm/include/mach/gpiomux.h
+++ b/arch/arm/mach-msm/include/mach/gpiomux.h
@@ -113,6 +113,7 @@
 enum msm_tlmm_misc_reg {
 	TLMM_ETM_MODE_REG = 0x2014,
 	TLMM_SDC2_HDRV_PULL_CTL = 0x2048,
+	TLMM_SPARE_REG = 0x2024,
 };
 
 void msm_tlmm_misc_reg_write(enum msm_tlmm_misc_reg misc_reg, int val);
diff --git a/arch/arm/mach-msm/pil-venus.c b/arch/arm/mach-msm/pil-venus.c
index a7ebbf7..e826a44 100644
--- a/arch/arm/mach-msm/pil-venus.c
+++ b/arch/arm/mach-msm/pil-venus.c
@@ -65,7 +65,7 @@
 
 
 /* PIL proxy vote timeout */
-#define VENUS_PROXY_TIMEOUT				10000
+#define VENUS_PROXY_TIMEOUT				2000
 
 /* Poll interval in uS */
 #define POLL_INTERVAL_US				50
@@ -288,17 +288,6 @@
 	unsigned long iova;
 	u32 ver, cpa_start_addr, cpa_end_addr, fw_start_addr, fw_end_addr;
 
-	/*
-	 * GDSC needs to remain on till Venus is shutdown. So, enable
-	 * the GDSC here again to make sure it remains on beyond the
-	 * expiry of the proxy vote timer.
-	 */
-	rc = regulator_enable(drv->gdsc);
-	if (rc) {
-		dev_err(pil->dev, "GDSC enable failed\n");
-		return rc;
-	}
-
 	/* Get Venus version number */
 	if (!drv->hw_ver_checked) {
 		ver = readl_relaxed(wrapper_base + VENUS_WRAPPER_HW_VERSION);
@@ -344,7 +333,7 @@
 	rc = iommu_attach_device(drv->iommu_fw_domain, drv->iommu_fw_ctx);
 	if (rc) {
 		dev_err(pil->dev, "venus fw iommu attach failed\n");
-		goto err_iommu_attach;
+		return rc;
 	}
 
 	/* Map virtual addr space 0 - fw_sz to firmware physical addr space */
@@ -366,9 +355,6 @@
 err_iommu_map:
 	iommu_detach_device(drv->iommu_fw_domain, drv->iommu_fw_ctx);
 
-err_iommu_attach:
-	regulator_disable(drv->gdsc);
-
 	return rc;
 }
 
@@ -424,8 +410,6 @@
 
 	venus_clock_disable_unprepare(pil->dev);
 
-	regulator_disable(drv->gdsc);
-
 	drv->is_booted = 0;
 
 	return 0;
@@ -454,22 +438,8 @@
 static int pil_venus_reset_trusted(struct pil_desc *pil)
 {
 	int rc;
-	struct venus_data *drv = dev_get_drvdata(pil->dev);
-
-	/*
-	 * GDSC needs to remain on till Venus is shutdown. So, enable
-	 * the GDSC here again to make sure it remains on beyond the
-	 * expiry of the proxy vote timer.
-	 */
-	rc = regulator_enable(drv->gdsc);
-	if (rc) {
-		dev_err(pil->dev, "GDSC enable failed\n");
-		return rc;
-	}
 
 	rc = pas_auth_and_reset(PAS_VIDC);
-	if (rc)
-		regulator_disable(drv->gdsc);
 
 	return rc;
 }
@@ -477,7 +447,6 @@
 static int pil_venus_shutdown_trusted(struct pil_desc *pil)
 {
 	int rc;
-	struct venus_data *drv = dev_get_drvdata(pil->dev);
 
 	venus_clock_prepare_enable(pil->dev);
 
@@ -485,8 +454,6 @@
 
 	venus_clock_disable_unprepare(pil->dev);
 
-	regulator_disable(drv->gdsc);
-
 	return rc;
 }
 
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index a740be6..4507f80 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -232,7 +232,7 @@
 	buf->virt = 0;
 	heap = me->smmu.enabled ? ION_HEAP(ION_IOMMU_HEAP_ID) :
 		ION_HEAP(ION_ADSP_HEAP_ID) | ION_HEAP(ION_AUDIO_HEAP_ID);
-	buf->handle = ion_alloc(clnt, buf->size, SZ_4K, heap, 0);
+	buf->handle = ion_alloc(clnt, buf->size, SZ_4K, heap, ION_FLAG_CACHED);
 	VERIFY(err, 0 == IS_ERR_OR_NULL(buf->handle));
 	if (err)
 		goto bail;
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index 2d70faa..adaff41 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -1249,8 +1249,7 @@
 			GFP_KERNEL);
 	if (!adc_qpnp) {
 		dev_err(&spmi->dev, "Unable to allocate memory\n");
-		rc = -ENOMEM;
-		goto fail;
+		return -ENOMEM;
 	}
 
 	iadc->dev = &(spmi->dev);
@@ -1259,7 +1258,7 @@
 	rc = qpnp_adc_get_devicetree_data(spmi, iadc->adc);
 	if (rc) {
 		dev_err(&spmi->dev, "failed to read device tree\n");
-		goto fail;
+		return rc;
 	}
 
 	iadc->vadc_dev = qpnp_get_vadc(&spmi->dev, "iadc");
@@ -1267,7 +1266,7 @@
 		rc = PTR_ERR(iadc->vadc_dev);
 		if (rc != -EPROBE_DEFER)
 			pr_err("vadc property missing, rc=%d\n", rc);
-		goto fail;
+		return rc;
 	}
 
 	mutex_init(&iadc->adc->adc_lock);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/imx135.c b/drivers/media/platform/msm/camera_v2/sensor/imx135.c
index 8368a4d..c26e4ff 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/imx135.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/imx135.c
@@ -68,7 +68,7 @@
 	{
 		.seq_type = SENSOR_CLK,
 		.seq_val = SENSOR_CAM_MCLK,
-		.config_val = 0,
+		.config_val = 24000000,
 		.delay = 1,
 	},
 	{
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 0447159..ddc168a 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
@@ -957,7 +957,7 @@
 };
 
 static struct msm_cam_clk_info cam_8974_clk_info[] = {
-	[SENSOR_CAM_MCLK] = {"cam_src_clk", 19200000},
+	[SENSOR_CAM_MCLK] = {"cam_src_clk", 24000000},
 	[SENSOR_CAM_CLK] = {"cam_clk", 0},
 };
 
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index 8350dde..509a68d 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -1170,6 +1170,7 @@
 					msg_hdr);
 		break;
 	case HFI_MSG_SYS_IDLE:
+	case HFI_MSG_SYS_PC_PREP_DONE:
 		break;
 	case HFI_MSG_SYS_SESSION_INIT_DONE:
 		SANITIZE_SESSION_PKT(msg_hdr);
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index 50149dc..e335ff0 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -36,6 +36,8 @@
 
 struct msm_vidc_drv *vidc_driver;
 
+uint32_t msm_vidc_pwr_collapse_delay = 2000;
+
 struct buffer_info {
 	struct list_head list;
 	int type;
@@ -781,6 +783,31 @@
 
 static DEVICE_ATTR(link_name, 0644, msm_vidc_link_name_show, NULL);
 
+static ssize_t store_pwr_collapse_delay(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	unsigned long val = 0;
+	int rc = 0;
+	rc = kstrtoul(buf, 0, &val);
+	if (rc)
+		return rc;
+	else if (val == 0)
+		return -EINVAL;
+	msm_vidc_pwr_collapse_delay = val;
+	return count;
+}
+
+static ssize_t show_pwr_collapse_delay(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", msm_vidc_pwr_collapse_delay);
+}
+
+static DEVICE_ATTR(pwr_collapse_delay, 0644, show_pwr_collapse_delay,
+		store_pwr_collapse_delay);
+
 static int __devinit msm_vidc_probe(struct platform_device *pdev)
 {
 	int rc = 0;
@@ -800,6 +827,12 @@
 		dprintk(VIDC_ERR, "Failed to init core\n");
 		goto err_v4l2_register;
 	}
+	rc = device_create_file(&pdev->dev, &dev_attr_pwr_collapse_delay);
+	if (rc) {
+		dprintk(VIDC_ERR,
+				"Failed to create pwr_collapse_delay sysfs node");
+		goto err_v4l2_register;
+	}
 	if (core->hfi_type == VIDC_HFI_Q6) {
 		dprintk(VIDC_ERR, "Q6 hfi device probe called\n");
 		nr += MSM_VIDC_MAX_DEVICES;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 9d3afa1..122f0e9 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -22,8 +22,6 @@
 #include "msm_smem.h"
 #include "msm_vidc_debug.h"
 
-#define HW_RESPONSE_TIMEOUT 1000
-
 #define IS_ALREADY_IN_STATE(__p, __d) ({\
 	int __rc = (__p >= __d);\
 	__rc; \
@@ -362,7 +360,7 @@
 	int rc = 0;
 	rc = wait_for_completion_timeout(
 		&inst->completions[SESSION_MSG_INDEX(cmd)],
-		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
 	if (!rc) {
 		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
 		msm_comm_recover_from_session_error(inst);
@@ -1128,7 +1126,7 @@
 	}
 	rc = wait_for_completion_timeout(
 		&core->completions[SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)],
-		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
 	if (!rc) {
 		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
 		rc = -EIO;
@@ -1150,7 +1148,7 @@
 	dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n");
 	rc = wait_for_completion_timeout(
 		&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)],
-		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
 	if (!rc) {
 		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
 		rc = -EIO;
@@ -2116,7 +2114,7 @@
 	}
 	rc = wait_for_completion_timeout(
 		&inst->completions[SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)],
-		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
 	if (!rc) {
 		dprintk(VIDC_ERR,
 			"Wait interrupted or timeout: %d\n", rc);
@@ -2703,7 +2701,7 @@
 	}
 	rc = wait_for_completion_timeout(
 		&inst->completions[SESSION_MSG_INDEX(SESSION_ABORT_DONE)],
-		msecs_to_jiffies(HW_RESPONSE_TIMEOUT));
+		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
 	if (!rc) {
 		dprintk(VIDC_ERR, "%s: Wait interrupted or timeout: %d\n",
 			__func__, rc);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index bea9070..03136ae 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -21,6 +21,7 @@
 int msm_fw_debug_mode = 0x1;
 int msm_fw_low_power_mode = 0x1;
 int msm_vp8_low_tier = 0x1;
+int msm_vidc_hw_rsp_timeout = 1000;
 
 struct debug_buffer {
 	char ptr[MAX_DBG_BUF_SIZE];
@@ -177,6 +178,11 @@
 		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
 		goto failed_create_dir;
 	}
+	if (!debugfs_create_u32("hw_rsp_timeout", S_IRUGO | S_IWUSR,
+			parent, &msm_vidc_hw_rsp_timeout)) {
+		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
+		goto failed_create_dir;
+	}
 failed_create_dir:
 	return dir;
 }
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.h b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
index 5b572c9..c9ecc6f 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
@@ -53,6 +53,7 @@
 extern int msm_fw_debug_mode;
 extern int msm_fw_low_power_mode;
 extern int msm_vp8_low_tier;
+extern int msm_vidc_hw_rsp_timeout;
 
 #define dprintk(__level, __fmt, arg...)	\
 	do { \
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_resources.h b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
index 8176ea5..e75b410 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_resources.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
@@ -87,5 +87,7 @@
 	return 0;
 }
 
+extern uint32_t msm_vidc_pwr_collapse_delay;
+
 #endif
 
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 99c51bf..aaf1f50 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -62,6 +62,18 @@
 	int ret;
 };
 
+#define TZBSP_VIDEO_SET_STATE 0xa
+
+enum tzbsp_video_state {
+	TZBSP_VIDEO_STATE_SUSPEND = 0,
+	TZBSP_VIDEO_STATE_RESUME
+};
+
+struct tzbsp_video_set_state_req {
+	u32 state; /*shoud be tzbsp_video_state enum value*/
+	u32 spare; /*reserved for future, should be zero*/
+};
+
 static void venus_hfi_dump_packet(u8 *packet)
 {
 	u32 c = 0, packet_size = *(u32 *)packet;
@@ -492,38 +504,320 @@
 	rmb();
 	return rc;
 }
-static inline void venus_hfi_clk_gating_on(struct venus_hfi_device *device)
+
+static int venus_hfi_core_start_cpu(struct venus_hfi_device *device)
 {
+	u32 ctrl_status = 0, count = 0, rc = 0;
+	int max_tries = 100;
+	venus_hfi_write_register(device,
+			VIDC_WRAPPER_INTR_MASK, 0x8, 0);
+	venus_hfi_write_register(device,
+			VIDC_CPU_CS_SCIACMDARG3, 1, 0);
+
+	while (!ctrl_status && count < max_tries) {
+		ctrl_status = venus_hfi_read_register(
+				device,
+				VIDC_CPU_CS_SCIACMDARG0);
+		if ((ctrl_status & 0xFE) == 0x4) {
+			dprintk(VIDC_ERR, "invalid setting for UC_REGION\n");
+			break;
+		}
+		usleep_range(500, 1000);
+		count++;
+	}
+	if (count >= max_tries)
+		rc = -ETIME;
+	return rc;
+}
+
+static int venus_hfi_iommu_attach(struct venus_hfi_device *device)
+{
+	int rc = 0;
+	struct iommu_domain *domain;
 	int i;
-	struct venus_core_clock *cl;
-	if (!device) {
-		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+	struct iommu_set *iommu_group_set;
+	struct iommu_group *group;
+	struct iommu_info *iommu_map;
+
+	if (!device || !device->res)
+		return -EINVAL;
+
+	iommu_group_set = &device->res->iommu_group_set;
+	for (i = 0; i < iommu_group_set->count; i++) {
+		iommu_map = &iommu_group_set->iommu_maps[i];
+		group = iommu_map->group;
+		domain = msm_get_iommu_domain(iommu_map->domain);
+		if (IS_ERR_OR_NULL(domain)) {
+			dprintk(VIDC_ERR,
+				"Failed to get domain: %s\n", iommu_map->name);
+			rc = PTR_ERR(domain);
+			break;
+		}
+		rc = iommu_attach_group(domain, group);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"IOMMU attach failed: %s\n", iommu_map->name);
+			break;
+		}
+	}
+	if (i < iommu_group_set->count) {
+		i--;
+		for (; i >= 0; i--) {
+			iommu_map = &iommu_group_set->iommu_maps[i];
+			group = iommu_map->group;
+			domain = msm_get_iommu_domain(iommu_map->domain);
+			if (group && domain)
+				iommu_detach_group(domain, group);
+		}
+	}
+	return rc;
+}
+
+static void venus_hfi_iommu_detach(struct venus_hfi_device *device)
+{
+	struct iommu_group *group;
+	struct iommu_domain *domain;
+	struct iommu_set *iommu_group_set;
+	struct iommu_info *iommu_map;
+	int i;
+
+	if (!device || !device->res) {
+		dprintk(VIDC_ERR, "Invalid paramter: %p\n", device);
 		return;
 	}
-	if (!device->clocks_enabled) {
-		dprintk(VIDC_DBG, "Clocks are already disabled");
-		goto already_disabled;
+
+	iommu_group_set = &device->res->iommu_group_set;
+	for (i = 0; i < iommu_group_set->count; i++) {
+		iommu_map = &iommu_group_set->iommu_maps[i];
+		group = iommu_map->group;
+		domain = msm_get_iommu_domain(iommu_map->domain);
+		if (group && domain)
+			iommu_detach_group(domain, group);
 	}
-	for (i = 0; i <= device->clk_gating_level; i++) {
-		cl = &device->resources.clock[i];
-		clk_disable(cl->clk);
-	}
-already_disabled:
-	device->clocks_enabled = 0;
 }
-static inline int venus_hfi_clk_gating_off(struct venus_hfi_device *device)
+
+static int venus_hfi_unvote_bus(void *dev,
+				enum session_type type, enum mem_type mtype)
+{
+	int rc = 0;
+	u32 handle = 0;
+	struct venus_hfi_device *device = dev;
+
+	if (!device) {
+		dprintk(VIDC_ERR, "%s invalid device handle %p",
+			__func__, device);
+		return -EINVAL;
+	}
+
+	if (mtype & DDR_MEM)
+		handle = device->resources.bus_info.ddr_handle[type];
+	if (mtype & OCMEM_MEM)
+		handle = device->resources.bus_info.ocmem_handle[type];
+
+	if (handle) {
+		rc = msm_bus_scale_client_update_request(
+				handle, 0);
+		if (rc)
+			dprintk(VIDC_ERR, "Failed to unvote bus: %d\n", rc);
+	} else {
+		dprintk(VIDC_ERR, "Failed to unvote bus, mtype: %d\n",
+				mtype);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static void venus_hfi_unvote_buses(void *dev, enum mem_type mtype)
 {
 	int i;
-	struct venus_core_clock *cl;
+	struct venus_hfi_device *device = dev;
+
+	if (!device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return;
+	}
+
+	for (i = 0; i < MSM_VIDC_MAX_DEVICES; i++) {
+		if ((mtype & DDR_MEM) &&
+			venus_hfi_unvote_bus(device, i, DDR_MEM))
+			dprintk(VIDC_WARN,
+				"Failed to unvote for DDR accesses\n");
+
+		if ((mtype & OCMEM_MEM) &&
+			venus_hfi_unvote_bus(device, i, OCMEM_MEM))
+			dprintk(VIDC_WARN,
+				"Failed to unvote for OCMEM accesses\n");
+	}
+}
+
+static const u32 venus_hfi_bus_table[] = {
+	36000,
+	110400,
+	244800,
+	489000,
+	783360,
+	979200,
+};
+
+static int venus_hfi_get_bus_vector(struct venus_hfi_device *device, int load,
+			enum session_type type, enum mem_type mtype)
+{
+	int num_rows = sizeof(venus_hfi_bus_table)/(sizeof(u32));
+	int i, j;
+	int idx = 0;
+
+	if (!device || (mtype != DDR_MEM && mtype != OCMEM_MEM) ||
+		(type != MSM_VIDC_ENCODER && type != MSM_VIDC_DECODER)) {
+		dprintk(VIDC_ERR, "%s invalid params", __func__);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < num_rows; i++) {
+		if (load <= venus_hfi_bus_table[i])
+			break;
+	}
+
+	if (type == MSM_VIDC_ENCODER)
+		idx = (mtype == DDR_MEM) ? BUS_IDX_ENC_DDR : BUS_IDX_ENC_OCMEM;
+	else
+		idx = (mtype == DDR_MEM) ? BUS_IDX_DEC_DDR : BUS_IDX_DEC_OCMEM;
+
+	j = clamp(i, 0, num_rows-1) + 1;
+
+	/* Ensure bus index remains within the supported range,
+	* as specified in the device dtsi file */
+	j = clamp(j, 0, device->res->bus_pdata[idx].num_usecases - 1);
+
+	dprintk(VIDC_DBG, "Required bus = %d\n", j);
+	return j;
+}
+
+static int venus_hfi_scale_bus(void *dev, int load,
+				enum session_type type, enum mem_type mtype)
+{
 	int rc = 0;
+	u32 handle = 0;
+	struct venus_hfi_device *device = dev;
+	int bus_vector = 0;
+
+	if (!device) {
+		dprintk(VIDC_ERR, "%s invalid device handle %p",
+			__func__, device);
+		return -EINVAL;
+	}
+
+	if (mtype & DDR_MEM)
+		handle = device->resources.bus_info.ddr_handle[type];
+	if (mtype & OCMEM_MEM)
+		handle = device->resources.bus_info.ocmem_handle[type];
+
+	if (handle) {
+		bus_vector = venus_hfi_get_bus_vector(device, load,
+				type, mtype);
+		if (bus_vector < 0) {
+			dprintk(VIDC_ERR, "Failed to get bus vector\n");
+			return -EINVAL;
+		}
+		device->bus_load[type] = load;
+		rc = msm_bus_scale_client_update_request(handle, bus_vector);
+		if (rc)
+			dprintk(VIDC_ERR, "Failed to scale bus: %d\n", rc);
+	} else {
+		dprintk(VIDC_ERR, "Failed to scale bus, mtype: %d\n",
+				mtype);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+static int venus_hfi_scale_buses(void *dev, enum mem_type mtype)
+{
+	int i, rc = 0;
+	struct venus_hfi_device *device = dev;
+
+	if (!device) {
+		dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+		return -EINVAL;
+	}
+	for (i = 0; i < MSM_VIDC_MAX_DEVICES; i++) {
+		if (mtype & DDR_MEM) {
+			rc = venus_hfi_scale_bus(device, device->bus_load[i],
+					i, DDR_MEM);
+			if (rc) {
+				dprintk(VIDC_ERR,
+						"Failed to scale bus for DDR accesses, session type %d, load %u\n",
+						i, device->bus_load[i]);
+				goto err_scale_bus;
+			}
+		}
+
+		if (mtype & OCMEM_MEM) {
+			rc = venus_hfi_scale_bus(device, device->bus_load[i],
+					i, OCMEM_MEM);
+			if (rc) {
+				dprintk(VIDC_ERR,
+						"Failed to scale bus for OCMEM accesses, session type %d, load %u\n",
+						i, device->bus_load[i]);
+				goto err_scale_bus;
+			}
+		}
+	}
+err_scale_bus:
+	return rc;
+}
+
+static inline int venus_hfi_tzbsp_set_video_state(enum tzbsp_video_state state)
+{
+	struct tzbsp_video_set_state_req cmd = {0};
+	int tzbsp_rsp = 0;
+	int rc = 0;
+	cmd.state = state;
+	cmd.spare = 0;
+	rc = scm_call(SCM_SVC_BOOT, TZBSP_VIDEO_SET_STATE, &cmd, sizeof(cmd),
+			&tzbsp_rsp, sizeof(tzbsp_rsp));
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed scm_call %d\n", rc);
+		return rc;
+	}
+	dprintk(VIDC_DBG, "Set state %d, resp %d\n", state, tzbsp_rsp);
+	if (tzbsp_rsp) {
+		dprintk(VIDC_ERR,
+				"Failed to set video core state to suspend: %d\n",
+				tzbsp_rsp);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static inline int venus_hfi_reset_core(struct venus_hfi_device *device)
+{
+	int rc = 0;
+	venus_hfi_write_register(device,
+			VIDC_CTRL_INIT, 0x1, 0);
+	rc = venus_hfi_core_start_cpu(device);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed to start core");
+	return rc;
+}
+
+
+/*Calling function is responsible to acquire device->clk_pwr_lock*/
+static inline int venus_hfi_clk_enable(struct venus_hfi_device *device)
+{
+	int rc = 0;
+	int i;
+	struct venus_core_clock *cl;
+
 	if (!device) {
 		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
 		return -EINVAL;
 	}
 	if (device->clocks_enabled) {
-		dprintk(VIDC_DBG, "Clocks are already enabled");
-		goto already_enabled;
+		dprintk(VIDC_DBG, "Clocks already enabled");
+		return 0;
 	}
+
 	for (i = 0; i <= device->clk_gating_level; i++) {
 		cl = &device->resources.clock[i];
 		rc = clk_enable(cl->clk);
@@ -534,17 +828,180 @@
 			dprintk(VIDC_DBG, "Clock: %s enabled\n", cl->name);
 		}
 	}
-already_enabled:
 	device->clocks_enabled = 1;
-	return rc;
+	return 0;
 fail_clk_enable:
-	for (; i >= 0; i--) {
+	for (i--; i >= 0; i--) {
 		cl = &device->resources.clock[i];
 		clk_disable(cl->clk);
 	}
 	return rc;
 }
 
+/*Calling function is responsible to acquire device->clk_pwr_lock*/
+static inline void venus_hfi_clk_disable(struct venus_hfi_device *device)
+{
+	int i;
+	struct venus_core_clock *cl;
+
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+		return;
+	}
+	if (!device->clocks_enabled) {
+		dprintk(VIDC_DBG, "Clocks already disabled");
+		return;
+	}
+
+	for (i = 0; i <= device->clk_gating_level; i++) {
+		cl = &device->resources.clock[i];
+		clk_disable(cl->clk);
+	}
+	device->clocks_enabled = 0;
+}
+
+static DECLARE_COMPLETION(pc_prep_done);
+
+static inline int venus_hfi_power_off(struct venus_hfi_device *device)
+{
+	int rc = 0;
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+		return -EINVAL;
+	}
+	if (!device->power_enabled) {
+		dprintk(VIDC_DBG, "Power already disabled");
+		goto already_disabled;
+	}
+
+	/*Temporarily enable clocks to make TZ call.*/
+	rc = venus_hfi_clk_enable(device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to enable clocks before TZ call");
+		return rc;
+	}
+	rc = venus_hfi_tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to suspend video core %d\n", rc);
+		venus_hfi_clk_disable(device);
+		return rc;
+	}
+	venus_hfi_clk_disable(device);
+	venus_hfi_iommu_detach(device);
+	rc = regulator_disable(device->gdsc);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to disable GDSC, %d", rc);
+		return rc;
+	}
+	if (device->res->has_ocmem)
+		venus_hfi_unvote_buses(device, DDR_MEM|OCMEM_MEM);
+	else
+		venus_hfi_unvote_buses(device, DDR_MEM);
+
+	device->power_enabled = 0;
+already_disabled:
+	return rc;
+}
+
+static inline int venus_hfi_power_on(struct venus_hfi_device *device)
+{
+	int rc = 0;
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+		return -EINVAL;
+	}
+
+	if (device->res->has_ocmem)
+		rc = venus_hfi_scale_buses(device, DDR_MEM|OCMEM_MEM);
+	else
+		rc = venus_hfi_scale_buses(device, DDR_MEM);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to scale buses");
+		goto err_scale_buses;
+	}
+
+	rc = regulator_enable(device->gdsc);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to enable GDSC %d", rc);
+		goto err_enable_gdsc;
+	}
+
+	rc = venus_hfi_iommu_attach(device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to attach iommu after power on");
+		goto err_iommu_attach;
+	}
+
+	rc = venus_hfi_clk_enable(device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to enable clocks");
+		goto err_enable_clk;
+	}
+
+	rc = venus_hfi_tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESUME);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to resume video core %d\n", rc);
+		goto err_set_video_state;
+	}
+	rc = venus_hfi_reset_core(device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to reset venus core");
+		goto err_reset_core;
+	}
+	device->power_enabled = 1;
+	return rc;
+err_reset_core:
+	venus_hfi_tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND);
+err_set_video_state:
+	venus_hfi_clk_disable(device);
+err_enable_clk:
+	venus_hfi_iommu_detach(device);
+err_iommu_attach:
+	regulator_disable(device->gdsc);
+err_enable_gdsc:
+	if (device->res->has_ocmem)
+		venus_hfi_unvote_buses(device, DDR_MEM|OCMEM_MEM);
+	else
+		venus_hfi_unvote_buses(device, DDR_MEM);
+err_scale_buses:
+	return rc;
+}
+
+static void venus_hfi_pm_hndlr(struct work_struct *work);
+static DECLARE_DELAYED_WORK(venus_hfi_pm_work, venus_hfi_pm_hndlr);
+
+static inline int venus_hfi_clk_gating_off(struct venus_hfi_device *device)
+{
+	int rc = 0;
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+		return -EINVAL;
+	}
+	if (device->clocks_enabled) {
+		dprintk(VIDC_DBG, "Clocks are already enabled");
+		goto already_enabled;
+	}
+	cancel_delayed_work(&venus_hfi_pm_work);
+	if (!device->power_enabled) {
+		/*This will enable clocks as well*/
+		rc = venus_hfi_power_on(device);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed venus power on");
+			goto fail_clk_power_on;
+		}
+	} else {
+		rc = venus_hfi_clk_enable(device);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed venus clock enable");
+			goto fail_clk_power_on;
+		}
+	}
+already_enabled:
+	device->clocks_enabled = 1;
+fail_clk_power_on:
+	return rc;
+}
+
 static unsigned long venus_hfi_get_clock_rate(struct venus_core_clock *clock,
 	int num_mbs_per_sec)
 {
@@ -569,7 +1026,7 @@
 		dprintk(VIDC_ERR, "Invalid args: %p\n", device);
 		return -EINVAL;
 	}
-	device->load = load;
+	device->clk_load = load;
 	rc = clk_set_rate(device->resources.clock[VCODEC_CLK].clk,
 		venus_hfi_get_clock_rate(&device->resources.clock[VCODEC_CLK],
 			load));
@@ -595,14 +1052,14 @@
 		dprintk(VIDC_ERR, "cannot write to shared Q's");
 		goto err_q_null;
 	}
-	mutex_lock(&device->clock_lock);
+	mutex_lock(&device->clk_pwr_lock);
 	result = venus_hfi_clk_gating_off(device);
 	if (result) {
 		dprintk(VIDC_ERR, "%s : Clock enable failed\n",
 			__func__);
 		goto err_q_write;
 	}
-	result = venus_hfi_scale_clocks(device, device->load);
+	result = venus_hfi_scale_clocks(device, device->clk_load);
 	if (result) {
 		dprintk(VIDC_ERR, "Clock scaling failed\n");
 		goto err_q_write;
@@ -618,7 +1075,7 @@
 		dprintk(VIDC_ERR, "venus_hfi_iface_cmdq_write:queue_full");
 	}
 err_q_write:
-	mutex_unlock(&device->clock_lock);
+	mutex_unlock(&device->clk_pwr_lock);
 err_q_null:
 	mutex_unlock(&device->write_lock);
 	return result;
@@ -642,7 +1099,7 @@
 		goto read_error_null;
 	}
 	q_info = &device->iface_queues[VIDC_IFACEQ_MSGQ_IDX];
-	mutex_lock(&device->clock_lock);
+	mutex_lock(&device->clk_pwr_lock);
 	rc = venus_hfi_clk_gating_off(device);
 	if (rc) {
 		dprintk(VIDC_ERR,
@@ -661,7 +1118,7 @@
 		rc = -ENODATA;
 	}
 read_error:
-	mutex_unlock(&device->clock_lock);
+	mutex_unlock(&device->clk_pwr_lock);
 read_error_null:
 	mutex_unlock(&device->read_lock);
 	return rc;
@@ -684,7 +1141,7 @@
 		rc = -ENODATA;
 		goto dbg_error_null;
 	}
-	mutex_lock(&device->clock_lock);
+	mutex_lock(&device->clk_pwr_lock);
 	rc = venus_hfi_clk_gating_off(device);
 	if (rc) {
 		dprintk(VIDC_ERR,
@@ -704,7 +1161,7 @@
 		rc = -ENODATA;
 	}
 dbg_error:
-	mutex_unlock(&device->clock_lock);
+	mutex_unlock(&device->clk_pwr_lock);
 dbg_error_null:
 	mutex_unlock(&device->read_lock);
 	return rc;
@@ -954,31 +1411,6 @@
 	return -ENOMEM;
 }
 
-static int venus_hfi_core_start_cpu(struct venus_hfi_device *device)
-{
-	u32 ctrl_status = 0, count = 0, rc = 0;
-	int max_tries = 100;
-	venus_hfi_write_register(device,
-			VIDC_WRAPPER_INTR_MASK, 0x8, 0);
-	venus_hfi_write_register(device,
-			VIDC_CPU_CS_SCIACMDARG3, 1, 0);
-
-	while (!ctrl_status && count < max_tries) {
-		ctrl_status = venus_hfi_read_register(
-				device,
-				VIDC_CPU_CS_SCIACMDARG0);
-		if ((ctrl_status & 0xFE) == 0x4) {
-			dprintk(VIDC_ERR, "invalid setting for UC_REGION\n");
-			break;
-		}
-		usleep_range(500, 1000);
-		count++;
-	}
-	if (count >= max_tries)
-		rc = -ETIME;
-	return rc;
-}
-
 static void venus_hfi_set_registers(struct venus_hfi_device *device)
 {
 	struct reg_set *reg_set;
@@ -1111,12 +1543,12 @@
 		return -ENODEV;
 	}
 	if (dev->hal_client) {
-		mutex_lock(&dev->clock_lock);
+		mutex_lock(&dev->clk_pwr_lock);
 		rc = venus_hfi_clk_gating_off(device);
 		if (rc) {
 			dprintk(VIDC_ERR,
 				"%s : Clock enable failed\n", __func__);
-			mutex_unlock(&dev->clock_lock);
+			mutex_unlock(&dev->clk_pwr_lock);
 			return -EIO;
 		}
 		venus_hfi_write_register(dev,
@@ -1124,38 +1556,12 @@
 		if (!(dev->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK))
 			disable_irq_nosync(dev->hal_data->irq);
 		dev->intr_status = 0;
-		mutex_unlock(&dev->clock_lock);
+		mutex_unlock(&dev->clk_pwr_lock);
 	}
 	dprintk(VIDC_INFO, "HAL exited\n");
 	return 0;
 }
 
-int venus_hfi_core_pc_prep(void *device)
-{
-	struct hfi_cmd_sys_pc_prep_packet pkt;
-	int rc = 0;
-	struct venus_hfi_device *dev;
-
-	if (device) {
-		dev = device;
-	} else {
-		dprintk(VIDC_ERR, "invalid device");
-		return -ENODEV;
-	}
-
-	rc = create_pkt_cmd_sys_pc_prep(&pkt);
-	if (rc) {
-		dprintk(VIDC_ERR, "Failed to create sys pc prep pkt");
-		goto err_create_pkt;
-	}
-
-	if (venus_hfi_iface_cmdq_write(dev, &pkt))
-		rc = -ENOTEMPTY;
-
-err_create_pkt:
-	return rc;
-}
-
 static void venus_hfi_core_clear_interrupt(struct venus_hfi_device *device)
 {
 	u32 intr_status = 0;
@@ -1163,12 +1569,12 @@
 
 	if (!device->callback)
 		return;
-	mutex_lock(&device->clock_lock);
+	mutex_lock(&device->clk_pwr_lock);
 	rc = venus_hfi_clk_gating_off(device);
 	if (rc) {
 		dprintk(VIDC_ERR,
 			"%s : Clock enable failed\n", __func__);
-		mutex_unlock(&device->clock_lock);
+		mutex_unlock(&device->clk_pwr_lock);
 		return;
 	}
 	intr_status = venus_hfi_read_register(
@@ -1192,7 +1598,7 @@
 			VIDC_CPU_CS_A2HSOFTINTCLR, 1, 0);
 	venus_hfi_write_register(device,
 			VIDC_WRAPPER_INTR_CLEAR, intr_status, 0);
-	mutex_unlock(&device->clock_lock);
+	mutex_unlock(&device->clk_pwr_lock);
 	dprintk(VIDC_DBG, "Cleared WRAPPER/A2H interrupt");
 }
 
@@ -1930,6 +2336,91 @@
 	return rc;
 }
 
+static int venus_hfi_core_pc_prep(void *device)
+{
+	struct hfi_cmd_sys_pc_prep_packet pkt;
+	int rc = 0;
+	struct venus_hfi_device *dev;
+
+	if (device) {
+		dev = device;
+	} else {
+		dprintk(VIDC_ERR, "invalid device");
+		return -ENODEV;
+	}
+
+	rc = create_pkt_cmd_sys_pc_prep(&pkt);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to create sys pc prep pkt");
+		goto err_create_pkt;
+	}
+
+	if (venus_hfi_iface_cmdq_write(dev, &pkt))
+		rc = -ENOTEMPTY;
+
+err_create_pkt:
+	return rc;
+}
+
+
+static void venus_hfi_pm_hndlr(struct work_struct *work)
+{
+	int rc = 0;
+	struct venus_hfi_device *device = list_first_entry(
+			&hal_ctxt.dev_head, struct venus_hfi_device, list);
+	mutex_lock(&device->clk_pwr_lock);
+	if (device->clocks_enabled || !device->power_enabled) {
+		dprintk(VIDC_DBG,
+				"Clocks status: %d, Power status: %d, ignore power off\n",
+				device->clocks_enabled, device->power_enabled);
+		goto clks_enabled;
+	}
+	mutex_unlock(&device->clk_pwr_lock);
+	init_completion(&pc_prep_done);
+	rc = venus_hfi_core_pc_prep(device);
+	if (rc) {
+		dprintk(VIDC_ERR, "Failed to prepare venus for power off");
+		return;
+	}
+	rc = wait_for_completion_timeout(&pc_prep_done,
+			msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
+	if (!rc) {
+		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d", rc);
+		return;
+	}
+
+	mutex_lock(&device->clk_pwr_lock);
+	if (device->clocks_enabled) {
+		dprintk(VIDC_ERR,
+				"Clocks are still enabled after PC_PREP_DONE, ignore power off");
+		goto clks_enabled;
+	}
+
+	rc = venus_hfi_power_off(device);
+	if (rc)
+		dprintk(VIDC_ERR, "Failed venus power off");
+clks_enabled:
+	mutex_unlock(&device->clk_pwr_lock);
+}
+
+static inline void venus_hfi_clk_gating_on(struct venus_hfi_device *device)
+{
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+		return;
+	}
+	if (!device->clocks_enabled) {
+		dprintk(VIDC_DBG, "Clocks are already disabled");
+		goto already_disabled;
+	}
+	venus_hfi_clk_disable(device);
+	if (!queue_delayed_work(device->venus_pm_workq, &venus_hfi_pm_work,
+			msecs_to_jiffies(msm_vidc_pwr_collapse_delay)))
+		dprintk(VIDC_DBG, "PM work already scheduled\n");
+already_disabled:
+	device->clocks_enabled = 0;
+}
+
 static int venus_hfi_try_clk_gating(struct venus_hfi_device *device)
 {
 	int rc = 0;
@@ -1939,15 +2430,21 @@
 		return -ENODEV;
 	}
 	mutex_lock(&device->write_lock);
-	mutex_lock(&device->clock_lock);
+	mutex_lock(&device->clk_pwr_lock);
 	rc = venus_hfi_is_cmd_pending(device);
 	ctrl_status = venus_hfi_read_register(
 		device,
 		VIDC_CPU_CS_SCIACMDARG0);
+	dprintk(VIDC_DBG,
+			"venus_hfi_try_clk_gating - rc %d, ctrl_status 0x%x",
+			rc, ctrl_status);
 	if (((ctrl_status & VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK)
-		!= 0) && !rc)
+		|| (ctrl_status & VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY))
+			&& !rc)
 		venus_hfi_clk_gating_on(device);
-	mutex_unlock(&device->clock_lock);
+	else
+		dprintk(VIDC_DBG, "Ignore clock gating");
+	mutex_unlock(&device->clk_pwr_lock);
 	mutex_unlock(&device->write_lock);
 	return rc;
 }
@@ -2006,6 +2503,14 @@
 		}
 		if (rc == HFI_MSG_SYS_IDLE)
 			rc = venus_hfi_try_clk_gating(device);
+		else if (rc == HFI_MSG_SYS_PC_PREP_DONE) {
+			dprintk(VIDC_DBG, "Received HFI_MSG_SYS_PC_PREP_DONE");
+			rc = venus_hfi_try_clk_gating(device);
+			if (rc)
+				dprintk(VIDC_ERR,
+					"Failed clk gating after PC_PREP_DONE");
+			complete(&pc_prep_done);
+		}
 	} else {
 		dprintk(VIDC_ERR, "SPURIOUS_INTERRUPT");
 	}
@@ -2380,118 +2885,6 @@
 	return -EINVAL;
 }
 
-
-static const u32 venus_hfi_bus_table[] = {
-	36000,
-	110400,
-	244800,
-	489000,
-	783360,
-	979200,
-};
-
-static int venus_hfi_get_bus_vector(struct venus_hfi_device *device, int load,
-			enum session_type type, enum mem_type mtype)
-{
-	int num_rows = sizeof(venus_hfi_bus_table)/(sizeof(u32));
-	int i, j;
-	int idx = 0;
-
-	if (!device || (mtype != DDR_MEM && mtype != OCMEM_MEM) ||
-		(type != MSM_VIDC_ENCODER && type != MSM_VIDC_DECODER)) {
-		dprintk(VIDC_ERR, "%s invalid params", __func__);
-		return -EINVAL;
-	}
-
-	for (i = 0; i < num_rows; i++) {
-		if (load <= venus_hfi_bus_table[i])
-			break;
-	}
-
-	if (type == MSM_VIDC_ENCODER)
-		idx = (mtype == DDR_MEM) ? BUS_IDX_ENC_DDR : BUS_IDX_ENC_OCMEM;
-	else
-		idx = (mtype == DDR_MEM) ? BUS_IDX_DEC_DDR : BUS_IDX_DEC_OCMEM;
-
-	j = clamp(i, 0, num_rows-1) + 1;
-
-	/* Ensure bus index remains within the supported range,
-	* as specified in the device dtsi file */
-	j = clamp(j, 0, device->res->bus_pdata[idx].num_usecases - 1);
-
-	dprintk(VIDC_DBG, "Required bus = %d\n", j);
-	return j;
-}
-
-static int venus_hfi_scale_bus(void *dev, int load,
-				enum session_type type, enum mem_type mtype)
-{
-	int rc = 0;
-	u32 handle = 0;
-	struct venus_hfi_device *device = dev;
-	int bus_vector = 0;
-
-	if (!device) {
-		dprintk(VIDC_ERR, "%s invalid device handle %p",
-			__func__, device);
-		return -EINVAL;
-	}
-
-	if (mtype & DDR_MEM)
-		handle = device->resources.bus_info.ddr_handle[type];
-	if (mtype & OCMEM_MEM)
-		handle = device->resources.bus_info.ocmem_handle[type];
-
-	if (handle) {
-		bus_vector = venus_hfi_get_bus_vector(device, load,
-				type, mtype);
-		if (bus_vector < 0) {
-			dprintk(VIDC_ERR, "Failed to get bus vector\n");
-			return -EINVAL;
-		}
-		rc = msm_bus_scale_client_update_request(handle, bus_vector);
-		if (rc)
-			dprintk(VIDC_ERR, "Failed to scale bus: %d\n", rc);
-	} else {
-		dprintk(VIDC_ERR, "Failed to scale bus, mtype: %d\n",
-				mtype);
-		rc = -EINVAL;
-	}
-
-	return rc;
-}
-
-static int venus_hfi_unvote_bus(void *dev,
-				enum session_type type, enum mem_type mtype)
-{
-	int rc = 0;
-	u32 handle = 0;
-	struct venus_hfi_device *device = dev;
-
-	if (!device) {
-		dprintk(VIDC_ERR, "%s invalid device handle %p",
-			__func__, device);
-		return -EINVAL;
-	}
-
-	if (mtype & DDR_MEM)
-		handle = device->resources.bus_info.ddr_handle[type];
-	if (mtype & OCMEM_MEM)
-		handle = device->resources.bus_info.ocmem_handle[type];
-
-	if (handle) {
-		rc = msm_bus_scale_client_update_request(
-				handle, 0);
-		if (rc)
-			dprintk(VIDC_ERR, "Failed to unvote bus: %d\n", rc);
-	} else {
-		dprintk(VIDC_ERR, "Failed to unvote bus, mtype: %d\n",
-				mtype);
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
 static int venus_hfi_set_ocmem(void *dev, struct ocmem_buf *ocmem)
 {
 	struct vidc_resource_hdr rhdr;
@@ -2657,6 +3050,15 @@
 	int rc = 0;
 
 	device->res = res;
+	if (!res) {
+		dprintk(VIDC_ERR, "Invalid params: %p\n", res);
+		return -ENODEV;
+	}
+	device->gdsc = devm_regulator_get(&res->pdev->dev, "vdd");
+	if (IS_ERR(device->gdsc)) {
+		dprintk(VIDC_ERR, "Failed to get Venus GDSC\n");
+		return -ENODEV;
+	}
 	rc = venus_hfi_init_clocks(res, device);
 	if (rc) {
 		dprintk(VIDC_ERR, "Failed to init clocks\n");
@@ -2686,6 +3088,7 @@
 err_init_bus:
 	venus_hfi_deinit_clocks(device);
 err_init_clocks:
+	device->gdsc = NULL;
 	return rc;
 }
 
@@ -2696,72 +3099,7 @@
 	venus_hfi_deregister_iommu_domains(device);
 	venus_hfi_deinit_bus(device);
 	venus_hfi_deinit_clocks(device);
-}
-
-static int venus_hfi_iommu_attach(struct venus_hfi_device *device)
-{
-	int rc = 0;
-	struct iommu_domain *domain;
-	int i;
-	struct iommu_set *iommu_group_set;
-	struct iommu_group *group;
-	struct iommu_info *iommu_map;
-
-	if (!device || !device->res)
-		return -EINVAL;
-
-	iommu_group_set = &device->res->iommu_group_set;
-	for (i = 0; i < iommu_group_set->count; i++) {
-		iommu_map = &iommu_group_set->iommu_maps[i];
-		group = iommu_map->group;
-		domain = msm_get_iommu_domain(iommu_map->domain);
-		if (IS_ERR_OR_NULL(domain)) {
-			dprintk(VIDC_ERR,
-				"Failed to get domain: %s\n", iommu_map->name);
-			rc = PTR_ERR(domain);
-			break;
-		}
-		rc = iommu_attach_group(domain, group);
-		if (rc) {
-			dprintk(VIDC_ERR,
-				"IOMMU attach failed: %s\n", iommu_map->name);
-			break;
-		}
-	}
-	if (i < iommu_group_set->count) {
-		i--;
-		for (; i >= 0; i--) {
-			iommu_map = &iommu_group_set->iommu_maps[i];
-			group = iommu_map->group;
-			domain = msm_get_iommu_domain(iommu_map->domain);
-			if (group && domain)
-				iommu_detach_group(domain, group);
-		}
-	}
-	return rc;
-}
-
-static void venus_hfi_iommu_detach(struct venus_hfi_device *device)
-{
-	struct iommu_group *group;
-	struct iommu_domain *domain;
-	struct iommu_set *iommu_group_set;
-	struct iommu_info *iommu_map;
-	int i;
-
-	if (!device || !device->res) {
-		dprintk(VIDC_ERR, "Invalid paramter: %p\n", device);
-		return;
-	}
-
-	iommu_group_set = &device->res->iommu_group_set;
-	for (i = 0; i < iommu_group_set->count; i++) {
-		iommu_map = &iommu_group_set->iommu_maps[i];
-		group = iommu_map->group;
-		domain = msm_get_iommu_domain(iommu_map->domain);
-		if (group && domain)
-			iommu_detach_group(domain, group);
-	}
+	device->gdsc = NULL;
 }
 
 static int venus_hfi_iommu_get_domain_partition(void *dev, u32 flags,
@@ -2833,12 +3171,12 @@
 	int rc = 0;
 	struct venus_hfi_device *device = dev;
 
-	if (!device) {
+	if (!device || !device->gdsc) {
 		dprintk(VIDC_ERR, "%s Invalid paramter: %p\n",
 			__func__, device);
 		return -EINVAL;
 	}
-	mutex_init(&device->clock_lock);
+	mutex_init(&device->clk_pwr_lock);
 	device->clk_gating_level = VCODEC_CLK;
 	rc = venus_hfi_iommu_attach(device);
 	if (rc) {
@@ -2846,14 +3184,21 @@
 		goto fail_iommu_attach;
 	}
 
-	if (!device->resources.fw.cookie)
+	if (!device->resources.fw.cookie) {
+		rc = regulator_enable(device->gdsc);
+		if (rc) {
+			dprintk(VIDC_ERR, "Failed to enable GDSC %d", rc);
+			goto fail_enable_gdsc;
+		}
 		device->resources.fw.cookie = subsystem_get("venus");
+	}
 
 	if (IS_ERR_OR_NULL(device->resources.fw.cookie)) {
 		dprintk(VIDC_ERR, "Failed to download firmware\n");
 		rc = -ENOMEM;
 		goto fail_load_fw;
 	}
+	device->power_enabled = 1;
 	/*Clocks can be enabled only after pil_get since
 	 * gdsc is turned-on in pil_get*/
 	rc = venus_hfi_enable_clks(device);
@@ -2875,6 +3220,8 @@
 	subsystem_put(device->resources.fw.cookie);
 fail_load_fw:
 	device->resources.fw.cookie = NULL;
+	regulator_disable(device->gdsc);
+fail_enable_gdsc:
 	venus_hfi_iommu_detach(device);
 fail_iommu_attach:
 	return rc;
@@ -2890,8 +3237,10 @@
 	}
 	if (device->resources.fw.cookie) {
 		flush_workqueue(device->vidc_workq);
+		flush_workqueue(device->venus_pm_workq);
 		venus_hfi_disable_clks(device);
 		subsystem_put(device->resources.fw.cookie);
+		regulator_disable(device->gdsc);
 		venus_hfi_interface_queues_release(dev);
 		venus_hfi_iommu_detach(device);
 		device->resources.fw.cookie = NULL;
@@ -2992,9 +3341,15 @@
 	hdevice->vidc_workq = create_singlethread_workqueue(
 		"msm_vidc_workerq_venus");
 	if (!hdevice->vidc_workq) {
-		dprintk(VIDC_ERR, ": create workq failed\n");
+		dprintk(VIDC_ERR, ": create vidc workq failed\n");
 		goto error_createq;
 	}
+	hdevice->venus_pm_workq = create_singlethread_workqueue(
+			"pm_workerq_venus");
+	if (!hdevice->venus_pm_workq) {
+		dprintk(VIDC_ERR, ": create pm workq failed\n");
+		goto error_createq_pm;
+	}
 
 	if (hal_ctxt.dev_count == 0)
 		INIT_LIST_HEAD(&hal_ctxt.dev_head);
@@ -3004,6 +3359,8 @@
 	hal_ctxt.dev_count++;
 
 	return (void *) hdevice;
+error_createq_pm:
+	destroy_workqueue(hdevice->vidc_workq);
 error_createq:
 err_init_regs:
 	kfree(hdevice);
@@ -3054,6 +3411,7 @@
 				free_irq(dev->hal_data->irq, close);
 				list_del(&close->list);
 				destroy_workqueue(close->vidc_workq);
+				destroy_workqueue(close->venus_pm_workq);
 				kfree(close->hal_data);
 				kfree(close);
 				break;
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.h b/drivers/media/platform/msm/vidc/venus_hfi.h
index 44cdf31..f1d8694 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.h
+++ b/drivers/media/platform/msm/vidc/venus_hfi.h
@@ -182,12 +182,14 @@
 	struct list_head sess_head;
 	u32 intr_status;
 	u32 device_id;
-	u32 load;
+	u32 clk_load;
+	u32 bus_load[MSM_VIDC_MAX_DEVICES];
 	u32 clocks_enabled;
+	u32 power_enabled;
 	enum vidc_clocks clk_gating_level;
 	struct mutex read_lock;
 	struct mutex write_lock;
-	struct mutex clock_lock;
+	struct mutex clk_pwr_lock;
 	struct mutex session_lock;
 	msm_vidc_callback callback;
 	struct vidc_mem_addr iface_q_table;
@@ -198,6 +200,7 @@
 	struct smem_client *hal_client;
 	struct hal_data *hal_data;
 	struct workqueue_struct *vidc_workq;
+	struct workqueue_struct *venus_pm_workq;
 	int spur_count;
 	int reg_count;
 	u32 base_addr;
@@ -206,6 +209,7 @@
 	u32 irq;
 	struct venus_resources resources;
 	struct msm_vidc_platform_resources *res;
+	struct regulator *gdsc;
 };
 
 void venus_hfi_delete_device(void *device);
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_io.h b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
index eeffe35..6377fbf 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_io.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
@@ -49,6 +49,7 @@
 #define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_SHFT	0x1
 #define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK	0x1
 #define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_SHFT	0x0
+#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY           0x100
 #define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK     0x40000000
 
 /* HFI_QTBL_INFO */
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index c6b0cfd..877525e 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -1112,12 +1112,16 @@
 		}
 	}
 
-	ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,
+	if (panel_data->panel_info.type == MIPI_CMD_PANEL) {
+		ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,
 						"qcom,platform-te-gpio", 0);
-	if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) {
-		pr_err("%s:%d, Disp_te gpio not specified\n",
+		if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) {
+			pr_err("%s:%d, Disp_te gpio not specified\n",
 						__func__, __LINE__);
-	} else {
+		}
+	}
+
+	if (gpio_is_valid(ctrl_pdata->disp_te_gpio)) {
 		rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te");
 		if (rc) {
 			pr_err("request TE gpio failed, rc=%d\n",