diff options
Diffstat (limited to 'arch/cris')
-rw-r--r-- | arch/cris/arch-v10/kernel/debugport.c | 273 |
1 files changed, 196 insertions, 77 deletions
diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c index 6cf069e5e7b6..f3a85b77c17e 100644 --- a/arch/cris/arch-v10/kernel/debugport.c +++ b/arch/cris/arch-v10/kernel/debugport.c | |||
@@ -12,6 +12,31 @@ | |||
12 | * init_etrax_debug() | 12 | * init_etrax_debug() |
13 | * | 13 | * |
14 | * $Log: debugport.c,v $ | 14 | * $Log: debugport.c,v $ |
15 | * Revision 1.27 2005/06/10 10:34:14 starvik | ||
16 | * Real console support | ||
17 | * | ||
18 | * Revision 1.26 2005/06/07 07:06:07 starvik | ||
19 | * Added LF->CR translation to make ETRAX customers happy. | ||
20 | * | ||
21 | * Revision 1.25 2005/03/08 08:56:47 mikaelam | ||
22 | * Do only set index as port->index if port is defined, otherwise use the index from the command line | ||
23 | * | ||
24 | * Revision 1.24 2005/01/19 10:26:33 mikaelam | ||
25 | * Return the cris serial driver in console device driver callback function | ||
26 | * | ||
27 | * Revision 1.23 2005/01/14 10:12:17 starvik | ||
28 | * KGDB on separate port. | ||
29 | * Console fixes from 2.4. | ||
30 | * | ||
31 | * Revision 1.22 2005/01/11 16:06:13 starvik | ||
32 | * typo | ||
33 | * | ||
34 | * Revision 1.21 2005/01/11 13:49:14 starvik | ||
35 | * Added raw_printk to be used where we don't trust the console. | ||
36 | * | ||
37 | * Revision 1.20 2004/12/27 11:18:32 starvik | ||
38 | * Merge of Linux 2.6.10 (not functional yet). | ||
39 | * | ||
15 | * Revision 1.19 2004/10/21 07:26:16 starvik | 40 | * Revision 1.19 2004/10/21 07:26:16 starvik |
16 | * Made it possible to specify console settings on kernel command line. | 41 | * Made it possible to specify console settings on kernel command line. |
17 | * | 42 | * |
@@ -114,7 +139,11 @@ struct dbg_port ports[]= | |||
114 | R_SERIAL0_BAUD, | 139 | R_SERIAL0_BAUD, |
115 | R_SERIAL0_TR_CTRL, | 140 | R_SERIAL0_TR_CTRL, |
116 | R_SERIAL0_REC_CTRL, | 141 | R_SERIAL0_REC_CTRL, |
117 | IO_STATE(R_IRQ_MASK1_SET, ser0_data, set) | 142 | IO_STATE(R_IRQ_MASK1_SET, ser0_data, set), |
143 | 0, | ||
144 | 115200, | ||
145 | 'N', | ||
146 | 8 | ||
118 | }, | 147 | }, |
119 | { | 148 | { |
120 | 1, | 149 | 1, |
@@ -124,7 +153,11 @@ struct dbg_port ports[]= | |||
124 | R_SERIAL1_BAUD, | 153 | R_SERIAL1_BAUD, |
125 | R_SERIAL1_TR_CTRL, | 154 | R_SERIAL1_TR_CTRL, |
126 | R_SERIAL1_REC_CTRL, | 155 | R_SERIAL1_REC_CTRL, |
127 | IO_STATE(R_IRQ_MASK1_SET, ser1_data, set) | 156 | IO_STATE(R_IRQ_MASK1_SET, ser1_data, set), |
157 | 0, | ||
158 | 115200, | ||
159 | 'N', | ||
160 | 8 | ||
128 | }, | 161 | }, |
129 | { | 162 | { |
130 | 2, | 163 | 2, |
@@ -134,7 +167,11 @@ struct dbg_port ports[]= | |||
134 | R_SERIAL2_BAUD, | 167 | R_SERIAL2_BAUD, |
135 | R_SERIAL2_TR_CTRL, | 168 | R_SERIAL2_TR_CTRL, |
136 | R_SERIAL2_REC_CTRL, | 169 | R_SERIAL2_REC_CTRL, |
137 | IO_STATE(R_IRQ_MASK1_SET, ser2_data, set) | 170 | IO_STATE(R_IRQ_MASK1_SET, ser2_data, set), |
171 | 0, | ||
172 | 115200, | ||
173 | 'N', | ||
174 | 8 | ||
138 | }, | 175 | }, |
139 | { | 176 | { |
140 | 3, | 177 | 3, |
@@ -144,11 +181,15 @@ struct dbg_port ports[]= | |||
144 | R_SERIAL3_BAUD, | 181 | R_SERIAL3_BAUD, |
145 | R_SERIAL3_TR_CTRL, | 182 | R_SERIAL3_TR_CTRL, |
146 | R_SERIAL3_REC_CTRL, | 183 | R_SERIAL3_REC_CTRL, |
147 | IO_STATE(R_IRQ_MASK1_SET, ser3_data, set) | 184 | IO_STATE(R_IRQ_MASK1_SET, ser3_data, set), |
185 | 0, | ||
186 | 115200, | ||
187 | 'N', | ||
188 | 8 | ||
148 | } | 189 | } |
149 | }; | 190 | }; |
150 | 191 | ||
151 | static struct tty_driver *serial_driver; | 192 | extern struct tty_driver *serial_driver; |
152 | 193 | ||
153 | struct dbg_port* port = | 194 | struct dbg_port* port = |
154 | #if defined(CONFIG_ETRAX_DEBUG_PORT0) | 195 | #if defined(CONFIG_ETRAX_DEBUG_PORT0) |
@@ -162,37 +203,44 @@ struct dbg_port* port = | |||
162 | #else | 203 | #else |
163 | NULL; | 204 | NULL; |
164 | #endif | 205 | #endif |
165 | /* Used by serial.c to register a debug_write_function so that the normal | ||
166 | * serial driver is used for kernel debug output | ||
167 | */ | ||
168 | typedef int (*debugport_write_function)(int i, const char *buf, unsigned int len); | ||
169 | 206 | ||
170 | debugport_write_function debug_write_function = NULL; | 207 | static struct dbg_port* kgdb_port = |
208 | #if defined(CONFIG_ETRAX_KGDB_PORT0) | ||
209 | &ports[0]; | ||
210 | #elif defined(CONFIG_ETRAX_KGDB_PORT1) | ||
211 | &ports[1]; | ||
212 | #elif defined(CONFIG_ETRAX_KGDB_PORT2) | ||
213 | &ports[2]; | ||
214 | #elif defined(CONFIG_ETRAX_KGDB_PORT3) | ||
215 | &ports[3]; | ||
216 | #else | ||
217 | NULL; | ||
218 | #endif | ||
171 | 219 | ||
172 | static void | 220 | static void |
173 | start_port(void) | 221 | start_port(struct dbg_port* p) |
174 | { | 222 | { |
175 | unsigned long rec_ctrl = 0; | 223 | unsigned long rec_ctrl = 0; |
176 | unsigned long tr_ctrl = 0; | 224 | unsigned long tr_ctrl = 0; |
177 | 225 | ||
178 | if (!port) | 226 | if (!p) |
179 | return; | 227 | return; |
180 | 228 | ||
181 | if (port->started) | 229 | if (p->started) |
182 | return; | 230 | return; |
183 | port->started = 1; | 231 | p->started = 1; |
184 | 232 | ||
185 | if (port->index == 0) | 233 | if (p->index == 0) |
186 | { | 234 | { |
187 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); | 235 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); |
188 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused); | 236 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused); |
189 | } | 237 | } |
190 | else if (port->index == 1) | 238 | else if (p->index == 1) |
191 | { | 239 | { |
192 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8); | 240 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8); |
193 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb); | 241 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb); |
194 | } | 242 | } |
195 | else if (port->index == 2) | 243 | else if (p->index == 2) |
196 | { | 244 | { |
197 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2); | 245 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2); |
198 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0); | 246 | genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0); |
@@ -211,69 +259,69 @@ start_port(void) | |||
211 | 259 | ||
212 | *R_GEN_CONFIG = genconfig_shadow; | 260 | *R_GEN_CONFIG = genconfig_shadow; |
213 | 261 | ||
214 | *port->xoff = | 262 | *p->xoff = |
215 | IO_STATE(R_SERIAL0_XOFF, tx_stop, enable) | | 263 | IO_STATE(R_SERIAL0_XOFF, tx_stop, enable) | |
216 | IO_STATE(R_SERIAL0_XOFF, auto_xoff, disable) | | 264 | IO_STATE(R_SERIAL0_XOFF, auto_xoff, disable) | |
217 | IO_FIELD(R_SERIAL0_XOFF, xoff_char, 0); | 265 | IO_FIELD(R_SERIAL0_XOFF, xoff_char, 0); |
218 | 266 | ||
219 | switch (port->baudrate) | 267 | switch (p->baudrate) |
220 | { | 268 | { |
221 | case 0: | 269 | case 0: |
222 | case 115200: | 270 | case 115200: |
223 | *port->baud = | 271 | *p->baud = |
224 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) | | 272 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) | |
225 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz); | 273 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz); |
226 | break; | 274 | break; |
227 | case 1200: | 275 | case 1200: |
228 | *port->baud = | 276 | *p->baud = |
229 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c1200Hz) | | 277 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c1200Hz) | |
230 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c1200Hz); | 278 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c1200Hz); |
231 | break; | 279 | break; |
232 | case 2400: | 280 | case 2400: |
233 | *port->baud = | 281 | *p->baud = |
234 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c2400Hz) | | 282 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c2400Hz) | |
235 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c2400Hz); | 283 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c2400Hz); |
236 | break; | 284 | break; |
237 | case 4800: | 285 | case 4800: |
238 | *port->baud = | 286 | *p->baud = |
239 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c4800Hz) | | 287 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c4800Hz) | |
240 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c4800Hz); | 288 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c4800Hz); |
241 | break; | 289 | break; |
242 | case 9600: | 290 | case 9600: |
243 | *port->baud = | 291 | *p->baud = |
244 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c9600Hz) | | 292 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c9600Hz) | |
245 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c9600Hz); | 293 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c9600Hz); |
246 | break; | 294 | break; |
247 | case 19200: | 295 | case 19200: |
248 | *port->baud = | 296 | *p->baud = |
249 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c19k2Hz) | | 297 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c19k2Hz) | |
250 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c19k2Hz); | 298 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c19k2Hz); |
251 | break; | 299 | break; |
252 | case 38400: | 300 | case 38400: |
253 | *port->baud = | 301 | *p->baud = |
254 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c38k4Hz) | | 302 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c38k4Hz) | |
255 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c38k4Hz); | 303 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c38k4Hz); |
256 | break; | 304 | break; |
257 | case 57600: | 305 | case 57600: |
258 | *port->baud = | 306 | *p->baud = |
259 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c57k6Hz) | | 307 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c57k6Hz) | |
260 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c57k6Hz); | 308 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c57k6Hz); |
261 | break; | 309 | break; |
262 | default: | 310 | default: |
263 | *port->baud = | 311 | *p->baud = |
264 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) | | 312 | IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) | |
265 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz); | 313 | IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz); |
266 | break; | 314 | break; |
267 | } | 315 | } |
268 | 316 | ||
269 | if (port->parity == 'E') { | 317 | if (p->parity == 'E') { |
270 | rec_ctrl = | 318 | rec_ctrl = |
271 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) | | 319 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) | |
272 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable); | 320 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable); |
273 | tr_ctrl = | 321 | tr_ctrl = |
274 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) | | 322 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) | |
275 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable); | 323 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable); |
276 | } else if (port->parity == 'O') { | 324 | } else if (p->parity == 'O') { |
277 | rec_ctrl = | 325 | rec_ctrl = |
278 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd) | | 326 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd) | |
279 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable); | 327 | IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable); |
@@ -288,8 +336,7 @@ start_port(void) | |||
288 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) | | 336 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) | |
289 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, disable); | 337 | IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, disable); |
290 | } | 338 | } |
291 | 339 | if (p->bits == 7) | |
292 | if (port->bits == 7) | ||
293 | { | 340 | { |
294 | rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit); | 341 | rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit); |
295 | tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit); | 342 | tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit); |
@@ -300,7 +347,7 @@ start_port(void) | |||
300 | tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit); | 347 | tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit); |
301 | } | 348 | } |
302 | 349 | ||
303 | *port->rec_ctrl = | 350 | *p->rec_ctrl = |
304 | IO_STATE(R_SERIAL0_REC_CTRL, dma_err, stop) | | 351 | IO_STATE(R_SERIAL0_REC_CTRL, dma_err, stop) | |
305 | IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable) | | 352 | IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable) | |
306 | IO_STATE(R_SERIAL0_REC_CTRL, rts_, active) | | 353 | IO_STATE(R_SERIAL0_REC_CTRL, rts_, active) | |
@@ -308,7 +355,7 @@ start_port(void) | |||
308 | IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, normal) | | 355 | IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, normal) | |
309 | rec_ctrl; | 356 | rec_ctrl; |
310 | 357 | ||
311 | *port->tr_ctrl = | 358 | *p->tr_ctrl = |
312 | IO_FIELD(R_SERIAL0_TR_CTRL, txd, 0) | | 359 | IO_FIELD(R_SERIAL0_TR_CTRL, txd, 0) | |
313 | IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable) | | 360 | IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable) | |
314 | IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, disabled) | | 361 | IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, disabled) | |
@@ -323,8 +370,18 @@ console_write_direct(struct console *co, const char *buf, unsigned int len) | |||
323 | int i; | 370 | int i; |
324 | unsigned long flags; | 371 | unsigned long flags; |
325 | local_irq_save(flags); | 372 | local_irq_save(flags); |
373 | |||
374 | if (!port) | ||
375 | return; | ||
376 | |||
326 | /* Send data */ | 377 | /* Send data */ |
327 | for (i = 0; i < len; i++) { | 378 | for (i = 0; i < len; i++) { |
379 | /* LF -> CRLF */ | ||
380 | if (buf[i] == '\n') { | ||
381 | while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready))) | ||
382 | ; | ||
383 | *port->write = '\r'; | ||
384 | } | ||
328 | /* Wait until transmitter is ready and send.*/ | 385 | /* Wait until transmitter is ready and send.*/ |
329 | while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready))) | 386 | while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready))) |
330 | ; | 387 | ; |
@@ -333,6 +390,25 @@ console_write_direct(struct console *co, const char *buf, unsigned int len) | |||
333 | local_irq_restore(flags); | 390 | local_irq_restore(flags); |
334 | } | 391 | } |
335 | 392 | ||
393 | int raw_printk(const char *fmt, ...) | ||
394 | { | ||
395 | static char buf[1024]; | ||
396 | int printed_len; | ||
397 | static int first = 1; | ||
398 | if (first) { | ||
399 | /* Force reinitialization of the port to get manual mode. */ | ||
400 | port->started = 0; | ||
401 | start_port(port); | ||
402 | first = 0; | ||
403 | } | ||
404 | va_list args; | ||
405 | va_start(args, fmt); | ||
406 | printed_len = vsnprintf(buf, sizeof(buf), fmt, args); | ||
407 | va_end(args); | ||
408 | console_write_direct(NULL, buf, strlen(buf)); | ||
409 | return printed_len; | ||
410 | } | ||
411 | |||
336 | static void | 412 | static void |
337 | console_write(struct console *co, const char *buf, unsigned int len) | 413 | console_write(struct console *co, const char *buf, unsigned int len) |
338 | { | 414 | { |
@@ -345,18 +421,7 @@ console_write(struct console *co, const char *buf, unsigned int len) | |||
345 | return; | 421 | return; |
346 | #endif | 422 | #endif |
347 | 423 | ||
348 | start_port(); | 424 | console_write_direct(co, buf, len); |
349 | |||
350 | #ifdef CONFIG_ETRAX_KGDB | ||
351 | /* kgdb needs to output debug info using the gdb protocol */ | ||
352 | putDebugString(buf, len); | ||
353 | return; | ||
354 | #endif | ||
355 | |||
356 | if (debug_write_function) | ||
357 | debug_write_function(co->index, buf, len); | ||
358 | else | ||
359 | console_write_direct(co, buf, len); | ||
360 | } | 425 | } |
361 | 426 | ||
362 | /* legacy function */ | 427 | /* legacy function */ |
@@ -374,8 +439,11 @@ getDebugChar(void) | |||
374 | { | 439 | { |
375 | unsigned long readval; | 440 | unsigned long readval; |
376 | 441 | ||
442 | if (!kgdb_port) | ||
443 | return 0; | ||
444 | |||
377 | do { | 445 | do { |
378 | readval = *port->read; | 446 | readval = *kgdb_port->read; |
379 | } while (!(readval & IO_MASK(R_SERIAL0_READ, data_avail))); | 447 | } while (!(readval & IO_MASK(R_SERIAL0_READ, data_avail))); |
380 | 448 | ||
381 | return (readval & IO_MASK(R_SERIAL0_READ, data_in)); | 449 | return (readval & IO_MASK(R_SERIAL0_READ, data_in)); |
@@ -386,9 +454,12 @@ getDebugChar(void) | |||
386 | void | 454 | void |
387 | putDebugChar(int val) | 455 | putDebugChar(int val) |
388 | { | 456 | { |
389 | while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready))) | 457 | if (!kgdb_port) |
458 | return; | ||
459 | |||
460 | while (!(*kgdb_port->read & IO_MASK(R_SERIAL0_READ, tr_ready))) | ||
390 | ; | 461 | ; |
391 | *port->write = val; | 462 | *kgdb_port->write = val; |
392 | } | 463 | } |
393 | 464 | ||
394 | /* Enable irq for receiving chars on the debug port, used by kgdb */ | 465 | /* Enable irq for receiving chars on the debug port, used by kgdb */ |
@@ -396,19 +467,16 @@ putDebugChar(int val) | |||
396 | void | 467 | void |
397 | enableDebugIRQ(void) | 468 | enableDebugIRQ(void) |
398 | { | 469 | { |
399 | *R_IRQ_MASK1_SET = port->irq; | 470 | if (!kgdb_port) |
471 | return; | ||
472 | |||
473 | *R_IRQ_MASK1_SET = kgdb_port->irq; | ||
400 | /* use R_VECT_MASK directly, since we really bypass Linux normal | 474 | /* use R_VECT_MASK directly, since we really bypass Linux normal |
401 | * IRQ handling in kgdb anyway, we don't need to use enable_irq | 475 | * IRQ handling in kgdb anyway, we don't need to use enable_irq |
402 | */ | 476 | */ |
403 | *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set); | 477 | *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set); |
404 | 478 | ||
405 | *port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable); | 479 | *kgdb_port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable); |
406 | } | ||
407 | |||
408 | static struct tty_driver* | ||
409 | etrax_console_device(struct console* co, int *index) | ||
410 | { | ||
411 | return serial_driver; | ||
412 | } | 480 | } |
413 | 481 | ||
414 | static int __init | 482 | static int __init |
@@ -428,11 +496,69 @@ console_setup(struct console *co, char *options) | |||
428 | if (*s) port->parity = *s++; | 496 | if (*s) port->parity = *s++; |
429 | if (*s) port->bits = *s++ - '0'; | 497 | if (*s) port->bits = *s++ - '0'; |
430 | port->started = 0; | 498 | port->started = 0; |
431 | start_port(); | 499 | start_port(0); |
432 | } | 500 | } |
433 | return 0; | 501 | return 0; |
434 | } | 502 | } |
435 | 503 | ||
504 | /* This is a dummy serial device that throws away anything written to it. | ||
505 | * This is used when no debug output is wanted. | ||
506 | */ | ||
507 | static struct tty_driver dummy_driver; | ||
508 | |||
509 | static int dummy_open(struct tty_struct *tty, struct file * filp) | ||
510 | { | ||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | static void dummy_close(struct tty_struct *tty, struct file * filp) | ||
515 | { | ||
516 | } | ||
517 | |||
518 | static int dummy_write(struct tty_struct * tty, | ||
519 | const unsigned char *buf, int count) | ||
520 | { | ||
521 | return count; | ||
522 | } | ||
523 | |||
524 | static int | ||
525 | dummy_write_room(struct tty_struct *tty) | ||
526 | { | ||
527 | return 8192; | ||
528 | } | ||
529 | |||
530 | void __init | ||
531 | init_dummy_console(void) | ||
532 | { | ||
533 | memset(&dummy_driver, 0, sizeof(struct tty_driver)); | ||
534 | dummy_driver.driver_name = "serial"; | ||
535 | dummy_driver.name = "ttyS"; | ||
536 | dummy_driver.major = TTY_MAJOR; | ||
537 | dummy_driver.minor_start = 68; | ||
538 | dummy_driver.num = 1; /* etrax100 has 4 serial ports */ | ||
539 | dummy_driver.type = TTY_DRIVER_TYPE_SERIAL; | ||
540 | dummy_driver.subtype = SERIAL_TYPE_NORMAL; | ||
541 | dummy_driver.init_termios = tty_std_termios; | ||
542 | dummy_driver.init_termios.c_cflag = | ||
543 | B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ | ||
544 | dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | ||
545 | |||
546 | dummy_driver.open = dummy_open; | ||
547 | dummy_driver.close = dummy_close; | ||
548 | dummy_driver.write = dummy_write; | ||
549 | dummy_driver.write_room = dummy_write_room; | ||
550 | if (tty_register_driver(&dummy_driver)) | ||
551 | panic("Couldn't register dummy serial driver\n"); | ||
552 | } | ||
553 | |||
554 | static struct tty_driver* | ||
555 | etrax_console_device(struct console* co, int *index) | ||
556 | { | ||
557 | if (port) | ||
558 | *index = port->index; | ||
559 | return port ? serial_driver : &dummy_driver; | ||
560 | } | ||
561 | |||
436 | static struct console sercons = { | 562 | static struct console sercons = { |
437 | name : "ttyS", | 563 | name : "ttyS", |
438 | write: console_write, | 564 | write: console_write, |
@@ -504,28 +630,21 @@ init_etrax_debug(void) | |||
504 | static int first = 1; | 630 | static int first = 1; |
505 | 631 | ||
506 | if (!first) { | 632 | if (!first) { |
507 | if (!port) { | 633 | unregister_console(&sercons); |
508 | register_console(&sercons0); | 634 | register_console(&sercons0); |
509 | register_console(&sercons1); | 635 | register_console(&sercons1); |
510 | register_console(&sercons2); | 636 | register_console(&sercons2); |
511 | register_console(&sercons3); | 637 | register_console(&sercons3); |
512 | unregister_console(&sercons); | 638 | init_dummy_console(); |
513 | } | ||
514 | return 0; | 639 | return 0; |
515 | } | 640 | } |
516 | first = 0; | ||
517 | if (port) | ||
518 | register_console(&sercons); | ||
519 | return 0; | ||
520 | } | ||
521 | 641 | ||
522 | int __init | 642 | first = 0; |
523 | init_console(void) | 643 | register_console(&sercons); |
524 | { | 644 | start_port(port); |
525 | serial_driver = alloc_tty_driver(1); | 645 | #ifdef CONFIG_ETRAX_KGDB |
526 | if (!serial_driver) | 646 | start_port(kgdb_port); |
527 | return -ENOMEM; | 647 | #endif |
528 | return 0; | 648 | return 0; |
529 | } | 649 | } |
530 | |||
531 | __initcall(init_etrax_debug); | 650 | __initcall(init_etrax_debug); |