Skip to content

Commit

Permalink
serial: 8250_dw: Allow TX FIFO to drain before writing to UART_LCR
Browse files Browse the repository at this point in the history
An issue has been observed on the Marvell Armada 38x serial port.

Writes to UART_LCR can result in characters that are currently held in the
TX FIFO being lost rather than sent, even if the userspace process has
attempted to flush them.

This is most visible when using the "resize" command (tested on Busybox),
where we have observed the escape code for restoring cursor position
becoming mangled.

Signed-off-by: Joshua Scott <joshua.scott@alliedtelesis.co.nz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Joshua Scott authored and gregkh committed Feb 28, 2018
1 parent b96408b commit 914eaf9
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions drivers/tty/serial/8250/8250_dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* LCR is written whilst busy. If it is, then a busy detect interrupt is
* raised, the LCR needs to be rewritten and the uart status register read.
*/
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/module.h>
Expand Down Expand Up @@ -119,10 +120,27 @@ static void dw8250_check_lcr(struct uart_port *p, int value)
*/
}

/* Returns once the transmitter is empty or we run out of retries */
static void dw8250_tx_wait_empty(struct uart_port *p, int tries)
{
unsigned int lsr;

while (tries--) {
lsr = readb (p->membase + (UART_LSR << p->regshift));
if (lsr & UART_LSR_TEMT)
break;
udelay (10);
}
}

static void dw8250_serial_out(struct uart_port *p, int offset, int value)
{
struct dw8250_data *d = p->private_data;

/* Allow the TX to drain before we reconfigure */
if (offset == UART_LCR)
dw8250_tx_wait_empty(p, 1000);

writeb(value, p->membase + (offset << p->regshift));

if (offset == UART_LCR && !d->uart_16550_compatible)
Expand Down

0 comments on commit 914eaf9

Please sign in to comment.