[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: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
Родитель
8f4895f2bd
Коммит
e623ebe6d9
|
@ -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)
|
||||||
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,12 +916,34 @@ static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
|
||||||
clk_disable_unprepare(pcdev->clk);
|
clk_disable_unprepare(pcdev->clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pxa_camera_eof(unsigned long arg)
|
||||||
|
{
|
||||||
|
struct pxa_camera_dev *pcdev = (struct pxa_camera_dev *)arg;
|
||||||
|
unsigned long cifr;
|
||||||
|
struct pxa_buffer *buf;
|
||||||
|
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)
|
static irqreturn_t pxa_camera_irq(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct pxa_camera_dev *pcdev = data;
|
struct pxa_camera_dev *pcdev = data;
|
||||||
unsigned long status, cifr, cicr0;
|
unsigned long status, cicr0;
|
||||||
struct pxa_buffer *buf;
|
|
||||||
struct videobuf_buffer *vb;
|
|
||||||
|
|
||||||
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,
|
||||||
|
@ -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)
|
||||||
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)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче