Skip to content

Commit 54ca955

Browse files
paligregkh
authored andcommitted
serial: mvebu-uart: fix tx lost characters at power off
Commit c685af1 ("serial: mvebu-uart: fix tx lost characters") fixed tx lost characters at low baud rates but started causing tx lost characters when kernel is going to power off or reboot. TX_EMP tells us when transmit queue is empty therefore all characters were transmitted. TX_RDY tells us when CPU can send a new character. Therefore we need to use different check prior transmitting new character and different check after all characters were sent. This patch splits polling code into two functions: wait_for_xmitr() which waits for TX_RDY and wait_for_xmite() which waits for TX_EMP. When rebooting A3720 platform without this patch on UART is print only: [ 42.699� And with this patch on UART is full output: [ 39.530216] reboot: Restarting system Fixes: c685af1 ("serial: mvebu-uart: fix tx lost characters") Signed-off-by: Pali Rohár <[email protected]> Cc: stable <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5c8fe58 commit 54ca955

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

drivers/tty/serial/mvebu-uart.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,14 @@ static void wait_for_xmitr(struct uart_port *port)
648648
(val & STAT_TX_RDY(port)), 1, 10000);
649649
}
650650

651+
static void wait_for_xmite(struct uart_port *port)
652+
{
653+
u32 val;
654+
655+
readl_poll_timeout_atomic(port->membase + UART_STAT, val,
656+
(val & STAT_TX_EMP), 1, 10000);
657+
}
658+
651659
static void mvebu_uart_console_putchar(struct uart_port *port, int ch)
652660
{
653661
wait_for_xmitr(port);
@@ -675,7 +683,7 @@ static void mvebu_uart_console_write(struct console *co, const char *s,
675683

676684
uart_console_write(port, s, count, mvebu_uart_console_putchar);
677685

678-
wait_for_xmitr(port);
686+
wait_for_xmite(port);
679687

680688
if (ier)
681689
writel(ier, port->membase + UART_CTRL(port));

0 commit comments

Comments
 (0)