git: 9c444571ab94 - stable/13 - aw_gpio: temporarily switch to input function if read in eint mode

From: Andriy Gapon <avg_at_FreeBSD.org>
Date: Sun, 21 Apr 2024 12:32:26 UTC
The branch stable/13 has been updated by avg:

URL: https://cgit.FreeBSD.org/src/commit/?id=9c444571ab94ac1c148100bfc85954f7029d7f09

commit 9c444571ab94ac1c148100bfc85954f7029d7f09
Author:     Andriy Gapon <avg@FreeBSD.org>
AuthorDate: 2024-02-18 13:55:20 +0000
Commit:     Andriy Gapon <avg@FreeBSD.org>
CommitDate: 2024-04-21 12:32:16 +0000

    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
    
    (cherry picked from commit b98558e69b0aefbb99120a8a6ca7efbb8cafab5b)
---
 sys/arm/allwinner/aw_gpio.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/sys/arm/allwinner/aw_gpio.c b/sys/arm/allwinner/aw_gpio.c
index 9d1defb5bf8c..5d0c3ded0c52 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);
 }