summaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/sc16is7xx.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index 7107a0fb1..fa7805d2c 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -652,7 +652,6 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
struct tty_port *tport = &port->state->port;
unsigned long flags;
unsigned int txlen;
- unsigned char *tail;
if (unlikely(port->x_char)) {
sc16is7xx_port_write(port, SC16IS7XX_THR_REG, port->x_char);
@@ -677,9 +676,19 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
txlen = 0;
}
- txlen = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail, txlen);
- sc16is7xx_fifo_write(port, tail, txlen);
- uart_xmit_advance(port, txlen);
+ /* Handle circular buffer wrap-around by sending multiple segments */
+ while (txlen > 0 && !kfifo_is_empty(&tport->xmit_fifo)) {
+ unsigned char *tail;
+ unsigned int to_send;
+
+ to_send = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail, txlen);
+ if (!to_send)
+ break;
+
+ sc16is7xx_fifo_write(port, tail, to_send);
+ uart_xmit_advance(port, to_send);
+ txlen -= to_send;
+ }
uart_port_lock_irqsave(port, &flags);
if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)