]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
serial: Allow uart_get_rs485_mode() to return errno
authorLukas Wunner <lukas@wunner.de>
Tue, 12 May 2020 12:40:02 +0000 (14:40 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 May 2020 12:47:05 +0000 (14:47 +0200)
We're about to amend uart_get_rs485_mode() to support a GPIO pin for
rs485 bus termination.  Retrieving the GPIO descriptor may fail, so
allow uart_get_rs485_mode() to return an errno and change all callers
to check for failure.

The GPIO descriptor is going to be stored in struct uart_port.  Pass
that struct to uart_get_rs485_mode() in lieu of a struct device and
struct serial_rs485, both of which are directly accessible from struct
uart_port.

A few drivers call uart_get_rs485_mode() before setting the struct
device pointer in struct uart_port.  Shuffle those calls around where
necessary.

[Heiko Stuebner did the ar933x_uart.c portion, hence his Signed-off-by.]

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://lore.kernel.org/r/271e814af4b0db3bffbbb74abf2b46b75add4516.1589285873.git.lukas@wunner.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/ar933x_uart.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/imx.c
drivers/tty/serial/omap-serial.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/stm32-usart.c
include/linux/serial_core.h

index 9548d3f8fc8e7f2f26f360a8c20e2199aed383d1..fc118f6498877f5559b51b1e52900976ab989839 100644 (file)
@@ -1026,7 +1026,9 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
 
                if (up->port.dev) {
                        uart->port.dev = up->port.dev;
-                       uart_get_rs485_mode(uart->port.dev, &uart->port.rs485);
+                       ret = uart_get_rs485_mode(&uart->port);
+                       if (ret)
+                               goto err;
                }
 
                if (up->port.flags & UPF_FIXED_TYPE)
index 7e7f1398019f4722c63f2109a0ee60dc3f5435a0..0c80a79d7442d614eecddc88a4dcd72bcdf1e4cf 100644 (file)
@@ -766,8 +766,6 @@ static int ar933x_uart_probe(struct platform_device *pdev)
                goto err_disable_clk;
        }
 
-       uart_get_rs485_mode(&pdev->dev, &port->rs485);
-
        port->mapbase = mem_res->start;
        port->line = id;
        port->irq = irq_res->start;
@@ -786,6 +784,10 @@ static int ar933x_uart_probe(struct platform_device *pdev)
        baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
        up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
 
+       ret = uart_get_rs485_mode(port);
+       if (ret)
+               goto err_disable_clk;
+
        up->gpios = mctrl_gpio_init(port, 0);
        if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS)
                return PTR_ERR(up->gpios);
index 8d7080efad9b55941452f3749ae1588fa1f00b8c..e43471b33710b3885dd2b1ec74d68cdec70a3901 100644 (file)
@@ -2491,8 +2491,6 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
        atmel_init_property(atmel_port, pdev);
        atmel_set_ops(port);
 
-       uart_get_rs485_mode(&mpdev->dev, &port->rs485);
-
        port->iotype            = UPIO_MEM;
        port->flags             = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
        port->ops               = &atmel_pops;
@@ -2506,6 +2504,10 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
 
        memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
 
+       ret = uart_get_rs485_mode(port);
+       if (ret)
+               return ret;
+
        /* for console, the clock could already be configured */
        if (!atmel_port->clk) {
                atmel_port->clk = clk_get(&mpdev->dev, "usart");
index 6a9909e564493f883960fd445fca41703bddb4f7..029324c77cd71430adefb71b263828fd82abb1e7 100644 (file)
@@ -2619,7 +2619,9 @@ static int lpuart_probe(struct platform_device *pdev)
        if (ret)
                goto failed_attach_port;
 
-       uart_get_rs485_mode(&pdev->dev, &sport->port.rs485);
+       ret = uart_get_rs485_mode(&sport->port);
+       if (ret)
+               goto failed_get_rs485;
 
        if (sport->port.rs485.flags & SER_RS485_RX_DURING_TX)
                dev_err(&pdev->dev, "driver doesn't support RX during TX\n");
@@ -2632,6 +2634,7 @@ static int lpuart_probe(struct platform_device *pdev)
 
        return 0;
 
+failed_get_rs485:
 failed_attach_port:
 failed_irq_request:
        lpuart_disable_clks(sport);
index f4023d9d8e7a172217b1037dccfa613b5edae2af..986d902fb7fe531bdc0c8deba7a6e0ec426ccbf2 100644 (file)
@@ -2304,7 +2304,11 @@ static int imx_uart_probe(struct platform_device *pdev)
        sport->ucr4 = readl(sport->port.membase + UCR4);
        sport->ufcr = readl(sport->port.membase + UFCR);
 
-       uart_get_rs485_mode(&pdev->dev, &sport->port.rs485);
+       ret = uart_get_rs485_mode(&sport->port);
+       if (ret) {
+               clk_disable_unprepare(sport->clk_ipg);
+               return ret;
+       }
 
        if (sport->port.rs485.flags & SER_RS485_ENABLED &&
            (!sport->have_rtscts && !sport->have_rtsgpio))
index c71c1a2266dc64202a7237d6fb8ce6f0322bedf7..8573fc9cb0cdf58abe4e3dc59e6c8a72845d375d 100644 (file)
@@ -1608,7 +1608,9 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up,
        if (!np)
                return 0;
 
-       uart_get_rs485_mode(up->dev, rs485conf);
+       ret = uart_get_rs485_mode(&up->port);
+       if (ret)
+               return ret;
 
        if (of_property_read_bool(np, "rs485-rts-active-high")) {
                rs485conf->flags |= SER_RS485_RTS_ON_SEND;
index 66a5e2faf57eabfb6cb8366c9aeb9ed215200604..43b6682877d5fabba7ac448a171d8e124af2824e 100644 (file)
@@ -3295,8 +3295,10 @@ EXPORT_SYMBOL(uart_remove_one_port);
  * This function implements the device tree binding described in
  * Documentation/devicetree/bindings/serial/rs485.txt.
  */
-void uart_get_rs485_mode(struct device *dev, struct serial_rs485 *rs485conf)
+int uart_get_rs485_mode(struct uart_port *port)
 {
+       struct serial_rs485 *rs485conf = &port->rs485;
+       struct device *dev = port->dev;
        u32 rs485_delay[2];
        int ret;
 
@@ -3328,6 +3330,8 @@ void uart_get_rs485_mode(struct device *dev, struct serial_rs485 *rs485conf)
                rs485conf->flags &= ~SER_RS485_RTS_ON_SEND;
                rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
        }
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(uart_get_rs485_mode);
 
index 17c2f3276888f26f480d42ea2b6b4c9b84f9964f..7d1acb3786b8038ab882edd7bc0a69ce02e615b9 100644 (file)
@@ -159,9 +159,7 @@ static int stm32_init_rs485(struct uart_port *port,
        if (!pdev->dev.of_node)
                return -ENODEV;
 
-       uart_get_rs485_mode(&pdev->dev, rs485conf);
-
-       return 0;
+       return uart_get_rs485_mode(port);
 }
 
 static int stm32_pending_rx(struct uart_port *port, u32 *sr, int *last_res,
@@ -959,7 +957,9 @@ static int stm32_init_port(struct stm32_port *stm32port,
 
        port->rs485_config = stm32_config_rs485;
 
-       stm32_init_rs485(port, pdev);
+       ret = stm32_init_rs485(port, pdev);
+       if (ret)
+               return ret;
 
        if (stm32port->info->cfg.has_wakeup) {
                stm32port->wakeirq = platform_get_irq(pdev, 1);
index 92f5eba8605286713abe80873c92488734822fdb..b649a2b894e79e7f32a7fb5c583af5e5f04d51e1 100644 (file)
@@ -472,5 +472,5 @@ extern int uart_handle_break(struct uart_port *port);
                                         (cflag) & CRTSCTS || \
                                         !((cflag) & CLOCAL))
 
-void uart_get_rs485_mode(struct device *dev, struct serial_rs485 *rs485conf);
+int uart_get_rs485_mode(struct uart_port *port);
 #endif /* LINUX_SERIAL_CORE_H */