diff options
-rw-r--r-- | arch/x86/include/asm/mrst.h | 3 | ||||
-rw-r--r-- | arch/x86/kernel/early_printk.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/early_printk_mrst.c | 89 |
3 files changed, 97 insertions, 1 deletions
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h index d0ea5bc505a3..4a711a684b17 100644 --- a/arch/x86/include/asm/mrst.h +++ b/arch/x86/include/asm/mrst.h | |||
@@ -47,4 +47,7 @@ extern enum mrst_timer_options mrst_timer_options; | |||
47 | 47 | ||
48 | extern struct console early_mrst_console; | 48 | extern struct console early_mrst_console; |
49 | extern void mrst_early_console_init(void); | 49 | extern void mrst_early_console_init(void); |
50 | |||
51 | extern struct console early_hsu_console; | ||
52 | extern void hsu_early_console_init(void); | ||
50 | #endif /* _ASM_X86_MRST_H */ | 53 | #endif /* _ASM_X86_MRST_H */ |
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 6082463768a2..4572f25f9325 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c | |||
@@ -245,6 +245,12 @@ static int __init setup_early_printk(char *buf) | |||
245 | mrst_early_console_init(); | 245 | mrst_early_console_init(); |
246 | early_console_register(&early_mrst_console, keep); | 246 | early_console_register(&early_mrst_console, keep); |
247 | } | 247 | } |
248 | |||
249 | if (!strncmp(buf, "hsu", 3)) { | ||
250 | hsu_early_console_init(); | ||
251 | early_console_register(&early_hsu_console, keep); | ||
252 | } | ||
253 | |||
248 | #endif | 254 | #endif |
249 | buf++; | 255 | buf++; |
250 | } | 256 | } |
diff --git a/arch/x86/kernel/early_printk_mrst.c b/arch/x86/kernel/early_printk_mrst.c index 05d27e1e2b62..65df603622b2 100644 --- a/arch/x86/kernel/early_printk_mrst.c +++ b/arch/x86/kernel/early_printk_mrst.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * early_printk_mrst.c - spi-uart early printk for Intel Moorestown platform | 2 | * early_printk_mrst.c - early consoles for Intel MID platforms |
3 | * | 3 | * |
4 | * Copyright (c) 2008-2010, Intel Corporation | 4 | * Copyright (c) 2008-2010, Intel Corporation |
5 | * | 5 | * |
@@ -9,9 +9,19 @@ | |||
9 | * of the License. | 9 | * of the License. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | /* | ||
13 | * This file implements two early consoles named mrst and hsu. | ||
14 | * mrst is based on Maxim3110 spi-uart device, it exists in both | ||
15 | * Moorestown and Medfield platforms, while hsu is based on a High | ||
16 | * Speed UART device which only exists in the Medfield platform | ||
17 | */ | ||
18 | |||
19 | #include <linux/serial_reg.h> | ||
20 | #include <linux/serial_mfd.h> | ||
12 | #include <linux/kmsg_dump.h> | 21 | #include <linux/kmsg_dump.h> |
13 | #include <linux/console.h> | 22 | #include <linux/console.h> |
14 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/delay.h> | ||
15 | #include <linux/init.h> | 25 | #include <linux/init.h> |
16 | #include <linux/io.h> | 26 | #include <linux/io.h> |
17 | 27 | ||
@@ -230,3 +240,80 @@ struct console early_mrst_console = { | |||
230 | .flags = CON_PRINTBUFFER, | 240 | .flags = CON_PRINTBUFFER, |
231 | .index = -1, | 241 | .index = -1, |
232 | }; | 242 | }; |
243 | |||
244 | /* | ||
245 | * Following is the early console based on Medfield HSU (High | ||
246 | * Speed UART) device. | ||
247 | */ | ||
248 | #define HSU_PORT2_PADDR 0xffa28180 | ||
249 | |||
250 | static void __iomem *phsu; | ||
251 | |||
252 | void hsu_early_console_init(void) | ||
253 | { | ||
254 | u8 lcr; | ||
255 | |||
256 | phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, | ||
257 | HSU_PORT2_PADDR); | ||
258 | |||
259 | /* Disable FIFO */ | ||
260 | writeb(0x0, phsu + UART_FCR); | ||
261 | |||
262 | /* Set to default 115200 bps, 8n1 */ | ||
263 | lcr = readb(phsu + UART_LCR); | ||
264 | writeb((0x80 | lcr), phsu + UART_LCR); | ||
265 | writeb(0x18, phsu + UART_DLL); | ||
266 | writeb(lcr, phsu + UART_LCR); | ||
267 | writel(0x3600, phsu + UART_MUL*4); | ||
268 | |||
269 | writeb(0x8, phsu + UART_MCR); | ||
270 | writeb(0x7, phsu + UART_FCR); | ||
271 | writeb(0x3, phsu + UART_LCR); | ||
272 | |||
273 | /* Clear IRQ status */ | ||
274 | readb(phsu + UART_LSR); | ||
275 | readb(phsu + UART_RX); | ||
276 | readb(phsu + UART_IIR); | ||
277 | readb(phsu + UART_MSR); | ||
278 | |||
279 | /* Enable FIFO */ | ||
280 | writeb(0x7, phsu + UART_FCR); | ||
281 | } | ||
282 | |||
283 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | ||
284 | |||
285 | static void early_hsu_putc(char ch) | ||
286 | { | ||
287 | unsigned int timeout = 10000; /* 10ms */ | ||
288 | u8 status; | ||
289 | |||
290 | while (--timeout) { | ||
291 | status = readb(phsu + UART_LSR); | ||
292 | if (status & BOTH_EMPTY) | ||
293 | break; | ||
294 | udelay(1); | ||
295 | } | ||
296 | |||
297 | /* Only write the char when there was no timeout */ | ||
298 | if (timeout) | ||
299 | writeb(ch, phsu + UART_TX); | ||
300 | } | ||
301 | |||
302 | static void early_hsu_write(struct console *con, const char *str, unsigned n) | ||
303 | { | ||
304 | int i; | ||
305 | |||
306 | for (i = 0; i < n && *str; i++) { | ||
307 | if (*str == '\n') | ||
308 | early_hsu_putc('\r'); | ||
309 | early_hsu_putc(*str); | ||
310 | str++; | ||
311 | } | ||
312 | } | ||
313 | |||
314 | struct console early_hsu_console = { | ||
315 | .name = "earlyhsu", | ||
316 | .write = early_hsu_write, | ||
317 | .flags = CON_PRINTBUFFER, | ||
318 | .index = -1, | ||
319 | }; | ||