allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / arch / cris / arch-v32 / kernel / debugport.c
blobd1272ad921531e6aefa04c9886fa2c4598f3fa6f
1 /*
2 * Copyright (C) 2003, Axis Communications AB.
3 */
5 #include <linux/console.h>
6 #include <linux/init.h>
7 #include <linux/major.h>
8 #include <linux/delay.h>
9 #include <linux/tty.h>
10 #include <asm/system.h>
11 #include <asm/io.h>
12 #include <asm/arch/hwregs/ser_defs.h>
13 #include <asm/arch/hwregs/dma_defs.h>
14 #include <asm/arch/pinmux.h>
16 #include <asm/irq.h>
17 #include <asm/arch/hwregs/intr_vect_defs.h>
19 struct dbg_port
21 unsigned char nbr;
22 unsigned long instance;
23 unsigned int started;
24 unsigned long baudrate;
25 unsigned char parity;
26 unsigned int bits;
29 struct dbg_port ports[] =
33 regi_ser0,
35 115200,
36 'N',
41 regi_ser1,
43 115200,
44 'N',
49 regi_ser2,
51 115200,
52 'N',
57 regi_ser3,
59 115200,
60 'N',
64 static struct dbg_port *port =
65 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
66 &ports[0];
67 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
68 &ports[1];
69 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
70 &ports[2];
71 #elif defined(CONFIG_ETRAX_DEBUG_PORT3)
72 &ports[3];
73 #else
74 NULL;
75 #endif
77 #ifdef CONFIG_ETRAX_KGDB
78 static struct dbg_port *kgdb_port =
79 #if defined(CONFIG_ETRAX_KGDB_PORT0)
80 &ports[0];
81 #elif defined(CONFIG_ETRAX_KGDB_PORT1)
82 &ports[1];
83 #elif defined(CONFIG_ETRAX_KGDB_PORT2)
84 &ports[2];
85 #elif defined(CONFIG_ETRAX_KGDB_PORT3)
86 &ports[3];
87 #else
88 NULL;
89 #endif
90 #endif
92 #ifdef CONFIG_ETRAXFS_SIM
93 extern void print_str( const char *str );
94 static char buffer[1024];
95 static char msg[] = "Debug: ";
96 static int buffer_pos = sizeof(msg) - 1;
97 #endif
99 extern struct tty_driver *serial_driver;
101 static void
102 start_port(struct dbg_port* p)
104 if (!p)
105 return;
107 if (p->started)
108 return;
109 p->started = 1;
111 if (p->nbr == 1)
112 crisv32_pinmux_alloc_fixed(pinmux_ser1);
113 else if (p->nbr == 2)
114 crisv32_pinmux_alloc_fixed(pinmux_ser2);
115 else if (p->nbr == 3)
116 crisv32_pinmux_alloc_fixed(pinmux_ser3);
118 /* Set up serial port registers */
119 reg_ser_rw_tr_ctrl tr_ctrl = {0};
120 reg_ser_rw_tr_dma_en tr_dma_en = {0};
122 reg_ser_rw_rec_ctrl rec_ctrl = {0};
123 reg_ser_rw_tr_baud_div tr_baud_div = {0};
124 reg_ser_rw_rec_baud_div rec_baud_div = {0};
126 tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493;
127 tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no;
128 tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8;
129 tr_ctrl.en = rec_ctrl.en = 1;
131 if (p->parity == 'O')
133 tr_ctrl.par_en = regk_ser_yes;
134 tr_ctrl.par = regk_ser_odd;
135 rec_ctrl.par_en = regk_ser_yes;
136 rec_ctrl.par = regk_ser_odd;
138 else if (p->parity == 'E')
140 tr_ctrl.par_en = regk_ser_yes;
141 tr_ctrl.par = regk_ser_even;
142 rec_ctrl.par_en = regk_ser_yes;
143 rec_ctrl.par = regk_ser_odd;
146 if (p->bits == 7)
148 tr_ctrl.data_bits = regk_ser_bits7;
149 rec_ctrl.data_bits = regk_ser_bits7;
152 REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div);
153 REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div);
154 REG_WR (ser, p->instance, rw_tr_dma_en, tr_dma_en);
155 REG_WR (ser, p->instance, rw_tr_ctrl, tr_ctrl);
156 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);
159 /* No debug */
160 #ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
162 static void
163 console_write(struct console *co, const char *buf, unsigned int len)
165 return;
168 /* Target debug */
169 #elif !defined(CONFIG_ETRAXFS_SIM)
171 static void
172 console_write_direct(struct console *co, const char *buf, unsigned int len)
174 int i;
175 reg_ser_r_stat_din stat;
176 reg_ser_rw_tr_dma_en tr_dma_en, old;
178 /* Switch to manual mode */
179 tr_dma_en = old = REG_RD (ser, port->instance, rw_tr_dma_en);
180 if (tr_dma_en.en == regk_ser_yes) {
181 tr_dma_en.en = regk_ser_no;
182 REG_WR(ser, port->instance, rw_tr_dma_en, tr_dma_en);
185 /* Send data */
186 for (i = 0; i < len; i++) {
187 /* LF -> CRLF */
188 if (buf[i] == '\n') {
189 do {
190 stat = REG_RD (ser, port->instance, r_stat_din);
191 } while (!stat.tr_rdy);
192 REG_WR_INT (ser, port->instance, rw_dout, '\r');
194 /* Wait until transmitter is ready and send.*/
195 do {
196 stat = REG_RD (ser, port->instance, r_stat_din);
197 } while (!stat.tr_rdy);
198 REG_WR_INT (ser, port->instance, rw_dout, buf[i]);
201 /* Restore mode */
202 if (tr_dma_en.en != old.en)
203 REG_WR(ser, port->instance, rw_tr_dma_en, old);
206 static void
207 console_write(struct console *co, const char *buf, unsigned int len)
209 if (!port)
210 return;
211 console_write_direct(co, buf, len);
216 #else
218 /* VCS debug */
220 static void
221 console_write(struct console *co, const char *buf, unsigned int len)
223 char* pos;
224 pos = memchr(buf, '\n', len);
225 if (pos) {
226 int l = ++pos - buf;
227 memcpy(buffer + buffer_pos, buf, l);
228 memcpy(buffer, msg, sizeof(msg) - 1);
229 buffer[buffer_pos + l] = '\0';
230 print_str(buffer);
231 buffer_pos = sizeof(msg) - 1;
232 if (pos - buf != len) {
233 memcpy(buffer + buffer_pos, pos, len - l);
234 buffer_pos += len - l;
236 } else {
237 memcpy(buffer + buffer_pos, buf, len);
238 buffer_pos += len;
242 #endif
244 int raw_printk(const char *fmt, ...)
246 static char buf[1024];
247 int printed_len;
248 va_list args;
249 va_start(args, fmt);
250 printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
251 va_end(args);
252 console_write(NULL, buf, strlen(buf));
253 return printed_len;
256 void
257 stupid_debug(char* buf)
259 console_write(NULL, buf, strlen(buf));
262 #ifdef CONFIG_ETRAX_KGDB
263 /* Use polling to get a single character from the kernel debug port */
265 getDebugChar(void)
267 reg_ser_rs_status_data stat;
268 reg_ser_rw_ack_intr ack_intr = { 0 };
270 do {
271 stat = REG_RD(ser, kgdb_instance, rs_status_data);
272 } while (!stat.data_avail);
274 /* Ack the data_avail interrupt. */
275 ack_intr.data_avail = 1;
276 REG_WR(ser, kgdb_instance, rw_ack_intr, ack_intr);
278 return stat.data;
281 /* Use polling to put a single character to the kernel debug port */
282 void
283 putDebugChar(int val)
285 reg_ser_r_status_data stat;
286 do {
287 stat = REG_RD (ser, kgdb_instance, r_status_data);
288 } while (!stat.tr_ready);
289 REG_WR (ser, kgdb_instance, rw_data_out, REG_TYPE_CONV(reg_ser_rw_data_out, int, val));
291 #endif /* CONFIG_ETRAX_KGDB */
293 static int __init
294 console_setup(struct console *co, char *options)
296 char* s;
298 if (options) {
299 port = &ports[co->index];
300 port->baudrate = 115200;
301 port->parity = 'N';
302 port->bits = 8;
303 port->baudrate = simple_strtoul(options, NULL, 10);
304 s = options;
305 while(*s >= '0' && *s <= '9')
306 s++;
307 if (*s) port->parity = *s++;
308 if (*s) port->bits = *s++ - '0';
309 port->started = 0;
310 start_port(port);
312 return 0;
315 /* This is a dummy serial device that throws away anything written to it.
316 * This is used when no debug output is wanted.
318 static struct tty_driver dummy_driver;
320 static int dummy_open(struct tty_struct *tty, struct file * filp)
322 return 0;
325 static void dummy_close(struct tty_struct *tty, struct file * filp)
329 static int dummy_write(struct tty_struct * tty,
330 const unsigned char *buf, int count)
332 return count;
335 static int
336 dummy_write_room(struct tty_struct *tty)
338 return 8192;
341 void __init
342 init_dummy_console(void)
344 memset(&dummy_driver, 0, sizeof(struct tty_driver));
345 dummy_driver.driver_name = "serial";
346 dummy_driver.name = "ttyS";
347 dummy_driver.major = TTY_MAJOR;
348 dummy_driver.minor_start = 68;
349 dummy_driver.num = 1; /* etrax100 has 4 serial ports */
350 dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
351 dummy_driver.subtype = SERIAL_TYPE_NORMAL;
352 dummy_driver.init_termios = tty_std_termios;
353 dummy_driver.init_termios.c_cflag =
354 B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
355 dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
357 dummy_driver.open = dummy_open;
358 dummy_driver.close = dummy_close;
359 dummy_driver.write = dummy_write;
360 dummy_driver.write_room = dummy_write_room;
361 if (tty_register_driver(&dummy_driver))
362 panic("Couldn't register dummy serial driver\n");
365 static struct tty_driver*
366 crisv32_console_device(struct console* co, int *index)
368 if (port)
369 *index = port->nbr;
370 return port ? serial_driver : &dummy_driver;
373 static struct console sercons = {
374 name : "ttyS",
375 write: console_write,
376 read : NULL,
377 device : crisv32_console_device,
378 unblank : NULL,
379 setup : console_setup,
380 flags : CON_PRINTBUFFER,
381 index : -1,
382 cflag : 0,
383 next : NULL
385 static struct console sercons0 = {
386 name : "ttyS",
387 write: console_write,
388 read : NULL,
389 device : crisv32_console_device,
390 unblank : NULL,
391 setup : console_setup,
392 flags : CON_PRINTBUFFER,
393 index : 0,
394 cflag : 0,
395 next : NULL
398 static struct console sercons1 = {
399 name : "ttyS",
400 write: console_write,
401 read : NULL,
402 device : crisv32_console_device,
403 unblank : NULL,
404 setup : console_setup,
405 flags : CON_PRINTBUFFER,
406 index : 1,
407 cflag : 0,
408 next : NULL
410 static struct console sercons2 = {
411 name : "ttyS",
412 write: console_write,
413 read : NULL,
414 device : crisv32_console_device,
415 unblank : NULL,
416 setup : console_setup,
417 flags : CON_PRINTBUFFER,
418 index : 2,
419 cflag : 0,
420 next : NULL
422 static struct console sercons3 = {
423 name : "ttyS",
424 write: console_write,
425 read : NULL,
426 device : crisv32_console_device,
427 unblank : NULL,
428 setup : console_setup,
429 flags : CON_PRINTBUFFER,
430 index : 3,
431 cflag : 0,
432 next : NULL
435 /* Register console for printk's, etc. */
436 int __init
437 init_etrax_debug(void)
439 static int first = 1;
441 if (!first) {
442 unregister_console(&sercons);
443 register_console(&sercons0);
444 register_console(&sercons1);
445 register_console(&sercons2);
446 register_console(&sercons3);
447 init_dummy_console();
448 return 0;
450 first = 0;
451 register_console(&sercons);
452 start_port(port);
454 #ifdef CONFIG_ETRAX_KGDB
455 start_port(kgdb_port);
456 #endif /* CONFIG_ETRAX_KGDB */
457 return 0;
460 __initcall(init_etrax_debug);