Skip to content

Commit 088da2a

Browse files
peterhurleygregkh
authored andcommitted
of: earlycon: Initialize port fields from DT properties
Read the optional "reg-offset", "reg-shift", "reg-io-width" and endianness properties and initialize the respective struct uart_port field if found. NB: These bindings are common to several drivers and the values merely indicate the default value; the registering earlycon setup() method can simply override the values if required. Acked-by: Rob Herring <[email protected]> Signed-off-by: Peter Hurley <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 4d118c9 commit 088da2a

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

drivers/of/fdt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ static int __init early_init_dt_scan_chosen_serial(void)
839839
if (addr == OF_BAD_ADDR)
840840
return -ENXIO;
841841

842-
of_setup_earlycon(addr, match, options);
842+
of_setup_earlycon(addr, match, offset, options);
843843
return 0;
844844
}
845845
return -ENODEV;

drivers/tty/serial/earlycon.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/io.h>
2020
#include <linux/serial_core.h>
2121
#include <linux/sizes.h>
22+
#include <linux/of_fdt.h>
2223

2324
#ifdef CONFIG_FIX_EARLYCON_MEM
2425
#include <asm/fixmap.h>
@@ -219,17 +220,47 @@ early_param("earlycon", param_setup_earlycon);
219220

220221
int __init of_setup_earlycon(unsigned long addr,
221222
const struct earlycon_id *match,
223+
unsigned long node,
222224
const char *options)
223225
{
224226
int err;
225227
struct uart_port *port = &early_console_dev.port;
228+
const __be32 *val;
229+
bool big_endian;
226230

227231
spin_lock_init(&port->lock);
228232
port->iotype = UPIO_MEM;
229233
port->mapbase = addr;
230234
port->uartclk = BASE_BAUD * 16;
231235
port->membase = earlycon_map(addr, SZ_4K);
232236

237+
val = of_get_flat_dt_prop(node, "reg-offset", NULL);
238+
if (val)
239+
port->mapbase += be32_to_cpu(*val);
240+
val = of_get_flat_dt_prop(node, "reg-shift", NULL);
241+
if (val)
242+
port->regshift = be32_to_cpu(*val);
243+
big_endian = of_get_flat_dt_prop(node, "big-endian", NULL) != NULL ||
244+
(IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) &&
245+
of_get_flat_dt_prop(node, "native-endian", NULL) != NULL);
246+
val = of_get_flat_dt_prop(node, "reg-io-width", NULL);
247+
if (val) {
248+
switch (be32_to_cpu(*val)) {
249+
case 1:
250+
port->iotype = UPIO_MEM;
251+
break;
252+
case 2:
253+
port->iotype = UPIO_MEM16;
254+
break;
255+
case 4:
256+
port->iotype = (big_endian) ? UPIO_MEM32BE : UPIO_MEM32;
257+
break;
258+
default:
259+
pr_warn("[%s] unsupported reg-io-width\n", match->name);
260+
return -EINVAL;
261+
}
262+
}
263+
233264
if (options) {
234265
strlcpy(early_console_dev.options, options,
235266
sizeof(early_console_dev.options));

include/linux/serial_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ extern const struct earlycon_id __earlycon_table_end[];
360360

361361
extern int setup_earlycon(char *buf);
362362
extern int of_setup_earlycon(unsigned long addr, const struct earlycon_id *match,
363+
unsigned long node,
363364
const char *options);
364365

365366
struct uart_port *uart_get_console(struct uart_port *ports, int nr,

0 commit comments

Comments
 (0)