diff options
Diffstat (limited to 'drivers/media/video/pxa_camera.c')
-rw-r--r-- | drivers/media/video/pxa_camera.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index a2f98ec14d9a..cfa113cedd3e 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c | |||
@@ -624,6 +624,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev) | |||
624 | cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB; | 624 | cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB; |
625 | __raw_writel(cicr0, pcdev->base + CICR0); | 625 | __raw_writel(cicr0, pcdev->base + CICR0); |
626 | 626 | ||
627 | pcdev->active = NULL; | ||
627 | dev_dbg(pcdev->dev, "%s\n", __func__); | 628 | dev_dbg(pcdev->dev, "%s\n", __func__); |
628 | } | 629 | } |
629 | 630 | ||
@@ -697,7 +698,6 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev, | |||
697 | 698 | ||
698 | if (list_empty(&pcdev->capture)) { | 699 | if (list_empty(&pcdev->capture)) { |
699 | pxa_camera_stop_capture(pcdev); | 700 | pxa_camera_stop_capture(pcdev); |
700 | pcdev->active = NULL; | ||
701 | for (i = 0; i < pcdev->channels; i++) | 701 | for (i = 0; i < pcdev->channels; i++) |
702 | pcdev->sg_tail[i] = NULL; | 702 | pcdev->sg_tail[i] = NULL; |
703 | return; | 703 | return; |
@@ -765,10 +765,20 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, | |||
765 | goto out; | 765 | goto out; |
766 | } | 766 | } |
767 | 767 | ||
768 | if (!pcdev->active) { | 768 | /* |
769 | dev_err(pcdev->dev, "DMA End IRQ with no active buffer!\n"); | 769 | * pcdev->active should not be NULL in DMA irq handler. |
770 | * | ||
771 | * But there is one corner case : if capture was stopped due to an | ||
772 | * overrun of channel 1, and at that same channel 2 was completed. | ||
773 | * | ||
774 | * When handling the overrun in DMA irq for channel 1, we'll stop the | ||
775 | * capture and restart it (and thus set pcdev->active to NULL). But the | ||
776 | * DMA irq handler will already be pending for channel 2. So on entering | ||
777 | * the DMA irq handler for channel 2 there will be no active buffer, yet | ||
778 | * that is normal. | ||
779 | */ | ||
780 | if (!pcdev->active) | ||
770 | goto out; | 781 | goto out; |
771 | } | ||
772 | 782 | ||
773 | vb = &pcdev->active->vb; | 783 | vb = &pcdev->active->vb; |
774 | buf = container_of(vb, struct pxa_buffer, vb); | 784 | 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, | |||
779 | status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel)); | 789 | status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel)); |
780 | 790 | ||
781 | if (status & DCSR_ENDINTR) { | 791 | if (status & DCSR_ENDINTR) { |
782 | if (camera_status & overrun) { | 792 | /* |
793 | * It's normal if the last frame creates an overrun, as there | ||
794 | * are no more DMA descriptors to fetch from QCI fifos | ||
795 | */ | ||
796 | if (camera_status & overrun && | ||
797 | !list_is_last(pcdev->capture.next, &pcdev->capture)) { | ||
783 | dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", | 798 | dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", |
784 | camera_status); | 799 | camera_status); |
785 | pxa_camera_stop_capture(pcdev); | 800 | pxa_camera_stop_capture(pcdev); |