[PATCH v5 06/14] serial: 8250_mxpcie: add custom handle_irq callback
Crescent Hsieh <[email protected]> Fri, 31 Jul 2026 15:48:12 +0800
| Newsgroups | org.kernel.vger.linux-serial,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Add a mxpcie-specific handle_irq() implementation for Moxa PCIe serial ports. This keeps the interrupt handling self-contained in the driver and provides a hook point for MUEx50-specific RX/TX paths added in subsequent patches. The handler processes RX, updates modem status, and handles TX when THRE is asserted. Signed-off-by: Crescent Hsieh <[email protected]> --- drivers/tty/serial/8250/8250_mxpcie.c | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/tty/serial/8250/8250_mxpcie.c b/drivers/tty/serial/8250/8250_mxpcie.c index 39eee8a9b82d..9190825ff3d3 100644 --- a/drivers/tty/serial/8250/8250_mxpcie.c +++ b/drivers/tty/serial/8250/8250_mxpcie.c @@ -263,6 +263,47 @@ static void mxpcie8250_unthrottle(struct uart_port *port) serial_out(up, UART_IER, up->ier); } +static bool mxpcie8250_should_rx(struct uart_8250_port *up, u16 lsr) +{ + struct uart_port *port = &up->port; + + if (!(lsr & (UART_LSR_DR | UART_LSR_BI))) + return false; + + if (!(port->status & (UPSTAT_AUTOCTS | UPSTAT_AUTORTS))) + return true; + if (lsr & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS)) + return true; + if (port->read_status_mask & UART_LSR_DR) + return true; + + return false; +} + +static int mxpcie8250_handle_irq(struct uart_port *port) +{ + struct uart_8250_port *up = up_to_u8250p(port); + u16 lsr; + u8 iir; + + iir = serial_in(up, UART_IIR); + if (iir & UART_IIR_NO_INT) + return 0; + + guard(uart_port_lock_check_sysrq_irqsave)(port); + + lsr = serial_lsr_in(up); + if (mxpcie8250_should_rx(up, lsr)) + lsr = serial8250_rx_chars(up, lsr); + + serial8250_modem_status(up); + + if ((lsr & UART_LSR_THRE) && (up->ier & UART_IER_THRI)) + serial8250_tx_chars(up); + + return 1; +} + static void mxpcie8250_init_board(struct pci_dev *pdev, struct mxpcie8250 *priv) { void __iomem *bar2_base = priv->bar2_base; @@ -362,6 +403,7 @@ static int mxpcie8250_probe(struct pci_dev *pdev, const struct pci_device_id *id up.port.shutdown = mxpcie8250_shutdown; up.port.throttle = mxpcie8250_throttle; up.port.unthrottle = mxpcie8250_unthrottle; + up.port.handle_irq = mxpcie8250_handle_irq; for (unsigned int i = 0; i < num_ports; i++) { mxpcie8250_setup_port(pdev, priv, &up, i); -- 2.45.2