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,