diff options
author | Daniel Thompson <daniel.thompson@linaro.org> | 2020-04-30 18:17:41 +0200 |
---|---|---|
committer | Daniel Thompson <daniel.thompson@linaro.org> | 2020-06-02 16:15:45 +0200 |
commit | a4912303ac6fede434acf5c23a9108cdaf79844a (patch) | |
tree | d1691d0b2f4795740ca5c5438b87f2d6f9a9de70 /drivers/tty/serial/kgdboc.c | |
parent | Documentation: kgdboc: Document new kgdboc_earlycon parameter (diff) | |
download | linux-a4912303ac6fede434acf5c23a9108cdaf79844a.tar.xz linux-a4912303ac6fede434acf5c23a9108cdaf79844a.zip |
serial: kgdboc: Allow earlycon initialization to be deferred
Currently there is no guarantee that an earlycon will be initialized
before kgdboc tries to adopt it. Almost the opposite: on systems
with ACPI then if earlycon has no arguments then it is guaranteed that
earlycon will not be initialized.
This patch mitigates the problem by giving kgdboc_earlycon a second
chance during console_init(). This isn't quite as good as stopping during
early parameter parsing but it is still early in the kernel boot.
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Link: https://lore.kernel.org/r/20200430161741.1832050-1-daniel.thompson@linaro.org
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Diffstat (limited to 'drivers/tty/serial/kgdboc.c')
-rw-r--r-- | drivers/tty/serial/kgdboc.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c index fa6f7a3e73b9..41396982e9e0 100644 --- a/drivers/tty/serial/kgdboc.c +++ b/drivers/tty/serial/kgdboc.c @@ -514,6 +514,10 @@ static struct kgdb_io kgdboc_earlycon_io_ops = { .is_console = true, }; +#define MAX_CONSOLE_NAME_LEN (sizeof((struct console *) 0)->name) +static char kgdboc_earlycon_param[MAX_CONSOLE_NAME_LEN] __initdata; +static bool kgdboc_earlycon_late_enable __initdata; + static int __init kgdboc_earlycon_init(char *opt) { struct console *con; @@ -533,7 +537,23 @@ static int __init kgdboc_earlycon_init(char *opt) } if (!con) { - pr_info("Couldn't find kgdb earlycon\n"); + /* + * Both earlycon and kgdboc_earlycon are initialized during * early parameter parsing. We cannot guarantee earlycon gets + * in first and, in any case, on ACPI systems earlycon may + * defer its own initialization (usually to somewhere within + * setup_arch() ). To cope with either of these situations + * we can defer our own initialization to a little later in + * the boot. + */ + if (!kgdboc_earlycon_late_enable) { + pr_info("No suitable earlycon yet, will try later\n"); + if (opt) + strscpy(kgdboc_earlycon_param, opt, + sizeof(kgdboc_earlycon_param)); + kgdboc_earlycon_late_enable = true; + } else { + pr_info("Couldn't find kgdb earlycon\n"); + } goto unlock; } @@ -556,6 +576,23 @@ unlock: } early_param("kgdboc_earlycon", kgdboc_earlycon_init); + +/* + * This is only intended for the late adoption of an early console. + * + * It is not a reliable way to adopt regular consoles because we can not + * control what order console initcalls are made and, in any case, many + * regular consoles are registered much later in the boot process than + * the console initcalls! + */ +static int __init kgdboc_earlycon_late_init(void) +{ + if (kgdboc_earlycon_late_enable) + kgdboc_earlycon_init(kgdboc_earlycon_param); + return 0; +} +console_initcall(kgdboc_earlycon_late_init); + #endif /* IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */ module_init(init_kgdboc); |