[PATCH 1/2] gpio: vybrid: read and write the GPIO block, not the PORT block
Mehmet Fide <[email protected]> Thu, 6 Aug 2026 14:47:59 +0200
| Newsgroups | gmane.comp.boot-loaders.u-boot |
|---|---|
| Message-ID | <20260806124800.262013-2-mehmet.fide__38654.5558738121$1786021537$gmane$org@gmail.com> |
From: Mehmet Fide <[email protected]> The Vybrid GPIO node describes two register ranges: the PORT block, which holds the pin control and interrupt registers, and the GPIO block, which holds the registers this driver touches (PDOR, PSOR, PCOR, PTOR, PDIR): gpio0: gpio@40049000 { compatible = "fsl,vf610-gpio"; reg = <0x40049000 0x1000 0x400ff000 0x40>; vybrid_gpio_odata_to_plat() takes the first range, so every set, clear and read goes to the PORT block: an output never changes level, an input returns a pin control register, and the write lands on the pin control register of an unrelated pad. The gpio command reports success either way. The direction is not affected. imx_iomux_gpio_set_direction() applies IOMUXC itself, so a pin requested as an output is driven, but always to the reset value of PDOR. The single range device tree this driver was written against described the GPIO block alone: gpio1: gpio@400ff000 { compatible = "fsl,vf610-gpio"; reg = <0x400ff000 0x40>; so the first range was the right one until the device trees were synchronised with Linux. Take the second range when the node has one and keep the first as the fallback, which is what the Linux driver does for the single range imx7ulp binding. Tested on a Colibri VF50: with the fix "gpio set 50" sets bit 18 of PDOR in the GPIO block at 0x400ff040 and the pin drives its load, and the display reset and backlight lines the board wires to GPIOs work again. Without it the register never changes. Fixes: e8a9521e649f ("vf500/vf610: synchronise device trees with linux") Signed-off-by: Mehmet Fide <[email protected]> --- drivers/gpio/vybrid_gpio.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/vybrid_gpio.c b/drivers/gpio/vybrid_gpio.c index 5b4bba96da7..3d2e16e8ef3 100644 --- a/drivers/gpio/vybrid_gpio.c +++ b/drivers/gpio/vybrid_gpio.c @@ -109,7 +109,13 @@ static int vybrid_gpio_odata_to_plat(struct udevice *dev) struct vybrid_gpio_plat *plat = dev_get_plat(dev); fdt_addr_t base_addr; - base_addr = dev_read_addr(dev); + /* + * The first reg range is the PORT block (pin control), the second one + * the GPIO block this driver reads and writes. + */ + base_addr = dev_read_addr_index(dev, 1); + if (base_addr == FDT_ADDR_T_NONE) + base_addr = dev_read_addr(dev); if (base_addr == FDT_ADDR_T_NONE) return -EINVAL; -- 2.54.0