mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
serial: 8250_mxpcie: add custom handle_irq callback
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@moxa.com> Link: https://patch.msgid.link/20260731074820.735619-7-crescentcy.hsieh@moxa.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
d98cf22e68
commit
e8224757c6
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user