diff options
Diffstat (limited to 'drivers/tty/serial/earlycon.c')
-rw-r--r-- | drivers/tty/serial/earlycon.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index c14873b67803..a5f380584cda 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c @@ -56,7 +56,6 @@ static void __init earlycon_init(struct earlycon_device *device, const char *name) { struct console *earlycon = device->con; - struct uart_port *port = &device->port; const char *s; size_t len; @@ -68,8 +67,14 @@ static void __init earlycon_init(struct earlycon_device *device, if (*s) earlycon->index = simple_strtoul(s, NULL, 10); len = s - name; - strlcpy(earlycon->name, name, min(len + 1, sizeof(earlycon->name))); + strscpy(earlycon->name, name, min(len + 1, sizeof(earlycon->name))); earlycon->data = &early_console_dev; +} + +static void __init earlycon_print_info(struct earlycon_device *device) +{ + struct console *earlycon = device->con; + struct uart_port *port = &device->port; if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM16 || port->iotype == UPIO_MEM32 || port->iotype == UPIO_MEM32BE) @@ -118,7 +123,7 @@ static int __init parse_options(struct earlycon_device *device, char *options) device->baud = simple_strtoul(options, NULL, 0); length = min(strcspn(options, " ") + 1, (size_t)(sizeof(device->options))); - strlcpy(device->options, options, length); + strscpy(device->options, options, length); } return 0; @@ -140,6 +145,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match) earlycon_init(&early_console_dev, match->name); err = match->setup(&early_console_dev, buf); + earlycon_print_info(&early_console_dev); if (err < 0) return err; if (!early_console_dev.con->write) @@ -169,7 +175,8 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match) */ int __init setup_earlycon(char *buf) { - const struct earlycon_id **p_match; + const struct earlycon_id *match; + bool empty_compatible = true; if (!buf || !buf[0]) return -EINVAL; @@ -177,14 +184,17 @@ int __init setup_earlycon(char *buf) if (early_con.flags & CON_ENABLED) return -EALREADY; - for (p_match = __earlycon_table; p_match < __earlycon_table_end; - p_match++) { - const struct earlycon_id *match = *p_match; +again: + for (match = __earlycon_table; match < __earlycon_table_end; match++) { size_t len = strlen(match->name); if (strncmp(buf, match->name, len)) continue; + /* prefer entries with empty compatible */ + if (empty_compatible && *match->compatible) + continue; + if (buf[len]) { if (buf[len] != ',') continue; @@ -195,6 +205,11 @@ int __init setup_earlycon(char *buf) return register_earlycon(buf, match); } + if (empty_compatible) { + empty_compatible = false; + goto again; + } + return -ENOENT; } @@ -238,6 +253,9 @@ int __init of_setup_earlycon(const struct earlycon_id *match, bool big_endian; u64 addr; + if (early_con.flags & CON_ENABLED) + return -EALREADY; + spin_lock_init(&port->lock); port->iotype = UPIO_MEM; addr = of_flat_dt_translate_address(node); @@ -286,11 +304,12 @@ int __init of_setup_earlycon(const struct earlycon_id *match, if (options) { early_console_dev.baud = simple_strtoul(options, NULL, 0); - strlcpy(early_console_dev.options, options, + strscpy(early_console_dev.options, options, sizeof(early_console_dev.options)); } earlycon_init(&early_console_dev, match->name); err = match->setup(&early_console_dev, options); + earlycon_print_info(&early_console_dev); if (err < 0) return err; if (!early_console_dev.con->write) |