aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWolfram Sang <w.sang@pengutronix.de>2008-12-21 04:54:32 -0500
committerGrant Likely <grant.likely@secretlab.ca>2008-12-21 04:54:32 -0500
commitaec739e010f8163eac225f4e331ac7fbd59ac5c8 (patch)
tree85b01751d95c1635d0825c02d43654444543fb21
parentb65149880d0467287fa4c7b4f19953392323f4ac (diff)
powerpc/mpc5200: add rts/cts handling in PSC UART driver
Add RTS/CTS-support for the PSC of the MPC5200B. Tested with a Phytec MPC5200B-IO. Signed-off-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r--arch/powerpc/include/asm/mpc52xx_psc.h11
-rw-r--r--drivers/serial/mpc52xx_uart.c41
2 files changed, 47 insertions, 5 deletions
diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/include/asm/mpc52xx_psc.h
index 8917ed630565..a218da6bec7c 100644
--- a/arch/powerpc/include/asm/mpc52xx_psc.h
+++ b/arch/powerpc/include/asm/mpc52xx_psc.h
@@ -68,12 +68,20 @@
68#define MPC52xx_PSC_IMR_ORERR 0x1000 68#define MPC52xx_PSC_IMR_ORERR 0x1000
69#define MPC52xx_PSC_IMR_IPC 0x8000 69#define MPC52xx_PSC_IMR_IPC 0x8000
70 70
71/* PSC input port change bit */ 71/* PSC input port change bits */
72#define MPC52xx_PSC_CTS 0x01 72#define MPC52xx_PSC_CTS 0x01
73#define MPC52xx_PSC_DCD 0x02 73#define MPC52xx_PSC_DCD 0x02
74#define MPC52xx_PSC_D_CTS 0x10 74#define MPC52xx_PSC_D_CTS 0x10
75#define MPC52xx_PSC_D_DCD 0x20 75#define MPC52xx_PSC_D_DCD 0x20
76 76
77/* PSC acr bits */
78#define MPC52xx_PSC_IEC_CTS 0x01
79#define MPC52xx_PSC_IEC_DCD 0x02
80
81/* PSC output port bits */
82#define MPC52xx_PSC_OP_RTS 0x01
83#define MPC52xx_PSC_OP_RES 0x02
84
77/* PSC mode fields */ 85/* PSC mode fields */
78#define MPC52xx_PSC_MODE_5_BITS 0x00 86#define MPC52xx_PSC_MODE_5_BITS 0x00
79#define MPC52xx_PSC_MODE_6_BITS 0x01 87#define MPC52xx_PSC_MODE_6_BITS 0x01
@@ -91,6 +99,7 @@
91#define MPC52xx_PSC_MODE_ONE_STOP_5_BITS 0x00 99#define MPC52xx_PSC_MODE_ONE_STOP_5_BITS 0x00
92#define MPC52xx_PSC_MODE_ONE_STOP 0x07 100#define MPC52xx_PSC_MODE_ONE_STOP 0x07
93#define MPC52xx_PSC_MODE_TWO_STOP 0x0f 101#define MPC52xx_PSC_MODE_TWO_STOP 0x0f
102#define MPC52xx_PSC_MODE_TXCTS 0x10
94 103
95#define MPC52xx_PSC_RFNUM_MASK 0x01ff 104#define MPC52xx_PSC_RFNUM_MASK 0x01ff
96 105
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index d82650d54391..d2a1fc29834e 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -429,14 +429,24 @@ mpc52xx_uart_tx_empty(struct uart_port *port)
429static void 429static void
430mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) 430mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
431{ 431{
432 /* Not implemented */ 432 if (mctrl & TIOCM_RTS)
433 out_8(&PSC(port)->op1, MPC52xx_PSC_OP_RTS);
434 else
435 out_8(&PSC(port)->op0, MPC52xx_PSC_OP_RTS);
433} 436}
434 437
435static unsigned int 438static unsigned int
436mpc52xx_uart_get_mctrl(struct uart_port *port) 439mpc52xx_uart_get_mctrl(struct uart_port *port)
437{ 440{
438 /* Not implemented */ 441 unsigned int ret = TIOCM_DSR;
439 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; 442 u8 status = in_8(&PSC(port)->mpc52xx_psc_ipcr);
443
444 if (!(status & MPC52xx_PSC_CTS))
445 ret |= TIOCM_CTS;
446 if (!(status & MPC52xx_PSC_DCD))
447 ret |= TIOCM_CAR;
448
449 return ret;
440} 450}
441 451
442static void 452static void
@@ -479,7 +489,15 @@ mpc52xx_uart_stop_rx(struct uart_port *port)
479static void 489static void
480mpc52xx_uart_enable_ms(struct uart_port *port) 490mpc52xx_uart_enable_ms(struct uart_port *port)
481{ 491{
482 /* Not implemented */ 492 struct mpc52xx_psc __iomem *psc = PSC(port);
493
494 /* clear D_*-bits by reading them */
495 in_8(&psc->mpc52xx_psc_ipcr);
496 /* enable CTS and DCD as IPC interrupts */
497 out_8(&psc->mpc52xx_psc_acr, MPC52xx_PSC_IEC_CTS | MPC52xx_PSC_IEC_DCD);
498
499 port->read_status_mask |= MPC52xx_PSC_IMR_IPC;
500 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
483} 501}
484 502
485static void 503static void
@@ -580,6 +598,10 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
580 MPC52xx_PSC_MODE_ONE_STOP_5_BITS : 598 MPC52xx_PSC_MODE_ONE_STOP_5_BITS :
581 MPC52xx_PSC_MODE_ONE_STOP; 599 MPC52xx_PSC_MODE_ONE_STOP;
582 600
601 if (new->c_cflag & CRTSCTS) {
602 mr1 |= MPC52xx_PSC_MODE_RXRTS;
603 mr2 |= MPC52xx_PSC_MODE_TXCTS;
604 }
583 605
584 baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); 606 baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
585 quot = uart_get_divisor(port, baud); 607 quot = uart_get_divisor(port, baud);
@@ -617,6 +639,9 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
617 out_8(&psc->ctur, ctr >> 8); 639 out_8(&psc->ctur, ctr >> 8);
618 out_8(&psc->ctlr, ctr & 0xff); 640 out_8(&psc->ctlr, ctr & 0xff);
619 641
642 if (UART_ENABLE_MS(port, new->c_cflag))
643 mpc52xx_uart_enable_ms(port);
644
620 /* Reenable TX & RX */ 645 /* Reenable TX & RX */
621 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); 646 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
622 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); 647 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
@@ -832,6 +857,7 @@ mpc52xx_uart_int(int irq, void *dev_id)
832 struct uart_port *port = dev_id; 857 struct uart_port *port = dev_id;
833 unsigned long pass = ISR_PASS_LIMIT; 858 unsigned long pass = ISR_PASS_LIMIT;
834 unsigned int keepgoing; 859 unsigned int keepgoing;
860 u8 status;
835 861
836 spin_lock(&port->lock); 862 spin_lock(&port->lock);
837 863
@@ -848,6 +874,13 @@ mpc52xx_uart_int(int irq, void *dev_id)
848 if (psc_ops->tx_rdy(port)) 874 if (psc_ops->tx_rdy(port))
849 keepgoing |= mpc52xx_uart_int_tx_chars(port); 875 keepgoing |= mpc52xx_uart_int_tx_chars(port);
850 876
877 status = in_8(&PSC(port)->mpc52xx_psc_ipcr);
878 if (status & MPC52xx_PSC_D_DCD)
879 uart_handle_dcd_change(port, !(status & MPC52xx_PSC_DCD));
880
881 if (status & MPC52xx_PSC_D_CTS)
882 uart_handle_cts_change(port, !(status & MPC52xx_PSC_CTS));
883
851 /* Limit number of iteration */ 884 /* Limit number of iteration */
852 if (!(--pass)) 885 if (!(--pass))
853 keepgoing = 0; 886 keepgoing = 0;