[PATCH 1/7] serial: max310x: Look up all channels before adding any port
From: Tapio Reijonen
Date: Wed Nov 11 2026 - 07:35:43 EST
The probe reads each channel's RS485 properties with
uart_get_rs485_mode() and adds the port in the same loop. The GPIO
lookups in uart_get_rs485_mode() can return -EPROBE_DEFER, and for
channel N > 0 that happens after channels 0..N-1 were added, with
their serial_base child devices bound. A probe must not defer after
creating child devices: the bound children re-trigger deferred probing
at once, so the probe runs in a loop for as long as the GPIO provider
is missing, see Documentation/driver-api/driver-model/driver.rst.
Read the properties of all channels first and add the ports in a
second loop. An error in the first loop goes to out_clk: no line is
assigned yet, so out_uart would test line 0 for every channel.
Fixes: bed094602ffb ("serial: max310x: honour rs485 properties from per-channel DT subnode")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Tapio Reijonen <tapio.reijonen@xxxxxxxxxxx>
---
drivers/tty/serial/max310x.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index a0ed70185555eed745d905b36c8b8f162468dd6f..bdfdf4a9000bbd18509746bbfd8ed0ade8164598 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -2010,18 +2010,11 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
goto out_uart;
#endif
+ /* Look up every channel before registering any: lookups may defer */
for (i = 0; i < devtype->nr; i++) {
struct fwnode_handle *saved_fwnode = dev_fwnode(dev);
struct device_node *port_np = NULL;
struct device_node *child;
- unsigned int line;
-
- line = find_first_zero_bit(max310x_lines, MAX310X_UART_NRMAX);
- if (line == MAX310X_UART_NRMAX) {
- ret = -ERANGE;
- goto out_uart;
- }
- s->p[i].port.line = line;
/* Locate the matching "serial@i" DT subnode, if any. */
for_each_available_child_of_node(dev->of_node, child) {
@@ -2050,12 +2043,23 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
device_set_node(dev, saved_fwnode);
of_node_put(port_np);
if (ret)
- goto out_uart;
+ goto out_clk;
} else if (devtype->nr == 1) {
ret = uart_get_rs485_mode(&s->p[i].port);
if (ret)
- goto out_uart;
+ goto out_clk;
}
+ }
+
+ for (i = 0; i < devtype->nr; i++) {
+ unsigned int line;
+
+ line = find_first_zero_bit(max310x_lines, MAX310X_UART_NRMAX);
+ if (line == MAX310X_UART_NRMAX) {
+ ret = -ERANGE;
+ goto out_uart;
+ }
+ s->p[i].port.line = line;
/* Register port */
ret = uart_add_one_port(&max310x_uart, &s->p[i].port);
--
2.47.3