Skip to content

Commit 8d17dc0

Browse files
tapioreijonengregkh
authored andcommitted
serial: max310x: improve interrupt handling
When there is a heavy load of receiving characters to all four UART's, the warning 'Hardware RX FIFO overrun' is sometimes detected. The current implementation always service first the highest UART until no more interrupt and then service another UART (ex: UART3 will be serviced for as long as there are interrupts for it, then UART2, etc). This commit handle all individual interrupt sources before reading the global IRQ register again. This commit has also a nice side-effect of improving the efficiency of the driver by reducing the number of reads of the global IRQ register. Signed-off-by: Tapio Reijonen <tapio.reijonen@vaisala.com> Reviewed-by: Jiri Slaby <jirislaby@kernel.org> Reviewed-by: Hugo Villeneuve <hvilleneuve@dimonoff.com> Link: https://lore.kernel.org/r/20250908-master-max310x-improve-interrupt-handling-v3-1-91985e82ba39@vaisala.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent fc702e7 commit 8d17dc0

1 file changed

Lines changed: 17 additions & 6 deletions

File tree

drivers/tty/serial/max310x.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -823,17 +823,28 @@ static irqreturn_t max310x_ist(int irq, void *dev_id)
823823
bool handled = false;
824824

825825
if (s->devtype->nr > 1) {
826+
bool done;
827+
826828
do {
827829
unsigned int val = ~0;
830+
unsigned long irq;
831+
unsigned int port;
832+
833+
done = true;
828834

829835
WARN_ON_ONCE(regmap_read(s->regmap,
830836
MAX310X_GLOBALIRQ_REG, &val));
831-
val = ((1 << s->devtype->nr) - 1) & ~val;
832-
if (!val)
833-
break;
834-
if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED)
835-
handled = true;
836-
} while (1);
837+
838+
irq = val;
839+
840+
for_each_clear_bit(port, &irq, s->devtype->nr) {
841+
done = false;
842+
843+
if (max310x_port_irq(s, port) == IRQ_HANDLED)
844+
handled = true;
845+
}
846+
847+
} while (!done);
837848
} else {
838849
if (max310x_port_irq(s, 0) == IRQ_HANDLED)
839850
handled = true;

0 commit comments

Comments
 (0)