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

[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
...@@ -223,6 +223,7 @@ struct pxa_camera_dev { ...@@ -223,6 +223,7 @@ struct pxa_camera_dev {
struct pxa_buffer *active; struct pxa_buffer *active;
struct pxa_dma_desc *sg_tail[3]; struct pxa_dma_desc *sg_tail[3];
struct tasklet_struct task_eof;
u32 save_cicr[5]; u32 save_cicr[5];
}; };
...@@ -597,6 +598,7 @@ static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev) ...@@ -597,6 +598,7 @@ static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
unsigned long cicr0; unsigned long cicr0;
dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__); 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 */ /* Enable End-Of-Frame Interrupt */
cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB; cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
cicr0 &= ~CICR0_EOFM; cicr0 &= ~CICR0_EOFM;
...@@ -914,13 +916,35 @@ static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev) ...@@ -914,13 +916,35 @@ static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
clk_disable_unprepare(pcdev->clk); 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; struct pxa_camera_dev *pcdev = (struct pxa_camera_dev *)arg;
unsigned long status, cifr, cicr0; unsigned long cifr;
struct pxa_buffer *buf; struct pxa_buffer *buf;
struct videobuf_buffer *vb; struct videobuf_buffer *vb;
dev_dbg(pcdev->soc_host.v4l2_dev.dev,
"Camera interrupt status 0x%x\n",
__raw_readl(pcdev->base + CISR));
/* Reset the FIFOs */
cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
__raw_writel(cifr, pcdev->base + CIFR);
pcdev->active = list_first_entry(&pcdev->capture,
struct pxa_buffer, vb.queue);
vb = &pcdev->active->vb;
buf = container_of(vb, struct pxa_buffer, vb);
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); status = __raw_readl(pcdev->base + CISR);
dev_dbg(pcdev->soc_host.v4l2_dev.dev, dev_dbg(pcdev->soc_host.v4l2_dev.dev,
"Camera interrupt status 0x%lx\n", status); "Camera interrupt status 0x%lx\n", status);
...@@ -931,20 +955,9 @@ static irqreturn_t pxa_camera_irq(int irq, void *data) ...@@ -931,20 +955,9 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
__raw_writel(status, pcdev->base + CISR); __raw_writel(status, pcdev->base + CISR);
if (status & CISR_EOF) { if (status & CISR_EOF) {
/* Reset the FIFOs */
cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
__raw_writel(cifr, pcdev->base + CIFR);
pcdev->active = list_first_entry(&pcdev->capture,
struct pxa_buffer, vb.queue);
vb = &pcdev->active->vb;
buf = container_of(vb, struct pxa_buffer, vb);
pxa_videobuf_set_actdma(pcdev, buf);
pxa_dma_start_channels(pcdev);
cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_EOFM; cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_EOFM;
__raw_writel(cicr0, pcdev->base + CICR0); __raw_writel(cicr0, pcdev->base + CICR0);
tasklet_schedule(&pcdev->task_eof);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -1839,6 +1852,7 @@ static int pxa_camera_probe(struct platform_device *pdev) ...@@ -1839,6 +1852,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
pcdev->soc_host.priv = pcdev; pcdev->soc_host.priv = pcdev;
pcdev->soc_host.v4l2_dev.dev = &pdev->dev; pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
pcdev->soc_host.nr = pdev->id; 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); err = soc_camera_host_register(&pcdev->soc_host);
if (err) if (err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment