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

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

parents e8cc2b97 33225d7b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ static inline int con_debug_leave(void)
 */

#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_BOOT	(8)
#define CON_ANYTIME	(16) /* Safe to call when cpu is offline */
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ struct console_cmdline
{
	char	name[16];			/* Name of the driver	    */
	int	index;				/* Minor dev. to use	    */
	bool	user_specified;			/* Specified by command line vs. platform */
	char	*options;			/* Options for the driver   */
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
	char	*brl_options;			/* Options for braille driver */
+78 −44
Original line number Diff line number Diff line
@@ -280,6 +280,7 @@ static struct console *exclusive_console;
static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];

static int preferred_console = -1;
static bool has_preferred_console;
int console_set_on_cmdline;
EXPORT_SYMBOL(console_set_on_cmdline);

@@ -2115,7 +2116,7 @@ asmlinkage __visible void early_printk(const char *fmt, ...)
#endif

static int __add_preferred_console(char *name, int idx, char *options,
				   char *brl_options)
				   char *brl_options, bool user_specified)
{
	struct console_cmdline *c;
	int i;
@@ -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 (!brl_options)
				preferred_console = i;
			if (user_specified)
				c->user_specified = true;
			return 0;
		}
	}
@@ -2139,6 +2142,7 @@ static int __add_preferred_console(char *name, int idx, char *options,
		preferred_console = i;
	strlcpy(c->name, name, sizeof(c->name));
	c->options = options;
	c->user_specified = user_specified;
	braille_set_options(c, brl_options);

	c->index = idx;
@@ -2193,7 +2197,7 @@ static int __init console_setup(char *str)
	idx = simple_strtoul(s, NULL, 10);
	*s = 0;

	__add_preferred_console(buf, idx, options, brl_options);
	__add_preferred_console(buf, idx, options, brl_options, true);
	console_set_on_cmdline = 1;
	return 1;
}
@@ -2214,7 +2218,7 @@ __setup("console=", console_setup);
 */
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;
@@ -2626,6 +2630,63 @@ static int __init keep_bootcon_setup(char *str)

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
 * to register the console printing procedure with printk() and to
@@ -2647,11 +2708,9 @@ early_param("keep_bootcon", keep_bootcon_setup);
 */
void register_console(struct console *newcon)
{
	int i;
	unsigned long flags;
	struct console *bcon = NULL;
	struct console_cmdline *c;
	static bool has_preferred;
	int err;

	if (console_drivers)
		for_each_console(bcon)
@@ -2678,15 +2737,15 @@ void register_console(struct console *newcon)
	if (console_drivers && console_drivers->flags & CON_BOOT)
		bcon = console_drivers;

	if (!has_preferred || bcon || !console_drivers)
		has_preferred = preferred_console >= 0;
	if (!has_preferred_console || bcon || !console_drivers)
		has_preferred_console = preferred_console >= 0;

	/*
	 *	See if we want to use this console driver. If we
	 *	didn't select a console we take the first one
	 *	that registers here.
	 */
	if (!has_preferred) {
	if (!has_preferred_console) {
		if (newcon->index < 0)
			newcon->index = 0;
		if (newcon->setup == NULL ||
@@ -2694,47 +2753,20 @@ void register_console(struct console *newcon)
			newcon->flags |= CON_ENABLED;
			if (newcon->device) {
				newcon->flags |= CON_CONSDEV;
				has_preferred = true;
				has_preferred_console = true;
			}
		}
	}

	/*
	 *	See if this console matches one we selected on
	 *	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;
	/* See if this console matches one we selected on the command line */
	err = try_enable_new_console(newcon, true);

			if (newcon->setup &&
			    newcon->setup(newcon, c->options) != 0)
				break;
		}
	/* If not, try to match against the platform default(s) */
	if (err == -ENOENT)
		err = try_enable_new_console(newcon, false);

		newcon->flags |= CON_ENABLED;
		if (i == preferred_console) {
			newcon->flags |= CON_CONSDEV;
			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;

	/*
@@ -2756,6 +2788,8 @@ void register_console(struct console *newcon)
		console_drivers = newcon;
		if (newcon->next)
			newcon->next->flags &= ~CON_CONSDEV;
		/* Ensure this flag is always set for the head of the list */
		newcon->flags |= CON_CONSDEV;
	} else {
		newcon->next = console_drivers->next;
		console_drivers->next = newcon;