diff options
Diffstat (limited to 'arch/sh/kernel/early_printk.c')
-rw-r--r-- | arch/sh/kernel/early_printk.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c new file mode 100644 index 000000000000..1378db375e17 --- /dev/null +++ b/arch/sh/kernel/early_printk.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/early_printk.c | ||
3 | * | ||
4 | * Copyright (C) 1999, 2000 Niibe Yutaka | ||
5 | * Copyright (C) 2002 M. R. Brown | ||
6 | * Copyright (C) 2004 Paul Mundt | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | #include <linux/console.h> | ||
13 | #include <linux/tty.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <asm/io.h> | ||
16 | |||
17 | #ifdef CONFIG_SH_STANDARD_BIOS | ||
18 | #include <asm/sh_bios.h> | ||
19 | |||
20 | /* | ||
21 | * Print a string through the BIOS | ||
22 | */ | ||
23 | static void sh_console_write(struct console *co, const char *s, | ||
24 | unsigned count) | ||
25 | { | ||
26 | sh_bios_console_write(s, count); | ||
27 | } | ||
28 | |||
29 | /* | ||
30 | * Setup initial baud/bits/parity. We do two things here: | ||
31 | * - construct a cflag setting for the first rs_open() | ||
32 | * - initialize the serial port | ||
33 | * Return non-zero if we didn't find a serial port. | ||
34 | */ | ||
35 | static int __init sh_console_setup(struct console *co, char *options) | ||
36 | { | ||
37 | int cflag = CREAD | HUPCL | CLOCAL; | ||
38 | |||
39 | /* | ||
40 | * Now construct a cflag setting. | ||
41 | * TODO: this is a totally bogus cflag, as we have | ||
42 | * no idea what serial settings the BIOS is using, or | ||
43 | * even if its using the serial port at all. | ||
44 | */ | ||
45 | cflag |= B115200 | CS8 | /*no parity*/0; | ||
46 | |||
47 | co->cflag = cflag; | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static struct console early_console = { | ||
53 | .name = "bios", | ||
54 | .write = sh_console_write, | ||
55 | .setup = sh_console_setup, | ||
56 | .flags = CON_PRINTBUFFER, | ||
57 | .index = -1, | ||
58 | }; | ||
59 | #endif | ||
60 | |||
61 | #ifdef CONFIG_EARLY_SCIF_CONSOLE | ||
62 | #define SCIF_REG 0xffe80000 | ||
63 | |||
64 | static void scif_sercon_putc(int c) | ||
65 | { | ||
66 | while (!(ctrl_inw(SCIF_REG + 0x10) & 0x20)) ; | ||
67 | |||
68 | ctrl_outb(c, SCIF_REG + 12); | ||
69 | ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0x9f), SCIF_REG + 0x10); | ||
70 | |||
71 | if (c == '\n') | ||
72 | scif_sercon_putc('\r'); | ||
73 | } | ||
74 | |||
75 | static void scif_sercon_flush(void) | ||
76 | { | ||
77 | ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10); | ||
78 | |||
79 | while (!(ctrl_inw(SCIF_REG + 0x10) & 0x40)) ; | ||
80 | |||
81 | ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10); | ||
82 | } | ||
83 | |||
84 | static void scif_sercon_write(struct console *con, const char *s, unsigned count) | ||
85 | { | ||
86 | while (count-- > 0) | ||
87 | scif_sercon_putc(*s++); | ||
88 | |||
89 | scif_sercon_flush(); | ||
90 | } | ||
91 | |||
92 | static int __init scif_sercon_setup(struct console *con, char *options) | ||
93 | { | ||
94 | con->cflag = CREAD | HUPCL | CLOCAL | B115200 | CS8; | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static struct console early_console = { | ||
100 | .name = "sercon", | ||
101 | .write = scif_sercon_write, | ||
102 | .setup = scif_sercon_setup, | ||
103 | .flags = CON_PRINTBUFFER, | ||
104 | .index = -1, | ||
105 | }; | ||
106 | |||
107 | void scif_sercon_init(int baud) | ||
108 | { | ||
109 | ctrl_outw(0, SCIF_REG + 8); | ||
110 | ctrl_outw(0, SCIF_REG); | ||
111 | |||
112 | /* Set baud rate */ | ||
113 | ctrl_outb((CONFIG_SH_PCLK_FREQ + 16 * baud) / | ||
114 | (32 * baud) - 1, SCIF_REG + 4); | ||
115 | |||
116 | ctrl_outw(12, SCIF_REG + 24); | ||
117 | ctrl_outw(8, SCIF_REG + 24); | ||
118 | ctrl_outw(0, SCIF_REG + 32); | ||
119 | ctrl_outw(0x60, SCIF_REG + 16); | ||
120 | ctrl_outw(0, SCIF_REG + 36); | ||
121 | ctrl_outw(0x30, SCIF_REG + 8); | ||
122 | } | ||
123 | #endif | ||
124 | |||
125 | void __init enable_early_printk(void) | ||
126 | { | ||
127 | #ifdef CONFIG_EARLY_SCIF_CONSOLE | ||
128 | scif_sercon_init(115200); | ||
129 | #endif | ||
130 | register_console(&early_console); | ||
131 | } | ||
132 | |||
133 | void disable_early_printk(void) | ||
134 | { | ||
135 | unregister_console(&early_console); | ||
136 | } | ||
137 | |||