2 * arch/xtensa/platforms/iss/console.c
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
8 * Copyright (C) 2001-2005 Tensilica Inc.
9 * Authors Christian Zankel, Joe Taylor
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/console.h>
16 #include <linux/init.h>
18 #include <linux/major.h>
19 #include <linux/param.h>
20 #include <linux/seq_file.h>
21 #include <linux/serial.h>
23 #include <linux/uaccess.h>
26 #include <platform/simcall.h>
28 #include <linux/tty.h>
29 #include <linux/tty_flip.h>
31 #define SERIAL_MAX_NUM_LINES 1
32 #define SERIAL_TIMER_VALUE (HZ / 10)
34 static void rs_poll(struct timer_list
*);
36 static struct tty_driver
*serial_driver
;
37 static struct tty_port serial_port
;
38 static DEFINE_TIMER(serial_timer
, rs_poll
);
40 static int rs_open(struct tty_struct
*tty
, struct file
* filp
)
43 mod_timer(&serial_timer
, jiffies
+ SERIAL_TIMER_VALUE
);
48 static void rs_close(struct tty_struct
*tty
, struct file
* filp
)
51 del_timer_sync(&serial_timer
);
55 static ssize_t
rs_write(struct tty_struct
* tty
, const u8
*buf
, size_t count
)
57 /* see drivers/char/serialX.c to reference original version */
59 simc_write(1, buf
, count
);
63 static void rs_poll(struct timer_list
*unused
)
65 struct tty_port
*port
= &serial_port
;
70 while (simc_poll(0)) {
71 rd
= simc_read(0, &c
, 1);
74 tty_insert_flip_char(port
, c
, TTY_NORMAL
);
79 tty_flip_buffer_push(port
);
81 mod_timer(&serial_timer
, jiffies
+ SERIAL_TIMER_VALUE
);
84 static unsigned int rs_write_room(struct tty_struct
*tty
)
86 /* Let's say iss can always accept 2K characters.. */
90 static int rs_proc_show(struct seq_file
*m
, void *v
)
92 seq_printf(m
, "serinfo:1.0 driver:0.1\n");
96 static const struct tty_operations serial_ops
= {
100 .write_room
= rs_write_room
,
101 .proc_show
= rs_proc_show
,
104 static int __init
rs_init(void)
106 struct tty_driver
*driver
;
109 driver
= tty_alloc_driver(SERIAL_MAX_NUM_LINES
, TTY_DRIVER_REAL_RAW
);
111 return PTR_ERR(driver
);
113 tty_port_init(&serial_port
);
115 /* Initialize the tty_driver structure */
117 driver
->driver_name
= "iss_serial";
118 driver
->name
= "ttyS";
119 driver
->major
= TTY_MAJOR
;
120 driver
->minor_start
= 64;
121 driver
->type
= TTY_DRIVER_TYPE_SERIAL
;
122 driver
->subtype
= SERIAL_TYPE_NORMAL
;
123 driver
->init_termios
= tty_std_termios
;
124 driver
->init_termios
.c_cflag
=
125 B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
127 tty_set_operations(driver
, &serial_ops
);
128 tty_port_link_device(&serial_port
, driver
, 0);
130 ret
= tty_register_driver(driver
);
132 pr_err("Couldn't register serial driver\n");
133 tty_driver_kref_put(driver
);
134 tty_port_destroy(&serial_port
);
139 serial_driver
= driver
;
145 static __exit
void rs_exit(void)
147 tty_unregister_driver(serial_driver
);
148 tty_driver_kref_put(serial_driver
);
149 tty_port_destroy(&serial_port
);
153 /* We use `late_initcall' instead of just `__initcall' as a workaround for
154 * the fact that (1) simcons_tty_init can't be called before tty_init,
155 * (2) tty_init is called via `module_init', (3) if statically linked,
156 * module_init == device_init, and (4) there's no ordering of init lists.
157 * We can do this easily because simcons is always statically linked, but
158 * other tty drivers that depend on tty_init and which must use
159 * `module_init' to declare their init routines are likely to be broken.
162 late_initcall(rs_init
);
165 #ifdef CONFIG_SERIAL_CONSOLE
167 static void iss_console_write(struct console
*co
, const char *s
, unsigned count
)
170 simc_write(1, s
, min(count
, strlen(s
)));
173 static struct tty_driver
* iss_console_device(struct console
*c
, int *index
)
176 return serial_driver
;
180 static struct console sercons
= {
182 .write
= iss_console_write
,
183 .device
= iss_console_device
,
184 .flags
= CON_PRINTBUFFER
,
188 static int __init
iss_console_init(void)
190 register_console(&sercons
);
194 console_initcall(iss_console_init
);
196 #endif /* CONFIG_SERIAL_CONSOLE */