Loading drivers/video/fbdev/core/fbmem.c +3 −0 Original line number Diff line number Diff line Loading @@ -1227,6 +1227,9 @@ static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (!info) return -ENODEV; mutex_lock(&info->lock); info->file = file; mutex_unlock(&info->lock); return do_fb_ioctl(info, cmd, arg); } Loading drivers/video/msm/mdss/mdss_fb.c +35 −164 Original line number Diff line number Diff line Loading @@ -877,7 +877,7 @@ static int mdss_fb_probe(struct platform_device *pdev) &(mfd->boot_notification_led)); } INIT_LIST_HEAD(&mfd->proc_list); INIT_LIST_HEAD(&mfd->file_list); mutex_init(&mfd->bl_lock); mutex_init(&mfd->switch_lock); Loading Loading @@ -2272,80 +2272,16 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd) return 0; } /** * mdss_fb_release_file_entry() - Releases file node entry from list * @info: Frame buffer info * @pinfo: Process list node in which file node entry is going to * be removed * @release_all: Releases all file node entries from list if this parameter * is true * * This function is called to remove the file node entry/entries from main * list. It also helps to find the process id if fb_open and fb_close * callers are different. */ static struct mdss_fb_proc_info *mdss_fb_release_file_entry( struct fb_info *info, struct mdss_fb_proc_info *pinfo, bool release_all) { struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; struct mdss_fb_file_info *file_info = NULL, *temp_file_info = NULL; struct mdss_fb_proc_info *proc_info = NULL, *temp_proc_info = NULL; struct file *file = info->file; bool node_found = false; if (!pinfo && release_all) { pr_err("process node not provided for release all case\n"); goto end; } if (pinfo) { proc_info = pinfo; list_for_each_entry_safe(file_info, temp_file_info, &pinfo->file_list, list) { if (!release_all && file_info->file != file) continue; list_del(&file_info->list); kfree(file_info); node_found = true; if (!release_all) break; } } if (!node_found) { list_for_each_entry_safe(proc_info, temp_proc_info, &mfd->proc_list, list) { list_for_each_entry_safe(file_info, temp_file_info, &proc_info->file_list, list) { if (file_info->file == file) { list_del(&file_info->list); kfree(file_info); goto end; } } } } end: return proc_info; } static int mdss_fb_open(struct fb_info *info, int user) { struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; struct mdss_fb_proc_info *pinfo = NULL; struct mdss_fb_file_info *file_info = NULL; int result; int pid = current->tgid; struct task_struct *task = current->group_leader; if (mfd->shutdown_pending) { pr_err_once("Shutdown pending. Aborting operation. Request from pid:%d name=%s\n", pid, task->comm); current->tgid, task->comm); sysfs_notify(&mfd->fbi->dev->kobj, NULL, "show_blank_event"); return -ESHUTDOWN; } Loading @@ -2356,27 +2292,8 @@ static int mdss_fb_open(struct fb_info *info, int user) return -ENOMEM; } list_for_each_entry(pinfo, &mfd->proc_list, list) { if (pinfo->pid == pid) break; } if ((pinfo == NULL) || (pinfo->pid != pid)) { pinfo = kmalloc(sizeof(*pinfo), GFP_KERNEL); if (!pinfo) { pr_err("unable to alloc process info\n"); kfree(file_info); return -ENOMEM; } pinfo->pid = pid; pinfo->ref_cnt = 0; list_add(&pinfo->list, &mfd->proc_list); INIT_LIST_HEAD(&pinfo->file_list); pr_debug("new process entry pid=%d\n", pinfo->pid); } file_info->file = info->file; list_add(&file_info->list, &pinfo->file_list); list_add(&file_info->list, &mfd->file_list); result = pm_runtime_get_sync(info->dev); Loading @@ -2395,37 +2312,31 @@ static int mdss_fb_open(struct fb_info *info, int user) } } pinfo->ref_cnt++; mfd->ref_cnt++; pr_debug("mfd refcount:%d file:%p\n", mfd->ref_cnt, info->file); return 0; blank_error: pm_runtime_put(info->dev); pm_error: list_del(&file_info->list); kfree(file_info); if (pinfo && !pinfo->ref_cnt) { list_del(&pinfo->list); kfree(pinfo); } return result; } static int mdss_fb_release_all(struct fb_info *info, bool release_all) { struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; struct mdss_fb_proc_info *pinfo = NULL, *temp_pinfo = NULL; struct mdss_fb_proc_info *proc_info = NULL; struct mdss_fb_file_info *file_info = NULL, *temp_file_info = NULL; struct file *file = info->file; int ret = 0; int pid = current->tgid; bool unknown_pid = true, release_needed = false; bool node_found = false; struct task_struct *task = current->group_leader; if (!mfd->ref_cnt) { pr_info("try to close unopened fb %d! from pid:%d name:%s\n", mfd->index, pid, task->comm); mfd->index, current->tgid, task->comm); return -EINVAL; } Loading @@ -2445,96 +2356,55 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all) pr_debug("release_all = %s\n", release_all ? "true" : "false"); list_for_each_entry_safe(pinfo, temp_pinfo, &mfd->proc_list, list) { if (!release_all && (pinfo->pid != pid)) list_for_each_entry_safe(file_info, temp_file_info, &mfd->file_list, list) { if (!release_all && file_info->file != file) continue; unknown_pid = false; pr_debug("found process %s pid=%d mfd->ref=%d pinfo->ref=%d\n", task->comm, pinfo->pid, mfd->ref_cnt, pinfo->ref_cnt); proc_info = mdss_fb_release_file_entry(info, pinfo, release_all); /* * if fb_release is called from different known process then * release the ref_count of original proc_info instead of * current process. */ if (!release_all && proc_info && proc_info != pinfo) { pr_info("fb_release called from different process for current file node\n"); pinfo = proc_info; } pr_debug("found file node mfd->ref=%d\n", mfd->ref_cnt); list_del(&file_info->list); kfree(file_info); do { if (mfd->ref_cnt < pinfo->ref_cnt) pr_warn("WARN:mfd->ref=%d < pinfo->ref=%d\n", mfd->ref_cnt, pinfo->ref_cnt); else mfd->ref_cnt--; pinfo->ref_cnt--; pm_runtime_put(info->dev); } while (release_all && pinfo->ref_cnt); if (pinfo->ref_cnt == 0) { list_del(&pinfo->list); kfree(pinfo); release_needed = !release_all; } node_found = true; if (!release_all) break; } if (unknown_pid) { pinfo = mdss_fb_release_file_entry(info, NULL, false); if (pinfo) { pr_debug("found known pid=%d reference for unknown caller pid=%d\n", pinfo->pid, pid); pid = pinfo->pid; mfd->ref_cnt--; pinfo->ref_cnt--; pm_runtime_put(info->dev); if (!pinfo->ref_cnt) { list_del(&pinfo->list); kfree(pinfo); release_needed = true; } } else { WARN("unknown caller:: process %s mfd->ref=%d\n", task->comm, mfd->ref_cnt); } } if (!node_found || (release_all && mfd->ref_cnt)) pr_warn("file node not found or wrong ref cnt: release all:%d refcnt:%d\n", release_all, mfd->ref_cnt); pr_debug("current process=%s pid=%d mfd->ref=%d file:%p\n", task->comm, current->tgid, mfd->ref_cnt, info->file); if (!mfd->ref_cnt || release_all) { /* resources (if any) will be released during blank */ if (mfd->mdp.release_fnc) mfd->mdp.release_fnc(mfd, true, pid); mfd->mdp.release_fnc(mfd, NULL); ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable); if (ret) { pr_err("can't turn off fb%d! rc=%d current process=%s pid=%d known pid=%d\n", mfd->index, ret, task->comm, current->tgid, pid); pr_err("can't turn off fb%d! rc=%d current process=%s pid=%d\n", mfd->index, ret, task->comm, current->tgid); return ret; } if (mfd->fb_ion_handle) mdss_fb_free_fb_ion_memory(mfd); atomic_set(&mfd->ioctl_ref_cnt, 0); } else if (release_needed) { pr_debug("current process=%s pid=%d known pid=%d mfd->ref=%d\n", task->comm, current->tgid, pid, mfd->ref_cnt); if (mfd->mdp.release_fnc) { ret = mfd->mdp.release_fnc(mfd, false, pid); } else { if (mfd->mdp.release_fnc) ret = mfd->mdp.release_fnc(mfd, file); /* display commit is needed to release resources */ if (ret) mdss_fb_pan_display(&mfd->fbi->var, mfd->fbi); } } return ret; } Loading Loading @@ -2971,6 +2841,7 @@ int mdss_fb_atomic_commit(struct fb_info *info, { struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; struct mdp_layer_commit_v1 *commit_v1; struct file *file = info->file; bool wait_for_finish; int ret = -EPERM; Loading Loading @@ -3005,7 +2876,7 @@ int mdss_fb_atomic_commit(struct fb_info *info, } else { __ioctl_transition_dyn_mode_state(mfd, MSMFB_ATOMIC_COMMIT, 1); ret = mfd->mdp.atomic_validate(mfd, commit_v1); ret = mfd->mdp.atomic_validate(mfd, file, commit_v1); } goto end; } else { Loading @@ -3015,7 +2886,7 @@ int mdss_fb_atomic_commit(struct fb_info *info, goto end; } ret = mfd->mdp.pre_commit(mfd, commit_v1); ret = mfd->mdp.pre_commit(mfd, file, commit_v1); if (ret) { pr_err("atomic pre commit failed\n"); goto end; Loading drivers/video/msm/mdss/mdss_fb.h +4 −12 Original line number Diff line number Diff line Loading @@ -188,17 +188,16 @@ struct msm_mdp_interface { int (*on_fnc)(struct msm_fb_data_type *mfd); int (*off_fnc)(struct msm_fb_data_type *mfd); /* called to release resources associated to the process */ int (*release_fnc)(struct msm_fb_data_type *mfd, bool release_all, uint32_t pid); int (*release_fnc)(struct msm_fb_data_type *mfd, struct file *file); int (*mode_switch)(struct msm_fb_data_type *mfd, u32 mode); int (*mode_switch_post)(struct msm_fb_data_type *mfd, u32 mode); int (*kickoff_fnc)(struct msm_fb_data_type *mfd, struct mdp_display_commit *data); int (*atomic_validate)(struct msm_fb_data_type *mfd, int (*atomic_validate)(struct msm_fb_data_type *mfd, struct file *file, struct mdp_layer_commit_v1 *commit); int (*pre_commit)(struct msm_fb_data_type *mfd, int (*pre_commit)(struct msm_fb_data_type *mfd, struct file *file, struct mdp_layer_commit_v1 *commit); int (*pre_commit_fnc)(struct msm_fb_data_type *mfd); int (*ioctl_handler)(struct msm_fb_data_type *mfd, u32 cmd, void *arg); Loading Loading @@ -234,13 +233,6 @@ struct mdss_fb_file_info { struct list_head list; }; struct mdss_fb_proc_info { int pid; u32 ref_cnt; struct list_head file_list; struct list_head list; }; struct msm_fb_backup_type { struct fb_info info; struct mdp_display_commit disp_commit; Loading Loading @@ -327,7 +319,7 @@ struct msm_fb_data_type { u32 is_power_setting; u32 dcm_state; struct list_head proc_list; struct list_head file_list; struct ion_client *fb_ion_client; struct ion_handle *fb_ion_handle; struct dma_buf *fbmem_buf; Loading drivers/video/msm/mdss/mdss_mdp.h +5 −5 Original line number Diff line number Diff line Loading @@ -516,7 +516,7 @@ struct mdss_mdp_pipe { struct kref kref; u32 play_cnt; int pid; struct file *file; bool is_handed_off; u32 flags; Loading Loading @@ -966,14 +966,14 @@ int mdss_mdp_secure_display_ctrl(unsigned int enable); int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd); int mdss_mdp_layer_atomic_validate(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *ov_commit); struct file *file, struct mdp_layer_commit_v1 *ov_commit); int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *ov_commit); struct file *file, struct mdp_layer_commit_v1 *ov_commit); int mdss_mdp_layer_atomic_validate_wfd(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *ov_commit); struct file *file, struct mdp_layer_commit_v1 *ov_commit); int mdss_mdp_layer_pre_commit_wfd(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *ov_commit); struct file *file, struct mdp_layer_commit_v1 *ov_commit); int mdss_mdp_async_position_update(struct msm_fb_data_type *mfd, struct mdp_position_update *update_pos); Loading drivers/video/msm/mdss/mdss_mdp_layer.c +17 −15 Original line number Diff line number Diff line Loading @@ -435,7 +435,6 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd, pipe->mixer_left = mixer; pipe->mfd = mfd; pipe->pid = current->tgid; pipe->play_cnt = 0; pipe->flags = 0; Loading Loading @@ -1061,7 +1060,7 @@ static void __handle_free_list(struct mdss_overlay_private *mdp5_data, * to find failed layer from layer_list based on "error_code". */ static int __validate_layers(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *commit) struct file *file, struct mdp_layer_commit_v1 *commit) { int ret, i, release_ndx = 0; u32 left_lm_layers = 0, right_lm_layers = 0; Loading Loading @@ -1251,10 +1250,9 @@ validate_exit: pr_debug("err=%d total_layer:%d left:%d right:%d release_ndx=0x%x processed=%d\n", ret, layer_count, left_lm_layers, right_lm_layers, release_ndx, i); if (IS_ERR_VALUE(ret)) { mutex_lock(&mdp5_data->list_lock); list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) { list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) { if (IS_ERR_VALUE(ret)) { if (pipe->ndx & release_ndx) { mdss_mdp_smp_unreserve(pipe); pipe->params_changed = 0; Loading @@ -1263,9 +1261,13 @@ validate_exit: list_del_init(&pipe->list); mdss_mdp_pipe_destroy(pipe); } } else { pipe->file = file; pr_debug("file pointer attached with pipe is %p\n", file); } mutex_unlock(&mdp5_data->list_lock); } mutex_unlock(&mdp5_data->list_lock); end: mutex_unlock(&mdp5_data->ov_lock); Loading @@ -1287,7 +1289,7 @@ end: * This function is called from client context and can return the error. */ int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *commit) struct file *file, struct mdp_layer_commit_v1 *commit) { int ret, i; int layer_count = commit->input_layer_cnt; Loading Loading @@ -1321,7 +1323,7 @@ int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd, } if (validate_failed) { ret = __validate_layers(mfd, commit); ret = __validate_layers(mfd, file, commit); if (ret) goto end; } else { Loading Loading @@ -1382,7 +1384,7 @@ end: * display. */ int mdss_mdp_layer_atomic_validate(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *commit) struct file *file, struct mdp_layer_commit_v1 *commit) { struct mdss_overlay_private *mdp5_data; Loading @@ -1404,11 +1406,11 @@ int mdss_mdp_layer_atomic_validate(struct msm_fb_data_type *mfd, return -EPERM; } return __validate_layers(mfd, commit); return __validate_layers(mfd, file, commit); } int mdss_mdp_layer_pre_commit_wfd(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *commit) struct file *file, struct mdp_layer_commit_v1 *commit) { int rc, count; struct mdss_overlay_private *mdp5_data; Loading Loading @@ -1446,7 +1448,7 @@ int mdss_mdp_layer_pre_commit_wfd(struct msm_fb_data_type *mfd, } } rc = mdss_mdp_layer_pre_commit(mfd, commit); rc = mdss_mdp_layer_pre_commit(mfd, file, commit); if (rc) { pr_err("fail to import input layer buffers\n"); goto input_layer_err; Loading @@ -1472,7 +1474,7 @@ fence_get_err: } int mdss_mdp_layer_atomic_validate_wfd(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *commit) struct file *file, struct mdp_layer_commit_v1 *commit) { int rc = 0; struct mdss_overlay_private *mdp5_data; Loading Loading @@ -1509,7 +1511,7 @@ int mdss_mdp_layer_atomic_validate_wfd(struct msm_fb_data_type *mfd, goto validate_failed; } rc = mdss_mdp_layer_atomic_validate(mfd, commit); rc = mdss_mdp_layer_atomic_validate(mfd, file, commit); if (rc) { pr_err("fail to validate the input layers = %d\n", rc); goto validate_failed; Loading Loading
drivers/video/fbdev/core/fbmem.c +3 −0 Original line number Diff line number Diff line Loading @@ -1227,6 +1227,9 @@ static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (!info) return -ENODEV; mutex_lock(&info->lock); info->file = file; mutex_unlock(&info->lock); return do_fb_ioctl(info, cmd, arg); } Loading
drivers/video/msm/mdss/mdss_fb.c +35 −164 Original line number Diff line number Diff line Loading @@ -877,7 +877,7 @@ static int mdss_fb_probe(struct platform_device *pdev) &(mfd->boot_notification_led)); } INIT_LIST_HEAD(&mfd->proc_list); INIT_LIST_HEAD(&mfd->file_list); mutex_init(&mfd->bl_lock); mutex_init(&mfd->switch_lock); Loading Loading @@ -2272,80 +2272,16 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd) return 0; } /** * mdss_fb_release_file_entry() - Releases file node entry from list * @info: Frame buffer info * @pinfo: Process list node in which file node entry is going to * be removed * @release_all: Releases all file node entries from list if this parameter * is true * * This function is called to remove the file node entry/entries from main * list. It also helps to find the process id if fb_open and fb_close * callers are different. */ static struct mdss_fb_proc_info *mdss_fb_release_file_entry( struct fb_info *info, struct mdss_fb_proc_info *pinfo, bool release_all) { struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; struct mdss_fb_file_info *file_info = NULL, *temp_file_info = NULL; struct mdss_fb_proc_info *proc_info = NULL, *temp_proc_info = NULL; struct file *file = info->file; bool node_found = false; if (!pinfo && release_all) { pr_err("process node not provided for release all case\n"); goto end; } if (pinfo) { proc_info = pinfo; list_for_each_entry_safe(file_info, temp_file_info, &pinfo->file_list, list) { if (!release_all && file_info->file != file) continue; list_del(&file_info->list); kfree(file_info); node_found = true; if (!release_all) break; } } if (!node_found) { list_for_each_entry_safe(proc_info, temp_proc_info, &mfd->proc_list, list) { list_for_each_entry_safe(file_info, temp_file_info, &proc_info->file_list, list) { if (file_info->file == file) { list_del(&file_info->list); kfree(file_info); goto end; } } } } end: return proc_info; } static int mdss_fb_open(struct fb_info *info, int user) { struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; struct mdss_fb_proc_info *pinfo = NULL; struct mdss_fb_file_info *file_info = NULL; int result; int pid = current->tgid; struct task_struct *task = current->group_leader; if (mfd->shutdown_pending) { pr_err_once("Shutdown pending. Aborting operation. Request from pid:%d name=%s\n", pid, task->comm); current->tgid, task->comm); sysfs_notify(&mfd->fbi->dev->kobj, NULL, "show_blank_event"); return -ESHUTDOWN; } Loading @@ -2356,27 +2292,8 @@ static int mdss_fb_open(struct fb_info *info, int user) return -ENOMEM; } list_for_each_entry(pinfo, &mfd->proc_list, list) { if (pinfo->pid == pid) break; } if ((pinfo == NULL) || (pinfo->pid != pid)) { pinfo = kmalloc(sizeof(*pinfo), GFP_KERNEL); if (!pinfo) { pr_err("unable to alloc process info\n"); kfree(file_info); return -ENOMEM; } pinfo->pid = pid; pinfo->ref_cnt = 0; list_add(&pinfo->list, &mfd->proc_list); INIT_LIST_HEAD(&pinfo->file_list); pr_debug("new process entry pid=%d\n", pinfo->pid); } file_info->file = info->file; list_add(&file_info->list, &pinfo->file_list); list_add(&file_info->list, &mfd->file_list); result = pm_runtime_get_sync(info->dev); Loading @@ -2395,37 +2312,31 @@ static int mdss_fb_open(struct fb_info *info, int user) } } pinfo->ref_cnt++; mfd->ref_cnt++; pr_debug("mfd refcount:%d file:%p\n", mfd->ref_cnt, info->file); return 0; blank_error: pm_runtime_put(info->dev); pm_error: list_del(&file_info->list); kfree(file_info); if (pinfo && !pinfo->ref_cnt) { list_del(&pinfo->list); kfree(pinfo); } return result; } static int mdss_fb_release_all(struct fb_info *info, bool release_all) { struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; struct mdss_fb_proc_info *pinfo = NULL, *temp_pinfo = NULL; struct mdss_fb_proc_info *proc_info = NULL; struct mdss_fb_file_info *file_info = NULL, *temp_file_info = NULL; struct file *file = info->file; int ret = 0; int pid = current->tgid; bool unknown_pid = true, release_needed = false; bool node_found = false; struct task_struct *task = current->group_leader; if (!mfd->ref_cnt) { pr_info("try to close unopened fb %d! from pid:%d name:%s\n", mfd->index, pid, task->comm); mfd->index, current->tgid, task->comm); return -EINVAL; } Loading @@ -2445,96 +2356,55 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all) pr_debug("release_all = %s\n", release_all ? "true" : "false"); list_for_each_entry_safe(pinfo, temp_pinfo, &mfd->proc_list, list) { if (!release_all && (pinfo->pid != pid)) list_for_each_entry_safe(file_info, temp_file_info, &mfd->file_list, list) { if (!release_all && file_info->file != file) continue; unknown_pid = false; pr_debug("found process %s pid=%d mfd->ref=%d pinfo->ref=%d\n", task->comm, pinfo->pid, mfd->ref_cnt, pinfo->ref_cnt); proc_info = mdss_fb_release_file_entry(info, pinfo, release_all); /* * if fb_release is called from different known process then * release the ref_count of original proc_info instead of * current process. */ if (!release_all && proc_info && proc_info != pinfo) { pr_info("fb_release called from different process for current file node\n"); pinfo = proc_info; } pr_debug("found file node mfd->ref=%d\n", mfd->ref_cnt); list_del(&file_info->list); kfree(file_info); do { if (mfd->ref_cnt < pinfo->ref_cnt) pr_warn("WARN:mfd->ref=%d < pinfo->ref=%d\n", mfd->ref_cnt, pinfo->ref_cnt); else mfd->ref_cnt--; pinfo->ref_cnt--; pm_runtime_put(info->dev); } while (release_all && pinfo->ref_cnt); if (pinfo->ref_cnt == 0) { list_del(&pinfo->list); kfree(pinfo); release_needed = !release_all; } node_found = true; if (!release_all) break; } if (unknown_pid) { pinfo = mdss_fb_release_file_entry(info, NULL, false); if (pinfo) { pr_debug("found known pid=%d reference for unknown caller pid=%d\n", pinfo->pid, pid); pid = pinfo->pid; mfd->ref_cnt--; pinfo->ref_cnt--; pm_runtime_put(info->dev); if (!pinfo->ref_cnt) { list_del(&pinfo->list); kfree(pinfo); release_needed = true; } } else { WARN("unknown caller:: process %s mfd->ref=%d\n", task->comm, mfd->ref_cnt); } } if (!node_found || (release_all && mfd->ref_cnt)) pr_warn("file node not found or wrong ref cnt: release all:%d refcnt:%d\n", release_all, mfd->ref_cnt); pr_debug("current process=%s pid=%d mfd->ref=%d file:%p\n", task->comm, current->tgid, mfd->ref_cnt, info->file); if (!mfd->ref_cnt || release_all) { /* resources (if any) will be released during blank */ if (mfd->mdp.release_fnc) mfd->mdp.release_fnc(mfd, true, pid); mfd->mdp.release_fnc(mfd, NULL); ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable); if (ret) { pr_err("can't turn off fb%d! rc=%d current process=%s pid=%d known pid=%d\n", mfd->index, ret, task->comm, current->tgid, pid); pr_err("can't turn off fb%d! rc=%d current process=%s pid=%d\n", mfd->index, ret, task->comm, current->tgid); return ret; } if (mfd->fb_ion_handle) mdss_fb_free_fb_ion_memory(mfd); atomic_set(&mfd->ioctl_ref_cnt, 0); } else if (release_needed) { pr_debug("current process=%s pid=%d known pid=%d mfd->ref=%d\n", task->comm, current->tgid, pid, mfd->ref_cnt); if (mfd->mdp.release_fnc) { ret = mfd->mdp.release_fnc(mfd, false, pid); } else { if (mfd->mdp.release_fnc) ret = mfd->mdp.release_fnc(mfd, file); /* display commit is needed to release resources */ if (ret) mdss_fb_pan_display(&mfd->fbi->var, mfd->fbi); } } return ret; } Loading Loading @@ -2971,6 +2841,7 @@ int mdss_fb_atomic_commit(struct fb_info *info, { struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; struct mdp_layer_commit_v1 *commit_v1; struct file *file = info->file; bool wait_for_finish; int ret = -EPERM; Loading Loading @@ -3005,7 +2876,7 @@ int mdss_fb_atomic_commit(struct fb_info *info, } else { __ioctl_transition_dyn_mode_state(mfd, MSMFB_ATOMIC_COMMIT, 1); ret = mfd->mdp.atomic_validate(mfd, commit_v1); ret = mfd->mdp.atomic_validate(mfd, file, commit_v1); } goto end; } else { Loading @@ -3015,7 +2886,7 @@ int mdss_fb_atomic_commit(struct fb_info *info, goto end; } ret = mfd->mdp.pre_commit(mfd, commit_v1); ret = mfd->mdp.pre_commit(mfd, file, commit_v1); if (ret) { pr_err("atomic pre commit failed\n"); goto end; Loading
drivers/video/msm/mdss/mdss_fb.h +4 −12 Original line number Diff line number Diff line Loading @@ -188,17 +188,16 @@ struct msm_mdp_interface { int (*on_fnc)(struct msm_fb_data_type *mfd); int (*off_fnc)(struct msm_fb_data_type *mfd); /* called to release resources associated to the process */ int (*release_fnc)(struct msm_fb_data_type *mfd, bool release_all, uint32_t pid); int (*release_fnc)(struct msm_fb_data_type *mfd, struct file *file); int (*mode_switch)(struct msm_fb_data_type *mfd, u32 mode); int (*mode_switch_post)(struct msm_fb_data_type *mfd, u32 mode); int (*kickoff_fnc)(struct msm_fb_data_type *mfd, struct mdp_display_commit *data); int (*atomic_validate)(struct msm_fb_data_type *mfd, int (*atomic_validate)(struct msm_fb_data_type *mfd, struct file *file, struct mdp_layer_commit_v1 *commit); int (*pre_commit)(struct msm_fb_data_type *mfd, int (*pre_commit)(struct msm_fb_data_type *mfd, struct file *file, struct mdp_layer_commit_v1 *commit); int (*pre_commit_fnc)(struct msm_fb_data_type *mfd); int (*ioctl_handler)(struct msm_fb_data_type *mfd, u32 cmd, void *arg); Loading Loading @@ -234,13 +233,6 @@ struct mdss_fb_file_info { struct list_head list; }; struct mdss_fb_proc_info { int pid; u32 ref_cnt; struct list_head file_list; struct list_head list; }; struct msm_fb_backup_type { struct fb_info info; struct mdp_display_commit disp_commit; Loading Loading @@ -327,7 +319,7 @@ struct msm_fb_data_type { u32 is_power_setting; u32 dcm_state; struct list_head proc_list; struct list_head file_list; struct ion_client *fb_ion_client; struct ion_handle *fb_ion_handle; struct dma_buf *fbmem_buf; Loading
drivers/video/msm/mdss/mdss_mdp.h +5 −5 Original line number Diff line number Diff line Loading @@ -516,7 +516,7 @@ struct mdss_mdp_pipe { struct kref kref; u32 play_cnt; int pid; struct file *file; bool is_handed_off; u32 flags; Loading Loading @@ -966,14 +966,14 @@ int mdss_mdp_secure_display_ctrl(unsigned int enable); int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd); int mdss_mdp_layer_atomic_validate(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *ov_commit); struct file *file, struct mdp_layer_commit_v1 *ov_commit); int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *ov_commit); struct file *file, struct mdp_layer_commit_v1 *ov_commit); int mdss_mdp_layer_atomic_validate_wfd(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *ov_commit); struct file *file, struct mdp_layer_commit_v1 *ov_commit); int mdss_mdp_layer_pre_commit_wfd(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *ov_commit); struct file *file, struct mdp_layer_commit_v1 *ov_commit); int mdss_mdp_async_position_update(struct msm_fb_data_type *mfd, struct mdp_position_update *update_pos); Loading
drivers/video/msm/mdss/mdss_mdp_layer.c +17 −15 Original line number Diff line number Diff line Loading @@ -435,7 +435,6 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd, pipe->mixer_left = mixer; pipe->mfd = mfd; pipe->pid = current->tgid; pipe->play_cnt = 0; pipe->flags = 0; Loading Loading @@ -1061,7 +1060,7 @@ static void __handle_free_list(struct mdss_overlay_private *mdp5_data, * to find failed layer from layer_list based on "error_code". */ static int __validate_layers(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *commit) struct file *file, struct mdp_layer_commit_v1 *commit) { int ret, i, release_ndx = 0; u32 left_lm_layers = 0, right_lm_layers = 0; Loading Loading @@ -1251,10 +1250,9 @@ validate_exit: pr_debug("err=%d total_layer:%d left:%d right:%d release_ndx=0x%x processed=%d\n", ret, layer_count, left_lm_layers, right_lm_layers, release_ndx, i); if (IS_ERR_VALUE(ret)) { mutex_lock(&mdp5_data->list_lock); list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) { list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) { if (IS_ERR_VALUE(ret)) { if (pipe->ndx & release_ndx) { mdss_mdp_smp_unreserve(pipe); pipe->params_changed = 0; Loading @@ -1263,9 +1261,13 @@ validate_exit: list_del_init(&pipe->list); mdss_mdp_pipe_destroy(pipe); } } else { pipe->file = file; pr_debug("file pointer attached with pipe is %p\n", file); } mutex_unlock(&mdp5_data->list_lock); } mutex_unlock(&mdp5_data->list_lock); end: mutex_unlock(&mdp5_data->ov_lock); Loading @@ -1287,7 +1289,7 @@ end: * This function is called from client context and can return the error. */ int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *commit) struct file *file, struct mdp_layer_commit_v1 *commit) { int ret, i; int layer_count = commit->input_layer_cnt; Loading Loading @@ -1321,7 +1323,7 @@ int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd, } if (validate_failed) { ret = __validate_layers(mfd, commit); ret = __validate_layers(mfd, file, commit); if (ret) goto end; } else { Loading Loading @@ -1382,7 +1384,7 @@ end: * display. */ int mdss_mdp_layer_atomic_validate(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *commit) struct file *file, struct mdp_layer_commit_v1 *commit) { struct mdss_overlay_private *mdp5_data; Loading @@ -1404,11 +1406,11 @@ int mdss_mdp_layer_atomic_validate(struct msm_fb_data_type *mfd, return -EPERM; } return __validate_layers(mfd, commit); return __validate_layers(mfd, file, commit); } int mdss_mdp_layer_pre_commit_wfd(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *commit) struct file *file, struct mdp_layer_commit_v1 *commit) { int rc, count; struct mdss_overlay_private *mdp5_data; Loading Loading @@ -1446,7 +1448,7 @@ int mdss_mdp_layer_pre_commit_wfd(struct msm_fb_data_type *mfd, } } rc = mdss_mdp_layer_pre_commit(mfd, commit); rc = mdss_mdp_layer_pre_commit(mfd, file, commit); if (rc) { pr_err("fail to import input layer buffers\n"); goto input_layer_err; Loading @@ -1472,7 +1474,7 @@ fence_get_err: } int mdss_mdp_layer_atomic_validate_wfd(struct msm_fb_data_type *mfd, struct mdp_layer_commit_v1 *commit) struct file *file, struct mdp_layer_commit_v1 *commit) { int rc = 0; struct mdss_overlay_private *mdp5_data; Loading Loading @@ -1509,7 +1511,7 @@ int mdss_mdp_layer_atomic_validate_wfd(struct msm_fb_data_type *mfd, goto validate_failed; } rc = mdss_mdp_layer_atomic_validate(mfd, commit); rc = mdss_mdp_layer_atomic_validate(mfd, file, commit); if (rc) { pr_err("fail to validate the input layers = %d\n", rc); goto validate_failed; Loading