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