Created attachment 216622 [details] a proof-of-concept patch I encountered this problem with gpiokeys on an Allwinner H3 based system. I observed it experimentally: a pin was always read as one regardless of whether a button was pressed or not. If I used gpioctl to place the pin into input mode then the input value reflected the button state (but gpiokeys obviously didn't work as interrupts were not generated). The documentation says: > PL_DAT > If the port is configured as input, the corresponding bit is the pin state. > If the port is configured as output, the pin state is the same as the corresponding bit. > The read bit value is the value setup by software. > If the port is configured as functional pin, the undefined value will be read. I used a hack / workaround in aw_gpio_pin_get_locked() to temporarily switch a pin in and out of AW_GPIO_INPUT function if its current function is eint_func. We probably need a flag to mark controllers that need such workaround and apply it conditionally.
This seems like a rather unfortunate limitation of the GPIO implementation :( I agree with you that the controller ought to have a quirk to automatically apply the workaround. Does the interrupt controller still work correctly with the pin being read? Does an interrupt get lost if the pin changes state while switched to input and then back?
(In reply to Ed Maste from comment #1) I don't have an answer to the questions. I tested only with gpiokeys and there the behavior was acceptable, not lost key events. Maybe that was because I was not fast enough to hit the right time window. I think that most drivers that can consume gpio interrupts do not actually read the same gpio pin. gpiokeys is an odd / special one here. It configures an interrupt on both edges and does not keep any internal state for a button. So, it has to query the pin state after getting an interrupt.
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=b98558e69b0aefbb99120a8a6ca7efbb8cafab5b commit b98558e69b0aefbb99120a8a6ca7efbb8cafab5b Author: Andriy Gapon <avg@FreeBSD.org> AuthorDate: 2024-02-18 13:55:20 +0000 Commit: Andriy Gapon <avg@FreeBSD.org> CommitDate: 2024-02-18 13:55:20 +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 MFC after: 1 month sys/arm/allwinner/aw_gpio.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
A commit in branch stable/14 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=43bf62a364c1b150cfdc64eb6b5f62ab3b48ee14 commit 43bf62a364c1b150cfdc64eb6b5f62ab3b48ee14 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:31:50 +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(+)
A commit in branch stable/13 references this bug: 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(+)