summaryrefslogtreecommitdiff
path: root/drivers/staging/media
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2015-11-09 22:01:57 (GMT)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-11-19 13:14:23 (GMT)
commit769161fd2d90fc5b5304c73a0f2be7298c5ce430 (patch)
tree42dcee13e00f50ecfa526acdb41d433be6baecfc /drivers/staging/media
parent425e186847971206981df9fce0c325655eb985b5 (diff)
downloadlinux-769161fd2d90fc5b5304c73a0f2be7298c5ce430.tar.xz
[media] media: omap4iss: csi2: Fix IRQ handling when stopping module
When stopping the CSI2 receiver the s_stream handler will wait for the IRQ handler to notice the stop request. The receiver, automatically disabled by the hardware after each frame, is then not reenabled by the IRQ handler as it returns immediately. As the IRQ handler check is performed before handling the context IRQ, the context IRQ source isn't cleared, and the CSI2 IRQ is then fired again immediately. The IRQ handler then fails to notice that the module is being stopped, processes the IRQ normally and reenables the CSI2 hardware. The problem goes unnoticed at stream stop time, but depending on the IRQ and s_stream scheduling timings, the CSI2 receiver can end up being hanged and will not produce any interrupt the next time it gets enabled, despite being soft-reset then. Fix this by checking for module stop after clearing the context IRQ source. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/staging/media')
-rw-r--r--drivers/staging/media/omap4iss/iss_csi2.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index c6e6d47..b941035 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -674,6 +674,9 @@ static void csi2_isr_ctx(struct iss_csi2_device *csi2,
status = iss_reg_read(csi2->iss, csi2->regs1, CSI2_CTX_IRQSTATUS(n));
iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_IRQSTATUS(n), status);
+ if (omap4iss_module_sync_is_stopping(&csi2->wait, &csi2->stopping))
+ return;
+
/* Propagate frame number */
if (status & CSI2_CTX_IRQ_FS) {
struct iss_pipeline *pipe =
@@ -776,9 +779,6 @@ void omap4iss_csi2_isr(struct iss_csi2_device *csi2)
pipe->error = true;
}
- if (omap4iss_module_sync_is_stopping(&csi2->wait, &csi2->stopping))
- return;
-
/* Successful cases */
if (csi2_irqstatus & CSI2_IRQ_CONTEXT0)
csi2_isr_ctx(csi2, &csi2->contexts[0]);