diff options
author | Yinghai Lu <yinghai@kernel.org> | 2010-07-14 14:26:57 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2010-07-14 15:07:16 -0400 |
commit | 70b0d22d581a5deef7b2876b0c3774635b8d846c (patch) | |
tree | 7ec83deb42a6b9bcbbc1517298a77cd380321af6 /arch/x86/boot | |
parent | ce0aa5dd20e44372f9617dd67c984f41fcdbed88 (diff) |
x86, setup: Only set early_serial_base after port is initialized
putchar is using early_serial_base to check if port is initialized.
So we only assign it after early_serial_init() is called,
in case we need use VGA to debug early serial console.
Also add display for port addr and baud.
-v2: update to current tip
Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
LKML-Reference: <4C3E0171.6050008@kernel.org>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/boot')
-rw-r--r-- | arch/x86/boot/tty.c | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/arch/x86/boot/tty.c b/arch/x86/boot/tty.c index f6d52e65f97a..ff4b27a0fc5e 100644 --- a/arch/x86/boot/tty.c +++ b/arch/x86/boot/tty.c | |||
@@ -152,35 +152,40 @@ int getchar_timeout(void) | |||
152 | return 0; /* Timeout! */ | 152 | return 0; /* Timeout! */ |
153 | } | 153 | } |
154 | 154 | ||
155 | static void early_serial_init(int baud) | 155 | static void early_serial_init(int port, int baud) |
156 | { | 156 | { |
157 | unsigned char c; | 157 | unsigned char c; |
158 | unsigned divisor; | 158 | unsigned divisor; |
159 | 159 | ||
160 | outb(0x3, early_serial_base + LCR); /* 8n1 */ | 160 | outb(0x3, port + LCR); /* 8n1 */ |
161 | outb(0, early_serial_base + IER); /* no interrupt */ | 161 | outb(0, port + IER); /* no interrupt */ |
162 | outb(0, early_serial_base + FCR); /* no fifo */ | 162 | outb(0, port + FCR); /* no fifo */ |
163 | outb(0x3, early_serial_base + MCR); /* DTR + RTS */ | 163 | outb(0x3, port + MCR); /* DTR + RTS */ |
164 | 164 | ||
165 | divisor = 115200 / baud; | 165 | divisor = 115200 / baud; |
166 | c = inb(early_serial_base + LCR); | 166 | c = inb(port + LCR); |
167 | outb(c | DLAB, early_serial_base + LCR); | 167 | outb(c | DLAB, port + LCR); |
168 | outb(divisor & 0xff, early_serial_base + DLL); | 168 | outb(divisor & 0xff, port + DLL); |
169 | outb((divisor >> 8) & 0xff, early_serial_base + DLH); | 169 | outb((divisor >> 8) & 0xff, port + DLH); |
170 | outb(c & ~DLAB, early_serial_base + LCR); | 170 | outb(c & ~DLAB, port + LCR); |
171 | |||
172 | early_serial_base = port; | ||
173 | |||
174 | printf("Early serial console at I/O port 0x%x baud: %d\n", port, baud); | ||
171 | } | 175 | } |
172 | 176 | ||
173 | static int parse_earlyprintk(void) | 177 | static void parse_earlyprintk(void) |
174 | { | 178 | { |
175 | int baud = DEFAULT_BAUD; | 179 | int baud = DEFAULT_BAUD; |
176 | char arg[32]; | 180 | char arg[32]; |
177 | int pos = 0; | 181 | int pos = 0; |
182 | int port = 0; | ||
178 | 183 | ||
179 | if (cmdline_find_option("earlyprintk", arg, sizeof arg) > 0) { | 184 | if (cmdline_find_option("earlyprintk", arg, sizeof arg) > 0) { |
180 | char *e; | 185 | char *e; |
181 | 186 | ||
182 | if (!strncmp(arg, "serial", 6)) { | 187 | if (!strncmp(arg, "serial", 6)) { |
183 | early_serial_base = DEFAULT_SERIAL_PORT; | 188 | port = DEFAULT_SERIAL_PORT; |
184 | pos += 6; | 189 | pos += 6; |
185 | } | 190 | } |
186 | 191 | ||
@@ -189,15 +194,15 @@ static int parse_earlyprintk(void) | |||
189 | 194 | ||
190 | if (!strncmp(arg, "ttyS", 4)) { | 195 | if (!strncmp(arg, "ttyS", 4)) { |
191 | static const int bases[] = { 0x3f8, 0x2f8 }; | 196 | static const int bases[] = { 0x3f8, 0x2f8 }; |
192 | int port = 0; | 197 | int idx = 0; |
193 | 198 | ||
194 | if (!strncmp(arg + pos, "ttyS", 4)) | 199 | if (!strncmp(arg + pos, "ttyS", 4)) |
195 | pos += 4; | 200 | pos += 4; |
196 | 201 | ||
197 | if (arg[pos++] == '1') | 202 | if (arg[pos++] == '1') |
198 | port = 1; | 203 | idx = 1; |
199 | 204 | ||
200 | early_serial_base = bases[port]; | 205 | port = bases[idx]; |
201 | } | 206 | } |
202 | 207 | ||
203 | if (arg[pos] == ',') | 208 | if (arg[pos] == ',') |
@@ -208,7 +213,8 @@ static int parse_earlyprintk(void) | |||
208 | baud = DEFAULT_BAUD; | 213 | baud = DEFAULT_BAUD; |
209 | } | 214 | } |
210 | 215 | ||
211 | return baud; | 216 | if (port) |
217 | early_serial_init(port, baud); | ||
212 | } | 218 | } |
213 | 219 | ||
214 | #define BASE_BAUD (1843200/16) | 220 | #define BASE_BAUD (1843200/16) |
@@ -227,44 +233,41 @@ static unsigned int probe_baud(int port) | |||
227 | return BASE_BAUD / quot; | 233 | return BASE_BAUD / quot; |
228 | } | 234 | } |
229 | 235 | ||
230 | static int parse_console_uart8250(void) | 236 | static void parse_console_uart8250(void) |
231 | { | 237 | { |
232 | char optstr[64], *options; | 238 | char optstr[64], *options; |
233 | int baud = DEFAULT_BAUD; | 239 | int baud = DEFAULT_BAUD; |
240 | int port = 0; | ||
234 | 241 | ||
235 | /* | 242 | /* |
236 | * console=uart8250,io,0x3f8,115200n8 | 243 | * console=uart8250,io,0x3f8,115200n8 |
237 | * need to make sure it is last one console ! | 244 | * need to make sure it is last one console ! |
238 | */ | 245 | */ |
239 | if (cmdline_find_option("console", optstr, sizeof optstr) <= 0) | 246 | if (cmdline_find_option("console", optstr, sizeof optstr) <= 0) |
240 | return baud; | 247 | return; |
241 | 248 | ||
242 | options = optstr; | 249 | options = optstr; |
243 | 250 | ||
244 | if (!strncmp(options, "uart8250,io,", 12)) | 251 | if (!strncmp(options, "uart8250,io,", 12)) |
245 | early_serial_base = simple_strtoull(options + 12, &options, 0); | 252 | port = simple_strtoull(options + 12, &options, 0); |
246 | else if (!strncmp(options, "uart,io,", 8)) | 253 | else if (!strncmp(options, "uart,io,", 8)) |
247 | early_serial_base = simple_strtoull(options + 8, &options, 0); | 254 | port = simple_strtoull(options + 8, &options, 0); |
248 | else | 255 | else |
249 | return baud; | 256 | return; |
250 | 257 | ||
251 | if (options && (options[0] == ',')) | 258 | if (options && (options[0] == ',')) |
252 | baud = simple_strtoull(options + 1, &options, 0); | 259 | baud = simple_strtoull(options + 1, &options, 0); |
253 | else | 260 | else |
254 | baud = probe_baud(early_serial_base); | 261 | baud = probe_baud(port); |
255 | 262 | ||
256 | return baud; | 263 | if (port) |
264 | early_serial_init(port, baud); | ||
257 | } | 265 | } |
258 | 266 | ||
259 | void console_init(void) | 267 | void console_init(void) |
260 | { | 268 | { |
261 | int baud; | 269 | parse_earlyprintk(); |
262 | |||
263 | baud = parse_earlyprintk(); | ||
264 | 270 | ||
265 | if (!early_serial_base) | 271 | if (!early_serial_base) |
266 | baud = parse_console_uart8250(); | 272 | parse_console_uart8250(); |
267 | |||
268 | if (early_serial_base != 0) | ||
269 | early_serial_init(baud); | ||
270 | } | 273 | } |