serial: core: Simplify uart_get_rs485_mode()
[platform/kernel/linux-starfive.git] / drivers / tty / serial / serial_core.c
index d5ba6e9..021e096 100644 (file)
@@ -146,7 +146,7 @@ static void __uart_start(struct uart_state *state)
 
        /* Increment the runtime PM usage count for the active check below */
        err = pm_runtime_get(&port_dev->dev);
-       if (err < 0) {
+       if (err < 0 && err != -EINPROGRESS) {
                pm_runtime_put_noidle(&port_dev->dev);
                return;
        }
@@ -1370,19 +1370,27 @@ static void uart_sanitize_serial_rs485(struct uart_port *port, struct serial_rs4
                return;
        }
 
+       rs485->flags &= supported_flags;
+
        /* Pick sane settings if the user hasn't */
-       if ((supported_flags & (SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND)) &&
-           !(rs485->flags & SER_RS485_RTS_ON_SEND) ==
+       if (!(rs485->flags & SER_RS485_RTS_ON_SEND) ==
            !(rs485->flags & SER_RS485_RTS_AFTER_SEND)) {
-               dev_warn_ratelimited(port->dev,
-                       "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n",
-                       port->name, port->line);
-               rs485->flags |= SER_RS485_RTS_ON_SEND;
-               rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
-               supported_flags |= SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND;
-       }
+               if (supported_flags & SER_RS485_RTS_ON_SEND) {
+                       rs485->flags |= SER_RS485_RTS_ON_SEND;
+                       rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
 
-       rs485->flags &= supported_flags;
+                       dev_warn_ratelimited(port->dev,
+                               "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n",
+                               port->name, port->line);
+               } else {
+                       rs485->flags |= SER_RS485_RTS_AFTER_SEND;
+                       rs485->flags &= ~SER_RS485_RTS_ON_SEND;
+
+                       dev_warn_ratelimited(port->dev,
+                               "%s (%d): invalid RTS setting, using RTS_AFTER_SEND instead\n",
+                               port->name, port->line);
+               }
+       }
 
        uart_sanitize_serial_rs485_delays(port, rs485);
 
@@ -1445,7 +1453,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port,
        int ret;
        unsigned long flags;
 
-       if (!port->rs485_config)
+       if (!(port->rs485_supported.flags & SER_RS485_ENABLED))
                return -ENOTTY;
 
        if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user)))
@@ -3564,9 +3572,13 @@ int uart_get_rs485_mode(struct uart_port *port)
 {
        struct serial_rs485 *rs485conf = &port->rs485;
        struct device *dev = port->dev;
+       enum gpiod_flags dflags;
+       struct gpio_desc *desc;
        u32 rs485_delay[2];
        int ret;
-       int rx_during_tx_gpio_flag;
+
+       if (!(port->rs485_supported.flags & SER_RS485_ENABLED))
+               return 0;
 
        ret = device_property_read_u32_array(dev, "rs485-rts-delay",
                                             rs485_delay, 2);
@@ -3605,26 +3617,19 @@ int uart_get_rs485_mode(struct uart_port *port)
         * bus participants enable it, no communication is possible at all.
         * Works fine for short cables and users may enable for longer cables.
         */
-       port->rs485_term_gpio = devm_gpiod_get_optional(dev, "rs485-term",
-                                                       GPIOD_OUT_LOW);
-       if (IS_ERR(port->rs485_term_gpio)) {
-               ret = PTR_ERR(port->rs485_term_gpio);
-               port->rs485_term_gpio = NULL;
-               return dev_err_probe(dev, ret, "Cannot get rs485-term-gpios\n");
-       }
+       desc = devm_gpiod_get_optional(dev, "rs485-term", GPIOD_OUT_LOW);
+       if (IS_ERR(desc))
+               return dev_err_probe(dev, PTR_ERR(desc), "Cannot get rs485-term-gpios\n");
+       port->rs485_term_gpio = desc;
        if (port->rs485_term_gpio)
                port->rs485_supported.flags |= SER_RS485_TERMINATE_BUS;
 
-       rx_during_tx_gpio_flag = (rs485conf->flags & SER_RS485_RX_DURING_TX) ?
-                                GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
-       port->rs485_rx_during_tx_gpio = devm_gpiod_get_optional(dev,
-                                                               "rs485-rx-during-tx",
-                                                               rx_during_tx_gpio_flag);
-       if (IS_ERR(port->rs485_rx_during_tx_gpio)) {
-               ret = PTR_ERR(port->rs485_rx_during_tx_gpio);
-               port->rs485_rx_during_tx_gpio = NULL;
-               return dev_err_probe(dev, ret, "Cannot get rs485-rx-during-tx-gpios\n");
-       }
+       dflags = (rs485conf->flags & SER_RS485_RX_DURING_TX) ?
+                GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
+       desc = devm_gpiod_get_optional(dev, "rs485-rx-during-tx", dflags);
+       if (IS_ERR(desc))
+               return dev_err_probe(dev, PTR_ERR(desc), "Cannot get rs485-rx-during-tx-gpios\n");
+       port->rs485_rx_during_tx_gpio = desc;
 
        return 0;
 }