Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Gabriel Somlo and committed by
Greg Kroah-Hartman
01a305a3 5602cf99

+13 -17
+13 -17
drivers/tty/serial/liteuart.c
··· 93 93 94 94 static void liteuart_stop_tx(struct uart_port *port) 95 95 { 96 + liteuart_update_irq_reg(port, false, EV_TX); 96 97 } 97 98 98 99 static void liteuart_start_tx(struct uart_port *port) 99 100 { 100 - struct circ_buf *xmit = &port->state->xmit; 101 - unsigned char ch; 102 - 103 - if (unlikely(port->x_char)) { 104 - litex_write8(port->membase + OFF_RXTX, port->x_char); 105 - port->icount.tx++; 106 - port->x_char = 0; 107 - } else if (!uart_circ_empty(xmit)) { 108 - while (xmit->head != xmit->tail) { 109 - ch = xmit->buf[xmit->tail]; 110 - uart_xmit_advance(port, 1); 111 - liteuart_putchar(port, ch); 112 - } 113 - } 114 - 115 - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 116 - uart_write_wakeup(port); 101 + liteuart_update_irq_reg(port, true, EV_TX); 117 102 } 118 103 119 104 static void liteuart_stop_rx(struct uart_port *port) ··· 129 144 tty_flip_buffer_push(&port->state->port); 130 145 } 131 146 147 + static void liteuart_tx_chars(struct uart_port *port) 148 + { 149 + u8 ch; 150 + 151 + uart_port_tx(port, ch, 152 + !litex_read8(port->membase + OFF_TXFULL), 153 + litex_write8(port->membase + OFF_RXTX, ch)); 154 + } 155 + 132 156 static irqreturn_t liteuart_interrupt(int irq, void *data) 133 157 { 134 158 struct liteuart_port *uart = data; ··· 153 159 isr = litex_read8(port->membase + OFF_EV_PENDING) & uart->irq_reg; 154 160 if (isr & EV_RX) 155 161 liteuart_rx_chars(port); 162 + if (isr & EV_TX) 163 + liteuart_tx_chars(port); 156 164 spin_unlock_irqrestore(&port->lock, flags); 157 165 158 166 return IRQ_RETVAL(isr);