• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/cris/arch-v10/kernel/
1/* Serialport functions for debugging
2 *
3 * Copyright (c) 2000-2007 Axis Communications AB
4 *
5 * Authors:  Bjorn Wesen
6 *
7 * Exports:
8 *    console_print_etrax(char *buf)
9 *    int getDebugChar()
10 *    putDebugChar(int)
11 *    enableDebugIRQ()
12 *    init_etrax_debug()
13 *
14 */
15
16#include <linux/console.h>
17#include <linux/init.h>
18#include <linux/major.h>
19#include <linux/delay.h>
20#include <linux/tty.h>
21#include <asm/system.h>
22#include <arch/svinto.h>
23#include <asm/io.h>             /* Get SIMCOUT. */
24
25extern void reset_watchdog(void);
26
27struct dbg_port
28{
29  unsigned int index;
30  const volatile unsigned* read;
31  volatile char* write;
32  volatile unsigned* xoff;
33  volatile char* baud;
34  volatile char* tr_ctrl;
35  volatile char* rec_ctrl;
36  unsigned long irq;
37  unsigned int started;
38  unsigned long baudrate;
39  unsigned char parity;
40  unsigned int bits;
41};
42
43struct dbg_port ports[]=
44{
45  {
46    0,
47    R_SERIAL0_READ,
48    R_SERIAL0_TR_DATA,
49    R_SERIAL0_XOFF,
50    R_SERIAL0_BAUD,
51    R_SERIAL0_TR_CTRL,
52    R_SERIAL0_REC_CTRL,
53    IO_STATE(R_IRQ_MASK1_SET, ser0_data, set),
54    0,
55    115200,
56    'N',
57    8
58  },
59  {
60    1,
61    R_SERIAL1_READ,
62    R_SERIAL1_TR_DATA,
63    R_SERIAL1_XOFF,
64    R_SERIAL1_BAUD,
65    R_SERIAL1_TR_CTRL,
66    R_SERIAL1_REC_CTRL,
67    IO_STATE(R_IRQ_MASK1_SET, ser1_data, set),
68    0,
69    115200,
70    'N',
71    8
72  },
73  {
74    2,
75    R_SERIAL2_READ,
76    R_SERIAL2_TR_DATA,
77    R_SERIAL2_XOFF,
78    R_SERIAL2_BAUD,
79    R_SERIAL2_TR_CTRL,
80    R_SERIAL2_REC_CTRL,
81    IO_STATE(R_IRQ_MASK1_SET, ser2_data, set),
82    0,
83    115200,
84    'N',
85    8
86  },
87  {
88    3,
89    R_SERIAL3_READ,
90    R_SERIAL3_TR_DATA,
91    R_SERIAL3_XOFF,
92    R_SERIAL3_BAUD,
93    R_SERIAL3_TR_CTRL,
94    R_SERIAL3_REC_CTRL,
95    IO_STATE(R_IRQ_MASK1_SET, ser3_data, set),
96    0,
97    115200,
98    'N',
99    8
100  }
101};
102
103#ifdef CONFIG_ETRAX_SERIAL
104extern struct tty_driver *serial_driver;
105#endif
106
107struct dbg_port* port =
108#if defined(CONFIG_ETRAX_DEBUG_PORT0)
109  &ports[0];
110#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
111  &ports[1];
112#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
113  &ports[2];
114#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
115  &ports[3];
116#else
117  NULL;
118#endif
119
120static struct dbg_port* kgdb_port =
121#if defined(CONFIG_ETRAX_KGDB_PORT0)
122  &ports[0];
123#elif defined(CONFIG_ETRAX_KGDB_PORT1)
124  &ports[1];
125#elif defined(CONFIG_ETRAX_KGDB_PORT2)
126  &ports[2];
127#elif defined(CONFIG_ETRAX_KGDB_PORT3)
128  &ports[3];
129#else
130  NULL;
131#endif
132
133static void
134start_port(struct dbg_port* p)
135{
136	unsigned long rec_ctrl = 0;
137	unsigned long tr_ctrl = 0;
138
139	if (!p)
140		return;
141
142	if (p->started)
143		return;
144	p->started = 1;
145
146	if (p->index == 0)
147	{
148		genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6);
149		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused);
150	}
151	else if (p->index == 1)
152	{
153		genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8);
154		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb);
155	}
156	else if (p->index == 2)
157	{
158		genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2);
159		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0);
160		genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3);
161		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, par0);
162		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, ser2, select);
163	}
164	else
165	{
166		genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4);
167		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1);
168		genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5);
169		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, par1);
170		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, ser3, select);
171	}
172
173	*R_GEN_CONFIG = genconfig_shadow;
174
175	*p->xoff =
176		IO_STATE(R_SERIAL0_XOFF, tx_stop, enable) |
177		IO_STATE(R_SERIAL0_XOFF, auto_xoff, disable) |
178		IO_FIELD(R_SERIAL0_XOFF, xoff_char, 0);
179
180	switch (p->baudrate)
181	{
182	case 0:
183	case 115200:
184		*p->baud =
185		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) |
186		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz);
187		break;
188	case 1200:
189		*p->baud =
190		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c1200Hz) |
191		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c1200Hz);
192		break;
193	case 2400:
194		*p->baud =
195		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c2400Hz) |
196		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c2400Hz);
197		break;
198	case 4800:
199		*p->baud =
200		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c4800Hz) |
201		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c4800Hz);
202		break;
203	case 9600:
204		*p->baud =
205		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c9600Hz) |
206		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c9600Hz);
207		  break;
208	case 19200:
209		*p->baud =
210		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c19k2Hz) |
211		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c19k2Hz);
212		 break;
213	case 38400:
214		*p->baud =
215		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c38k4Hz) |
216		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c38k4Hz);
217		break;
218	case 57600:
219		*p->baud =
220		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c57k6Hz) |
221		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c57k6Hz);
222		break;
223	default:
224		*p->baud =
225		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) |
226		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz);
227		  break;
228        }
229
230	if (p->parity == 'E') {
231		rec_ctrl =
232		  IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) |
233		  IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
234		tr_ctrl =
235		  IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) |
236		  IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable);
237	} else if (p->parity == 'O') {
238		rec_ctrl =
239		  IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd) |
240		  IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
241		tr_ctrl =
242		  IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd) |
243		  IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable);
244	} else {
245		rec_ctrl =
246		  IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) |
247		  IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, disable);
248		tr_ctrl =
249		  IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) |
250		  IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, disable);
251	}
252	if (p->bits == 7)
253	{
254		rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit);
255		tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit);
256	}
257	else
258	{
259		rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_8bit);
260		tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit);
261	}
262
263	*p->rec_ctrl =
264		IO_STATE(R_SERIAL0_REC_CTRL, dma_err, stop) |
265		IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable) |
266		IO_STATE(R_SERIAL0_REC_CTRL, rts_, active) |
267		IO_STATE(R_SERIAL0_REC_CTRL, sampling, middle) |
268		IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, normal) |
269		rec_ctrl;
270
271	*p->tr_ctrl =
272		IO_FIELD(R_SERIAL0_TR_CTRL, txd, 0) |
273		IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable) |
274		IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, disabled) |
275		IO_STATE(R_SERIAL0_TR_CTRL, stop_bits, one_bit) |
276		IO_STATE(R_SERIAL0_TR_CTRL, tr_stick_par, normal) |
277		tr_ctrl;
278}
279
280static void
281console_write_direct(struct console *co, const char *buf, unsigned int len)
282{
283	int i;
284	unsigned long flags;
285
286        if (!port)
287		return;
288
289	local_irq_save(flags);
290
291	/* Send data */
292	for (i = 0; i < len; i++) {
293		/* LF -> CRLF */
294		if (buf[i] == '\n') {
295			while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
296			;
297			*port->write = '\r';
298		}
299		/* Wait until transmitter is ready and send.*/
300		while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
301			;
302		*port->write = buf[i];
303	}
304
305	/*
306	 * Feed the watchdog, otherwise it will reset the chip during boot.
307	 * The time to send an ordinary boot message line (10-90 chars)
308	 * varies between 1-8ms at 115200. What makes up for the additional
309	 * 90ms that allows the watchdog to bite?
310	*/
311	reset_watchdog();
312
313	local_irq_restore(flags);
314}
315
316static void
317console_write(struct console *co, const char *buf, unsigned int len)
318{
319	if (!port)
320		return;
321
322#ifdef CONFIG_SVINTO_SIM
323	/* no use to simulate the serial debug output */
324	SIMCOUT(buf, len);
325	return;
326#endif
327
328        console_write_direct(co, buf, len);
329}
330
331/* legacy function */
332
333void
334console_print_etrax(const char *buf)
335{
336	console_write(NULL, buf, strlen(buf));
337}
338
339/* Use polling to get a single character FROM the debug port */
340
341int
342getDebugChar(void)
343{
344	unsigned long readval;
345
346	if (!kgdb_port)
347		return 0;
348
349	do {
350		readval = *kgdb_port->read;
351	} while (!(readval & IO_MASK(R_SERIAL0_READ, data_avail)));
352
353	return (readval & IO_MASK(R_SERIAL0_READ, data_in));
354}
355
356/* Use polling to put a single character to the debug port */
357
358void
359putDebugChar(int val)
360{
361	if (!kgdb_port)
362		return;
363
364	while (!(*kgdb_port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
365		;
366	*kgdb_port->write = val;
367}
368
369/* Enable irq for receiving chars on the debug port, used by kgdb */
370
371void
372enableDebugIRQ(void)
373{
374	if (!kgdb_port)
375		return;
376
377	*R_IRQ_MASK1_SET = kgdb_port->irq;
378	/* use R_VECT_MASK directly, since we really bypass Linux normal
379	 * IRQ handling in kgdb anyway, we don't need to use enable_irq
380	 */
381	*R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);
382
383	*kgdb_port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
384}
385
386static int __init
387console_setup(struct console *co, char *options)
388{
389	char* s;
390
391	if (options) {
392		port = &ports[co->index];
393		port->baudrate = 115200;
394                port->parity = 'N';
395                port->bits = 8;
396		port->baudrate = simple_strtoul(options, NULL, 10);
397		s = options;
398		while(*s >= '0' && *s <= '9')
399			s++;
400		if (*s) port->parity = *s++;
401		if (*s) port->bits   = *s++ - '0';
402		port->started = 0;
403		start_port(0);
404	}
405	return 0;
406}
407
408
409/* This is a dummy serial device that throws away anything written to it.
410 * This is used when no debug output is wanted.
411 */
412static struct tty_driver dummy_driver;
413
414static int dummy_open(struct tty_struct *tty, struct file * filp)
415{
416	return 0;
417}
418
419static void dummy_close(struct tty_struct *tty, struct file * filp)
420{
421}
422
423static int dummy_write(struct tty_struct * tty,
424                       const unsigned char *buf, int count)
425{
426	return count;
427}
428
429static int dummy_write_room(struct tty_struct *tty)
430{
431	return 8192;
432}
433
434static const struct tty_operations dummy_ops = {
435	.open = dummy_open,
436	.close = dummy_close,
437	.write = dummy_write,
438	.write_room = dummy_write_room,
439};
440
441void __init
442init_dummy_console(void)
443{
444	memset(&dummy_driver, 0, sizeof(struct tty_driver));
445	dummy_driver.driver_name = "serial";
446	dummy_driver.name = "ttyS";
447	dummy_driver.major = TTY_MAJOR;
448	dummy_driver.minor_start = 68;
449	dummy_driver.num = 1;       /* etrax100 has 4 serial ports */
450	dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
451	dummy_driver.subtype = SERIAL_TYPE_NORMAL;
452	dummy_driver.init_termios = tty_std_termios;
453	/* Normally B9600 default... */
454	dummy_driver.init_termios.c_cflag =
455		B115200 | CS8 | CREAD | HUPCL | CLOCAL;
456	dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
457	dummy_driver.init_termios.c_ispeed = 115200;
458	dummy_driver.init_termios.c_ospeed = 115200;
459
460	dummy_driver.ops = &dummy_ops;
461	if (tty_register_driver(&dummy_driver))
462		panic("Couldn't register dummy serial driver\n");
463}
464
465static struct tty_driver*
466etrax_console_device(struct console* co, int *index)
467{
468	if (port)
469		*index = port->index;
470	else
471		*index = 0;
472#ifdef CONFIG_ETRAX_SERIAL
473        return port ? serial_driver : &dummy_driver;
474#else
475	return &dummy_driver;
476#endif
477}
478
479static struct console sercons = {
480	name : "ttyS",
481	write: console_write,
482	read : NULL,
483	device : etrax_console_device,
484	unblank : NULL,
485	setup : console_setup,
486	flags : CON_PRINTBUFFER,
487	index : -1,
488	cflag : 0,
489	next : NULL
490};
491static struct console sercons0 = {
492	name : "ttyS",
493	write: console_write,
494	read : NULL,
495	device : etrax_console_device,
496	unblank : NULL,
497	setup : console_setup,
498	flags : CON_PRINTBUFFER,
499	index : 0,
500	cflag : 0,
501	next : NULL
502};
503
504static struct console sercons1 = {
505	name : "ttyS",
506	write: console_write,
507	read : NULL,
508	device : etrax_console_device,
509	unblank : NULL,
510	setup : console_setup,
511	flags : CON_PRINTBUFFER,
512	index : 1,
513	cflag : 0,
514	next : NULL
515};
516static struct console sercons2 = {
517	name : "ttyS",
518	write: console_write,
519	read : NULL,
520	device : etrax_console_device,
521	unblank : NULL,
522	setup : console_setup,
523	flags : CON_PRINTBUFFER,
524	index : 2,
525	cflag : 0,
526	next : NULL
527};
528static struct console sercons3 = {
529	name : "ttyS",
530	write: console_write,
531	read : NULL,
532	device : etrax_console_device,
533	unblank : NULL,
534	setup : console_setup,
535	flags : CON_PRINTBUFFER,
536	index : 3,
537	cflag : 0,
538	next : NULL
539};
540/*
541 *      Register console (for printk's etc)
542 */
543
544int __init
545init_etrax_debug(void)
546{
547	static int first = 1;
548
549	if (!first) {
550		unregister_console(&sercons);
551		register_console(&sercons0);
552		register_console(&sercons1);
553		register_console(&sercons2);
554		register_console(&sercons3);
555                init_dummy_console();
556		return 0;
557	}
558
559	first = 0;
560	register_console(&sercons);
561	start_port(port);
562#ifdef CONFIG_ETRAX_KGDB
563	start_port(kgdb_port);
564#endif
565	return 0;
566}
567__initcall(init_etrax_debug);
568