Merge "msm: SSR: Make subsystem restart into a bus" into msm-3.4
diff --git a/arch/arm/boot/dts/msm8974-camera.dtsi b/arch/arm/boot/dts/msm8974-camera.dtsi
index cf4f098..fd35103 100644
--- a/arch/arm/boot/dts/msm8974-camera.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera.dtsi
@@ -125,6 +125,7 @@
 		reg-names = "jpeg";
 		interrupts = <0 59 0>;
 		interrupt-names = "jpeg";
+                vdd-supply = <&gdsc_jpeg>;
 	};
 
 	qcom,jpeg@fda20000 {
@@ -134,6 +135,7 @@
 		reg-names = "jpeg";
 		interrupts = <0 60 0>;
 		interrupt-names = "jpeg";
+		vdd-supply = <&gdsc_jpeg>;
 	};
 
 	qcom,jpeg@fda24000 {
@@ -143,6 +145,7 @@
 		reg-names = "jpeg";
 		interrupts = <0 61 0>;
 		interrupt-names = "jpeg";
+		vdd-supply = <&gdsc_jpeg>;
 	};
 
 	qcom,irqrouter@fda00000 {
diff --git a/arch/arm/boot/dts/msm9625-cdp.dts b/arch/arm/boot/dts/msm9625-cdp.dts
new file mode 100644
index 0000000..6733f59
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-cdp.dts
@@ -0,0 +1,21 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625 CDP";
+	compatible = "qcom,msm9625-cdp", "qcom,msm9625";
+	qcom,msm-id = <134 1 0>;
+};
diff --git a/arch/arm/boot/dts/msm9625-mtp.dts b/arch/arm/boot/dts/msm9625-mtp.dts
new file mode 100644
index 0000000..32185dc
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-mtp.dts
@@ -0,0 +1,21 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625 MTP";
+	compatible = "qcom,msm9625-mtp", "qcom,msm9625";
+	qcom,msm-id = <134 8 0>;
+};
diff --git a/arch/arm/boot/dts/msm9625-rumi.dts b/arch/arm/boot/dts/msm9625-rumi.dts
new file mode 100644
index 0000000..e4fa000
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-rumi.dts
@@ -0,0 +1,21 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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.dtsi"
+
+/ {
+	model = "Qualcomm MSM 9625 RUMI";
+	compatible = "qcom,msm9625-rumi", "qcom,msm9625";
+	qcom,msm-id = <134 15 0>;
+};
diff --git a/arch/arm/boot/dts/msm9625.dts b/arch/arm/boot/dts/msm9625.dtsi
similarity index 99%
rename from arch/arm/boot/dts/msm9625.dts
rename to arch/arm/boot/dts/msm9625.dtsi
index 041b4dd..07233bb 100644
--- a/arch/arm/boot/dts/msm9625.dts
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -10,7 +10,6 @@
  * GNU General Public License for more details.
  */
 
-/dts-v1/;
 /include/ "skeleton.dtsi"
 
 / {
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 0a99036..09c341f 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -194,6 +194,7 @@
 # CONFIG_FB_MSM_BACKLIGHT is not set
 CONFIG_FB_MSM_MDSS=y
 CONFIG_FB_MSM_MDSS_WRITEBACK=y
+CONFIG_FB_MSM_MDSS_HDMI_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/mach-msm/adsp-8974.c b/arch/arm/mach-msm/adsp-8974.c
new file mode 100644
index 0000000..0ded432
--- /dev/null
+++ b/arch/arm/mach-msm/adsp-8974.c
@@ -0,0 +1,295 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/workqueue.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/err.h>
+
+#include <mach/irqs.h>
+#include <mach/scm.h>
+#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
+#include <mach/subsystem_notif.h>
+
+#include "smd_private.h"
+#include "ramdump.h"
+#include "sysmon.h"
+
+#define SCM_Q6_NMI_CMD			0x1
+#define MODULE_NAME			"adsp_8974"
+#define MAX_BUF_SIZE			0x51
+
+/* Subsystem restart: QDSP6 data, functions */
+static void lpass_fatal_fn(struct work_struct *);
+static DECLARE_WORK(lpass_fatal_work, lpass_fatal_fn);
+
+struct lpass_ssr {
+	void *lpass_ramdump_dev;
+} lpass_ssr;
+
+static struct lpass_ssr lpass_ssr_8974;
+static int q6_crash_shutdown;
+
+static int riva_notifier_cb(struct notifier_block *this, unsigned long code,
+								void *ss_handle)
+{
+	int ret;
+	switch (code) {
+	case SUBSYS_BEFORE_SHUTDOWN:
+		pr_debug("%s: R-Notify: Shutdown started\n", __func__);
+		ret = sysmon_send_event(SYSMON_SS_LPASS, "wcnss",
+				SUBSYS_BEFORE_SHUTDOWN);
+		if (ret < 0)
+			pr_err("%s: sysmon_send_event error %d", __func__,
+				ret);
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+static void *ssr_notif_hdle;
+static struct notifier_block rnb = {
+	.notifier_call = riva_notifier_cb,
+};
+
+static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
+								void *ss_handle)
+{
+	int ret;
+	switch (code) {
+	case SUBSYS_BEFORE_SHUTDOWN:
+		pr_debug("%s: M-Notify: Shutdown started\n", __func__);
+		ret = sysmon_send_event(SYSMON_SS_LPASS, "modem",
+				SUBSYS_BEFORE_SHUTDOWN);
+		if (ret < 0)
+			pr_err("%s: sysmon_send_event error %d", __func__,
+				ret);
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+static void *ssr_modem_notif_hdle;
+static struct notifier_block mnb = {
+	.notifier_call = modem_notifier_cb,
+};
+
+static void lpass_log_failure_reason(void)
+{
+	char *reason;
+	char buffer[MAX_BUF_SIZE];
+	unsigned size;
+
+	reason = smem_get_entry(SMEM_SSR_REASON_LPASS0, &size);
+
+	if (!reason) {
+		pr_err("%s: subsystem failure reason: (unknown, smem_get_entry failed).",
+			 MODULE_NAME);
+		return;
+	}
+
+	if (reason[0] == '\0') {
+		pr_err("%s: subsystem failure reason: (unknown, init value found)",
+			 MODULE_NAME);
+		return;
+	}
+
+	size = size < MAX_BUF_SIZE ? size : (MAX_BUF_SIZE-1);
+	memcpy(buffer, reason, size);
+	buffer[size] = '\0';
+	pr_err("%s: subsystem failure reason: %s", MODULE_NAME, buffer);
+	memset((void *)reason, 0x0, size);
+	wmb();
+}
+
+static void lpass_fatal_fn(struct work_struct *work)
+{
+	pr_err("%s %s: Watchdog bite received from Q6!\n", MODULE_NAME,
+		__func__);
+	lpass_log_failure_reason();
+	panic(MODULE_NAME ": Resetting the SoC");
+}
+
+static void lpass_smsm_state_cb(void *data, uint32_t old_state,
+				uint32_t new_state)
+{
+	/* Ignore if we're the one that set SMSM_RESET */
+	if (q6_crash_shutdown)
+		return;
+
+	if (new_state & SMSM_RESET) {
+		pr_debug("%s: LPASS SMSM state changed to SMSM_RESET, new_state= 0x%x, old_state = 0x%x\n",
+			 __func__, new_state, old_state);
+		lpass_log_failure_reason();
+		panic(MODULE_NAME ": Resetting the SoC");
+	}
+}
+
+static void send_q6_nmi(void)
+{
+	/* Send NMI to QDSP6 via an SCM call. */
+	scm_call_atomic1(SCM_SVC_UTIL, SCM_Q6_NMI_CMD, 0x1);
+	pr_debug("%s: Q6 NMI was sent.\n", __func__);
+}
+
+static int lpass_shutdown(const struct subsys_desc *subsys)
+{
+	send_q6_nmi();
+
+	/* The write needs to go through before the q6 is shutdown. */
+	mb();
+
+	pil_force_shutdown("q6");
+	disable_irq_nosync(LPASS_Q6SS_WDOG_EXPIRED);
+
+	return 0;
+}
+
+static int lpass_powerup(const struct subsys_desc *subsys)
+{
+	int ret;
+
+	if (get_restart_level() == RESET_SUBSYS_INDEPENDENT) {
+		pr_debug("%s: Wait for ADSP power up!", __func__);
+		msleep(10000);
+	}
+
+	ret = pil_force_boot("q6");
+	enable_irq(LPASS_Q6SS_WDOG_EXPIRED);
+	return ret;
+}
+/* RAM segments - address and size for 8974 */
+static struct ramdump_segment q6_segments[] = { {0x8da00000, 0x8f200000 -
+					0x8da00000}, {0x28400000, 0x20000} };
+static int lpass_ramdump(int enable, const struct subsys_desc *subsys)
+{
+	pr_debug("%s: enable[%d]\n", __func__, enable);
+	if (enable)
+		return do_ramdump(lpass_ssr_8974.lpass_ramdump_dev,
+				q6_segments,
+				ARRAY_SIZE(q6_segments));
+	else
+		return 0;
+}
+
+static void lpass_crash_shutdown(const struct subsys_desc *subsys)
+{
+	q6_crash_shutdown = 1;
+	send_q6_nmi();
+}
+
+static irqreturn_t lpass_wdog_bite_irq(int irq, void *dev_id)
+{
+	int ret;
+
+	pr_debug("%s: rxed irq[0x%x]", __func__, irq);
+	disable_irq_nosync(LPASS_Q6SS_WDOG_EXPIRED);
+	ret = schedule_work(&lpass_fatal_work);
+
+	return IRQ_HANDLED;
+}
+
+static struct subsys_device *lpass_8974_dev;
+
+static struct subsys_desc lpass_8974 = {
+	.name = "lpass",
+	.shutdown = lpass_shutdown,
+	.powerup = lpass_powerup,
+	.ramdump = lpass_ramdump,
+	.crash_shutdown = lpass_crash_shutdown
+};
+
+static int __init lpass_restart_init(void)
+{
+	lpass_8974_dev = subsys_register(&lpass_8974);
+	if (IS_ERR(lpass_8974_dev))
+		return PTR_ERR(lpass_8974_dev);
+	return 0;
+}
+
+static int __init lpass_fatal_init(void)
+{
+	int ret;
+
+	ret = smsm_state_cb_register(SMSM_Q6_STATE, SMSM_RESET,
+		lpass_smsm_state_cb, 0);
+
+	if (ret < 0)
+		pr_err("%s: Unable to register SMSM callback! (%d)\n",
+				__func__, ret);
+
+	ret = request_irq(LPASS_Q6SS_WDOG_EXPIRED, lpass_wdog_bite_irq,
+			IRQF_TRIGGER_RISING, "q6_wdog", NULL);
+
+	if (ret < 0) {
+		pr_err("%s: Unable to request LPASS_Q6SS_WDOG_EXPIRED irq.",
+			__func__);
+		goto out;
+	}
+	ret = lpass_restart_init();
+	if (ret < 0) {
+		pr_err("%s: Unable to reg with lpass ssr. (%d)\n",
+				__func__, ret);
+		goto out;
+	}
+
+	lpass_ssr_8974.lpass_ramdump_dev = create_ramdump_device("lpass");
+
+	if (!lpass_ssr_8974.lpass_ramdump_dev) {
+		pr_err("%s: Unable to create ramdump device.\n",
+				__func__);
+		ret = -ENOMEM;
+		goto out;
+	}
+	ssr_notif_hdle = subsys_notif_register_notifier("riva",
+							&rnb);
+	if (IS_ERR(ssr_notif_hdle) < 0) {
+		ret = PTR_ERR(ssr_notif_hdle);
+		pr_err("%s: subsys_register_notifier for Riva: err = %d\n",
+			__func__, ret);
+		free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
+		goto out;
+	}
+
+	ssr_modem_notif_hdle = subsys_notif_register_notifier("modem",
+							&mnb);
+	if (IS_ERR(ssr_modem_notif_hdle) < 0) {
+		ret = PTR_ERR(ssr_modem_notif_hdle);
+		pr_err("%s: subsys_register_notifier for Modem: err = %d\n",
+			__func__, ret);
+		subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+		free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
+		goto out;
+	}
+
+	pr_info("%s: lpass SSR driver init'ed.\n", __func__);
+out:
+	return ret;
+}
+
+static void __exit lpass_fatal_exit(void)
+{
+	subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+	subsys_notif_unregister_notifier(ssr_modem_notif_hdle, &mnb);
+	subsys_unregister(lpass_8974_dev);
+	free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
+}
+
+module_init(lpass_fatal_init);
+module_exit(lpass_fatal_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 47a5a08..2a02450 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -887,7 +887,7 @@
 };
 
 static int phy_init_seq[] = {
-	0x38, 0x81, /* update DC voltage level */
+	0x68, 0x81, /* update DC voltage level */
 	0x24, 0x82, /* set pre-emphasis and rise/fall time */
 	-1
 };
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 7760f07..61b9a73 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1451,7 +1451,7 @@
 static int hsusb_phy_init_seq[] = {
 	0x44, 0x80, /* set VBUS valid threshold
 			and disconnect valid threshold */
-	0x38, 0x81, /* update DC voltage level */
+	0x68, 0x81, /* update DC voltage level */
 	0x24, 0x82, /* set preemphasis and rise/fall time */
 	0x13, 0x83, /* set source impedance adjusment */
 	-1};
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index a3de539..2cd654c 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1434,7 +1434,7 @@
 static int wr_phy_init_seq[] = {
 	0x44, 0x80, /* set VBUS valid threshold
 			and disconnect valid threshold */
-	0x38, 0x81, /* update DC voltage level */
+	0x68, 0x81, /* update DC voltage level */
 	0x14, 0x82, /* set preemphasis and rise/fall time */
 	0x13, 0x83, /* set source impedance adjusment */
 	-1};
@@ -1442,7 +1442,7 @@
 static int liquid_v1_phy_init_seq[] = {
 	0x44, 0x80,/* set VBUS valid threshold
 			and disconnect valid threshold */
-	0x3C, 0x81,/* update DC voltage level */
+	0x6C, 0x81,/* update DC voltage level */
 	0x18, 0x82,/* set preemphasis and rise/fall time */
 	0x23, 0x83,/* set source impedance sdjusment */
 	-1};
@@ -1450,7 +1450,7 @@
 static int sglte_phy_init_seq[] = {
 	0x44, 0x80, /* set VBUS valid threshold
 			and disconnect valid threshold */
-	0x3A, 0x81, /* update DC voltage level */
+	0x6A, 0x81, /* update DC voltage level */
 	0x24, 0x82, /* set preemphasis and rise/fall time */
 	0x13, 0x83, /* set source impedance adjusment */
 	-1};
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index e599739..177577e 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -612,7 +612,7 @@
 static int shelby_phy_init_seq[] = {
 	0x44, 0x80,/* set VBUS valid threshold and
 			disconnect valid threshold */
-	0x38, 0x81, /* update DC voltage level */
+	0x68, 0x81, /* update DC voltage level */
 	0x24, 0x82,/* set preemphasis and rise/fall time */
 	0x13, 0x83,/* set source impedance adjustment */
 	-1};
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 357f0b7..e7f5b53 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -5173,17 +5173,36 @@
 	CLK_LOOKUP("bus_clk", camss_vfe_vfe_axi_clk.c,	 "fda14000.qcom,vfe"),
 	CLK_LOOKUP("alt_bus_clk", camss_vfe_vfe_ocmemnoc_clk.c,
 					"fda14000.qcom,vfe"),
-	CLK_LOOKUP("core_clk", camss_jpeg_jpeg0_clk.c, ""),
-	CLK_LOOKUP("core_clk", camss_jpeg_jpeg1_clk.c, ""),
-	CLK_LOOKUP("core_clk", camss_jpeg_jpeg2_clk.c, ""),
+	/*Jpeg Clocks*/
+	CLK_LOOKUP("core_clk", camss_jpeg_jpeg0_clk.c, "fda1c000.qcom,jpeg"),
+	CLK_LOOKUP("core_clk", camss_jpeg_jpeg1_clk.c, "fda20000.qcom,jpeg"),
+	CLK_LOOKUP("core_clk", camss_jpeg_jpeg2_clk.c, "fda24000.qcom,jpeg"),
+	CLK_LOOKUP("iface_clk", camss_jpeg_jpeg_ahb_clk.c,
+						"fda1c000.qcom,jpeg"),
+	CLK_LOOKUP("iface_clk", camss_jpeg_jpeg_ahb_clk.c,
+						"fda20000.qcom,jpeg"),
+	CLK_LOOKUP("iface_clk", camss_jpeg_jpeg_ahb_clk.c,
+						"fda24000.qcom,jpeg"),
 	CLK_LOOKUP("iface_clk", camss_jpeg_jpeg_ahb_clk.c,
 						"fda64000.qcom,iommu"),
 	CLK_LOOKUP("core_clk", camss_jpeg_jpeg_axi_clk.c,
 						"fda64000.qcom,iommu"),
-	CLK_LOOKUP("bus_clk", camss_jpeg_jpeg_axi_clk.c, ""),
-	CLK_LOOKUP("bus_clk", camss_jpeg_jpeg_ocmemnoc_clk.c, ""),
+	CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda1c000.qcom,jpeg"),
+	CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda20000.qcom,jpeg"),
+	CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda24000.qcom,jpeg"),
+	CLK_LOOKUP("alt_bus_clk", camss_jpeg_jpeg_ocmemnoc_clk.c,
+						"fda1c000.qcom,jpeg"),
+	CLK_LOOKUP("alt_bus_clk", camss_jpeg_jpeg_ocmemnoc_clk.c,
+						"fda20000.qcom,jpeg"),
+	CLK_LOOKUP("alt_bus_clk", camss_jpeg_jpeg_ocmemnoc_clk.c,
+						"fda24000.qcom,jpeg"),
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+						"fda1c000.qcom,jpeg"),
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+						"fda20000.qcom,jpeg"),
+	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+						"fda24000.qcom,jpeg"),
 	CLK_LOOKUP("iface_clk", camss_micro_ahb_clk.c, ""),
-	CLK_LOOKUP("iface_clk", camss_top_ahb_clk.c, ""),
 	CLK_LOOKUP("iface_clk", camss_vfe_cpp_ahb_clk.c, "fda44000.qcom,iommu"),
 	CLK_LOOKUP("core_clk", camss_vfe_cpp_clk.c, "fda44000.qcom,iommu"),
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdp.0"),
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index aac83e5..25723d5 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -129,7 +129,11 @@
 	pm8xxx_reset_pwr_off(0);
 
 	if (lower_pshold) {
-		__raw_writel(0, PSHOLD_CTL_SU);
+		if (!use_restart_v2())
+			__raw_writel(0, PSHOLD_CTL_SU);
+		else
+			__raw_writel(0, MSM_MPM2_PSHOLD_BASE);
+
 		mdelay(10000);
 		printk(KERN_ERR "Powering off has failed\n");
 	}
diff --git a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
index 1b029b1..7c2514b 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
@@ -178,15 +178,11 @@
 	priv->no_switch_cnt = 0;
 }
 
+#ifdef CONFIG_MSM_SCM
 static int tz_init(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale)
 {
 	struct tz_priv *priv;
 
-	/* Trustzone is only valid for some SOCs */
-	if (!(cpu_is_msm8x60() || cpu_is_msm8960() || cpu_is_apq8064() ||
-		cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627()))
-		return -EINVAL;
-
 	priv = pwrscale->priv = kzalloc(sizeof(struct tz_priv), GFP_KERNEL);
 	if (pwrscale->priv == NULL)
 		return -ENOMEM;
@@ -197,6 +193,12 @@
 
 	return 0;
 }
+#else
+static int tz_init(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale)
+{
+	return -EINVAL;
+}
+#endif /* CONFIG_MSM_SCM */
 
 static void tz_close(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale)
 {
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.c b/drivers/media/video/msm/vfe/msm_vfe40.c
index 1297379..e958241 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.c
+++ b/drivers/media/video/msm/vfe/msm_vfe40.c
@@ -806,7 +806,7 @@
 		vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_0);
 	msm_camera_io_w(0x800080,
 		vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_1);
-	msm_camera_io_w(0xFFFFF,
+	msm_camera_io_w(0x198FFFFF,
 		vfe40_ctrl->share_ctrl->vfebase + VFE_CGC_OVERRIDE);
 
 	msm_camera_io_w(0,
@@ -1289,6 +1289,12 @@
 			vfe40_ctrl->share_ctrl->vfebase +
 			VFE_REG_UPDATE_CMD);
 
+	msm_camera_io_w_mb(0x00003fff,
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_AXI_BUS_CMD_OFF);
+	msm_camera_io_w_mb(1,
+			vfe40_ctrl->share_ctrl->vfebase +
+			V40_BUS_PM_CMD);
 	if (vfe_operation_mode) {
 		msm_camera_io_w_mb(1, vfe40_ctrl->share_ctrl->vfebase +
 			VFE_CAMIF_COMMAND);
@@ -1345,8 +1351,6 @@
 	vfe40_ctrl->share_ctrl->start_ack_pending = TRUE;
 	vfe40_start_common(vfe40_ctrl);
 
-	msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase + 0x18C);
-	msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase + 0x188);
 	return 0;
 }
 static int vfe40_capture_raw(
@@ -1381,12 +1385,9 @@
 
 	vfe40_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
 
-	vfe40_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
 
 	vfe40_start_common(vfe40_ctrl);
 	/* for debug */
-	msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase + 0x18C);
-	msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase + 0x188);
 	return 0;
 }
 
@@ -1639,7 +1640,7 @@
 	outch = vfe40_get_ch(path, axi_ctrl->share_ctrl);
 	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
 		/* Configure Preview Ping Pong */
-		pr_info("%s Configure ping/pong address for %d",
+		pr_info("%s Configure ping/pong address for %d\n",
 						__func__, path);
 		vfe40_put_ch_ping_addr(
 			axi_ctrl->share_ctrl->vfebase, outch->ch0,
@@ -3153,7 +3154,6 @@
 		irq_mask &= ~(0x1 << (share_ctrl->outpath.out3.ch0 +
 			VFE_WM_OFFSET));
 	}
-
 	msm_camera_io_w_mb(reg_update,
 		share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
 	msm_camera_io_w(irq_mask, share_ctrl->vfebase +
@@ -3326,7 +3326,6 @@
 				msm_camera_io_w(0, share_ctrl->vfebase +
 					vfe40_AXI_WM_CFG[
 				share_ctrl->outpath.out0.ch1]);
-
 				share_ctrl->liveshot_state = VFE_STATE_STOPPED;
 				msm_camera_io_w_mb(1, share_ctrl->vfebase +
 				VFE_REG_UPDATE_CMD);
@@ -3387,11 +3386,10 @@
 				msm_camera_io_w_mb
 				(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
 					share_ctrl->vfebase +
-				VFE_CAMIF_COMMAND);
+					VFE_CAMIF_COMMAND);
 				vfe40_ctrl->snapshot_frame_cnt = -1;
 				vfe40_ctrl->frame_skip_cnt = 31;
-					vfe40_ctrl->frame_skip_pattern =
-								0xffffffff;
+				vfe40_ctrl->frame_skip_pattern = 0xffffffff;
 			} /*if snapshot count is 0*/
 		} /*if frame is not being dropped*/
 		vfe40_ctrl->snapshot_frame_cnt++;
@@ -3607,6 +3605,8 @@
 static void vfe40_process_common_error_irq(
 	struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
 {
+	if (errStatus & VFE40_IMASK_BUS_BDG_HALT_ACK)
+		pr_err("vfe40_irq: BUS BDG HALT ACK\n");
 
 	if (errStatus & VFE40_IMASK_IMG_MAST_0_BUS_OVFL)
 		pr_err("vfe40_irq: image master 0 bus overflow\n");
@@ -5455,9 +5455,14 @@
 
 	if (axi_ctrl->share_ctrl->outpath.output_mode &
 			VFE40_OUTPUT_MODE_PRIMARY) {
-		irq_comp_mask |= (
-			0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
-			0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1);
+		if (vfe_params.cmd_type == AXI_CMD_RAW_CAPTURE) {
+			irq_comp_mask |=
+				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0;
+		} else {
+			irq_comp_mask |= (
+				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
+				0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1);
+		}
 		irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
 	} else if (axi_ctrl->share_ctrl->outpath.output_mode &
 			   VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
@@ -5551,12 +5556,21 @@
 	default:
 		if (axi_ctrl->share_ctrl->outpath.output_mode &
 			VFE40_OUTPUT_MODE_PRIMARY) {
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch0]);
-			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
-				vfe40_AXI_WM_CFG[axi_ctrl->
-				share_ctrl->outpath.out0.ch1]);
+			if (vfe_params.cmd_type == AXI_CMD_RAW_CAPTURE) {
+				msm_camera_io_w(1,
+					axi_ctrl->share_ctrl->vfebase +
+					vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch0]);
+			} else {
+				msm_camera_io_w(1,
+					axi_ctrl->share_ctrl->vfebase +
+					vfe40_AXI_WM_CFG[axi_ctrl
+					->share_ctrl->outpath.out0.ch0]);
+				msm_camera_io_w(1,
+					axi_ctrl->share_ctrl->vfebase +
+					vfe40_AXI_WM_CFG[axi_ctrl->
+					share_ctrl->outpath.out0.ch1]);
+			}
 		} else if (axi_ctrl->share_ctrl->outpath.output_mode &
 				VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
 			msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
@@ -5592,6 +5606,7 @@
 		}
 		break;
 	}
+
 	if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
 		msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
 			vfe40_AXI_WM_CFG[axi_ctrl->share_ctrl->
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.h b/drivers/media/video/msm/vfe/msm_vfe40.h
index 5b73751..8201d18 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.h
+++ b/drivers/media/video/msm/vfe/msm_vfe40.h
@@ -204,6 +204,7 @@
 #define V40_AXI_OUT_LEN           344
 #define V40_AXI_CFG_LEN           71
 
+#define V40_BUS_PM_CMD            0x00000270
 #define V40_FOV_ENC_OFF           0x00000854
 #define V40_FOV_ENC_LEN           16
 #define V40_FOV_VIEW_OFF          0x00000864
@@ -719,7 +720,7 @@
 #define VFE40_IMASK_ERROR_ONLY_0  0x0
 /* when normal case, don't want to block error status. */
 /* bit 0-21 are error irq bits */
-#define VFE40_IMASK_COMMON_ERROR_ONLY_1       0x0000FE00
+#define VFE40_IMASK_COMMON_ERROR_ONLY_1       0x0000FF00
 #define VFE40_IMASK_VFE_ERROR_ONLY_1          0x00FF01FF
 #define VFE40_IMASK_CAMIF_ERROR               (0x00000001<<0)
 #define VFE40_IMASK_BHIST_OVWR                (0x00000001<<1)
@@ -729,6 +730,7 @@
 #define VFE40_IMASK_REALIGN_BUF_CB_OVFL       (0x00000001<<5)
 #define VFE40_IMASK_REALIGN_BUF_CR_OVFL       (0x00000001<<6)
 #define VFE40_IMASK_VIOLATION                 (0x00000001<<7)
+#define VFE40_IMASK_BUS_BDG_HALT_ACK          (0x00000001<<8)
 #define VFE40_IMASK_IMG_MAST_0_BUS_OVFL       (0x00000001<<9)
 #define VFE40_IMASK_IMG_MAST_1_BUS_OVFL       (0x00000001<<10)
 #define VFE40_IMASK_IMG_MAST_2_BUS_OVFL       (0x00000001<<11)
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index c0f8014..4939b64 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -674,6 +674,7 @@
 	unsigned long flags;
 	struct vb2_buf_entry *temp;
 	struct list_head *ptr, *next;
+	inst->in_reconfig = false;
 	rc = msm_comm_set_scratch_buffers(inst);
 	if (rc) {
 		pr_err("Failed to set scratch buffers: %d\n", rc);
@@ -786,62 +787,18 @@
 int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec)
 {
 	int rc = 0;
-	bool ip_flush = false,
-	     op_flush = false;
-
 	switch (dec->cmd) {
 	case V4L2_DEC_QCOM_CMD_FLUSH:
-		mutex_lock(&inst->sync_lock);
-		ip_flush = dec->flags & V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT;
-		op_flush = dec->flags & V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
-		/* Only support flush on decoder (for now)*/
-		if (inst->session_type == MSM_VIDC_ENCODER) {
-			pr_err("Buffer flushing not supported for encoder\n");
-			rc = -ENOTSUPP;
-			mutex_unlock(&inst->sync_lock);
-			break;
-		}
-
-		/* Certain types of flushes aren't supported such as: */
-		/* 1) Input only flush */
-		if (ip_flush && !op_flush) {
-			pr_err("Input only flush not supported\n");
-			rc = -ENOTSUPP;
-			mutex_unlock(&inst->sync_lock);
-			break;
-		}
-
-		/* 2) Output only flush when in reconfig */
-		if (!ip_flush && op_flush && !inst->in_reconfig) {
-			pr_err("Output only flush only supported when reconfiguring\n");
-			rc = -ENOTSUPP;
-			mutex_unlock(&inst->sync_lock);
-			break;
-		}
-
-		/* Finally flush */
-		if (op_flush && ip_flush)
-			rc = vidc_hal_session_flush(inst->session,
-					HAL_FLUSH_ALL);
-		else if (ip_flush)
-			rc = vidc_hal_session_flush(inst->session,
-					HAL_FLUSH_INPUT);
-		else if (op_flush)
-			rc = vidc_hal_session_flush(inst->session,
-					HAL_FLUSH_OUTPUT);
-		mutex_unlock(&inst->sync_lock);
+		rc = msm_comm_flush(inst, dec->flags);
 		break;
 	case V4L2_DEC_CMD_STOP:
 		rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
-		if (rc)
-			pr_err("Failed to close instance\n");
 		break;
 	default:
 		pr_err("Unknown Decoder Command\n");
 		rc = -ENOTSUPP;
 		goto exit;
 	}
-
 	if (rc) {
 		pr_err("Failed to exec decoder cmd %d\n", dec->cmd);
 		goto exit;
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 1b1a0c5..2564a55 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -1251,9 +1251,16 @@
 int msm_venc_cmd(struct msm_vidc_inst *inst, struct v4l2_encoder_cmd *enc)
 {
 	int rc = 0;
-	rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
+	switch (enc->cmd) {
+	case V4L2_ENC_QCOM_CMD_FLUSH:
+		rc = msm_comm_flush(inst, enc->flags);
+		break;
+	case V4L2_ENC_CMD_STOP:
+		rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
+		break;
+	}
 	if (rc)
-		pr_err("Failed to close instance\n");
+		pr_err("Command: %d failed with rc = %d\n", enc->cmd, rc);
 	return rc;
 }
 
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 3f7e333..d85273d 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -1584,3 +1584,27 @@
 err_no_mem:
 	return rc;
 }
+
+int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
+{
+	int rc =  0;
+	bool ip_flush = false;
+	bool op_flush = false;
+	ip_flush = flags & V4L2_QCOM_CMD_FLUSH_OUTPUT;
+	op_flush = flags & V4L2_QCOM_CMD_FLUSH_CAPTURE;
+
+	if (ip_flush && !op_flush) {
+		pr_warn("Input only flush not supported\n");
+		return 0;
+	}
+	mutex_lock(&inst->sync_lock);
+	if (inst->in_reconfig && !ip_flush && op_flush) {
+		rc = vidc_hal_session_flush(inst->session,
+				HAL_FLUSH_OUTPUT);
+	} else {
+		rc = vidc_hal_session_flush(inst->session,
+				HAL_FLUSH_ALL);
+	}
+	mutex_unlock(&inst->sync_lock);
+	return rc;
+}
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.h b/drivers/media/video/msm_vidc/msm_vidc_common.h
index 69e466e..69aa53a 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.h
@@ -31,6 +31,7 @@
 int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst);
 int msm_comm_qbuf(struct vb2_buffer *vb);
 int msm_comm_scale_clocks(struct msm_vidc_core *core, enum session_type type);
+int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags);
 #define IS_PRIV_CTRL(idx) (\
 		(V4L2_CTRL_ID2CLASS(idx) == V4L2_CTRL_CLASS_MPEG) && \
 		V4L2_CTRL_DRIVER_PRIV(idx))
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
index 2021ec6..8e9e57f 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ b/drivers/media/video/msm_vidc/vidc_hal.c
@@ -607,6 +607,28 @@
 	return rc;
 }
 
+static void set_vbif_registers(struct hal_device *device)
+{
+	write_register(device->hal_data->register_base_addr,
+			VIDC_VENUS0_VENUS_WRAPPER_VBIF_REQ_PRIORITY, 0, 0);
+	write_register(device->hal_data->register_base_addr,
+			VIDC_VENUS0_VENUS_WRAPPER_VBIF_PRIORITY_LEVEL, 0, 0);
+	write_register(device->hal_data->register_base_addr,
+		VIDC_VBIF_ARB_CTL, 0x30, 0);
+	write_register(device->hal_data->register_base_addr,
+		VIDC_VBIF_ROUND_ROBIN_QOS_ARB, 0x1, 0);
+	write_register(device->hal_data->register_base_addr,
+		VIDC_VBIF_OUT_AXI_AOOO_EN, 0x00000FFF, 0);
+	write_register(device->hal_data->register_base_addr,
+		VIDC_VBIF_OUT_AXI_AOOO, 0x0FFF0FFF, 0);
+	write_register(device->hal_data->register_base_addr,
+		VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF0, 0x22222222, 0);
+	write_register(device->hal_data->register_base_addr,
+		VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF1, 0x00002222, 0);
+	write_register(device->hal_data->register_base_addr,
+		VIDC_VBIF_DDR_OUT_MAX_BURST, 0x00000707, 0);
+}
+
 int vidc_hal_core_init(void *device, int domain)
 {
 	struct hfi_cmd_sys_init_packet pkt;
@@ -627,7 +649,7 @@
 	/*Disable Dynamic clock gating for Venus VBIF*/
 	write_register(dev->hal_data->register_base_addr,
 				   VIDC_VENUS_VBIF_CLK_ON, 1, 0);
-
+	set_vbif_registers(dev);
 	if (!dev->hal_client) {
 		dev->hal_client = msm_smem_new_client(SMEM_ION);
 		if (dev->hal_client == NULL) {
diff --git a/drivers/media/video/msm_vidc/vidc_hal_io.h b/drivers/media/video/msm_vidc/vidc_hal_io.h
index c1058e6..571a053 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_io.h
+++ b/drivers/media/video/msm_vidc/vidc_hal_io.h
@@ -98,7 +98,28 @@
 #define VIDC_WRAPPER_AXI_HALT		(VIDC_WRAPPER_BASE_OFFS + 0x2008)
 #define VIDC_WRAPPER_AXI_HALT_STATUS	(VIDC_WRAPPER_BASE_OFFS + 0x200C)
 #define VIDC_WRAPPER_CPU_CGC_DIS	(VIDC_WRAPPER_BASE_OFFS + 0x2010)
-#define VIDC_VENUS_VBIF_CLK_ON		0x80004
-
+#define VIDC_VENUS_VBIF_CLK_ON		(VIDC_VBIF_BASE_OFFS + 0x4)
+#define VIDC_VBIF_IN_RD_LIM_CONF0	(VIDC_VBIF_BASE_OFFS + 0xB0)
+#define VIDC_VBIF_IN_RD_LIM_CONF1	(VIDC_VBIF_BASE_OFFS + 0xB4)
+#define VIDC_VBIF_IN_RD_LIM_CONF2	(VIDC_VBIF_BASE_OFFS + 0xB8)
+#define VIDC_VBIF_IN_WR_LIM_CONF0	(VIDC_VBIF_BASE_OFFS + 0xC0)
+#define VIDC_VBIF_IN_WR_LIM_CONF1	(VIDC_VBIF_BASE_OFFS + 0xC4)
+#define VIDC_VBIF_IN_WR_LIM_CONF2	(VIDC_VBIF_BASE_OFFS + 0xC8)
+#define VIDC_VBIF_OUT_RD_LIM_CONF0	(VIDC_VBIF_BASE_OFFS + 0xD0)
+#define VIDC_VBIF_OUT_WR_LIM_CONF0	(VIDC_VBIF_BASE_OFFS + 0xD4)
+#define VIDC_VBIF_DDR_OUT_MAX_BURST	(VIDC_VBIF_BASE_OFFS + 0xD8)
+#define VIDC_VBIF_ARB_CTL			(VIDC_VBIF_BASE_OFFS + 0xF0)
+#define VIDC_VBIF_DDR_ARB_CONF0		(VIDC_VBIF_BASE_OFFS + 0xF4)
+#define VIDC_VBIF_DDR_ARB_CONF1		(VIDC_VBIF_BASE_OFFS + 0xF8)
+#define VIDC_VBIF_ROUND_ROBIN_QOS_ARB	(VIDC_VBIF_BASE_OFFS + 0x124)
+#define VIDC_VBIF_OUT_AXI_AOOO_EN	(VIDC_VBIF_BASE_OFFS + 0x178)
+#define VIDC_VBIF_OUT_AXI_AOOO	(VIDC_VBIF_BASE_OFFS + 0x17C)
+#define VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF0 \
+	(VIDC_VBIF_BASE_OFFS + 0x160)
+#define VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF1 \
+	(VIDC_VBIF_BASE_OFFS + 0x164)
+#define VIDC_VENUS0_VENUS_WRAPPER_VBIF_REQ_PRIORITY \
+	(VIDC_WRAPPER_BASE_OFFS + 0x20)
+#define VIDC_VENUS0_VENUS_WRAPPER_VBIF_PRIORITY_LEVEL \
+	(VIDC_WRAPPER_BASE_OFFS + 0x24)
 #endif
-
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index 59ae13b..c78fd0c 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -990,10 +990,10 @@
 	}
 
 	ch_id--;
-	ctrl_bridge_disconnect(ch_id);
+	ctrl_bridge_disconnect(dev->id);
 	platform_device_unregister(dev->pdev);
 	usb_set_intfdata(intf, NULL);
-	__dev[ch_id] = NULL;
+	__dev[dev->id] = NULL;
 
 	cancel_work_sync(&dev->process_rx_w);
 	cancel_work_sync(&dev->kevent);
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 70685e7..4fc78cd 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1537,6 +1537,7 @@
 				mdp_clk_disable_unprepare();
 		}
 	}
+	pr_debug("%s: on=%d cnt=%d\n", __func__, on, mdp_clk_cnt);
 	mutex_unlock(&mdp_suspend_mutex);
 }
 
@@ -2060,8 +2061,10 @@
 	int ret = 0;
 	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
 
+	pr_debug("%s:+\n", __func__);
 	mdp_histogram_ctrl_all(FALSE);
 
+	mdp_clk_ctrl(1);
 	if (mfd->panel.type == MIPI_CMD_PANEL)
 		mdp4_dsi_cmd_off(pdev);
 	else if (mfd->panel.type == MIPI_VIDEO_PANEL)
@@ -2074,9 +2077,11 @@
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	ret = panel_next_off(pdev);
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	mdp_clk_ctrl(0);
 
 	if (mdp_rev >= MDP_REV_41 && mfd->panel.type == MIPI_CMD_PANEL)
 		mdp_dsi_cmd_overlay_suspend(mfd);
+	pr_debug("%s:-\n", __func__);
 	return ret;
 }
 
@@ -2097,6 +2102,8 @@
 	struct msm_fb_data_type *mfd;
 	mfd = platform_get_drvdata(pdev);
 
+	pr_debug("%s:+\n", __func__);
+
 	if (mdp_rev >= MDP_REV_40) {
 		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 		mdp_clk_ctrl(1);
@@ -2126,8 +2133,8 @@
 	ret = panel_next_on(pdev);
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 
-
 	mdp_histogram_ctrl_all(TRUE);
+	pr_debug("%s:-\n", __func__);
 
 	return ret;
 }
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 054741f..c845053 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -480,7 +480,7 @@
 			struct mdp4_overlay_pipe *pipe);
 void mdp4_dmae_done_dtv(void);
 void mdp4_dtv_wait4vsync(int cndx, long long *vtime);
-void mdp4_dtv_vsync_ctrl(int cndx, int enable);
+void mdp4_dtv_vsync_ctrl(struct fb_info *info, int enable);
 void mdp4_dtv_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
 #else
 static inline void mdp4_overlay_dtv_start(void)
@@ -516,7 +516,7 @@
 {
     /* empty */
 }
-static inline void mdp4_dtv_vsync_ctrl(int cndx, long long *vtime)
+static inline void mdp4_dtv_vsync_ctrl(struct fb_info *info, int enable)
 {
     /* empty */
 }
@@ -548,7 +548,7 @@
 int mdp4_atv_off(struct platform_device *pdev);
 void mdp4_dsi_video_fxn_register(cmd_fxn_t fxn);
 void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd);
-void mdp4_lcdc_vsync_ctrl(int cndx, int enable);
+void mdp4_lcdc_vsync_ctrl(struct fb_info *info, int enable);
 void mdp4_overlay0_done_dsi_video(int cndx);
 void mdp4_overlay0_done_dsi_cmd(int cndx);
 void mdp4_primary_rdptr(void);
@@ -773,8 +773,8 @@
 void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime);
 void mdp4_dsi_cmd_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
 void mdp4_dsi_video_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
-void mdp4_dsi_cmd_vsync_ctrl(int cndx, int enable);
-void mdp4_dsi_video_vsync_ctrl(int cndx, int enable);
+void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info, int enable);
+void mdp4_dsi_video_vsync_ctrl(struct fb_info *info, int enable);
 #ifdef CONFIG_FB_MSM_MDP303
 static inline void mdp4_dsi_cmd_del_timer(void)
 {
@@ -822,10 +822,12 @@
 			struct mdp4_overlay_pipe *pipe)
 {
 }
-static inline void mdp4_dsi_cmd_vsync_ctrl(int cndx, int enable)
+static inline void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info,
+				int enable)
 {
 }
-static inline void mdp4_dsi_video_vsync_ctrl(int cndx, int enable)
+static inline void mdp4_dsi_video_vsync_ctrl(struct fb_info *info,
+				int enable)
 {
 }
 
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index c07b3a7..3a1531f 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -3174,13 +3174,13 @@
 
 	if (!hdmi_prim_display && info->node == 0) {
 		if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
-			mdp4_dsi_video_vsync_ctrl(0, cmd);
+			mdp4_dsi_video_vsync_ctrl(info, cmd);
 		else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
-			mdp4_dsi_cmd_vsync_ctrl(0, cmd);
+			mdp4_dsi_cmd_vsync_ctrl(info, cmd);
 		else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
-			mdp4_lcdc_vsync_ctrl(0, cmd);
+			mdp4_lcdc_vsync_ctrl(info, cmd);
 	} else if (hdmi_prim_display || info->node == 1)
-		mdp4_dtv_vsync_ctrl(0, cmd);
+		mdp4_dtv_vsync_ctrl(info, cmd);
 
 	return 0;
 }
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index c788c33..6232de0 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -39,7 +39,7 @@
 static int vsync_start_y_adjust = 4;
 
 #define MAX_CONTROLLER	1
-#define VSYNC_EXPIRE_TICK 4
+#define VSYNC_EXPIRE_TICK 8
 
 static struct vsycn_ctrl {
 	struct device *dev;
@@ -58,7 +58,7 @@
 	int blt_change;
 	int blt_free;
 	int blt_end;
-	int fake_vsync;
+	int uevent;
 	struct mutex update_lock;
 	struct completion ov_comp;
 	struct completion dmap_comp;
@@ -70,6 +70,7 @@
 	int vsync_enabled;
 	int clk_enabled;
 	int clk_control;
+	int new_update;
 	ktime_t vsync_time;
 	struct work_struct vsync_work;
 	struct work_struct clk_work;
@@ -379,26 +380,59 @@
 	return cnt;
 }
 
-void mdp4_dsi_cmd_vsync_ctrl(int cndx, int enable)
-{
-	struct vsycn_ctrl *vctrl;
+static void mdp4_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd);
 
-	if (cndx >= MAX_CONTROLLER) {
-		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
-		return;
-	}
+void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info, int enable)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct vsycn_ctrl *vctrl;
+	unsigned long flags;
+	int clk_set_on = 0;
+	int cndx = 0;
 
 	vctrl = &vsync_ctrl_db[cndx];
 
-	if (enable && vctrl->fake_vsync) {
-		vctrl->fake_vsync = 0;
-		schedule_work(&vctrl->vsync_work);
+	pr_debug("%s: clk_enabled=%d vsycn_enabeld=%d req=%d\n", __func__,
+		vctrl->clk_enabled, vctrl->vsync_enabled, enable);
+
+	mutex_lock(&vctrl->update_lock);
+
+	if (vctrl->vsync_enabled == enable) {
+		mutex_unlock(&vctrl->update_lock);
+		return;
 	}
 
-	if (vctrl->vsync_enabled == enable)
-		return;
-
 	vctrl->vsync_enabled = enable;
+
+	if (enable) {
+		if (vctrl->clk_enabled == 0) {
+			pr_debug("%s: SET_CLK_ON\n", __func__);
+			mipi_dsi_clk_cfg(1);
+			mdp_clk_ctrl(1);
+			vctrl->clk_enabled = 1;
+			clk_set_on = 1;
+		}
+		spin_lock_irqsave(&vctrl->spin_lock, flags);
+		vctrl->clk_control = 0;
+		vctrl->expire_tick = 0;
+		vctrl->uevent = 1;
+		vctrl->new_update = 1;
+		if (clk_set_on) {
+			vsync_irq_enable(INTR_PRIMARY_RDPTR,
+						MDP_PRIM_RDPTR_TERM);
+		}
+		spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+		mdp4_overlay_update_dsi_cmd(mfd);
+	} else {
+		spin_lock_irqsave(&vctrl->spin_lock, flags);
+		vctrl->clk_control = 1;
+		vctrl->uevent = 0;
+		if (vctrl->clk_enabled)
+			vctrl->expire_tick = VSYNC_EXPIRE_TICK;
+		spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+	}
+	mutex_unlock(&vctrl->update_lock);
 }
 
 void mdp4_dsi_cmd_wait4vsync(int cndx, long long *vtime)
@@ -479,13 +513,21 @@
 	pr_debug("%s: ISR, cpu=%d\n", __func__, smp_processor_id());
 	vctrl->rdptr_intr_tot++;
 	vctrl->vsync_time = ktime_get();
-	schedule_work(&vctrl->vsync_work);
 
 	spin_lock(&vctrl->spin_lock);
+	if (vctrl->uevent)
+		schedule_work(&vctrl->vsync_work);
+
 	if (vctrl->wait_vsync_cnt) {
 		complete(&vctrl->vsync_comp);
 		vctrl->wait_vsync_cnt = 0;
 	}
+
+	if (vctrl->expire_tick) {
+		vctrl->expire_tick--;
+		if (vctrl->expire_tick == 0)
+			schedule_work(&vctrl->clk_work);
+	}
 	spin_unlock(&vctrl->spin_lock);
 }
 
@@ -578,16 +620,19 @@
 {
 	struct vsycn_ctrl *vctrl =
 		container_of(work, typeof(*vctrl), clk_work);
+	unsigned long flags;
 
 	mutex_lock(&vctrl->update_lock);
-	if (vctrl->clk_control) {
-		if (vctrl->clk_enabled) {
-			mdp_clk_ctrl(0);
-			vctrl->clk_enabled = 0;
-			vctrl->fake_vsync = 1;
-		}
+	if (vctrl->clk_control && vctrl->clk_enabled) {
+		pr_debug("%s: SET_CLK_OFF\n", __func__);
+		mdp_clk_ctrl(0);
+		mipi_dsi_clk_cfg(0);
+		spin_lock_irqsave(&vctrl->spin_lock, flags);
+		vsync_irq_disable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
+		vctrl->clk_enabled = 0;
+		vctrl->clk_control = 0;
+		spin_unlock_irqrestore(&vctrl->spin_lock, flags);
 	}
-
 	mutex_unlock(&vctrl->update_lock);
 }
 
@@ -746,7 +791,7 @@
 	pipe->srcp0_addr = (uint32)src;
 }
 
-void mdp4_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd)
+static void mdp4_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd)
 {
 	int ptype;
 	struct mdp4_overlay_pipe *pipe;
@@ -760,30 +805,31 @@
 
 	vctrl = &vsync_ctrl_db[cndx];
 
-	/* MDP cmd block enable */
-	mdp_clk_ctrl(1);
+	if (vctrl->base_pipe == NULL) {
+		ptype = mdp4_overlay_format2type(mfd->fb_imgType);
+		if (ptype < 0)
+			printk(KERN_INFO "%s: format2type failed\n", __func__);
+		pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0);
+		if (pipe == NULL) {
+			printk(KERN_INFO "%s: pipe_alloc failed\n", __func__);
+			return;
+		}
+		pipe->pipe_used++;
+		pipe->mixer_stage  = MDP4_MIXER_STAGE_BASE;
+		pipe->mixer_num  = MDP4_MIXER0;
+		pipe->src_format = mfd->fb_imgType;
+		mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DSI_CMD);
+		ret = mdp4_overlay_format2pipe(pipe);
+		if (ret < 0)
+			printk(KERN_INFO "%s: format2type failed\n", __func__);
 
-	ptype = mdp4_overlay_format2type(mfd->fb_imgType);
-	if (ptype < 0)
-		printk(KERN_INFO "%s: format2type failed\n", __func__);
-	pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0);
-	if (pipe == NULL) {
-		printk(KERN_INFO "%s: pipe_alloc failed\n", __func__);
-		return;
+		vctrl->base_pipe = pipe; /* keep it */
+		mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
+		pipe->ov_blt_addr = 0;
+		pipe->dma_blt_addr = 0;
+	} else {
+		pipe = vctrl->base_pipe;
 	}
-	pipe->pipe_used++;
-	pipe->mixer_stage  = MDP4_MIXER_STAGE_BASE;
-	pipe->mixer_num  = MDP4_MIXER0;
-	pipe->src_format = mfd->fb_imgType;
-	mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DSI_CMD);
-	ret = mdp4_overlay_format2pipe(pipe);
-	if (ret < 0)
-		printk(KERN_INFO "%s: format2type failed\n", __func__);
-
-	vctrl->base_pipe = pipe; /* keep it */
-	mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
-	pipe->ov_blt_addr = 0;
-	pipe->dma_blt_addr = 0;
 
 	MDP_OUTP(MDP_BASE + 0x021c, 10); /* read pointer */
 
@@ -795,7 +841,6 @@
 	/* disable dsi trigger */
 	MDP_OUTP(MDP_BASE + 0x000a4, 0x00);
 
-
 	mdp4_overlay_setup_pipe_addr(mfd, pipe);
 
 	mdp4_overlay_rgb_setup(pipe);
@@ -810,9 +855,7 @@
 
 	mdp4_overlay_dmap_cfg(mfd, 0);
 
-	mdp4_mixer_stage_commit(pipe->mixer_num);
-	/* MDP cmd block disable */
-	mdp_clk_ctrl(0);
+	wmb();
 }
 
 /* 3D side by side */
@@ -916,7 +959,7 @@
 	struct msm_fb_data_type *mfd;
 	struct vsycn_ctrl *vctrl;
 
-	pr_info("%s+:\n", __func__);
+	pr_debug("%s+:\n", __func__);
 
 	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
 
@@ -925,15 +968,13 @@
 	vctrl->dev = mfd->fbi->dev;
 
 	mdp_clk_ctrl(1);
-	vsync_irq_enable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
-
-	if (vctrl->base_pipe == NULL)
-		mdp4_overlay_update_dsi_cmd(mfd);
+	mdp4_overlay_update_dsi_cmd(mfd);
+	mdp_clk_ctrl(0);
 
 	mdp4_iommu_attach();
 
 	atomic_set(&vctrl->suspend, 0);
-	pr_info("%s-:\n", __func__);
+	pr_debug("%s-:\n", __func__);
 
 
 	return ret;
@@ -947,7 +988,7 @@
 	struct vsycn_ctrl *vctrl;
 	struct mdp4_overlay_pipe *pipe;
 
-	pr_info("%s+:\n", __func__);
+	pr_debug("%s+:\n", __func__);
 
 	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
 
@@ -966,11 +1007,25 @@
 	mdp4_overlay_pipe_free(pipe);
 	vctrl->base_pipe = NULL;
 
-	vctrl->fake_vsync = 1;
+	if (vctrl->clk_enabled) {
+		/*
+		 * in case of suspend, vsycn_ctrl off is not
+		 * received from frame work which left clock on
+		 * then, clock need to be turned off here
+		 */
+		mdp_clk_ctrl(0);
+	}
+
+	vctrl->clk_enabled = 0;
+	vctrl->vsync_enabled = 0;
+	vctrl->clk_control = 0;
+	vctrl->expire_tick = 0;
+	vctrl->uevent = 0;
 
 	vsync_irq_disable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
 
-	pr_info("%s-:\n", __func__);
+
+	pr_debug("%s-:\n", __func__);
 
 	/*
 	 * footswitch off
@@ -1012,6 +1067,7 @@
 	int cndx = 0;
 	struct vsycn_ctrl *vctrl;
 	struct mdp4_overlay_pipe *pipe;
+	unsigned long flags;
 	long long xx;
 
 	vctrl = &vsync_ctrl_db[cndx];
@@ -1019,13 +1075,31 @@
 	if (!mfd->panel_power_on)
 		return;
 
-	vctrl->clk_control = 0;
 	pipe = vctrl->base_pipe;
 	if (pipe == NULL) {
 		pr_err("%s: NO base pipe\n", __func__);
 		return;
 	}
 
+	mutex_lock(&vctrl->update_lock);
+	if (!vctrl->clk_enabled) {
+		pr_err("%s: mdp clocks disabled\n", __func__);
+		mutex_unlock(&vctrl->update_lock);
+		return;
+
+	}
+	mutex_unlock(&vctrl->update_lock);
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (vctrl->expire_tick) {
+		/*
+		 * in the middle of shutting clocks down
+		 * delay to allow pan display to go through
+		 */
+		vctrl->expire_tick = VSYNC_EXPIRE_TICK;
+	}
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
 	if (pipe->mixer_stage == MDP4_MIXER_STAGE_BASE) {
 		mdp4_mipi_vsync_enable(mfd, pipe, 0);
 		mdp4_overlay_setup_pipe_addr(mfd, pipe);
@@ -1033,13 +1107,12 @@
 	}
 
 	mdp4_overlay_mdp_perf_upd(mfd, 1);
+
 	mutex_lock(&mfd->dma->ov_mutex);
 	mdp4_dsi_cmd_pipe_commit();
 	mutex_unlock(&mfd->dma->ov_mutex);
 
 	mdp4_dsi_cmd_wait4vsync(0, &xx);
-	vctrl->expire_tick = VSYNC_EXPIRE_TICK;
-	vctrl->clk_control = 1;
 
 	mdp4_overlay_mdp_perf_upd(mfd, 0);
 }
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index a461c3b..04da0a3 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -256,14 +256,10 @@
 	return cnt;
 }
 
-void mdp4_dsi_video_vsync_ctrl(int cndx, int enable)
+void mdp4_dsi_video_vsync_ctrl(struct fb_info *info, int enable)
 {
 	struct vsycn_ctrl *vctrl;
-
-	if (cndx >= MAX_CONTROLLER) {
-		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
-		return;
-	}
+	int cndx = 0;
 
 	vctrl = &vsync_ctrl_db[cndx];
 
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index e131369..8a0b092 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -238,14 +238,10 @@
 	return cnt;
 }
 
-void mdp4_dtv_vsync_ctrl(int cndx, int enable)
+void mdp4_dtv_vsync_ctrl(struct fb_info *info, int enable)
 {
 	struct vsycn_ctrl *vctrl;
-
-	if (cndx >= MAX_CONTROLLER) {
-		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
-		return;
-	}
+	int cndx = 0;
 
 	vctrl = &vsync_ctrl_db[cndx];
 
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index a2fabca..aa2de32 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -260,14 +260,10 @@
 	return cnt;
 }
 
-void mdp4_lcdc_vsync_ctrl(int cndx, int enable)
+void mdp4_lcdc_vsync_ctrl(struct fb_info *info, int enable)
 {
 	struct vsycn_ctrl *vctrl;
-
-	if (cndx >= MAX_CONTROLLER) {
-		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
-		return;
-	}
+	int cndx = 0;
 
 	vctrl = &vsync_ctrl_db[cndx];
 
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 886e8de..3017200 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -14,6 +14,7 @@
 #ifndef MDSS_H
 #define MDSS_H
 
+#include <linux/ion.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
@@ -52,24 +53,24 @@
 
 	u32 mdp_irq_mask;
 
-	u32 clk_ena;
 	u32 suspend;
 	u32 timeout;
 
-	u32 fs_ena;
-	u32 vsync_ena;
+	u8 clk_ena;
+	u8 fs_ena;
+	u8 vsync_ena;
+	u8 eintf_ena;
 
-	u32 intf;
-	u32 eintf_ena;
 	u32 prim_ptype;
 	u32 res_init;
-	u32 pdev_lcnt;
 	u32 bus_hdl;
 
 	u32 smp_mb_cnt;
 	u32 smp_mb_size;
 	u32 *pipe_type_map;
 	u32 *mixer_type_map;
+
+	struct ion_client *iclient;
 };
 extern struct mdss_data_type *mdss_res;
 
@@ -91,4 +92,10 @@
 void mdss_enable_irq(struct mdss_hw *hw);
 void mdss_disable_irq(struct mdss_hw *hw);
 void mdss_disable_irq_nosync(struct mdss_hw *hw);
+static inline struct ion_client *mdss_get_ionclient(void)
+{
+	if (!mdss_res)
+		return NULL;
+	return mdss_res->iclient;
+}
 #endif /* MDSS_H */
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 1f83b2b..5ea52e7 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -204,9 +204,6 @@
 	mfd->panel_info.frame_count = 0;
 	mfd->bl_level = 0;
 	mfd->fb_imgType = MDP_RGBA_8888;
-	mfd->iclient = msm_ion_client_create(-1, pdev->name);
-	if (IS_ERR(mfd->iclient))
-		mfd->iclient = NULL;
 
 	mfd->pdev = pdev;
 
@@ -592,7 +589,7 @@
 	size *= mfd->fb_page;
 
 	if (mfd->index == 0) {
-		struct ion_client *iclient = mfd->iclient;
+		struct ion_client *iclient = mdss_get_ionclient();
 
 		if (iclient) {
 			mfd->ihdl = ion_alloc(iclient, size, SZ_4K,
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index ab140fe..dd84ce5 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -89,10 +89,10 @@
 	u32 var_pixclock;
 
 	u32 mdp_fb_page_protection;
-	struct ion_client *iclient;
 
 	struct mdss_mdp_ctl *ctl;
 	struct mdss_mdp_wb *wb;
+	struct list_head overlay_list;
 };
 
 int mdss_fb_get_phys_info(unsigned long *start, unsigned long *len, int fb_num);
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index ce55e71..4604d4a 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -608,7 +608,7 @@
 
 static u32 mdss_mdp_res_init(struct mdss_data_type *mdata)
 {
-	u32 rc;
+	u32 rc = 0;
 
 	rc = mdss_mdp_irq_clk_setup(mdata);
 	if (rc)
@@ -639,6 +639,13 @@
 	mdata->prim_ptype = NO_PANEL;
 	mdata->irq_ena = false;
 
+	mdata->iclient = msm_ion_client_create(-1, mdata->pdev->name);
+	if (IS_ERR_OR_NULL(mdata->iclient)) {
+		pr_err("msm_ion_client_create() return error (%p)\n",
+				mdata->iclient);
+		mdata->iclient = NULL;
+	}
+
 	rc = mdss_hw_init(mdata);
 
 	return rc;
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index a282c3a..a77c18e 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -200,7 +200,6 @@
 	int p_need;
 	struct file *srcp_file;
 	struct ion_handle *srcp_ihdl;
-	struct ion_client *iclient;
 };
 
 struct mdss_mdp_data {
@@ -240,6 +239,9 @@
 	u32 params_changed;
 
 	unsigned long smp[MAX_PLANES];
+
+	struct mdss_mdp_data buffers[2];
+	struct list_head list;
 };
 
 struct mdss_mdp_writeback_arg {
@@ -276,6 +278,7 @@
 void mdss_mdp_footswitch_ctrl(int on);
 
 int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd);
+int mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd);
 int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl);
 int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl);
 
@@ -301,7 +304,6 @@
 void mdss_mdp_pipe_unlock(struct mdss_mdp_pipe *pipe);
 
 int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe);
-int mdss_mdp_pipe_release_all(struct msm_fb_data_type *mfd);
 int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe,
 			     struct mdss_mdp_data *src_data);
 
@@ -311,8 +313,7 @@
 			     struct mdss_mdp_plane_sizes *ps);
 struct mdss_mdp_format_params *mdss_mdp_get_format_params(u32 format);
 int mdss_mdp_put_img(struct mdss_mdp_img_data *data);
-int mdss_mdp_get_img(struct ion_client *iclient, struct msmfb_data *img,
-		     struct mdss_mdp_img_data *data);
+int mdss_mdp_get_img(struct msmfb_data *img, struct mdss_mdp_img_data *data);
 
 int mdss_mdp_wb_kickoff(struct mdss_mdp_ctl *ctl);
 int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 21f4071..1486779 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -595,7 +595,7 @@
 
 	mutex_unlock(&ctl->lock);
 
-	mdss_mdp_pipe_release_all(mfd);
+	mdss_mdp_overlay_release_all(mfd);
 
 	if (!mfd->ref_cnt)
 		mdss_mdp_ctl_destroy(mfd);
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 1cb474d..6719d9e 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -279,6 +279,9 @@
 			return -ENOMEM;
 		}
 
+		mutex_lock(&mfd->lock);
+		list_add(&pipe->list, &mfd->overlay_list);
+		mutex_unlock(&mfd->lock);
 		pipe->mixer = mixer;
 		pipe->mfd = mfd;
 	} else {
@@ -343,6 +346,79 @@
 	return ret;
 }
 
+static inline int mdss_mdp_overlay_get_buf(struct msm_fb_data_type *mfd,
+					   struct mdss_mdp_data *data,
+					   struct msmfb_data *planes,
+					   int num_planes)
+{
+	int i;
+
+	memset(data, 0, sizeof(*data));
+	for (i = 0; i < num_planes; i++) {
+		mdss_mdp_get_img(&planes[i], &data->p[i]);
+		if (data->p[0].len == 0)
+			break;
+	}
+
+	if (i != num_planes) {
+		for (; i >= 0; i--)
+			mdss_mdp_put_img(&data->p[i]);
+		return -ENOMEM;
+	}
+
+	data->num_planes = num_planes;
+
+	return 0;
+}
+
+static inline int mdss_mdp_overlay_free_buf(struct mdss_mdp_data *data)
+{
+	int i;
+	for (i = 0; i < data->num_planes && data->p[i].len; i++)
+		mdss_mdp_put_img(&data->p[i]);
+
+	data->num_planes = 0;
+
+	return 0;
+}
+
+static int mdss_mdp_overlay_kickoff(struct mdss_mdp_ctl *ctl)
+{
+	int ret;
+
+	if (ctl->mfd->kickoff_fnc)
+		ret = ctl->mfd->kickoff_fnc(ctl);
+	else
+		ret = mdss_mdp_display_commit(ctl, NULL);
+	if (IS_ERR_VALUE(ret))
+		return ret;
+
+	pr_debug("freeing previous buffers\n");
+
+	mutex_lock(&ctl->mfd->lock);
+	if (!list_empty(&ctl->mfd->overlay_list)) {
+		struct mdss_mdp_pipe *pipe;
+		struct mdss_mdp_data *data;
+		int buf_ndx;
+
+		list_for_each_entry(pipe, &ctl->mfd->overlay_list, list) {
+			buf_ndx = (pipe->play_cnt - 1) & 1; /* prev buffer */
+			data = &pipe->buffers[buf_ndx];
+
+			if (data->num_planes) {
+				pr_debug("free buffer ndx=%d pnum=%d\n",
+						buf_ndx, pipe->num);
+				mdss_mdp_overlay_free_buf(data);
+			}
+		}
+	}
+	mutex_unlock(&ctl->mfd->lock);
+
+	pr_debug("done freeing previous buffers\n");
+
+	return ret;
+}
+
 static int mdss_mdp_overlay_unset(struct msm_fb_data_type *mfd, int ndx)
 {
 	struct mdss_mdp_pipe *pipe;
@@ -374,6 +450,9 @@
 			unset_ndx |= pipe_ndx;
 			pipe = mdss_mdp_pipe_get_locked(pipe_ndx);
 			if (pipe) {
+				mutex_lock(&mfd->lock);
+				list_del(&pipe->list);
+				mutex_unlock(&mfd->lock);
 				mdss_mdp_mixer_pipe_unstage(pipe);
 				cleanup_pipes[clean_cnt++] = pipe;
 			} else {
@@ -383,15 +462,51 @@
 	}
 
 	if (clean_cnt) {
-		ret = mfd->kickoff_fnc(mfd->ctl);
+		int j;
+		ret = mdss_mdp_overlay_kickoff(mfd->ctl);
 
-		for (i = 0; i < clean_cnt; i++)
-			mdss_mdp_pipe_destroy(cleanup_pipes[i]);
+		for (i = 0; i < clean_cnt; i++) {
+			pipe = cleanup_pipes[i];
+			for (j = 0; j < ARRAY_SIZE(pipe->buffers); j++)
+				mdss_mdp_overlay_free_buf(&pipe->buffers[i]);
+
+			mdss_mdp_pipe_destroy(pipe);
+		}
 	}
 
 	return ret;
 }
 
+int mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd)
+{
+	struct mdss_mdp_pipe *pipe;
+	u32 unset_ndx = 0;
+	int cnt = 0;
+
+	mutex_lock(&mfd->lock);
+	if (!list_empty(&mfd->overlay_list)) {
+		list_for_each_entry(pipe, &mfd->overlay_list, list) {
+			if (pipe->ndx & MDSS_MDP_ROT_SESSION_MASK) {
+				struct mdss_mdp_rotator_session *rot;
+				rot = mdss_mdp_rotator_session_get(pipe->ndx);
+				if (rot)
+					mdss_mdp_rotator_finish(rot);
+			} else {
+				unset_ndx |= pipe->ndx;
+				cnt++;
+			}
+		}
+	}
+	mutex_unlock(&mfd->lock);
+
+	if (unset_ndx) {
+		pr_debug("%d pipes need cleanup (%x)\n", cnt, unset_ndx);
+		mdss_mdp_overlay_unset(mfd, unset_ndx);
+	}
+
+	return 0;
+}
+
 static int mdss_mdp_overlay_play_wait(struct msm_fb_data_type *mfd,
 				      struct msmfb_overlay_data *req)
 {
@@ -400,41 +515,59 @@
 	if (!mfd || !mfd->ctl)
 		return -ENODEV;
 
-	ret = mfd->kickoff_fnc(mfd->ctl);
+	ret = mdss_mdp_overlay_kickoff(mfd->ctl);
 	if (!ret)
 		pr_err("error displaying\n");
 
 	return ret;
 }
 
-static int mdss_mdp_overlay_rotate(struct msmfb_overlay_data *req,
-				   struct mdss_mdp_data *src_data,
-				   struct mdss_mdp_data *dst_data)
+static int mdss_mdp_overlay_rotate(struct msm_fb_data_type *mfd,
+				   struct msmfb_overlay_data *req)
 {
 	struct mdss_mdp_rotator_session *rot;
+	struct mdss_mdp_data src_data, dst_data;
 	int ret;
 
+	ret = mdss_mdp_overlay_get_buf(mfd, &src_data, &req->data, 1);
+	if (ret) {
+		pr_err("src_data pmem error\n");
+		goto rotate_done;
+	}
+
+	ret = mdss_mdp_overlay_get_buf(mfd, &dst_data, &req->dst_data, 1);
+	if (ret) {
+		pr_err("dst_data pmem error\n");
+		goto rotate_done;
+	}
+
 	rot = mdss_mdp_rotator_session_get(req->id);
 	if (!rot) {
 		pr_err("invalid session id=%x\n", req->id);
-		return -ENODEV;
+		ret = -ENODEV;
+		goto rotate_done;
 	}
 
-	ret = mdss_mdp_rotator_queue(rot, src_data, dst_data);
+	ret = mdss_mdp_rotator_queue(rot, &src_data, &dst_data);
 	if (ret) {
 		pr_err("rotator queue error session id=%x\n", req->id);
-		return ret;
+		goto rotate_done;
 	}
 
+rotate_done:
+	mdss_mdp_overlay_free_buf(&dst_data);
+	mdss_mdp_overlay_free_buf(&src_data);
+
 	return 0;
 }
 
-static int mdss_mdp_overlay_queue(struct msmfb_overlay_data *req,
-				  struct mdss_mdp_data *src_data)
+static int mdss_mdp_overlay_queue(struct msm_fb_data_type *mfd,
+				  struct msmfb_overlay_data *req)
 {
-	struct mdss_mdp_pipe *pipe;
 	struct mdss_mdp_ctl *ctl;
-	int ret;
+	struct mdss_mdp_pipe *pipe;
+	struct mdss_mdp_data *src_data;
+	int ret, buf_ndx;
 
 	pipe = mdss_mdp_pipe_get_locked(req->id);
 	if (pipe == NULL) {
@@ -444,13 +577,23 @@
 
 	pr_debug("ov queue pnum=%d\n", pipe->num);
 
-	ret = mdss_mdp_pipe_queue_data(pipe, src_data);
+	buf_ndx = (pipe->play_cnt + 1) & 1; /* next buffer */
+	src_data = &pipe->buffers[buf_ndx];
+	mdss_mdp_overlay_free_buf(src_data);
+
+	ret = mdss_mdp_overlay_get_buf(mfd, src_data, &req->data, 1);
+	if (IS_ERR_VALUE(ret)) {
+		pr_err("src_data pmem error\n");
+	} else {
+		ret = mdss_mdp_pipe_queue_data(pipe, src_data);
+		if (IS_ERR_VALUE(ret))
+			mdss_mdp_overlay_free_buf(src_data);
+	}
 	ctl = pipe->mixer->ctl;
 	mdss_mdp_pipe_unlock(pipe);
 
 	if (ret == 0 && !(pipe->flags & MDP_OV_PLAY_NOWAIT))
-		ret = ctl->mfd->kickoff_fnc(ctl);
-
+		ret = mdss_mdp_overlay_kickoff(ctl);
 
 	return ret;
 }
@@ -458,41 +601,14 @@
 static int mdss_mdp_overlay_play(struct msm_fb_data_type *mfd,
 				 struct msmfb_overlay_data *req)
 {
-	struct mdss_mdp_data src_data;
 	int ret = 0;
 
-	if (mfd == NULL)
-		return -ENODEV;
-
 	pr_debug("play req id=%x\n", req->id);
 
-	memset(&src_data, 0, sizeof(src_data));
-	mdss_mdp_get_img(mfd->iclient, &req->data, &src_data.p[0]);
-	if (src_data.p[0].len == 0) {
-		pr_err("src data pmem error\n");
-		return -ENOMEM;
-	}
-	src_data.num_planes = 1;
-
-	if (req->id & MDSS_MDP_ROT_SESSION_MASK) {
-		struct mdss_mdp_data dst_data;
-		memset(&dst_data, 0, sizeof(dst_data));
-
-		mdss_mdp_get_img(mfd->iclient, &req->dst_data, &dst_data.p[0]);
-		if (dst_data.p[0].len == 0) {
-			pr_err("dst data pmem error\n");
-			return -ENOMEM;
-		}
-		dst_data.num_planes = 1;
-
-		ret = mdss_mdp_overlay_rotate(req, &src_data, &dst_data);
-
-		mdss_mdp_put_img(&dst_data.p[0]);
-	} else {
-		ret = mdss_mdp_overlay_queue(req, &src_data);
-	}
-
-	mdss_mdp_put_img(&src_data.p[0]);
+	if (req->id & MDSS_MDP_ROT_SESSION_MASK)
+		ret = mdss_mdp_overlay_rotate(mfd, req);
+	else
+		ret = mdss_mdp_overlay_queue(mfd, req);
 
 	return ret;
 }
@@ -577,6 +693,12 @@
 	offset = fbi->var.xoffset * bpp +
 		 fbi->var.yoffset * fbi->fix.line_length;
 
+	if (offset > fbi->fix.smem_len) {
+		pr_err("invalid fb offset=%u total length=%u\n",
+		       offset, fbi->fix.smem_len);
+		return;
+	}
+
 	data.p[0].addr = fbi->fix.smem_start + offset;
 	data.p[0].len = fbi->fix.smem_len - offset;
 	data.num_planes = 1;
@@ -612,7 +734,7 @@
 	}
 
 	if (fbi->var.activate & FB_ACTIVATE_VBL)
-		mfd->kickoff_fnc(mfd->ctl);
+		mdss_mdp_overlay_kickoff(mfd->ctl);
 }
 
 static void mdss_mdp_overlay_handle_vsync(struct mdss_mdp_ctl *ctl, ktime_t t)
@@ -772,11 +894,6 @@
 	return 0;
 }
 
-static int mdss_mdp_overlay_kickoff(struct mdss_mdp_ctl *ctl)
-{
-	return mdss_mdp_display_commit(ctl, NULL);
-}
-
 static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
 					  u32 cmd, void __user *argp)
 {
@@ -897,8 +1014,8 @@
 
 	if (mfd->panel_info.type == WRITEBACK_PANEL)
 		mfd->kickoff_fnc = mdss_mdp_wb_kickoff;
-	else
-		mfd->kickoff_fnc = mdss_mdp_overlay_kickoff;
+
+	INIT_LIST_HEAD(&mfd->overlay_list);
 
 	return 0;
 }
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index c94068a..c936b7d 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -272,35 +272,6 @@
 	return 0;
 }
 
-int mdss_mdp_pipe_release_all(struct msm_fb_data_type *mfd)
-{
-	struct mdss_mdp_pipe *pipe;
-	int i;
-
-	if (!mfd)
-		return -ENODEV;
-
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
-	mutex_lock(&mdss_mdp_sspp_lock);
-	for (i = 0; i < MDSS_MDP_MAX_SSPP; i++) {
-		pipe = &mdss_mdp_pipe_list[i];
-		if (atomic_read(&pipe->ref_cnt) && pipe->mfd == mfd) {
-			pr_debug("release pnum=%d\n", pipe->num);
-			if (mdss_mdp_pipe_lock(pipe) == 0) {
-				mdss_mdp_mixer_pipe_unstage(pipe);
-				mdss_mdp_pipe_free(pipe);
-			} else {
-				pr_err("unable to lock pipe=%d for release",
-				       pipe->num);
-			}
-		}
-	}
-	mutex_unlock(&mdss_mdp_sspp_lock);
-	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
-
-	return 0;
-}
-
 static inline void mdss_mdp_pipe_write(struct mdss_mdp_pipe *pipe,
 				       u32 reg, u32 val)
 {
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 53cd378..6fd8463 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -284,33 +284,33 @@
 
 int mdss_mdp_put_img(struct mdss_mdp_img_data *data)
 {
-	/* only source may use frame buffer */
+	struct ion_client *iclient = mdss_get_ionclient();
 	if (data->flags & MDP_MEMORY_ID_TYPE_FB) {
+		pr_debug("fb mem buf=0x%x\n", data->addr);
 		fput_light(data->srcp_file, data->p_need);
-		return 0;
-	}
-	if (data->srcp_file) {
+		data->srcp_file = NULL;
+	} else if (data->srcp_file) {
+		pr_debug("pmem buf=0x%x\n", data->addr);
 		put_pmem_file(data->srcp_file);
 		data->srcp_file = NULL;
-		return 0;
-	}
-	if (!IS_ERR_OR_NULL(data->srcp_ihdl)) {
-		ion_free(data->iclient, data->srcp_ihdl);
-		data->iclient = NULL;
+	} else if (!IS_ERR_OR_NULL(data->srcp_ihdl)) {
+		pr_debug("ion hdl=%p buf=0x%x\n", data->srcp_ihdl, data->addr);
+		ion_free(iclient, data->srcp_ihdl);
 		data->srcp_ihdl = NULL;
-		return 0;
+	} else {
+		return -ENOMEM;
 	}
 
-	return -ENOMEM;
+	return 0;
 }
 
-int mdss_mdp_get_img(struct ion_client *iclient, struct msmfb_data *img,
-		     struct mdss_mdp_img_data *data)
+int mdss_mdp_get_img(struct msmfb_data *img, struct mdss_mdp_img_data *data)
 {
 	struct file *file;
 	int ret = -EINVAL;
 	int fb_num;
 	unsigned long *start, *len;
+	struct ion_client *iclient = mdss_get_ionclient();
 
 	start = (unsigned long *) &data->addr;
 	len = (unsigned long *) &data->len;
@@ -323,19 +323,36 @@
 					start, len);
 	} else if (img->flags & MDP_MEMORY_ID_TYPE_FB) {
 		file = fget_light(img->memory_id, &data->p_need);
-		if (file && FB_MAJOR ==
-				MAJOR(file->f_dentry->d_inode->i_rdev)) {
-			data->srcp_file = file;
+		if (file == NULL) {
+			pr_err("invalid framebuffer file (%d)\n",
+					img->memory_id);
+			return -EINVAL;
+		}
+		data->srcp_file = file;
+
+		if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
 			fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
 			ret = mdss_fb_get_phys_info(start, len, fb_num);
+			if (ret)
+				pr_err("mdss_fb_get_phys_info() failed\n");
+		} else {
+			pr_err("invalid FB_MAJOR\n");
+			ret = -1;
 		}
 	} else if (iclient) {
-		data->iclient = iclient;
 		data->srcp_ihdl = ion_import_dma_buf(iclient, img->memory_id);
-		if (IS_ERR_OR_NULL(data->srcp_ihdl))
-			return PTR_ERR(data->srcp_ihdl);
-		ret = ion_phys(iclient, data->srcp_ihdl,
-			       start, (size_t *) len);
+		if (IS_ERR_OR_NULL(data->srcp_ihdl)) {
+			pr_err("error on ion_import_fd\n");
+			ret = PTR_ERR(data->srcp_ihdl);
+			data->srcp_ihdl = NULL;
+			return ret;
+		}
+		ret = ion_phys(iclient, data->srcp_ihdl, start, (size_t *) len);
+		if (IS_ERR_VALUE(ret)) {
+			ion_free(iclient, data->srcp_ihdl);
+			pr_err("failed to map ion handle (%d)\n", ret);
+			return ret;
+		}
 	} else {
 		unsigned long vstart;
 		ret = get_pmem_file(img->memory_id, start, &vstart, len,
@@ -345,9 +362,11 @@
 	if (!ret && (img->offset < data->len)) {
 		data->addr += img->offset;
 		data->len -= img->offset;
+
+		pr_debug("mem=%d ihdl=%p buf=0x%x len=0x%x\n", img->memory_id,
+			 data->srcp_ihdl, data->addr, data->len);
 	} else {
-		mdss_mdp_put_img(data);
-		ret = -EINVAL;
+		return -EINVAL;
 	}
 
 	return ret;
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index 26e459f..8c4b1b9 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -67,33 +67,34 @@
 	static struct ion_handle *ihdl;
 	static void *videomemory;
 	static ion_phys_addr_t mdss_wb_mem;
-	static struct mdss_mdp_data buffer = { .num_planes = 1,	};
-	struct fb_info *fbi;
-	size_t img_size;
+	static struct mdss_mdp_data mdss_wb_buffer = { .num_planes = 1, };
 
-	fbi = mfd->fbi;
-	img_size = fbi->var.xres * fbi->var.yres * fbi->var.bits_per_pixel / 8;
+	if (IS_ERR_OR_NULL(ihdl)) {
+		struct fb_info *fbi;
+		size_t img_size;
+		struct ion_client *iclient = mdss_get_ionclient();
+		struct mdss_mdp_img_data *img = mdss_wb_buffer.p;
 
-	if (ihdl == NULL) {
-		ihdl = ion_alloc(mfd->iclient, img_size, SZ_4K,
+		fbi = mfd->fbi;
+		img_size = fbi->var.xres * fbi->var.yres *
+			fbi->var.bits_per_pixel / 8;
+
+		ihdl = ion_alloc(iclient, img_size, SZ_4K,
 				 ION_HEAP(ION_SF_HEAP_ID));
-		if (!IS_ERR_OR_NULL(ihdl)) {
-			videomemory = ion_map_kernel(mfd->iclient, ihdl, 0);
-			ion_phys(mfd->iclient, ihdl, &mdss_wb_mem, &img_size);
-		} else {
+		if (IS_ERR_OR_NULL(ihdl)) {
 			pr_err("unable to alloc fbmem from ion (%p)\n", ihdl);
-			ihdl = NULL;
+			return NULL;
 		}
+
+		videomemory = ion_map_kernel(iclient, ihdl, 0);
+		ion_phys(iclient, ihdl, &mdss_wb_mem, &img_size);
+
+		img->addr = mdss_wb_mem;
+		img->len = img_size;
+		pr_debug("ihdl=%p virt=%p phys=0x%lx iova=0x%x size=%u\n",
+			 ihdl, videomemory, mdss_wb_mem, img->addr, img_size);
 	}
-
-	if (mdss_wb_mem) {
-		buffer.p[0].addr = (u32) mdss_wb_mem;
-		buffer.p[0].len = img_size;
-
-		return &buffer;
-	}
-
-	return NULL;
+	return &mdss_wb_buffer;
 }
 #else
 static inline
@@ -266,7 +267,7 @@
 
 	node->buf_data.num_planes = 1;
 	buf = &node->buf_data.p[0];
-	ret = mdss_mdp_get_img(mfd->iclient, data, buf);
+	ret = mdss_mdp_get_img(data, buf);
 	if (IS_ERR_VALUE(ret)) {
 		pr_err("error getting buffer info\n");
 		goto register_fail;
@@ -394,6 +395,9 @@
 	if (!ctl || !ctl->mfd)
 		return -ENODEV;
 
+	if (!ctl->power_on)
+		return 0;
+
 	mutex_lock(&mdss_mdp_wb_buf_lock);
 	wb = ctl->mfd->wb;
 	if (wb) {
diff --git a/drivers/video/msm/mhl/mhl_8334.c b/drivers/video/msm/mhl/mhl_8334.c
index be160c4..f3b8cd1 100644
--- a/drivers/video/msm/mhl/mhl_8334.c
+++ b/drivers/video/msm/mhl/mhl_8334.c
@@ -531,40 +531,62 @@
 static int mhl_i2c_probe(struct i2c_client *client,
 	const struct i2c_device_id *id)
 {
-	int ret = -ENODEV;
+	int ret;
+	struct msm_mhl_platform_data *tmp = client->dev.platform_data;
+	if (!tmp->mhl_enabled) {
+		ret = -ENODEV;
+		pr_warn("MHL feautre left disabled\n");
+		goto probe_early_exit;
+	}
 	mhl_msm_state->mhl_data = kzalloc(sizeof(struct msm_mhl_platform_data),
 		GFP_KERNEL);
 	if (!(mhl_msm_state->mhl_data)) {
 		ret = -ENOMEM;
 		pr_err("MHL I2C Probe failed - no mem\n");
-		goto probe_exit;
+		goto probe_early_exit;
 	}
 	mhl_msm_state->i2c_client = client;
-
 	spin_lock_init(&mhl_state_lock);
-
 	i2c_set_clientdata(client, mhl_msm_state);
 	mhl_msm_state->mhl_data = client->dev.platform_data;
 	pr_debug("MHL: mhl_msm_state->mhl_data->irq=[%d]\n",
 		mhl_msm_state->mhl_data->irq);
 	msc_send_workqueue = create_workqueue("mhl_msc_cmd_queue");
 
-	if (!mhl_msm_state->mhl_data->mhl_enabled) {
-		pr_info("MHL Display not enabled\n");
-		return -ENODEV;
-	}
-
+	mhl_msm_state->cur_state = POWER_STATE_D0_MHL;
 	/* Init GPIO stuff here */
 	ret = mhl_sii_gpio_setup(1);
-	if (ret == -1) {
+	if (ret) {
 		pr_err("MHL: mhl_gpio_init has failed\n");
 		ret = -ENODEV;
+		goto probe_early_exit;
+	}
+	mhl_sii_power_on();
+	/* MHL SII 8334 chip specific init */
+	mhl_chip_init();
+	init_completion(&mhl_msm_state->rgnd_done);
+	/* Request IRQ stuff here */
+	pr_debug("MHL: mhl_msm_state->mhl_data->irq=[%d]\n",
+		mhl_msm_state->mhl_data->irq);
+	ret = request_threaded_irq(mhl_msm_state->mhl_data->irq, NULL,
+				   &mhl_tx_isr,
+				 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+				 "mhl_tx_isr", mhl_msm_state);
+	if (ret) {
+		pr_err("request_threaded_irq failed, status: %d\n",
+			ret);
 		goto probe_exit;
+	} else {
+		pr_debug("request_threaded_irq succeeded\n");
 	}
 
-	mhl_sii_power_on();
+	INIT_WORK(&mhl_msm_state->mhl_msc_send_work, mhl_msc_send_work);
+	INIT_LIST_HEAD(&mhl_msm_state->list_cmd);
+	mhl_msm_state->msc_command_put_work = list_cmd_put;
+	mhl_msm_state->msc_command_get_work = list_cmd_get;
+	init_completion(&mhl_msm_state->msc_cmd_done);
 
-	pr_debug("I2C PROBE successful\n");
+	pr_debug("i2c probe successful\n");
 	return 0;
 
 probe_exit:
@@ -574,6 +596,7 @@
 		kfree(mhl_msm_state->mhl_data);
 		mhl_msm_state->mhl_data = NULL;
 	}
+probe_early_exit:
 	return ret;
 }
 
@@ -636,7 +659,6 @@
 		ret = -ENOMEM;
 		goto init_exit;
 	}
-
 	mhl_msm_state->i2c_client = NULL;
 	ret = i2c_add_driver(&mhl_sii_i2c_driver);
 	if (ret) {
@@ -645,6 +667,7 @@
 		goto init_exit;
 	} else {
 		if (mhl_msm_state->i2c_client == NULL) {
+			i2c_del_driver(&mhl_sii_i2c_driver);
 			pr_err("MHL: I2C driver add failed\n");
 			ret = -ENODEV;
 			goto init_exit;
@@ -652,36 +675,9 @@
 		pr_info("MHL: I2C driver added\n");
 	}
 
-	/* Request IRQ stuff here */
-	pr_debug("MHL: mhl_msm_state->mhl_data->irq=[%d]\n",
-		mhl_msm_state->mhl_data->irq);
-	ret = request_threaded_irq(mhl_msm_state->mhl_data->irq, NULL,
-				   &mhl_tx_isr,
-				 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-				 "mhl_tx_isr", mhl_msm_state);
-	if (ret != 0) {
-		pr_err("request_threaded_irq failed, status: %d\n",
-			ret);
-		ret = -EACCES; /* Error code???? */
-		goto init_exit;
-	} else
-		pr_debug("request_threaded_irq succeeded\n");
-
-	INIT_WORK(&mhl_msm_state->mhl_msc_send_work, mhl_msc_send_work);
-	mhl_msm_state->cur_state = POWER_STATE_D0_MHL;
-	INIT_LIST_HEAD(&mhl_msm_state->list_cmd);
-	mhl_msm_state->msc_command_put_work = list_cmd_put;
-	mhl_msm_state->msc_command_get_work = list_cmd_get;
-	init_completion(&mhl_msm_state->msc_cmd_done);
-
-	/* MHL SII 8334 chip specific init */
-	mhl_chip_init();
-	init_completion(&mhl_msm_state->rgnd_done);
 	return 0;
-
 init_exit:
 	pr_err("Exiting from the init with err\n");
-	i2c_del_driver(&mhl_sii_i2c_driver);
 	if (!mhl_msm_state) {
 		kfree(mhl_msm_state);
 		mhl_msm_state = NULL;
@@ -846,9 +842,6 @@
 	if (0x02 == rgnd_imp) {
 		pr_debug("MHL: MHL DEVICE!!!\n");
 		mhl_i2c_reg_modify(TX_PAGE_3, 0x0018, BIT0, BIT0);
-		/*
-		 * Handling the MHL event in driver
-		 */
 		mhl_msm_state->mhl_mode = TRUE;
 		if (notify_usb_online)
 			notify_usb_online(1);
@@ -985,8 +978,7 @@
 	uint8_t intr_5_stat;
 
 	/*
-	 * Clear INT 5 ??
-	 * Probably need to revisit this later
+	 * Clear INT 5
 	 * INTR5 is related to FIFO underflow/overflow reset
 	 * which is handled in 8334 by auto FIFO reset
 	 */
@@ -1464,6 +1456,7 @@
 }
 
 
+/* MSC, RCP, RAP messages - mandatory for compliance */
 static void mhl_cbus_isr(void)
 {
 	uint8_t regval;
@@ -1477,7 +1470,10 @@
 	if (regval == 0xff)
 		return;
 
-	/* clear all interrupts that were raised even if we did not process */
+	/*
+	 * clear all interrupts that were raised
+	 * even if we did not process
+	 */
 	if (regval)
 		mhl_i2c_reg_write(TX_PAGE_CBUS, 0x08, regval);
 
diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
index e6e8aca..7d534ed 100644
--- a/drivers/video/msm/mipi_dsi.c
+++ b/drivers/video/msm/mipi_dsi.c
@@ -79,6 +79,14 @@
 
 	mdp4_overlay_dsi_state_set(ST_DSI_SUSPEND);
 
+	/* make sure dsi clk is on so that
+	 * dcs commands can be sent
+	 */
+	mipi_dsi_clk_cfg(1);
+
+	/* make sure dsi_cmd_mdp is idle */
+	mipi_dsi_cmd_mdp_busy();
+
 	/*
 	 * Desctiption: change to DSI_CMD_MODE since it needed to
 	 * tx DCS dsiplay off comamnd to panel
diff --git a/drivers/video/msm/mipi_dsi.h b/drivers/video/msm/mipi_dsi.h
index 2f691cf..a7832ed 100644
--- a/drivers/video/msm/mipi_dsi.h
+++ b/drivers/video/msm/mipi_dsi.h
@@ -344,6 +344,7 @@
 int mipi_dsi_cmdlist_put(struct dcs_cmd_req *cmdreq);
 struct dcs_cmd_req *mipi_dsi_cmdlist_get(void);
 void mipi_dsi_cmdlist_commit(int from_mdp);
+void mipi_dsi_cmd_mdp_busy(void);
 
 #ifdef CONFIG_FB_MSM_MDP303
 void update_lane_config(struct msm_panel_info *pinfo);
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
index 39a071b..d7992a7 100644
--- a/drivers/video/msm/mipi_dsi_host.c
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -1604,10 +1604,12 @@
 		mipi_dsi_cmd_mdp_busy();
 	}
 
-	if (req->flags && CMD_REQ_RX)
+	mipi_dsi_clk_cfg(1);
+	if (req->flags & CMD_REQ_RX)
 		mipi_dsi_cmdlist_rx(req);
 	else
 		mipi_dsi_cmdlist_tx(req);
+	mipi_dsi_clk_cfg(0);
 
 	mutex_unlock(&cmd_mutex);
 }
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index f68265a..68bcd5c 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -2079,10 +2079,6 @@
 	mutex_unlock(&client_ctx->msg_queue_lock);
 	vcd_status = vcd_close(client_ctx->vcd_handle);
 
-	if (vcd_status) {
-		mutex_unlock(&vid_dec_device_p->lock);
-		return false;
-	}
 	client_ctx->user_ion_client = NULL;
 	memset((void *)client_ctx, 0, sizeof(struct video_client_ctx));
 	vid_dec_device_p->num_clients--;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
index 53495e0..1281127 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
@@ -858,7 +858,7 @@
 	} else {
 		VCD_MSG_ERROR("Unsupported API in client state %d",
 				  cctxt->clnt_state.state);
-
+		vcd_destroy_client_context(cctxt);
 		rc = VCD_ERR_BAD_STATE;
 	}
 
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index e7cbb79..f6229b5 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -354,12 +354,15 @@
 
 /*
 
-	mdp_block_type defines the identifiers for each of pipes in MDP 4.3
+	mdp_block_type defines the identifiers for pipes in MDP 4.3 and up
 
 	MDP_BLOCK_RESERVED is provided for backward compatibility and is
 	deprecated. It corresponds to DMA_P. So MDP_BLOCK_DMA_P should be used
 	instead.
 
+	MDP_LOGICAL_BLOCK_DISP_0 identifies the display pipe which fb0 uses,
+	same for others.
+
 */
 
 enum {
@@ -374,6 +377,9 @@
 	MDP_BLOCK_DMA_S,
 	MDP_BLOCK_DMA_E,
 	MDP_BLOCK_OVERLAY_2,
+	MDP_LOGICAL_BLOCK_DISP_0 = 0x1000,
+	MDP_LOGICAL_BLOCK_DISP_1,
+	MDP_LOGICAL_BLOCK_DISP_2,
 	MDP_BLOCK_MAX,
 };
 
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 78b5b84..7b5aa0b 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -2074,6 +2074,7 @@
 #define V4L2_ENC_CMD_STOP       (1)
 #define V4L2_ENC_CMD_PAUSE      (2)
 #define V4L2_ENC_CMD_RESUME     (3)
+#define V4L2_ENC_QCOM_CMD_FLUSH  (4)
 
 /* Flags for V4L2_ENC_CMD_STOP */
 #define V4L2_ENC_CMD_STOP_AT_GOP_END    (1 << 0)
@@ -2111,6 +2112,9 @@
 #define V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT  (1 << 0)
 #define V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE (1 << 1)
 
+#define V4L2_QCOM_CMD_FLUSH_OUTPUT  (1 << 0)
+#define V4L2_QCOM_CMD_FLUSH_CAPTURE (1 << 1)
+
 /* Play format requirements (returned by the driver): */
 
 /* The decoder has no special format requirements */
diff --git a/sound/soc/msm/mdm9615.c b/sound/soc/msm/mdm9615.c
index b80a0a9..05786a7 100644
--- a/sound/soc/msm/mdm9615.c
+++ b/sound/soc/msm/mdm9615.c
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/mfd/wcd9xxx/core.h>
 #include <sound/core.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
@@ -42,10 +43,8 @@
 #define SAMPLE_RATE_8KHZ 8000
 #define SAMPLE_RATE_16KHZ 16000
 
-#define BOTTOM_SPK_AMP_POS	0x1
-#define BOTTOM_SPK_AMP_NEG	0x2
-#define TOP_SPK_AMP_POS		0x4
-#define TOP_SPK_AMP_NEG		0x8
+#define TOP_AND_BOTTOM_SPK_AMP_POS	0x1
+#define TOP_AND_BOTTOM_SPK_AMP_NEG	0x2
 
 #define GPIO_AUX_PCM_DOUT 23
 #define GPIO_AUX_PCM_DIN 22
@@ -62,6 +61,10 @@
 #define TABLA_MBHC_DEF_BUTTONS 8
 #define TABLA_MBHC_DEF_RLOADS 5
 
+#define PM8018_IRQ_BASE			(NR_MSM_IRQS + NR_GPIO_IRQS)
+#define JACK_DETECT_GPIO 3
+#define JACK_DETECT_INT PM8018_GPIO_IRQ(PM8018_IRQ_BASE, JACK_DETECT_GPIO)
+
 /*
  * Added for I2S
  */
@@ -245,16 +248,13 @@
 /*
  * Added for I2S
  */
-
-static u32 top_spk_pamp_gpio  = PM8018_GPIO_PM_TO_SYS(3);
-static u32 bottom_spk_pamp_gpio = PM8018_GPIO_PM_TO_SYS(5);
+static u32 top_and_bottom_spk_pamp_gpio = PM8018_GPIO_PM_TO_SYS(5);
 
 void *sif_virt_addr;
 void *secpcm_portslc_virt_addr;
 
 static int mdm9615_spk_control;
-static int mdm9615_ext_bottom_spk_pamp;
-static int mdm9615_ext_top_spk_pamp;
+static int mdm9615_ext_top_and_bottom_spk_pamp;
 static int mdm9615_slim_0_rx_ch = 1;
 static int mdm9615_slim_0_tx_ch = 1;
 
@@ -271,6 +271,14 @@
 static struct snd_soc_jack hs_jack;
 static struct snd_soc_jack button_jack;
 
+static bool hs_detect_use_gpio;
+module_param(hs_detect_use_gpio, bool, 0444);
+MODULE_PARM_DESC(hs_detect_use_gpio, "Use GPIO for headset detection");
+
+static bool hs_detect_use_firmware;
+module_param(hs_detect_use_firmware, bool, 0444);
+MODULE_PARM_DESC(hs_detect_use_firmware, "Use firmware for headset detection");
+
 static int mdm9615_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
 					bool dapm);
 static struct tabla_mbhc_config mbhc_cfg = {
@@ -300,39 +308,26 @@
 		.function       = PM_GPIO_FUNC_NORMAL,
 	};
 
-	if (spk_amp_gpio == bottom_spk_pamp_gpio) {
+	if (spk_amp_gpio == top_and_bottom_spk_pamp_gpio) {
 
-		ret = gpio_request(bottom_spk_pamp_gpio, "BOTTOM_SPK_AMP");
+		ret = gpio_request(top_and_bottom_spk_pamp_gpio,
+				   "TOP_AND_BOTTOM_SPK_AMP");
 		if (ret) {
-			pr_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n",
-				__func__, bottom_spk_pamp_gpio);
+			pr_err("%s: Error requesting TOP AND BOTTOM SPK AMP GPIO %u\n",
+				__func__, top_and_bottom_spk_pamp_gpio);
 			return;
 		}
-		ret = pm8xxx_gpio_config(bottom_spk_pamp_gpio, &param);
+		ret = pm8xxx_gpio_config(top_and_bottom_spk_pamp_gpio, &param);
 		if (ret)
-			pr_err("%s: Failed to configure Bottom Spk Ampl"
-				" gpio %u\n", __func__, bottom_spk_pamp_gpio);
+			pr_err("%s: Failed to configure Top & Bottom Spk Ampl\n"
+				"gpio %u\n", __func__,
+				top_and_bottom_spk_pamp_gpio);
 		else {
-			pr_debug("%s: enable Bottom spkr amp gpio\n", __func__);
-			gpio_direction_output(bottom_spk_pamp_gpio, 1);
+			pr_debug("%s: enable Top & Bottom spkr amp gpio\n",
+				 __func__);
+			gpio_direction_output(top_and_bottom_spk_pamp_gpio, 1);
 		}
 
-	} else if (spk_amp_gpio == top_spk_pamp_gpio) {
-
-		ret = gpio_request(top_spk_pamp_gpio, "TOP_SPK_AMP");
-		if (ret) {
-			pr_err("%s: Error requesting GPIO %d\n", __func__,
-				top_spk_pamp_gpio);
-			return;
-		}
-		ret = pm8xxx_gpio_config(top_spk_pamp_gpio, &param);
-		if (ret)
-			pr_err("%s: Failed to configure Top Spk Ampl"
-				" gpio %u\n", __func__, top_spk_pamp_gpio);
-		else {
-			pr_debug("%s: enable Top spkr amp gpio\n", __func__);
-			gpio_direction_output(top_spk_pamp_gpio, 1);
-		}
 	} else {
 		pr_err("%s: ERROR : Invalid External Speaker Ampl GPIO."
 			" gpio = %u\n", __func__, spk_amp_gpio);
@@ -342,49 +337,30 @@
 
 static void mdm9615_ext_spk_power_amp_on(u32 spk)
 {
-	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {
-
-		if ((mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
-			(mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {
-
-			pr_debug("%s() External Bottom Speaker Ampl already "
+	if (spk & (TOP_AND_BOTTOM_SPK_AMP_POS | TOP_AND_BOTTOM_SPK_AMP_NEG)) {
+		if ((mdm9615_ext_top_and_bottom_spk_pamp &
+		     TOP_AND_BOTTOM_SPK_AMP_POS) &&
+		    (mdm9615_ext_top_and_bottom_spk_pamp &
+		     TOP_AND_BOTTOM_SPK_AMP_NEG)) {
+			pr_debug("%s() External Speaker Ampl already "
 				"turned on. spk = 0x%08x\n", __func__, spk);
 			return;
 		}
 
-		mdm9615_ext_bottom_spk_pamp |= spk;
+		mdm9615_ext_top_and_bottom_spk_pamp |= spk;
 
-		if ((mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
-			(mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {
-
-			mdm9615_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio);
-			pr_debug("%s: slepping 4 ms after turning on external "
-				" Bottom Speaker Ampl\n", __func__);
+		if ((mdm9615_ext_top_and_bottom_spk_pamp &
+		     TOP_AND_BOTTOM_SPK_AMP_POS) &&
+		    (mdm9615_ext_top_and_bottom_spk_pamp &
+		     TOP_AND_BOTTOM_SPK_AMP_NEG)) {
+			mdm9615_enable_ext_spk_amp_gpio(
+					top_and_bottom_spk_pamp_gpio);
+			pr_debug("%s: slepping 4 ms after turning on external\n"
+				"Speaker Ampl\n", __func__);
 			usleep_range(4000, 4000);
 		}
 
-	} else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {
-
-		if ((mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
-			(mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {
-
-			pr_debug("%s() External Top Speaker Ampl already"
-				"turned on. spk = 0x%08x\n", __func__, spk);
-			return;
-		}
-
-		mdm9615_ext_top_spk_pamp |= spk;
-
-		if ((mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
-			(mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {
-
-			mdm9615_enable_ext_spk_amp_gpio(top_spk_pamp_gpio);
-			pr_debug("%s: sleeping 4 ms after turning on "
-				" external Top Speaker Ampl\n", __func__);
-			usleep_range(4000, 4000);
-		}
-	} else  {
-
+	} else {
 		pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n",
 			__func__, spk);
 		return;
@@ -393,33 +369,20 @@
 
 static void mdm9615_ext_spk_power_amp_off(u32 spk)
 {
-	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {
+	if (spk & (TOP_AND_BOTTOM_SPK_AMP_POS | TOP_AND_BOTTOM_SPK_AMP_NEG)) {
 
-		if (!mdm9615_ext_bottom_spk_pamp)
+		if (!mdm9615_ext_top_and_bottom_spk_pamp)
 			return;
 
-		gpio_direction_output(bottom_spk_pamp_gpio, 0);
-		gpio_free(bottom_spk_pamp_gpio);
-		mdm9615_ext_bottom_spk_pamp = 0;
+		gpio_direction_output(top_and_bottom_spk_pamp_gpio, 0);
+		gpio_free(top_and_bottom_spk_pamp_gpio);
+		mdm9615_ext_top_and_bottom_spk_pamp = 0;
 
 		pr_debug("%s: sleeping 4 ms after turning off external Bottom"
 			" Speaker Ampl\n", __func__);
 
 		usleep_range(4000, 4000);
 
-	} else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {
-
-		if (!mdm9615_ext_top_spk_pamp)
-			return;
-
-		gpio_direction_output(top_spk_pamp_gpio, 0);
-		gpio_free(top_spk_pamp_gpio);
-		mdm9615_ext_top_spk_pamp = 0;
-
-		pr_debug("%s: sleeping 4 ms after turning off external Top"
-			" Spkaker Ampl\n", __func__);
-
-		usleep_range(4000, 4000);
 	} else  {
 
 		pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n",
@@ -434,15 +397,11 @@
 
 	pr_debug("%s: mdm9615_spk_control = %d", __func__, mdm9615_spk_control);
 	if (mdm9615_spk_control == MDM9615_SPK_ON) {
-		snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
-		snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
-		snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
-		snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
+		snd_soc_dapm_enable_pin(dapm, "Ext Spk Pos");
+		snd_soc_dapm_enable_pin(dapm, "Ext Spk Neg");
 	} else {
-		snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos");
-		snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg");
-		snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos");
-		snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg");
+		snd_soc_dapm_disable_pin(dapm, "Ext Spk Pos");
+		snd_soc_dapm_disable_pin(dapm, "Ext Spk Neg");
 	}
 
 	snd_soc_dapm_sync(dapm);
@@ -474,14 +433,12 @@
 	pr_debug("%s() %x\n", __func__, SND_SOC_DAPM_EVENT_ON(event));
 
 	if (SND_SOC_DAPM_EVENT_ON(event)) {
-		if (!strncmp(w->name, "Ext Spk Bottom Pos", 18))
-			mdm9615_ext_spk_power_amp_on(BOTTOM_SPK_AMP_POS);
-		else if (!strncmp(w->name, "Ext Spk Bottom Neg", 18))
-			mdm9615_ext_spk_power_amp_on(BOTTOM_SPK_AMP_NEG);
-		else if (!strncmp(w->name, "Ext Spk Top Pos", 15))
-			mdm9615_ext_spk_power_amp_on(TOP_SPK_AMP_POS);
-		else if  (!strncmp(w->name, "Ext Spk Top Neg", 15))
-			mdm9615_ext_spk_power_amp_on(TOP_SPK_AMP_NEG);
+		if (!strncmp(w->name, "Ext Spk Pos", 11))
+			mdm9615_ext_spk_power_amp_on(
+					TOP_AND_BOTTOM_SPK_AMP_POS);
+		else if (!strncmp(w->name, "Ext Spk Neg", 11))
+			mdm9615_ext_spk_power_amp_on(
+					TOP_AND_BOTTOM_SPK_AMP_NEG);
 		else {
 			pr_err("%s() Invalid Speaker Widget = %s\n",
 					__func__, w->name);
@@ -489,14 +446,12 @@
 		}
 
 	} else {
-		if (!strncmp(w->name, "Ext Spk Bottom Pos", 18))
-			mdm9615_ext_spk_power_amp_off(BOTTOM_SPK_AMP_POS);
-		else if (!strncmp(w->name, "Ext Spk Bottom Neg", 18))
-			mdm9615_ext_spk_power_amp_off(BOTTOM_SPK_AMP_NEG);
-		else if (!strncmp(w->name, "Ext Spk Top Pos", 15))
-			mdm9615_ext_spk_power_amp_off(TOP_SPK_AMP_POS);
-		else if  (!strncmp(w->name, "Ext Spk Top Neg", 15))
-			mdm9615_ext_spk_power_amp_off(TOP_SPK_AMP_NEG);
+		if (!strncmp(w->name, "Ext Spk Pos", 11))
+			mdm9615_ext_spk_power_amp_off(
+					TOP_AND_BOTTOM_SPK_AMP_POS);
+		else if (!strncmp(w->name, "Ext Spk Neg", 11))
+			mdm9615_ext_spk_power_amp_off(
+					TOP_AND_BOTTOM_SPK_AMP_NEG);
 		else {
 			pr_err("%s() Invalid Speaker Widget = %s\n",
 					__func__, w->name);
@@ -557,11 +512,8 @@
 	SND_SOC_DAPM_SUPPLY("MCLK",  SND_SOC_NOPM, 0, 0,
 	mdm9615_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_SPK("Ext Spk Bottom Pos", mdm9615_spkramp_event),
-	SND_SOC_DAPM_SPK("Ext Spk Bottom Neg", mdm9615_spkramp_event),
-
-	SND_SOC_DAPM_SPK("Ext Spk Top Pos", mdm9615_spkramp_event),
-	SND_SOC_DAPM_SPK("Ext Spk Top Neg", mdm9615_spkramp_event),
+	SND_SOC_DAPM_SPK("Ext Spk Pos", mdm9615_spkramp_event),
+	SND_SOC_DAPM_SPK("Ext Spk Neg", mdm9615_spkramp_event),
 
 	SND_SOC_DAPM_MIC("Handset Mic", NULL),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
@@ -584,11 +536,11 @@
 	{"LDO_H", NULL, "MCLK"},
 
 	/* Speaker path */
-	{"Ext Spk Bottom Pos", NULL, "LINEOUT1"},
-	{"Ext Spk Bottom Neg", NULL, "LINEOUT3"},
+	{"Ext Spk Pos", NULL, "LINEOUT1"},
+	{"Ext Spk Neg", NULL, "LINEOUT3"},
 
-	{"Ext Spk Top Pos", NULL, "LINEOUT2"},
-	{"Ext Spk Top Neg", NULL, "LINEOUT4"},
+	{"Ext Spk Pos", NULL, "LINEOUT2"},
+	{"Ext Spk Neg", NULL, "LINEOUT4"},
 
 	/* Microphone path */
 	{"AMIC1", NULL, "MIC BIAS1 External"},
@@ -1006,10 +958,8 @@
 
 	snd_soc_dapm_add_routes(dapm, common_audio_map,
 		ARRAY_SIZE(common_audio_map));
-	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
-	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
-	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
-	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
+	snd_soc_dapm_enable_pin(dapm, "Ext Spk Pos");
+	snd_soc_dapm_enable_pin(dapm, "Ext Spk Neg");
 
 	snd_soc_dapm_sync(dapm);
 
@@ -1510,6 +1460,13 @@
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct pm_gpio jack_gpio_cfg = {
+		.direction = PM_GPIO_DIR_IN,
+		.pull = PM_GPIO_PULL_NO,
+		.function = PM_GPIO_FUNC_NORMAL,
+		.vin_sel = 2,
+		.inv_int_pol = 0,
+	};
 
 	pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));
 
@@ -1521,10 +1478,8 @@
 	snd_soc_dapm_add_routes(dapm, common_audio_map,
 		ARRAY_SIZE(common_audio_map));
 
-	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
-	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
-	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
-	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
+	snd_soc_dapm_enable_pin(dapm, "Ext Spk Pos");
+	snd_soc_dapm_enable_pin(dapm, "Ext Spk Neg");
 
 	snd_soc_dapm_sync(dapm);
 
@@ -1545,6 +1500,22 @@
 	}
 	codec_clk = clk_get(cpu_dai->dev, "osr_clk");
 
+	if (hs_detect_use_gpio) {
+		mbhc_cfg.gpio = PM8018_GPIO_PM_TO_SYS(JACK_DETECT_GPIO);
+		mbhc_cfg.gpio_irq = JACK_DETECT_INT;
+	}
+
+	if (mbhc_cfg.gpio) {
+		err = pm8xxx_gpio_config(mbhc_cfg.gpio, &jack_gpio_cfg);
+		if (err) {
+			pr_err("%s: pm8xxx_gpio_config JACK_DETECT failed %d\n",
+			       __func__, err);
+			return err;
+		}
+	}
+
+	mbhc_cfg.read_fw_bin = hs_detect_use_firmware;
+
 	err = tabla_hs_detect(codec, &mbhc_cfg);
 
 	return err;
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 011912e..16a4aaa 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -199,7 +199,7 @@
 					SNDRV_PCM_RATE_KNOT),
 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
 			.channels_min = 1,
-			.channels_max = 6,
+			.channels_max = 8,
 			.rate_min =	8000,
 			.rate_max = 48000,
 		},
@@ -225,7 +225,7 @@
 					SNDRV_PCM_RATE_KNOT),
 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
 			.channels_min = 1,
-			.channels_max = 6,
+			.channels_max = 8,
 			.rate_min =	8000,
 			.rate_max = 48000,
 		},
@@ -240,7 +240,7 @@
 					SNDRV_PCM_RATE_KNOT),
 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
 			.channels_min = 1,
-			.channels_max = 6,
+			.channels_max = 8,
 			.rate_min =	8000,
 			.rate_max = 48000,
 		},
@@ -255,7 +255,7 @@
 					SNDRV_PCM_RATE_KNOT),
 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
 			.channels_min = 1,
-			.channels_max = 6,
+			.channels_max = 8,
 			.rate_min =	8000,
 			.rate_max = 48000,
 		},
diff --git a/sound/soc/msm/msm-multi-ch-pcm-q6.c b/sound/soc/msm/msm-multi-ch-pcm-q6.c
index a33a01f..5b0759c 100644
--- a/sound/soc/msm/msm-multi-ch-pcm-q6.c
+++ b/sound/soc/msm/msm-multi-ch-pcm-q6.c
@@ -47,11 +47,11 @@
 static struct snd_msm_volume multi_ch_pcm_audio = {NULL, 0x2000};
 
 #define PLAYBACK_NUM_PERIODS		8
-#define PLAYBACK_MAX_PERIOD_SIZE	4032
+#define PLAYBACK_MAX_PERIOD_SIZE	12288
 #define PLAYBACK_MIN_PERIOD_SIZE        256
 #define CAPTURE_NUM_PERIODS		16
 #define CAPTURE_MIN_PERIOD_SIZE		320
-#define CAPTURE_MAX_PERIOD_SIZE		5376
+#define CAPTURE_MAX_PERIOD_SIZE		12288
 
 static struct snd_pcm_hardware msm_pcm_hardware_capture = {
 	.info =                 (SNDRV_PCM_INFO_MMAP |
@@ -303,8 +303,8 @@
 
 	pr_debug("Samp_rate = %d\n", prtd->samp_rate);
 	pr_debug("Channel = %d\n", prtd->channel_mode);
-	ret = q6asm_enc_cfg_blk_pcm(prtd->audio_client, prtd->samp_rate,
-					prtd->channel_mode);
+	ret = q6asm_enc_cfg_blk_multi_ch_pcm(prtd->audio_client,
+		 prtd->samp_rate, prtd->channel_mode);
 	if (ret < 0)
 		pr_debug("%s: cmd cfg pcm was block failed", __func__);
 
@@ -399,7 +399,8 @@
 	/* Capture path */
 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 		runtime->hw = msm_pcm_hardware_capture;
-		ret = q6asm_open_read(prtd->audio_client, FORMAT_LINEAR_PCM);
+		ret = q6asm_open_read(prtd->audio_client,
+				FORMAT_MULTI_CHANNEL_LINEAR_PCM);
 		if (ret < 0) {
 			pr_err("%s: pcm in open failed\n", __func__);
 			q6asm_audio_client_free(prtd->audio_client);
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 1aac158..3a226b4 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -1885,7 +1885,16 @@
 	enc_cfg.enc_blk.cfg.mpcm.sample_rate = rate;
 	enc_cfg.enc_blk.cfg.mpcm.is_signed = 1;
 	enc_cfg.enc_blk.cfg.mpcm.is_interleaved = 1;
-	if (channels == 2) {
+	if (channels == 1) {
+		enc_cfg.enc_blk.cfg.mpcm.channel_mapping[0] = PCM_CHANNEL_FL;
+		enc_cfg.enc_blk.cfg.mpcm.channel_mapping[1] = 0;
+		enc_cfg.enc_blk.cfg.mpcm.channel_mapping[2] = 0;
+		enc_cfg.enc_blk.cfg.mpcm.channel_mapping[3] = 0;
+		enc_cfg.enc_blk.cfg.mpcm.channel_mapping[4] = 0;
+		enc_cfg.enc_blk.cfg.mpcm.channel_mapping[5] = 0;
+		enc_cfg.enc_blk.cfg.mpcm.channel_mapping[6] = 0;
+		enc_cfg.enc_blk.cfg.mpcm.channel_mapping[7] = 0;
+	} else if (channels == 2) {
 		enc_cfg.enc_blk.cfg.mpcm.channel_mapping[0] = PCM_CHANNEL_FL;
 		enc_cfg.enc_blk.cfg.mpcm.channel_mapping[1] = PCM_CHANNEL_FR;
 		enc_cfg.enc_blk.cfg.mpcm.channel_mapping[2] = 0;
@@ -2040,6 +2049,11 @@
 	} else if (num_channels == 2) {
 		channel_mapping[0] = PCM_CHANNEL_FL;
 		channel_mapping[1] = PCM_CHANNEL_FR;
+	} else if (num_channels == 4) {
+		channel_mapping[0] = PCM_CHANNEL_FL;
+		channel_mapping[1] = PCM_CHANNEL_FR;
+		channel_mapping[1] = PCM_CHANNEL_LB;
+		channel_mapping[1] = PCM_CHANNEL_RB;
 	} else if (num_channels == 6) {
 		channel_mapping[0] = PCM_CHANNEL_FC;
 		channel_mapping[1] = PCM_CHANNEL_FL;
@@ -2047,6 +2061,15 @@
 		channel_mapping[3] = PCM_CHANNEL_LB;
 		channel_mapping[4] = PCM_CHANNEL_RB;
 		channel_mapping[5] = PCM_CHANNEL_LFE;
+	} else if (num_channels == 8) {
+		channel_mapping[0] = PCM_CHANNEL_FC;
+		channel_mapping[1] = PCM_CHANNEL_FL;
+		channel_mapping[2] = PCM_CHANNEL_FR;
+		channel_mapping[3] = PCM_CHANNEL_LB;
+		channel_mapping[4] = PCM_CHANNEL_RB;
+		channel_mapping[5] = PCM_CHANNEL_LFE;
+		channel_mapping[6] = PCM_CHANNEL_FLC;
+		channel_mapping[7] = PCM_CHANNEL_FRC;
 	} else {
 		pr_err("%s: ERROR.unsupported num_ch = %u\n", __func__,
 				num_channels);
@@ -2303,6 +2326,11 @@
 	} else if (channels == 2) {
 		channel_mapping[0] = PCM_CHANNEL_FL;
 		channel_mapping[1] = PCM_CHANNEL_FR;
+	} else if (channels == 4) {
+		channel_mapping[0] = PCM_CHANNEL_FL;
+		channel_mapping[1] = PCM_CHANNEL_FR;
+		channel_mapping[1] = PCM_CHANNEL_LB;
+		channel_mapping[1] = PCM_CHANNEL_RB;
 	} else if (channels == 6) {
 		channel_mapping[0] = PCM_CHANNEL_FC;
 		channel_mapping[1] = PCM_CHANNEL_FL;
@@ -2310,6 +2338,15 @@
 		channel_mapping[3] = PCM_CHANNEL_LB;
 		channel_mapping[4] = PCM_CHANNEL_RB;
 		channel_mapping[5] = PCM_CHANNEL_LFE;
+	} else if (channels == 8) {
+		channel_mapping[0] = PCM_CHANNEL_FC;
+		channel_mapping[1] = PCM_CHANNEL_FL;
+		channel_mapping[2] = PCM_CHANNEL_FR;
+		channel_mapping[3] = PCM_CHANNEL_LB;
+		channel_mapping[4] = PCM_CHANNEL_RB;
+		channel_mapping[5] = PCM_CHANNEL_LFE;
+		channel_mapping[6] = PCM_CHANNEL_FLC;
+		channel_mapping[7] = PCM_CHANNEL_FRC;
 	} else {
 		pr_err("%s: ERROR.unsupported num_ch = %u\n", __func__,
 				channels);
diff --git a/tools/perf/util/scripting-engines/trace-event-json-export.c b/tools/perf/util/scripting-engines/trace-event-json-export.c
index 3fb6da7..2aec459 100644
--- a/tools/perf/util/scripting-engines/trace-event-json-export.c
+++ b/tools/perf/util/scripting-engines/trace-event-json-export.c
@@ -53,8 +53,8 @@
 
 	value = eval_flag(field_value);
 
-	fprintf(ofp , ",\n[\"%s\",%d,{\"field\":\"%s\",\"value\":%llu,
-			\"name\":\"%s\"}]",
+	fprintf(ofp,
+		",\n[\"%s\",%d,{\"field\":\"%s\",\"value\":%llu,\"name\":\"%s\"}]",
 		handler_name, id, field_name, value, field_str);
 }
 
@@ -77,12 +77,12 @@
 {
 	if (field_type == PRINT_FLAGS) {
 		const char *handler_name = "define_flag_field";
-		fprintf(ofp , ",\n[\"%s\",%d,{\"field\":\"%s\",
-				\"delim\":\"%s\"}]",
-				handler_name, id, field_name, delim);
+		fprintf(ofp,
+			",\n[\"%s\",%d,{\"field\":\"%s\",\"delim\":\"%s\"}]",
+			handler_name, id, field_name, delim);
 	} else {
 		const char *handler_name = "define_symbol_field";
-		fprintf(ofp , ",\n[\"%s\",%d,{\"field\":\"%s\"}]",
+		fprintf(ofp, ",\n[\"%s\",%d,{\"field\":\"%s\"}]",
 				handler_name, id, field_name);
 	}
 }
@@ -140,27 +140,27 @@
 	const char *handler_name = "define_event";
 	struct format_field *field = 0;
 
-	fprintf(ofp , ",\n[\"%s\",%d,{\"system\":\"%s\",
-			\"name\":\"%s\",\"args\":{",
+	fprintf(ofp,
+		",\n[\"%s\",%d,{\"system\":\"%s\",\"name\":\"%s\",\"args\":{",
 			handler_name, event->id, ev_system, ev_name);
 
-	fprintf(ofp , "%s\"%s\":%d", prefix(indx), "common_s", indx);
+	fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_s", indx);
 	indx++;
-	fprintf(ofp , "%s\"%s\":%d", prefix(indx), "common_ns", indx);
+	fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_ns", indx);
 	indx++;
-	fprintf(ofp , "%s\"%s\":%d", prefix(indx), "common_cpu", indx);
+	fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_cpu", indx);
 	indx++;
-	fprintf(ofp , "%s\"%s\":%d", prefix(indx), "common_comm", indx);
+	fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_comm", indx);
 	indx++;
 	for (field = event->format.common_fields; field; field = field->next) {
-		fprintf(ofp , "%s\"%s\":%d", prefix(indx), field->name, indx);
+		fprintf(ofp, "%s\"%s\":%d", prefix(indx), field->name, indx);
 		indx++;
 	}
 	for (field = event->format.fields; field; field = field->next) {
-		fprintf(ofp , "%s\"%s\":%d", prefix(indx), field->name, indx);
+		fprintf(ofp, "%s\"%s\":%d", prefix(indx), field->name, indx);
 		indx++;
 	}
-	fprintf(ofp , "}}]");
+	fprintf(ofp, "}}]");
 }
 
 static inline struct event *find_cache_event(int type)
@@ -191,14 +191,14 @@
 			offset &= 0xffff;
 		} else
 			offset = field->offset;
-		fprintf(ofp , "%s\"%s\"", prefix(indx), (char *)data + offset);
+		fprintf(ofp, "%s\"%s\"", prefix(indx), (char *)data + offset);
 	} else { /* FIELD_IS_NUMERIC */
 		val = read_size(data + field->offset, field->size);
 		if (field->flags & FIELD_IS_SIGNED)
-			fprintf(ofp , "%s%lld", prefix(indx),
+			fprintf(ofp, "%s%lld", prefix(indx),
 					(long long int) val);
 		else
-			fprintf(ofp , "%s%llu", prefix(indx), val);
+			fprintf(ofp, "%s%llu", prefix(indx), val);
 	}
 }
 
@@ -227,7 +227,7 @@
 	s = nsecs / NSECS_PER_SEC;
 	ns = nsecs - s * NSECS_PER_SEC;
 
-	fprintf(ofp , ",\n[\"event\",%d,[%lu,%lu,%d,\"%s\"",
+	fprintf(ofp, ",\n[\"event\",%d,[%lu,%lu,%d,\"%s\"",
 			type, s, ns, cpu, comm);
 
 	indx += 4;
@@ -258,7 +258,7 @@
 	} else
 		ofp = stdout;
 
-	fprintf(ofp , "[[\"trace_start\"]");
+	fprintf(ofp, "[[\"trace_start\"]");
 
 	return err;
 }
@@ -270,7 +270,7 @@
 {
 	int err = 0;
 
-	fprintf(ofp , ",\n[\"trace_end\"]]");
+	fprintf(ofp, ",\n[\"trace_end\"]]");
 
 	return err;
 }
@@ -288,14 +288,14 @@
 		fprintf(stderr, "couldn't open %s\n", fname);
 		return -EBADF;
 	}
-	fprintf(ofp ,  "[[\"generate_start\"]");
+	fprintf(ofp, "[[\"generate_start\"]");
 
 	while ((event = trace_find_next_event(event))) {
 		define_event(event);
 		define_event_symbols(event, event->print_fmt.args);
 	}
 
-	fprintf(ofp ,  ",\n[\"generate_end\"]]");
+	fprintf(ofp, ",\n[\"generate_end\"]]");
 
 	fclose(ofp);