aboutsummaryrefslogtreecommitdiff
path: root/sys/arm
diff options
context:
space:
mode:
authorAndriy Gapon <avg@FreeBSD.org>2024-02-18 13:55:20 +0000
committerAndriy Gapon <avg@FreeBSD.org>2024-02-18 13:55:20 +0000
commitb98558e69b0aefbb99120a8a6ca7efbb8cafab5b (patch)
treee4ebda876dab343e81878897c9041066a2bbe696 /sys/arm
parent2fb174d18a42d1b2965164186843540ee65881ea (diff)
downloadsrc-b98558e69b0aefbb99120a8a6ca7efbb8cafab5b.tar.gz
src-b98558e69b0aefbb99120a8a6ca7efbb8cafab5b.zip
aw_gpio: temporarily switch to input function if read in eint mode
This is needed for gpiokeys driver that needs to read input state after receiving an interrupt for either edge. PR: 248138 MFC after: 1 month
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/allwinner/aw_gpio.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/sys/arm/allwinner/aw_gpio.c b/sys/arm/allwinner/aw_gpio.c
index cee2cf056f42..6ff0516acb3f 100644
--- a/sys/arm/allwinner/aw_gpio.c
+++ b/sys/arm/allwinner/aw_gpio.c
@@ -654,18 +654,30 @@ aw_gpio_pin_get_locked(struct aw_gpio_softc *sc,uint32_t pin,
unsigned int *val)
{
uint32_t bank, reg_data;
+ int32_t func;
+ int err;
AW_GPIO_LOCK_ASSERT(sc);
if (pin > sc->conf->padconf->npins)
return (EINVAL);
+ func = aw_gpio_get_function(sc, pin);
+ if (func == sc->conf->padconf->pins[pin].eint_func) { /* "pl_eintX */
+ err = aw_gpio_set_function(sc, pin, AW_GPIO_INPUT);
+ if (err != 0)
+ return (err);
+ }
+
bank = sc->conf->padconf->pins[pin].port;
pin = sc->conf->padconf->pins[pin].pin;
reg_data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
*val = (reg_data & (1 << pin)) ? 1 : 0;
+ if (func == sc->conf->padconf->pins[pin].eint_func)
+ (void)aw_gpio_set_function(sc, pin, func);
+
return (0);
}