Skip to content

Commit ff707df

Browse files
jognesspmladek
authored andcommitted
tty: serial: sh-sci: use setup() callback for early console
When setting up the early console, the setup() callback of the regular console is used. It is called manually before registering the early console instead of providing a setup() callback for the early console. This is probably because the early setup needs a different @options during the early stage. The issue here is that the setup() callback is called without the console_list_lock held and functions such as uart_set_options() expect that. Rather than manually calling the setup() function before registering, provide an early console setup() callback that will use the different early options. This ensures that the error checking, ordering, and locking context when setting up the early console are correct. Since this early console can only be registered via the earlyprintk= parameter, the @options argument of the setup() callback will always be NULL. Rather than simply ignoring the argument, add a WARN_ON() to get our attention in case the setup() callback semantics should change in the future. Note that technically the current implementation works because it is only used in early boot. And since the early console setup is performed before registering, it cannot race with anything and thus does not need any locking. However, longterm maintenance is easier when drivers rely on the subsystem API rather than manually implementing steps that could cause breakage in the future. Signed-off-by: John Ogness <[email protected]> Reviewed-by: Geert Uytterhoeven <[email protected]> Reviewed-by: Petr Mladek <[email protected]> Signed-off-by: Petr Mladek <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 848a9c1 commit ff707df

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

drivers/tty/serial/sh-sci.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3054,15 +3054,29 @@ static struct console serial_console = {
30543054
};
30553055

30563056
#ifdef CONFIG_SUPERH
3057+
static char early_serial_buf[32];
3058+
3059+
static int early_serial_console_setup(struct console *co, char *options)
3060+
{
3061+
/*
3062+
* This early console is always registered using the earlyprintk=
3063+
* parameter, which does not call add_preferred_console(). Thus
3064+
* @options is always NULL and the options for this early console
3065+
* are passed using a custom buffer.
3066+
*/
3067+
WARN_ON(options);
3068+
3069+
return serial_console_setup(co, early_serial_buf);
3070+
}
3071+
30573072
static struct console early_serial_console = {
30583073
.name = "early_ttySC",
30593074
.write = serial_console_write,
3075+
.setup = early_serial_console_setup,
30603076
.flags = CON_PRINTBUFFER,
30613077
.index = -1,
30623078
};
30633079

3064-
static char early_serial_buf[32];
3065-
30663080
static int sci_probe_earlyprintk(struct platform_device *pdev)
30673081
{
30683082
const struct plat_sci_port *cfg = dev_get_platdata(&pdev->dev);
@@ -3074,8 +3088,6 @@ static int sci_probe_earlyprintk(struct platform_device *pdev)
30743088

30753089
sci_init_single(pdev, &sci_ports[pdev->id], pdev->id, cfg, true);
30763090

3077-
serial_console_setup(&early_serial_console, early_serial_buf);
3078-
30793091
if (!strstr(early_serial_buf, "keep"))
30803092
early_serial_console.flags |= CON_BOOT;
30813093

0 commit comments

Comments
 (0)