[PATCH 04/34] x86: Probe device if needed in intel_gpio_xlate()

Simon Glass sjg at chromium.org
Mon Mar 15 06:00:04 CET 2021

The Intel GPIO binding allows GPIOs to be globally numbered, so that it
does not matter which GPIO bank is specified in the device tree. This is
convenient and avoid confusion since the banks do not have the same number
of GPIOs and the numbering is not sequential.

The GPIO uclass ensures that the device mentioned in the devicetree
binding is probed. It is fine for the driver to update gpio_desc to point
to a different driver, but this may not have been probed. If it has not
been, then it cannot be claimed since there is no uclass data.

We could handle this in the GPIO uclass but so far it is an unusual
situation so it is probably not worth the extra code. Handle this case in
the GPIO driver by probing the selected device if necessary.

Signed-off-by: Simon Glass <sjg at chromium.org>

 drivers/gpio/intel_gpio.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c
index ab46a94dbc1..f15ce7b59ee 100644
--- a/drivers/gpio/intel_gpio.c
+++ b/drivers/gpio/intel_gpio.c
@@ -23,6 +23,7 @@
 #include <asm/pci.h>
 #include <asm/arch/gpio.h>
 #include <dm/acpi.h>
+#include <dm/device-internal.h>
 #include <dt-bindings/gpio/x86-gpio.h>
 static int intel_gpio_get_value(struct udevice *dev, uint offset)
@@ -85,7 +86,7 @@ static int intel_gpio_xlate(struct udevice *orig_dev, struct gpio_desc *desc,
 	 * GPIO numbers are global in the device tree so it doesn't matter
-	 * which one is used
+	 * which @orig_dev is used
 	gpio = args->args[0];
 	ret = intel_pinctrl_get_pad(gpio, &pinctrl, &desc->offset);
@@ -97,6 +98,17 @@ static int intel_gpio_xlate(struct udevice *orig_dev, struct gpio_desc *desc,
 	desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
 	desc->dev = dev;
+	/*
+	 * Handle the case where the wrong GPIO device was provided, since this
+	 * will not have been probed by the GPIO uclass before calling here
+	 * (see gpio_request_tail()).
+	 */
+	if (orig_dev != dev) {
+		ret = device_probe(dev);
+		if (ret)
+			return log_msg_ret("probe", ret);
+	}
 	return 0;

More information about the U-Boot mailing list