diff options
author | Roy Huang <roy.huang@analog.com> | 2007-07-12 04:43:46 -0400 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2007-07-12 04:43:46 -0400 |
commit | f4d640c9be1979a603ed017e1e03a16ba3a4d7a1 (patch) | |
tree | 4196f746e1b1c483a0921a19faf5305f4e479c07 /drivers | |
parent | db83b991bce1b4792125d4b23bb108e8cfd5d366 (diff) |
Blackfin serial driver: supporting BF548-EZKIT serial port
Signed-off-by: Roy Huang <roy.huang@analog.com>
Signed-off-by: Mike Frysinger <michael.frysinger@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/serial/Kconfig | 46 | ||||
-rw-r--r-- | drivers/serial/bfin_5xx.c | 77 |
2 files changed, 117 insertions, 6 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 71a4ac53a7ef..2adbed4e10f3 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -599,7 +599,7 @@ config UART0_RTS_PIN | |||
599 | 599 | ||
600 | config SERIAL_BFIN_UART1 | 600 | config SERIAL_BFIN_UART1 |
601 | bool "Enable UART1" | 601 | bool "Enable UART1" |
602 | depends on SERIAL_BFIN && (BF534 || BF536 || BF537) | 602 | depends on SERIAL_BFIN && (BF534 || BF536 || BF537 || BF54x) |
603 | help | 603 | help |
604 | Enable UART1 | 604 | Enable UART1 |
605 | 605 | ||
@@ -612,18 +612,58 @@ config BFIN_UART1_CTSRTS | |||
612 | 612 | ||
613 | config UART1_CTS_PIN | 613 | config UART1_CTS_PIN |
614 | int "UART1 CTS pin" | 614 | int "UART1 CTS pin" |
615 | depends on BFIN_UART1_CTSRTS | 615 | depends on BFIN_UART1_CTSRTS && (BF53x || BF561) |
616 | default -1 | 616 | default -1 |
617 | help | 617 | help |
618 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | 618 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. |
619 | 619 | ||
620 | config UART1_RTS_PIN | 620 | config UART1_RTS_PIN |
621 | int "UART1 RTS pin" | 621 | int "UART1 RTS pin" |
622 | depends on BFIN_UART1_CTSRTS | 622 | depends on BFIN_UART1_CTSRTS && (BF53x || BF561) |
623 | default -1 | 623 | default -1 |
624 | help | 624 | help |
625 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | 625 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. |
626 | 626 | ||
627 | config SERIAL_BFIN_UART2 | ||
628 | bool "Enable UART2" | ||
629 | depends on SERIAL_BFIN && (BF54x) | ||
630 | help | ||
631 | Enable UART2 | ||
632 | |||
633 | config BFIN_UART2_CTSRTS | ||
634 | bool "Enable UART2 hardware flow control" | ||
635 | depends on SERIAL_BFIN_UART2 | ||
636 | help | ||
637 | Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS | ||
638 | signal. | ||
639 | |||
640 | config UART2_CTS_PIN | ||
641 | int "UART2 CTS pin" | ||
642 | depends on BFIN_UART2_CTSRTS | ||
643 | default -1 | ||
644 | help | ||
645 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | ||
646 | |||
647 | config UART2_RTS_PIN | ||
648 | int "UART2 RTS pin" | ||
649 | depends on BFIN_UART2_CTSRTS | ||
650 | default -1 | ||
651 | help | ||
652 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | ||
653 | |||
654 | config SERIAL_BFIN_UART3 | ||
655 | bool "Enable UART3" | ||
656 | depends on SERIAL_BFIN && (BF54x) | ||
657 | help | ||
658 | Enable UART3 | ||
659 | |||
660 | config BFIN_UART3_CTSRTS | ||
661 | bool "Enable UART3 hardware flow control" | ||
662 | depends on SERIAL_BFIN_UART3 | ||
663 | help | ||
664 | Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS | ||
665 | signal. | ||
666 | |||
627 | config SERIAL_IMX | 667 | config SERIAL_IMX |
628 | bool "IMX serial port support" | 668 | bool "IMX serial port support" |
629 | depends on ARM && ARCH_IMX | 669 | depends on ARM && ARCH_IMX |
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index f7926dc7fa78..66c92bc36f3d 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -86,15 +86,29 @@ static void bfin_serial_stop_tx(struct uart_port *port) | |||
86 | { | 86 | { |
87 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 87 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
88 | 88 | ||
89 | #ifdef CONFIG_BF54x | ||
90 | while (!(UART_GET_LSR(uart) & TEMT)) | ||
91 | continue; | ||
92 | #endif | ||
93 | |||
89 | #ifdef CONFIG_SERIAL_BFIN_DMA | 94 | #ifdef CONFIG_SERIAL_BFIN_DMA |
90 | disable_dma(uart->tx_dma_channel); | 95 | disable_dma(uart->tx_dma_channel); |
91 | #else | 96 | #else |
97 | #ifdef CONFIG_BF54x | ||
98 | /* Waiting for Transmission Finished */ | ||
99 | while (!(UART_GET_LSR(uart) & TFI)) | ||
100 | continue; | ||
101 | /* Clear TFI bit */ | ||
102 | UART_PUT_LSR(uart, TFI); | ||
103 | UART_CLEAR_IER(uart, ETBEI); | ||
104 | #else | ||
92 | unsigned short ier; | 105 | unsigned short ier; |
93 | 106 | ||
94 | ier = UART_GET_IER(uart); | 107 | ier = UART_GET_IER(uart); |
95 | ier &= ~ETBEI; | 108 | ier &= ~ETBEI; |
96 | UART_PUT_IER(uart, ier); | 109 | UART_PUT_IER(uart, ier); |
97 | #endif | 110 | #endif |
111 | #endif | ||
98 | } | 112 | } |
99 | 113 | ||
100 | /* | 114 | /* |
@@ -107,12 +121,16 @@ static void bfin_serial_start_tx(struct uart_port *port) | |||
107 | #ifdef CONFIG_SERIAL_BFIN_DMA | 121 | #ifdef CONFIG_SERIAL_BFIN_DMA |
108 | bfin_serial_dma_tx_chars(uart); | 122 | bfin_serial_dma_tx_chars(uart); |
109 | #else | 123 | #else |
124 | #ifdef CONFIG_BF54x | ||
125 | UART_SET_IER(uart, ETBEI); | ||
126 | #else | ||
110 | unsigned short ier; | 127 | unsigned short ier; |
111 | ier = UART_GET_IER(uart); | 128 | ier = UART_GET_IER(uart); |
112 | ier |= ETBEI; | 129 | ier |= ETBEI; |
113 | UART_PUT_IER(uart, ier); | 130 | UART_PUT_IER(uart, ier); |
114 | bfin_serial_tx_chars(uart); | 131 | bfin_serial_tx_chars(uart); |
115 | #endif | 132 | #endif |
133 | #endif | ||
116 | } | 134 | } |
117 | 135 | ||
118 | /* | 136 | /* |
@@ -121,6 +139,9 @@ static void bfin_serial_start_tx(struct uart_port *port) | |||
121 | static void bfin_serial_stop_rx(struct uart_port *port) | 139 | static void bfin_serial_stop_rx(struct uart_port *port) |
122 | { | 140 | { |
123 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 141 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
142 | #ifdef CONFIG_BF54x | ||
143 | UART_CLEAR_IER(uart, ERBFI); | ||
144 | #else | ||
124 | unsigned short ier; | 145 | unsigned short ier; |
125 | 146 | ||
126 | ier = UART_GET_IER(uart); | 147 | ier = UART_GET_IER(uart); |
@@ -129,6 +150,7 @@ static void bfin_serial_stop_rx(struct uart_port *port) | |||
129 | #endif | 150 | #endif |
130 | ier &= ~ERBFI; | 151 | ier &= ~ERBFI; |
131 | UART_PUT_IER(uart, ier); | 152 | UART_PUT_IER(uart, ier); |
153 | #endif | ||
132 | } | 154 | } |
133 | 155 | ||
134 | /* | 156 | /* |
@@ -325,10 +347,21 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) | |||
325 | { | 347 | { |
326 | struct bfin_serial_port *uart = dev_id; | 348 | struct bfin_serial_port *uart = dev_id; |
327 | 349 | ||
350 | #ifdef CONFIG_BF54x | ||
351 | unsigned short status; | ||
352 | spin_lock(&uart->port.lock); | ||
353 | status = UART_GET_LSR(uart); | ||
354 | while ((UART_GET_IER(uart) & ERBFI) && (status & DR)) { | ||
355 | bfin_serial_rx_chars(uart); | ||
356 | status = UART_GET_LSR(uart); | ||
357 | } | ||
358 | spin_unlock(&uart->port.lock); | ||
359 | #else | ||
328 | spin_lock(&uart->port.lock); | 360 | spin_lock(&uart->port.lock); |
329 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY) | 361 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY) |
330 | bfin_serial_rx_chars(uart); | 362 | bfin_serial_rx_chars(uart); |
331 | spin_unlock(&uart->port.lock); | 363 | spin_unlock(&uart->port.lock); |
364 | #endif | ||
332 | return IRQ_HANDLED; | 365 | return IRQ_HANDLED; |
333 | } | 366 | } |
334 | 367 | ||
@@ -336,10 +369,21 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) | |||
336 | { | 369 | { |
337 | struct bfin_serial_port *uart = dev_id; | 370 | struct bfin_serial_port *uart = dev_id; |
338 | 371 | ||
372 | #ifdef CONFIG_BF54x | ||
373 | unsigned short status; | ||
374 | spin_lock(&uart->port.lock); | ||
375 | status = UART_GET_LSR(uart); | ||
376 | while ((UART_GET_IER(uart) & ETBEI) && (status & THRE)) { | ||
377 | bfin_serial_tx_chars(uart); | ||
378 | status = UART_GET_LSR(uart); | ||
379 | } | ||
380 | spin_unlock(&uart->port.lock); | ||
381 | #else | ||
339 | spin_lock(&uart->port.lock); | 382 | spin_lock(&uart->port.lock); |
340 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY) | 383 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY) |
341 | bfin_serial_tx_chars(uart); | 384 | bfin_serial_tx_chars(uart); |
342 | spin_unlock(&uart->port.lock); | 385 | spin_unlock(&uart->port.lock); |
386 | #endif | ||
343 | return IRQ_HANDLED; | 387 | return IRQ_HANDLED; |
344 | } | 388 | } |
345 | 389 | ||
@@ -350,7 +394,6 @@ static void bfin_serial_do_work(struct work_struct *work) | |||
350 | 394 | ||
351 | bfin_serial_mctrl_check(uart); | 395 | bfin_serial_mctrl_check(uart); |
352 | } | 396 | } |
353 | |||
354 | #endif | 397 | #endif |
355 | 398 | ||
356 | #ifdef CONFIG_SERIAL_BFIN_DMA | 399 | #ifdef CONFIG_SERIAL_BFIN_DMA |
@@ -399,9 +442,13 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) | |||
399 | set_dma_x_count(uart->tx_dma_channel, uart->tx_count); | 442 | set_dma_x_count(uart->tx_dma_channel, uart->tx_count); |
400 | set_dma_x_modify(uart->tx_dma_channel, 1); | 443 | set_dma_x_modify(uart->tx_dma_channel, 1); |
401 | enable_dma(uart->tx_dma_channel); | 444 | enable_dma(uart->tx_dma_channel); |
445 | #ifdef CONFIG_BF54x | ||
446 | UART_SET_IER(uart, ETBEI); | ||
447 | #else | ||
402 | ier = UART_GET_IER(uart); | 448 | ier = UART_GET_IER(uart); |
403 | ier |= ETBEI; | 449 | ier |= ETBEI; |
404 | UART_PUT_IER(uart, ier); | 450 | UART_PUT_IER(uart, ier); |
451 | #endif | ||
405 | spin_unlock_irqrestore(&uart->port.lock, flags); | 452 | spin_unlock_irqrestore(&uart->port.lock, flags); |
406 | } | 453 | } |
407 | 454 | ||
@@ -481,9 +528,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) | |||
481 | if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { | 528 | if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { |
482 | clear_dma_irqstat(uart->tx_dma_channel); | 529 | clear_dma_irqstat(uart->tx_dma_channel); |
483 | disable_dma(uart->tx_dma_channel); | 530 | disable_dma(uart->tx_dma_channel); |
531 | #ifdef CONFIG_BF54x | ||
532 | UART_CLEAR_IER(uart, ETBEI); | ||
533 | #else | ||
484 | ier = UART_GET_IER(uart); | 534 | ier = UART_GET_IER(uart); |
485 | ier &= ~ETBEI; | 535 | ier &= ~ETBEI; |
486 | UART_PUT_IER(uart, ier); | 536 | UART_PUT_IER(uart, ier); |
537 | #endif | ||
487 | xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1); | 538 | xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1); |
488 | uart->port.icount.tx+=uart->tx_count; | 539 | uart->port.icount.tx+=uart->tx_count; |
489 | 540 | ||
@@ -665,7 +716,11 @@ static int bfin_serial_startup(struct uart_port *port) | |||
665 | return -EBUSY; | 716 | return -EBUSY; |
666 | } | 717 | } |
667 | #endif | 718 | #endif |
719 | #ifdef CONFIG_BF54x | ||
720 | UART_SET_IER(uart, ERBFI); | ||
721 | #else | ||
668 | UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI); | 722 | UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI); |
723 | #endif | ||
669 | return 0; | 724 | return 0; |
670 | } | 725 | } |
671 | 726 | ||
@@ -756,29 +811,41 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
756 | 811 | ||
757 | /* Disable UART */ | 812 | /* Disable UART */ |
758 | ier = UART_GET_IER(uart); | 813 | ier = UART_GET_IER(uart); |
814 | #ifdef CONFIG_BF54x | ||
815 | UART_CLEAR_IER(uart, 0xF); | ||
816 | #else | ||
759 | UART_PUT_IER(uart, 0); | 817 | UART_PUT_IER(uart, 0); |
818 | #endif | ||
760 | 819 | ||
820 | #ifndef CONFIG_BF54x | ||
761 | /* Set DLAB in LCR to Access DLL and DLH */ | 821 | /* Set DLAB in LCR to Access DLL and DLH */ |
762 | val = UART_GET_LCR(uart); | 822 | val = UART_GET_LCR(uart); |
763 | val |= DLAB; | 823 | val |= DLAB; |
764 | UART_PUT_LCR(uart, val); | 824 | UART_PUT_LCR(uart, val); |
765 | SSYNC(); | 825 | SSYNC(); |
826 | #endif | ||
766 | 827 | ||
767 | UART_PUT_DLL(uart, quot & 0xFF); | 828 | UART_PUT_DLL(uart, quot & 0xFF); |
768 | SSYNC(); | 829 | SSYNC(); |
769 | UART_PUT_DLH(uart, (quot >> 8) & 0xFF); | 830 | UART_PUT_DLH(uart, (quot >> 8) & 0xFF); |
770 | SSYNC(); | 831 | SSYNC(); |
771 | 832 | ||
833 | #ifndef CONFIG_BF54x | ||
772 | /* Clear DLAB in LCR to Access THR RBR IER */ | 834 | /* Clear DLAB in LCR to Access THR RBR IER */ |
773 | val = UART_GET_LCR(uart); | 835 | val = UART_GET_LCR(uart); |
774 | val &= ~DLAB; | 836 | val &= ~DLAB; |
775 | UART_PUT_LCR(uart, val); | 837 | UART_PUT_LCR(uart, val); |
776 | SSYNC(); | 838 | SSYNC(); |
839 | #endif | ||
777 | 840 | ||
778 | UART_PUT_LCR(uart, lcr); | 841 | UART_PUT_LCR(uart, lcr); |
779 | 842 | ||
780 | /* Enable UART */ | 843 | /* Enable UART */ |
844 | #ifdef CONFIG_BF54x | ||
845 | UART_SET_IER(uart, ier); | ||
846 | #else | ||
781 | UART_PUT_IER(uart, ier); | 847 | UART_PUT_IER(uart, ier); |
848 | #endif | ||
782 | 849 | ||
783 | val = UART_GET_GCTL(uart); | 850 | val = UART_GET_GCTL(uart); |
784 | val |= UCEN; | 851 | val |= UCEN; |
@@ -890,15 +957,15 @@ static void __init bfin_serial_init_ports(void) | |||
890 | bfin_serial_resource[i].uart_rts_pin; | 957 | bfin_serial_resource[i].uart_rts_pin; |
891 | #endif | 958 | #endif |
892 | bfin_serial_hw_init(&bfin_serial_ports[i]); | 959 | bfin_serial_hw_init(&bfin_serial_ports[i]); |
893 | |||
894 | } | 960 | } |
961 | |||
895 | } | 962 | } |
896 | 963 | ||
897 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE | 964 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE |
898 | static void bfin_serial_console_putchar(struct uart_port *port, int ch) | 965 | static void bfin_serial_console_putchar(struct uart_port *port, int ch) |
899 | { | 966 | { |
900 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 967 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
901 | while (!(UART_GET_LSR(uart))) | 968 | while (!(UART_GET_LSR(uart) & THRE)) |
902 | barrier(); | 969 | barrier(); |
903 | UART_PUT_CHAR(uart, ch); | 970 | UART_PUT_CHAR(uart, ch); |
904 | SSYNC(); | 971 | SSYNC(); |
@@ -950,18 +1017,22 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud, | |||
950 | case 2: *bits = 7; break; | 1017 | case 2: *bits = 7; break; |
951 | case 3: *bits = 8; break; | 1018 | case 3: *bits = 8; break; |
952 | } | 1019 | } |
1020 | #ifndef CONFIG_BF54x | ||
953 | /* Set DLAB in LCR to Access DLL and DLH */ | 1021 | /* Set DLAB in LCR to Access DLL and DLH */ |
954 | val = UART_GET_LCR(uart); | 1022 | val = UART_GET_LCR(uart); |
955 | val |= DLAB; | 1023 | val |= DLAB; |
956 | UART_PUT_LCR(uart, val); | 1024 | UART_PUT_LCR(uart, val); |
1025 | #endif | ||
957 | 1026 | ||
958 | dll = UART_GET_DLL(uart); | 1027 | dll = UART_GET_DLL(uart); |
959 | dlh = UART_GET_DLH(uart); | 1028 | dlh = UART_GET_DLH(uart); |
960 | 1029 | ||
1030 | #ifndef CONFIG_BF54x | ||
961 | /* Clear DLAB in LCR to Access THR RBR IER */ | 1031 | /* Clear DLAB in LCR to Access THR RBR IER */ |
962 | val = UART_GET_LCR(uart); | 1032 | val = UART_GET_LCR(uart); |
963 | val &= ~DLAB; | 1033 | val &= ~DLAB; |
964 | UART_PUT_LCR(uart, val); | 1034 | UART_PUT_LCR(uart, val); |
1035 | #endif | ||
965 | 1036 | ||
966 | *baud = get_sclk() / (16*(dll | dlh << 8)); | 1037 | *baud = get_sclk() / (16*(dll | dlh << 8)); |
967 | } | 1038 | } |