lkml.org 
[lkml]   [2022]   [Nov]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH printk v3 40/40] tty: serial: sh-sci: use setup() callback for early console
Date
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.

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 <john.ogness@linutronix.de>
---
drivers/tty/serial/sh-sci.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 62f773286d44..f3a1cfec757a 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -3054,15 +3054,26 @@ static struct console serial_console = {
};

#ifdef CONFIG_SUPERH
+static char early_serial_buf[32];
+
+static int early_serial_console_setup(struct console *co, char *options)
+{
+ WARN_ON(options);
+ /*
+ * Use @early_serial_buf because @options will always be
+ * NULL at this early stage.
+ */
+ return serial_console_setup(co, early_serial_buf);
+}
+
static struct console early_serial_console = {
.name = "early_ttySC",
.write = serial_console_write,
+ .setup = early_serial_console_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
};

-static char early_serial_buf[32];
-
static int sci_probe_earlyprintk(struct platform_device *pdev)
{
const struct plat_sci_port *cfg = dev_get_platdata(&pdev->dev);
@@ -3074,8 +3085,6 @@ static int sci_probe_earlyprintk(struct platform_device *pdev)

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

- serial_console_setup(&early_serial_console, early_serial_buf);
-
if (!strstr(early_serial_buf, "keep"))
early_serial_console.flags |= CON_BOOT;

--
2.30.2
\
 
 \ /
  Last update: 2022-11-07 15:20    [W:0.505 / U:0.092 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site