diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index dc79465c8f0eee08d297995876062c67b525c360..976590875ee759899810bb9a762f00bb5062b22d 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -91,7 +91,7 @@ static void vsync_irq_disable(int intr, int term)
static int mdp4_overlay_writeback_update(struct msm_fb_data_type *mfd);
static void mdp4_wfd_queue_wakeup(struct msm_fb_data_type *mfd,
struct msmfb_writeback_data_list *node);
-static void mdp4_wfd_dequeue_update(struct msm_fb_data_type *mfd,
+static int mdp4_wfd_dequeue_update(struct msm_fb_data_type *mfd,
struct msmfb_writeback_data_list **wfdnode);
int mdp4_overlay_writeback_on(struct platform_device *pdev)
@@ -363,6 +363,7 @@ int mdp4_wfd_pipe_commit(struct msm_fb_data_type *mfd,
unsigned long flags;
int cnt = 0;
struct msmfb_writeback_data_list *node = NULL;
+ int rc = 0;
vctrl = &vsync_ctrl_db[cndx];
@@ -383,8 +384,18 @@ int mdp4_wfd_pipe_commit(struct msm_fb_data_type *mfd,
vp->update_cnt = 0; /* reset */
mutex_unlock(&vctrl->update_lock);
- mdp4_wfd_dequeue_update(mfd, &node);
-
+ rc = mdp4_wfd_dequeue_update(mfd, &node);
+ if (rc != 0) {
+ pr_err("%s: mdp4_wfd_dequeue_update failed !! mfd=%x\n",
+ __func__, (int)mfd);
+ pipe = vp->plist;
+ for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+ pipe->pipe_used = 0;
+ pr_info("%s: dequeue update failed, unsetting pipes\n",
+ __func__);
+ }
+ return cnt;
+ }
/* free previous committed iommu back to pool */
mdp4_overlay_iommu_unmap_freelist(mixer);
@@ -774,7 +785,7 @@ terminate_err:
return rc;
}
-static void mdp4_wfd_dequeue_update(struct msm_fb_data_type *mfd,
+static int mdp4_wfd_dequeue_update(struct msm_fb_data_type *mfd,
struct msmfb_writeback_data_list **wfdnode)
{
struct vsycn_ctrl *vctrl;
@@ -782,7 +793,7 @@ static void mdp4_wfd_dequeue_update(struct msm_fb_data_type *mfd,
struct msmfb_writeback_data_list *node = NULL;
if (mfd && !mfd->panel_power_on)
- return;
+ return -EPERM;
pr_debug("%s:+ mfd=%x\n", __func__, (int)mfd);
@@ -809,8 +820,18 @@ static void mdp4_wfd_dequeue_update(struct msm_fb_data_type *mfd,
if (!pipe->ov_blt_addr) {
pr_err("%s: no writeback buffer 0x%x, %p\n", __func__,
(unsigned int)pipe->ov_blt_addr, node);
+
+ if (node) {
+ mutex_lock(&mfd->writeback_mutex);
+ list_add_tail(&node->active_entry,
+ &mfd->writeback_free_queue);
+ node->state = IN_FREE_QUEUE;
+ mfd->writeback_active_cnt--;
+ mutex_unlock(&mfd->writeback_mutex);
+ }
+
mutex_unlock(&mfd->unregister_mutex);
- return;
+ return -EINVAL;
}
mdp4_overlay_writeback_update(mfd);
@@ -818,6 +839,7 @@ static void mdp4_wfd_dequeue_update(struct msm_fb_data_type *mfd,
*wfdnode = node;
mutex_unlock(&mfd->unregister_mutex);
+ return 0;
}
static void mdp4_wfd_queue_wakeup(struct msm_fb_data_type *mfd,