aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt3
-rw-r--r--drivers/serial/8250_early.c57
2 files changed, 45 insertions, 15 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 44f6b19c50bb..d529b1363e95 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -681,8 +681,11 @@ and is between 256 and 4096 characters. It is defined in the file
681 earlycon= [KNL] Output early console device and options. 681 earlycon= [KNL] Output early console device and options.
682 uart[8250],io,<addr>[,options] 682 uart[8250],io,<addr>[,options]
683 uart[8250],mmio,<addr>[,options] 683 uart[8250],mmio,<addr>[,options]
684 uart[8250],mmio32,<addr>[,options]
684 Start an early, polled-mode console on the 8250/16550 685 Start an early, polled-mode console on the 8250/16550
685 UART at the specified I/O port or MMIO address. 686 UART at the specified I/O port or MMIO address.
687 MMIO inter-register address stride is either 8bit (mmio)
688 or 32bit (mmio32).
686 The options are the same as for ttyS, above. 689 The options are the same as for ttyS, above.
687 690
688 earlyprintk= [X86,SH,BLACKFIN] 691 earlyprintk= [X86,SH,BLACKFIN]
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c
index f279745e9fef..b745792ec25a 100644
--- a/drivers/serial/8250_early.c
+++ b/drivers/serial/8250_early.c
@@ -19,9 +19,11 @@
19 * The user can specify the device directly, e.g., 19 * The user can specify the device directly, e.g.,
20 * earlycon=uart8250,io,0x3f8,9600n8 20 * earlycon=uart8250,io,0x3f8,9600n8
21 * earlycon=uart8250,mmio,0xff5e0000,115200n8 21 * earlycon=uart8250,mmio,0xff5e0000,115200n8
22 * earlycon=uart8250,mmio32,0xff5e0000,115200n8
22 * or 23 * or
23 * console=uart8250,io,0x3f8,9600n8 24 * console=uart8250,io,0x3f8,9600n8
24 * console=uart8250,mmio,0xff5e0000,115200n8 25 * console=uart8250,mmio,0xff5e0000,115200n8
26 * console=uart8250,mmio32,0xff5e0000,115200n8
25 */ 27 */
26 28
27#include <linux/tty.h> 29#include <linux/tty.h>
@@ -48,18 +50,31 @@ static struct early_serial8250_device early_device;
48 50
49static unsigned int __init serial_in(struct uart_port *port, int offset) 51static unsigned int __init serial_in(struct uart_port *port, int offset)
50{ 52{
51 if (port->iotype == UPIO_MEM) 53 switch (port->iotype) {
54 case UPIO_MEM:
52 return readb(port->membase + offset); 55 return readb(port->membase + offset);
53 else 56 case UPIO_MEM32:
57 return readl(port->membase + (offset << 2));
58 case UPIO_PORT:
54 return inb(port->iobase + offset); 59 return inb(port->iobase + offset);
60 default:
61 return 0;
62 }
55} 63}
56 64
57static void __init serial_out(struct uart_port *port, int offset, int value) 65static void __init serial_out(struct uart_port *port, int offset, int value)
58{ 66{
59 if (port->iotype == UPIO_MEM) 67 switch (port->iotype) {
68 case UPIO_MEM:
60 writeb(value, port->membase + offset); 69 writeb(value, port->membase + offset);
61 else 70 break;
71 case UPIO_MEM32:
72 writel(value, port->membase + (offset << 2));
73 break;
74 case UPIO_PORT:
62 outb(value, port->iobase + offset); 75 outb(value, port->iobase + offset);
76 break;
77 }
63} 78}
64 79
65#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) 80#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
@@ -137,15 +152,21 @@ static int __init parse_options(struct early_serial8250_device *device,
137 char *options) 152 char *options)
138{ 153{
139 struct uart_port *port = &device->port; 154 struct uart_port *port = &device->port;
140 int mmio, length; 155 int mmio, mmio32, length;
141 156
142 if (!options) 157 if (!options)
143 return -ENODEV; 158 return -ENODEV;
144 159
145 port->uartclk = BASE_BAUD * 16; 160 port->uartclk = BASE_BAUD * 16;
146 if (!strncmp(options, "mmio,", 5)) { 161
147 port->iotype = UPIO_MEM; 162 mmio = !strncmp(options, "mmio,", 5);
148 port->mapbase = simple_strtoul(options + 5, &options, 0); 163 mmio32 = !strncmp(options, "mmio32,", 7);
164 if (mmio || mmio32) {
165 port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32);
166 port->mapbase = simple_strtoul(options + (mmio ? 5 : 7),
167 &options, 0);
168 if (mmio32)
169 port->regshift = 2;
149#ifdef CONFIG_FIX_EARLYCON_MEM 170#ifdef CONFIG_FIX_EARLYCON_MEM
150 set_fixmap_nocache(FIX_EARLYCON_MEM_BASE, 171 set_fixmap_nocache(FIX_EARLYCON_MEM_BASE,
151 port->mapbase & PAGE_MASK); 172 port->mapbase & PAGE_MASK);
@@ -157,11 +178,10 @@ static int __init parse_options(struct early_serial8250_device *device,
157 if (!port->membase) { 178 if (!port->membase) {
158 printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n", 179 printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n",
159 __func__, 180 __func__,
160 (unsigned long long)port->mapbase); 181 (unsigned long long) port->mapbase);
161 return -ENOMEM; 182 return -ENOMEM;
162 } 183 }
163#endif 184#endif
164 mmio = 1;
165 } else if (!strncmp(options, "io,", 3)) { 185 } else if (!strncmp(options, "io,", 3)) {
166 port->iotype = UPIO_PORT; 186 port->iotype = UPIO_PORT;
167 port->iobase = simple_strtoul(options + 3, &options, 0); 187 port->iobase = simple_strtoul(options + 3, &options, 0);
@@ -181,11 +201,18 @@ static int __init parse_options(struct early_serial8250_device *device,
181 device->baud); 201 device->baud);
182 } 202 }
183 203
184 printk(KERN_INFO "Early serial console at %s 0x%llx (options '%s')\n", 204 if (mmio || mmio32)
185 mmio ? "MMIO" : "I/O port", 205 printk(KERN_INFO
186 mmio ? (unsigned long long) port->mapbase 206 "Early serial console at MMIO%s 0x%llu (options '%s')\n",
187 : (unsigned long long) port->iobase, 207 mmio32 ? "32" : "",
188 device->options); 208 (unsigned long long)port->mapbase,
209 device->options);
210 else
211 printk(KERN_INFO
212 "Early serial console at I/O port 0x%lu (options '%s')\n",
213 port->iobase,
214 device->options);
215
189 return 0; 216 return 0;
190} 217}
191 218