Merge "ASoC: msm: qdsp6v2: Fix bugs in listen client and server"
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index a41f9d5..c0253da 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -283,6 +283,7 @@
 CONFIG_ION=y
 CONFIG_ION_MSM=y
 CONFIG_MSM_KGSL=y
+CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
 CONFIG_FB=y
 CONFIG_FB_VIRTUAL=y
 CONFIG_FB_MSM=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index fe77fc4..ce5ee8d 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -282,6 +282,7 @@
 CONFIG_ION=y
 CONFIG_ION_MSM=y
 CONFIG_MSM_KGSL=y
+CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
 CONFIG_FB=y
 CONFIG_FB_MSM=y
 # CONFIG_FB_MSM_BACKLIGHT is not set
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index bdb5455..5e12a0d 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -138,41 +138,6 @@
 	spin_unlock_irqrestore(&mdm_devices_lock, flags);
 }
 
-struct mdm_device *mdm_get_device_by_device_id(int device_id)
-{
-	unsigned long flags;
-	struct mdm_device *mdev = NULL;
-
-	spin_lock_irqsave(&mdm_devices_lock, flags);
-	list_for_each_entry(mdev, &mdm_devices, link) {
-		if (mdev && mdev->mdm_data.device_id == device_id) {
-			spin_unlock_irqrestore(&mdm_devices_lock, flags);
-			return mdev;
-		}
-	}
-	spin_unlock_irqrestore(&mdm_devices_lock, flags);
-	return NULL;
-}
-
-struct mdm_device *mdm_get_device_by_name(const char *name)
-{
-	unsigned long flags;
-	struct mdm_device *mdev;
-
-	if (!name)
-		return NULL;
-	spin_lock_irqsave(&mdm_devices_lock, flags);
-	list_for_each_entry(mdev, &mdm_devices, link) {
-		if (mdev && !strncmp(mdev->device_name, name,
-				sizeof(mdev->device_name))) {
-			spin_unlock_irqrestore(&mdm_devices_lock, flags);
-			return mdev;
-		}
-	}
-	spin_unlock_irqrestore(&mdm_devices_lock, flags);
-	return NULL;
-}
-
 /* If the platform's cascading_ssr flag is set, the subsystem
  * restart module will restart the other modems so stop
  * monitoring them as well.
@@ -390,19 +355,13 @@
 	}
 }
 
-long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
+static long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
 				unsigned long arg)
 {
 	int status, ret = 0;
-	struct mdm_device *mdev;
+	struct mdm_device *mdev = filp->private_data;
 	struct mdm_modem_drv *mdm_drv;
 
-	mdev = mdm_get_device_by_name(filp->f_path.dentry->d_iname);
-	if (!mdev) {
-		pr_err("%s: mdm_device not found\n", __func__);
-		return -ENODEV;
-	}
-
 	if (_IOC_TYPE(cmd) != CHARM_CODE) {
 		pr_err("%s: invalid ioctl code to mdm id %d\n",
 			   __func__, mdev->mdm_data.device_id);
@@ -559,6 +518,11 @@
 /* set the mdm_device as the file's private data */
 static int mdm_modem_open(struct inode *inode, struct file *file)
 {
+	struct miscdevice *misc = file->private_data;
+	struct mdm_device *mdev = container_of(misc,
+			struct mdm_device, misc_device);
+
+	file->private_data = mdev;
 	return 0;
 }
 
@@ -1072,6 +1036,7 @@
 		goto init_err;
 	}
 
+	platform_set_drvdata(pdev, mdev);
 	mdm_modem_initialize_data(pdev, mdev);
 
 	if (mdm_ops->debug_state_changed_cb)
@@ -1118,10 +1083,7 @@
 static int __devexit mdm_modem_remove(struct platform_device *pdev)
 {
 	int ret;
-	struct mdm_device *mdev = mdm_get_device_by_device_id(pdev->id);
-
-	if (!mdev)
-		return -ENODEV;
+	struct mdm_device *mdev = platform_get_drvdata(pdev);
 
 	pr_debug("%s: removing device id %d\n",
 			__func__, mdev->mdm_data.device_id);
@@ -1135,9 +1097,7 @@
 static void mdm_modem_shutdown(struct platform_device *pdev)
 {
 	struct mdm_modem_drv *mdm_drv;
-	struct mdm_device *mdev = mdm_get_device_by_device_id(pdev->id);
-	if (!mdev)
-		return;
+	struct mdm_device *mdev = platform_get_drvdata(pdev);
 
 	pr_debug("%s: shutting down device id %d\n",
 		 __func__, mdev->mdm_data.device_id);
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index d0e3e34..d7bf193 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -603,10 +603,10 @@
 
 static unsigned int _adreno_iommu_setstate_v0(struct kgsl_device *device,
 					unsigned int *cmds_orig,
-					unsigned int pt_val,
+					phys_addr_t pt_val,
 					int num_iommu_units, uint32_t flags)
 {
-	unsigned int reg_pt_val;
+	phys_addr_t reg_pt_val;
 	unsigned int *cmds = cmds_orig;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	int i;
@@ -632,8 +632,10 @@
 		 * IOMMU units
 		 */
 		for (i = 0; i < num_iommu_units; i++) {
-			reg_pt_val = (pt_val + kgsl_mmu_get_pt_lsb(&device->mmu,
-						i, KGSL_IOMMU_CONTEXT_USER));
+			reg_pt_val = kgsl_mmu_get_default_ttbr0(&device->mmu,
+						i, KGSL_IOMMU_CONTEXT_USER);
+			reg_pt_val &= ~KGSL_IOMMU_CTX_TTBR0_ADDR_MASK;
+			reg_pt_val |= (pt_val & KGSL_IOMMU_CTX_TTBR0_ADDR_MASK);
 			/*
 			 * Set address of the new pagetable by writng to IOMMU
 			 * TTBR0 register
@@ -662,8 +664,11 @@
 		 * tlb flush
 		 */
 		for (i = 0; i < num_iommu_units; i++) {
-			reg_pt_val = (pt_val + kgsl_mmu_get_pt_lsb(&device->mmu,
+			reg_pt_val = (pt_val + kgsl_mmu_get_default_ttbr0(
+						&device->mmu,
 						i, KGSL_IOMMU_CONTEXT_USER));
+			reg_pt_val &= ~KGSL_IOMMU_CTX_TTBR0_ADDR_MASK;
+			reg_pt_val |= (pt_val & KGSL_IOMMU_CTX_TTBR0_ADDR_MASK);
 
 			*cmds++ = cp_type3_packet(CP_MEM_WRITE, 2);
 			*cmds++ = kgsl_mmu_get_reg_gpuaddr(&device->mmu, i,
@@ -707,17 +712,20 @@
 
 static unsigned int _adreno_iommu_setstate_v1(struct kgsl_device *device,
 					unsigned int *cmds_orig,
-					unsigned int pt_val,
+					phys_addr_t pt_val,
 					int num_iommu_units, uint32_t flags)
 {
+	phys_addr_t ttbr0_val;
 	unsigned int reg_pt_val;
 	unsigned int *cmds = cmds_orig;
 	int i;
 	unsigned int ttbr0, tlbiall, tlbstatus, tlbsync, mmu_ctrl;
 
 	for (i = 0; i < num_iommu_units; i++) {
-		reg_pt_val = (pt_val + kgsl_mmu_get_pt_lsb(&device->mmu,
-				i, KGSL_IOMMU_CONTEXT_USER));
+		ttbr0_val = kgsl_mmu_get_default_ttbr0(&device->mmu,
+				i, KGSL_IOMMU_CONTEXT_USER);
+		ttbr0_val &= ~KGSL_IOMMU_CTX_TTBR0_ADDR_MASK;
+		ttbr0_val |= (pt_val & KGSL_IOMMU_CTX_TTBR0_ADDR_MASK);
 		if (flags & KGSL_MMUFLAGS_PTUPDATE) {
 			mmu_ctrl = kgsl_mmu_get_reg_ahbaddr(
 				&device->mmu, i,
@@ -753,8 +761,19 @@
 				KGSL_IOMMU_IMPLDEF_MICRO_MMU_CTRL_IDLE, 0xF);
 			}
 			/* set ttbr0 */
-			*cmds++ = cp_type0_packet(ttbr0, 1);
-			*cmds++ = reg_pt_val;
+			if (sizeof(phys_addr_t) > sizeof(unsigned long)) {
+				reg_pt_val = ttbr0_val & 0xFFFFFFFF;
+				*cmds++ = cp_type0_packet(ttbr0, 1);
+				*cmds++ = reg_pt_val;
+				reg_pt_val = (unsigned int)
+				((ttbr0_val & 0xFFFFFFFF00000000ULL) >> 32);
+				*cmds++ = cp_type0_packet(ttbr0 + 1, 1);
+				*cmds++ = reg_pt_val;
+			} else {
+				reg_pt_val = ttbr0_val;
+				*cmds++ = cp_type0_packet(ttbr0, 1);
+				*cmds++ = reg_pt_val;
+			}
 			if (kgsl_mmu_hw_halt_supported(&device->mmu, i)) {
 				/* unlock the IOMMU lock */
 				*cmds++ = cp_type3_packet(CP_REG_RMW, 3);
@@ -796,7 +815,7 @@
 					unsigned int context_id,
 					uint32_t flags)
 {
-	unsigned int pt_val;
+	phys_addr_t pt_val;
 	unsigned int link[230];
 	unsigned int *cmds = &link[0];
 	int sizedwords = 0;
@@ -808,7 +827,8 @@
 
 	if (!adreno_dev->drawctxt_active ||
 		KGSL_STATE_ACTIVE != device->state ||
-		!device->active_cnt) {
+		!device->active_cnt ||
+		device->cff_dump_enable) {
 		kgsl_mmu_device_setstate(&device->mmu, flags);
 		return;
 	}
@@ -891,7 +911,7 @@
 	 * writes For CFF dump we must idle and use the registers so that it is
 	 * easier to filter out the mmu accesses from the dump
 	 */
-	if (!kgsl_cff_dump_enable && adreno_dev->drawctxt_active) {
+	if (!device->cff_dump_enable && adreno_dev->drawctxt_active) {
 		context = idr_find(&device->context_idr, context_id);
 		if (context == NULL)
 			return;
@@ -1814,7 +1834,7 @@
 	/* Power down the device */
 	kgsl_pwrctrl_disable(device);
 
-	kgsl_cffdump_close(device->id);
+	kgsl_cffdump_close(device);
 
 	return 0;
 }
@@ -1861,11 +1881,11 @@
 	while ((context = idr_get_next(&device->context_idr, &next))) {
 		temp_adreno_context = context->devctxt;
 		if (temp_adreno_context->flags & CTXT_FLAGS_GPU_HANG) {
-			kgsl_sharedmem_writel(&device->memstore,
+			kgsl_sharedmem_writel(device, &device->memstore,
 				KGSL_MEMSTORE_OFFSET(context->id,
 				soptimestamp),
 				rb->timestamp[context->id]);
-			kgsl_sharedmem_writel(&device->memstore,
+			kgsl_sharedmem_writel(device, &device->memstore,
 				KGSL_MEMSTORE_OFFSET(context->id,
 				eoptimestamp),
 				rb->timestamp[context->id]);
@@ -2542,7 +2562,7 @@
 	else
 		device->mmu.hwpagetable = device->mmu.defaultpagetable;
 	rb->timestamp[KGSL_MEMSTORE_GLOBAL] = timestamp;
-	kgsl_sharedmem_writel(&device->memstore,
+	kgsl_sharedmem_writel(device, &device->memstore,
 			KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
 			eoptimestamp),
 			rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
@@ -2581,7 +2601,7 @@
 		INIT_COMPLETION(device->ft_gate);
 		/* Detected a hang */
 
-		kgsl_cffdump_hang(device->id);
+		kgsl_cffdump_hang(device);
 		/* Run fault tolerance at max power level */
 		curr_pwrlevel = pwr->active_pwrlevel;
 		kgsl_pwrctrl_pwrlevel_change(device, pwr->max_pwrlevel);
@@ -2823,7 +2843,7 @@
 
 	memset(prev_reg_val, 0, sizeof(prev_reg_val));
 
-	kgsl_cffdump_regpoll(device->id,
+	kgsl_cffdump_regpoll(device,
 		adreno_dev->gpudev->reg_rbbm_status << 2,
 		0x00000000, 0x80000000);
 
@@ -2945,7 +2965,7 @@
 /* Find a memory structure attached to an adreno context */
 
 struct kgsl_memdesc *adreno_find_ctxtmem(struct kgsl_device *device,
-	unsigned int pt_base, unsigned int gpuaddr, unsigned int size)
+	phys_addr_t pt_base, unsigned int gpuaddr, unsigned int size)
 {
 	struct kgsl_context *context;
 	struct adreno_context *adreno_context = NULL;
@@ -2977,7 +2997,7 @@
 }
 
 struct kgsl_memdesc *adreno_find_region(struct kgsl_device *device,
-						unsigned int pt_base,
+						phys_addr_t pt_base,
 						unsigned int gpuaddr,
 						unsigned int size)
 {
@@ -3006,7 +3026,7 @@
 	return adreno_find_ctxtmem(device, pt_base, gpuaddr, size);
 }
 
-uint8_t *adreno_convertaddr(struct kgsl_device *device, unsigned int pt_base,
+uint8_t *adreno_convertaddr(struct kgsl_device *device, phys_addr_t pt_base,
 			    unsigned int gpuaddr, unsigned int size)
 {
 	struct kgsl_memdesc *memdesc;
@@ -3080,7 +3100,7 @@
 
 	kgsl_trace_regwrite(device, offsetwords, value);
 
-	kgsl_cffdump_regwrite(device->id, offsetwords << 2, value);
+	kgsl_cffdump_regwrite(device, offsetwords << 2, value);
 	reg = (unsigned int *)(device->reg_virt + (offsetwords << 2));
 
 	/*ensure previous writes post before this one,
@@ -3140,18 +3160,18 @@
 		/* Make sure the memstore read has posted */
 		mb();
 		if (timestamp_cmp(ref_ts, timestamp) >= 0) {
-			kgsl_sharedmem_writel(&device->memstore,
+			kgsl_sharedmem_writel(device, &device->memstore,
 					KGSL_MEMSTORE_OFFSET(context_id,
 						ref_wait_ts), timestamp);
 			/* Make sure the memstore write is posted */
 			wmb();
 		}
 	} else {
-		kgsl_sharedmem_writel(&device->memstore,
+		kgsl_sharedmem_writel(device, &device->memstore,
 				KGSL_MEMSTORE_OFFSET(context_id,
 					ref_wait_ts), timestamp);
 		enableflag = 1;
-		kgsl_sharedmem_writel(&device->memstore,
+		kgsl_sharedmem_writel(device, &device->memstore,
 				KGSL_MEMSTORE_OFFSET(context_id,
 					ts_cmp_enable), enableflag);
 
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 77b654b..816940f 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -302,15 +302,15 @@
 							*adreno_dev);
 
 struct kgsl_memdesc *adreno_find_region(struct kgsl_device *device,
-						unsigned int pt_base,
+						phys_addr_t pt_base,
 						unsigned int gpuaddr,
 						unsigned int size);
 
 uint8_t *adreno_convertaddr(struct kgsl_device *device,
-	unsigned int pt_base, unsigned int gpuaddr, unsigned int size);
+	phys_addr_t pt_base, unsigned int gpuaddr, unsigned int size);
 
 struct kgsl_memdesc *adreno_find_ctxtmem(struct kgsl_device *device,
-	unsigned int pt_base, unsigned int gpuaddr, unsigned int size);
+	phys_addr_t pt_base, unsigned int gpuaddr, unsigned int size);
 
 void *adreno_snapshot(struct kgsl_device *device, void *snapshot, int *remain,
 		int hang);
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index dd9bdc3..b0a1fe8 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1364,8 +1364,9 @@
 	drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW;
 
 	/* blank out gmem shadow. */
-	kgsl_sharedmem_set(&drawctxt->context_gmem_shadow.gmemshadow, 0, 0,
-			   drawctxt->context_gmem_shadow.size);
+	kgsl_sharedmem_set(drawctxt->dev_priv->device,
+			&drawctxt->context_gmem_shadow.gmemshadow, 0, 0,
+			drawctxt->context_gmem_shadow.size);
 
 	/* build quad vertex buffer */
 	build_quad_vtxbuff(drawctxt, &drawctxt->context_gmem_shadow,
@@ -1388,7 +1389,7 @@
 	kgsl_cache_range_op(&drawctxt->context_gmem_shadow.gmemshadow,
 			    KGSL_CACHE_OP_FLUSH);
 
-	kgsl_cffdump_syncmem(NULL,
+	kgsl_cffdump_syncmem(drawctxt->dev_priv,
 			&drawctxt->context_gmem_shadow.gmemshadow,
 			drawctxt->context_gmem_shadow.gmemshadow.gpuaddr,
 			drawctxt->context_gmem_shadow.gmemshadow.size, false);
@@ -1414,8 +1415,8 @@
 	if (ret)
 		return ret;
 
-	kgsl_sharedmem_set(&drawctxt->gpustate, 0, 0,
-		_context_size(adreno_dev));
+	kgsl_sharedmem_set(drawctxt->dev_priv->device, &drawctxt->gpustate, 0,
+		0, _context_size(adreno_dev));
 
 	tmp_ctx.cmd = tmp_ctx.start
 	    = (unsigned int *)((char *)drawctxt->gpustate.hostptr + CMD_OFFSET);
@@ -1439,7 +1440,7 @@
 	kgsl_cache_range_op(&drawctxt->gpustate,
 			    KGSL_CACHE_OP_FLUSH);
 
-	kgsl_cffdump_syncmem(NULL, &drawctxt->gpustate,
+	kgsl_cffdump_syncmem(drawctxt->dev_priv, &drawctxt->gpustate,
 			drawctxt->gpustate.gpuaddr,
 			drawctxt->gpustate.size, false);
 
@@ -1515,7 +1516,7 @@
 			"Current active context has caused gpu hang\n");
 
 	if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
-		kgsl_cffdump_syncmem(NULL, &context->gpustate,
+		kgsl_cffdump_syncmem(context->dev_priv, &context->gpustate,
 			context->reg_save[1],
 			context->reg_save[2] << 2, true);
 		/* save registers and constants. */
@@ -1524,7 +1525,8 @@
 			context->reg_save, 3);
 
 		if (context->flags & CTXT_FLAGS_SHADER_SAVE) {
-			kgsl_cffdump_syncmem(NULL, &context->gpustate,
+			kgsl_cffdump_syncmem(context->dev_priv,
+				&context->gpustate,
 				context->shader_save[1],
 				context->shader_save[2] << 2, true);
 			/* save shader partitioning and instructions. */
@@ -1532,7 +1534,8 @@
 				KGSL_CMD_FLAGS_PMODE,
 				context->shader_save, 3);
 
-			kgsl_cffdump_syncmem(NULL, &context->gpustate,
+			kgsl_cffdump_syncmem(context->dev_priv,
+				&context->gpustate,
 				context->shader_fixup[1],
 				context->shader_fixup[2] << 2, true);
 			/*
@@ -1549,7 +1552,7 @@
 
 	if ((context->flags & CTXT_FLAGS_GMEM_SAVE) &&
 	    (context->flags & CTXT_FLAGS_GMEM_SHADOW)) {
-		kgsl_cffdump_syncmem(NULL, &context->gpustate,
+		kgsl_cffdump_syncmem(context->dev_priv, &context->gpustate,
 			context->context_gmem_shadow.gmem_save[1],
 			context->context_gmem_shadow.gmem_save[2] << 2, true);
 		/* save gmem.
@@ -1559,7 +1562,7 @@
 			KGSL_CMD_FLAGS_PMODE,
 			context->context_gmem_shadow.gmem_save, 3);
 
-		kgsl_cffdump_syncmem(NULL, &context->gpustate,
+		kgsl_cffdump_syncmem(context->dev_priv, &context->gpustate,
 			context->chicken_restore[1],
 			context->chicken_restore[2] << 2, true);
 
@@ -1603,7 +1606,7 @@
 	 *  (note: changes shader. shader must not already be restored.)
 	 */
 	if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
-		kgsl_cffdump_syncmem(NULL, &context->gpustate,
+		kgsl_cffdump_syncmem(context->dev_priv, &context->gpustate,
 			context->context_gmem_shadow.gmem_restore[1],
 			context->context_gmem_shadow.gmem_restore[2] << 2,
 			true);
@@ -1613,7 +1616,8 @@
 			context->context_gmem_shadow.gmem_restore, 3);
 
 		if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
-			kgsl_cffdump_syncmem(NULL, &context->gpustate,
+			kgsl_cffdump_syncmem(context->dev_priv,
+				&context->gpustate,
 				context->chicken_restore[1],
 				context->chicken_restore[2] << 2, true);
 
@@ -1627,7 +1631,7 @@
 	}
 
 	if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
-		kgsl_cffdump_syncmem(NULL, &context->gpustate,
+		kgsl_cffdump_syncmem(context->dev_priv, &context->gpustate,
 			context->reg_restore[1],
 			context->reg_restore[2] << 2, true);
 
@@ -1637,7 +1641,8 @@
 
 		/* restore shader instructions & partitioning. */
 		if (context->flags & CTXT_FLAGS_SHADER_RESTORE) {
-			kgsl_cffdump_syncmem(NULL, &context->gpustate,
+			kgsl_cffdump_syncmem(context->dev_priv,
+				&context->gpustate,
 				context->shader_restore[1],
 				context->shader_restore[2] << 2, true);
 
@@ -1862,54 +1867,56 @@
 
 	cmds_gpu = rb->buffer_desc.gpuaddr + sizeof(uint)*(rb->wptr-19);
 
-	GSL_RB_WRITE(cmds, cmds_gpu, cp_type3_packet(CP_ME_INIT, 18));
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, cp_type3_packet(CP_ME_INIT,
+			18));
 	/* All fields present (bits 9:0) */
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x000003ff);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x000003ff);
 	/* Disable/Enable Real-Time Stream processing (present but ignored) */
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
 	/* Enable (2D <-> 3D) implicit synchronization (present but ignored) */
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
 
-	GSL_RB_WRITE(cmds, cmds_gpu,
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
 		SUBBLOCK_OFFSET(REG_RB_SURFACE_INFO));
-	GSL_RB_WRITE(cmds, cmds_gpu,
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
 		SUBBLOCK_OFFSET(REG_PA_SC_WINDOW_OFFSET));
-	GSL_RB_WRITE(cmds, cmds_gpu,
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
 		SUBBLOCK_OFFSET(REG_VGT_MAX_VTX_INDX));
-	GSL_RB_WRITE(cmds, cmds_gpu,
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
 		SUBBLOCK_OFFSET(REG_SQ_PROGRAM_CNTL));
-	GSL_RB_WRITE(cmds, cmds_gpu,
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
 		SUBBLOCK_OFFSET(REG_RB_DEPTHCONTROL));
-	GSL_RB_WRITE(cmds, cmds_gpu,
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
 		SUBBLOCK_OFFSET(REG_PA_SU_POINT_SIZE));
-	GSL_RB_WRITE(cmds, cmds_gpu,
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
 		SUBBLOCK_OFFSET(REG_PA_SC_LINE_CNTL));
-	GSL_RB_WRITE(cmds, cmds_gpu,
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
 		SUBBLOCK_OFFSET(REG_PA_SU_POLY_OFFSET_FRONT_SCALE));
 
 	/* Instruction memory size: */
-	GSL_RB_WRITE(cmds, cmds_gpu,
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
 		(adreno_encode_istore_size(adreno_dev)
 		| adreno_dev->pix_shader_start));
 	/* Maximum Contexts */
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000001);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000001);
 	/* Write Confirm Interval and The CP will wait the
 	* wait_interval * 16 clocks between polling  */
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
 
 	/* NQ and External Memory Swap */
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
 	/* Protected mode error checking
 	 * If iommu is used then protection needs to be turned off
 	 * to enable context bank switching */
 	if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype())
-		GSL_RB_WRITE(cmds, cmds_gpu, 0);
+		GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0);
 	else
-		GSL_RB_WRITE(cmds, cmds_gpu, GSL_RB_PROTECTED_MODE_CONTROL);
+		GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
+				GSL_RB_PROTECTED_MODE_CONTROL);
 	/* Disable header dumping and Header dump address */
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
 	/* Header dump size */
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
 
 	adreno_ringbuffer_submit(rb);
 
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 1cdc87a..884b72b 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2360,7 +2360,8 @@
 	if (ret)
 		return ret;
 
-	kgsl_sharedmem_set(&drawctxt->gpustate, 0, 0, CONTEXT_SIZE);
+	kgsl_sharedmem_set(&adreno_dev->dev, &drawctxt->gpustate, 0, 0,
+			CONTEXT_SIZE);
 	tmp_ctx.cmd = drawctxt->gpustate.hostptr + CMD_OFFSET;
 
 	if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) {
@@ -2419,7 +2420,7 @@
 		 * already be saved.)
 		 */
 
-		kgsl_cffdump_syncmem(NULL,
+		kgsl_cffdump_syncmem(context->dev_priv,
 			&context->gpustate,
 			context->context_gmem_shadow.gmem_save[1],
 			context->context_gmem_shadow.gmem_save[2] << 2, true);
@@ -2461,7 +2462,7 @@
 	 */
 
 	if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
-		kgsl_cffdump_syncmem(NULL,
+		kgsl_cffdump_syncmem(context->dev_priv,
 			&context->gpustate,
 			context->context_gmem_shadow.gmem_restore[1],
 			context->context_gmem_shadow.gmem_restore[2] << 2,
@@ -2509,25 +2510,26 @@
 
 	cmds_gpu = rb->buffer_desc.gpuaddr + sizeof(uint) * (rb->wptr - 18);
 
-	GSL_RB_WRITE(cmds, cmds_gpu, cp_type3_packet(CP_ME_INIT, 17));
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x000003f7);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000080);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000100);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000180);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00006600);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000150);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x0000014e);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000154);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000001);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
+			cp_type3_packet(CP_ME_INIT, 17));
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x000003f7);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000080);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000100);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000180);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00006600);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000150);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x0000014e);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000154);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000001);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
 	/* Protected mode control - turned off for A3XX */
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
-	GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
+	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0x00000000);
 
 	adreno_ringbuffer_submit(rb);
 
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index 980ff13..12b9e7c 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -19,27 +19,12 @@
 
 #include "kgsl.h"
 #include "adreno.h"
+#include "kgsl_cffdump.h"
 
 #include "a2xx_reg.h"
 
 unsigned int kgsl_cff_dump_enable;
 
-static int kgsl_cff_dump_enable_set(void *data, u64 val)
-{
-#ifdef CONFIG_MSM_KGSL_CFF_DUMP
-	kgsl_cff_dump_enable = (val != 0);
-	return 0;
-#else
-	return -EINVAL;
-#endif
-}
-
-static int kgsl_cff_dump_enable_get(void *data, u64 *val)
-{
-	*val = kgsl_cff_dump_enable;
-	return 0;
-}
-
 DEFINE_SIMPLE_ATTRIBUTE(kgsl_cff_dump_enable_fops, kgsl_cff_dump_enable_get,
 			kgsl_cff_dump_enable_set, "%llu\n");
 
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index 176717d..b32cdae 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -192,19 +192,20 @@
 
 	drawctxt->type =
 		(*flags & KGSL_CONTEXT_TYPE_MASK) >> KGSL_CONTEXT_TYPE_SHIFT;
+	drawctxt->dev_priv = context->dev_priv;
 
 	ret = adreno_dev->gpudev->ctxt_create(adreno_dev, drawctxt);
 	if (ret)
 		goto err;
 
-	kgsl_sharedmem_writel(&device->memstore,
+	kgsl_sharedmem_writel(device, &device->memstore,
 			KGSL_MEMSTORE_OFFSET(drawctxt->id, ref_wait_ts),
 			KGSL_INIT_REFTIMESTAMP);
-	kgsl_sharedmem_writel(&device->memstore,
+	kgsl_sharedmem_writel(device, &device->memstore,
 			KGSL_MEMSTORE_OFFSET(drawctxt->id, ts_cmp_enable), 0);
-	kgsl_sharedmem_writel(&device->memstore,
+	kgsl_sharedmem_writel(device, &device->memstore,
 			KGSL_MEMSTORE_OFFSET(drawctxt->id, soptimestamp), 0);
-	kgsl_sharedmem_writel(&device->memstore,
+	kgsl_sharedmem_writel(device, &device->memstore,
 			KGSL_MEMSTORE_OFFSET(drawctxt->id, eoptimestamp), 0);
 
 	context->devctxt = drawctxt;
diff --git a/drivers/gpu/msm/adreno_drawctxt.h b/drivers/gpu/msm/adreno_drawctxt.h
index f0f3b6b..2b8e600 100644
--- a/drivers/gpu/msm/adreno_drawctxt.h
+++ b/drivers/gpu/msm/adreno_drawctxt.h
@@ -131,6 +131,7 @@
 	struct kgsl_memdesc constant_load_commands[3];
 	struct kgsl_memdesc cond_execs[4];
 	struct kgsl_memdesc hlsqcontrol_restore_commands[1];
+	struct kgsl_device_private *dev_priv;
 };
 
 int adreno_drawctxt_create(struct kgsl_device *device,
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 2249907..c7b6b5b 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -190,8 +190,9 @@
 	}
 }
 
-static void dump_ib(struct kgsl_device *device, char* buffId, uint32_t pt_base,
-	uint32_t base_offset, uint32_t ib_base, uint32_t ib_size, bool dump)
+static void dump_ib(struct kgsl_device *device, char *buffId,
+	phys_addr_t pt_base, uint32_t base_offset, uint32_t ib_base,
+	uint32_t ib_size, bool dump)
 {
 	uint8_t *base_addr = adreno_convertaddr(device, pt_base,
 		ib_base, ib_size*sizeof(uint32_t));
@@ -214,7 +215,7 @@
 	uint32_t offsets[IB_LIST_SIZE];
 };
 
-static void dump_ib1(struct kgsl_device *device, uint32_t pt_base,
+static void dump_ib1(struct kgsl_device *device, phys_addr_t pt_base,
 			uint32_t base_offset,
 			uint32_t ib1_base, uint32_t ib1_size,
 			struct ib_list *ib_list, bool dump)
@@ -719,7 +720,7 @@
 {
 	unsigned int cp_ib1_base, cp_ib1_bufsz;
 	unsigned int cp_ib2_base, cp_ib2_bufsz;
-	unsigned int pt_base, cur_pt_base;
+	phys_addr_t pt_base, cur_pt_base;
 	unsigned int cp_rb_base, cp_rb_ctrl, rb_count;
 	unsigned int cp_rb_wptr, cp_rb_rptr;
 	unsigned int i;
@@ -862,20 +863,20 @@
 						&device->mmu, 0,
 						KGSL_IOMMU_CONTEXT_USER,
 						KGSL_IOMMU_CTX_TTBR0), 1))) {
-			KGSL_LOG_DUMP(device, "Current pagetable: %x\t"
-				"pagetable base: %x\n",
+			KGSL_LOG_DUMP(device,
+				"Current pagetable: %x\t pagetable base: %pa\n",
 				kgsl_mmu_get_ptname_from_ptbase(&device->mmu,
 								cur_pt_base),
-				cur_pt_base);
+				&cur_pt_base);
 
 			/* Set cur_pt_base to the new pagetable base */
 			cur_pt_base = rb_copy[read_idx++];
 
-			KGSL_LOG_DUMP(device, "New pagetable: %x\t"
-				"pagetable base: %x\n",
+			KGSL_LOG_DUMP(device,
+				"New pagetable: %x\t pagetable base: %pa\n",
 				kgsl_mmu_get_ptname_from_ptbase(&device->mmu,
 								cur_pt_base),
-				cur_pt_base);
+				&cur_pt_base);
 		}
 	}
 
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 61ea916..4e95e93 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -76,7 +76,8 @@
 		cmds = (unsigned int *)rb->buffer_desc.hostptr + rb->wptr;
 		cmds_gpu = rb->buffer_desc.gpuaddr + sizeof(uint)*rb->wptr;
 
-		GSL_RB_WRITE(cmds, cmds_gpu, cp_nop_packet(nopcount));
+		GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
+				cp_nop_packet(nopcount));
 
 		/* Make sure that rptr is not 0 before submitting
 		 * commands at the end of ringbuffer. We do not
@@ -331,10 +332,10 @@
 	if (rb->flags & KGSL_FLAGS_STARTED)
 		return 0;
 
-	kgsl_sharedmem_set(&rb->memptrs_desc, 0, 0,
+	kgsl_sharedmem_set(rb->device, &rb->memptrs_desc, 0, 0,
 			   sizeof(struct kgsl_rbmemptrs));
 
-	kgsl_sharedmem_set(&rb->buffer_desc, 0, 0xAA,
+	kgsl_sharedmem_set(rb->device, &rb->buffer_desc, 0, 0xAA,
 			   (rb->sizedwords << 2));
 
 	if (adreno_is_a2xx(adreno_dev)) {
@@ -612,12 +613,13 @@
 	rcmd_gpu = rb->buffer_desc.gpuaddr
 		+ sizeof(uint)*(rb->wptr-total_sizedwords);
 
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_nop_packet(1));
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, KGSL_CMD_IDENTIFIER);
+	GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, cp_nop_packet(1));
+	GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, KGSL_CMD_IDENTIFIER);
 
 	if (flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE) {
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_nop_packet(1));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, KGSL_CMD_INTERNAL_IDENTIFIER);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, cp_nop_packet(1));
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
+				KGSL_CMD_INTERNAL_IDENTIFIER);
 	}
 
 	/* always increment the global timestamp. once. */
@@ -636,32 +638,35 @@
 	timestamp = rb->timestamp[context_id];
 
 	/* scratchpad ts for fault tolerance */
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type0_packet(REG_CP_TIMESTAMP, 1));
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
+	GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
+			cp_type0_packet(REG_CP_TIMESTAMP, 1));
+	GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
+			rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
 
 	/* start-of-pipeline timestamp */
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type3_packet(CP_MEM_WRITE, 2));
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
+	GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
+			cp_type3_packet(CP_MEM_WRITE, 2));
+	GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, (gpuaddr +
 		KGSL_MEMSTORE_OFFSET(context_id, soptimestamp)));
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
+	GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, timestamp);
 
 	if (flags & KGSL_CMD_FLAGS_PMODE) {
 		/* disable protected mode error checking */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_SET_PROTECTED_MODE, 1));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, 0);
 	}
 
 	for (i = 0; i < sizedwords; i++) {
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, *cmds);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, *cmds);
 		cmds++;
 	}
 
 	if (flags & KGSL_CMD_FLAGS_PMODE) {
 		/* re-enable protected mode error checking */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_SET_PROTECTED_MODE, 1));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, 1);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, 1);
 	}
 
 	/* HW Workaround for MMU Page fault
@@ -669,9 +674,9 @@
 	* GPU completes it.
 	*/
 	if (adreno_is_a2xx(adreno_dev)) {
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_WAIT_FOR_IDLE, 1));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x00);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, 0x00);
 	}
 
 	if (adreno_is_a3xx(adreno_dev)) {
@@ -680,12 +685,13 @@
 		 * resources pending for indirect loads after the timestamp
 		 */
 
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_EVENT_WRITE, 1));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x07); /* HLSQ_FLUSH */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds,
+			rcmd_gpu, 0x07); /* HLSQ_FLUSH */
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_WAIT_FOR_IDLE, 1));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x00);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, 0x00);
 	}
 
 	/*
@@ -693,62 +699,64 @@
 	 * enabled, then context_id will be KGSL_MEMSTORE_GLOBAL so all
 	 * eop timestamps will work out.
 	 */
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type3_packet(CP_EVENT_WRITE, 3));
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, CACHE_FLUSH_TS);
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
+	GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
+			cp_type3_packet(CP_EVENT_WRITE, 3));
+	GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, CACHE_FLUSH_TS);
+	GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, (gpuaddr +
 		KGSL_MEMSTORE_OFFSET(context_id, eoptimestamp)));
-	GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
+	GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, timestamp);
 
 	if (KGSL_MEMSTORE_GLOBAL != context_id) {
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_MEM_WRITE, 2));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, (gpuaddr +
 			KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
 				eoptimestamp)));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
 	}
 
 	if (adreno_is_a20x(adreno_dev)) {
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_EVENT_WRITE, 1));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, CACHE_FLUSH);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, CACHE_FLUSH);
 	}
 
 	if (context) {
 		/* Conditional execution based on memory values */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_COND_EXEC, 4));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, (gpuaddr +
 			KGSL_MEMSTORE_OFFSET(
 				context_id, ts_cmp_enable)) >> 2);
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, (gpuaddr +
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, (gpuaddr +
 			KGSL_MEMSTORE_OFFSET(
 				context_id, ref_wait_ts)) >> 2);
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, timestamp);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, timestamp);
 		/* # of conditional command DWORDs */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, 8);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, 8);
 
 		/* Clear the ts_cmp_enable for the context */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_MEM_WRITE, 2));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, gpuaddr +
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, gpuaddr +
 			KGSL_MEMSTORE_OFFSET(
 				context_id, ts_cmp_enable));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x0);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, 0x0);
 
 		/* Clear the ts_cmp_enable for the global timestamp */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_MEM_WRITE, 2));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, gpuaddr +
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, gpuaddr +
 			KGSL_MEMSTORE_OFFSET(
 				KGSL_MEMSTORE_GLOBAL, ts_cmp_enable));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x0);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, 0x0);
 
 		/* Trigger the interrupt */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_INTERRUPT, 1));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, CP_INT_CNTL__RB_INT_MASK);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
+				CP_INT_CNTL__RB_INT_MASK);
 	}
 
 	/*
@@ -758,24 +766,25 @@
 	if ((context) && (context->flags & CTXT_FLAGS_PER_CONTEXT_TS) &&
 		(flags & (KGSL_CMD_FLAGS_INTERNAL_ISSUE |
 		KGSL_CMD_FLAGS_GET_INT))) {
-			GSL_RB_WRITE(ringcmds, rcmd_gpu,
+			GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 				cp_type3_packet(CP_INTERRUPT, 1));
-			GSL_RB_WRITE(ringcmds, rcmd_gpu,
+			GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 				CP_INT_CNTL__RB_INT_MASK);
 	}
 
 	if (adreno_is_a3xx(adreno_dev)) {
 		/* Dummy set-constant to trigger context rollover */
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			cp_type3_packet(CP_SET_CONSTANT, 2));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
 			(0x4<<16)|(A3XX_HLSQ_CL_KERNEL_GROUP_X_REG - 0x2000));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, 0);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, 0);
 	}
 
 	if (flags & KGSL_CMD_FLAGS_EOF) {
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_nop_packet(1));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, KGSL_END_OF_FRAME_IDENTIFIER);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, cp_nop_packet(1));
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu,
+				KGSL_END_OF_FRAME_IDENTIFIER);
 	}
 
 	adreno_ringbuffer_submit(rb);
@@ -1150,7 +1159,8 @@
 			if (val[i] == cp_nop_packet(4)) {
 				temp_rb_rptr = adreno_ringbuffer_dec_wrapped(
 						temp_rb_rptr, size);
-				kgsl_sharedmem_writel(&rb->buffer_desc,
+				kgsl_sharedmem_writel(rb->device,
+					&rb->buffer_desc,
 					temp_rb_rptr, cp_nop_packet(1));
 			}
 			KGSL_FT_INFO(rb->device,
@@ -1312,7 +1322,7 @@
 	ringcmds = (unsigned int *)rb->buffer_desc.hostptr + rb->wptr;
 	rcmd_gpu = rb->buffer_desc.gpuaddr + sizeof(unsigned int) * rb->wptr;
 	for (i = 0; i < num_rb_contents; i++)
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, rb_buff[i]);
+		GSL_RB_WRITE(rb->device, ringcmds, rcmd_gpu, rb_buff[i]);
 	rb->wptr += num_rb_contents;
 	adreno_ringbuffer_submit(rb);
 }
diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h
index e563ec7..115533e 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.h
+++ b/drivers/gpu/msm/adreno_ringbuffer.h
@@ -60,11 +60,11 @@
 };
 
 
-#define GSL_RB_WRITE(ring, gpuaddr, data) \
+#define GSL_RB_WRITE(device, ring, gpuaddr, data) \
 	do { \
 		*ring = data; \
 		wmb(); \
-		kgsl_cffdump_setmem(gpuaddr, data, 4); \
+		kgsl_cffdump_setmem(device, gpuaddr, data, 4); \
 		ring++; \
 		gpuaddr += sizeof(uint); \
 	} while (0)
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index 144c3d6..d6ce298 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -34,7 +34,7 @@
 static struct kgsl_snapshot_obj {
 	int type;
 	uint32_t gpuaddr;
-	uint32_t ptbase;
+	phys_addr_t ptbase;
 	void *ptr;
 	int dwords;
 } objbuf[SNAPSHOT_OBJ_BUFSIZE];
@@ -43,7 +43,8 @@
 static int objbufptr;
 
 /* Push a new buffer object onto the list */
-static void push_object(struct kgsl_device *device, int type, uint32_t ptbase,
+static void push_object(struct kgsl_device *device, int type,
+	phys_addr_t ptbase,
 	uint32_t gpuaddr, int dwords)
 {
 	int index;
@@ -94,7 +95,7 @@
  * to be dumped
  */
 
-static int find_object(int type, unsigned int gpuaddr, unsigned int ptbase)
+static int find_object(int type, unsigned int gpuaddr, phys_addr_t ptbase)
 {
 	int index;
 
@@ -184,7 +185,7 @@
 };
 
 static int ib_parse_load_state(struct kgsl_device *device, unsigned int *pkt,
-	unsigned int ptbase)
+	phys_addr_t ptbase)
 {
 	unsigned int block, source, type;
 	int ret = 0;
@@ -243,7 +244,7 @@
  */
 
 static int ib_parse_set_bin_data(struct kgsl_device *device, unsigned int *pkt,
-	unsigned int ptbase)
+	phys_addr_t ptbase)
 {
 	int ret;
 
@@ -276,7 +277,7 @@
  */
 
 static int ib_parse_mem_write(struct kgsl_device *device, unsigned int *pkt,
-	unsigned int ptbase)
+	phys_addr_t ptbase)
 {
 	int ret;
 
@@ -307,7 +308,7 @@
  */
 
 static int ib_parse_draw_indx(struct kgsl_device *device, unsigned int *pkt,
-	unsigned int ptbase)
+	phys_addr_t ptbase)
 {
 	int ret = 0, i;
 
@@ -439,7 +440,7 @@
  */
 
 static int ib_parse_type3(struct kgsl_device *device, unsigned int *ptr,
-	unsigned int ptbase)
+	phys_addr_t ptbase)
 {
 	int opcode = cp_type3_opcode(*ptr);
 
@@ -464,7 +465,7 @@
  */
 
 static void ib_parse_type0(struct kgsl_device *device, unsigned int *ptr,
-	unsigned int ptbase)
+	phys_addr_t ptbase)
 {
 	int size = type0_pkt_size(*ptr);
 	int offset = type0_pkt_offset(*ptr);
@@ -542,12 +543,12 @@
 	}
 }
 
-static inline int parse_ib(struct kgsl_device *device, unsigned int ptbase,
+static inline int parse_ib(struct kgsl_device *device, phys_addr_t ptbase,
 		unsigned int gpuaddr, unsigned int dwords);
 
 /* Add an IB as a GPU object, but first, parse it to find more goodies within */
 
-static int ib_add_gpu_object(struct kgsl_device *device, unsigned int ptbase,
+static int ib_add_gpu_object(struct kgsl_device *device, phys_addr_t ptbase,
 		unsigned int gpuaddr, unsigned int dwords)
 {
 	int i, ret, rem = dwords;
@@ -625,7 +626,7 @@
  * access the dynamic data from the sysfs file.  Push all other IBs on the
  * dynamic list
  */
-static inline int parse_ib(struct kgsl_device *device, unsigned int ptbase,
+static inline int parse_ib(struct kgsl_device *device, phys_addr_t ptbase,
 		unsigned int gpuaddr, unsigned int dwords)
 {
 	unsigned int ib1base, ib2base;
@@ -657,7 +658,8 @@
 	unsigned int *data = snapshot + sizeof(*header);
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
-	unsigned int ptbase, rptr, *rbptr, ibbase;
+	unsigned int rptr, *rbptr, ibbase;
+	phys_addr_t ptbase;
 	int index, size, i;
 	int parse_ibs = 0, ib_parse_start;
 
@@ -824,7 +826,7 @@
 	struct kgsl_snapshot_replay_mem_list *header = snapshot;
 	struct kgsl_process_private *private = NULL;
 	struct kgsl_process_private *tmp_private;
-	unsigned int ptbase;
+	phys_addr_t ptbase;
 	struct rb_node *node;
 	struct kgsl_mem_entry *entry = NULL;
 	int num_mem;
@@ -861,7 +863,7 @@
 		return 0;
 	}
 	header->num_entries = num_mem;
-	header->ptbase = ptbase;
+	header->ptbase = (__u32)ptbase;
 	/*
 	 * Walk throught the memory list and store the
 	 * tuples(gpuaddr, size, memtype) in snapshot
@@ -897,7 +899,7 @@
 
 	/* Write the sub-header for the section */
 	header->gpuaddr = obj->gpuaddr;
-	header->ptbase = obj->ptbase;
+	header->ptbase = (__u32)obj->ptbase;
 	header->size = obj->dwords;
 
 	/* Write the contents of the ib */
@@ -957,8 +959,9 @@
 		int hang)
 {
 	int i;
-	uint32_t ptbase, ibbase, ibsize;
+	uint32_t ibbase, ibsize;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+	phys_addr_t ptbase;
 
 	/* Reset the list of objects */
 	objbufptr = 0;
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 9b67c61..94754be 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -154,8 +154,8 @@
  */
 
 struct kgsl_mem_entry * __must_check
-kgsl_get_mem_entry(struct kgsl_device *device, unsigned int ptbase,
-		   unsigned int gpuaddr, unsigned int size)
+kgsl_get_mem_entry(struct kgsl_device *device,
+	phys_addr_t ptbase, unsigned int gpuaddr, unsigned int size)
 {
 	struct kgsl_process_private *priv;
 	struct kgsl_mem_entry *entry;
@@ -814,6 +814,27 @@
 	return private;
 }
 
+int kgsl_close_device(struct kgsl_device *device)
+{
+	int result = 0;
+	device->open_count--;
+	if (device->open_count == 0) {
+		BUG_ON(device->active_cnt > 1);
+		result = device->ftbl->stop(device);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
+		/*
+		 * active_cnt special case: we just stopped the device,
+		 * so no need to use kgsl_active_count_put()
+		 */
+		device->active_cnt--;
+	} else {
+		kgsl_active_count_put(device);
+	}
+	return result;
+
+}
+EXPORT_SYMBOL(kgsl_close_device);
+
 static int kgsl_release(struct inode *inodep, struct file *filep)
 {
 	int result = 0;
@@ -833,8 +854,10 @@
 		if (context == NULL)
 			break;
 
-		if (context->dev_priv == dev_priv)
+		if (context->dev_priv == dev_priv) {
 			kgsl_context_detach(context);
+			context->dev_priv = NULL;
+		}
 
 		next = next + 1;
 	}
@@ -846,19 +869,7 @@
 	 */
 	kgsl_cancel_events(device, dev_priv);
 
-	device->open_count--;
-	if (device->open_count == 0) {
-		BUG_ON(device->active_cnt > 1);
-		result = device->ftbl->stop(device);
-		kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
-		/*
-		 * active_cnt special case: we just stopped the device,
-		 * so no need to use kgsl_active_count_put()
-		 */
-		device->active_cnt--;
-	} else {
-		kgsl_active_count_put(device);
-	}
+	result = kgsl_close_device(device);
 	mutex_unlock(&device->mutex);
 	kfree(dev_priv);
 
@@ -868,6 +879,43 @@
 	return result;
 }
 
+int kgsl_open_device(struct kgsl_device *device)
+{
+	int result = 0;
+	if (device->open_count == 0) {
+		/*
+		 * active_cnt special case: we are starting up for the first
+		 * time, so use this sequence instead of the kgsl_pwrctrl_wake()
+		 * which will be called by kgsl_active_count_get().
+		 */
+		device->active_cnt++;
+		kgsl_sharedmem_set(device, &device->memstore, 0, 0,
+				device->memstore.size);
+
+		result = device->ftbl->init(device);
+		if (result)
+			goto err;
+
+		result = device->ftbl->start(device);
+		if (result)
+			goto err;
+		/*
+		 * Make sure the gates are open, so they don't block until
+		 * we start suspend or FT.
+		 */
+		complete_all(&device->ft_gate);
+		complete_all(&device->hwaccess_gate);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
+		kgsl_active_count_put(device);
+	}
+	device->open_count++;
+err:
+	if (result)
+		device->active_cnt--;
+	return result;
+}
+EXPORT_SYMBOL(kgsl_open_device);
+
 static int kgsl_open(struct inode *inodep, struct file *filep)
 {
 	int result;
@@ -905,33 +953,9 @@
 
 	mutex_lock(&device->mutex);
 
-	if (device->open_count == 0) {
-		/*
-		 * active_cnt special case: we are starting up for the first
-		 * time, so use this sequence instead of the kgsl_pwrctrl_wake()
-		 * which will be called by kgsl_active_count_get().
-		 */
-		device->active_cnt++;
-		kgsl_sharedmem_set(&device->memstore, 0, 0,
-				device->memstore.size);
-
-		result = device->ftbl->init(device);
-		if (result)
-			goto err_freedevpriv;
-
-		result = device->ftbl->start(device);
-		if (result)
-			goto err_freedevpriv;
-		/*
-		 * Make sure the gates are open, so they don't block until
-		 * we start suspend or FT.
-		 */
-		complete_all(&device->ft_gate);
-		complete_all(&device->hwaccess_gate);
-		kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
-		kgsl_active_count_put(device);
-	}
-	device->open_count++;
+	result = kgsl_open_device(device);
+	if (result)
+		goto err_freedevpriv;
 	mutex_unlock(&device->mutex);
 
 	/*
@@ -959,11 +983,9 @@
 		kgsl_pwrctrl_enable(device);
 		result = device->ftbl->stop(device);
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
+		device->active_cnt--;
 	}
 err_freedevpriv:
-	/* only the first open takes an active count */
-	if (device->open_count == 0)
-		device->active_cnt--;
 	mutex_unlock(&device->mutex);
 	filep->private_data = NULL;
 	kfree(dev_priv);
@@ -2438,7 +2460,8 @@
 	int result = 0;
 	struct kgsl_cff_user_event *param = data;
 
-	kgsl_cffdump_user_event(param->cff_opcode, param->op1, param->op2,
+	kgsl_cffdump_user_event(dev_priv->device, param->cff_opcode,
+			param->op1, param->op2,
 			param->op3, param->op4, param->op5);
 
 	return result;
@@ -3309,7 +3332,7 @@
 
 	BUG_ON(device == NULL);
 
-	kgsl_cffdump_hang(device->id);
+	kgsl_cffdump_hang(device);
 
 	/* For a manual dump, make sure that the system is idle */
 
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index de3f619..4a1f291 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -207,7 +207,7 @@
 int kgsl_postmortem_dump(struct kgsl_device *device, int manual);
 
 struct kgsl_mem_entry *kgsl_get_mem_entry(struct kgsl_device *device,
-		unsigned int ptbase, unsigned int gpuaddr, unsigned int size);
+		phys_addr_t ptbase, unsigned int gpuaddr, unsigned int size);
 
 struct kgsl_mem_entry *kgsl_sharedmem_find_region(
 	struct kgsl_process_private *private, unsigned int gpuaddr,
@@ -238,6 +238,10 @@
 		unsigned int timestamp, unsigned int flags,
 		int result, unsigned int type);
 
+int kgsl_open_device(struct kgsl_device *device);
+
+int kgsl_close_device(struct kgsl_device *device);
+
 #ifdef CONFIG_MSM_KGSL_DRM
 extern int kgsl_drm_init(struct platform_device *dev);
 extern void kgsl_drm_exit(void);
diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c
index c3bdf80..99f4235 100644
--- a/drivers/gpu/msm/kgsl_cffdump.c
+++ b/drivers/gpu/msm/kgsl_cffdump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2012,2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -335,8 +335,6 @@
 		return;
 	}
 
-	kgsl_cff_dump_enable = 0;
-
 	spin_lock_init(&cffdump_lock);
 
 	dir = debugfs_create_dir("cff", debugfs_dir);
@@ -360,53 +358,54 @@
 void kgsl_cffdump_open(struct kgsl_device *device)
 {
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
-	if (!kgsl_cff_dump_enable)
+	if (!device->cff_dump_enable)
 		return;
 
 	if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype()) {
-		kgsl_cffdump_memory_base(device->id,
+		kgsl_cffdump_memory_base(device,
 			KGSL_PAGETABLE_BASE,
 			KGSL_IOMMU_GLOBAL_MEM_BASE +
 			KGSL_IOMMU_GLOBAL_MEM_SIZE -
 			KGSL_PAGETABLE_BASE,
 			adreno_dev->gmem_size);
 	} else {
-		kgsl_cffdump_memory_base(device->id,
+		kgsl_cffdump_memory_base(device,
 			kgsl_mmu_get_base_addr(&device->mmu),
 			kgsl_mmu_get_ptsize(&device->mmu),
 			adreno_dev->gmem_size);
 	}
 }
 
-void kgsl_cffdump_memory_base(enum kgsl_deviceid device_id, unsigned int base,
+void kgsl_cffdump_memory_base(struct kgsl_device *device, unsigned int base,
 			      unsigned int range, unsigned gmemsize)
 {
-	if (!kgsl_cff_dump_enable)
+	if (!device->cff_dump_enable)
 		return;
-	cffdump_printline(device_id, CFF_OP_MEMORY_BASE, base,
+	cffdump_printline(device->id, CFF_OP_MEMORY_BASE, base,
 			range, gmemsize, 0, 0);
 }
 
-void kgsl_cffdump_hang(enum kgsl_deviceid device_id)
+void kgsl_cffdump_hang(struct kgsl_device *device)
 {
-	if (!kgsl_cff_dump_enable)
+	if (!device->cff_dump_enable)
 		return;
-	cffdump_printline(device_id, CFF_OP_HANG, 0, 0, 0, 0, 0);
+	cffdump_printline(device->id, CFF_OP_HANG, 0, 0, 0, 0, 0);
 }
 
-void kgsl_cffdump_close(enum kgsl_deviceid device_id)
+void kgsl_cffdump_close(struct kgsl_device *device)
 {
-	if (!kgsl_cff_dump_enable)
+	if (!device->cff_dump_enable)
 		return;
-	cffdump_printline(device_id, CFF_OP_EOF, 0, 0, 0, 0, 0);
+	cffdump_printline(device->id, CFF_OP_EOF, 0, 0, 0, 0, 0);
 }
 
 
-void kgsl_cffdump_user_event(unsigned int cff_opcode, unsigned int op1,
+void kgsl_cffdump_user_event(struct kgsl_device *device,
+		unsigned int cff_opcode, unsigned int op1,
 		unsigned int op2, unsigned int op3,
 		unsigned int op4, unsigned int op5)
 {
-	if (!kgsl_cff_dump_enable)
+	if (!device->cff_dump_enable)
 		return;
 	cffdump_printline(-1, cff_opcode, op1, op2, op3, op4, op5);
 }
@@ -415,9 +414,10 @@
 	struct kgsl_memdesc *memdesc, uint gpuaddr, uint sizebytes,
 	bool clean_cache)
 {
+	struct kgsl_device *device = dev_priv->device;
 	const void *src;
 
-	if (!kgsl_cff_dump_enable)
+	if (!device->cff_dump_enable)
 		return;
 
 	total_syncmem += sizebytes;
@@ -437,9 +437,9 @@
 	}
 	src = (uint *)kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr);
 	if (memdesc->hostptr == NULL) {
-		KGSL_CORE_ERR("no kernel mapping for "
-			"gpuaddr: 0x%08x, m->host: 0x%p, phys: 0x%08x\n",
-			gpuaddr, memdesc->hostptr, memdesc->physaddr);
+		KGSL_CORE_ERR(
+		"no kernel map for gpuaddr: 0x%08x, m->host: 0x%p, phys: %pa\n",
+		gpuaddr, memdesc->hostptr, &memdesc->physaddr);
 		return;
 	}
 
@@ -465,9 +465,10 @@
 			0, 0, 0);
 }
 
-void kgsl_cffdump_setmem(uint addr, uint value, uint sizebytes)
+void kgsl_cffdump_setmem(struct kgsl_device *device,
+			uint addr, uint value, uint sizebytes)
 {
-	if (!kgsl_cff_dump_enable)
+	if (!device || !device->cff_dump_enable)
 		return;
 
 	while (sizebytes > 3) {
@@ -483,37 +484,37 @@
 				0, 0, 0);
 }
 
-void kgsl_cffdump_regwrite(enum kgsl_deviceid device_id, uint addr,
+void kgsl_cffdump_regwrite(struct kgsl_device *device, uint addr,
 	uint value)
 {
-	if (!kgsl_cff_dump_enable)
+	if (!device->cff_dump_enable)
 		return;
 
-	cffdump_printline(device_id, CFF_OP_WRITE_REG, addr, value,
+	cffdump_printline(device->id, CFF_OP_WRITE_REG, addr, value,
 			0, 0, 0);
 }
 
-void kgsl_cffdump_regpoll(enum kgsl_deviceid device_id, uint addr,
+void kgsl_cffdump_regpoll(struct kgsl_device *device, uint addr,
 	uint value, uint mask)
 {
-	if (!kgsl_cff_dump_enable)
+	if (!device->cff_dump_enable)
 		return;
 
-	cffdump_printline(device_id, CFF_OP_POLL_REG, addr, value,
+	cffdump_printline(device->id, CFF_OP_POLL_REG, addr, value,
 			mask, 0, 0);
 }
 
-void kgsl_cffdump_slavewrite(uint addr, uint value)
+void kgsl_cffdump_slavewrite(struct kgsl_device *device, uint addr, uint value)
 {
-	if (!kgsl_cff_dump_enable)
+	if (!device->cff_dump_enable)
 		return;
 
 	cffdump_printline(-1, CFF_OP_WRITE_REG, addr, value, 0, 0, 0);
 }
 
-int kgsl_cffdump_waitirq(void)
+int kgsl_cffdump_waitirq(struct kgsl_device *device)
 {
-	if (!kgsl_cff_dump_enable)
+	if (!device->cff_dump_enable)
 		return 0;
 
 	cffdump_printline(-1, CFF_OP_WAIT_IRQ, 0, 0, 0, 0, 0);
@@ -614,3 +615,59 @@
 	}
 }
 
+int kgsl_cff_dump_enable_set(void *data, u64 val)
+{
+	int ret = 0;
+	struct kgsl_device *device = (struct kgsl_device *)data;
+	int i;
+
+	mutex_lock(&kgsl_driver.devlock);
+	/*
+	 * If CFF dump enabled then set active count to prevent device
+	 * from restarting because simulator cannot run device restarts
+	 */
+	if (val) {
+		/* Check if CFF is on for some other device already */
+		for (i = 0; i < KGSL_DEVICE_MAX; i++) {
+			if (kgsl_driver.devp[i]) {
+				struct kgsl_device *device_temp =
+						kgsl_driver.devp[i];
+				if (device_temp->cff_dump_enable &&
+					device != device_temp) {
+					KGSL_CORE_ERR(
+					"CFF is on for another device %d\n",
+					device_temp->id);
+					ret = -EINVAL;
+					goto done;
+				}
+			}
+		}
+		if (!device->cff_dump_enable) {
+			mutex_lock(&device->mutex);
+			device->cff_dump_enable = 1;
+			ret = kgsl_open_device(device);
+			if (!ret)
+				ret = kgsl_active_count_get(device);
+			if (ret)
+				device->cff_dump_enable = 0;
+			mutex_unlock(&device->mutex);
+		}
+	} else if (device->cff_dump_enable && !val) {
+		mutex_lock(&device->mutex);
+		ret = kgsl_close_device(device);
+		device->cff_dump_enable = 0;
+		mutex_unlock(&device->mutex);
+	}
+done:
+	mutex_unlock(&kgsl_driver.devlock);
+	return ret;
+}
+EXPORT_SYMBOL(kgsl_cff_dump_enable_set);
+
+int kgsl_cff_dump_enable_get(void *data, u64 *val)
+{
+	struct kgsl_device *device = (struct kgsl_device *)data;
+	*val = device->cff_dump_enable;
+	return 0;
+}
+EXPORT_SYMBOL(kgsl_cff_dump_enable_get);
diff --git a/drivers/gpu/msm/kgsl_cffdump.h b/drivers/gpu/msm/kgsl_cffdump.h
index d5656f8..641348e 100644
--- a/drivers/gpu/msm/kgsl_cffdump.h
+++ b/drivers/gpu/msm/kgsl_cffdump.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2011,2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,8 @@
 #ifndef __KGSL_CFFDUMP_H
 #define __KGSL_CFFDUMP_H
 
+extern unsigned int kgsl_cff_dump_enable;
+
 #ifdef CONFIG_MSM_KGSL_CFF_DUMP
 
 #include <linux/types.h>
@@ -23,46 +25,64 @@
 void kgsl_cffdump_init(void);
 void kgsl_cffdump_destroy(void);
 void kgsl_cffdump_open(struct kgsl_device *device);
-void kgsl_cffdump_close(enum kgsl_deviceid device_id);
+void kgsl_cffdump_close(struct kgsl_device *device);
 void kgsl_cffdump_syncmem(struct kgsl_device_private *dev_priv,
 	struct kgsl_memdesc *memdesc, uint physaddr, uint sizebytes,
 	bool clean_cache);
-void kgsl_cffdump_setmem(uint addr, uint value, uint sizebytes);
-void kgsl_cffdump_regwrite(enum kgsl_deviceid device_id, uint addr,
+void kgsl_cffdump_setmem(struct kgsl_device *device, uint addr,
+			uint value, uint sizebytes);
+void kgsl_cffdump_regwrite(struct kgsl_device *device, uint addr,
 	uint value);
-void kgsl_cffdump_regpoll(enum kgsl_deviceid device_id, uint addr,
+void kgsl_cffdump_regpoll(struct kgsl_device *device, uint addr,
 	uint value, uint mask);
 bool kgsl_cffdump_parse_ibs(struct kgsl_device_private *dev_priv,
 	const struct kgsl_memdesc *memdesc, uint gpuaddr, int sizedwords,
 	bool check_only);
-void kgsl_cffdump_user_event(unsigned int cff_opcode, unsigned int op1,
+void kgsl_cffdump_user_event(struct kgsl_device *device,
+		unsigned int cff_opcode, unsigned int op1,
 		unsigned int op2, unsigned int op3,
 		unsigned int op4, unsigned int op5);
 static inline bool kgsl_cffdump_flags_no_memzero(void) { return true; }
 
-void kgsl_cffdump_memory_base(enum kgsl_deviceid device_id, unsigned int base,
+void kgsl_cffdump_memory_base(struct kgsl_device *device, unsigned int base,
 			      unsigned int range, unsigned int gmemsize);
 
-void kgsl_cffdump_hang(enum kgsl_deviceid device_id);
+void kgsl_cffdump_hang(struct kgsl_device *device);
+int kgsl_cff_dump_enable_set(void *data, u64 val);
+int kgsl_cff_dump_enable_get(void *data, u64 *val);
 
 #else
 
 #define kgsl_cffdump_init()					(void)0
 #define kgsl_cffdump_destroy()					(void)0
 #define kgsl_cffdump_open(device)				(void)0
-#define kgsl_cffdump_close(device_id)				(void)0
+#define kgsl_cffdump_close(device)				(void)0
 #define kgsl_cffdump_syncmem(dev_priv, memdesc, addr, sizebytes, clean_cache) \
 	(void) 0
-#define kgsl_cffdump_setmem(addr, value, sizebytes)		(void)0
-#define kgsl_cffdump_regwrite(device_id, addr, value)		(void)0
-#define kgsl_cffdump_regpoll(device_id, addr, value, mask)	(void)0
+#define kgsl_cffdump_setmem(device, addr, value, sizebytes)	(void)0
+#define kgsl_cffdump_regwrite(device, addr, value)		(void)0
+#define kgsl_cffdump_regpoll(device, addr, value, mask)	(void)0
 #define kgsl_cffdump_parse_ibs(dev_priv, memdesc, gpuaddr, \
 	sizedwords, check_only)					true
 #define kgsl_cffdump_flags_no_memzero()				true
-#define kgsl_cffdump_memory_base(base, range, gmemsize)		(void)0
-#define kgsl_cffdump_hang(device_id)				(void)0
-#define kgsl_cffdump_user_event(cff_opcode, op1, op2, op3, op4, op5) \
-	(void)param
+#define kgsl_cffdump_memory_base(davice, base, range, gmemsize)	(void)0
+#define kgsl_cffdump_hang(device)				(void)0
+static inline void kgsl_cffdump_user_event(struct kgsl_device *device,
+		unsigned int cff_opcode, unsigned int op1,
+		unsigned int op2, unsigned int op3,
+		unsigned int op4, unsigned int op5)
+{
+	return;
+}
+static inline int kgsl_cff_dump_enable_set(void *data, u64 val)
+{
+	return -EINVAL;
+}
+
+static inline int kgsl_cff_dump_enable_get(void *data, u64 *val)
+{
+	return -EINVAL;
+}
 
 #endif /* CONFIG_MSM_KGSL_CFF_DUMP */
 
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 3ee9e4e..6477cbd 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -226,6 +226,7 @@
 	int pm_ib_enabled;
 
 	int reset_counter; /* Track how many GPU core resets have occured */
+	int cff_dump_enable;
 };
 
 void kgsl_process_events(struct work_struct *work);
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index 6f139b9..68052b1 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -359,7 +359,7 @@
 
 int kgsl_gpummu_pt_equal(struct kgsl_mmu *mmu,
 			struct kgsl_pagetable *pt,
-			unsigned int pt_base)
+			phys_addr_t pt_base)
 {
 	struct kgsl_gpummu_pt *gpummu_pt = pt ? pt->priv : NULL;
 	return gpummu_pt && pt_base && (gpummu_pt->base.gpuaddr == pt_base);
@@ -458,15 +458,20 @@
 	if (gpummu_pt->base.hostptr == NULL)
 		goto err_flushfilter;
 
+	/* Do a check before truncating phys_addr_t to unsigned 32 */
+	if (sizeof(phys_addr_t) > sizeof(unsigned int)) {
+		WARN_ONCE(1, "Cannot use LPAE with gpummu\n");
+		goto err_flushfilter;
+	}
+	gpummu_pt->base.gpuaddr = gpummu_pt->base.physaddr;
+	gpummu_pt->base.size = KGSL_PAGETABLE_SIZE;
+
 	/* ptpool allocations are from coherent memory, so update the
 	   device statistics acordingly */
 
 	KGSL_STATS_ADD(KGSL_PAGETABLE_SIZE, kgsl_driver.stats.coherent,
 		       kgsl_driver.stats.coherent_max);
 
-	gpummu_pt->base.gpuaddr = gpummu_pt->base.physaddr;
-	gpummu_pt->base.size = KGSL_PAGETABLE_SIZE;
-
 	return (void *)gpummu_pt;
 
 err_flushfilter:
@@ -576,7 +581,7 @@
 	kgsl_regwrite(device, MH_INTERRUPT_MASK,
 			GSL_MMU_INT_MASK | MH_INTERRUPT_MASK__MMU_PAGE_FAULT);
 
-	kgsl_sharedmem_set(&mmu->setstate_memory, 0, 0,
+	kgsl_sharedmem_set(device, &mmu->setstate_memory, 0, 0,
 			   mmu->setstate_memory.size);
 
 	/* TRAN_ERROR needs a 32 byte (32 byte aligned) chunk of memory
@@ -723,7 +728,7 @@
 	return 0;
 }
 
-static unsigned int
+static phys_addr_t
 kgsl_gpummu_get_current_ptbase(struct kgsl_mmu *mmu)
 {
 	unsigned int ptbase;
@@ -731,7 +736,7 @@
 	return ptbase;
 }
 
-static unsigned int
+static phys_addr_t
 kgsl_gpummu_get_pt_base_addr(struct kgsl_mmu *mmu,
 			struct kgsl_pagetable *pt)
 {
@@ -757,7 +762,7 @@
 	.mmu_get_pt_base_addr = kgsl_gpummu_get_pt_base_addr,
 	.mmu_enable_clk = NULL,
 	.mmu_disable_clk_on_ts = NULL,
-	.mmu_get_pt_lsb = NULL,
+	.mmu_get_default_ttbr0 = NULL,
 	.mmu_get_reg_gpuaddr = NULL,
 	.mmu_get_reg_ahbaddr = NULL,
 	.mmu_get_num_iommu_units = kgsl_gpummu_get_num_iommu_units,
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 4fb2f87..b86e0e1 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -609,11 +609,12 @@
  */
 static int kgsl_iommu_pt_equal(struct kgsl_mmu *mmu,
 				struct kgsl_pagetable *pt,
-				unsigned int pt_base)
+				phys_addr_t pt_base)
 {
 	struct kgsl_iommu_pt *iommu_pt = pt ? pt->priv : NULL;
-	unsigned int domain_ptbase = iommu_pt ?
+	phys_addr_t domain_ptbase = iommu_pt ?
 				iommu_get_pt_base_addr(iommu_pt->domain) : 0;
+
 	/* Only compare the valid address bits of the pt_base */
 	domain_ptbase &= KGSL_IOMMU_CTX_TTBR0_ADDR_MASK;
 
@@ -1152,7 +1153,7 @@
  * Return - actual pagetable address that the ttbr0 register is programmed
  * with
  */
-static unsigned int kgsl_iommu_get_pt_base_addr(struct kgsl_mmu *mmu,
+static phys_addr_t kgsl_iommu_get_pt_base_addr(struct kgsl_mmu *mmu,
 						struct kgsl_pagetable *pt)
 {
 	struct kgsl_iommu_pt *iommu_pt = pt->priv;
@@ -1161,17 +1162,15 @@
 }
 
 /*
- * kgsl_iommu_get_pt_lsb - Return the lsb of the ttbr0 IOMMU register
+ * kgsl_iommu_get_default_ttbr0 - Return the ttbr0 value programmed by
+ * iommu driver
  * @mmu - Pointer to mmu structure
  * @hostptr - Pointer to the IOMMU register map. This is used to match
  * the iommu device whose lsb value is to be returned
  * @ctx_id - The context bank whose lsb valus is to be returned
- * Return - returns the lsb which is the last 14 bits of the ttbr0 IOMMU
- * register. ttbr0 is the actual PTBR for of the IOMMU. The last 14 bits
- * are only programmed once in the beginning when a domain is attached
- * does not change.
+ * Return - returns the ttbr0 value programmed by iommu driver
  */
-static int kgsl_iommu_get_pt_lsb(struct kgsl_mmu *mmu,
+static phys_addr_t kgsl_iommu_get_default_ttbr0(struct kgsl_mmu *mmu,
 				unsigned int unit_id,
 				enum kgsl_iommu_context_id ctx_id)
 {
@@ -1182,7 +1181,7 @@
 		for (j = 0; j < iommu_unit->dev_count; j++)
 			if (unit_id == i &&
 				ctx_id == iommu_unit->dev[j].ctx_id)
-				return iommu_unit->dev[j].pt_lsb;
+				return iommu_unit->dev[j].default_ttbr0;
 	}
 	return 0;
 }
@@ -1386,7 +1385,7 @@
 
 	/* A nop is required in an indirect buffer when switching
 	 * pagetables in-stream */
-	kgsl_sharedmem_writel(&mmu->setstate_memory,
+	kgsl_sharedmem_writel(mmu->device, &mmu->setstate_memory,
 				KGSL_IOMMU_SETSTATE_NOP_OFFSET,
 				cp_nop_packet(1));
 
@@ -1626,18 +1625,26 @@
 	for (i = 0; i < iommu->unit_count; i++) {
 		struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
 		for (j = 0; j < iommu_unit->dev_count; j++) {
-			iommu_unit->dev[j].pt_lsb = KGSL_IOMMMU_PT_LSB(iommu,
+			if (sizeof(phys_addr_t) > sizeof(unsigned long)) {
+				iommu_unit->dev[j].default_ttbr0 =
+						KGSL_IOMMU_GET_CTX_REG_LL(iommu,
+						iommu_unit,
+						iommu_unit->dev[j].ctx_id,
+						TTBR0);
+			} else {
+				iommu_unit->dev[j].default_ttbr0 =
 						KGSL_IOMMU_GET_CTX_REG(iommu,
 						iommu_unit,
 						iommu_unit->dev[j].ctx_id,
-						TTBR0));
+						TTBR0);
+			}
 		}
 	}
 	kgsl_iommu_lock_rb_in_tlb(mmu);
 	_iommu_unlock();
 
 	/* For complete CFF */
-	kgsl_cffdump_setmem(mmu->setstate_memory.gpuaddr +
+	kgsl_cffdump_setmem(mmu->device, mmu->setstate_memory.gpuaddr +
 				KGSL_IOMMU_SETSTATE_NOP_OFFSET,
 				cp_nop_packet(1), sizeof(unsigned int));
 
@@ -1806,10 +1813,10 @@
 	return 0;
 }
 
-static unsigned int
+static phys_addr_t
 kgsl_iommu_get_current_ptbase(struct kgsl_mmu *mmu)
 {
-	unsigned int pt_base;
+	phys_addr_t pt_base;
 	struct kgsl_iommu *iommu = mmu->priv;
 	/* We cannot enable or disable the clocks in interrupt context, this
 	 function is called from interrupt context if there is an axi error */
@@ -1842,16 +1849,14 @@
 	struct kgsl_iommu *iommu = mmu->priv;
 	int temp;
 	int i;
-	unsigned int pt_base = kgsl_iommu_get_pt_base_addr(mmu,
+	phys_addr_t pt_base = kgsl_iommu_get_pt_base_addr(mmu,
 						mmu->hwpagetable);
-	unsigned int pt_val;
+	phys_addr_t pt_val;
 
 	if (kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_USER)) {
 		KGSL_DRV_ERR(mmu->device, "Failed to enable iommu clocks\n");
 		return;
 	}
-	/* Mask off the lsb of the pt base address since lsb will not change */
-	pt_base &= KGSL_IOMMU_CTX_TTBR0_ADDR_MASK;
 
 	/* For v0 SMMU GPU needs to be idle for tlb invalidate as well */
 	if (msm_soc_version_supports_iommu_v0())
@@ -1866,12 +1871,21 @@
 		for (i = 0; i < iommu->unit_count; i++) {
 			/* get the lsb value which should not change when
 			 * changing ttbr0 */
-			pt_val = kgsl_iommu_get_pt_lsb(mmu, i,
+			pt_val = kgsl_iommu_get_default_ttbr0(mmu, i,
 						KGSL_IOMMU_CONTEXT_USER);
-			pt_val += pt_base;
 
-			KGSL_IOMMU_SET_CTX_REG(iommu, (&iommu->iommu_units[i]),
-				KGSL_IOMMU_CONTEXT_USER, TTBR0, pt_val);
+			pt_base &= KGSL_IOMMU_CTX_TTBR0_ADDR_MASK;
+			pt_val &= ~KGSL_IOMMU_CTX_TTBR0_ADDR_MASK;
+			pt_val |= pt_base;
+			if (sizeof(phys_addr_t) > sizeof(unsigned long)) {
+				KGSL_IOMMU_SET_CTX_REG_LL(iommu,
+					(&iommu->iommu_units[i]),
+					KGSL_IOMMU_CONTEXT_USER, TTBR0, pt_val);
+			} else {
+				KGSL_IOMMU_SET_CTX_REG(iommu,
+					(&iommu->iommu_units[i]),
+					KGSL_IOMMU_CONTEXT_USER, TTBR0, pt_val);
+			}
 
 			mb();
 			temp = KGSL_IOMMU_GET_CTX_REG(iommu,
@@ -1976,7 +1990,7 @@
 	.mmu_get_current_ptbase = kgsl_iommu_get_current_ptbase,
 	.mmu_enable_clk = kgsl_iommu_enable_clk,
 	.mmu_disable_clk_on_ts = kgsl_iommu_disable_clk_on_ts,
-	.mmu_get_pt_lsb = kgsl_iommu_get_pt_lsb,
+	.mmu_get_default_ttbr0 = kgsl_iommu_get_default_ttbr0,
 	.mmu_get_reg_gpuaddr = kgsl_iommu_get_reg_gpuaddr,
 	.mmu_get_reg_ahbaddr = kgsl_iommu_get_reg_ahbaddr,
 	.mmu_get_num_iommu_units = kgsl_iommu_get_num_iommu_units,
diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h
index b1b83c0..53b3946 100644
--- a/drivers/gpu/msm/kgsl_iommu.h
+++ b/drivers/gpu/msm/kgsl_iommu.h
@@ -47,7 +47,12 @@
 #define KGSL_IOMMU_V1_FSYNR0_WNR_SHIFT		4
 
 /* TTBR0 register fields */
+#ifdef CONFIG_ARM_LPAE
+#define KGSL_IOMMU_CTX_TTBR0_ADDR_MASK_LPAE	0x000000FFFFFFFFE0ULL
+#define KGSL_IOMMU_CTX_TTBR0_ADDR_MASK KGSL_IOMMU_CTX_TTBR0_ADDR_MASK_LPAE
+#else
 #define KGSL_IOMMU_CTX_TTBR0_ADDR_MASK		0xFFFFC000
+#endif
 
 /* TLBSTATUS register fields */
 #define KGSL_IOMMU_CTX_TLBSTATUS_SACTIVE BIT(0)
@@ -102,6 +107,20 @@
 #define KGSL_IOMMU_MAX_DEVS_PER_UNIT 2
 
 /* Macros to read/write IOMMU registers */
+#define KGSL_IOMMU_SET_CTX_REG_LL(iommu, iommu_unit, ctx, REG, val)	\
+		writell_relaxed(val,					\
+		iommu_unit->reg_map.hostptr +				\
+		iommu->iommu_reg_list[KGSL_IOMMU_CTX_##REG].reg_offset +\
+		(ctx << KGSL_IOMMU_CTX_SHIFT) +				\
+		iommu->ctx_offset)
+
+#define KGSL_IOMMU_GET_CTX_REG_LL(iommu, iommu_unit, ctx, REG)		\
+		readl_relaxed(						\
+		iommu_unit->reg_map.hostptr +				\
+		iommu->iommu_reg_list[KGSL_IOMMU_CTX_##REG].reg_offset +\
+		(ctx << KGSL_IOMMU_CTX_SHIFT) +				\
+		iommu->ctx_offset)
+
 #define KGSL_IOMMU_SET_CTX_REG(iommu, iommu_unit, ctx, REG, val)	\
 		writel_relaxed(val,					\
 		iommu_unit->reg_map.hostptr +				\
@@ -128,8 +147,7 @@
  * @dev: Device pointer to iommu context
  * @attached: Indicates whether this iommu context is presently attached to
  * a pagetable/domain or not
- * @pt_lsb: The LSB of IOMMU_TTBR0 register which is the pagetable
- * register
+ * @default_ttbr0: The TTBR0 value set by iommu driver on start up
  * @ctx_id: This iommu units context id. It can be either 0 or 1
  * @clk_enabled: If set indicates that iommu clocks of this iommu context
  * are on, else the clocks are off
@@ -139,7 +157,7 @@
 struct kgsl_iommu_device {
 	struct device *dev;
 	bool attached;
-	unsigned int pt_lsb;
+	phys_addr_t default_ttbr0;
 	enum kgsl_iommu_context_id ctx_id;
 	bool clk_enabled;
 	struct kgsl_device *kgsldev;
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 3ebfdcd..12a4b25 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -314,7 +314,7 @@
 }
 
 int
-kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu, unsigned int pt_base)
+kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu, phys_addr_t pt_base)
 {
 	struct kgsl_pagetable *pt;
 	int ptid = -1;
@@ -335,7 +335,7 @@
 EXPORT_SYMBOL(kgsl_mmu_get_ptname_from_ptbase);
 
 unsigned int
-kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu, unsigned int pt_base,
+kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu, phys_addr_t pt_base,
 					unsigned int addr)
 {
 	struct kgsl_pagetable *pt;
@@ -372,7 +372,7 @@
 	status = kgsl_allocate_contiguous(&mmu->setstate_memory, PAGE_SIZE);
 	if (status)
 		return status;
-	kgsl_sharedmem_set(&mmu->setstate_memory, 0, 0,
+	kgsl_sharedmem_set(device, &mmu->setstate_memory, 0, 0,
 				mmu->setstate_memory.size);
 
 	if (KGSL_MMU_TYPE_NONE == kgsl_mmu_type) {
@@ -410,7 +410,8 @@
 
 static void mh_axi_error(struct kgsl_device *device, const char* type)
 {
-	unsigned int reg, gpu_err, phys_err, pt_base;
+	unsigned int reg, gpu_err, phys_err;
+	phys_addr_t pt_base;
 
 	kgsl_regread(device, MH_AXI_ERROR, &reg);
 	pt_base = kgsl_mmu_get_current_ptbase(&device->mmu);
@@ -423,8 +424,8 @@
 	kgsl_regwrite(device, MH_DEBUG_CTRL, 45);
 	kgsl_regread(device, MH_DEBUG_DATA, &phys_err);
 	KGSL_MEM_CRIT(device,
-			"axi %s error: %08x pt %08x gpu %08x phys %08x\n",
-			type, reg, pt_base, gpu_err, phys_err);
+			"axi %s error: %08x pt %pa gpu %08x phys %08x\n",
+			type, reg, &pt_base, gpu_err, phys_err);
 }
 
 void kgsl_mh_intrcallback(struct kgsl_device *device)
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 02cde94..a4fffec 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -139,13 +139,13 @@
 	void (*mmu_device_setstate) (struct kgsl_mmu *mmu,
 					uint32_t flags);
 	void (*mmu_pagefault) (struct kgsl_mmu *mmu);
-	unsigned int (*mmu_get_current_ptbase)
+	phys_addr_t (*mmu_get_current_ptbase)
 			(struct kgsl_mmu *mmu);
 	void (*mmu_disable_clk_on_ts)
 		(struct kgsl_mmu *mmu, uint32_t ts, bool ts_valid);
 	int (*mmu_enable_clk)
 		(struct kgsl_mmu *mmu, int ctx_id);
-	int (*mmu_get_pt_lsb)(struct kgsl_mmu *mmu,
+	phys_addr_t (*mmu_get_default_ttbr0)(struct kgsl_mmu *mmu,
 				unsigned int unit_id,
 				enum kgsl_iommu_context_id ctx_id);
 	unsigned int (*mmu_get_reg_gpuaddr)(struct kgsl_mmu *mmu,
@@ -156,8 +156,8 @@
 	int (*mmu_get_num_iommu_units)(struct kgsl_mmu *mmu);
 	int (*mmu_pt_equal) (struct kgsl_mmu *mmu,
 			struct kgsl_pagetable *pt,
-			unsigned int pt_base);
-	unsigned int (*mmu_get_pt_base_addr)
+			phys_addr_t pt_base);
+	phys_addr_t (*mmu_get_pt_base_addr)
 			(struct kgsl_mmu *mmu,
 			struct kgsl_pagetable *pt);
 	int (*mmu_setup_pt) (struct kgsl_mmu *mmu,
@@ -228,9 +228,9 @@
 void kgsl_setstate(struct kgsl_mmu *mmu, unsigned int context_id,
 			uint32_t flags);
 int kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu,
-					unsigned int pt_base);
+					phys_addr_t pt_base);
 unsigned int kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu,
-			unsigned int pt_base, unsigned int addr);
+			phys_addr_t pt_base, unsigned int addr);
 int kgsl_mmu_pt_get_flags(struct kgsl_pagetable *pt,
 			enum kgsl_deviceid id);
 void kgsl_mmu_ptpool_destroy(void *ptpool);
@@ -246,7 +246,7 @@
  * of as wrappers around the actual function
  */
 
-static inline unsigned int kgsl_mmu_get_current_ptbase(struct kgsl_mmu *mmu)
+static inline phys_addr_t kgsl_mmu_get_current_ptbase(struct kgsl_mmu *mmu)
 {
 	if (mmu->mmu_ops && mmu->mmu_ops->mmu_get_current_ptbase)
 		return mmu->mmu_ops->mmu_get_current_ptbase(mmu);
@@ -277,7 +277,7 @@
 
 static inline int kgsl_mmu_pt_equal(struct kgsl_mmu *mmu,
 			struct kgsl_pagetable *pt,
-			unsigned int pt_base)
+			phys_addr_t pt_base)
 {
 	if (mmu->mmu_ops && mmu->mmu_ops->mmu_pt_equal)
 		return mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base);
@@ -285,7 +285,7 @@
 		return 1;
 }
 
-static inline unsigned int kgsl_mmu_get_pt_base_addr(struct kgsl_mmu *mmu,
+static inline phys_addr_t kgsl_mmu_get_pt_base_addr(struct kgsl_mmu *mmu,
 						struct kgsl_pagetable *pt)
 {
 	if (mmu->mmu_ops && mmu->mmu_ops->mmu_get_pt_base_addr)
@@ -294,12 +294,13 @@
 		return 0;
 }
 
-static inline int kgsl_mmu_get_pt_lsb(struct kgsl_mmu *mmu,
+static inline phys_addr_t kgsl_mmu_get_default_ttbr0(struct kgsl_mmu *mmu,
 					unsigned int unit_id,
 					enum kgsl_iommu_context_id ctx_id)
 {
-	if (mmu->mmu_ops && mmu->mmu_ops->mmu_get_pt_lsb)
-		return mmu->mmu_ops->mmu_get_pt_lsb(mmu, unit_id, ctx_id);
+	if (mmu->mmu_ops && mmu->mmu_ops->mmu_get_default_ttbr0)
+		return mmu->mmu_ops->mmu_get_default_ttbr0(mmu, unit_id,
+							ctx_id);
 	else
 		return 0;
 }
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 1691762..01f0768 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -879,7 +879,8 @@
 EXPORT_SYMBOL(kgsl_sharedmem_readl);
 
 int
-kgsl_sharedmem_writel(const struct kgsl_memdesc *memdesc,
+kgsl_sharedmem_writel(struct kgsl_device *device,
+			const struct kgsl_memdesc *memdesc,
 			unsigned int offsetbytes,
 			uint32_t src)
 {
@@ -892,7 +893,8 @@
 	WARN_ON(offsetbytes + sizeof(uint32_t) > memdesc->size);
 	if (offsetbytes + sizeof(uint32_t) > memdesc->size)
 		return -ERANGE;
-	kgsl_cffdump_setmem(memdesc->gpuaddr + offsetbytes,
+	kgsl_cffdump_setmem(device,
+		memdesc->gpuaddr + offsetbytes,
 		src, sizeof(uint32_t));
 	dst = (uint32_t *)(memdesc->hostptr + offsetbytes);
 	*dst = src;
@@ -901,14 +903,16 @@
 EXPORT_SYMBOL(kgsl_sharedmem_writel);
 
 int
-kgsl_sharedmem_set(const struct kgsl_memdesc *memdesc, unsigned int offsetbytes,
-			unsigned int value, unsigned int sizebytes)
+kgsl_sharedmem_set(struct kgsl_device *device,
+		const struct kgsl_memdesc *memdesc, unsigned int offsetbytes,
+		unsigned int value, unsigned int sizebytes)
 {
 	BUG_ON(memdesc == NULL || memdesc->hostptr == NULL);
 	BUG_ON(offsetbytes + sizebytes > memdesc->size);
 
-	kgsl_cffdump_setmem(memdesc->gpuaddr + offsetbytes, value,
-			    sizebytes);
+	kgsl_cffdump_setmem(device,
+		memdesc->gpuaddr + offsetbytes, value,
+		sizebytes);
 	memset(memdesc->hostptr + offsetbytes, value, sizebytes);
 	return 0;
 }
diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h
index 14ae0dc..985b9b8 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.h
+++ b/drivers/gpu/msm/kgsl_sharedmem.h
@@ -55,11 +55,13 @@
 			uint32_t *dst,
 			unsigned int offsetbytes);
 
-int kgsl_sharedmem_writel(const struct kgsl_memdesc *memdesc,
+int kgsl_sharedmem_writel(struct kgsl_device *device,
+			const struct kgsl_memdesc *memdesc,
 			unsigned int offsetbytes,
 			uint32_t src);
 
-int kgsl_sharedmem_set(const struct kgsl_memdesc *memdesc,
+int kgsl_sharedmem_set(struct kgsl_device *device,
+			const struct kgsl_memdesc *memdesc,
 			unsigned int offsetbytes, unsigned int value,
 			unsigned int sizebytes);
 
@@ -154,7 +156,7 @@
 
 static inline int
 memdesc_sg_phys(struct kgsl_memdesc *memdesc,
-		unsigned int physaddr, unsigned int size)
+		phys_addr_t physaddr, unsigned int size)
 {
 	memdesc->sg = kgsl_sg_alloc(1);
 	if (memdesc->sg == NULL)
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index 6fcd912..d3edbba 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -27,7 +27,7 @@
 
 struct kgsl_snapshot_object {
 	unsigned int gpuaddr;
-	unsigned int ptbase;
+	phys_addr_t ptbase;
 	unsigned int size;
 	unsigned int offset;
 	int type;
@@ -140,6 +140,7 @@
 	int hang = (int) priv;
 	int ctxtcount = 0;
 	int size = sizeof(*header);
+	phys_addr_t temp_ptbase;
 
 	/* Figure out how many active contexts there are - these will
 	 * be appended on the end of the structure */
@@ -181,11 +182,14 @@
 	kgsl_sharedmem_readl(&device->memstore, &header->current_context,
 		KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context));
 
+
 	/* Get the current PT base */
-	header->ptbase = kgsl_mmu_get_current_ptbase(&device->mmu);
+	temp_ptbase = kgsl_mmu_get_current_ptbase(&device->mmu);
+	/* Truncate to 32 bits in case LPAE is used */
+	header->ptbase = (__u32)temp_ptbase;
 	/* And the PID for the task leader */
 	pid = header->pid = kgsl_mmu_get_ptname_from_ptbase(&device->mmu,
-								header->ptbase);
+								temp_ptbase);
 
 	task = find_task_by_vpid(pid);
 
@@ -267,7 +271,7 @@
 
 	header.size = ALIGN(obj->size, 4) >> 2;
 	header.gpuaddr = obj->gpuaddr;
-	header.ptbase = obj->ptbase;
+	header.ptbase = (__u32)obj->ptbase;
 	header.type = obj->type;
 
 	ret = obj_itr_out(itr, &header, sizeof(header));
@@ -309,7 +313,7 @@
  * Return 1 if the object is already in the list - this can save us from
  * having to parse the sme thing over again.
 */
-int kgsl_snapshot_have_object(struct kgsl_device *device, unsigned int ptbase,
+int kgsl_snapshot_have_object(struct kgsl_device *device, phys_addr_t ptbase,
 	unsigned int gpuaddr, unsigned int size)
 {
 	struct kgsl_snapshot_object *obj;
@@ -339,7 +343,7 @@
  * size of the object being frozen
  */
 
-int kgsl_snapshot_get_object(struct kgsl_device *device, unsigned int ptbase,
+int kgsl_snapshot_get_object(struct kgsl_device *device, phys_addr_t ptbase,
 	unsigned int gpuaddr, unsigned int size, unsigned int type)
 {
 	struct kgsl_mem_entry *entry;
diff --git a/drivers/gpu/msm/kgsl_snapshot.h b/drivers/gpu/msm/kgsl_snapshot.h
index 4db2815..61a3b22 100644
--- a/drivers/gpu/msm/kgsl_snapshot.h
+++ b/drivers/gpu/msm/kgsl_snapshot.h
@@ -320,10 +320,10 @@
 	unsigned int data, unsigned int start, unsigned int count);
 
 /* Freeze a GPU buffer so it can be dumped in the snapshot */
-int kgsl_snapshot_get_object(struct kgsl_device *device, unsigned int ptbase,
+int kgsl_snapshot_get_object(struct kgsl_device *device, phys_addr_t ptbase,
 	unsigned int gpuaddr, unsigned int size, unsigned int type);
 
-int kgsl_snapshot_have_object(struct kgsl_device *device, unsigned int ptbase,
+int kgsl_snapshot_have_object(struct kgsl_device *device, phys_addr_t ptbase,
 	unsigned int gpuaddr, unsigned int size);
 
 #endif
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 49265fc..7004ad7 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -467,10 +467,10 @@
 	addmarker(&z180_dev->ringbuffer, z180_dev->current_timestamp);
 
 	/* monkey patch the IB so that it jumps back to the ringbuffer */
-	kgsl_sharedmem_writel(&entry->memdesc,
+	kgsl_sharedmem_writel(device, &entry->memdesc,
 		      ((sizedwords + 1) * sizeof(unsigned int)),
 		      rb_gpuaddr(z180_dev, z180_dev->current_timestamp));
-	kgsl_sharedmem_writel(&entry->memdesc,
+	kgsl_sharedmem_writel(device, &entry->memdesc,
 			      ((sizedwords + 2) * sizeof(unsigned int)),
 			      nextcnt);
 
@@ -710,7 +710,7 @@
 	BUG_ON(offsetwords*sizeof(uint32_t) >= device->reg_len);
 
 	reg = (unsigned int *)(device->reg_virt + (offsetwords << 2));
-	kgsl_cffdump_regwrite(device->id, offsetwords << 2, value);
+	kgsl_cffdump_regwrite(device, offsetwords << 2, value);
 	/*ensure previous writes post before this one,
 	 * i.e. act like normal writel() */
 	wmb();
diff --git a/drivers/gpu/msm/z180_postmortem.c b/drivers/gpu/msm/z180_postmortem.c
index 55b8faa..5d929cf 100644
--- a/drivers/gpu/msm/z180_postmortem.c
+++ b/drivers/gpu/msm/z180_postmortem.c
@@ -118,7 +118,7 @@
 	int rb_slot_num = -1;
 	struct z180_device *z180_dev = Z180_DEVICE(device);
 	struct kgsl_mem_entry *entry = NULL;
-	unsigned int pt_base;
+	phys_addr_t pt_base;
 	unsigned int i;
 	unsigned int j;
 	char linebuf[CHARS_PER_LINE];
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index b8c3c44..bd4344b 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -442,6 +442,45 @@
 }
 EXPORT_SYMBOL(dvb_dmx_video_pattern_search);
 
+/**
+ * dvb_dmx_notify_section_event() - Notify demux event for all filters of a
+ * specified section feed.
+ *
+ * @feed:		dvb_demux_feed object
+ * @event:		demux event to notify
+ * @should_lock:	specifies whether the function should lock the demux
+ *
+ * Caller is responsible for locking the demux properly, either by doing the
+ * locking itself and setting 'should_lock' to 0, or have the function do it
+ * by setting 'should_lock' to 1.
+ */
+int dvb_dmx_notify_section_event(struct dvb_demux_feed *feed,
+	struct dmx_data_ready *event, int should_lock)
+{
+	struct dvb_demux_filter *f;
+
+	if (feed == NULL || event == NULL || feed->type != DMX_TYPE_SEC)
+		return -EINVAL;
+
+	if (!should_lock && !spin_is_locked(&feed->demux->lock))
+		return -EINVAL;
+
+	if (should_lock)
+		spin_lock(&feed->demux->lock);
+
+	f = feed->filter;
+	while (f && feed->feed.sec.is_filtering) {
+		feed->data_ready_cb.sec(&f->filter, event);
+		f = f->next;
+	}
+
+	if (should_lock)
+		spin_unlock(&feed->demux->lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(dvb_dmx_notify_section_event);
+
 static int dvb_dmx_check_pes_end(struct dvb_demux_feed *feed)
 {
 	struct dmx_data_ready data;
@@ -1310,8 +1349,7 @@
 		dmx_data_ready.scrambling_bits.new_value = scrambling_bits;
 
 		if (feed->type == DMX_TYPE_SEC)
-			feed->data_ready_cb.sec(&feed->filter->filter,
-					&dmx_data_ready);
+			dvb_dmx_notify_section_event(feed, &dmx_data_ready, 0);
 		else
 			feed->data_ready_cb.ts(&feed->feed.ts, &dmx_data_ready);
 	}
@@ -2735,7 +2773,7 @@
 	struct dvb_demux_feed *feed = (struct dvb_demux_feed *)section_feed;
 	struct dvb_demux *dvbdmx = feed->demux;
 	struct dmx_data_ready data;
-	int ret;
+	int ret = 0;
 
 	data.data_length = 0;
 
@@ -2760,13 +2798,11 @@
 	switch (cmd->type) {
 	case DMX_OOB_CMD_EOS:
 		data.status = DMX_OK_EOS;
-		ret = feed->data_ready_cb.sec(&feed->filter->filter, &data);
 		break;
 
 	case DMX_OOB_CMD_MARKER:
 		data.status = DMX_OK_MARKER;
 		data.marker.id = cmd->params.marker.id;
-		ret = feed->data_ready_cb.sec(&feed->filter->filter, &data);
 		break;
 
 	default:
@@ -2774,6 +2810,9 @@
 		break;
 	}
 
+	if (!ret)
+		ret = dvb_dmx_notify_section_event(feed, &data, 1);
+
 	mutex_unlock(&dvbdmx->mutex);
 	return ret;
 }
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index 9fb1a12..aeafa57 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -325,6 +325,8 @@
 		u64 curr_match_tsp, u64 prev_match_tsp,
 		u64 curr_pusi_tsp, u64 prev_pusi_tsp);
 void dvb_dmx_notify_idx_events(struct dvb_demux_feed *feed);
+int dvb_dmx_notify_section_event(struct dvb_demux_feed *feed,
+	struct dmx_data_ready *event, int should_lock);
 
 /**
  * dvb_dmx_is_video_feed - Returns whether the PES feed
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 88f2f08..74a920c 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -567,11 +567,18 @@
 	if (buf_state == MSM_ISP_BUFFER_STATE_DIVERTED) {
 		buf_info = msm_isp_get_buf_ptr(buf_mgr,
 						info->handle, info->buf_idx);
-		if (info->dirty_buf)
-			msm_isp_put_buf(buf_mgr, info->handle, info->buf_idx);
-		else
-			msm_isp_buf_done(buf_mgr, info->handle, info->buf_idx,
-				buf_info->tv, buf_info->frame_id);
+		if (info->dirty_buf) {
+			rc = msm_isp_put_buf(buf_mgr,
+				info->handle, info->buf_idx);
+		} else {
+			if (BUF_SRC(bufq->stream_id))
+				pr_err("%s: Invalid native buffer state\n",
+					__func__);
+			else
+				rc = msm_isp_buf_done(buf_mgr,
+					info->handle, info->buf_idx,
+					buf_info->tv, buf_info->frame_id);
+		}
 	} else {
 		bufq = msm_isp_get_bufq(buf_mgr, info->handle);
 		if (BUF_SRC(bufq->stream_id)) {
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
index 790bbc1..a63fccf 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -4111,7 +4111,7 @@
 		MPQ_DVB_DBG_PRINT("%s: Notify CRC err event\n", __func__);
 		event.status = DMX_CRC_ERROR;
 		event.data_length = 0;
-		feed->data_ready_cb.sec(&feed->filter->filter, &event);
+		dvb_dmx_notify_section_event(feed, &event, 1);
 	}
 
 	if (sts->error_indicators & SDMX_FILTER_ERR_D_BUF_FULL)
@@ -4145,12 +4145,7 @@
 	if (sts->status_indicators & SDMX_FILTER_STATUS_EOS) {
 		event.data_length = 0;
 		event.status = DMX_OK_EOS;
-		f = feed->filter;
-
-		while (f && sec->is_filtering) {
-			feed->data_ready_cb.sec(&f->filter, &event);
-			f = f->next;
-		}
+		dvb_dmx_notify_section_event(feed, &event, 1);
 	}
 
 }
@@ -4471,10 +4466,12 @@
 {
 	int i;
 	int j;
+	int sdmx_filters;
 	struct sdmx_filter_status *sts;
 	struct mpq_feed *mpq_feed;
 
-	for (i = 0; i < mpq_demux->sdmx_filter_count; i++) {
+	sdmx_filters = mpq_demux->sdmx_filter_count;
+	for (i = 0; i < sdmx_filters; i++) {
 		/*
 		 * MPQ_TODO: review lookup optimization
 		 * Can have the related mpq_feed index already associated with
@@ -4817,21 +4814,11 @@
 		event.status = DMX_OK_MARKER;
 		event.marker.id = cmd->params.marker.id;
 
-		if (feed->type == DMX_TYPE_SEC) {
-			struct dvb_demux_filter *f = feed->filter;
-			struct dmx_section_feed *sec = &feed->feed.sec;
-
-			while (f && sec->is_filtering) {
-				ret = feed->data_ready_cb.sec(&f->filter,
-					&event);
-				if (ret)
-					break;
-				f = f->next;
-			}
-		} else {
+		if (feed->type == DMX_TYPE_SEC)
+			ret = dvb_dmx_notify_section_event(feed, &event, 1);
+		else
 			/* MPQ_TODO: Notify decoder via the stream buffer */
 			ret = feed->data_ready_cb.ts(&feed->feed.ts, &event);
-		}
 		break;
 
 	default:
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index e0fffbd..a395b7c 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.c
@@ -46,6 +46,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/string.h>
+#include <mach/msm_bus.h>
 
 /*
  * General defines
@@ -437,6 +438,7 @@
 	struct list_head devlist; /* list of all devices */
 	struct platform_device *pdev;
 	void __iomem *base;
+	uint32_t tsif_bus_client;
 	unsigned int tspp_irq;
 	unsigned int bam_irq;
 	u32 bam_handle;
@@ -773,12 +775,24 @@
 		return -EINVAL;
 	}
 
+	if (device->tsif_bus_client) {
+		rc = msm_bus_scale_client_update_request(
+					device->tsif_bus_client, 1);
+		if (rc) {
+			pr_err("tspp: Can't enable bus\n");
+			return -EBUSY;
+		}
+	}
+
 	if (device->tsif_vreg) {
 		rc = regulator_set_voltage(device->tsif_vreg,
 					RPM_REGULATOR_CORNER_SUPER_TURBO,
 					RPM_REGULATOR_CORNER_SUPER_TURBO);
 		if (rc) {
 			pr_err("Unable to set CX voltage.\n");
+			if (device->tsif_bus_client)
+				msm_bus_scale_client_update_request(
+					device->tsif_bus_client, 0);
 			return rc;
 		}
 	}
@@ -791,6 +805,10 @@
 					RPM_REGULATOR_CORNER_SVS_SOC,
 					RPM_REGULATOR_CORNER_SUPER_TURBO);
 		}
+
+		if (device->tsif_bus_client)
+			msm_bus_scale_client_update_request(
+				device->tsif_bus_client, 0);
 		return -EBUSY;
 	}
 
@@ -803,6 +821,10 @@
 					RPM_REGULATOR_CORNER_SVS_SOC,
 					RPM_REGULATOR_CORNER_SUPER_TURBO);
 		}
+
+		if (device->tsif_bus_client)
+			msm_bus_scale_client_update_request(
+				device->tsif_bus_client, 0);
 		return -EBUSY;
 	}
 
@@ -831,6 +853,13 @@
 		if (rc)
 			pr_err("Unable to set CX voltage.\n");
 	}
+
+	if (device->tsif_bus_client) {
+		rc = msm_bus_scale_client_update_request(
+					device->tsif_bus_client, 0);
+		if (rc)
+			pr_err("tspp: Can't disable bus\n");
+	}
 }
 
 /*** TSIF functions ***/
@@ -2851,6 +2880,7 @@
 	struct resource *mem_tspp;
 	struct resource *mem_bam;
 	struct tspp_channel *channel;
+	struct msm_bus_scale_pdata *tspp_bus_pdata = NULL;
 
 	if (pdev->dev.of_node) {
 		/* get information from device tree */
@@ -2862,9 +2892,12 @@
 			pdev->id = -1;
 
 		pdev->dev.platform_data = data;
+
+		tspp_bus_pdata = msm_bus_cl_get_pdata(pdev);
 	} else {
 		/* must have platform data */
 		data = pdev->dev.platform_data;
+		tspp_bus_pdata = NULL;
 	}
 	if (!data) {
 		pr_err("tspp: Platform data not available");
@@ -2891,6 +2924,16 @@
 	device->pdev = pdev;
 	platform_set_drvdata(pdev, device);
 
+	/* register bus client */
+	if (tspp_bus_pdata) {
+		device->tsif_bus_client =
+			msm_bus_scale_register_client(tspp_bus_pdata);
+		if (!device->tsif_bus_client)
+			pr_err("tspp: Unable to register bus client\n");
+	} else {
+		device->tsif_bus_client = 0;
+	}
+
 	/* map regulators */
 	if (data->tsif_vreg_present) {
 		device->tsif_vreg = devm_regulator_get(&pdev->dev, "vdd_cx");
@@ -3108,6 +3151,8 @@
 	if (device->tsif_vreg)
 		regulator_disable(device->tsif_vreg);
 err_regultaor:
+	if (device->tsif_bus_client)
+		msm_bus_scale_unregister_client(device->tsif_bus_client);
 	kfree(device);
 
 out:
@@ -3143,6 +3188,9 @@
 			free_irq(device->tsif[i].tsif_irq,  &device->tsif[i]);
 	}
 
+	if (device->tsif_bus_client)
+		msm_bus_scale_unregister_client(device->tsif_bus_client);
+
 	wake_lock_destroy(&device->wake_lock);
 	free_irq(device->tspp_irq, device);
 
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index d872254..3986cdd 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -87,6 +87,10 @@
 
 static int msmsdcc_prep_xfer(struct msmsdcc_host *host, struct mmc_data
 			     *data);
+static void msmsdcc_msm_bus_cancel_work_and_set_vote(struct msmsdcc_host *host,
+						struct mmc_ios *ios);
+static void msmsdcc_msm_bus_queue_work(struct msmsdcc_host *host);
+
 
 static u64 dma_mask = DMA_BIT_MASK(32);
 static unsigned int msmsdcc_pwrsave = 1;
@@ -2731,12 +2735,14 @@
 	int rc = 0;
 
 	if (enable && !atomic_read(&host->clks_on)) {
+		msmsdcc_msm_bus_cancel_work_and_set_vote(host, &host->mmc->ios);
+
 		if (!IS_ERR_OR_NULL(host->bus_clk)) {
 			rc = clk_prepare_enable(host->bus_clk);
 			if (rc) {
 				pr_err("%s: %s: failed to enable the bus-clock with error %d\n",
 					mmc_hostname(host->mmc), __func__, rc);
-				goto out;
+				goto remove_vote;
 			}
 		}
 		if (!IS_ERR(host->pclk)) {
@@ -2764,6 +2770,18 @@
 			clk_disable_unprepare(host->pclk);
 		if (!IS_ERR_OR_NULL(host->bus_clk))
 			clk_disable_unprepare(host->bus_clk);
+
+		/*
+		 * If clock gating is enabled, then remove the vote
+		 * immediately because clocks will be disabled only
+		 * after MSM_MMC_CLK_GATE_DELAY and thus no additional
+		 * delay is required to remove the bus vote.
+		 */
+		 if (host->mmc->clkgate_delay)
+			msmsdcc_msm_bus_cancel_work_and_set_vote(host, NULL);
+		 else
+			 msmsdcc_msm_bus_queue_work(host);
+
 		atomic_set(&host->clks_on, 0);
 	}
 	goto out;
@@ -2774,6 +2792,8 @@
 disable_bus:
 	if (!IS_ERR_OR_NULL(host->bus_clk))
 		clk_disable_unprepare(host->bus_clk);
+remove_vote:
+	msmsdcc_msm_bus_cancel_work_and_set_vote(host, NULL);
 out:
 	return rc;
 }
@@ -3388,6 +3408,14 @@
 				(1 + ((3 * USEC_PER_SEC) /
 				      (host->clk_rate ? host->clk_rate :
 				       msmsdcc_get_min_sup_clk_rate(host))));
+			spin_unlock_irqrestore(&host->lock, flags);
+			/*
+			 * Update bus vote incase of frequency change due to
+			 * clock scaling.
+			 */
+			msmsdcc_msm_bus_cancel_work_and_set_vote(host,
+								&mmc->ios);
+			spin_lock_irqsave(&host->lock, flags);
 		}
 		/*
 		 * give atleast 2 MCLK cycles delay for clocks
@@ -3625,7 +3653,6 @@
 		return rc;
 	}
 out:
-	msmsdcc_msm_bus_cancel_work_and_set_vote(host, &mmc->ios);
 	return 0;
 }
 
@@ -3654,7 +3681,6 @@
 	}
 
 out:
-	msmsdcc_msm_bus_queue_work(host);
 	return rc;
 }
 #else
@@ -3690,7 +3716,6 @@
 		msmsdcc_pm_qos_update_latency(host, 0);
 		return rc;
 	}
-	msmsdcc_msm_bus_cancel_work_and_set_vote(host, &mmc->ios);
 	return 0;
 }
 
@@ -3713,7 +3738,6 @@
 		return rc;
 	}
 out:
-	msmsdcc_msm_bus_queue_work(host);
 	return rc;
 }
 #endif
@@ -6065,6 +6089,17 @@
 		      msmsdcc_get_min_sup_clk_rate(host)));
 
 	atomic_set(&host->clks_on, 1);
+
+	ret = msmsdcc_msm_bus_register(host);
+	if (ret)
+		goto clk_disable;
+
+	if (host->msm_bus_vote.client_handle)
+		INIT_DELAYED_WORK(&host->msm_bus_vote.vote_work,
+				  msmsdcc_msm_bus_work);
+
+	msmsdcc_msm_bus_cancel_work_and_set_vote(host, &mmc->ios);
+
 	/* Apply Hard reset to SDCC to put it in power on default state */
 	msmsdcc_hard_reset(host);
 
@@ -6077,18 +6112,10 @@
 	pm_qos_add_request(&host->pm_qos_req_dma,
 			PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
 
-	ret = msmsdcc_msm_bus_register(host);
-	if (ret)
-		goto pm_qos_remove;
-
-	if (host->msm_bus_vote.client_handle)
-		INIT_DELAYED_WORK(&host->msm_bus_vote.vote_work,
-				  msmsdcc_msm_bus_work);
-
 	ret = msmsdcc_vreg_init(host, true);
 	if (ret) {
 		pr_err("%s: msmsdcc_vreg_init() failed (%d)\n", __func__, ret);
-		goto clk_disable;
+		goto pm_qos_remove;
 	}
 
 
@@ -6439,12 +6466,13 @@
 		msmsdcc_sps_exit(host);
  vreg_deinit:
 	msmsdcc_vreg_init(host, false);
- clk_disable:
-	clk_disable_unprepare(host->clk);
-	msmsdcc_msm_bus_unregister(host);
  pm_qos_remove:
 	if (host->cpu_dma_latency)
 		pm_qos_remove_request(&host->pm_qos_req_dma);
+	msmsdcc_msm_bus_cancel_work_and_set_vote(host, NULL);
+	msmsdcc_msm_bus_unregister(host);
+ clk_disable:
+	clk_disable_unprepare(host->clk);
  clk_put:
 	clk_put(host->clk);
  pclk_disable:
@@ -6765,8 +6793,13 @@
 	}
 	pr_debug("%s: %s: ends with err=%d\n", mmc_hostname(mmc), __func__, rc);
 out:
-	/* set bus bandwidth to 0 immediately */
-	msmsdcc_msm_bus_cancel_work_and_set_vote(host, NULL);
+	/*
+	 * Remove the vote immediately only if clocks are off in which
+	 * case we might have queued work to remove vote but it may not
+	 * be completed before runtime suspend or system suspend.
+	 */
+	if (!atomic_read(&host->clks_on))
+		msmsdcc_msm_bus_cancel_work_and_set_vote(host, NULL);
 	msmsdcc_print_pm_stats(host, start, __func__, rc);
 	return rc;
 }
diff --git a/drivers/spmi/spmi-dbgfs.c b/drivers/spmi/spmi-dbgfs.c
index b825ade..27df09333 100644
--- a/drivers/spmi/spmi-dbgfs.c
+++ b/drivers/spmi/spmi-dbgfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -24,7 +24,6 @@
  *        /spmi-#
  */
 
-#define DEBUG
 #define pr_fmt(fmt) "%s:%d: " fmt, __func__, __LINE__
 
 #include <linux/kernel.h>
@@ -582,7 +581,7 @@
 {
 	struct dentry *root, *file;
 
-	pr_debug("Creating SPMI debugfs file-system at\n");
+	pr_debug("Creating SPMI debugfs file-system\n");
 	root = debugfs_create_dir(DFS_ROOT_NAME, NULL);
 	if (IS_ERR(root)) {
 		pr_err("Error creating top level directory err:%ld",
@@ -697,6 +696,41 @@
 }
 
 /*
+ * spmi_dfs_del_controller: deletes spmi controller entry
+ * @return zero on success
+ */
+int spmi_dfs_del_controller(struct spmi_controller *ctrl)
+{
+	int rc;
+	struct list_head *pos, *tmp;
+	struct spmi_ctrl_data *ctrl_data;
+
+	pr_debug("Deleting controller %s\n", ctrl->dev.kobj.name);
+
+	rc = mutex_lock_interruptible(&dbgfs_data.lock);
+	if (rc)
+		return rc;
+
+	list_for_each_safe(pos, tmp, &dbgfs_data.ctrl) {
+		ctrl_data = list_entry(pos, struct spmi_ctrl_data, node);
+
+		if (ctrl_data->ctrl == ctrl) {
+			debugfs_remove_recursive(ctrl_data->dir);
+			list_del(pos);
+			kfree(ctrl_data);
+			rc = 0;
+			goto done;
+		}
+	}
+	rc = -EINVAL;
+	pr_debug("Unknown controller %s\n", ctrl->dev.kobj.name);
+
+done:
+	mutex_unlock(&dbgfs_data.lock);
+	return rc;
+}
+
+/*
  * spmi_dfs_create_file: creates a new file in the SPMI debugfs
  * @returns valid dentry pointer on success or NULL
  */
diff --git a/drivers/spmi/spmi-dbgfs.h b/drivers/spmi/spmi-dbgfs.h
index 2a0d815..10e98b9 100644
--- a/drivers/spmi/spmi-dbgfs.h
+++ b/drivers/spmi/spmi-dbgfs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -16,8 +16,10 @@
 
 #ifdef CONFIG_DEBUG_FS
 int spmi_dfs_add_controller(struct spmi_controller *ctrl);
+int spmi_dfs_del_controller(struct spmi_controller *ctrl);
 #else
 static int spmi_dfs_add_controller(struct spmi_controller *ctrl) { return 0; }
+static int spmi_dfs_del_controller(struct spmi_controller *ctrl) { return 0; }
 #endif
 
 struct dentry *spmi_dfs_create_file(struct spmi_controller *ctrl,
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index f5c9d2f..fc21fbb 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -32,9 +32,8 @@
 static DEFINE_MUTEX(board_lock);
 static LIST_HEAD(board_list);
 static DEFINE_IDR(ctrl_idr);
-static struct device_type spmi_ctrl_type = { 0 };
-
-#define to_spmi(dev)	platform_get_drvdata(to_platform_device(dev))
+static struct device_type spmi_dev_type;
+static struct device_type spmi_ctrl_type;
 
 /* Forward declarations */
 struct bus_type spmi_bus_type;
@@ -69,6 +68,9 @@
 	int	id;
 	int	status;
 
+	if (!ctrl)
+		return -EINVAL;
+
 	pr_debug("adding controller for bus %d (0x%p)\n", ctrl->nr, ctrl);
 
 	if (ctrl->nr & ~MAX_ID_MASK) {
@@ -98,18 +100,70 @@
 }
 EXPORT_SYMBOL_GPL(spmi_add_controller);
 
+/* Remove a device associated with a controller */
+static int spmi_ctrl_remove_device(struct device *dev, void *data)
+{
+	struct spmi_device *spmidev = to_spmi_device(dev);
+	struct spmi_controller *ctrl = data;
+
+	if (dev->type == &spmi_dev_type && spmidev->ctrl == ctrl)
+		spmi_remove_device(spmidev);
+
+	return 0;
+}
+
 /**
  * spmi_del_controller: Controller tear-down.
- * @ctrl: controller to which this device is to be added to.
+ * @ctrl: controller to be removed.
  *
  * Controller added with the above API is torn down using this API.
  */
 int spmi_del_controller(struct spmi_controller *ctrl)
 {
-	return -ENXIO;
+	struct spmi_controller *found;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	/* Check that the ctrl has been added */
+	mutex_lock(&board_lock);
+	found = idr_find(&ctrl_idr, ctrl->nr);
+	mutex_unlock(&board_lock);
+	if (found != ctrl)
+		return -EINVAL;
+
+	/* Remove all the clients associated with this controller */
+	mutex_lock(&board_lock);
+	bus_for_each_dev(&spmi_bus_type, NULL, ctrl, spmi_ctrl_remove_device);
+	mutex_unlock(&board_lock);
+
+	spmi_dfs_del_controller(ctrl);
+
+	mutex_lock(&board_lock);
+	idr_remove(&ctrl_idr, ctrl->nr);
+	mutex_unlock(&board_lock);
+
+	init_completion(&ctrl->dev_released);
+	device_unregister(&ctrl->dev);
+	wait_for_completion(&ctrl->dev_released);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(spmi_del_controller);
 
+#define spmi_ctrl_attr_gr NULL
+static void spmi_ctrl_release(struct device *dev)
+{
+	struct spmi_controller *ctrl = to_spmi_controller(dev);
+
+	complete(&ctrl->dev_released);
+}
+
+static struct device_type spmi_ctrl_type = {
+	.groups		= spmi_ctrl_attr_gr,
+	.release	= spmi_ctrl_release,
+};
+
 #define spmi_device_attr_gr NULL
 #define spmi_device_uevent NULL
 static void spmi_dev_release(struct device *dev)
@@ -141,7 +195,7 @@
 {
 	struct spmi_device *spmidev;
 
-	if (!ctrl) {
+	if (!ctrl || !spmi_busnum_to_ctrl(ctrl->nr)) {
 		pr_err("Missing SPMI controller\n");
 		return NULL;
 	}
@@ -174,12 +228,15 @@
 	if (dev->bus != &spmi_bus_type || dev->type != &spmi_dev_type)
 		return NULL;
 
+	if (!spmidev->ctrl || !spmi_busnum_to_ctrl(spmidev->ctrl->nr))
+		return NULL;
+
 	return dev;
 }
 
 /**
  * spmi_add_device: Add a new device without register board info.
- * @ctrl: controller to which this device is to be added to.
+ * @spmi_dev: spmi_device to be added (registered).
  *
  * Called when device doesn't have an explicit client-driver to be probed, or
  * the client-driver is a module installed dynamically.
@@ -190,7 +247,7 @@
 	struct device *dev = get_valid_device(spmidev);
 
 	if (!dev) {
-		pr_err("%s: invalid SPMI device\n", __func__);
+		pr_err("invalid SPMI device\n");
 		return -EINVAL;
 	}
 
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 65c9e90..0ff19a2 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -393,7 +393,8 @@
 
 
 
-int mdp3_clk_set_rate(int clk_type, unsigned long clk_rate)
+int mdp3_clk_set_rate(int clk_type, unsigned long clk_rate,
+			int client)
 {
 	int ret = 0;
 	unsigned long rounded_rate;
@@ -407,6 +408,19 @@
 			mutex_unlock(&mdp3_res->res_mutex);
 			return -EINVAL;
 		}
+		if (clk_type == MDP3_CLK_CORE) {
+			if (client == MDP3_CLIENT_DMA_P) {
+				mdp3_res->dma_core_clk_request = rounded_rate;
+			} else if (client == MDP3_CLIENT_PPP) {
+				mdp3_res->ppp_core_clk_request = rounded_rate;
+			} else {
+				pr_err("unrecognized client=%d\n", client);
+				mutex_unlock(&mdp3_res->res_mutex);
+				return -EINVAL;
+			}
+			rounded_rate = max(mdp3_res->dma_core_clk_request,
+				mdp3_res->ppp_core_clk_request);
+		}
 		if (rounded_rate != clk_get_rate(clk)) {
 			ret = clk_set_rate(clk, rounded_rate);
 			if (ret)
@@ -948,7 +962,7 @@
 {
 	int rc;
 	rc = mdp3_ctrl_init(mfd);
-	rc |= mdp3_ppp_res_init();
+	rc |= mdp3_ppp_res_init(mfd);
 	return rc;
 }
 
diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h
index e52f7bc..31fcd0e 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -141,7 +141,7 @@
 void mdp3_irq_disable(int type);
 void mdp3_irq_disable_nosync(int type);
 int mdp3_set_intr_callback(u32 type, struct mdp3_intr_cb *cb);
-int mdp3_clk_set_rate(int clk_type, unsigned long clk_rate);
+int mdp3_clk_set_rate(int clk_type, unsigned long clk_rate, int client);
 int mdp3_clk_enable(int enable);
 int mdp3_bus_scale_set_quota(int client, u64 ab_quota, u64 ib_quota);
 int mdp3_put_img(struct mdp3_img_data *data);
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index 9c572a5..ce68013 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -130,52 +130,41 @@
 	return 0;
 }
 
-static int mdp3_ctrl_blit_req(struct msm_fb_data_type *mfd, void __user *p)
+static int mdp3_ctrl_async_blit_req(struct msm_fb_data_type *mfd,
+	void __user *p)
 {
-	const int MAX_LIST_WINDOW = 16;
-	struct mdp_blit_req req_list[MAX_LIST_WINDOW];
-	struct mdp_blit_req_list req_list_header;
-	int rc, count, i, req_list_count;
+	struct mdp_async_blit_req_list req_list_header;
+	int rc, count;
+	void __user *p_req;
 
 	if (copy_from_user(&req_list_header, p, sizeof(req_list_header)))
 		return -EFAULT;
-	p += sizeof(req_list_header);
+	p_req = p + sizeof(req_list_header);
 	count = req_list_header.count;
 	if (count < 0 || count >= MAX_BLIT_REQ)
 		return -EINVAL;
-	while (count > 0) {
-		/*
-		 * Access the requests through a narrow window to decrease copy
-		 * overhead and make larger requests accessible to the
-		 * coherency management code.
-		 * NOTE: The window size is intended to be larger than the
-		 *       typical request size, but not require more than 2
-		 *       kbytes of stack storage.
-		 */
-		req_list_count = count;
-		if (req_list_count > MAX_LIST_WINDOW)
-			req_list_count = MAX_LIST_WINDOW;
-		if (copy_from_user(&req_list, p,
-				sizeof(struct mdp_blit_req)*req_list_count))
-			return -EFAULT;
-		/*
-		 * Do the blit DMA, if required -- returning early only if
-		 * there is a failure.
-		 */
-		for (i = 0; i < req_list_count; i++) {
-			if (!(req_list[i].flags & MDP_NO_BLIT)) {
-				/* Do the actual blit. */
-				rc = mdp3_ppp_start_blit(mfd, &(req_list[i]));
-				if (rc)
-					return rc;
-			}
-		}
+	rc = mdp3_ppp_parse_req(p_req, &req_list_header, 1);
+	if (!rc)
+		rc = copy_to_user(p, &req_list_header, sizeof(req_list_header));
+	return rc;
+}
 
-		/* Go to next window of requests. */
-		count -= req_list_count;
-		p += sizeof(struct mdp_blit_req)*req_list_count;
-	}
-	return 0;
+static int mdp3_ctrl_blit_req(struct msm_fb_data_type *mfd, void __user *p)
+{
+	struct mdp_async_blit_req_list req_list_header;
+	int rc, count;
+	void __user *p_req;
+
+	if (copy_from_user(&(req_list_header.count), p,
+			sizeof(struct mdp_blit_req_list)))
+		return -EFAULT;
+	p_req = p + sizeof(struct mdp_blit_req_list);
+	count = req_list_header.count;
+	if (count < 0 || count >= MAX_BLIT_REQ)
+		return -EINVAL;
+	req_list_header.sync.acq_fen_fd_cnt = 0;
+	rc = mdp3_ppp_parse_req(p_req, &req_list_header, 0);
+	return rc;
 }
 
 static ssize_t mdp3_vsync_show_event(struct device *dev,
@@ -239,8 +228,10 @@
 	int rc = 0;
 	if (status) {
 
-		mdp3_clk_set_rate(MDP3_CLK_CORE, MDP_CORE_CLK_RATE);
-		mdp3_clk_set_rate(MDP3_CLK_VSYNC, MDP_VSYNC_CLK_RATE);
+		mdp3_clk_set_rate(MDP3_CLK_CORE, MDP_CORE_CLK_RATE,
+				MDP3_CLIENT_DMA_P);
+		mdp3_clk_set_rate(MDP3_CLK_VSYNC, MDP_VSYNC_CLK_RATE,
+				MDP3_CLIENT_DMA_P);
 
 		rc = mdp3_clk_enable(true);
 		if (rc)
@@ -745,6 +736,9 @@
 			rc = -EFAULT;
 		}
 		break;
+	case MSMFB_ASYNC_BLIT:
+		rc = mdp3_ctrl_async_blit_req(mfd, argp);
+		break;
 	case MSMFB_BLIT:
 		rc = mdp3_ctrl_blit_req(mfd, argp);
 		break;
diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
index 7164086..3f31932 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.c
+++ b/drivers/video/msm/mdss/mdp3_ppp.c
@@ -20,6 +20,8 @@
 #include <linux/uaccess.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
+#include <linux/sync.h>
+#include <linux/sw_sync.h>
 #include "linux/proc_fs.h"
 
 #include "mdss_fb.h"
@@ -28,6 +30,10 @@
 #include "mdp3.h"
 
 #define MDP_IS_IMGTYPE_BAD(x) ((x) >= MDP_IMGTYPE_LIMIT)
+#define MDP_BLIT_CLK_RATE	200000000
+#define MDP_PPP_MAX_BPP 4
+#define MDP_PPP_DYNAMIC_FACTOR 3
+#define MDP_PPP_MAX_READ_WRITE 3
 
 static const bool valid_fmt[MDP_IMGTYPE_LIMIT] = {
 	[MDP_RGB_565] = true,
@@ -47,11 +53,45 @@
 	[MDP_Y_CRCB_H2V1] = true,
 };
 
+#define MAX_LIST_WINDOW 16
+#define MDP3_PPP_MAX_LIST_REQ 8
+
+struct blit_req_list {
+	int count;
+	struct mdp_blit_req req_list[MAX_LIST_WINDOW];
+	struct mdp3_img_data src_data[MAX_LIST_WINDOW];
+	struct mdp3_img_data dst_data[MAX_LIST_WINDOW];
+	struct sync_fence *acq_fen[MDP_MAX_FENCE_FD];
+	u32 acq_fen_cnt;
+	int cur_rel_fen_fd;
+	struct sync_pt *cur_rel_sync_pt;
+	struct sync_fence *cur_rel_fence;
+	struct sync_fence *last_rel_fence;
+};
+
+struct blit_req_queue {
+	struct blit_req_list req[MDP3_PPP_MAX_LIST_REQ];
+	int count;
+	int push_idx;
+	int pop_idx;
+};
+
 struct ppp_status {
 	int busy;
+	bool wait_for_pop;
 	spinlock_t ppp_lock;
 	struct completion ppp_comp;
-	struct mutex config_mutex;
+	struct completion pop_q_comp;
+	struct mutex req_mutex; /* Protect request queue */
+	struct mutex config_ppp_mutex; /* Only one client configure register */
+	struct msm_fb_data_type *mfd;
+
+	struct work_struct blit_work;
+	struct blit_req_queue req_q;
+
+	struct sw_sync_timeline *timeline;
+	int timeline_value;
+
 };
 
 static struct ppp_status *ppp_stat;
@@ -295,24 +335,22 @@
 	mdp3_ppp_pipe_wait();
 }
 
-int mdp3_ppp_turnon(struct ppp_blit_op *blit_op, int on_off)
+int mdp3_ppp_turnon(struct msm_fb_data_type *mfd, int on_off)
 {
-	unsigned long clk_rate = 0, dst_rate = 0, src_rate = 0;
-	int ab = 0;
-	int ib = 0;
-	if (on_off) {
-		dst_rate = blit_op->dst.roi.width * blit_op->dst.roi.height;
-		src_rate = blit_op->src.roi.width * blit_op->src.roi.height;
-		clk_rate = max(dst_rate, src_rate);
-		clk_rate = clk_rate * 36 * 12;
+	struct mdss_panel_info *panel_info = mfd->panel_info;
+	int ab = 0, ib = 0;
+	int rate = 0;
 
-		ab = blit_op->dst.roi.width * blit_op->dst.roi.height *
-			ppp_bpp(blit_op->dst.color_fmt) * 2 +
-			blit_op->src.roi.width * blit_op->src.roi.height *
-			ppp_bpp(blit_op->src.color_fmt);
-		ab = ab * 120;
+	if (on_off) {
+		rate = MDP_BLIT_CLK_RATE;
+		ab = panel_info->xres * panel_info->yres *
+			panel_info->mipi.frame_rate *
+			MDP_PPP_MAX_BPP *
+			MDP_PPP_DYNAMIC_FACTOR *
+			MDP_PPP_MAX_READ_WRITE;
 		ib = (ab * 3) / 2;
 	}
+	mdp3_clk_set_rate(MDP3_CLK_CORE, rate, MDP3_CLIENT_PPP);
 	mdp3_clk_enable(on_off);
 	mdp3_bus_scale_set_quota(MDP3_CLIENT_PPP, ab, ib);
 	return 0;
@@ -322,10 +360,8 @@
 {
 	/* Wait for the pipe to clear */
 	do { } while (mdp3_ppp_pipe_wait() <= 0);
-	mutex_lock(&ppp_stat->config_mutex);
 	config_ppp_op_mode(blit_op);
 	mdp3_ppp_kickoff();
-	mutex_unlock(&ppp_stat->config_mutex);
 }
 
 static void mdp3_ppp_process_req(struct ppp_blit_op *blit_op,
@@ -504,7 +540,7 @@
 	}
 }
 
-static int mdp3_ppp_blit_addr(struct msm_fb_data_type *mfd,
+static int mdp3_ppp_blit(struct msm_fb_data_type *mfd,
 	struct mdp_blit_req *req, struct mdp3_img_data *src_data,
 	struct mdp3_img_data *dst_data)
 {
@@ -524,8 +560,6 @@
 
 	mdp3_ppp_process_req(&blit_op, req, src_data, dst_data);
 
-	mdp3_ppp_turnon(&blit_op, 1);
-
 	if (((blit_op.mdp_op & (MDPOP_TRANSP | MDPOP_ALPHAB)) ||
 	     (req->src.format == MDP_ARGB_8888) ||
 	     (req->src.format == MDP_BGRA_8888) ||
@@ -536,41 +570,13 @@
 		mdp3_start_ppp(&blit_op);
 	}
 
-	/* MDP cmd block disable */
-	mdp3_ppp_turnon(&blit_op, 0);
-
 	return 0;
 }
 
-static int mdp3_ppp_blit(struct msm_fb_data_type *mfd, struct mdp_blit_req *req)
-{
-	struct mdp3_img_data src_data;
-	struct mdp3_img_data dst_data;
-	int rc;
-	mdp3_ppp_iommu_attach();
-
-	mdp3_ppp_get_img(&req->src, req, &src_data);
-	if (src_data.len == 0) {
-		pr_err("mdp_ppp: couldn't retrieve src img from mem\n");
-		return -EINVAL;
-	}
-
-	mdp3_ppp_get_img(&req->dst, req, &dst_data);
-	if (dst_data.len == 0) {
-		mdp3_put_img(&src_data);
-		pr_err("mdp_ppp: couldn't retrieve dest img from mem\n");
-		return -EINVAL;
-	}
-
-	rc = mdp3_ppp_blit_addr(mfd, req, &src_data, &dst_data);
-	mdp3_put_img(&src_data);
-	mdp3_put_img(&dst_data);
-	mdp3_ppp_iommu_dettach();
-	return rc;
-}
-
 static int mdp3_ppp_blit_workaround(struct msm_fb_data_type *mfd,
-		struct mdp_blit_req *req, unsigned int remainder)
+		struct mdp_blit_req *req, unsigned int remainder,
+		struct mdp3_img_data *src_data,
+		struct mdp3_img_data *dst_data)
 {
 	int ret;
 	struct mdp_blit_req splitreq;
@@ -669,7 +675,7 @@
 	}
 
 	/* No need to split in height */
-	ret = mdp3_ppp_blit(mfd, &splitreq);
+	ret = mdp3_ppp_blit(mfd, &splitreq, src_data, dst_data);
 
 	if (ret)
 		return ret;
@@ -698,11 +704,13 @@
 	}
 
 	/* No need to split in height ... just width */
-	return mdp3_ppp_blit(mfd, &splitreq);
+	return mdp3_ppp_blit(mfd, &splitreq, src_data, dst_data);
 }
 
 int mdp3_ppp_start_blit(struct msm_fb_data_type *mfd,
-		struct mdp_blit_req *req)
+		struct mdp_blit_req *req,
+		struct mdp3_img_data *src_data,
+		struct mdp3_img_data *dst_data)
 {
 	int ret;
 	unsigned int remainder = 0, is_bpp_4 = 0;
@@ -742,19 +750,316 @@
 	is_bpp_4 = (ret == 4) ? 1 : 0;
 
 	if ((is_bpp_4 && (remainder == 6 || remainder == 14)))
-		ret = mdp3_ppp_blit_workaround(mfd, req, remainder);
+		ret = mdp3_ppp_blit_workaround(mfd, req, remainder,
+				src_data, dst_data);
 	else
-		ret = mdp3_ppp_blit(mfd, req);
+		ret = mdp3_ppp_blit(mfd, req, src_data, dst_data);
 
+	mdp3_put_img(src_data);
+	mdp3_put_img(dst_data);
 	return ret;
 }
 
-int mdp3_ppp_res_init(void)
+void mdp3_ppp_wait_for_fence(struct blit_req_list *req)
 {
-	ppp_stat = kmalloc(sizeof(struct ppp_status), GFP_KERNEL);
+	int i, ret = 0;
+	/* buf sync */
+	for (i = 0; i < req->acq_fen_cnt; i++) {
+		ret = sync_fence_wait(req->acq_fen[i],
+				WAIT_FENCE_FINAL_TIMEOUT);
+		if (ret < 0) {
+			pr_err("%s: sync_fence_wait failed! ret = %x\n",
+				__func__, ret);
+			break;
+		}
+		sync_fence_put(req->acq_fen[i]);
+	}
+
+	if (ret < 0) {
+		while (i < req->acq_fen_cnt) {
+			sync_fence_put(req->acq_fen[i]);
+			i++;
+		}
+	}
+	req->acq_fen_cnt = 0;
+}
+
+void mdp3_ppp_signal_timeline(struct blit_req_list *req)
+{
+	sw_sync_timeline_inc(ppp_stat->timeline, 1);
+	req->last_rel_fence = req->cur_rel_fence;
+	req->cur_rel_fence = 0;
+}
+
+
+static void mdp3_ppp_deinit_buf_sync(struct blit_req_list *req)
+{
+	int i;
+
+	put_unused_fd(req->cur_rel_fen_fd);
+	sync_fence_put(req->cur_rel_fence);
+	req->cur_rel_fence = NULL;
+	req->cur_rel_fen_fd = 0;
+	ppp_stat->timeline_value--;
+	for (i = 0; i < req->acq_fen_cnt; i++)
+		sync_fence_put(req->acq_fen[i]);
+	req->acq_fen_cnt = 0;
+}
+
+static int mdp3_ppp_handle_buf_sync(struct blit_req_list *req,
+	struct mdp_buf_sync *buf_sync)
+{
+	int i, fence_cnt = 0, ret = 0;
+	int acq_fen_fd[MDP_MAX_FENCE_FD];
+	struct sync_fence *fence;
+
+	if ((buf_sync->acq_fen_fd_cnt > MDP_MAX_FENCE_FD) ||
+		(ppp_stat->timeline == NULL))
+		return -EINVAL;
+
+	if (buf_sync->acq_fen_fd_cnt)
+		ret = copy_from_user(acq_fen_fd, buf_sync->acq_fen_fd,
+				buf_sync->acq_fen_fd_cnt * sizeof(int));
+	if (ret) {
+		pr_err("%s: copy_from_user failed\n", __func__);
+		return ret;
+	}
+	for (i = 0; i < buf_sync->acq_fen_fd_cnt; i++) {
+		fence = sync_fence_fdget(acq_fen_fd[i]);
+		if (fence == NULL) {
+			pr_info("%s: null fence! i=%d fd=%d\n", __func__, i,
+				acq_fen_fd[i]);
+			ret = -EINVAL;
+			break;
+		}
+		req->acq_fen[i] = fence;
+	}
+	fence_cnt = i;
+	if (ret)
+		goto buf_sync_err_1;
+	req->acq_fen_cnt = fence_cnt;
+	if (buf_sync->flags & MDP_BUF_SYNC_FLAG_WAIT)
+		mdp3_ppp_wait_for_fence(req);
+
+	req->cur_rel_sync_pt = sw_sync_pt_create(ppp_stat->timeline,
+			ppp_stat->timeline_value++);
+	if (req->cur_rel_sync_pt == NULL) {
+		pr_err("%s: cannot create sync point\n", __func__);
+		ret = -ENOMEM;
+		goto buf_sync_err_2;
+	}
+	/* create fence */
+	req->cur_rel_fence = sync_fence_create("ppp-fence",
+			req->cur_rel_sync_pt);
+	if (req->cur_rel_fence == NULL) {
+		sync_pt_free(req->cur_rel_sync_pt);
+		req->cur_rel_sync_pt = NULL;
+		pr_err("%s: cannot create fence\n", __func__);
+		ret = -ENOMEM;
+		goto buf_sync_err_2;
+	}
+	/* create fd */
+	return ret;
+buf_sync_err_2:
+	ppp_stat->timeline_value--;
+buf_sync_err_1:
+	for (i = 0; i < fence_cnt; i++)
+		sync_fence_put(req->acq_fen[i]);
+	req->acq_fen_cnt = 0;
+	return ret;
+}
+
+void mdp3_ppp_req_push(struct blit_req_queue *req_q, struct blit_req_list *req)
+{
+	int idx = req_q->push_idx;
+	req_q->req[idx] = *req;
+	req_q->count++;
+	req_q->push_idx = (req_q->push_idx + 1) % MDP3_PPP_MAX_LIST_REQ;
+}
+
+struct blit_req_list *mdp3_ppp_next_req(struct blit_req_queue *req_q)
+{
+	struct blit_req_list *req;
+	if (req_q->count == 0)
+		return NULL;
+	req = &req_q->req[req_q->pop_idx];
+	return req;
+}
+
+void mdp3_ppp_req_pop(struct blit_req_queue *req_q)
+{
+	req_q->count--;
+	req_q->pop_idx = (req_q->pop_idx + 1) % MDP3_PPP_MAX_LIST_REQ;
+}
+
+static void mdp3_ppp_blit_wq_handler(struct work_struct *work)
+{
+	struct msm_fb_data_type *mfd = ppp_stat->mfd;
+	struct blit_req_list *req;
+	int i, rc;
+
+	req = mdp3_ppp_next_req(&ppp_stat->req_q);
+	mutex_lock(&ppp_stat->config_ppp_mutex);
+
+	mdp3_ppp_iommu_attach();
+	mdp3_ppp_turnon(mfd, 1);
+	while (req) {
+		mdp3_ppp_wait_for_fence(req);
+		for (i = 0; i < req->count; i++) {
+			if (!(req->req_list[i].flags & MDP_NO_BLIT)) {
+				/* Do the actual blit. */
+				rc = mdp3_ppp_start_blit(mfd,
+						&(req->req_list[i]),
+						&req->src_data[i],
+						&req->dst_data[i]);
+				if (rc)
+					break;
+			}
+		}
+		/* Signal to release fence */
+		mutex_lock(&ppp_stat->req_mutex);
+		mdp3_ppp_signal_timeline(req);
+		mdp3_ppp_req_pop(&ppp_stat->req_q);
+		req = mdp3_ppp_next_req(&ppp_stat->req_q);
+		if (ppp_stat->wait_for_pop)
+			complete(&ppp_stat->pop_q_comp);
+		mutex_unlock(&ppp_stat->req_mutex);
+	}
+	mdp3_ppp_turnon(mfd, 0);
+	mdp3_ppp_iommu_dettach();
+	mutex_unlock(&ppp_stat->config_ppp_mutex);
+}
+
+int mdp3_ppp_parse_req(void __user *p,
+	struct mdp_async_blit_req_list *req_list_header,
+	int async)
+{
+	struct blit_req_list *req;
+	struct blit_req_queue *req_q = &ppp_stat->req_q;
+	struct sync_fence *fence = NULL;
+	int count, rc, idx, i;
+	count = req_list_header->count;
+
+	mutex_lock(&ppp_stat->req_mutex);
+	while (req_q->count >= MDP3_PPP_MAX_LIST_REQ) {
+		ppp_stat->wait_for_pop = true;
+		mutex_unlock(&ppp_stat->req_mutex);
+		rc = wait_for_completion_interruptible_timeout(
+		   &ppp_stat->pop_q_comp, 5 * HZ);
+		if (rc == 0) {
+			/* This will only occur if there is serious problem */
+			pr_err("%s: timeout exiting queuing request\n",
+				   __func__);
+			return -EBUSY;
+		}
+		mutex_lock(&ppp_stat->req_mutex);
+		ppp_stat->wait_for_pop = false;
+	}
+	idx = req_q->push_idx;
+	req = &req_q->req[idx];
+
+	if (copy_from_user(&req->req_list, p,
+			sizeof(struct mdp_blit_req) * count))
+		return -EFAULT;
+
+	rc = mdp3_ppp_handle_buf_sync(req, &req_list_header->sync);
+	if (rc < 0) {
+		pr_err("%s: Failed create sync point\n", __func__);
+		return rc;
+	}
+	req->count = count;
+
+	/* We need to grab ion handle while client thread */
+	for (i = 0; i < count; i++) {
+		rc = mdp3_ppp_get_img(&req->req_list[i].src,
+				&req->req_list[i], &req->src_data[i]);
+		if (rc < 0 || req->src_data[i].len == 0) {
+			pr_err("mdp_ppp: couldn't retrieve src img from mem\n");
+			goto parse_err_1;
+		}
+
+		rc = mdp3_ppp_get_img(&req->req_list[i].dst,
+				&req->req_list[i], &req->dst_data[i]);
+		if (rc < 0 || req->dst_data[i].len == 0) {
+			mdp3_put_img(&req->src_data[i]);
+			pr_err("mdp_ppp: couldn't retrieve dest img from mem\n");
+			goto parse_err_1;
+		}
+	}
+
+	if (async) {
+		req->cur_rel_fen_fd = get_unused_fd_flags(0);
+		if (req->cur_rel_fen_fd < 0) {
+			pr_err("%s: get_unused_fd_flags failed\n", __func__);
+			rc  = -ENOMEM;
+			goto parse_err_2;
+		}
+		sync_fence_install(req->cur_rel_fence, req->cur_rel_fen_fd);
+		rc = copy_to_user(req_list_header->sync.rel_fen_fd,
+			&req->cur_rel_fen_fd, sizeof(int));
+		if (rc) {
+			pr_err("%s:copy_to_user failed\n", __func__);
+			goto parse_err_3;
+		}
+	} else {
+		fence = req->cur_rel_fence;
+	}
+
+	mdp3_ppp_req_push(req_q, req);
+	mutex_unlock(&ppp_stat->req_mutex);
+	schedule_work(&ppp_stat->blit_work);
+	if (!async) {
+		/* wait for release fence */
+		rc = sync_fence_wait(fence,
+				5 * MSEC_PER_SEC);
+		if (rc < 0)
+			pr_err("%s: sync blit! rc = %x\n", __func__, rc);
+
+		sync_fence_put(fence);
+		fence = NULL;
+	}
+	return 0;
+
+parse_err_3:
+	put_unused_fd(req->cur_rel_fen_fd);
+parse_err_2:
+	sync_fence_put(req->cur_rel_fence);
+	req->cur_rel_fence = NULL;
+	req->cur_rel_fen_fd = 0;
+parse_err_1:
+	for (i--; i >= 0; i--) {
+		mdp3_put_img(&req->src_data[i]);
+		mdp3_put_img(&req->dst_data[i]);
+	}
+	mdp3_ppp_deinit_buf_sync(req);
+	return rc;
+}
+
+int mdp3_ppp_res_init(struct msm_fb_data_type *mfd)
+{
+	const char timeline_name[] = "mdp3_ppp";
+	ppp_stat = kzalloc(sizeof(struct ppp_status), GFP_KERNEL);
+	if (!ppp_stat) {
+		pr_err("%s: kmalloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	/*Setup sync_pt timeline for ppp*/
+	ppp_stat->timeline = sw_sync_timeline_create(timeline_name);
+	if (ppp_stat->timeline == NULL) {
+		pr_err("%s: cannot create time line\n", __func__);
+		return -ENOMEM;
+	} else {
+		ppp_stat->timeline_value = 1;
+	}
+
+	INIT_WORK(&ppp_stat->blit_work, mdp3_ppp_blit_wq_handler);
+	init_completion(&ppp_stat->pop_q_comp);
 	spin_lock_init(&ppp_stat->ppp_lock);
-	mutex_init(&ppp_stat->config_mutex);
+	mutex_init(&ppp_stat->req_mutex);
+	mutex_init(&ppp_stat->config_ppp_mutex);
 	ppp_stat->busy = false;
+	ppp_stat->mfd = mfd;
 	mdp3_ppp_callback_setup();
 	return 0;
 }
diff --git a/drivers/video/msm/mdss/mdp3_ppp.h b/drivers/video/msm/mdss/mdp3_ppp.h
index afac419..b4252ca 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.h
+++ b/drivers/video/msm/mdss/mdp3_ppp.h
@@ -18,7 +18,7 @@
 
 #define PPP_WRITEL(val, off) MDP3_REG_WRITE(off, val)
 
-#define MAX_BLIT_REQ 256
+#define MAX_BLIT_REQ 16
 #define PPP_UPSCALE_MAX 64
 #define PPP_BLUR_SCALE_MAX 128
 #define PPP_LUT_MAX 256
@@ -403,11 +403,12 @@
 void ppp_load_x_scale_table(int idx);
 void ppp_load_y_scale_table(int idx);
 
-int mdp3_ppp_start_blit(struct msm_fb_data_type *mfd,
-	struct mdp_blit_req *req);
-int mdp3_ppp_res_init(void);
+int mdp3_ppp_res_init(struct msm_fb_data_type *mfd);
 int mdp3_ppp_init(void);
 int config_ppp_op_mode(struct ppp_blit_op *blit_op);
 void ppp_enable(void);
+int mdp3_ppp_parse_req(void __user *p,
+	struct mdp_async_blit_req_list *req_list_header,
+	int async);
 
 #endif
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 58fb5c1..6d41c13 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -78,6 +78,7 @@
 #define MSMFB_METADATA_GET  _IOW(MSMFB_IOCTL_MAGIC, 166, struct msmfb_metadata)
 #define MSMFB_WRITEBACK_SET_MIRRORING_HINT _IOW(MSMFB_IOCTL_MAGIC, 167, \
 						unsigned int)
+#define MSMFB_ASYNC_BLIT              _IOW(MSMFB_IOCTL_MAGIC, 168, unsigned int)
 
 #define FB_TYPE_3D_PANEL 0x10101010
 #define MDP_IMGTYPE2_START 0x10000
@@ -766,6 +767,12 @@
 	int *rel_fen_fd;
 };
 
+struct mdp_async_blit_req_list {
+	struct mdp_buf_sync sync;
+	uint32_t count;
+	struct mdp_blit_req req[];
+};
+
 #define MDP_DISPLAY_COMMIT_OVERLAY	1
 struct mdp_buf_fence {
 	uint32_t flags;
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index 25d937a..e8e932e 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -54,6 +54,7 @@
 struct spmi_controller {
 	struct device		dev;
 	unsigned int		nr;
+	struct completion	dev_released;
 	int		(*cmd)(struct spmi_controller *, u8 opcode, u8 sid);
 	int		(*read_cmd)(struct spmi_controller *,
 				u8 opcode, u8 sid, u16 addr, u8 bc, u8 *buf);