diff options
Diffstat (limited to 'drivers/tty/serial/imx.c')
-rw-r--r-- | drivers/tty/serial/imx.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index a70356dad1b7..e3e152cbc75e 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -205,6 +205,7 @@ struct imx_port { | |||
205 | struct timer_list timer; | 205 | struct timer_list timer; |
206 | unsigned int old_status; | 206 | unsigned int old_status; |
207 | unsigned int have_rtscts:1; | 207 | unsigned int have_rtscts:1; |
208 | unsigned int have_rtsgpio:1; | ||
208 | unsigned int dte_mode:1; | 209 | unsigned int dte_mode:1; |
209 | unsigned int irda_inv_rx:1; | 210 | unsigned int irda_inv_rx:1; |
210 | unsigned int irda_inv_tx:1; | 211 | unsigned int irda_inv_tx:1; |
@@ -335,15 +336,15 @@ static void imx_port_ucrs_restore(struct uart_port *port, | |||
335 | 336 | ||
336 | static void imx_port_rts_active(struct imx_port *sport, unsigned long *ucr2) | 337 | static void imx_port_rts_active(struct imx_port *sport, unsigned long *ucr2) |
337 | { | 338 | { |
338 | *ucr2 &= ~UCR2_CTSC; | 339 | *ucr2 &= ~(UCR2_CTSC | UCR2_CTS); |
339 | *ucr2 |= UCR2_CTS; | ||
340 | 340 | ||
341 | mctrl_gpio_set(sport->gpios, sport->port.mctrl | TIOCM_RTS); | 341 | mctrl_gpio_set(sport->gpios, sport->port.mctrl | TIOCM_RTS); |
342 | } | 342 | } |
343 | 343 | ||
344 | static void imx_port_rts_inactive(struct imx_port *sport, unsigned long *ucr2) | 344 | static void imx_port_rts_inactive(struct imx_port *sport, unsigned long *ucr2) |
345 | { | 345 | { |
346 | *ucr2 &= ~(UCR2_CTSC | UCR2_CTS); | 346 | *ucr2 &= ~UCR2_CTSC; |
347 | *ucr2 |= UCR2_CTS; | ||
347 | 348 | ||
348 | mctrl_gpio_set(sport->gpios, sport->port.mctrl & ~TIOCM_RTS); | 349 | mctrl_gpio_set(sport->gpios, sport->port.mctrl & ~TIOCM_RTS); |
349 | } | 350 | } |
@@ -376,9 +377,9 @@ static void imx_stop_tx(struct uart_port *port) | |||
376 | readl(port->membase + USR2) & USR2_TXDC) { | 377 | readl(port->membase + USR2) & USR2_TXDC) { |
377 | temp = readl(port->membase + UCR2); | 378 | temp = readl(port->membase + UCR2); |
378 | if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) | 379 | if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) |
379 | imx_port_rts_inactive(sport, &temp); | ||
380 | else | ||
381 | imx_port_rts_active(sport, &temp); | 380 | imx_port_rts_active(sport, &temp); |
381 | else | ||
382 | imx_port_rts_inactive(sport, &temp); | ||
382 | temp |= UCR2_RXEN; | 383 | temp |= UCR2_RXEN; |
383 | writel(temp, port->membase + UCR2); | 384 | writel(temp, port->membase + UCR2); |
384 | 385 | ||
@@ -584,9 +585,9 @@ static void imx_start_tx(struct uart_port *port) | |||
584 | if (port->rs485.flags & SER_RS485_ENABLED) { | 585 | if (port->rs485.flags & SER_RS485_ENABLED) { |
585 | temp = readl(port->membase + UCR2); | 586 | temp = readl(port->membase + UCR2); |
586 | if (port->rs485.flags & SER_RS485_RTS_ON_SEND) | 587 | if (port->rs485.flags & SER_RS485_RTS_ON_SEND) |
587 | imx_port_rts_inactive(sport, &temp); | ||
588 | else | ||
589 | imx_port_rts_active(sport, &temp); | 588 | imx_port_rts_active(sport, &temp); |
589 | else | ||
590 | imx_port_rts_inactive(sport, &temp); | ||
590 | if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) | 591 | if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) |
591 | temp &= ~UCR2_RXEN; | 592 | temp &= ~UCR2_RXEN; |
592 | writel(temp, port->membase + UCR2); | 593 | writel(temp, port->membase + UCR2); |
@@ -1476,9 +1477,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1476 | */ | 1477 | */ |
1477 | if (port->rs485.flags & | 1478 | if (port->rs485.flags & |
1478 | SER_RS485_RTS_AFTER_SEND) | 1479 | SER_RS485_RTS_AFTER_SEND) |
1479 | imx_port_rts_inactive(sport, &ucr2); | ||
1480 | else | ||
1481 | imx_port_rts_active(sport, &ucr2); | 1480 | imx_port_rts_active(sport, &ucr2); |
1481 | else | ||
1482 | imx_port_rts_inactive(sport, &ucr2); | ||
1482 | } else { | 1483 | } else { |
1483 | imx_port_rts_auto(sport, &ucr2); | 1484 | imx_port_rts_auto(sport, &ucr2); |
1484 | } | 1485 | } |
@@ -1488,9 +1489,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1488 | } else if (port->rs485.flags & SER_RS485_ENABLED) { | 1489 | } else if (port->rs485.flags & SER_RS485_ENABLED) { |
1489 | /* disable transmitter */ | 1490 | /* disable transmitter */ |
1490 | if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) | 1491 | if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) |
1491 | imx_port_rts_inactive(sport, &ucr2); | ||
1492 | else | ||
1493 | imx_port_rts_active(sport, &ucr2); | 1492 | imx_port_rts_active(sport, &ucr2); |
1493 | else | ||
1494 | imx_port_rts_inactive(sport, &ucr2); | ||
1494 | } | 1495 | } |
1495 | 1496 | ||
1496 | 1497 | ||
@@ -1725,16 +1726,16 @@ static int imx_rs485_config(struct uart_port *port, | |||
1725 | rs485conf->delay_rts_after_send = 0; | 1726 | rs485conf->delay_rts_after_send = 0; |
1726 | 1727 | ||
1727 | /* RTS is required to control the transmitter */ | 1728 | /* RTS is required to control the transmitter */ |
1728 | if (!sport->have_rtscts) | 1729 | if (!sport->have_rtscts && !sport->have_rtsgpio) |
1729 | rs485conf->flags &= ~SER_RS485_ENABLED; | 1730 | rs485conf->flags &= ~SER_RS485_ENABLED; |
1730 | 1731 | ||
1731 | if (rs485conf->flags & SER_RS485_ENABLED) { | 1732 | if (rs485conf->flags & SER_RS485_ENABLED) { |
1732 | /* disable transmitter */ | 1733 | /* disable transmitter */ |
1733 | temp = readl(sport->port.membase + UCR2); | 1734 | temp = readl(sport->port.membase + UCR2); |
1734 | if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) | 1735 | if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) |
1735 | imx_port_rts_inactive(sport, &temp); | ||
1736 | else | ||
1737 | imx_port_rts_active(sport, &temp); | 1736 | imx_port_rts_active(sport, &temp); |
1737 | else | ||
1738 | imx_port_rts_inactive(sport, &temp); | ||
1738 | writel(temp, sport->port.membase + UCR2); | 1739 | writel(temp, sport->port.membase + UCR2); |
1739 | } | 1740 | } |
1740 | 1741 | ||
@@ -2048,6 +2049,9 @@ static int serial_imx_probe_dt(struct imx_port *sport, | |||
2048 | if (of_get_property(np, "fsl,dte-mode", NULL)) | 2049 | if (of_get_property(np, "fsl,dte-mode", NULL)) |
2049 | sport->dte_mode = 1; | 2050 | sport->dte_mode = 1; |
2050 | 2051 | ||
2052 | if (of_get_property(np, "rts-gpios", NULL)) | ||
2053 | sport->have_rtsgpio = 1; | ||
2054 | |||
2051 | return 0; | 2055 | return 0; |
2052 | } | 2056 | } |
2053 | #else | 2057 | #else |