diff options
author | Sonic Zhang <sonic.zhang@analog.com> | 2009-04-07 11:51:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-07 11:44:05 -0400 |
commit | 6f95570e407d03c5140a220e054f9b18abdc7041 (patch) | |
tree | d239c58f148bf0644ee38c86da0fdd36f204240d /drivers/serial | |
parent | 1dcb884ca8048efb4ce2999d367c26369ab2227c (diff) |
Change hardware flow control from poll to interrupt driven
Only the CTS bit is affected.
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/bfin_5xx.c | 131 |
1 files changed, 82 insertions, 49 deletions
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index f9b5a72e261a..fbbddb9e73f6 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -63,7 +63,6 @@ static int kgdboc_break_enabled; | |||
63 | #define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT) | 63 | #define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT) |
64 | 64 | ||
65 | #define DMA_RX_FLUSH_JIFFIES (HZ / 50) | 65 | #define DMA_RX_FLUSH_JIFFIES (HZ / 50) |
66 | #define CTS_CHECK_JIFFIES (HZ / 50) | ||
67 | 66 | ||
68 | #ifdef CONFIG_SERIAL_BFIN_DMA | 67 | #ifdef CONFIG_SERIAL_BFIN_DMA |
69 | static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); | 68 | static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); |
@@ -71,8 +70,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); | |||
71 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart); | 70 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart); |
72 | #endif | 71 | #endif |
73 | 72 | ||
74 | static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); | ||
75 | |||
76 | static void bfin_serial_reset_irda(struct uart_port *port); | 73 | static void bfin_serial_reset_irda(struct uart_port *port); |
77 | 74 | ||
78 | /* | 75 | /* |
@@ -264,12 +261,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) | |||
264 | { | 261 | { |
265 | struct circ_buf *xmit = &uart->port.info->xmit; | 262 | struct circ_buf *xmit = &uart->port.info->xmit; |
266 | 263 | ||
267 | /* | ||
268 | * Check the modem control lines before | ||
269 | * transmitting anything. | ||
270 | */ | ||
271 | bfin_serial_mctrl_check(uart); | ||
272 | |||
273 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { | 264 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { |
274 | #ifdef CONFIG_BF54x | 265 | #ifdef CONFIG_BF54x |
275 | /* Clear TFI bit */ | 266 | /* Clear TFI bit */ |
@@ -328,12 +319,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) | |||
328 | 319 | ||
329 | uart->tx_done = 0; | 320 | uart->tx_done = 0; |
330 | 321 | ||
331 | /* | ||
332 | * Check the modem control lines before | ||
333 | * transmitting anything. | ||
334 | */ | ||
335 | bfin_serial_mctrl_check(uart); | ||
336 | |||
337 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { | 322 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { |
338 | uart->tx_count = 0; | 323 | uart->tx_count = 0; |
339 | uart->tx_done = 1; | 324 | uart->tx_done = 1; |
@@ -524,29 +509,21 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
524 | #endif | 509 | #endif |
525 | } | 510 | } |
526 | 511 | ||
512 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
527 | /* | 513 | /* |
528 | * Handle any change of modem status signal since we were last called. | 514 | * Handle any change of modem status signal. |
529 | */ | 515 | */ |
530 | static void bfin_serial_mctrl_check(struct bfin_serial_port *uart) | 516 | static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id) |
531 | { | 517 | { |
532 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | 518 | struct bfin_serial_port *uart = dev_id; |
533 | unsigned int status; | 519 | unsigned int status; |
534 | struct uart_info *info = uart->port.info; | ||
535 | struct tty_struct *tty = info->port.tty; | ||
536 | 520 | ||
537 | status = bfin_serial_get_mctrl(&uart->port); | 521 | status = bfin_serial_get_mctrl(&uart->port); |
538 | uart_handle_cts_change(&uart->port, status & TIOCM_CTS); | 522 | uart_handle_cts_change(&uart->port, status & TIOCM_CTS); |
539 | if (!(status & TIOCM_CTS)) { | 523 | |
540 | tty->hw_stopped = 1; | 524 | return IRQ_HANDLED; |
541 | uart->cts_timer.data = (unsigned long)(uart); | ||
542 | uart->cts_timer.function = (void *)bfin_serial_mctrl_check; | ||
543 | uart->cts_timer.expires = jiffies + CTS_CHECK_JIFFIES; | ||
544 | add_timer(&(uart->cts_timer)); | ||
545 | } else { | ||
546 | tty->hw_stopped = 0; | ||
547 | } | ||
548 | #endif | ||
549 | } | 525 | } |
526 | #endif | ||
550 | 527 | ||
551 | /* | 528 | /* |
552 | * Interrupts are always disabled. | 529 | * Interrupts are always disabled. |
@@ -606,7 +583,7 @@ static int bfin_serial_startup(struct uart_port *port) | |||
606 | uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; | 583 | uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; |
607 | add_timer(&(uart->rx_dma_timer)); | 584 | add_timer(&(uart->rx_dma_timer)); |
608 | #else | 585 | #else |
609 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ | 586 | # if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ |
610 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) | 587 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) |
611 | if (kgdboc_port_line == uart->port.line && kgdboc_break_enabled) | 588 | if (kgdboc_port_line == uart->port.line && kgdboc_break_enabled) |
612 | kgdboc_break_enabled = 0; | 589 | kgdboc_break_enabled = 0; |
@@ -661,11 +638,28 @@ static int bfin_serial_startup(struct uart_port *port) | |||
661 | } | 638 | } |
662 | } | 639 | } |
663 | # endif | 640 | # endif |
664 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ | 641 | # if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ |
665 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) | 642 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) |
666 | } | 643 | } |
667 | # endif | 644 | # endif |
668 | #endif | 645 | #endif |
646 | |||
647 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
648 | if (uart->cts_pin >= 0) { | ||
649 | if (request_irq(gpio_to_irq(uart->cts_pin), | ||
650 | bfin_serial_mctrl_cts_int, | ||
651 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | | ||
652 | IRQF_DISABLED, "BFIN_UART_CTS", uart)) { | ||
653 | uart->cts_pin = -1; | ||
654 | pr_info("Unable to attach BlackFin UART CTS interrupt.\ | ||
655 | So, disable it.\n"); | ||
656 | } | ||
657 | } | ||
658 | if (uart->rts_pin >= 0) { | ||
659 | gpio_request(uart->rts_pin, DRIVER_NAME); | ||
660 | gpio_direction_output(uart->rts_pin, 0); | ||
661 | } | ||
662 | #endif | ||
669 | UART_SET_IER(uart, ERBFI); | 663 | UART_SET_IER(uart, ERBFI); |
670 | return 0; | 664 | return 0; |
671 | } | 665 | } |
@@ -699,6 +693,13 @@ static void bfin_serial_shutdown(struct uart_port *port) | |||
699 | free_irq(uart->port.irq, uart); | 693 | free_irq(uart->port.irq, uart); |
700 | free_irq(uart->port.irq+1, uart); | 694 | free_irq(uart->port.irq+1, uart); |
701 | #endif | 695 | #endif |
696 | |||
697 | # ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
698 | if (uart->cts_pin >= 0) | ||
699 | free_irq(gpio_to_irq(uart->cts_pin), uart); | ||
700 | if (uart->rts_pin >= 0) | ||
701 | gpio_free(uart->rts_pin); | ||
702 | # endif | ||
702 | } | 703 | } |
703 | 704 | ||
704 | static void | 705 | static void |
@@ -864,6 +865,20 @@ static void bfin_serial_set_ldisc(struct uart_port *port) | |||
864 | } | 865 | } |
865 | } | 866 | } |
866 | 867 | ||
868 | static void bfin_serial_reset_irda(struct uart_port *port) | ||
869 | { | ||
870 | int line = port->line; | ||
871 | unsigned short val; | ||
872 | |||
873 | val = UART_GET_GCTL(&bfin_serial_ports[line]); | ||
874 | val &= ~(IREN | RPOLC); | ||
875 | UART_PUT_GCTL(&bfin_serial_ports[line], val); | ||
876 | SSYNC(); | ||
877 | val |= (IREN | RPOLC); | ||
878 | UART_PUT_GCTL(&bfin_serial_ports[line], val); | ||
879 | SSYNC(); | ||
880 | } | ||
881 | |||
867 | #ifdef CONFIG_CONSOLE_POLL | 882 | #ifdef CONFIG_CONSOLE_POLL |
868 | static void bfin_serial_poll_put_char(struct uart_port *port, unsigned char chr) | 883 | static void bfin_serial_poll_put_char(struct uart_port *port, unsigned char chr) |
869 | { | 884 | { |
@@ -909,20 +924,6 @@ static int bfin_kgdboc_port_startup(struct uart_port *port) | |||
909 | } | 924 | } |
910 | #endif | 925 | #endif |
911 | 926 | ||
912 | static void bfin_serial_reset_irda(struct uart_port *port) | ||
913 | { | ||
914 | int line = port->line; | ||
915 | unsigned short val; | ||
916 | |||
917 | val = UART_GET_GCTL(&bfin_serial_ports[line]); | ||
918 | val &= ~(IREN | RPOLC); | ||
919 | UART_PUT_GCTL(&bfin_serial_ports[line], val); | ||
920 | SSYNC(); | ||
921 | val |= (IREN | RPOLC); | ||
922 | UART_PUT_GCTL(&bfin_serial_ports[line], val); | ||
923 | SSYNC(); | ||
924 | } | ||
925 | |||
926 | static struct uart_ops bfin_serial_pops = { | 927 | static struct uart_ops bfin_serial_pops = { |
927 | .tx_empty = bfin_serial_tx_empty, | 928 | .tx_empty = bfin_serial_tx_empty, |
928 | .set_mctrl = bfin_serial_set_mctrl, | 929 | .set_mctrl = bfin_serial_set_mctrl, |
@@ -952,6 +953,39 @@ static struct uart_ops bfin_serial_pops = { | |||
952 | #endif | 953 | #endif |
953 | }; | 954 | }; |
954 | 955 | ||
956 | static void __init bfin_serial_hw_init(void) | ||
957 | { | ||
958 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
959 | peripheral_request(P_UART0_TX, DRIVER_NAME); | ||
960 | peripheral_request(P_UART0_RX, DRIVER_NAME); | ||
961 | #endif | ||
962 | |||
963 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
964 | peripheral_request(P_UART1_TX, DRIVER_NAME); | ||
965 | peripheral_request(P_UART1_RX, DRIVER_NAME); | ||
966 | |||
967 | # if defined(CONFIG_BFIN_UART1_CTSRTS) && defined(CONFIG_BF54x) | ||
968 | peripheral_request(P_UART1_RTS, DRIVER_NAME); | ||
969 | peripheral_request(P_UART1_CTS, DRIVER_NAME); | ||
970 | # endif | ||
971 | #endif | ||
972 | |||
973 | #ifdef CONFIG_SERIAL_BFIN_UART2 | ||
974 | peripheral_request(P_UART2_TX, DRIVER_NAME); | ||
975 | peripheral_request(P_UART2_RX, DRIVER_NAME); | ||
976 | #endif | ||
977 | |||
978 | #ifdef CONFIG_SERIAL_BFIN_UART3 | ||
979 | peripheral_request(P_UART3_TX, DRIVER_NAME); | ||
980 | peripheral_request(P_UART3_RX, DRIVER_NAME); | ||
981 | |||
982 | # if defined(CONFIG_BFIN_UART3_CTSRTS) && defined(CONFIG_BF54x) | ||
983 | peripheral_request(P_UART3_RTS, DRIVER_NAME); | ||
984 | peripheral_request(P_UART3_CTS, DRIVER_NAME); | ||
985 | # endif | ||
986 | #endif | ||
987 | } | ||
988 | |||
955 | static void __init bfin_serial_init_ports(void) | 989 | static void __init bfin_serial_init_ports(void) |
956 | { | 990 | { |
957 | static int first = 1; | 991 | static int first = 1; |
@@ -961,6 +995,8 @@ static void __init bfin_serial_init_ports(void) | |||
961 | return; | 995 | return; |
962 | first = 0; | 996 | first = 0; |
963 | 997 | ||
998 | bfin_serial_hw_init(); | ||
999 | |||
964 | for (i = 0; i < nr_active_ports; i++) { | 1000 | for (i = 0; i < nr_active_ports; i++) { |
965 | bfin_serial_ports[i].port.uartclk = get_sclk(); | 1001 | bfin_serial_ports[i].port.uartclk = get_sclk(); |
966 | bfin_serial_ports[i].port.fifosize = BFIN_UART_TX_FIFO_SIZE; | 1002 | bfin_serial_ports[i].port.fifosize = BFIN_UART_TX_FIFO_SIZE; |
@@ -984,15 +1020,12 @@ static void __init bfin_serial_init_ports(void) | |||
984 | init_timer(&(bfin_serial_ports[i].rx_dma_timer)); | 1020 | init_timer(&(bfin_serial_ports[i].rx_dma_timer)); |
985 | #endif | 1021 | #endif |
986 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | 1022 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS |
987 | init_timer(&(bfin_serial_ports[i].cts_timer)); | ||
988 | bfin_serial_ports[i].cts_pin = | 1023 | bfin_serial_ports[i].cts_pin = |
989 | bfin_serial_resource[i].uart_cts_pin; | 1024 | bfin_serial_resource[i].uart_cts_pin; |
990 | bfin_serial_ports[i].rts_pin = | 1025 | bfin_serial_ports[i].rts_pin = |
991 | bfin_serial_resource[i].uart_rts_pin; | 1026 | bfin_serial_resource[i].uart_rts_pin; |
992 | #endif | 1027 | #endif |
993 | bfin_serial_hw_init(&bfin_serial_ports[i]); | ||
994 | } | 1028 | } |
995 | |||
996 | } | 1029 | } |
997 | 1030 | ||
998 | #if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) | 1031 | #if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) |