aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/cris/arch-v32/kernel/debugport.c342
1 files changed, 43 insertions, 299 deletions
diff --git a/arch/cris/arch-v32/kernel/debugport.c b/arch/cris/arch-v32/kernel/debugport.c
index d1272ad92153..15af4c293157 100644
--- a/arch/cris/arch-v32/kernel/debugport.c
+++ b/arch/cris/arch-v32/kernel/debugport.c
@@ -4,17 +4,12 @@
4 4
5#include <linux/console.h> 5#include <linux/console.h>
6#include <linux/init.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> 7#include <asm/system.h>
11#include <asm/io.h> 8#include <hwregs/reg_rdwr.h>
12#include <asm/arch/hwregs/ser_defs.h> 9#include <hwregs/reg_map.h>
13#include <asm/arch/hwregs/dma_defs.h> 10#include <hwregs/ser_defs.h>
14#include <asm/arch/pinmux.h> 11#include <hwregs/dma_defs.h>
15 12#include <asm/arch/mach/pinmux.h>
16#include <asm/irq.h>
17#include <asm/arch/hwregs/intr_vect_defs.h>
18 13
19struct dbg_port 14struct dbg_port
20{ 15{
@@ -59,45 +54,50 @@ struct dbg_port ports[] =
59 115200, 54 115200,
60 'N', 55 'N',
61 8 56 8
62 } 57 },
58#if CONFIG_ETRAX_SERIAL_PORTS == 5
59 {
60 4,
61 regi_ser4,
62 0,
63 115200,
64 'N',
65 8
66 },
67#endif
63}; 68};
64static struct dbg_port *port = 69static struct dbg_port *port =
65#if defined(CONFIG_ETRAX_DEBUG_PORT0) 70#if defined(CONFIG_ETRAX_DEBUG_PORT0)
66&ports[0]; 71 &ports[0];
67#elif defined(CONFIG_ETRAX_DEBUG_PORT1) 72#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
68&ports[1]; 73 &ports[1];
69#elif defined(CONFIG_ETRAX_DEBUG_PORT2) 74#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
70&ports[2]; 75 &ports[2];
71#elif defined(CONFIG_ETRAX_DEBUG_PORT3) 76#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
72&ports[3]; 77 &ports[3];
78#elif defined(CONFIG_ETRAX_DEBUG_PORT4)
79 &ports[4];
73#else 80#else
74NULL; 81 NULL;
75#endif 82#endif
76 83
77#ifdef CONFIG_ETRAX_KGDB 84#ifdef CONFIG_ETRAX_KGDB
78static struct dbg_port *kgdb_port = 85static struct dbg_port *kgdb_port =
79#if defined(CONFIG_ETRAX_KGDB_PORT0) 86#if defined(CONFIG_ETRAX_KGDB_PORT0)
80&ports[0]; 87 &ports[0];
81#elif defined(CONFIG_ETRAX_KGDB_PORT1) 88#elif defined(CONFIG_ETRAX_KGDB_PORT1)
82&ports[1]; 89 &ports[1];
83#elif defined(CONFIG_ETRAX_KGDB_PORT2) 90#elif defined(CONFIG_ETRAX_KGDB_PORT2)
84&ports[2]; 91 &ports[2];
85#elif defined(CONFIG_ETRAX_KGDB_PORT3) 92#elif defined(CONFIG_ETRAX_KGDB_PORT3)
86&ports[3]; 93 &ports[3];
94#elif defined(CONFIG_ETRAX_KGDB_PORT4)
95 &ports[4];
87#else 96#else
88NULL; 97 NULL;
89#endif 98#endif
90#endif 99#endif
91 100
92#ifdef CONFIG_ETRAXFS_SIM
93extern void print_str( const char *str );
94static char buffer[1024];
95static char msg[] = "Debug: ";
96static int buffer_pos = sizeof(msg) - 1;
97#endif
98
99extern struct tty_driver *serial_driver;
100
101static void 101static void
102start_port(struct dbg_port* p) 102start_port(struct dbg_port* p)
103{ 103{
@@ -114,6 +114,10 @@ start_port(struct dbg_port* p)
114 crisv32_pinmux_alloc_fixed(pinmux_ser2); 114 crisv32_pinmux_alloc_fixed(pinmux_ser2);
115 else if (p->nbr == 3) 115 else if (p->nbr == 3)
116 crisv32_pinmux_alloc_fixed(pinmux_ser3); 116 crisv32_pinmux_alloc_fixed(pinmux_ser3);
117#if CONFIG_ETRAX_SERIAL_PORTS == 5
118 else if (p->nbr == 4)
119 crisv32_pinmux_alloc_fixed(pinmux_ser4);
120#endif
117 121
118 /* Set up serial port registers */ 122 /* Set up serial port registers */
119 reg_ser_rw_tr_ctrl tr_ctrl = {0}; 123 reg_ser_rw_tr_ctrl tr_ctrl = {0};
@@ -156,124 +160,21 @@ start_port(struct dbg_port* p)
156 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl); 160 REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);
157} 161}
158 162
159/* No debug */
160#ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
161
162static void
163console_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
171static void
172console_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
206static void
207console_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
220static void
221console_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
244int 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
256void
257stupid_debug(char* buf)
258{
259 console_write(NULL, buf, strlen(buf));
260}
261
262#ifdef CONFIG_ETRAX_KGDB 163#ifdef CONFIG_ETRAX_KGDB
263/* Use polling to get a single character from the kernel debug port */ 164/* Use polling to get a single character from the kernel debug port */
264int 165int
265getDebugChar(void) 166getDebugChar(void)
266{ 167{
267 reg_ser_rs_status_data stat; 168 reg_ser_rs_stat_din stat;
268 reg_ser_rw_ack_intr ack_intr = { 0 }; 169 reg_ser_rw_ack_intr ack_intr = { 0 };
269 170
270 do { 171 do {
271 stat = REG_RD(ser, kgdb_instance, rs_status_data); 172 stat = REG_RD(ser, kgdb_port->instance, rs_stat_din);
272 } while (!stat.data_avail); 173 } while (!stat.dav);
273 174
274 /* Ack the data_avail interrupt. */ 175 /* Ack the data_avail interrupt. */
275 ack_intr.data_avail = 1; 176 ack_intr.dav = 1;
276 REG_WR(ser, kgdb_instance, rw_ack_intr, ack_intr); 177 REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr);
277 178
278 return stat.data; 179 return stat.data;
279} 180}
@@ -282,173 +183,18 @@ getDebugChar(void)
282void 183void
283putDebugChar(int val) 184putDebugChar(int val)
284{ 185{
285 reg_ser_r_status_data stat; 186 reg_ser_r_stat_din stat;
286 do { 187 do {
287 stat = REG_RD (ser, kgdb_instance, r_status_data); 188 stat = REG_RD(ser, kgdb_port->instance, r_stat_din);
288 } while (!stat.tr_ready); 189 } while (!stat.tr_rdy);
289 REG_WR (ser, kgdb_instance, rw_data_out, REG_TYPE_CONV(reg_ser_rw_data_out, int, val)); 190 REG_WR_INT(ser, kgdb_port->instance, rw_dout, val);
290} 191}
291#endif /* CONFIG_ETRAX_KGDB */ 192#endif /* CONFIG_ETRAX_KGDB */
292 193
293static int __init
294console_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 */
318static struct tty_driver dummy_driver;
319
320static int dummy_open(struct tty_struct *tty, struct file * filp)
321{
322 return 0;
323}
324
325static void dummy_close(struct tty_struct *tty, struct file * filp)
326{
327}
328
329static int dummy_write(struct tty_struct * tty,
330 const unsigned char *buf, int count)
331{
332 return count;
333}
334
335static int
336dummy_write_room(struct tty_struct *tty)
337{
338 return 8192;
339}
340
341void __init
342init_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
365static struct tty_driver*
366crisv32_console_device(struct console* co, int *index)
367{
368 if (port)
369 *index = port->nbr;
370 return port ? serial_driver : &dummy_driver;
371}
372
373static 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};
385static 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
398static 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};
410static 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};
422static 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. */ 194/* Register console for printk's, etc. */
436int __init 195int __init
437init_etrax_debug(void) 196init_etrax_debug(void)
438{ 197{
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); 198 start_port(port);
453 199
454#ifdef CONFIG_ETRAX_KGDB 200#ifdef CONFIG_ETRAX_KGDB
@@ -456,5 +202,3 @@ init_etrax_debug(void)
456#endif /* CONFIG_ETRAX_KGDB */ 202#endif /* CONFIG_ETRAX_KGDB */
457 return 0; 203 return 0;
458} 204}
459
460__initcall(init_etrax_debug);