Esempio n. 1
0
static int fimc_m2m_open(struct file *file)
{
    struct fimc_dev *fimc = video_drvdata(file);
    struct fimc_ctx *ctx;
    int ret = -EBUSY;

    pr_debug("pid: %d, state: %#lx\n", task_pid_nr(current), fimc->state);

    if (mutex_lock_interruptible(&fimc->lock))
        return -ERESTARTSYS;
    /*
     * Don't allow simultaneous open() of the mem-to-mem and the
     * capture video node that belong to same FIMC IP instance.
     */
    if (test_bit(ST_CAPT_BUSY, &fimc->state))
        goto unlock;

    ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
    if (!ctx) {
        ret = -ENOMEM;
        goto unlock;
    }
    v4l2_fh_init(&ctx->fh, &fimc->m2m.vfd);
    ctx->fimc_dev = fimc;

    /* Default color format */
    ctx->s_frame.fmt = fimc_get_format(0);
    ctx->d_frame.fmt = fimc_get_format(0);

    ret = fimc_ctrls_create(ctx);
    if (ret)
        goto error_fh;

    /* Use separate control handler per file handle */
    ctx->fh.ctrl_handler = &ctx->ctrls.handler;
    file->private_data = &ctx->fh;
    v4l2_fh_add(&ctx->fh);

    /* Setup the device context for memory-to-memory mode */
    ctx->state = FIMC_CTX_M2M;
    ctx->flags = 0;
    ctx->in_path = FIMC_IO_DMA;
    ctx->out_path = FIMC_IO_DMA;
    ctx->scaler.enabled = 1;

    ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
    if (IS_ERR(ctx->m2m_ctx)) {
        ret = PTR_ERR(ctx->m2m_ctx);
        goto error_c;
    }

    if (fimc->m2m.refcnt++ == 0)
        set_bit(ST_M2M_RUN, &fimc->state);

    ret = fimc_m2m_set_default_format(ctx);
    if (ret < 0)
        goto error_m2m_ctx;

    mutex_unlock(&fimc->lock);
    return 0;

error_m2m_ctx:
    v4l2_m2m_ctx_release(ctx->m2m_ctx);
error_c:
    fimc_ctrls_delete(ctx);
error_fh:
    v4l2_fh_del(&ctx->fh);
    v4l2_fh_exit(&ctx->fh);
    kfree(ctx);
unlock:
    mutex_unlock(&fimc->lock);
    return ret;
}
Esempio n. 2
0
static int fimc_m2m_open(struct file *file)
{
	struct fimc_dev *fimc = video_drvdata(file);
	struct fimc_ctx *ctx;
	int ret = -EBUSY;

	dbg("pid: %d, state: 0x%lx, refcnt: %d",
	    task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);

	if (mutex_lock_interruptible(&fimc->lock))
		return -ERESTARTSYS;
	/*
	 * Return if the corresponding video capture node
	 * is already opened.
	 */
	if (fimc->vid_cap.refcnt > 0)
		goto unlock;

	ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
	if (!ctx) {
		ret = -ENOMEM;
		goto unlock;
	}
	v4l2_fh_init(&ctx->fh, fimc->m2m.vfd);
	ctx->fimc_dev = fimc;

	/* Default color format */
	ctx->s_frame.fmt = fimc_get_format(0);
	ctx->d_frame.fmt = fimc_get_format(0);

	ret = fimc_ctrls_create(ctx);
	if (ret)
		goto error_fh;

	/* Use separate control handler per file handle */
	ctx->fh.ctrl_handler = &ctx->ctrls.handler;
	file->private_data = &ctx->fh;
	v4l2_fh_add(&ctx->fh);

	/* Setup the device context for memory-to-memory mode */
	ctx->state = FIMC_CTX_M2M;
	ctx->flags = 0;
	ctx->in_path = FIMC_IO_DMA;
	ctx->out_path = FIMC_IO_DMA;

	ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
	if (IS_ERR(ctx->m2m_ctx)) {
		ret = PTR_ERR(ctx->m2m_ctx);
		goto error_c;
	}

	if (fimc->m2m.refcnt++ == 0)
		set_bit(ST_M2M_RUN, &fimc->state);

	mutex_unlock(&fimc->lock);
	return 0;

error_c:
	fimc_ctrls_delete(ctx);
error_fh:
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);
unlock:
	mutex_unlock(&fimc->lock);
	return ret;
}