Re: [PATCH] serial: 8250: clear stuck RX-timeout interrupt on LPC32xx (PORT_LPC3220)

Andy Shevchenko <[email protected]>
Newsgroups gmane.linux.serial,gmane.linux.kernel,gmane.linux.kernel.stable
Organization Intel Finland Oy - BIC 0357606-4 - c/o Alberga Business Park, 6 krs, Bertel Jungin Aukio 5, 02600 Espoo
Message-ID <[email protected]>
On Fri, Jul 17, 2026 at 09:35:30AM -0300, Ryan Wilbur wrote:
> The LPC32xx UART can latch an RX character-timeout interrupt while the
> RX FIFO is empty: IIR reports UART_IIR_RX_TIMEOUT (0x0c) but LSR.DR is
> clear. A character timeout is only cleared by reading RHR, but
> serial8250_rx_chars() reads RHR only when LSR.DR is set, so nothing ever
> clears the condition. The interrupt is level-triggered and re-fires
> immediately, so on a single-core ARM926 the resulting interrupt
> storm livelocks the CPU.
> 
> It is reproducible when userspace repeatedly opens the front-panel port
> (ttyS1): serial8250_do_set_termios() re-enables interrupts on unlock and
> the handler then spins forever with iir=0xcc lsr=0x60 ier=0x05, tripping
> the soft-lockup detector in serial8250_handle_irq_locked().
> 
> Fix this by doing one throwaway RHR read to clear the timeout. It is gated
> on PORT_LPC3220 and only fires when the FIFO is empty (LSR.DR clear), so
> no real received data is ever discarded, and it is a no-op on healthy
> UARTs which never report a timeout with DR==0.
> 
> This is the same class of bug already worked around for other 8250 cores;
> see commit 424d79183af0 ("serial: 8250_dw: Avoid "too much work" from bogus rx timeout interrupt")
> which reports the identical iir=0xcc/lsr=0x60. See also
> UART_RX_TIMEOUT_QUIRK in 8250_omap, and the note in 8250_bcm7271.

...

> +	/*
> +	 * On PORT_LPC3220 the UART can raise an RX character-timeout
> +	 * interrupt with an empty RX FIFO (IIR reports RX_TIMEOUT but
> +	 * LSR.DR is clear). The timeout is only cleared by reading RHR,
> +	 * but the RX path below is skipped when the FIFO is empty, so
> +	 * nothing clears it. IRQ then re-fires immediately and livelocks
> +	 * this single-core. Do one throwaway RHR read to clear it.

> +	 * Same bug worked around for other 8250 cores (8250_dw, 8250_omap, 8250_bcm7271).

This is 8250-port.c.

> +	 */
> +	if (port->type == PORT_LPC3220 &&

Why do we have this then?

> +	    (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT &&
> +	    !(status & UART_LSR_DR))
> +		serial_in(up, UART_RX);

-- 
With Best Regards,
Andy Shevchenko
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.