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>
This commit is contained in:
Simon Glass 2021-03-15 18:00:04 +13:00
parent 72d98ee091
commit 7d252d0279
1 changed files with 13 additions and 1 deletions

View 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;
}