drivers/media/platform/sunxi/sun8i-di/sun8i-di.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
Extension
.c
Size
25979 bytes
Lines
1012
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret < 0) {
			dev_err(dev, "Failed to enable module\n");

			goto err_runtime_get;
		}

		ctx->first_field =
			ctx->src_fmt.field == V4L2_FIELD_INTERLACED_BT;
		ctx->field = ctx->first_field;

		ctx->prev = NULL;
		ctx->aborting = 0;

		ctx->flag1_buf = dma_alloc_coherent(dev, FLAG_SIZE,
						    &ctx->flag1_buf_dma,
						    GFP_KERNEL);
		if (!ctx->flag1_buf) {
			ret = -ENOMEM;

			goto err_no_mem1;
		}

		ctx->flag2_buf = dma_alloc_coherent(dev, FLAG_SIZE,
						    &ctx->flag2_buf_dma,
						    GFP_KERNEL);
		if (!ctx->flag2_buf) {
			ret = -ENOMEM;

			goto err_no_mem2;
		}
	}

	return 0;

err_no_mem2:
	dma_free_coherent(dev, FLAG_SIZE, ctx->flag1_buf,
			  ctx->flag1_buf_dma);
err_no_mem1:
	pm_runtime_put(dev);
err_runtime_get:
	deinterlace_queue_cleanup(vq, VB2_BUF_STATE_QUEUED);

	return ret;
}

static void deinterlace_stop_streaming(struct vb2_queue *vq)
{
	struct deinterlace_ctx *ctx = vb2_get_drv_priv(vq);

	if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
		struct device *dev = ctx->dev->dev;

		dma_free_coherent(dev, FLAG_SIZE, ctx->flag1_buf,
				  ctx->flag1_buf_dma);
		dma_free_coherent(dev, FLAG_SIZE, ctx->flag2_buf,
				  ctx->flag2_buf_dma);

		pm_runtime_put(dev);
	}

	deinterlace_queue_cleanup(vq, VB2_BUF_STATE_ERROR);
}

static const struct vb2_ops deinterlace_qops = {
	.queue_setup		= deinterlace_queue_setup,
	.buf_prepare		= deinterlace_buf_prepare,
	.buf_queue		= deinterlace_buf_queue,
	.start_streaming	= deinterlace_start_streaming,
	.stop_streaming		= deinterlace_stop_streaming,
};

static int deinterlace_queue_init(void *priv, struct vb2_queue *src_vq,
				  struct vb2_queue *dst_vq)
{
	struct deinterlace_ctx *ctx = priv;
	int ret;

	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
	src_vq->drv_priv = ctx;
	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
	src_vq->min_queued_buffers = 1;
	src_vq->ops = &deinterlace_qops;
	src_vq->mem_ops = &vb2_dma_contig_memops;
	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
	src_vq->lock = &ctx->dev->dev_mutex;
	src_vq->dev = ctx->dev->dev;

	ret = vb2_queue_init(src_vq);
	if (ret)

Annotation

Implementation Notes