[PATCH 3/3] serial: max310x: honour rs485 properties from per-port DT subnode

From: Tapio Reijonen

Date: Mon May 25 2026 - 05:44:34 EST


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 ports 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 one named "port"
with matching reg, and temporarily retarget the parent device's
fwnode while uart_get_rs485_mode() runs, so each port picks up its
own subnode's properties. Probe is serialised, so the swap is safe.

For single-port variants (max3107, max3108), fall back to the chip's
own fwnode when no port@0 subnode is present, so existing DTs that
declare rs485 properties at the top level keep working.

Signed-off-by: Tapio Reijonen <tapio.reijonen@xxxxxxxxxxx>
---
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 5cb7d01e404663dc25b88bc7b4f8df61be2135ec..745498034293cf74c8b4d25b45739e787f1843de 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -1426,6 +1426,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);
@@ -1435,6 +1438,40 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
}
s->p[i].port.line = line;

+ /* Locate the matching "port@i" DT subnode, if any. */
+ for_each_available_child_of_node(dev->of_node, child) {
+ u32 reg;
+
+ if (!of_node_name_eq(child, "port"))
+ continue;
+ if (of_property_read_u32(child, "reg", &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)

--
2.47.3