drivers/media/pci/cobalt/cobalt-irq.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/cobalt/cobalt-irq.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/cobalt/cobalt-irq.c
Extension
.c
Size
7407 bytes
Lines
248
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

ioread32(&vmr->hactive_area) != s->timings.bt.width) {
			cobalt_dbg(1, "unstable\n");
			if (s->enable_freewheel)
				goto restart_fw;
			goto done;
		}
		if (!s->enable_cvi) {
			s->enable_cvi = true;
			iowrite32(M00389_CONTROL_BITMAP_ENABLE_MSK, &cvi->control);
			goto done;
		}
		if (!(ioread32(&cvi->status) & M00389_STATUS_BITMAP_LOCK_MSK)) {
			cobalt_dbg(1, "cvi no lock\n");
			if (s->enable_freewheel)
				goto restart_fw;
			goto done;
		}
		if (!s->enable_freewheel) {
			cobalt_dbg(1, "stable\n");
			s->enable_freewheel = true;
			iowrite32(0, &fw->ctrl);
			goto done;
		}
		cobalt_dbg(1, "enabled fw\n");
		iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK |
			  M00233_CONTROL_BITMAP_ENABLE_INTERRUPT_MSK,
			  &vmr->control);
		iowrite32(M00473_CTRL_BITMAP_ENABLE_MSK, &fw->ctrl);
		s->enable_freewheel = false;
		s->unstable_frame = false;
		s->skip_first_frames = 2;
		skip = true;
		goto done;
	}
	if (ioread32(&fw->status) & M00473_STATUS_BITMAP_FREEWHEEL_MODE_MSK) {
restart_fw:
		cobalt_dbg(1, "lost lock\n");
		iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK,
			  &vmr->control);
		iowrite32(M00473_CTRL_BITMAP_ENABLE_MSK |
			  M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK,
			  &fw->ctrl);
		iowrite32(0, &cvi->control);
		s->unstable_frame = true;
		s->enable_freewheel = false;
		s->enable_cvi = false;
	}
done:
	if (s->skip_first_frames) {
		skip = true;
		s->skip_first_frames--;
	}
	cb->vb.vb2_buf.timestamp = ktime_get_ns();
	/* TODO: the sequence number should be read from the FPGA so we
	   also know about dropped frames. */
	cb->vb.sequence = s->sequence++;
	vb2_buffer_done(&cb->vb.vb2_buf,
			(skip || s->unstable_frame) ?
			VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
}

irqreturn_t cobalt_irq_handler(int irq, void *dev_id)
{
	struct cobalt *cobalt = (struct cobalt *)dev_id;
	u32 dma_interrupt =
		cobalt_read_bar0(cobalt, DMA_INTERRUPT_STATUS_REG) & 0xffff;
	u32 mask = cobalt_read_bar1(cobalt, COBALT_SYS_STAT_MASK);
	u32 edge = cobalt_read_bar1(cobalt, COBALT_SYS_STAT_EDGE);
	int i;

	/* Clear DMA interrupt */
	cobalt_write_bar0(cobalt, DMA_INTERRUPT_STATUS_REG, dma_interrupt);
	cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, mask & ~edge);
	cobalt_write_bar1(cobalt, COBALT_SYS_STAT_EDGE, edge);

	for (i = 0; i < COBALT_NUM_STREAMS; i++) {
		struct cobalt_stream *s = &cobalt->streams[i];
		unsigned dma_fifo_mask = s->dma_fifo_mask;

		if (dma_interrupt & (1 << s->dma_channel)) {
			cobalt->irq_dma[i]++;
			/* Give fresh buffer to user and chain newly
			 * queued buffers */
			cobalt_dma_stream_queue_handler(s);
			if (!s->is_audio) {
				edge &= ~dma_fifo_mask;
				cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK,
						  mask & ~edge);
			}
		}

Annotation

Implementation Notes