Let's add serial_base_match_and_update_preferred_console() for consoles using DEVNAME:0.0 style naming. The earlier approach to add it caused issues in the kernel command line ordering as we were calling __add_preferred_console() again for the deferred consoles. Signed-off-by: Tony Lindgren <tony.lindgren@xxxxxxxxxxxxxxx> --- drivers/tty/serial/serial_base.h | 16 ++++++++++++ drivers/tty/serial/serial_base_bus.c | 37 ++++++++++++++++++++++++++++ drivers/tty/serial/serial_core.c | 4 +++ 3 files changed, 57 insertions(+) diff --git a/drivers/tty/serial/serial_base.h b/drivers/tty/serial/serial_base.h index b6c38d2edfd4..0d50db5b660b 100644 --- a/drivers/tty/serial/serial_base.h +++ b/drivers/tty/serial/serial_base.h @@ -49,3 +49,19 @@ void serial_ctrl_unregister_port(struct uart_driver *drv, struct uart_port *port int serial_core_register_port(struct uart_driver *drv, struct uart_port *port); void serial_core_unregister_port(struct uart_driver *drv, struct uart_port *port); + +#ifdef CONFIG_SERIAL_CORE_CONSOLE + +int serial_base_match_and_update_preferred_console(struct uart_driver *drv, + struct uart_port *port); + +#else + +static inline +int serial_base_match_and_update_preferred_console(struct uart_driver *drv, + struct uart_port *port) +{ + return 0; +} + +#endif diff --git a/drivers/tty/serial/serial_base_bus.c b/drivers/tty/serial/serial_base_bus.c index 4df2a4b10445..d822499ba9d6 100644 --- a/drivers/tty/serial/serial_base_bus.c +++ b/drivers/tty/serial/serial_base_bus.c @@ -8,6 +8,7 @@ * The serial core bus manages the serial core controller instances. */ +#include <linux/cleanup.h> #include <linux/container_of.h> #include <linux/device.h> #include <linux/idr.h> @@ -204,6 +205,42 @@ void serial_base_port_device_remove(struct serial_port_device *port_dev) put_device(&port_dev->dev); } +#ifdef CONFIG_SERIAL_CORE_CONSOLE + +/** + * serial_base_match_and_update_preferred_console - Match and update a preferred console + * @drv: Serial port device driver + * @port: Serial port instance + * + * Tries to match and update the preferred console for a serial port for + * the kernel command line option console=DEVNAME:0.0. + * + * Cannot be called early for ISA ports, depends on struct device. + * + * Return: 0 on success, negative error code on failure. + */ +int serial_base_match_and_update_preferred_console(struct uart_driver *drv, + struct uart_port *port) +{ + const char *port_match __free(kfree) = NULL; + int ret; + + port_match = kasprintf(GFP_KERNEL, "%s:%d.%d", dev_name(port->dev), + port->ctrl_id, port->port_id); + if (!port_match) + return -ENOMEM; + + ret = match_devname_and_update_preferred_console(port_match, + drv->dev_name, + port->line); + if (ret == -ENOENT) + return 0; + + return ret; +} + +#endif + static int serial_base_init(void) { int ret; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2a8006e3d687..9a18d0b95a41 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -3422,6 +3422,10 @@ int serial_core_register_port(struct uart_driver *drv, struct uart_port *port) if (ret) goto err_unregister_ctrl_dev; + ret = serial_base_match_and_update_preferred_console(drv, port); + if (ret) + goto err_unregister_port_dev; + ret = serial_core_add_one_port(drv, port); if (ret) goto err_unregister_port_dev; -- 2.45.2