diff options
author | Daniel Scheller <d.scheller@gmx.net> | 2018-04-09 12:47:42 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-05-04 10:38:57 -0400 |
commit | 285d490c31bd30e3afb67032e3c5ced003cdc895 (patch) | |
tree | bb82e6222badaae00aba7fd87861eaaed387468d | |
parent | e8227689f93984348468c9153e23db06ef95491e (diff) |
media: ddbridge: improve separated MSI IRQ handling
Improve IRQ handling in the separated MSG/I2C and IO/TSDATA handlers by
applying a mask for recognized bits immediately upon reading the IRQ mask
from the hardware, so only the bits/IRQs that actually were set will be
acked.
Picked up from the upstream dddvb-0.9.33 release.
Signed-off-by: Daniel Scheller <d.scheller@gmx.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r-- | drivers/media/pci/ddbridge/ddbridge-core.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 951abcee768a..cb2d9d811580 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -2428,16 +2428,17 @@ static void irq_handle_io(struct ddb *dev, u32 s) irqreturn_t ddb_irq_handler0(int irq, void *dev_id) { struct ddb *dev = (struct ddb *)dev_id; - u32 s = ddbreadl(dev, INTERRUPT_STATUS); + u32 mask = 0x8fffff00; + u32 s = mask & ddbreadl(dev, INTERRUPT_STATUS); + if (!s) + return IRQ_NONE; do { if (s & 0x80000000) return IRQ_NONE; - if (!(s & 0xfffff00)) - return IRQ_NONE; - ddbwritel(dev, s & 0xfffff00, INTERRUPT_ACK); + ddbwritel(dev, s, INTERRUPT_ACK); irq_handle_io(dev, s); - } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); + } while ((s = mask & ddbreadl(dev, INTERRUPT_STATUS))); return IRQ_HANDLED; } @@ -2445,16 +2446,17 @@ irqreturn_t ddb_irq_handler0(int irq, void *dev_id) irqreturn_t ddb_irq_handler1(int irq, void *dev_id) { struct ddb *dev = (struct ddb *)dev_id; - u32 s = ddbreadl(dev, INTERRUPT_STATUS); + u32 mask = 0x8000000f; + u32 s = mask & ddbreadl(dev, INTERRUPT_STATUS); + if (!s) + return IRQ_NONE; do { if (s & 0x80000000) return IRQ_NONE; - if (!(s & 0x0000f)) - return IRQ_NONE; - ddbwritel(dev, s & 0x0000f, INTERRUPT_ACK); + ddbwritel(dev, s, INTERRUPT_ACK); irq_handle_msg(dev, s); - } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); + } while ((s = mask & ddbreadl(dev, INTERRUPT_STATUS))); return IRQ_HANDLED; } |