[PATCH v3] serial: amba-pl011: don't wait for BUSY after every earlycon character
From: Eric Curtin
Date: Mon Jul 20 2026 - 08:26:22 EST
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 <ericcurtin17@xxxxxxxxx>
---
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