aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/bfin_sport_uart.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-05-25 02:38:26 -0400
committerGrant Likely <grant.likely@secretlab.ca>2010-05-25 02:38:26 -0400
commitb1e50ebcf24668e57f058deb48b0704b5391ed0f (patch)
tree17e1b69b249d0738317b732186340c9dd053f1a1 /drivers/serial/bfin_sport_uart.c
parent0c2a2ae32793e3500a15a449612485f5d17dd431 (diff)
parent7e125f7b9cbfce4101191b8076d606c517a73066 (diff)
Merge remote branch 'origin' into secretlab/next-spi
Diffstat (limited to 'drivers/serial/bfin_sport_uart.c')
-rw-r--r--drivers/serial/bfin_sport_uart.c209
1 files changed, 142 insertions, 67 deletions
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index c88f8ad3ff82..e57fb3d228e2 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -34,32 +34,12 @@
34#include <linux/tty_flip.h> 34#include <linux/tty_flip.h>
35#include <linux/serial_core.h> 35#include <linux/serial_core.h>
36 36
37#include <asm/bfin_sport.h>
37#include <asm/delay.h> 38#include <asm/delay.h>
38#include <asm/portmux.h> 39#include <asm/portmux.h>
39 40
40#include "bfin_sport_uart.h" 41#include "bfin_sport_uart.h"
41 42
42#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
43unsigned short bfin_uart_pin_req_sport0[] =
44 {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \
45 P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0};
46#endif
47#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
48unsigned short bfin_uart_pin_req_sport1[] =
49 {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \
50 P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0};
51#endif
52#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
53unsigned short bfin_uart_pin_req_sport2[] =
54 {P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, \
55 P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0};
56#endif
57#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
58unsigned short bfin_uart_pin_req_sport3[] =
59 {P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS, \
60 P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0};
61#endif
62
63struct sport_uart_port { 43struct sport_uart_port {
64 struct uart_port port; 44 struct uart_port port;
65 int err_irq; 45 int err_irq;
@@ -69,9 +49,13 @@ struct sport_uart_port {
69 unsigned short txmask2; 49 unsigned short txmask2;
70 unsigned char stopb; 50 unsigned char stopb;
71/* unsigned char parib; */ 51/* unsigned char parib; */
52#ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
53 int cts_pin;
54 int rts_pin;
55#endif
72}; 56};
73 57
74static void sport_uart_tx_chars(struct sport_uart_port *up); 58static int sport_uart_tx_chars(struct sport_uart_port *up);
75static void sport_stop_tx(struct uart_port *port); 59static void sport_stop_tx(struct uart_port *port);
76 60
77static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) 61static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value)
@@ -219,6 +203,59 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id)
219 return IRQ_HANDLED; 203 return IRQ_HANDLED;
220} 204}
221 205
206#ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
207static unsigned int sport_get_mctrl(struct uart_port *port)
208{
209 struct sport_uart_port *up = (struct sport_uart_port *)port;
210 if (up->cts_pin < 0)
211 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
212
213 /* CTS PIN is negative assertive. */
214 if (SPORT_UART_GET_CTS(up))
215 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
216 else
217 return TIOCM_DSR | TIOCM_CAR;
218}
219
220static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl)
221{
222 struct sport_uart_port *up = (struct sport_uart_port *)port;
223 if (up->rts_pin < 0)
224 return;
225
226 /* RTS PIN is negative assertive. */
227 if (mctrl & TIOCM_RTS)
228 SPORT_UART_ENABLE_RTS(up);
229 else
230 SPORT_UART_DISABLE_RTS(up);
231}
232
233/*
234 * Handle any change of modem status signal.
235 */
236static irqreturn_t sport_mctrl_cts_int(int irq, void *dev_id)
237{
238 struct sport_uart_port *up = (struct sport_uart_port *)dev_id;
239 unsigned int status;
240
241 status = sport_get_mctrl(&up->port);
242 uart_handle_cts_change(&up->port, status & TIOCM_CTS);
243
244 return IRQ_HANDLED;
245}
246#else
247static unsigned int sport_get_mctrl(struct uart_port *port)
248{
249 pr_debug("%s enter\n", __func__);
250 return TIOCM_CTS | TIOCM_CD | TIOCM_DSR;
251}
252
253static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl)
254{
255 pr_debug("%s enter\n", __func__);
256}
257#endif
258
222/* Reqeust IRQ, Setup clock */ 259/* Reqeust IRQ, Setup clock */
223static int sport_startup(struct uart_port *port) 260static int sport_startup(struct uart_port *port)
224{ 261{
@@ -247,6 +284,21 @@ static int sport_startup(struct uart_port *port)
247 goto fail2; 284 goto fail2;
248 } 285 }
249 286
287#ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
288 if (up->cts_pin >= 0) {
289 if (request_irq(gpio_to_irq(up->cts_pin),
290 sport_mctrl_cts_int,
291 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
292 IRQF_DISABLED, "BFIN_SPORT_UART_CTS", up)) {
293 up->cts_pin = -1;
294 dev_info(port->dev, "Unable to attach BlackFin UART \
295 over SPORT CTS interrupt. So, disable it.\n");
296 }
297 }
298 if (up->rts_pin >= 0)
299 gpio_direction_output(up->rts_pin, 0);
300#endif
301
250 return 0; 302 return 0;
251 fail2: 303 fail2:
252 free_irq(up->port.irq+1, up); 304 free_irq(up->port.irq+1, up);
@@ -256,23 +308,35 @@ static int sport_startup(struct uart_port *port)
256 return ret; 308 return ret;
257} 309}
258 310
259static void sport_uart_tx_chars(struct sport_uart_port *up) 311/*
312 * sport_uart_tx_chars
313 *
314 * ret 1 means need to enable sport.
315 * ret 0 means do nothing.
316 */
317static int sport_uart_tx_chars(struct sport_uart_port *up)
260{ 318{
261 struct circ_buf *xmit = &up->port.state->xmit; 319 struct circ_buf *xmit = &up->port.state->xmit;
262 320
263 if (SPORT_GET_STAT(up) & TXF) 321 if (SPORT_GET_STAT(up) & TXF)
264 return; 322 return 0;
265 323
266 if (up->port.x_char) { 324 if (up->port.x_char) {
267 tx_one_byte(up, up->port.x_char); 325 tx_one_byte(up, up->port.x_char);
268 up->port.icount.tx++; 326 up->port.icount.tx++;
269 up->port.x_char = 0; 327 up->port.x_char = 0;
270 return; 328 return 1;
271 } 329 }
272 330
273 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { 331 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
274 sport_stop_tx(&up->port); 332 /* The waiting loop to stop SPORT TX from TX interrupt is
275 return; 333 * too long. This may block SPORT RX interrupts and cause
334 * RX FIFO overflow. So, do stop sport TX only after the last
335 * char in TX FIFO is moved into the shift register.
336 */
337 if (SPORT_GET_STAT(up) & TXHRE)
338 sport_stop_tx(&up->port);
339 return 0;
276 } 340 }
277 341
278 while(!(SPORT_GET_STAT(up) & TXF) && !uart_circ_empty(xmit)) { 342 while(!(SPORT_GET_STAT(up) & TXF) && !uart_circ_empty(xmit)) {
@@ -283,6 +347,8 @@ static void sport_uart_tx_chars(struct sport_uart_port *up)
283 347
284 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 348 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
285 uart_write_wakeup(&up->port); 349 uart_write_wakeup(&up->port);
350
351 return 1;
286} 352}
287 353
288static unsigned int sport_tx_empty(struct uart_port *port) 354static unsigned int sport_tx_empty(struct uart_port *port)
@@ -298,23 +364,15 @@ static unsigned int sport_tx_empty(struct uart_port *port)
298 return 0; 364 return 0;
299} 365}
300 366
301static unsigned int sport_get_mctrl(struct uart_port *port)
302{
303 pr_debug("%s enter\n", __func__);
304 return (TIOCM_CTS | TIOCM_CD | TIOCM_DSR);
305}
306
307static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl)
308{
309 pr_debug("%s enter\n", __func__);
310}
311
312static void sport_stop_tx(struct uart_port *port) 367static void sport_stop_tx(struct uart_port *port)
313{ 368{
314 struct sport_uart_port *up = (struct sport_uart_port *)port; 369 struct sport_uart_port *up = (struct sport_uart_port *)port;
315 370
316 pr_debug("%s enter\n", __func__); 371 pr_debug("%s enter\n", __func__);
317 372
373 if (!(SPORT_GET_TCR1(up) & TSPEN))
374 return;
375
318 /* Although the hold register is empty, last byte is still in shift 376 /* Although the hold register is empty, last byte is still in shift
319 * register and not sent out yet. So, put a dummy data into TX FIFO. 377 * register and not sent out yet. So, put a dummy data into TX FIFO.
320 * Then, sport tx stops when last byte is shift out and the dummy 378 * Then, sport tx stops when last byte is shift out and the dummy
@@ -337,11 +395,12 @@ static void sport_start_tx(struct uart_port *port)
337 pr_debug("%s enter\n", __func__); 395 pr_debug("%s enter\n", __func__);
338 396
339 /* Write data into SPORT FIFO before enable SPROT to transmit */ 397 /* Write data into SPORT FIFO before enable SPROT to transmit */
340 sport_uart_tx_chars(up); 398 if (sport_uart_tx_chars(up)) {
399 /* Enable transmit, then an interrupt will generated */
400 SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
401 SSYNC();
402 }
341 403
342 /* Enable transmit, then an interrupt will generated */
343 SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
344 SSYNC();
345 pr_debug("%s exit\n", __func__); 404 pr_debug("%s exit\n", __func__);
346} 405}
347 406
@@ -379,6 +438,10 @@ static void sport_shutdown(struct uart_port *port)
379 free_irq(up->port.irq, up); 438 free_irq(up->port.irq, up);
380 free_irq(up->port.irq+1, up); 439 free_irq(up->port.irq+1, up);
381 free_irq(up->err_irq, up); 440 free_irq(up->err_irq, up);
441#ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
442 if (up->cts_pin >= 0)
443 free_irq(gpio_to_irq(up->cts_pin), up);
444#endif
382} 445}
383 446
384static const char *sport_type(struct uart_port *port) 447static const char *sport_type(struct uart_port *port)
@@ -448,27 +511,14 @@ static void sport_set_termios(struct uart_port *port,
448 /* up->parib = 1; */ 511 /* up->parib = 1; */
449 } 512 }
450 513
451 port->read_status_mask = OE; 514 spin_lock_irqsave(&up->port.lock, flags);
452 if (termios->c_iflag & INPCK) 515
453 port->read_status_mask |= (FE | PE); 516 port->read_status_mask = 0;
454 if (termios->c_iflag & (BRKINT | PARMRK))
455 port->read_status_mask |= BI;
456 517
457 /* 518 /*
458 * Characters to ignore 519 * Characters to ignore
459 */ 520 */
460 port->ignore_status_mask = 0; 521 port->ignore_status_mask = 0;
461 if (termios->c_iflag & IGNPAR)
462 port->ignore_status_mask |= FE | PE;
463 if (termios->c_iflag & IGNBRK) {
464 port->ignore_status_mask |= BI;
465 /*
466 * If we're ignoring parity and break indicators,
467 * ignore overruns too (for real raw support).
468 */
469 if (termios->c_iflag & IGNPAR)
470 port->ignore_status_mask |= OE;
471 }
472 522
473 /* RX extract mask */ 523 /* RX extract mask */
474 up->rxmask = 0x01 | (((up->csize + up->stopb) * 2 - 1) << 0x8); 524 up->rxmask = 0x01 | (((up->csize + up->stopb) * 2 - 1) << 0x8);
@@ -488,8 +538,6 @@ static void sport_set_termios(struct uart_port *port,
488 /* uart baud rate */ 538 /* uart baud rate */
489 port->uartclk = uart_get_baud_rate(port, termios, old, 0, get_sclk()/16); 539 port->uartclk = uart_get_baud_rate(port, termios, old, 0, get_sclk()/16);
490 540
491 spin_lock_irqsave(&up->port.lock, flags);
492
493 /* Disable UART */ 541 /* Disable UART */
494 SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); 542 SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN);
495 SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); 543 SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN);
@@ -542,6 +590,8 @@ struct uart_ops sport_uart_ops = {
542static struct sport_uart_port *bfin_sport_uart_ports[BFIN_SPORT_UART_MAX_PORTS]; 590static struct sport_uart_port *bfin_sport_uart_ports[BFIN_SPORT_UART_MAX_PORTS];
543 591
544#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE 592#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
593#define CLASS_BFIN_SPORT_CONSOLE "bfin-sport-console"
594
545static int __init 595static int __init
546sport_uart_console_setup(struct console *co, char *options) 596sport_uart_console_setup(struct console *co, char *options)
547{ 597{
@@ -549,7 +599,11 @@ sport_uart_console_setup(struct console *co, char *options)
549 int baud = 57600; 599 int baud = 57600;
550 int bits = 8; 600 int bits = 8;
551 int parity = 'n'; 601 int parity = 'n';
602# ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
603 int flow = 'r';
604# else
552 int flow = 'n'; 605 int flow = 'n';
606# endif
553 607
554 /* Check whether an invalid uart number has been specified */ 608 /* Check whether an invalid uart number has been specified */
555 if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS) 609 if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS)
@@ -690,11 +744,11 @@ static int __devinit sport_uart_probe(struct platform_device *pdev)
690 744
691 if (bfin_sport_uart_ports[pdev->id] == NULL) { 745 if (bfin_sport_uart_ports[pdev->id] == NULL) {
692 bfin_sport_uart_ports[pdev->id] = 746 bfin_sport_uart_ports[pdev->id] =
693 kmalloc(sizeof(struct sport_uart_port), GFP_KERNEL); 747 kzalloc(sizeof(struct sport_uart_port), GFP_KERNEL);
694 sport = bfin_sport_uart_ports[pdev->id]; 748 sport = bfin_sport_uart_ports[pdev->id];
695 if (!sport) { 749 if (!sport) {
696 dev_err(&pdev->dev, 750 dev_err(&pdev->dev,
697 "Fail to kmalloc sport_uart_port\n"); 751 "Fail to malloc sport_uart_port\n");
698 return -ENOMEM; 752 return -ENOMEM;
699 } 753 }
700 754
@@ -720,13 +774,13 @@ static int __devinit sport_uart_probe(struct platform_device *pdev)
720 goto out_error_free_peripherals; 774 goto out_error_free_peripherals;
721 } 775 }
722 776
723 sport->port.membase = ioremap(res->start, 777 sport->port.membase = ioremap(res->start, resource_size(res));
724 res->end - res->start);
725 if (!sport->port.membase) { 778 if (!sport->port.membase) {
726 dev_err(&pdev->dev, "Cannot map sport IO\n"); 779 dev_err(&pdev->dev, "Cannot map sport IO\n");
727 ret = -ENXIO; 780 ret = -ENXIO;
728 goto out_error_free_peripherals; 781 goto out_error_free_peripherals;
729 } 782 }
783 sport->port.mapbase = res->start;
730 784
731 sport->port.irq = platform_get_irq(pdev, 0); 785 sport->port.irq = platform_get_irq(pdev, 0);
732 if (sport->port.irq < 0) { 786 if (sport->port.irq < 0) {
@@ -741,6 +795,22 @@ static int __devinit sport_uart_probe(struct platform_device *pdev)
741 ret = -ENOENT; 795 ret = -ENOENT;
742 goto out_error_unmap; 796 goto out_error_unmap;
743 } 797 }
798#ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
799 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
800 if (res == NULL)
801 sport->cts_pin = -1;
802 else
803 sport->cts_pin = res->start;
804
805 res = platform_get_resource(pdev, IORESOURCE_IO, 1);
806 if (res == NULL)
807 sport->rts_pin = -1;
808 else
809 sport->rts_pin = res->start;
810
811 if (sport->rts_pin >= 0)
812 gpio_request(sport->rts_pin, DRV_NAME);
813#endif
744 } 814 }
745 815
746#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE 816#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
@@ -779,6 +849,10 @@ static int __devexit sport_uart_remove(struct platform_device *pdev)
779 849
780 if (sport) { 850 if (sport) {
781 uart_remove_one_port(&sport_uart_reg, &sport->port); 851 uart_remove_one_port(&sport_uart_reg, &sport->port);
852#ifdef CONFIG_SERIAL_BFIN_CTSRTS
853 if (sport->rts_pin >= 0)
854 gpio_free(sport->rts_pin);
855#endif
782 iounmap(sport->port.membase); 856 iounmap(sport->port.membase);
783 peripheral_free_list( 857 peripheral_free_list(
784 (unsigned short *)pdev->dev.platform_data); 858 (unsigned short *)pdev->dev.platform_data);
@@ -802,7 +876,7 @@ static struct platform_driver sport_uart_driver = {
802 876
803#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE 877#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
804static __initdata struct early_platform_driver early_sport_uart_driver = { 878static __initdata struct early_platform_driver early_sport_uart_driver = {
805 .class_str = DRV_NAME, 879 .class_str = CLASS_BFIN_SPORT_CONSOLE,
806 .pdrv = &sport_uart_driver, 880 .pdrv = &sport_uart_driver,
807 .requested_id = EARLY_PLATFORM_ID_UNSET, 881 .requested_id = EARLY_PLATFORM_ID_UNSET,
808}; 882};
@@ -811,7 +885,8 @@ static int __init sport_uart_rs_console_init(void)
811{ 885{
812 early_platform_driver_register(&early_sport_uart_driver, DRV_NAME); 886 early_platform_driver_register(&early_sport_uart_driver, DRV_NAME);
813 887
814 early_platform_driver_probe(DRV_NAME, BFIN_SPORT_UART_MAX_PORTS, 0); 888 early_platform_driver_probe(CLASS_BFIN_SPORT_CONSOLE,
889 BFIN_SPORT_UART_MAX_PORTS, 0);
815 890
816 register_console(&sport_uart_console); 891 register_console(&sport_uart_console);
817 892
@@ -824,7 +899,7 @@ static int __init sport_uart_init(void)
824{ 899{
825 int ret; 900 int ret;
826 901
827 pr_info("Serial: Blackfin uart over sport driver\n"); 902 pr_info("Blackfin uart over sport driver\n");
828 903
829 ret = uart_register_driver(&sport_uart_reg); 904 ret = uart_register_driver(&sport_uart_reg);
830 if (ret) { 905 if (ret) {