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

Shenwei Wang
2025-11-07T21:24:04Z

> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Thursday, November 6, 2025 6:32 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Bjorn Andersson <andersson@kernel.org>; Mathieu Poirier
> <mathieu.poirier@linaro.org>; Rob Herring <robh@kernel.org>; Krzysztof
> Kozlowski <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Shawn
> Guo <shawnguo@kernel.org>; Sascha Hauer <s.hauer@pengutronix.de>;
> Jonathan Corbet <corbet@lwn.net>; Linus Walleij <linus.walleij@linaro.org>;
> Bartosz Golaszewski <brgl@bgdev.pl>; Pengutronix Kernel Team
> <kernel@pengutronix.de>; Fabio Estevam <festevam@gmail.com>; Peng Fan
> <peng.fan@nxp.com>; linux-remoteproc@vger.kernel.org;
> devicetree@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org; linux-
> doc@vger.kernel.org; dl-linux-imx <linux-imx@nxp.com>
> Subject: [EXT] Re: [PATCH v5 3/5] docs: staging: gpio-rpmsg: gpio over rpmsg bus
> >
> > 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?
>

The remote system should always aim to stay in a power-efficient state by shutting down
or clock-gating any blocks that aren't in use. In this wakeup scenario, if no GPIO lines are
requested or marked as wakeup sources for Linux, the remote firmware should put the
GPIO controller into a low-power state.

> > > > > > +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?
>

Okay. To fully simulate a level-triggered interrupt, a notification reply message is required.

Remote firmware sequence:
Receive the level-triggered GPIO interrupt.
Mask the interrupt for the corresponding line.
Send a notification message to Linux.
Wait for the notification reply, then unmask the interrupt for the line.

Linux sequence:
Receive the notification message.
Invoke the interrupt handler for the line.
Send a notification reply to the remote firmware to indicate End of Interrupt (EOI).

Thanks,
Shenwei

> Andrew