Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / arch / cris / arch-v32 / kernel / debugport.c
1 /*
2  * Copyright (C) 2003, Axis Communications AB.
3  */
4
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>
15
16 #include <asm/irq.h>
17 #include <asm/arch/hwregs/intr_vect_defs.h>
18
19 struct dbg_port
20 {
21         unsigned char nbr;
22         unsigned long instance;
23         unsigned int started;
24         unsigned long baudrate;
25         unsigned char parity;
26         unsigned int bits;
27 };
28
29 struct dbg_port ports[] =
30 {
31   {
32     0,
33     regi_ser0,
34     0,
35     115200,
36     'N',
37     8
38   },
39   {
40     1,
41     regi_ser1,
42     0,
43     115200,
44     'N',
45     8
46   },
47   {
48     2,
49     regi_ser2,
50     0,
51     115200,
52     'N',
53     8
54   },
55   {
56     3,
57     regi_ser3,
58     0,
59     115200,
60     'N',
61     8
62   }
63 };
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
76
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
91
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
98
99 extern struct tty_driver *serial_driver;
100
101 static void
102 start_port(struct dbg_port* p)
103 {
104         if (!p)
105                 return;
106
107         if (p->started)
108                 return;
109         p->started = 1;
110
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);
117
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};
121
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};
125
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;
130
131         if (p->parity == 'O')
132         {
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;
137         }
138         else if (p->parity == 'E')
139         {
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;
144         }
145
146         if (p->bits == 7)
147         {
148                 tr_ctrl.data_bits = regk_ser_bits7;
149                 rec_ctrl.data_bits = regk_ser_bits7;
150         }
151
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);
157 }
158
159 /* No debug */
160 #ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
161
162 static void
163 console_write(struct console *co, const char *buf, unsigned int len)
164 {
165         return;
166 }
167
168 /* Target debug */
169 #elif !defined(CONFIG_ETRAXFS_SIM)
170
171 static void
172 console_write_direct(struct console *co, const char *buf, unsigned int len)
173 {
174         int i;
175         reg_ser_r_stat_din stat;
176         reg_ser_rw_tr_dma_en tr_dma_en, old;
177
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);
183         }
184
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');
193                 }
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]);
199         }
200
201         /* Restore mode */
202         if (tr_dma_en.en != old.en)
203                 REG_WR(ser, port->instance, rw_tr_dma_en, old);
204 }
205
206 static void
207 console_write(struct console *co, const char *buf, unsigned int len)
208 {
209         if (!port)
210                 return;
211         console_write_direct(co, buf, len);
212 }
213
214
215
216 #else
217
218 /* VCS debug */
219
220 static void
221 console_write(struct console *co, const char *buf, unsigned int len)
222 {
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;
235                 }
236         } else {
237                 memcpy(buffer + buffer_pos, buf, len);
238                 buffer_pos += len;
239         }
240 }
241
242 #endif
243
244 int raw_printk(const char *fmt, ...)
245 {
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;
254 }
255
256 void
257 stupid_debug(char* buf)
258 {
259   console_write(NULL, buf, strlen(buf));
260 }
261
262 #ifdef CONFIG_ETRAX_KGDB
263 /* Use polling to get a single character from the kernel debug port */
264 int
265 getDebugChar(void)
266 {
267         reg_ser_rs_status_data stat;
268         reg_ser_rw_ack_intr ack_intr = { 0 };
269
270         do {
271                 stat = REG_RD(ser, kgdb_instance, rs_status_data);
272         } while (!stat.data_avail);
273
274         /* Ack the data_avail interrupt. */
275         ack_intr.data_avail = 1;
276         REG_WR(ser, kgdb_instance, rw_ack_intr, ack_intr);
277
278         return stat.data;
279 }
280
281 /* Use polling to put a single character to the kernel debug port */
282 void
283 putDebugChar(int val)
284 {
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));
290 }
291 #endif /* CONFIG_ETRAX_KGDB */
292
293 static int __init
294 console_setup(struct console *co, char *options)
295 {
296         char* s;
297
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);
311         }
312         return 0;
313 }
314
315 /* This is a dummy serial device that throws away anything written to it.
316  * This is used when no debug output is wanted.
317  */
318 static struct tty_driver dummy_driver;
319
320 static int dummy_open(struct tty_struct *tty, struct file * filp)
321 {
322         return 0;
323 }
324
325 static void dummy_close(struct tty_struct *tty, struct file * filp)
326 {
327 }
328
329 static int dummy_write(struct tty_struct * tty,
330                        const unsigned char *buf, int count)
331 {
332         return count;
333 }
334
335 static int
336 dummy_write_room(struct tty_struct *tty)
337 {
338         return 8192;
339 }
340
341 void __init
342 init_dummy_console(void)
343 {
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;
356
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");
363 }
364
365 static struct tty_driver*
366 crisv32_console_device(struct console* co, int *index)
367 {
368         if (port)
369                 *index = port->nbr;
370         return port ? serial_driver : &dummy_driver;
371 }
372
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
384 };
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
396 };
397
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
409 };
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
421 };
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
433 };
434
435 /* Register console for printk's, etc. */
436 int __init
437 init_etrax_debug(void)
438 {
439         static int first = 1;
440
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;
449         }
450         first = 0;
451         register_console(&sercons);
452         start_port(port);
453
454 #ifdef CONFIG_ETRAX_KGDB
455         start_port(kgdb_port);
456 #endif /* CONFIG_ETRAX_KGDB */
457         return 0;
458 }
459
460 __initcall(init_etrax_debug);