diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-11-05 00:34:23 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-11-05 00:34:23 +0200 |
commit | 81a04a87e3f14c489d50e505d148145397364b4a (patch) | |
tree | 9b6ecc49ba830a5e4fadc19a313920c3e2543ada /linux/drivers/media/video | |
parent | 8106c036a919ae34375e102150dceda249895549 (diff) | |
download | mediapointer-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.c | 15 |
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); |