Re: [PATCH v5 3/5] docs: staging: gpio-rpmsg: gpio over rpmsg bus

Andrew Lunn
2025-11-07T00:31:52Z

> > > > > +- **wk**: Wakeup enable.
> > > > > +
> > > > > + - 0: Disable wakeup from GPIO
> > > > > + - 1: Enable wakeup from GPIO
> > > >
> > > > What do you mean by wakeup?
> > > >
> > >
> > > The gpio line can be enabled as an wakeup source for the system.
> >
> > Keep going.....
> >
> > Does that imply if none of the lines have wakeup enabled, the GPIO controller can
> > be suspended when Linux suspends? How does the GPIO controller know it can
> > suspend? There is no message for that. How does it know to come out of
> > suspension?
> >
>
> The power state of the remote GPIO controller is entirely managed by the remote firmware.
> The remote firmware operates as an independent system from Linux, with its own power states
> and policies for transitioning between modes. The wakeup field is solely intended to inform the
> remote firmware whether the GPIO line should be used as a wakeup source for the Linux system.

O.K. How does the firmware use this information? How should it change
its behaviour?

> > > > > +Notification Message
> > > > > +--------------------
> > > > > +
> > > > > +Notifications are sent with **Type=2 (GPIO_RPMSG_NOTIFY)**:
> > > > > +
> > > > > +.. code-block:: none
> > > > > +
> > > > > + +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
> > > > > + |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D|
> > > > > + | 5 | 1 | 0 | 2 | 0 | 0 |line |port | 0 | 0 |
> > > > > +
> > > > > + +-----+-----+-----+-----+-----+-----------+-----+-----+-----+---
> > > > > + -+
> > > > > +
> > > > > +- **line**: The GPIO line index.
> > > > > +- **port**: The GPIO controller index.
> > > >
> > > > There is no need to acknowledge the notification? How do level interrupts
> > work?
> > > >
> > >
> > > Currently, there is no need to acknowledge the message, as the
> > > interrupt is managed entirely by the remote firmware. On the Linux
> > > side, a single notification message is received when an interrupt is triggered.
> >
> > That sounds broken.
> >
> > A level interrupt is not cleared until the level changes. The typical flow is:
> >
> > Interrupt fires.
> >
> > Interrupt is masked
> >
> > Interrupt handler is called, which reads/write registers in the device who pin is
> > connected to the GPIO
> >
> > Interrupt is unmasked
> >
>
> The sequences you mentioned above are managed entirely by the remote firmware. On the Linux
> side, it only receives a notification message when a GPIO line is triggered, which then invokes the
> corresponding interrupt handler.
>
> Since the interrupt handling sequences are implemented in the remote firmware, the Linux driver
> can treat level-triggered and edge-triggered types in the same manner.

That is wrong. Edge and level are different and need different
handling. That is why the GPIO framework and the interrupt core
handles them differently.

The devices i mostly deal with are Ethernet PHYs. These are level
devices, the interrupt is active low. Within the PHY there are
multiple interrupt sources, which all get logically NORed together to
form the interrupt output line. Talking to the PHY over MDIO is
slow. Sometimes you need to read multiple registers to find out what
caused the interrupt and clear it. So your initial read suggests
interrupt source Y triggered the interrupt. While you are clearing Y,
source X becomes active. After you have cleared Y, the NORed interrupt
line is still active, because of X. The interrupt handler exits, the
IRQ core reenabled the interrupt, and you expect it to fire again so
that you go handle source X. If it does not fire again, you have lost
an interrupt, and potentially the hardware stops working.

There are also other use cases of level interrupts. You sometimes see
two PHY devices sharing one level interrupt. You get the same sort of
race condition. PHY #1 pulls the interrupt low, triggering an
interrupt. While handling it, PHY #2 also pulls it low. When the
handler exits, it has only handled the interrupt from PHY #1. PHY #2
is still pulling the interrupt low, and needs its handler calling. So
it is required the interrupt fires again when it is re-enabled.

Given the protocol you have defined, how do you tell the firmware that
Linux has finished handling the interrupt, and it should notify Linux
again if the interrupt is still active?

Andrew