Loading drivers/video/msm/mdss/mdss_fb.c +85 −22 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ static int __mdss_fb_sync_buf_done_callback(struct notifier_block *p, unsigned long val, void *data); static int __mdss_fb_display_thread(void *data); static void mdss_fb_pan_idle(struct msm_fb_data_type *mfd); static int mdss_fb_pan_idle(struct msm_fb_data_type *mfd); static int mdss_fb_send_panel_event(struct msm_fb_data_type *mfd, int event, void *arg); void mdss_fb_no_update_notify_timer_cb(unsigned long data) Loading Loading @@ -299,6 +299,7 @@ static void mdss_fb_shutdown(struct platform_device *pdev) { struct msm_fb_data_type *mfd = platform_get_drvdata(pdev); mfd->shutdown_pending = true; lock_fb_info(mfd->fbi); mdss_fb_release_all(mfd->fbi, true); unlock_fb_info(mfd->fbi); Loading Loading @@ -781,13 +782,18 @@ static int mdss_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); unsigned long off = vma->vm_pgoff << PAGE_SHIFT; struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; int ret = 0; if (!start) { pr_warn("No framebuffer memory is allocated.\n"); return -ENOMEM; } mdss_fb_pan_idle(mfd); ret = mdss_fb_pan_idle(mfd); if (ret) { pr_err("Shutdown pending. Aborting operation\n"); return ret; } /* Set VM flags. */ start &= PAGE_MASK; Loading Loading @@ -1144,13 +1150,6 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd) mfd->index, fbi->var.xres, fbi->var.yres, fbi->fix.smem_len); mfd->disp_thread = kthread_run(__mdss_fb_display_thread, mfd, "mdss_fb%d", mfd->index); if (IS_ERR(mfd->disp_thread)) { pr_err("unable to start display thread %d\n", mfd->index); return PTR_ERR(mfd->disp_thread); } return 0; } Loading @@ -1161,6 +1160,11 @@ static int mdss_fb_open(struct fb_info *info, int user) int result; int pid = current->tgid; if (mfd->shutdown_pending) { pr_err("Shutdown pending. Aborting operation\n"); return -EPERM; } list_for_each_entry(pinfo, &mfd->proc_list, list) { if (pinfo->pid == pid) break; Loading @@ -1180,23 +1184,47 @@ static int mdss_fb_open(struct fb_info *info, int user) result = pm_runtime_get_sync(info->dev); if (result < 0) if (result < 0) { pr_err("pm_runtime: fail to wake up\n"); goto pm_error; } if (!mfd->ref_cnt) { mfd->disp_thread = kthread_run(__mdss_fb_display_thread, mfd, "mdss_fb%d", mfd->index); if (IS_ERR(mfd->disp_thread)) { pr_err("unable to start display thread %d\n", mfd->index); result = PTR_ERR(mfd->disp_thread); goto thread_error; } result = mdss_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable); if (result) { pm_runtime_put(info->dev); pr_err("can't turn on fb%d! rc=%d\n", mfd->index, result); return result; goto blank_error; } } pinfo->ref_cnt++; mfd->ref_cnt++; return 0; blank_error: kthread_stop(mfd->disp_thread); thread_error: if (pinfo && !pinfo->ref_cnt) { list_del(&pinfo->list); kfree(pinfo); } pm_runtime_put(info->dev); pm_error: return result; } static int mdss_fb_release_all(struct fb_info *info, bool release_all) Loading Loading @@ -1238,6 +1266,9 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all) pm_runtime_put(info->dev); } while (release_all && pinfo->ref_cnt); if (release_all) kthread_stop(mfd->disp_thread); if (pinfo->ref_cnt == 0) { list_del(&pinfo->list); kfree(pinfo); Loading Loading @@ -1274,6 +1305,8 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all) } if (!mfd->ref_cnt) { kthread_stop(mfd->disp_thread); ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable); if (ret) { Loading Loading @@ -1452,21 +1485,28 @@ static int __mdss_fb_sync_buf_done_callback(struct notifier_block *p, * hardware configuration. After this function returns it is safe to perform * software updates for next frame. */ static void mdss_fb_pan_idle(struct msm_fb_data_type *mfd) static int mdss_fb_pan_idle(struct msm_fb_data_type *mfd) { int ret; int ret = 0; ret = wait_event_timeout(mfd->idle_wait_q, !atomic_read(&mfd->commits_pending), (!atomic_read(&mfd->commits_pending) || mfd->shutdown_pending), msecs_to_jiffies(WAIT_DISP_OP_TIMEOUT)); if (!ret) { pr_err("wait for idle timeout %d pending=%d\n", ret, atomic_read(&mfd->commits_pending)); mdss_fb_signal_timeline(&mfd->mdp_sync_pt_data); } else if (mfd->shutdown_pending) { pr_debug("Shutdown signalled\n"); return -EPERM; } return 0; } static int mdss_fb_pan_display_ex(struct fb_info *info, struct mdp_display_commit *disp_commit) { Loading @@ -1484,7 +1524,11 @@ static int mdss_fb_pan_display_ex(struct fb_info *info, if (var->yoffset > (info->var.yres_virtual - info->var.yres)) return -EINVAL; mdss_fb_pan_idle(mfd); ret = mdss_fb_pan_idle(mfd); if (ret) { pr_err("Shutdown pending. Aborting operation\n"); return ret; } mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex); if (info->fix.xpanstep) Loading Loading @@ -1621,14 +1665,20 @@ static int __mdss_fb_display_thread(void *data) while (1) { wait_event(mfd->commit_wait_q, atomic_read(&mfd->commits_pending)); (atomic_read(&mfd->commits_pending) || kthread_should_stop())); ret = __mdss_fb_perform_commit(mfd); if (kthread_should_stop()) break; ret = __mdss_fb_perform_commit(mfd); atomic_dec(&mfd->commits_pending); wake_up_all(&mfd->idle_wait_q); } atomic_set(&mfd->commits_pending, 0); wake_up_all(&mfd->idle_wait_q); return ret; } Loading Loading @@ -1752,8 +1802,14 @@ static int mdss_fb_set_par(struct fb_info *info) struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; struct fb_var_screeninfo *var = &info->var; int old_imgType; int ret = 0; ret = mdss_fb_pan_idle(mfd); if (ret) { pr_err("Shutdown pending. Aborting operation\n"); return ret; } mdss_fb_pan_idle(mfd); old_imgType = mfd->fb_imgType; switch (var->bits_per_pixel) { case 16: Loading Loading @@ -1813,7 +1869,7 @@ static int mdss_fb_set_par(struct fb_info *info) mfd->panel_reconfig = false; } return 0; return ret; } int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state) Loading Loading @@ -2052,8 +2108,15 @@ static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd, mfd = (struct msm_fb_data_type *)info->par; mdss_fb_power_setting_idle(mfd); if ((cmd != MSMFB_VSYNC_CTRL) && (cmd != MSMFB_OVERLAY_VSYNC_CTRL) && (cmd != MSMFB_ASYNC_BLIT) && (cmd != MSMFB_BLIT)) mdss_fb_pan_idle(mfd); (cmd != MSMFB_ASYNC_BLIT) && (cmd != MSMFB_BLIT) && (cmd != MSMFB_NOTIFY_UPDATE)) { ret = mdss_fb_pan_idle(mfd); if (ret) { pr_debug("Shutdown pending. Aborting operation %x\n", cmd); return ret; } } switch (cmd) { case MSMFB_CURSOR: Loading drivers/video/msm/mdss/mdss_fb.h +1 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,7 @@ struct msm_fb_data_type { atomic_t commits_pending; wait_queue_head_t commit_wait_q; wait_queue_head_t idle_wait_q; bool shutdown_pending; struct msm_fb_backup_type msm_fb_backup; struct completion power_set_comp; Loading Loading
drivers/video/msm/mdss/mdss_fb.c +85 −22 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ static int __mdss_fb_sync_buf_done_callback(struct notifier_block *p, unsigned long val, void *data); static int __mdss_fb_display_thread(void *data); static void mdss_fb_pan_idle(struct msm_fb_data_type *mfd); static int mdss_fb_pan_idle(struct msm_fb_data_type *mfd); static int mdss_fb_send_panel_event(struct msm_fb_data_type *mfd, int event, void *arg); void mdss_fb_no_update_notify_timer_cb(unsigned long data) Loading Loading @@ -299,6 +299,7 @@ static void mdss_fb_shutdown(struct platform_device *pdev) { struct msm_fb_data_type *mfd = platform_get_drvdata(pdev); mfd->shutdown_pending = true; lock_fb_info(mfd->fbi); mdss_fb_release_all(mfd->fbi, true); unlock_fb_info(mfd->fbi); Loading Loading @@ -781,13 +782,18 @@ static int mdss_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); unsigned long off = vma->vm_pgoff << PAGE_SHIFT; struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; int ret = 0; if (!start) { pr_warn("No framebuffer memory is allocated.\n"); return -ENOMEM; } mdss_fb_pan_idle(mfd); ret = mdss_fb_pan_idle(mfd); if (ret) { pr_err("Shutdown pending. Aborting operation\n"); return ret; } /* Set VM flags. */ start &= PAGE_MASK; Loading Loading @@ -1144,13 +1150,6 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd) mfd->index, fbi->var.xres, fbi->var.yres, fbi->fix.smem_len); mfd->disp_thread = kthread_run(__mdss_fb_display_thread, mfd, "mdss_fb%d", mfd->index); if (IS_ERR(mfd->disp_thread)) { pr_err("unable to start display thread %d\n", mfd->index); return PTR_ERR(mfd->disp_thread); } return 0; } Loading @@ -1161,6 +1160,11 @@ static int mdss_fb_open(struct fb_info *info, int user) int result; int pid = current->tgid; if (mfd->shutdown_pending) { pr_err("Shutdown pending. Aborting operation\n"); return -EPERM; } list_for_each_entry(pinfo, &mfd->proc_list, list) { if (pinfo->pid == pid) break; Loading @@ -1180,23 +1184,47 @@ static int mdss_fb_open(struct fb_info *info, int user) result = pm_runtime_get_sync(info->dev); if (result < 0) if (result < 0) { pr_err("pm_runtime: fail to wake up\n"); goto pm_error; } if (!mfd->ref_cnt) { mfd->disp_thread = kthread_run(__mdss_fb_display_thread, mfd, "mdss_fb%d", mfd->index); if (IS_ERR(mfd->disp_thread)) { pr_err("unable to start display thread %d\n", mfd->index); result = PTR_ERR(mfd->disp_thread); goto thread_error; } result = mdss_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable); if (result) { pm_runtime_put(info->dev); pr_err("can't turn on fb%d! rc=%d\n", mfd->index, result); return result; goto blank_error; } } pinfo->ref_cnt++; mfd->ref_cnt++; return 0; blank_error: kthread_stop(mfd->disp_thread); thread_error: if (pinfo && !pinfo->ref_cnt) { list_del(&pinfo->list); kfree(pinfo); } pm_runtime_put(info->dev); pm_error: return result; } static int mdss_fb_release_all(struct fb_info *info, bool release_all) Loading Loading @@ -1238,6 +1266,9 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all) pm_runtime_put(info->dev); } while (release_all && pinfo->ref_cnt); if (release_all) kthread_stop(mfd->disp_thread); if (pinfo->ref_cnt == 0) { list_del(&pinfo->list); kfree(pinfo); Loading Loading @@ -1274,6 +1305,8 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all) } if (!mfd->ref_cnt) { kthread_stop(mfd->disp_thread); ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable); if (ret) { Loading Loading @@ -1452,21 +1485,28 @@ static int __mdss_fb_sync_buf_done_callback(struct notifier_block *p, * hardware configuration. After this function returns it is safe to perform * software updates for next frame. */ static void mdss_fb_pan_idle(struct msm_fb_data_type *mfd) static int mdss_fb_pan_idle(struct msm_fb_data_type *mfd) { int ret; int ret = 0; ret = wait_event_timeout(mfd->idle_wait_q, !atomic_read(&mfd->commits_pending), (!atomic_read(&mfd->commits_pending) || mfd->shutdown_pending), msecs_to_jiffies(WAIT_DISP_OP_TIMEOUT)); if (!ret) { pr_err("wait for idle timeout %d pending=%d\n", ret, atomic_read(&mfd->commits_pending)); mdss_fb_signal_timeline(&mfd->mdp_sync_pt_data); } else if (mfd->shutdown_pending) { pr_debug("Shutdown signalled\n"); return -EPERM; } return 0; } static int mdss_fb_pan_display_ex(struct fb_info *info, struct mdp_display_commit *disp_commit) { Loading @@ -1484,7 +1524,11 @@ static int mdss_fb_pan_display_ex(struct fb_info *info, if (var->yoffset > (info->var.yres_virtual - info->var.yres)) return -EINVAL; mdss_fb_pan_idle(mfd); ret = mdss_fb_pan_idle(mfd); if (ret) { pr_err("Shutdown pending. Aborting operation\n"); return ret; } mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex); if (info->fix.xpanstep) Loading Loading @@ -1621,14 +1665,20 @@ static int __mdss_fb_display_thread(void *data) while (1) { wait_event(mfd->commit_wait_q, atomic_read(&mfd->commits_pending)); (atomic_read(&mfd->commits_pending) || kthread_should_stop())); ret = __mdss_fb_perform_commit(mfd); if (kthread_should_stop()) break; ret = __mdss_fb_perform_commit(mfd); atomic_dec(&mfd->commits_pending); wake_up_all(&mfd->idle_wait_q); } atomic_set(&mfd->commits_pending, 0); wake_up_all(&mfd->idle_wait_q); return ret; } Loading Loading @@ -1752,8 +1802,14 @@ static int mdss_fb_set_par(struct fb_info *info) struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; struct fb_var_screeninfo *var = &info->var; int old_imgType; int ret = 0; ret = mdss_fb_pan_idle(mfd); if (ret) { pr_err("Shutdown pending. Aborting operation\n"); return ret; } mdss_fb_pan_idle(mfd); old_imgType = mfd->fb_imgType; switch (var->bits_per_pixel) { case 16: Loading Loading @@ -1813,7 +1869,7 @@ static int mdss_fb_set_par(struct fb_info *info) mfd->panel_reconfig = false; } return 0; return ret; } int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state) Loading Loading @@ -2052,8 +2108,15 @@ static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd, mfd = (struct msm_fb_data_type *)info->par; mdss_fb_power_setting_idle(mfd); if ((cmd != MSMFB_VSYNC_CTRL) && (cmd != MSMFB_OVERLAY_VSYNC_CTRL) && (cmd != MSMFB_ASYNC_BLIT) && (cmd != MSMFB_BLIT)) mdss_fb_pan_idle(mfd); (cmd != MSMFB_ASYNC_BLIT) && (cmd != MSMFB_BLIT) && (cmd != MSMFB_NOTIFY_UPDATE)) { ret = mdss_fb_pan_idle(mfd); if (ret) { pr_debug("Shutdown pending. Aborting operation %x\n", cmd); return ret; } } switch (cmd) { case MSMFB_CURSOR: Loading
drivers/video/msm/mdss/mdss_fb.h +1 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,7 @@ struct msm_fb_data_type { atomic_t commits_pending; wait_queue_head_t commit_wait_q; wait_queue_head_t idle_wait_q; bool shutdown_pending; struct msm_fb_backup_type msm_fb_backup; struct completion power_set_comp; Loading