Merge "arm/dt: msm8974: Add charger devices"
diff --git a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
index 1f7e488..7731b33 100644
--- a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
@@ -39,17 +39,17 @@
 		qcom,mdss-pan-dsi-dma-tr = <0x04>;
 		qcom,mdss-pan-frame-rate = <60>;
 		qcom,panel-phy-regulatorSettings = [03 01 01 00  /* Regualotor settings */
-						    20 00 01 00];
+						    20 00 01];
 		qcom,panel-phy-timingSettings = [69 29 1f 00 55 55
 						    19 2a 2a 03 04 00];
 		qcom,panel-phy-strengthCtrl = [77 06];
-		qcom,panel-phy-bistCtrl = [00 00 01 ff           /* BIST Ctrl settings */
+		qcom,panel-phy-bistCtrl = [00 00 b1 ff           /* BIST Ctrl settings */
 					   00 00];
-		qcom,panel-phy-laneConfig = [05 c2 00 00 00 00 00 01 75 /* lane0 config */
-					     05 c2 00 00 00 00 00 01 75 /* lane1 config */
-					     05 c2 00 00 00 00 00 01 75 /* lane2 config */
-					     05 c2 00 00 00 00 00 01 75 /* lane3 config */
-					     00 c2 00 00 00 00 00 01 97]; /* Clk ln config */
+		qcom,panel-phy-laneConfig = [00 c2 45 00 00 00 00 01 75 /* lane0 config */
+					     00 c2 45 00 00 00 00 01 75 /* lane1 config */
+					     00 c2 45 00 00 00 00 01 75 /* lane2 config */
+					     00 c2 45 00 00 00 00 01 75 /* lane3 config */
+					     00 02 45 00 00 00 00 01 97]; /* Clk ln config */
 
 		qcom,panel-on-cmds = [23 01 00 00 0a 02 b0 00
 					23 01 00 00 0a 02 b2 00
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index ffd4518..da0e1e5 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -60,6 +60,10 @@
 			<244800 133330000>;
 	};
 
+	qcom,wfd {
+		compatible = "qcom,msm-wfd";
+	};
+
 	serial@f991f000 {
 		compatible = "qcom,msm-lsuart-v14";
 		reg = <0xf991f000 0x1000>;
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 7b7adca..8ad3b66 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -55,7 +55,7 @@
 		compatible = "qcom,msm_sps";
 		reg = <0xf9984000 0x15000>,
 		      <0xf9999000 0xb000>,
-		      <0xfe800000 0x4800>;
+		      <0xfe803000 0x4800>;
 		interrupts = <0 94 0>;
 		qcom,device-type = <2>;
 	};
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 1a02fce..d5e4638 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -1809,6 +1809,10 @@
 	in_global_reset = 0;
 	vote_dfab();
 	if (!power_management_only_mode) {
+		sps_disconnect(bam_tx_pipe);
+		sps_disconnect(bam_rx_pipe);
+		__memzero(rx_desc_mem_buf.base, rx_desc_mem_buf.size);
+		__memzero(tx_desc_mem_buf.base, tx_desc_mem_buf.size);
 		i = sps_device_reset(a2_device_handle);
 		if (i)
 			pr_err("%s: device reset failed rc = %d\n", __func__,
@@ -1861,12 +1865,6 @@
 
 	/* tear down BAM connection */
 	INIT_COMPLETION(bam_connection_completion);
-	if (!power_management_only_mode) {
-		sps_disconnect(bam_tx_pipe);
-		sps_disconnect(bam_rx_pipe);
-		__memzero(rx_desc_mem_buf.base, rx_desc_mem_buf.size);
-		__memzero(tx_desc_mem_buf.base, tx_desc_mem_buf.size);
-	}
 	unvote_dfab();
 
 	mutex_lock(&bam_rx_pool_mutexlock);
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index 4d147c3..14e1185 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -67,7 +67,9 @@
 static int pll_byte_clk_rate;
 static int pll_pclk_rate;
 static int pll_initialized;
+static int pll_enabled;
 static struct clk *mdss_dsi_ahb_clk;
+static unsigned long dsi_pll_rate;
 
 static void __iomem *hdmi_phy_base;
 static void __iomem *hdmi_phy_pll_base;
@@ -135,6 +137,7 @@
 	int pll_divcfg1, pll_divcfg2;
 	int half_bitclk_rate;
 
+	pr_debug("%s:\n", __func__);
 	if (pll_initialized)
 		return 0;
 
@@ -193,10 +196,13 @@
 	REG_W(0x00, mdss_dsi_base + 0x0290); /* CAL CFG9 */
 	REG_W(0x20, mdss_dsi_base + 0x029c); /* EFUSE CFG */
 
+	dsi_pll_rate = rate;
+
 	pll_byte_clk_rate = 53000000;
 	pll_pclk_rate = 105000000;
 
 	clk_disable(mdss_dsi_ahb_clk);
+	pr_debug("%s: **** PLL initialized success\n", __func__);
 	pll_initialized = 1;
 
 	return 0;
@@ -206,11 +212,19 @@
 {
 	u32 status;
 	u32 max_reads, timeout_us;
-	static int pll_enabled;
+	int i;
 
 	if (pll_enabled)
 		return 0;
 
+	if (!pll_initialized) {
+		if (dsi_pll_rate)
+			mdss_dsi_pll_byte_set_rate(c, dsi_pll_rate);
+		else
+			pr_err("%s: Calling clk_en before set_rate\n",
+						__func__);
+	}
+
 	if (!mdss_dsi_ahb_clk) {
 		pr_err("%s: mdss_dsi_ahb_clk not initialized\n",
 				__func__);
@@ -218,26 +232,39 @@
 	}
 
 	clk_enable(mdss_dsi_ahb_clk);
-	/* PLL power up */
-	REG_W(0x01, mdss_dsi_base + 0x0220); /* GLB CFG */
-	REG_W(0x05, mdss_dsi_base + 0x0220); /* GLB CFG */
-	udelay(20);
-	REG_W(0x07, mdss_dsi_base + 0x0220); /* GLB CFG */
-	udelay(20);
-	REG_W(0x0f, mdss_dsi_base + 0x0220); /* GLB CFG */
 
-	/* poll for PLL ready status */
-	max_reads = 20;
-	timeout_us = 100;
-	if (readl_poll_timeout_noirq((mdss_dsi_base + 0x02c0),
-			   status,
-			   ((status & 0x01) == 1),
-				     max_reads, timeout_us)) {
+	/* PLL power up */
+	for (i = 0; i < 3; i++) {
+		REG_W(0x01, mdss_dsi_base + 0x0220); /* GLB CFG */
+		REG_W(0x05, mdss_dsi_base + 0x0220); /* GLB CFG */
+		udelay(20);
+		REG_W(0x07, mdss_dsi_base + 0x0220); /* GLB CFG */
+		udelay(20);
+		REG_W(0x0f, mdss_dsi_base + 0x0220); /* GLB CFG */
+
+		/* poll for PLL ready status */
+		max_reads = 20;
+		timeout_us = 100;
+		if (readl_poll_timeout_noirq((mdss_dsi_base + 0x02c0),
+				   status,
+				   ((status & 0x01) == 1),
+					     max_reads, timeout_us)) {
+			pr_debug("%s: DSI PLL status=%x failed to Lock\n",
+			       __func__, status);
+			pr_debug("%s:Trying to power UP PLL again\n",
+			       __func__);
+		} else
+			break;
+	}
+
+	if ((status & 0x01) != 1) {
 		pr_err("%s: DSI PLL status=%x failed to Lock\n",
 		       __func__, status);
 		clk_disable(mdss_dsi_ahb_clk);
 		return -EINVAL;
 	}
+
+	pr_debug("%s: **** PLL Lock success\n", __func__);
 	clk_disable(mdss_dsi_ahb_clk);
 	pll_enabled = 1;
 
@@ -253,6 +280,9 @@
 	clk_enable(mdss_dsi_ahb_clk);
 	writel_relaxed(0x00, mdss_dsi_base + 0x0220); /* GLB CFG */
 	clk_disable(mdss_dsi_ahb_clk);
+	pr_debug("%s: **** disable pll Initialize\n", __func__);
+	pll_initialized = 0;
+	pll_enabled = 0;
 }
 
 void hdmi_pll_disable(void)
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index a7e34d9..2e4b756 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -471,13 +471,20 @@
 
 	pr_debug("%s[%p]:\n", __func__, audio);
 
-	mutex_lock(&audio->write_lock);
 	audio->eos_rsp = 0;
 
+	pr_debug("%s[%p]Wait for write done from DSP\n", __func__, audio);
 	rc = wait_event_interruptible(audio->write_wait,
 					(list_empty(&audio->out_queue)) ||
 					audio->wflush || audio->stopped);
 
+	if (audio->stopped || audio->wflush) {
+		pr_debug("%s[%p]: Audio Flushed or Stopped,this is not EOS\n"
+			, __func__, audio);
+		audio->wflush = 0;
+		rc = -EBUSY;
+	}
+
 	if (rc < 0) {
 		pr_err("%s[%p]: wait event for list_empty failed, rc = %d\n",
 			__func__, audio, rc);
@@ -485,11 +492,14 @@
 	}
 
 	rc = q6asm_cmd(audio->ac, CMD_EOS);
+	pr_debug("%s[%p]: EOS cmd sent to DSP\n", __func__, audio);
 
 	if (rc < 0)
 		pr_err("%s[%p]: q6asm_cmd failed, rc = %d",
 			__func__, audio, rc);
 
+	pr_debug("%s[%p]: wait for RENDERED_EOS from DSP\n"
+		, __func__, audio);
 	rc = wait_event_interruptible(audio->write_wait,
 					(audio->eos_rsp || audio->wflush ||
 					audio->stopped));
@@ -500,22 +510,18 @@
 		goto done;
 	}
 
-	if (audio->eos_rsp == 1) {
-		rc = audio_aio_enable(audio);
-		if (rc)
-			pr_err("%s[%p]: audio enable failed\n",
-				__func__, audio);
-		else {
-			audio->drv_status &= ~ADRV_STATUS_PAUSE;
-			audio->enabled = 1;
-		}
+	if (audio->stopped || audio->wflush) {
+		audio->wflush = 0;
+		pr_debug("%s[%p]: Audio Flushed or Stopped,this is not EOS\n"
+			, __func__, audio);
+		rc = -EBUSY;
 	}
 
-	if (audio->stopped || audio->wflush)
-		rc = -EBUSY;
+	if (audio->eos_rsp == 1)
+		pr_debug("%s[%p]: EOS\n", __func__, audio);
+
 
 done:
-	mutex_unlock(&audio->write_lock);
 	mutex_lock(&audio->lock);
 	audio->drv_status &= ~ADRV_STATUS_FSYNC;
 	mutex_unlock(&audio->lock);
@@ -963,7 +969,8 @@
 			audio->drv_ops.out_flush(audio);
 		} else
 			audio->drv_ops.out_flush(audio);
-		audio->drv_ops.in_flush(audio);
+		if (audio->feedback == NON_TUNNEL_MODE)
+			audio->drv_ops.in_flush(audio);
 	}
 }
 
@@ -1167,7 +1174,11 @@
 			rc = -EINTR;
 		} else {
 			audio->rflush = 0;
-			audio->wflush = 0;
+			if (audio->drv_status & ADRV_STATUS_FSYNC)
+				wake_up(&audio->write_wait);
+			else
+				audio->wflush = 0;
+
 		}
 		audio->eos_flag = 0;
 		audio->eos_rsp = 0;
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index c7ed329..aacd355 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -17,6 +17,7 @@
 msm_kgsl_core-$(CONFIG_MSM_SCM) += kgsl_pwrscale_trustzone.o
 msm_kgsl_core-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += kgsl_pwrscale_idlestats.o
 msm_kgsl_core-$(CONFIG_MSM_DCVS) += kgsl_pwrscale_msm.o
+msm_kgsl_core-$(CONFIG_SYNC) += kgsl_sync.o
 
 msm_adreno-y += \
 	adreno_ringbuffer.o \
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 21227a0..5904abb 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -36,6 +36,7 @@
 #include "kgsl_sharedmem.h"
 #include "kgsl_device.h"
 #include "kgsl_trace.h"
+#include "kgsl_sync.h"
 
 #undef MODULE_PARAM_PREFIX
 #define MODULE_PARAM_PREFIX "kgsl."
@@ -368,6 +369,12 @@
 	context->id = id;
 	context->dev_priv = dev_priv;
 
+	if (kgsl_sync_timeline_create(context)) {
+		idr_remove(&dev_priv->device->context_idr, id);
+		kfree(context);
+		return NULL;
+	}
+
 	return context;
 }
 
@@ -412,6 +419,7 @@
 {
 	struct kgsl_context *context = container_of(kref, struct kgsl_context,
 						    refcount);
+	kgsl_sync_timeline_destroy(context);
 	kfree(context);
 }
 
@@ -1435,42 +1443,43 @@
 	if (ret)
 		return ret;
 
-	if (phys == 0) {
-		ret = -EINVAL;
+	ret = -ERANGE;
+
+	if (phys == 0)
+		goto err;
+
+	/* Make sure the length of the region, the offset and the desired
+	 * size are all page aligned or bail
+	 */
+	if ((len & ~PAGE_MASK) ||
+		(offset & ~PAGE_MASK) ||
+		(size & ~PAGE_MASK)) {
+		KGSL_CORE_ERR("length offset or size is not page aligned\n");
 		goto err;
 	}
 
-	if (offset >= len) {
-		ret = -EINVAL;
+	/* The size or offset can never be greater than the PMEM length */
+	if (offset >= len || size > len)
 		goto err;
-	}
 
+	/* If size is 0, then adjust it to default to the size of the region
+	 * minus the offset.  If size isn't zero, then make sure that it will
+	 * fit inside of the region.
+	 */
 	if (size == 0)
-		size = len;
+		size = len - offset;
 
-	/* Adjust the size of the region to account for the offset */
-	size += offset & ~PAGE_MASK;
-
-	size = ALIGN(size, PAGE_SIZE);
-
-	if (_check_region(offset & PAGE_MASK, size, len)) {
-		KGSL_CORE_ERR("Offset (%ld) + size (%d) is larger"
-			      "than pmem region length %ld\n",
-			      offset & PAGE_MASK, size, len);
-		ret = -EINVAL;
+	else if (_check_region(offset, size, len))
 		goto err;
 
-	}
-
 	entry->priv_data = filep;
 
 	entry->memdesc.pagetable = pagetable;
 	entry->memdesc.size = size;
-	entry->memdesc.physaddr = phys + (offset & PAGE_MASK);
-	entry->memdesc.hostptr = (void *) (virt + (offset & PAGE_MASK));
+	entry->memdesc.physaddr = phys + offset;
+	entry->memdesc.hostptr = (void *) (virt + offset);
 
-	ret = memdesc_sg_phys(&entry->memdesc,
-		phys + (offset & PAGE_MASK), size);
+	ret = memdesc_sg_phys(&entry->memdesc, phys + offset, size);
 	if (ret)
 		goto err;
 
@@ -2016,6 +2025,11 @@
 			param->context_id, param->timestamp, param->priv,
 			param->len, dev_priv);
 		break;
+	case KGSL_TIMESTAMP_EVENT_FENCE:
+		ret = kgsl_add_fence_event(dev_priv->device,
+			param->context_id, param->timestamp, param->priv,
+			param->len, dev_priv);
+		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -2092,6 +2106,8 @@
 		cmd = IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP;
 	else if (cmd == IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_OLD)
 		cmd = IOCTL_KGSL_CMDSTREAM_READTIMESTAMP;
+	else if (cmd == IOCTL_KGSL_TIMESTAMP_EVENT_OLD)
+		cmd = IOCTL_KGSL_TIMESTAMP_EVENT;
 
 	nr = _IOC_NR(cmd);
 
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 2a2e916..2ca3a4f 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -22,6 +22,7 @@
 #include "kgsl_pwrctrl.h"
 #include "kgsl_log.h"
 #include "kgsl_pwrscale.h"
+#include <linux/sync.h>
 
 #define KGSL_TIMEOUT_NONE       0
 #define KGSL_TIMEOUT_DEFAULT    0xFFFFFFFF
@@ -236,6 +237,12 @@
 	 * context was responsible for causing it
 	 */
 	unsigned int reset_status;
+
+	/*
+	 * Timeline used to create fences that can be signaled when a
+	 * sync_pt timestamp expires.
+	 */
+	struct sync_timeline *timeline;
 };
 
 struct kgsl_process_private {
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
new file mode 100644
index 0000000..a2dfe3b
--- /dev/null
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -0,0 +1,214 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "kgsl_sync.h"
+
+struct sync_pt *kgsl_sync_pt_create(struct sync_timeline *timeline,
+	unsigned int timestamp)
+{
+	struct sync_pt *pt;
+	pt = sync_pt_create(timeline, (int) sizeof(struct kgsl_sync_pt));
+	if (pt) {
+		struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) pt;
+		kpt->timestamp = timestamp;
+	}
+	return pt;
+}
+
+/*
+ * This should only be called on sync_pts which have been created but
+ * not added to a fence.
+ */
+void kgsl_sync_pt_destroy(struct sync_pt *pt)
+{
+	sync_pt_free(pt);
+}
+
+static struct sync_pt *kgsl_sync_pt_dup(struct sync_pt *pt)
+{
+	struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) pt;
+	return kgsl_sync_pt_create(pt->parent, kpt->timestamp);
+}
+
+static int kgsl_sync_pt_has_signaled(struct sync_pt *pt)
+{
+	struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) pt;
+	struct kgsl_sync_timeline *ktimeline =
+		 (struct kgsl_sync_timeline *) pt->parent;
+	unsigned int ts = kpt->timestamp;
+	unsigned int last_ts = ktimeline->last_timestamp;
+	if (timestamp_cmp(last_ts, ts) >= 0) {
+		/* signaled */
+		return 1;
+	}
+	return 0;
+}
+
+static int kgsl_sync_pt_compare(struct sync_pt *a, struct sync_pt *b)
+{
+	struct kgsl_sync_pt *kpt_a = (struct kgsl_sync_pt *) a;
+	struct kgsl_sync_pt *kpt_b = (struct kgsl_sync_pt *) b;
+	unsigned int ts_a = kpt_a->timestamp;
+	unsigned int ts_b = kpt_b->timestamp;
+	return timestamp_cmp(ts_a, ts_b);
+}
+
+struct kgsl_fence_event_priv {
+	struct kgsl_context *context;
+};
+
+/**
+ * kgsl_fence_event_cb - Event callback for a fence timestamp event
+ * @device - The KGSL device that expired the timestamp
+ * @priv - private data for the event
+ * @context_id - the context id that goes with the timestamp
+ * @timestamp - the timestamp that triggered the event
+ *
+ * Signal a fence following the expiration of a timestamp
+ */
+
+static inline void kgsl_fence_event_cb(struct kgsl_device *device,
+	void *priv, u32 context_id, u32 timestamp)
+{
+	struct kgsl_fence_event_priv *ev = priv;
+	kgsl_sync_timeline_signal(ev->context->timeline, timestamp);
+	kgsl_context_put(ev->context);
+	kfree(ev);
+}
+
+/**
+ * kgsl_add_fence_event - Create a new fence event
+ * @device - KGSL device to create the event on
+ * @timestamp - Timestamp to trigger the event
+ * @data - Return fence fd stored in struct kgsl_timestamp_event_fence
+ * @len - length of the fence event
+ * @owner - driver instance that owns this event
+ * @returns 0 on success or error code on error
+ *
+ * Create a fence and register an event to signal the fence when
+ * the timestamp expires
+ */
+
+int kgsl_add_fence_event(struct kgsl_device *device,
+	u32 context_id, u32 timestamp, void __user *data, int len,
+	struct kgsl_device_private *owner)
+{
+	struct kgsl_fence_event_priv *event;
+	struct kgsl_timestamp_event_fence priv;
+	struct kgsl_context *context;
+	struct sync_pt *pt;
+	struct sync_fence *fence = NULL;
+	int ret = -EINVAL;
+
+	if (len != sizeof(priv))
+		return -EINVAL;
+
+	context = kgsl_find_context(owner, context_id);
+	if (context == NULL)
+		return -EINVAL;
+
+	event = kzalloc(sizeof(*event), GFP_KERNEL);
+	if (event == NULL)
+		return -ENOMEM;
+	event->context = context;
+	kgsl_context_get(context);
+
+	pt = kgsl_sync_pt_create(context->timeline, timestamp);
+	if (pt == NULL) {
+		KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n");
+		ret = -ENOMEM;
+		goto fail_pt;
+	}
+
+	fence = sync_fence_create("kgsl-fence", pt);
+	if (fence == NULL) {
+		/* only destroy pt when not added to fence */
+		kgsl_sync_pt_destroy(pt);
+		KGSL_DRV_ERR(device, "sync_fence_create failed\n");
+		ret = -ENOMEM;
+		goto fail_fence;
+	}
+
+	priv.fence_fd = get_unused_fd_flags(0);
+	if (priv.fence_fd < 0) {
+		KGSL_DRV_ERR(device, "invalid fence fd\n");
+		ret = -EINVAL;
+		goto fail_fd;
+	}
+	sync_fence_install(fence, priv.fence_fd);
+
+	if (copy_to_user(data, &priv, sizeof(priv))) {
+		ret = -EFAULT;
+		goto fail_copy_fd;
+	}
+
+	ret = kgsl_add_event(device, context_id, timestamp,
+			kgsl_fence_event_cb, event, owner);
+	if (ret)
+		goto fail_event;
+
+	return 0;
+
+fail_event:
+fail_copy_fd:
+	/* clean up sync_fence_install */
+	sync_fence_put(fence);
+	put_unused_fd(priv.fence_fd);
+fail_fd:
+	/* clean up sync_fence_create */
+	sync_fence_put(fence);
+fail_fence:
+fail_pt:
+	kgsl_context_put(context);
+	kfree(event);
+	return ret;
+}
+
+static const struct sync_timeline_ops kgsl_sync_timeline_ops = {
+	.dup = kgsl_sync_pt_dup,
+	.has_signaled = kgsl_sync_pt_has_signaled,
+	.compare = kgsl_sync_pt_compare,
+};
+
+int kgsl_sync_timeline_create(struct kgsl_context *context)
+{
+	struct kgsl_sync_timeline *ktimeline;
+
+	context->timeline = sync_timeline_create(&kgsl_sync_timeline_ops,
+		(int) sizeof(struct kgsl_sync_timeline), "kgsl-timeline");
+	if (context->timeline == NULL)
+		return -EINVAL;
+
+	ktimeline = (struct kgsl_sync_timeline *) context->timeline;
+	ktimeline->last_timestamp = 0;
+
+	return 0;
+}
+
+void kgsl_sync_timeline_signal(struct sync_timeline *timeline,
+	unsigned int timestamp)
+{
+	struct kgsl_sync_timeline *ktimeline =
+		(struct kgsl_sync_timeline *) timeline;
+	ktimeline->last_timestamp = timestamp;
+	sync_timeline_signal(timeline);
+}
+
+void kgsl_sync_timeline_destroy(struct kgsl_context *context)
+{
+	sync_timeline_destroy(context->timeline);
+}
diff --git a/drivers/gpu/msm/kgsl_sync.h b/drivers/gpu/msm/kgsl_sync.h
new file mode 100644
index 0000000..06b3ad0
--- /dev/null
+++ b/drivers/gpu/msm/kgsl_sync.h
@@ -0,0 +1,75 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __KGSL_SYNC_H
+#define __KGSL_SYNC_H
+
+#include <linux/sync.h>
+#include "kgsl_device.h"
+
+struct kgsl_sync_timeline {
+	struct sync_timeline timeline;
+	unsigned int last_timestamp;
+};
+
+struct kgsl_sync_pt {
+	struct sync_pt pt;
+	unsigned int timestamp;
+};
+
+#if defined(CONFIG_SYNC)
+struct sync_pt *kgsl_sync_pt_create(struct sync_timeline *timeline,
+	unsigned int timestamp);
+void kgsl_sync_pt_destroy(struct sync_pt *pt);
+int kgsl_add_fence_event(struct kgsl_device *device,
+	u32 context_id, u32 timestamp, void __user *data, int len,
+	struct kgsl_device_private *owner);
+int kgsl_sync_timeline_create(struct kgsl_context *context);
+void kgsl_sync_timeline_signal(struct sync_timeline *timeline,
+	unsigned int timestamp);
+void kgsl_sync_timeline_destroy(struct kgsl_context *context);
+#else
+static inline struct sync_pt
+*kgsl_sync_pt_create(struct sync_timeline *timeline, unsigned int timestamp)
+{
+	return NULL;
+}
+
+static inline void kgsl_sync_pt_destroy(struct sync_pt *pt)
+{
+}
+
+static inline int kgsl_add_fence_event(struct kgsl_device *device,
+	u32 context_id, u32 timestamp, void __user *data, int len,
+	struct kgsl_device_private *owner)
+{
+	return -EINVAL;
+}
+
+static int kgsl_sync_timeline_create(struct kgsl_context *context)
+{
+	context->timeline = NULL;
+	return 0;
+}
+
+static inline void
+kgsl_sync_timeline_signal(struct sync_timeline *timeline,
+	unsigned int timestamp)
+{
+}
+
+static inline void kgsl_sync_timeline_destroy(struct kgsl_context *context)
+{
+}
+#endif
+
+#endif /* __KGSL_SYNC_H */
diff --git a/drivers/media/dvb/mpq/video/mpq_dvb_video.c b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
index 3dc31bb..4b3fb0c 100644
--- a/drivers/media/dvb/mpq/video/mpq_dvb_video.c
+++ b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
@@ -868,7 +868,7 @@
 	if (rc)
 		DBG("Failed in mpq_int_vid_dec_get_buffer_req : %d\n", rc);
 
-	vdec_buf_req.num_output_buffers = 15;
+	vdec_buf_req.num_output_buffers = 12;
 	rc = mpq_int_set_out_buffer_req(client_ctx, &vdec_buf_req);
 	if (rc)
 		DBG("Failed in mpq_int_set_out_buffer_req (15) : %d\n", rc);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h
index 88ec1ad..04af6b6 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h
@@ -14,12 +14,13 @@
 #define MSM_JPEG_COMMON_H
 
 #ifdef MSM_JPEG_DEBUG
-#define JPEG_DBG(fmt, args...) printk(fmt, ##args)
+#define JPEG_DBG(fmt, args...) pr_info(fmt, ##args)
 #else
 #define JPEG_DBG(fmt, args...) do { } while (0)
 #endif
 
 #define JPEG_PR_ERR   pr_err
+#define JPEG_DBG_HIGH   pr_err
 
 enum JPEG_MODE {
 	JPEG_MODE_DISABLE,
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c
index 7905ff3..b67245c 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c
@@ -17,122 +17,130 @@
 #include "msm_jpeg_platform.h"
 #include "msm_jpeg_common.h"
 
-static struct msm_jpeg_hw_pingpong fe_pingpong_buf;
-static struct msm_jpeg_hw_pingpong we_pingpong_buf;
-static int we_pingpong_index;
-static int reset_done_ack;
-static spinlock_t reset_lock;
-static wait_queue_head_t reset_wait;
-
-int msm_jpeg_core_reset(uint8_t op_mode, void *base, int size)
-{
+int msm_jpeg_core_reset(struct msm_jpeg_device *pgmn_dev, uint8_t op_mode,
+	void *base, int size) {
 	unsigned long flags;
 	int rc = 0;
 	int tm = 500; /*500ms*/
-	memset(&fe_pingpong_buf, 0, sizeof(fe_pingpong_buf));
-	fe_pingpong_buf.is_fe = 1;
-	we_pingpong_index = 0;
-	memset(&we_pingpong_buf, 0, sizeof(we_pingpong_buf));
-	spin_lock_irqsave(&reset_lock, flags);
-	reset_done_ack = 0;
+	JPEG_DBG("%s:%d] reset", __func__, __LINE__);
+	memset(&pgmn_dev->fe_pingpong_buf, 0,
+		sizeof(pgmn_dev->fe_pingpong_buf));
+	pgmn_dev->fe_pingpong_buf.is_fe = 1;
+	memset(&pgmn_dev->we_pingpong_buf, 0,
+		sizeof(pgmn_dev->we_pingpong_buf));
+	spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
+	pgmn_dev->reset_done_ack = 0;
 	msm_jpeg_hw_reset(base, size);
-	spin_unlock_irqrestore(&reset_lock, flags);
+	spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
 	rc = wait_event_interruptible_timeout(
-			reset_wait,
-			reset_done_ack,
+			pgmn_dev->reset_wait,
+			pgmn_dev->reset_done_ack,
 			msecs_to_jiffies(tm));
 
-	if (!reset_done_ack) {
+	if (!pgmn_dev->reset_done_ack) {
 		JPEG_DBG("%s: reset ACK failed %d", __func__, rc);
 		return -EBUSY;
 	}
 
 	JPEG_DBG("%s: reset_done_ack rc %d", __func__, rc);
-	spin_lock_irqsave(&reset_lock, flags);
-	reset_done_ack = 0;
-	spin_unlock_irqrestore(&reset_lock, flags);
+	spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
+	pgmn_dev->reset_done_ack = 0;
+	spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
 
 	return 0;
 }
 
-void msm_jpeg_core_release(int release_buf, int domain_num)
-{
+void msm_jpeg_core_release(struct msm_jpeg_device *pgmn_dev,
+	int domain_num) {
 	int i = 0;
 	for (i = 0; i < 2; i++) {
-		if (we_pingpong_buf.buf_status[i] && release_buf)
-			msm_jpeg_platform_p2v(we_pingpong_buf.buf[i].file,
-				&we_pingpong_buf.buf[i].handle, domain_num);
-		we_pingpong_buf.buf_status[i] = 0;
+		if (pgmn_dev->we_pingpong_buf.buf_status[i] &&
+			pgmn_dev->release_buf)
+			msm_jpeg_platform_p2v(pgmn_dev,
+				pgmn_dev->we_pingpong_buf.buf[i].file,
+				&pgmn_dev->we_pingpong_buf.buf[i].handle,
+					domain_num);
+		pgmn_dev->we_pingpong_buf.buf_status[i] = 0;
 	}
 }
 
-void msm_jpeg_core_init(void)
+void msm_jpeg_core_init(struct msm_jpeg_device *pgmn_dev)
 {
-	init_waitqueue_head(&reset_wait);
-	spin_lock_init(&reset_lock);
+	init_waitqueue_head(&pgmn_dev->reset_wait);
+	spin_lock_init(&pgmn_dev->reset_lock);
 }
 
-int msm_jpeg_core_fe_start(void)
+int msm_jpeg_core_fe_start(struct msm_jpeg_device *pgmn_dev)
 {
-	msm_jpeg_hw_fe_start();
+	msm_jpeg_hw_fe_start(pgmn_dev->base);
 	return 0;
 }
 
 /* fetch engine */
-int msm_jpeg_core_fe_buf_update(struct msm_jpeg_core_buf *buf)
+int msm_jpeg_core_fe_buf_update(struct msm_jpeg_device *pgmn_dev,
+	struct msm_jpeg_core_buf *buf)
 {
+	if (0 == buf->cbcr_len)
+		buf->cbcr_buffer_addr = 0x0;
 	JPEG_DBG("%s:%d] 0x%08x %d 0x%08x %d\n", __func__, __LINE__,
 		(int) buf->y_buffer_addr, buf->y_len,
 		(int) buf->cbcr_buffer_addr, buf->cbcr_len);
-	return msm_jpeg_hw_pingpong_update(&fe_pingpong_buf, buf);
+	return msm_jpeg_hw_pingpong_update(&pgmn_dev->fe_pingpong_buf, buf,
+		pgmn_dev->base);
 }
 
-void *msm_jpeg_core_fe_pingpong_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_fe_pingpong_irq(int jpeg_irq_status,
+	struct msm_jpeg_device *pgmn_dev)
 {
-	return msm_jpeg_hw_pingpong_irq(&fe_pingpong_buf);
+	return msm_jpeg_hw_pingpong_irq(&pgmn_dev->fe_pingpong_buf);
 }
 
 /* write engine */
-int msm_jpeg_core_we_buf_update(struct msm_jpeg_core_buf *buf)
-{
+int msm_jpeg_core_we_buf_update(struct msm_jpeg_device *pgmn_dev,
+	struct msm_jpeg_core_buf *buf) {
 	JPEG_DBG("%s:%d] 0x%08x 0x%08x %d\n", __func__, __LINE__,
 		(int) buf->y_buffer_addr, (int) buf->cbcr_buffer_addr,
 		buf->y_len);
-	we_pingpong_buf.buf[0] = *buf;
-	we_pingpong_buf.buf_status[0] = 1;
+	pgmn_dev->we_pingpong_buf.buf[0] = *buf;
+	pgmn_dev->we_pingpong_buf.buf_status[0] = 1;
 	msm_jpeg_hw_we_buffer_update(
-			&we_pingpong_buf.buf[0], 0);
+		&pgmn_dev->we_pingpong_buf.buf[0], 0, pgmn_dev->base);
 
 	return 0;
 }
 
-int msm_jpeg_core_we_buf_reset(struct msm_jpeg_hw_buf *buf)
+int msm_jpeg_core_we_buf_reset(struct msm_jpeg_device *pgmn_dev,
+	struct msm_jpeg_hw_buf *buf)
 {
 	int i = 0;
 	for (i = 0; i < 2; i++) {
-		if (we_pingpong_buf.buf[i].y_buffer_addr
-					== buf->y_buffer_addr)
-			we_pingpong_buf.buf_status[i] = 0;
+		if (pgmn_dev->we_pingpong_buf.buf[i].y_buffer_addr
+			== buf->y_buffer_addr)
+			pgmn_dev->we_pingpong_buf.buf_status[i] = 0;
 	}
 	return 0;
 }
 
-void *msm_jpeg_core_we_pingpong_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_we_pingpong_irq(int jpeg_irq_status,
+	struct msm_jpeg_device *pgmn_dev)
 {
 	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
 
-	return msm_jpeg_hw_pingpong_irq(&we_pingpong_buf);
+	return msm_jpeg_hw_pingpong_irq(&pgmn_dev->we_pingpong_buf);
 }
 
-void *msm_jpeg_core_framedone_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_framedone_irq(int jpeg_irq_status,
+	struct msm_jpeg_device *pgmn_dev)
 {
 	struct msm_jpeg_hw_buf *buf_p;
 
 	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
 
-	buf_p = msm_jpeg_hw_pingpong_active_buffer(&we_pingpong_buf);
-	if (buf_p) {
-		buf_p->framedone_len = msm_jpeg_hw_encode_output_size();
+	buf_p = msm_jpeg_hw_pingpong_active_buffer(
+		&pgmn_dev->we_pingpong_buf);
+	if (buf_p && !pgmn_dev->decode_flag) {
+		buf_p->framedone_len =
+			msm_jpeg_hw_encode_output_size(pgmn_dev->base);
 		JPEG_DBG("%s:%d] framedone_len %d\n", __func__, __LINE__,
 			buf_p->framedone_len);
 	}
@@ -140,14 +148,16 @@
 	return buf_p;
 }
 
-void *msm_jpeg_core_reset_ack_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_reset_ack_irq(int jpeg_irq_status,
+	struct msm_jpeg_device *pgmn_dev)
 {
 	/* @todo return the status back to msm_jpeg_core_reset */
 	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
 	return NULL;
 }
 
-void *msm_jpeg_core_err_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_err_irq(int jpeg_irq_status,
+	struct msm_jpeg_device *pgmn_dev)
 {
 	JPEG_PR_ERR("%s:%d]\n", __func__, jpeg_irq_status);
 	return NULL;
@@ -155,15 +165,32 @@
 
 static int (*msm_jpeg_irq_handler) (int, void *, void *);
 
+void msm_jpeg_core_return_buffers(struct msm_jpeg_device *pgmn_dev,
+	 int jpeg_irq_status)
+{
+	void *data = NULL;
+	data = msm_jpeg_core_fe_pingpong_irq(jpeg_irq_status,
+		pgmn_dev);
+	if (msm_jpeg_irq_handler)
+		msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_FE,
+			pgmn_dev, data);
+	data = msm_jpeg_core_we_pingpong_irq(jpeg_irq_status,
+		pgmn_dev);
+	if (msm_jpeg_irq_handler)
+		msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_WE,
+			pgmn_dev, data);
+}
+
 irqreturn_t msm_jpeg_core_irq(int irq_num, void *context)
 {
 	void *data = NULL;
 	unsigned long flags;
 	int jpeg_irq_status;
+	struct msm_jpeg_device *pgmn_dev = (struct msm_jpeg_device *)context;
 
 	JPEG_DBG("%s:%d] irq_num = %d\n", __func__, __LINE__, irq_num);
 
-	jpeg_irq_status = msm_jpeg_hw_irq_get_status();
+	jpeg_irq_status = msm_jpeg_hw_irq_get_status(pgmn_dev->base);
 
 	JPEG_DBG("%s:%d] jpeg_irq_status = %0x\n", __func__, __LINE__,
 		jpeg_irq_status);
@@ -171,18 +198,26 @@
 	/*For reset and framedone IRQs, clear all bits*/
 	if (jpeg_irq_status & 0x10000000) {
 		msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
-			JPEG_IRQ_CLEAR_ALL);
+			JPEG_IRQ_CLEAR_ALL, pgmn_dev->base);
 	} else if (jpeg_irq_status & 0x1) {
 		msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
-			JPEG_IRQ_CLEAR_ALL);
+			JPEG_IRQ_CLEAR_ALL, pgmn_dev->base);
+		if (pgmn_dev->decode_flag)
+			msm_jpeg_decode_status(pgmn_dev->base);
 	} else {
 		msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
-			jpeg_irq_status);
+			jpeg_irq_status, pgmn_dev->base);
 	}
 
 	if (msm_jpeg_hw_irq_is_frame_done(jpeg_irq_status)) {
+		/* send fe ping pong irq */
+		data = msm_jpeg_core_fe_pingpong_irq(jpeg_irq_status,
+			pgmn_dev);
+		if (msm_jpeg_irq_handler)
+			msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_FE,
+				context, data);
 		data = msm_jpeg_core_framedone_irq(jpeg_irq_status,
-			context);
+			pgmn_dev);
 		if (msm_jpeg_irq_handler)
 			msm_jpeg_irq_handler(
 				MSM_JPEG_HW_MASK_COMP_FRAMEDONE,
@@ -190,11 +225,11 @@
 	}
 	if (msm_jpeg_hw_irq_is_reset_ack(jpeg_irq_status)) {
 		data = msm_jpeg_core_reset_ack_irq(jpeg_irq_status,
-			context);
-		spin_lock_irqsave(&reset_lock, flags);
-		reset_done_ack = 1;
-		spin_unlock_irqrestore(&reset_lock, flags);
-		wake_up(&reset_wait);
+			pgmn_dev);
+		spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
+		pgmn_dev->reset_done_ack = 1;
+		spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
+		wake_up(&pgmn_dev->reset_wait);
 		if (msm_jpeg_irq_handler)
 			msm_jpeg_irq_handler(
 				MSM_JPEG_HW_MASK_COMP_RESET_ACK,
@@ -203,7 +238,10 @@
 
 	/* Unexpected/unintended HW interrupt */
 	if (msm_jpeg_hw_irq_is_err(jpeg_irq_status)) {
-		data = msm_jpeg_core_err_irq(jpeg_irq_status, context);
+		if (pgmn_dev->decode_flag)
+			msm_jpeg_decode_status(pgmn_dev->base);
+		msm_jpeg_core_return_buffers(pgmn_dev, jpeg_irq_status);
+		data = msm_jpeg_core_err_irq(jpeg_irq_status, pgmn_dev);
 		if (msm_jpeg_irq_handler)
 			msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_ERR,
 				context, data);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h
index b5c725c..212eaff 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h
@@ -15,6 +15,7 @@
 
 #include <linux/interrupt.h>
 #include "msm_jpeg_hw.h"
+#include "msm_jpeg_sync.h"
 
 #define msm_jpeg_core_buf msm_jpeg_hw_buf
 
@@ -23,13 +24,17 @@
 void msm_jpeg_core_irq_install(int (*irq_handler) (int, void *, void *));
 void msm_jpeg_core_irq_remove(void);
 
-int msm_jpeg_core_fe_buf_update(struct msm_jpeg_core_buf *buf);
-int msm_jpeg_core_we_buf_update(struct msm_jpeg_core_buf *buf);
-int msm_jpeg_core_we_buf_reset(struct msm_jpeg_hw_buf *buf);
+int msm_jpeg_core_fe_buf_update(struct msm_jpeg_device *pgmn_dev,
+	struct msm_jpeg_core_buf *buf);
+int msm_jpeg_core_we_buf_update(struct msm_jpeg_device *pgmn_dev,
+	struct msm_jpeg_core_buf *buf);
+int msm_jpeg_core_we_buf_reset(struct msm_jpeg_device *pgmn_dev,
+	struct msm_jpeg_hw_buf *buf);
 
-int msm_jpeg_core_reset(uint8_t op_mode, void *base, int size);
-int msm_jpeg_core_fe_start(void);
+int msm_jpeg_core_reset(struct msm_jpeg_device *pgmn_dev, uint8_t op_mode,
+	void *base, int size);
+int msm_jpeg_core_fe_start(struct msm_jpeg_device *);
 
-void msm_jpeg_core_release(int, int);
-void msm_jpeg_core_init(void);
+void msm_jpeg_core_release(struct msm_jpeg_device *, int);
+void msm_jpeg_core_init(struct msm_jpeg_device *);
 #endif /* MSM_JPEG_CORE_H */
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c
index 45a9a38..0662f54 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c
@@ -31,9 +31,7 @@
 #include "msm_jpeg_common.h"
 
 #define MSM_JPEG_NAME "jpeg"
-#define MSM_JPEGE1_NAME "jpege1"
-#define MSM_JPEGD_NAME "jpegd"
-
+#define DEV_NAME_LEN 10
 
 static int msm_jpeg_open(struct inode *inode, struct file *filp)
 {
@@ -146,7 +144,7 @@
 	int rc = -1;
 	struct device *dev;
 	struct msm_jpeg_device *msm_jpeg_device_p;
-	char devname[10];
+	char devname[DEV_NAME_LEN];
 
 	msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC);
 	if (!msm_jpeg_device_p) {
@@ -158,7 +156,7 @@
 
 	if (pdev->dev.of_node)
 		of_property_read_u32((&pdev->dev)->of_node, "cell-index",
-								&pdev->id);
+			&pdev->id);
 
 	snprintf(devname, sizeof(devname), "%s%d", MSM_JPEG_NAME, pdev->id);
 
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
index 0bfb6a8..e311e4c 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
@@ -17,11 +17,8 @@
 
 #include <linux/io.h>
 
-static void *jpeg_region_base;
-static uint32_t jpeg_region_size;
-
 int msm_jpeg_hw_pingpong_update(struct msm_jpeg_hw_pingpong *pingpong_hw,
-	struct msm_jpeg_hw_buf *buf)
+	struct msm_jpeg_hw_buf *buf, void *base)
 {
 	int buf_free_index = -1;
 
@@ -41,11 +38,13 @@
 	if (pingpong_hw->is_fe) {
 		/* it is fe */
 		msm_jpeg_hw_fe_buffer_update(
-			&pingpong_hw->buf[buf_free_index], buf_free_index);
+			&pingpong_hw->buf[buf_free_index], buf_free_index,
+			base);
 	} else {
 		/* it is we */
 		msm_jpeg_hw_we_buffer_update(
-			&pingpong_hw->buf[buf_free_index], buf_free_index);
+			&pingpong_hw->buf[buf_free_index], buf_free_index,
+			base);
 	}
 	return 0;
 }
@@ -81,12 +80,10 @@
 		JPEG_IRQ_STATUS_BMSK, {0} },
 };
 
-int msm_jpeg_hw_irq_get_status(void)
+int msm_jpeg_hw_irq_get_status(void *base)
 {
 	uint32_t n_irq_status = 0;
-	rmb();
-	n_irq_status = msm_jpeg_hw_read(&hw_cmd_irq_get_status[0]);
-	rmb();
+	n_irq_status = msm_jpeg_hw_read(&hw_cmd_irq_get_status[0], base);
 	return n_irq_status;
 }
 
@@ -97,11 +94,12 @@
 	JPEG_ENCODE_OUTPUT_SIZE_STATUS_BMSK, {0} } ,
 };
 
-long msm_jpeg_hw_encode_output_size(void)
+long msm_jpeg_hw_encode_output_size(void *base)
 {
 	uint32_t encode_output_size = 0;
 
-	encode_output_size = msm_jpeg_hw_read(&hw_cmd_encode_output_size[0]);
+	encode_output_size = msm_jpeg_hw_read(&hw_cmd_encode_output_size[0],
+		base);
 
 	return encode_output_size;
 }
@@ -112,12 +110,12 @@
 		JPEG_IRQ_CLEAR_BMSK, {JPEG_IRQ_CLEAR_ALL} },
 };
 
-void msm_jpeg_hw_irq_clear(uint32_t mask, uint32_t data)
+void msm_jpeg_hw_irq_clear(uint32_t mask, uint32_t data, void *base)
 {
 	JPEG_DBG("%s:%d] mask %0x data %0x", __func__, __LINE__, mask, data);
 	hw_cmd_irq_clear[0].mask = mask;
 	hw_cmd_irq_clear[0].data = data;
-	msm_jpeg_hw_write(&hw_cmd_irq_clear[0]);
+	msm_jpeg_hw_write(&hw_cmd_irq_clear[0], base);
 }
 
 struct msm_jpeg_hw_cmd hw_cmd_fe_ping_update[] = {
@@ -137,26 +135,26 @@
 };
 
 void msm_jpeg_hw_fe_buffer_update(struct msm_jpeg_hw_buf *p_input,
-	uint8_t pingpong_index)
+	uint8_t pingpong_index, void *base)
 {
 	struct msm_jpeg_hw_cmd *hw_cmd_p;
 
 	if (pingpong_index == 0) {
 		hw_cmd_p = &hw_cmd_fe_ping_update[0];
 		wmb();
-		msm_jpeg_hw_write(hw_cmd_p++);
+		msm_jpeg_hw_write(hw_cmd_p++, base);
 		wmb();
-		msm_jpeg_hw_write(hw_cmd_p++);
+		msm_jpeg_hw_write(hw_cmd_p++, base);
 		wmb();
-		msm_jpeg_hw_write(hw_cmd_p++);
+		msm_jpeg_hw_write(hw_cmd_p++, base);
 		wmb();
 		hw_cmd_p->data = p_input->y_buffer_addr;
-		msm_jpeg_hw_write(hw_cmd_p++);
+		msm_jpeg_hw_write(hw_cmd_p++, base);
 		wmb();
-		msm_jpeg_hw_write(hw_cmd_p++);
+		msm_jpeg_hw_write(hw_cmd_p++, base);
 		wmb();
 		hw_cmd_p->data = p_input->cbcr_buffer_addr;
-		msm_jpeg_hw_write(hw_cmd_p++);
+		msm_jpeg_hw_write(hw_cmd_p++, base);
 		wmb();
 
 	}
@@ -169,9 +167,9 @@
 		JPEG_CMD_BMSK, {JPEG_OFFLINE_CMD_START} },
 };
 
-void msm_jpeg_hw_fe_start(void)
+void msm_jpeg_hw_fe_start(void *base)
 {
-	msm_jpeg_hw_write(&hw_cmd_fe_start[0]);
+	msm_jpeg_hw_write(&hw_cmd_fe_start[0], base);
 
 	return;
 }
@@ -180,20 +178,46 @@
 	/* type, repeat n times, offset, mask, data or pdata */
 	{MSM_JPEG_HW_CMD_TYPE_WRITE, 1, JPEG_PLN0_WR_PNTR_ADDR,
 		JPEG_PLN0_WR_PNTR_BMSK, {0} },
+	{MSM_JPEG_HW_CMD_TYPE_WRITE, 1, JPEG_PLN1_WR_PNTR_ADDR,
+		JPEG_PLN0_WR_PNTR_BMSK, {0} },
+	{MSM_JPEG_HW_CMD_TYPE_WRITE, 1, JPEG_PLN2_WR_PNTR_ADDR,
+		JPEG_PLN0_WR_PNTR_BMSK, {0} },
 };
 
+void msm_jpeg_decode_status(void *base)
+{
+	uint32_t data;
+	data = readl_relaxed(base + JPEG_DECODE_MCUS_DECODED_STATUS);
+	JPEG_DBG_HIGH("Decode MCUs decode status %u", data);
+	data = readl_relaxed(base + JPEG_DECODE_BITS_CONSUMED_STATUS);
+	JPEG_DBG_HIGH("Decode bits consumed status %u", data);
+	data = readl_relaxed(base + JPEG_DECODE_PRED_Y_STATE);
+	JPEG_DBG_HIGH("Decode prediction Y state %u", data);
+	data = readl_relaxed(base + JPEG_DECODE_PRED_C_STATE);
+	JPEG_DBG_HIGH("Decode prediction C state %u", data);
+	data = readl_relaxed(base + JPEG_DECODE_RSM_STATE);
+	JPEG_DBG_HIGH("Decode prediction RSM state %u", data);
+}
+
+
 void msm_jpeg_hw_we_buffer_update(struct msm_jpeg_hw_buf *p_input,
-	uint8_t pingpong_index)
+	uint8_t pingpong_index, void *base)
 {
 	struct msm_jpeg_hw_cmd *hw_cmd_p;
 
 	if (pingpong_index == 0) {
 		hw_cmd_p = &hw_cmd_we_ping_update[0];
 		hw_cmd_p->data = p_input->y_buffer_addr;
-		JPEG_PR_ERR("%s Output buffer address is %x\n", __func__,
-						p_input->y_buffer_addr);
-		msm_jpeg_hw_write(hw_cmd_p++);
-
+		JPEG_PR_ERR("%s Output pln0 buffer address is %x\n", __func__,
+			p_input->y_buffer_addr);
+		msm_jpeg_hw_write(hw_cmd_p++, base);
+		hw_cmd_p->data = p_input->cbcr_buffer_addr;
+		JPEG_PR_ERR("%s Output pln1 buffer address is %x\n", __func__,
+			p_input->cbcr_buffer_addr);
+		msm_jpeg_hw_write(hw_cmd_p++, base);
+		JPEG_PR_ERR("%s Output pln2 buffer address is %x\n", __func__,
+			p_input->pln2_addr);
+		msm_jpeg_hw_write(hw_cmd_p++, base);
 	}
 	return;
 }
@@ -210,31 +234,26 @@
 		JPEG_RESET_CMD_RMSK, {JPEG_RESET_DEFAULT} },
 };
 
-void msm_jpeg_hw_init(void *base, int size)
-{
-	jpeg_region_base = base;
-	jpeg_region_size = size;
-}
-
 void msm_jpeg_hw_reset(void *base, int size)
 {
 	struct msm_jpeg_hw_cmd *hw_cmd_p;
 
 	hw_cmd_p = &hw_cmd_reset[0];
 	wmb();
-	msm_jpeg_hw_write(hw_cmd_p++);
+	msm_jpeg_hw_write(hw_cmd_p++, base);
 	wmb();
-	msm_jpeg_hw_write(hw_cmd_p++);
+	msm_jpeg_hw_write(hw_cmd_p++, base);
 	wmb();
-	msm_jpeg_hw_write(hw_cmd_p++);
+	msm_jpeg_hw_write(hw_cmd_p++, base);
 	wmb();
-	msm_jpeg_hw_write(hw_cmd_p);
+	msm_jpeg_hw_write(hw_cmd_p, base);
 	wmb();
 
 	return;
 }
 
-uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *hw_cmd_p)
+uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *hw_cmd_p,
+	 void *jpeg_region_base)
 {
 	uint32_t *paddr;
 	uint32_t data;
@@ -247,7 +266,8 @@
 	return data;
 }
 
-void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *hw_cmd_p)
+void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *hw_cmd_p,
+	void *jpeg_region_base)
 {
 	uint32_t *paddr;
 	uint32_t old_data, new_data;
@@ -266,17 +286,18 @@
 	writel_relaxed(new_data, paddr);
 }
 
-int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us)
+int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us,
+	void *base)
 {
 	int tm = hw_cmd_p->n;
 	uint32_t data;
 	uint32_t wait_data = hw_cmd_p->data & hw_cmd_p->mask;
 
-	data = msm_jpeg_hw_read(hw_cmd_p);
+	data = msm_jpeg_hw_read(hw_cmd_p, base);
 	if (data != wait_data) {
 		while (tm) {
 			udelay(m_us);
-			data = msm_jpeg_hw_read(hw_cmd_p);
+			data = msm_jpeg_hw_read(hw_cmd_p, base);
 			if (data == wait_data)
 				break;
 			tm--;
@@ -295,41 +316,42 @@
 	}
 }
 
-int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_cmds)
+int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_cmds,
+	uint32_t max_size, void *base)
 {
 	int is_copy_to_user = -1;
 	uint32_t data;
 
 	while (m_cmds--) {
-		if (hw_cmd_p->offset > jpeg_region_size) {
+		if (hw_cmd_p->offset > max_size) {
 			JPEG_PR_ERR("%s:%d] %d exceed hw region %d\n", __func__,
-				__LINE__, hw_cmd_p->offset, jpeg_region_size);
+				__LINE__, hw_cmd_p->offset, max_size);
 			return -EFAULT;
 		}
 
 		switch (hw_cmd_p->type) {
 		case MSM_JPEG_HW_CMD_TYPE_READ:
-			hw_cmd_p->data = msm_jpeg_hw_read(hw_cmd_p);
+			hw_cmd_p->data = msm_jpeg_hw_read(hw_cmd_p, base);
 			is_copy_to_user = 1;
 			break;
 
 		case MSM_JPEG_HW_CMD_TYPE_WRITE:
-			msm_jpeg_hw_write(hw_cmd_p);
+			msm_jpeg_hw_write(hw_cmd_p, base);
 			break;
 
 		case MSM_JPEG_HW_CMD_TYPE_WRITE_OR:
-			data = msm_jpeg_hw_read(hw_cmd_p);
+			data = msm_jpeg_hw_read(hw_cmd_p, base);
 			hw_cmd_p->data = (hw_cmd_p->data & hw_cmd_p->mask) |
 				data;
-			msm_jpeg_hw_write(hw_cmd_p);
+			msm_jpeg_hw_write(hw_cmd_p, base);
 			break;
 
 		case MSM_JPEG_HW_CMD_TYPE_UWAIT:
-			msm_jpeg_hw_wait(hw_cmd_p, 1);
+			msm_jpeg_hw_wait(hw_cmd_p, 1, base);
 			break;
 
 		case MSM_JPEG_HW_CMD_TYPE_MWAIT:
-			msm_jpeg_hw_wait(hw_cmd_p, 1000);
+			msm_jpeg_hw_wait(hw_cmd_p, 1000, base);
 			break;
 
 		case MSM_JPEG_HW_CMD_TYPE_UDELAY:
@@ -350,15 +372,14 @@
 	return is_copy_to_user;
 }
 
-void msm_jpeg_io_dump(int size)
+void msm_jpeg_io_dump(void *base, int size)
 {
 	char line_str[128], *p_str;
-	void __iomem *addr = jpeg_region_base;
+	void __iomem *addr = (void __iomem *)base;
 	int i;
 	u32 *p = (u32 *) addr;
 	u32 data;
-	JPEG_PR_ERR("%s: %p %d reg_size %d\n", __func__, addr, size,
-							jpeg_region_size);
+	JPEG_DBG_HIGH("%s:%d] %p %d", __func__, __LINE__, addr, size);
 	line_str[0] = '\0';
 	p_str = line_str;
 	for (i = 0; i < size/4; i++) {
@@ -370,11 +391,12 @@
 		snprintf(p_str, 12, "%08x ", data);
 		p_str += 9;
 		if ((i + 1) % 4 == 0) {
-			JPEG_PR_ERR("%s\n", line_str);
+			JPEG_DBG_HIGH("%s\n", line_str);
 			line_str[0] = '\0';
 			p_str = line_str;
 		}
 	}
 	if (line_str[0] != '\0')
-		JPEG_PR_ERR("%s\n", line_str);
+		JPEG_DBG_HIGH("%s\n", line_str);
 }
+
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
index 73a0e27..e90b941 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
@@ -28,6 +28,8 @@
 	uint32_t cbcr_len;
 	uint32_t num_of_mcu_rows;
 	struct ion_handle *handle;
+	uint32_t pln2_addr;
+	uint32_t pln2_offset;
 };
 
 struct msm_jpeg_hw_pingpong {
@@ -38,14 +40,14 @@
 };
 
 int msm_jpeg_hw_pingpong_update(struct msm_jpeg_hw_pingpong *pingpong_hw,
-	struct msm_jpeg_hw_buf *buf);
+	struct msm_jpeg_hw_buf *buf, void *);
 void *msm_jpeg_hw_pingpong_irq(struct msm_jpeg_hw_pingpong *pingpong_hw);
 void *msm_jpeg_hw_pingpong_active_buffer(struct msm_jpeg_hw_pingpong
 	*pingpong_hw);
 
-void msm_jpeg_hw_irq_clear(uint32_t, uint32_t);
-int msm_jpeg_hw_irq_get_status(void);
-long msm_jpeg_hw_encode_output_size(void);
+void msm_jpeg_hw_irq_clear(uint32_t, uint32_t, void *);
+int msm_jpeg_hw_irq_get_status(void *);
+long msm_jpeg_hw_encode_output_size(void *);
 #define MSM_JPEG_HW_MASK_COMP_FRAMEDONE \
 		MSM_JPEG_HW_IRQ_STATUS_FRAMEDONE_MASK
 #define MSM_JPEG_HW_MASK_COMP_FE \
@@ -56,13 +58,14 @@
 #define MSM_JPEG_HW_MASK_COMP_RESET_ACK \
 		MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK
 #define MSM_JPEG_HW_MASK_COMP_ERR \
-		(MSM_JPEG_HW_IRQ_STATUS_FE_RTOVF_MASK | \
-		MSM_JPEG_HW_IRQ_STATUS_FE_VFE_OVERFLOW_MASK | \
-		MSM_JPEG_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_MASK | \
-		MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_MASK | \
-		MSM_JPEG_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_MASK | \
-		MSM_JPEG_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_MASK | \
-		MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK | \
+		(MSM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF | \
+		MSM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR | \
+		MSM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR | \
+		MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF | \
+		MSM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW | \
+		MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM | \
+		MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ | \
+		MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM | \
 		MSM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK)
 
 #define msm_jpeg_hw_irq_is_frame_done(jpeg_irq_status) \
@@ -77,25 +80,26 @@
 	(jpeg_irq_status & MSM_JPEG_HW_MASK_COMP_ERR)
 
 void msm_jpeg_hw_fe_buffer_update(struct msm_jpeg_hw_buf *p_input,
-	uint8_t pingpong_index);
+	uint8_t pingpong_index, void *);
 void msm_jpeg_hw_we_buffer_update(struct msm_jpeg_hw_buf *p_input,
-	uint8_t pingpong_index);
+	uint8_t pingpong_index, void *);
 
 void msm_jpeg_hw_we_buffer_cfg(uint8_t is_realtime);
 
-void msm_jpeg_hw_fe_start(void);
+void msm_jpeg_hw_fe_start(void *);
 void msm_jpeg_hw_clk_cfg(void);
 
 void msm_jpeg_hw_reset(void *base, int size);
 void msm_jpeg_hw_irq_cfg(void);
-void msm_jpeg_hw_init(void *base, int size);
 
-uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *hw_cmd_p);
-void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *hw_cmd_p);
-int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us);
-void msm_jpeg_hw_delay(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us);
-int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_cmds);
+uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *, void *);
+void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *, void *);
+int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *, int, void *);
+void msm_jpeg_hw_delay(struct msm_jpeg_hw_cmd *, int);
+int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *, int ,
+	uint32_t , void *);
 void msm_jpeg_hw_region_dump(int size);
-void msm_jpeg_io_dump(int size);
+void msm_jpeg_io_dump(void *base, int size);
+void msm_jpeg_decode_status(void *base);
 
 #endif /* MSM_JPEG_HW_H */
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
index ae64c32..928d59e 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
@@ -37,30 +37,25 @@
 #define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_PINGPONG_MASK 0x00000020
 #define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_PINGPONG_SHIFT 0x00000005
 
-#define MSM_JPEG_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_MASK 0x00000040
-#define MSM_JPEG_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_SHIFT 0x00000006
-
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_MASK 0x00000080
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_SHIFT 0x00000007
-
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_MASK 0x00000100
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_SHIFT 0x00000008
-
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_MASK 0x00000200
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_SHIFT 0x00000009
-
 #define MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK 0x10000000
 #define MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a
 
 #define MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800
 #define MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b
 
-#define MSM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK 0x00001000
-#define MSM_JPEG_HW_IRQ_STATUS_VIOLATION_SHIFT 0x0000000c
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF      (0x1<<19)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR     (0x1<<20)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR   (0x1<<21)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF (0x1<<22)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW    (0x1<<23)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM       (0x1<<24)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ   (0x1<<25)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM       (0x1<<26)
+#define MSM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK        (0x1<<29)
 
 #define JPEG_OFFLINE_CMD_START 0x00000001
 
-#define JPEG_RESET_DEFAULT 0x00000003 /* cfff? */
+#define JPEG_RESET_DEFAULT 0x00020000
 
 #define JPEG_IRQ_DISABLE_ALL 0x00000000
 #define JPEG_IRQ_CLEAR_ALL 0xFFFFFFFF
@@ -87,6 +82,9 @@
 #define JPEG_PLN1_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000D0)
 #define JPEG_PLN1_WR_PNTR_BMSK 0xFFFFFFFF
 
+#define JPEG_PLN2_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000D4)
+#define JPEG_PLN2_WR_PNTR_BMSK 0xFFFFFFFF
+
 #define JPEG_IRQ_MASK_ADDR (JPEG_REG_BASE + 0x00000018)
 #define JPEG_IRQ_MASK_BMSK 0xFFFFFFFF
 #define JPEG_IRQ_ALLSOURCES_ENABLE 0xFFFFFFFF
@@ -103,6 +101,11 @@
 #define JPEG_ENCODE_OUTPUT_SIZE_STATUS_ADDR (JPEG_REG_BASE + 0x00000180)
 #define JPEG_ENCODE_OUTPUT_SIZE_STATUS_BMSK 0x1FFFFFFF
 
+#define JPEG_DECODE_MCUS_DECODED_STATUS   (JPEG_REG_BASE + 0x00000258)
+#define JPEG_DECODE_BITS_CONSUMED_STATUS  (JPEG_REG_BASE + 0x0000025C)
+#define JPEG_DECODE_PRED_Y_STATE          (JPEG_REG_BASE + 0x00000260)
+#define JPEG_DECODE_PRED_C_STATE          (JPEG_REG_BASE + 0x00000264)
+#define JPEG_DECODE_RSM_STATE             (JPEG_REG_BASE + 0x00000268)
 
 #define VBIF_BASE_ADDRESS                      0xFDA60000
 #define VBIF_REGION_SIZE                       0xC30
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
index 981c56c..0370f63 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
@@ -26,36 +26,32 @@
 #include "msm_jpeg_common.h"
 #include "msm_jpeg_hw.h"
 
-/* AXI rate in KHz */
-struct ion_client *jpeg_client;
-static void *jpeg_vbif;
-
-void msm_jpeg_platform_p2v(struct file  *file,
-				struct ion_handle **ionhandle, int domain_num)
+void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file  *file,
+	struct ion_handle **ionhandle, int domain_num)
 {
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_unmap_iommu(jpeg_client, *ionhandle, domain_num, 0);
-	ion_free(jpeg_client, *ionhandle);
+	ion_unmap_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0);
+	ion_free(pgmn_dev->jpeg_client, *ionhandle);
 	*ionhandle = NULL;
 #elif CONFIG_ANDROID_PMEM
 	put_pmem_file(file);
 #endif
 }
 
-uint32_t msm_jpeg_platform_v2p(int fd, uint32_t len, struct file **file_p,
-				struct ion_handle **ionhandle, int domain_num)
-{
+uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
+	uint32_t len, struct file **file_p, struct ion_handle **ionhandle,
+	int domain_num) {
 	unsigned long paddr;
 	unsigned long size;
 	int rc;
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	*ionhandle = ion_import_dma_buf(jpeg_client, fd);
+	*ionhandle = ion_import_dma_buf(pgmn_dev->jpeg_client, fd);
 	if (IS_ERR_OR_NULL(*ionhandle))
 		return 0;
 
-	rc = ion_map_iommu(jpeg_client, *ionhandle, domain_num, 0,
-			 SZ_4K, 0, &paddr, (unsigned long *)&size, UNCACHED, 0);
-	JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__,
+	rc = ion_map_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0,
+		SZ_4K, 0, &paddr, (unsigned long *)&size, UNCACHED,
+0); JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__,
 							(uint32_t)paddr, size);
 
 #elif CONFIG_ANDROID_PMEM
@@ -81,7 +77,7 @@
 	return paddr;
 error1:
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_free(jpeg_client, *ionhandle);
+	ion_free(pgmn_dev->jpeg_client, *ionhandle);
 #endif
 	return 0;
 }
@@ -149,10 +145,10 @@
 	}
 	jpeg_irq = jpeg_irq_res->start;
 	JPEG_DBG("%s base address: 0x%x, jpeg irq number: %d\n", __func__,
-						jpeg_mem->start, jpeg_irq);
+		jpeg_mem->start, jpeg_irq);
 
 	jpeg_io = request_mem_region(jpeg_mem->start,
-					resource_size(jpeg_mem), pdev->name);
+		resource_size(jpeg_mem), pdev->name);
 	if (!jpeg_io) {
 		JPEG_PR_ERR("%s: region already claimed\n", __func__);
 		return -EBUSY;
@@ -165,14 +161,14 @@
 		goto fail1;
 	}
 
-	jpeg_vbif = ioremap(VBIF_BASE_ADDRESS, VBIF_REGION_SIZE);
-	if (!jpeg_vbif) {
+	pgmn_dev->jpeg_vbif = ioremap(VBIF_BASE_ADDRESS, VBIF_REGION_SIZE);
+	if (!pgmn_dev->jpeg_vbif) {
 		rc = -ENOMEM;
 		JPEG_PR_ERR("%s:%d] ioremap failed\n", __func__, __LINE__);
 		goto fail1;
 	}
 	JPEG_DBG("%s:%d] jpeg_vbif 0x%x", __func__, __LINE__,
-						(uint32_t)jpeg_vbif);
+		(uint32_t)pgmn_dev->jpeg_vbif);
 
 	pgmn_dev->jpeg_fs = regulator_get(&pgmn_dev->pdev->dev, "vdd");
 	rc = regulator_enable(pgmn_dev->jpeg_fs);
@@ -202,9 +198,8 @@
 					(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
 	}
 #endif
-	set_vbif_params(jpeg_vbif);
+	set_vbif_params(pgmn_dev->jpeg_vbif);
 
-	msm_jpeg_hw_init(jpeg_base, resource_size(jpeg_mem));
 	rc = request_irq(jpeg_irq, handler, IRQF_TRIGGER_RISING, "jpeg",
 		context);
 	if (rc) {
@@ -218,7 +213,7 @@
 	*irq  = jpeg_irq;
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	jpeg_client = msm_ion_client_create(-1, "camera/jpeg");
+	pgmn_dev->jpeg_client = msm_ion_client_create(-1, "camera/jpeg");
 #endif
 	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
 
@@ -276,11 +271,11 @@
 		regulator_disable(pgmn_dev->jpeg_fs);
 		pgmn_dev->jpeg_fs = NULL;
 	}
-	iounmap(jpeg_vbif);
+	iounmap(pgmn_dev->jpeg_vbif);
 	iounmap(base);
 	release_mem_region(mem->start, resource_size(mem));
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_client_destroy(jpeg_client);
+	ion_client_destroy(pgmn_dev->jpeg_client);
 #endif
 	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
 	return result;
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h
index 8a37cef..cd80d2e 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h
@@ -18,12 +18,13 @@
 #include <linux/ion.h>
 #include <linux/iommu.h>
 #include <mach/iommu.h>
+#include "msm_jpeg_sync.h"
 
-
-void msm_jpeg_platform_p2v(struct file  *file,
-				struct ion_handle **ionhandle, int domain_num);
-uint32_t msm_jpeg_platform_v2p(int fd, uint32_t len, struct file **file,
-				struct ion_handle **ionhandle, int domain_num);
+void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file *file,
+	struct ion_handle **ionhandle, int domain_num);
+uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
+	uint32_t len, struct file **file, struct ion_handle **ionhandle,
+	int domain_num);
 
 int msm_jpeg_platform_clk_enable(void);
 int msm_jpeg_platform_clk_disable(void);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
index 6ac4a5e..a0aaf03 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
@@ -22,7 +22,9 @@
 #include "msm_jpeg_platform.h"
 #include "msm_jpeg_common.h"
 
-static int release_buf;
+#define JPEG_REG_SIZE 0x308
+#define JPEG_DEV_CNT 3
+#define JPEG_DEC_ID 2
 
 inline void msm_jpeg_q_init(char const *name, struct msm_jpeg_q *q_p)
 {
@@ -143,15 +145,15 @@
 	return 0;
 }
 
-inline void msm_jpeg_outbuf_q_cleanup(struct msm_jpeg_q *q_p,
-				int domain_num)
+inline void msm_jpeg_outbuf_q_cleanup(struct msm_jpeg_device *pgmn_dev,
+	struct msm_jpeg_q *q_p, int domain_num)
 {
 	struct msm_jpeg_core_buf *buf_p;
 	JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
 	do {
 		buf_p = msm_jpeg_q_out(q_p);
 		if (buf_p) {
-			msm_jpeg_platform_p2v(buf_p->file,
+			msm_jpeg_platform_p2v(pgmn_dev, buf_p->file,
 				&buf_p->handle, domain_num);
 			JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
 			kfree(buf_p);
@@ -289,10 +291,10 @@
 	if (buf_out) {
 		JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
 			(int) buf_out->y_buffer_addr, buf_out->y_len);
-		rc = msm_jpeg_core_we_buf_update(buf_out);
+		rc = msm_jpeg_core_we_buf_update(pgmn_dev, buf_out);
 		kfree(buf_out);
 	} else {
-		msm_jpeg_core_we_buf_reset(buf_in);
+		msm_jpeg_core_we_buf_reset(pgmn_dev, buf_in);
 		JPEG_DBG("%s:%d] no output buffer\n", __func__, __LINE__);
 		rc = -2;
 	}
@@ -320,7 +322,7 @@
 	}
 
 	buf_cmd = buf_p->vbuf;
-	msm_jpeg_platform_p2v(buf_p->file, &buf_p->handle,
+	msm_jpeg_platform_p2v(pgmn_dev, buf_p->file, &buf_p->handle,
 		pgmn_dev->domain_num);
 	kfree(buf_p);
 
@@ -347,6 +349,7 @@
 {
 	struct msm_jpeg_buf buf_cmd;
 	struct msm_jpeg_core_buf *buf_p;
+	memset(&buf_cmd, 0x0, sizeof(struct msm_jpeg_buf));
 
 	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
 	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_jpeg_buf))) {
@@ -364,7 +367,7 @@
 		__func__, __LINE__, (int) buf_cmd.vaddr, buf_cmd.y_len,
 		buf_cmd.fd);
 
-	buf_p->y_buffer_addr = msm_jpeg_platform_v2p(buf_cmd.fd,
+	buf_p->y_buffer_addr = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
 		buf_cmd.y_len, &buf_p->file, &buf_p->handle,
 		pgmn_dev->domain_num);
 	if (!buf_p->y_buffer_addr) {
@@ -372,9 +375,18 @@
 		kfree(buf_p);
 		return -EFAULT;
 	}
-	JPEG_DBG("%s:%d]After v2p y_address =0x%08x, handle = %p\n",
-		__func__, __LINE__, buf_p->y_buffer_addr, buf_p->handle);
+
+	if (buf_cmd.cbcr_len)
+		buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr +
+			buf_cmd.y_len;
+	else
+		buf_p->cbcr_buffer_addr = 0x0;
+
+	JPEG_DBG("%s:%d] After v2p pln0_addr =0x%x,pln0_len %d pl1_len %d",
+		__func__, __LINE__, buf_p->y_buffer_addr,
+		buf_cmd.y_len, buf_cmd.cbcr_len);
 	buf_p->y_len = buf_cmd.y_len;
+	buf_p->cbcr_len = buf_cmd.cbcr_len;
 	buf_p->vbuf = buf_cmd;
 
 	msm_jpeg_q_in(&pgmn_dev->output_buf_q, buf_p);
@@ -403,9 +415,9 @@
 	buf_out = msm_jpeg_q_out(&pgmn_dev->input_buf_q);
 
 	if (buf_out) {
-		rc = msm_jpeg_core_fe_buf_update(buf_out);
+		rc = msm_jpeg_core_fe_buf_update(pgmn_dev, buf_out);
 		kfree(buf_out);
-		msm_jpeg_core_fe_start();
+		msm_jpeg_core_fe_start(pgmn_dev);
 	} else {
 		JPEG_DBG("%s:%d] no input buffer\n", __func__, __LINE__);
 		rc = -EFAULT;
@@ -433,8 +445,8 @@
 	}
 
 	buf_cmd = buf_p->vbuf;
-	msm_jpeg_platform_p2v(buf_p->file, &buf_p->handle,
-					pgmn_dev->domain_num);
+	msm_jpeg_platform_p2v(pgmn_dev, buf_p->file, &buf_p->handle,
+		pgmn_dev->domain_num);
 	kfree(buf_p);
 
 	JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
@@ -460,6 +472,7 @@
 {
 	struct msm_jpeg_core_buf *buf_p;
 	struct msm_jpeg_buf buf_cmd;
+	memset(&buf_cmd, 0x0, sizeof(struct msm_jpeg_buf));
 
 	if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_jpeg_buf))) {
 		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
@@ -475,20 +488,26 @@
 	JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
 		(int) buf_cmd.vaddr, buf_cmd.y_len);
 
-	buf_p->y_buffer_addr    = msm_jpeg_platform_v2p(buf_cmd.fd,
+	buf_p->y_buffer_addr    = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
 		buf_cmd.y_len + buf_cmd.cbcr_len, &buf_p->file,
 		&buf_p->handle, pgmn_dev->domain_num) + buf_cmd.offset
 		+ buf_cmd.y_off;
 	buf_p->y_len          = buf_cmd.y_len;
-	buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr + buf_cmd.y_len
-						+ buf_cmd.cbcr_off;
 	buf_p->cbcr_len       = buf_cmd.cbcr_len;
 	buf_p->num_of_mcu_rows = buf_cmd.num_of_mcu_rows;
+	buf_p->y_len = buf_cmd.y_len;
+	buf_p->cbcr_len = buf_cmd.cbcr_len;
+	if (buf_cmd.cbcr_len)
+		buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr + buf_cmd.y_len
+			+ buf_cmd.cbcr_off;
+	else
+		buf_p->cbcr_buffer_addr = 0x0;
+
 	JPEG_DBG("%s: y_addr=%x, y_len=%x, cbcr_addr=%x, cbcr_len=%x, fd =%d\n",
 		__func__, buf_p->y_buffer_addr, buf_p->y_len,
 		buf_p->cbcr_buffer_addr, buf_p->cbcr_len, buf_cmd.fd);
 
-	if (!buf_p->y_buffer_addr || !buf_p->cbcr_buffer_addr) {
+	if (!buf_p->y_buffer_addr) {
 		JPEG_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
 		kfree(buf_p);
 		return -EFAULT;
@@ -559,13 +578,15 @@
 	JPEG_DBG("%s:%d] platform resources - mem %p, base %p, irq %d\n",
 		__func__, __LINE__,
 		pgmn_dev->mem, pgmn_dev->base, pgmn_dev->irq);
+	pgmn_dev->res_size = resource_size(pgmn_dev->mem);
 
 	msm_jpeg_q_cleanup(&pgmn_dev->evt_q);
 	msm_jpeg_q_cleanup(&pgmn_dev->output_rtn_q);
-	msm_jpeg_outbuf_q_cleanup(&pgmn_dev->output_buf_q,
-	pgmn_dev->domain_num); msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
+	msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->output_buf_q,
+		pgmn_dev->domain_num);
+	msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
 	msm_jpeg_q_cleanup(&pgmn_dev->input_buf_q);
-	msm_jpeg_core_init();
+	msm_jpeg_core_init(pgmn_dev);
 
 	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
 	return rc;
@@ -583,13 +604,14 @@
 	pgmn_dev->open_count--;
 	mutex_unlock(&pgmn_dev->lock);
 
-	msm_jpeg_core_release(release_buf, pgmn_dev->domain_num);
+	msm_jpeg_core_release(pgmn_dev, pgmn_dev->domain_num);
 	msm_jpeg_q_cleanup(&pgmn_dev->evt_q);
 	msm_jpeg_q_cleanup(&pgmn_dev->output_rtn_q);
-	msm_jpeg_outbuf_q_cleanup(&pgmn_dev->output_buf_q,
-					pgmn_dev->domain_num);
+	msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->output_buf_q,
+		pgmn_dev->domain_num);
 	msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
-	msm_jpeg_outbuf_q_cleanup(&pgmn_dev->input_buf_q, pgmn_dev->domain_num);
+	msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->input_buf_q,
+		pgmn_dev->domain_num);
 
 	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
 	if (pgmn_dev->open_count)
@@ -598,6 +620,7 @@
 	msm_jpeg_platform_release(pgmn_dev->mem, pgmn_dev->base,
 		pgmn_dev->irq, pgmn_dev);
 
+	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
 	return 0;
 }
 
@@ -612,7 +635,8 @@
 		return -EFAULT;
 	}
 
-	is_copy_to_user = msm_jpeg_hw_exec_cmds(&hw_cmd, 1);
+	is_copy_to_user = msm_jpeg_hw_exec_cmds(&hw_cmd, 1,
+		pgmn_dev->res_size, pgmn_dev->base);
 	JPEG_DBG("%s:%d] type %d, n %d, offset %d, mask %x, data %x,pdata %x\n",
 		__func__, __LINE__, hw_cmd.type, hw_cmd.n, hw_cmd.offset,
 		hw_cmd.mask, hw_cmd.data, (int) hw_cmd.pdata);
@@ -657,7 +681,8 @@
 
 	hw_cmd_p = (struct msm_jpeg_hw_cmd *) &(hw_cmds_p->hw_cmd);
 
-	is_copy_to_user = msm_jpeg_hw_exec_cmds(hw_cmd_p, m);
+	is_copy_to_user = msm_jpeg_hw_exec_cmds(hw_cmd_p, m,
+		 pgmn_dev->res_size, pgmn_dev->base);
 
 	if (is_copy_to_user >= 0) {
 		if (copy_to_user(arg, hw_cmds_p, len)) {
@@ -678,12 +703,12 @@
 
 	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
 
-	release_buf = 1;
+	pgmn_dev->release_buf = 1;
 	for (i = 0; i < 2; i++) {
 		buf_out = msm_jpeg_q_out(&pgmn_dev->input_buf_q);
 
 		if (buf_out) {
-			msm_jpeg_core_fe_buf_update(buf_out);
+			msm_jpeg_core_fe_buf_update(pgmn_dev, buf_out);
 			kfree(buf_out);
 		} else {
 			JPEG_DBG("%s:%d] no input buffer\n", __func__,
@@ -696,8 +721,8 @@
 		buf_out_free[i] = msm_jpeg_q_out(&pgmn_dev->output_buf_q);
 
 		if (buf_out_free[i]) {
-			msm_jpeg_core_we_buf_update(buf_out_free[i]);
-			release_buf = 0;
+			msm_jpeg_core_we_buf_update(pgmn_dev, buf_out_free[i]);
+			pgmn_dev->release_buf = 0;
 		} else {
 			JPEG_DBG("%s:%d] no output buffer\n",
 			__func__, __LINE__);
@@ -708,6 +733,7 @@
 	for (i = 0; i < 2; i++)
 		kfree(buf_out_free[i]);
 
+	msm_jpeg_io_dump(pgmn_dev->base, JPEG_REG_SIZE);
 	rc = msm_jpeg_ioctl_hw_cmds(pgmn_dev, arg);
 	JPEG_DBG("%s:%d]\n", __func__, __LINE__);
 	return rc;
@@ -727,7 +753,7 @@
 
 	pgmn_dev->op_mode = ctrl_cmd.type;
 
-	rc = msm_jpeg_core_reset(pgmn_dev->op_mode, pgmn_dev->base,
+	rc = msm_jpeg_core_reset(pgmn_dev, pgmn_dev->op_mode, pgmn_dev->base,
 		resource_size(pgmn_dev->mem));
 	return rc;
 }
@@ -736,7 +762,7 @@
 	unsigned long arg)
 {
 	JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
-	msm_jpeg_io_dump(arg);
+	msm_jpeg_io_dump(pgmn_dev->base, JPEG_REG_SIZE);
 	return 0;
 }
 
@@ -836,9 +862,10 @@
 
 int __msm_jpeg_init(struct msm_jpeg_device *pgmn_dev)
 {
-	int rc = 0, i = 0;
+	int rc = 0, i = 0, j = 0;
 	int idx = 0;
-	char *iommu_name[3] = {"jpeg_enc0", "jpeg_enc1", "jpeg_dec"};
+	char *iommu_name[JPEG_DEV_CNT] = {"jpeg_enc0", "jpeg_enc1",
+		"jpeg_dec"};
 
 	mutex_init(&pgmn_dev->lock);
 
@@ -847,6 +874,7 @@
 	idx = pgmn_dev->pdev->id;
 	pgmn_dev->idx = idx;
 	pgmn_dev->iommu_cnt = 1;
+	pgmn_dev->decode_flag = (idx == JPEG_DEC_ID);
 
 	msm_jpeg_q_init("evt_q", &pgmn_dev->evt_q);
 	msm_jpeg_q_init("output_rtn_q", &pgmn_dev->output_rtn_q);
@@ -855,21 +883,23 @@
 	msm_jpeg_q_init("input_buf_q", &pgmn_dev->input_buf_q);
 
 #ifdef CONFIG_MSM_IOMMU
-/*get device context for IOMMU*/
+	j = (pgmn_dev->iommu_cnt <= 1) ? idx : 0;
+	/*get device context for IOMMU*/
 	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
-		pgmn_dev->iommu_ctx_arr[i] = msm_iommu_get_ctx(iommu_name[i]);
-		JPEG_DBG("%s:%d] name %s", __func__, __LINE__, iommu_name[i]);
+		pgmn_dev->iommu_ctx_arr[i] = msm_iommu_get_ctx(iommu_name[j]);
+		JPEG_DBG("%s:%d] name %s", __func__, __LINE__, iommu_name[j]);
 		JPEG_DBG("%s:%d] ctx 0x%x", __func__, __LINE__,
-					(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
+			(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
 		if (!pgmn_dev->iommu_ctx_arr[i]) {
 			JPEG_PR_ERR("%s: No iommu fw context found\n",
 					__func__);
 			goto error;
 		}
+		j++;
 	}
 	pgmn_dev->domain_num = camera_register_domain();
 	JPEG_DBG("%s:%d] dom_num 0x%x", __func__, __LINE__,
-				pgmn_dev->domain_num);
+		pgmn_dev->domain_num);
 	if (pgmn_dev->domain_num < 0) {
 		JPEG_PR_ERR("%s: could not register domain\n", __func__);
 		goto error;
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h
index 1d82060..1ac4838 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h
@@ -21,7 +21,7 @@
 #include <linux/platform_device.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-subdev.h>
-#include "msm_jpeg_core.h"
+#include "msm_jpeg_hw.h"
 
 #define JPEG_7X 0x1
 #define JPEG_8X60 (0x1 << 1)
@@ -88,6 +88,17 @@
 	struct iommu_domain *domain;
 	struct device *iommu_ctx_arr[3];
 	int iommu_cnt;
+	int decode_flag;
+	struct ion_client *jpeg_client;
+	void *jpeg_vbif;
+	int release_buf;
+	struct msm_jpeg_hw_pingpong fe_pingpong_buf;
+	struct msm_jpeg_hw_pingpong we_pingpong_buf;
+	int we_pingpong_index;
+	int reset_done_ack;
+	spinlock_t reset_lock;
+	wait_queue_head_t reset_wait;
+	uint32_t res_size;
 };
 
 int __msm_jpeg_open(struct msm_jpeg_device *pgmn_dev);
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 6c0f224..c137c08 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -95,7 +95,7 @@
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.minimum = MIN_FRAME_RATE,
 		.maximum = MAX_FRAME_RATE,
-		.default_value = DEFAULT_FRAME_RATE,
+		.default_value = MIN_FRAME_RATE,
 		.step = 1,
 		.menu_skip_mask = 0,
 		.qmenu = NULL,
diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c
index ba16ed9..7ed8ffa 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.c
+++ b/drivers/net/usb/rmnet_usb_ctrl.c
@@ -122,6 +122,55 @@
 	return 0;
 }
 
+static void get_encap_work(struct work_struct *w)
+{
+	struct usb_device	*udev;
+	struct rmnet_ctrl_dev	*dev =
+			container_of(w, struct rmnet_ctrl_dev, get_encap_work);
+	int			status;
+
+	udev = interface_to_usbdev(dev->intf);
+
+	status = usb_autopm_get_interface(dev->intf);
+	if (status < 0 && status != -EAGAIN && status != -EACCES) {
+		dev->get_encap_failure_cnt++;
+		return;
+	}
+
+	usb_fill_control_urb(dev->rcvurb, udev,
+				usb_rcvctrlpipe(udev, 0),
+				(unsigned char *)dev->in_ctlreq,
+				dev->rcvbuf,
+				DEFAULT_READ_URB_LENGTH,
+				resp_avail_cb, dev);
+
+
+	usb_anchor_urb(dev->rcvurb, &dev->rx_submitted);
+	status = usb_submit_urb(dev->rcvurb, GFP_KERNEL);
+	if (status) {
+		dev->get_encap_failure_cnt++;
+		usb_unanchor_urb(dev->rcvurb);
+		usb_autopm_put_interface(dev->intf);
+		dev_err(dev->devicep,
+		"%s: Error submitting Read URB %d\n", __func__, status);
+		goto resubmit_int_urb;
+	}
+
+	return;
+
+resubmit_int_urb:
+	/*check if it is already submitted in resume*/
+	if (!dev->inturb->anchor) {
+		usb_anchor_urb(dev->inturb, &dev->rx_submitted);
+		status = usb_submit_urb(dev->inturb, GFP_KERNEL);
+		if (status) {
+			usb_unanchor_urb(dev->inturb);
+			dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
+				__func__, status);
+		}
+	}
+}
+
 static void notification_available_cb(struct urb *urb)
 {
 	int				status;
@@ -133,12 +182,13 @@
 
 	switch (urb->status) {
 	case 0:
+	/*if non zero lenght of data received while unlink*/
+	case -ENOENT:
 		/*success*/
 		break;
 
 	/*do not resubmit*/
 	case -ESHUTDOWN:
-	case -ENOENT:
 	case -ECONNRESET:
 	case -EPROTO:
 		return;
@@ -156,26 +206,17 @@
 		goto resubmit_int_urb;
 	}
 
+	if (!urb->actual_length)
+		return;
+
 	ctrl = urb->transfer_buffer;
 
 	switch (ctrl->bNotificationType) {
 	case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
 		dev->resp_avail_cnt++;
-		usb_fill_control_urb(dev->rcvurb, udev,
-					usb_rcvctrlpipe(udev, 0),
-					(unsigned char *)dev->in_ctlreq,
-					dev->rcvbuf,
-					DEFAULT_READ_URB_LENGTH,
-					resp_avail_cb, dev);
-
-		status = usb_submit_urb(dev->rcvurb, GFP_ATOMIC);
-		if (status) {
-			dev_err(dev->devicep,
-			"%s: Error submitting Read URB %d\n", __func__, status);
-			goto resubmit_int_urb;
-		}
 
 		usb_mark_last_busy(udev);
+		queue_work(dev->wq, &dev->get_encap_work);
 
 		if (!dev->resp_available) {
 			dev->resp_available = true;
@@ -189,10 +230,13 @@
 	}
 
 resubmit_int_urb:
+	usb_anchor_urb(urb, &dev->rx_submitted);
 	status = usb_submit_urb(urb, GFP_ATOMIC);
-	if (status)
+	if (status) {
+		usb_unanchor_urb(urb);
 		dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
 		__func__, status);
+	}
 
 	return;
 }
@@ -208,6 +252,8 @@
 
 	udev = interface_to_usbdev(dev->intf);
 
+	usb_autopm_put_interface_async(dev->intf);
+
 	switch (urb->status) {
 	case 0:
 		/*success*/
@@ -263,41 +309,41 @@
 	wake_up(&dev->read_wait_queue);
 
 resubmit_int_urb:
-	/*re-submit int urb to check response available*/
-	usb_mark_last_busy(udev);
-	status = usb_submit_urb(dev->inturb, GFP_ATOMIC);
-	if (status)
-		dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
-			__func__, status);
+	/*check if it is already submitted in resume*/
+	if (!dev->inturb->anchor) {
+		usb_mark_last_busy(udev);
+		usb_anchor_urb(dev->inturb, &dev->rx_submitted);
+		status = usb_submit_urb(dev->inturb, GFP_ATOMIC);
+		if (status) {
+			usb_unanchor_urb(dev->inturb);
+			dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
+				__func__, status);
+		}
+	}
 }
 
 int rmnet_usb_ctrl_start_rx(struct rmnet_ctrl_dev *dev)
 {
 	int	retval = 0;
 
+	usb_anchor_urb(dev->inturb, &dev->rx_submitted);
 	retval = usb_submit_urb(dev->inturb, GFP_KERNEL);
-	if (retval < 0)
-		dev_err(dev->devicep, "%s Intr submit %d\n", __func__, retval);
+	if (retval < 0) {
+		usb_unanchor_urb(dev->inturb);
+		dev_err(dev->devicep, "%s Intr submit %d\n", __func__,
+				retval);
+	}
 
 	return retval;
 }
 
-int rmnet_usb_ctrl_stop_rx(struct rmnet_ctrl_dev *dev)
+int rmnet_usb_ctrl_suspend(struct rmnet_ctrl_dev *dev)
 {
-	if (!is_dev_connected(dev)) {
-		dev_dbg(dev->devicep, "%s: Ctrl device disconnected\n",
-			__func__);
-		return -ENODEV;
-	}
-
-	dev_dbg(dev->devicep, "%s\n", __func__);
-
-	usb_kill_urb(dev->rcvurb);
-	usb_kill_urb(dev->inturb);
+	if (!flush_work_sync(&dev->get_encap_work))
+		usb_kill_anchored_urbs(&dev->rx_submitted);
 
 	return 0;
 }
-
 static int rmnet_usb_ctrl_alloc_rx(struct rmnet_ctrl_dev *dev)
 {
 	int	retval = -ENOMEM;
@@ -826,7 +872,6 @@
 
 void rmnet_usb_ctrl_disconnect(struct rmnet_ctrl_dev *dev)
 {
-	rmnet_usb_ctrl_stop_rx(dev);
 
 	mutex_lock(&dev->dev_lock);
 
@@ -839,13 +884,16 @@
 
 	wake_up(&dev->read_wait_queue);
 
+	cancel_work_sync(&dev->get_encap_work);
+
+	usb_kill_anchored_urbs(&dev->tx_submitted);
+	usb_kill_anchored_urbs(&dev->rx_submitted);
+
 	usb_free_urb(dev->inturb);
 	dev->inturb = NULL;
 
 	kfree(dev->intbuf);
 	dev->intbuf = NULL;
-
-	usb_kill_anchored_urbs(&dev->tx_submitted);
 }
 
 #if defined(CONFIG_DEBUG_FS)
@@ -879,6 +927,7 @@
 				"cbits_tomdm:              %d\n"
 				"mdm_wait_timeout:         %u\n"
 				"zlp_cnt:                  %u\n"
+				"get_encap_failure_cnt     %u\n"
 				"dev opened:               %s\n",
 				dev, dev->name,
 				dev->snd_encap_cmd_cnt,
@@ -890,6 +939,7 @@
 				dev->cbits_tomdm,
 				dev->mdm_wait_timeout,
 				dev->zlp_cnt,
+				dev->get_encap_failure_cnt,
 				dev->is_opened ? "OPEN" : "CLOSE");
 
 	}
@@ -968,12 +1018,21 @@
 		/*for debug purpose*/
 		snprintf(dev->name, CTRL_DEV_MAX_LEN, "hsicctl%d", n);
 
+		dev->wq = create_singlethread_workqueue(dev->name);
+		if (!dev->wq) {
+			pr_err("unable to allocate workqueue");
+			kfree(dev);
+			goto error0;
+		}
+
 		mutex_init(&dev->dev_lock);
 		spin_lock_init(&dev->rx_lock);
 		init_waitqueue_head(&dev->read_wait_queue);
 		init_waitqueue_head(&dev->open_wait_queue);
 		INIT_LIST_HEAD(&dev->rx_list);
 		init_usb_anchor(&dev->tx_submitted);
+		init_usb_anchor(&dev->rx_submitted);
+		INIT_WORK(&dev->get_encap_work, get_encap_work);
 
 		status = rmnet_usb_ctrl_alloc_rx(dev);
 		if (status < 0) {
@@ -1074,6 +1133,7 @@
 		device_remove_file(ctrl_dev[i]->devicep, &dev_attr_modem_wait);
 #endif
 		cdev_del(&ctrl_dev[i]->cdev);
+		destroy_workqueue(ctrl_dev[i]->wq);
 		kfree(ctrl_dev[i]);
 		ctrl_dev[i] = NULL;
 		device_destroy(ctrldev_classp, MKDEV(MAJOR(ctrldev_num), i));
diff --git a/drivers/net/usb/rmnet_usb_ctrl.h b/drivers/net/usb/rmnet_usb_ctrl.h
index 7a84817..a8f8079 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.h
+++ b/drivers/net/usb/rmnet_usb_ctrl.h
@@ -34,6 +34,7 @@
 	struct urb		*rcvurb;
 	struct urb		*inturb;
 	struct usb_anchor	tx_submitted;
+	struct usb_anchor	rx_submitted;
 	void			*rcvbuf;
 	void			*intbuf;
 	struct usb_ctrlrequest	*in_ctlreq;
@@ -44,6 +45,9 @@
 	wait_queue_head_t	read_wait_queue;
 	wait_queue_head_t	open_wait_queue;
 
+	struct workqueue_struct	*wq;
+	struct work_struct	get_encap_work;
+
 	unsigned		is_opened;
 
 	bool			is_connected;
@@ -66,6 +70,7 @@
 	unsigned int		snd_encap_cmd_cnt;
 	unsigned int		get_encap_resp_cnt;
 	unsigned int		resp_avail_cnt;
+	unsigned int		get_encap_failure_cnt;
 	unsigned int		set_ctrl_line_state_cnt;
 	unsigned int		tx_ctrl_err_cnt;
 	unsigned int		zlp_cnt;
@@ -74,7 +79,7 @@
 extern struct rmnet_ctrl_dev *ctrl_dev[];
 
 extern int rmnet_usb_ctrl_start_rx(struct rmnet_ctrl_dev *);
-extern int rmnet_usb_ctrl_stop_rx(struct rmnet_ctrl_dev *);
+extern int rmnet_usb_ctrl_suspend(struct rmnet_ctrl_dev *dev);
 extern int rmnet_usb_ctrl_init(void);
 extern void rmnet_usb_ctrl_exit(void);
 extern int rmnet_usb_ctrl_probe(struct usb_interface *intf,
diff --git a/drivers/net/usb/rmnet_usb_data.c b/drivers/net/usb/rmnet_usb_data.c
index b8c6140..17ff067 100644
--- a/drivers/net/usb/rmnet_usb_data.c
+++ b/drivers/net/usb/rmnet_usb_data.c
@@ -87,7 +87,6 @@
 {
 	struct usbnet		*unet;
 	struct rmnet_ctrl_dev	*dev;
-	int			time = 0;
 	int			retval = 0;
 
 	unet = usb_get_intfdata(iface);
@@ -107,19 +106,12 @@
 
 	retval = usbnet_suspend(iface, message);
 	if (!retval) {
-		if (message.event & PM_EVENT_SUSPEND) {
-			time = usb_wait_anchor_empty_timeout(&dev->tx_submitted,
-								1000);
-			if (!time)
-				usb_kill_anchored_urbs(&dev->tx_submitted);
-
-			retval = rmnet_usb_ctrl_stop_rx(dev);
-			iface->dev.power.power_state.event = message.event;
-		}
-		/*  TBD : do we need to set/clear usbnet->udev->reset_resume*/
-		} else
+		retval = rmnet_usb_ctrl_suspend(dev);
+		iface->dev.power.power_state.event = message.event;
+	} else {
 		dev_dbg(&iface->dev,
 			"%s: device is busy can not suspend\n", __func__);
+	}
 
 fail:
 	return retval;
diff --git a/drivers/tty/smux_ctl.c b/drivers/tty/smux_ctl.c
index 7e0e6f8..c17495b 100644
--- a/drivers/tty/smux_ctl.c
+++ b/drivers/tty/smux_ctl.c
@@ -770,12 +770,13 @@
 	poll_wait(file, &devp->read_wait_queue, wait);
 
 	readable = smux_ctl_readable(devp->id);
-	if (readable < 0) {
+	if (readable > 0) {
+		mask = POLLIN | POLLRDNORM;
+	} else if ((readable < 0) && (readable != -ERESTARTSYS)) {
+		/* error case (non-signal) received */
 		pr_err(SMUX_CTL_MODULE_NAME ": %s err%d during poll for smuxctl%d\n",
 			__func__, readable, devp->id);
 		mask = POLLERR;
-	} else if (readable) {
-		mask = POLLIN | POLLRDNORM;
 	}
 
 	return mask;
diff --git a/drivers/usb/gadget/u_data_hsic.c b/drivers/usb/gadget/u_data_hsic.c
index 89d2887..746c041 100644
--- a/drivers/usb/gadget/u_data_hsic.c
+++ b/drivers/usb/gadget/u_data_hsic.c
@@ -220,6 +220,7 @@
 		req->context = skb;
 		req->buf = skb->data;
 		req->length = skb->len;
+		req->zero = 1;
 
 		port->n_tx_req_queued++;
 		if (port->n_tx_req_queued == ghsic_data_tx_intr_thld) {
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index fee7a09..b7f1878 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -659,12 +659,6 @@
 		return 0;
 	}
 
-	if (!(readl_relaxed(USB_PORTSC) & PORT_PE)) {
-		dev_dbg(mehci->dev, "%s:port is not enabled skip suspend\n",
-				__func__);
-		return -EAGAIN;
-	}
-
 	disable_irq(hcd->irq);
 
 	/* make sure we don't race against a remote wakeup */
@@ -934,6 +928,15 @@
 
 static int ehci_hsic_bus_suspend(struct usb_hcd *hcd)
 {
+	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
+
+	if (!(readl_relaxed(USB_PORTSC) & PORT_PE)) {
+		dbg_log_event(NULL, "RH suspend attempt failed", 0);
+		dev_dbg(mehci->dev, "%s:port is not enabled skip suspend\n",
+				__func__);
+		return -EAGAIN;
+	}
+
 	dbg_log_event(NULL, "Suspend RH", 0);
 	return ehci_bus_suspend(hcd);
 }
diff --git a/drivers/video/msm/mipi_NT35510.c b/drivers/video/msm/mipi_NT35510.c
index 0c6ff79..d75198a 100644
--- a/drivers/video/msm/mipi_NT35510.c
+++ b/drivers/video/msm/mipi_NT35510.c
@@ -32,8 +32,8 @@
 static char write_ram[2] = {0x2c, 0x00}; /* write ram */
 
 static struct dsi_cmd_desc nt35510_display_off_cmds[] = {
-	{DTYPE_DCS_WRITE, 1, 0, 0, 150, sizeof(display_off), display_off},
-	{DTYPE_DCS_WRITE, 1, 0, 0, 150, sizeof(enter_sleep), enter_sleep}
+	{DTYPE_DCS_WRITE, 1, 0, 0, 50, sizeof(display_off), display_off},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 50, sizeof(enter_sleep), enter_sleep}
 };
 
 static char cmd0[6] = {
@@ -213,46 +213,46 @@
 };
 static char config_MADCTL[2] = {0x36, 0x00};
 static struct dsi_cmd_desc nt35510_cmd_display_on_cmds[] = {
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd0), cmd0},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd1), cmd1},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd2), cmd2},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd3), cmd3},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd4), cmd4},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd5), cmd5},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd6), cmd6},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd7), cmd7},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd8), cmd8},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd9), cmd9},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd10), cmd10},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd11), cmd11},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd12), cmd12},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd13), cmd13},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd14), cmd14},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd15), cmd15},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd16), cmd16},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd17), cmd17},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd18), cmd18},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd19), cmd19},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd20), cmd20},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd21), cmd21},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd22), cmd22},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd23), cmd23},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd24), cmd24},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd25), cmd25},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd26), cmd26},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd27), cmd27},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd0), cmd0},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd1), cmd1},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd2), cmd2},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd3), cmd3},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd4), cmd4},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd5), cmd5},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd6), cmd6},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd7), cmd7},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd8), cmd8},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd9), cmd9},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd10), cmd10},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd11), cmd11},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd12), cmd12},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd13), cmd13},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd14), cmd14},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd15), cmd15},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd16), cmd16},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd17), cmd17},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd18), cmd18},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd19), cmd19},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd20), cmd20},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd21), cmd21},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd22), cmd22},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd23), cmd23},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd24), cmd24},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd25), cmd25},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd26), cmd26},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd27), cmd27},
 
-	{DTYPE_DCS_WRITE, 1, 0, 0, 150,	sizeof(exit_sleep), exit_sleep},
-	{DTYPE_DCS_WRITE, 1, 0, 0, 10,	sizeof(display_on), display_on},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 0,	sizeof(exit_sleep), exit_sleep},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 0,	sizeof(display_on), display_on},
 
-	{DTYPE_DCS_WRITE1, 1, 0, 0, 150,
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 0,
 		sizeof(config_MADCTL), config_MADCTL},
 
-	{DTYPE_DCS_WRITE, 1, 0, 0, 10,	sizeof(write_ram), write_ram},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 0,	sizeof(write_ram), write_ram},
 };
 
 static struct dsi_cmd_desc nt35510_cmd_display_on_cmds_rotate[] = {
-	{DTYPE_DCS_LWRITE, 1, 0, 0, 50,
+	{DTYPE_DCS_LWRITE, 1, 0, 0, 0,
 		sizeof(cmd19_rotate), cmd19_rotate},
 };
 
@@ -430,34 +430,34 @@
 };
 static char config_video_MADCTL[2] = {0x36, 0xC0};
 static struct dsi_cmd_desc nt35510_video_display_on_cmds[] = {
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video0), video0},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video1), video1},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video2), video2},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video3), video3},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video4), video4},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video5), video5},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video6), video6},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video7), video7},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video8), video8},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video9), video9},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video10), video10},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video11), video11},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video12), video12},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video13), video13},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video14), video14},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video15), video15},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video16), video16},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video17), video17},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video18), video18},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video19), video19},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video20), video20},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video21), video21},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video22), video22},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video23), video23},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video24), video24},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video25), video25},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video26), video26},
-	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video27), video27},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video0), video0},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video1), video1},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video2), video2},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video3), video3},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video4), video4},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video5), video5},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video6), video6},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video7), video7},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video8), video8},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video9), video9},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video10), video10},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video11), video11},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video12), video12},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video13), video13},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video14), video14},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video15), video15},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video16), video16},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video17), video17},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video18), video18},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video19), video19},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video20), video20},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video21), video21},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video22), video22},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video23), video23},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video24), video24},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video25), video25},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video26), video26},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video27), video27},
 	{DTYPE_DCS_WRITE, 1, 0, 0, NT35510_SLEEP_OFF_DELAY, sizeof(exit_sleep),
 			exit_sleep},
 	{DTYPE_DCS_WRITE, 1, 0, 0, NT35510_DISPLAY_ON_DELAY, sizeof(display_on),
@@ -465,7 +465,7 @@
 };
 
 static struct dsi_cmd_desc nt35510_video_display_on_cmds_rotate[] = {
-	{DTYPE_DCS_WRITE1, 1, 0, 0, 150,
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 0,
 		sizeof(config_video_MADCTL), config_video_MADCTL},
 };
 static int mipi_nt35510_lcd_on(struct platform_device *pdev)
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index 4f19de9..d94bc5b 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -1258,6 +1258,8 @@
 				output_vcd_frm->flags |=
 					VCD_FRAME_FLAG_DATACORRUPT;
 		}
+		if (decoder->codec.codec != VCD_CODEC_H264)
+			output_vcd_frm->flags &= ~VCD_FRAME_FLAG_DATACORRUPT;
 		output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top;
 		vidc_sm_get_picture_times(&ddl->shared_mem
 			[ddl->command_channel],
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 2253655..71ff639 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -2,7 +2,7 @@
 #define _MSM_KGSL_H
 
 #define KGSL_VERSION_MAJOR        3
-#define KGSL_VERSION_MINOR        11
+#define KGSL_VERSION_MINOR        12
 
 /*context flags */
 #define KGSL_CONTEXT_SAVE_GMEM		0x00000001
@@ -432,7 +432,8 @@
 
 /*
  * A timestamp event allows the user space to register an action following an
- * expired timestamp.
+ * expired timestamp. Note IOCTL_KGSL_TIMESTAMP_EVENT has been redefined to
+ * _IOWR to support fences which need to return a fd for the priv parameter.
  */
 
 struct kgsl_timestamp_event {
@@ -443,7 +444,7 @@
 	size_t len;              /* Size of the event specific blob */
 };
 
-#define IOCTL_KGSL_TIMESTAMP_EVENT \
+#define IOCTL_KGSL_TIMESTAMP_EVENT_OLD \
 	_IOW(KGSL_IOC_TYPE, 0x31, struct kgsl_timestamp_event)
 
 /* A genlock timestamp event releases an existing lock on timestamp expire */
@@ -454,6 +455,14 @@
 	int handle; /* Handle of the genlock lock to release */
 };
 
+/* A fence timestamp event releases an existing lock on timestamp expire */
+
+#define KGSL_TIMESTAMP_EVENT_FENCE 2
+
+struct kgsl_timestamp_event_fence {
+	int fence_fd; /* Fence to signal */
+};
+
 /*
  * Set a property within the kernel.  Uses the same structure as
  * IOCTL_KGSL_GETPROPERTY
@@ -462,6 +471,9 @@
 #define IOCTL_KGSL_SETPROPERTY \
 	_IOW(KGSL_IOC_TYPE, 0x32, struct kgsl_device_getproperty)
 
+#define IOCTL_KGSL_TIMESTAMP_EVENT \
+	_IOWR(KGSL_IOC_TYPE, 0x33, struct kgsl_timestamp_event)
+
 #ifdef __KERNEL__
 #ifdef CONFIG_MSM_KGSL_DRM
 int kgsl_gem_obj_addr(int drm_fd, int handle, unsigned long *start,
diff --git a/include/media/msm_jpeg.h b/include/media/msm_jpeg.h
index 11c3247..56829f1 100644
--- a/include/media/msm_jpeg.h
+++ b/include/media/msm_jpeg.h
@@ -85,6 +85,8 @@
 
 	uint32_t num_of_mcu_rows;
 	uint32_t offset;
+	uint32_t pln2_off;
+	uint32_t pln2_len;
 };
 
 #define MSM_JPEG_HW_CMD_TYPE_READ      0