serial: max310x: register GPIO controller before adding UART ports

The MAX310x exposes four GPIOs per UART port via an in-driver
gpio_chip. devm_gpiochip_add_data() used to run after the per-port
uart_add_one_port() loop, so a device-tree consumer referencing one of
the chip's own GPIOs (for example rs485-term-gpios = <&max310x 0 ...>)
could not resolve it during port registration: the GPIO provider it
waits for is the very driver still trying to register, and the lookup
returns -EPROBE_DEFER on its own provider, deferring probe forever.

Split the per-port setup into two passes around the gpio_chip
registration:

  1. Initialise per-port state - port struct fields, regmap binding,
     IRQ disable, work queues. The gpio_chip callbacks dereference
     s->p[i].regmap via to_max310x_port() and become callable as soon
     as the chip is visible to gpiolib, so every entry must be
     populated first.
  2. devm_gpiochip_add_data() - register the gpio_chip.
  3. Allocate a line, uart_add_one_port(), set_bit(), max310x_power().
     Keeping line allocation, registration and set_bit() together
     preserves the existing "bit set <=> port registered" rollback
     invariant that out_uart relies on.

Signed-off-by: Tapio Reijonen <tapio.reijonen@vaisala.com>
Link: https://patch.msgid.link/20260615-b4-max310x-rs485-dt-v3-1-7e79f064bdd7@vaisala.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Tapio Reijonen
2026-06-15 10:27:35 +00:00
committed by Greg Kroah-Hartman
parent de96e8b27b
commit 25b51d1fd3

View File

@@ -1390,17 +1390,12 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);
/*
* Set up each port's state before registering the gpiochip,
* since the gpiochip callbacks will read s->p[i].regmap as
* soon as gpiolib exposes the controller.
*/
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;
}
/* Initialize port data */
s->p[i].port.line = line;
s->p[i].port.dev = dev;
s->p[i].port.irq = irq;
s->p[i].port.type = PORT_MAX310X;
@@ -1430,20 +1425,16 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
INIT_WORK(&s->p[i].md_work, max310x_md_proc);
/* Initialize queue for changing RS485 mode */
INIT_WORK(&s->p[i].rs_work, max310x_rs_proc);
/* Register port */
ret = uart_add_one_port(&max310x_uart, &s->p[i].port);
if (ret)
goto out_uart;
set_bit(line, max310x_lines);
/* Go to suspend mode */
max310x_power(&s->p[i].port, 0);
}
#ifdef CONFIG_GPIOLIB
/* Setup GPIO controller */
/*
* Register the GPIO controller before adding the UART ports so
* that consumers referencing the chip's own GPIOs from device
* tree (for example rs485-term-gpios = <&max310x ...>) can
* resolve them at uart_add_one_port() time instead of receiving
* -EPROBE_DEFER from their own provider.
*/
s->gpio.owner = THIS_MODULE;
s->gpio.parent = dev;
s->gpio.label = devtype->name;
@@ -1460,6 +1451,27 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
goto out_uart;
#endif
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);
if (ret)
goto out_uart;
set_bit(line, max310x_lines);
/* Go to suspend mode */
max310x_power(&s->p[i].port, 0);
}
/* Setup interrupt */
ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist,
IRQF_ONESHOT | IRQF_SHARED, dev_name(dev), s);