Bug 248138 - aw_gpio: some hardware does not support reading input while in interrupt mode
Summary: aw_gpio: some hardware does not support reading input while in interrupt mode
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-arm (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-07-21 08:46 UTC by Andriy Gapon
Modified: 2020-07-23 15:46 UTC (History)
1 user (show)

See Also:


Attachments
a proof-of-concept patch (986 bytes, patch)
2020-07-21 08:46 UTC, Andriy Gapon
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andriy Gapon freebsd_committer 2020-07-21 08:46:05 UTC
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.
Comment 1 Ed Maste freebsd_committer 2020-07-23 15:00:56 UTC
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?
Comment 2 Andriy Gapon freebsd_committer 2020-07-23 15:46:49 UTC
(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.