Thread (51 messages) 51 messages, 11 authors, 2025-12-03

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

From: Shenwei Wang <shenwei.wang@nxp.com>
Date: 2025-11-07 21:24:04
Also in: imx, linux-devicetree, linux-doc, linux-remoteproc, lkml

-----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
[off-list ref]; Rob Herring [off-list ref]; Krzysztof
Kozlowski [off-list ref]; Conor Dooley [off-list ref]; Shawn
Guo [off-list ref]; Sascha Hauer [off-list ref];
Jonathan Corbet [off-list ref]; Linus Walleij [off-list ref];
Bartosz Golaszewski [off-list ref]; Pengutronix Kernel Team
[off-list ref]; Fabio Estevam [off-list ref]; Peng Fan
[off-list ref]; 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 [off-list ref]
Subject: [EXT] Re: [PATCH v5 3/5] docs: staging: gpio-rpmsg: gpio over rpmsg bus
quoted
The power state of the remote GPIO controller is entirely managed by the
remote firmware.
quoted
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.
quoted
quoted
quoted
quoted
quoted
+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|
quoted
quoted
quoted
quoted
quoted
+   | 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?
quoted
quoted
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.
quoted
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
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help