tty: 8250_omap: Use software emulated RS485 direction control
authorMatwey V. Kornilov <matwey@sai.msu.ru>
Mon, 1 Feb 2016 18:09:22 +0000 (21:09 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Feb 2016 06:23:26 +0000 (22:23 -0800)
Use software emulated RS485 direction control to provide RS485 API
existed in omap_serial driver. Note that 8250_omap issues interrupt
on shift register empty which is single prerequesite for using software
emulated RS485.

Signed-off-by: Matwey V. Kornilov <matwey@sai.msu.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_omap.c

index a2c0734..d710985 100644 (file)
@@ -697,6 +697,36 @@ static void omap_8250_throttle(struct uart_port *port)
        pm_runtime_put_autosuspend(port->dev);
 }
 
+static int omap_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;
+}
+
 static void omap_8250_unthrottle(struct uart_port *port)
 {
        unsigned long flags;
@@ -1146,6 +1176,7 @@ static int omap8250_probe(struct platform_device *pdev)
        up.port.shutdown = omap_8250_shutdown;
        up.port.throttle = omap_8250_throttle;
        up.port.unthrottle = omap_8250_unthrottle;
+       up.port.rs485_config = omap_8250_rs485_config;
 
        if (pdev->dev.of_node) {
                const struct of_device_id *id;