static int gsc_m2m_open(struct file *file) { struct gsc_dev *gsc = video_drvdata(file); struct gsc_ctx *ctx = NULL; int ret; gsc_dbg("pid: %d, state: 0x%lx", task_pid_nr(current), gsc->state); if (gsc_out_opened(gsc) || gsc_cap_opened(gsc)) return -EBUSY; ctx = kzalloc(sizeof *ctx, GFP_KERNEL); if (!ctx) return -ENOMEM; v4l2_fh_init(&ctx->fh, gsc->m2m.vfd); ret = gsc_ctrls_create(ctx); if (ret) goto error_fh; /* Use separate control handler per file handle */ ctx->fh.ctrl_handler = &ctx->ctrl_handler; file->private_data = &ctx->fh; v4l2_fh_add(&ctx->fh); ctx->gsc_dev = gsc; /* Default color format */ ctx->s_frame.fmt = get_format(0); ctx->d_frame.fmt = get_format(0); /* Setup the device context for mem2mem mode. */ ctx->state |= GSC_CTX_M2M; ctx->flags = 0; ctx->in_path = GSC_DMA; ctx->out_path = GSC_DMA; spin_lock_init(&ctx->slock); INIT_LIST_HEAD(&ctx->fence_wait_list); INIT_WORK(&ctx->fence_work, gsc_m2m_fence_work); ctx->m2m_ctx = v4l2_m2m_ctx_init(gsc->m2m.m2m_dev, ctx, queue_init); if (IS_ERR(ctx->m2m_ctx)) { gsc_err("Failed to initialize m2m context"); ret = PTR_ERR(ctx->m2m_ctx); goto error_fh; } if (gsc->m2m.refcnt++ == 0) set_bit(ST_M2M_OPEN, &gsc->state); gsc_dbg("gsc m2m driver is opened, ctx(0x%p)", ctx); return 0; error_fh: v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); kfree(ctx); return ret; }
static int gsc_capture_open(struct file *file) { struct gsc_dev *gsc = video_drvdata(file); int ret = v4l2_fh_open(file); if (ret) return ret; if (gsc_m2m_opened(gsc) || gsc_out_opened(gsc) || gsc_cap_opened(gsc)) { v4l2_fh_release(file); return -EBUSY; } set_bit(ST_CAPT_OPEN, &gsc->state); pm_runtime_get_sync(&gsc->pdev->dev); if (++gsc->cap.refcnt == 1) { ret = gsc_cap_pipeline_initialize(gsc, &gsc->cap.vfd->entity, true); if (ret < 0) { gsc_err("gsc pipeline initialization failed\n"); goto err; } ret = gsc_capture_ctrls_create(gsc); if (ret) { gsc_err("failed to create controls\n"); goto err; } } gsc_dbg("pid: %d, state: 0x%lx", task_pid_nr(current), gsc->state); return 0; err: pm_runtime_put_sync(&gsc->pdev->dev); v4l2_fh_release(file); clear_bit(ST_CAPT_OPEN, &gsc->state); return ret; }