It's horrid and if we inline it into callers, we can get rid of a lot of sugar around. So: * x_char handling becomes a single iowrite8. * xmit->buf handling is a single loop simply writing characters one by one directly from the buf instead of complex cnt_to_end computations. Until the buf is empty or fifo size is reached. Signed-off-by: Jiri Slaby <jslaby@xxxxxxx> --- drivers/tty/serial/pch_uart.c | 46 ++++++++++------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 6cb631487383..4fcb6c144b54 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -550,18 +550,6 @@ static u8 pch_uart_hal_get_modem(struct eg20t_port *priv) return (u8)msr; } -static void pch_uart_hal_write(struct eg20t_port *priv, - const unsigned char *buf, int tx_size) -{ - int i; - unsigned int thr; - - for (i = 0; i < tx_size;) { - thr = buf[i++]; - iowrite8(thr, priv->membase + PCH_UART_THR); - } -} - static int pch_uart_hal_read(struct eg20t_port *priv, unsigned char *buf, int rx_size) { @@ -769,23 +757,21 @@ static void pch_dma_tx_complete(void *arg) pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT); } -static int pop_tx(struct eg20t_port *priv, int size) +static bool pop_tx(struct eg20t_port *priv, unsigned int size) { - int count = 0; + unsigned int count = 0; struct uart_port *port = &priv->port; struct circ_buf *xmit = &port->state->xmit; - if (uart_tx_stopped(port) || uart_circ_empty(xmit)) + if (uart_tx_stopped(port)) goto pop_tx_end; - do { - int cnt_to_end = - CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); - int sz = min(size - count, cnt_to_end); - pch_uart_hal_write(priv, &xmit->buf[xmit->tail], sz); - xmit->tail = (xmit->tail + sz) & (UART_XMIT_SIZE - 1); - count += sz; - } while (!uart_circ_empty(xmit) && count < size); + while (!uart_circ_empty(xmit) && count < size) { + iowrite8(xmit->buf[xmit->tail], priv->membase + PCH_UART_THR); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + count++; + } pop_tx_end: dev_dbg(priv->port.dev, "%d characters. Remained %d characters.(%lu)\n", @@ -859,7 +845,6 @@ static unsigned int handle_tx(struct eg20t_port *priv) struct uart_port *port = &priv->port; struct circ_buf *xmit = &port->state->xmit; int fifo_size; - int tx_size; int size; int tx_empty; @@ -874,7 +859,7 @@ static unsigned int handle_tx(struct eg20t_port *priv) fifo_size = max(priv->fifo_size, 1); tx_empty = 1; if (port->x_char) { - pch_uart_hal_write(priv, &port->x_char, 1); + iowrite8(port->x_char, priv->membase + PCH_UART_THR); port->icount.tx++; port->x_char = 0; tx_empty = 0; @@ -884,13 +869,8 @@ static unsigned int handle_tx(struct eg20t_port *priv) size = min(xmit->head - xmit->tail, fifo_size); if (size < 0) size = fifo_size; - if (size) { - tx_size = pop_tx(priv, size); - if (tx_size > 0) { - port->icount.tx += tx_size; - tx_empty = 0; - } - } + if (size && pop_tx(priv, size)) + tx_empty = 0; priv->tx_empty = tx_empty; @@ -935,7 +915,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) fifo_size = max(priv->fifo_size, 1); if (port->x_char) { - pch_uart_hal_write(priv, &port->x_char, 1); + iowrite8(port->x_char, priv->membase + PCH_UART_THR); port->icount.tx++; port->x_char = 0; fifo_size--; -- 2.36.0