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: Closed FIXED
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: 2024-04-21 12:33 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 freebsd_triage 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 freebsd_triage 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 freebsd_triage 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.
Comment 3 commit-hook freebsd_committer freebsd_triage 2024-02-18 13:57:35 UTC
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(+)
Comment 4 commit-hook freebsd_committer freebsd_triage 2024-04-21 12:32:45 UTC
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(+)
Comment 5 commit-hook freebsd_committer freebsd_triage 2024-04-21 12:32:46 UTC
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(+)