mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-05 10:04:12 +08:00
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: Joshua Scott <joshua.scott@alliedtelesis.co.nz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
b96408b474
commit
914eaf935e
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user