Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e623ebe6 authored by Robert Jarzmik's avatar Robert Jarzmik Committed by Mauro Carvalho Chehab
Browse files

[media] pxa_camera: move interrupt to tasklet



In preparation for dmaengine conversion, move the camera interrupt
handling into a tasklet. This won't change the global flow, as this
interrupt is only used to detect the end of frame and activate DMA fifos
handling.

Signed-off-by: default avatarRobert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 8f4895f2
Loading
Loading
Loading
Loading
+29 −15
Original line number Diff line number Diff line
@@ -223,6 +223,7 @@ struct pxa_camera_dev {

	struct pxa_buffer	*active;
	struct pxa_dma_desc	*sg_tail[3];
	struct tasklet_struct	task_eof;

	u32			save_cicr[5];
};
@@ -597,6 +598,7 @@ static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
	unsigned long cicr0;

	dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
	__raw_writel(__raw_readl(pcdev->base + CISR), pcdev->base + CISR);
	/* Enable End-Of-Frame Interrupt */
	cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
	cicr0 &= ~CICR0_EOFM;
@@ -914,23 +916,17 @@ static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
	clk_disable_unprepare(pcdev->clk);
}

static irqreturn_t pxa_camera_irq(int irq, void *data)
static void pxa_camera_eof(unsigned long arg)
{
	struct pxa_camera_dev *pcdev = data;
	unsigned long status, cifr, cicr0;
	struct pxa_camera_dev *pcdev = (struct pxa_camera_dev *)arg;
	unsigned long cifr;
	struct pxa_buffer *buf;
	struct videobuf_buffer *vb;

	status = __raw_readl(pcdev->base + CISR);
	dev_dbg(pcdev->soc_host.v4l2_dev.dev,
		"Camera interrupt status 0x%lx\n", status);

	if (!status)
		return IRQ_NONE;
		"Camera interrupt status 0x%x\n",
		__raw_readl(pcdev->base + CISR));

	__raw_writel(status, pcdev->base + CISR);

	if (status & CISR_EOF) {
	/* Reset the FIFOs */
	cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
	__raw_writel(cifr, pcdev->base + CIFR);
@@ -942,9 +938,26 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
	pxa_videobuf_set_actdma(pcdev, buf);

	pxa_dma_start_channels(pcdev);
}

static irqreturn_t pxa_camera_irq(int irq, void *data)
{
	struct pxa_camera_dev *pcdev = data;
	unsigned long status, cicr0;

	status = __raw_readl(pcdev->base + CISR);
	dev_dbg(pcdev->soc_host.v4l2_dev.dev,
		"Camera interrupt status 0x%lx\n", status);

	if (!status)
		return IRQ_NONE;

	__raw_writel(status, pcdev->base + CISR);

	if (status & CISR_EOF) {
		cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_EOFM;
		__raw_writel(cicr0, pcdev->base + CICR0);
		tasklet_schedule(&pcdev->task_eof);
	}

	return IRQ_HANDLED;
@@ -1839,6 +1852,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
	pcdev->soc_host.priv		= pcdev;
	pcdev->soc_host.v4l2_dev.dev	= &pdev->dev;
	pcdev->soc_host.nr		= pdev->id;
	tasklet_init(&pcdev->task_eof, pxa_camera_eof, (unsigned long)pcdev);

	err = soc_camera_host_register(&pcdev->soc_host);
	if (err)