aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof HaƂasa <khalasa@piap.pl>2014-11-14 07:35:06 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-11-21 12:45:35 -0500
commit3c787b108fe0d1c341a76e718a25897ae14673cf (patch)
tree2e31ba0629b6a6195e35e0fb7bc193383bfb7d79
parentb31eb901c4e5eeef4c83c43dfbc7fe0d4348cb21 (diff)
[media] solo6x10: fix a race in IRQ handler
The IRQs have to be acknowledged before they are serviced, otherwise some events may be skipped. Also, acknowledging IRQs just before returning from the handler doesn't leave enough time for the device to deassert the INTx line, and for bridges to propagate this change. This resulted in twice the IRQ rate on ARMv6 dual core CPU. Signed-off-by: Krzysztof Ha?asa <khalasa@piap.pl> Acked-by: Andrey Utkin <andrey.utkin@corp.bluecherry.net> Tested-by: Andrey Utkin <andrey.utkin@corp.bluecherry.net> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-core.c10
1 files changed, 2 insertions, 8 deletions
diff --git a/drivers/media/pci/solo6x10/solo6x10-core.c b/drivers/media/pci/solo6x10/solo6x10-core.c
index 172583d736fe..8cbe6b49f4c2 100644
--- a/drivers/media/pci/solo6x10/solo6x10-core.c
+++ b/drivers/media/pci/solo6x10/solo6x10-core.c
@@ -105,11 +105,8 @@ static irqreturn_t solo_isr(int irq, void *data)
105 if (!status) 105 if (!status)
106 return IRQ_NONE; 106 return IRQ_NONE;
107 107
108 if (status & ~solo_dev->irq_mask) { 108 /* Acknowledge all interrupts immediately */
109 solo_reg_write(solo_dev, SOLO_IRQ_STAT, 109 solo_reg_write(solo_dev, SOLO_IRQ_STAT, status);
110 status & ~solo_dev->irq_mask);
111 status &= solo_dev->irq_mask;
112 }
113 110
114 if (status & SOLO_IRQ_PCI_ERR) 111 if (status & SOLO_IRQ_PCI_ERR)
115 solo_p2m_error_isr(solo_dev); 112 solo_p2m_error_isr(solo_dev);
@@ -132,9 +129,6 @@ static irqreturn_t solo_isr(int irq, void *data)
132 if (status & SOLO_IRQ_G723) 129 if (status & SOLO_IRQ_G723)
133 solo_g723_isr(solo_dev); 130 solo_g723_isr(solo_dev);
134 131
135 /* Clear all interrupts handled */
136 solo_reg_write(solo_dev, SOLO_IRQ_STAT, status);
137
138 return IRQ_HANDLED; 132 return IRQ_HANDLED;
139} 133}
140 134