From bed094602ffb5c90fe761977c44653968809ebf3 Mon Sep 17 00:00:00 2001 From: Tapio Reijonen Date: Mon, 15 Jun 2026 10:27:37 +0000 Subject: [PATCH] serial: max310x: honour rs485 properties from per-channel DT subnode The MAX310x DT binding pulls in /schemas/serial/rs485.yaml via its allOf list, advertising the rs485-* properties defined there - none of which were honoured at runtime, because the driver never called uart_get_rs485_mode(). All channels share the parent SPI/I2C device, so uart_get_rs485_mode() called directly on each port would read the same chip-level fwnode for every call. Walk dev->of_node's children for the "serial@N" subnode with matching reg, and temporarily retarget the parent device's fwnode while uart_get_rs485_mode() runs, so each channel picks up its own subnode's properties. Probe is serialised, so the swap is safe. For single-channel variants (max3107, max3108), fall back to the chip's own fwnode when no subnode is present, so existing DTs that declare rs485 properties at the top level keep working. Signed-off-by: Tapio Reijonen Link: https://patch.msgid.link/20260615-b4-max310x-rs485-dt-v3-3-7e79f064bdd7@vaisala.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 3e26bdf8806b..022502986c5f 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -1452,6 +1452,9 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty #endif 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); @@ -1461,6 +1464,40 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty } 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) { + u32 reg; + + if (!of_node_name_eq(child, "serial")) + continue; + if (of_property_read_u32(child, "reg", ®)) + continue; + if (reg == i) { + port_np = child; + break; + } + } + + /* + * Temporarily retarget dev's fwnode to the per-port subnode + * so uart_get_rs485_mode() picks up the per-port properties. + * For single-port variants, fall back to the chip's own + * fwnode so legacy DTs that declare rs485 properties at the + * top level keep working. + */ + if (port_np) { + device_set_node(dev, of_fwnode_handle(port_np)); + ret = uart_get_rs485_mode(&s->p[i].port); + device_set_node(dev, saved_fwnode); + of_node_put(port_np); + if (ret) + goto out_uart; + } else if (devtype->nr == 1) { + ret = uart_get_rs485_mode(&s->p[i].port); + if (ret) + goto out_uart; + } + /* Register port */ ret = uart_add_one_port(&max310x_uart, &s->p[i].port); if (ret)