On 5/17/07, Maciej W. Rozycki <[email protected]> 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: <[email protected]>
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 */
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]