summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2007-11-05 00:34:23 +0200
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-11-05 00:34:23 +0200
commit81a04a87e3f14c489d50e505d148145397364b4a (patch)
tree9b6ecc49ba830a5e4fadc19a313920c3e2543ada /linux/drivers/media/video
parent8106c036a919ae34375e102150dceda249895549 (diff)
downloadmediapointer-dvb-s2-81a04a87e3f14c489d50e505d148145397364b4a.tar.gz
mediapointer-dvb-s2-81a04a87e3f14c489d50e505d148145397364b4a.tar.bz2
Fix theoretical races between IRQ handler and .suspend/resume
From: Maxim Levitsky <maximlevitsky@gmail.com> *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>
Diffstat (limited to 'linux/drivers/media/video')
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-core.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c
index c8398066f..4de076e7e 100644
--- a/linux/drivers/media/video/saa7134/saa7134-core.c
+++ b/linux/drivers/media/video/saa7134/saa7134-core.c
@@ -649,6 +649,10 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id)
unsigned long report,status;
int loop, handled = 0;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
+ /* To make sure we see correct value of dev->insuspend */
+ smp_rmb();
+#endif
if (dev->insuspend)
goto out;
@@ -1275,8 +1279,16 @@ 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;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
+ smp_wmb();
+#endif
+ 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*/
@@ -1341,6 +1353,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);