int __init of_setup_earlycon(unsigned long addr, int (*setup)(struct earlycon_device *, const char *)) { int err; struct uart_port *port = &early_console_dev.port; port->iotype = UPIO_MEM; port->mapbase = addr; port->uartclk = BASE_BAUD * 16; port->membase = earlycon_map(addr, SZ_4K); early_console_dev.con->data = &early_console_dev; err = setup(&early_console_dev, NULL); if (err < 0) return err; if (!early_console_dev.con->write) return -ENODEV; register_console(early_console_dev.con); return 0; }
int __init setup_earlycon(char *buf, const char *match, int (*setup)(struct earlycon_device *, const char *)) { int err; size_t len; struct uart_port *port = &early_console_dev.port; if (!buf || !match || !setup) return 0; len = strlen(match); if (strncmp(buf, match, len)) return 0; if (buf[len] && (buf[len] != ',')) return 0; buf += len + 1; err = parse_options(&early_console_dev, buf); /* On parsing error, pass the options buf to the setup function */ if (!err) buf = NULL; if (port->mapbase) port->membase = earlycon_map(port->mapbase, 64); early_console_dev.con->data = &early_console_dev; err = setup(&early_console_dev, buf); if (err < 0) return err; if (!early_console_dev.con->write) return -ENODEV; register_console(early_console_dev.con); return 0; }
static int __init register_earlycon(char *buf, const struct earlycon_id *match) { int err; struct uart_port *port = &early_console_dev.port; /* On parsing error, pass the options buf to the setup function */ if (buf && !parse_options(&early_console_dev, buf)) buf = NULL; spin_lock_init(&port->lock); port->uartclk = BASE_BAUD * 16; if (port->mapbase) port->membase = earlycon_map(port->mapbase, 64); earlycon_init(&early_console_dev, match->name); err = match->setup(&early_console_dev, buf); if (err < 0) return err; if (!early_console_dev.con->write) return -ENODEV; register_console(early_console_dev.con); return 0; }
int __init of_setup_earlycon(const struct earlycon_id *match, unsigned long node, const char *options) { int err; struct uart_port *port = &early_console_dev.port; const __be32 *val; bool big_endian; u64 addr; spin_lock_init(&port->lock); port->iotype = UPIO_MEM; addr = of_flat_dt_translate_address(node); if (addr == OF_BAD_ADDR) { pr_warn("[%s] bad address\n", match->name); return -ENXIO; } port->mapbase = addr; port->uartclk = BASE_BAUD * 16; port->membase = earlycon_map(port->mapbase, SZ_4K); val = of_get_flat_dt_prop(node, "reg-offset", NULL); if (val) port->mapbase += be32_to_cpu(*val); val = of_get_flat_dt_prop(node, "reg-shift", NULL); if (val) port->regshift = be32_to_cpu(*val); big_endian = of_get_flat_dt_prop(node, "big-endian", NULL) != NULL || (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) && of_get_flat_dt_prop(node, "native-endian", NULL) != NULL); val = of_get_flat_dt_prop(node, "reg-io-width", NULL); if (val) { switch (be32_to_cpu(*val)) { case 1: port->iotype = UPIO_MEM; break; case 2: port->iotype = UPIO_MEM16; break; case 4: port->iotype = (big_endian) ? UPIO_MEM32BE : UPIO_MEM32; break; default: pr_warn("[%s] unsupported reg-io-width\n", match->name); return -EINVAL; } } if (options) { strlcpy(early_console_dev.options, options, sizeof(early_console_dev.options)); } earlycon_init(&early_console_dev, match->name); err = match->setup(&early_console_dev, options); if (err < 0) return err; if (!early_console_dev.con->write) return -ENODEV; register_console(early_console_dev.con); return 0; }