On Mon, 10 Jul 2017 23:21:07 PDT (-0700), m...@ellerman.id.au wrote: > Palmer Dabbelt <pal...@dabbelt.com> writes: >> > ... >> +#ifdef CONFIG_EARLY_PRINTK >> +static void sbi_console_write(struct console *co, const char *buf, >> + unsigned int n) >> +{ >> + int i; >> + >> + for (i = 0; i < n; ++i) { >> + if (buf[i] == '\n') >> + sbi_console_putchar('\r'); >> + sbi_console_putchar(buf[i]); >> + } >> +} >> + >> +static struct console early_console_dev __initdata = { >> + .name = "early", >> + .write = sbi_console_write, >> + .flags = CON_PRINTBUFFER | CON_BOOT, > > AFAICS you could add CON_ANYTIME here, which would mean this console > would print output before the CPU is online. > > I think it doesn't currently matter because you call parse_early_param() > from setup_arch(), at which point the boot CPU has been marked online. > > But if this console can actually work earlier then you might be better > off just registering it unconditionally very early.
That seems like a good idea. I'm not familiar with how all this works, but from my understanding of this early_initcall() should be sufficient to make this work? The only other driver that sets CON_ANYTIME and supports EARLY_PRINTK is hvc_xen, but that installs a header to let init code register the console directly. The early_initcall mechanism seems cleaner if it does the right thing. How does this look? diff --git a/drivers/tty/hvc/hvc_sbi.c b/drivers/tty/hvc/hvc_sbi.c index 98114cbd85f1..534d6b75a2c6 100644 --- a/drivers/tty/hvc/hvc_sbi.c +++ b/drivers/tty/hvc/hvc_sbi.c @@ -87,11 +87,11 @@ static void sbi_console_write(struct console *co, const char *buf, static struct console early_console_dev __initdata = { .name = "early", .write = sbi_console_write, - .flags = CON_PRINTBUFFER | CON_BOOT, + .flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME, .index = -1 }; -static int __init setup_early_printk(char *str) +static int __init setup_early_printk(void) { if (early_console == NULL) { early_console = &early_console_dev; @@ -99,5 +99,5 @@ static int __init setup_early_printk(char *str) } return 0; } -early_param("earlyprintk", setup_early_printk); +early_initcall(setup_early_printk); #endif