Re: [PATCH 08/17] tty: New RISC-V SBI console driver

From: Palmer Dabbelt
Date: Tue Jul 11 2017 - 12:22:45 EST


On Mon, 10 Jul 2017 23:21:07 PDT (-0700), mpe@xxxxxxxxxxxxxx wrote:
> Palmer Dabbelt <palmer@xxxxxxxxxxx> 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