Skip to content

Commit 5f10170

Browse files
claudiubezneagregkh
authored andcommitted
serial: sh-sci: Clean sci_ports[0] after at earlycon exit
The early_console_setup() function initializes sci_ports[0].port with an object of type struct uart_port obtained from the struct earlycon_device passed as an argument to early_console_setup(). Later, during serial port probing, the serial port used as earlycon (e.g., port A) might be remapped to a different position in the sci_ports[] array, and a different serial port (e.g., port B) might be assigned to slot 0. For example: sci_ports[0] = port B sci_ports[X] = port A In this scenario, the new port mapped at index zero (port B) retains the data associated with the earlycon configuration. Consequently, after the Linux boot process, any access to the serial port now mapped to sci_ports[0] (port B) will block the original earlycon port (port A). To address this, introduce an early_console_exit() function to clean up sci_ports[0] when earlycon is exited. To prevent the cleanup of sci_ports[0] while the serial device is still being used by earlycon, introduce the struct sci_port::probing flag and account for it in early_console_exit(). 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 9f7dea8 commit 5f10170

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

drivers/tty/serial/sh-sci.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ static struct sci_port sci_ports[SCI_NPORTS];
166166
static unsigned long sci_ports_in_use;
167167
static struct uart_driver sci_uart_driver;
168168
static bool sci_uart_earlycon;
169+
static bool sci_uart_earlycon_dev_probing;
169170

170171
static inline struct sci_port *
171172
to_sci_port(struct uart_port *uart)
@@ -3386,7 +3387,8 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev,
33863387
static int sci_probe_single(struct platform_device *dev,
33873388
unsigned int index,
33883389
struct plat_sci_port *p,
3389-
struct sci_port *sciport)
3390+
struct sci_port *sciport,
3391+
struct resource *sci_res)
33903392
{
33913393
int ret;
33923394

@@ -3433,6 +3435,14 @@ static int sci_probe_single(struct platform_device *dev,
34333435
sciport->port.flags |= UPF_HARD_FLOW;
34343436
}
34353437

3438+
if (sci_uart_earlycon && sci_ports[0].port.mapbase == sci_res->start) {
3439+
/*
3440+
* Skip cleanup the sci_port[0] in early_console_exit(), this
3441+
* port is the same as the earlycon one.
3442+
*/
3443+
sci_uart_earlycon_dev_probing = true;
3444+
}
3445+
34363446
return uart_add_one_port(&sci_uart_driver, &sciport->port);
34373447
}
34383448

@@ -3491,7 +3501,7 @@ static int sci_probe(struct platform_device *dev)
34913501

34923502
platform_set_drvdata(dev, sp);
34933503

3494-
ret = sci_probe_single(dev, dev_id, p, sp);
3504+
ret = sci_probe_single(dev, dev_id, p, sp, res);
34953505
if (ret)
34963506
return ret;
34973507

@@ -3574,6 +3584,22 @@ sh_early_platform_init_buffer("earlyprintk", &sci_driver,
35743584
#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
35753585
static struct plat_sci_port port_cfg;
35763586

3587+
static int early_console_exit(struct console *co)
3588+
{
3589+
struct sci_port *sci_port = &sci_ports[0];
3590+
3591+
/*
3592+
* Clean the slot used by earlycon. A new SCI device might
3593+
* map to this slot.
3594+
*/
3595+
if (!sci_uart_earlycon_dev_probing) {
3596+
memset(sci_port, 0, sizeof(*sci_port));
3597+
sci_uart_earlycon = false;
3598+
}
3599+
3600+
return 0;
3601+
}
3602+
35773603
static int __init early_console_setup(struct earlycon_device *device,
35783604
int type)
35793605
{
@@ -3591,6 +3617,8 @@ static int __init early_console_setup(struct earlycon_device *device,
35913617
SCSCR_RE | SCSCR_TE | port_cfg.scscr);
35923618

35933619
device->con->write = serial_console_write;
3620+
device->con->exit = early_console_exit;
3621+
35943622
return 0;
35953623
}
35963624
static int __init sci_early_console_setup(struct earlycon_device *device,

0 commit comments

Comments
 (0)