From: Tomas Alvarez Vanoli Date: Mon, 14 Jul 2025 13:22:16 +0000 (+0200) Subject: km: qrio: fix set_gpio read/modify/write X-Git-Tag: v2025.10-rc1~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b408cca7b765aa5a95fc41ad90c32685a93a08e3;p=thirdparty%2Fu-boot.git km: qrio: fix set_gpio read/modify/write Setting GPIO by reading the value of the GPRT register, toggling the correct bit and then writing it causes input values to transfer to the output. Here's how (example): 1) set gpio 17 and 18 as input. 2) set gpio 17 output value to 0 (read gprt, change 17 to 0, write). 3) set gpio 18 output value to 0 (read gprt, change 18 to 0, write). The problem here is that because we set 17 as input, and it's a pull-up, when we read gprt in step 3, the bit 17 will be 1 and not 0. Instead of doing read/write/modify, the solution is to keep track internally of the user set GPIOs, and replace the read step with this static variable. Signed-off-by: Tomas Alvarez Vanoli Signed-off-by: Holger Brunck --- diff --git a/board/keymile/common/qrio.c b/board/keymile/common/qrio.c index c8299483299..f8f8d5edede 100644 --- a/board/keymile/common/qrio.c +++ b/board/keymile/common/qrio.c @@ -18,6 +18,11 @@ #define DIRECT_OFF 0x18 #define GPRT_OFF 0x1c +// used to keep track of the user settings for the input/output +static u32 gprt_user[2] = { 0x0, 0x0 }; +// convert the bank offset to the correct static user gprt +#define QRIO_USER_GRPT_BANK(bank) gprt_user[(bank - 0x40) / 0x20] + void show_qrio(void) { void __iomem *qrio_base = (void *)CFG_SYS_QRIO_BASE; @@ -72,12 +77,13 @@ void qrio_set_gpio(u8 port_off, u8 gpio_nr, bool value) mask = 1U << gpio_nr; - gprt = in_be32(qrio_base + port_off + GPRT_OFF); + gprt = QRIO_USER_GRPT_BANK(port_off); if (value) gprt |= mask; else gprt &= ~mask; + QRIO_USER_GRPT_BANK(port_off) = gprt; out_be32(qrio_base + port_off + GPRT_OFF, gprt); }