aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2009-04-07 11:51:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 11:44:05 -0400
commit6f95570e407d03c5140a220e054f9b18abdc7041 (patch)
treed239c58f148bf0644ee38c86da0fdd36f204240d
parent1dcb884ca8048efb4ce2999d367c26369ab2227c (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>
-rw-r--r--arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h26
-rw-r--r--arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h20
-rw-r--r--arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h27
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h45
-rw-r--r--arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h20
-rw-r--r--drivers/serial/bfin_5xx.c131
6 files changed, 82 insertions, 187 deletions
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
index e8c41fd842b5..d2b160c14f04 100644
--- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
@@ -167,29 +167,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
167}; 167};
168 168
169#define DRIVER_NAME "bfin-uart" 169#define DRIVER_NAME "bfin-uart"
170
171static void bfin_serial_hw_init(struct bfin_serial_port *uart)
172{
173
174#ifdef CONFIG_SERIAL_BFIN_UART0
175 peripheral_request(P_UART0_TX, DRIVER_NAME);
176 peripheral_request(P_UART0_RX, DRIVER_NAME);
177#endif
178
179#ifdef CONFIG_SERIAL_BFIN_UART1
180 peripheral_request(P_UART1_TX, DRIVER_NAME);
181 peripheral_request(P_UART1_RX, DRIVER_NAME);
182#endif
183
184#ifdef CONFIG_SERIAL_BFIN_CTSRTS
185 if (uart->cts_pin >= 0) {
186 gpio_request(uart->cts_pin, DRIVER_NAME);
187 gpio_direction_input(uart->cts_pin);
188 }
189
190 if (uart->rts_pin >= 0) {
191 gpio_request(uart->rts_pin, DRIVER_NAME);
192 gpio_direction_output(uart->rts_pin, 0);
193 }
194#endif
195}
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
index 5f517f53b0fd..70356ddf8509 100644
--- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
@@ -142,23 +142,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
142}; 142};
143 143
144#define DRIVER_NAME "bfin-uart" 144#define DRIVER_NAME "bfin-uart"
145
146static void bfin_serial_hw_init(struct bfin_serial_port *uart)
147{
148
149#ifdef CONFIG_SERIAL_BFIN_UART0
150 peripheral_request(P_UART0_TX, DRIVER_NAME);
151 peripheral_request(P_UART0_RX, DRIVER_NAME);
152#endif
153
154#ifdef CONFIG_SERIAL_BFIN_CTSRTS
155 if (uart->cts_pin >= 0) {
156 gpio_request(uart->cts_pin, DRIVER_NAME);
157 gpio_direction_input(uart->cts_pin);
158 }
159 if (uart->rts_pin >= 0) {
160 gpio_request(uart->rts_pin, DRIVER_NAME);
161 gpio_direction_output(uart->rts_pin, 0);
162 }
163#endif
164}
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
index 9e34700844a2..d46fc4f50cf2 100644
--- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
@@ -99,7 +99,6 @@ struct bfin_serial_port {
99 struct work_struct tx_dma_workqueue; 99 struct work_struct tx_dma_workqueue;
100#endif 100#endif
101#ifdef CONFIG_SERIAL_BFIN_CTSRTS 101#ifdef CONFIG_SERIAL_BFIN_CTSRTS
102 struct timer_list cts_timer;
103 int cts_pin; 102 int cts_pin;
104 int rts_pin; 103 int rts_pin;
105#endif 104#endif
@@ -167,29 +166,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
167}; 166};
168 167
169#define DRIVER_NAME "bfin-uart" 168#define DRIVER_NAME "bfin-uart"
170
171static void bfin_serial_hw_init(struct bfin_serial_port *uart)
172{
173
174#ifdef CONFIG_SERIAL_BFIN_UART0
175 peripheral_request(P_UART0_TX, DRIVER_NAME);
176 peripheral_request(P_UART0_RX, DRIVER_NAME);
177#endif
178
179#ifdef CONFIG_SERIAL_BFIN_UART1
180 peripheral_request(P_UART1_TX, DRIVER_NAME);
181 peripheral_request(P_UART1_RX, DRIVER_NAME);
182#endif
183
184#ifdef CONFIG_SERIAL_BFIN_CTSRTS
185 if (uart->cts_pin >= 0) {
186 gpio_request(uart->cts_pin, DRIVER_NAME);
187 gpio_direction_input(uart->cts_pin);
188 }
189
190 if (uart->rts_pin >= 0) {
191 gpio_request(uart->rts_pin, DRIVER_NAME);
192 gpio_direction_output(uart->rts_pin, 0);
193 }
194#endif
195}
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
index c05e79cba257..388e2328aeba 100644
--- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
@@ -181,48 +181,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
181}; 181};
182 182
183#define DRIVER_NAME "bfin-uart" 183#define DRIVER_NAME "bfin-uart"
184
185static void bfin_serial_hw_init(struct bfin_serial_port *uart)
186{
187#ifdef CONFIG_SERIAL_BFIN_UART0
188 peripheral_request(P_UART0_TX, DRIVER_NAME);
189 peripheral_request(P_UART0_RX, DRIVER_NAME);
190#endif
191
192#ifdef CONFIG_SERIAL_BFIN_UART1
193 peripheral_request(P_UART1_TX, DRIVER_NAME);
194 peripheral_request(P_UART1_RX, DRIVER_NAME);
195
196#ifdef CONFIG_BFIN_UART1_CTSRTS
197 peripheral_request(P_UART1_RTS, DRIVER_NAME);
198 peripheral_request(P_UART1_CTS, DRIVER_NAME);
199#endif
200#endif
201
202#ifdef CONFIG_SERIAL_BFIN_UART2
203 peripheral_request(P_UART2_TX, DRIVER_NAME);
204 peripheral_request(P_UART2_RX, DRIVER_NAME);
205#endif
206
207#ifdef CONFIG_SERIAL_BFIN_UART3
208 peripheral_request(P_UART3_TX, DRIVER_NAME);
209 peripheral_request(P_UART3_RX, DRIVER_NAME);
210
211#ifdef CONFIG_BFIN_UART3_CTSRTS
212 peripheral_request(P_UART3_RTS, DRIVER_NAME);
213 peripheral_request(P_UART3_CTS, DRIVER_NAME);
214#endif
215#endif
216 SSYNC();
217#ifdef CONFIG_SERIAL_BFIN_CTSRTS
218 if (uart->cts_pin >= 0) {
219 gpio_request(uart->cts_pin, DRIVER_NAME);
220 gpio_direction_input(uart->cts_pin);
221 }
222
223 if (uart->rts_pin >= 0) {
224 gpio_request(uart->rts_pin, DRIVER_NAME);
225 gpio_direction_output(uart->rts_pin, 0);
226 }
227#endif
228}
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
index ca8c5f645209..d0469e3e16d8 100644
--- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
@@ -142,23 +142,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
142}; 142};
143 143
144#define DRIVER_NAME "bfin-uart" 144#define DRIVER_NAME "bfin-uart"
145
146static void bfin_serial_hw_init(struct bfin_serial_port *uart)
147{
148
149#ifdef CONFIG_SERIAL_BFIN_UART0
150 peripheral_request(P_UART0_TX, DRIVER_NAME);
151 peripheral_request(P_UART0_RX, DRIVER_NAME);
152#endif
153
154#ifdef CONFIG_SERIAL_BFIN_CTSRTS
155 if (uart->cts_pin >= 0) {
156 gpio_request(uart->cts_pin, DRIVER_NAME);
157 gpio_direction_input(uart->cts_pin);
158 }
159 if (uart->rts_pin >= 0) {
160 gpio_request(uart->rts_pin, DRIVER_NAME);
161 gpio_direction_output(uart->rts_pin, 0);
162 }
163#endif
164}
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
69static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); 68static 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);
71static void bfin_serial_tx_chars(struct bfin_serial_port *uart); 70static void bfin_serial_tx_chars(struct bfin_serial_port *uart);
72#endif 71#endif
73 72
74static void bfin_serial_mctrl_check(struct bfin_serial_port *uart);
75
76static void bfin_serial_reset_irda(struct uart_port *port); 73static 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 */
530static void bfin_serial_mctrl_check(struct bfin_serial_port *uart) 516static 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
704static void 705static void
@@ -864,6 +865,20 @@ static void bfin_serial_set_ldisc(struct uart_port *port)
864 } 865 }
865} 866}
866 867
868static 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
868static void bfin_serial_poll_put_char(struct uart_port *port, unsigned char chr) 883static 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
912static 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
926static struct uart_ops bfin_serial_pops = { 927static 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
956static 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
955static void __init bfin_serial_init_ports(void) 989static 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)