mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 06:34:12 +08:00
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>
This commit is contained in:
parent
5602cf99dc
commit
01a305a366
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user