Skip to content

Commit e349cd5

Browse files
claudiubezneagregkh
authored andcommitted
serial: sh-sci: Increment the runtime usage counter for the earlycon device
commit 651dee03696e1dfde6d9a7e8664bbdcd9a10ea7f upstream. 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: Claudiu Beznea <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 61749c9 commit e349cd5

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
@@ -3351,6 +3351,22 @@ static int sci_probe_single(struct platform_device *dev,
33513351
}
33523352

33533353
if (sci_uart_earlycon && sci_ports[0].port.mapbase == sci_res->start) {
3354+
/*
3355+
* In case:
3356+
* - this is the earlycon port (mapped on index 0 in sci_ports[]) and
3357+
* - it now maps to an alias other than zero and
3358+
* - the earlycon is still alive (e.g., "earlycon keep_bootcon" is
3359+
* available in bootargs)
3360+
*
3361+
* we need to avoid disabling clocks and PM domains through the runtime
3362+
* PM APIs called in __device_attach(). For this, increment the runtime
3363+
* PM reference counter (the clocks and PM domains were already enabled
3364+
* by the bootloader). Otherwise the earlycon may access the HW when it
3365+
* has no clocks enabled leading to failures (infinite loop in
3366+
* sci_poll_put_char()).
3367+
*/
3368+
pm_runtime_get_noresume(&dev->dev);
3369+
33543370
/*
33553371
* Skip cleanup the sci_port[0] in early_console_exit(), this
33563372
* port is the same as the earlycon one.

0 commit comments

Comments
 (0)