Commit 6a0af9fc authored by Petr Mladek's avatar Petr Mladek

Merge branch 'for-5.7-preferred-console' into for-linus

parents e8cc2b97 33225d7b
...@@ -135,7 +135,7 @@ static inline int con_debug_leave(void) ...@@ -135,7 +135,7 @@ static inline int con_debug_leave(void)
*/ */
#define CON_PRINTBUFFER (1) #define CON_PRINTBUFFER (1)
#define CON_CONSDEV (2) /* Last on the command line */ #define CON_CONSDEV (2) /* Preferred console, /dev/console */
#define CON_ENABLED (4) #define CON_ENABLED (4)
#define CON_BOOT (8) #define CON_BOOT (8)
#define CON_ANYTIME (16) /* Safe to call when cpu is offline */ #define CON_ANYTIME (16) /* Safe to call when cpu is offline */
......
...@@ -6,6 +6,7 @@ struct console_cmdline ...@@ -6,6 +6,7 @@ struct console_cmdline
{ {
char name[16]; /* Name of the driver */ char name[16]; /* Name of the driver */
int index; /* Minor dev. to use */ int index; /* Minor dev. to use */
bool user_specified; /* Specified by command line vs. platform */
char *options; /* Options for the driver */ char *options; /* Options for the driver */
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE #ifdef CONFIG_A11Y_BRAILLE_CONSOLE
char *brl_options; /* Options for braille driver */ char *brl_options; /* Options for braille driver */
......
...@@ -280,6 +280,7 @@ static struct console *exclusive_console; ...@@ -280,6 +280,7 @@ static struct console *exclusive_console;
static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES]; static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
static int preferred_console = -1; static int preferred_console = -1;
static bool has_preferred_console;
int console_set_on_cmdline; int console_set_on_cmdline;
EXPORT_SYMBOL(console_set_on_cmdline); EXPORT_SYMBOL(console_set_on_cmdline);
...@@ -2115,7 +2116,7 @@ asmlinkage __visible void early_printk(const char *fmt, ...) ...@@ -2115,7 +2116,7 @@ asmlinkage __visible void early_printk(const char *fmt, ...)
#endif #endif
static int __add_preferred_console(char *name, int idx, char *options, static int __add_preferred_console(char *name, int idx, char *options,
char *brl_options) char *brl_options, bool user_specified)
{ {
struct console_cmdline *c; struct console_cmdline *c;
int i; int i;
...@@ -2130,6 +2131,8 @@ static int __add_preferred_console(char *name, int idx, char *options, ...@@ -2130,6 +2131,8 @@ static int __add_preferred_console(char *name, int idx, char *options,
if (strcmp(c->name, name) == 0 && c->index == idx) { if (strcmp(c->name, name) == 0 && c->index == idx) {
if (!brl_options) if (!brl_options)
preferred_console = i; preferred_console = i;
if (user_specified)
c->user_specified = true;
return 0; return 0;
} }
} }
...@@ -2139,6 +2142,7 @@ static int __add_preferred_console(char *name, int idx, char *options, ...@@ -2139,6 +2142,7 @@ static int __add_preferred_console(char *name, int idx, char *options,
preferred_console = i; preferred_console = i;
strlcpy(c->name, name, sizeof(c->name)); strlcpy(c->name, name, sizeof(c->name));
c->options = options; c->options = options;
c->user_specified = user_specified;
braille_set_options(c, brl_options); braille_set_options(c, brl_options);
c->index = idx; c->index = idx;
...@@ -2193,7 +2197,7 @@ static int __init console_setup(char *str) ...@@ -2193,7 +2197,7 @@ static int __init console_setup(char *str)
idx = simple_strtoul(s, NULL, 10); idx = simple_strtoul(s, NULL, 10);
*s = 0; *s = 0;
__add_preferred_console(buf, idx, options, brl_options); __add_preferred_console(buf, idx, options, brl_options, true);
console_set_on_cmdline = 1; console_set_on_cmdline = 1;
return 1; return 1;
} }
...@@ -2214,7 +2218,7 @@ __setup("console=", console_setup); ...@@ -2214,7 +2218,7 @@ __setup("console=", console_setup);
*/ */
int add_preferred_console(char *name, int idx, char *options) int add_preferred_console(char *name, int idx, char *options)
{ {
return __add_preferred_console(name, idx, options, NULL); return __add_preferred_console(name, idx, options, NULL, false);
} }
bool console_suspend_enabled = true; bool console_suspend_enabled = true;
...@@ -2626,6 +2630,63 @@ static int __init keep_bootcon_setup(char *str) ...@@ -2626,6 +2630,63 @@ static int __init keep_bootcon_setup(char *str)
early_param("keep_bootcon", keep_bootcon_setup); early_param("keep_bootcon", keep_bootcon_setup);
/*
* This is called by register_console() to try to match
* the newly registered console with any of the ones selected
* by either the command line or add_preferred_console() and
* setup/enable it.
*
* Care need to be taken with consoles that are statically
* enabled such as netconsole
*/
static int try_enable_new_console(struct console *newcon, bool user_specified)
{
struct console_cmdline *c;
int i;
for (i = 0, c = console_cmdline;
i < MAX_CMDLINECONSOLES && c->name[0];
i++, c++) {
if (c->user_specified != user_specified)
continue;
if (!newcon->match ||
newcon->match(newcon, c->name, c->index, c->options) != 0) {
/* default matching */
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
if (strcmp(c->name, newcon->name) != 0)
continue;
if (newcon->index >= 0 &&
newcon->index != c->index)
continue;
if (newcon->index < 0)
newcon->index = c->index;
if (_braille_register_console(newcon, c))
return 0;
if (newcon->setup &&
newcon->setup(newcon, c->options) != 0)
return -EIO;
}
newcon->flags |= CON_ENABLED;
if (i == preferred_console) {
newcon->flags |= CON_CONSDEV;
has_preferred_console = true;
}
return 0;
}
/*
* Some consoles, such as pstore and netconsole, can be enabled even
* without matching. Accept the pre-enabled consoles only when match()
* and setup() had a change to be called.
*/
if (newcon->flags & CON_ENABLED && c->user_specified == user_specified)
return 0;
return -ENOENT;
}
/* /*
* The console driver calls this routine during kernel initialization * The console driver calls this routine during kernel initialization
* to register the console printing procedure with printk() and to * to register the console printing procedure with printk() and to
...@@ -2647,11 +2708,9 @@ early_param("keep_bootcon", keep_bootcon_setup); ...@@ -2647,11 +2708,9 @@ early_param("keep_bootcon", keep_bootcon_setup);
*/ */
void register_console(struct console *newcon) void register_console(struct console *newcon)
{ {
int i;
unsigned long flags; unsigned long flags;
struct console *bcon = NULL; struct console *bcon = NULL;
struct console_cmdline *c; int err;
static bool has_preferred;
if (console_drivers) if (console_drivers)
for_each_console(bcon) for_each_console(bcon)
...@@ -2678,15 +2737,15 @@ void register_console(struct console *newcon) ...@@ -2678,15 +2737,15 @@ void register_console(struct console *newcon)
if (console_drivers && console_drivers->flags & CON_BOOT) if (console_drivers && console_drivers->flags & CON_BOOT)
bcon = console_drivers; bcon = console_drivers;
if (!has_preferred || bcon || !console_drivers) if (!has_preferred_console || bcon || !console_drivers)
has_preferred = preferred_console >= 0; has_preferred_console = preferred_console >= 0;
/* /*
* See if we want to use this console driver. If we * See if we want to use this console driver. If we
* didn't select a console we take the first one * didn't select a console we take the first one
* that registers here. * that registers here.
*/ */
if (!has_preferred) { if (!has_preferred_console) {
if (newcon->index < 0) if (newcon->index < 0)
newcon->index = 0; newcon->index = 0;
if (newcon->setup == NULL || if (newcon->setup == NULL ||
...@@ -2694,47 +2753,20 @@ void register_console(struct console *newcon) ...@@ -2694,47 +2753,20 @@ void register_console(struct console *newcon)
newcon->flags |= CON_ENABLED; newcon->flags |= CON_ENABLED;
if (newcon->device) { if (newcon->device) {
newcon->flags |= CON_CONSDEV; newcon->flags |= CON_CONSDEV;
has_preferred = true; has_preferred_console = true;
} }
} }
} }
/* /* See if this console matches one we selected on the command line */
* See if this console matches one we selected on err = try_enable_new_console(newcon, true);
* the command line.
*/
for (i = 0, c = console_cmdline;
i < MAX_CMDLINECONSOLES && c->name[0];
i++, c++) {
if (!newcon->match ||
newcon->match(newcon, c->name, c->index, c->options) != 0) {
/* default matching */
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
if (strcmp(c->name, newcon->name) != 0)
continue;
if (newcon->index >= 0 &&
newcon->index != c->index)
continue;
if (newcon->index < 0)
newcon->index = c->index;
if (_braille_register_console(newcon, c))
return;
if (newcon->setup &&
newcon->setup(newcon, c->options) != 0)
break;
}
newcon->flags |= CON_ENABLED; /* If not, try to match against the platform default(s) */
if (i == preferred_console) { if (err == -ENOENT)
newcon->flags |= CON_CONSDEV; err = try_enable_new_console(newcon, false);
has_preferred = true;
}
break;
}
if (!(newcon->flags & CON_ENABLED)) /* printk() messages are not printed to the Braille console. */
if (err || newcon->flags & CON_BRL)
return; return;
/* /*
...@@ -2756,6 +2788,8 @@ void register_console(struct console *newcon) ...@@ -2756,6 +2788,8 @@ void register_console(struct console *newcon)
console_drivers = newcon; console_drivers = newcon;
if (newcon->next) if (newcon->next)
newcon->next->flags &= ~CON_CONSDEV; newcon->next->flags &= ~CON_CONSDEV;
/* Ensure this flag is always set for the head of the list */
newcon->flags |= CON_CONSDEV;
} else { } else {
newcon->next = console_drivers->next; newcon->next = console_drivers->next;
console_drivers->next = newcon; console_drivers->next = newcon;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment