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