x86: Probe device if needed in intel_gpio_xlate()

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>
diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c
index ab46a94..f15ce7b 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 @@
 
 	/*
 	 * 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 @@
 	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;
 }