lkml.org 
[lkml]   [2007]   [May]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [patch] early printk and boot console fixups.
    On 5/17/07, Maciej W. Rozycki <macro@linux-mips.org> wrote:
    > On Wed, 16 May 2007, Bjorn Helgaas wrote:
    >
    > > > Given the generic name of "uart" I am assuming this will work with any
    > > > UART driver making use of the serial_core.c core -- am I correct?
    > >
    > > I knew somebody would ask that eventually :-)
    > >
    > > Unfortunately, the answer is "no." "console=uart" only works with
    > > 8250-compatible devices.
    >
    > But is it a design limitation or is it just that other UART drivers have
    > to be modified to work with this option? My point is if the former, then
    > the option should be something like "console=8250" (the right-hand side
    > being the name of the driver involved; others may want to add support for
    > other drivers). If the latter, then it's fine as is as other UART drivers
    > may be wired to this code as a need arises.
    >
    > Maciej
    >
    Actually that early_uart is not real early one.
    it is called via console_initcall.

    for IA64, Bjom is calling that directly in setup_arch.

    Please check my patch to make it to be called via early_param, that
    will be good to other platform.

    also you may extend to support other early_uart.

    YH
    [PATCH] serial: make early_uart to use early_prarm instead of console_initcall

    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.
    new command line will be
    earlycon=uart,io,0x3f8,9600n8 console=ttyS0,9600
    it will print in very early stage
    Early serial console at I/O port 0x3f8 (options '9600n8')
    later for console it will print
    console handover: boot [uart0] -> real [ttyS0]

    Signed-off-by: <yinghai.lu@sun.com>

    diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
    index 48e259a..2a76618 100644
    --- a/drivers/serial/8250.c
    +++ b/drivers/serial/8250.c
    @@ -2533,39 +2538,6 @@ static int __init serial8250_console_init(void)
    }
    console_initcall(serial8250_console_init);

    -static int __init find_port(struct uart_port *p)
    -{
    - int line;
    - struct uart_port *port;
    -
    - for (line = 0; line < nr_uarts; line++) {
    - port = &serial8250_ports[line].port;
    - if (uart_match_port(p, port))
    - return line;
    - }
    - 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
    #else
    #define SERIAL8250_CONSOLE NULL
    diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c
    index 7e51119..f320f8f 100644
    --- a/drivers/serial/8250_early.c
    +++ b/drivers/serial/8250_early.c
    @@ -17,13 +17,9 @@
    * we locate the device directly by its MMIO or I/O port address.
    *
    * The user can specify the device directly, e.g.,
    - * console=uart,io,0x3f8,9600n8
    - * console=uart,mmio,0xff5e0000,115200n8
    - * or platform code can call early_uart_console_init() to set
    - * the early UART device.
    + * earlycon=uart,io,0x3f8,9600n8
    + * earlycon=uart,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>
    @@ -42,7 +38,6 @@ struct early_uart_device {
    };

    static struct early_uart_device early_device __initdata;
    -static int early_uart_registered __initdata;

    static unsigned int __init serial_in(struct uart_port *port, int offset)
    {
    @@ -175,6 +170,13 @@ static int __init parse_options(struct early_uart_device *device, char *options)
    return 0;
    }

    +static struct console early_uart_console __initdata = {
    + .name = "uart",
    + .write = early_uart_write,
    + .flags = CON_PRINTBUFFER,
    + .index = -1,
    +};
    +
    static int __init early_uart_setup(struct console *console, char *options)
    {
    struct early_uart_device *device = &early_device;
    @@ -190,61 +192,41 @@ static int __init early_uart_setup(struct console *console, char *options)
    return 0;
    }

    -static struct console early_uart_console __initdata = {
    - .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)
    +static int __init setup_early_serial_console(char *cmdline)
    {
    char *options;
    int err;

    - options = strstr(cmdline, "console=uart,");
    + options = strstr(cmdline, "uart,");
    if (!options)
    return -ENODEV;

    options = strchr(cmdline, ',') + 1;
    if ((err = early_uart_setup(NULL, options)) < 0)
    return err;
    - return early_uart_console_init();
    +
    + register_console(&early_uart_console);
    + early_uart_console.flags |= CON_BOOT;
    + return 0;
    }

    -static int __init early_uart_console_switch(void)
    +early_param("earlycon", setup_early_serial_console);
    +
    +static int __init early_uart_console_post(void)
    {
    struct early_uart_device *device = &early_device;
    struct uart_port *port = &device->port;
    - int mmio, line;
    + int mmio;

    if (!(early_uart_console.flags & CON_ENABLED))
    return 0;

    - /* Try to start the normal driver on a matching line. */
    mmio = (port->iotype == UPIO_MEM);
    - line = serial8250_start_console(port, device->options);
    - if (line < 0)
    - printk("No ttyS device at %s 0x%lx for console\n",
    - mmio ? "MMIO" : "I/O port",
    - mmio ? port->mapbase :
    - (unsigned long) port->iobase);
    -
    - unregister_console(&early_uart_console);
    +
    if (mmio)
    iounmap(port->membase);

    return 0;
    }
    -late_initcall(early_uart_console_switch);
    +
    +late_initcall(early_uart_console_post);
    diff --git a/include/linux/serial.h b/include/linux/serial.h
    index 33fc8cb..deb7143 100644
    --- a/include/linux/serial.h
    +++ b/include/linux/serial.h
    @@ -177,11 +177,5 @@ struct serial_icounter_struct {
    #ifdef __KERNEL__
    #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 /* _LINUX_SERIAL_H */
    \
     
     \ /
      Last update: 2007-05-17 18:57    [W:4.589 / U:0.088 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site