예제 #1
0
파일: gsc-m2m.c 프로젝트: hedongjie/m35x
static int gsc_m2m_release(struct file *file)
{
	struct gsc_ctx *ctx = fh_to_ctx(file->private_data);
	struct gsc_dev *gsc = ctx->gsc_dev;

	gsc_dbg("pid: %d, state: 0x%lx, refcnt= %d",
		task_pid_nr(current), gsc->state, gsc->m2m.refcnt);

	/* if we didn't properly sequence with the secure side to turn off
	 * content protection, we may be left in a very bad state and the
	 * only way to recover this reliably is to reboot.
	 */
	BUG_ON(gsc->protected_content);

	kfree(ctx->m2m_ctx->cap_q_ctx.q.name);
	kfree(ctx->m2m_ctx->out_q_ctx.q.name);
	v4l2_m2m_ctx_release(ctx->m2m_ctx);
	gsc_ctrls_delete(ctx);
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);

	if (--gsc->m2m.refcnt <= 0)
		clear_bit(ST_M2M_OPEN, &gsc->state);
	kfree(ctx);
	return 0;
}
예제 #2
0
파일: hva-v4l2.c 프로젝트: acton393/linux
static int hva_release(struct file *file)
{
	struct hva_ctx *ctx = fh_to_ctx(file->private_data);
	struct hva_dev *hva = ctx_to_hdev(ctx);
	struct device *dev = ctx_to_dev(ctx);
	const struct hva_enc *enc = ctx->enc;

	if (enc) {
		dev_dbg(dev, "%s %s encoder closed\n", ctx->name, enc->name);
		enc->close(ctx);
		ctx->enc = NULL;

		/* clear instance context in instances array */
		hva->instances[ctx->id] = NULL;
		hva->nb_of_instances--;
	}

	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);

	v4l2_ctrl_handler_free(&ctx->ctrl_handler);

	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);

	dev_info(dev, "%s encoder instance released\n", ctx->name);

	kfree(ctx);

	return 0;
}
예제 #3
0
static int gsc_m2m_release(struct file *file)
{
	struct gsc_ctx *ctx = fh_to_ctx(file->private_data);
	struct gsc_dev *gsc = ctx->gsc_dev;

	gsc_dbg("pid: %d, state: 0x%lx, refcnt= %d",
		task_pid_nr(current), gsc->state, gsc->m2m.refcnt);

	v4l2_m2m_ctx_release(ctx->m2m_ctx);
	gsc_ctrls_delete(ctx);
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);

	if (--gsc->m2m.refcnt <= 0)
		clear_bit(ST_M2M_OPEN, &gsc->state);

	/* This is unnormal case */
	if (gsc->protected_content) {
		int id = gsc->id + 3;
		gsc_err("DRM should be disabled before device close");
		exynos_smc(SMC_PROTECTION_SET, 0, id, 0);
		gsc_set_protected_content(gsc, false);
	}

	kfree(ctx);
	return 0;
}
예제 #4
0
파일: bdisp-v4l2.c 프로젝트: AK101111/linux
static int bdisp_release(struct file *file)
{
	struct bdisp_ctx *ctx = fh_to_ctx(file->private_data);
	struct bdisp_dev *bdisp = ctx->bdisp_dev;

	dev_dbg(bdisp->dev, "%s\n", __func__);

	if (mutex_lock_interruptible(&bdisp->lock))
		return -ERESTARTSYS;

	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);

	bdisp_ctrls_delete(ctx);

	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);

	if (--bdisp->m2m.refcnt <= 0)
		clear_bit(ST_M2M_OPEN, &bdisp->state);

	bdisp_hw_free_nodes(ctx);

	kfree(ctx);

	mutex_unlock(&bdisp->lock);

	return 0;
}
예제 #5
0
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;
}
예제 #6
0
static int rockchip_vpu_open(struct file *filp)
{
	struct rockchip_vpu_dev *vpu = video_drvdata(filp);
	struct video_device *vdev = video_devdata(filp);
	struct rockchip_vpu_ctx *ctx;
	int ret;

	/*
	 * We do not need any extra locking here, because we operate only
	 * on local data here, except reading few fields from dev, which
	 * do not change through device's lifetime (which is guaranteed by
	 * reference on module from open()) and V4L2 internal objects (such
	 * as vdev and ctx->fh), which have proper locking done in respective
	 * helper functions used here.
	 */

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	ctx->dev = vpu;
	if (vdev == vpu->vfd_enc)
		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx,
						    &enc_queue_init);
	else
		ctx->fh.m2m_ctx = ERR_PTR(-ENODEV);
	if (IS_ERR(ctx->fh.m2m_ctx)) {
		ret = PTR_ERR(ctx->fh.m2m_ctx);
		kfree(ctx);
		return ret;
	}

	v4l2_fh_init(&ctx->fh, vdev);
	filp->private_data = &ctx->fh;
	v4l2_fh_add(&ctx->fh);

	if (vdev == vpu->vfd_enc) {
		rockchip_vpu_enc_reset_dst_fmt(vpu, ctx);
		rockchip_vpu_enc_reset_src_fmt(vpu, ctx);
	}

	ret = rockchip_vpu_ctrls_setup(vpu, ctx);
	if (ret) {
		vpu_err("Failed to set up controls\n");
		goto err_fh_free;
	}
	ctx->fh.ctrl_handler = &ctx->ctrl_handler;

	return 0;

err_fh_free:
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);
	return ret;
}
예제 #7
0
static int s5p_jpeg_open(struct file *file)
{
	struct s5p_jpeg *jpeg = video_drvdata(file);
	struct video_device *vfd = video_devdata(file);
	struct s5p_jpeg_ctx *ctx;
	struct s5p_jpeg_fmt *out_fmt;
	int ret = 0;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	if (mutex_lock_interruptible(&jpeg->lock)) {
		ret = -ERESTARTSYS;
		goto free;
	}

	v4l2_fh_init(&ctx->fh, vfd);
	/* 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->jpeg = jpeg;
	if (vfd == jpeg->vfd_encoder) {
		ctx->mode = S5P_JPEG_ENCODE;
		out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_RGB565);
	} else {
		ctx->mode = S5P_JPEG_DECODE;
		out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_JPEG);
	}

	ret = s5p_jpeg_controls_create(ctx);
	if (ret < 0)
		goto error;

	ctx->m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
	if (IS_ERR(ctx->m2m_ctx)) {
		ret = PTR_ERR(ctx->m2m_ctx);
		goto error;
	}

	ctx->out_q.fmt = out_fmt;
	ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV);
	mutex_unlock(&jpeg->lock);
	return 0;

error:
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	mutex_unlock(&jpeg->lock);
free:
	kfree(ctx);
	return ret;
}
예제 #8
0
int v4l2_fh_release(struct file *filp)
{
	struct v4l2_fh *fh = filp->private_data;

	if (fh) {
		v4l2_fh_del(fh);
		v4l2_fh_exit(fh);
		kfree(fh);
	}
	return 0;
}
예제 #9
0
static int subdev_open(struct file *file)
{
    struct video_device *vdev = video_devdata(file);
    struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
    struct v4l2_subdev_fh *subdev_fh;
#if defined(CONFIG_MEDIA_CONTROLLER)
    struct media_entity *entity = NULL;
#endif
    int ret;

    subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL);
    if (subdev_fh == NULL)
        return -ENOMEM;

    ret = subdev_fh_init(subdev_fh, sd);
    if (ret) {
        kfree(subdev_fh);
        return ret;
    }

    v4l2_fh_init(&subdev_fh->vfh, vdev);
    v4l2_fh_add(&subdev_fh->vfh);
    file->private_data = &subdev_fh->vfh;
#if defined(CONFIG_MEDIA_CONTROLLER)
    if (sd->v4l2_dev->mdev) {
        entity = media_entity_get(&sd->entity);
        if (!entity) {
            ret = -EBUSY;
            goto err;
        }
    }
#endif

    if (sd->internal_ops && sd->internal_ops->open) {
        ret = sd->internal_ops->open(sd, subdev_fh);
        if (ret < 0)
            goto err;
    }

    return 0;

err:
#if defined(CONFIG_MEDIA_CONTROLLER)
    if (entity)
        media_entity_put(entity);
#endif
    v4l2_fh_del(&subdev_fh->vfh);
    v4l2_fh_exit(&subdev_fh->vfh);
    subdev_fh_free(subdev_fh);
    kfree(subdev_fh);

    return ret;
}
예제 #10
0
static int s5p_jpeg_release(struct file *file)
{
	struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);

	v4l2_m2m_ctx_release(ctx->m2m_ctx);
	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);

	return 0;
}
static int camera_v4l2_fh_release(struct file *filep)
{
	struct camera_v4l2_private *sp = fh_to_private(filep->private_data);

	if (sp) {
		v4l2_fh_del(&sp->fh);
		v4l2_fh_exit(&sp->fh);
	}

	kzfree(sp);
	return 0;
}
예제 #12
0
파일: g2d.c 프로젝트: 7799/linux
static int g2d_release(struct file *file)
{
	struct g2d_dev *dev = video_drvdata(file);
	struct g2d_ctx *ctx = fh2ctx(file->private_data);

	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);
	v4l2_info(&dev->v4l2_dev, "instance closed\n");
	return 0;
}
예제 #13
0
static int s5p_jpeg_release(struct file *file)
{
	struct s5p_jpeg *jpeg = video_drvdata(file);
	struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);

	mutex_lock(&jpeg->lock);
	v4l2_m2m_ctx_release(ctx->m2m_ctx);
	mutex_unlock(&jpeg->lock);
	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);

	return 0;
}
예제 #14
0
/*
 * msm_jpegdma_open - Fd device open method.
 * @file: Pointer to file struct.
 */
static int msm_jpegdma_open(struct file *file)
{
	struct msm_jpegdma_device *device = video_drvdata(file);
	struct video_device *video = video_devdata(file);
	struct jpegdma_ctx *ctx;
	int ret;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	mutex_init(&ctx->lock);
	ctx->jdma_device = device;
	dev_dbg(ctx->jdma_device->dev, "Jpeg v4l2 dma open\n");
	/* Set ctx defaults */
	ctx->timeperframe.numerator = 1;
	ctx->timeperframe.denominator = MSM_JPEGDMA_DEFAULT_FPS;
	atomic_set(&ctx->active, 0);

	v4l2_fh_init(&ctx->fh, video);

	file->private_data = &ctx->fh;
	v4l2_fh_add(&ctx->fh);

	ctx->m2m_ctx = v4l2_m2m_ctx_init(device->m2m_dev,
		ctx, msm_jpegdma_queue_init);
	if (IS_ERR_OR_NULL(ctx->m2m_ctx)) {
		ret = PTR_ERR(ctx->m2m_ctx);
		goto error_m2m_init;
	}
	init_completion(&ctx->completion);
	complete_all(&ctx->completion);
	dev_dbg(ctx->jdma_device->dev, "Jpeg v4l2 dma open success\n");

	ret = cam_config_ahb_clk(CAM_AHB_CLIENT_JPEG, CAMERA_AHB_SVS_VOTE);
	if (ret < 0) {
		pr_err("%s: failed to vote for AHB\n", __func__);
		goto error_m2m_init;
	}

	return 0;

error_m2m_init:
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);
	return ret;
}
예제 #15
0
static int rockchip_vpu_release(struct file *filp)
{
	struct rockchip_vpu_ctx *ctx =
		container_of(filp->private_data, struct rockchip_vpu_ctx, fh);

	/*
	 * No need for extra locking because this was the last reference
	 * to this file.
	 */
	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
	kfree(ctx);

	return 0;
}
예제 #16
0
/*
 * msm_jpegdma_release - Fd device release method.
 * @file: Pointer to file struct.
 */
static int msm_jpegdma_release(struct file *file)
{
	struct jpegdma_ctx *ctx = msm_jpegdma_ctx_from_fh(file->private_data);

	atomic_set(&ctx->active, 0);
	complete_all(&ctx->completion);
	v4l2_m2m_ctx_release(ctx->m2m_ctx);
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);

	if (cam_config_ahb_clk(CAM_AHB_CLIENT_JPEG,
		CAMERA_AHB_SUSPEND_VOTE) < 0)
		pr_err("%s: failed to remove vote for AHB\n", __func__);

	return 0;
}
예제 #17
0
static int gsc_m2m_release(struct file *file)
{
	struct gsc_ctx *ctx = fh_to_ctx(file->private_data);
	struct gsc_dev *gsc = ctx->gsc_dev;

	gsc_dbg("pid: %d, state: 0x%lx, refcnt= %d",
		task_pid_nr(current), gsc->state, gsc->m2m.refcnt);

	v4l2_m2m_ctx_release(ctx->m2m_ctx);
	gsc_ctrls_delete(ctx);
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);

	if (--gsc->m2m.refcnt <= 0)
		clear_bit(ST_M2M_OPEN, &gsc->state);
	kfree(ctx);
	return 0;
}
예제 #18
0
static int subdev_close(struct file *file)
{
	struct video_device *vdev = video_devdata(file);
	struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
	struct v4l2_fh *vfh = file->private_data;
	struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);

	v4l2_subdev_call(sd, file, close, subdev_fh);
#if defined(CONFIG_MEDIA_CONTROLLER)
	if (sd->v4l2_dev->mdev)
		media_entity_put(&sd->entity);
#endif
	v4l2_fh_del(vfh);
	v4l2_fh_exit(vfh);
	subdev_fh_free(subdev_fh);
	kfree(subdev_fh);
	file->private_data = NULL;

	return 0;
}
예제 #19
0
static int
hwcam_dev_vo_close(
        struct file* filep)
{
    hwcam_dev_t* cam = NULL;
    struct v4l2_fh* eq = NULL;

    cam = (hwcam_dev_t*)video_drvdata(filep);
    swap(filep->private_data, eq);
	BUG_ON(!cam || !eq);

	if (eq) {
        hwcam_cfgstream_intf_t* stm = NULL;
        hwcam_user_t* user = VO2USER(eq);

        swap(user->stream, stm);

        if (stm) {
            hwcam_cfgstream_intf_umount(stm);
            hwcam_cfgstream_intf_put(stm);
        }

        if (v4l2_fh_is_singular(eq)) {
            hwcam_cfgpipeline_intf_t* pl = NULL;
            swap(cam->pipeline, pl);
            if (pl) {
                hwcam_cfgpipeline_intf_umount(pl);
                hwcam_cfgpipeline_intf_put(pl);
            }
        }

        v4l2_fh_del(eq);
        v4l2_fh_exit(eq);
        HWCAM_CFG_INFO("hwcam_dev_vo_close");
        hwcam_user_intf_put(&user->intf);
	}

	return 0;
}
예제 #20
0
static int fimc_m2m_release(struct file *file)
{
    struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
    struct fimc_dev *fimc = ctx->fimc_dev;

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

    mutex_lock(&fimc->lock);

    v4l2_m2m_ctx_release(ctx->m2m_ctx);
    fimc_ctrls_delete(ctx);
    v4l2_fh_del(&ctx->fh);
    v4l2_fh_exit(&ctx->fh);

    if (--fimc->m2m.refcnt <= 0)
        clear_bit(ST_M2M_RUN, &fimc->state);
    kfree(ctx);

    mutex_unlock(&fimc->lock);
    return 0;
}
예제 #21
0
/*
 * msm_fd_release - Fd device release method.
 * @file: Pointer to file struct.
 */
static int msm_fd_release(struct file *file)
{
	struct fd_ctx *ctx = msm_fd_ctx_from_fh(file->private_data);

	vb2_queue_release(&ctx->vb2_q);

	vfree(ctx->stats);

	if (ctx->work_buf.handle)
		msm_fd_hw_unmap_buffer(&ctx->work_buf);

	iommu_detach_device(ctx->fd_device->iommu_domain,
		ctx->fd_device->iommu_dev);
	ion_client_destroy(ctx->mem_pool.client);

	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);

	kfree(ctx);

	return 0;
}
예제 #22
0
static int
uvc_v4l2_release(struct file *file)
{
	struct video_device *vdev = video_devdata(file);
	struct uvc_device *uvc = video_get_drvdata(vdev);
	struct uvc_file_handle *handle = to_uvc_file_handle(file->private_data);
	struct uvc_video *video = handle->device;

	uvc_function_disconnect(uvc);

	uvc_video_enable(video, 0);
	mutex_lock(&video->queue.mutex);
	if (uvc_free_buffers(&video->queue) < 0)
		printk(KERN_ERR "uvc_v4l2_release: Unable to free "
				"buffers.\n");
	mutex_unlock(&video->queue.mutex);

	file->private_data = NULL;
	v4l2_fh_del(&handle->vfh);
	v4l2_fh_exit(&handle->vfh);
	kfree(handle);
	return 0;
}
예제 #23
0
static int hva_release(struct file *file)
{
	struct hva_ctx *ctx = fh_to_ctx(file->private_data);
	struct hva_dev *hva = ctx_to_hdev(ctx);
	struct device *dev = ctx_to_dev(ctx);
	const struct hva_enc *enc = ctx->enc;

	if (enc) {
		dev_dbg(dev, "%s %s encoder closed\n", ctx->name, enc->name);
		enc->close(ctx);
		ctx->enc = NULL;

		/* clear instance context in instances array */
		hva->instances[ctx->id] = NULL;
		hva->nb_of_instances--;
	}

	/* trace a summary of instance before closing (debug purpose) */
	hva_dbg_summary(ctx);

	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);

	v4l2_ctrl_handler_free(&ctx->ctrl_handler);

	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);

#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
	hva_dbg_ctx_remove(ctx);
#endif

	dev_info(dev, "%s encoder instance released\n", ctx->name);

	kfree(ctx);

	return 0;
}
예제 #24
0
static int
uvc_v4l2_open(struct file *file)
{
	struct video_device *vdev = video_devdata(file);
	struct uvc_device *uvc = video_get_drvdata(vdev);
	struct uvc_file_handle *handle;
	int ret;

	handle = kzalloc(sizeof(*handle), GFP_KERNEL);
	if (handle == NULL)
		return -ENOMEM;

	ret = v4l2_fh_init(&handle->vfh, vdev);
	if (ret < 0)
		goto error;

	ret = v4l2_event_init(&handle->vfh);
	if (ret < 0)
		goto error;

	ret = v4l2_event_alloc(&handle->vfh, 8);
	if (ret < 0)
		goto error;

	v4l2_fh_add(&handle->vfh);

	handle->device = &uvc->video;
	file->private_data = &handle->vfh;

	uvc_function_connect(uvc);
	return 0;

error:
	v4l2_fh_exit(&handle->vfh);
	return ret;
}
예제 #25
0
static int subdev_open(struct file *file)
{
	struct video_device *vdev = video_devdata(file);
	struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
	struct v4l2_subdev_fh *subdev_fh;
#if defined(CONFIG_MEDIA_CONTROLLER)
	struct media_entity *entity = NULL;
#endif
	int ret;

	if (!sd->initialized)
		return -EAGAIN;

	subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL);
	if (subdev_fh == NULL)
		return -ENOMEM;

	ret = subdev_fh_init(subdev_fh, sd);
	if (ret) {
		kfree(subdev_fh);
		return ret;
	}

	ret = v4l2_fh_init(&subdev_fh->vfh, vdev);
	if (ret)
		goto err;

	if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) {
		ret = v4l2_event_init(&subdev_fh->vfh);
		if (ret)
			goto err;

		ret = v4l2_event_alloc(&subdev_fh->vfh, sd->nevents);
		if (ret)
			goto err;
	}

	v4l2_fh_add(&subdev_fh->vfh);
	file->private_data = &subdev_fh->vfh;
#if defined(CONFIG_MEDIA_CONTROLLER)
	if (sd->v4l2_dev->mdev) {
		entity = media_entity_get(&sd->entity);
		if (!entity) {
			ret = -EBUSY;
			goto err;
		}
	}
#endif

	ret = v4l2_subdev_call(sd, file, open, subdev_fh);
	if (ret < 0 && ret != -ENOIOCTLCMD)
		goto err;

	return 0;

err:
#if defined(CONFIG_MEDIA_CONTROLLER)
	if (entity)
		media_entity_put(entity);
#endif
	v4l2_fh_del(&subdev_fh->vfh);
	v4l2_fh_exit(&subdev_fh->vfh);
	subdev_fh_free(subdev_fh);
	kfree(subdev_fh);

	return ret;
}
예제 #26
0
static int gsc_m2m_open(struct file *file)
{
	struct gsc_dev *gsc = video_drvdata(file);
	struct gsc_ctx *ctx = NULL;
	int ret;

	pr_debug("pid: %d, state: 0x%lx", task_pid_nr(current), gsc->state);

	if (mutex_lock_interruptible(&gsc->lock))
		return -ERESTARTSYS;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx) {
		ret = -ENOMEM;
		goto unlock;
	}

	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;

	ctx->m2m_ctx = v4l2_m2m_ctx_init(gsc->m2m.m2m_dev, ctx, queue_init);
	if (IS_ERR(ctx->m2m_ctx)) {
		pr_err("Failed to initialize m2m context");
		ret = PTR_ERR(ctx->m2m_ctx);
		goto error_ctrls;
	}

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

	pr_debug("gsc m2m driver is opened, ctx(0x%p)", ctx);

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

error_ctrls:
	gsc_ctrls_delete(ctx);
	v4l2_fh_del(&ctx->fh);
error_fh:
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);
unlock:
	mutex_unlock(&gsc->lock);
	return ret;
}
예제 #27
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;
}
예제 #28
0
int ivtv_v4l2_close(struct file *filp)
{
	struct v4l2_fh *fh = filp->private_data;
	struct ivtv_open_id *id = fh2id(fh);
	struct ivtv *itv = id->itv;
	struct ivtv_stream *s = &itv->streams[id->type];

	IVTV_DEBUG_FILE("close %s\n", s->name);

	mutex_lock(&itv->serialize_lock);

	/* Stop radio */
	if (id->type == IVTV_ENC_STREAM_TYPE_RAD &&
			v4l2_fh_is_singular_file(filp)) {
		/* Closing radio device, return to TV mode */
		ivtv_mute(itv);
		/* Mark that the radio is no longer in use */
		clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
		/* Switch tuner to TV */
		ivtv_call_all(itv, video, s_std, itv->std);
		/* Select correct audio input (i.e. TV tuner or Line in) */
		ivtv_audio_set_io(itv);
		if (itv->hw_flags & IVTV_HW_SAA711X) {
			ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
					SAA7115_FREQ_32_11_MHZ, 0);
		}
		if (atomic_read(&itv->capturing) > 0) {
			/* Undo video mute */
			ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
					v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) |
					(v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));
		}
		/* Done! Unmute and continue. */
		ivtv_unmute(itv);
	}

	v4l2_fh_del(fh);
	v4l2_fh_exit(fh);

	/* Easy case first: this stream was never claimed by us */
	if (s->fh != &id->fh)
		goto close_done;

	/* 'Unclaim' this stream */

	if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
		struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT];

		ivtv_stop_decoding(id, V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);

		/* If all output streams are closed, and if the user doesn't have
		   IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */
		if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) {
			/* disable CC on TV-out */
			ivtv_disable_cc(itv);
		}
	} else {
		ivtv_stop_capture(id, 0);
	}
close_done:
	kfree(id);
	mutex_unlock(&itv->serialize_lock);
	return 0;
}
예제 #29
0
파일: bdisp-v4l2.c 프로젝트: AK101111/linux
static int bdisp_open(struct file *file)
{
	struct bdisp_dev *bdisp = video_drvdata(file);
	struct bdisp_ctx *ctx = NULL;
	int ret;

	if (mutex_lock_interruptible(&bdisp->lock))
		return -ERESTARTSYS;

	/* Allocate memory for both context and node */
	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx) {
		ret = -ENOMEM;
		goto unlock;
	}
	ctx->bdisp_dev = bdisp;

	if (bdisp_hw_alloc_nodes(ctx)) {
		dev_err(bdisp->dev, "no memory for nodes\n");
		ret = -ENOMEM;
		goto mem_ctx;
	}

	v4l2_fh_init(&ctx->fh, bdisp->m2m.vdev);

	ret = bdisp_ctrls_create(ctx);
	if (ret) {
		dev_err(bdisp->dev, "Failed to create control\n");
		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);

	/* Default format */
	ctx->src = bdisp_dflt_fmt;
	ctx->dst = bdisp_dflt_fmt;

	/* Setup the device context for mem2mem mode. */
	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(bdisp->m2m.m2m_dev, ctx,
					    queue_init);
	if (IS_ERR(ctx->fh.m2m_ctx)) {
		dev_err(bdisp->dev, "Failed to initialize m2m context\n");
		ret = PTR_ERR(ctx->fh.m2m_ctx);
		goto error_ctrls;
	}

	bdisp->m2m.refcnt++;
	set_bit(ST_M2M_OPEN, &bdisp->state);

	dev_dbg(bdisp->dev, "driver opened, ctx = 0x%p\n", ctx);

	mutex_unlock(&bdisp->lock);

	return 0;

error_ctrls:
	bdisp_ctrls_delete(ctx);
error_fh:
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	bdisp_hw_free_nodes(ctx);
mem_ctx:
	kfree(ctx);
unlock:
	mutex_unlock(&bdisp->lock);

	return ret;
}
예제 #30
0
static int ivtv_open(struct file *filp)
{
	struct video_device *vdev = video_devdata(filp);
	struct ivtv_stream *s = video_get_drvdata(vdev);
	struct ivtv *itv = s->itv;
	struct ivtv_open_id *item;
	int res = 0;

	IVTV_DEBUG_FILE("open %s\n", s->name);

	if (ivtv_init_on_first_open(itv)) {
		IVTV_ERR("Failed to initialize on device %s\n",
			 video_device_node_name(vdev));
		return -ENXIO;
	}

#ifdef CONFIG_VIDEO_ADV_DEBUG
	/* Unless ivtv_fw_debug is set, error out if firmware dead. */
	if (ivtv_fw_debug) {
		IVTV_WARN("Opening %s with dead firmware lockout disabled\n",
			  video_device_node_name(vdev));
		IVTV_WARN("Selected firmware errors will be ignored\n");
	} else {
#else
	if (1) {
#endif
		res = ivtv_firmware_check(itv, "ivtv_serialized_open");
		if (res == -EAGAIN)
			res = ivtv_firmware_check(itv, "ivtv_serialized_open");
		if (res < 0)
			return -EIO;
	}

	if (s->type == IVTV_DEC_STREAM_TYPE_MPG &&
		test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags))
		return -EBUSY;

	if (s->type == IVTV_DEC_STREAM_TYPE_YUV &&
		test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags))
		return -EBUSY;

	if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
		if (read_reg(0x82c) == 0) {
			IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n");
			/* return -ENODEV; */
		}
		ivtv_udma_alloc(itv);
	}

	/* Allocate memory */
	item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL);
	if (NULL == item) {
		IVTV_DEBUG_WARN("nomem on v4l2 open\n");
		return -ENOMEM;
	}
	v4l2_fh_init(&item->fh, &s->vdev);
	item->itv = itv;
	item->type = s->type;

	filp->private_data = &item->fh;
	v4l2_fh_add(&item->fh);

	if (item->type == IVTV_ENC_STREAM_TYPE_RAD &&
			v4l2_fh_is_singular_file(filp)) {
		if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
			if (atomic_read(&itv->capturing) > 0) {
				/* switching to radio while capture is
				   in progress is not polite */
				v4l2_fh_del(&item->fh);
				v4l2_fh_exit(&item->fh);
				kfree(item);
				return -EBUSY;
			}
		}
		/* Mark that the radio is being used. */
		set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
		/* We have the radio */
		ivtv_mute(itv);
		/* Switch tuner to radio */
		ivtv_call_all(itv, tuner, s_radio);
		/* Select the correct audio input (i.e. radio tuner) */
		ivtv_audio_set_io(itv);
		if (itv->hw_flags & IVTV_HW_SAA711X) {
			ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
				SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL);
		}
		/* Done! Unmute and continue. */
		ivtv_unmute(itv);
	}

	/* YUV or MPG Decoding Mode? */
	if (s->type == IVTV_DEC_STREAM_TYPE_MPG) {
		clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
	} else if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
		set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
		/* For yuv, we need to know the dma size before we start */
		itv->dma_data_req_size =
				1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
		itv->yuv_info.stream_size = 0;
	}
	return 0;
}

int ivtv_v4l2_open(struct file *filp)
{
	struct video_device *vdev = video_devdata(filp);
	int res;

	if (mutex_lock_interruptible(vdev->lock))
		return -ERESTARTSYS;
	res = ivtv_open(filp);
	mutex_unlock(vdev->lock);
	return res;
}

void ivtv_mute(struct ivtv *itv)
{
	if (atomic_read(&itv->capturing))
		ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 1);
	IVTV_DEBUG_INFO("Mute\n");
}

void ivtv_unmute(struct ivtv *itv)
{
	if (atomic_read(&itv->capturing)) {
		ivtv_msleep_timeout(100, 0);
		ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
		ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0);
	}
	IVTV_DEBUG_INFO("Unmute\n");
}