@@ -917,6 +917,52 @@ static void lpuart_dma_rx_free(struct uart_port *port)
917917 sport -> dma_rx_cookie = - EINVAL ;
918918}
919919
920+ static int lpuart_config_rs485 (struct uart_port * port ,
921+ struct serial_rs485 * rs485 )
922+ {
923+ struct lpuart_port * sport = container_of (port ,
924+ struct lpuart_port , port );
925+
926+ u8 modem = readb (sport -> port .membase + UARTMODEM ) &
927+ ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE );
928+ writeb (modem , sport -> port .membase + UARTMODEM );
929+
930+ if (rs485 -> flags & SER_RS485_ENABLED ) {
931+ /* Enable auto RS-485 RTS mode */
932+ modem |= UARTMODEM_TXRTSE ;
933+
934+ /*
935+ * RTS needs to be logic HIGH either during transer _or_ after
936+ * transfer, other variants are not supported by the hardware.
937+ */
938+
939+ if (!(rs485 -> flags & (SER_RS485_RTS_ON_SEND |
940+ SER_RS485_RTS_AFTER_SEND )))
941+ rs485 -> flags |= SER_RS485_RTS_ON_SEND ;
942+
943+ if (rs485 -> flags & SER_RS485_RTS_ON_SEND &&
944+ rs485 -> flags & SER_RS485_RTS_AFTER_SEND )
945+ rs485 -> flags &= ~SER_RS485_RTS_AFTER_SEND ;
946+
947+ /*
948+ * The hardware defaults to RTS logic HIGH while transfer.
949+ * Switch polarity in case RTS shall be logic HIGH
950+ * after transfer.
951+ * Note: UART is assumed to be active high.
952+ */
953+ if (rs485 -> flags & SER_RS485_RTS_ON_SEND )
954+ modem &= ~UARTMODEM_TXRTSPOL ;
955+ else if (rs485 -> flags & SER_RS485_RTS_AFTER_SEND )
956+ modem |= UARTMODEM_TXRTSPOL ;
957+ }
958+
959+ /* Store the new configuration */
960+ sport -> port .rs485 = * rs485 ;
961+
962+ writeb (modem , sport -> port .membase + UARTMODEM );
963+ return 0 ;
964+ }
965+
920966static unsigned int lpuart_get_mctrl (struct uart_port * port )
921967{
922968 unsigned int temp = 0 ;
@@ -950,17 +996,22 @@ static unsigned int lpuart32_get_mctrl(struct uart_port *port)
950996static void lpuart_set_mctrl (struct uart_port * port , unsigned int mctrl )
951997{
952998 unsigned char temp ;
999+ struct lpuart_port * sport = container_of (port ,
1000+ struct lpuart_port , port );
9531001
954- temp = readb (port -> membase + UARTMODEM ) &
1002+ /* Make sure RXRTSE bit is not set when RS485 is enabled */
1003+ if (!(sport -> port .rs485 .flags & SER_RS485_ENABLED )) {
1004+ temp = readb (sport -> port .membase + UARTMODEM ) &
9551005 ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE );
9561006
957- if (mctrl & TIOCM_RTS )
958- temp |= UARTMODEM_RXRTSE ;
1007+ if (mctrl & TIOCM_RTS )
1008+ temp |= UARTMODEM_RXRTSE ;
9591009
960- if (mctrl & TIOCM_CTS )
961- temp |= UARTMODEM_TXCTSE ;
1010+ if (mctrl & TIOCM_CTS )
1011+ temp |= UARTMODEM_TXCTSE ;
9621012
963- writeb (temp , port -> membase + UARTMODEM );
1013+ writeb (temp , port -> membase + UARTMODEM );
1014+ }
9641015}
9651016
9661017static void lpuart32_set_mctrl (struct uart_port * port , unsigned int mctrl )
@@ -1256,6 +1307,13 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
12561307 cr1 |= UARTCR1_M ;
12571308 }
12581309
1310+ /*
1311+ * When auto RS-485 RTS mode is enabled,
1312+ * hardware flow control need to be disabled.
1313+ */
1314+ if (sport -> port .rs485 .flags & SER_RS485_ENABLED )
1315+ termios -> c_cflag &= ~CRTSCTS ;
1316+
12591317 if (termios -> c_cflag & CRTSCTS ) {
12601318 modem |= (UARTMODEM_RXRTSE | UARTMODEM_TXCTSE );
12611319 } else {
@@ -1870,6 +1928,8 @@ static int lpuart_probe(struct platform_device *pdev)
18701928 sport -> port .ops = & lpuart_pops ;
18711929 sport -> port .flags = UPF_BOOT_AUTOCONF ;
18721930
1931+ sport -> port .rs485_config = lpuart_config_rs485 ;
1932+
18731933 sport -> clk = devm_clk_get (& pdev -> dev , "ipg" );
18741934 if (IS_ERR (sport -> clk )) {
18751935 ret = PTR_ERR (sport -> clk );
@@ -1910,6 +1970,12 @@ static int lpuart_probe(struct platform_device *pdev)
19101970 dev_info (sport -> port .dev , "DMA rx channel request failed, "
19111971 "operating without rx DMA\n" );
19121972
1973+ if (of_property_read_bool (np , "linux,rs485-enabled-at-boot-time" )) {
1974+ sport -> port .rs485 .flags |= SER_RS485_ENABLED ;
1975+ sport -> port .rs485 .flags |= SER_RS485_RTS_ON_SEND ;
1976+ writeb (UARTMODEM_TXRTSE , sport -> port .membase + UARTMODEM );
1977+ }
1978+
19131979 return 0 ;
19141980}
19151981
0 commit comments