Commit c150c0f3 authored by Lukas Wunner's avatar Lukas Wunner Committed by Greg Kroah-Hartman

serial: Allow uart_get_rs485_mode() to return errno

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: default avatarHeiko Stuebner <heiko@sntech.de>
Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
Link: https://lore.kernel.org/r/271e814af4b0db3bffbbb74abf2b46b75add4516.1589285873.git.lukas@wunner.deSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e0a851fe
...@@ -1026,7 +1026,9 @@ int serial8250_register_8250_port(struct uart_8250_port *up) ...@@ -1026,7 +1026,9 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
if (up->port.dev) { if (up->port.dev) {
uart->port.dev = 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) if (up->port.flags & UPF_FIXED_TYPE)
......
...@@ -766,8 +766,6 @@ static int ar933x_uart_probe(struct platform_device *pdev) ...@@ -766,8 +766,6 @@ static int ar933x_uart_probe(struct platform_device *pdev)
goto err_disable_clk; goto err_disable_clk;
} }
uart_get_rs485_mode(&pdev->dev, &port->rs485);
port->mapbase = mem_res->start; port->mapbase = mem_res->start;
port->line = id; port->line = id;
port->irq = irq_res->start; port->irq = irq_res->start;
...@@ -786,6 +784,10 @@ static int ar933x_uart_probe(struct platform_device *pdev) ...@@ -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); baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD); 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); up->gpios = mctrl_gpio_init(port, 0);
if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS) if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS)
return PTR_ERR(up->gpios); return PTR_ERR(up->gpios);
......
...@@ -2491,8 +2491,6 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, ...@@ -2491,8 +2491,6 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
atmel_init_property(atmel_port, pdev); atmel_init_property(atmel_port, pdev);
atmel_set_ops(port); atmel_set_ops(port);
uart_get_rs485_mode(&mpdev->dev, &port->rs485);
port->iotype = UPIO_MEM; port->iotype = UPIO_MEM;
port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP; port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
port->ops = &atmel_pops; port->ops = &atmel_pops;
...@@ -2506,6 +2504,10 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, ...@@ -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)); 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 */ /* for console, the clock could already be configured */
if (!atmel_port->clk) { if (!atmel_port->clk) {
atmel_port->clk = clk_get(&mpdev->dev, "usart"); atmel_port->clk = clk_get(&mpdev->dev, "usart");
......
...@@ -2619,7 +2619,9 @@ static int lpuart_probe(struct platform_device *pdev) ...@@ -2619,7 +2619,9 @@ static int lpuart_probe(struct platform_device *pdev)
if (ret) if (ret)
goto failed_attach_port; 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) if (sport->port.rs485.flags & SER_RS485_RX_DURING_TX)
dev_err(&pdev->dev, "driver doesn't support RX during TX\n"); dev_err(&pdev->dev, "driver doesn't support RX during TX\n");
...@@ -2632,6 +2634,7 @@ static int lpuart_probe(struct platform_device *pdev) ...@@ -2632,6 +2634,7 @@ static int lpuart_probe(struct platform_device *pdev)
return 0; return 0;
failed_get_rs485:
failed_attach_port: failed_attach_port:
failed_irq_request: failed_irq_request:
lpuart_disable_clks(sport); lpuart_disable_clks(sport);
......
...@@ -2304,7 +2304,11 @@ static int imx_uart_probe(struct platform_device *pdev) ...@@ -2304,7 +2304,11 @@ static int imx_uart_probe(struct platform_device *pdev)
sport->ucr4 = readl(sport->port.membase + UCR4); sport->ucr4 = readl(sport->port.membase + UCR4);
sport->ufcr = readl(sport->port.membase + UFCR); 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 && if (sport->port.rs485.flags & SER_RS485_ENABLED &&
(!sport->have_rtscts && !sport->have_rtsgpio)) (!sport->have_rtscts && !sport->have_rtsgpio))
......
...@@ -1608,7 +1608,9 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up, ...@@ -1608,7 +1608,9 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up,
if (!np) if (!np)
return 0; 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")) { if (of_property_read_bool(np, "rs485-rts-active-high")) {
rs485conf->flags |= SER_RS485_RTS_ON_SEND; rs485conf->flags |= SER_RS485_RTS_ON_SEND;
......
...@@ -3295,8 +3295,10 @@ EXPORT_SYMBOL(uart_remove_one_port); ...@@ -3295,8 +3295,10 @@ EXPORT_SYMBOL(uart_remove_one_port);
* This function implements the device tree binding described in * This function implements the device tree binding described in
* Documentation/devicetree/bindings/serial/rs485.txt. * 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]; u32 rs485_delay[2];
int ret; int ret;
...@@ -3328,6 +3330,8 @@ void uart_get_rs485_mode(struct device *dev, struct serial_rs485 *rs485conf) ...@@ -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_ON_SEND;
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
} }
return 0;
} }
EXPORT_SYMBOL_GPL(uart_get_rs485_mode); EXPORT_SYMBOL_GPL(uart_get_rs485_mode);
......
...@@ -159,9 +159,7 @@ static int stm32_init_rs485(struct uart_port *port, ...@@ -159,9 +159,7 @@ static int stm32_init_rs485(struct uart_port *port,
if (!pdev->dev.of_node) if (!pdev->dev.of_node)
return -ENODEV; return -ENODEV;
uart_get_rs485_mode(&pdev->dev, rs485conf); return uart_get_rs485_mode(port);
return 0;
} }
static int stm32_pending_rx(struct uart_port *port, u32 *sr, int *last_res, 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, ...@@ -959,7 +957,9 @@ static int stm32_init_port(struct stm32_port *stm32port,
port->rs485_config = stm32_config_rs485; 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) { if (stm32port->info->cfg.has_wakeup) {
stm32port->wakeirq = platform_get_irq(pdev, 1); stm32port->wakeirq = platform_get_irq(pdev, 1);
......
...@@ -472,5 +472,5 @@ extern int uart_handle_break(struct uart_port *port); ...@@ -472,5 +472,5 @@ extern int uart_handle_break(struct uart_port *port);
(cflag) & CRTSCTS || \ (cflag) & CRTSCTS || \
!((cflag) & CLOCAL)) !((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 */ #endif /* LINUX_SERIAL_CORE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment