diff options
Diffstat (limited to 'drivers/tty/serial/max310x.c')
-rw-r--r-- | drivers/tty/serial/max310x.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 828a2853bd4a..9e4e70f864ea 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -685,9 +685,10 @@ static void max310x_handle_tx(struct uart_port *port) uart_write_wakeup(port); } -static void max310x_port_irq(struct max310x_port *s, int portno) +static irqreturn_t max310x_port_irq(struct max310x_port *s, int portno) { struct uart_port *port = &s->p[portno].port; + irqreturn_t res = IRQ_NONE; do { unsigned int ists, lsr, rxlen; @@ -698,6 +699,8 @@ static void max310x_port_irq(struct max310x_port *s, int portno) if (!ists && !rxlen) break; + res = IRQ_HANDLED; + if (ists & MAX310X_IRQ_CTS_BIT) { lsr = max310x_port_read(port, MAX310X_LSR_IRQSTS_REG); uart_handle_cts_change(port, @@ -711,11 +714,13 @@ static void max310x_port_irq(struct max310x_port *s, int portno) mutex_unlock(&s->mutex); } } while (1); + return res; } static irqreturn_t max310x_ist(int irq, void *dev_id) { struct max310x_port *s = (struct max310x_port *)dev_id; + bool handled = false; if (s->devtype->nr > 1) { do { @@ -726,12 +731,15 @@ static irqreturn_t max310x_ist(int irq, void *dev_id) val = ((1 << s->devtype->nr) - 1) & ~val; if (!val) break; - max310x_port_irq(s, fls(val) - 1); + if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED) + handled = true; } while (1); - } else - max310x_port_irq(s, 0); + } else { + if (max310x_port_irq(s, 0) == IRQ_HANDLED) + handled = true; + } - return IRQ_HANDLED; + return IRQ_RETVAL(handled); } static void max310x_wq_proc(struct work_struct *ws) @@ -1239,7 +1247,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, /* Setup interrupt */ ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist, - IRQF_ONESHOT, dev_name(dev), s); + IRQF_ONESHOT | IRQF_SHARED, dev_name(dev), s); if (!ret) return 0; |