summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mack <daniel@zonque.org>2020-05-21 11:11:51 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-05-22 11:06:14 +0200
commit2d12fc792cdd43da8502de4a425a98e520b1c302 (patch)
treeef4637d6d21417e3400834e4382bd43ab811d6ba
parent6393ff1c4435acc343b1481f5b834b918cb42b12 (diff)
downloadlinux-stable-2d12fc792cdd43da8502de4a425a98e520b1c302.tar.gz
linux-stable-2d12fc792cdd43da8502de4a425a98e520b1c302.tar.bz2
linux-stable-2d12fc792cdd43da8502de4a425a98e520b1c302.zip
sc16is7xx: Allow sharing the IRQ line
When the interrupt line is shared with other devices, the IRQ must be level-triggered, as only one device can trigger a falling edge. To support this, try to acquire the IRQ with IRQF_TRIGGER_LOW|IRQF_SHARED first. Interrupt controllers that lack support for level-triggers will return an error, in which case the driver will now retry the acqusition with IRQF_TRIGGER_FALLING, which was also the default before. Signed-off-by: Daniel Mack <daniel@zonque.org> Link: https://lore.kernel.org/r/20200521091152.404404-6-daniel@zonque.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/sc16is7xx.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index 3908a2154b7f..7d98367d6e83 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -1293,7 +1293,19 @@ static int sc16is7xx_probe(struct device *dev,
sc16is7xx_power(&s->p[i].port, 0);
}
- /* Setup interrupt */
+ /*
+ * Setup interrupt. We first try to acquire the IRQ line as level IRQ.
+ * If that succeeds, we can allow sharing the interrupt as well.
+ * In case the interrupt controller doesn't support that, we fall
+ * back to a non-shared falling-edge trigger.
+ */
+ ret = devm_request_threaded_irq(dev, irq, NULL, sc16is7xx_irq,
+ IRQF_TRIGGER_LOW | IRQF_SHARED |
+ IRQF_ONESHOT,
+ dev_name(dev), s);
+ if (!ret)
+ return 0;
+
ret = devm_request_threaded_irq(dev, irq, NULL, sc16is7xx_irq,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
dev_name(dev), s);