aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/serial_txx9.c
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2009-06-24 13:34:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-24 12:55:50 -0400
commita10b32db34898d0db58a58ef76a70c374931bbff (patch)
treee0936a775663f1489d5a0f69da196fc0e8470773 /drivers/serial/serial_txx9.c
parentbe98eb2c2fc88d9d61cfeab5c11ab1118ca0bba9 (diff)
kgdb: kgdboc console poll hooks for serial_txx9 uart
Implement the serial polling hooks for the serial_txx9 uart for use with kgdboc. This patch once got SOB from Jason on Jul 2008 and (perhaps) merged into kgdb-next branch, but lost somewhere then. I resend it now with Jason's Acked-by. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Acked-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/serial/serial_txx9.c')
-rw-r--r--drivers/serial/serial_txx9.c113
1 files changed, 92 insertions, 21 deletions
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 7313c2edcb83..54dd16d66a4b 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -461,6 +461,94 @@ static void serial_txx9_break_ctl(struct uart_port *port, int break_state)
461 spin_unlock_irqrestore(&up->port.lock, flags); 461 spin_unlock_irqrestore(&up->port.lock, flags);
462} 462}
463 463
464#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || (CONFIG_CONSOLE_POLL)
465/*
466 * Wait for transmitter & holding register to empty
467 */
468static void wait_for_xmitr(struct uart_txx9_port *up)
469{
470 unsigned int tmout = 10000;
471
472 /* Wait up to 10ms for the character(s) to be sent. */
473 while (--tmout &&
474 !(sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS))
475 udelay(1);
476
477 /* Wait up to 1s for flow control if necessary */
478 if (up->port.flags & UPF_CONS_FLOW) {
479 tmout = 1000000;
480 while (--tmout &&
481 (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS))
482 udelay(1);
483 }
484}
485#endif
486
487#ifdef CONFIG_CONSOLE_POLL
488/*
489 * Console polling routines for writing and reading from the uart while
490 * in an interrupt or debug context.
491 */
492
493static int serial_txx9_get_poll_char(struct uart_port *port)
494{
495 unsigned int ier;
496 unsigned char c;
497 struct uart_txx9_port *up = (struct uart_txx9_port *)port;
498
499 /*
500 * First save the IER then disable the interrupts
501 */
502 ier = sio_in(up, TXX9_SIDICR);
503 sio_out(up, TXX9_SIDICR, 0);
504
505 while (sio_in(up, TXX9_SIDISR) & TXX9_SIDISR_UVALID)
506 ;
507
508 c = sio_in(up, TXX9_SIRFIFO);
509
510 /*
511 * Finally, clear RX interrupt status
512 * and restore the IER
513 */
514 sio_mask(up, TXX9_SIDISR, TXX9_SIDISR_RDIS);
515 sio_out(up, TXX9_SIDICR, ier);
516 return c;
517}
518
519
520static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c)
521{
522 unsigned int ier;
523 struct uart_txx9_port *up = (struct uart_txx9_port *)port;
524
525 /*
526 * First save the IER then disable the interrupts
527 */
528 ier = sio_in(up, TXX9_SIDICR);
529 sio_out(up, TXX9_SIDICR, 0);
530
531 wait_for_xmitr(up);
532 /*
533 * Send the character out.
534 * If a LF, also do CR...
535 */
536 sio_out(up, TXX9_SITFIFO, c);
537 if (c == 10) {
538 wait_for_xmitr(up);
539 sio_out(up, TXX9_SITFIFO, 13);
540 }
541
542 /*
543 * Finally, wait for transmitter to become empty
544 * and restore the IER
545 */
546 wait_for_xmitr(up);
547 sio_out(up, TXX9_SIDICR, ier);
548}
549
550#endif /* CONFIG_CONSOLE_POLL */
551
464static int serial_txx9_startup(struct uart_port *port) 552static int serial_txx9_startup(struct uart_port *port)
465{ 553{
466 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 554 struct uart_txx9_port *up = (struct uart_txx9_port *)port;
@@ -781,6 +869,10 @@ static struct uart_ops serial_txx9_pops = {
781 .release_port = serial_txx9_release_port, 869 .release_port = serial_txx9_release_port,
782 .request_port = serial_txx9_request_port, 870 .request_port = serial_txx9_request_port,
783 .config_port = serial_txx9_config_port, 871 .config_port = serial_txx9_config_port,
872#ifdef CONFIG_CONSOLE_POLL
873 .poll_get_char = serial_txx9_get_poll_char,
874 .poll_put_char = serial_txx9_put_poll_char,
875#endif
784}; 876};
785 877
786static struct uart_txx9_port serial_txx9_ports[UART_NR]; 878static struct uart_txx9_port serial_txx9_ports[UART_NR];
@@ -803,27 +895,6 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv,
803 895
804#ifdef CONFIG_SERIAL_TXX9_CONSOLE 896#ifdef CONFIG_SERIAL_TXX9_CONSOLE
805 897
806/*
807 * Wait for transmitter & holding register to empty
808 */
809static inline void wait_for_xmitr(struct uart_txx9_port *up)
810{
811 unsigned int tmout = 10000;
812
813 /* Wait up to 10ms for the character(s) to be sent. */
814 while (--tmout &&
815 !(sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS))
816 udelay(1);
817
818 /* Wait up to 1s for flow control if necessary */
819 if (up->port.flags & UPF_CONS_FLOW) {
820 tmout = 1000000;
821 while (--tmout &&
822 (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS))
823 udelay(1);
824 }
825}
826
827static void serial_txx9_console_putchar(struct uart_port *port, int ch) 898static void serial_txx9_console_putchar(struct uart_port *port, int ch)
828{ 899{
829 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 900 struct uart_txx9_port *up = (struct uart_txx9_port *)port;