]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
x86: Probe device if needed in intel_gpio_xlate()
authorSimon Glass <sjg@chromium.org>
Mon, 15 Mar 2021 05:00:04 +0000 (18:00 +1300)
committerSimon Glass <sjg@chromium.org>
Sat, 27 Mar 2021 00:59:36 +0000 (13:59 +1300)
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@chromium.org>
drivers/gpio/intel_gpio.c

index ab46a94dbc15a7cd1109f21122435ebc57b1e423..f15ce7b59eeae8e0ffdae49c3b9179dff79b4758 100644 (file)
@@ -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;
 }