-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
printk: Save console options for add_preferred_console_match()
Driver subsystems may need to translate the preferred console name to the character device name used. We already do some of this in console_setup() with a few hardcoded names, but that does not scale well. The console options are parsed early in console_setup(), and the consoles are added with __add_preferred_console(). At this point we don't know much about the character device names and device drivers getting probed. To allow driver subsystems to set up a preferred console, let's save the kernel command line console options. To add a preferred console from a driver subsystem with optional character device name translation, let's add a new function add_preferred_console_match(). This allows the serial core layer to support console=DEVNAME:0.0 style hardware based addressing in addition to the current console=ttyS0 style naming. And we can start moving console_setup() character device parsing to the driver subsystem specific code. We use a separate array from the console_cmdline array as the character device name and index may be unknown at the console_setup() time. And eventually there's no need to call __add_preferred_console() until the subsystem is ready to handle the console. Adding the console name in addition to the character device name, and a flag for an added console, could be added to the struct console_cmdline. And the console_cmdline array handling could be modified accordingly. But that complicates things compared saving the console options, and then adding the consoles when the subsystems handling the consoles are ready. Co-developed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://lore.kernel.org/r/20240327110021.59793-2-tony@atomide.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
- Loading branch information
Tony Lindgren
authored and
Greg Kroah-Hartman
committed
Apr 9, 2024
1 parent
e51c3e1
commit f03e8c1
Showing
5 changed files
with
167 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Kernel command line console options for hardware based addressing | ||
* | ||
* Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/ | ||
* Author: Tony Lindgren <tony@atomide.com> | ||
*/ | ||
|
||
#include <linux/console.h> | ||
#include <linux/init.h> | ||
#include <linux/string.h> | ||
#include <linux/types.h> | ||
|
||
#include <asm/errno.h> | ||
|
||
#include "console_cmdline.h" | ||
|
||
/* | ||
* Allow longer DEVNAME:0.0 style console naming such as abcd0000.serial:0.0 | ||
* in addition to the legacy ttyS0 style naming. | ||
*/ | ||
#define CONSOLE_NAME_MAX 32 | ||
|
||
#define CONSOLE_OPT_MAX 16 | ||
#define CONSOLE_BRL_OPT_MAX 16 | ||
|
||
struct console_option { | ||
char name[CONSOLE_NAME_MAX]; | ||
char opt[CONSOLE_OPT_MAX]; | ||
char brl_opt[CONSOLE_BRL_OPT_MAX]; | ||
u8 has_brl_opt:1; | ||
}; | ||
|
||
/* Updated only at console_setup() time, no locking needed */ | ||
static struct console_option conopt[MAX_CMDLINECONSOLES]; | ||
|
||
/** | ||
* console_opt_save - Saves kernel command line console option for driver use | ||
* @str: Kernel command line console name and option | ||
* @brl_opt: Braille console options | ||
* | ||
* Saves a kernel command line console option for driver subsystems to use for | ||
* adding a preferred console during init. Called from console_setup() only. | ||
* | ||
* Return: 0 on success, negative error code on failure. | ||
*/ | ||
int __init console_opt_save(const char *str, const char *brl_opt) | ||
{ | ||
struct console_option *con; | ||
size_t namelen, optlen; | ||
const char *opt; | ||
int i; | ||
|
||
namelen = strcspn(str, ","); | ||
if (namelen == 0 || namelen >= CONSOLE_NAME_MAX) | ||
return -EINVAL; | ||
|
||
opt = str + namelen; | ||
if (*opt == ',') | ||
opt++; | ||
|
||
optlen = strlen(opt); | ||
if (optlen >= CONSOLE_OPT_MAX) | ||
return -EINVAL; | ||
|
||
for (i = 0; i < MAX_CMDLINECONSOLES; i++) { | ||
con = &conopt[i]; | ||
|
||
if (con->name[0]) { | ||
if (!strncmp(str, con->name, namelen)) | ||
return 0; | ||
continue; | ||
} | ||
|
||
/* | ||
* The name isn't terminated, only opt is. Empty opt is fine, | ||
* but brl_opt can be either empty or NULL. For more info, see | ||
* _braille_console_setup(). | ||
*/ | ||
strscpy(con->name, str, namelen + 1); | ||
strscpy(con->opt, opt, CONSOLE_OPT_MAX); | ||
if (brl_opt) { | ||
strscpy(con->brl_opt, brl_opt, CONSOLE_BRL_OPT_MAX); | ||
con->has_brl_opt = 1; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
return -ENOMEM; | ||
} | ||
|
||
static struct console_option *console_opt_find(const char *name) | ||
{ | ||
struct console_option *con; | ||
int i; | ||
|
||
for (i = 0; i < MAX_CMDLINECONSOLES; i++) { | ||
con = &conopt[i]; | ||
if (!strcmp(name, con->name)) | ||
return con; | ||
} | ||
|
||
return NULL; | ||
} | ||
|
||
/** | ||
* add_preferred_console_match - Adds a preferred console if a match is found | ||
* @match: Expected console on kernel command line, such as console=DEVNAME:0.0 | ||
* @name: Name of the console character device to add such as ttyS | ||
* @idx: Index for the console | ||
* | ||
* Allows driver subsystems to add a console after translating the command | ||
* line name to the character device name used for the console. Options are | ||
* added automatically based on the kernel command line. Duplicate preferred | ||
* consoles are ignored by __add_preferred_console(). | ||
* | ||
* Return: 0 on success, negative error code on failure. | ||
*/ | ||
int add_preferred_console_match(const char *match, const char *name, | ||
const short idx) | ||
{ | ||
struct console_option *con; | ||
char *brl_opt = NULL; | ||
|
||
if (!match || !strlen(match) || !name || !strlen(name) || | ||
idx < 0) | ||
return -EINVAL; | ||
|
||
con = console_opt_find(match); | ||
if (!con) | ||
return -ENOENT; | ||
|
||
/* | ||
* See __add_preferred_console(). It checks for NULL brl_options to set | ||
* the preferred_console flag. Empty brl_opt instead of NULL leads into | ||
* the preferred_console flag not set, and CON_CONSDEV not being set, | ||
* and the boot console won't get disabled at the end of console_setup(). | ||
*/ | ||
if (con->has_brl_opt) | ||
brl_opt = con->brl_opt; | ||
|
||
console_opt_add_preferred_console(name, idx, con->opt, brl_opt); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters