[MIPS] Always pass -msoft-float.
[linux-2.6/openmoko-kernel/knife-kernel.git] / arch / cris / arch-v32 / kernel / debugport.c
blobffc1ebf2dfee30b4a3b4ceb039236e4fea58d079
1 /*
2 * Copyright (C) 2003, Axis Communications AB.
3 */
5 #include <linux/config.h>
6 #include <linux/console.h>
7 #include <linux/init.h>
8 #include <linux/major.h>
9 #include <linux/delay.h>
10 #include <linux/tty.h>
11 #include <asm/system.h>
12 #include <asm/io.h>
13 #include <asm/arch/hwregs/ser_defs.h>
14 #include <asm/arch/hwregs/dma_defs.h>
15 #include <asm/arch/pinmux.h>
17 #include <asm/irq.h>
18 #include <asm/arch/hwregs/intr_vect_defs.h>
20 struct dbg_port
22 unsigned char nbr;
23 unsigned long instance;
24 unsigned int started;
25 unsigned long baudrate;
26 unsigned char parity;
27 unsigned int bits;
30 struct dbg_port ports[] =
34 regi_ser0,
36 115200,
37 'N',
42 regi_ser1,
44 115200,
45 'N',
50 regi_ser2,
52 115200,
53 'N',
58 regi_ser3,
60 115200,
61 'N',
65 static struct dbg_port *port =
66 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
67 &ports[0];
68 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
69 &ports[1];
70 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
71 &ports[2];
72 #elif defined(CONFIG_ETRAX_DEBUG_PORT3)
73 &ports[3];
74 #else
75 NULL;
76 #endif
78 #ifdef CONFIG_ETRAX_KGDB
79 static struct dbg_port *kgdb_port =
80 #if defined(CONFIG_ETRAX_KGDB_PORT0)
81 &ports[0];
82 #elif defined(CONFIG_ETRAX_KGDB_PORT1)
83 &ports[1];
84 #elif defined(CONFIG_ETRAX_KGDB_PORT2)
85 &ports[2];
86 #elif defined(CONFIG_ETRAX_KGDB_PORT3)
87 &ports[3];
88 #else
89 NULL;
90 #endif
91 #endif
93 #ifdef CONFIG_ETRAXFS_SIM
94 extern void print_str( const char *str );
95 static char buffer[1024];
96 static char msg[] = "Debug: ";
97 static int buffer_pos = sizeof(msg) - 1;
98 #endif
100 extern struct tty_driver *serial_driver;
102 static void
103 start_port(struct dbg_port* p)
105 if (!p)
106 return;
108 if (p->started)
109 return;
110 p->started = 1;
112 if (p->nbr == 1)
113 crisv32_pinmux_alloc_fixed(pinmux_ser1);
114 else if (p->nbr == 2)
115 crisv32_pinmux_alloc_fixed(pinmux_ser2);
116 else if (p->nbr == 3)
117 crisv32_pinmux_alloc_fixed(pinmux_ser3);
119 /* Set up serial port registers */
120 reg_ser_rw_tr_ctrl tr_ctrl = {0};
121 reg_ser_rw_tr_dma_en tr_dma_en = {0};
123 reg_ser_rw_rec_ctrl rec_ctrl = {0};
124 reg_ser_rw_tr_baud_div tr_baud_div = {0};
125 reg_ser_rw_rec_baud_div rec_baud_div = {0};
127 tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493;
128 tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no;
129 tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8;
130 tr_ctrl.en = rec_ctrl.en = 1;
132 if (p->parity == 'O')
134 tr_ctrl.par_en = regk_ser_yes;
135 tr_ctrl.par = regk_ser_odd;
136 rec_ctrl.par_en = regk_ser_yes;
137 rec_ctrl.par = regk_ser_odd;
139 else if (p->parity == 'E')
141 tr_ctrl.par_en = regk_ser_yes;
142 tr_ctrl.par = regk_ser_even;
143 rec_ctrl.par_en = regk_ser_yes;
144 rec_ctrl.par = regk_ser_odd;
147 if (p->bits == 7)
149 tr_ctrl.data_bits = regk_ser_bits7;
150 rec_ctrl.data_bits = regk_ser_bits7;
153 REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div);
154 REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div);
155 REG_WR (ser, p->instance, rw_tr_dma_en, tr_dma_en);
156 REG_WR (ser, p->instance, rw_tr_ctrl, tr_ctrl);
157 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);
160 /* No debug */
161 #ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
163 static void
164 console_write(struct console *co, const char *buf, unsigned int len)
166 return;
169 /* Target debug */
170 #elif !defined(CONFIG_ETRAXFS_SIM)
172 static void
173 console_write_direct(struct console *co, const char *buf, unsigned int len)
175 int i;
176 reg_ser_r_stat_din stat;
177 reg_ser_rw_tr_dma_en tr_dma_en, old;
179 /* Switch to manual mode */
180 tr_dma_en = old = REG_RD (ser, port->instance, rw_tr_dma_en);
181 if (tr_dma_en.en == regk_ser_yes) {
182 tr_dma_en.en = regk_ser_no;
183 REG_WR(ser, port->instance, rw_tr_dma_en, tr_dma_en);
186 /* Send data */
187 for (i = 0; i < len; i++) {
188 /* LF -> CRLF */
189 if (buf[i] == '\n') {
190 do {
191 stat = REG_RD (ser, port->instance, r_stat_din);
192 } while (!stat.tr_rdy);
193 REG_WR_INT (ser, port->instance, rw_dout, '\r');
195 /* Wait until transmitter is ready and send.*/
196 do {
197 stat = REG_RD (ser, port->instance, r_stat_din);
198 } while (!stat.tr_rdy);
199 REG_WR_INT (ser, port->instance, rw_dout, buf[i]);
202 /* Restore mode */
203 if (tr_dma_en.en != old.en)
204 REG_WR(ser, port->instance, rw_tr_dma_en, old);
207 static void
208 console_write(struct console *co, const char *buf, unsigned int len)
210 if (!port)
211 return;
212 console_write_direct(co, buf, len);
217 #else
219 /* VCS debug */
221 static void
222 console_write(struct console *co, const char *buf, unsigned int len)
224 char* pos;
225 pos = memchr(buf, '\n', len);
226 if (pos) {
227 int l = ++pos - buf;
228 memcpy(buffer + buffer_pos, buf, l);
229 memcpy(buffer, msg, sizeof(msg) - 1);
230 buffer[buffer_pos + l] = '\0';
231 print_str(buffer);
232 buffer_pos = sizeof(msg) - 1;
233 if (pos - buf != len) {
234 memcpy(buffer + buffer_pos, pos, len - l);
235 buffer_pos += len - l;
237 } else {
238 memcpy(buffer + buffer_pos, buf, len);
239 buffer_pos += len;
243 #endif
245 int raw_printk(const char *fmt, ...)
247 static char buf[1024];
248 int printed_len;
249 va_list args;
250 va_start(args, fmt);
251 printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
252 va_end(args);
253 console_write(NULL, buf, strlen(buf));
254 return printed_len;
257 void
258 stupid_debug(char* buf)
260 console_write(NULL, buf, strlen(buf));
263 #ifdef CONFIG_ETRAX_KGDB
264 /* Use polling to get a single character from the kernel debug port */
266 getDebugChar(void)
268 reg_ser_rs_status_data stat;
269 reg_ser_rw_ack_intr ack_intr = { 0 };
271 do {
272 stat = REG_RD(ser, kgdb_instance, rs_status_data);
273 } while (!stat.data_avail);
275 /* Ack the data_avail interrupt. */
276 ack_intr.data_avail = 1;
277 REG_WR(ser, kgdb_instance, rw_ack_intr, ack_intr);
279 return stat.data;
282 /* Use polling to put a single character to the kernel debug port */
283 void
284 putDebugChar(int val)
286 reg_ser_r_status_data stat;
287 do {
288 stat = REG_RD (ser, kgdb_instance, r_status_data);
289 } while (!stat.tr_ready);
290 REG_WR (ser, kgdb_instance, rw_data_out, REG_TYPE_CONV(reg_ser_rw_data_out, int, val));
292 #endif /* CONFIG_ETRAX_KGDB */
294 static int __init
295 console_setup(struct console *co, char *options)
297 char* s;
299 if (options) {
300 port = &ports[co->index];
301 port->baudrate = 115200;
302 port->parity = 'N';
303 port->bits = 8;
304 port->baudrate = simple_strtoul(options, NULL, 10);
305 s = options;
306 while(*s >= '0' && *s <= '9')
307 s++;
308 if (*s) port->parity = *s++;
309 if (*s) port->bits = *s++ - '0';
310 port->started = 0;
311 start_port(port);
313 return 0;
316 /* This is a dummy serial device that throws away anything written to it.
317 * This is used when no debug output is wanted.
319 static struct tty_driver dummy_driver;
321 static int dummy_open(struct tty_struct *tty, struct file * filp)
323 return 0;
326 static void dummy_close(struct tty_struct *tty, struct file * filp)
330 static int dummy_write(struct tty_struct * tty,
331 const unsigned char *buf, int count)
333 return count;
336 static int
337 dummy_write_room(struct tty_struct *tty)
339 return 8192;
342 void __init
343 init_dummy_console(void)
345 memset(&dummy_driver, 0, sizeof(struct tty_driver));
346 dummy_driver.driver_name = "serial";
347 dummy_driver.name = "ttyS";
348 dummy_driver.major = TTY_MAJOR;
349 dummy_driver.minor_start = 68;
350 dummy_driver.num = 1; /* etrax100 has 4 serial ports */
351 dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
352 dummy_driver.subtype = SERIAL_TYPE_NORMAL;
353 dummy_driver.init_termios = tty_std_termios;
354 dummy_driver.init_termios.c_cflag =
355 B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
356 dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
358 dummy_driver.open = dummy_open;
359 dummy_driver.close = dummy_close;
360 dummy_driver.write = dummy_write;
361 dummy_driver.write_room = dummy_write_room;
362 if (tty_register_driver(&dummy_driver))
363 panic("Couldn't register dummy serial driver\n");
366 static struct tty_driver*
367 crisv32_console_device(struct console* co, int *index)
369 if (port)
370 *index = port->nbr;
371 return port ? serial_driver : &dummy_driver;
374 static struct console sercons = {
375 name : "ttyS",
376 write: console_write,
377 read : NULL,
378 device : crisv32_console_device,
379 unblank : NULL,
380 setup : console_setup,
381 flags : CON_PRINTBUFFER,
382 index : -1,
383 cflag : 0,
384 next : NULL
386 static struct console sercons0 = {
387 name : "ttyS",
388 write: console_write,
389 read : NULL,
390 device : crisv32_console_device,
391 unblank : NULL,
392 setup : console_setup,
393 flags : CON_PRINTBUFFER,
394 index : 0,
395 cflag : 0,
396 next : NULL
399 static struct console sercons1 = {
400 name : "ttyS",
401 write: console_write,
402 read : NULL,
403 device : crisv32_console_device,
404 unblank : NULL,
405 setup : console_setup,
406 flags : CON_PRINTBUFFER,
407 index : 1,
408 cflag : 0,
409 next : NULL
411 static struct console sercons2 = {
412 name : "ttyS",
413 write: console_write,
414 read : NULL,
415 device : crisv32_console_device,
416 unblank : NULL,
417 setup : console_setup,
418 flags : CON_PRINTBUFFER,
419 index : 2,
420 cflag : 0,
421 next : NULL
423 static struct console sercons3 = {
424 name : "ttyS",
425 write: console_write,
426 read : NULL,
427 device : crisv32_console_device,
428 unblank : NULL,
429 setup : console_setup,
430 flags : CON_PRINTBUFFER,
431 index : 3,
432 cflag : 0,
433 next : NULL
436 /* Register console for printk's, etc. */
437 int __init
438 init_etrax_debug(void)
440 static int first = 1;
442 if (!first) {
443 unregister_console(&sercons);
444 register_console(&sercons0);
445 register_console(&sercons1);
446 register_console(&sercons2);
447 register_console(&sercons3);
448 init_dummy_console();
449 return 0;
451 first = 0;
452 register_console(&sercons);
453 start_port(port);
455 #ifdef CONFIG_ETRAX_KGDB
456 start_port(kgdb_port);
457 #endif /* CONFIG_ETRAX_KGDB */
458 return 0;
461 __initcall(init_etrax_debug);