diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2011-12-07 08:34:50 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-12-20 09:53:43 -0200 |
commit | 875e2e3edf48a206c64195666cf408dd3d119137 (patch) | |
tree | d86bf2075ed22fe669af4896afbe41f357f52fcd /drivers/media/video/omap3isp/isp.c | |
parent | c3cd257402fdcd650816ec25b83480a24912430a (diff) | |
download | op-kernel-dev-875e2e3edf48a206c64195666cf408dd3d119137.zip op-kernel-dev-875e2e3edf48a206c64195666cf408dd3d119137.tar.gz |
[media] omap3isp: Mark next captured frame as faulty when an SBL overflow occurs
Instead of trying to propagate errors down the pipeline manually (and
failing to do so properly in all cases), flag SBL errors in the pipeline
to which the entity that triggered the error belongs, and use pipeline
error flags to mark buffers as faulty when completing them.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/omap3isp/isp.c')
-rw-r--r-- | drivers/media/video/omap3isp/isp.c | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index b818cac..5cc15ba 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c @@ -410,6 +410,7 @@ static inline void isp_isr_dbg(struct isp_device *isp, u32 irqstatus) static void isp_isr_sbl(struct isp_device *isp) { struct device *dev = isp->dev; + struct isp_pipeline *pipe; u32 sbl_pcr; /* @@ -423,27 +424,38 @@ static void isp_isr_sbl(struct isp_device *isp) if (sbl_pcr) dev_dbg(dev, "SBL overflow (PCR = 0x%08x)\n", sbl_pcr); - if (sbl_pcr & (ISPSBL_PCR_CCDC_WBL_OVF | ISPSBL_PCR_CSIA_WBL_OVF - | ISPSBL_PCR_CSIB_WBL_OVF)) { - isp->isp_ccdc.error = 1; - if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW) - isp->isp_prev.error = 1; - if (isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER) - isp->isp_res.error = 1; + if (sbl_pcr & ISPSBL_PCR_CSIB_WBL_OVF) { + pipe = to_isp_pipeline(&isp->isp_ccp2.subdev.entity); + if (pipe != NULL) + pipe->error = true; + } + + if (sbl_pcr & ISPSBL_PCR_CSIA_WBL_OVF) { + pipe = to_isp_pipeline(&isp->isp_csi2a.subdev.entity); + if (pipe != NULL) + pipe->error = true; + } + + if (sbl_pcr & ISPSBL_PCR_CCDC_WBL_OVF) { + pipe = to_isp_pipeline(&isp->isp_ccdc.subdev.entity); + if (pipe != NULL) + pipe->error = true; } if (sbl_pcr & ISPSBL_PCR_PRV_WBL_OVF) { - isp->isp_prev.error = 1; - if (isp->isp_res.input == RESIZER_INPUT_VP && - !(isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER)) - isp->isp_res.error = 1; + pipe = to_isp_pipeline(&isp->isp_prev.subdev.entity); + if (pipe != NULL) + pipe->error = true; } if (sbl_pcr & (ISPSBL_PCR_RSZ1_WBL_OVF | ISPSBL_PCR_RSZ2_WBL_OVF | ISPSBL_PCR_RSZ3_WBL_OVF - | ISPSBL_PCR_RSZ4_WBL_OVF)) - isp->isp_res.error = 1; + | ISPSBL_PCR_RSZ4_WBL_OVF)) { + pipe = to_isp_pipeline(&isp->isp_res.subdev.entity); + if (pipe != NULL) + pipe->error = true; + } if (sbl_pcr & ISPSBL_PCR_H3A_AF_WBL_OVF) omap3isp_stat_sbl_overflow(&isp->isp_af); @@ -471,24 +483,17 @@ static irqreturn_t isp_isr(int irq, void *_isp) IRQ0STATUS_HS_VS_IRQ; struct isp_device *isp = _isp; u32 irqstatus; - int ret; irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); isp_reg_writel(isp, irqstatus, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); isp_isr_sbl(isp); - if (irqstatus & IRQ0STATUS_CSIA_IRQ) { - ret = omap3isp_csi2_isr(&isp->isp_csi2a); - if (ret) - isp->isp_ccdc.error = 1; - } + if (irqstatus & IRQ0STATUS_CSIA_IRQ) + omap3isp_csi2_isr(&isp->isp_csi2a); - if (irqstatus & IRQ0STATUS_CSIB_IRQ) { - ret = omap3isp_ccp2_isr(&isp->isp_ccp2); - if (ret) - isp->isp_ccdc.error = 1; - } + if (irqstatus & IRQ0STATUS_CSIB_IRQ) + omap3isp_ccp2_isr(&isp->isp_ccp2); if (irqstatus & IRQ0STATUS_CCDC_VD0_IRQ) { if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW) |