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:
> 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
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.