Skip to content

Commit 651dee0

Browse files
claudiubezneagregkh
authored andcommitted
serial: sh-sci: Increment the runtime usage counter for the earlycon device
In the sh-sci driver, serial ports are mapped to the sci_ports[] array, with earlycon mapped at index zero. The uart_add_one_port() function eventually calls __device_attach(), which, in turn, calls pm_request_idle(). The identified code path is as follows: uart_add_one_port() -> serial_ctrl_register_port() -> serial_core_register_port() -> serial_core_port_device_add() -> serial_base_port_add() -> device_add() -> bus_probe_device() -> device_initial_probe() -> __device_attach() -> // ... if (dev->p->dead) { // ... } else if (dev->driver) { // ... } else { // ... pm_request_idle(dev); // ... } The earlycon device clocks are enabled by the bootloader. However, the pm_request_idle() call in __device_attach() disables the SCI port clocks while earlycon is still active. The earlycon write function, serial_console_write(), calls sci_poll_put_char() via serial_console_putchar(). If the SCI port clocks are disabled, writing to earlycon may sometimes cause the SR.TDFE bit to remain unset indefinitely, causing the while loop in sci_poll_put_char() to never exit. On single-core SoCs, this can result in the system being blocked during boot when this issue occurs. To resolve this, increment the runtime PM usage counter for the earlycon SCI device before registering the UART port. Fixes: 0b0cced ("serial: sh-sci: Add CONFIG_SERIAL_EARLYCON support") Cc: [email protected] Signed-off-by: Claudiu Beznea <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5f10170 commit 651dee0

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

drivers/tty/serial/sh-sci.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3436,6 +3436,22 @@ static int sci_probe_single(struct platform_device *dev,
34363436
}
34373437

34383438
if (sci_uart_earlycon && sci_ports[0].port.mapbase == sci_res->start) {
3439+
/*
3440+
* In case:
3441+
* - this is the earlycon port (mapped on index 0 in sci_ports[]) and
3442+
* - it now maps to an alias other than zero and
3443+
* - the earlycon is still alive (e.g., "earlycon keep_bootcon" is
3444+
* available in bootargs)
3445+
*
3446+
* we need to avoid disabling clocks and PM domains through the runtime
3447+
* PM APIs called in __device_attach(). For this, increment the runtime
3448+
* PM reference counter (the clocks and PM domains were already enabled
3449+
* by the bootloader). Otherwise the earlycon may access the HW when it
3450+
* has no clocks enabled leading to failures (infinite loop in
3451+
* sci_poll_put_char()).
3452+
*/
3453+
pm_runtime_get_noresume(&dev->dev);
3454+
34393455
/*
34403456
* Skip cleanup the sci_port[0] in early_console_exit(), this
34413457
* port is the same as the earlycon one.

0 commit comments

Comments
 (0)