This is a note to let you know that I've just added the patch titled serial: sc16is7xx: remove obsolete loop in sc16is7xx_port_irq() to the 6.7-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: serial-sc16is7xx-remove-obsolete-loop-in-sc16is7xx_port_irq.patch and it can be found in the queue-6.7 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From ed647256e8f226241ecff7baaecdb8632ffc7ec1 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve <hvilleneuve@xxxxxxxxxxxx> Date: Thu, 21 Dec 2023 18:18:11 -0500 Subject: serial: sc16is7xx: remove obsolete loop in sc16is7xx_port_irq() From: Hugo Villeneuve <hvilleneuve@xxxxxxxxxxxx> commit ed647256e8f226241ecff7baaecdb8632ffc7ec1 upstream. Commit 834449872105 ("sc16is7xx: Fix for multi-channel stall") changed sc16is7xx_port_irq() from looping multiple times when there was still interrupts to serve. It simply changed the do {} while(1) loop to a do {} while(0) loop, which makes the loop itself now obsolete. Clean the code by removing this obsolete do {} while(0) loop. Fixes: 834449872105 ("sc16is7xx: Fix for multi-channel stall") Cc: <stable@xxxxxxxxxxxxxxx> Suggested-by: Andy Shevchenko <andy.shevchenko@xxxxxxxxx> Signed-off-by: Hugo Villeneuve <hvilleneuve@xxxxxxxxxxxx> Link: https://lore.kernel.org/r/20231221231823.2327894-5-hugo@xxxxxxxxxxx Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/tty/serial/sc16is7xx.c | 89 +++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 46 deletions(-) --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -725,58 +725,55 @@ static void sc16is7xx_update_mlines(stru static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) { bool rc = true; + unsigned int iir, rxlen; struct uart_port *port = &s->p[portno].port; struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); mutex_lock(&one->efr_lock); - do { - unsigned int iir, rxlen; - - iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG); - if (iir & SC16IS7XX_IIR_NO_INT_BIT) { - rc = false; - goto out_port_irq; - } - - iir &= SC16IS7XX_IIR_ID_MASK; - - switch (iir) { - case SC16IS7XX_IIR_RDI_SRC: - case SC16IS7XX_IIR_RLSE_SRC: - case SC16IS7XX_IIR_RTOI_SRC: - case SC16IS7XX_IIR_XOFFI_SRC: - rxlen = sc16is7xx_port_read(port, SC16IS7XX_RXLVL_REG); - - /* - * There is a silicon bug that makes the chip report a - * time-out interrupt but no data in the FIFO. This is - * described in errata section 18.1.4. - * - * When this happens, read one byte from the FIFO to - * clear the interrupt. - */ - if (iir == SC16IS7XX_IIR_RTOI_SRC && !rxlen) - rxlen = 1; - - if (rxlen) - sc16is7xx_handle_rx(port, rxlen, iir); - break; + iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG); + if (iir & SC16IS7XX_IIR_NO_INT_BIT) { + rc = false; + goto out_port_irq; + } + + iir &= SC16IS7XX_IIR_ID_MASK; + + switch (iir) { + case SC16IS7XX_IIR_RDI_SRC: + case SC16IS7XX_IIR_RLSE_SRC: + case SC16IS7XX_IIR_RTOI_SRC: + case SC16IS7XX_IIR_XOFFI_SRC: + rxlen = sc16is7xx_port_read(port, SC16IS7XX_RXLVL_REG); + + /* + * There is a silicon bug that makes the chip report a + * time-out interrupt but no data in the FIFO. This is + * described in errata section 18.1.4. + * + * When this happens, read one byte from the FIFO to + * clear the interrupt. + */ + if (iir == SC16IS7XX_IIR_RTOI_SRC && !rxlen) + rxlen = 1; + + if (rxlen) + sc16is7xx_handle_rx(port, rxlen, iir); + break; /* CTSRTS interrupt comes only when CTS goes inactive */ - case SC16IS7XX_IIR_CTSRTS_SRC: - case SC16IS7XX_IIR_MSI_SRC: - sc16is7xx_update_mlines(one); - break; - case SC16IS7XX_IIR_THRI_SRC: - sc16is7xx_handle_tx(port); - break; - default: - dev_err_ratelimited(port->dev, - "ttySC%i: Unexpected interrupt: %x", - port->line, iir); - break; - } - } while (0); + case SC16IS7XX_IIR_CTSRTS_SRC: + case SC16IS7XX_IIR_MSI_SRC: + sc16is7xx_update_mlines(one); + break; + case SC16IS7XX_IIR_THRI_SRC: + sc16is7xx_handle_tx(port); + break; + default: + dev_err_ratelimited(port->dev, + "ttySC%i: Unexpected interrupt: %x", + port->line, iir); + break; + } out_port_irq: mutex_unlock(&one->efr_lock); Patches currently in stable-queue which might be from hvilleneuve@xxxxxxxxxxxx are queue-6.7/serial-sc16is7xx-remove-wasteful-static-buffer-in-sc16is7xx_regmap_name.patch queue-6.7/serial-sc16is7xx-remove-global-regmap-from-struct-sc16is7xx_port.patch queue-6.7/serial-sc16is7xx-change-efr-lock-to-operate-on-each-channels.patch queue-6.7/serial-sc16is7xx-remove-obsolete-loop-in-sc16is7xx_port_irq.patch queue-6.7/serial-sc16is7xx-convert-from-_raw_-to-_noinc_-regmap-functions-for-fifo.patch queue-6.7/serial-sc16is7xx-fix-unconditional-activation-of-thri-interrupt.patch queue-6.7/serial-sc16is7xx-remove-unused-line-structure-member.patch queue-6.7/serial-sc16is7xx-fix-invalid-sc16is7xx_lines-bitfield-in-case-of-probe-error.patch queue-6.7/serial-sc16is7xx-improve-do-while-loop-in-sc16is7xx_irq.patch queue-6.7/serial-sc16is7xx-improve-regmap-debugfs-by-using-one-regmap-per-port.patch