aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Levitsky2007-11-04 19:34:23 -0300
committerMauro Carvalho Chehab2008-01-25 19:02:44 -0200
commit3203cb86d22c63504f8368151029bf9dad014ddb (patch)
treec8bc84fcfb3f0b3b5d001f40b2d4a046e87de2e3
parent0d65cd4f2bfe70872e4218d9d35d37a7000d6739 (diff)
V4L/DVB (6668): Fix theoretical races between IRQ handler and .suspend/resume
*dev->insuspend = 1 should be set before synchronize_irq *ACK interrupts after synchronize_irq, to make sure there aren't pending interrupts. *Add barrier before we restart interrupts so the handler will 100% see the dev->insuspend Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 40cdec26a7f4..85c165d17301 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1181,8 +1181,13 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
saa_writel(SAA7134_IRQ2, 0);
saa_writel(SAA7134_MAIN_CTRL, 0);
- synchronize_irq(pci_dev->irq);
dev->insuspend = 1;
+ synchronize_irq(pci_dev->irq);
+
+ /* ACK interrupts once more, just in case,
+ since the IRQ handler won't ack them anymore*/
+
+ saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT));
/* Disable timeout timers - if we have active buffers, we will
fill them on resume*/
@@ -1246,6 +1251,7 @@ static int saa7134_resume(struct pci_dev *pci_dev)
/* start DMA now*/
dev->insuspend = 0;
+ smp_wmb();
saa7134_set_dmabits(dev);
spin_unlock_irqrestore(&dev->slock, flags);