serial: convert early_uart to earlycon for 8250
Beacuse SERIAL_PORT_DFNS is removed from include/asm-i386/serial.h and include/asm-x86_64/serial.h. the serial8250_ports need to be probed late in serial initializing stage. the console_init=>serial8250_console_init=> register_console=>serial8250_console_setup will return -ENDEV, and console ttyS0 can not be enabled at that time. need to wait till uart_add_one_port in drivers/serial/serial_core.c to call register_console to get console ttyS0. that is too late. Make early_uart to use early_param, so uart console can be used earlier. Make it to be bootconsole with CON_BOOT flag, so can use console handover feature. and it will switch to corresponding normal serial console automatically. new command line will be: console=uart8250,io,0x3f8,9600n8 console=uart8250,mmio,0xff5e0000,115200n8 or earlycon=uart8250,io,0x3f8,9600n8 earlycon=uart8250,mmio,0xff5e0000,115200n8 it will print in very early stage: Early serial console at I/O port 0x3f8 (options '9600n8') console [uart0] enabled later for console it will print: console handover: boot [uart0] -> real [ttyS0] Signed-off-by: <yinghai.lu@sun.com> Cc: Andi Kleen <ak@suse.de> Cc: Bjorn Helgaas <bjorn.helgaas@hp.com> Cc: Russell King <rmk@arm.linux.org.uk> Cc: Gerd Hoffmann <kraxel@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
b1c931e393
commit
18a8bd949d
|
@ -462,13 +462,20 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
Documentation/networking/netconsole.txt for an
|
Documentation/networking/netconsole.txt for an
|
||||||
alternative.
|
alternative.
|
||||||
|
|
||||||
uart,io,<addr>[,options]
|
uart[8250],io,<addr>[,options]
|
||||||
uart,mmio,<addr>[,options]
|
uart[8250],mmio,<addr>[,options]
|
||||||
Start an early, polled-mode console on the 8250/16550
|
Start an early, polled-mode console on the 8250/16550
|
||||||
UART at the specified I/O port or MMIO address,
|
UART at the specified I/O port or MMIO address,
|
||||||
switching to the matching ttyS device later. The
|
switching to the matching ttyS device later. The
|
||||||
options are the same as for ttyS, above.
|
options are the same as for ttyS, above.
|
||||||
|
|
||||||
|
earlycon= [KNL] Output early console device and options.
|
||||||
|
uart[8250],io,<addr>[,options]
|
||||||
|
uart[8250],mmio,<addr>[,options]
|
||||||
|
Start an early, polled-mode console on the 8250/16550
|
||||||
|
UART at the specified I/O port or MMIO address.
|
||||||
|
The options are the same as for ttyS, above.
|
||||||
|
|
||||||
cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver
|
cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver
|
||||||
Format:
|
Format:
|
||||||
<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
|
<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
|
||||||
|
|
|
@ -390,10 +390,6 @@ early_console_setup (char *cmdline)
|
||||||
if (!efi_setup_pcdp_console(cmdline))
|
if (!efi_setup_pcdp_console(cmdline))
|
||||||
earlycons++;
|
earlycons++;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
|
||||||
if (!early_serial_console_init(cmdline))
|
|
||||||
earlycons++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (earlycons) ? 0 : -1;
|
return (earlycons) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/console.h>
|
#include <linux/console.h>
|
||||||
#include <linux/efi.h>
|
#include <linux/efi.h>
|
||||||
#include <linux/serial.h>
|
#include <linux/serial.h>
|
||||||
|
#include <linux/serial_8250.h>
|
||||||
#include <asm/vga.h>
|
#include <asm/vga.h>
|
||||||
#include "pcdp.h"
|
#include "pcdp.h"
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ setup_serial_console(struct pcdp_uart *uart)
|
||||||
char parity;
|
char parity;
|
||||||
|
|
||||||
mmio = (uart->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY);
|
mmio = (uart->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY);
|
||||||
p += sprintf(p, "console=uart,%s,0x%lx",
|
p += sprintf(p, "uart8250,%s,0x%lx",
|
||||||
mmio ? "mmio" : "io", uart->addr.address);
|
mmio ? "mmio" : "io", uart->addr.address);
|
||||||
if (uart->baud) {
|
if (uart->baud) {
|
||||||
p += sprintf(p, ",%lu", uart->baud);
|
p += sprintf(p, ",%lu", uart->baud);
|
||||||
|
@ -41,7 +42,8 @@ setup_serial_console(struct pcdp_uart *uart)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return early_serial_console_init(options);
|
add_preferred_console("uart", 8250, &options[9]);
|
||||||
|
return setup_early_serial8250_console(options);
|
||||||
#else
|
#else
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2514,12 +2514,18 @@ static int __init serial8250_console_setup(struct console *co, char *options)
|
||||||
return uart_set_options(port, co, baud, parity, bits, flow);
|
return uart_set_options(port, co, baud, parity, bits, flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __init serial8250_console_early_setup(void)
|
||||||
|
{
|
||||||
|
return serial8250_find_port_for_earlycon();
|
||||||
|
}
|
||||||
|
|
||||||
static struct uart_driver serial8250_reg;
|
static struct uart_driver serial8250_reg;
|
||||||
static struct console serial8250_console = {
|
static struct console serial8250_console = {
|
||||||
.name = "ttyS",
|
.name = "ttyS",
|
||||||
.write = serial8250_console_write,
|
.write = serial8250_console_write,
|
||||||
.device = uart_console_device,
|
.device = uart_console_device,
|
||||||
.setup = serial8250_console_setup,
|
.setup = serial8250_console_setup,
|
||||||
|
.early_setup = serial8250_console_early_setup,
|
||||||
.flags = CON_PRINTBUFFER,
|
.flags = CON_PRINTBUFFER,
|
||||||
.index = -1,
|
.index = -1,
|
||||||
.data = &serial8250_reg,
|
.data = &serial8250_reg,
|
||||||
|
@ -2533,7 +2539,7 @@ static int __init serial8250_console_init(void)
|
||||||
}
|
}
|
||||||
console_initcall(serial8250_console_init);
|
console_initcall(serial8250_console_init);
|
||||||
|
|
||||||
static int __init find_port(struct uart_port *p)
|
int serial8250_find_port(struct uart_port *p)
|
||||||
{
|
{
|
||||||
int line;
|
int line;
|
||||||
struct uart_port *port;
|
struct uart_port *port;
|
||||||
|
@ -2546,26 +2552,6 @@ static int __init find_port(struct uart_port *p)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init serial8250_start_console(struct uart_port *port, char *options)
|
|
||||||
{
|
|
||||||
int line;
|
|
||||||
|
|
||||||
line = find_port(port);
|
|
||||||
if (line < 0)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
add_preferred_console("ttyS", line, options);
|
|
||||||
printk("Adding console on ttyS%d at %s 0x%lx (options '%s')\n",
|
|
||||||
line, port->iotype == UPIO_MEM ? "MMIO" : "I/O port",
|
|
||||||
port->iotype == UPIO_MEM ? (unsigned long) port->mapbase :
|
|
||||||
(unsigned long) port->iobase, options);
|
|
||||||
if (!(serial8250_console.flags & CON_ENABLED)) {
|
|
||||||
serial8250_console.flags &= ~CON_PRINTBUFFER;
|
|
||||||
register_console(&serial8250_console);
|
|
||||||
}
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SERIAL8250_CONSOLE &serial8250_console
|
#define SERIAL8250_CONSOLE &serial8250_console
|
||||||
#else
|
#else
|
||||||
#define SERIAL8250_CONSOLE NULL
|
#define SERIAL8250_CONSOLE NULL
|
||||||
|
|
|
@ -17,13 +17,11 @@
|
||||||
* we locate the device directly by its MMIO or I/O port address.
|
* we locate the device directly by its MMIO or I/O port address.
|
||||||
*
|
*
|
||||||
* The user can specify the device directly, e.g.,
|
* The user can specify the device directly, e.g.,
|
||||||
* console=uart,io,0x3f8,9600n8
|
* earlycon=uart8250,io,0x3f8,9600n8
|
||||||
* console=uart,mmio,0xff5e0000,115200n8
|
* earlycon=uart8250,mmio,0xff5e0000,115200n8
|
||||||
* or platform code can call early_uart_console_init() to set
|
* or
|
||||||
* the early UART device.
|
* console=uart8250,io,0x3f8,9600n8
|
||||||
*
|
* console=uart8250,mmio,0xff5e0000,115200n8
|
||||||
* After the normal serial driver starts, we try to locate the
|
|
||||||
* matching ttyS device and start a console there.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/tty.h>
|
#include <linux/tty.h>
|
||||||
|
@ -32,17 +30,21 @@
|
||||||
#include <linux/serial_core.h>
|
#include <linux/serial_core.h>
|
||||||
#include <linux/serial_reg.h>
|
#include <linux/serial_reg.h>
|
||||||
#include <linux/serial.h>
|
#include <linux/serial.h>
|
||||||
|
#include <linux/serial_8250.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/serial.h>
|
#include <asm/serial.h>
|
||||||
|
#ifdef CONFIG_FIX_EARLYCON_MEM
|
||||||
|
#include <asm/pgtable.h>
|
||||||
|
#include <asm/fixmap.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct early_uart_device {
|
struct early_serial8250_device {
|
||||||
struct uart_port port;
|
struct uart_port port;
|
||||||
char options[16]; /* e.g., 115200n8 */
|
char options[16]; /* e.g., 115200n8 */
|
||||||
unsigned int baud;
|
unsigned int baud;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct early_uart_device early_device __initdata;
|
static struct early_serial8250_device early_device;
|
||||||
static int early_uart_registered __initdata;
|
|
||||||
|
|
||||||
static unsigned int __init serial_in(struct uart_port *port, int offset)
|
static unsigned int __init serial_in(struct uart_port *port, int offset)
|
||||||
{
|
{
|
||||||
|
@ -80,7 +82,7 @@ static void __init putc(struct uart_port *port, int c)
|
||||||
serial_out(port, UART_TX, c);
|
serial_out(port, UART_TX, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init early_uart_write(struct console *console, const char *s, unsigned int count)
|
static void __init early_serial8250_write(struct console *console, const char *s, unsigned int count)
|
||||||
{
|
{
|
||||||
struct uart_port *port = &early_device.port;
|
struct uart_port *port = &early_device.port;
|
||||||
unsigned int ier;
|
unsigned int ier;
|
||||||
|
@ -111,7 +113,7 @@ static unsigned int __init probe_baud(struct uart_port *port)
|
||||||
return (port->uartclk / 16) / quot;
|
return (port->uartclk / 16) / quot;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init init_port(struct early_uart_device *device)
|
static void __init init_port(struct early_serial8250_device *device)
|
||||||
{
|
{
|
||||||
struct uart_port *port = &device->port;
|
struct uart_port *port = &device->port;
|
||||||
unsigned int divisor;
|
unsigned int divisor;
|
||||||
|
@ -130,10 +132,9 @@ static void __init init_port(struct early_uart_device *device)
|
||||||
serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
|
serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init parse_options(struct early_uart_device *device, char *options)
|
static int __init parse_options(struct early_serial8250_device *device, char *options)
|
||||||
{
|
{
|
||||||
struct uart_port *port = &device->port;
|
struct uart_port *port = &device->port;
|
||||||
int mapsize = 64;
|
|
||||||
int mmio, length;
|
int mmio, length;
|
||||||
|
|
||||||
if (!options)
|
if (!options)
|
||||||
|
@ -143,12 +144,18 @@ static int __init parse_options(struct early_uart_device *device, char *options)
|
||||||
if (!strncmp(options, "mmio,", 5)) {
|
if (!strncmp(options, "mmio,", 5)) {
|
||||||
port->iotype = UPIO_MEM;
|
port->iotype = UPIO_MEM;
|
||||||
port->mapbase = simple_strtoul(options + 5, &options, 0);
|
port->mapbase = simple_strtoul(options + 5, &options, 0);
|
||||||
port->membase = ioremap(port->mapbase, mapsize);
|
#ifdef CONFIG_FIX_EARLYCON_MEM
|
||||||
|
set_fixmap_nocache(FIX_EARLYCON_MEM_BASE, port->mapbase & PAGE_MASK);
|
||||||
|
port->membase = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
|
||||||
|
port->membase += port->mapbase & ~PAGE_MASK;
|
||||||
|
#else
|
||||||
|
port->membase = ioremap(port->mapbase, 64);
|
||||||
if (!port->membase) {
|
if (!port->membase) {
|
||||||
printk(KERN_ERR "%s: Couldn't ioremap 0x%lx\n",
|
printk(KERN_ERR "%s: Couldn't ioremap 0x%lx\n",
|
||||||
__FUNCTION__, port->mapbase);
|
__FUNCTION__, port->mapbase);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
mmio = 1;
|
mmio = 1;
|
||||||
} else if (!strncmp(options, "io,", 3)) {
|
} else if (!strncmp(options, "io,", 3)) {
|
||||||
port->iotype = UPIO_PORT;
|
port->iotype = UPIO_PORT;
|
||||||
|
@ -175,9 +182,16 @@ static int __init parse_options(struct early_uart_device *device, char *options)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init early_uart_setup(struct console *console, char *options)
|
static struct console early_serial8250_console __initdata = {
|
||||||
|
.name = "uart",
|
||||||
|
.write = early_serial8250_write,
|
||||||
|
.flags = CON_PRINTBUFFER | CON_BOOT,
|
||||||
|
.index = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init early_serial8250_setup(char *options)
|
||||||
{
|
{
|
||||||
struct early_uart_device *device = &early_device;
|
struct early_serial8250_device *device = &early_device;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (device->port.membase || device->port.iobase)
|
if (device->port.membase || device->port.iobase)
|
||||||
|
@ -190,61 +204,48 @@ static int __init early_uart_setup(struct console *console, char *options)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct console early_uart_console __initdata = {
|
int __init setup_early_serial8250_console(char *cmdline)
|
||||||
.name = "uart",
|
|
||||||
.write = early_uart_write,
|
|
||||||
.setup = early_uart_setup,
|
|
||||||
.flags = CON_PRINTBUFFER,
|
|
||||||
.index = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init early_uart_console_init(void)
|
|
||||||
{
|
|
||||||
if (!early_uart_registered) {
|
|
||||||
register_console(&early_uart_console);
|
|
||||||
early_uart_registered = 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
console_initcall(early_uart_console_init);
|
|
||||||
|
|
||||||
int __init early_serial_console_init(char *cmdline)
|
|
||||||
{
|
{
|
||||||
char *options;
|
char *options;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
options = strstr(cmdline, "console=uart,");
|
options = strstr(cmdline, "uart8250,");
|
||||||
|
if (!options) {
|
||||||
|
options = strstr(cmdline, "uart,");
|
||||||
if (!options)
|
if (!options)
|
||||||
return -ENODEV;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
options = strchr(cmdline, ',') + 1;
|
options = strchr(cmdline, ',') + 1;
|
||||||
if ((err = early_uart_setup(NULL, options)) < 0)
|
if ((err = early_serial8250_setup(options)) < 0)
|
||||||
return err;
|
return err;
|
||||||
return early_uart_console_init();
|
|
||||||
|
register_console(&early_serial8250_console);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init early_uart_console_switch(void)
|
int __init serial8250_find_port_for_earlycon(void)
|
||||||
{
|
{
|
||||||
struct early_uart_device *device = &early_device;
|
struct early_serial8250_device *device = &early_device;
|
||||||
struct uart_port *port = &device->port;
|
struct uart_port *port = &device->port;
|
||||||
int mmio, line;
|
int line;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!(early_uart_console.flags & CON_ENABLED))
|
if (!device->port.membase && !device->port.iobase)
|
||||||
return 0;
|
return -ENODEV;
|
||||||
|
|
||||||
/* Try to start the normal driver on a matching line. */
|
line = serial8250_find_port(port);
|
||||||
mmio = (port->iotype == UPIO_MEM);
|
|
||||||
line = serial8250_start_console(port, device->options);
|
|
||||||
if (line < 0)
|
if (line < 0)
|
||||||
printk("No ttyS device at %s 0x%lx for console\n",
|
return -ENODEV;
|
||||||
mmio ? "MMIO" : "I/O port",
|
|
||||||
mmio ? port->mapbase :
|
|
||||||
(unsigned long) port->iobase);
|
|
||||||
|
|
||||||
unregister_console(&early_uart_console);
|
ret = update_console_cmdline("uart", 8250,
|
||||||
if (mmio)
|
"ttyS", line, device->options);
|
||||||
iounmap(port->membase);
|
if (ret < 0)
|
||||||
|
ret = update_console_cmdline("uart", 0,
|
||||||
|
"ttyS", line, device->options);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
late_initcall(early_uart_console_switch);
|
|
||||||
|
early_param("earlycon", setup_early_serial8250_console);
|
||||||
|
|
|
@ -62,8 +62,22 @@ config SERIAL_8250_CONSOLE
|
||||||
kernel will automatically use the first serial line, /dev/ttyS0, as
|
kernel will automatically use the first serial line, /dev/ttyS0, as
|
||||||
system console.
|
system console.
|
||||||
|
|
||||||
|
you can set that using a kernel command line option such as
|
||||||
|
"console=uart8250,io,0x3f8,9600n8"
|
||||||
|
"console=uart8250,mmio,0xff5e0000,115200n8".
|
||||||
|
and it will switch to normal serial console when correponding port is
|
||||||
|
ready.
|
||||||
|
"earlycon=uart8250,io,0x3f8,9600n8"
|
||||||
|
"earlycon=uart8250,mmio,0xff5e0000,115200n8".
|
||||||
|
it will not only setup early console.
|
||||||
|
|
||||||
If unsure, say N.
|
If unsure, say N.
|
||||||
|
|
||||||
|
config FIX_EARLYCON_MEM
|
||||||
|
bool
|
||||||
|
depends on X86
|
||||||
|
default y
|
||||||
|
|
||||||
config SERIAL_8250_GSC
|
config SERIAL_8250_GSC
|
||||||
tristate
|
tristate
|
||||||
depends on SERIAL_8250 && GSC
|
depends on SERIAL_8250 && GSC
|
||||||
|
|
|
@ -54,6 +54,8 @@ extern unsigned long __FIXADDR_TOP;
|
||||||
enum fixed_addresses {
|
enum fixed_addresses {
|
||||||
FIX_HOLE,
|
FIX_HOLE,
|
||||||
FIX_VDSO,
|
FIX_VDSO,
|
||||||
|
FIX_DBGP_BASE,
|
||||||
|
FIX_EARLYCON_MEM_BASE,
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */
|
FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -129,6 +129,7 @@ extern void iounmap(volatile void __iomem *addr);
|
||||||
*/
|
*/
|
||||||
extern void *bt_ioremap(unsigned long offset, unsigned long size);
|
extern void *bt_ioremap(unsigned long offset, unsigned long size);
|
||||||
extern void bt_iounmap(void *addr, unsigned long size);
|
extern void bt_iounmap(void *addr, unsigned long size);
|
||||||
|
extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
|
||||||
|
|
||||||
/* Use early IO mappings for DMI because it's initialized early */
|
/* Use early IO mappings for DMI because it's initialized early */
|
||||||
#define dmi_ioremap bt_ioremap
|
#define dmi_ioremap bt_ioremap
|
||||||
|
|
|
@ -35,6 +35,8 @@ enum fixed_addresses {
|
||||||
VSYSCALL_LAST_PAGE,
|
VSYSCALL_LAST_PAGE,
|
||||||
VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
|
VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
|
||||||
VSYSCALL_HPET,
|
VSYSCALL_HPET,
|
||||||
|
FIX_DBGP_BASE,
|
||||||
|
FIX_EARLYCON_MEM_BASE,
|
||||||
FIX_HPET_BASE,
|
FIX_HPET_BASE,
|
||||||
FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */
|
FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */
|
||||||
FIX_IO_APIC_BASE_0,
|
FIX_IO_APIC_BASE_0,
|
||||||
|
|
|
@ -144,6 +144,7 @@ extern void early_iounmap(void *addr, unsigned long size);
|
||||||
*/
|
*/
|
||||||
extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
|
extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
|
||||||
extern void iounmap(volatile void __iomem *addr);
|
extern void iounmap(volatile void __iomem *addr);
|
||||||
|
extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ISA I/O bus memory addresses are 1:1 with the physical address.
|
* ISA I/O bus memory addresses are 1:1 with the physical address.
|
||||||
|
|
|
@ -99,6 +99,7 @@ struct console {
|
||||||
struct tty_driver *(*device)(struct console *, int *);
|
struct tty_driver *(*device)(struct console *, int *);
|
||||||
void (*unblank)(void);
|
void (*unblank)(void);
|
||||||
int (*setup)(struct console *, char *);
|
int (*setup)(struct console *, char *);
|
||||||
|
int (*early_setup)(void);
|
||||||
short flags;
|
short flags;
|
||||||
short index;
|
short index;
|
||||||
int cflag;
|
int cflag;
|
||||||
|
@ -107,6 +108,7 @@ struct console {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int add_preferred_console(char *name, int idx, char *options);
|
extern int add_preferred_console(char *name, int idx, char *options);
|
||||||
|
extern int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options);
|
||||||
extern void register_console(struct console *);
|
extern void register_console(struct console *);
|
||||||
extern int unregister_console(struct console *);
|
extern int unregister_console(struct console *);
|
||||||
extern struct console *console_drivers;
|
extern struct console *console_drivers;
|
||||||
|
|
|
@ -177,11 +177,5 @@ struct serial_icounter_struct {
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
/* Allow architectures to override entries in serial8250_ports[] at run time: */
|
|
||||||
struct uart_port; /* forward declaration */
|
|
||||||
extern int early_serial_setup(struct uart_port *port);
|
|
||||||
extern int early_serial_console_init(char *options);
|
|
||||||
extern int serial8250_start_console(struct uart_port *port, char *options);
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* _LINUX_SERIAL_H */
|
#endif /* _LINUX_SERIAL_H */
|
||||||
|
|
|
@ -60,4 +60,8 @@ void serial8250_unregister_port(int line);
|
||||||
void serial8250_suspend_port(int line);
|
void serial8250_suspend_port(int line);
|
||||||
void serial8250_resume_port(int line);
|
void serial8250_resume_port(int line);
|
||||||
|
|
||||||
|
extern int serial8250_find_port(struct uart_port *p);
|
||||||
|
extern int serial8250_find_port_for_earlycon(void);
|
||||||
|
extern int setup_early_serial8250_console(char *cmdline);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -453,7 +453,10 @@ static int __init do_early_param(char *param, char *val)
|
||||||
struct obs_kernel_param *p;
|
struct obs_kernel_param *p;
|
||||||
|
|
||||||
for (p = __setup_start; p < __setup_end; p++) {
|
for (p = __setup_start; p < __setup_end; p++) {
|
||||||
if (p->early && strcmp(param, p->str) == 0) {
|
if ((p->early && strcmp(param, p->str) == 0) ||
|
||||||
|
(strcmp(param, "console") == 0 &&
|
||||||
|
strcmp(p->str, "earlycon") == 0)
|
||||||
|
) {
|
||||||
if (p->setup_func(val) != 0)
|
if (p->setup_func(val) != 0)
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"Malformed early option '%s'\n", param);
|
"Malformed early option '%s'\n", param);
|
||||||
|
|
|
@ -726,6 +726,25 @@ int __init add_preferred_console(char *name, int idx, char *options)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __init update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options)
|
||||||
|
{
|
||||||
|
struct console_cmdline *c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
|
||||||
|
if (strcmp(console_cmdline[i].name, name) == 0 &&
|
||||||
|
console_cmdline[i].index == idx) {
|
||||||
|
c = &console_cmdline[i];
|
||||||
|
memcpy(c->name, name_new, sizeof(c->name));
|
||||||
|
c->name[sizeof(c->name) - 1] = 0;
|
||||||
|
c->options = options;
|
||||||
|
c->index = idx_new;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
/* not found */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
|
#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
|
||||||
/**
|
/**
|
||||||
* suspend_console - suspend the console subsystem
|
* suspend_console - suspend the console subsystem
|
||||||
|
@ -942,6 +961,9 @@ void register_console(struct console *console)
|
||||||
if (preferred_console < 0 || bootconsole || !console_drivers)
|
if (preferred_console < 0 || bootconsole || !console_drivers)
|
||||||
preferred_console = selected_console;
|
preferred_console = selected_console;
|
||||||
|
|
||||||
|
if (console->early_setup)
|
||||||
|
console->early_setup();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See if we want to use this console driver. If we
|
* See if we want to use this console driver. If we
|
||||||
* didn't select a console we take the first one
|
* didn't select a console we take the first one
|
||||||
|
|
Loading…
Reference in New Issue