[PATCH v3] serial: amba-pl011: don't wait for BUSY after every earlycon character
Eric Curtin <[email protected]> Mon, 20 Jul 2026 12:17:41 +0000
| Newsgroups | org.kernel.vger.linux-serial,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
pl011_putc(), used exclusively by the pl011 earlycon (pl011_early_write() -> uart_console_write()), waits for UART01x_FR_TXFF to clear before writing a character (correct: don't overrun the TX FIFO) and then *also* busy-waited for UART01x_FR_BUSY to clear before returning, i.e. it waited for the character to be fully shifted out on the wire before the next character in the string could even be considered. Waiting for BUSY per character defeats the TX FIFO: instead of letting the UART buffer several queued bytes and transmit them back to back, every single character printed through earlycon was forced to wait for that character's own complete transmission (a full UART bit-time at the configured baud rate) before the driver would even look at writing the next one. This is wasted time on real hardware, and it is much worse under virtualization: each read of UARTFR and each write to UARTDR is an MMIO access that traps to the hypervisor, so every extra poll is a full VM-exit/entry round trip. The regular (non-early) console path already gets this right: it waits for TXFF per character while filling the FIFO, then waits for BUSY only once, after the whole string has been written (see the tail of pl011_console_write_atomic()). The QDF2400 erratum 44 earlycon path (qdf2400_e44_putc()) is intentionally different because that erratum requires waiting for the stuck BUSY bit workaround per character, and is left untouched by this change. This patch was written with the assistance of an AI coding tool (OpenCode CLI, using Claude as the backing model). The tool was given the observation that earlycon output was slower than expected under virtualization and asked to locate the cause and propose a fix; it identified the redundant per-character BUSY wait in pl011_putc() shown above and produced the one-line removal in this patch. The analysis and diff were reviewed by hand against the driver's other console write paths (pl011_console_write_atomic()/qdf2400_e44_putc()) to confirm the change is safe and does not affect the QDF2400 erratum workaround. Testing was done by booting a VM with a pl011 earlycon console with and without this change and comparing boot log timing. Signed-off-by: Eric Curtin <[email protected]> --- drivers/tty/serial/amba-pl011.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 8ed91e1da22b..2a25095e8d8c 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2741,8 +2741,6 @@ static void pl011_putc(struct uart_port *port, unsigned char c) writel(c, port->membase + UART01x_DR); else writeb(c, port->membase + UART01x_DR); - while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY) - cpu_relax(); } static void pl011_early_write(struct console *con, const char *s, unsigned int n) -- 2.54.0