All of lore.kernel.org
 help / color / mirror / Atom feed
From: Petr Mladek <pmladek@suse.com>
To: John Ogness <john.ogness@linutronix.de>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Marcos Paulo de Souza <mpdesouza@suse.com>,
	Chris Down <chris@chrisdown.name>,
	Naveen Kumar Chaudhary <naveen.osdev@gmail.com>,
	linux-kernel@vger.kernel.org, Petr Mladek <pmladek@suse.com>
Subject: [PATCH v4 08/11] printk: Try to register each console as Braille first
Date: Thu,  4 Jun 2026 12:14:55 +0200	[thread overview]
Message-ID: <20260604101459.393162-9-pmladek@suse.com> (raw)
In-Reply-To: <20260604101459.393162-1-pmladek@suse.com>

Braille consoles are unique: they can only be enabled via the command
line and use the preferred console framework for initialization, yet
they are never added to the console_list or associated with
/dev/console. Because of this, the preferred_console variable remains
unset when only a Braille console is requested.

Currently, try_enable_preferred_console() must be called even when
"preferred_dev_console" variable is not set, just to catch these "hidden"
Braille requests.

Refactor the logic by adding a parameter to try_enable_preferred_console()
to explicitly handle Braille vs. non-Braille cases. It will eventually
allow to skip try_enable_preferred_console() when there are no preferred
consoles. This improves code robustness by ensuring the console
setup is explicit and only performed once.

Note that _braille_register_console() is skipped when the given console
driver has a match() callback and it succeeded. It means that it took
over an early console and can't be used as a Braille console.

As a result try_enable_braille_console() might return success even
when it did not enabled the console in the Braille mode. It is
the reason why register_console() has to explicitly check whether
CON_BRL flag was really set and could skip the further steps.

The refactoring even fixes two subtle bugs:

1. When only the Braille console is defined on the command line,
   the original code might attempt to enable the same console twice—once
   as a default and once as a Braille console. This results in calling
   the setup() callback twice and incorrectly setting the CON_CONSDEV flag.

2. When the same console is defined on the command line using devname
   and then as Braille console, for example:

      console=00:00:0.0,115200 console=brl,ttyS0,115200

   It would have two separate entries in preferred_consoles[] array.

   The 2nd (Braille) entry would be used when univ8250_console_init()
   tries to register the generic "ttyS" console driver. Note that
   the 1st entry still does not have defined the "name" entry at
   this stage.

   The 1st non-Braille entry would be used later when serial8250_init()
   registers all found devices, assigns "tty0" for the given "00:00:0.0"
   devname and tries to register the same struct console once again.

   The original code would call newcon->setup() twice in this scenario.
   It won't add the console into console_list only because the later
   check in register_console() would detect CON_BRL flag set from
   the 1st registration and return early.

Signed-off-by: Petr Mladek <pmladek@suse.com>
---
 kernel/printk/printk.c | 56 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 50 insertions(+), 6 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 5fb9581804c7..3a645558c18a 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -367,6 +367,7 @@ static int console_locked;
 static struct preferred_console preferred_consoles[MAX_PREFERRED_CONSOLES];
 
 static int preferred_dev_console = -1;
+static bool want_braille_console;
 int console_set_on_cmdline;
 EXPORT_SYMBOL(console_set_on_cmdline);
 
@@ -2648,7 +2649,9 @@ static int add_or_update_preferred_console(unsigned int i,
 
 	braille_update_options(pc, brl_options);
 
-	if (!brl_options)
+	if (brl_options)
+		want_braille_console = true;
+	else
 		preferred_dev_console = i;
 
 	/*
@@ -3977,8 +3980,9 @@ static int console_call_setup(struct console *newcon, char *options)
  * by either the command line or add_preferred_console() and
  * setup/enable it.
  */
-static int try_enable_preferred_console(struct console *newcon,
-					bool user_specified)
+static int __try_enable_preferred_console(struct console *newcon,
+					  bool user_specified,
+					  bool try_only_braille)
 {
 	struct preferred_console *pc;
 	int i, err;
@@ -3989,8 +3993,19 @@ static int try_enable_preferred_console(struct console *newcon,
 		/* Console not yet initialized? */
 		if (!pc->name[0])
 			continue;
-		if (pc->user_specified != user_specified)
-			continue;
+
+		/*
+		 * @try_only_braille and @user_specifified define which
+		 * preferred console entries are handled in this round.
+		 */
+		if (try_only_braille) {
+			if (!is_braille_console_preferred(pc))
+				continue;
+		} else {
+			if (pc->user_specified != user_specified)
+				continue;
+		}
+
 		if (!newcon->match ||
 		    newcon->match(newcon, pc->name, pc->index, pc->options) != 0) {
 			/* default matching */
@@ -4003,7 +4018,7 @@ static int try_enable_preferred_console(struct console *newcon,
 			if (newcon->index < 0)
 				newcon->index = pc->index;
 
-			if (is_braille_console_preferred(pc))
+			if (try_only_braille)
 				return _braille_register_console(newcon, pc);
 
 			err = console_call_setup(newcon, pc->options);
@@ -4019,6 +4034,17 @@ static int try_enable_preferred_console(struct console *newcon,
 	return -ENOENT;
 }
 
+static int try_enable_preferred_console(struct console *newcon,
+					bool user_specified)
+{
+	return __try_enable_preferred_console(newcon, user_specified, false);
+}
+
+static int try_enable_braille_console(struct console *newcon)
+{
+	return __try_enable_preferred_console(newcon, true, true);
+}
+
 /* Try to enable the console unconditionally */
 static void try_enable_default_console(struct console *newcon)
 {
@@ -4041,6 +4067,24 @@ static int try_enable_console(struct console *newcon)
 {
 	int err;
 
+	/*
+	 * First, try to enable the console driver as a Braille console.
+	 * It would have metadata in the preferred_consoles[] array.
+	 * But it won't be counted as @preferred_console because
+	 * it does not get printk() messages and is not associated
+	 * with /dev/console.
+	 *
+	 * Note that it might succeed also when the driver has a match()
+	 * callback and it took over a boot console. In this case,
+	 * the driver will continue working as a classic non-Braille
+	 * console.
+	 */
+	if (want_braille_console) {
+		err = try_enable_braille_console(newcon);
+		if (err != -ENOENT)
+			return err;
+	}
+
 	/*
 	 * See if we want to enable this console driver by default.
 	 *
-- 
2.54.0


  parent reply	other threads:[~2026-06-04 10:16 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-04 10:14 [PATCH v4 00/11] printk: Clean up preferred console handling Petr Mladek
2026-06-04 10:14 ` [PATCH v4 01/11] printk: Handle pre-enabled consoles in the top-level register_console() Petr Mladek
2026-07-14 13:33   ` John Ogness
2026-07-15 14:43     ` Petr Mladek
2026-06-04 10:14 ` [PATCH v4 02/11] printk: Rename struct console_cmdline to preferred_console Petr Mladek
2026-06-04 10:14 ` [PATCH v4 03/11] printk: Rename preferred_console to preferred_dev_console Petr Mladek
2026-06-04 10:14 ` [PATCH v4 04/11] printk: Separate code for adding/updating preferred console metadata Petr Mladek
2026-07-14 14:35   ` John Ogness
2026-07-15 15:52     ` Petr Mladek
2026-06-04 10:14 ` [PATCH v4 05/11] printk: Cleanup _braille_(un)register_console() wrappers Petr Mladek
2026-06-04 10:14 ` [PATCH v4 06/11] console/braille: Lock console->setup() call during the registration Petr Mladek
2026-07-15 14:41   ` John Ogness
2026-06-04 10:14 ` [PATCH v4 07/11] printk: Separate code for enabling console Petr Mladek
2026-07-15 16:01   ` John Ogness
2026-06-04 10:14 ` Petr Mladek [this message]
2026-06-04 10:14 ` [PATCH v4 09/11] printk: Do not set Braille console as preferred_console Petr Mladek
2026-06-04 10:14 ` [PATCH v4 10/11] printk: Modify try_enable_default_console() to return error/success Petr Mladek
2026-06-04 10:14 ` [PATCH v4 11/11] printk: Try enable preferred consoles only when there are any Petr Mladek
2026-07-14  8:42 ` [PATCH v4 00/11] printk: Clean up preferred console handling Petr Mladek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260604101459.393162-9-pmladek@suse.com \
    --to=pmladek@suse.com \
    --cc=chris@chrisdown.name \
    --cc=john.ogness@linutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mpdesouza@suse.com \
    --cc=naveen.osdev@gmail.com \
    --cc=rostedt@goodmis.org \
    --cc=senozhatsky@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.