diff options
author | Gabriel Somlo <gsomlo@gmail.com> | 2022-11-23 16:04:59 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-01-19 16:59:41 +0300 |
commit | 01a305a36639a438e27503202a46f191b74bd168 (patch) | |
tree | e91089dc2664c68f6571a6a472b493e16344bf12 /drivers/tty/serial/liteuart.c | |
parent | 5602cf99dcdcc0bf8f9a5979b7443fbe46686995 (diff) | |
download | linux-01a305a36639a438e27503202a46f191b74bd168.tar.xz |
serial: liteuart: add IRQ support for the TX path
Switch the TX path to IRQ-driven operation, while maintaining support
for polling mode via the poll timer.
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
Link: https://lore.kernel.org/r/20221123130500.1030189-14-gsomlo@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/liteuart.c')
-rw-r--r-- | drivers/tty/serial/liteuart.c | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/drivers/tty/serial/liteuart.c b/drivers/tty/serial/liteuart.c index 8685c97d391e..6e9f58d3957c 100644 --- a/drivers/tty/serial/liteuart.c +++ b/drivers/tty/serial/liteuart.c @@ -93,27 +93,12 @@ static void liteuart_update_irq_reg(struct uart_port *port, bool set, u8 mask) static void liteuart_stop_tx(struct uart_port *port) { + liteuart_update_irq_reg(port, false, EV_TX); } static void liteuart_start_tx(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - unsigned char ch; - - if (unlikely(port->x_char)) { - litex_write8(port->membase + OFF_RXTX, port->x_char); - port->icount.tx++; - port->x_char = 0; - } else if (!uart_circ_empty(xmit)) { - while (xmit->head != xmit->tail) { - ch = xmit->buf[xmit->tail]; - uart_xmit_advance(port, 1); - liteuart_putchar(port, ch); - } - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + liteuart_update_irq_reg(port, true, EV_TX); } static void liteuart_stop_rx(struct uart_port *port) @@ -144,6 +129,15 @@ static void liteuart_rx_chars(struct uart_port *port) tty_flip_buffer_push(&port->state->port); } +static void liteuart_tx_chars(struct uart_port *port) +{ + u8 ch; + + uart_port_tx(port, ch, + !litex_read8(port->membase + OFF_TXFULL), + litex_write8(port->membase + OFF_RXTX, ch)); +} + static irqreturn_t liteuart_interrupt(int irq, void *data) { struct liteuart_port *uart = data; @@ -159,6 +153,8 @@ static irqreturn_t liteuart_interrupt(int irq, void *data) isr = litex_read8(port->membase + OFF_EV_PENDING) & uart->irq_reg; if (isr & EV_RX) liteuart_rx_chars(port); + if (isr & EV_TX) + liteuart_tx_chars(port); spin_unlock_irqrestore(&port->lock, flags); return IRQ_RETVAL(isr); |