aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/bfin_5xx.c
diff options
context:
space:
mode:
authorRoy Huang <roy.huang@analog.com>2007-07-12 04:43:46 -0400
committerBryan Wu <bryan.wu@analog.com>2007-07-12 04:43:46 -0400
commitf4d640c9be1979a603ed017e1e03a16ba3a4d7a1 (patch)
tree4196f746e1b1c483a0921a19faf5305f4e479c07 /drivers/serial/bfin_5xx.c
parentdb83b991bce1b4792125d4b23bb108e8cfd5d366 (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/serial/bfin_5xx.c')
-rw-r--r--drivers/serial/bfin_5xx.c77
1 files changed, 74 insertions, 3 deletions
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)
121static void bfin_serial_stop_rx(struct uart_port *port) 139static 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
898static void bfin_serial_console_putchar(struct uart_port *port, int ch) 965static 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 }