2 * Console support for OMAP STI/XTI
4 * Copyright (C) 2004, 2005, 2006 Nokia Corporation
5 * Written by: Paul Mundt <paul.mundt@nokia.com>
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
11 #include <linux/console.h>
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/tty.h>
16 #include <linux/tty_driver.h>
17 #include <asm/arch/sti.h>
18 #include <asm/arch/board.h>
20 #define DRV_NAME "sticon"
22 static struct tty_driver *tty_driver;
23 static DEFINE_SPINLOCK(sti_console_lock);
24 static unsigned int sti_console_channel = -1;
25 static int sti_line_done = -1;
28 * Write a string to any channel (including terminating NULL)
29 * Returns number of characters written.
31 static int sti_channel_puts(const char *string, unsigned int channel, int len)
36 * sti_line_done is needed to determine when we have reached the
37 * end of the line. write() has a tendency to hand us small
38 * strings which otherwise end up creating newlines.. we need to
39 * keep the channel open and in append mode until the line has
42 if (sti_line_done != 0) {
43 #ifdef __LITTLE_ENDIAN
44 sti_channel_writeb(0xc3, channel);
46 sti_channel_writeb(0xc0, channel);
48 xchg(&sti_line_done, 0);
51 while (*string && count != len) {
57 xchg(&sti_line_done, 1);
58 sti_channel_writeb(0, channel);
61 sti_channel_writeb(c, channel);
65 sti_channel_flush(channel);
70 static int sti_tty_open(struct tty_struct *tty, struct file *filp)
75 static int sti_tty_write(struct tty_struct *tty,
76 const unsigned char *buf, int len)
81 spin_lock_irqsave(&sti_console_lock, flags);
82 bytes = sti_channel_puts(buf, sti_console_channel, len);
83 spin_unlock_irqrestore(&sti_console_lock, flags);
88 static int sti_tty_write_room(struct tty_struct *tty)
93 static int sti_tty_chars_in_buffer(struct tty_struct *tty)
98 static struct tty_operations sti_tty_ops = {
100 .write = sti_tty_write,
101 .write_room = sti_tty_write_room,
102 .chars_in_buffer = sti_tty_chars_in_buffer,
105 static void sti_console_write(struct console *c, const char *s, unsigned n)
109 spin_lock_irqsave(&sti_console_lock, flags);
110 sti_channel_puts(s, sti_console_channel, n);
111 spin_unlock_irqrestore(&sti_console_lock, flags);
114 static struct tty_driver *sti_console_device(struct console *c, int *index)
120 static int sti_console_setup(struct console *c, char *opts)
125 static struct console sti_console = {
127 .write = sti_console_write,
128 .device = sti_console_device,
129 .setup = sti_console_setup,
130 .flags = CON_PRINTBUFFER | CON_ENABLED,
134 static int __init sti_console_init(void)
136 const struct omap_sti_console_config *info;
138 info = omap_get_config(OMAP_TAG_STI_CONSOLE,
139 struct omap_sti_console_config);
140 if (info && info->enable) {
141 add_preferred_console(DRV_NAME, 0, NULL);
143 sti_console_channel = info->channel;
146 if (unlikely(sti_console_channel == -1))
149 register_console(&sti_console);
153 __initcall(sti_console_init);
155 static int __init sti_tty_init(void)
157 struct tty_driver *tty;
160 tty = alloc_tty_driver(1);
164 tty->name = DRV_NAME;
165 tty->driver_name = DRV_NAME;
166 tty->major = 0; /* dynamic major */
167 tty->minor_start = 0;
168 tty->type = TTY_DRIVER_TYPE_SYSTEM;
169 tty->subtype = SYSTEM_TYPE_SYSCONS;
170 tty->init_termios = tty_std_termios;
172 tty_set_operations(tty, &sti_tty_ops);
174 ret = tty_register_driver(tty);
183 late_initcall(sti_tty_init);
185 module_param(sti_console_channel, uint, 0);
186 MODULE_PARM_DESC(sti_console_channel, "STI console channel");
187 MODULE_AUTHOR("Paul Mundt");
188 MODULE_DESCRIPTION("OMAP STI console support");
189 MODULE_LICENSE("GPL");