[PATCH 06/15] serial: 8250_mxpcie: add custom handle_irq callback
From: Crescent Hsieh
Date: Mon May 04 2026 - 04:51:10 EST
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 <crescentcy.hsieh@xxxxxxxx>
---
drivers/tty/serial/8250/8250_mxpcie.c | 48 +++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_mxpcie.c b/drivers/tty/serial/8250/8250_mxpcie.c
index 99fd789b7665..9860f2ac2572 100644
--- a/drivers/tty/serial/8250/8250_mxpcie.c
+++ b/drivers/tty/serial/8250/8250_mxpcie.c
@@ -265,6 +265,53 @@ static void mxpcie8250_unthrottle(struct uart_port *port)
uart_port_unlock_irqrestore(port, flags);
}
+static u16 mxpcie8250_rx_chars(struct uart_8250_port *up, u16 lsr)
+{
+ struct uart_port *port = &up->port;
+
+ if (!(lsr & (UART_LSR_DR | UART_LSR_BI)))
+ return lsr;
+
+ if (!(port->status & (UPSTAT_AUTOCTS | UPSTAT_AUTORTS)))
+ goto do_rx;
+ if (lsr & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
+ goto do_rx;
+ if (port->read_status_mask & UART_LSR_DR)
+ goto do_rx;
+
+ return lsr;
+
+do_rx:
+ return serial8250_rx_chars(up, lsr);
+}
+
+static int mxpcie8250_handle_irq(struct uart_port *port)
+{
+ struct uart_8250_port *up = up_to_u8250p(port);
+ unsigned long flags;
+ u16 lsr;
+ u8 iir;
+
+ iir = serial_in(up, UART_IIR);
+ if (iir & UART_IIR_NO_INT)
+ return 0;
+
+ uart_port_lock_irqsave(port, &flags);
+
+ lsr = serial_lsr_in(up);
+
+ lsr = mxpcie8250_rx_chars(up, lsr);
+
+ serial8250_modem_status(up);
+
+ if ((lsr & UART_LSR_THRE) && (up->ier & UART_IER_THRI))
+ serial8250_tx_chars(up);
+
+ uart_unlock_and_check_sysrq_irqrestore(port, flags);
+
+ return 1;
+}
+
static void mxpcie8250_init_board(struct pci_dev *pdev, struct mxpcie8250 *priv)
{
void __iomem *bar2_base = priv->bar2_base;
@@ -364,6 +411,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 (i = 0; i < num_ports; i++) {
mxpcie8250_setup_port(pdev, priv, &up, i);
--
2.43.0