tty: 8250_of: Use software emulated RS485 direction control
authorHeiko Schocher <hs@denx.de>
Fri, 13 Sep 2019 05:01:05 +0000 (07:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Oct 2019 12:50:01 +0000 (14:50 +0200)
Use software emulated RS485 direction control to provide RS485 API

Currently it is not possible to use rs485 as pointer to
rs485_config struct in struct uart_port is NULL in case we
configure the port through device tree.

Signed-off-by: Heiko Schocher <hs@denx.de>
Link: https://lore.kernel.org/r/20190913050105.1132080-1-hs@denx.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_of.c

index 0826cfdbd40637560a8ccdc77c6be68ba0e2f048..92fbf46ce3bd95df737c177d8636b00d4efd4c05 100644 (file)
@@ -48,6 +48,36 @@ static inline void tegra_serial_handle_break(struct uart_port *port)
 }
 #endif
 
+static int of_8250_rs485_config(struct uart_port *port,
+                                 struct serial_rs485 *rs485)
+{
+       struct uart_8250_port *up = up_to_u8250p(port);
+
+       /* Clamp the delays to [0, 100ms] */
+       rs485->delay_rts_before_send = min(rs485->delay_rts_before_send, 100U);
+       rs485->delay_rts_after_send  = min(rs485->delay_rts_after_send, 100U);
+
+       port->rs485 = *rs485;
+
+       /*
+        * Both serial8250_em485_init and serial8250_em485_destroy
+        * are idempotent
+        */
+       if (rs485->flags & SER_RS485_ENABLED) {
+               int ret = serial8250_em485_init(up);
+
+               if (ret) {
+                       rs485->flags &= ~SER_RS485_ENABLED;
+                       port->rs485.flags &= ~SER_RS485_ENABLED;
+               }
+               return ret;
+       }
+
+       serial8250_em485_destroy(up);
+
+       return 0;
+}
+
 /*
  * Fill a struct uart_port for a given device node
  */
@@ -178,6 +208,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
                port->flags |= UPF_SKIP_TEST;
 
        port->dev = &ofdev->dev;
+       port->rs485_config = of_8250_rs485_config;
 
        switch (type) {
        case PORT_TEGRA: