On Wed, 16 Nov 2022, Gabriel Somlo wrote: > Switch the TX path to IRQ-driven operation, while maintaining support > for polling mode via the poll timer. > > Signed-off-by: Gabriel Somlo <gsomlo@xxxxxxxxx> > --- > > Changes from v3: > - remove superfluous curly braces from liteuart_interrupt() > - simplified [start|stop]_tx() by using shadow irq register from > patch 12/14 > - simplified liteuart_tx_chars() by rebasing on top of tty-next tree > > drivers/tty/serial/liteuart.c | 30 +++++++++++++----------------- > 1 file changed, 13 insertions(+), 17 deletions(-) > > diff --git a/drivers/tty/serial/liteuart.c b/drivers/tty/serial/liteuart.c > index fad778578986..977fc4349b47 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; > @@ -154,6 +148,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(&port->lock); > > return IRQ_RETVAL(isr); Looks very clean now with uart_port_tx(), thanks. Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx> -- i.