Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver

Shenwei Wang
2026-05-05T14:41:53Z

> -----Original Message-----
> From: Beleswar Prasad Padhi <b-padhi@ti.com>
> Sent: Monday, May 4, 2026 3:17 AM
> To: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; Mathieu Poirier
> <mathieu.poirier@linaro.org>
> Cc: Shenwei Wang <shenwei.wang@nxp.com>; Andrew Lunn
> <andrew@lunn.ch>; Linus Walleij <linusw@kernel.org>; Bartosz Golaszewski
> <brgl@kernel.org>; Jonathan Corbet <corbet@lwn.net>; Rob Herring
> <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>; Conor Dooley
> <conor+dt@kernel.org>; Bjorn Andersson <andersson@kernel.org>; Frank Li
> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>; Shuah Khan
> <skhan@linuxfoundation.org>; linux-gpio@vger.kernel.org; linux-
> doc@vger.kernel.org; linux-kernel@vger.kernel.org; Pengutronix Kernel Team
> <kernel@pengutronix.de>; Fabio Estevam <festevam@gmail.com>; Peng Fan
> <peng.fan@nxp.com>; devicetree@vger.kernel.org; linux-
> remoteproc@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> kernel@lists.infradead.org; dl-linux-imx <linux-imx@nxp.com>; Bartosz
> Golaszewski <brgl@bgdev.pl>
> Subject: [EXT] Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
>
> Caution: This is an external email. Please take care when clicking links or opening
> attachments. When in doubt, report the message using the 'Report this email'
> button
>
>
> Hi Arnaud,
>
> On 30/04/26 22:10, Arnaud POULIQUEN wrote:
> >
> >
> > On 4/30/26 14:56, Beleswar Prasad Padhi wrote:
> >> Hello Arnaud,
> >>
> >> On 30/04/26 13:05, Arnaud POULIQUEN wrote:
> >>> Hello,
> >>>
> >>> On 4/29/26 21:20, Mathieu Poirier wrote:
> >>>> On Wed, 29 Apr 2026 at 12:07, Padhi, Beleswar <b-padhi@ti.com> wrote:
> >>>>>
> >>>>> Hi Mathieu,
> >>>>>
> >>>>> On 4/29/2026 11:03 PM, Mathieu Poirier wrote:
> >>>>>> On Wed, 29 Apr 2026 at 10:53, Shenwei Wang
> <shenwei.wang@nxp.com> wrote:
> >>>>
>
> [...]
>
> >>>>> My mental model looks like this for the complete picture:
> >>>>>
> >>>>> 1. namespace/channel#1 = rpmsg-io
> >>>>> a. ept1 -> gpio-controller@1
> >>>>> b. ept2 -> gpio-controller@2
> >>>>>
> >>>>
> >>>> I've asked for one endpoint per GPIO controller since the very
> >>>> beginning. I don't yet have a strong opinion on whether to use one
> >>>> namespace request per GPIO controller or a single request that
> >>>> spins off multiple endpoints. I'll have to look at your link and
> >>>> reflect on that. Regardless of how we proceed on that front,
> >>>> multiplexing needs to happen at the endpoint level rather than the
> >>>> packet level. This is the only way this work can move forward.
> >>>>
> >>>
> >>> I would be more in favor of Mathieu’s proposal: “An endpoint is created with
> every namespace request.”
> >>>
> >>> If the endpoint is created only on the Linux side, how do we match the Linux
> endpoint address with the local port field on the remote side?
> >>
> >>
> >> Simply by sending a message to the remote containing the newly
> >> created endpoint and the port idx. Note that is this done just one
> >> time, after this Linux need not have the port field in the message
> >> everytime its sending a message.
> >>
> >>>
> >>> With a multi-namespace approach, the namespace could be rpmsg-io-[addr],
> where [addr] corresponds to the GPIO controller address in the DT. This would:
> >>
> >>
> >> You will face the same problem in this case also that you asked above:
> >> "how do we match the Linux endpoint address with the local port field
> >> on the remote side?"
> >
> > Sorry I probably introduced confusion here my sentence should be;
> > With a multi-namespace approach, the namespace could be
> > rpmsg-io-[port], where [port] corresponds to the GPIO controller port in the
> DT.
> >
> >
> > For instance:
> >
> > rpmsg {
> > rpmsg-io {
> > #address-cells = <1>;
> > #size-cells = <0>;
> >
> > gpio@25 {
> > compatible = "rpmsg-gpio";
> > reg = <25>;
> > gpio-controller;
> > #gpio-cells = <2>;
> > #interrupt-cells = <2>;
> > interrupt-controller;
> > };
> >
> > gpio@32 {
> > compatible = "rpmsg-gpio";
> > reg = <32>;
> > gpio-controller;
> > #gpio-cells = <2>;
> > #interrupt-cells = <2>;
> > interrupt-controller;
> > };
> > };
> > };
> >
> > rpmsg-io-25 would match with gpio@25
> > rpmsg-io-32 would match with gpio@32
> >
> >
> >>
> >> Because the endpoint that is created on a namespace request is also
> >> dynamic in nature. How will the remote know which endpoint addr Linux
> >> allocated for a namespace that it announced?
> >>
> >> As an example/PoC, I created a firmware example which announces
> >> 2 name services to Linux, one is the standard "rpmsg_chrdev" and the
> >> other is a TI specific name service "ti.ipc4.ping-pong". You can see
> >> it created 2 different addresses (0x400 and 0x401) for each of the
> >> name service request from the same firmware:
> >>
> >> root@j784s4-evm:~# dmesg | grep virtio0 | grep -i channel
> >> [  9.290275] virtio_rpmsg_bus virtio0: creating channel ti.ipc4.ping-pong addr
> 0xd
> >> [  9.311230] virtio_rpmsg_bus virtio0: creating channel rpmsg_chrdev addr
> 0xe
> >> [  9.496645] rpmsg_chrdev virtio0.rpmsg_chrdev.-1.14: DEBUG: Channel
> formed from src = 0x400 to dst = 0xe
> >> [  9.707255] rpmsg_client_sample virtio0.ti.ipc4.ping-pong.-1.13: new
> channel: 0x401 -> 0xd!
> >>
> >> So in this case, rpmsg-io-1 can have different ept addr than
> >> rpmsg-io-2 Back to same problem. Simple solution is to reply to
> >> remote with the created ept addr and the index.
> >
> > That why I would like to suggest to use the name service field to identify the
> port/controller, instead of the endpoint address.
> >>
> >>>
> >>> - match the RPMsg probe with the DT,
> >>
> >>
> >> We can probe from all controllers with a single name service
> >> announcement too.
> >>
> >>> - provide a simple mapping between the port and the endpoint on both
> >>> sides,
> >>
> >>
> >> We are trying to get rid of this mapping from Linux side to adapt the
> >> gpio-virtio design.
> >>
> >>> - allow multiple endpoints on the remote side,
> >>
> >>
> >> We can support this as well with single nameservice model.
> >> There is no limitation. Remote has to send a message with its newly
> >> created ept that's all.
> >>
> >>> - provide a simple discovery mechanism for remote capabilities.
> >>
> >>
> >> A single announcement: "rpmsg-io" is also discovery mechanism.
> >>
> >> Feel free to let me know if you have concerns with any of the
> >> suggestions!
> >
> > My only concern, whatever the solution, is that we find a smart
> > solution to associate the correct endpoint with the correct GPIO
> > port/controller defined in the DT.
>
>
> In my solution, there is no need to have this map of endpoint to GPIO port at
> Linux side. This aligns more with virtio-gpio design as well.
>
> >
> > I may have misunderstood your solution. Could you please help me
> > understand your proposal by explaining how you would handle three GPIO
> > ports defined in the DT, considering that the endpoint addresses on
> > the Linux side can be random?
> > If I assume there is a unique endpoint on the remote side, I do not
> > understand how you can match, on the firmware side, the Linux endpoint
> > address to the GPIO port.
>
>
> Sure, let me take an example:
> Assumptions: 3 GPIO ports in DT, 3 endpoints in Linux (one per port),
> 1 endpoint in remote (0xd) and 1 rpmsg channel (rpmsg-io)
>
> rpmsg {
> rpmsg-io {
> #address-cells = <1>;
> #size-cells = <0>;
>
> gpio@25 {
> compatible = "rpmsg-gpio";
> reg = <25>;
> gpio-controller;
> #gpio-cells = <2>;
> #interrupt-cells = <2>;
> interrupt-controller;
> };
>
> gpio@32 {
> compatible = "rpmsg-gpio";
> reg = <32>;
> gpio-controller;
> #gpio-cells = <2>;
> #interrupt-cells = <2>;
> interrupt-controller;
> };
>
> gpio@35 {
> compatible = "rpmsg-gpio";
> reg = <35>;
> gpio-controller;
> #gpio-cells = <2>;
> #interrupt-cells = <2>;
> interrupt-controller;
> };
> };
> };
>
> Code Flow:
> 1. "rpmsg-io" channel is announced from remote firmware with unique dst
> ept = 0xd.
>
> 2. rpmsg_core.c creates the default dynamic local ept for the channel
> ept = 0x405.
>
> 3. rpmsg_core.c assigns the allocated addr to rpdev device:
> rpdev->src = 0x405 and rpdev->dst = 0xd.
>
> 4. rpmsg_gpio_channel_probe() is triggered. For *each* of the GPIO ports
> in DT, it will trigger rpmsg_gpiochip_register() which will now:
> a. Call port->ept = rpmsg_create_ept(rpdev,
> rpmsg_gpio_channel_callback,
> port,
> {rpdev.id.name,
> RPMSG_ADDR_ANY,
> RPMSG_ADDR_ANY});
> Ex- port->ept->addr = 0x408
>
> b. Prepare a 8-byte message having 2 fields:
> port->ept->addr (0x408) and port->idx (25)
>
> c. Send this message to remote firmware on default channel ept
> (0x405 -> 0xd) by:
> rpmsg_send(rpdev->ept, &message, sizeof(message));
>
> d. Remote side receives this message and creates a map of the
> linux_ept_addr to gpio_port. (0x408 <-> 25)
>
> 5. After this point, any gpio messages sent from Linux from gpio port
> endpoints (Ex- 0x408) can be decoded at remote side by looking up
> its map (Ex- map[0x408] = 25).
>
> 6. Any messages sent from remote to Linux for a particular gpio port can
> also be decoded at Linux by simply fetching the priv pointer to get
> the per-port device:
> struct rpmsg_gpio_port *port = priv;
>
> So Linux does not need to send the port idx everytime while sending a gpio
> message anymore.
>

I support the idea of encoding the port index directly into ept->addr.
To keep the design simple, we can rely on a predefined rule to derive ept->src, rather than
exchanging additional configuration. One approach is to use the default channel address as
the base address and encode the port index into the lower bits. For example:

ept->src = (baseaddr << 8) | port_index;

With this scheme, the endpoint-to-port mapping can be encoded implicitly, eliminating the need
for an extra message to exchange EPT and port mapping information.

Thanks,
Shenwei

> Thanks,
> Beleswar
>
> …