Commit 914eaf93 authored by Joshua Scott's avatar Joshua Scott Committed by Greg Kroah-Hartman

serial: 8250_dw: Allow TX FIFO to drain before writing to UART_LCR

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: default avatarJoshua Scott <joshua.scott@alliedtelesis.co.nz>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b96408b4
......@@ -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>
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment