From fd9d23cef028abd4799308a43920811db613caf6 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 31 Mar 2009 03:44:22 -0300 Subject: [PATCH] --- yaml --- r: 142387 b: refs/heads/master c: 8c62e221c71a0240f16ea8aa29609f93a68c2ff9 h: refs/heads/master i: 142385: bdfb48241605bbc0dc829703980bdacbcbf41622 142383: 9a9a6f1d4d7cb192d41999db387b8b2bcbed1922 v: v3 --- [refs] | 2 +- trunk/drivers/media/video/pxa_camera.c | 25 ++++++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index 5248e734b208..edc134874ea0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 256b02332a0ba1d7382d736d776e605be63ded17 +refs/heads/master: 8c62e221c71a0240f16ea8aa29609f93a68c2ff9 diff --git a/trunk/drivers/media/video/pxa_camera.c b/trunk/drivers/media/video/pxa_camera.c index a2f98ec14d9a..cfa113cedd3e 100644 --- a/trunk/drivers/media/video/pxa_camera.c +++ b/trunk/drivers/media/video/pxa_camera.c @@ -624,6 +624,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev) cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB; __raw_writel(cicr0, pcdev->base + CICR0); + pcdev->active = NULL; dev_dbg(pcdev->dev, "%s\n", __func__); } @@ -697,7 +698,6 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev, if (list_empty(&pcdev->capture)) { pxa_camera_stop_capture(pcdev); - pcdev->active = NULL; for (i = 0; i < pcdev->channels; i++) pcdev->sg_tail[i] = NULL; return; @@ -765,10 +765,20 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, goto out; } - if (!pcdev->active) { - dev_err(pcdev->dev, "DMA End IRQ with no active buffer!\n"); + /* + * pcdev->active should not be NULL in DMA irq handler. + * + * But there is one corner case : if capture was stopped due to an + * overrun of channel 1, and at that same channel 2 was completed. + * + * When handling the overrun in DMA irq for channel 1, we'll stop the + * capture and restart it (and thus set pcdev->active to NULL). But the + * DMA irq handler will already be pending for channel 2. So on entering + * the DMA irq handler for channel 2 there will be no active buffer, yet + * that is normal. + */ + if (!pcdev->active) goto out; - } vb = &pcdev->active->vb; buf = container_of(vb, struct pxa_buffer, vb); @@ -779,7 +789,12 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel)); if (status & DCSR_ENDINTR) { - if (camera_status & overrun) { + /* + * It's normal if the last frame creates an overrun, as there + * are no more DMA descriptors to fetch from QCI fifos + */ + if (camera_status & overrun && + !list_is_last(pcdev->capture.next, &pcdev->capture)) { dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", camera_status); pxa_camera_stop_capture(pcdev);