Loading drivers/video/msm/mdss/mdss_mdp_intf_writeback.c +78 −4 Original line number Diff line number Diff line Loading @@ -48,6 +48,8 @@ struct mdss_mdp_writeback_ctx { void (*callback_fnc) (void *arg); void *callback_arg; spinlock_t wb_lock; struct list_head vsync_handlers; }; static struct mdss_mdp_writeback_ctx wb_ctx_list[MDSS_MDP_MAX_WRITEBACK] = { Loading Loading @@ -300,14 +302,73 @@ static int mdss_mdp_writeback_prepare_rot(struct mdss_mdp_ctl *ctl, void *arg) return mdss_mdp_writeback_format_setup(ctx, format); } static int mdss_mdp_wb_add_vsync_handler(struct mdss_mdp_ctl *ctl, struct mdss_mdp_vsync_handler *handle) { struct mdss_mdp_writeback_ctx *ctx; unsigned long flags; int ret = 0; if (!handle || !(handle->vsync_handler)) { ret = -EINVAL; goto exit; } ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data; if (!ctx) { pr_err("invalid ctx for ctl=%d\n", ctl->num); ret = -ENODEV; goto exit; } spin_lock_irqsave(&ctx->wb_lock, flags); if (!handle->enabled) { handle->enabled = true; list_add(&handle->list, &ctx->vsync_handlers); } spin_unlock_irqrestore(&ctx->wb_lock, flags); exit: return ret; } static int mdss_mdp_wb_remove_vsync_handler(struct mdss_mdp_ctl *ctl, struct mdss_mdp_vsync_handler *handle) { struct mdss_mdp_writeback_ctx *ctx; unsigned long flags; int ret = 0; if (!handle || !(handle->vsync_handler)) { ret = -EINVAL; goto exit; } ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data; if (!ctx) { pr_err("invalid ctx for ctl=%d\n", ctl->num); ret = -ENODEV; goto exit; } spin_lock_irqsave(&ctx->wb_lock, flags); if (handle->enabled) { handle->enabled = false; list_del_init(&handle->list); } spin_unlock_irqrestore(&ctx->wb_lock, flags); exit: return ret; } static int mdss_mdp_writeback_stop(struct mdss_mdp_ctl *ctl) { struct mdss_mdp_writeback_ctx *ctx; struct mdss_mdp_vsync_handler *t, *handle; pr_debug("stop ctl=%d\n", ctl->num); ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data; if (ctx) { list_for_each_entry_safe(handle, t, &ctx->vsync_handlers, list) mdss_mdp_wb_remove_vsync_handler(ctl, handle); mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num, NULL, NULL); Loading @@ -320,13 +381,16 @@ static int mdss_mdp_writeback_stop(struct mdss_mdp_ctl *ctl) static void mdss_mdp_writeback_intr_done(void *arg) { struct mdss_mdp_writeback_ctx *ctx; struct mdss_mdp_ctl *ctl = arg; struct mdss_mdp_writeback_ctx *ctx = ctl->priv_data; struct mdss_mdp_vsync_handler *tmp; ktime_t vsync_time; ctx = (struct mdss_mdp_writeback_ctx *) arg; if (!ctx) { pr_err("invalid ctx\n"); return; } vsync_time = ktime_get(); pr_debug("intr wb_num=%d\n", ctx->wb_num); Loading @@ -335,6 +399,12 @@ static void mdss_mdp_writeback_intr_done(void *arg) if (ctx->callback_fnc) ctx->callback_fnc(ctx->callback_arg); spin_lock(&ctx->wb_lock); list_for_each_entry(tmp, &ctx->vsync_handlers, list) { tmp->vsync_handler(ctl, vsync_time); } spin_unlock(&ctx->wb_lock); complete_all(&ctx->wb_comp); } Loading Loading @@ -400,7 +470,7 @@ static int mdss_mdp_writeback_display(struct mdss_mdp_ctl *ctl, void *arg) } mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num, mdss_mdp_writeback_intr_done, ctx); mdss_mdp_writeback_intr_done, ctl); ctx->callback_fnc = wb_args->callback_fnc; ctx->callback_arg = wb_args->priv_data; Loading Loading @@ -446,6 +516,8 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) ctx->base = ctl->wb_base; ctx->initialized = false; init_completion(&ctx->wb_comp); spin_lock_init(&ctx->wb_lock); INIT_LIST_HEAD(&ctx->vsync_handlers); if (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR) ctl->prepare_fnc = mdss_mdp_writeback_prepare_rot; Loading @@ -454,6 +526,8 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) ctl->stop_fnc = mdss_mdp_writeback_stop; ctl->display_fnc = mdss_mdp_writeback_display; ctl->wait_fnc = mdss_mdp_wb_wait4comp; ctl->add_vsync_handler = mdss_mdp_wb_add_vsync_handler; ctl->remove_vsync_handler = mdss_mdp_wb_remove_vsync_handler; return ret; } Loading Loading
drivers/video/msm/mdss/mdss_mdp_intf_writeback.c +78 −4 Original line number Diff line number Diff line Loading @@ -48,6 +48,8 @@ struct mdss_mdp_writeback_ctx { void (*callback_fnc) (void *arg); void *callback_arg; spinlock_t wb_lock; struct list_head vsync_handlers; }; static struct mdss_mdp_writeback_ctx wb_ctx_list[MDSS_MDP_MAX_WRITEBACK] = { Loading Loading @@ -300,14 +302,73 @@ static int mdss_mdp_writeback_prepare_rot(struct mdss_mdp_ctl *ctl, void *arg) return mdss_mdp_writeback_format_setup(ctx, format); } static int mdss_mdp_wb_add_vsync_handler(struct mdss_mdp_ctl *ctl, struct mdss_mdp_vsync_handler *handle) { struct mdss_mdp_writeback_ctx *ctx; unsigned long flags; int ret = 0; if (!handle || !(handle->vsync_handler)) { ret = -EINVAL; goto exit; } ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data; if (!ctx) { pr_err("invalid ctx for ctl=%d\n", ctl->num); ret = -ENODEV; goto exit; } spin_lock_irqsave(&ctx->wb_lock, flags); if (!handle->enabled) { handle->enabled = true; list_add(&handle->list, &ctx->vsync_handlers); } spin_unlock_irqrestore(&ctx->wb_lock, flags); exit: return ret; } static int mdss_mdp_wb_remove_vsync_handler(struct mdss_mdp_ctl *ctl, struct mdss_mdp_vsync_handler *handle) { struct mdss_mdp_writeback_ctx *ctx; unsigned long flags; int ret = 0; if (!handle || !(handle->vsync_handler)) { ret = -EINVAL; goto exit; } ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data; if (!ctx) { pr_err("invalid ctx for ctl=%d\n", ctl->num); ret = -ENODEV; goto exit; } spin_lock_irqsave(&ctx->wb_lock, flags); if (handle->enabled) { handle->enabled = false; list_del_init(&handle->list); } spin_unlock_irqrestore(&ctx->wb_lock, flags); exit: return ret; } static int mdss_mdp_writeback_stop(struct mdss_mdp_ctl *ctl) { struct mdss_mdp_writeback_ctx *ctx; struct mdss_mdp_vsync_handler *t, *handle; pr_debug("stop ctl=%d\n", ctl->num); ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data; if (ctx) { list_for_each_entry_safe(handle, t, &ctx->vsync_handlers, list) mdss_mdp_wb_remove_vsync_handler(ctl, handle); mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num, NULL, NULL); Loading @@ -320,13 +381,16 @@ static int mdss_mdp_writeback_stop(struct mdss_mdp_ctl *ctl) static void mdss_mdp_writeback_intr_done(void *arg) { struct mdss_mdp_writeback_ctx *ctx; struct mdss_mdp_ctl *ctl = arg; struct mdss_mdp_writeback_ctx *ctx = ctl->priv_data; struct mdss_mdp_vsync_handler *tmp; ktime_t vsync_time; ctx = (struct mdss_mdp_writeback_ctx *) arg; if (!ctx) { pr_err("invalid ctx\n"); return; } vsync_time = ktime_get(); pr_debug("intr wb_num=%d\n", ctx->wb_num); Loading @@ -335,6 +399,12 @@ static void mdss_mdp_writeback_intr_done(void *arg) if (ctx->callback_fnc) ctx->callback_fnc(ctx->callback_arg); spin_lock(&ctx->wb_lock); list_for_each_entry(tmp, &ctx->vsync_handlers, list) { tmp->vsync_handler(ctl, vsync_time); } spin_unlock(&ctx->wb_lock); complete_all(&ctx->wb_comp); } Loading Loading @@ -400,7 +470,7 @@ static int mdss_mdp_writeback_display(struct mdss_mdp_ctl *ctl, void *arg) } mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num, mdss_mdp_writeback_intr_done, ctx); mdss_mdp_writeback_intr_done, ctl); ctx->callback_fnc = wb_args->callback_fnc; ctx->callback_arg = wb_args->priv_data; Loading Loading @@ -446,6 +516,8 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) ctx->base = ctl->wb_base; ctx->initialized = false; init_completion(&ctx->wb_comp); spin_lock_init(&ctx->wb_lock); INIT_LIST_HEAD(&ctx->vsync_handlers); if (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR) ctl->prepare_fnc = mdss_mdp_writeback_prepare_rot; Loading @@ -454,6 +526,8 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) ctl->stop_fnc = mdss_mdp_writeback_stop; ctl->display_fnc = mdss_mdp_writeback_display; ctl->wait_fnc = mdss_mdp_wb_wait4comp; ctl->add_vsync_handler = mdss_mdp_wb_add_vsync_handler; ctl->remove_vsync_handler = mdss_mdp_wb_remove_vsync_handler; return ret; } Loading