Merge "USB: dwc3: msm: Host: Don't turn off core clock when SS session is active"
diff --git a/arch/arm/boot/dts/msm9625-v2-1-cdp.dts b/arch/arm/boot/dts/msm9625-cdp.dtsi
similarity index 79%
rename from arch/arm/boot/dts/msm9625-v2-1-cdp.dts
rename to arch/arm/boot/dts/msm9625-cdp.dtsi
index da07100..1f9cbb0 100644
--- a/arch/arm/boot/dts/msm9625-v2-1-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-cdp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, 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
@@ -10,17 +10,10 @@
  * GNU General Public License for more details.
  */
 
-/dts-v1/;
-
-/include/ "msm9625-v2-1.dtsi"
+/include/ "msm9625-display.dtsi"
+/include/ "qpic-panel-ili-qvga.dtsi"
 
 / {
-	model = "Qualcomm MSM 9625V2.1 CDP";
-	compatible = "qcom,msm9625-cdp", "qcom,msm9625", "qcom,cdp";
-	qcom,msm-id = <134 1 0x20001>, <152 1 0x20001>, <149 1 0x20001>,
-		      <150 1 0x20001>, <151 1 0x20001>, <148 1 0x20001>,
-		      <173 1 0x20001>, <174 1 0x20001>, <175 1 0x20001>;
-
 	i2c@f9925000 {
 		charger@57 {
 			compatible = "summit,smb137c";
@@ -42,10 +35,18 @@
 
 	wlan0: qca,wlan {
 		cell-index = <0>;
-		compatible = "qca,ar6004-sdio";
+		compatible = "qca,ar6004-hsic";
 		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
 		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
-		qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+		qca,vdd-io-supply = <&pm8019_l11>;
+	};
+
+	qca,wlan_ar6003 {
+		cell-index = <0>;
+		compatible = "qca,ar6003-sdio";
+		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+		qca,vdd-io-supply = <&pm8019_l11>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm9625-v2-1-cdp.dts b/arch/arm/boot/dts/msm9625-mtp.dtsi
similarity index 73%
copy from arch/arm/boot/dts/msm9625-v2-1-cdp.dts
copy to arch/arm/boot/dts/msm9625-mtp.dtsi
index da07100..cc0bf5e 100644
--- a/arch/arm/boot/dts/msm9625-v2-1-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-mtp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, 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
@@ -10,17 +10,7 @@
  * GNU General Public License for more details.
  */
 
-/dts-v1/;
-
-/include/ "msm9625-v2-1.dtsi"
-
 / {
-	model = "Qualcomm MSM 9625V2.1 CDP";
-	compatible = "qcom,msm9625-cdp", "qcom,msm9625", "qcom,cdp";
-	qcom,msm-id = <134 1 0x20001>, <152 1 0x20001>, <149 1 0x20001>,
-		      <150 1 0x20001>, <151 1 0x20001>, <148 1 0x20001>,
-		      <173 1 0x20001>, <174 1 0x20001>, <175 1 0x20001>;
-
 	i2c@f9925000 {
 		charger@57 {
 			compatible = "summit,smb137c";
@@ -42,10 +32,18 @@
 
 	wlan0: qca,wlan {
 		cell-index = <0>;
-		compatible = "qca,ar6004-sdio";
+		compatible = "qca,ar6004-hsic";
 		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
 		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
-		qca,ar6004-vdd-io-supply = <&pm8019_l11>;
+		qca,vdd-io-supply = <&pm8019_l11>;
+	};
+
+	qca,wlan_ar6003 {
+		cell-index = <0>;
+		compatible = "qca,ar6003-sdio";
+		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
+		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
+		qca,vdd-io-supply = <&pm8019_l11>;
 	};
 };
 
@@ -89,11 +87,23 @@
 	};
 
 	mpp@a300 { /* MPP 4 */
+		/* VADC channel 19 */
+		qcom,mode = <4>;
+		qcom,ain-route = <3>; /* AMUX 8 */
+		qcom,master-en = <1>;
+		qcom,src-sel = <0>; /* Function constant */
+		qcom,invert = <1>;
 	};
 
 	mpp@a400 { /* MPP 5 */
 	};
 
 	mpp@a500 { /* MPP 6 */
+		/* channel 21 */
+		qcom,mode = <4>;
+		qcom,ain-route = <1>; /* AMUX 6 */
+		qcom,master-en = <1>;
+		qcom,src-sel = <0>; /* Function constant */
+		qcom,invert = <1>;
 	};
 };
diff --git a/arch/arm/boot/dts/msm9625-v1-cdp.dts b/arch/arm/boot/dts/msm9625-v1-cdp.dts
index cf17c69..d7537eb 100644
--- a/arch/arm/boot/dts/msm9625-v1-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-v1-cdp.dts
@@ -13,6 +13,7 @@
 /dts-v1/;
 
 /include/ "msm9625-v1.dtsi"
+/include/ "msm9625-cdp.dtsi"
 
 / {
 	model = "Qualcomm MSM 9625V1 CDP";
@@ -20,88 +21,4 @@
 	qcom,msm-id = <134 1 0>, <152 1 0>, <149 1 0>, <150 1 0>,
 		      <151 1 0>, <148 1 0>, <173 1 0>, <174 1 0>,
 		      <175 1 0>;
-
-	i2c@f9925000 {
-		charger@57 {
-			compatible = "summit,smb137c";
-			reg = <0x57>;
-			summit,chg-current-ma = <1500>;
-			summit,term-current-ma = <50>;
-			summit,pre-chg-current-ma = <100>;
-			summit,float-voltage-mv = <4200>;
-			summit,thresh-voltage-mv = <3000>;
-			summit,recharge-thresh-mv = <75>;
-			summit,system-voltage-mv = <4250>;
-			summit,charging-timeout = <382>;
-			summit,pre-charge-timeout = <48>;
-			summit,therm-current-ua = <10>;
-			summit,temperature-min = <4>; /*  0 C */
-			summit,temperature-max = <3>; /* 45 C */
-		};
-	};
-
-	wlan0: qca,wlan {
-		cell-index = <0>;
-		compatible = "qca,ar6004-sdio";
-		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
-		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
-		qca,vdd-io-supply = <&pm8019_l11>;
-	};
-
-	qca,wlan_ar6003 {
-		cell-index = <0>;
-		compatible = "qca,ar6003-sdio";
-		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
-		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
-		qca,vdd-io-supply = <&pm8019_l11>;
-	};
-};
-
-/* PM8019 GPIO and MPP configuration */
-&pm8019_gpios {
-	gpio@c000 { /* GPIO 1 */
-	};
-
-	gpio@c100 { /* GPIO 2 */
-	};
-
-	gpio@c200 { /* GPIO 3 */
-	};
-
-	gpio@c300 { /* GPIO 4 */
-		/* ext_2p95v regulator enable config */
-		qcom,mode = <1>; /* Digital output */
-		qcom,output-type = <0>; /* CMOS */
-		qcom,invert = <0>; /* Output low */
-		qcom,out-strength = <1>; /* Low */
-		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
-		qcom,src-sel = <0>; /* Constant */
-		qcom,master-en = <1>; /* Enable GPIO */
-	};
-
-	gpio@c400 { /* GPIO 5 */
-	};
-
-	gpio@c500 { /* GPIO 6 */
-	};
-};
-
-&pm8019_mpps {
-	mpp@a000 { /* MPP 1 */
-	};
-
-	mpp@a100 { /* MPP 2 */
-	};
-
-	mpp@a200 { /* MPP 3 */
-	};
-
-	mpp@a300 { /* MPP 4 */
-	};
-
-	mpp@a400 { /* MPP 5 */
-	};
-
-	mpp@a500 { /* MPP 6 */
-	};
 };
diff --git a/arch/arm/boot/dts/msm9625-v1-mtp.dts b/arch/arm/boot/dts/msm9625-v1-mtp.dts
index 24aa3af..a70ec1a 100644
--- a/arch/arm/boot/dts/msm9625-v1-mtp.dts
+++ b/arch/arm/boot/dts/msm9625-v1-mtp.dts
@@ -13,6 +13,7 @@
 /dts-v1/;
 
 /include/ "msm9625-v1.dtsi"
+/include/ "msm9625-mtp.dtsi"
 
 / {
 	model = "Qualcomm MSM 9625V1 MTP";
@@ -20,100 +21,4 @@
 	qcom,msm-id = <134 7 0>, <152 7 0>, <149 7 0>, <150 7 0>,
 		      <151 7 0>, <148 7 0>, <173 7 0>, <174 7 0>,
 		      <175 7 0>;
-
-	i2c@f9925000 {
-		charger@57 {
-			compatible = "summit,smb137c";
-			reg = <0x57>;
-			summit,chg-current-ma = <1500>;
-			summit,term-current-ma = <50>;
-			summit,pre-chg-current-ma = <100>;
-			summit,float-voltage-mv = <4200>;
-			summit,thresh-voltage-mv = <3000>;
-			summit,recharge-thresh-mv = <75>;
-			summit,system-voltage-mv = <4250>;
-			summit,charging-timeout = <382>;
-			summit,pre-charge-timeout = <48>;
-			summit,therm-current-ua = <10>;
-			summit,temperature-min = <4>; /*  0 C */
-			summit,temperature-max = <3>; /* 45 C */
-		};
-	};
-
-	wlan0: qca,wlan {
-		cell-index = <0>;
-		compatible = "qca,ar6004-sdio";
-		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
-		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
-		qca,vdd-io-supply = <&pm8019_l11>;
-	};
-
-	qca,wlan_ar6003 {
-		cell-index = <0>;
-		compatible = "qca,ar6003-sdio";
-		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
-		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
-		qca,vdd-io-supply = <&pm8019_l11>;
-	};
-};
-
-/* PM8019 GPIO and MPP configuration */
-&pm8019_gpios {
-	gpio@c000 { /* GPIO 1 */
-	};
-
-	gpio@c100 { /* GPIO 2 */
-	};
-
-	gpio@c200 { /* GPIO 3 */
-	};
-
-	gpio@c300 { /* GPIO 4 */
-		/* ext_2p95v regulator enable config */
-		qcom,mode = <1>; /* Digital output */
-		qcom,output-type = <0>; /* CMOS */
-		qcom,invert = <0>; /* Output low */
-		qcom,out-strength = <1>; /* Low */
-		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
-		qcom,src-sel = <0>; /* Constant */
-		qcom,master-en = <1>; /* Enable GPIO */
-	};
-
-	gpio@c400 { /* GPIO 5 */
-	};
-
-	gpio@c500 { /* GPIO 6 */
-	};
-};
-
-&pm8019_mpps {
-	mpp@a000 { /* MPP 1 */
-	};
-
-	mpp@a100 { /* MPP 2 */
-	};
-
-	mpp@a200 { /* MPP 3 */
-	};
-
-	mpp@a300 { /* MPP 4 */
-		/* VADC channel 19 */
-		qcom,mode = <4>;
-		qcom,ain-route = <3>; /* AMUX 8 */
-		qcom,master-en = <1>;
-		qcom,src-sel = <0>; /* Function constant */
-		qcom,invert = <1>;
-	};
-
-	mpp@a400 { /* MPP 5 */
-	};
-
-	mpp@a500 { /* MPP 6 */
-		/* VADC channel 21 */
-		qcom,mode = <4>;
-		qcom,ain-route = <1>; /* AMUX 6 */
-		qcom,master-en = <1>;
-		qcom,src-sel = <0>; /* Function constant */
-		qcom,invert = <1>;
-	};
 };
diff --git a/arch/arm/boot/dts/msm9625-v2-1-mtp.dts b/arch/arm/boot/dts/msm9625-v2-1-mtp.dts
deleted file mode 100644
index 1e0f3c0..0000000
--- a/arch/arm/boot/dts/msm9625-v2-1-mtp.dts
+++ /dev/null
@@ -1,99 +0,0 @@
-/* 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.
- */
-
-/dts-v1/;
-
-/include/ "msm9625-v2-1.dtsi"
-
-/ {
-	model = "Qualcomm MSM 9625V2.1 MTP";
-	compatible = "qcom,msm9625-mtp", "qcom,msm9625", "qcom,mtp";
-	qcom,msm-id = <134 7 0x20001>, <152 7 0x20001>, <149 7 0x20001>,
-		      <150 7 0x20001>, <151 7 0x20001>, <148 7 0x20001>,
-		      <173 7 0x20001>, <174 7 0x20001>, <175 7 0x20001>;
-
-	i2c@f9925000 {
-		charger@57 {
-			compatible = "summit,smb137c";
-			reg = <0x57>;
-			summit,chg-current-ma = <1500>;
-			summit,term-current-ma = <50>;
-			summit,pre-chg-current-ma = <100>;
-			summit,float-voltage-mv = <4200>;
-			summit,thresh-voltage-mv = <3000>;
-			summit,recharge-thresh-mv = <75>;
-			summit,system-voltage-mv = <4250>;
-			summit,charging-timeout = <382>;
-			summit,pre-charge-timeout = <48>;
-			summit,therm-current-ua = <10>;
-			summit,temperature-min = <4>; /*  0 C */
-			summit,temperature-max = <3>; /* 45 C */
-		};
-	};
-
-	wlan0: qca,wlan {
-		cell-index = <0>;
-		compatible = "qca,ar6004-sdio";
-		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
-		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
-		qca,ar6004-vdd-io-supply = <&pm8019_l11>;
-	};
-};
-
-/* PM8019 GPIO and MPP configuration */
-&pm8019_gpios {
-	gpio@c000 { /* GPIO 1 */
-	};
-
-	gpio@c100 { /* GPIO 2 */
-	};
-
-	gpio@c200 { /* GPIO 3 */
-	};
-
-	gpio@c300 { /* GPIO 4 */
-		/* ext_2p95v regulator enable config */
-		qcom,mode = <1>; /* Digital output */
-		qcom,output-type = <0>; /* CMOS */
-		qcom,invert = <0>; /* Output low */
-		qcom,out-strength = <1>; /* Low */
-		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
-		qcom,src-sel = <0>; /* Constant */
-		qcom,master-en = <1>; /* Enable GPIO */
-	};
-
-	gpio@c400 { /* GPIO 5 */
-	};
-
-	gpio@c500 { /* GPIO 6 */
-	};
-};
-
-&pm8019_mpps {
-	mpp@a000 { /* MPP 1 */
-	};
-
-	mpp@a100 { /* MPP 2 */
-	};
-
-	mpp@a200 { /* MPP 3 */
-	};
-
-	mpp@a300 { /* MPP 4 */
-	};
-
-	mpp@a400 { /* MPP 5 */
-	};
-
-	mpp@a500 { /* MPP 6 */
-	};
-};
diff --git a/arch/arm/boot/dts/msm9625-v2-cdp.dts b/arch/arm/boot/dts/msm9625-v2-cdp.dts
index 660bdbd..9fbe5ec 100644
--- a/arch/arm/boot/dts/msm9625-v2-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-v2-cdp.dts
@@ -13,8 +13,7 @@
 /dts-v1/;
 
 /include/ "msm9625-v2.dtsi"
-/include/ "msm9625-display.dtsi"
-/include/ "qpic-panel-ili-qvga.dtsi"
+/include/ "msm9625-cdp.dtsi"
 
 / {
 	model = "Qualcomm MSM 9625V2 CDP";
@@ -22,88 +21,4 @@
 	qcom,msm-id = <134 1 0x20000>, <152 1 0x20000>, <149 1 0x20000>,
 		      <150 1 0x20000>, <151 1 0x20000>, <148 1 0x20000>,
 		      <173 1 0x20000>, <174 1 0x20000>, <175 1 0x20000>;
-
-	i2c@f9925000 {
-		charger@57 {
-			compatible = "summit,smb137c";
-			reg = <0x57>;
-			summit,chg-current-ma = <1500>;
-			summit,term-current-ma = <50>;
-			summit,pre-chg-current-ma = <100>;
-			summit,float-voltage-mv = <4200>;
-			summit,thresh-voltage-mv = <3000>;
-			summit,recharge-thresh-mv = <75>;
-			summit,system-voltage-mv = <4250>;
-			summit,charging-timeout = <382>;
-			summit,pre-charge-timeout = <48>;
-			summit,therm-current-ua = <10>;
-			summit,temperature-min = <4>; /*  0 C */
-			summit,temperature-max = <3>; /* 45 C */
-		};
-	};
-
-	wlan0: qca,wlan {
-		cell-index = <0>;
-		compatible = "qca,ar6004-hsic";
-		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
-		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
-		qca,vdd-io-supply = <&pm8019_l11>;
-	};
-
-	qca,wlan_ar6003 {
-		cell-index = <0>;
-		compatible = "qca,ar6003-sdio";
-		qca,chip-pwd-l-gpios = <&msmgpio 62 0>;
-		qca,pm-enable-gpios = <&pm8019_gpios 3 0x0>;
-		qca,vdd-io-supply = <&pm8019_l11>;
-	};
-};
-
-/* PM8019 GPIO and MPP configuration */
-&pm8019_gpios {
-	gpio@c000 { /* GPIO 1 */
-	};
-
-	gpio@c100 { /* GPIO 2 */
-	};
-
-	gpio@c200 { /* GPIO 3 */
-	};
-
-	gpio@c300 { /* GPIO 4 */
-		/* ext_2p95v regulator enable config */
-		qcom,mode = <1>; /* Digital output */
-		qcom,output-type = <0>; /* CMOS */
-		qcom,invert = <0>; /* Output low */
-		qcom,out-strength = <1>; /* Low */
-		qcom,vin-sel = <2>; /* PM8019 L11 - 1.8V */
-		qcom,src-sel = <0>; /* Constant */
-		qcom,master-en = <1>; /* Enable GPIO */
-	};
-
-	gpio@c400 { /* GPIO 5 */
-	};
-
-	gpio@c500 { /* GPIO 6 */
-	};
-};
-
-&pm8019_mpps {
-	mpp@a000 { /* MPP 1 */
-	};
-
-	mpp@a100 { /* MPP 2 */
-	};
-
-	mpp@a200 { /* MPP 3 */
-	};
-
-	mpp@a300 { /* MPP 4 */
-	};
-
-	mpp@a400 { /* MPP 5 */
-	};
-
-	mpp@a500 { /* MPP 6 */
-	};
 };
diff --git a/arch/arm/boot/dts/msm9625-v2-mtp.dts b/arch/arm/boot/dts/msm9625-v2-mtp.dts
index c9e54be..5324e2c 100644
--- a/arch/arm/boot/dts/msm9625-v2-mtp.dts
+++ b/arch/arm/boot/dts/msm9625-v2-mtp.dts
@@ -13,6 +13,7 @@
 /dts-v1/;
 
 /include/ "msm9625-v2.dtsi"
+/include/ "msm9625-mtp.dtsi"
 
 / {
 	model = "Qualcomm MSM 9625V2 MTP";
diff --git a/arch/arm/boot/dts/msm9625-v2.1-cdp.dts b/arch/arm/boot/dts/msm9625-v2.1-cdp.dts
new file mode 100644
index 0000000..b643593
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v2.1-cdp.dts
@@ -0,0 +1,24 @@
+/* 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.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625-v2.1.dtsi"
+/include/ "msm9625-cdp.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625V2.1 CDP";
+	compatible = "qcom,msm9625-cdp", "qcom,msm9625", "qcom,cdp";
+	qcom,msm-id = <134 1 0x20001>, <152 1 0x20001>, <149 1 0x20001>,
+		      <150 1 0x20001>, <151 1 0x20001>, <148 1 0x20001>,
+		      <173 1 0x20001>, <174 1 0x20001>, <175 1 0x20001>;
+};
diff --git a/arch/arm/boot/dts/msm9625-v2.1-mtp.dts b/arch/arm/boot/dts/msm9625-v2.1-mtp.dts
new file mode 100644
index 0000000..8bbcc0d
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-v2.1-mtp.dts
@@ -0,0 +1,24 @@
+/* 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.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625-v2.1.dtsi"
+/include/ "msm9625-mtp.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625V2.1 MTP";
+	compatible = "qcom,msm9625-mtp", "qcom,msm9625", "qcom,mtp";
+	qcom,msm-id = <134 7 0x20001>, <152 7 0x20001>, <149 7 0x20001>,
+		      <150 7 0x20001>, <151 7 0x20001>, <148 7 0x20001>,
+		      <173 7 0x20001>, <174 7 0x20001>, <175 7 0x20001>;
+};
diff --git a/arch/arm/boot/dts/msm9625-v2-1.dtsi b/arch/arm/boot/dts/msm9625-v2.1.dtsi
similarity index 100%
rename from arch/arm/boot/dts/msm9625-v2-1.dtsi
rename to arch/arm/boot/dts/msm9625-v2.1.dtsi
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index f67cb0d..aa2c028 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -98,6 +98,7 @@
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
 CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index b5e67fd..c9f068a 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -102,6 +102,7 @@
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
 CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
diff --git a/arch/arm/configs/msm9625-perf_defconfig b/arch/arm/configs/msm9625-perf_defconfig
index 42acd99..ae73bad 100644
--- a/arch/arm/configs/msm9625-perf_defconfig
+++ b/arch/arm/configs/msm9625-perf_defconfig
@@ -230,9 +230,6 @@
 CONFIG_REGULATOR_QPNP=y
 CONFIG_ION=y
 CONFIG_ION_MSM=y
-CONFIG_FB=y
-CONFIG_FB_MSM=y
-CONFIG_FB_MSM_QPIC_PANEL_DETECT=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 041e89a..f7c3bff 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -231,9 +231,6 @@
 CONFIG_REGULATOR_QPNP=y
 CONFIG_ION=y
 CONFIG_ION_MSM=y
-CONFIG_FB=y
-CONFIG_FB_MSM=y
-CONFIG_FB_MSM_QPIC_PANEL_DETECT=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index f20f6ae..8c366da 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -76,8 +76,8 @@
         dtb-$(CONFIG_ARCH_MSM9625)	+= msm9625-v1-rumi.dtb
 	dtb-$(CONFIG_ARCH_MSM9625)      += msm9625-v2-cdp.dtb
 	dtb-$(CONFIG_ARCH_MSM9625)      += msm9625-v2-mtp.dtb
-	dtb-$(CONFIG_ARCH_MSM9625)      += msm9625-v2-1-mtp.dtb
-	dtb-$(CONFIG_ARCH_MSM9625)      += msm9625-v2-1-cdp.dtb
+	dtb-$(CONFIG_ARCH_MSM9625)      += msm9625-v2.1-mtp.dtb
+	dtb-$(CONFIG_ARCH_MSM9625)      += msm9625-v2.1-cdp.dtb
 
 # MSM8226
    zreladdr-$(CONFIG_ARCH_MSM8226)	:= 0x00008000
diff --git a/arch/arm/mach-msm/board-9625-gpiomux.c b/arch/arm/mach-msm/board-9625-gpiomux.c
index 75aaaec..a6ac986 100644
--- a/arch/arm/mach-msm/board-9625-gpiomux.c
+++ b/arch/arm/mach-msm/board-9625-gpiomux.c
@@ -276,6 +276,7 @@
 	},
 };
 
+#ifdef CONFIG_FB_MSM_QPIC
 static struct gpiomux_setting qpic_lcdc_a_d = {
 	.func = GPIOMUX_FUNC_1,
 	.drv = GPIOMUX_DRV_10MA,
@@ -327,6 +328,17 @@
 	},
 };
 
+static void msm9625_disp_init_gpiomux(void)
+{
+	msm_gpiomux_install(msm9625_qpic_lcdc_configs,
+			ARRAY_SIZE(msm9625_qpic_lcdc_configs));
+}
+#else
+static void msm9625_disp_init_gpiomux(void)
+{
+}
+#endif /* CONFIG_FB_MSM_QPIC */
+
 void __init msm9625_init_gpiomux(void)
 {
 	int rc;
@@ -347,7 +359,5 @@
 			ARRAY_SIZE(mdm9625_cdc_reset_config));
 	msm_gpiomux_install(sdc2_card_det_config,
 		ARRAY_SIZE(sdc2_card_det_config));
-	msm_gpiomux_install(msm9625_qpic_lcdc_configs,
-			ARRAY_SIZE(msm9625_qpic_lcdc_configs));
-
+	msm9625_disp_init_gpiomux();
 }
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index f3ee02b..439ecdc 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -2782,7 +2782,7 @@
 	if (device->state == KGSL_STATE_ACTIVE) {
 		/* Is the ring buffer is empty? */
 		GSL_RB_GET_READPTR(rb, &rb->rptr);
-		if (!device->active_cnt && (rb->rptr == rb->wptr)) {
+		if (rb->rptr == rb->wptr) {
 			/*
 			 * Are there interrupts pending? If so then pretend we
 			 * are not idle - this avoids the possiblity that we go
@@ -3596,15 +3596,20 @@
 {
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
-	unsigned int cycles;
+	unsigned int cycles = 0;
 
-	/* Get the busy cycles counted since the counter was last reset */
-	/* Calling this function also resets and restarts the counter */
+	/*
+	 * Get the busy cycles counted since the counter was last reset.
+	 * If we're not currently active, there shouldn't have been
+	 * any cycles since the last time this function was called.
+	 */
+	if (device->state == KGSL_STATE_ACTIVE)
+		cycles = adreno_dev->gpudev->busy_cycles(adreno_dev);
 
-	cycles = adreno_dev->gpudev->busy_cycles(adreno_dev);
-
-	/* In order to calculate idle you have to have run the algorithm *
-	 * at least once to get a start time. */
+	/*
+	 * In order to calculate idle you have to have run the algorithm
+	 * at least once to get a start time.
+	 */
 	if (pwr->time != 0) {
 		s64 tmp = ktime_to_us(ktime_get());
 		stats->total_time = tmp - pwr->time;
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index ef599e9..980ff13 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -93,4 +93,7 @@
 	 adreno_dev->ft_pf_policy = KGSL_FT_PAGEFAULT_DEFAULT_POLICY;
 	 debugfs_create_u32("ft_pagefault_policy", 0644, device->d_debugfs,
 			&adreno_dev->ft_pf_policy);
+
+	debugfs_create_u32("active_cnt", 0444, device->d_debugfs,
+			   &device->active_cnt);
 }
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 53ef392..08dd886 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -413,27 +413,6 @@
 	kfree(context);
 }
 
-static void kgsl_check_idle_locked(struct kgsl_device *device)
-{
-	if (device->pwrctrl.nap_allowed == true &&
-	    device->state == KGSL_STATE_ACTIVE &&
-		device->requested_state == KGSL_STATE_NONE) {
-		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
-		kgsl_pwrscale_idle(device);
-		if (kgsl_pwrctrl_sleep(device) != 0)
-			mod_timer(&device->idle_timer,
-				  jiffies +
-				  device->pwrctrl.interval_timeout);
-	}
-}
-
-static void kgsl_check_idle(struct kgsl_device *device)
-{
-	mutex_lock(&device->mutex);
-	kgsl_check_idle_locked(device);
-	mutex_unlock(&device->mutex);
-}
-
 struct kgsl_device *kgsl_get_device(int dev_idx)
 {
 	int i;
@@ -496,13 +475,12 @@
 	policy_saved = device->pwrscale.policy;
 	device->pwrscale.policy = NULL;
 	kgsl_pwrctrl_request_state(device, KGSL_STATE_SUSPEND);
-	/* Make sure no user process is waiting for a timestamp *
-	 * before supending */
-	if (device->active_cnt != 0) {
-		mutex_unlock(&device->mutex);
-		wait_for_completion(&device->suspend_gate);
-		mutex_lock(&device->mutex);
-	}
+	/*
+	 * Make sure no user process is waiting for a timestamp
+	 * before supending.
+	 */
+	kgsl_active_count_wait(device);
+
 	/* Don't let the timer wake us during suspended sleep. */
 	del_timer_sync(&device->idle_timer);
 	switch (device->state) {
@@ -513,6 +491,8 @@
 			device->ftbl->idle(device);
 		case KGSL_STATE_NAP:
 		case KGSL_STATE_SLEEP:
+			/* make sure power is on to stop the device */
+			kgsl_pwrctrl_enable(device);
 			/* Get the completion ready to be waited upon. */
 			INIT_COMPLETION(device->hwaccess_gate);
 			device->ftbl->suspend_context(device);
@@ -632,9 +612,16 @@
 	device->pwrctrl.restore_slumber = false;
 	if (device->pwrscale.policy == NULL)
 		kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_TURBO);
-	kgsl_pwrctrl_wake(device);
+	if (kgsl_pwrctrl_wake(device) != 0)
+		return;
+	/*
+	 * We don't have a way to go directly from
+	 * a deeper sleep state to NAP, which is
+	 * the desired state here.
+	 */
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
+	kgsl_pwrctrl_sleep(device);
 	mutex_unlock(&device->mutex);
-	kgsl_check_idle(device);
 	KGSL_PWR_WARN(device, "late resume end\n");
 }
 EXPORT_SYMBOL(kgsl_late_resume_driver);
@@ -745,7 +732,7 @@
 	filep->private_data = NULL;
 
 	mutex_lock(&device->mutex);
-	kgsl_check_suspended(device);
+	kgsl_active_count_get(device);
 
 	while (1) {
 		context = idr_get_next(&device->context_idr, &next);
@@ -767,10 +754,17 @@
 
 	device->open_count--;
 	if (device->open_count == 0) {
+		BUG_ON(device->active_cnt > 1);
 		result = device->ftbl->stop(device);
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
+		/*
+		 * active_cnt special case: we just stopped the device,
+		 * so no need to use kgsl_active_count_put()
+		 */
+		device->active_cnt--;
+	} else {
+		kgsl_active_count_put(device);
 	}
-
 	mutex_unlock(&device->mutex);
 	kfree(dev_priv);
 
@@ -816,9 +810,14 @@
 	filep->private_data = dev_priv;
 
 	mutex_lock(&device->mutex);
-	kgsl_check_suspended(device);
 
 	if (device->open_count == 0) {
+		/*
+		 * active_cnt special case: we are starting up for the first
+		 * time, so use this sequence instead of the kgsl_pwrctrl_wake()
+		 * which will be called by kgsl_active_count_get().
+		 */
+		device->active_cnt++;
 		kgsl_sharedmem_set(&device->memstore, 0, 0,
 				device->memstore.size);
 
@@ -831,6 +830,7 @@
 			goto err_freedevpriv;
 
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
+		kgsl_active_count_put(device);
 	}
 	device->open_count++;
 	mutex_unlock(&device->mutex);
@@ -856,10 +856,15 @@
 	mutex_lock(&device->mutex);
 	device->open_count--;
 	if (device->open_count == 0) {
+		/* make sure power is on to stop the device */
+		kgsl_pwrctrl_enable(device);
 		result = device->ftbl->stop(device);
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
 	}
 err_freedevpriv:
+	/* only the first open takes an active count */
+	if (device->open_count == 0)
+		device->active_cnt--;
 	mutex_unlock(&device->mutex);
 	filep->private_data = NULL;
 	kfree(dev_priv);
@@ -1073,10 +1078,6 @@
 	struct kgsl_device *device = dev_priv->device;
 	unsigned int context_id = context ? context->id : KGSL_MEMSTORE_GLOBAL;
 
-	/* Set the active count so that suspend doesn't do the wrong thing */
-
-	device->active_cnt++;
-
 	trace_kgsl_waittimestamp_entry(device, context_id,
 				       kgsl_readtimestamp(device, context,
 							KGSL_TIMESTAMP_RETIRED),
@@ -1090,9 +1091,6 @@
 							KGSL_TIMESTAMP_RETIRED),
 				      result);
 
-	/* Fire off any pending suspend operations that are in flight */
-	kgsl_active_count_put(dev_priv->device);
-
 	return result;
 }
 
@@ -1887,7 +1885,6 @@
 
 	trace_kgsl_mem_map(entry, param->fd);
 
-	kgsl_check_idle(dev_priv->device);
 	return result;
 
 error_unmap:
@@ -1907,7 +1904,6 @@
 	}
 error:
 	kfree(entry);
-	kgsl_check_idle(dev_priv->device);
 	return result;
 }
 
@@ -2035,7 +2031,6 @@
 
 	entry->memtype = KGSL_MEM_ENTRY_KERNEL;
 
-	kgsl_check_idle(dev_priv->device);
 	*ret_entry = entry;
 	return result;
 err:
@@ -2370,7 +2365,7 @@
 			kgsl_ioctl_cff_user_event, 0),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_TIMESTAMP_EVENT,
 			kgsl_ioctl_timestamp_event,
-			KGSL_IOCTL_LOCK),
+			KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_SETPROPERTY,
 			kgsl_ioctl_device_setproperty,
 			KGSL_IOCTL_LOCK | KGSL_IOCTL_WAKE),
@@ -2462,14 +2457,19 @@
 
 	if (lock) {
 		mutex_lock(&dev_priv->device->mutex);
-		if (use_hw)
-			kgsl_check_suspended(dev_priv->device);
+		if (use_hw) {
+			ret = kgsl_active_count_get(dev_priv->device);
+			if (ret < 0)
+				goto unlock;
+		}
 	}
 
 	ret = func(dev_priv, cmd, uptr);
 
+unlock:
 	if (lock) {
-		kgsl_check_idle_locked(dev_priv->device);
+		if (use_hw)
+			kgsl_active_count_put(dev_priv->device);
 		mutex_unlock(&dev_priv->device->mutex);
 	}
 
@@ -3032,11 +3032,7 @@
 	/* For a manual dump, make sure that the system is idle */
 
 	if (manual) {
-		if (device->active_cnt != 0) {
-			mutex_unlock(&device->mutex);
-			wait_for_completion(&device->suspend_gate);
-			mutex_lock(&device->mutex);
-		}
+		kgsl_active_count_wait(device);
 
 		if (device->state == KGSL_STATE_ACTIVE)
 			kgsl_idle(device);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 0d11660..ac82820 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -454,23 +454,4 @@
 	kref_put(&context->refcount, kgsl_context_destroy);
 }
 
-/**
- * kgsl_active_count_put - Decrease the device active count
- * @device: Pointer to a KGSL device
- *
- * Decrease the active count for the KGSL device and trigger the suspend_gate
- * completion if it hits zero
- */
-static inline void
-kgsl_active_count_put(struct kgsl_device *device)
-{
-	if (device->active_cnt == 1)
-		INIT_COMPLETION(device->suspend_gate);
-
-	device->active_cnt--;
-
-	if (device->active_cnt == 0)
-		complete(&device->suspend_gate);
-}
-
 #endif  /* __KGSL_DEVICE_H */
diff --git a/drivers/gpu/msm/kgsl_events.c b/drivers/gpu/msm/kgsl_events.c
index 9e9c0da..d872783 100644
--- a/drivers/gpu/msm/kgsl_events.c
+++ b/drivers/gpu/msm/kgsl_events.c
@@ -51,6 +51,7 @@
 	void (*cb)(struct kgsl_device *, void *, u32, u32), void *priv,
 	void *owner)
 {
+	int ret;
 	struct kgsl_event *event;
 	unsigned int cur_ts;
 	struct kgsl_context *context = NULL;
@@ -82,6 +83,16 @@
 	if (event == NULL)
 		return -ENOMEM;
 
+	/*
+	 * Increase the active count on the device to avoid going into power
+	 * saving modes while events are pending
+	 */
+	ret = kgsl_active_count_get_light(device);
+	if (ret < 0) {
+		kfree(event);
+		return ret;
+	}
+
 	event->context = context;
 	event->timestamp = ts;
 	event->priv = priv;
@@ -112,13 +123,6 @@
 	} else
 		_add_event_to_list(&device->events, event);
 
-	/*
-	 * Increase the active count on the device to avoid going into power
-	 * saving modes while events are pending
-	 */
-
-	device->active_cnt++;
-
 	queue_work(device->work_queue, &device->ts_expired_ws);
 	return 0;
 }
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 2f8d93e..7d05aea 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -1055,6 +1055,14 @@
 	pwr->power_flags = 0;
 }
 
+/**
+ * kgsl_idle_check() - Work function for GPU interrupts and idle timeouts.
+ * @device: The device
+ *
+ * This function is called for work that is queued by the interrupt
+ * handler or the idle timer. It attempts to transition to a clocks
+ * off state if the active_cnt is 0 and the hardware is idle.
+ */
 void kgsl_idle_check(struct work_struct *work)
 {
 	struct kgsl_device *device = container_of(work, struct kgsl_device,
@@ -1064,15 +1072,22 @@
 		return;
 
 	mutex_lock(&device->mutex);
-	if (device->state & (KGSL_STATE_ACTIVE | KGSL_STATE_NAP)) {
-		kgsl_pwrscale_idle(device);
 
-		if (kgsl_pwrctrl_sleep(device) != 0) {
+	kgsl_pwrscale_idle(device);
+
+	if (device->state == KGSL_STATE_ACTIVE
+		   || device->state ==  KGSL_STATE_NAP) {
+		if (device->active_cnt > 0 || kgsl_pwrctrl_sleep(device) != 0) {
+
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+
 			mod_timer(&device->idle_timer,
 					jiffies +
 					device->pwrctrl.interval_timeout);
-			/* If the GPU has been too busy to sleep, make sure *
-			 * that is acurately reflected in the % busy numbers. */
+			/*
+			 * If the GPU has been too busy to sleep, make sure
+			 * that is acurately reflected in the % busy numbers.
+			 */
 			device->pwrctrl.clk_stats.no_nap_cnt++;
 			if (device->pwrctrl.clk_stats.no_nap_cnt >
 							 UPDATE_BUSY) {
@@ -1104,54 +1119,26 @@
 	}
 }
 
+
+/**
+ * kgsl_pre_hwaccess - Enforce preconditions for touching registers
+ * @device: The device
+ *
+ * This function ensures that the correct lock is held and that the GPU
+ * clock is on immediately before a register is read or written. Note
+ * that this function does not check active_cnt because the registers
+ * must be accessed during device start and stop, when the active_cnt
+ * may legitimately be 0.
+ */
 void kgsl_pre_hwaccess(struct kgsl_device *device)
 {
+	/* In order to touch a register you must hold the device mutex...*/
 	BUG_ON(!mutex_is_locked(&device->mutex));
-	switch (device->state) {
-	case KGSL_STATE_ACTIVE:
-		return;
-	case KGSL_STATE_NAP:
-	case KGSL_STATE_SLEEP:
-	case KGSL_STATE_SLUMBER:
-		kgsl_pwrctrl_wake(device);
-		break;
-	case KGSL_STATE_SUSPEND:
-		kgsl_check_suspended(device);
-		break;
-	case KGSL_STATE_INIT:
-	case KGSL_STATE_HUNG:
-	case KGSL_STATE_DUMP_AND_FT:
-		if (test_bit(KGSL_PWRFLAGS_CLK_ON,
-					 &device->pwrctrl.power_flags))
-			break;
-		else
-			KGSL_PWR_ERR(device,
-					"hw access while clocks off from state %d\n",
-					device->state);
-		break;
-	default:
-		KGSL_PWR_ERR(device, "hw access while in unknown state %d\n",
-					 device->state);
-		break;
-	}
+	/* and have the clock on! */
+	BUG_ON(!test_bit(KGSL_PWRFLAGS_CLK_ON, &device->pwrctrl.power_flags));
 }
 EXPORT_SYMBOL(kgsl_pre_hwaccess);
 
-void kgsl_check_suspended(struct kgsl_device *device)
-{
-	if (device->requested_state == KGSL_STATE_SUSPEND ||
-				device->state == KGSL_STATE_SUSPEND) {
-		mutex_unlock(&device->mutex);
-		wait_for_completion(&device->hwaccess_gate);
-		mutex_lock(&device->mutex);
-	} else if (device->state == KGSL_STATE_DUMP_AND_FT) {
-		mutex_unlock(&device->mutex);
-		wait_for_completion(&device->ft_gate);
-		mutex_lock(&device->mutex);
-	} else if (device->state == KGSL_STATE_SLUMBER)
-		kgsl_pwrctrl_wake(device);
-}
-
 static int
 _nap(struct kgsl_device *device)
 {
@@ -1230,6 +1217,8 @@
 	case KGSL_STATE_NAP:
 	case KGSL_STATE_SLEEP:
 		del_timer_sync(&device->idle_timer);
+		/* make sure power is on to stop the device*/
+		kgsl_pwrctrl_enable(device);
 		device->ftbl->suspend_context(device);
 		device->ftbl->stop(device);
 		_sleep_accounting(device);
@@ -1278,9 +1267,9 @@
 
 /******************************************************************/
 /* Caller must hold the device mutex. */
-void kgsl_pwrctrl_wake(struct kgsl_device *device)
+int kgsl_pwrctrl_wake(struct kgsl_device *device)
 {
-	int status;
+	int status = 0;
 	unsigned int context_id;
 	unsigned int state = device->state;
 	unsigned int ts_processed = 0xdeaddead;
@@ -1329,8 +1318,10 @@
 		KGSL_PWR_WARN(device, "unhandled state %s\n",
 				kgsl_pwrstate_to_str(device->state));
 		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+		status = -EINVAL;
 		break;
 	}
+	return status;
 }
 EXPORT_SYMBOL(kgsl_pwrctrl_wake);
 
@@ -1396,3 +1387,124 @@
 }
 EXPORT_SYMBOL(kgsl_pwrstate_to_str);
 
+
+/**
+ * kgsl_active_count_get() - Increase the device active count
+ * @device: Pointer to a KGSL device
+ *
+ * Increase the active count for the KGSL device and turn on
+ * clocks if this is the first reference. Code paths that need
+ * to touch the hardware or wait for the hardware to complete
+ * an operation must hold an active count reference until they
+ * are finished. An error code will be returned if waking the
+ * device fails. The device mutex must be held while *calling
+ * this function.
+ */
+int kgsl_active_count_get(struct kgsl_device *device)
+{
+	int ret = 0;
+	BUG_ON(!mutex_is_locked(&device->mutex));
+
+	if (device->active_cnt == 0) {
+		if (device->requested_state == KGSL_STATE_SUSPEND ||
+				device->state == KGSL_STATE_SUSPEND) {
+			mutex_unlock(&device->mutex);
+			wait_for_completion(&device->hwaccess_gate);
+			mutex_lock(&device->mutex);
+		} else if (device->state == KGSL_STATE_DUMP_AND_FT) {
+			mutex_unlock(&device->mutex);
+			wait_for_completion(&device->ft_gate);
+			mutex_lock(&device->mutex);
+		}
+		ret = kgsl_pwrctrl_wake(device);
+	}
+	if (ret == 0)
+		device->active_cnt++;
+	return ret;
+}
+EXPORT_SYMBOL(kgsl_active_count_get);
+
+/**
+ * kgsl_active_count_get_light() - Increase the device active count
+ * @device: Pointer to a KGSL device
+ *
+ * Increase the active count for the KGSL device WITHOUT
+ * turning on the clocks. Currently this is only used for creating
+ * kgsl_events. The device mutex must be held while calling this function.
+ */
+int kgsl_active_count_get_light(struct kgsl_device *device)
+{
+	BUG_ON(!mutex_is_locked(&device->mutex));
+
+	if (device->state != KGSL_STATE_ACTIVE) {
+		dev_WARN_ONCE(device->dev, 1, "device in unexpected state %s\n",
+				kgsl_pwrstate_to_str(device->state));
+		return -EINVAL;
+	}
+
+	if (device->active_cnt == 0) {
+		dev_WARN_ONCE(device->dev, 1, "active count is 0!\n");
+		return -EINVAL;
+	}
+
+	device->active_cnt++;
+	return 0;
+}
+EXPORT_SYMBOL(kgsl_active_count_get_light);
+
+/**
+ * kgsl_active_count_put() - Decrease the device active count
+ * @device: Pointer to a KGSL device
+ *
+ * Decrease the active count for the KGSL device and turn off
+ * clocks if there are no remaining references. This function will
+ * transition the device to NAP if there are no other pending state
+ * changes. It also completes the suspend gate.  The device mutex must
+ * be held while calling this function.
+ */
+void kgsl_active_count_put(struct kgsl_device *device)
+{
+	BUG_ON(!mutex_is_locked(&device->mutex));
+	BUG_ON(device->active_cnt == 0);
+
+	kgsl_pwrscale_idle(device);
+	if (device->active_cnt > 1) {
+		device->active_cnt--;
+		return;
+	}
+
+	INIT_COMPLETION(device->suspend_gate);
+
+	if (device->pwrctrl.nap_allowed == true &&
+			(device->state == KGSL_STATE_ACTIVE &&
+			device->requested_state == KGSL_STATE_NONE)) {
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
+		if (kgsl_pwrctrl_sleep(device) != 0)
+			mod_timer(&device->idle_timer,
+					jiffies
+					+ device->pwrctrl.interval_timeout);
+	}
+	device->active_cnt--;
+
+	if (device->active_cnt == 0)
+		complete(&device->suspend_gate);
+}
+EXPORT_SYMBOL(kgsl_active_count_put);
+
+/**
+ * kgsl_active_count_wait() - Wait for activity to finish.
+ * @device: Pointer to a KGSL device
+ *
+ * Block until all active_cnt users put() their reference.
+ */
+void kgsl_active_count_wait(struct kgsl_device *device)
+{
+	BUG_ON(!mutex_is_locked(&device->mutex));
+
+	if (device->active_cnt != 0) {
+		mutex_unlock(&device->mutex);
+		wait_for_completion(&device->suspend_gate);
+		mutex_lock(&device->mutex);
+	}
+}
+EXPORT_SYMBOL(kgsl_active_count_wait);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index ced52e1..0fd64c3 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -99,9 +99,8 @@
 void kgsl_timer(unsigned long data);
 void kgsl_idle_check(struct work_struct *work);
 void kgsl_pre_hwaccess(struct kgsl_device *device);
-void kgsl_check_suspended(struct kgsl_device *device);
 int kgsl_pwrctrl_sleep(struct kgsl_device *device);
-void kgsl_pwrctrl_wake(struct kgsl_device *device);
+int kgsl_pwrctrl_wake(struct kgsl_device *device);
 void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device,
 	unsigned int level);
 int kgsl_pwrctrl_init_sysfs(struct kgsl_device *device);
@@ -115,4 +114,10 @@
 
 void kgsl_pwrctrl_set_state(struct kgsl_device *device, unsigned int state);
 void kgsl_pwrctrl_request_state(struct kgsl_device *device, unsigned int state);
+
+int kgsl_active_count_get(struct kgsl_device *device);
+int kgsl_active_count_get_light(struct kgsl_device *device);
+void kgsl_active_count_put(struct kgsl_device *device);
+void kgsl_active_count_wait(struct kgsl_device *device);
+
 #endif /* __KGSL_PWRCTRL_H */
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index deda0c8..29b269a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -397,6 +397,7 @@
 	atomic_t st_enabled;
 	atomic_t st_pending_irqs;
 	struct completion st_completion;
+	struct completion st_powerdown;
 #endif
 };
 
@@ -1001,8 +1002,8 @@
 static irqreturn_t mxt_filter_interrupt(struct mxt_data *data)
 {
 	if (atomic_read(&data->st_enabled)) {
-		atomic_cmpxchg(&data->st_pending_irqs, 0, 1);
-		complete(&data->st_completion);
+		if (atomic_cmpxchg(&data->st_pending_irqs, 0, 1) == 0)
+			complete(&data->st_completion);
 		return IRQ_HANDLED;
 	}
 	return IRQ_NONE;
@@ -1996,6 +1997,7 @@
 		atomic_set(&data->st_enabled, 0);
 		complete(&data->st_completion);
 		mxt_interrupt(data->client->irq, data);
+		complete(&data->st_powerdown);
 		break;
 	case 1:
 		if (atomic_read(&data->st_enabled)) {
@@ -2008,6 +2010,8 @@
 			err = -EIO;
 			break;
 		}
+		INIT_COMPLETION(data->st_completion);
+		INIT_COMPLETION(data->st_powerdown);
 		atomic_set(&data->st_pending_irqs, 0);
 		atomic_set(&data->st_enabled, 1);
 		break;
@@ -2035,7 +2039,7 @@
 		return err;
 
 	if (atomic_cmpxchg(&data->st_pending_irqs, 1, 0) != 1)
-		return -EBADF;
+		return -EINVAL;
 
 	return scnprintf(buf, PAGE_SIZE, "%u", 1);
 }
@@ -2064,9 +2068,25 @@
 	.attrs = mxt_attrs,
 };
 
+
+#if defined(CONFIG_SECURE_TOUCH)
+static void mxt_secure_touch_stop(struct mxt_data *data)
+{
+	if (atomic_read(&data->st_enabled)) {
+		complete(&data->st_completion);
+		wait_for_completion_interruptible(&data->st_powerdown);
+	}
+}
+#else
+static void mxt_secure_touch_stop(struct mxt_data *data)
+{
+}
+#endif
+
 static int mxt_start(struct mxt_data *data)
 {
 	int error;
+	mxt_secure_touch_stop(data);
 
 	/* restore the old power state values and reenable touch */
 	error = __mxt_write_reg(data->client, data->t7_start_addr,
@@ -2084,6 +2104,7 @@
 {
 	int error;
 	u8 t7_data[T7_DATA_SIZE] = {0};
+	mxt_secure_touch_stop(data);
 
 	error = __mxt_write_reg(data->client, data->t7_start_addr,
 				T7_DATA_SIZE, t7_data);
@@ -2465,6 +2486,7 @@
 
 	/* calibrate */
 	if (data->pdata->need_calibration) {
+		mxt_secure_touch_stop(data);
 		error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
 					MXT_COMMAND_CALIBRATE, 1);
 		if (error < 0)
@@ -2800,12 +2822,13 @@
 #endif
 
 #if defined(CONFIG_SECURE_TOUCH)
-static void __devinit secure_touch_init(struct mxt_data *data)
+static void __devinit mxt_secure_touch_init(struct mxt_data *data)
 {
 	init_completion(&data->st_completion);
+	init_completion(&data->st_powerdown);
 }
 #else
-static void __devinit secure_touch_init(struct mxt_data *data)
+static void __devinit mxt_secure_touch_init(struct mxt_data *data)
 {
 }
 #endif
@@ -3002,7 +3025,7 @@
 
 	mxt_debugfs_init(data);
 
-	secure_touch_init(data);
+	mxt_secure_touch_init(data);
 
 	return 0;
 
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 61adfec..55e3e4e 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -673,7 +673,7 @@
 		app_id = ret;
 
 	if (app_id) {
-		pr_warn("App id %d (%s) already exists\n", app_id,
+		pr_debug("App id %d (%s) already exists\n", app_id,
 			(char *)(req.app_name));
 		spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
 		list_for_each_entry(entry,
@@ -831,7 +831,7 @@
 					break;
 				} else {
 					ptr_app->ref_cnt--;
-					pr_warn("Can't unload app(%d) inuse\n",
+					pr_debug("Can't unload app(%d) inuse\n",
 							ptr_app->app_id);
 					break;
 				}
@@ -2316,7 +2316,7 @@
 		pr_err(" scm call to check if app is loaded failed");
 		return ret;	/* scm call failed */
 	} else if (ret > 0) {
-		pr_warn("App id %d (%s) already exists\n", ret,
+		pr_debug("App id %d (%s) already exists\n", ret,
 			(char *)(req.app_name));
 		spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
 		list_for_each_entry(entry,
diff --git a/drivers/video/msm/mdss/dsi_host_v2.c b/drivers/video/msm/mdss/dsi_host_v2.c
index 453cbaa..887dde7 100644
--- a/drivers/video/msm/mdss/dsi_host_v2.c
+++ b/drivers/video/msm/mdss/dsi_host_v2.c
@@ -29,6 +29,7 @@
 #define DSI_POLL_SLEEP_US 1000
 #define DSI_POLL_TIMEOUT_US 16000
 #define DSI_ESC_CLK_RATE 19200000
+#define DSI_DMA_CMD_TIMEOUT_MS 200
 
 struct dsi_host_v2_private {
 	struct completion dma_comp;
@@ -426,18 +427,15 @@
 
 	dsi_ctrl = MIPI_INP(ctrl_base + DSI_CTRL);
 	/*If Video enabled, Keep Video and Cmd mode ON */
-	if (dsi_ctrl & 0x02)
-		dsi_ctrl &= ~0x05;
-	else
-		dsi_ctrl &= ~0x07;
+
+
+	dsi_ctrl &= ~0x06;
 
 	if (mode == DSI_VIDEO_MODE) {
-		dsi_ctrl |= 0x03;
+		dsi_ctrl |= 0x02;
 		intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK;
 	} else {		/* command mode */
-		dsi_ctrl |= 0x05;
-		if (pdata->panel_info.type == MIPI_VIDEO_PANEL)
-			dsi_ctrl |= 0x02;
+		dsi_ctrl |= 0x04;
 
 		intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_ERROR_MASK |
 				DSI_INTR_CMD_MDP_DONE_MASK;
@@ -480,7 +478,7 @@
 
 int msm_dsi_cmd_dma_tx(struct dsi_buf *tp)
 {
-	int len;
+	int len, rc;
 	unsigned long size, addr;
 	unsigned char *ctrl_base = dsi_host_private->dsi_base;
 
@@ -505,12 +503,17 @@
 	MIPI_OUTP(ctrl_base + DSI_CMD_MODE_DMA_SW_TRIGGER, 0x01);
 	wmb();
 
-	wait_for_completion_interruptible(&dsi_host_private->dma_comp);
+	rc = wait_for_completion_timeout(&dsi_host_private->dma_comp,
+				msecs_to_jiffies(DSI_DMA_CMD_TIMEOUT_MS));
+	if (rc == 0) {
+		pr_err("DSI command transaction time out\n");
+		rc = -ETIME;
+	}
 
 	dma_unmap_single(&dsi_host_private->dis_dev, tp->dmap, size,
 			DMA_TO_DEVICE);
 	tp->dmap = 0;
-	return 0;
+	return rc;
 }
 
 int msm_dsi_cmd_dma_rx(struct dsi_buf *rp, int rlen)
@@ -723,6 +726,7 @@
 
 static int msm_dsi_cal_clk_rate(struct mdss_panel_data *pdata,
 				u32 *bitclk_rate,
+				u32 *dsiclk_rate,
 				u32 *byteclk_rate,
 				u32 *pclk_rate)
 {
@@ -761,10 +765,11 @@
 	*bitclk_rate /= lanes;
 
 	*byteclk_rate = *bitclk_rate / 8;
+	*dsiclk_rate = *byteclk_rate * lanes;
 	*pclk_rate = *byteclk_rate * lanes * 8 / pdata->panel_info.bpp;
 
-	pr_debug("bitclk=%u, byteclk=%u, pck_=%u\n",
-		*bitclk_rate, *byteclk_rate, *pclk_rate);
+	pr_debug("dsiclk_rate=%u, byteclk=%u, pck_=%u\n",
+		*dsiclk_rate, *byteclk_rate, *pclk_rate);
 	return 0;
 }
 
@@ -777,7 +782,7 @@
 	u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height;
 	u32 ystride, bpp, data;
 	u32 dummy_xres, dummy_yres;
-	u32 bitclk_rate = 0, byteclk_rate = 0, pclk_rate = 0;
+	u32 bitclk_rate = 0, byteclk_rate = 0, pclk_rate = 0, dsiclk_rate = 0;
 	unsigned char *ctrl_base = dsi_host_private->dsi_base;
 
 	pr_debug("msm_dsi_on\n");
@@ -794,8 +799,10 @@
 	msm_dsi_phy_sw_reset(dsi_host_private->dsi_base);
 	msm_dsi_phy_init(dsi_host_private->dsi_base, pdata);
 
-	msm_dsi_cal_clk_rate(pdata, &bitclk_rate, &byteclk_rate, &pclk_rate);
-	msm_dsi_clk_set_rate(DSI_ESC_CLK_RATE, byteclk_rate, pclk_rate);
+	msm_dsi_cal_clk_rate(pdata, &bitclk_rate, &dsiclk_rate,
+				&byteclk_rate, &pclk_rate);
+	msm_dsi_clk_set_rate(DSI_ESC_CLK_RATE, dsiclk_rate,
+				byteclk_rate, pclk_rate);
 	msm_dsi_prepare_clocks();
 	msm_dsi_clk_enable();
 
@@ -879,12 +886,11 @@
 	int ret = 0;
 
 	pr_debug("msm_dsi_off\n");
-	msm_dsi_clk_set_rate(0, 0, 0);
+	msm_dsi_controller_cfg(0);
+	msm_dsi_clk_set_rate(DSI_ESC_CLK_RATE, 0, 0, 0);
 	msm_dsi_clk_disable();
 	msm_dsi_unprepare_clocks();
 
-	/* disable DSI controller */
-	msm_dsi_controller_cfg(0);
 	msm_dsi_ahb_ctrl(0);
 
 	ret = msm_dsi_regulator_disable();
diff --git a/drivers/video/msm/mdss/dsi_io_v2.c b/drivers/video/msm/mdss/dsi_io_v2.c
index 0486c4c..93f2c76 100644
--- a/drivers/video/msm/mdss/dsi_io_v2.c
+++ b/drivers/video/msm/mdss/dsi_io_v2.c
@@ -29,6 +29,7 @@
 	struct clk *dsi_esc_clk;
 	struct clk *dsi_pixel_clk;
 	struct clk *dsi_ahb_clk;
+	struct clk *dsi_clk;
 	int msm_dsi_clk_on;
 	int msm_dsi_ahb_clk_on;
 };
@@ -97,6 +98,13 @@
 {
 	int rc = 0;
 
+	dsi_io_private->dsi_clk = clk_get(&dev->dev, "dsi_clk");
+	if (IS_ERR(dsi_io_private->dsi_clk)) {
+		pr_err("can't find dsi core_clk\n");
+		rc = PTR_ERR(dsi_io_private->dsi_clk);
+		dsi_io_private->dsi_clk = NULL;
+		return rc;
+	}
 	dsi_io_private->dsi_byte_clk = clk_get(&dev->dev, "byte_clk");
 	if (IS_ERR(dsi_io_private->dsi_byte_clk)) {
 		pr_err("can't find dsi byte_clk\n");
@@ -135,6 +143,10 @@
 
 void msm_dsi_clk_deinit(void)
 {
+	if (dsi_io_private->dsi_clk) {
+		clk_put(dsi_io_private->dsi_clk);
+		dsi_io_private->dsi_clk = NULL;
+	}
 	if (dsi_io_private->dsi_byte_clk) {
 		clk_put(dsi_io_private->dsi_byte_clk);
 		dsi_io_private->dsi_byte_clk = NULL;
@@ -156,6 +168,7 @@
 
 int msm_dsi_prepare_clocks(void)
 {
+	clk_prepare(dsi_io_private->dsi_clk);
 	clk_prepare(dsi_io_private->dsi_byte_clk);
 	clk_prepare(dsi_io_private->dsi_esc_clk);
 	clk_prepare(dsi_io_private->dsi_pixel_clk);
@@ -164,16 +177,24 @@
 
 int msm_dsi_unprepare_clocks(void)
 {
+	clk_unprepare(dsi_io_private->dsi_clk);
 	clk_unprepare(dsi_io_private->dsi_esc_clk);
 	clk_unprepare(dsi_io_private->dsi_byte_clk);
 	clk_unprepare(dsi_io_private->dsi_pixel_clk);
 	return 0;
 }
 
-int msm_dsi_clk_set_rate(unsigned long esc_rate, unsigned long byte_rate,
+int msm_dsi_clk_set_rate(unsigned long esc_rate,
+			unsigned long dsi_rate,
+			unsigned long byte_rate,
 			unsigned long pixel_rate)
 {
 	int rc;
+	rc = clk_set_rate(dsi_io_private->dsi_clk, dsi_rate);
+	if (rc) {
+		pr_err("dsi_esc_clk - clk_set_rate failed =%d\n", rc);
+		return rc;
+	}
 
 	rc = clk_set_rate(dsi_io_private->dsi_esc_clk, esc_rate);
 	if (rc) {
@@ -202,6 +223,7 @@
 		return 0;
 	}
 
+	clk_enable(dsi_io_private->dsi_clk);
 	clk_enable(dsi_io_private->dsi_esc_clk);
 	clk_enable(dsi_io_private->dsi_byte_clk);
 	clk_enable(dsi_io_private->dsi_pixel_clk);
@@ -217,6 +239,7 @@
 		return 0;
 	}
 
+	clk_disable(dsi_io_private->dsi_clk);
 	clk_disable(dsi_io_private->dsi_byte_clk);
 	clk_disable(dsi_io_private->dsi_esc_clk);
 	clk_disable(dsi_io_private->dsi_pixel_clk);
@@ -246,7 +269,7 @@
 
 void msm_dsi_regulator_deinit(void)
 {
-	if (dsi_io_private->vdda_vreg) {
+	if (!IS_ERR(dsi_io_private->vdda_vreg)) {
 		devm_regulator_put(dsi_io_private->vdda_vreg);
 		dsi_io_private->vdda_vreg = NULL;
 	}
diff --git a/drivers/video/msm/mdss/dsi_io_v2.h b/drivers/video/msm/mdss/dsi_io_v2.h
index 25ecd7f..285bf30 100644
--- a/drivers/video/msm/mdss/dsi_io_v2.h
+++ b/drivers/video/msm/mdss/dsi_io_v2.h
@@ -29,7 +29,9 @@
 
 int msm_dsi_unprepare_clocks(void);
 
-int msm_dsi_clk_set_rate(unsigned long esc_rate, unsigned long byte_rate,
+int msm_dsi_clk_set_rate(unsigned long esc_rate,
+			unsigned long dsi_rate,
+			unsigned long byte_rate,
 			unsigned long pixel_rate);
 
 int msm_dsi_clk_enable(void);
diff --git a/drivers/video/msm/mdss/dsi_panel_v2.c b/drivers/video/msm/mdss/dsi_panel_v2.c
index 6686de3..e46ea3b 100644
--- a/drivers/video/msm/mdss/dsi_panel_v2.c
+++ b/drivers/video/msm/mdss/dsi_panel_v2.c
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/leds.h>
+#include <linux/err.h>
 #include <linux/regulator/consumer.h>
 
 #include "dsi_v2.h"
@@ -32,6 +33,7 @@
 
 	int rst_gpio;
 	int disp_en_gpio;
+	int video_mode_gpio;
 	char bl_ctrl;
 
 	struct regulator *vddio_vreg;
@@ -40,6 +42,9 @@
 	struct dsi_panel_cmds_list *on_cmds_list;
 	struct dsi_panel_cmds_list *off_cmds_list;
 	struct mdss_dsi_phy_ctrl phy_params;
+
+	char *on_cmds;
+	char *off_cmds;
 };
 
 static struct dsi_panel_private *panel_private;
@@ -82,15 +87,54 @@
 	kfree(panel_private->dsi_panel_tx_buf.start);
 	kfree(panel_private->dsi_panel_rx_buf.start);
 
-	if (panel_private->vddio_vreg)
+	if (!IS_ERR(panel_private->vddio_vreg))
 		devm_regulator_put(panel_private->vddio_vreg);
 
-	if (panel_private->vdda_vreg)
-		devm_regulator_put(panel_private->vddio_vreg);
+	if (!IS_ERR(panel_private->vdda_vreg))
+		devm_regulator_put(panel_private->vdda_vreg);
 
+	if (panel_private->on_cmds_list) {
+		kfree(panel_private->on_cmds_list->buf);
+		kfree(panel_private->on_cmds_list);
+	}
+	if (panel_private->off_cmds_list) {
+		kfree(panel_private->off_cmds_list->buf);
+		kfree(panel_private->off_cmds_list);
+	}
+
+	kfree(panel_private->on_cmds);
+	kfree(panel_private->off_cmds);
 	kfree(panel_private);
 	panel_private = NULL;
 }
+int dsi_panel_power(int enable)
+{
+	int ret;
+	if (enable) {
+		ret = regulator_enable(panel_private->vddio_vreg);
+		if (ret) {
+			pr_err("dsi_panel_power regulator enable vddio fail\n");
+			return ret;
+		}
+		ret = regulator_enable(panel_private->vdda_vreg);
+		if (ret) {
+			pr_err("dsi_panel_power regulator enable vdda fail\n");
+			return ret;
+		}
+	} else {
+		ret = regulator_disable(panel_private->vddio_vreg);
+		if (ret) {
+			pr_err("dsi_panel_power regulator disable vddio fail\n");
+			return ret;
+		}
+		ret = regulator_disable(panel_private->vdda_vreg);
+		if (ret) {
+			pr_err("dsi_panel_power regulator dsiable vdda fail\n");
+			return ret;
+		}
+	}
+	return 0;
+}
 
 void dsi_panel_reset(struct mdss_panel_data *pdata, int enable)
 {
@@ -113,6 +157,8 @@
 	pr_debug("%s: enable = %d\n", __func__, enable);
 
 	if (enable) {
+		dsi_panel_power(1);
+		gpio_request(panel_private->rst_gpio, "panel_reset");
 		gpio_set_value(panel_private->rst_gpio, 1);
 		/*
 		 * these delay values are by experiments currently, will need
@@ -123,12 +169,34 @@
 		udelay(200);
 		gpio_set_value(panel_private->rst_gpio, 1);
 		msleep(20);
-		if (gpio_is_valid(panel_private->disp_en_gpio))
+		if (gpio_is_valid(panel_private->disp_en_gpio)) {
+			gpio_request(panel_private->disp_en_gpio,
+					"panel_enable");
 			gpio_set_value(panel_private->disp_en_gpio, 1);
+		}
+		if (gpio_is_valid(panel_private->video_mode_gpio)) {
+			gpio_request(panel_private->video_mode_gpio,
+					"panel_video_mdoe");
+			if (pdata->panel_info.mipi.mode == DSI_VIDEO_MODE)
+				gpio_set_value(panel_private->video_mode_gpio,
+						1);
+			else
+				gpio_set_value(panel_private->video_mode_gpio,
+						0);
+		}
 	} else {
 		gpio_set_value(panel_private->rst_gpio, 0);
-		if (gpio_is_valid(panel_private->disp_en_gpio))
+		gpio_free(panel_private->rst_gpio);
+
+		if (gpio_is_valid(panel_private->disp_en_gpio)) {
 			gpio_set_value(panel_private->disp_en_gpio, 0);
+			gpio_free(panel_private->disp_en_gpio);
+		}
+
+		if (gpio_is_valid(panel_private->video_mode_gpio))
+			gpio_free(panel_private->video_mode_gpio);
+
+		dsi_panel_power(0);
 	}
 }
 
@@ -196,13 +264,42 @@
 	panel_private->disp_en_gpio = of_get_named_gpio(np,
 						"qcom,enable-gpio", 0);
 	panel_private->rst_gpio = of_get_named_gpio(np, "qcom,rst-gpio", 0);
+	panel_private->video_mode_gpio = of_get_named_gpio(np,
+						"qcom,mode-selection-gpio", 0);
 	return 0;
 }
 
 static int dsi_panel_parse_regulator(struct platform_device *pdev)
 {
+	int ret;
 	panel_private->vddio_vreg = devm_regulator_get(&pdev->dev, "vddio");
+	if (IS_ERR(panel_private->vddio_vreg)) {
+		pr_err("%s: could not get vddio vreg, rc=%ld\n",
+			__func__, PTR_ERR(panel_private->vddio_vreg));
+		return PTR_ERR(panel_private->vddio_vreg);
+	}
+	ret = regulator_set_voltage(panel_private->vddio_vreg,
+					1800000,
+					1800000);
+	if (ret) {
+		pr_err("%s: set voltage failed on vddio_vreg, rc=%d\n",
+			__func__, ret);
+		return ret;
+	}
 	panel_private->vdda_vreg = devm_regulator_get(&pdev->dev, "vdda");
+	if (IS_ERR(panel_private->vdda_vreg)) {
+		pr_err("%s: could not get vdda_vreg , rc=%ld\n",
+			__func__, PTR_ERR(panel_private->vdda_vreg));
+		return PTR_ERR(panel_private->vdda_vreg);
+	}
+	ret = regulator_set_voltage(panel_private->vdda_vreg,
+					2850000,
+					2850000);
+	if (ret) {
+		pr_err("%s: set voltage failed on vdda_vreg, rc=%d\n",
+			__func__, ret);
+		return ret;
+	}
 	return 0;
 }
 
@@ -398,180 +495,163 @@
 	int cmd_plen, data_offset;
 	const char *data;
 	const char *on_cmds_state, *off_cmds_state;
-	char *on_cmds = NULL, *off_cmds = NULL;
 	int num_of_on_cmds = 0, num_of_off_cmds = 0;
 
 	data = of_get_property(np, "qcom,panel-on-cmds", &len);
 	if (!data) {
 		pr_err("%s:%d, Unable to read ON cmds", __func__, __LINE__);
-		goto parse_init_cmds_error;
+		return -EINVAL;
 	}
 
-	on_cmds = kzalloc(sizeof(char) * len, GFP_KERNEL);
-	if (!on_cmds)
-		goto parse_init_cmds_error;
+	panel_private->on_cmds = kzalloc(sizeof(char) * len, GFP_KERNEL);
+	if (!panel_private->on_cmds)
+		return -ENOMEM;
 
-	memcpy(on_cmds, data, len);
+	memcpy(panel_private->on_cmds, data, len);
 
 	data_offset = 0;
 	cmd_plen = 0;
 	while ((len - data_offset) >= DT_CMD_HDR) {
 		data_offset += (DT_CMD_HDR - 1);
-		cmd_plen = on_cmds[data_offset++];
+		cmd_plen = panel_private->on_cmds[data_offset++];
 		data_offset += cmd_plen;
 		num_of_on_cmds++;
 	}
 	if (!num_of_on_cmds) {
 		pr_err("%s:%d, No ON cmds specified", __func__, __LINE__);
-		goto parse_init_cmds_error;
+		return -EINVAL;
 	}
 
-	panel_data->dsi_panel_on_cmds =
+	panel_private->on_cmds_list =
 		kzalloc(sizeof(struct dsi_panel_cmds_list), GFP_KERNEL);
-	if (!panel_data->dsi_panel_on_cmds)
-		goto parse_init_cmds_error;
+	if (!panel_private->on_cmds_list)
+		return -ENOMEM;
 
-	(panel_data->dsi_panel_on_cmds)->buf =
+	panel_private->on_cmds_list->buf =
 		kzalloc((num_of_on_cmds * sizeof(struct dsi_cmd_desc)),
 			GFP_KERNEL);
-	if (!(panel_data->dsi_panel_on_cmds)->buf)
-		goto parse_init_cmds_error;
+	if (!panel_private->on_cmds_list->buf)
+		return -ENOMEM;
 
 	data_offset = 0;
 	for (i = 0; i < num_of_on_cmds; i++) {
-		panel_data->dsi_panel_on_cmds->buf[i].dtype =
-						on_cmds[data_offset++];
-		panel_data->dsi_panel_on_cmds->buf[i].last =
-						on_cmds[data_offset++];
-		panel_data->dsi_panel_on_cmds->buf[i].vc =
-						on_cmds[data_offset++];
-		panel_data->dsi_panel_on_cmds->buf[i].ack =
-						on_cmds[data_offset++];
-		panel_data->dsi_panel_on_cmds->buf[i].wait =
-						on_cmds[data_offset++];
-		panel_data->dsi_panel_on_cmds->buf[i].dlen =
-						on_cmds[data_offset++];
-		panel_data->dsi_panel_on_cmds->buf[i].payload =
-						&on_cmds[data_offset];
-		data_offset += (panel_data->dsi_panel_on_cmds->buf[i].dlen);
+		panel_private->on_cmds_list->buf[i].dtype =
+					panel_private->on_cmds[data_offset++];
+		panel_private->on_cmds_list->buf[i].last =
+					panel_private->on_cmds[data_offset++];
+		panel_private->on_cmds_list->buf[i].vc =
+					panel_private->on_cmds[data_offset++];
+		panel_private->on_cmds_list->buf[i].ack =
+					panel_private->on_cmds[data_offset++];
+		panel_private->on_cmds_list->buf[i].wait =
+					panel_private->on_cmds[data_offset++];
+		panel_private->on_cmds_list->buf[i].dlen =
+					panel_private->on_cmds[data_offset++];
+		panel_private->on_cmds_list->buf[i].payload =
+					&panel_private->on_cmds[data_offset];
+		data_offset += (panel_private->on_cmds_list->buf[i].dlen);
 	}
 
 	if (data_offset != len) {
 		pr_err("%s:%d, Incorrect ON command entries",
 						__func__, __LINE__);
-		goto parse_init_cmds_error;
+		return -EINVAL;
 	}
 
-	(panel_data->dsi_panel_on_cmds)->size = num_of_on_cmds;
+	panel_private->on_cmds_list->size = num_of_on_cmds;
 
 	on_cmds_state = of_get_property(pdev->dev.of_node,
 					"qcom,on-cmds-dsi-state", NULL);
 	if (!strncmp(on_cmds_state, "DSI_LP_MODE", 11)) {
-		(panel_data->dsi_panel_on_cmds)->ctrl_state = DSI_LP_MODE;
+		panel_private->on_cmds_list->ctrl_state = DSI_LP_MODE;
 	} else if (!strncmp(on_cmds_state, "DSI_HS_MODE", 11)) {
-		(panel_data->dsi_panel_on_cmds)->ctrl_state = DSI_HS_MODE;
+		panel_private->on_cmds_list->ctrl_state = DSI_HS_MODE;
 	} else {
 		pr_debug("%s: ON cmds state not specified. Set Default\n",
 							__func__);
-		(panel_data->dsi_panel_on_cmds)->ctrl_state = DSI_LP_MODE;
+		panel_private->on_cmds_list->ctrl_state = DSI_LP_MODE;
 	}
 
-	panel_private->on_cmds_list = panel_data->dsi_panel_on_cmds;
+	panel_data->dsi_panel_on_cmds = panel_private->on_cmds_list;
+
 	data = of_get_property(np, "qcom,panel-off-cmds", &len);
 	if (!data) {
 		pr_err("%s:%d, Unable to read OFF cmds", __func__, __LINE__);
-		goto parse_init_cmds_error;
+		return -EINVAL;
 	}
 
-	off_cmds = kzalloc(sizeof(char) * len, GFP_KERNEL);
-	if (!off_cmds)
-		goto parse_init_cmds_error;
+	panel_private->off_cmds = kzalloc(sizeof(char) * len, GFP_KERNEL);
+	if (!panel_private->off_cmds)
+		return -ENOMEM;
 
-	memcpy(off_cmds, data, len);
+	memcpy(panel_private->off_cmds, data, len);
 
 	data_offset = 0;
 	cmd_plen = 0;
 	while ((len - data_offset) >= DT_CMD_HDR) {
 		data_offset += (DT_CMD_HDR - 1);
-		cmd_plen = off_cmds[data_offset++];
+		cmd_plen = panel_private->off_cmds[data_offset++];
 		data_offset += cmd_plen;
 		num_of_off_cmds++;
 	}
 	if (!num_of_off_cmds) {
 		pr_err("%s:%d, No OFF cmds specified", __func__, __LINE__);
-		goto parse_init_cmds_error;
+		return -ENOMEM;
 	}
 
-	panel_data->dsi_panel_off_cmds =
+	panel_private->off_cmds_list =
 		kzalloc(sizeof(struct dsi_panel_cmds_list), GFP_KERNEL);
-	if (!panel_data->dsi_panel_off_cmds)
-		goto parse_init_cmds_error;
+	if (!panel_private->off_cmds_list)
+		return -ENOMEM;
 
-	(panel_data->dsi_panel_off_cmds)->buf = kzalloc(num_of_off_cmds
+	panel_private->off_cmds_list->buf = kzalloc(num_of_off_cmds
 					* sizeof(struct dsi_cmd_desc),
 						GFP_KERNEL);
-	if (!(panel_data->dsi_panel_off_cmds)->buf)
-		goto parse_init_cmds_error;
+	if (!panel_private->off_cmds_list->buf)
+		return -ENOMEM;
 
 	data_offset = 0;
 	for (i = 0; i < num_of_off_cmds; i++) {
-		panel_data->dsi_panel_off_cmds->buf[i].dtype =
-						off_cmds[data_offset++];
-		panel_data->dsi_panel_off_cmds->buf[i].last =
-						off_cmds[data_offset++];
-		panel_data->dsi_panel_off_cmds->buf[i].vc =
-						off_cmds[data_offset++];
-		panel_data->dsi_panel_off_cmds->buf[i].ack =
-						off_cmds[data_offset++];
-		panel_data->dsi_panel_off_cmds->buf[i].wait =
-						off_cmds[data_offset++];
-		panel_data->dsi_panel_off_cmds->buf[i].dlen =
-						off_cmds[data_offset++];
-		panel_data->dsi_panel_off_cmds->buf[i].payload =
-						&off_cmds[data_offset];
-		data_offset += (panel_data->dsi_panel_off_cmds->buf[i].dlen);
+		panel_private->off_cmds_list->buf[i].dtype =
+					panel_private->off_cmds[data_offset++];
+		panel_private->off_cmds_list->buf[i].last =
+					panel_private->off_cmds[data_offset++];
+		panel_private->off_cmds_list->buf[i].vc =
+					panel_private->off_cmds[data_offset++];
+		panel_private->off_cmds_list->buf[i].ack =
+					panel_private->off_cmds[data_offset++];
+		panel_private->off_cmds_list->buf[i].wait =
+					panel_private->off_cmds[data_offset++];
+		panel_private->off_cmds_list->buf[i].dlen =
+					panel_private->off_cmds[data_offset++];
+		panel_private->off_cmds_list->buf[i].payload =
+					&panel_private->off_cmds[data_offset];
+		data_offset += (panel_private->off_cmds_list->buf[i].dlen);
 	}
 
 	if (data_offset != len) {
 		pr_err("%s:%d, Incorrect OFF command entries",
 						__func__, __LINE__);
-		goto parse_init_cmds_error;
+		return -EINVAL;
 	}
 
-	(panel_data->dsi_panel_off_cmds)->size = num_of_off_cmds;
-			off_cmds_state = of_get_property(pdev->dev.of_node,
+	panel_private->off_cmds_list->size = num_of_off_cmds;
+	off_cmds_state = of_get_property(pdev->dev.of_node,
 				"qcom,off-cmds-dsi-state", NULL);
 	if (!strncmp(off_cmds_state, "DSI_LP_MODE", 11)) {
-		(panel_data->dsi_panel_off_cmds)->ctrl_state =
+		panel_private->off_cmds_list->ctrl_state =
 						DSI_LP_MODE;
 	} else if (!strncmp(off_cmds_state, "DSI_HS_MODE", 11)) {
-		(panel_data->dsi_panel_off_cmds)->ctrl_state = DSI_HS_MODE;
+		panel_private->off_cmds_list->ctrl_state = DSI_HS_MODE;
 	} else {
 		pr_debug("%s: ON cmds state not specified. Set Default\n",
 							__func__);
-		(panel_data->dsi_panel_off_cmds)->ctrl_state = DSI_LP_MODE;
+		panel_private->off_cmds_list->ctrl_state = DSI_LP_MODE;
 	}
 
-	panel_private->off_cmds_list = panel_data->dsi_panel_on_cmds;
-	kfree(on_cmds);
-	kfree(off_cmds);
+	panel_data->dsi_panel_off_cmds = panel_private->off_cmds_list;
 
 	return 0;
-parse_init_cmds_error:
-	if (panel_data->dsi_panel_on_cmds) {
-		kfree((panel_data->dsi_panel_on_cmds)->buf);
-		kfree(panel_data->dsi_panel_on_cmds);
-		panel_data->dsi_panel_on_cmds = NULL;
-	}
-	if (panel_data->dsi_panel_off_cmds) {
-		kfree((panel_data->dsi_panel_off_cmds)->buf);
-		kfree(panel_data->dsi_panel_off_cmds);
-		panel_data->dsi_panel_off_cmds = NULL;
-	}
-
-	kfree(on_cmds);
-	kfree(off_cmds);
-	return -EINVAL;
 }
 
 static int dsi_panel_parse_backlight(struct platform_device *pdev,
@@ -709,6 +789,7 @@
 
 	vendor_pdata.on = dsi_panel_on;
 	vendor_pdata.off = dsi_panel_off;
+	vendor_pdata.reset = dsi_panel_reset;
 	vendor_pdata.bl_fnc = dsi_panel_bl_ctrl;
 
 	rc = dsi_panel_device_register_v2(pdev, &vendor_pdata,
diff --git a/drivers/video/msm/mdss/dsi_v2.c b/drivers/video/msm/mdss/dsi_v2.c
index 5e46bf5..5833796 100644
--- a/drivers/video/msm/mdss/dsi_v2.c
+++ b/drivers/video/msm/mdss/dsi_v2.c
@@ -29,6 +29,14 @@
 	if (!panel_common_data || !pdata)
 		return -ENODEV;
 
+	if (dsi_intf.op_mode_config)
+		dsi_intf.op_mode_config(DSI_CMD_MODE, pdata);
+
+	pr_debug("panel off commands\n");
+	if (panel_common_data->off)
+		panel_common_data->off(pdata);
+
+	pr_debug("turn off dsi controller\n");
 	if (dsi_intf.off)
 		rc = dsi_intf.off(pdata);
 
@@ -37,9 +45,9 @@
 		return rc;
 	}
 
-	pr_debug("dsi_off reset\n");
-	if (panel_common_data->off)
-		panel_common_data->off(pdata);
+	pr_debug("turn off panel power\n");
+	if (panel_common_data->reset)
+		panel_common_data->reset(pdata, 0);
 
 	return rc;
 }
@@ -53,8 +61,6 @@
 	if (!panel_common_data || !pdata)
 		return -ENODEV;
 
-	if (panel_common_data->reset)
-		panel_common_data->reset(1);
 
 	pr_debug("dsi_on DSI controller ont\n");
 	if (dsi_intf.on)
@@ -64,6 +70,9 @@
 		pr_err("mdss_dsi_on DSI failed %d\n", rc);
 		return rc;
 	}
+	pr_debug("dsi_on power on panel\n");
+	if (panel_common_data->reset)
+		panel_common_data->reset(pdata, 1);
 
 	pr_debug("dsi_on DSI panel ont\n");
 	if (panel_common_data->on)
diff --git a/drivers/video/msm/mdss/dsi_v2.h b/drivers/video/msm/mdss/dsi_v2.h
index fa868ab..f68527c 100644
--- a/drivers/video/msm/mdss/dsi_v2.h
+++ b/drivers/video/msm/mdss/dsi_v2.h
@@ -189,7 +189,7 @@
 	struct mdss_panel_info panel_info;
 	int (*on) (struct mdss_panel_data *pdata);
 	int (*off) (struct mdss_panel_data *pdata);
-	void (*reset)(int enable);
+	void (*reset)(struct mdss_panel_data *pdata, int enable);
 	void (*bl_fnc) (struct mdss_panel_data *pdata, u32 bl_level);
 	struct dsi_panel_cmds_list *dsi_panel_on_cmds;
 	struct dsi_panel_cmds_list *dsi_panel_off_cmds;
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 890b00b..52243eb 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -47,7 +47,7 @@
 #include "mdp3_hwio.h"
 #include "mdp3_ctrl.h"
 
-#define MDP_CORE_HW_VERSION	0x03030304
+#define MDP_CORE_HW_VERSION	0x03040310
 struct mdp3_hw_resource *mdp3_res;
 
 #define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val)		\
@@ -302,16 +302,7 @@
 	return ret;
 }
 
-int mdp3_vsync_clk_enable(int enable)
-{
-	int ret = 0;
 
-	pr_debug("vsync clk enable=%d\n", enable);
-	mutex_lock(&mdp3_res->res_mutex);
-	mdp3_clk_update(MDP3_CLK_VSYNC, enable);
-	mutex_unlock(&mdp3_res->res_mutex);
-	return ret;
-}
 
 int mdp3_clk_set_rate(int clk_type, unsigned long clk_rate)
 {
@@ -400,6 +391,9 @@
 	if (rc)
 		return rc;
 
+	rc = mdp3_clk_register("dsi_clk", MDP3_CLK_DSI);
+	if (rc)
+		return rc;
 	return rc;
 }
 
@@ -409,6 +403,7 @@
 	clk_put(mdp3_res->clocks[MDP3_CLK_CORE]);
 	clk_put(mdp3_res->clocks[MDP3_CLK_VSYNC]);
 	clk_put(mdp3_res->clocks[MDP3_CLK_LCDC]);
+	clk_put(mdp3_res->clocks[MDP3_CLK_DSI]);
 }
 
 int mdp3_clk_enable(int enable)
@@ -421,6 +416,7 @@
 	rc = mdp3_clk_update(MDP3_CLK_AHB, enable);
 	rc |= mdp3_clk_update(MDP3_CLK_CORE, enable);
 	rc |= mdp3_clk_update(MDP3_CLK_VSYNC, enable);
+	rc |= mdp3_clk_update(MDP3_CLK_DSI, enable);
 	mutex_unlock(&mdp3_res->res_mutex);
 	return rc;
 }
@@ -577,12 +573,14 @@
 	int rc;
 
 	rc = mdp3_clk_update(MDP3_CLK_AHB, 1);
+	rc |= mdp3_clk_update(MDP3_CLK_CORE, 1);
 	if (rc)
 		return rc;
 
 	mdp3_res->mdp_rev = MDP3_REG_READ(MDP3_REG_HW_VERSION);
 
 	rc = mdp3_clk_update(MDP3_CLK_AHB, 0);
+	rc |= mdp3_clk_update(MDP3_CLK_CORE, 0);
 	if (rc)
 		pr_err("fail to turn off the MDP3_CLK_AHB clk\n");
 
diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h
index c853664..5774e5a 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -29,6 +29,7 @@
 	MDP3_CLK_CORE,
 	MDP3_CLK_VSYNC,
 	MDP3_CLK_LCDC,
+	MDP3_CLK_DSI,
 	MDP3_MAX_CLK
 };
 
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index e07c0a4..99b7604 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -28,7 +28,7 @@
 
 void vsync_notify_handler(void *arg)
 {
-	struct mdp3_session_data *session = (struct mdp3_session_data *)session;
+	struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
 	complete(&session->vsync_comp);
 }
 
@@ -100,18 +100,30 @@
 	.attrs = vsync_fs_attrs,
 };
 
-static int mdp3_ctrl_res_req_dma(struct msm_fb_data_type *mfd, int status)
+static int mdp3_ctrl_res_req_bus(struct msm_fb_data_type *mfd, int status)
 {
 	int rc = 0;
 	if (status) {
 		struct mdss_panel_info *panel_info = mfd->panel_info;
 		int ab = 0;
 		int ib = 0;
-		unsigned long core_clk = 0;
-		int vtotal = 0;
 		ab = panel_info->xres * panel_info->yres * 4;
 		ab *= panel_info->mipi.frame_rate;
 		ib = (ab * 3) / 2;
+		rc = mdp3_bus_scale_set_quota(MDP3_BW_CLIENT_DMA_P, ab, ib);
+	} else {
+		rc = mdp3_bus_scale_set_quota(MDP3_BW_CLIENT_DMA_P, 0, 0);
+	}
+	return rc;
+}
+
+static int mdp3_ctrl_res_req_clk(struct msm_fb_data_type *mfd, int status)
+{
+	int rc = 0;
+	if (status) {
+		struct mdss_panel_info *panel_info = mfd->panel_info;
+		unsigned long core_clk;
+		int vtotal;
 		vtotal = panel_info->lcdc.v_back_porch +
 			panel_info->lcdc.v_front_porch +
 			panel_info->lcdc.v_pulse_width +
@@ -126,10 +138,8 @@
 		if (rc)
 			return rc;
 
-		mdp3_bus_scale_set_quota(MDP3_BW_CLIENT_DMA_P, ab, ib);
 	} else {
 		rc = mdp3_clk_enable(false);
-		rc |= mdp3_bus_scale_set_quota(MDP3_BW_CLIENT_DMA_P, 0, 0);
 	}
 	return rc;
 }
@@ -285,13 +295,25 @@
 	}
 	mutex_lock(&mdp3_session->lock);
 	if (mdp3_session->status) {
-		pr_info("fb%d is on already", mfd->index);
+		pr_debug("fb%d is on already", mfd->index);
 		goto on_error;
 	}
 
-	rc = mdp3_ctrl_res_req_dma(mfd, 1);
+	/* request bus bandwidth before DSI DMA traffic */
+	rc = mdp3_ctrl_res_req_bus(mfd, 1);
+	if (rc)
+		pr_err("fail to request bus resource\n");
+
+	panel = mdp3_session->panel;
+	if (panel->event_handler)
+		rc = panel->event_handler(panel, MDSS_EVENT_PANEL_ON, NULL);
 	if (rc) {
-		pr_err("resource request for dma on failed\n");
+		pr_err("fail to turn on the panel\n");
+		goto on_error;
+	}
+	rc = mdp3_ctrl_res_req_clk(mfd, 1);
+	if (rc) {
+		pr_err("fail to request mdp clk resource\n");
 		goto on_error;
 	}
 
@@ -304,16 +326,9 @@
 	rc = mdp3_ctrl_intf_init(mfd, mdp3_session->intf);
 	if (rc) {
 		pr_err("display interface init failed\n");
-		goto on_error;
-	}
 
-	panel = mdp3_session->panel;
 
-	if (panel->event_handler)
-		rc = panel->event_handler(panel, MDSS_EVENT_PANEL_ON, NULL);
 
-	if (rc) {
-		pr_err("fail to turn on the panel\n");
 		goto on_error;
 	}
 
@@ -348,26 +363,31 @@
 	mutex_lock(&mdp3_session->lock);
 
 	if (!mdp3_session->status) {
-		pr_info("fb%d is off already", mfd->index);
+		pr_debug("fb%d is off already", mfd->index);
 		goto off_error;
 	}
 
-	panel = mdp3_session->panel;
-	if (panel->event_handler)
-		rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
-
-	if (rc)
-		pr_err("fail to turn off the panel\n");
+	pr_debug("mdp3_ctrl_off stop mdp3 dma engine\n");
 
 	rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
 
 	if (rc)
 		pr_err("fail to stop the MDP3 dma\n");
 
-	rc = mdp3_ctrl_res_req_dma(mfd, 0);
+	pr_debug("mdp3_ctrl_off stop dsi panel and controller\n");
+	panel = mdp3_session->panel;
+	if (panel->event_handler)
+		rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
 	if (rc)
-		pr_err("resource release  for dma on failed\n");
+		pr_err("fail to turn off the panel\n");
 
+	pr_debug("mdp3_ctrl_off release bus and clock\n");
+	rc = mdp3_ctrl_res_req_bus(mfd, 0);
+	if (rc)
+		pr_err("mdp bus resource release failed\n");
+	rc = mdp3_ctrl_res_req_clk(mfd, 0);
+	if (rc)
+		pr_err("mdp clock resource release failed\n");
 off_error:
 	mdp3_session->status = 0;
 
diff --git a/drivers/video/msm/mdss/mdss_qpic.c b/drivers/video/msm/mdss/mdss_qpic.c
index be02113..fa6bd3d 100644
--- a/drivers/video/msm/mdss/mdss_qpic.c
+++ b/drivers/video/msm/mdss/mdss_qpic.c
@@ -428,7 +428,7 @@
 					param[0]);
 				param++;
 				bytes_left -= 4;
-				space++;
+				space--;
 			} else if (bytes_left == 2) {
 				QPIC_OUTPW(QPIC_REG_QPIC_LCDC_FIFO_DATA_PORT0,
 					*(u16 *)param);