[PATCH 4/5] 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: <[email protected]>
Documentation/kernel-parameters.txt | 11 +++
arch/ia64/kernel/setup.c | 4 -
drivers/serial/8250.c | 28 ++-------
drivers/serial/8250_early.c | 104 ++++++++++++++----------------------
drivers/serial/Kconfig | 10 +++
include/asm-i386/fixmap.h | 2
include/asm-i386/io.h | 13 ++++
include/asm-ia64/io.h | 4 +
include/asm-x86_64/fixmap.h | 4 +
include/asm-x86_64/io.h | 13 ++++
include/linux/console.h | 2
include/linux/serial.h | 6 --
include/linux/serial_8250.h | 3 +
init/main.c | 5 +
kernel/printk.c | 22 +++++++
15 files changed, 133 insertions(+), 98 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index aae2282..b51fbac 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -464,13 +464,20 @@ and is between 256 and 4096 characters. It is defined in the file
Documentation/networking/netconsole.txt for an
alternative.
- uart,io,<addr>[,options]
- uart,mmio,<addr>[,options]
+ uart8250,io,<addr>[,options]
+ uart8250,mmio,<addr>[,options]
Start an early, polled-mode console on the 8250/16550
UART at the specified I/O port or MMIO address,
switching to the matching ttyS device later. The
options are the same as for ttyS, above.
+ earlycon= [KNL] Output early console device and options.
+ uart8250,io,<addr>[,options]
+ uart8250,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
Format:
<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index eaa6a24..dd7f95b 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -390,10 +390,6 @@ early_console_setup (char *cmdline)
if (!efi_setup_pcdp_console(cmdline))
earlycons++;
#endif
-#ifdef CONFIG_SERIAL_8250_CONSOLE
- if (!early_serial_console_init(cmdline))
- earlycons++;
-#endif
return (earlycons) ? 0 : -1;
}
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index c84dab0..0b3ec38 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -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);
}
+static int __init serial8250_console_early_setup(void)
+{
+ return serial8250_find_port_for_earlycon();
+}
+
static struct uart_driver serial8250_reg;
static struct console serial8250_console = {
.name = "ttyS",
.write = serial8250_console_write,
.device = uart_console_device,
.setup = serial8250_console_setup,
+ .early_setup = serial8250_console_early_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
.data = &serial8250_reg,
@@ -2533,7 +2539,7 @@ static int __init serial8250_console_init(void)
}
console_initcall(serial8250_console_init);
-static int __init find_port(struct uart_port *p)
+int serial8250_find_port(struct uart_port *p)
{
int line;
struct uart_port *port;
@@ -2546,26 +2552,6 @@ static int __init find_port(struct uart_port *p)
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..820d164 100644
--- a/drivers/serial/8250_early.c
+++ b/drivers/serial/8250_early.c
@@ -17,13 +17,11 @@
* 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.
- *
- * After the normal serial driver starts, we try to locate the
- * matching ttyS device and start a console there.
+ * earlycon=uart8250,io,0x3f8,9600n8
+ * earlycon=uart8250,mmio,0xff5e0000,115200n8
+ * or
+ * console=uart8250,io,0x3f8,9600n8
+ * console=uart8250,mmio,0xff5e0000,115200n8
*/
#include <linux/tty.h>
@@ -32,17 +30,17 @@
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <linux/serial.h>
+#include <linux/serial_8250.h>
#include <asm/io.h>
#include <asm/serial.h>
-struct early_uart_device {
+struct early_serial8250_device {
struct uart_port port;
char options[16]; /* e.g., 115200n8 */
unsigned int baud;
};
-static struct early_uart_device early_device __initdata;
-static int early_uart_registered __initdata;
+static struct early_serial8250_device early_device;
static unsigned int __init serial_in(struct uart_port *port, int offset)
{
@@ -80,7 +78,7 @@ static void __init putc(struct uart_port *port, int 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;
unsigned int ier;
@@ -111,7 +109,7 @@ static unsigned int __init probe_baud(struct uart_port *port)
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;
unsigned int divisor;
@@ -130,10 +128,9 @@ static void __init init_port(struct early_uart_device *device)
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;
- int mapsize = 64;
int mmio, length;
if (!options)
@@ -143,12 +140,7 @@ static int __init parse_options(struct early_uart_device *device, char *options)
if (!strncmp(options, "mmio,", 5)) {
port->iotype = UPIO_MEM;
port->mapbase = simple_strtoul(options + 5, &options, 0);
- port->membase = ioremap(port->mapbase, mapsize);
- if (!port->membase) {
- printk(KERN_ERR "%s: Couldn't ioremap 0x%lx\n",
- __FUNCTION__, port->mapbase);
- return -ENOMEM;
- }
+ port->membase = fix_ioremap(FIX_EARLYCON_MEM_BASE, port->mapbase);
mmio = 1;
} else if (!strncmp(options, "io,", 3)) {
port->iotype = UPIO_PORT;
@@ -175,9 +167,16 @@ static int __init parse_options(struct early_uart_device *device, char *options)
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,
+ .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;
if (device->port.membase || device->port.iobase)
@@ -190,61 +189,40 @@ 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_serial8250_console(char *cmdline)
{
char *options;
int err;
- options = strstr(cmdline, "console=uart,");
+ options = strstr(cmdline, "uart8250,");
if (!options)
- return -ENODEV;
+ return 0;
options = strchr(cmdline, ',') + 1;
- if ((err = early_uart_setup(NULL, options)) < 0)
+ if ((err = early_serial8250_setup(options)) < 0)
return err;
- return early_uart_console_init();
+
+ early_serial8250_console.flags |= CON_BOOT;
+ register_console(&early_serial8250_console);
+
+ return 0;
}
-static int __init early_uart_console_switch(void)
+int 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;
- int mmio, line;
+ int line;
- if (!(early_uart_console.flags & CON_ENABLED))
- return 0;
+ if (!device->port.membase && !device->port.iobase)
+ return -ENODEV;
- /* Try to start the normal driver on a matching line. */
- mmio = (port->iotype == UPIO_MEM);
- line = serial8250_start_console(port, device->options);
+ line = serial8250_find_port(port);
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 -ENODEV;
- return 0;
+ return update_console_cmdline("uart", 8250,
+ "ttyS", line, device->options);
}
-late_initcall(early_uart_console_switch);
+
+early_param("earlycon", setup_early_serial8250_console);
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 315ea99..4a43fd6 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -62,6 +62,16 @@ config SERIAL_8250_CONSOLE
kernel will automatically use the first serial line, /dev/ttyS0, as
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.
config SERIAL_8250_GSC
diff --git a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h
index 80ea052..249e753 100644
--- a/include/asm-i386/fixmap.h
+++ b/include/asm-i386/fixmap.h
@@ -54,6 +54,8 @@ extern unsigned long __FIXADDR_TOP;
enum fixed_addresses {
FIX_HOLE,
FIX_VDSO,
+ FIX_DBGP_BASE,
+ FIX_EARLYCON_MEM_BASE,
#ifdef CONFIG_X86_LOCAL_APIC
FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */
#endif
diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h
index e797586..6c8748d 100644
--- a/include/asm-i386/io.h
+++ b/include/asm-i386/io.h
@@ -130,6 +130,19 @@ extern void iounmap(volatile void __iomem *addr);
extern void *bt_ioremap(unsigned long offset, unsigned long size);
extern void bt_iounmap(void *addr, unsigned long size);
+#include <asm/pgtable.h>
+#include <asm/fixmap.h>
+
+static inline void __iomem * fix_ioremap (unsigned idx, unsigned long phys)
+{
+ void __iomem * vaddr;
+ set_fixmap_nocache(idx, phys & PAGE_MASK);
+ vaddr = (void __iomem *)__fix_to_virt(idx);
+ vaddr += phys & ~PAGE_MASK;
+
+ return vaddr;
+}
+
/* Use early IO mappings for DMI because it's initialized early */
#define dmi_ioremap bt_ioremap
#define dmi_iounmap bt_iounmap
diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h
index eb17a86..e29eaf8 100644
--- a/include/asm-ia64/io.h
+++ b/include/asm-ia64/io.h
@@ -423,6 +423,10 @@ extern void __iomem * ioremap(unsigned long offset, unsigned long size);
extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
extern void iounmap (volatile void __iomem *addr);
+/* for console=uart8250,mmio,0xffe5000,9600n8 */
+#define FIX_EARLYCON_MEM_BASE 1
+#define fix_ioremap(idx, phys) ioremap(phys, 64)
+
/* Use normal IO mappings for DMI */
#define dmi_ioremap ioremap
#define dmi_iounmap(x,l) iounmap(x)
diff --git a/include/asm-x86_64/fixmap.h b/include/asm-x86_64/fixmap.h
index e90e167..2acb9b7 100644
--- a/include/asm-x86_64/fixmap.h
+++ b/include/asm-x86_64/fixmap.h
@@ -35,6 +35,8 @@ enum fixed_addresses {
VSYSCALL_LAST_PAGE,
VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
VSYSCALL_HPET,
+ FIX_DBGP_BASE,
+ FIX_EARLYCON_MEM_BASE,
FIX_HPET_BASE,
FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */
FIX_IO_APIC_BASE_0,
@@ -84,7 +86,7 @@ static __always_inline unsigned long fix_to_virt(const unsigned int idx)
if (idx >= __end_of_fixed_addresses)
__this_fixmap_does_not_exist();
- return __fix_to_virt(idx);
+ return __fix_to_virt(idx);
}
#endif
diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
index de2cd9a..e2d66de 100644
--- a/include/asm-x86_64/io.h
+++ b/include/asm-x86_64/io.h
@@ -145,6 +145,19 @@ extern void early_iounmap(void *addr, unsigned long size);
extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
extern void iounmap(volatile void __iomem *addr);
+#include <asm/pgtable.h>
+#include <asm/fixmap.h>
+
+static inline void __iomem * fix_ioremap (unsigned idx, unsigned long phys)
+{
+ void __iomem * vaddr;
+ set_fixmap_nocache(idx, phys & PAGE_MASK);
+ vaddr = (void __iomem *)__fix_to_virt(idx);
+ vaddr += phys & ~PAGE_MASK;
+
+ return vaddr;
+}
+
/*
* ISA I/O bus memory addresses are 1:1 with the physical address.
*/
diff --git a/include/linux/console.h b/include/linux/console.h
index 62ef6e1..c44d3df 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -99,6 +99,7 @@ struct console {
struct tty_driver *(*device)(struct console *, int *);
void (*unblank)(void);
int (*setup)(struct console *, char *);
+ int (*early_setup)(void);
short flags;
short index;
int cflag;
@@ -107,6 +108,7 @@ struct console {
};
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 int unregister_console(struct console *);
extern struct console *console_drivers;
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 */
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 71310d8..23519fb 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -60,4 +60,7 @@ void serial8250_unregister_port(int line);
void serial8250_suspend_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);
+
#endif
diff --git a/init/main.c b/init/main.c
index eb8bdba..58dbe75 100644
--- a/init/main.c
+++ b/init/main.c
@@ -452,7 +452,10 @@ static int __init do_early_param(char *param, char *val)
struct obs_kernel_param *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)
printk(KERN_WARNING
"Malformed early option '%s'\n", param);
diff --git a/kernel/printk.c b/kernel/printk.c
index 0bbdeac..7b96cae 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -726,6 +726,25 @@ int __init add_preferred_console(char *name, int idx, char *options)
return 0;
}
+int 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
/**
* suspend_console - suspend the console subsystem
@@ -942,6 +961,9 @@ void register_console(struct console *console)
if (preferred_console < 0 || bootconsole || !console_drivers)
preferred_console = selected_console;
+ if (console->early_setup)
+ console->early_setup();
+
/*
* See if we want to use this console driver. If we
* didn't select a console we take the first one
On Tue, 29 May 2007 18:43:59 -0700
Yinghai Lu <[email protected]> wrote:
> [PATCH 4/5] 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]
>
>
> Documentation/kernel-parameters.txt | 11 +++
> arch/ia64/kernel/setup.c | 4 -
> drivers/serial/8250.c | 28 ++-------
> drivers/serial/8250_early.c | 104 ++++++++++++++----------------------
> drivers/serial/Kconfig | 10 +++
> include/asm-i386/fixmap.h | 2
> include/asm-i386/io.h | 13 ++++
> include/asm-ia64/io.h | 4 +
> include/asm-x86_64/fixmap.h | 4 +
> include/asm-x86_64/io.h | 13 ++++
> include/linux/console.h | 2
> include/linux/serial.h | 6 --
> include/linux/serial_8250.h | 3 +
> init/main.c | 5 +
> kernel/printk.c | 22 +++++++
> 15 files changed, 133 insertions(+), 98 deletions(-)
This is a lot of tricky stuff in areas which I'm not very familar with.
Need help, am not getting it.
> @@ -143,12 +140,7 @@ static int __init parse_options(struct early_uart_device *device, char *options)
> if (!strncmp(options, "mmio,", 5)) {
> port->iotype = UPIO_MEM;
> port->mapbase = simple_strtoul(options + 5, &options, 0);
> - port->membase = ioremap(port->mapbase, mapsize);
> - if (!port->membase) {
> - printk(KERN_ERR "%s: Couldn't ioremap 0x%lx\n",
> - __FUNCTION__, port->mapbase);
> - return -ENOMEM;
> - }
> + port->membase = fix_ioremap(FIX_EARLYCON_MEM_BASE, port->mapbase);
A number of useful-looking warnigns such as the above got removed. How come?
> mmio = 1;
> } else if (!strncmp(options, "io,", 3)) {
> port->iotype = UPIO_PORT;
> @@ -175,9 +167,16 @@ static int __init parse_options(struct early_uart_device *device, char *options)
> 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,
Should this have CON_BOOT set as well?
See
ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.21-rc7/2.6.21-rc7-mm2/broken-out/fixes-and-cleanups-for-earlyprintk-aka-boot-console.patch,
which is now in mainline.
> + .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;
>
> if (device->port.membase || device->port.iobase)
> @@ -190,61 +189,40 @@ 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,
> -};
hm, that didn't have CON_BOOT.
> +static inline void __iomem * fix_ioremap (unsigned idx, unsigned long phys)
I don't suppose it'd help much if I were to complain about the coding style
(no space after the * or after the function name, please).
> +{
> + void __iomem * vaddr;
> + set_fixmap_nocache(idx, phys & PAGE_MASK);
> + vaddr = (void __iomem *)__fix_to_virt(idx);
> + vaddr += phys & ~PAGE_MASK;
> +
> + return vaddr;
> +}
Probably this was a bit too large for inlining.
> /* Use early IO mappings for DMI because it's initialized early */
> #define dmi_ioremap bt_ioremap
> #define dmi_iounmap bt_iounmap
> diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h
> index eb17a86..e29eaf8 100644
> --- a/include/asm-ia64/io.h
> +++ b/include/asm-ia64/io.h
> @@ -423,6 +423,10 @@ extern void __iomem * ioremap(unsigned long offset, unsigned long size);
> extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
> extern void iounmap (volatile void __iomem *addr);
>
> +/* for console=uart8250,mmio,0xffe5000,9600n8 */
> +#define FIX_EARLYCON_MEM_BASE 1
> +#define fix_ioremap(idx, phys) ioremap(phys, 64)
> +
> /* Use normal IO mappings for DMI */
> #define dmi_ioremap ioremap
> #define dmi_iounmap(x,l) iounmap(x)
So we touch ia64 as well?
>
> +int 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;
> +}
Shouldn't this be __init?
serial8250_find_port_for_earlycon() had its __init removed. Why?
This patch conflicts with David's
serial-use-resource_size_t-for-port-io-addresses.patch in minor ways, but
there may be functional conflicts as well. David's patch seems to be a bit
stuck, so I'll drop it and I'll merge these instead. But I don't know what
I'm doing.
Andrew Morton wrote:
> On Tue, 29 May 2007 18:43:59 -0700
> Yinghai Lu <[email protected]> wrote:
>
>> [PATCH 4/5] 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]
>>
>>
>> Documentation/kernel-parameters.txt | 11 +++
>> arch/ia64/kernel/setup.c | 4 -
>> drivers/serial/8250.c | 28 ++-------
>> drivers/serial/8250_early.c | 104 ++++++++++++++----------------------
>> drivers/serial/Kconfig | 10 +++
>> include/asm-i386/fixmap.h | 2
>> include/asm-i386/io.h | 13 ++++
>> include/asm-ia64/io.h | 4 +
>> include/asm-x86_64/fixmap.h | 4 +
>> include/asm-x86_64/io.h | 13 ++++
>> include/linux/console.h | 2
>> include/linux/serial.h | 6 --
>> include/linux/serial_8250.h | 3 +
>> init/main.c | 5 +
>> kernel/printk.c | 22 +++++++
>> 15 files changed, 133 insertions(+), 98 deletions(-)
>
> This is a lot of tricky stuff in areas which I'm not very familar with.
> Need help, am not getting it.
>
>> @@ -143,12 +140,7 @@ static int __init parse_options(struct early_uart_device *device, char *options)
>> if (!strncmp(options, "mmio,", 5)) {
>> port->iotype = UPIO_MEM;
>> port->mapbase = simple_strtoul(options + 5, &options, 0);
>> - port->membase = ioremap(port->mapbase, mapsize);
>> - if (!port->membase) {
>> - printk(KERN_ERR "%s: Couldn't ioremap 0x%lx\n",
>> - __FUNCTION__, port->mapbase);
>> - return -ENOMEM;
>> - }
>> + port->membase = fix_ioremap(FIX_EARLYCON_MEM_BASE, port->mapbase);
>
> A number of useful-looking warnigns such as the above got removed. How come?
earycon, when you can not get fix_ioremap work, you can not get anything from boot.
>
>> mmio = 1;
>> } else if (!strncmp(options, "io,", 3)) {
>> port->iotype = UPIO_PORT;
>> @@ -175,9 +167,16 @@ static int __init parse_options(struct early_uart_device *device, char *options)
>> 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,
>
> Should this have CON_BOOT set as well?
>
> See
> ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.21-rc7/2.6.21-rc7-mm2/broken-out/fixes-and-cleanups-for-earlyprintk-aka-boot-console.patch,
> which is now in mainline.
>
I put that into setup_early_serial8250_console.
-int __init early_serial_console_init(char *cmdline)
+static int __init setup_early_serial8250_console(char *cmdline)
{
char *options;
int err;
- options = strstr(cmdline, "console=uart,");
+ options = strstr(cmdline, "uart8250,");
if (!options)
- return -ENODEV;
+ return 0;
options = strchr(cmdline, ',') + 1;
- if ((err = early_uart_setup(NULL, options)) < 0)
+ if ((err = early_serial8250_setup(options)) < 0)
return err;
- return early_uart_console_init();
+
+ early_serial8250_console.flags |= CON_BOOT;
+ register_console(&early_serial8250_console);
+
+ return 0;
}
we may use
>> + .flags = CON_PRINTBUFFER | CAN_BOOT;
instead that line.
>> + .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;
>>
>> if (device->port.membase || device->port.iobase)
>> @@ -190,61 +189,40 @@ 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,
>> -};
>
> hm, that didn't have CON_BOOT.
>
>> +static inline void __iomem * fix_ioremap (unsigned idx, unsigned long phys)
>
> I don't suppose it'd help much if I were to complain about the coding style
> (no space after the * or after the function name, please).
>
>> +{
>> + void __iomem * vaddr;
>> + set_fixmap_nocache(idx, phys & PAGE_MASK);
>> + vaddr = (void __iomem *)__fix_to_virt(idx);
>> + vaddr += phys & ~PAGE_MASK;
>> +
>> + return vaddr;
>> +}
>
> Probably this was a bit too large for inlining.
current only one calling, later will use that for usb debug cable.
>
>> /* Use early IO mappings for DMI because it's initialized early */
>> #define dmi_ioremap bt_ioremap
>> #define dmi_iounmap bt_iounmap
>> diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h
>> index eb17a86..e29eaf8 100644
>> --- a/include/asm-ia64/io.h
>> +++ b/include/asm-ia64/io.h
>> @@ -423,6 +423,10 @@ extern void __iomem * ioremap(unsigned long offset, unsigned long size);
>> extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
>> extern void iounmap (volatile void __iomem *addr);
>>
>> +/* for console=uart8250,mmio,0xffe5000,9600n8 */
>> +#define FIX_EARLYCON_MEM_BASE 1
>> +#define fix_ioremap(idx, phys) ioremap(phys, 64)
>> +
>> /* Use normal IO mappings for DMI */
>> #define dmi_ioremap ioremap
>> #define dmi_iounmap(x,l) iounmap(x)
>
> So we touch ia64 as well?
>
>>
>> +int 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;
>> +}
>
> Shouldn't this be __init?
>
> serial8250_find_port_for_earlycon() had its __init removed. Why?
with __init, the compiler will cry about .init.text and .text missection.
YH
On Wed, 30 May 2007 12:58:11 -0700
Yinghai Lu <[email protected]> wrote:
> >> +int 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;
> >> +}
> >
> > Shouldn't this be __init?
> >
> > serial8250_find_port_for_earlycon() had its __init removed. Why?
> with __init, the compiler will cry about .init.text and .text missection.
But was this the correct fix for that? afaict the only caller of
this function is __init anyway.
On Wednesday 30 May 2007 13:18, Andrew Morton wrote:
> On Wed, 30 May 2007 12:58:11 -0700
> Yinghai Lu <[email protected]> wrote:
>
> > >> +int 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;
> > >> +}
> > >
> > > Shouldn't this be __init?
> > >
> > > serial8250_find_port_for_earlycon() had its __init removed. Why?
> > with __init, the compiler will cry about .init.text and .text missection.
>
> But was this the correct fix for that? afaict the only caller of
> this function is __init anyway.
>
You are right.
serial8250_find_port_for_earlycon and
update_console_cmdline in kernel/printk.c
could be __init
YH
On Wed, 30 May 2007 13:58:52 -0700
Yinghai Lu <[email protected]> wrote:
> On Wednesday 30 May 2007 13:18, Andrew Morton wrote:
> > On Wed, 30 May 2007 12:58:11 -0700
> > Yinghai Lu <[email protected]> wrote:
> >
> > > >> +int 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;
> > > >> +}
> > > >
> > > > Shouldn't this be __init?
> > > >
> > > > serial8250_find_port_for_earlycon() had its __init removed. Why?
> > > with __init, the compiler will cry about .init.text and .text missection.
> >
> > But was this the correct fix for that? afaict the only caller of
> > this function is __init anyway.
> >
> You are right.
> serial8250_find_port_for_earlycon and
> update_console_cmdline in kernel/printk.c
> could be __init
OK, please send a fixup sometime.
On Tue, 29 May 2007 18:43:59 -0700 Yinghai Lu <[email protected]> wrote:
> [PATCH 4/5] serial: convert early_uart to earlycon for 8250
drivers/serial/8250_early.c: In function 'parse_options':
drivers/serial/8250_early.c:143: error: 'FIX_EARLYCON_MEM_BASE' undeclared (first use in this function)
drivers/serial/8250_early.c:143: error: (Each undeclared identifier is reported only once
That was with http://userweb.kernel.org/~akpm/config-sony.txt, but this is
going to break a whole pile of architectures (alpha, powerpc, others).
I think I'll give up on it now.
On 5/30/07, Andrew Morton <[email protected]> wrote:
> On Tue, 29 May 2007 18:43:59 -0700 Yinghai Lu <[email protected]> wrote:
>
> > [PATCH 4/5] serial: convert early_uart to earlycon for 8250
>
> drivers/serial/8250_early.c: In function 'parse_options':
> drivers/serial/8250_early.c:143: error: 'FIX_EARLYCON_MEM_BASE' undeclared (first use in this function)
> drivers/serial/8250_early.c:143: error: (Each undeclared identifier is reported only once
>
> That was with http://userweb.kernel.org/~akpm/config-sony.txt, but this is
> going to break a whole pile of architectures (alpha, powerpc, others).
alpha, powerpc, others may need sth like ia64, if they do not support fixmap.
diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h
index eb17a86..e29eaf8 100644
--- a/include/asm-ia64/io.h
+++ b/include/asm-ia64/io.h
@@ -423,6 +423,10 @@ extern void __iomem * ioremap(unsigned long
offset, unsigned long size);
extern void __iomem * ioremap_nocache (unsigned long offset, unsigned
long size);
extern void iounmap (volatile void __iomem *addr);
+/* for console=uart8250,mmio,0xffe5000,9600n8 */
+#define FIX_EARLYCON_MEM_BASE 1
+#define fix_ioremap(idx, phys) ioremap(phys, 64)
+
/* Use normal IO mappings for DMI */
#define dmi_ioremap ioremap
#define dmi_iounmap(x,l) iounmap(x)
$ find . -name "fixmap.h"
./asm-sh/fixmap.h
./asm-um/fixmap.h
./asm-parisc/fixmap.h
./asm-x86_64/fixmap.h
./asm-sparc/fixmap.h
./asm-i386/fixmap.h
./asm-mips/fixmap.h
they will need
diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
index de2cd9a..e2d66de 100644
--- a/include/asm-x86_64/io.h
+++ b/include/asm-x86_64/io.h
@@ -145,6 +145,19 @@ extern void early_iounmap(void *addr, unsigned long size);
extern void __iomem * ioremap_nocache (unsigned long offset, unsigned
long size);
extern void iounmap(volatile void __iomem *addr);
+#include <asm/pgtable.h>
+#include <asm/fixmap.h>
+
+static inline void __iomem * fix_ioremap (unsigned idx, unsigned long phys)
+{
+ void __iomem * vaddr;
+ set_fixmap_nocache(idx, phys & PAGE_MASK);
+ vaddr = (void __iomem *)__fix_to_virt(idx);
+ vaddr += phys & ~PAGE_MASK;
+
+ return vaddr;
+}
+
/*
* ISA I/O bus memory addresses are 1:1 with the physical address.
*/
YH
On 5/30/07, Yinghai Lu <[email protected]> wrote:
> On 5/30/07, Andrew Morton <[email protected]> wrote:
> > On Tue, 29 May 2007 18:43:59 -0700 Yinghai Lu <[email protected]> wrote:
> >
> > > [PATCH 4/5] serial: convert early_uart to earlycon for 8250
> >
> > drivers/serial/8250_early.c: In function 'parse_options':
> > drivers/serial/8250_early.c:143: error: 'FIX_EARLYCON_MEM_BASE' undeclared (first use in this function)
> > drivers/serial/8250_early.c:143: error: (Each undeclared identifier is reported only once
> >
> > That was with http://userweb.kernel.org/~akpm/config-sony.txt, but this is
> > going to break a whole pile of architectures (alpha, powerpc, others).
>
> alpha, powerpc, others may need sth like ia64, if they do not support fixmap.
>
>
or create dummy fixmap.h that doesn't support fixmap.
YH
On Wed, 30 May 2007 21:34:35 -0700 "Yinghai Lu" <[email protected]> wrote:
> they will need
> diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
> index de2cd9a..e2d66de 100644
> --- a/include/asm-x86_64/io.h
> +++ b/include/asm-x86_64/io.h
> @@ -145,6 +145,19 @@ extern void early_iounmap(void *addr, unsigned long size);
> extern void __iomem * ioremap_nocache (unsigned long offset, unsigned
> long size);
> extern void iounmap(volatile void __iomem *addr);
>
> +#include <asm/pgtable.h>
> +#include <asm/fixmap.h>
> +
> +static inline void __iomem * fix_ioremap (unsigned idx, unsigned long phys)
> +{
> + void __iomem * vaddr;
> + set_fixmap_nocache(idx, phys & PAGE_MASK);
> + vaddr = (void __iomem *)__fix_to_virt(idx);
> + vaddr += phys & ~PAGE_MASK;
> +
> + return vaddr;
> +}
> +
I hope not - I just removed that inlined function. It's too large and the
inclusion of pgtable.h in io.h causes all sorts of problems.
This function should go into arch/.../mm/ioremap.c
On 5/30/07, Andrew Morton <[email protected]> wrote:
> On Wed, 30 May 2007 21:34:35 -0700 "Yinghai Lu" <[email protected]> wrote:
>
> > they will need
> > diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
> > index de2cd9a..e2d66de 100644
> > --- a/include/asm-x86_64/io.h
> > +++ b/include/asm-x86_64/io.h
> > @@ -145,6 +145,19 @@ extern void early_iounmap(void *addr, unsigned long size);
> > extern void __iomem * ioremap_nocache (unsigned long offset, unsigned
> > long size);
> > extern void iounmap(volatile void __iomem *addr);
> >
> > +#include <asm/pgtable.h>
> > +#include <asm/fixmap.h>
> > +
> > +static inline void __iomem * fix_ioremap (unsigned idx, unsigned long phys)
> > +{
> > + void __iomem * vaddr;
> > + set_fixmap_nocache(idx, phys & PAGE_MASK);
> > + vaddr = (void __iomem *)__fix_to_virt(idx);
> > + vaddr += phys & ~PAGE_MASK;
> > +
> > + return vaddr;
> > +}
> > +
>
> I hope not - I just removed that inlined function. It's too large and the
> inclusion of pgtable.h in io.h causes all sorts of problems.
>
> This function should go into arch/.../mm/ioremap.c
>
agree, but need to keep
#include <asm/fixmap.h>
and will create dummy fixmap.h for arch that doesn't support fixmap
YH
On Wed, 30 May 2007 21:36:41 -0700 "Yinghai Lu" <[email protected]> wrote:
> On 5/30/07, Yinghai Lu <[email protected]> wrote:
> > On 5/30/07, Andrew Morton <[email protected]> wrote:
> > > On Tue, 29 May 2007 18:43:59 -0700 Yinghai Lu <[email protected]> wrote:
> > >
> > > > [PATCH 4/5] serial: convert early_uart to earlycon for 8250
> > >
> > > drivers/serial/8250_early.c: In function 'parse_options':
> > > drivers/serial/8250_early.c:143: error: 'FIX_EARLYCON_MEM_BASE' undeclared (first use in this function)
> > > drivers/serial/8250_early.c:143: error: (Each undeclared identifier is reported only once
> > >
> > > That was with http://userweb.kernel.org/~akpm/config-sony.txt, but this is
> > > going to break a whole pile of architectures (alpha, powerpc, others).
> >
> > alpha, powerpc, others may need sth like ia64, if they do not support fixmap.
> >
> >
>
> or create dummy fixmap.h that doesn't support fixmap.
>
You could require that the architecture implement some specific function
for mapping the early-uart. Say,
void __iomem *map_early_uart(unsigned long phys_addr, unsigned long len);
void unmap_early_uart(void * __iomem *addr);
then, in drivers/serial/8250_early.c, do
void __iomem * __attribute__((weak))
map_early_uart(unsigned long phys_addr, unsigned long len)
{
return ioremap(phys_addr, len);
}
void __attribute__((weak)) unmap_early_uart(void * __iomem *addr)
{
iounmap(addr);
}
and in arch/i386/mm/ioremap.c
#ifdef CONFIG_something
void __iomem *map_early_uart(unsigned long phys_addr, unsigned long len)
{
void __iomem * vaddr;
set_fixmap_nocache(idx, phys & PAGE_MASK);
vaddr = (void __iomem *)__fix_to_virt(idx);
vaddr += phys & ~PAGE_MASK;
return vaddr;
}
void unmap_early_uart(void * __iomem *addr)
{
/* nothing to do */
}
#endif
or such.
On Wed, 30 May 2007 21:42:15 -0700 "Yinghai Lu" <[email protected]> wrote:
> On 5/30/07, Andrew Morton <[email protected]> wrote:
> > On Wed, 30 May 2007 21:34:35 -0700 "Yinghai Lu" <[email protected]> wrote:
> >
> > > they will need
> > > diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
> > > index de2cd9a..e2d66de 100644
> > > --- a/include/asm-x86_64/io.h
> > > +++ b/include/asm-x86_64/io.h
> > > @@ -145,6 +145,19 @@ extern void early_iounmap(void *addr, unsigned long size);
> > > extern void __iomem * ioremap_nocache (unsigned long offset, unsigned
> > > long size);
> > > extern void iounmap(volatile void __iomem *addr);
> > >
> > > +#include <asm/pgtable.h>
> > > +#include <asm/fixmap.h>
> > > +
> > > +static inline void __iomem * fix_ioremap (unsigned idx, unsigned long phys)
> > > +{
> > > + void __iomem * vaddr;
> > > + set_fixmap_nocache(idx, phys & PAGE_MASK);
> > > + vaddr = (void __iomem *)__fix_to_virt(idx);
> > > + vaddr += phys & ~PAGE_MASK;
> > > +
> > > + return vaddr;
> > > +}
> > > +
> >
> > I hope not - I just removed that inlined function. It's too large and the
> > inclusion of pgtable.h in io.h causes all sorts of problems.
> >
> > This function should go into arch/.../mm/ioremap.c
> >
> agree, but need to keep
>
> #include <asm/fixmap.h>
No, there's no need for that and it is undesirable.
> and will create dummy fixmap.h for arch that doesn't support fixmap
So's that. If we avoid the inlined function we will avoid adding more
include requirements.
On Wednesday 30 May 2007 10:48:59 pm Andrew Morton wrote:
> On Wed, 30 May 2007 21:36:41 -0700 "Yinghai Lu" <[email protected]> wrote:
>
> > On 5/30/07, Yinghai Lu <[email protected]> wrote:
> > > On 5/30/07, Andrew Morton <[email protected]> wrote:
> > > > On Tue, 29 May 2007 18:43:59 -0700 Yinghai Lu <[email protected]> wrote:
> > > >
> > > > > [PATCH 4/5] serial: convert early_uart to earlycon for 8250
> > > >
> > > > drivers/serial/8250_early.c: In function 'parse_options':
> > > > drivers/serial/8250_early.c:143: error: 'FIX_EARLYCON_MEM_BASE' undeclared (first use in this function)
> > > > drivers/serial/8250_early.c:143: error: (Each undeclared identifier is reported only once
> > > >
> > > > That was with http://userweb.kernel.org/~akpm/config-sony.txt, but this is
> > > > going to break a whole pile of architectures (alpha, powerpc, others).
> > >
> > > alpha, powerpc, others may need sth like ia64, if they do not support fixmap.
> >
> > or create dummy fixmap.h that doesn't support fixmap.
>
> You could require that the architecture implement some specific function
> for mapping the early-uart.
We could, but we already have bt_ioremap, dmi_ioremap, and early_ioremap.
Do we really want to proliferate more flavors of "early ioremap"? I'd
rather consolidate the ones we already have.
On 5/31/07, Bjorn Helgaas <[email protected]> wrote:
> On Wednesday 30 May 2007 10:48:59 pm Andrew Morton wrote:
> > You could require that the architecture implement some specific function
> > for mapping the early-uart.
>
> We could, but we already have bt_ioremap, dmi_ioremap, and early_ioremap.
> Do we really want to proliferate more flavors of "early ioremap"? I'd
> rather consolidate the ones we already have.
>
not really.
dhcp-umpk12-63-201:/home/yhlu/xx/xx/kernel/linux-2.6/include # grep
bt_ioremap * -r
asm-i386/dmi.h:#define dmi_ioremap bt_ioremap
asm-i386/io.h: * bt_ioremap() and bt_iounmap() are for temporary early boot-time
asm-i386/io.h:extern void *bt_ioremap(unsigned long offset, unsigned long size);
asm-i386/io.h:#define dmi_ioremap bt_ioremap
dhcp-umpk12-63-201:/home/yhlu/xx/xx/kernel/linux-2.6/include # grep
early_ioremap * -r
asm-x86_64/dmi.h:#define dmi_ioremap early_ioremap
asm-x86_64/io.h:extern void *early_ioremap(unsigned long addr,
unsigned long size);
dhcp-umpk12-63-201:/home/yhlu/xx/xx/kernel/linux-2.6/include # grep
dmi_ioremap * -r
asm-i386/dmi.h:#define dmi_ioremap bt_ioremap
asm-i386/io.h:#define dmi_ioremap bt_ioremap
asm-ia64/io.h:#define dmi_ioremap ioremap
asm-x86_64/dmi.h:extern void *dmi_ioremap(unsigned long addr, unsigned
long size);
asm-x86_64/dmi.h:#define dmi_ioremap early_ioremap
YH
On Thursday 31 May 2007 10:32:42 am Yinghai Lu wrote:
> On 5/31/07, Bjorn Helgaas <[email protected]> wrote:
> > On Wednesday 30 May 2007 10:48:59 pm Andrew Morton wrote:
> > > You could require that the architecture implement some specific function
> > > for mapping the early-uart.
> >
> > We could, but we already have bt_ioremap, dmi_ioremap, and early_ioremap.
> > Do we really want to proliferate more flavors of "early ioremap"? I'd
> > rather consolidate the ones we already have.
> >
> not really.
I'm sorry, I don't understand the point you're making.
Andrew's proposal was that we could add early_uart_ioremap to the list of
bt_ioremap and dmi_ioremap.
I'm suggesting that maybe we should make bt_ioremap smart enough that
we could use it for early uart mapping. And maybe we could get rid
of dmi_ioremap, and make DMI use bt_ioremap as well (this would require
some shims for x86_64 and ia64).
> dhcp-umpk12-63-201:/home/yhlu/xx/xx/kernel/linux-2.6/include # grep
> bt_ioremap * -r
> asm-i386/dmi.h:#define dmi_ioremap bt_ioremap
> asm-i386/io.h: * bt_ioremap() and bt_iounmap() are for temporary early boot-time
> asm-i386/io.h:extern void *bt_ioremap(unsigned long offset, unsigned long size);
> asm-i386/io.h:#define dmi_ioremap bt_ioremap
>
> dhcp-umpk12-63-201:/home/yhlu/xx/xx/kernel/linux-2.6/include # grep
> early_ioremap * -r
> asm-x86_64/dmi.h:#define dmi_ioremap early_ioremap
> asm-x86_64/io.h:extern void *early_ioremap(unsigned long addr,
> unsigned long size);
>
> dhcp-umpk12-63-201:/home/yhlu/xx/xx/kernel/linux-2.6/include # grep
> dmi_ioremap * -r
> asm-i386/dmi.h:#define dmi_ioremap bt_ioremap
> asm-i386/io.h:#define dmi_ioremap bt_ioremap
> asm-ia64/io.h:#define dmi_ioremap ioremap
> asm-x86_64/dmi.h:extern void *dmi_ioremap(unsigned long addr, unsigned
> long size);
> asm-x86_64/dmi.h:#define dmi_ioremap early_ioremap
On 5/31/07, Bjorn Helgaas <[email protected]> wrote:
> > not really.
>
> I'm sorry, I don't understand the point you're making.
>
> Andrew's proposal was that we could add early_uart_ioremap to the list of
> bt_ioremap and dmi_ioremap.
>
for i386, bt_ioremap is using fixmap, and it is temporary boot-time
mappings, used before ioremap() is functional.
but we need one as permanent fixed address.
for x86_64, early_ioremap. I'd like to make to static, because
dmi_ioremap could use ioremap instead.
Fix address could make the earlycon can be used more earlier.
YH