示例#1
0
static int iss_video_release(struct file *file)
{
	struct iss_video *video = video_drvdata(file);
	struct v4l2_fh *vfh = file->private_data;
	struct iss_video_fh *handle = to_iss_video_fh(vfh);

	/* Disable streaming and free the buffers queue resources. */
	iss_video_streamoff(file, vfh, video->type);

	omap4iss_pipeline_pm_use(&video->video.entity, 0);

	/* Release the videobuf2 queue */
	vb2_queue_release(&handle->queue);

	/* Release the file handle. */
	v4l2_fh_del(vfh);
	kfree(handle);
	file->private_data = NULL;

	omap4iss_put(video->iss);

	return 0;
}
示例#2
0
文件: iss.c 项目: a2hojsjsjs/linux
static int iss_probe(struct platform_device *pdev)
{
	struct iss_platform_data *pdata = pdev->dev.platform_data;
	struct iss_device *iss;
	unsigned int i;
	int ret;

	if (!pdata)
		return -EINVAL;

	iss = devm_kzalloc(&pdev->dev, sizeof(*iss), GFP_KERNEL);
	if (!iss)
		return -ENOMEM;

	mutex_init(&iss->iss_mutex);

	iss->dev = &pdev->dev;
	iss->pdata = pdata;

	iss->raw_dmamask = DMA_BIT_MASK(32);
	iss->dev->dma_mask = &iss->raw_dmamask;
	iss->dev->coherent_dma_mask = DMA_BIT_MASK(32);

	platform_set_drvdata(pdev, iss);

	/*
	 * TODO: When implementing DT support switch to syscon regmap lookup by
	 * phandle.
	 */
	iss->syscon = syscon_regmap_lookup_by_compatible("syscon");
	if (IS_ERR(iss->syscon)) {
		ret = PTR_ERR(iss->syscon);
		goto error;
	}

	/* Clocks */
	ret = iss_map_mem_resource(pdev, iss, OMAP4_ISS_MEM_TOP);
	if (ret < 0)
		goto error;

	ret = iss_get_clocks(iss);
	if (ret < 0)
		goto error;

	if (!omap4iss_get(iss))
		goto error;

	ret = iss_reset(iss);
	if (ret < 0)
		goto error_iss;

	iss->revision = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION);
	dev_info(iss->dev, "Revision %08x found\n", iss->revision);

	for (i = 1; i < OMAP4_ISS_MEM_LAST; i++) {
		ret = iss_map_mem_resource(pdev, iss, i);
		if (ret)
			goto error_iss;
	}

	/* Configure BTE BW_LIMITER field to max recommended value (1 GB) */
	iss_reg_update(iss, OMAP4_ISS_MEM_BTE, BTE_CTRL,
		       BTE_CTRL_BW_LIMITER_MASK,
		       18 << BTE_CTRL_BW_LIMITER_SHIFT);

	/* Perform ISP reset */
	ret = omap4iss_subclk_enable(iss, OMAP4_ISS_SUBCLK_ISP);
	if (ret < 0)
		goto error_iss;

	ret = iss_isp_reset(iss);
	if (ret < 0)
		goto error_iss;

	dev_info(iss->dev, "ISP Revision %08x found\n",
		 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_REVISION));

	/* Interrupt */
	ret = platform_get_irq(pdev, 0);
	if (ret <= 0) {
		dev_err(iss->dev, "No IRQ resource\n");
		ret = -ENODEV;
		goto error_iss;
	}
	iss->irq_num = ret;

	if (devm_request_irq(iss->dev, iss->irq_num, iss_isr, IRQF_SHARED,
			     "OMAP4 ISS", iss)) {
		dev_err(iss->dev, "Unable to request IRQ\n");
		ret = -EINVAL;
		goto error_iss;
	}

	/* Entities */
	ret = iss_initialize_modules(iss);
	if (ret < 0)
		goto error_iss;

	ret = iss_register_entities(iss);
	if (ret < 0)
		goto error_modules;

	ret = media_entity_enum_init(&iss->crashed, &iss->media_dev);
	if (ret)
		goto error_entities;

	ret = iss_create_links(iss);
	if (ret < 0)
		goto error_entities;

	omap4iss_put(iss);

	return 0;

error_entities:
	iss_unregister_entities(iss);
	media_entity_enum_cleanup(&iss->crashed);
error_modules:
	iss_cleanup_modules(iss);
error_iss:
	omap4iss_put(iss);
error:
	platform_set_drvdata(pdev, NULL);

	mutex_destroy(&iss->iss_mutex);

	return ret;
}
示例#3
0
static int iss_video_open(struct file *file)
{
	struct iss_video *video = video_drvdata(file);
	struct iss_video_fh *handle;
	struct vb2_queue *q;
	int ret = 0;

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

	v4l2_fh_init(&handle->vfh, &video->video);
	v4l2_fh_add(&handle->vfh);

	/* If this is the first user, initialise the pipeline. */
	if (omap4iss_get(video->iss) == NULL) {
		ret = -EBUSY;
		goto done;
	}

	ret = omap4iss_pipeline_pm_use(&video->video.entity, 1);
	if (ret < 0) {
		omap4iss_put(video->iss);
		goto done;
	}

	video->alloc_ctx = vb2_dma_contig_init_ctx(video->iss->dev);
	if (IS_ERR(video->alloc_ctx)) {
		ret = PTR_ERR(video->alloc_ctx);
		omap4iss_put(video->iss);
		goto done;
	}

	q = &handle->queue;

	q->type = video->type;
	q->io_modes = VB2_MMAP;
	q->drv_priv = handle;
	q->ops = &iss_video_vb2ops;
	q->mem_ops = &vb2_dma_contig_memops;
	q->buf_struct_size = sizeof(struct iss_buffer);
	q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;

	ret = vb2_queue_init(q);
	if (ret) {
		omap4iss_put(video->iss);
		goto done;
	}

	memset(&handle->format, 0, sizeof(handle->format));
	handle->format.type = video->type;
	handle->timeperframe.denominator = 1;

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

done:
	if (ret < 0) {
		v4l2_fh_del(&handle->vfh);
		kfree(handle);
	}

	return ret;
}
示例#4
0
static int iss_probe(struct platform_device *pdev)
{
	struct iss_platform_data *pdata = pdev->dev.platform_data;
	struct iss_device *iss;
	unsigned int i;
	int ret;

	if (pdata == NULL)
		return -EINVAL;

	iss = devm_kzalloc(&pdev->dev, sizeof(*iss), GFP_KERNEL);
	if (!iss) {
		dev_err(&pdev->dev, "Could not allocate memory\n");
		return -ENOMEM;
	}

	mutex_init(&iss->iss_mutex);

	iss->dev = &pdev->dev;
	iss->pdata = pdata;

	iss->raw_dmamask = DMA_BIT_MASK(32);
	iss->dev->dma_mask = &iss->raw_dmamask;
	iss->dev->coherent_dma_mask = DMA_BIT_MASK(32);

	platform_set_drvdata(pdev, iss);

	/* Clocks */
	ret = iss_map_mem_resource(pdev, iss, OMAP4_ISS_MEM_TOP);
	if (ret < 0)
		goto error;

	ret = iss_get_clocks(iss);
	if (ret < 0)
		goto error;

	if (omap4iss_get(iss) == NULL)
		goto error;

	ret = iss_reset(iss);
	if (ret < 0)
		goto error_iss;

	iss->revision = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION);
	dev_info(iss->dev, "Revision %08x found\n", iss->revision);

	for (i = 1; i < OMAP4_ISS_MEM_LAST; i++) {
		ret = iss_map_mem_resource(pdev, iss, i);
		if (ret)
			goto error_iss;
	}

	/* Configure BTE BW_LIMITER field to max recommended value (1 GB) */
	iss_reg_update(iss, OMAP4_ISS_MEM_BTE, BTE_CTRL,
		       BTE_CTRL_BW_LIMITER_MASK,
		       18 << BTE_CTRL_BW_LIMITER_SHIFT);

	/* Perform ISP reset */
	ret = omap4iss_subclk_enable(iss, OMAP4_ISS_SUBCLK_ISP);
	if (ret < 0)
		goto error_iss;

	ret = iss_isp_reset(iss);
	if (ret < 0)
		goto error_iss;

	dev_info(iss->dev, "ISP Revision %08x found\n",
		 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_REVISION));

	/* Interrupt */
	iss->irq_num = platform_get_irq(pdev, 0);
	if (iss->irq_num <= 0) {
		dev_err(iss->dev, "No IRQ resource\n");
		ret = -ENODEV;
		goto error_iss;
	}

	if (devm_request_irq(iss->dev, iss->irq_num, iss_isr, IRQF_SHARED,
			     "OMAP4 ISS", iss)) {
		dev_err(iss->dev, "Unable to request IRQ\n");
		ret = -EINVAL;
		goto error_iss;
	}

	/* Entities */
	ret = iss_initialize_modules(iss);
	if (ret < 0)
		goto error_iss;

	ret = iss_register_entities(iss);
	if (ret < 0)
		goto error_modules;

	omap4iss_put(iss);

	return 0;

error_modules:
	iss_cleanup_modules(iss);
error_iss:
	omap4iss_put(iss);
error:
	platform_set_drvdata(pdev, NULL);

	mutex_destroy(&iss->iss_mutex);

	return ret;
}