Skip to content

Commit c7cef0a

Browse files
peterhurleygregkh
authored andcommitted
console: Add extensible console matching
Add match() method to struct console which allows the console to perform console command line matching instead of (or in addition to) default console matching (ie., by fixed name and index). The match() method returns 0 to indicate a successful match; normal console matching occurs if no match() method is defined or the match() method returns non-zero. The match() method is expected to set the console index if required. Re-implement earlycon-to-console-handoff with direct matching of "console=uart|uart8250,..." to the 8250 ttyS console. Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e13cb72 commit c7cef0a

File tree

5 files changed

+67
-77
lines changed

5 files changed

+67
-77
lines changed

drivers/tty/serial/8250/8250_core.c

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3322,17 +3322,62 @@ static int serial8250_console_setup(struct console *co, char *options)
33223322
return uart_set_options(port, co, baud, parity, bits, flow);
33233323
}
33243324

3325-
static int serial8250_console_early_setup(void)
3325+
/**
3326+
* serial8250_console_match - non-standard console matching
3327+
* @co: registering console
3328+
* @name: name from console command line
3329+
* @idx: index from console command line
3330+
* @options: ptr to option string from console command line
3331+
*
3332+
* Only attempts to match console command lines of the form:
3333+
* console=uart<>,io|mmio|mmio32,<addr>,<options>
3334+
* console=uart<>,<addr>,options
3335+
* This form is used to register an initial earlycon boot console and
3336+
* replace it with the serial8250_console at 8250 driver init.
3337+
*
3338+
* Performs console setup for a match (as required by interface)
3339+
*
3340+
* Returns 0 if console matches; otherwise non-zero to use default matching
3341+
*/
3342+
static int serial8250_console_match(struct console *co, char *name, int idx,
3343+
char *options)
33263344
{
3327-
return serial8250_find_port_for_earlycon();
3345+
char match[] = "uart"; /* 8250-specific earlycon name */
3346+
unsigned char iotype;
3347+
unsigned long addr;
3348+
int i;
3349+
3350+
if (strncmp(name, match, 4) != 0)
3351+
return -ENODEV;
3352+
3353+
if (uart_parse_earlycon(options, &iotype, &addr, &options))
3354+
return -ENODEV;
3355+
3356+
/* try to match the port specified on the command line */
3357+
for (i = 0; i < nr_uarts; i++) {
3358+
struct uart_port *port = &serial8250_ports[i].port;
3359+
3360+
if (port->iotype != iotype)
3361+
continue;
3362+
if ((iotype == UPIO_MEM || iotype == UPIO_MEM32) &&
3363+
(port->mapbase != addr))
3364+
continue;
3365+
if (iotype == UPIO_PORT && port->iobase != addr)
3366+
continue;
3367+
3368+
co->index = i;
3369+
return serial8250_console_setup(co, options);
3370+
}
3371+
3372+
return -ENODEV;
33283373
}
33293374

33303375
static struct console serial8250_console = {
33313376
.name = "ttyS",
33323377
.write = serial8250_console_write,
33333378
.device = uart_console_device,
33343379
.setup = serial8250_console_setup,
3335-
.early_setup = serial8250_console_early_setup,
3380+
.match = serial8250_console_match,
33363381
.flags = CON_PRINTBUFFER | CON_ANYTIME,
33373382
.index = -1,
33383383
.data = &serial8250_reg,
@@ -3346,19 +3391,6 @@ static int __init serial8250_console_init(void)
33463391
}
33473392
console_initcall(serial8250_console_init);
33483393

3349-
int serial8250_find_port(struct uart_port *p)
3350-
{
3351-
int line;
3352-
struct uart_port *port;
3353-
3354-
for (line = 0; line < nr_uarts; line++) {
3355-
port = &serial8250_ports[line].port;
3356-
if (uart_match_port(p, port))
3357-
return line;
3358-
}
3359-
return -ENODEV;
3360-
}
3361-
33623394
#define SERIAL8250_CONSOLE &serial8250_console
33633395
#else
33643396
#define SERIAL8250_CONSOLE NULL

drivers/tty/serial/8250/8250_early.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -173,26 +173,3 @@ int __init setup_early_serial8250_console(char *cmdline)
173173

174174
return setup_earlycon(cmdline, match, early_serial8250_setup);
175175
}
176-
177-
int serial8250_find_port_for_earlycon(void)
178-
{
179-
struct earlycon_device *device = early_device;
180-
struct uart_port *port = device ? &device->port : NULL;
181-
int line;
182-
int ret;
183-
184-
if (!port || (!port->membase && !port->iobase))
185-
return -ENODEV;
186-
187-
line = serial8250_find_port(port);
188-
if (line < 0)
189-
return -ENODEV;
190-
191-
ret = update_console_cmdline("uart", 8250,
192-
"ttyS", line, device->options);
193-
if (ret < 0)
194-
ret = update_console_cmdline("uart", 0,
195-
"ttyS", line, device->options);
196-
197-
return ret;
198-
}

include/linux/console.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ struct console {
123123
struct tty_driver *(*device)(struct console *, int *);
124124
void (*unblank)(void);
125125
int (*setup)(struct console *, char *);
126-
int (*early_setup)(void);
126+
int (*match)(struct console *, char *name, int idx, char *options);
127127
short flags;
128128
short index;
129129
int cflag;
@@ -141,7 +141,6 @@ extern int console_set_on_cmdline;
141141
extern struct console *early_console;
142142

143143
extern int add_preferred_console(char *name, int idx, char *options);
144-
extern int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options);
145144
extern void register_console(struct console *);
146145
extern int unregister_console(struct console *);
147146
extern struct console *console_drivers;

include/linux/serial_8250.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,6 @@ void serial8250_resume_port(int line);
118118

119119
extern int early_serial_setup(struct uart_port *port);
120120

121-
extern int serial8250_find_port(struct uart_port *p);
122-
extern int serial8250_find_port_for_earlycon(void);
123121
extern unsigned int serial8250_early_in(struct uart_port *port, int offset);
124122
extern void serial8250_early_out(struct uart_port *port, int offset, int value);
125123
extern int setup_early_serial8250_console(char *cmdline);

kernel/printk/printk.c

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,24 +2017,6 @@ int add_preferred_console(char *name, int idx, char *options)
20172017
return __add_preferred_console(name, idx, options, NULL);
20182018
}
20192019

2020-
int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options)
2021-
{
2022-
struct console_cmdline *c;
2023-
int i;
2024-
2025-
for (i = 0, c = console_cmdline;
2026-
i < MAX_CMDLINECONSOLES && c->name[0];
2027-
i++, c++)
2028-
if (strcmp(c->name, name) == 0 && c->index == idx) {
2029-
strlcpy(c->name, name_new, sizeof(c->name));
2030-
c->options = options;
2031-
c->index = idx_new;
2032-
return i;
2033-
}
2034-
/* not found */
2035-
return -1;
2036-
}
2037-
20382020
bool console_suspend_enabled = true;
20392021
EXPORT_SYMBOL(console_suspend_enabled);
20402022

@@ -2436,9 +2418,6 @@ void register_console(struct console *newcon)
24362418
if (preferred_console < 0 || bcon || !console_drivers)
24372419
preferred_console = selected_console;
24382420

2439-
if (newcon->early_setup)
2440-
newcon->early_setup();
2441-
24422421
/*
24432422
* See if we want to use this console driver. If we
24442423
* didn't select a console we take the first one
@@ -2464,21 +2443,26 @@ void register_console(struct console *newcon)
24642443
for (i = 0, c = console_cmdline;
24652444
i < MAX_CMDLINECONSOLES && c->name[0];
24662445
i++, c++) {
2467-
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
2468-
if (strcmp(c->name, newcon->name) != 0)
2469-
continue;
2470-
if (newcon->index >= 0 &&
2471-
newcon->index != c->index)
2472-
continue;
2473-
if (newcon->index < 0)
2474-
newcon->index = c->index;
2446+
if (!newcon->match ||
2447+
newcon->match(newcon, c->name, c->index, c->options) != 0) {
2448+
/* default matching */
2449+
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
2450+
if (strcmp(c->name, newcon->name) != 0)
2451+
continue;
2452+
if (newcon->index >= 0 &&
2453+
newcon->index != c->index)
2454+
continue;
2455+
if (newcon->index < 0)
2456+
newcon->index = c->index;
24752457

2476-
if (_braille_register_console(newcon, c))
2477-
return;
2458+
if (_braille_register_console(newcon, c))
2459+
return;
2460+
2461+
if (newcon->setup &&
2462+
newcon->setup(newcon, c->options) != 0)
2463+
break;
2464+
}
24782465

2479-
if (newcon->setup &&
2480-
newcon->setup(newcon, console_cmdline[i].options) != 0)
2481-
break;
24822466
newcon->flags |= CON_ENABLED;
24832467
if (i == selected_console) {
24842468
newcon->flags |= CON_CONSDEV;

0 commit comments

Comments
 (0)