public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform
@ 2026-02-12 21:36 Shenwei Wang
  2026-02-12 21:36 ` [PATCH v8 1/4] docs: driver-api: gpio: rpmsg gpio driver over rpmsg bus Shenwei Wang
                   ` (4 more replies)
  0 siblings, 5 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-12 21:36 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio, linux-doc, linux-kernel,
	Pengutronix Kernel Team, Fabio Estevam, Shenwei Wang, Peng Fan,
	devicetree, linux-remoteproc, imx, linux-arm-kernel, linux-imx,
	arnaud.pouliquen

Support the remote devices on the remote processor via the RPMSG bus on
i.MX platform.

Changes in v8:
 - Add "depends on REMOTEPROC" in Kconfig to fix the build error reported
   by the kernel test robot.
 - Move the .rst patch before the .yaml patch.
 - Handle the "ngpios" DT property based on Andrew's feedback.

Changes in v7:
 - Reworked the driver to use the rpmsg_driver framework instead of
   platform_driver, based on feedback from Bjorn and Arnaud.
 - Updated gpio-rpmsg.yaml and imx_rproc.yaml according to comments from
   Rob and Arnaud.
 - Further refinements to gpio-rpmsg.yaml per Arnaud's feedback.

Changes in v6:
 - make the driver more generic with the actions below:
     rename the driver file to gpio-rpmsg.c
     remove the imx related info in the function and variable names
     rename the imx_rpmsg.h to rpdev_info.h
     create a gpio-rpmsg.yaml and refer it in imx_rproc.yaml
 - update the gpio-rpmsg.rst according to the feedback from Andrew and
   move the source file to driver-api/gpio
 - fix the bug reported by Zhongqiu Han
 - remove the I2C related info

Changes in v5:
 - move the gpio-rpmsg.rst from admin-guide to staging directory after
   discussion with Randy Dunlap.
 - add include files with some code improvements per Bartosz's comments.

Changes in v4:
 - add a documentation to describe the transport protocol per Andrew's
   comments.
 - add a new handler to get the gpio direction.

Changes in v3:
 - fix various format issue and return value check per Peng 's review
   comments.
 - add the logic to also populate the subnodes which are not in the
   device map per Arnaud's request. (in imx_rproc.c)
 - update the yaml per Frank's review comments.

Changes in v2:
 - re-implemented the gpio driver per Linus Walleij's feedback by using
   GPIOLIB_IRQCHIP helper library.
 - fix various format issue per Mathieu/Peng 's review comments.
 - update the yaml doc per Rob's feedback

Shenwei Wang (4):
  docs: driver-api: gpio: rpmsg gpio driver over rpmsg bus
  dt-bindings: remoteproc: imx_rproc: Add "rpmsg" subnode support
  gpio: rpmsg: add generic rpmsg GPIO driver
  arm64: dts: imx8ulp: Add rpmsg node under imx_rproc

 .../devicetree/bindings/gpio/gpio-rpmsg.yaml  |  55 ++
 .../bindings/remoteproc/fsl,imx-rproc.yaml    |  53 ++
 Documentation/driver-api/gpio/gpio-rpmsg.rst  | 236 +++++++
 Documentation/driver-api/gpio/index.rst       |   1 +
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi    |  25 +
 drivers/gpio/Kconfig                          |  17 +
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-rpmsg.c                     | 588 ++++++++++++++++++
 8 files changed, 976 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-rpmsg.yaml
 create mode 100644 Documentation/driver-api/gpio/gpio-rpmsg.rst
 create mode 100644 drivers/gpio/gpio-rpmsg.c

--
2.43.0



^ permalink raw reply	[flat|nested] 69+ messages in thread

* [PATCH v8 1/4] docs: driver-api: gpio: rpmsg gpio driver over rpmsg bus
  2026-02-12 21:36 [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform Shenwei Wang
@ 2026-02-12 21:36 ` Shenwei Wang
  2026-02-12 21:36 ` [PATCH v8 2/4] dt-bindings: remoteproc: imx_rproc: Add "rpmsg" subnode support Shenwei Wang
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-12 21:36 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio, linux-doc, linux-kernel,
	Pengutronix Kernel Team, Fabio Estevam, Shenwei Wang, Peng Fan,
	devicetree, linux-remoteproc, imx, linux-arm-kernel, linux-imx,
	arnaud.pouliquen

Describes the gpio rpmsg transport protocol over the rpmsg bus between
the remote system and Linux.

Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
---
 Documentation/driver-api/gpio/gpio-rpmsg.rst | 236 +++++++++++++++++++
 Documentation/driver-api/gpio/index.rst      |   1 +
 2 files changed, 237 insertions(+)
 create mode 100644 Documentation/driver-api/gpio/gpio-rpmsg.rst

diff --git a/Documentation/driver-api/gpio/gpio-rpmsg.rst b/Documentation/driver-api/gpio/gpio-rpmsg.rst
new file mode 100644
index 000000000000..59eb0d49002a
--- /dev/null
+++ b/Documentation/driver-api/gpio/gpio-rpmsg.rst
@@ -0,0 +1,236 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+GPIO RPMSG Protocol
+===================
+
+The GPIO RPMSG transport protocol is used for communication and interaction
+with GPIO controllers located on remote cores on the RPMSG bus.
+
+Message Format
+--------------
+
+The RPMSG message consists of a 14-byte packet with the following layout:
+
+.. code-block:: none
+
+   +-----+-------+--------+-----+-----+------------+-----+-----+-----+----+
+   |0x00 |0x01   |0x02    |0x03 |0x04 |0x05..0x09  |0x0A |0x0B |0x0C |0x0D|
+   | ID  |vendor |version |type |cmd  |reserved[5] |line |port |  data    |
+   +-----+-------+--------+-----+-----+------------+-----+-----+-----+----+
+
+- **ID (Message Identification Code)**: Must be 0x5. Indicates the GPIO message.
+
+- **Vendor**: Vendor ID number.
+  - 0: Reserved
+  - 1: NXP
+
+- **Version**: Vendor-specific version number (such as software release).
+
+- **Type (Message Type)**: The message type can be one of:
+
+  - 0: GPIO_RPMSG_SETUP
+  - 1: GPIO_RPMSG_REPLY
+  - 2: GPIO_RPMSG_NOTIFY
+
+- **Cmd**: Command code, used for GPIO_RPMSG_SETUP messages.
+
+- **reserved[5]**: Reserved bytes. Should always be 0.
+
+- **line**: The GPIO line(pin) index of the port.
+
+- **port**: The GPIO port(bank) index.
+
+- **data**: See details in the command description below.
+
+GPIO Commands
+-------------
+
+Commands are specified in the **Cmd** field for **GPIO_RPMSG_SETUP** (Type=0) messages.
+
+The SETUP message is always sent from Linux to the remote firmware. Each
+SETUP corresponds to a single REPLY message. The GPIO driver should
+serialize messages and determine whether a REPLY message is required. If a
+REPLY message is expected but not received within the specified timeout
+period (currently 1 second in the Linux driver), the driver should return
+-ETIMEOUT.
+
+GPIO_RPMSG_INPUT_INIT (Cmd=0)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Request:**
+
+.. code-block:: none
+
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D|
+   | 5   | 1   | 0   | 0   | 0   |  0        |line |port | val | wk |
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+
+- **val**: Interrupt trigger type.
+
+  - 0: Interrupt disabled
+  - 1: Rising edge trigger
+  - 2: Falling edge trigger
+  - 3: Both edge trigger
+  - 4: Low level trigger
+  - 5: High level trigger
+
+- **wk**: Wakeup enable.
+
+  The remote system should always aim to stay in a power-efficient state by
+  shutting down or clock-gating the GPIO blocks that aren't in use. Since
+  the remoteproc driver is responsible for managing the power states of the
+  remote firmware, the GPIO driver does not require to know the firmware's
+  running states.
+
+  When the wakeup bit is set, the remote firmware should configure the line
+  as a wakeup source. The firmware should send the notification message to
+  Linux after it is woken from the GPIO line.
+
+  - 0: Disable wakeup from GPIO
+  - 1: Enable wakeup from GPIO
+
+**Reply:**
+
+.. code-block:: none
+
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D|
+   | 5   | 1   | 0   | 1   | 1   |  0        |line |port | err | 0  |
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+
+- **err**: Error code from the remote core.
+
+  - 0: Success
+  - 1: General error (Early remote software only returns this unclassified error)
+  - 2: Not supported (A command is not supported by the remote firmware)
+  - 3: Resource not available (The resource is not allocated to Linux)
+  - 4: Resource busy (The resource is already in use)
+  - 5: Parameter error
+
+GPIO_RPMSG_OUTPUT_INIT (Cmd=1)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Request:**
+
+.. code-block:: none
+
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D|
+   | 5   | 1   | 0   | 0   | 1   |  0        |line |port | val | 0  |
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+
+- **val**: Output level.
+
+  - 0: Low
+  - 1: High
+
+**Reply:**
+
+.. code-block:: none
+
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D|
+   | 5   | 1   | 0   | 1   | 1   |  0        |line |port | err | 0  |
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+
+- **err**: See above for definitions.
+
+GPIO_RPMSG_INPUT_GET (Cmd=2)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Request:**
+
+.. code-block:: none
+
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D|
+   | 5   | 1   | 0   | 0   | 2   |  0        |line |port | 0   | 0  |
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+
+**Reply:**
+
+.. code-block:: none
+
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+-----+
+   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D |
+   | 5   | 1   | 0   | 1   | 2   |  0        |line |port | err |level|
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+-----+
+
+- **err**: See above for definitions.
+
+- **level**: Input level.
+
+  - 0: Low
+  - 1: High
+
+GPIO_RPMSG_GET_DIRECTION (Cmd=3)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Request:**
+
+.. code-block:: none
+
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D|
+   | 5   | 1   | 0   | 0   | 3   |  0        |line |port | 0   | 0  |
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+
+**Reply:**
+
+.. code-block:: none
+
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+-----+
+   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D |
+   | 5   | 1   | 0   | 1   | 3   |  0        |line |port | err | dir |
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+-----+
+
+- **err**: See above for definitions.
+
+- **dir**: Direction.
+
+  - 0: Output
+  - 1: Input
+
+GPIO_RPMSG_NOTIFY_REPLY (Cmd=4)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The reply message for the notification is optional. The remote firmware can
+implement it to simulate the interrupt acknowledgment behavior.
+
+**Request:**
+
+.. code-block:: none
+
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D|
+   | 5   | 1   | 0   | 0   | 4   |  0        |line |port |level| 0  |
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+
+- **line**: The GPIO line(pin) index of the port.
+- **port**: The GPIO port(bank) index.
+
+Notification Message
+--------------------
+
+Notifications are sent with **Type=2 (GPIO_RPMSG_NOTIFY)**:
+
+When a GPIO line asserts an interrupt on the remote processor, the firmware
+should immediately mask the corresponding interrupt source and send a
+notification message to the Linux. Upon completion of the interrupt
+handling on the Linux side, the driver should issue a
+**GPIO_RPMSG_INPUT_INIT** command to the firmware to unmask the interrupt.
+
+A Notification message can arrive between a SETUP and its REPLY message,
+and the driver is expected to handle this scenario.
+
+.. code-block:: none
+
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D|
+   | 5   | 1   | 0   | 2   | 0   |  0        |line |port |type | 0  |
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+
+- **line**: The GPIO line(pin) index of the port.
+- **port**: The GPIO port(bank) index.
+- **type**: Optional parameter to indicate the trigger event type.
+
diff --git a/Documentation/driver-api/gpio/index.rst b/Documentation/driver-api/gpio/index.rst
index bee58f709b9a..e5eb1f82f01f 100644
--- a/Documentation/driver-api/gpio/index.rst
+++ b/Documentation/driver-api/gpio/index.rst
@@ -16,6 +16,7 @@ Contents:
    drivers-on-gpio
    bt8xxgpio
    pca953x
+   gpio-rpmsg
 
 Core
 ====
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v8 2/4] dt-bindings: remoteproc: imx_rproc: Add "rpmsg" subnode support
  2026-02-12 21:36 [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform Shenwei Wang
  2026-02-12 21:36 ` [PATCH v8 1/4] docs: driver-api: gpio: rpmsg gpio driver over rpmsg bus Shenwei Wang
@ 2026-02-12 21:36 ` Shenwei Wang
  2026-02-12 21:36 ` [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver Shenwei Wang
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-12 21:36 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio, linux-doc, linux-kernel,
	Pengutronix Kernel Team, Fabio Estevam, Shenwei Wang, Peng Fan,
	devicetree, linux-remoteproc, imx, linux-arm-kernel, linux-imx,
	arnaud.pouliquen

Remote processors may announce multiple GPIO controllers over an RPMSG
channel. These GPIO controllers may require corresponding device tree
nodes, especially when acting as providers, to supply phandles for their
consumers.

Define an RPMSG node to work as a container for a group of RPMSG channels
under the imx_rproc node. Each subnode within "rpmsg" represents an
individual RPMSG channel. The name of each subnode corresponds to the
channel name as defined by the remote processor.

All remote devices associated with a given channel are defined as child
nodes under the corresponding channel node.

Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
---
 .../devicetree/bindings/gpio/gpio-rpmsg.yaml  | 55 +++++++++++++++++++
 .../bindings/remoteproc/fsl,imx-rproc.yaml    | 53 ++++++++++++++++++
 2 files changed, 108 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-rpmsg.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-rpmsg.yaml b/Documentation/devicetree/bindings/gpio/gpio-rpmsg.yaml
new file mode 100644
index 000000000000..6c78b6850321
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-rpmsg.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-rpmsg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic RPMSG GPIO Controller
+
+maintainers:
+  - Shenwei Wang <shenwei.wang@nxp.com>
+
+description:
+  On an AMP platform, some GPIO controllers are exposed by the remote processor
+  through the RPMSG bus. The RPMSG GPIO transport protocol defines the packet
+  structure and communication flow between Linux and the remote firmware. Those
+  controllers are managed via this transport protocol. For more details of the
+  protocol, check the document below.
+  Documentation/driver-api/gpio/gpio-rpmsg.rst
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - fsl,rpmsg-gpio
+          - const: rpmsg-gpio
+      - const: rpmsg-gpio
+
+  reg:
+    description:
+      The reg property represents the index of the GPIO controllers. Since
+      the driver manages controllers on a remote system, this index tells
+      the remote system which controller to operate.
+    maxItems: 1
+
+  "#gpio-cells":
+    const: 2
+
+  gpio-controller: true
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - "#gpio-cells"
+  - "#interrupt-cells"
+
+allOf:
+  - $ref: /schemas/gpio/gpio.yaml#
+
+unevaluatedProperties: false
diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
index ce8ec0119469..88281ffc18ca 100644
--- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
@@ -85,6 +85,34 @@ properties:
       This property is to specify the resource id of the remote processor in SoC
       which supports SCFW
 
+  rpmsg:
+    type: object
+    additionalProperties: false
+    description:
+      Represents the RPMSG bus between Linux and the remote system. Contains
+      a group of RPMSG channel devices running on the bus.
+
+    properties:
+      rpmsg-io-channel:
+        type: object
+        additionalProperties: false
+        properties:
+          '#address-cells':
+            const: 1
+
+          '#size-cells':
+            const: 0
+
+        patternProperties:
+          "gpio@[0-9a-f]+$":
+            type: object
+            $ref: /schemas/gpio/gpio-rpmsg.yaml#
+            unevaluatedProperties: false
+
+        required:
+          - '#address-cells'
+          - '#size-cells'
+
 required:
   - compatible
 
@@ -147,5 +175,30 @@ examples:
                 &mu 3 1>;
       memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>;
       syscon = <&src>;
+
+      rpmsg {
+        rpmsg-io-channel {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          gpio@0 {
+            compatible = "rpmsg-gpio";
+            reg = <0>;
+            gpio-controller;
+            #gpio-cells = <2>;
+            #interrupt-cells = <2>;
+            interrupt-controller;
+          };
+
+          gpio@1 {
+            compatible = "rpmsg-gpio";
+            reg = <1>;
+            gpio-controller;
+            #gpio-cells = <2>;
+            #interrupt-cells = <2>;
+            interrupt-controller;
+          };
+        };
+      };
     };
 ...
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-12 21:36 [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform Shenwei Wang
  2026-02-12 21:36 ` [PATCH v8 1/4] docs: driver-api: gpio: rpmsg gpio driver over rpmsg bus Shenwei Wang
  2026-02-12 21:36 ` [PATCH v8 2/4] dt-bindings: remoteproc: imx_rproc: Add "rpmsg" subnode support Shenwei Wang
@ 2026-02-12 21:36 ` Shenwei Wang
  2026-02-18 10:20   ` Bartosz Golaszewski
  2026-02-19  9:20   ` Arnaud POULIQUEN
  2026-02-12 21:36 ` [PATCH v8 4/4] arm64: dts: imx8ulp: Add rpmsg node under imx_rproc Shenwei Wang
  2026-02-20  9:18 ` [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform Daniel Baluta
  4 siblings, 2 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-12 21:36 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio, linux-doc, linux-kernel,
	Pengutronix Kernel Team, Fabio Estevam, Shenwei Wang, Peng Fan,
	devicetree, linux-remoteproc, imx, linux-arm-kernel, linux-imx,
	arnaud.pouliquen, Bartosz Golaszewski, Andrew Lunn

On an AMP platform, the system may include two processors:
	- An MCU running an RTOS
	- An MPU running Linux

These processors communicate via the RPMSG protocol.
The driver implements the standard GPIO interface, allowing
the Linux side to control GPIO controllers which reside in
the remote processor via RPMSG protocol.

Cc: Bartosz Golaszewski <brgl@bgdev.pl>
Cc: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
---
 drivers/gpio/Kconfig      |  17 ++
 drivers/gpio/Makefile     |   1 +
 drivers/gpio/gpio-rpmsg.c | 588 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 606 insertions(+)
 create mode 100644 drivers/gpio/gpio-rpmsg.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b45fb799e36c..3179a54f0634 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1892,6 +1892,23 @@ config GPIO_SODAVILLE
 
 endmenu
 
+menu "RPMSG GPIO drivers"
+	depends on RPMSG
+
+config GPIO_RPMSG
+	tristate "Generic RPMSG GPIO support"
+	depends on REMOTEPROC
+	select GPIOLIB_IRQCHIP
+	default REMOTEPROC
+	help
+	  Say yes here to support the generic GPIO functions over the RPMSG
+	  bus. Currently supported devices: i.MX7ULP, i.MX8ULP, i.MX8x, and
+	  i.MX9x.
+
+	  If unsure, say N.
+
+endmenu
+
 menu "SPI GPIO expanders"
 	depends on SPI_MASTER
 
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index c05f7d795c43..501aba56ad68 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -158,6 +158,7 @@ obj-$(CONFIG_GPIO_RDC321X)		+= gpio-rdc321x.o
 obj-$(CONFIG_GPIO_REALTEK_OTTO)		+= gpio-realtek-otto.o
 obj-$(CONFIG_GPIO_REG)			+= gpio-reg.o
 obj-$(CONFIG_GPIO_ROCKCHIP)	+= gpio-rockchip.o
+obj-$(CONFIG_GPIO_RPMSG)		+= gpio-rpmsg.o
 obj-$(CONFIG_GPIO_RTD)			+= gpio-rtd.o
 obj-$(CONFIG_ARCH_SA1100)		+= gpio-sa1100.o
 obj-$(CONFIG_GPIO_SAMA5D2_PIOBU)	+= gpio-sama5d2-piobu.o
diff --git a/drivers/gpio/gpio-rpmsg.c b/drivers/gpio/gpio-rpmsg.c
new file mode 100644
index 000000000000..163f51fd45b5
--- /dev/null
+++ b/drivers/gpio/gpio-rpmsg.c
@@ -0,0 +1,588 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2026 NXP
+ *
+ * The driver exports a standard gpiochip interface to control
+ * the GPIO controllers via RPMSG on a remote processor.
+ */
+#include <linux/completion.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/init.h>
+#include <linux/irqdomain.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+#include <linux/rpmsg.h>
+
+#define RPMSG_GPIO_ID		5
+#define RPMSG_VENDOR		1
+#define RPMSG_VERSION		0
+
+#define GPIOS_PER_PORT_DEFAULT	32
+#define RPMSG_TIMEOUT		1000
+
+/* GPIO RPMSG header type */
+#define GPIO_RPMSG_SETUP	0
+#define GPIO_RPMSG_REPLY	1
+#define GPIO_RPMSG_NOTIFY	2
+
+/* GPIO Interrupt trigger type */
+#define GPIO_RPMSG_TRI_IGNORE		0
+#define GPIO_RPMSG_TRI_RISING		1
+#define GPIO_RPMSG_TRI_FALLING		2
+#define GPIO_RPMSG_TRI_BOTH_EDGE	3
+#define GPIO_RPMSG_TRI_LOW_LEVEL	4
+#define GPIO_RPMSG_TRI_HIGH_LEVEL	5
+
+/* GPIO RPMSG commands */
+#define GPIO_RPMSG_INPUT_INIT		0
+#define GPIO_RPMSG_OUTPUT_INIT		1
+#define GPIO_RPMSG_INPUT_GET		2
+#define GPIO_RPMSG_DIRECTION_GET	3
+
+#define MAX_PORT_PER_CHANNEL    10
+
+/*
+ * @rproc_name: the name of the remote proc.
+ * @channel_devices: an array of the devices related to the rpdev.
+ */
+struct rpdev_drvdata {
+	const char *rproc_name;
+	void *channel_devices[MAX_PORT_PER_CHANNEL];
+};
+
+struct gpio_rpmsg_head {
+	u8 id;		/* Message ID Code */
+	u8 vendor;	/* Vendor ID number */
+	u8 version;	/* Vendor-specific version number */
+	u8 type;	/* Message type */
+	u8 cmd;		/* Command code */
+	u8 reserved[5];
+} __packed;
+
+struct gpio_rpmsg_packet {
+	struct gpio_rpmsg_head header;
+	u8 pin_idx;
+	u8 port_idx;
+	union {
+		u8 event;
+		u8 retcode;
+		u8 value;
+	} out;
+	union {
+		u8 wakeup;
+		u8 value;
+	} in;
+} __packed __aligned(8);
+
+struct gpio_rpmsg_pin {
+	u8 irq_shutdown;
+	u8 irq_unmask;
+	u8 irq_mask;
+	u32 irq_wake_enable;
+	u32 irq_type;
+	struct gpio_rpmsg_packet msg;
+};
+
+struct gpio_rpmsg_info {
+	struct rpmsg_device *rpdev;
+	struct gpio_rpmsg_packet *reply_msg;
+	struct completion cmd_complete;
+	struct mutex lock;
+	void **port_store;
+};
+
+struct rpmsg_gpio_port {
+	struct gpio_chip gc;
+	struct gpio_rpmsg_pin gpio_pins[GPIOS_PER_PORT_DEFAULT];
+	struct gpio_rpmsg_info info;
+	u32 ngpios;
+	u32 idx;
+};
+
+static int gpio_send_message(struct rpmsg_gpio_port *port,
+			     struct gpio_rpmsg_packet *msg,
+			     bool sync)
+{
+	struct gpio_rpmsg_info *info = &port->info;
+	int err;
+
+	reinit_completion(&info->cmd_complete);
+	err = rpmsg_send(info->rpdev->ept, msg, sizeof(struct gpio_rpmsg_packet));
+	if (err) {
+		dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
+		return err;
+	}
+
+	if (sync) {
+		err = wait_for_completion_timeout(&info->cmd_complete,
+						  msecs_to_jiffies(RPMSG_TIMEOUT));
+		if (err == 0) {
+			dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
+			return -ETIMEDOUT;
+		}
+
+		if (info->reply_msg->out.retcode != 0) {
+			dev_err(&info->rpdev->dev, "remote core replies an error: %d!\n",
+				info->reply_msg->out.retcode);
+			return -EINVAL;
+		}
+
+		/* copy the reply message */
+		memcpy(&port->gpio_pins[info->reply_msg->pin_idx].msg,
+		       info->reply_msg, sizeof(*info->reply_msg));
+	}
+
+	return 0;
+}
+
+static struct gpio_rpmsg_packet *gpio_setup_msg_common(struct rpmsg_gpio_port *port,
+						       unsigned int offset,
+						       u8 cmd)
+{
+	struct gpio_rpmsg_packet *msg = &port->gpio_pins[offset].msg;
+
+	memset(msg, 0, sizeof(struct gpio_rpmsg_packet));
+	msg->header.id = RPMSG_GPIO_ID;
+	msg->header.vendor = RPMSG_VENDOR;
+	msg->header.version = RPMSG_VERSION;
+	msg->header.type = GPIO_RPMSG_SETUP;
+	msg->header.cmd = cmd;
+	msg->pin_idx = offset;
+	msg->port_idx = port->idx;
+
+	return msg;
+}
+
+static int rpmsg_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
+	struct gpio_rpmsg_packet *msg;
+	int ret;
+
+	guard(mutex)(&port->info.lock);
+
+	msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_INPUT_GET);
+
+	ret = gpio_send_message(port, msg, true);
+	if (!ret)
+		ret = !!port->gpio_pins[gpio].msg.in.value;
+
+	return ret;
+}
+
+static int rpmsg_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
+	struct gpio_rpmsg_packet *msg;
+	int ret;
+
+	guard(mutex)(&port->info.lock);
+
+	msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_DIRECTION_GET);
+
+	ret = gpio_send_message(port, msg, true);
+	if (!ret)
+		ret = !!port->gpio_pins[gpio].msg.in.value;
+
+	return ret;
+}
+
+static int rpmsg_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
+	struct gpio_rpmsg_packet *msg;
+
+	guard(mutex)(&port->info.lock);
+
+	msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_INPUT_INIT);
+
+	return gpio_send_message(port, msg, true);
+}
+
+static int rpmsg_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
+	struct gpio_rpmsg_packet *msg;
+
+	guard(mutex)(&port->info.lock);
+
+	msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_OUTPUT_INIT);
+	msg->out.value = val;
+
+	return gpio_send_message(port, msg, true);
+}
+
+static int rpmsg_gpio_direction_output(struct gpio_chip *gc,
+				       unsigned int gpio,
+				       int val)
+{
+	return rpmsg_gpio_set(gc, gpio, val);
+}
+
+static int gpio_rpmsg_irq_set_type(struct irq_data *d, u32 type)
+{
+	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
+	u32 gpio_idx = d->hwirq;
+	int edge = 0;
+	int ret = 0;
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		edge = GPIO_RPMSG_TRI_RISING;
+		irq_set_handler_locked(d, handle_simple_irq);
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		edge = GPIO_RPMSG_TRI_FALLING;
+		irq_set_handler_locked(d, handle_simple_irq);
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		edge = GPIO_RPMSG_TRI_BOTH_EDGE;
+		irq_set_handler_locked(d, handle_simple_irq);
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		edge = GPIO_RPMSG_TRI_LOW_LEVEL;
+		irq_set_handler_locked(d, handle_level_irq);
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		edge = GPIO_RPMSG_TRI_HIGH_LEVEL;
+		irq_set_handler_locked(d, handle_level_irq);
+		break;
+	default:
+		ret = -EINVAL;
+		irq_set_handler_locked(d, handle_bad_irq);
+		break;
+	}
+
+	port->gpio_pins[gpio_idx].irq_type = edge;
+
+	return ret;
+}
+
+static int gpio_rpmsg_irq_set_wake(struct irq_data *d, u32 enable)
+{
+	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
+	u32 gpio_idx = d->hwirq;
+
+	port->gpio_pins[gpio_idx].irq_wake_enable = enable;
+
+	return 0;
+}
+
+/*
+ * This unmask/mask function is invoked in two situations:
+ *   - when an interrupt is being set up, and
+ *   - after an interrupt has occurred.
+ *
+ * The GPIO driver does not access hardware registers directly.
+ * Instead, it caches all relevant information locally, and then sends
+ * the accumulated state to the remote system at this stage.
+ */
+static void gpio_rpmsg_unmask_irq(struct irq_data *d)
+{
+	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
+	u32 gpio_idx = d->hwirq;
+
+	port->gpio_pins[gpio_idx].irq_unmask = 1;
+}
+
+static void gpio_rpmsg_mask_irq(struct irq_data *d)
+{
+	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
+	u32 gpio_idx = d->hwirq;
+
+	/*
+	 * When an interrupt occurs, the remote system masks the interrupt
+	 * and then sends a notification to Linux. After Linux processes
+	 * that notification, it sends an RPMsg command back to the remote
+	 * system to unmask the interrupt again.
+	 */
+	port->gpio_pins[gpio_idx].irq_mask = 1;
+}
+
+static void gpio_rpmsg_irq_shutdown(struct irq_data *d)
+{
+	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
+	u32 gpio_idx = d->hwirq;
+
+	port->gpio_pins[gpio_idx].irq_shutdown = 1;
+}
+
+static void gpio_rpmsg_irq_bus_lock(struct irq_data *d)
+{
+	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
+
+	mutex_lock(&port->info.lock);
+}
+
+static void gpio_rpmsg_irq_bus_sync_unlock(struct irq_data *d)
+{
+	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
+	struct gpio_rpmsg_packet *msg = NULL;
+	u32 gpio_idx = d->hwirq;
+
+	/*
+	 * For mask irq, do nothing here.
+	 * The remote system will mask interrupt after an interrupt occurs,
+	 * and then send a notify to Linux system.
+	 * After Linux system dealt with the notify, it will send an rpmsg to
+	 * the remote system to unmask this interrupt again.
+	 */
+	if (port->gpio_pins[gpio_idx].irq_mask && !port->gpio_pins[gpio_idx].irq_unmask) {
+		port->gpio_pins[gpio_idx].irq_mask = 0;
+		mutex_unlock(&port->info.lock);
+		return;
+	}
+
+	msg = gpio_setup_msg_common(port, gpio_idx, GPIO_RPMSG_INPUT_INIT);
+
+	if (port->gpio_pins[gpio_idx].irq_shutdown) {
+		msg->out.event = GPIO_RPMSG_TRI_IGNORE;
+		msg->in.wakeup = 0;
+		port->gpio_pins[gpio_idx].irq_shutdown = 0;
+	} else {
+		/* if not set irq type, then use low level as trigger type */
+		msg->out.event = port->gpio_pins[gpio_idx].irq_type;
+		if (!msg->out.event)
+			msg->out.event = GPIO_RPMSG_TRI_LOW_LEVEL;
+		if (port->gpio_pins[gpio_idx].irq_unmask) {
+			msg->in.wakeup = 0;
+			port->gpio_pins[gpio_idx].irq_unmask = 0;
+		} else /* irq set wake */
+			msg->in.wakeup = port->gpio_pins[gpio_idx].irq_wake_enable;
+	}
+
+	gpio_send_message(port, msg, false);
+	mutex_unlock(&port->info.lock);
+}
+
+static const struct irq_chip gpio_rpmsg_irq_chip = {
+	.irq_mask = gpio_rpmsg_mask_irq,
+	.irq_unmask = gpio_rpmsg_unmask_irq,
+	.irq_set_wake = gpio_rpmsg_irq_set_wake,
+	.irq_set_type = gpio_rpmsg_irq_set_type,
+	.irq_shutdown = gpio_rpmsg_irq_shutdown,
+	.irq_bus_lock = gpio_rpmsg_irq_bus_lock,
+	.irq_bus_sync_unlock = gpio_rpmsg_irq_bus_sync_unlock,
+	.flags = IRQCHIP_IMMUTABLE,
+};
+
+static void rpmsg_gpio_remove_action(void *data)
+{
+	struct rpmsg_gpio_port *port = data;
+
+	port->info.port_store[port->idx] = NULL;
+}
+
+static int rpmsg_gpiochip_register(struct rpmsg_device *rpdev, struct device_node *np)
+{
+	struct rpdev_drvdata *drvdata = dev_get_drvdata(&rpdev->dev);
+	struct rpmsg_gpio_port *port;
+	struct gpio_irq_chip *girq;
+	struct gpio_chip *gc;
+	int ret;
+
+	port = devm_kzalloc(&rpdev->dev, sizeof(*port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(np, "reg", &port->idx);
+	if (ret)
+		return ret;
+
+	if (port->idx >= MAX_PORT_PER_CHANNEL)
+		return -EINVAL;
+
+	ret = devm_mutex_init(&rpdev->dev, &port->info.lock);
+	if (ret)
+		return ret;
+
+	ret = of_property_read_u32(np, "ngpios", &port->ngpios);
+	if (ret)
+		port->ngpios = GPIOS_PER_PORT_DEFAULT;
+
+	init_completion(&port->info.cmd_complete);
+	port->info.reply_msg = devm_kzalloc(&rpdev->dev,
+					    sizeof(struct gpio_rpmsg_packet),
+					    GFP_KERNEL);
+	port->info.port_store = drvdata->channel_devices;
+	port->info.port_store[port->idx] = port;
+	port->info.rpdev = rpdev;
+
+	gc = &port->gc;
+	gc->owner = THIS_MODULE;
+	gc->parent = &rpdev->dev;
+	gc->fwnode = of_fwnode_handle(np);
+	gc->ngpio = port->ngpios;
+	gc->base = -1;
+	gc->label = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-gpio%d",
+				   drvdata->rproc_name, port->idx);
+
+	gc->direction_input = rpmsg_gpio_direction_input;
+	gc->direction_output = rpmsg_gpio_direction_output;
+	gc->get_direction = rpmsg_gpio_get_direction;
+	gc->get = rpmsg_gpio_get;
+	gc->set = rpmsg_gpio_set;
+
+	girq = &gc->irq;
+	gpio_irq_chip_set_chip(girq, &gpio_rpmsg_irq_chip);
+	girq->parent_handler = NULL;
+	girq->num_parents = 0;
+	girq->parents = NULL;
+	girq->chip->name = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-gpio%d",
+					  drvdata->rproc_name, port->idx);
+
+	ret = devm_add_action_or_reset(&rpdev->dev, rpmsg_gpio_remove_action, port);
+	if (ret)
+		return ret;
+
+	return devm_gpiochip_add_data(&rpdev->dev, gc, port);
+}
+
+static const char *rpmsg_get_rproc_node_name(struct rpmsg_device *rpdev)
+{
+	const char *name = NULL;
+	struct device_node *np;
+	struct rproc *rproc;
+
+	rproc = rproc_get_by_child(&rpdev->dev);
+
+	if (!rproc)
+		return NULL;
+
+	np = of_node_get(rproc->dev.of_node);
+	if (!np && rproc->dev.parent)
+		np = of_node_get(rproc->dev.parent->of_node);
+
+	if (np) {
+		name = devm_kstrdup(&rpdev->dev, np->name, GFP_KERNEL);
+		of_node_put(np);
+	}
+
+	return name;
+}
+
+static struct device_node *
+rpmsg_get_channel_ofnode(struct rpmsg_device *rpdev, char *chan_name)
+{
+	struct device_node *np_chan = NULL, *np;
+	struct rproc *rproc;
+
+	rproc = rproc_get_by_child(&rpdev->dev);
+	if (!rproc)
+		return NULL;
+
+	np = of_node_get(rproc->dev.of_node);
+	if (!np && rproc->dev.parent)
+		np = of_node_get(rproc->dev.parent->of_node);
+
+	if (np) {
+		/* Balance the of_node_put() performed by of_find_node_by_name(). */
+		of_node_get(np);
+		np_chan = of_find_node_by_name(np, chan_name);
+		of_node_put(np);
+	}
+
+	return np_chan;
+}
+
+static int
+rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void *data,
+			    int len, void *priv, u32 src)
+{
+	struct gpio_rpmsg_packet *msg = data;
+	struct rpmsg_gpio_port *port = NULL;
+	struct rpdev_drvdata *drvdata;
+
+	drvdata = dev_get_drvdata(&rpdev->dev);
+	if (drvdata && msg && msg->port_idx < MAX_PORT_PER_CHANNEL)
+		port = drvdata->channel_devices[msg->port_idx];
+
+	if (!port)
+		return -ENODEV;
+
+	if (msg->header.type == GPIO_RPMSG_REPLY) {
+		*port->info.reply_msg = *msg;
+		complete(&port->info.cmd_complete);
+	} else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
+		generic_handle_domain_irq_safe(port->gc.irq.domain, msg->pin_idx);
+	} else
+		dev_err(&rpdev->dev, "wrong command type!\n");
+
+	return 0;
+}
+
+static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev)
+{
+	struct device *dev = &rpdev->dev;
+	struct rpdev_drvdata *drvdata;
+	struct device_node *np;
+	int ret;
+
+	if (!dev->of_node) {
+		np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
+		if (np) {
+			dev->of_node = np;
+			set_primary_fwnode(dev, of_fwnode_handle(np));
+		}
+		return -EPROBE_DEFER;
+	}
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	drvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);
+	dev_set_drvdata(dev, drvdata);
+
+	for_each_child_of_node_scoped(dev->of_node, child) {
+		if (!of_device_is_available(child))
+			continue;
+
+		if (!of_match_node(dev->driver->of_match_table, child))
+			continue;
+
+		ret = rpmsg_gpiochip_register(rpdev, child);
+		if (ret < 0)
+			dev_err(dev, "Failed to register: %pOF\n", child);
+	}
+
+	return 0;
+}
+
+static void rpmsg_gpio_channel_remove(struct rpmsg_device *rpdev)
+{
+	dev_info(&rpdev->dev, "rpmsg gpio channel driver is removed\n");
+}
+
+static const struct of_device_id rpmsg_gpio_dt_ids[] = {
+	{ .compatible = "rpmsg-gpio" },
+	{ /* sentinel */ }
+};
+
+static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {
+	{ .name	= "rpmsg-io-channel" },
+	{ },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);
+
+static struct rpmsg_driver rpmsg_gpio_channel_client = {
+	.drv.name	= KBUILD_MODNAME,
+	.drv.of_match_table = rpmsg_gpio_dt_ids,
+	.id_table	= rpmsg_gpio_channel_id_table,
+	.probe		= rpmsg_gpio_channel_probe,
+	.callback	= rpmsg_gpio_channel_callback,
+	.remove		= rpmsg_gpio_channel_remove,
+};
+module_rpmsg_driver(rpmsg_gpio_channel_client);
+
+MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>");
+MODULE_DESCRIPTION("generic rpmsg gpio driver");
+MODULE_LICENSE("GPL");
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v8 4/4] arm64: dts: imx8ulp: Add rpmsg node under imx_rproc
  2026-02-12 21:36 [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform Shenwei Wang
                   ` (2 preceding siblings ...)
  2026-02-12 21:36 ` [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver Shenwei Wang
@ 2026-02-12 21:36 ` Shenwei Wang
  2026-02-20  9:18 ` [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform Daniel Baluta
  4 siblings, 0 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-12 21:36 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio, linux-doc, linux-kernel,
	Pengutronix Kernel Team, Fabio Estevam, Shenwei Wang, Peng Fan,
	devicetree, linux-remoteproc, imx, linux-arm-kernel, linux-imx,
	arnaud.pouliquen

Add the RPMSG bus node along with its GPIO subnodes to the device
tree.

Enable remote device communication and GPIO control via RPMSG on
the i.MX platform.

Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index 9b5d98766512..ad1ef00a1e3d 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -191,6 +191,31 @@ scmi_sensor: protocol@15 {
 	cm33: remoteproc-cm33 {
 		compatible = "fsl,imx8ulp-cm33";
 		status = "disabled";
+
+		rpmsg {
+			rpmsg-io-channel {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				rpmsg_gpioa: gpio@0 {
+					compatible = "rpmsg-gpio";
+					reg = <0>;
+					gpio-controller;
+					#gpio-cells = <2>;
+					#interrupt-cells = <2>;
+					interrupt-controller;
+				};
+
+				rpmsg_gpiob: gpio@1 {
+					compatible = "rpmsg-gpio";
+					reg = <1>;
+					gpio-controller;
+					#gpio-cells = <2>;
+					#interrupt-cells = <2>;
+					interrupt-controller;
+				};
+			};
+		};
 	};
 
 	soc: soc@0 {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-12 21:36 ` [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver Shenwei Wang
@ 2026-02-18 10:20   ` Bartosz Golaszewski
  2026-02-18 16:28     ` Shenwei Wang
  2026-02-19  9:20   ` Arnaud POULIQUEN
  1 sibling, 1 reply; 69+ messages in thread
From: Bartosz Golaszewski @ 2026-02-18 10:20 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Shuah Khan, linux-gpio, linux-doc, linux-kernel,
	Pengutronix Kernel Team, Fabio Estevam, Peng Fan, devicetree,
	linux-remoteproc, imx, linux-arm-kernel, linux-imx,
	arnaud.pouliquen, Bartosz Golaszewski, Andrew Lunn, Linus Walleij,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer

On Thu, 12 Feb 2026 22:36:55 +0100, Shenwei Wang <shenwei.wang@nxp.com> said:
> On an AMP platform, the system may include two processors:
> 	- An MCU running an RTOS
> 	- An MPU running Linux
>
> These processors communicate via the RPMSG protocol.
> The driver implements the standard GPIO interface, allowing
> the Linux side to control GPIO controllers which reside in
> the remote processor via RPMSG protocol.
>
> Cc: Bartosz Golaszewski <brgl@bgdev.pl>
> Cc: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
> ---
>  drivers/gpio/Kconfig      |  17 ++
>  drivers/gpio/Makefile     |   1 +
>  drivers/gpio/gpio-rpmsg.c | 588 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 606 insertions(+)
>  create mode 100644 drivers/gpio/gpio-rpmsg.c
>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index b45fb799e36c..3179a54f0634 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -1892,6 +1892,23 @@ config GPIO_SODAVILLE
>
>  endmenu
>
> +menu "RPMSG GPIO drivers"
> +	depends on RPMSG
> +
> +config GPIO_RPMSG
> +	tristate "Generic RPMSG GPIO support"
> +	depends on REMOTEPROC
> +	select GPIOLIB_IRQCHIP
> +	default REMOTEPROC

You're using a lot of OF-centric APIs here, don't you need to depend on OF?
Alternatively, it seems that only rpmsg_get_channel_ofnode() really requires
OF-nodes and everything else could just use firmware node API.

> +	help
> +	  Say yes here to support the generic GPIO functions over the RPMSG
> +	  bus. Currently supported devices: i.MX7ULP, i.MX8ULP, i.MX8x, and
> +	  i.MX9x.
> +
> +	  If unsure, say N.
> +
> +endmenu
> +
>  menu "SPI GPIO expanders"
>  	depends on SPI_MASTER
>
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index c05f7d795c43..501aba56ad68 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -158,6 +158,7 @@ obj-$(CONFIG_GPIO_RDC321X)		+= gpio-rdc321x.o
>  obj-$(CONFIG_GPIO_REALTEK_OTTO)		+= gpio-realtek-otto.o
>  obj-$(CONFIG_GPIO_REG)			+= gpio-reg.o
>  obj-$(CONFIG_GPIO_ROCKCHIP)	+= gpio-rockchip.o
> +obj-$(CONFIG_GPIO_RPMSG)		+= gpio-rpmsg.o
>  obj-$(CONFIG_GPIO_RTD)			+= gpio-rtd.o
>  obj-$(CONFIG_ARCH_SA1100)		+= gpio-sa1100.o
>  obj-$(CONFIG_GPIO_SAMA5D2_PIOBU)	+= gpio-sama5d2-piobu.o
> diff --git a/drivers/gpio/gpio-rpmsg.c b/drivers/gpio/gpio-rpmsg.c
> new file mode 100644
> index 000000000000..163f51fd45b5
> --- /dev/null
> +++ b/drivers/gpio/gpio-rpmsg.c
> @@ -0,0 +1,588 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright 2026 NXP
> + *
> + * The driver exports a standard gpiochip interface to control
> + * the GPIO controllers via RPMSG on a remote processor.
> + */

Add newline here.

[snip]

> +
> +static struct device_node *
> +rpmsg_get_channel_ofnode(struct rpmsg_device *rpdev, char *chan_name)
> +{
> +	struct device_node *np_chan = NULL, *np;
> +	struct rproc *rproc;
> +
> +	rproc = rproc_get_by_child(&rpdev->dev);
> +	if (!rproc)
> +		return NULL;
> +
> +	np = of_node_get(rproc->dev.of_node);
> +	if (!np && rproc->dev.parent)
> +		np = of_node_get(rproc->dev.parent->of_node);
> +
> +	if (np) {
> +		/* Balance the of_node_put() performed by of_find_node_by_name(). */
> +		of_node_get(np);
> +		np_chan = of_find_node_by_name(np, chan_name);
> +		of_node_put(np);

If you put np here, why even bother with "balancing". If you don't do
of_node_get() before calling of_find_node_by_name(), you'll be in the
same place, no?

> +	}
> +
> +	return np_chan;
> +}
> +
> +static int
> +rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void *data,
> +			    int len, void *priv, u32 src)
> +{
> +	struct gpio_rpmsg_packet *msg = data;
> +	struct rpmsg_gpio_port *port = NULL;
> +	struct rpdev_drvdata *drvdata;
> +
> +	drvdata = dev_get_drvdata(&rpdev->dev);
> +	if (drvdata && msg && msg->port_idx < MAX_PORT_PER_CHANNEL)
> +		port = drvdata->channel_devices[msg->port_idx];
> +
> +	if (!port)
> +		return -ENODEV;
> +
> +	if (msg->header.type == GPIO_RPMSG_REPLY) {
> +		*port->info.reply_msg = *msg;
> +		complete(&port->info.cmd_complete);
> +	} else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
> +		generic_handle_domain_irq_safe(port->gc.irq.domain, msg->pin_idx);
> +	} else
> +		dev_err(&rpdev->dev, "wrong command type!\n");
> +
> +	return 0;
> +}
> +
> +static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev)
> +{
> +	struct device *dev = &rpdev->dev;
> +	struct rpdev_drvdata *drvdata;
> +	struct device_node *np;
> +	int ret;
> +
> +	if (!dev->of_node) {
> +		np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
> +		if (np) {
> +			dev->of_node = np;
> +			set_primary_fwnode(dev, of_fwnode_handle(np));
> +		}
> +		return -EPROBE_DEFER;
> +	}
> +
> +	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> +	if (!drvdata)
> +		return -ENOMEM;
> +
> +	drvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);
> +	dev_set_drvdata(dev, drvdata);
> +
> +	for_each_child_of_node_scoped(dev->of_node, child) {

Like mentioned above: this could be:

device_for_each_child_node() {
	fwnode_device_is_available();
	...
}

> +		if (!of_device_is_available(child))
> +			continue;
> +
> +		if (!of_match_node(dev->driver->of_match_table, child))
> +			continue;
> +
> +		ret = rpmsg_gpiochip_register(rpdev, child);
> +		if (ret < 0)
> +			dev_err(dev, "Failed to register: %pOF\n", child);
> +	}
> +
> +	return 0;
> +}
> +
> +static void rpmsg_gpio_channel_remove(struct rpmsg_device *rpdev)
> +{
> +	dev_info(&rpdev->dev, "rpmsg gpio channel driver is removed\n");
> +}

Please drop this, no need to log it,

> +
> +static const struct of_device_id rpmsg_gpio_dt_ids[] = {
> +	{ .compatible = "rpmsg-gpio" },
> +	{ /* sentinel */ }
> +};
> +
> +static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {
> +	{ .name	= "rpmsg-io-channel" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);
> +
> +static struct rpmsg_driver rpmsg_gpio_channel_client = {
> +	.drv.name	= KBUILD_MODNAME,
> +	.drv.of_match_table = rpmsg_gpio_dt_ids,

Can you please do:

	.drv = {
		.name = "open-coded-name",
		.of_match_table = ...
	};

?

Bartosz

> +	.id_table	= rpmsg_gpio_channel_id_table,
> +	.probe		= rpmsg_gpio_channel_probe,
> +	.callback	= rpmsg_gpio_channel_callback,
> +	.remove		= rpmsg_gpio_channel_remove,
> +};
> +module_rpmsg_driver(rpmsg_gpio_channel_client);
> +
> +MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>");
> +MODULE_DESCRIPTION("generic rpmsg gpio driver");
> +MODULE_LICENSE("GPL");
> --
> 2.43.0
>
>


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-18 10:20   ` Bartosz Golaszewski
@ 2026-02-18 16:28     ` Shenwei Wang
  0 siblings, 0 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-18 16:28 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	arnaud.pouliquen@foss.st.com, Bartosz Golaszewski, Andrew Lunn,
	Linus Walleij, Jonathan Corbet, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Bjorn Andersson, Mathieu Poirier, Frank Li,
	Sascha Hauer



> -----Original Message-----
> From: Bartosz Golaszewski <brgl@kernel.org>
> Sent: Wednesday, February 18, 2026 4:20 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: 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>;
> arnaud.pouliquen@foss.st.com; Bartosz Golaszewski <brgl@bgdev.pl>; 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>; Mathieu
> Poirier <mathieu.poirier@linaro.org>; Frank Li <frank.li@nxp.com>; Sascha Hauer
> <s.hauer@pengutronix.de>
> Subject: [EXT] Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > Cc: Bartosz Golaszewski <brgl@bgdev.pl>
> > Cc: Andrew Lunn <andrew@lunn.ch>
> > Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
> > ---
> >  drivers/gpio/Kconfig      |  17 ++
> >  drivers/gpio/Makefile     |   1 +
> >  drivers/gpio/gpio-rpmsg.c | 588
> > ++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 606 insertions(+)
> >  create mode 100644 drivers/gpio/gpio-rpmsg.c
> >
> > +     rproc = rproc_get_by_child(&rpdev->dev);
> > +     if (!rproc)
> > +             return NULL;
> > +
> > +     np = of_node_get(rproc->dev.of_node);
> > +     if (!np && rproc->dev.parent)
> > +             np = of_node_get(rproc->dev.parent->of_node);
> > +
> > +     if (np) {
> > +             /* Balance the of_node_put() performed by of_find_node_by_name().
> */
> > +             of_node_get(np);
> > +             np_chan = of_find_node_by_name(np, chan_name);
> > +             of_node_put(np);
> 
> If you put np here, why even bother with "balancing". If you don't do
> of_node_get() before calling of_find_node_by_name(), you'll be in the same
> place, no?
> 

Yeah, the end result is the same. In this case, the comment just needs to say that 
of_find_node_by_name() does an internal of_node_put(), so we don’t need to 
call of_node_put() again.

> > +     }
> > +
> > +     return np_chan;
> > +}
> > +
> > +static int
> > +rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void *data,
> > +                         int len, void *priv, u32 src) {
> > +     struct gpio_rpmsg_packet *msg = data;
> > +     struct rpmsg_gpio_port *port = NULL;
> > +     struct rpdev_drvdata *drvdata;
> > +
> > +     drvdata = dev_get_drvdata(&rpdev->dev);
> > +     if (drvdata && msg && msg->port_idx < MAX_PORT_PER_CHANNEL)
> > +             port = drvdata->channel_devices[msg->port_idx];
> > +
> > +     if (!port)
> > +             return -ENODEV;
> > +
> > +     if (msg->header.type == GPIO_RPMSG_REPLY) {
> > +             *port->info.reply_msg = *msg;
> > +             complete(&port->info.cmd_complete);
> > +     } else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
> > +             generic_handle_domain_irq_safe(port->gc.irq.domain, msg->pin_idx);
> > +     } else
> > +             dev_err(&rpdev->dev, "wrong command type!\n");
> > +
> > +     return 0;
> > +}
> > +
> > +static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev) {
> > +     struct device *dev = &rpdev->dev;
> > +     struct rpdev_drvdata *drvdata;
> > +     struct device_node *np;
> > +     int ret;
> > +
> > +     if (!dev->of_node) {
> > +             np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
> > +             if (np) {
> > +                     dev->of_node = np;
> > +                     set_primary_fwnode(dev, of_fwnode_handle(np));
> > +             }
> > +             return -EPROBE_DEFER;
> > +     }
> > +
> > +     drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > +     if (!drvdata)
> > +             return -ENOMEM;
> > +
> > +     drvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);
> > +     dev_set_drvdata(dev, drvdata);
> > +
> > +     for_each_child_of_node_scoped(dev->of_node, child) {
> 
> Like mentioned above: this could be:
> 
> device_for_each_child_node() {
>         fwnode_device_is_available();
>         ...
> }
> 

Since the suggested change still wouldn’t remove the OF‑specific calls used later, I’d rather 
keep the current approach and just add the OF dependents in Kconfig.

Thanks,
Shenwei

> > +             if (!of_device_is_available(child))
> > +                     continue;
> > +
> > +             if (!of_match_node(dev->driver->of_match_table, child))
> > +                     continue;
> > +
> > +             ret = rpmsg_gpiochip_register(rpdev, child);
> > +             if (ret < 0)
> > +                     dev_err(dev, "Failed to register: %pOF\n", child);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static void rpmsg_gpio_channel_remove(struct rpmsg_device *rpdev) {
> > +     dev_info(&rpdev->dev, "rpmsg gpio channel driver is removed\n");
> > +}
> 
> Please drop this, no need to log it,
> 
> > +
> > +static const struct of_device_id rpmsg_gpio_dt_ids[] = {
> > +     { .compatible = "rpmsg-gpio" },
> > +     { /* sentinel */ }
> > +};
> > +
> > +static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {
> > +     { .name = "rpmsg-io-channel" },
> > +     { },
> > +};
> > +MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);
> > +
> > +static struct rpmsg_driver rpmsg_gpio_channel_client = {
> > +     .drv.name       = KBUILD_MODNAME,
> > +     .drv.of_match_table = rpmsg_gpio_dt_ids,
> 
> Can you please do:
> 
>         .drv = {
>                 .name = "open-coded-name",
>                 .of_match_table = ...
>         };
> 
> ?
> 
> Bartosz
> 
> > +     .id_table       = rpmsg_gpio_channel_id_table,
> > +     .probe          = rpmsg_gpio_channel_probe,
> > +     .callback       = rpmsg_gpio_channel_callback,
> > +     .remove         = rpmsg_gpio_channel_remove,
> > +};
> > +module_rpmsg_driver(rpmsg_gpio_channel_client);
> > +
> > +MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>");
> > +MODULE_DESCRIPTION("generic rpmsg gpio driver");
> > +MODULE_LICENSE("GPL");
> > --
> > 2.43.0
> >
> >

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-12 21:36 ` [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver Shenwei Wang
  2026-02-18 10:20   ` Bartosz Golaszewski
@ 2026-02-19  9:20   ` Arnaud POULIQUEN
  2026-02-19 13:26     ` Andrew Lunn
                       ` (3 more replies)
  1 sibling, 4 replies; 69+ messages in thread
From: Arnaud POULIQUEN @ 2026-02-19  9:20 UTC (permalink / raw)
  To: Shenwei Wang, Linus Walleij, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio, linux-doc, linux-kernel,
	Pengutronix Kernel Team, Fabio Estevam, Peng Fan, devicetree,
	linux-remoteproc, imx, linux-arm-kernel, linux-imx,
	Bartosz Golaszewski, Andrew Lunn

Hello Shenwei,

This versiob seems much more generic, thanks!

On 2/12/26 22:36, Shenwei Wang wrote:
> On an AMP platform, the system may include two processors:
> 	- An MCU running an RTOS
> 	- An MPU running Linux
> 
> These processors communicate via the RPMSG protocol.
> The driver implements the standard GPIO interface, allowing
> the Linux side to control GPIO controllers which reside in
> the remote processor via RPMSG protocol.
> 
> Cc: Bartosz Golaszewski <brgl@bgdev.pl>
> Cc: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
> ---
>   drivers/gpio/Kconfig      |  17 ++
>   drivers/gpio/Makefile     |   1 +
>   drivers/gpio/gpio-rpmsg.c | 588 ++++++++++++++++++++++++++++++++++++++
>   3 files changed, 606 insertions(+)
>   create mode 100644 drivers/gpio/gpio-rpmsg.c
> 
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index b45fb799e36c..3179a54f0634 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -1892,6 +1892,23 @@ config GPIO_SODAVILLE
>   
>   endmenu
>   
> +menu "RPMSG GPIO drivers"
> +	depends on RPMSG
> +
> +config GPIO_RPMSG
> +	tristate "Generic RPMSG GPIO support"
> +	depends on REMOTEPROC
> +	select GPIOLIB_IRQCHIP
> +	default REMOTEPROC
> +	help
> +	  Say yes here to support the generic GPIO functions over the RPMSG
> +	  bus. Currently supported devices: i.MX7ULP, i.MX8ULP, i.MX8x, and
> +	  i.MX9x.
> +
> +	  If unsure, say N.
> +
> +endmenu
> +
>   menu "SPI GPIO expanders"
>   	depends on SPI_MASTER
>   
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index c05f7d795c43..501aba56ad68 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -158,6 +158,7 @@ obj-$(CONFIG_GPIO_RDC321X)		+= gpio-rdc321x.o
>   obj-$(CONFIG_GPIO_REALTEK_OTTO)		+= gpio-realtek-otto.o
>   obj-$(CONFIG_GPIO_REG)			+= gpio-reg.o
>   obj-$(CONFIG_GPIO_ROCKCHIP)	+= gpio-rockchip.o
> +obj-$(CONFIG_GPIO_RPMSG)		+= gpio-rpmsg.o
>   obj-$(CONFIG_GPIO_RTD)			+= gpio-rtd.o
>   obj-$(CONFIG_ARCH_SA1100)		+= gpio-sa1100.o
>   obj-$(CONFIG_GPIO_SAMA5D2_PIOBU)	+= gpio-sama5d2-piobu.o
> diff --git a/drivers/gpio/gpio-rpmsg.c b/drivers/gpio/gpio-rpmsg.c
> new file mode 100644
> index 000000000000..163f51fd45b5
> --- /dev/null
> +++ b/drivers/gpio/gpio-rpmsg.c
> @@ -0,0 +1,588 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright 2026 NXP
> + *
> + * The driver exports a standard gpiochip interface to control
> + * the GPIO controllers via RPMSG on a remote processor.
> + */
> +#include <linux/completion.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/init.h>
> +#include <linux/irqdomain.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/remoteproc.h>
> +#include <linux/rpmsg.h>
> +
> +#define RPMSG_GPIO_ID		5
> +#define RPMSG_VENDOR		1
> +#define RPMSG_VERSION		0
> +
> +#define GPIOS_PER_PORT_DEFAULT	32
> +#define RPMSG_TIMEOUT		1000
> +
> +/* GPIO RPMSG header type */
> +#define GPIO_RPMSG_SETUP	0
> +#define GPIO_RPMSG_REPLY	1
> +#define GPIO_RPMSG_NOTIFY	2
> +
> +/* GPIO Interrupt trigger type */
> +#define GPIO_RPMSG_TRI_IGNORE		0
> +#define GPIO_RPMSG_TRI_RISING		1
> +#define GPIO_RPMSG_TRI_FALLING		2
> +#define GPIO_RPMSG_TRI_BOTH_EDGE	3
> +#define GPIO_RPMSG_TRI_LOW_LEVEL	4
> +#define GPIO_RPMSG_TRI_HIGH_LEVEL	5
> +
> +/* GPIO RPMSG commands */
> +#define GPIO_RPMSG_INPUT_INIT		0
> +#define GPIO_RPMSG_OUTPUT_INIT		1
> +#define GPIO_RPMSG_INPUT_GET		2
> +#define GPIO_RPMSG_DIRECTION_GET	3
> +
> +#define MAX_PORT_PER_CHANNEL    10
> +
> +/*
> + * @rproc_name: the name of the remote proc.
> + * @channel_devices: an array of the devices related to the rpdev.
> + */
> +struct rpdev_drvdata {
> +	const char *rproc_name;
> +	void *channel_devices[MAX_PORT_PER_CHANNEL];
> +};
> +
> +struct gpio_rpmsg_head {

Sometime the prefix is gpio_rpmsg, sometime rpmsg_gpio or just gpio,
could you use "rpmsg_gpio" prefix in the whole driver?

> +	u8 id;		/* Message ID Code */
> +	u8 vendor;	/* Vendor ID number */

Does this fields above are mandatory, seems that it is just some 
constant values that are useless.

> +	u8 version;	/* Vendor-specific version number */

Why it is vendor specific? the version should represent the rpmsg-tty 
protocol version.

> +	u8 type;	/* Message type */
> +	u8 cmd;		/* Command code */
> +	u8 reserved[5];

What is the purpose of this reserved field?

> +} __packed;
> +
> +struct gpio_rpmsg_packet {
> +	struct gpio_rpmsg_head header;
> +	u8 pin_idx;
> +	u8 port_idx;
> +	union {
> +		u8 event;
> +		u8 retcode;
> +		u8 value;
> +	} out;
> +	union {
> +		u8 wakeup;
> +		u8 value;
> +	} in;
> +} __packed __aligned(8);

Any reason to use __packed and alignement here?
This structure will be copied in a vring buffer right?

> +
> +struct gpio_rpmsg_pin {
> +	u8 irq_shutdown;
> +	u8 irq_unmask;
> +	u8 irq_mask;
> +	u32 irq_wake_enable;
> +	u32 irq_type;
> +	struct gpio_rpmsg_packet msg;
> +};
> +
> +struct gpio_rpmsg_info {
> +	struct rpmsg_device *rpdev;
> +	struct gpio_rpmsg_packet *reply_msg;
> +	struct completion cmd_complete;
> +	struct mutex lock;
> +	void **port_store;
> +};
> +
> +struct rpmsg_gpio_port {
> +	struct gpio_chip gc;
> +	struct gpio_rpmsg_pin gpio_pins[GPIOS_PER_PORT_DEFAULT];
> +	struct gpio_rpmsg_info info;
> +	u32 ngpios;
> +	u32 idx;
> +};
> +
> +static int gpio_send_message(struct rpmsg_gpio_port *port,

s/gpio_send_message/rpmsg_gpio_send_message

> +			     struct gpio_rpmsg_packet *msg,
> +			     bool sync)
> +{
> +	struct gpio_rpmsg_info *info = &port->info;
> +	int err;
> +
> +	reinit_completion(&info->cmd_complete);
> +	err = rpmsg_send(info->rpdev->ept, msg, sizeof(struct gpio_rpmsg_packet));
> +	if (err) {
> +		dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
> +		return err;
> +	}
> +
> +	if (sync) {
> +		err = wait_for_completion_timeout(&info->cmd_complete,
> +						  msecs_to_jiffies(RPMSG_TIMEOUT));
> +		if (err == 0) {
> +			dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> +			return -ETIMEDOUT;

strange condition you return an error if err == 0, for redability use 
'ret' variable or simply:

		if(!wait_for_completion_timeout(&info->cmd_complete,
				  msecs_to_jiffies(RPMSG_TIMEOUT)) {
			dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
			return -ETIMEDOUT;
		}

> +
> +		if (info->reply_msg->out.retcode != 0) {
> +			dev_err(&info->rpdev->dev, "remote core replies an error: %d!\n",
> +				info->reply_msg->out.retcode);
> +			return -EINVAL;
> +		}
> +
> +		/* copy the reply message */
> +		memcpy(&port->gpio_pins[info->reply_msg->pin_idx].msg,
> +		       info->reply_msg, sizeof(*info->reply_msg));
> +	}
> +
> +	return 0;
> +}
> +
> +static struct gpio_rpmsg_packet *gpio_setup_msg_common(struct rpmsg_gpio_port *port,
> +						       unsigned int offset,
> +						       u8 cmd)
> +{
> +	struct gpio_rpmsg_packet *msg = &port->gpio_pins[offset].msg;
> +
> +	memset(msg, 0, sizeof(struct gpio_rpmsg_packet));
> +	msg->header.id = RPMSG_GPIO_ID;
> +	msg->header.vendor = RPMSG_VENDOR;
> +	msg->header.version = RPMSG_VERSION;
> +	msg->header.type = GPIO_RPMSG_SETUP;
> +	msg->header.cmd = cmd;
> +	msg->pin_idx = offset;
> +	msg->port_idx = port->idx;
> +
> +	return msg;
> +}
> +
> +static int rpmsg_gpio_get(struct gpio_chip *gc, unsigned int gpio)
> +{
> +	struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> +	struct gpio_rpmsg_packet *msg;
> +	int ret;
> +
> +	guard(mutex)(&port->info.lock);
> +
> +	msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_INPUT_GET);
> +
> +	ret = gpio_send_message(port, msg, true);
> +	if (!ret)
> +		ret = !!port->gpio_pins[gpio].msg.in.value;
> +
> +	return ret;
> +}
> +
> +static int rpmsg_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio)
> +{
> +	struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> +	struct gpio_rpmsg_packet *msg;
> +	int ret;
> +
> +	guard(mutex)(&port->info.lock);
> +
> +	msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_DIRECTION_GET);
> +
> +	ret = gpio_send_message(port, msg, true);
> +	if (!ret)
> +		ret = !!port->gpio_pins[gpio].msg.in.value;
> +
> +	return ret;
> +}
> +
> +static int rpmsg_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio)
> +{
> +	struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> +	struct gpio_rpmsg_packet *msg;
> +
> +	guard(mutex)(&port->info.lock);
> +
> +	msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_INPUT_INIT);
> +
> +	return gpio_send_message(port, msg, true);
> +}
> +
> +static int rpmsg_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
> +{
> +	struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> +	struct gpio_rpmsg_packet *msg;
> +
> +	guard(mutex)(&port->info.lock);
> +
> +	msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_OUTPUT_INIT);
> +	msg->out.value = val;
> +
> +	return gpio_send_message(port, msg, true);
> +}
> +
> +static int rpmsg_gpio_direction_output(struct gpio_chip *gc,
> +				       unsigned int gpio,
> +				       int val)
> +{
> +	return rpmsg_gpio_set(gc, gpio, val);
> +}
> +
> +static int gpio_rpmsg_irq_set_type(struct irq_data *d, u32 type)
> +{
> +	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> +	u32 gpio_idx = d->hwirq;
> +	int edge = 0;
> +	int ret = 0;
> +
> +	switch (type) {
> +	case IRQ_TYPE_EDGE_RISING:
> +		edge = GPIO_RPMSG_TRI_RISING;
> +		irq_set_handler_locked(d, handle_simple_irq);
> +		break;
> +	case IRQ_TYPE_EDGE_FALLING:
> +		edge = GPIO_RPMSG_TRI_FALLING;
> +		irq_set_handler_locked(d, handle_simple_irq);
> +		break;
> +	case IRQ_TYPE_EDGE_BOTH:
> +		edge = GPIO_RPMSG_TRI_BOTH_EDGE;
> +		irq_set_handler_locked(d, handle_simple_irq);
> +		break;
> +	case IRQ_TYPE_LEVEL_LOW:
> +		edge = GPIO_RPMSG_TRI_LOW_LEVEL;
> +		irq_set_handler_locked(d, handle_level_irq);
> +		break;
> +	case IRQ_TYPE_LEVEL_HIGH:
> +		edge = GPIO_RPMSG_TRI_HIGH_LEVEL;
> +		irq_set_handler_locked(d, handle_level_irq);
> +		break;
> +	default:
> +		ret = -EINVAL;
> +		irq_set_handler_locked(d, handle_bad_irq);
> +		break;
> +	}
> +
> +	port->gpio_pins[gpio_idx].irq_type = edge;
> +
> +	return ret;
> +}
> +
> +static int gpio_rpmsg_irq_set_wake(struct irq_data *d, u32 enable)
> +{
> +	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> +	u32 gpio_idx = d->hwirq;
> +
> +	port->gpio_pins[gpio_idx].irq_wake_enable = enable;
> +
> +	return 0;
> +}
> +
> +/*
> + * This unmask/mask function is invoked in two situations:
> + *   - when an interrupt is being set up, and
> + *   - after an interrupt has occurred.
> + *
> + * The GPIO driver does not access hardware registers directly.
> + * Instead, it caches all relevant information locally, and then sends
> + * the accumulated state to the remote system at this stage.
> + */
> +static void gpio_rpmsg_unmask_irq(struct irq_data *d)
> +{
> +	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> +	u32 gpio_idx = d->hwirq;
> +
> +	port->gpio_pins[gpio_idx].irq_unmask = 1;
> +}
> +
> +static void gpio_rpmsg_mask_irq(struct irq_data *d)
> +{
> +	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> +	u32 gpio_idx = d->hwirq;
> +
> +	/*
> +	 * When an interrupt occurs, the remote system masks the interrupt
> +	 * and then sends a notification to Linux. After Linux processes
> +	 * that notification, it sends an RPMsg command back to the remote
> +	 * system to unmask the interrupt again.
> +	 */
> +	port->gpio_pins[gpio_idx].irq_mask = 1;
> +}
> +
> +static void gpio_rpmsg_irq_shutdown(struct irq_data *d)
> +{
> +	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> +	u32 gpio_idx = d->hwirq;
> +
> +	port->gpio_pins[gpio_idx].irq_shutdown = 1;
> +}
> +
> +static void gpio_rpmsg_irq_bus_lock(struct irq_data *d)
> +{
> +	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> +
> +	mutex_lock(&port->info.lock);
> +}
> +
> +static void gpio_rpmsg_irq_bus_sync_unlock(struct irq_data *d)
> +{
> +	struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> +	struct gpio_rpmsg_packet *msg = NULL;
> +	u32 gpio_idx = d->hwirq;
> +
> +	/*
> +	 * For mask irq, do nothing here.
> +	 * The remote system will mask interrupt after an interrupt occurs,
> +	 * and then send a notify to Linux system.
> +	 * After Linux system dealt with the notify, it will send an rpmsg to
> +	 * the remote system to unmask this interrupt again.
> +	 */
> +	if (port->gpio_pins[gpio_idx].irq_mask && !port->gpio_pins[gpio_idx].irq_unmask) {
> +		port->gpio_pins[gpio_idx].irq_mask = 0;
> +		mutex_unlock(&port->info.lock);
> +		return;
> +	}
> +
> +	msg = gpio_setup_msg_common(port, gpio_idx, GPIO_RPMSG_INPUT_INIT);
> +
> +	if (port->gpio_pins[gpio_idx].irq_shutdown) {
> +		msg->out.event = GPIO_RPMSG_TRI_IGNORE;
> +		msg->in.wakeup = 0;
> +		port->gpio_pins[gpio_idx].irq_shutdown = 0;
> +	} else {
> +		/* if not set irq type, then use low level as trigger type */
> +		msg->out.event = port->gpio_pins[gpio_idx].irq_type;
> +		if (!msg->out.event)
> +			msg->out.event = GPIO_RPMSG_TRI_LOW_LEVEL;
> +		if (port->gpio_pins[gpio_idx].irq_unmask) {
> +			msg->in.wakeup = 0;
> +			port->gpio_pins[gpio_idx].irq_unmask = 0;
> +		} else /* irq set wake */
> +			msg->in.wakeup = port->gpio_pins[gpio_idx].irq_wake_enable;
> +	}
> +
> +	gpio_send_message(port, msg, false);
> +	mutex_unlock(&port->info.lock);
> +}
> +
> +static const struct irq_chip gpio_rpmsg_irq_chip = {
> +	.irq_mask = gpio_rpmsg_mask_irq,
> +	.irq_unmask = gpio_rpmsg_unmask_irq,
> +	.irq_set_wake = gpio_rpmsg_irq_set_wake,
> +	.irq_set_type = gpio_rpmsg_irq_set_type,
> +	.irq_shutdown = gpio_rpmsg_irq_shutdown,
> +	.irq_bus_lock = gpio_rpmsg_irq_bus_lock,
> +	.irq_bus_sync_unlock = gpio_rpmsg_irq_bus_sync_unlock,
> +	.flags = IRQCHIP_IMMUTABLE,
> +};
> +
> +static void rpmsg_gpio_remove_action(void *data)
> +{
> +	struct rpmsg_gpio_port *port = data;
> +
> +	port->info.port_store[port->idx] = NULL;
> +}
> +
> +static int rpmsg_gpiochip_register(struct rpmsg_device *rpdev, struct device_node *np)
> +{
> +	struct rpdev_drvdata *drvdata = dev_get_drvdata(&rpdev->dev);
> +	struct rpmsg_gpio_port *port;
> +	struct gpio_irq_chip *girq;
> +	struct gpio_chip *gc;
> +	int ret;
> +
> +	port = devm_kzalloc(&rpdev->dev, sizeof(*port), GFP_KERNEL);
> +	if (!port)
> +		return -ENOMEM;
> +
> +	ret = of_property_read_u32(np, "reg", &port->idx);
> +	if (ret)
> +		return ret;
> +
> +	if (port->idx >= MAX_PORT_PER_CHANNEL)
> +		return -EINVAL;
> +
> +	ret = devm_mutex_init(&rpdev->dev, &port->info.lock);
> +	if (ret)
> +		return ret;
> +
> +	ret = of_property_read_u32(np, "ngpios", &port->ngpios);
> +	if (ret)
> +		port->ngpios = GPIOS_PER_PORT_DEFAULT;
> +
> +	init_completion(&port->info.cmd_complete);
> +	port->info.reply_msg = devm_kzalloc(&rpdev->dev,
> +					    sizeof(struct gpio_rpmsg_packet),
> +					    GFP_KERNEL);
> +	port->info.port_store = drvdata->channel_devices;
> +	port->info.port_store[port->idx] = port;
> +	port->info.rpdev = rpdev;
> +
> +	gc = &port->gc;
> +	gc->owner = THIS_MODULE;
> +	gc->parent = &rpdev->dev;
> +	gc->fwnode = of_fwnode_handle(np);
> +	gc->ngpio = port->ngpios;
> +	gc->base = -1;
> +	gc->label = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-gpio%d",
> +				   drvdata->rproc_name, port->idx);
> +
> +	gc->direction_input = rpmsg_gpio_direction_input;
> +	gc->direction_output = rpmsg_gpio_direction_output;
> +	gc->get_direction = rpmsg_gpio_get_direction;
> +	gc->get = rpmsg_gpio_get;
> +	gc->set = rpmsg_gpio_set;
> +
> +	girq = &gc->irq;
> +	gpio_irq_chip_set_chip(girq, &gpio_rpmsg_irq_chip);
> +	girq->parent_handler = NULL;
> +	girq->num_parents = 0;
> +	girq->parents = NULL;
> +	girq->chip->name = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-gpio%d",
> +					  drvdata->rproc_name, port->idx);
> +
> +	ret = devm_add_action_or_reset(&rpdev->dev, rpmsg_gpio_remove_action, port);
> +	if (ret)
> +		return ret;
> +
> +	return devm_gpiochip_add_data(&rpdev->dev, gc, port);
> +}
> +
> +static const char *rpmsg_get_rproc_node_name(struct rpmsg_device *rpdev)
> +{
> +	const char *name = NULL;
> +	struct device_node *np;
> +	struct rproc *rproc;
> +
> +	rproc = rproc_get_by_child(&rpdev->dev);
> +
> +	if (!rproc)
> +		return NULL;
> +
> +	np = of_node_get(rproc->dev.of_node);
> +	if (!np && rproc->dev.parent)
> +		np = of_node_get(rproc->dev.parent->of_node);
> +
> +	if (np) {
> +		name = devm_kstrdup(&rpdev->dev, np->name, GFP_KERNEL);
> +		of_node_put(np);
> +	}

What about simply returning rproc->name?

> +
> +	return name;
> +}
> +
> +static struct device_node *
> +rpmsg_get_channel_ofnode(struct rpmsg_device *rpdev, char *chan_name)
> +{
> +	struct device_node *np_chan = NULL, *np;
> +	struct rproc *rproc;
> +
> +	rproc = rproc_get_by_child(&rpdev->dev);
> +	if (!rproc)
> +		return NULL;
> +
> +	np = of_node_get(rproc->dev.of_node);
> +	if (!np && rproc->dev.parent)
> +		np = of_node_get(rproc->dev.parent->of_node);

Is a topology where they is no rproc->dev node but a parent node exist?

> +
> +	if (np) {
> +		/* Balance the of_node_put() performed by of_find_node_by_name(). */
> +		of_node_get(np);
> +		np_chan = of_find_node_by_name(np, chan_name);
> +		of_node_put(np);
> +	}
> +
> +	return np_chan;
> +}
> +
> +static int
> +rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void *data,
> +			    int len, void *priv, u32 src)
> +{
> +	struct gpio_rpmsg_packet *msg = data;
> +	struct rpmsg_gpio_port *port = NULL;
> +	struct rpdev_drvdata *drvdata;
> +
> +	drvdata = dev_get_drvdata(&rpdev->dev);
> +	if (drvdata && msg && msg->port_idx < MAX_PORT_PER_CHANNEL)
> +		port = drvdata->channel_devices[msg->port_idx];
> +
> +	if (!port)
> +		return -ENODEV;
> +
> +	if (msg->header.type == GPIO_RPMSG_REPLY) {
> +		*port->info.reply_msg = *msg;
> +		complete(&port->info.cmd_complete);

What happen if the remoteprocessor answer after the completion timeout?
Could it result in desynchronization between the request and the answer?

Having a cmd_counter in gpio_rpmsg_head could help to identify current 
request and answer

the use of reinit_completion could be also needed

> +	} else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
> +		generic_handle_domain_irq_safe(port->gc.irq.domain, msg->pin_idx);
> +	} else
> +		dev_err(&rpdev->dev, "wrong command type!\n");

Could you print the msg->header.type value to help for debug?

> +
> +	return 0;
> +}
> +
> +static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev)
> +{
> +	struct device *dev = &rpdev->dev;
> +	struct rpdev_drvdata *drvdata;
> +	struct device_node *np;
> +	int ret;
> +
> +	if (!dev->of_node) {
> +		np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
> +		if (np) {
> +			dev->of_node = np;
> +			set_primary_fwnode(dev, of_fwnode_handle(np));
> +		}
> +		return -EPROBE_DEFER;
> +	}
> +
> +	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> +	if (!drvdata)
> +		return -ENOMEM;
> +
> +	drvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);
> +	dev_set_drvdata(dev, drvdata);
> +
> +	for_each_child_of_node_scoped(dev->of_node, child) {
> +		if (!of_device_is_available(child))
> +			continue;
> +
> +		if (!of_match_node(dev->driver->of_match_table, child))
> +			continue;
> +
> +		ret = rpmsg_gpiochip_register(rpdev, child);
> +		if (ret < 0)
> +			dev_err(dev, "Failed to register: %pOF\n", child);
> +	}
> +
> +	return 0;

return ret
or indicate why the return of rpmsg_gpiochip_register is not taken into 
account


> +}
> +
> +static void rpmsg_gpio_channel_remove(struct rpmsg_device *rpdev)
> +{
> +	dev_info(&rpdev->dev, "rpmsg gpio channel driver is removed\n");
> +}
> +
> +static const struct of_device_id rpmsg_gpio_dt_ids[] = {
> +	{ .compatible = "rpmsg-gpio" },
> +	{ /* sentinel */ }
> +};
> +
> +static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {
> +	{ .name	= "rpmsg-io-channel" },

I would remove the "-channel" suffix to have similar naming than 
"rpmsg-tty" and "rpmsg-raw"

Regards,
Arnaud

> +	{ },
> +};
> +MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);
> +
> +static struct rpmsg_driver rpmsg_gpio_channel_client = {
> +	.drv.name	= KBUILD_MODNAME,
> +	.drv.of_match_table = rpmsg_gpio_dt_ids,
> +	.id_table	= rpmsg_gpio_channel_id_table,
> +	.probe		= rpmsg_gpio_channel_probe,
> +	.callback	= rpmsg_gpio_channel_callback,
> +	.remove		= rpmsg_gpio_channel_remove,
> +};
> +module_rpmsg_driver(rpmsg_gpio_channel_client);
> +
> +MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>");
> +MODULE_DESCRIPTION("generic rpmsg gpio driver");
> +MODULE_LICENSE("GPL");



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19  9:20   ` Arnaud POULIQUEN
@ 2026-02-19 13:26     ` Andrew Lunn
  2026-02-19 14:17       ` Shenwei Wang
  2026-02-19 13:42     ` Andrew Lunn
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-19 13:26 UTC (permalink / raw)
  To: Arnaud POULIQUEN
  Cc: Shenwei Wang, Linus Walleij, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer, Shuah Khan, linux-gpio,
	linux-doc, linux-kernel, Pengutronix Kernel Team, Fabio Estevam,
	Peng Fan, devicetree, linux-remoteproc, imx, linux-arm-kernel,
	linux-imx, Bartosz Golaszewski

> > +	if (sync) {
> > +		err = wait_for_completion_timeout(&info->cmd_complete,
> > +						  msecs_to_jiffies(RPMSG_TIMEOUT));
> > +		if (err == 0) {
> > +			dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> > +			return -ETIMEDOUT;
> 
> strange condition you return an error if err == 0, for redability use 'ret'
> variable or simply:
> 
> 		if(!wait_for_completion_timeout(&info->cmd_complete,
> 				  msecs_to_jiffies(RPMSG_TIMEOUT)) {
> 			dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> 			return -ETIMEDOUT;
> 		}

This will be from a comment i made. It appears that
do_wait_for_common() can return -ERESTARTSYS. I assume that should be
returned to user space?

	Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19  9:20   ` Arnaud POULIQUEN
  2026-02-19 13:26     ` Andrew Lunn
@ 2026-02-19 13:42     ` Andrew Lunn
  2026-02-20  9:16       ` Arnaud POULIQUEN
  2026-02-19 20:04     ` Shenwei Wang
  2026-02-19 21:13     ` Shenwei Wang
  3 siblings, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-19 13:42 UTC (permalink / raw)
  To: Arnaud POULIQUEN
  Cc: Shenwei Wang, Linus Walleij, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer, Shuah Khan, linux-gpio,
	linux-doc, linux-kernel, Pengutronix Kernel Team, Fabio Estevam,
	Peng Fan, devicetree, linux-remoteproc, imx, linux-arm-kernel,
	linux-imx, Bartosz Golaszewski

> > +	u8 id;		/* Message ID Code */
> > +	u8 vendor;	/* Vendor ID number */
> 
> Does this fields above are mandatory, seems that it is just some constant
> values that are useless.
> 
> > +	u8 version;	/* Vendor-specific version number */
> 
> Why it is vendor specific? the version should represent the rpmsg-tty
> protocol version.
> 
> > +	u8 type;	/* Message type */
> > +	u8 cmd;		/* Command code */
> > +	u8 reserved[5];
> 
> What is the purpose of this reserved field?

They have an implementation of the other end running on there systems,
and it sounds like it is widely deployed, and they are trying to keep
backwards compatibility. The protocol also implements more than
GPIO. There is also I2C, maybe watchdog, i don't remember, but early
versions of this patchset had a list. Some of these fields are used
for some of these other devices.

I've been arguing it should be a clean design, with the protocol
focusing on GPIO. And that the rpmsg channel makes it clear this is a
GPIO device, the protocol itself does not need to include fields to
differentiate between GPIO, I2C etc.

When they start submitting I2C over rpmsg, i expect the same sort of
discussion will start again, so the likelihood of keeping backwards
compatible with there firmware seems low to me.

	   Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19 13:26     ` Andrew Lunn
@ 2026-02-19 14:17       ` Shenwei Wang
  2026-02-19 15:25         ` Andrew Lunn
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-19 14:17 UTC (permalink / raw)
  To: Andrew Lunn, Arnaud POULIQUEN
  Cc: Linus Walleij, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer, Shuah Khan,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Thursday, February 19, 2026 7:27 AM
> To: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> Cc: Shenwei Wang <shenwei.wang@nxp.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> 
> > > +   if (sync) {
> > > +           err = wait_for_completion_timeout(&info->cmd_complete,
> > > +                                             msecs_to_jiffies(RPMSG_TIMEOUT));
> > > +           if (err == 0) {
> > > +                   dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> > > +                   return -ETIMEDOUT;
> >
> > strange condition you return an error if err == 0, for redability use 'ret'
> > variable or simply:
> >
> >               if(!wait_for_completion_timeout(&info->cmd_complete,
> >                                 msecs_to_jiffies(RPMSG_TIMEOUT)) {
> >                       dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> >                       return -ETIMEDOUT;
> >               }
> 
> This will be from a comment i made. It appears that
> do_wait_for_common() can return -ERESTARTSYS. I assume that should be
> returned to user space?
> 

It looks like there might be a bit of confusion around what wait_for_completion_timeout() 
actually returns. That function never returns -ERESTARTSYS. Instead, its behavior is pretty 
simple:

- 0 means the wait timed out
- A positive value means the completion happened (the value is just the remaining jiffies)

So the driver returns the timeout error, and the upper application can decide how it wants
to handle that situation, for example restart or ignore.

Thanks,
Shenwei

>         Andrew



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19 14:17       ` Shenwei Wang
@ 2026-02-19 15:25         ` Andrew Lunn
  2026-02-19 16:42           ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-19 15:25 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Thu, Feb 19, 2026 at 02:17:26PM +0000, Shenwei Wang wrote:
> 
> 
> > -----Original Message-----
> > From: Andrew Lunn <andrew@lunn.ch>
> > Sent: Thursday, February 19, 2026 7:27 AM
> > To: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> > Cc: Shenwei Wang <shenwei.wang@nxp.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > 
> > > > +   if (sync) {
> > > > +           err = wait_for_completion_timeout(&info->cmd_complete,
> > > > +                                             msecs_to_jiffies(RPMSG_TIMEOUT));
> > > > +           if (err == 0) {
> > > > +                   dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> > > > +                   return -ETIMEDOUT;
> > >
> > > strange condition you return an error if err == 0, for redability use 'ret'
> > > variable or simply:
> > >
> > >               if(!wait_for_completion_timeout(&info->cmd_complete,
> > >                                 msecs_to_jiffies(RPMSG_TIMEOUT)) {
> > >                       dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> > >                       return -ETIMEDOUT;
> > >               }
> > 
> > This will be from a comment i made. It appears that
> > do_wait_for_common() can return -ERESTARTSYS. I assume that should be
> > returned to user space?
> > 
> 
> It looks like there might be a bit of confusion around what wait_for_completion_timeout() 
> actually returns. That function never returns -ERESTARTSYS. Instead, its behavior is pretty 
> simple:
> 
> - 0 means the wait timed out
> - A positive value means the completion happened (the value is just the remaining jiffies)
> 
> So the driver returns the timeout error, and the upper application can decide how it wants
> to handle that situation, for example restart or ignore.

wait_for_completion_timeout():
	return wait_for_common(x, timeout, TASK_UNINTERRUPTIBLE);

wait_for_common():
	return __wait_for_common(x, io_schedule_timeout, timeout, state);

__wait_for_common():
	timeout = do_wait_for_common(x, action, timeout, state);
	...
	return timeout;

do_wait_for_common():

		do {
			if (signal_pending_state(state, current)) {
				timeout = -ERESTARTSYS;
				break;
			}
...		
		} while (!x->done && timeout);
...
		if (!x->done)
			return timeout;
...
	return timeout ?: 1;

This last line is interesting, and i had to go look at the
documentation:

https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html

So this is equivalent to

        return timeout ? timeout : 1;

Hence, it does appear wait_for_completion_timeout() can return
-ERESTARTSYS

There is however a comment in include/linux/errno.h

/*
 * These should never be seen by user programs.  To return one of ERESTART*
 * codes, signal_pending() MUST be set.  Note that ptrace can observe these
 * at syscall exit tracing, but they will never be left for the debugged user
 * process to see.
 */
#define ERESTARTSYS	512

So we do seem to be talking about a corner case, allowing gdb(1) to
know about it, but not user space.

	Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19 15:25         ` Andrew Lunn
@ 2026-02-19 16:42           ` Shenwei Wang
  0 siblings, 0 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-19 16:42 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Thursday, February 19, 2026 9:25 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> On Thu, Feb 19, 2026 at 02:17:26PM +0000, Shenwei Wang wrote:
> >
> >
> > > -----Original Message-----
> > > From: Andrew Lunn <andrew@lunn.ch>
> > > Sent: Thursday, February 19, 2026 7:27 AM
> > > To: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> > > Cc: Shenwei Wang <shenwei.wang@nxp.com>; 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>; Mathieu Poirier
> > > <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg
> > > GPIO driver
> > >
> > > > > +   if (sync) {
> > > > > +           err = wait_for_completion_timeout(&info->cmd_complete,
> > > > > +                                             msecs_to_jiffies(RPMSG_TIMEOUT));
> > > > > +           if (err == 0) {
> > > > > +                   dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> > > > > +                   return -ETIMEDOUT;
> > > >
> > > > strange condition you return an error if err == 0, for redability use 'ret'
> > > > variable or simply:
> > > >
> > > >               if(!wait_for_completion_timeout(&info->cmd_complete,
> > > >                                 msecs_to_jiffies(RPMSG_TIMEOUT)) {
> > > >                       dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> > > >                       return -ETIMEDOUT;
> > > >               }
> > >
> > > This will be from a comment i made. It appears that
> > > do_wait_for_common() can return -ERESTARTSYS. I assume that should
> > > be returned to user space?
> > >
> >
> > It looks like there might be a bit of confusion around what
> > wait_for_completion_timeout() actually returns. That function never
> > returns -ERESTARTSYS. Instead, its behavior is pretty
> > simple:
> >
> > - 0 means the wait timed out
> > - A positive value means the completion happened (the value is just
> > the remaining jiffies)
> >
> > So the driver returns the timeout error, and the upper application can
> > decide how it wants to handle that situation, for example restart or ignore.
> 
> wait_for_completion_timeout():
>         return wait_for_common(x, timeout, TASK_UNINTERRUPTIBLE);
> 
> wait_for_common():
>         return __wait_for_common(x, io_schedule_timeout, timeout, state);
> 
> __wait_for_common():
>         timeout = do_wait_for_common(x, action, timeout, state);
>         ...
>         return timeout;
> 
> do_wait_for_common():
> 
>                 do {
>                         if (signal_pending_state(state, current)) {
>                                 timeout = -ERESTARTSYS;

Once wait_for_common() is called with state = TASK_UNINTERRUPTIBLE, signal_pending_state() will 
always return false. As a result, -ERESTARTSYS is not a possible return value in this scenario.

Thanks,
Shenwei 

>                                 break;
>                         }
> ...
>                 } while (!x->done && timeout); ...
>                 if (!x->done)
>                         return timeout;
> ...
>         return timeout ?: 1;
>         Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19  9:20   ` Arnaud POULIQUEN
  2026-02-19 13:26     ` Andrew Lunn
  2026-02-19 13:42     ` Andrew Lunn
@ 2026-02-19 20:04     ` Shenwei Wang
  2026-02-19 20:50       ` Andrew Lunn
  2026-02-20  9:12       ` Arnaud POULIQUEN
  2026-02-19 21:13     ` Shenwei Wang
  3 siblings, 2 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-19 20:04 UTC (permalink / raw)
  To: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski, Andrew Lunn



> -----Original Message-----
> From: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> Sent: Thursday, February 19, 2026 3:21 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
> Cc: 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>; Andrew Lunn <andrew@lunn.ch>
> Subject: [EXT] Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> 
> Hello Shenwei,
> 
> This versiob seems much more generic, thanks!
> 
> On 2/12/26 22:36, Shenwei Wang wrote:
> > On an AMP platform, the system may include two processors:
> >       - An MCU running an RTOS
> >       - An MPU running Linux
> >
> > These processors communicate via the RPMSG protocol.
> > The driver implements the standard GPIO interface, allowing the Linux
> > side to control GPIO controllers which reside in the remote processor
> > via RPMSG protocol.
> >
> > Cc: Bartosz Golaszewski <brgl@bgdev.pl>
> > Cc: Andrew Lunn <andrew@lunn.ch>
> > Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
> > ---
> >   drivers/gpio/Kconfig      |  17 ++
> >   drivers/gpio/Makefile     |   1 +
> >   drivers/gpio/gpio-rpmsg.c | 588
> ++++++++++++++++++++++++++++++++++++++
> >   3 files changed, 606 insertions(+)
> >   create mode 100644 drivers/gpio/gpio-rpmsg.c
> >
> > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index
> > b45fb799e36c..3179a54f0634 100644
> > --- a/drivers/gpio/Kconfig
> > +++ b/drivers/gpio/Kconfig
> > @@ -1892,6 +1892,23 @@ config GPIO_SODAVILLE
> >
> >   endmenu
> >
> > +menu "RPMSG GPIO drivers"
> > +     depends on RPMSG
> > +
> > +config GPIO_RPMSG
> > +     tristate "Generic RPMSG GPIO support"
> > +     depends on REMOTEPROC
> > +     select GPIOLIB_IRQCHIP
> > +     default REMOTEPROC
> > +     help
> > +       Say yes here to support the generic GPIO functions over the RPMSG
> > +       bus. Currently supported devices: i.MX7ULP, i.MX8ULP, i.MX8x, and
> > +       i.MX9x.
> > +
> > +       If unsure, say N.
> > +
> > +endmenu
> > +
> >   menu "SPI GPIO expanders"
> >       depends on SPI_MASTER
> >
> > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index
> > c05f7d795c43..501aba56ad68 100644
> > --- a/drivers/gpio/Makefile
> > +++ b/drivers/gpio/Makefile
> > @@ -158,6 +158,7 @@ obj-$(CONFIG_GPIO_RDC321X)                += gpio-
> rdc321x.o
> >   obj-$(CONFIG_GPIO_REALTEK_OTTO)             += gpio-realtek-otto.o
> >   obj-$(CONFIG_GPIO_REG)                      += gpio-reg.o
> >   obj-$(CONFIG_GPIO_ROCKCHIP) += gpio-rockchip.o
> > +obj-$(CONFIG_GPIO_RPMSG)             += gpio-rpmsg.o
> >   obj-$(CONFIG_GPIO_RTD)                      += gpio-rtd.o
> >   obj-$(CONFIG_ARCH_SA1100)           += gpio-sa1100.o
> >   obj-$(CONFIG_GPIO_SAMA5D2_PIOBU)    += gpio-sama5d2-piobu.o
> > diff --git a/drivers/gpio/gpio-rpmsg.c b/drivers/gpio/gpio-rpmsg.c new
> > file mode 100644 index 000000000000..163f51fd45b5
> > --- /dev/null
> > +++ b/drivers/gpio/gpio-rpmsg.c
> > @@ -0,0 +1,588 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright 2026 NXP
> > + *
> > + * The driver exports a standard gpiochip interface to control
> > + * the GPIO controllers via RPMSG on a remote processor.
> > + */
> > +#include <linux/completion.h>
> > +#include <linux/device.h>
> > +#include <linux/err.h>
> > +#include <linux/gpio/driver.h>
> > +#include <linux/init.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/module.h>
> > +#include <linux/mutex.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/remoteproc.h>
> > +#include <linux/rpmsg.h>
> > +
> > +#define RPMSG_GPIO_ID                5
> > +#define RPMSG_VENDOR         1
> > +#define RPMSG_VERSION                0
> > +
> > +#define GPIOS_PER_PORT_DEFAULT       32
> > +#define RPMSG_TIMEOUT                1000
> > +
> > +/* GPIO RPMSG header type */
> > +#define GPIO_RPMSG_SETUP     0
> > +#define GPIO_RPMSG_REPLY     1
> > +#define GPIO_RPMSG_NOTIFY    2
> > +
> > +/* GPIO Interrupt trigger type */
> > +#define GPIO_RPMSG_TRI_IGNORE                0
> > +#define GPIO_RPMSG_TRI_RISING                1
> > +#define GPIO_RPMSG_TRI_FALLING               2
> > +#define GPIO_RPMSG_TRI_BOTH_EDGE     3
> > +#define GPIO_RPMSG_TRI_LOW_LEVEL     4
> > +#define GPIO_RPMSG_TRI_HIGH_LEVEL    5
> > +
> > +/* GPIO RPMSG commands */
> > +#define GPIO_RPMSG_INPUT_INIT                0
> > +#define GPIO_RPMSG_OUTPUT_INIT               1
> > +#define GPIO_RPMSG_INPUT_GET         2
> > +#define GPIO_RPMSG_DIRECTION_GET     3
> > +
> > +#define MAX_PORT_PER_CHANNEL    10
> > +
> > +/*
> > + * @rproc_name: the name of the remote proc.
> > + * @channel_devices: an array of the devices related to the rpdev.
> > + */
> > +struct rpdev_drvdata {
> > +     const char *rproc_name;
> > +     void *channel_devices[MAX_PORT_PER_CHANNEL];
> > +};
> > +
> > +struct gpio_rpmsg_head {
> 
> Sometime the prefix is gpio_rpmsg, sometime rpmsg_gpio or just gpio, could you
> use "rpmsg_gpio" prefix in the whole driver?
> 

All the types use prefix gpio_rpmsg. All the functions use rpmsg_gpio.

> > +     u8 id;          /* Message ID Code */
> > +     u8 vendor;      /* Vendor ID number */
> 
> Does this fields above are mandatory, seems that it is just some constant values
> that are useless.
> 
> > +     u8 version;     /* Vendor-specific version number */
> 
> Why it is vendor specific? the version should represent the rpmsg-tty protocol
> version.
> 
> > +     u8 type;        /* Message type */
> > +     u8 cmd;         /* Command code */
> > +     u8 reserved[5];
> 
> What is the purpose of this reserved field?
> 
> > +} __packed;
> > +
> > +struct gpio_rpmsg_packet {
> > +     struct gpio_rpmsg_head header;
> > +     u8 pin_idx;
> > +     u8 port_idx;
> > +     union {
> > +             u8 event;
> > +             u8 retcode;
> > +             u8 value;
> > +     } out;
> > +     union {
> > +             u8 wakeup;
> > +             u8 value;
> > +     } in;
> > +} __packed __aligned(8);
> 
> Any reason to use __packed and alignement here?
> This structure will be copied in a vring buffer right?
> 

Using __packed together with an explicit alignment is a common pattern for defining 
communication packets. The goal is to ensure a stable and predictable layout across 
different architectures and compilers. Even though this structure is copied into a vring 
buffer, enforcing the layout avoids potential ABI or padding differences that could lead 
to compatibility issues when the data is parsed on the other side.

> > +
> > +struct gpio_rpmsg_pin {
> > +     u8 irq_shutdown;
> > +     u8 irq_unmask;
> > +     u8 irq_mask;
> > +     u32 irq_wake_enable;
> > +     u32 irq_type;
> > +     struct gpio_rpmsg_packet msg;
> > +};
> > +
> > +struct gpio_rpmsg_info {
> > +     struct rpmsg_device *rpdev;
> > +     struct gpio_rpmsg_packet *reply_msg;
> > +     struct completion cmd_complete;
> > +     struct mutex lock;
> > +     void **port_store;
> > +};
> > +
> > +struct rpmsg_gpio_port {
> > +     struct gpio_chip gc;
> > +     struct gpio_rpmsg_pin gpio_pins[GPIOS_PER_PORT_DEFAULT];
> > +     struct gpio_rpmsg_info info;
> > +     u32 ngpios;
> > +     u32 idx;
> > +};
> > +
> > +static int gpio_send_message(struct rpmsg_gpio_port *port,
> 
> s/gpio_send_message/rpmsg_gpio_send_message
> 
> > +                          struct gpio_rpmsg_packet *msg,
> > +                          bool sync)
> > +{
> > +     struct gpio_rpmsg_info *info = &port->info;
> > +     int err;
> > +
> > +     reinit_completion(&info->cmd_complete);
> > +     err = rpmsg_send(info->rpdev->ept, msg, sizeof(struct gpio_rpmsg_packet));
> > +     if (err) {
> > +             dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
> > +             return err;
> > +     }
> > +
> > +     if (sync) {
> > +             err = wait_for_completion_timeout(&info->cmd_complete,
> > +                                               msecs_to_jiffies(RPMSG_TIMEOUT));
> > +             if (err == 0) {
> > +                     dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> > +                     return -ETIMEDOUT;
> 
> strange condition you return an error if err == 0, for redability use 'ret' variable or
> simply:
> 

Agree. Changing to "ret" is clearer here.

>                 if(!wait_for_completion_timeout(&info->cmd_complete,
>                                   msecs_to_jiffies(RPMSG_TIMEOUT)) {
>                         dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
>                         return -ETIMEDOUT;
>                 }
> 
> > +
> > +             if (info->reply_msg->out.retcode != 0) {
> > +                     dev_err(&info->rpdev->dev, "remote core replies an error: %d!\n",
> > +                             info->reply_msg->out.retcode);
> > +                     return -EINVAL;
> > +             }
> > +
> > +             /* copy the reply message */
> > +             memcpy(&port->gpio_pins[info->reply_msg->pin_idx].msg,
> > +                    info->reply_msg, sizeof(*info->reply_msg));
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static struct gpio_rpmsg_packet *gpio_setup_msg_common(struct
> rpmsg_gpio_port *port,
> > +                                                    unsigned int offset,
> > +                                                    u8 cmd) {
> > +     struct gpio_rpmsg_packet *msg = &port->gpio_pins[offset].msg;
> > +
> > +     memset(msg, 0, sizeof(struct gpio_rpmsg_packet));
> > +     msg->header.id = RPMSG_GPIO_ID;
> > +     msg->header.vendor = RPMSG_VENDOR;
> > +     msg->header.version = RPMSG_VERSION;
> > +     msg->header.type = GPIO_RPMSG_SETUP;
> > +     msg->header.cmd = cmd;
> > +     msg->pin_idx = offset;
> > +     msg->port_idx = port->idx;
> > +
> > +     return msg;
> > +}
> > +
> > +static int rpmsg_gpio_get(struct gpio_chip *gc, unsigned int gpio) {
> > +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> > +     struct gpio_rpmsg_packet *msg;
> > +     int ret;
> > +
> > +     guard(mutex)(&port->info.lock);
> > +
> > +     msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_INPUT_GET);
> > +
> > +     ret = gpio_send_message(port, msg, true);
> > +     if (!ret)
> > +             ret = !!port->gpio_pins[gpio].msg.in.value;
> > +
> > +     return ret;
> > +}
> > +
> > +static int rpmsg_gpio_get_direction(struct gpio_chip *gc, unsigned
> > +int gpio) {
> > +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> > +     struct gpio_rpmsg_packet *msg;
> > +     int ret;
> > +
> > +     guard(mutex)(&port->info.lock);
> > +
> > +     msg = gpio_setup_msg_common(port, gpio,
> > + GPIO_RPMSG_DIRECTION_GET);
> > +
> > +     ret = gpio_send_message(port, msg, true);
> > +     if (!ret)
> > +             ret = !!port->gpio_pins[gpio].msg.in.value;
> > +
> > +     return ret;
> > +}
> > +
> > +static int rpmsg_gpio_direction_input(struct gpio_chip *gc, unsigned
> > +int gpio) {
> > +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> > +     struct gpio_rpmsg_packet *msg;
> > +
> > +     guard(mutex)(&port->info.lock);
> > +
> > +     msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_INPUT_INIT);
> > +
> > +     return gpio_send_message(port, msg, true); }
> > +
> > +static int rpmsg_gpio_set(struct gpio_chip *gc, unsigned int gpio,
> > +int val) {
> > +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> > +     struct gpio_rpmsg_packet *msg;
> > +
> > +     guard(mutex)(&port->info.lock);
> > +
> > +     msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_OUTPUT_INIT);
> > +     msg->out.value = val;
> > +
> > +     return gpio_send_message(port, msg, true); }
> > +
> > +static int rpmsg_gpio_direction_output(struct gpio_chip *gc,
> > +                                    unsigned int gpio,
> > +                                    int val) {
> > +     return rpmsg_gpio_set(gc, gpio, val); }
> > +
> > +static int gpio_rpmsg_irq_set_type(struct irq_data *d, u32 type) {
> > +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > +     u32 gpio_idx = d->hwirq;
> > +     int edge = 0;
> > +     int ret = 0;
> > +
> > +     switch (type) {
> > +     case IRQ_TYPE_EDGE_RISING:
> > +             edge = GPIO_RPMSG_TRI_RISING;
> > +             irq_set_handler_locked(d, handle_simple_irq);
> > +             break;
> > +     case IRQ_TYPE_EDGE_FALLING:
> > +             edge = GPIO_RPMSG_TRI_FALLING;
> > +             irq_set_handler_locked(d, handle_simple_irq);
> > +             break;
> > +     case IRQ_TYPE_EDGE_BOTH:
> > +             edge = GPIO_RPMSG_TRI_BOTH_EDGE;
> > +             irq_set_handler_locked(d, handle_simple_irq);
> > +             break;
> > +     case IRQ_TYPE_LEVEL_LOW:
> > +             edge = GPIO_RPMSG_TRI_LOW_LEVEL;
> > +             irq_set_handler_locked(d, handle_level_irq);
> > +             break;
> > +     case IRQ_TYPE_LEVEL_HIGH:
> > +             edge = GPIO_RPMSG_TRI_HIGH_LEVEL;
> > +             irq_set_handler_locked(d, handle_level_irq);
> > +             break;
> > +     default:
> > +             ret = -EINVAL;
> > +             irq_set_handler_locked(d, handle_bad_irq);
> > +             break;
> > +     }
> > +
> > +     port->gpio_pins[gpio_idx].irq_type = edge;
> > +
> > +     return ret;
> > +}
> > +
> > +static int gpio_rpmsg_irq_set_wake(struct irq_data *d, u32 enable) {
> > +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > +     u32 gpio_idx = d->hwirq;
> > +
> > +     port->gpio_pins[gpio_idx].irq_wake_enable = enable;
> > +
> > +     return 0;
> > +}
> > +
> > +/*
> > + * This unmask/mask function is invoked in two situations:
> > + *   - when an interrupt is being set up, and
> > + *   - after an interrupt has occurred.
> > + *
> > + * The GPIO driver does not access hardware registers directly.
> > + * Instead, it caches all relevant information locally, and then
> > +sends
> > + * the accumulated state to the remote system at this stage.
> > + */
> > +static void gpio_rpmsg_unmask_irq(struct irq_data *d) {
> > +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > +     u32 gpio_idx = d->hwirq;
> > +
> > +     port->gpio_pins[gpio_idx].irq_unmask = 1; }
> > +
> > +static void gpio_rpmsg_mask_irq(struct irq_data *d) {
> > +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > +     u32 gpio_idx = d->hwirq;
> > +
> > +     /*
> > +      * When an interrupt occurs, the remote system masks the interrupt
> > +      * and then sends a notification to Linux. After Linux processes
> > +      * that notification, it sends an RPMsg command back to the remote
> > +      * system to unmask the interrupt again.
> > +      */
> > +     port->gpio_pins[gpio_idx].irq_mask = 1; }
> > +
> > +static void gpio_rpmsg_irq_shutdown(struct irq_data *d) {
> > +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > +     u32 gpio_idx = d->hwirq;
> > +
> > +     port->gpio_pins[gpio_idx].irq_shutdown = 1; }
> > +
> > +static void gpio_rpmsg_irq_bus_lock(struct irq_data *d) {
> > +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > +
> > +     mutex_lock(&port->info.lock);
> > +}
> > +
> > +static void gpio_rpmsg_irq_bus_sync_unlock(struct irq_data *d) {
> > +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > +     struct gpio_rpmsg_packet *msg = NULL;
> > +     u32 gpio_idx = d->hwirq;
> > +
> > +     /*
> > +      * For mask irq, do nothing here.
> > +      * The remote system will mask interrupt after an interrupt occurs,
> > +      * and then send a notify to Linux system.
> > +      * After Linux system dealt with the notify, it will send an rpmsg to
> > +      * the remote system to unmask this interrupt again.
> > +      */
> > +     if (port->gpio_pins[gpio_idx].irq_mask && !port-
> >gpio_pins[gpio_idx].irq_unmask) {
> > +             port->gpio_pins[gpio_idx].irq_mask = 0;
> > +             mutex_unlock(&port->info.lock);
> > +             return;
> > +     }
> > +
> > +     msg = gpio_setup_msg_common(port, gpio_idx,
> > + GPIO_RPMSG_INPUT_INIT);
> > +
> > +     if (port->gpio_pins[gpio_idx].irq_shutdown) {
> > +             msg->out.event = GPIO_RPMSG_TRI_IGNORE;
> > +             msg->in.wakeup = 0;
> > +             port->gpio_pins[gpio_idx].irq_shutdown = 0;
> > +     } else {
> > +             /* if not set irq type, then use low level as trigger type */
> > +             msg->out.event = port->gpio_pins[gpio_idx].irq_type;
> > +             if (!msg->out.event)
> > +                     msg->out.event = GPIO_RPMSG_TRI_LOW_LEVEL;
> > +             if (port->gpio_pins[gpio_idx].irq_unmask) {
> > +                     msg->in.wakeup = 0;
> > +                     port->gpio_pins[gpio_idx].irq_unmask = 0;
> > +             } else /* irq set wake */
> > +                     msg->in.wakeup = port->gpio_pins[gpio_idx].irq_wake_enable;
> > +     }
> > +
> > +     gpio_send_message(port, msg, false);
> > +     mutex_unlock(&port->info.lock);
> > +}
> > +
> > +static const struct irq_chip gpio_rpmsg_irq_chip = {
> > +     .irq_mask = gpio_rpmsg_mask_irq,
> > +     .irq_unmask = gpio_rpmsg_unmask_irq,
> > +     .irq_set_wake = gpio_rpmsg_irq_set_wake,
> > +     .irq_set_type = gpio_rpmsg_irq_set_type,
> > +     .irq_shutdown = gpio_rpmsg_irq_shutdown,
> > +     .irq_bus_lock = gpio_rpmsg_irq_bus_lock,
> > +     .irq_bus_sync_unlock = gpio_rpmsg_irq_bus_sync_unlock,
> > +     .flags = IRQCHIP_IMMUTABLE,
> > +};
> > +
> > +static void rpmsg_gpio_remove_action(void *data) {
> > +     struct rpmsg_gpio_port *port = data;
> > +
> > +     port->info.port_store[port->idx] = NULL; }
> > +
> > +static int rpmsg_gpiochip_register(struct rpmsg_device *rpdev, struct
> > +device_node *np) {
> > +     struct rpdev_drvdata *drvdata = dev_get_drvdata(&rpdev->dev);
> > +     struct rpmsg_gpio_port *port;
> > +     struct gpio_irq_chip *girq;
> > +     struct gpio_chip *gc;
> > +     int ret;
> > +
> > +     port = devm_kzalloc(&rpdev->dev, sizeof(*port), GFP_KERNEL);
> > +     if (!port)
> > +             return -ENOMEM;
> > +
> > +     ret = of_property_read_u32(np, "reg", &port->idx);
> > +     if (ret)
> > +             return ret;
> > +
> > +     if (port->idx >= MAX_PORT_PER_CHANNEL)
> > +             return -EINVAL;
> > +
> > +     ret = devm_mutex_init(&rpdev->dev, &port->info.lock);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = of_property_read_u32(np, "ngpios", &port->ngpios);
> > +     if (ret)
> > +             port->ngpios = GPIOS_PER_PORT_DEFAULT;
> > +
> > +     init_completion(&port->info.cmd_complete);
> > +     port->info.reply_msg = devm_kzalloc(&rpdev->dev,
> > +                                         sizeof(struct gpio_rpmsg_packet),
> > +                                         GFP_KERNEL);
> > +     port->info.port_store = drvdata->channel_devices;
> > +     port->info.port_store[port->idx] = port;
> > +     port->info.rpdev = rpdev;
> > +
> > +     gc = &port->gc;
> > +     gc->owner = THIS_MODULE;
> > +     gc->parent = &rpdev->dev;
> > +     gc->fwnode = of_fwnode_handle(np);
> > +     gc->ngpio = port->ngpios;
> > +     gc->base = -1;
> > +     gc->label = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-gpio%d",
> > +                                drvdata->rproc_name, port->idx);
> > +
> > +     gc->direction_input = rpmsg_gpio_direction_input;
> > +     gc->direction_output = rpmsg_gpio_direction_output;
> > +     gc->get_direction = rpmsg_gpio_get_direction;
> > +     gc->get = rpmsg_gpio_get;
> > +     gc->set = rpmsg_gpio_set;
> > +
> > +     girq = &gc->irq;
> > +     gpio_irq_chip_set_chip(girq, &gpio_rpmsg_irq_chip);
> > +     girq->parent_handler = NULL;
> > +     girq->num_parents = 0;
> > +     girq->parents = NULL;
> > +     girq->chip->name = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-
> gpio%d",
> > +                                       drvdata->rproc_name,
> > + port->idx);
> > +
> > +     ret = devm_add_action_or_reset(&rpdev->dev,
> rpmsg_gpio_remove_action, port);
> > +     if (ret)
> > +             return ret;
> > +
> > +     return devm_gpiochip_add_data(&rpdev->dev, gc, port); }
> > +
> > +static const char *rpmsg_get_rproc_node_name(struct rpmsg_device
> > +*rpdev) {
> > +     const char *name = NULL;
> > +     struct device_node *np;
> > +     struct rproc *rproc;
> > +
> > +     rproc = rproc_get_by_child(&rpdev->dev);
> > +
> > +     if (!rproc)
> > +             return NULL;
> > +
> > +     np = of_node_get(rproc->dev.of_node);
> > +     if (!np && rproc->dev.parent)
> > +             np = of_node_get(rproc->dev.parent->of_node);
> > +
> > +     if (np) {
> > +             name = devm_kstrdup(&rpdev->dev, np->name, GFP_KERNEL);
> > +             of_node_put(np);
> > +     }
> 
> What about simply returning rproc->name?
> 

rproc->name doesn’t serve the purpose here. It only reflects the remoteproc driver’s name, 
not the identity of a specific remoteproc instance. What we need is a unique and meaningful 
identifier for this particular instance, and using the DT node name provides exactly that.

Thanks,
Shenwei

> > +
> > +     return name;
> > +}
> > +
> > +static struct device_node *
> > +rpmsg_get_channel_ofnode(struct rpmsg_device *rpdev, char *chan_name)
> > +{
> > +     struct device_node *np_chan = NULL, *np;
> > +     struct rproc *rproc;
> > +
> > +     rproc = rproc_get_by_child(&rpdev->dev);
> > +     if (!rproc)
> > +             return NULL;
> > +
> > +     np = of_node_get(rproc->dev.of_node);
> > +     if (!np && rproc->dev.parent)
> > +             np = of_node_get(rproc->dev.parent->of_node);
> 
> Is a topology where they is no rproc->dev node but a parent node exist?
> 
> > +
> > +     if (np) {
> > +             /* Balance the of_node_put() performed by of_find_node_by_name().
> */
> > +             of_node_get(np);
> > +             np_chan = of_find_node_by_name(np, chan_name);
> > +             of_node_put(np);
> > +     }
> > +
> > +     return np_chan;
> > +}
> > +
> > +static int
> > +rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void *data,
> > +                         int len, void *priv, u32 src) {
> > +     struct gpio_rpmsg_packet *msg = data;
> > +     struct rpmsg_gpio_port *port = NULL;
> > +     struct rpdev_drvdata *drvdata;
> > +
> > +     drvdata = dev_get_drvdata(&rpdev->dev);
> > +     if (drvdata && msg && msg->port_idx < MAX_PORT_PER_CHANNEL)
> > +             port = drvdata->channel_devices[msg->port_idx];
> > +
> > +     if (!port)
> > +             return -ENODEV;
> > +
> > +     if (msg->header.type == GPIO_RPMSG_REPLY) {
> > +             *port->info.reply_msg = *msg;
> > +             complete(&port->info.cmd_complete);
> 
> What happen if the remoteprocessor answer after the completion timeout?
> Could it result in desynchronization between the request and the answer?
> 
> Having a cmd_counter in gpio_rpmsg_head could help to identify current request
> and answer
> 
> the use of reinit_completion could be also needed
> 
> > +     } else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
> > +             generic_handle_domain_irq_safe(port->gc.irq.domain, msg->pin_idx);
> > +     } else
> > +             dev_err(&rpdev->dev, "wrong command type!\n");
> 
> Could you print the msg->header.type value to help for debug?
> 
> > +
> > +     return 0;
> > +}
> > +
> > +static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev) {
> > +     struct device *dev = &rpdev->dev;
> > +     struct rpdev_drvdata *drvdata;
> > +     struct device_node *np;
> > +     int ret;
> > +
> > +     if (!dev->of_node) {
> > +             np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
> > +             if (np) {
> > +                     dev->of_node = np;
> > +                     set_primary_fwnode(dev, of_fwnode_handle(np));
> > +             }
> > +             return -EPROBE_DEFER;
> > +     }
> > +
> > +     drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > +     if (!drvdata)
> > +             return -ENOMEM;
> > +
> > +     drvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);
> > +     dev_set_drvdata(dev, drvdata);
> > +
> > +     for_each_child_of_node_scoped(dev->of_node, child) {
> > +             if (!of_device_is_available(child))
> > +                     continue;
> > +
> > +             if (!of_match_node(dev->driver->of_match_table, child))
> > +                     continue;
> > +
> > +             ret = rpmsg_gpiochip_register(rpdev, child);
> > +             if (ret < 0)
> > +                     dev_err(dev, "Failed to register: %pOF\n", child);
> > +     }
> > +
> > +     return 0;
> 
> return ret
> or indicate why the return of rpmsg_gpiochip_register is not taken into account
> 
> 
> > +}
> > +
> > +static void rpmsg_gpio_channel_remove(struct rpmsg_device *rpdev) {
> > +     dev_info(&rpdev->dev, "rpmsg gpio channel driver is removed\n");
> > +}
> > +
> > +static const struct of_device_id rpmsg_gpio_dt_ids[] = {
> > +     { .compatible = "rpmsg-gpio" },
> > +     { /* sentinel */ }
> > +};
> > +
> > +static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {
> > +     { .name = "rpmsg-io-channel" },
> 
> I would remove the "-channel" suffix to have similar naming than "rpmsg-tty" and
> "rpmsg-raw"
> 
> Regards,
> Arnaud
> 
> > +     { },
> > +};
> > +MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);
> > +
> > +static struct rpmsg_driver rpmsg_gpio_channel_client = {
> > +     .drv.name       = KBUILD_MODNAME,
> > +     .drv.of_match_table = rpmsg_gpio_dt_ids,
> > +     .id_table       = rpmsg_gpio_channel_id_table,
> > +     .probe          = rpmsg_gpio_channel_probe,
> > +     .callback       = rpmsg_gpio_channel_callback,
> > +     .remove         = rpmsg_gpio_channel_remove,
> > +};
> > +module_rpmsg_driver(rpmsg_gpio_channel_client);
> > +
> > +MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>");
> > +MODULE_DESCRIPTION("generic rpmsg gpio driver");
> > +MODULE_LICENSE("GPL");


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19 20:04     ` Shenwei Wang
@ 2026-02-19 20:50       ` Andrew Lunn
  2026-02-19 21:12         ` Shenwei Wang
  2026-02-20  9:12       ` Arnaud POULIQUEN
  1 sibling, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-19 20:50 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> > Any reason to use __packed and alignement here?
> > This structure will be copied in a vring buffer right?
> > 
> 
> Using __packed together with an explicit alignment is a common pattern for defining 
> communication packets. The goal is to ensure a stable and predictable layout across 
> different architectures and compilers.

Being mostly a netdev person, i can say that the network Maintainers
actually refuses patches with __packed. If you have designed your
protocol correctly, defined your structure correctly, you should not
need them.

We do however accept things like

	BUILD_BUG_ON(sizeof(strcut foo) != 8);

just to make sure the compile is doing what you expect.

	Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19 20:50       ` Andrew Lunn
@ 2026-02-19 21:12         ` Shenwei Wang
  0 siblings, 0 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-19 21:12 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Thursday, February 19, 2026 2:51 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > > Any reason to use __packed and alignement here?
> > > This structure will be copied in a vring buffer right?
> > >
> >
> > Using __packed together with an explicit alignment is a common pattern
> > for defining communication packets. The goal is to ensure a stable and
> > predictable layout across different architectures and compilers.
> 
> Being mostly a netdev person, i can say that the network Maintainers actually
> refuses patches with __packed. If you have designed your protocol correctly,
> defined your structure correctly, you should not need them.
> 

The fact is that there are many __packed usages just under the Ethernet directory.
$ grep -rn __packed drivers/net/ethernet | wc -l
553

Regards,
Shenwei

> We do however accept things like
> 
>         BUILD_BUG_ON(sizeof(strcut foo) != 8);
> 
> just to make sure the compile is doing what you expect.
> 
>         Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19  9:20   ` Arnaud POULIQUEN
                       ` (2 preceding siblings ...)
  2026-02-19 20:04     ` Shenwei Wang
@ 2026-02-19 21:13     ` Shenwei Wang
  2026-02-20  9:32       ` Arnaud POULIQUEN
  3 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-19 21:13 UTC (permalink / raw)
  To: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski, Andrew Lunn



> -----Original Message-----
> From: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> Sent: Thursday, February 19, 2026 3:21 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
> Cc: 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>; Andrew Lunn <andrew@lunn.ch>
> Subject: [EXT] Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > +     rproc = rproc_get_by_child(&rpdev->dev);
> > +     if (!rproc)
> > +             return NULL;
> > +
> > +     np = of_node_get(rproc->dev.of_node);
> > +     if (!np && rproc->dev.parent)
> > +             np = of_node_get(rproc->dev.parent->of_node);
> 
> Is a topology where they is no rproc->dev node but a parent node exist?
> 

If no rproc->dev, it should return NULL in the above check.

> > +
> > +     if (np) {
> > +             /* Balance the of_node_put() performed by of_find_node_by_name().
> */
> > +             of_node_get(np);
> > +             np_chan = of_find_node_by_name(np, chan_name);
> > +             of_node_put(np);
> > +     }
> > +
> > +     return np_chan;
> > +}
> > +
> > +static int
> > +rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void *data,
> > +                         int len, void *priv, u32 src) {
> > +     struct gpio_rpmsg_packet *msg = data;
> > +     struct rpmsg_gpio_port *port = NULL;
> > +     struct rpdev_drvdata *drvdata;
> > +
> > +     drvdata = dev_get_drvdata(&rpdev->dev);
> > +     if (drvdata && msg && msg->port_idx < MAX_PORT_PER_CHANNEL)
> > +             port = drvdata->channel_devices[msg->port_idx];
> > +
> > +     if (!port)
> > +             return -ENODEV;
> > +
> > +     if (msg->header.type == GPIO_RPMSG_REPLY) {
> > +             *port->info.reply_msg = *msg;
> > +             complete(&port->info.cmd_complete);
> 
> What happen if the remoteprocessor answer after the completion timeout?
> Could it result in desynchronization between the request and the answer?

If the remote processor responds after the timeout, that late reply will be ignored. The current 
transfer should fail with TIMEOUT, and the state won’t be carried over because cmd_complete 
is reinitialized before each new request, so a stale completion won’t desynchronize the next 
transaction. Each command–reply cycle is isolated, so a delayed reply cannot corrupt or mix with 
a subsequent request.

> 
> Having a cmd_counter in gpio_rpmsg_head could help to identify current request
> and answer
> 
> the use of reinit_completion could be also needed
> 
> > +     } else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
> > +             generic_handle_domain_irq_safe(port->gc.irq.domain, msg->pin_idx);
> > +     } else
> > +             dev_err(&rpdev->dev, "wrong command type!\n");
> 
> Could you print the msg->header.type value to help for debug?
> 

Sure. Will add it in next version.

> > +
> > +     return 0;
> > +}
> > +
> > +static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev) {
> > +     struct device *dev = &rpdev->dev;
> > +     struct rpdev_drvdata *drvdata;
> > +     struct device_node *np;
> > +     int ret;
> > +
> > +     if (!dev->of_node) {
> > +             np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
> > +             if (np) {
> > +                     dev->of_node = np;
> > +                     set_primary_fwnode(dev, of_fwnode_handle(np));
> > +             }
> > +             return -EPROBE_DEFER;
> > +     }
> > +
> > +     drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > +     if (!drvdata)
> > +             return -ENOMEM;
> > +
> > +     drvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);
> > +     dev_set_drvdata(dev, drvdata);
> > +
> > +     for_each_child_of_node_scoped(dev->of_node, child) {
> > +             if (!of_device_is_available(child))
> > +                     continue;
> > +
> > +             if (!of_match_node(dev->driver->of_match_table, child))
> > +                     continue;
> > +
> > +             ret = rpmsg_gpiochip_register(rpdev, child);
> > +             if (ret < 0)
> > +                     dev_err(dev, "Failed to register: %pOF\n", child);
> > +     }
> > +
> > +     return 0;
> 
> return ret
> or indicate why the return of rpmsg_gpiochip_register is not taken into account
> 

rpmsg_gpiochip_register() failing only affects whether the GPIO instance gets created. The 
rpmsg channel driver itself can still probe successfully and continue to operate for other features. 

> 
> > +}
> > +
> > +static void rpmsg_gpio_channel_remove(struct rpmsg_device *rpdev) {
> > +     dev_info(&rpdev->dev, "rpmsg gpio channel driver is removed\n");
> > +}
> > +
> > +static const struct of_device_id rpmsg_gpio_dt_ids[] = {
> > +     { .compatible = "rpmsg-gpio" },
> > +     { /* sentinel */ }
> > +};
> > +
> > +static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {
> > +     { .name = "rpmsg-io-channel" },
> 
> I would remove the "-channel" suffix to have similar naming than "rpmsg-tty" and
> "rpmsg-raw"
> 

The channel name comes from the remote firmware, so we can’t freely rename it on the 
Linux side. On i.MX platforms the firmware follows its own naming conventions, and the *-channel 
suffix is part of that scheme.

Thanks,
Shenwei

> Regards,
> Arnaud
> 
> > +     { },
> > +};
> > +MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);
> > +
> > +static struct rpmsg_driver rpmsg_gpio_channel_client = {
> > +     .drv.name       = KBUILD_MODNAME,
> > +     .drv.of_match_table = rpmsg_gpio_dt_ids,
> > +     .id_table       = rpmsg_gpio_channel_id_table,
> > +     .probe          = rpmsg_gpio_channel_probe,
> > +     .callback       = rpmsg_gpio_channel_callback,
> > +     .remove         = rpmsg_gpio_channel_remove,
> > +};
> > +module_rpmsg_driver(rpmsg_gpio_channel_client);
> > +
> > +MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>");
> > +MODULE_DESCRIPTION("generic rpmsg gpio driver");
> > +MODULE_LICENSE("GPL");


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19 20:04     ` Shenwei Wang
  2026-02-19 20:50       ` Andrew Lunn
@ 2026-02-20  9:12       ` Arnaud POULIQUEN
  2026-02-20 15:47         ` Shenwei Wang
  1 sibling, 1 reply; 69+ messages in thread
From: Arnaud POULIQUEN @ 2026-02-20  9:12 UTC (permalink / raw)
  To: Shenwei Wang, Linus Walleij, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski, Andrew Lunn



On 2/19/26 21:04, Shenwei Wang wrote:
> 
> 
>> -----Original Message-----
>> From: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
>> Sent: Thursday, February 19, 2026 3:21 AM
>> To: Shenwei Wang <shenwei.wang@nxp.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
>> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
>> Cc: 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>; Andrew Lunn <andrew@lunn.ch>
>> Subject: [EXT] Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
>>
>> Hello Shenwei,
>>
>> This versiob seems much more generic, thanks!
>>
>> On 2/12/26 22:36, Shenwei Wang wrote:
>>> On an AMP platform, the system may include two processors:
>>>        - An MCU running an RTOS
>>>        - An MPU running Linux
>>>
>>> These processors communicate via the RPMSG protocol.
>>> The driver implements the standard GPIO interface, allowing the Linux
>>> side to control GPIO controllers which reside in the remote processor
>>> via RPMSG protocol.
>>>
>>> Cc: Bartosz Golaszewski <brgl@bgdev.pl>
>>> Cc: Andrew Lunn <andrew@lunn.ch>
>>> Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
>>> ---
>>>    drivers/gpio/Kconfig      |  17 ++
>>>    drivers/gpio/Makefile     |   1 +
>>>    drivers/gpio/gpio-rpmsg.c | 588
>> ++++++++++++++++++++++++++++++++++++++
>>>    3 files changed, 606 insertions(+)
>>>    create mode 100644 drivers/gpio/gpio-rpmsg.c
>>>
>>> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index
>>> b45fb799e36c..3179a54f0634 100644
>>> --- a/drivers/gpio/Kconfig
>>> +++ b/drivers/gpio/Kconfig
>>> @@ -1892,6 +1892,23 @@ config GPIO_SODAVILLE
>>>
>>>    endmenu
>>>
>>> +menu "RPMSG GPIO drivers"
>>> +     depends on RPMSG
>>> +
>>> +config GPIO_RPMSG
>>> +     tristate "Generic RPMSG GPIO support"
>>> +     depends on REMOTEPROC
>>> +     select GPIOLIB_IRQCHIP
>>> +     default REMOTEPROC
>>> +     help
>>> +       Say yes here to support the generic GPIO functions over the RPMSG
>>> +       bus. Currently supported devices: i.MX7ULP, i.MX8ULP, i.MX8x, and
>>> +       i.MX9x.
>>> +
>>> +       If unsure, say N.
>>> +
>>> +endmenu
>>> +
>>>    menu "SPI GPIO expanders"
>>>        depends on SPI_MASTER
>>>
>>> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index
>>> c05f7d795c43..501aba56ad68 100644
>>> --- a/drivers/gpio/Makefile
>>> +++ b/drivers/gpio/Makefile
>>> @@ -158,6 +158,7 @@ obj-$(CONFIG_GPIO_RDC321X)                += gpio-
>> rdc321x.o
>>>    obj-$(CONFIG_GPIO_REALTEK_OTTO)             += gpio-realtek-otto.o
>>>    obj-$(CONFIG_GPIO_REG)                      += gpio-reg.o
>>>    obj-$(CONFIG_GPIO_ROCKCHIP) += gpio-rockchip.o
>>> +obj-$(CONFIG_GPIO_RPMSG)             += gpio-rpmsg.o
>>>    obj-$(CONFIG_GPIO_RTD)                      += gpio-rtd.o
>>>    obj-$(CONFIG_ARCH_SA1100)           += gpio-sa1100.o
>>>    obj-$(CONFIG_GPIO_SAMA5D2_PIOBU)    += gpio-sama5d2-piobu.o
>>> diff --git a/drivers/gpio/gpio-rpmsg.c b/drivers/gpio/gpio-rpmsg.c new
>>> file mode 100644 index 000000000000..163f51fd45b5
>>> --- /dev/null
>>> +++ b/drivers/gpio/gpio-rpmsg.c
>>> @@ -0,0 +1,588 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +/*
>>> + * Copyright 2026 NXP
>>> + *
>>> + * The driver exports a standard gpiochip interface to control
>>> + * the GPIO controllers via RPMSG on a remote processor.
>>> + */
>>> +#include <linux/completion.h>
>>> +#include <linux/device.h>
>>> +#include <linux/err.h>
>>> +#include <linux/gpio/driver.h>
>>> +#include <linux/init.h>
>>> +#include <linux/irqdomain.h>
>>> +#include <linux/mod_devicetable.h>
>>> +#include <linux/module.h>
>>> +#include <linux/mutex.h>
>>> +#include <linux/of.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/of_platform.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/remoteproc.h>
>>> +#include <linux/rpmsg.h>
>>> +
>>> +#define RPMSG_GPIO_ID                5
>>> +#define RPMSG_VENDOR         1
>>> +#define RPMSG_VERSION                0
>>> +
>>> +#define GPIOS_PER_PORT_DEFAULT       32
>>> +#define RPMSG_TIMEOUT                1000
>>> +
>>> +/* GPIO RPMSG header type */
>>> +#define GPIO_RPMSG_SETUP     0
>>> +#define GPIO_RPMSG_REPLY     1
>>> +#define GPIO_RPMSG_NOTIFY    2
>>> +
>>> +/* GPIO Interrupt trigger type */
>>> +#define GPIO_RPMSG_TRI_IGNORE                0
>>> +#define GPIO_RPMSG_TRI_RISING                1
>>> +#define GPIO_RPMSG_TRI_FALLING               2
>>> +#define GPIO_RPMSG_TRI_BOTH_EDGE     3
>>> +#define GPIO_RPMSG_TRI_LOW_LEVEL     4
>>> +#define GPIO_RPMSG_TRI_HIGH_LEVEL    5
>>> +
>>> +/* GPIO RPMSG commands */
>>> +#define GPIO_RPMSG_INPUT_INIT                0
>>> +#define GPIO_RPMSG_OUTPUT_INIT               1
>>> +#define GPIO_RPMSG_INPUT_GET         2
>>> +#define GPIO_RPMSG_DIRECTION_GET     3
>>> +
>>> +#define MAX_PORT_PER_CHANNEL    10
>>> +
>>> +/*
>>> + * @rproc_name: the name of the remote proc.
>>> + * @channel_devices: an array of the devices related to the rpdev.
>>> + */
>>> +struct rpdev_drvdata {
>>> +     const char *rproc_name;
>>> +     void *channel_devices[MAX_PORT_PER_CHANNEL];
>>> +};
>>> +
>>> +struct gpio_rpmsg_head {
>>
>> Sometime the prefix is gpio_rpmsg, sometime rpmsg_gpio or just gpio, could you
>> use "rpmsg_gpio" prefix in the whole driver?
>>
> 
> All the types use prefix gpio_rpmsg. All the functions use rpmsg_gpio.
> 
>>> +     u8 id;          /* Message ID Code */
>>> +     u8 vendor;      /* Vendor ID number */
>>
>> Does this fields above are mandatory, seems that it is just some constant values
>> that are useless.
>>
>>> +     u8 version;     /* Vendor-specific version number */
>>
>> Why it is vendor specific? the version should represent the rpmsg-tty protocol
>> version.
>>
>>> +     u8 type;        /* Message type */
>>> +     u8 cmd;         /* Command code */
>>> +     u8 reserved[5];
>>
>> What is the purpose of this reserved field?
>>
>>> +} __packed;
>>> +
>>> +struct gpio_rpmsg_packet {
>>> +     struct gpio_rpmsg_head header;
>>> +     u8 pin_idx;
>>> +     u8 port_idx;
>>> +     union {
>>> +             u8 event;
>>> +             u8 retcode;
>>> +             u8 value;
>>> +     } out;
>>> +     union {
>>> +             u8 wakeup;
>>> +             u8 value;
>>> +     } in;
>>> +} __packed __aligned(8);
>>
>> Any reason to use __packed and alignement here?
>> This structure will be copied in a vring buffer right?
>>
> 
> Using __packed together with an explicit alignment is a common pattern for defining
> communication packets. The goal is to ensure a stable and predictable layout across
> different architectures and compilers. Even though this structure is copied into a vring
> buffer, enforcing the layout avoids potential ABI or padding differences that could lead
> to compatibility issues when the data is parsed on the other side.
> 

Please could you give a concrete example for this rpmsg, I can not see a 
situation where adding padding at the end of the RPMsg is usefull?


>>> +
>>> +struct gpio_rpmsg_pin {
>>> +     u8 irq_shutdown;
>>> +     u8 irq_unmask;
>>> +     u8 irq_mask;
>>> +     u32 irq_wake_enable;
>>> +     u32 irq_type;
>>> +     struct gpio_rpmsg_packet msg;
>>> +};
>>> +
>>> +struct gpio_rpmsg_info {
>>> +     struct rpmsg_device *rpdev;
>>> +     struct gpio_rpmsg_packet *reply_msg;
>>> +     struct completion cmd_complete;
>>> +     struct mutex lock;
>>> +     void **port_store;
>>> +};
>>> +
>>> +struct rpmsg_gpio_port {
>>> +     struct gpio_chip gc;
>>> +     struct gpio_rpmsg_pin gpio_pins[GPIOS_PER_PORT_DEFAULT];
>>> +     struct gpio_rpmsg_info info;
>>> +     u32 ngpios;
>>> +     u32 idx;
>>> +};
>>> +
>>> +static int gpio_send_message(struct rpmsg_gpio_port *port,
>>
>> s/gpio_send_message/rpmsg_gpio_send_message
>>
>>> +                          struct gpio_rpmsg_packet *msg,
>>> +                          bool sync)
>>> +{
>>> +     struct gpio_rpmsg_info *info = &port->info;
>>> +     int err;
>>> +
>>> +     reinit_completion(&info->cmd_complete);
>>> +     err = rpmsg_send(info->rpdev->ept, msg, sizeof(struct gpio_rpmsg_packet));
>>> +     if (err) {
>>> +             dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
>>> +             return err;
>>> +     }
>>> +
>>> +     if (sync) {
>>> +             err = wait_for_completion_timeout(&info->cmd_complete,
>>> +                                               msecs_to_jiffies(RPMSG_TIMEOUT));
>>> +             if (err == 0) {
>>> +                     dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
>>> +                     return -ETIMEDOUT;
>>
>> strange condition you return an error if err == 0, for redability use 'ret' variable or
>> simply:
>>
> 
> Agree. Changing to "ret" is clearer here.
> 
>>                  if(!wait_for_completion_timeout(&info->cmd_complete,
>>                                    msecs_to_jiffies(RPMSG_TIMEOUT)) {
>>                          dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
>>                          return -ETIMEDOUT;
>>                  }
>>
>>> +
>>> +             if (info->reply_msg->out.retcode != 0) {
>>> +                     dev_err(&info->rpdev->dev, "remote core replies an error: %d!\n",
>>> +                             info->reply_msg->out.retcode);
>>> +                     return -EINVAL;
>>> +             }
>>> +
>>> +             /* copy the reply message */
>>> +             memcpy(&port->gpio_pins[info->reply_msg->pin_idx].msg,
>>> +                    info->reply_msg, sizeof(*info->reply_msg));
>>> +     }
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +static struct gpio_rpmsg_packet *gpio_setup_msg_common(struct
>> rpmsg_gpio_port *port,
>>> +                                                    unsigned int offset,
>>> +                                                    u8 cmd) {
>>> +     struct gpio_rpmsg_packet *msg = &port->gpio_pins[offset].msg;
>>> +
>>> +     memset(msg, 0, sizeof(struct gpio_rpmsg_packet));
>>> +     msg->header.id = RPMSG_GPIO_ID;
>>> +     msg->header.vendor = RPMSG_VENDOR;
>>> +     msg->header.version = RPMSG_VERSION;
>>> +     msg->header.type = GPIO_RPMSG_SETUP;
>>> +     msg->header.cmd = cmd;
>>> +     msg->pin_idx = offset;
>>> +     msg->port_idx = port->idx;
>>> +
>>> +     return msg;
>>> +}
>>> +
>>> +static int rpmsg_gpio_get(struct gpio_chip *gc, unsigned int gpio) {
>>> +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
>>> +     struct gpio_rpmsg_packet *msg;
>>> +     int ret;
>>> +
>>> +     guard(mutex)(&port->info.lock);
>>> +
>>> +     msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_INPUT_GET);
>>> +
>>> +     ret = gpio_send_message(port, msg, true);
>>> +     if (!ret)
>>> +             ret = !!port->gpio_pins[gpio].msg.in.value;
>>> +
>>> +     return ret;
>>> +}
>>> +
>>> +static int rpmsg_gpio_get_direction(struct gpio_chip *gc, unsigned
>>> +int gpio) {
>>> +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
>>> +     struct gpio_rpmsg_packet *msg;
>>> +     int ret;
>>> +
>>> +     guard(mutex)(&port->info.lock);
>>> +
>>> +     msg = gpio_setup_msg_common(port, gpio,
>>> + GPIO_RPMSG_DIRECTION_GET);
>>> +
>>> +     ret = gpio_send_message(port, msg, true);
>>> +     if (!ret)
>>> +             ret = !!port->gpio_pins[gpio].msg.in.value;
>>> +
>>> +     return ret;
>>> +}
>>> +
>>> +static int rpmsg_gpio_direction_input(struct gpio_chip *gc, unsigned
>>> +int gpio) {
>>> +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
>>> +     struct gpio_rpmsg_packet *msg;
>>> +
>>> +     guard(mutex)(&port->info.lock);
>>> +
>>> +     msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_INPUT_INIT);
>>> +
>>> +     return gpio_send_message(port, msg, true); }
>>> +
>>> +static int rpmsg_gpio_set(struct gpio_chip *gc, unsigned int gpio,
>>> +int val) {
>>> +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
>>> +     struct gpio_rpmsg_packet *msg;
>>> +
>>> +     guard(mutex)(&port->info.lock);
>>> +
>>> +     msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_OUTPUT_INIT);
>>> +     msg->out.value = val;
>>> +
>>> +     return gpio_send_message(port, msg, true); }
>>> +
>>> +static int rpmsg_gpio_direction_output(struct gpio_chip *gc,
>>> +                                    unsigned int gpio,
>>> +                                    int val) {
>>> +     return rpmsg_gpio_set(gc, gpio, val); }
>>> +
>>> +static int gpio_rpmsg_irq_set_type(struct irq_data *d, u32 type) {
>>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
>>> +     u32 gpio_idx = d->hwirq;
>>> +     int edge = 0;
>>> +     int ret = 0;
>>> +
>>> +     switch (type) {
>>> +     case IRQ_TYPE_EDGE_RISING:
>>> +             edge = GPIO_RPMSG_TRI_RISING;
>>> +             irq_set_handler_locked(d, handle_simple_irq);
>>> +             break;
>>> +     case IRQ_TYPE_EDGE_FALLING:
>>> +             edge = GPIO_RPMSG_TRI_FALLING;
>>> +             irq_set_handler_locked(d, handle_simple_irq);
>>> +             break;
>>> +     case IRQ_TYPE_EDGE_BOTH:
>>> +             edge = GPIO_RPMSG_TRI_BOTH_EDGE;
>>> +             irq_set_handler_locked(d, handle_simple_irq);
>>> +             break;
>>> +     case IRQ_TYPE_LEVEL_LOW:
>>> +             edge = GPIO_RPMSG_TRI_LOW_LEVEL;
>>> +             irq_set_handler_locked(d, handle_level_irq);
>>> +             break;
>>> +     case IRQ_TYPE_LEVEL_HIGH:
>>> +             edge = GPIO_RPMSG_TRI_HIGH_LEVEL;
>>> +             irq_set_handler_locked(d, handle_level_irq);
>>> +             break;
>>> +     default:
>>> +             ret = -EINVAL;
>>> +             irq_set_handler_locked(d, handle_bad_irq);
>>> +             break;
>>> +     }
>>> +
>>> +     port->gpio_pins[gpio_idx].irq_type = edge;
>>> +
>>> +     return ret;
>>> +}
>>> +
>>> +static int gpio_rpmsg_irq_set_wake(struct irq_data *d, u32 enable) {
>>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
>>> +     u32 gpio_idx = d->hwirq;
>>> +
>>> +     port->gpio_pins[gpio_idx].irq_wake_enable = enable;
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +/*
>>> + * This unmask/mask function is invoked in two situations:
>>> + *   - when an interrupt is being set up, and
>>> + *   - after an interrupt has occurred.
>>> + *
>>> + * The GPIO driver does not access hardware registers directly.
>>> + * Instead, it caches all relevant information locally, and then
>>> +sends
>>> + * the accumulated state to the remote system at this stage.
>>> + */
>>> +static void gpio_rpmsg_unmask_irq(struct irq_data *d) {
>>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
>>> +     u32 gpio_idx = d->hwirq;
>>> +
>>> +     port->gpio_pins[gpio_idx].irq_unmask = 1; }
>>> +
>>> +static void gpio_rpmsg_mask_irq(struct irq_data *d) {
>>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
>>> +     u32 gpio_idx = d->hwirq;
>>> +
>>> +     /*
>>> +      * When an interrupt occurs, the remote system masks the interrupt
>>> +      * and then sends a notification to Linux. After Linux processes
>>> +      * that notification, it sends an RPMsg command back to the remote
>>> +      * system to unmask the interrupt again.
>>> +      */
>>> +     port->gpio_pins[gpio_idx].irq_mask = 1; }
>>> +
>>> +static void gpio_rpmsg_irq_shutdown(struct irq_data *d) {
>>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
>>> +     u32 gpio_idx = d->hwirq;
>>> +
>>> +     port->gpio_pins[gpio_idx].irq_shutdown = 1; }
>>> +
>>> +static void gpio_rpmsg_irq_bus_lock(struct irq_data *d) {
>>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
>>> +
>>> +     mutex_lock(&port->info.lock);
>>> +}
>>> +
>>> +static void gpio_rpmsg_irq_bus_sync_unlock(struct irq_data *d) {
>>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
>>> +     struct gpio_rpmsg_packet *msg = NULL;
>>> +     u32 gpio_idx = d->hwirq;
>>> +
>>> +     /*
>>> +      * For mask irq, do nothing here.
>>> +      * The remote system will mask interrupt after an interrupt occurs,
>>> +      * and then send a notify to Linux system.
>>> +      * After Linux system dealt with the notify, it will send an rpmsg to
>>> +      * the remote system to unmask this interrupt again.
>>> +      */
>>> +     if (port->gpio_pins[gpio_idx].irq_mask && !port-
>>> gpio_pins[gpio_idx].irq_unmask) {
>>> +             port->gpio_pins[gpio_idx].irq_mask = 0;
>>> +             mutex_unlock(&port->info.lock);
>>> +             return;
>>> +     }
>>> +
>>> +     msg = gpio_setup_msg_common(port, gpio_idx,
>>> + GPIO_RPMSG_INPUT_INIT);
>>> +
>>> +     if (port->gpio_pins[gpio_idx].irq_shutdown) {
>>> +             msg->out.event = GPIO_RPMSG_TRI_IGNORE;
>>> +             msg->in.wakeup = 0;
>>> +             port->gpio_pins[gpio_idx].irq_shutdown = 0;
>>> +     } else {
>>> +             /* if not set irq type, then use low level as trigger type */
>>> +             msg->out.event = port->gpio_pins[gpio_idx].irq_type;
>>> +             if (!msg->out.event)
>>> +                     msg->out.event = GPIO_RPMSG_TRI_LOW_LEVEL;
>>> +             if (port->gpio_pins[gpio_idx].irq_unmask) {
>>> +                     msg->in.wakeup = 0;
>>> +                     port->gpio_pins[gpio_idx].irq_unmask = 0;
>>> +             } else /* irq set wake */
>>> +                     msg->in.wakeup = port->gpio_pins[gpio_idx].irq_wake_enable;
>>> +     }
>>> +
>>> +     gpio_send_message(port, msg, false);
>>> +     mutex_unlock(&port->info.lock);
>>> +}
>>> +
>>> +static const struct irq_chip gpio_rpmsg_irq_chip = {
>>> +     .irq_mask = gpio_rpmsg_mask_irq,
>>> +     .irq_unmask = gpio_rpmsg_unmask_irq,
>>> +     .irq_set_wake = gpio_rpmsg_irq_set_wake,
>>> +     .irq_set_type = gpio_rpmsg_irq_set_type,
>>> +     .irq_shutdown = gpio_rpmsg_irq_shutdown,
>>> +     .irq_bus_lock = gpio_rpmsg_irq_bus_lock,
>>> +     .irq_bus_sync_unlock = gpio_rpmsg_irq_bus_sync_unlock,
>>> +     .flags = IRQCHIP_IMMUTABLE,
>>> +};
>>> +
>>> +static void rpmsg_gpio_remove_action(void *data) {
>>> +     struct rpmsg_gpio_port *port = data;
>>> +
>>> +     port->info.port_store[port->idx] = NULL; }
>>> +
>>> +static int rpmsg_gpiochip_register(struct rpmsg_device *rpdev, struct
>>> +device_node *np) {
>>> +     struct rpdev_drvdata *drvdata = dev_get_drvdata(&rpdev->dev);
>>> +     struct rpmsg_gpio_port *port;
>>> +     struct gpio_irq_chip *girq;
>>> +     struct gpio_chip *gc;
>>> +     int ret;
>>> +
>>> +     port = devm_kzalloc(&rpdev->dev, sizeof(*port), GFP_KERNEL);
>>> +     if (!port)
>>> +             return -ENOMEM;
>>> +
>>> +     ret = of_property_read_u32(np, "reg", &port->idx);
>>> +     if (ret)
>>> +             return ret;
>>> +
>>> +     if (port->idx >= MAX_PORT_PER_CHANNEL)
>>> +             return -EINVAL;
>>> +
>>> +     ret = devm_mutex_init(&rpdev->dev, &port->info.lock);
>>> +     if (ret)
>>> +             return ret;
>>> +
>>> +     ret = of_property_read_u32(np, "ngpios", &port->ngpios);
>>> +     if (ret)
>>> +             port->ngpios = GPIOS_PER_PORT_DEFAULT;
>>> +
>>> +     init_completion(&port->info.cmd_complete);
>>> +     port->info.reply_msg = devm_kzalloc(&rpdev->dev,
>>> +                                         sizeof(struct gpio_rpmsg_packet),
>>> +                                         GFP_KERNEL);
>>> +     port->info.port_store = drvdata->channel_devices;
>>> +     port->info.port_store[port->idx] = port;
>>> +     port->info.rpdev = rpdev;
>>> +
>>> +     gc = &port->gc;
>>> +     gc->owner = THIS_MODULE;
>>> +     gc->parent = &rpdev->dev;
>>> +     gc->fwnode = of_fwnode_handle(np);
>>> +     gc->ngpio = port->ngpios;
>>> +     gc->base = -1;
>>> +     gc->label = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-gpio%d",
>>> +                                drvdata->rproc_name, port->idx);
>>> +
>>> +     gc->direction_input = rpmsg_gpio_direction_input;
>>> +     gc->direction_output = rpmsg_gpio_direction_output;
>>> +     gc->get_direction = rpmsg_gpio_get_direction;
>>> +     gc->get = rpmsg_gpio_get;
>>> +     gc->set = rpmsg_gpio_set;
>>> +
>>> +     girq = &gc->irq;
>>> +     gpio_irq_chip_set_chip(girq, &gpio_rpmsg_irq_chip);
>>> +     girq->parent_handler = NULL;
>>> +     girq->num_parents = 0;
>>> +     girq->parents = NULL;
>>> +     girq->chip->name = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-
>> gpio%d",
>>> +                                       drvdata->rproc_name,
>>> + port->idx);
>>> +
>>> +     ret = devm_add_action_or_reset(&rpdev->dev,
>> rpmsg_gpio_remove_action, port);
>>> +     if (ret)
>>> +             return ret;
>>> +
>>> +     return devm_gpiochip_add_data(&rpdev->dev, gc, port); }
>>> +
>>> +static const char *rpmsg_get_rproc_node_name(struct rpmsg_device
>>> +*rpdev) {
>>> +     const char *name = NULL;
>>> +     struct device_node *np;
>>> +     struct rproc *rproc;
>>> +
>>> +     rproc = rproc_get_by_child(&rpdev->dev);
>>> +
>>> +     if (!rproc)
>>> +             return NULL;
>>> +
>>> +     np = of_node_get(rproc->dev.of_node);
>>> +     if (!np && rproc->dev.parent)
>>> +             np = of_node_get(rproc->dev.parent->of_node);
>>> +
>>> +     if (np) {
>>> +             name = devm_kstrdup(&rpdev->dev, np->name, GFP_KERNEL);
>>> +             of_node_put(np);
>>> +     }
>>
>> What about simply returning rproc->name?
>>
> 
> rproc->name doesn’t serve the purpose here. It only reflects the remoteproc driver’s name,
> not the identity of a specific remoteproc instance. What we need is a unique and meaningful
> identifier for this particular instance, and using the DT node name provides exactly that.

It should, rproc->name is used for find the 
/dev/remoteproc/remoteproc<X> instance

Regards,
Arnaud

> 
> Thanks,
> Shenwei
> 
>>> +
>>> +     return name;
>>> +}
>>> +
>>> +static struct device_node *
>>> +rpmsg_get_channel_ofnode(struct rpmsg_device *rpdev, char *chan_name)
>>> +{
>>> +     struct device_node *np_chan = NULL, *np;
>>> +     struct rproc *rproc;
>>> +
>>> +     rproc = rproc_get_by_child(&rpdev->dev);
>>> +     if (!rproc)
>>> +             return NULL;
>>> +
>>> +     np = of_node_get(rproc->dev.of_node);
>>> +     if (!np && rproc->dev.parent)
>>> +             np = of_node_get(rproc->dev.parent->of_node);
>>
>> Is a topology where they is no rproc->dev node but a parent node exist?
>>
>>> +
>>> +     if (np) {
>>> +             /* Balance the of_node_put() performed by of_find_node_by_name().
>> */
>>> +             of_node_get(np);
>>> +             np_chan = of_find_node_by_name(np, chan_name);
>>> +             of_node_put(np);
>>> +     }
>>> +
>>> +     return np_chan;
>>> +}
>>> +
>>> +static int
>>> +rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void *data,
>>> +                         int len, void *priv, u32 src) {
>>> +     struct gpio_rpmsg_packet *msg = data;
>>> +     struct rpmsg_gpio_port *port = NULL;
>>> +     struct rpdev_drvdata *drvdata;
>>> +
>>> +     drvdata = dev_get_drvdata(&rpdev->dev);
>>> +     if (drvdata && msg && msg->port_idx < MAX_PORT_PER_CHANNEL)
>>> +             port = drvdata->channel_devices[msg->port_idx];
>>> +
>>> +     if (!port)
>>> +             return -ENODEV;
>>> +
>>> +     if (msg->header.type == GPIO_RPMSG_REPLY) {
>>> +             *port->info.reply_msg = *msg;
>>> +             complete(&port->info.cmd_complete);
>>
>> What happen if the remoteprocessor answer after the completion timeout?
>> Could it result in desynchronization between the request and the answer?
>>
>> Having a cmd_counter in gpio_rpmsg_head could help to identify current request
>> and answer
>>
>> the use of reinit_completion could be also needed
>>
>>> +     } else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
>>> +             generic_handle_domain_irq_safe(port->gc.irq.domain, msg->pin_idx);
>>> +     } else
>>> +             dev_err(&rpdev->dev, "wrong command type!\n");
>>
>> Could you print the msg->header.type value to help for debug?
>>
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev) {
>>> +     struct device *dev = &rpdev->dev;
>>> +     struct rpdev_drvdata *drvdata;
>>> +     struct device_node *np;
>>> +     int ret;
>>> +
>>> +     if (!dev->of_node) {
>>> +             np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
>>> +             if (np) {
>>> +                     dev->of_node = np;
>>> +                     set_primary_fwnode(dev, of_fwnode_handle(np));
>>> +             }
>>> +             return -EPROBE_DEFER;
>>> +     }
>>> +
>>> +     drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
>>> +     if (!drvdata)
>>> +             return -ENOMEM;
>>> +
>>> +     drvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);
>>> +     dev_set_drvdata(dev, drvdata);
>>> +
>>> +     for_each_child_of_node_scoped(dev->of_node, child) {
>>> +             if (!of_device_is_available(child))
>>> +                     continue;
>>> +
>>> +             if (!of_match_node(dev->driver->of_match_table, child))
>>> +                     continue;
>>> +
>>> +             ret = rpmsg_gpiochip_register(rpdev, child);
>>> +             if (ret < 0)
>>> +                     dev_err(dev, "Failed to register: %pOF\n", child);
>>> +     }
>>> +
>>> +     return 0;
>>
>> return ret
>> or indicate why the return of rpmsg_gpiochip_register is not taken into account
>>
>>
>>> +}
>>> +
>>> +static void rpmsg_gpio_channel_remove(struct rpmsg_device *rpdev) {
>>> +     dev_info(&rpdev->dev, "rpmsg gpio channel driver is removed\n");
>>> +}
>>> +
>>> +static const struct of_device_id rpmsg_gpio_dt_ids[] = {
>>> +     { .compatible = "rpmsg-gpio" },
>>> +     { /* sentinel */ }
>>> +};
>>> +
>>> +static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {
>>> +     { .name = "rpmsg-io-channel" },
>>
>> I would remove the "-channel" suffix to have similar naming than "rpmsg-tty" and
>> "rpmsg-raw"
>>
>> Regards,
>> Arnaud
>>
>>> +     { },
>>> +};
>>> +MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);
>>> +
>>> +static struct rpmsg_driver rpmsg_gpio_channel_client = {
>>> +     .drv.name       = KBUILD_MODNAME,
>>> +     .drv.of_match_table = rpmsg_gpio_dt_ids,
>>> +     .id_table       = rpmsg_gpio_channel_id_table,
>>> +     .probe          = rpmsg_gpio_channel_probe,
>>> +     .callback       = rpmsg_gpio_channel_callback,
>>> +     .remove         = rpmsg_gpio_channel_remove,
>>> +};
>>> +module_rpmsg_driver(rpmsg_gpio_channel_client);
>>> +
>>> +MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>");
>>> +MODULE_DESCRIPTION("generic rpmsg gpio driver");
>>> +MODULE_LICENSE("GPL");
> 



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19 13:42     ` Andrew Lunn
@ 2026-02-20  9:16       ` Arnaud POULIQUEN
  2026-02-20 13:48         ` Andrew Lunn
  0 siblings, 1 reply; 69+ messages in thread
From: Arnaud POULIQUEN @ 2026-02-20  9:16 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Shenwei Wang, Linus Walleij, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer, Shuah Khan, linux-gpio,
	linux-doc, linux-kernel, Pengutronix Kernel Team, Fabio Estevam,
	Peng Fan, devicetree, linux-remoteproc, imx, linux-arm-kernel,
	linux-imx, Bartosz Golaszewski



On 2/19/26 14:42, Andrew Lunn wrote:
>>> +	u8 id;		/* Message ID Code */
>>> +	u8 vendor;	/* Vendor ID number */
>>
>> Does this fields above are mandatory, seems that it is just some constant
>> values that are useless.
>>
>>> +	u8 version;	/* Vendor-specific version number */
>>
>> Why it is vendor specific? the version should represent the rpmsg-tty
>> protocol version.
>>
>>> +	u8 type;	/* Message type */
>>> +	u8 cmd;		/* Command code */
>>> +	u8 reserved[5];
>>
>> What is the purpose of this reserved field?
> 
> They have an implementation of the other end running on there systems,
> and it sounds like it is widely deployed, and they are trying to keep
> backwards compatibility. The protocol also implements more than
> GPIO. There is also I2C, maybe watchdog, i don't remember, but early
> versions of this patchset had a list. Some of these fields are used
> for some of these other devices.
> 
> I've been arguing it should be a clean design, with the protocol
> focusing on GPIO. And that the rpmsg channel makes it clear this is a
> GPIO device, the protocol itself does not need to include fields to
> differentiate between GPIO, I2C etc.
> 
> When they start submitting I2C over rpmsg, i expect the same sort of
> discussion will start again, so the likelihood of keeping backwards
> compatible with there firmware seems low to me.

Agree with you.

Thanks,
Arnaud

> 
> 	   Andrew



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform
  2026-02-12 21:36 [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform Shenwei Wang
                   ` (3 preceding siblings ...)
  2026-02-12 21:36 ` [PATCH v8 4/4] arm64: dts: imx8ulp: Add rpmsg node under imx_rproc Shenwei Wang
@ 2026-02-20  9:18 ` Daniel Baluta
  2026-02-20 15:24   ` Shenwei Wang
  4 siblings, 1 reply; 69+ messages in thread
From: Daniel Baluta @ 2026-02-20  9:18 UTC (permalink / raw)
  To: Shenwei Wang, Linus Walleij, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio, linux-doc, linux-kernel,
	Pengutronix Kernel Team, Fabio Estevam, Peng Fan, devicetree,
	linux-remoteproc, imx, linux-arm-kernel, linux-imx,
	arnaud.pouliquen

On 2/12/26 23:36, Shenwei Wang wrote:
> mments.
>  - update the yaml doc per Rob's feedback
>
> Shenwei Wang (4):
>   docs: driver-api: gpio: rpmsg gpio driver over rpmsg bus
>   dt-bindings: remoteproc: imx_rproc: Add "rpmsg" subnode support
>   gpio: rpmsg: add generic rpmsg GPIO driver
>   arm64: dts: imx8ulp: Add rpmsg node under imx_rproc
>

Shenwei, do you have a full example on how to test this? Including remote firmware part.


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-19 21:13     ` Shenwei Wang
@ 2026-02-20  9:32       ` Arnaud POULIQUEN
  2026-02-20 15:12         ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Arnaud POULIQUEN @ 2026-02-20  9:32 UTC (permalink / raw)
  To: Shenwei Wang, Linus Walleij, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski, Andrew Lunn



On 2/19/26 22:13, Shenwei Wang wrote:
> 
> 
>> -----Original Message-----
>> From: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
>> Sent: Thursday, February 19, 2026 3:21 AM
>> To: Shenwei Wang <shenwei.wang@nxp.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
>> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
>> Cc: 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>; Andrew Lunn <andrew@lunn.ch>
>> Subject: [EXT] Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
>>> +     rproc = rproc_get_by_child(&rpdev->dev);
>>> +     if (!rproc)
>>> +             return NULL;
>>> +
>>> +     np = of_node_get(rproc->dev.of_node);
>>> +     if (!np && rproc->dev.parent)
>>> +             np = of_node_get(rproc->dev.parent->of_node);
>>
>> Is a topology where they is no rproc->dev node but a parent node exist?
>>
> 
> If no rproc->dev, it should return NULL in the above check.

Regarding rproc_alloc, seems that rproc->dev.of_node is always NULL.
so probably test on it is useless.

> 
>>> +
>>> +     if (np) {
>>> +             /* Balance the of_node_put() performed by of_find_node_by_name().
>> */
>>> +             of_node_get(np);
>>> +             np_chan = of_find_node_by_name(np, chan_name);
>>> +             of_node_put(np);
>>> +     }
>>> +
>>> +     return np_chan;
>>> +}
>>> +
>>> +static int
>>> +rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void *data,
>>> +                         int len, void *priv, u32 src) {
>>> +     struct gpio_rpmsg_packet *msg = data;
>>> +     struct rpmsg_gpio_port *port = NULL;
>>> +     struct rpdev_drvdata *drvdata;
>>> +
>>> +     drvdata = dev_get_drvdata(&rpdev->dev);
>>> +     if (drvdata && msg && msg->port_idx < MAX_PORT_PER_CHANNEL)
>>> +             port = drvdata->channel_devices[msg->port_idx];
>>> +
>>> +     if (!port)
>>> +             return -ENODEV;
>>> +
>>> +     if (msg->header.type == GPIO_RPMSG_REPLY) {
>>> +             *port->info.reply_msg = *msg;
>>> +             complete(&port->info.cmd_complete);
>>
>> What happen if the remoteprocessor answer after the completion timeout?
>> Could it result in desynchronization between the request and the answer?
> 
> If the remote processor responds after the timeout, that late reply will be ignored. The current
> transfer should fail with TIMEOUT, and the state won’t be carried over because cmd_complete
> is reinitialized before each new request, so a stale completion won’t desynchronize the next
> transaction. Each command–reply cycle is isolated, so a delayed reply cannot corrupt or mix with
> a subsequent request.

I missed the reinit_completion. Indeed, that prevents issue if reply 
arrive after the time out.

That said a second request can be sent before the remote processor 
responds to the first one:
- resquest 1 sent to remoteprocessor.
- timeout occurs
- request 2 sent to remote processor
- reply of request 1 received

Wouldn't this lead to a desynchronization between requests and replies? 
I do not see a mechanism that would prevent this

> 
>>
>> Having a cmd_counter in gpio_rpmsg_head could help to identify current request
>> and answer
>>
>> the use of reinit_completion could be also needed
>>
>>> +     } else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
>>> +             generic_handle_domain_irq_safe(port->gc.irq.domain, msg->pin_idx);
>>> +     } else
>>> +             dev_err(&rpdev->dev, "wrong command type!\n");
>>
>> Could you print the msg->header.type value to help for debug?
>>
> 
> Sure. Will add it in next version.
> 
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev) {
>>> +     struct device *dev = &rpdev->dev;
>>> +     struct rpdev_drvdata *drvdata;
>>> +     struct device_node *np;
>>> +     int ret;
>>> +
>>> +     if (!dev->of_node) {
>>> +             np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
>>> +             if (np) {
>>> +                     dev->of_node = np;
>>> +                     set_primary_fwnode(dev, of_fwnode_handle(np));
>>> +             }
>>> +             return -EPROBE_DEFER;
>>> +     }
>>> +
>>> +     drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
>>> +     if (!drvdata)
>>> +             return -ENOMEM;
>>> +
>>> +     drvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);
>>> +     dev_set_drvdata(dev, drvdata);
>>> +
>>> +     for_each_child_of_node_scoped(dev->of_node, child) {
>>> +             if (!of_device_is_available(child))
>>> +                     continue;
>>> +
>>> +             if (!of_match_node(dev->driver->of_match_table, child))
>>> +                     continue;
>>> +
>>> +             ret = rpmsg_gpiochip_register(rpdev, child);
>>> +             if (ret < 0)
>>> +                     dev_err(dev, "Failed to register: %pOF\n", child);
>>> +     }
>>> +
>>> +     return 0;
>>
>> return ret
>> or indicate why the return of rpmsg_gpiochip_register is not taken into account
>>
> 
> rpmsg_gpiochip_register() failing only affects whether the GPIO instance gets created. The
> rpmsg channel driver itself can still probe successfully and continue to operate for other features.

This is not safe, by default you have to exist with error if something 
fails, ensuring that all resources allocated during the probe are released.
If there is a strong reason to not do this you have to explain the 
exception in a comment.

> 
>>
>>> +}
>>> +
>>> +static void rpmsg_gpio_channel_remove(struct rpmsg_device *rpdev) {
>>> +     dev_info(&rpdev->dev, "rpmsg gpio channel driver is removed\n");
>>> +}
>>> +
>>> +static const struct of_device_id rpmsg_gpio_dt_ids[] = {
>>> +     { .compatible = "rpmsg-gpio" },
>>> +     { /* sentinel */ }
>>> +};
>>> +
>>> +static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {
>>> +     { .name = "rpmsg-io-channel" },
>>
>> I would remove the "-channel" suffix to have similar naming than "rpmsg-tty" and
>> "rpmsg-raw"
>>
> 
> The channel name comes from the remote firmware, so we can’t freely rename it on the
> Linux side. On i.MX platforms the firmware follows its own naming conventions, and the *-channel
> suffix is part of that scheme.

As Andrew mentioned, in other words, you cannot expect to impose 
upstream constraints based on your downstream legacy. Your legacy 
firmware will continue to be supported by your legacy NXP rpmsg GPIO driver.

Moreover, changing the name of this rpmsg channel will help you have 
both drivers coexist in your downstream kernel.

Regards
Arnaud


> 
> Thanks,
> Shenwei
> 
>> Regards,
>> Arnaud
>>
>>> +     { },
>>> +};
>>> +MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);
>>> +
>>> +static struct rpmsg_driver rpmsg_gpio_channel_client = {
>>> +     .drv.name       = KBUILD_MODNAME,
>>> +     .drv.of_match_table = rpmsg_gpio_dt_ids,
>>> +     .id_table       = rpmsg_gpio_channel_id_table,
>>> +     .probe          = rpmsg_gpio_channel_probe,
>>> +     .callback       = rpmsg_gpio_channel_callback,
>>> +     .remove         = rpmsg_gpio_channel_remove,
>>> +};
>>> +module_rpmsg_driver(rpmsg_gpio_channel_client);
>>> +
>>> +MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>");
>>> +MODULE_DESCRIPTION("generic rpmsg gpio driver");
>>> +MODULE_LICENSE("GPL");
> 



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20  9:16       ` Arnaud POULIQUEN
@ 2026-02-20 13:48         ` Andrew Lunn
  2026-02-20 16:36           ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-20 13:48 UTC (permalink / raw)
  To: Arnaud POULIQUEN
  Cc: Shenwei Wang, Linus Walleij, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer, Shuah Khan, linux-gpio,
	linux-doc, linux-kernel, Pengutronix Kernel Team, Fabio Estevam,
	Peng Fan, devicetree, linux-remoteproc, imx, linux-arm-kernel,
	linux-imx, Bartosz Golaszewski

On Fri, Feb 20, 2026 at 10:16:42AM +0100, Arnaud POULIQUEN wrote:
> 
> 
> On 2/19/26 14:42, Andrew Lunn wrote:
> > > > +	u8 id;		/* Message ID Code */
> > > > +	u8 vendor;	/* Vendor ID number */
> > > 
> > > Does this fields above are mandatory, seems that it is just some constant
> > > values that are useless.
> > > 
> > > > +	u8 version;	/* Vendor-specific version number */
> > > 
> > > Why it is vendor specific? the version should represent the rpmsg-tty
> > > protocol version.
> > > 
> > > > +	u8 type;	/* Message type */
> > > > +	u8 cmd;		/* Command code */
> > > > +	u8 reserved[5];
> > > 
> > > What is the purpose of this reserved field?
> > 
> > They have an implementation of the other end running on there systems,
> > and it sounds like it is widely deployed, and they are trying to keep
> > backwards compatibility. The protocol also implements more than
> > GPIO. There is also I2C, maybe watchdog, i don't remember, but early
> > versions of this patchset had a list. Some of these fields are used
> > for some of these other devices.
> > 
> > I've been arguing it should be a clean design, with the protocol
> > focusing on GPIO. And that the rpmsg channel makes it clear this is a
> > GPIO device, the protocol itself does not need to include fields to
> > differentiate between GPIO, I2C etc.
> > 
> > When they start submitting I2C over rpmsg, i expect the same sort of
> > discussion will start again, so the likelihood of keeping backwards
> > compatible with there firmware seems low to me.
> 
> Agree with you.

Hi Shenwei

We now have two Maintainers who think you should make a clean
design...

You should go talk with your Management and decide what they want to
do. Drop this patch series and only support the out of tree driver? Or
rework this driver and the firmware to the liking of the mainline
Maintainers.

	Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20  9:32       ` Arnaud POULIQUEN
@ 2026-02-20 15:12         ` Shenwei Wang
  0 siblings, 0 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-20 15:12 UTC (permalink / raw)
  To: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski, Andrew Lunn



> -----Original Message-----
> From: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> Sent: Friday, February 20, 2026 3:33 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
> Cc: 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>; Andrew Lunn <andrew@lunn.ch>
> Subject: [EXT] Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> >> Subject: [EXT] Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO
> >> driver
> >>> +     rproc = rproc_get_by_child(&rpdev->dev);
> >>> +     if (!rproc)
> >>> +             return NULL;
> >>> +
> >>> +     np = of_node_get(rproc->dev.of_node);
> >>> +     if (!np && rproc->dev.parent)
> >>> +             np = of_node_get(rproc->dev.parent->of_node);
> >>
> >> Is a topology where they is no rproc->dev node but a parent node exist?
> >>
> >
> > If no rproc->dev, it should return NULL in the above check.
> 
> Regarding rproc_alloc, seems that rproc->dev.of_node is always NULL.
> so probably test on it is useless.
> 

Even if rproc->dev.of_node happens to be NULL in current rproc_alloc() usage, the logic here is
written to handle both cases correctly. It’s safer not to rely on that assumption, since making 
decisions based on an expected NULL value could break if the allocation path changes in the future. 
Keeping the check avoids this unnecessary constraint.

> >
> >>> +
> >>> +     if (np) {
> >>> +             /* Balance the of_node_put() performed by
> of_find_node_by_name().
> >> */
> >>> +             of_node_get(np);
> >>> +             np_chan = of_find_node_by_name(np, chan_name);
> >>> +             of_node_put(np);
> >>> +     }
> >>> +
> >>> +     return np_chan;
> >>> +}
> >>> +
> >>> +static int
> >>> +rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void *data,
> >>> +                         int len, void *priv, u32 src) {
> >>> +     struct gpio_rpmsg_packet *msg = data;
> >>> +     struct rpmsg_gpio_port *port = NULL;
> >>> +     struct rpdev_drvdata *drvdata;
> >>> +
> >>> +     drvdata = dev_get_drvdata(&rpdev->dev);
> >>> +     if (drvdata && msg && msg->port_idx < MAX_PORT_PER_CHANNEL)
> >>> +             port = drvdata->channel_devices[msg->port_idx];
> >>> +
> >>> +     if (!port)
> >>> +             return -ENODEV;
> >>> +
> >>> +     if (msg->header.type == GPIO_RPMSG_REPLY) {
> >>> +             *port->info.reply_msg = *msg;
> >>> +             complete(&port->info.cmd_complete);
> >>
> >> What happen if the remoteprocessor answer after the completion timeout?
> >> Could it result in desynchronization between the request and the answer?
> >
> > If the remote processor responds after the timeout, that late reply
> > will be ignored. The current transfer should fail with TIMEOUT, and
> > the state won’t be carried over because cmd_complete is reinitialized
> > before each new request, so a stale completion won’t desynchronize the
> > next transaction. Each command–reply cycle is isolated, so a delayed reply
> cannot corrupt or mix with a subsequent request.
> 
> I missed the reinit_completion. Indeed, that prevents issue if reply arrive after
> the time out.
> 
> That said a second request can be sent before the remote processor responds to
> the first one:
> - resquest 1 sent to remoteprocessor.
> - timeout occurs
> - request 2 sent to remote processor
> - reply of request 1 received
> 
> Wouldn't this lead to a desynchronization between requests and replies?
> I do not see a mechanism that would prevent this
> 

There’s a lock in place that sequences the requests, so we won’t end up with two requests 
running in parallel. If request 1 hasn’t completed yet, request 2 won’t start.

> >
> >>
> >> Having a cmd_counter in gpio_rpmsg_head could help to identify
> >> current request and answer
> >>
> >> the use of reinit_completion could be also needed
> >>
> >>> +     } else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
> >>> +             generic_handle_domain_irq_safe(port->gc.irq.domain, msg-
> >pin_idx);
> >>> +     } else
> >>> +             dev_err(&rpdev->dev, "wrong command type!\n");
> >>
> >> Could you print the msg->header.type value to help for debug?
> >>
> >
> > Sure. Will add it in next version.
> >
> >>> +
> >>> +     return 0;
> >>> +}
> >>> +
> >>> +static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev) {
> >>> +     struct device *dev = &rpdev->dev;
> >>> +     struct rpdev_drvdata *drvdata;
> >>> +     struct device_node *np;
> >>> +     int ret;
> >>> +
> >>> +     if (!dev->of_node) {
> >>> +             np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
> >>> +             if (np) {
> >>> +                     dev->of_node = np;
> >>> +                     set_primary_fwnode(dev, of_fwnode_handle(np));
> >>> +             }
> >>> +             return -EPROBE_DEFER;
> >>> +     }
> >>> +
> >>> +     drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> >>> +     if (!drvdata)
> >>> +             return -ENOMEM;
> >>> +
> >>> +     drvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);
> >>> +     dev_set_drvdata(dev, drvdata);
> >>> +
> >>> +     for_each_child_of_node_scoped(dev->of_node, child) {
> >>> +             if (!of_device_is_available(child))
> >>> +                     continue;
> >>> +
> >>> +             if (!of_match_node(dev->driver->of_match_table, child))
> >>> +                     continue;
> >>> +
> >>> +             ret = rpmsg_gpiochip_register(rpdev, child);
> >>> +             if (ret < 0)
> >>> +                     dev_err(dev, "Failed to register: %pOF\n", child);
> >>> +     }
> >>> +
> >>> +     return 0;
> >>
> >> return ret
> >> or indicate why the return of rpmsg_gpiochip_register is not taken
> >> into account
> >>
> >
> > rpmsg_gpiochip_register() failing only affects whether the GPIO
> > instance gets created. The rpmsg channel driver itself can still probe
> successfully and continue to operate for other features.
> 
> This is not safe, by default you have to exist with error if something fails, ensuring
> that all resources allocated during the probe are released.
> If there is a strong reason to not do this you have to explain the exception in a
> comment.
> 

I wouldn’t say it is not safe. The behavior here really depends on the policy we want for this 
driver: either fail fast (one failure causes the entire probe to fail) or best‑effort (continue even 
if some parts fail). Both approaches can be valid as long as the logic is consistent.

> >
> >>
> >>> +}
> >>> +
> >>> +static void rpmsg_gpio_channel_remove(struct rpmsg_device *rpdev) {
> >>> +     dev_info(&rpdev->dev, "rpmsg gpio channel driver is
> >>> +removed\n"); }
> >>> +
> >>> +static const struct of_device_id rpmsg_gpio_dt_ids[] = {
> >>> +     { .compatible = "rpmsg-gpio" },
> >>> +     { /* sentinel */ }
> >>> +};
> >>> +
> >>> +static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {
> >>> +     { .name = "rpmsg-io-channel" },
> >>
> >> I would remove the "-channel" suffix to have similar naming than
> >> "rpmsg-tty" and "rpmsg-raw"
> >>
> >
> > The channel name comes from the remote firmware, so we can’t freely
> > rename it on the Linux side. On i.MX platforms the firmware follows
> > its own naming conventions, and the *-channel suffix is part of that scheme.
> 
> As Andrew mentioned, in other words, you cannot expect to impose upstream
> constraints based on your downstream legacy. Your legacy firmware will
> continue to be supported by your legacy NXP rpmsg GPIO driver.
> 
> Moreover, changing the name of this rpmsg channel will help you have both
> drivers coexist in your downstream kernel.
> 

The id_table can support multiple channel names, so we don’t have to choose only one. 
Our driver depends on the company’s IP, which has been widely deployed by our customers, 
so we still need to keep supporting the existing channel name used on i.MX platforms.

At the same time, we can add the suggested "rpmsg-io" entry to the table so the driver works for 
both the generic use case and i.MX platforms.

Thanks,
Shenwei

> Regards
> Arnaud
> 
> 
> >
> > Thanks,
> > Shenwei
> >
> >> Regards,
> >> Arnaud
> >>
> >>> +     { },
> >>> +};
> >>> +MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);
> >>> +
> >>> +static struct rpmsg_driver rpmsg_gpio_channel_client = {
> >>> +     .drv.name       = KBUILD_MODNAME,
> >>> +     .drv.of_match_table = rpmsg_gpio_dt_ids,
> >>> +     .id_table       = rpmsg_gpio_channel_id_table,
> >>> +     .probe          = rpmsg_gpio_channel_probe,
> >>> +     .callback       = rpmsg_gpio_channel_callback,
> >>> +     .remove         = rpmsg_gpio_channel_remove,
> >>> +};
> >>> +module_rpmsg_driver(rpmsg_gpio_channel_client);
> >>> +
> >>> +MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>");
> >>> +MODULE_DESCRIPTION("generic rpmsg gpio driver");
> >>> +MODULE_LICENSE("GPL");
> >


^ permalink raw reply	[flat|nested] 69+ messages in thread

* RE: [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform
  2026-02-20  9:18 ` [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform Daniel Baluta
@ 2026-02-20 15:24   ` Shenwei Wang
  0 siblings, 0 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-20 15:24 UTC (permalink / raw)
  To: Daniel Baluta (OSS), Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	arnaud.pouliquen@foss.st.com



> -----Original Message-----
> From: Daniel Baluta (OSS) <daniel.baluta@oss.nxp.com>
> Sent: Friday, February 20, 2026 3:18 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
> Cc: 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>;
> arnaud.pouliquen@foss.st.com
> Subject: Re: [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform
> 
> On 2/12/26 23:36, Shenwei Wang wrote:
> > mments.
> >  - update the yaml doc per Rob's feedback
> >
> > Shenwei Wang (4):
> >   docs: driver-api: gpio: rpmsg gpio driver over rpmsg bus
> >   dt-bindings: remoteproc: imx_rproc: Add "rpmsg" subnode support
> >   gpio: rpmsg: add generic rpmsg GPIO driver
> >   arm64: dts: imx8ulp: Add rpmsg node under imx_rproc
> >
> 
> Shenwei, do you have a full example on how to test this? Including remote
> firmware part.

It can be tested on a i.MX8ULP EVK board by disabling the downstream version of rpmsg gpio driver.

Thanks,
Shenwei

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20  9:12       ` Arnaud POULIQUEN
@ 2026-02-20 15:47         ` Shenwei Wang
  2026-02-20 16:19           ` Andrew Lunn
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-20 15:47 UTC (permalink / raw)
  To: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer
  Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski, Andrew Lunn



> -----Original Message-----
> From: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> Sent: Friday, February 20, 2026 3:13 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
> Cc: 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>; Andrew Lunn <andrew@lunn.ch>
> Subject: [EXT] Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> >>> @@ -158,6 +158,7 @@ obj-$(CONFIG_GPIO_RDC321X)                += gpio-
> >> rdc321x.o
> >>>    obj-$(CONFIG_GPIO_REALTEK_OTTO)             += gpio-realtek-otto.o
> >>>    obj-$(CONFIG_GPIO_REG)                      += gpio-reg.o
> >>>    obj-$(CONFIG_GPIO_ROCKCHIP) += gpio-rockchip.o
> >>> +obj-$(CONFIG_GPIO_RPMSG)             += gpio-rpmsg.o
> >>>    obj-$(CONFIG_GPIO_RTD)                      += gpio-rtd.o
> >>>    obj-$(CONFIG_ARCH_SA1100)           += gpio-sa1100.o
> >>>    obj-$(CONFIG_GPIO_SAMA5D2_PIOBU)    += gpio-sama5d2-piobu.o
> >>> diff --git a/drivers/gpio/gpio-rpmsg.c b/drivers/gpio/gpio-rpmsg.c
> >>> new file mode 100644 index 000000000000..163f51fd45b5
> >>> --- /dev/null
> >>> +++ b/drivers/gpio/gpio-rpmsg.c
> >>> @@ -0,0 +1,588 @@
> >>> +// SPDX-License-Identifier: GPL-2.0-only
> >>> +/*
> >>> + * Copyright 2026 NXP
> >>> + *
> >>> + * The driver exports a standard gpiochip interface to control
> >>> + * the GPIO controllers via RPMSG on a remote processor.
> >>> + */
> >>> +#include <linux/completion.h>
> >>> +#include <linux/device.h>
> >>> +#include <linux/err.h>
> >>> +#include <linux/gpio/driver.h>
> >>> +#include <linux/init.h>
> >>> +#include <linux/irqdomain.h>
> >>> +#include <linux/mod_devicetable.h>
> >>> +#include <linux/module.h>
> >>> +#include <linux/mutex.h>
> >>> +#include <linux/of.h>
> >>> +#include <linux/of_device.h>
> >>> +#include <linux/of_platform.h>
> >>> +#include <linux/platform_device.h>
> >>> +#include <linux/remoteproc.h>
> >>> +#include <linux/rpmsg.h>
> >>> +
> >>> +#define RPMSG_GPIO_ID                5
> >>> +#define RPMSG_VENDOR         1
> >>> +#define RPMSG_VERSION                0
> >>> +
> >>> +#define GPIOS_PER_PORT_DEFAULT       32
> >>> +#define RPMSG_TIMEOUT                1000
> >>> +
> >>> +/* GPIO RPMSG header type */
> >>> +#define GPIO_RPMSG_SETUP     0
> >>> +#define GPIO_RPMSG_REPLY     1
> >>> +#define GPIO_RPMSG_NOTIFY    2
> >>> +
> >>> +/* GPIO Interrupt trigger type */
> >>> +#define GPIO_RPMSG_TRI_IGNORE                0
> >>> +#define GPIO_RPMSG_TRI_RISING                1
> >>> +#define GPIO_RPMSG_TRI_FALLING               2
> >>> +#define GPIO_RPMSG_TRI_BOTH_EDGE     3
> >>> +#define GPIO_RPMSG_TRI_LOW_LEVEL     4
> >>> +#define GPIO_RPMSG_TRI_HIGH_LEVEL    5
> >>> +
> >>> +/* GPIO RPMSG commands */
> >>> +#define GPIO_RPMSG_INPUT_INIT                0
> >>> +#define GPIO_RPMSG_OUTPUT_INIT               1
> >>> +#define GPIO_RPMSG_INPUT_GET         2
> >>> +#define GPIO_RPMSG_DIRECTION_GET     3
> >>> +
> >>> +#define MAX_PORT_PER_CHANNEL    10
> >>> +
> >>> +/*
> >>> + * @rproc_name: the name of the remote proc.
> >>> + * @channel_devices: an array of the devices related to the rpdev.
> >>> + */
> >>> +struct rpdev_drvdata {
> >>> +     const char *rproc_name;
> >>> +     void *channel_devices[MAX_PORT_PER_CHANNEL];
> >>> +};
> >>> +
> >>> +struct gpio_rpmsg_head {
> >>
> >> Sometime the prefix is gpio_rpmsg, sometime rpmsg_gpio or just gpio,
> >> could you use "rpmsg_gpio" prefix in the whole driver?
> >>
> >
> > All the types use prefix gpio_rpmsg. All the functions use rpmsg_gpio.
> >
> >>> +     u8 id;          /* Message ID Code */
> >>> +     u8 vendor;      /* Vendor ID number */
> >>
> >> Does this fields above are mandatory, seems that it is just some
> >> constant values that are useless.
> >>
> >>> +     u8 version;     /* Vendor-specific version number */
> >>
> >> Why it is vendor specific? the version should represent the rpmsg-tty
> >> protocol version.
> >>
> >>> +     u8 type;        /* Message type */
> >>> +     u8 cmd;         /* Command code */
> >>> +     u8 reserved[5];
> >>
> >> What is the purpose of this reserved field?
> >>
> >>> +} __packed;
> >>> +
> >>> +struct gpio_rpmsg_packet {
> >>> +     struct gpio_rpmsg_head header;
> >>> +     u8 pin_idx;
> >>> +     u8 port_idx;
> >>> +     union {
> >>> +             u8 event;
> >>> +             u8 retcode;
> >>> +             u8 value;
> >>> +     } out;
> >>> +     union {
> >>> +             u8 wakeup;
> >>> +             u8 value;
> >>> +     } in;
> >>> +} __packed __aligned(8);
> >>
> >> Any reason to use __packed and alignement here?
> >> This structure will be copied in a vring buffer right?
> >>
> >
> > Using __packed together with an explicit alignment is a common pattern
> > for defining communication packets. The goal is to ensure a stable and
> > predictable layout across different architectures and compilers. Even
> > though this structure is copied into a vring buffer, enforcing the
> > layout avoids potential ABI or padding differences that could lead to
> compatibility issues when the data is parsed on the other side.
> >
> 
> Please could you give a concrete example for this rpmsg, I can not see a situation
> where adding padding at the end of the RPMsg is usefull?
> 

I asked the AI to provide the following examples.

Example: 32‑bit ARM vs 64‑bit ARM (AArch32 vs AArch64)
Consider this message header:
struct msg_hdr {    
    u8  id;
    u32 size;
    u8  flags;
};

What happens without __packed:

On AArch32 (ARMv7), u32 is 4‑byte aligned, but the compiler may insert 1 byte of padding between id and size, 
and then 3 bytes of padding between flags and the end of the struct, making the layout:

Byte offsets (AArch32):
0: id
1-3: padding
4-7: size
8: flags
9-11: padding   <-- trailing padding may be added
struct size = 12 bytes


On AArch64, compilers may choose a different padding strategy (e.g., using 8‑byte alignment rules), resulting in:

Byte offsets (AArch64):
0: id
1-7: padding    <-- larger padding may appear
8-11: size
12: flags
13-15: padding
struct size = 16 bytes

Compiler‑specific example (GCC vs Clang)
GCC and Clang historically differed in how they align mixed‑type fields on ARM:
struct example {
    u8 a;
    u16 b;
    u32 c;
};

Without __packed:

GCC on ARM might place:

1 byte padding after a
align b at offset 2
align c at offset 4

Clang on ARM for the same structure may use:

1 byte padding after a
2 bytes padding after b
align c at offset 4 (same), but produce different total size.

This difference alone is enough to corrupt RPMsg payload interpretation if one side expects offsets computed by GCC and the other compiled with Clang.

Thanks,
Shenwei

> 
> >>> +
> >>> +struct gpio_rpmsg_pin {
> >>> +     u8 irq_shutdown;
> >>> +     u8 irq_unmask;
> >>> +     u8 irq_mask;
> >>> +     u32 irq_wake_enable;
> >>> +     u32 irq_type;
> >>> +     struct gpio_rpmsg_packet msg;
> >>> +};
> >>> +
> >>> +struct gpio_rpmsg_info {
> >>> +     struct rpmsg_device *rpdev;
> >>> +     struct gpio_rpmsg_packet *reply_msg;
> >>> +     struct completion cmd_complete;
> >>> +     struct mutex lock;
> >>> +     void **port_store;
> >>> +};
> >>> +
> >>> +struct rpmsg_gpio_port {
> >>> +     struct gpio_chip gc;
> >>> +     struct gpio_rpmsg_pin gpio_pins[GPIOS_PER_PORT_DEFAULT];
> >>> +     struct gpio_rpmsg_info info;
> >>> +     u32 ngpios;
> >>> +     u32 idx;
> >>> +};
> >>> +
> >>> +static int gpio_send_message(struct rpmsg_gpio_port *port,
> >>
> >> s/gpio_send_message/rpmsg_gpio_send_message
> >>
> >>> +                          struct gpio_rpmsg_packet *msg,
> >>> +                          bool sync) {
> >>> +     struct gpio_rpmsg_info *info = &port->info;
> >>> +     int err;
> >>> +
> >>> +     reinit_completion(&info->cmd_complete);
> >>> +     err = rpmsg_send(info->rpdev->ept, msg, sizeof(struct
> gpio_rpmsg_packet));
> >>> +     if (err) {
> >>> +             dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", err);
> >>> +             return err;
> >>> +     }
> >>> +
> >>> +     if (sync) {
> >>> +             err = wait_for_completion_timeout(&info->cmd_complete,
> >>> +                                               msecs_to_jiffies(RPMSG_TIMEOUT));
> >>> +             if (err == 0) {
> >>> +                     dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> >>> +                     return -ETIMEDOUT;
> >>
> >> strange condition you return an error if err == 0, for redability use
> >> 'ret' variable or
> >> simply:
> >>
> >
> > Agree. Changing to "ret" is clearer here.
> >
> >>                  if(!wait_for_completion_timeout(&info->cmd_complete,
> >>                                    msecs_to_jiffies(RPMSG_TIMEOUT)) {
> >>                          dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> >>                          return -ETIMEDOUT;
> >>                  }
> >>
> >>> +
> >>> +             if (info->reply_msg->out.retcode != 0) {
> >>> +                     dev_err(&info->rpdev->dev, "remote core replies an
> error: %d!\n",
> >>> +                             info->reply_msg->out.retcode);
> >>> +                     return -EINVAL;
> >>> +             }
> >>> +
> >>> +             /* copy the reply message */
> >>> +             memcpy(&port->gpio_pins[info->reply_msg->pin_idx].msg,
> >>> +                    info->reply_msg, sizeof(*info->reply_msg));
> >>> +     }
> >>> +
> >>> +     return 0;
> >>> +}
> >>> +
> >>> +static struct gpio_rpmsg_packet *gpio_setup_msg_common(struct
> >> rpmsg_gpio_port *port,
> >>> +                                                    unsigned int offset,
> >>> +                                                    u8 cmd) {
> >>> +     struct gpio_rpmsg_packet *msg = &port->gpio_pins[offset].msg;
> >>> +
> >>> +     memset(msg, 0, sizeof(struct gpio_rpmsg_packet));
> >>> +     msg->header.id = RPMSG_GPIO_ID;
> >>> +     msg->header.vendor = RPMSG_VENDOR;
> >>> +     msg->header.version = RPMSG_VERSION;
> >>> +     msg->header.type = GPIO_RPMSG_SETUP;
> >>> +     msg->header.cmd = cmd;
> >>> +     msg->pin_idx = offset;
> >>> +     msg->port_idx = port->idx;
> >>> +
> >>> +     return msg;
> >>> +}
> >>> +
> >>> +static int rpmsg_gpio_get(struct gpio_chip *gc, unsigned int gpio) {
> >>> +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> >>> +     struct gpio_rpmsg_packet *msg;
> >>> +     int ret;
> >>> +
> >>> +     guard(mutex)(&port->info.lock);
> >>> +
> >>> +     msg = gpio_setup_msg_common(port, gpio, GPIO_RPMSG_INPUT_GET);
> >>> +
> >>> +     ret = gpio_send_message(port, msg, true);
> >>> +     if (!ret)
> >>> +             ret = !!port->gpio_pins[gpio].msg.in.value;
> >>> +
> >>> +     return ret;
> >>> +}
> >>> +
> >>> +static int rpmsg_gpio_get_direction(struct gpio_chip *gc, unsigned
> >>> +int gpio) {
> >>> +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> >>> +     struct gpio_rpmsg_packet *msg;
> >>> +     int ret;
> >>> +
> >>> +     guard(mutex)(&port->info.lock);
> >>> +
> >>> +     msg = gpio_setup_msg_common(port, gpio,
> >>> + GPIO_RPMSG_DIRECTION_GET);
> >>> +
> >>> +     ret = gpio_send_message(port, msg, true);
> >>> +     if (!ret)
> >>> +             ret = !!port->gpio_pins[gpio].msg.in.value;
> >>> +
> >>> +     return ret;
> >>> +}
> >>> +
> >>> +static int rpmsg_gpio_direction_input(struct gpio_chip *gc,
> >>> +unsigned int gpio) {
> >>> +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> >>> +     struct gpio_rpmsg_packet *msg;
> >>> +
> >>> +     guard(mutex)(&port->info.lock);
> >>> +
> >>> +     msg = gpio_setup_msg_common(port, gpio,
> >>> + GPIO_RPMSG_INPUT_INIT);
> >>> +
> >>> +     return gpio_send_message(port, msg, true); }
> >>> +
> >>> +static int rpmsg_gpio_set(struct gpio_chip *gc, unsigned int gpio,
> >>> +int val) {
> >>> +     struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> >>> +     struct gpio_rpmsg_packet *msg;
> >>> +
> >>> +     guard(mutex)(&port->info.lock);
> >>> +
> >>> +     msg = gpio_setup_msg_common(port, gpio,
> GPIO_RPMSG_OUTPUT_INIT);
> >>> +     msg->out.value = val;
> >>> +
> >>> +     return gpio_send_message(port, msg, true); }
> >>> +
> >>> +static int rpmsg_gpio_direction_output(struct gpio_chip *gc,
> >>> +                                    unsigned int gpio,
> >>> +                                    int val) {
> >>> +     return rpmsg_gpio_set(gc, gpio, val); }
> >>> +
> >>> +static int gpio_rpmsg_irq_set_type(struct irq_data *d, u32 type) {
> >>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> >>> +     u32 gpio_idx = d->hwirq;
> >>> +     int edge = 0;
> >>> +     int ret = 0;
> >>> +
> >>> +     switch (type) {
> >>> +     case IRQ_TYPE_EDGE_RISING:
> >>> +             edge = GPIO_RPMSG_TRI_RISING;
> >>> +             irq_set_handler_locked(d, handle_simple_irq);
> >>> +             break;
> >>> +     case IRQ_TYPE_EDGE_FALLING:
> >>> +             edge = GPIO_RPMSG_TRI_FALLING;
> >>> +             irq_set_handler_locked(d, handle_simple_irq);
> >>> +             break;
> >>> +     case IRQ_TYPE_EDGE_BOTH:
> >>> +             edge = GPIO_RPMSG_TRI_BOTH_EDGE;
> >>> +             irq_set_handler_locked(d, handle_simple_irq);
> >>> +             break;
> >>> +     case IRQ_TYPE_LEVEL_LOW:
> >>> +             edge = GPIO_RPMSG_TRI_LOW_LEVEL;
> >>> +             irq_set_handler_locked(d, handle_level_irq);
> >>> +             break;
> >>> +     case IRQ_TYPE_LEVEL_HIGH:
> >>> +             edge = GPIO_RPMSG_TRI_HIGH_LEVEL;
> >>> +             irq_set_handler_locked(d, handle_level_irq);
> >>> +             break;
> >>> +     default:
> >>> +             ret = -EINVAL;
> >>> +             irq_set_handler_locked(d, handle_bad_irq);
> >>> +             break;
> >>> +     }
> >>> +
> >>> +     port->gpio_pins[gpio_idx].irq_type = edge;
> >>> +
> >>> +     return ret;
> >>> +}
> >>> +
> >>> +static int gpio_rpmsg_irq_set_wake(struct irq_data *d, u32 enable) {
> >>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> >>> +     u32 gpio_idx = d->hwirq;
> >>> +
> >>> +     port->gpio_pins[gpio_idx].irq_wake_enable = enable;
> >>> +
> >>> +     return 0;
> >>> +}
> >>> +
> >>> +/*
> >>> + * This unmask/mask function is invoked in two situations:
> >>> + *   - when an interrupt is being set up, and
> >>> + *   - after an interrupt has occurred.
> >>> + *
> >>> + * The GPIO driver does not access hardware registers directly.
> >>> + * Instead, it caches all relevant information locally, and then
> >>> +sends
> >>> + * the accumulated state to the remote system at this stage.
> >>> + */
> >>> +static void gpio_rpmsg_unmask_irq(struct irq_data *d) {
> >>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> >>> +     u32 gpio_idx = d->hwirq;
> >>> +
> >>> +     port->gpio_pins[gpio_idx].irq_unmask = 1; }
> >>> +
> >>> +static void gpio_rpmsg_mask_irq(struct irq_data *d) {
> >>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> >>> +     u32 gpio_idx = d->hwirq;
> >>> +
> >>> +     /*
> >>> +      * When an interrupt occurs, the remote system masks the interrupt
> >>> +      * and then sends a notification to Linux. After Linux processes
> >>> +      * that notification, it sends an RPMsg command back to the remote
> >>> +      * system to unmask the interrupt again.
> >>> +      */
> >>> +     port->gpio_pins[gpio_idx].irq_mask = 1; }
> >>> +
> >>> +static void gpio_rpmsg_irq_shutdown(struct irq_data *d) {
> >>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> >>> +     u32 gpio_idx = d->hwirq;
> >>> +
> >>> +     port->gpio_pins[gpio_idx].irq_shutdown = 1; }
> >>> +
> >>> +static void gpio_rpmsg_irq_bus_lock(struct irq_data *d) {
> >>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> >>> +
> >>> +     mutex_lock(&port->info.lock);
> >>> +}
> >>> +
> >>> +static void gpio_rpmsg_irq_bus_sync_unlock(struct irq_data *d) {
> >>> +     struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> >>> +     struct gpio_rpmsg_packet *msg = NULL;
> >>> +     u32 gpio_idx = d->hwirq;
> >>> +
> >>> +     /*
> >>> +      * For mask irq, do nothing here.
> >>> +      * The remote system will mask interrupt after an interrupt occurs,
> >>> +      * and then send a notify to Linux system.
> >>> +      * After Linux system dealt with the notify, it will send an rpmsg to
> >>> +      * the remote system to unmask this interrupt again.
> >>> +      */
> >>> +     if (port->gpio_pins[gpio_idx].irq_mask && !port-
> >>> gpio_pins[gpio_idx].irq_unmask) {
> >>> +             port->gpio_pins[gpio_idx].irq_mask = 0;
> >>> +             mutex_unlock(&port->info.lock);
> >>> +             return;
> >>> +     }
> >>> +
> >>> +     msg = gpio_setup_msg_common(port, gpio_idx,
> >>> + GPIO_RPMSG_INPUT_INIT);
> >>> +
> >>> +     if (port->gpio_pins[gpio_idx].irq_shutdown) {
> >>> +             msg->out.event = GPIO_RPMSG_TRI_IGNORE;
> >>> +             msg->in.wakeup = 0;
> >>> +             port->gpio_pins[gpio_idx].irq_shutdown = 0;
> >>> +     } else {
> >>> +             /* if not set irq type, then use low level as trigger type */
> >>> +             msg->out.event = port->gpio_pins[gpio_idx].irq_type;
> >>> +             if (!msg->out.event)
> >>> +                     msg->out.event = GPIO_RPMSG_TRI_LOW_LEVEL;
> >>> +             if (port->gpio_pins[gpio_idx].irq_unmask) {
> >>> +                     msg->in.wakeup = 0;
> >>> +                     port->gpio_pins[gpio_idx].irq_unmask = 0;
> >>> +             } else /* irq set wake */
> >>> +                     msg->in.wakeup = port->gpio_pins[gpio_idx].irq_wake_enable;
> >>> +     }
> >>> +
> >>> +     gpio_send_message(port, msg, false);
> >>> +     mutex_unlock(&port->info.lock); }
> >>> +
> >>> +static const struct irq_chip gpio_rpmsg_irq_chip = {
> >>> +     .irq_mask = gpio_rpmsg_mask_irq,
> >>> +     .irq_unmask = gpio_rpmsg_unmask_irq,
> >>> +     .irq_set_wake = gpio_rpmsg_irq_set_wake,
> >>> +     .irq_set_type = gpio_rpmsg_irq_set_type,
> >>> +     .irq_shutdown = gpio_rpmsg_irq_shutdown,
> >>> +     .irq_bus_lock = gpio_rpmsg_irq_bus_lock,
> >>> +     .irq_bus_sync_unlock = gpio_rpmsg_irq_bus_sync_unlock,
> >>> +     .flags = IRQCHIP_IMMUTABLE,
> >>> +};
> >>> +
> >>> +static void rpmsg_gpio_remove_action(void *data) {
> >>> +     struct rpmsg_gpio_port *port = data;
> >>> +
> >>> +     port->info.port_store[port->idx] = NULL; }
> >>> +
> >>> +static int rpmsg_gpiochip_register(struct rpmsg_device *rpdev,
> >>> +struct device_node *np) {
> >>> +     struct rpdev_drvdata *drvdata = dev_get_drvdata(&rpdev->dev);
> >>> +     struct rpmsg_gpio_port *port;
> >>> +     struct gpio_irq_chip *girq;
> >>> +     struct gpio_chip *gc;
> >>> +     int ret;
> >>> +
> >>> +     port = devm_kzalloc(&rpdev->dev, sizeof(*port), GFP_KERNEL);
> >>> +     if (!port)
> >>> +             return -ENOMEM;
> >>> +
> >>> +     ret = of_property_read_u32(np, "reg", &port->idx);
> >>> +     if (ret)
> >>> +             return ret;
> >>> +
> >>> +     if (port->idx >= MAX_PORT_PER_CHANNEL)
> >>> +             return -EINVAL;
> >>> +
> >>> +     ret = devm_mutex_init(&rpdev->dev, &port->info.lock);
> >>> +     if (ret)
> >>> +             return ret;
> >>> +
> >>> +     ret = of_property_read_u32(np, "ngpios", &port->ngpios);
> >>> +     if (ret)
> >>> +             port->ngpios = GPIOS_PER_PORT_DEFAULT;
> >>> +
> >>> +     init_completion(&port->info.cmd_complete);
> >>> +     port->info.reply_msg = devm_kzalloc(&rpdev->dev,
> >>> +                                         sizeof(struct gpio_rpmsg_packet),
> >>> +                                         GFP_KERNEL);
> >>> +     port->info.port_store = drvdata->channel_devices;
> >>> +     port->info.port_store[port->idx] = port;
> >>> +     port->info.rpdev = rpdev;
> >>> +
> >>> +     gc = &port->gc;
> >>> +     gc->owner = THIS_MODULE;
> >>> +     gc->parent = &rpdev->dev;
> >>> +     gc->fwnode = of_fwnode_handle(np);
> >>> +     gc->ngpio = port->ngpios;
> >>> +     gc->base = -1;
> >>> +     gc->label = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-gpio%d",
> >>> +                                drvdata->rproc_name, port->idx);
> >>> +
> >>> +     gc->direction_input = rpmsg_gpio_direction_input;
> >>> +     gc->direction_output = rpmsg_gpio_direction_output;
> >>> +     gc->get_direction = rpmsg_gpio_get_direction;
> >>> +     gc->get = rpmsg_gpio_get;
> >>> +     gc->set = rpmsg_gpio_set;
> >>> +
> >>> +     girq = &gc->irq;
> >>> +     gpio_irq_chip_set_chip(girq, &gpio_rpmsg_irq_chip);
> >>> +     girq->parent_handler = NULL;
> >>> +     girq->num_parents = 0;
> >>> +     girq->parents = NULL;
> >>> +     girq->chip->name = devm_kasprintf(&rpdev->dev, GFP_KERNEL,
> >>> + "%s-
> >> gpio%d",
> >>> +                                       drvdata->rproc_name,
> >>> + port->idx);
> >>> +
> >>> +     ret = devm_add_action_or_reset(&rpdev->dev,
> >> rpmsg_gpio_remove_action, port);
> >>> +     if (ret)
> >>> +             return ret;
> >>> +
> >>> +     return devm_gpiochip_add_data(&rpdev->dev, gc, port); }
> >>> +
> >>> +static const char *rpmsg_get_rproc_node_name(struct rpmsg_device
> >>> +*rpdev) {
> >>> +     const char *name = NULL;
> >>> +     struct device_node *np;
> >>> +     struct rproc *rproc;
> >>> +
> >>> +     rproc = rproc_get_by_child(&rpdev->dev);
> >>> +
> >>> +     if (!rproc)
> >>> +             return NULL;
> >>> +
> >>> +     np = of_node_get(rproc->dev.of_node);
> >>> +     if (!np && rproc->dev.parent)
> >>> +             np = of_node_get(rproc->dev.parent->of_node);
> >>> +
> >>> +     if (np) {
> >>> +             name = devm_kstrdup(&rpdev->dev, np->name, GFP_KERNEL);
> >>> +             of_node_put(np);
> >>> +     }
> >>
> >> What about simply returning rproc->name?
> >>
> >
> > rproc->name doesn’t serve the purpose here. It only reflects the
> > rproc->remoteproc driver’s name,
> > not the identity of a specific remoteproc instance. What we need is a
> > unique and meaningful identifier for this particular instance, and using the DT
> node name provides exactly that.
> 
> It should, rproc->name is used for find the /dev/remoteproc/remoteproc<X>
> instance
> 
> Regards,
> Arnaud
> 
> >
> > Thanks,
> > Shenwei
> >
> >>> +
> >>> +     return name;
> >>> +}
> >>> +
> >>> +static struct device_node *
> >>> +rpmsg_get_channel_ofnode(struct rpmsg_device *rpdev, char
> >>> +*chan_name) {
> >>> +     struct device_node *np_chan = NULL, *np;
> >>> +     struct rproc *rproc;
> >>> +
> >>> +     rproc = rproc_get_by_child(&rpdev->dev);
> >>> +     if (!rproc)
> >>> +             return NULL;
> >>> +
> >>> +     np = of_node_get(rproc->dev.of_node);
> >>> +     if (!np && rproc->dev.parent)
> >>> +             np = of_node_get(rproc->dev.parent->of_node);
> >>
> >> Is a topology where they is no rproc->dev node but a parent node exist?
> >>
> >>> +
> >>> +     if (np) {
> >>> +             /* Balance the of_node_put() performed by
> of_find_node_by_name().
> >> */
> >>> +             of_node_get(np);
> >>> +             np_chan = of_find_node_by_name(np, chan_name);
> >>> +             of_node_put(np);
> >>> +     }
> >>> +
> >>> +     return np_chan;
> >>> +}
> >>> +
> >>> +static int
> >>> +rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void *data,
> >>> +                         int len, void *priv, u32 src) {
> >>> +     struct gpio_rpmsg_packet *msg = data;
> >>> +     struct rpmsg_gpio_port *port = NULL;
> >>> +     struct rpdev_drvdata *drvdata;
> >>> +
> >>> +     drvdata = dev_get_drvdata(&rpdev->dev);
> >>> +     if (drvdata && msg && msg->port_idx < MAX_PORT_PER_CHANNEL)
> >>> +             port = drvdata->channel_devices[msg->port_idx];
> >>> +
> >>> +     if (!port)
> >>> +             return -ENODEV;
> >>> +
> >>> +     if (msg->header.type == GPIO_RPMSG_REPLY) {
> >>> +             *port->info.reply_msg = *msg;
> >>> +             complete(&port->info.cmd_complete);
> >>
> >> What happen if the remoteprocessor answer after the completion timeout?
> >> Could it result in desynchronization between the request and the answer?
> >>
> >> Having a cmd_counter in gpio_rpmsg_head could help to identify
> >> current request and answer
> >>
> >> the use of reinit_completion could be also needed
> >>
> >>> +     } else if (msg->header.type == GPIO_RPMSG_NOTIFY) {
> >>> +             generic_handle_domain_irq_safe(port->gc.irq.domain, msg-
> >pin_idx);
> >>> +     } else
> >>> +             dev_err(&rpdev->dev, "wrong command type!\n");
> >>
> >> Could you print the msg->header.type value to help for debug?
> >>
> >>> +
> >>> +     return 0;
> >>> +}
> >>> +
> >>> +static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev) {
> >>> +     struct device *dev = &rpdev->dev;
> >>> +     struct rpdev_drvdata *drvdata;
> >>> +     struct device_node *np;
> >>> +     int ret;
> >>> +
> >>> +     if (!dev->of_node) {
> >>> +             np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
> >>> +             if (np) {
> >>> +                     dev->of_node = np;
> >>> +                     set_primary_fwnode(dev, of_fwnode_handle(np));
> >>> +             }
> >>> +             return -EPROBE_DEFER;
> >>> +     }
> >>> +
> >>> +     drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> >>> +     if (!drvdata)
> >>> +             return -ENOMEM;
> >>> +
> >>> +     drvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);
> >>> +     dev_set_drvdata(dev, drvdata);
> >>> +
> >>> +     for_each_child_of_node_scoped(dev->of_node, child) {
> >>> +             if (!of_device_is_available(child))
> >>> +                     continue;
> >>> +
> >>> +             if (!of_match_node(dev->driver->of_match_table, child))
> >>> +                     continue;
> >>> +
> >>> +             ret = rpmsg_gpiochip_register(rpdev, child);
> >>> +             if (ret < 0)
> >>> +                     dev_err(dev, "Failed to register: %pOF\n", child);
> >>> +     }
> >>> +
> >>> +     return 0;
> >>
> >> return ret
> >> or indicate why the return of rpmsg_gpiochip_register is not taken
> >> into account
> >>
> >>
> >>> +}
> >>> +
> >>> +static void rpmsg_gpio_channel_remove(struct rpmsg_device *rpdev) {
> >>> +     dev_info(&rpdev->dev, "rpmsg gpio channel driver is
> >>> +removed\n"); }
> >>> +
> >>> +static const struct of_device_id rpmsg_gpio_dt_ids[] = {
> >>> +     { .compatible = "rpmsg-gpio" },
> >>> +     { /* sentinel */ }
> >>> +};
> >>> +
> >>> +static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {
> >>> +     { .name = "rpmsg-io-channel" },
> >>
> >> I would remove the "-channel" suffix to have similar naming than
> >> "rpmsg-tty" and "rpmsg-raw"
> >>
> >> Regards,
> >> Arnaud
> >>
> >>> +     { },
> >>> +};
> >>> +MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);
> >>> +
> >>> +static struct rpmsg_driver rpmsg_gpio_channel_client = {
> >>> +     .drv.name       = KBUILD_MODNAME,
> >>> +     .drv.of_match_table = rpmsg_gpio_dt_ids,
> >>> +     .id_table       = rpmsg_gpio_channel_id_table,
> >>> +     .probe          = rpmsg_gpio_channel_probe,
> >>> +     .callback       = rpmsg_gpio_channel_callback,
> >>> +     .remove         = rpmsg_gpio_channel_remove,
> >>> +};
> >>> +module_rpmsg_driver(rpmsg_gpio_channel_client);
> >>> +
> >>> +MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>");
> >>> +MODULE_DESCRIPTION("generic rpmsg gpio driver");
> >>> +MODULE_LICENSE("GPL");
> >


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20 15:47         ` Shenwei Wang
@ 2026-02-20 16:19           ` Andrew Lunn
  2026-02-20 17:09             ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-20 16:19 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> Example: 32‑bit ARM vs 64‑bit ARM (AArch32 vs AArch64)
> Consider this message header:
> struct msg_hdr {    
>     u8  id;
>     u32 size;
>     u8  flags;
> };

That is just a bad design. The point of not allowing __packed is that
it forces you to design your structures correctly. Maybe AI has no
idea of taste, but Maintainer do and would not allow a u32 to be
unaligned like this.

   Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20 13:48         ` Andrew Lunn
@ 2026-02-20 16:36           ` Shenwei Wang
  2026-02-20 17:45             ` Andrew Lunn
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-20 16:36 UTC (permalink / raw)
  To: Andrew Lunn, Arnaud POULIQUEN
  Cc: Linus Walleij, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer, Shuah Khan,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Friday, February 20, 2026 7:49 AM
> To: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> Cc: Shenwei Wang <shenwei.wang@nxp.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> >
> > On 2/19/26 14:42, Andrew Lunn wrote:
> > > > > +       u8 id;          /* Message ID Code */
> > > > > +       u8 vendor;      /* Vendor ID number */
> > > >
> > > > Does this fields above are mandatory, seems that it is just some
> > > > constant values that are useless.
> > > >
> > > > > +       u8 version;     /* Vendor-specific version number */
> > > >
> > > > Why it is vendor specific? the version should represent the
> > > > rpmsg-tty protocol version.
> > > >
> > > > > +       u8 type;        /* Message type */
> > > > > +       u8 cmd;         /* Command code */
> > > > > +       u8 reserved[5];
> > > >
> > > > What is the purpose of this reserved field?
> > >
> > > They have an implementation of the other end running on there
> > > systems, and it sounds like it is widely deployed, and they are
> > > trying to keep backwards compatibility. The protocol also implements
> > > more than GPIO. There is also I2C, maybe watchdog, i don't remember,
> > > but early versions of this patchset had a list. Some of these fields
> > > are used for some of these other devices.
> > >
> > > I've been arguing it should be a clean design, with the protocol
> > > focusing on GPIO. And that the rpmsg channel makes it clear this is
> > > a GPIO device, the protocol itself does not need to include fields
> > > to differentiate between GPIO, I2C etc.
> > >
> > > When they start submitting I2C over rpmsg, i expect the same sort of
> > > discussion will start again, so the likelihood of keeping backwards
> > > compatible with there firmware seems low to me.
> >
> > Agree with you.
> 
> Hi Shenwei
> 
> We now have two Maintainers who think you should make a clean design...
> 
> You should go talk with your Management and decide what they want to do.
> Drop this patch series and only support the out of tree driver? Or rework this
> driver and the firmware to the liking of the mainline Maintainers.
> 

The driver is meant to support a specific piece of hardware, and its design follows the 
company’s existing IP, which is already widely deployed. While we're open to sharing 
the IP details with anyone who wants to adopt the technology, changing the IP itself 
isn’t the goal of this patch series.

From the driver perspective, the implementation is clean and generic, and it can support 
multiple hardware variants—even those based on other vendors’ IP—without requiring 
architectural changes. I think it would be more productive if the review focused on the 
driver’s implementation and integration into the subsystem, rather than asking to redesign 
or replace an existing, widely‑released IP block. The intention here is to upstream support 
for hardware/firmware that already exists, not to redefine it.

If there are concerns about specific design elements within the driver, I’m happy to address 
those, but redesigning the hardware/firmware interface is not something this series can solve.

Thanks,
Shenwei


>         Andrew

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20 16:19           ` Andrew Lunn
@ 2026-02-20 17:09             ` Shenwei Wang
  2026-02-20 17:42               ` Andrew Lunn
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-20 17:09 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Friday, February 20, 2026 10:19 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > Example: 32‑bit ARM vs 64‑bit ARM (AArch32 vs AArch64) Consider this
> > message header:
> > struct msg_hdr {
> >     u8  id;
> >     u32 size;
> >     u8  flags;
> > };
> 
> That is just a bad design. The point of not allowing __packed is that it forces you
> to design your structures correctly. Maybe AI has no idea of taste, but Maintainer
> do and would not allow a u32 to be unaligned like this.
> 

Let’s keep the discussion technical instead of taste. 😊

My point with the earlier example was simply to illustrate how layout differences can 
happen across architectures or compilers. I’m more interested in understanding how 
you would prefer this specific structure to be defined so that it avoids unaligned fields 
while still maintaining a stable on‑wire format.

For the rpmsg‑gpio driver specifically, I can drop the __packed annotation if that is the 
consensus, since the known configurations work without requiring it. 

Thanks,
Shenwei

>    Andrew

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20 17:09             ` Shenwei Wang
@ 2026-02-20 17:42               ` Andrew Lunn
  2026-02-20 19:09                 ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-20 17:42 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> > > struct msg_hdr {
> > >     u8  id;
> > >     u32 size;
> > >     u8  flags;
> > > };
> > 
> > That is just a bad design. The point of not allowing __packed is that it forces you
> > to design your structures correctly. Maybe AI has no idea of taste, but Maintainer
> > do and would not allow a u32 to be unaligned like this.
> > 
> 
> Let’s keep the discussion technical instead of taste. 😊
> 
> My point with the earlier example was simply to illustrate how layout differences can 
> happen across architectures or compilers. I’m more interested in understanding how 
> you would prefer this specific structure to be defined so that it avoids unaligned fields 
> while still maintaining a stable on‑wire format.

struct msg_hdr {
    u32 size;
    u8  id;
    u8  flags;
};

The compiler will lay this out as you expect, it won't add any padding
between the fields.

You need to be careful with sizeof(struct msg_hdr). On 8 and 16 bit
machines, it is probably 6. On 32, or 64 bit machine it is probably 8.

I would say having a 6 byte message is probably a bad design, and you
should try to make the u32 a u16 if you can. Again, not using the
__packed is making you think about the design, and probably makes the
design better as a result.

    Andrew



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20 16:36           ` Shenwei Wang
@ 2026-02-20 17:45             ` Andrew Lunn
  2026-02-20 18:57               ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-20 17:45 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> If there are concerns about specific design elements within the driver, I’m happy to address 
> those, but redesigning the hardware/firmware interface is not something this series can solve.

Then i think you are limited to using the out of tree driver.

Sorry.

	Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20 17:45             ` Andrew Lunn
@ 2026-02-20 18:57               ` Shenwei Wang
  2026-02-20 20:21                 ` Mathieu Poirier
                                   ` (2 more replies)
  0 siblings, 3 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-20 18:57 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Friday, February 20, 2026 11:45 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > If there are concerns about specific design elements within the
> > driver, I’m happy to address those, but redesigning the hardware/firmware
> interface is not something this series can solve.
> 
> Then i think you are limited to using the out of tree driver.
> 

Thanks for the feedback.

To clarify: is Linux moving toward supporting only fully open hardware platforms? I’m 
not aware of any rule that prevents a company from upstreaming a driver that implements 
support for an existing hardware/firmware interface.

Given that, I’d like to hear from the GPIO subsystem maintainers — @Linus Walleij and 
@Bartosz Golaszewski — on whether a driver that works with the current hardware/firmware 
design could still be acceptable for upstream inclusion. My understanding is that upstream 
generally supports existing, real-world hardware as long as the driver meets subsystem standards.

Regards,
Shenwei

> Sorry.
> 
>         Andrew

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20 17:42               ` Andrew Lunn
@ 2026-02-20 19:09                 ` Shenwei Wang
  2026-02-20 20:41                   ` Andrew Lunn
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-20 19:09 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Friday, February 20, 2026 11:42 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > > > struct msg_hdr {
> > > >     u8  id;
> > > >     u32 size;
> > > >     u8  flags;
> > > > };
> > >
> > > That is just a bad design. The point of not allowing __packed is
> > > that it forces you to design your structures correctly. Maybe AI has
> > > no idea of taste, but Maintainer do and would not allow a u32 to be unaligned
> like this.
> > >
> >
> > Let’s keep the discussion technical instead of taste. 😊
> >
> > My point with the earlier example was simply to illustrate how layout
> > differences can happen across architectures or compilers. I’m more
> > interested in understanding how you would prefer this specific
> > structure to be defined so that it avoids unaligned fields while still maintaining a
> stable on‑wire format.
> 
> struct msg_hdr {
>     u32 size;
>     u8  id;
>     u8  flags;
> };
> 
> The compiler will lay this out as you expect, it won't add any padding between
> the fields.
> 

Yes, most compilers will lay this out without inserting padding between the fields. 
However, for a communication packet, we cannot freely reorder or tweak members 
just to satisfy alignment rules—the field order itself becomes part of the protocol definition.

Even within netdev, where you’re very familiar, the classic ethhdr still carries the packed annotation 
despite being naturally aligned:

struct ethhdr {
	unsigned char	h_dest[ETH_ALEN];	/* destination eth addr	*/
	unsigned char	h_source[ETH_ALEN];	/* source ether addr	*/
	__be16		h_proto;		/* packet type ID field	*/
} __attribute__((packed));

Thanks,
Shenwei

> You need to be careful with sizeof(struct msg_hdr). On 8 and 16 bit machines, it is
> probably 6. On 32, or 64 bit machine it is probably 8.
> 
> I would say having a 6 byte message is probably a bad design, and you should try
> to make the u32 a u16 if you can. Again, not using the __packed is making you
> think about the design, and probably makes the design better as a result.
> 
>     Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20 18:57               ` Shenwei Wang
@ 2026-02-20 20:21                 ` Mathieu Poirier
  2026-02-20 20:59                 ` Andrew Lunn
  2026-02-22 14:48                 ` Linus Walleij
  2 siblings, 0 replies; 69+ messages in thread
From: Mathieu Poirier @ 2026-02-20 20:21 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Andrew Lunn, Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Frank Li, Sascha Hauer, Shuah Khan,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Fri, 20 Feb 2026 at 11:57, Shenwei Wang <shenwei.wang@nxp.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Andrew Lunn <andrew@lunn.ch>
> > Sent: Friday, February 20, 2026 11:45 AM
> > To: Shenwei Wang <shenwei.wang@nxp.com>
> > Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > > If there are concerns about specific design elements within the
> > > driver, I’m happy to address those, but redesigning the hardware/firmware
> > interface is not something this series can solve.
> >
> > Then i think you are limited to using the out of tree driver.
> >
>
> Thanks for the feedback.
>
> To clarify: is Linux moving toward supporting only fully open hardware platforms? I’m
> not aware of any rule that prevents a company from upstreaming a driver that implements
> support for an existing hardware/firmware interface.
>
> Given that, I’d like to hear from the GPIO subsystem maintainers — @Linus Walleij and
> @Bartosz Golaszewski — on whether a driver that works with the current hardware/firmware
> design could still be acceptable for upstream inclusion. My understanding is that upstream
> generally supports existing, real-world hardware as long as the driver meets subsystem standards.
>

The HW can't be changed but firmware can.  It is not realistic to
think upstream can accommodate all the quirks happening in downstream
trees - this approach simply doesn't scale.

As if I wasn't clear enough already (along with many others), the
current implementation will not be merged upstream for reasons that
have been amply discussed.  You either comply with the comments we
provided or use the existing out of tree driver.

> Regards,
> Shenwei
>
> > Sorry.
> >
> >         Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20 19:09                 ` Shenwei Wang
@ 2026-02-20 20:41                   ` Andrew Lunn
  0 siblings, 0 replies; 69+ messages in thread
From: Andrew Lunn @ 2026-02-20 20:41 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> Yes, most compilers will lay this out without inserting padding between the fields. 
> However, for a communication packet, we cannot freely reorder or tweak members 
> just to satisfy alignment rules—the field order itself becomes part of the protocol definition.

Notice i've been saying design. If the design is poor, the
implementation has to jump through hoops to make it work, which is
when __packed it useful, it allows you to implement a bad design.

> Even within netdev, where you’re very familiar, the classic ethhdr still carries the packed annotation 
> despite being naturally aligned:
> 
> struct ethhdr {
> 	unsigned char	h_dest[ETH_ALEN];	/* destination eth addr	*/
> 	unsigned char	h_source[ETH_ALEN];	/* source ether addr	*/
> 	__be16		h_proto;		/* packet type ID field	*/
> } __attribute__((packed));

And a lot of engineers will agree that this header is badly
designed. The network stack goes to a lot of trouble to ensure the
Ethernet header is placed into an skbuf with an offset of 2 bytes, so
the IP header is 4 byte aligned. This also makes the DMA engines more
complex, having to do an unaligned transfer at the start. More hoops
to jump though because of bad design.

None of the IP, UDP, TCP headers etc have packed, because they are all
well designed. The IETF did a better design job than IEEE.

       Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20 18:57               ` Shenwei Wang
  2026-02-20 20:21                 ` Mathieu Poirier
@ 2026-02-20 20:59                 ` Andrew Lunn
  2026-02-22 14:48                 ` Linus Walleij
  2 siblings, 0 replies; 69+ messages in thread
From: Andrew Lunn @ 2026-02-20 20:59 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> To clarify: is Linux moving toward supporting only fully open hardware platforms? I’m 
> not aware of any rule that prevents a company from upstreaming a driver that implements 
> support for an existing hardware/firmware interface.

You are not the first to be requested to implement a clean generic
interface which is vendor neutral for these sorts of peripherals, with
firmware on the other side. Look back in the archives, there was a USB
attached microcontroller offering GPIO, I2C, SPI, etc. In the end the
vendor decided to keep with there out of tree driver. But if it had
progressed, it might of been possible for you to implement that same
protocol over rpmsg, rather than USB. They are similar. And there is
also greybus, which is also a solution in this problem space.

	 Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-20 18:57               ` Shenwei Wang
  2026-02-20 20:21                 ` Mathieu Poirier
  2026-02-20 20:59                 ` Andrew Lunn
@ 2026-02-22 14:48                 ` Linus Walleij
  2026-02-23 14:24                   ` Arnaud POULIQUEN
  2 siblings, 1 reply; 69+ messages in thread
From: Linus Walleij @ 2026-02-22 14:48 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Andrew Lunn, Arnaud POULIQUEN, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Fri, Feb 20, 2026 at 7:57 PM Shenwei Wang <shenwei.wang@nxp.com> wrote:

> Given that, I’d like to hear from the GPIO subsystem maintainers — @Linus Walleij and
> @Bartosz Golaszewski — on whether a driver that works with the current hardware/firmware
> design could still be acceptable for upstream inclusion. My understanding is that upstream
> generally supports existing, real-world hardware as long as the driver meets subsystem standards.

What a swell party this has become.

In this kind of situations I usually refer to
Documentation/process/management-style.rst

What is the message I as a maintainer is getting from NXP regarding
"gpio: rpmsg: add generic rpmsg GPIO driver"?

Arnaud, who is the only person in this discussion who actually wrote
a standard RPMSG driver (drivers/tty/rpmsg_tty.c), must ACK this
patch if it wants to call itself a "generic" RPMSG GPIO driver, if he
does not, then it isn't.

Is it generic? If it is not, let's call it "NXP rpmsg GPIO driver" and rename
files etc accordingly. Maybe it can share code with the actual generic
RPMSG driver once that arrives, that is more of a library question.

Yours,
Linus Walleij


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-22 14:48                 ` Linus Walleij
@ 2026-02-23 14:24                   ` Arnaud POULIQUEN
  2026-02-23 14:42                     ` Bjorn Andersson
  2026-02-23 20:33                     ` Shenwei Wang
  0 siblings, 2 replies; 69+ messages in thread
From: Arnaud POULIQUEN @ 2026-02-23 14:24 UTC (permalink / raw)
  To: Linus Walleij, Shenwei Wang
  Cc: Andrew Lunn, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer, Shuah Khan,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

Hello Linus,

On 2/22/26 15:48, Linus Walleij wrote:
> On Fri, Feb 20, 2026 at 7:57 PM Shenwei Wang <shenwei.wang@nxp.com> wrote:
> 
>> Given that, I’d like to hear from the GPIO subsystem maintainers — @Linus Walleij and
>> @Bartosz Golaszewski — on whether a driver that works with the current hardware/firmware
>> design could still be acceptable for upstream inclusion. My understanding is that upstream
>> generally supports existing, real-world hardware as long as the driver meets subsystem standards.
> 
> What a swell party this has become.
> 
> In this kind of situations I usually refer to
> Documentation/process/management-style.rst
>

Thank you for pointing out the document, I was not aware of its 
existence. Very informative!
That help me to understand you proposal below.


> What is the message I as a maintainer is getting from NXP regarding
> "gpio: rpmsg: add generic rpmsg GPIO driver"?
> 
> Arnaud, who is the only person in this discussion who actually wrote
> a standard RPMSG driver (drivers/tty/rpmsg_tty.c), must ACK this
> patch if it wants to call itself a "generic" RPMSG GPIO driver, if he
> does not, then it isn't.

In Fact there are already 2 "generic" drivers, the second one it the 
drivers/rpmsg/rpmsg_char.c, both are used on several platforms.

It is in my plan to test the rpmsg-gpio on ST platform if we go with the 
generic approach.

> 
> Is it generic? If it is not, let's call it "NXP rpmsg GPIO driver" and rename
> files etc accordingly. Maybe it can share code with the actual generic
> RPMSG driver once that arrives, that is more of a library question.

I would like to (re)express my concerns regarding the creation of an 
NXP-specific driver. To clarify my concerns, ST, like probably some 
other SoC vendors, has rpmsg-gpio and rpmsg-i2c drivers in downstream 
with plans to upstream them.

If we proceed in this direction:

-Any vendor wishing to upstream an rpmsg-gpio driver might submit their 
own platform-specific version.

- If NXP upstreams other rpmsg drivers, these will likely remain 
NXP-centric to maintain compatibility with their legacy firmware and the 
nxp-rpmsg-gpio driver, leading to platform-specific versions in several 
frameworks.

- The implementation will impact not only the Linux side but also the 
remote side. Indeed, some operating systems like Zephyr or NuttX 
implement the rpmsg device side (Zephyr already implements the rpmsg-tty)

Maintaining a generic approach for RPMsg, similar to what is done for 
Virtio, seems to me a more reliable solution, even though it may induce 
some downstream costs (ST would also need to break compatibility with 
legacy ST remote proc firmware).


In the end, I am just trying to influence the direction for RPMsg, but 
based on the discussions in this thread, it seems others share similar 
expectations, which should probably be taken into account as well.

Thanks and Regards,
Arnaud


I just want to

> 
> Yours,
> Linus Walleij



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-23 14:24                   ` Arnaud POULIQUEN
@ 2026-02-23 14:42                     ` Bjorn Andersson
  2026-02-24 15:56                       ` Shenwei Wang
  2026-02-23 20:33                     ` Shenwei Wang
  1 sibling, 1 reply; 69+ messages in thread
From: Bjorn Andersson @ 2026-02-23 14:42 UTC (permalink / raw)
  To: Arnaud POULIQUEN
  Cc: Linus Walleij, Shenwei Wang, Andrew Lunn, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Mathieu Poirier, Frank Li, Sascha Hauer, Shuah Khan,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Mon, Feb 23, 2026 at 03:24:43PM +0100, Arnaud POULIQUEN wrote:
> On 2/22/26 15:48, Linus Walleij wrote:
> > On Fri, Feb 20, 2026 at 7:57 PM Shenwei Wang <shenwei.wang@nxp.com> wrote:
[..]
> > 
> > Is it generic? If it is not, let's call it "NXP rpmsg GPIO driver" and rename
> > files etc accordingly. Maybe it can share code with the actual generic
> > RPMSG driver once that arrives, that is more of a library question.
> 
> I would like to (re)express my concerns regarding the creation of an
> NXP-specific driver. To clarify my concerns, ST, like probably some other
> SoC vendors, has rpmsg-gpio and rpmsg-i2c drivers in downstream with plans
> to upstream them.
> 
> If we proceed in this direction:
> 
> -Any vendor wishing to upstream an rpmsg-gpio driver might submit their own
> platform-specific version.
> 
> - If NXP upstreams other rpmsg drivers, these will likely remain NXP-centric
> to maintain compatibility with their legacy firmware and the nxp-rpmsg-gpio
> driver, leading to platform-specific versions in several frameworks.
> 
> - The implementation will impact not only the Linux side but also the remote
> side. Indeed, some operating systems like Zephyr or NuttX implement the
> rpmsg device side (Zephyr already implements the rpmsg-tty)
> 
> Maintaining a generic approach for RPMsg, similar to what is done for
> Virtio, seems to me a more reliable solution, even though it may induce some
> downstream costs (ST would also need to break compatibility with legacy ST
> remote proc firmware).
> 

Could the virtio-based mechanism be used directly (without rpmsg)?


If not, it would be good to derive a generic rpmsg-gpio protocol from
the virtio protocol, and land implementations of this in e.g. Linux and
Zephyr to establish that option.

Regards,
Bjorn

> 
> In the end, I am just trying to influence the direction for RPMsg, but based
> on the discussions in this thread, it seems others share similar
> expectations, which should probably be taken into account as well.
> 
> Thanks and Regards,
> Arnaud
> 
> 
> I just want to
> 
> > 
> > Yours,
> > Linus Walleij
> 


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-23 14:24                   ` Arnaud POULIQUEN
  2026-02-23 14:42                     ` Bjorn Andersson
@ 2026-02-23 20:33                     ` Shenwei Wang
  2026-02-24  8:46                       ` Arnaud POULIQUEN
  2026-02-24  9:37                       ` Linus Walleij
  1 sibling, 2 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-23 20:33 UTC (permalink / raw)
  To: Arnaud POULIQUEN, Linus Walleij
  Cc: Andrew Lunn, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer, Shuah Khan,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> Sent: Monday, February 23, 2026 8:25 AM
> To: Linus Walleij <linusw@kernel.org>; Shenwei Wang
> <shenwei.wang@nxp.com>
> Cc: Andrew Lunn <andrew@lunn.ch>; 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>; Mathieu Poirier
> <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> Hello Linus,
> 
> On 2/22/26 15:48, Linus Walleij wrote:
> > On Fri, Feb 20, 2026 at 7:57 PM Shenwei Wang <shenwei.wang@nxp.com>
> wrote:
> >
> >> Given that, I’d like to hear from the GPIO subsystem maintainers —
> >> @Linus Walleij and @Bartosz Golaszewski — on whether a driver that
> >> works with the current hardware/firmware design could still be
> >> acceptable for upstream inclusion. My understanding is that upstream
> generally supports existing, real-world hardware as long as the driver meets
> subsystem standards.
> >
> > What a swell party this has become.
> >
> > In this kind of situations I usually refer to
> > Documentation/process/management-style.rst
> >
> 
> Thank you for pointing out the document, I was not aware of its existence. Very
> informative!
> That help me to understand you proposal below.
> 
> 
> > What is the message I as a maintainer is getting from NXP regarding
> > "gpio: rpmsg: add generic rpmsg GPIO driver"?
> >
> > Arnaud, who is the only person in this discussion who actually wrote a
> > standard RPMSG driver (drivers/tty/rpmsg_tty.c), must ACK this patch
> > if it wants to call itself a "generic" RPMSG GPIO driver, if he does
> > not, then it isn't.
> 
> In Fact there are already 2 "generic" drivers, the second one it the
> drivers/rpmsg/rpmsg_char.c, both are used on several platforms.
> 
> It is in my plan to test the rpmsg-gpio on ST platform if we go with the generic
> approach.
> 
> >
> > Is it generic? If it is not, let's call it "NXP rpmsg GPIO driver" and
> > rename files etc accordingly. Maybe it can share code with the actual
> > generic RPMSG driver once that arrives, that is more of a library question.
> 
> I would like to (re)express my concerns regarding the creation of an NXP-specific
> driver. To clarify my concerns, ST, like probably some other SoC vendors, has
> rpmsg-gpio and rpmsg-i2c drivers in downstream with plans to upstream them.
> 

Linus, thank you for jumping in and providing the guidance.

I would like to clarify one point here: what we are discussing now is not whether the 
driver itself is generic, but rather that the current protocol is not as perfect as Arnaud 
would expect, since it contains a few fields that may not be required on their platforms.

Arnaud, if you agree with the points above, my proposal is the following:
 - Remove the fields you mentioned in the protocol and update the driver accordingly so 
that we can establish a true baseline for a generic implementation we all agree.
 - Then prepare a separate patch to add support for existing NXP platforms by introducing 
the necessary fix‑up functions.

Please let me know if this approach works for you. My goal is to find a solution that works for 
everyone — even though I know that pleasing everyone is almost impossible.

Thanks,
Shenwei

> If we proceed in this direction:
> 
> -Any vendor wishing to upstream an rpmsg-gpio driver might submit their own
> platform-specific version.
> 
> - If NXP upstreams other rpmsg drivers, these will likely remain NXP-centric to
> maintain compatibility with their legacy firmware and the nxp-rpmsg-gpio driver,
> leading to platform-specific versions in several frameworks.
> 
> - The implementation will impact not only the Linux side but also the remote side.
> Indeed, some operating systems like Zephyr or NuttX implement the rpmsg device
> side (Zephyr already implements the rpmsg-tty)
> 
> Maintaining a generic approach for RPMsg, similar to what is done for Virtio,
> seems to me a more reliable solution, even though it may induce some
> downstream costs (ST would also need to break compatibility with legacy ST
> remote proc firmware).
> 
> 
> In the end, I am just trying to influence the direction for RPMsg, but based on the
> discussions in this thread, it seems others share similar expectations, which
> should probably be taken into account as well.
> 
> Thanks and Regards,
> Arnaud
> 
> 
> I just want to
> 
> >
> > Yours,
> > Linus Walleij


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-23 20:33                     ` Shenwei Wang
@ 2026-02-24  8:46                       ` Arnaud POULIQUEN
  2026-02-24 16:05                         ` Shenwei Wang
  2026-02-24  9:37                       ` Linus Walleij
  1 sibling, 1 reply; 69+ messages in thread
From: Arnaud POULIQUEN @ 2026-02-24  8:46 UTC (permalink / raw)
  To: Shenwei Wang, Linus Walleij
  Cc: Andrew Lunn, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer, Shuah Khan,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

Hello Shenwei

On 2/23/26 21:33, Shenwei Wang wrote:
> 
> 
>> -----Original Message-----
>> From: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
>> Sent: Monday, February 23, 2026 8:25 AM
>> To: Linus Walleij <linusw@kernel.org>; Shenwei Wang
>> <shenwei.wang@nxp.com>
>> Cc: Andrew Lunn <andrew@lunn.ch>; 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>; Mathieu Poirier
>> <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
>> Hello Linus,
>>
>> On 2/22/26 15:48, Linus Walleij wrote:
>>> On Fri, Feb 20, 2026 at 7:57 PM Shenwei Wang <shenwei.wang@nxp.com>
>> wrote:
>>>
>>>> Given that, I’d like to hear from the GPIO subsystem maintainers —
>>>> @Linus Walleij and @Bartosz Golaszewski — on whether a driver that
>>>> works with the current hardware/firmware design could still be
>>>> acceptable for upstream inclusion. My understanding is that upstream
>> generally supports existing, real-world hardware as long as the driver meets
>> subsystem standards.
>>>
>>> What a swell party this has become.
>>>
>>> In this kind of situations I usually refer to
>>> Documentation/process/management-style.rst
>>>
>>
>> Thank you for pointing out the document, I was not aware of its existence. Very
>> informative!
>> That help me to understand you proposal below.
>>
>>
>>> What is the message I as a maintainer is getting from NXP regarding
>>> "gpio: rpmsg: add generic rpmsg GPIO driver"?
>>>
>>> Arnaud, who is the only person in this discussion who actually wrote a
>>> standard RPMSG driver (drivers/tty/rpmsg_tty.c), must ACK this patch
>>> if it wants to call itself a "generic" RPMSG GPIO driver, if he does
>>> not, then it isn't.
>>
>> In Fact there are already 2 "generic" drivers, the second one it the
>> drivers/rpmsg/rpmsg_char.c, both are used on several platforms.
>>
>> It is in my plan to test the rpmsg-gpio on ST platform if we go with the generic
>> approach.
>>
>>>
>>> Is it generic? If it is not, let's call it "NXP rpmsg GPIO driver" and
>>> rename files etc accordingly. Maybe it can share code with the actual
>>> generic RPMSG driver once that arrives, that is more of a library question.
>>
>> I would like to (re)express my concerns regarding the creation of an NXP-specific
>> driver. To clarify my concerns, ST, like probably some other SoC vendors, has
>> rpmsg-gpio and rpmsg-i2c drivers in downstream with plans to upstream them.
>>
> 
> Linus, thank you for jumping in and providing the guidance.
> 
> I would like to clarify one point here: what we are discussing now is not whether the
> driver itself is generic, but rather that the current protocol is not as perfect as Arnaud
> would expect, since it contains a few fields that may not be required on their platforms.
> 
> Arnaud, if you agree with the points above, my proposal is the following:
>   - Remove the fields you mentioned in the protocol and update the driver accordingly so
> that we can establish a true baseline for a generic implementation we all agree.
>   - Then prepare a separate patch to add support for existing NXP platforms by introducing
> the necessary fix‑up functions.
> 
> Please let me know if this approach works for you. My goal is to find a solution that works for
> everyone — even though I know that pleasing everyone is almost impossible.
This looks reasonable to me, but I am not a maintainer, so I will let 
maintainers share their opinions on your proposition.

Please note that you have also to answer to Bjorn and Mathieu about the 
rational to use RPMsg instead of the virtio protocol.

For the ST platform, the main advantage of RPMsg is the ability to mix 
buses on one virtio interface, whereas Virtio requires allocating vrings 
and mailbox channels per Virtio type. When data rate is not the 
priority, RPMsg may be preferable.

Another limitation e observed, when prototyping a virtio-i2c between 
Linux and a remote processor is the allocation of specific DMA memory 
region shared between the processors[1].

[1] 
https://github.com/arnopo/linux/commit/ae47a1cbf95125ab10952283622653d626e56e6a

Thanks and regards,
Arnaud

> 
> Thanks,
> Shenwei
> 
>> If we proceed in this direction:
>>
>> -Any vendor wishing to upstream an rpmsg-gpio driver might submit their own
>> platform-specific version.
>>
>> - If NXP upstreams other rpmsg drivers, these will likely remain NXP-centric to
>> maintain compatibility with their legacy firmware and the nxp-rpmsg-gpio driver,
>> leading to platform-specific versions in several frameworks.
>>
>> - The implementation will impact not only the Linux side but also the remote side.
>> Indeed, some operating systems like Zephyr or NuttX implement the rpmsg device
>> side (Zephyr already implements the rpmsg-tty)
>>
>> Maintaining a generic approach for RPMsg, similar to what is done for Virtio,
>> seems to me a more reliable solution, even though it may induce some
>> downstream costs (ST would also need to break compatibility with legacy ST
>> remote proc firmware).
>>
>>
>> In the end, I am just trying to influence the direction for RPMsg, but based on the
>> discussions in this thread, it seems others share similar expectations, which
>> should probably be taken into account as well.
>>
>> Thanks and Regards,
>> Arnaud
>>
>>
>> I just want to
>>
>>>
>>> Yours,
>>> Linus Walleij
> 



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-23 20:33                     ` Shenwei Wang
  2026-02-24  8:46                       ` Arnaud POULIQUEN
@ 2026-02-24  9:37                       ` Linus Walleij
  1 sibling, 0 replies; 69+ messages in thread
From: Linus Walleij @ 2026-02-24  9:37 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Andrew Lunn, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Mon, Feb 23, 2026 at 9:33 PM Shenwei Wang <shenwei.wang@nxp.com> wrote:

> Arnaud, if you agree with the points above, my proposal is the following:
>  - Remove the fields you mentioned in the protocol and update the driver accordingly so
> that we can establish a true baseline for a generic implementation we all agree.
>  - Then prepare a separate patch to add support for existing NXP platforms by introducing
> the necessary fix‑up functions.
>
> Please let me know if this approach works for you. My goal is to find a solution that works for
> everyone — even though I know that pleasing everyone is almost impossible.

This looks good to me, and Arnaud seems happy too so let's go ahead
with this.

Yours,
Linus Walleij


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-23 14:42                     ` Bjorn Andersson
@ 2026-02-24 15:56                       ` Shenwei Wang
  2026-02-24 16:04                         ` Daniel Baluta
  2026-02-24 18:09                         ` Mathieu Poirier
  0 siblings, 2 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-24 15:56 UTC (permalink / raw)
  To: Bjorn Andersson, Arnaud POULIQUEN
  Cc: Linus Walleij, Andrew Lunn, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Mathieu Poirier,
	Frank Li, Sascha Hauer, Shuah Khan, linux-gpio@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Pengutronix Kernel Team, Fabio Estevam, Peng Fan,
	devicetree@vger.kernel.org, linux-remoteproc@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	dl-linux-imx, Bartosz Golaszewski



> -----Original Message-----
> From: Bjorn Andersson <andersson@kernel.org>
> Sent: Monday, February 23, 2026 8:43 AM
> To: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> Cc: Linus Walleij <linusw@kernel.org>; Shenwei Wang
> <shenwei.wang@nxp.com>; Andrew Lunn <andrew@lunn.ch>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> On Mon, Feb 23, 2026 at 03:24:43PM +0100, Arnaud POULIQUEN wrote:
> > On 2/22/26 15:48, Linus Walleij wrote:
> > > On Fri, Feb 20, 2026 at 7:57 PM Shenwei Wang <shenwei.wang@nxp.com>
> wrote:
> [..]
> > >
> > > Is it generic? If it is not, let's call it "NXP rpmsg GPIO driver"
> > > and rename files etc accordingly. Maybe it can share code with the
> > > actual generic RPMSG driver once that arrives, that is more of a library
> question.
> >
> > I would like to (re)express my concerns regarding the creation of an
> > NXP-specific driver. To clarify my concerns, ST, like probably some
> > other SoC vendors, has rpmsg-gpio and rpmsg-i2c drivers in downstream
> > with plans to upstream them.
> >
> > If we proceed in this direction:
> >
> > -Any vendor wishing to upstream an rpmsg-gpio driver might submit
> > their own platform-specific version.
> >
> > - If NXP upstreams other rpmsg drivers, these will likely remain
> > NXP-centric to maintain compatibility with their legacy firmware and
> > the nxp-rpmsg-gpio driver, leading to platform-specific versions in several
> frameworks.
> >
> > - The implementation will impact not only the Linux side but also the
> > remote side. Indeed, some operating systems like Zephyr or NuttX
> > implement the rpmsg device side (Zephyr already implements the
> > rpmsg-tty)
> >
> > Maintaining a generic approach for RPMsg, similar to what is done for
> > Virtio, seems to me a more reliable solution, even though it may
> > induce some downstream costs (ST would also need to break
> > compatibility with legacy ST remote proc firmware).
> >
> 
> Could the virtio-based mechanism be used directly (without rpmsg)?
> 

Technically, yes—it's possible to use the virtio mechanism directly without rpmsg.
It’s a bit like talking straight to the IP layer without involving TCP or UDP: doable, but 
at a lower‑level approach.

As for the idea of gpio‑virtio, which could be an optional solution that certain customers 
might prefer. I recall hearing this idea from Mathieu originally, though I’m not sure whether 
he plans to implement it.

As the chip vendor, NXP’s role is to provide all possible options and let customers choose 
the approach that best fits their needs; we don’t make that decision for them.

Thanks,
Shenwei

> 
> If not, it would be good to derive a generic rpmsg-gpio protocol from the virtio
> protocol, and land implementations of this in e.g. Linux and Zephyr to establish
> that option.
> 
> Regards,
> Bjorn
> 
> >
> > In the end, I am just trying to influence the direction for RPMsg, but
> > based on the discussions in this thread, it seems others share similar
> > expectations, which should probably be taken into account as well.
> >
> > Thanks and Regards,
> > Arnaud
> >
> >
> > I just want to
> >
> > >
> > > Yours,
> > > Linus Walleij
> >

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 15:56                       ` Shenwei Wang
@ 2026-02-24 16:04                         ` Daniel Baluta
  2026-02-24 16:56                           ` Shenwei Wang
  2026-02-24 18:09                         ` Mathieu Poirier
  1 sibling, 1 reply; 69+ messages in thread
From: Daniel Baluta @ 2026-02-24 16:04 UTC (permalink / raw)
  To: Shenwei Wang, Bjorn Andersson, Arnaud POULIQUEN
  Cc: Linus Walleij, Andrew Lunn, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Mathieu Poirier,
	Frank Li, Sascha Hauer, Shuah Khan, linux-gpio@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Pengutronix Kernel Team, Fabio Estevam, Peng Fan,
	devicetree@vger.kernel.org, linux-remoteproc@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	dl-linux-imx, Bartosz Golaszewski

On 2/24/26 17:56, Shenwei Wang wrote:
> Technically, yes—it's possible to use the virtio mechanism directly without rpmsg.
> It’s a bit like talking straight to the IP layer without involving TCP or UDP: doable, but 
> at a lower‑level approach.
>
> As for the idea of gpio‑virtio, which could be an optional solution that certain customers 
> might prefer. I recall hearing this idea from Mathieu originally, though I’m not sure whether 
> he plans to implement it.

gpio-virtio is already upstream in drivers/gpio/gpio-virtio.c




^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24  8:46                       ` Arnaud POULIQUEN
@ 2026-02-24 16:05                         ` Shenwei Wang
  2026-02-24 17:31                           ` Andrew Lunn
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-24 16:05 UTC (permalink / raw)
  To: Arnaud POULIQUEN, Linus Walleij
  Cc: Andrew Lunn, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Mathieu Poirier, Frank Li, Sascha Hauer, Shuah Khan,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> Sent: Tuesday, February 24, 2026 2:47 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; Linus Walleij
> <linusw@kernel.org>
> Cc: Andrew Lunn <andrew@lunn.ch>; 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>; Mathieu Poirier
> <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> Hello Shenwei
>
> On 2/23/26 21:33, Shenwei Wang wrote:
> >
> >
> >> -----Original Message-----
> >> From: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> >> Sent: Monday, February 23, 2026 8:25 AM
> >> To: Linus Walleij <linusw@kernel.org>; Shenwei Wang
> >> <shenwei.wang@nxp.com>
> >> Cc: Andrew Lunn <andrew@lunn.ch>; 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>;
> >> Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO
> >> driver Hello Linus,
> >>
> >> On 2/22/26 15:48, Linus Walleij wrote:
> >>> On Fri, Feb 20, 2026 at 7:57 PM Shenwei Wang <shenwei.wang@nxp.com>
> >> wrote:
> >>>
> >>>> Given that, I’d like to hear from the GPIO subsystem maintainers —
> >>>> @Linus Walleij and @Bartosz Golaszewski — on whether a driver that
> >>>> works with the current hardware/firmware design could still be
> >>>> acceptable for upstream inclusion. My understanding is that
> >>>> upstream
> >> generally supports existing, real-world hardware as long as the
> >> driver meets subsystem standards.
> >>>
> >>> What a swell party this has become.
> >>>
> >>> In this kind of situations I usually refer to
> >>> Documentation/process/management-style.rst
> >>>
> >>
> >> Thank you for pointing out the document, I was not aware of its
> >> existence. Very informative!
> >> That help me to understand you proposal below.
> >>
> >>
> >>> What is the message I as a maintainer is getting from NXP regarding
> >>> "gpio: rpmsg: add generic rpmsg GPIO driver"?
> >>>
> >>> Arnaud, who is the only person in this discussion who actually wrote
> >>> a standard RPMSG driver (drivers/tty/rpmsg_tty.c), must ACK this
> >>> patch if it wants to call itself a "generic" RPMSG GPIO driver, if
> >>> he does not, then it isn't.
> >>
> >> In Fact there are already 2 "generic" drivers, the second one it the
> >> drivers/rpmsg/rpmsg_char.c, both are used on several platforms.
> >>
> >> It is in my plan to test the rpmsg-gpio on ST platform if we go with
> >> the generic approach.
> >>
> >>>
> >>> Is it generic? If it is not, let's call it "NXP rpmsg GPIO driver"
> >>> and rename files etc accordingly. Maybe it can share code with the
> >>> actual generic RPMSG driver once that arrives, that is more of a library
> question.
> >>
> >> I would like to (re)express my concerns regarding the creation of an
> >> NXP-specific driver. To clarify my concerns, ST, like probably some
> >> other SoC vendors, has rpmsg-gpio and rpmsg-i2c drivers in downstream with
> plans to upstream them.
> >>
> >
> > Linus, thank you for jumping in and providing the guidance.
> >
> > I would like to clarify one point here: what we are discussing now is
> > not whether the driver itself is generic, but rather that the current
> > protocol is not as perfect as Arnaud would expect, since it contains a few fields
> that may not be required on their platforms.
> >
> > Arnaud, if you agree with the points above, my proposal is the following:
> >   - Remove the fields you mentioned in the protocol and update the
> > driver accordingly so that we can establish a true baseline for a generic
> implementation we all agree.
> >   - Then prepare a separate patch to add support for existing NXP
> > platforms by introducing the necessary fix‑up functions.
> >
> > Please let me know if this approach works for you. My goal is to find
> > a solution that works for everyone — even though I know that pleasing
> everyone is almost impossible.
> This looks reasonable to me, but I am not a maintainer, so I will let maintainers
> share their opinions on your proposition.
>

Hi Arnaud,
Glad to hear you find this approach reasonable.
To be more specific, I’m proposing to do the following modifications for the protocol:

  - remove the “id” field (Message ID Code)
  - remove the “reserved[5]” field
  - and also reorder the fields so that port_idx appears before pin_idx

If you think additional fields should be removed or adjusted, please let me know.

Thanks,
Shenwei

> Please note that you have also to answer to Bjorn and Mathieu about the rational
> to use RPMsg instead of the virtio protocol.
>
> For the ST platform, the main advantage of RPMsg is the ability to mix buses on
> one virtio interface, whereas Virtio requires allocating vrings and mailbox
> channels per Virtio type. When data rate is not the priority, RPMsg may be
> preferable.
>
> Another limitation e observed, when prototyping a virtio-i2c between Linux and a
> remote processor is the allocation of specific DMA memory region shared
> between the processors[1].
>
> [1]
> https://github.co/
> m%2Farnopo%2Flinux%2Fcommit%2Fae47a1cbf95125ab10952283622653d626e
> 56e6a&data=05%7C02%7Cshenwei.wang%40nxp.com%7Cdcff50d0e65541164d
> b908de73814b8f%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6390
> 75196360168552%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWU
> sIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%
> 7C0%7C%7C%7C&sdata=HcTtPbkXm%2BTDwrmgxWj5zwBCGE9Jp3fj9AWlBriw%
> 2BRY%3D&reserved=0
>
> Thanks and regards,
> Arnaud
>
> >
> > Thanks,
> > Shenwei
> >
> >> If we proceed in this direction:
> >>
> >> -Any vendor wishing to upstream an rpmsg-gpio driver might submit
> >> their own platform-specific version.
> >>
> >> - If NXP upstreams other rpmsg drivers, these will likely remain
> >> NXP-centric to maintain compatibility with their legacy firmware and
> >> the nxp-rpmsg-gpio driver, leading to platform-specific versions in several
> frameworks.
> >>
> >> - The implementation will impact not only the Linux side but also the remote
> side.
> >> Indeed, some operating systems like Zephyr or NuttX implement the
> >> rpmsg device side (Zephyr already implements the rpmsg-tty)
> >>
> >> Maintaining a generic approach for RPMsg, similar to what is done for
> >> Virtio, seems to me a more reliable solution, even though it may
> >> induce some downstream costs (ST would also need to break
> >> compatibility with legacy ST remote proc firmware).
> >>
> >>
> >> In the end, I am just trying to influence the direction for RPMsg,
> >> but based on the discussions in this thread, it seems others share
> >> similar expectations, which should probably be taken into account as well.
> >>
> >> Thanks and Regards,
> >> Arnaud
> >>
> >>
> >> I just want to
> >>
> >>>
> >>> Yours,
> >>> Linus Walleij
> >


^ permalink raw reply	[flat|nested] 69+ messages in thread

* RE: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 16:04                         ` Daniel Baluta
@ 2026-02-24 16:56                           ` Shenwei Wang
  0 siblings, 0 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-24 16:56 UTC (permalink / raw)
  To: Daniel Baluta (OSS), Bjorn Andersson, Arnaud POULIQUEN
  Cc: Linus Walleij, Andrew Lunn, Bartosz Golaszewski, Jonathan Corbet,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Mathieu Poirier,
	Frank Li, Sascha Hauer, Shuah Khan, linux-gpio@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Pengutronix Kernel Team, Fabio Estevam, Peng Fan,
	devicetree@vger.kernel.org, linux-remoteproc@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	dl-linux-imx, Bartosz Golaszewski



> -----Original Message-----
> From: Daniel Baluta (OSS) <daniel.baluta@oss.nxp.com>
> Sent: Tuesday, February 24, 2026 10:04 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; Bjorn Andersson
> <andersson@kernel.org>; Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> Cc: Linus Walleij <linusw@kernel.org>; Andrew Lunn <andrew@lunn.ch>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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: Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> 
> On 2/24/26 17:56, Shenwei Wang wrote:
> > Technically, yes—it's possible to use the virtio mechanism directly without
> rpmsg.
> > It’s a bit like talking straight to the IP layer without involving TCP
> > or UDP: doable, but at a lower‑level approach.
> >
> > As for the idea of gpio‑virtio, which could be an optional solution
> > that certain customers might prefer. I recall hearing this idea from
> > Mathieu originally, though I’m not sure whether he plans to implement it.
> 
> gpio-virtio is already upstream in drivers/gpio/gpio-virtio.c
> 

I’m not an expert on virtio, but having the gpio‑virtio driver upstream on the Linux side doesn’t 
necessarily mean the overall solution is complete. The remote firmware still needs to implement 
the virtio‑GPIO backend, expose the virtio‑GPIO device, and handle all of the underlying hardware 
interactions.

My understanding is that this firmware-side implementation is the part we were interested in.

Thanks,
Shenwei



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 16:05                         ` Shenwei Wang
@ 2026-02-24 17:31                           ` Andrew Lunn
  2026-02-24 17:54                             ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-24 17:31 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> Hi Arnaud,
> Glad to hear you find this approach reasonable.
> To be more specific, I’m proposing to do the following modifications for the protocol:
> 
>   - remove the “id” field (Message ID Code)
>   - remove the “reserved[5]” field
>   - and also reorder the fields so that port_idx appears before pin_idx
> 
> If you think additional fields should be removed or adjusted, please let me know.

I would squash head and body into one. Remove vendor and version. Do
we need both cmd and type? It seems like they can be combined. And is
port_idx needed? Don't you just instantiate more instances of the
device, one per port. That is how you would do it with MMIO GPIOs.

struct gpio_rpmsg_packet {
	u8 cmd;
	u8 pin;
	union {
		u8 event;
		u8 retcode;
		u8 value;
	} out;
	union {
		u8 wakeup;
		u8 value;
	} in;
}

4 bytes, a nice size.

#define GPIO_RPMSG_CMD_DIR_INPUT 	1
#define GPIO_RPMSG_CMD_DIR_OUTPUT 	2
#define GPIO_RPMSG_CMD_GET_DIR		3
#define GPIO_RPMSG_CMD_GET		4
#define GPIO_RPMSG_CMD_SET		5

These map onto the gpio_chip ops. And i leave space for the _multiple
ops if they are needed in the future.

#define GPIO_PRMSG_CMD_INTR_CONFIG	32
#define GPIO_PRMSG_CMD_INTR_EVENT	33

And then interrupt handling. These are less obvious, struct irq_chip
has a lot more ops, so i'm not very confident this is sufficient.

	Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 17:31                           ` Andrew Lunn
@ 2026-02-24 17:54                             ` Shenwei Wang
  2026-02-24 18:18                               ` Andrew Lunn
  2026-02-24 18:26                               ` Andrew Lunn
  0 siblings, 2 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-24 17:54 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Tuesday, February 24, 2026 11:31 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 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,
> > Glad to hear you find this approach reasonable.
> > To be more specific, I’m proposing to do the following modifications for the
> protocol:
> >
> >   - remove the “id” field (Message ID Code)
> >   - remove the “reserved[5]” field
> >   - and also reorder the fields so that port_idx appears before
> > pin_idx
> >
> > If you think additional fields should be removed or adjusted, please let me
> know.
> 
> I would squash head and body into one. Remove vendor and version. Do we need
> both cmd and type? It seems like they can be combined. And is port_idx needed?
> Don't you just instantiate more instances of the device, one per port. That is how
> you would do it with MMIO GPIOs.
> 

I don’t think we can remove port_idx if the protocol is expected to support multiple 
instances. If you only ever support a single instance, then sure, it becomes redundant—but 
imposing a single‑instance limitation on a generic protocol doesn’t seem appropriate.

Regarding type, it’s needed, especially for the in packets. There are two distinct kinds of incoming 
packets: notification‑in and reply‑in. Because of that differences, Combining cmd and type would 
blur that distinction and complicate the implementation.

Thanks,
Shenwei

> struct gpio_rpmsg_packet {
>         u8 cmd;
>         u8 pin;
>         union {
>                 u8 event;
>                 u8 retcode;
>                 u8 value;
>         } out;
>         union {
>                 u8 wakeup;
>                 u8 value;
>         } in;
> }
> 
> 4 bytes, a nice size.
> 
> #define GPIO_RPMSG_CMD_DIR_INPUT        1
> #define GPIO_RPMSG_CMD_DIR_OUTPUT       2
> #define GPIO_RPMSG_CMD_GET_DIR          3
> #define GPIO_RPMSG_CMD_GET              4
> #define GPIO_RPMSG_CMD_SET              5
> 
> These map onto the gpio_chip ops. And i leave space for the _multiple ops if they
> are needed in the future.
> 
> #define GPIO_PRMSG_CMD_INTR_CONFIG      32
> #define GPIO_PRMSG_CMD_INTR_EVENT       33
> 
> And then interrupt handling. These are less obvious, struct irq_chip has a lot more
> ops, so i'm not very confident this is sufficient.
> 
>         Andrew

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 15:56                       ` Shenwei Wang
  2026-02-24 16:04                         ` Daniel Baluta
@ 2026-02-24 18:09                         ` Mathieu Poirier
  2026-02-24 20:16                           ` Shenwei Wang
  1 sibling, 1 reply; 69+ messages in thread
From: Mathieu Poirier @ 2026-02-24 18:09 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Bjorn Andersson, Arnaud POULIQUEN, Linus Walleij, Andrew Lunn,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Tue, 24 Feb 2026 at 08:56, Shenwei Wang <shenwei.wang@nxp.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Bjorn Andersson <andersson@kernel.org>
> > Sent: Monday, February 23, 2026 8:43 AM
> > To: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> > Cc: Linus Walleij <linusw@kernel.org>; Shenwei Wang
> > <shenwei.wang@nxp.com>; Andrew Lunn <andrew@lunn.ch>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > On Mon, Feb 23, 2026 at 03:24:43PM +0100, Arnaud POULIQUEN wrote:
> > > On 2/22/26 15:48, Linus Walleij wrote:
> > > > On Fri, Feb 20, 2026 at 7:57 PM Shenwei Wang <shenwei.wang@nxp.com>
> > wrote:
> > [..]
> > > >
> > > > Is it generic? If it is not, let's call it "NXP rpmsg GPIO driver"
> > > > and rename files etc accordingly. Maybe it can share code with the
> > > > actual generic RPMSG driver once that arrives, that is more of a library
> > question.
> > >
> > > I would like to (re)express my concerns regarding the creation of an
> > > NXP-specific driver. To clarify my concerns, ST, like probably some
> > > other SoC vendors, has rpmsg-gpio and rpmsg-i2c drivers in downstream
> > > with plans to upstream them.
> > >
> > > If we proceed in this direction:
> > >
> > > -Any vendor wishing to upstream an rpmsg-gpio driver might submit
> > > their own platform-specific version.
> > >
> > > - If NXP upstreams other rpmsg drivers, these will likely remain
> > > NXP-centric to maintain compatibility with their legacy firmware and
> > > the nxp-rpmsg-gpio driver, leading to platform-specific versions in several
> > frameworks.
> > >
> > > - The implementation will impact not only the Linux side but also the
> > > remote side. Indeed, some operating systems like Zephyr or NuttX
> > > implement the rpmsg device side (Zephyr already implements the
> > > rpmsg-tty)
> > >
> > > Maintaining a generic approach for RPMsg, similar to what is done for
> > > Virtio, seems to me a more reliable solution, even though it may
> > > induce some downstream costs (ST would also need to break
> > > compatibility with legacy ST remote proc firmware).
> > >
> >
> > Could the virtio-based mechanism be used directly (without rpmsg)?
> >
>
> Technically, yes—it's possible to use the virtio mechanism directly without rpmsg.
> It’s a bit like talking straight to the IP layer without involving TCP or UDP: doable, but
> at a lower‑level approach.
>
> As for the idea of gpio‑virtio, which could be an optional solution that certain customers
> might prefer. I recall hearing this idea from Mathieu originally, though I’m not sure whether
> he plans to implement it.
>

As Daniel pointed out, gpio-virtio is already available and already
includes a protocol that is generic - no need to redefine a new one as
this set is trying to.

As mentioned in a previous email, I understand some implementations
will have restricted memory and need to use RPMSG.  For those cases a
generic rpmsg-gpio protocol should be derived from gpio-virtio that
would only deal with breaking down the standard gpio-virtio protocol
into something digestible by RPMSG.  That was Bjorn's point in an
earlier message.  This will allow to use the same interface and be
flexible in how we want to talk to the transport medium, i.e pure
gpio-virtio or rpmsg-gpio.

Fortunately RPMSG already uses channels to differentiate between
traffic, no need to multiplex everything on the same channel.  That
too needs to go.

> As the chip vendor, NXP’s role is to provide all possible options and let customers choose
> the approach that best fits their needs; we don’t make that decision for them.

As kernel maintainers, our role is to advise on designs that are
generic, simple, maintainable and stand the test of time.

>
> Thanks,
> Shenwei
>
> >
> > If not, it would be good to derive a generic rpmsg-gpio protocol from the virtio
> > protocol, and land implementations of this in e.g. Linux and Zephyr to establish
> > that option.
> >
> > Regards,
> > Bjorn
> >
> > >
> > > In the end, I am just trying to influence the direction for RPMsg, but
> > > based on the discussions in this thread, it seems others share similar
> > > expectations, which should probably be taken into account as well.
> > >
> > > Thanks and Regards,
> > > Arnaud
> > >
> > >
> > > I just want to
> > >
> > > >
> > > > Yours,
> > > > Linus Walleij
> > >


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 17:54                             ` Shenwei Wang
@ 2026-02-24 18:18                               ` Andrew Lunn
  2026-02-24 19:51                                 ` Shenwei Wang
  2026-02-24 18:26                               ` Andrew Lunn
  1 sibling, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-24 18:18 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> I don’t think we can remove port_idx if the protocol is expected to support multiple 
> instances. If you only ever support a single instance, then sure, it becomes redundant—but 
> imposing a single‑instance limitation on a generic protocol doesn’t seem appropriate.

The DT binding example is:

+      rpmsg {
+        rpmsg-io-channel {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          gpio@0 {
+            compatible = "rpmsg-gpio";
+            reg = <0>;
+            gpio-controller;
+            #gpio-cells = <2>;
+            #interrupt-cells = <2>;
+            interrupt-controller;
+          };
+
+          gpio@1 {
+            compatible = "rpmsg-gpio";
+            reg = <1>;
+            gpio-controller;
+            #gpio-cells = <2>;
+            #interrupt-cells = <2>;
+            interrupt-controller;
+          };
+        };
+      };

Doesn't this instantiates the driver twice, once on channel 0 and once
on channel 1?

How does port_idx fit into this?

> Regarding type, it’s needed, especially for the in packets. There are two distinct kinds of incoming 
> packets: notification‑in and reply‑in. Because of that differences, Combining cmd and type would 
> blur that distinction and complicate the implementation.

> > #define GPIO_RPMSG_CMD_DIR_INPUT        1
> > #define GPIO_RPMSG_CMD_DIR_OUTPUT       2
> > #define GPIO_RPMSG_CMD_GET_DIR          3
> > #define GPIO_RPMSG_CMD_GET              4
> > #define GPIO_RPMSG_CMD_SET              5

These are all simple RPCs. You make a request, your get a reply, using
the same CMD. I don't see how you can make any mixup here.

> > These map onto the gpio_chip ops. And i leave space for the _multiple ops if they
> > are needed in the future.
> > 
> > #define GPIO_PRMSG_CMD_INTR_CONFIG      32
> > #define GPIO_PRMSG_CMD_INTR_EVENT       33

GPIO_PRMSG_CMD_INTR_CONFIG is again just a plain RPC, request of
"please configure the interrupt handling like this", replay of
"yes, done".

GPIO_PRMSG_CMD_INTR_EVENT is more interesting. The other end can
spontaneously send this, indicating an interrupt. Once Linux has
handled the interrupt, especially level interrupts, it needs to be
acknowledged. So it sends back an GPIO_PRMSG_CMD_INTR_EVENT. It could
be considered an RPC in the opposite direction, but i think that would
be wrong. I expect there are multiple overlapping
GPIO_PRMSG_CMD_INTR_EVENT flying around, so you cannot enforce a
strict RPC style communication.

What is blurry or complicated here?

       Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 17:54                             ` Shenwei Wang
  2026-02-24 18:18                               ` Andrew Lunn
@ 2026-02-24 18:26                               ` Andrew Lunn
  2026-02-24 20:33                                 ` Shenwei Wang
  1 sibling, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-24 18:26 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> Regarding type, it’s needed, especially for the in packets. There are two distinct kinds of incoming 
> packets: notification‑in and reply‑in. Because of that differences, Combining cmd and type would 
> blur that distinction and complicate the implementation.

[Goes and looks at gpio-virtio]

https://elixir.bootlin.com/linux/v6.19.3/source/include/uapi/linux/virtio_gpio.h#L13

/* Virtio GPIO request types */
#define VIRTIO_GPIO_MSG_GET_NAMES		0x0001
#define VIRTIO_GPIO_MSG_GET_DIRECTION		0x0002
#define VIRTIO_GPIO_MSG_SET_DIRECTION		0x0003
#define VIRTIO_GPIO_MSG_GET_VALUE		0x0004
#define VIRTIO_GPIO_MSG_SET_VALUE		0x0005
#define VIRTIO_GPIO_MSG_IRQ_TYPE		0x0006

	Andrew
 


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 18:18                               ` Andrew Lunn
@ 2026-02-24 19:51                                 ` Shenwei Wang
  2026-02-24 21:01                                   ` Andrew Lunn
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-24 19:51 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Tuesday, February 24, 2026 12:18 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 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
> 
> 
> > I don’t think we can remove port_idx if the protocol is expected to
> > support multiple instances. If you only ever support a single
> > instance, then sure, it becomes redundant—but imposing a single‑instance
> limitation on a generic protocol doesn’t seem appropriate.
> 
> The DT binding example is:
> 
> +      rpmsg {
> +        rpmsg-io-channel {
> +          #address-cells = <1>;
> +          #size-cells = <0>;
> +
> +          gpio@0 {
> +            compatible = "rpmsg-gpio";
> +            reg = <0>;
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            #interrupt-cells = <2>;
> +            interrupt-controller;
> +          };
> +
> +          gpio@1 {
> +            compatible = "rpmsg-gpio";
> +            reg = <1>;
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            #interrupt-cells = <2>;
> +            interrupt-controller;
> +          };
> +        };
> +      };
> 
> Doesn't this instantiates the driver twice, once on channel 0 and once on channel
> 1?
> 
> How does port_idx fit into this?

I think you were assuming there is only one remoteproc in the system?
In practice, the setup can look more like this:

+ remote_cm33{
+     rpmsg {
+        rpmsg-io-channel {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          gpio@0 {
+            compatible = "rpmsg-gpio";
+            reg = <0>;
+            gpio-controller;
+            #gpio-cells = <2>;
+            #interrupt-cells = <2>;
+            interrupt-controller;
+          };
+          gpio@1 {
+            compatible = "rpmsg-gpio";
+            reg = <1>;
+            gpio-controller;
+            #gpio-cells = <2>;
+            #interrupt-cells = <2>;
+            interrupt-controller;
+          };
+  ...
+        };
+      };
+};
+
+ remote_dsp {
+     rpmsg {
+        rpmsg-io-channel {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          gpio@0 {
+            compatible = "rpmsg-gpio";
+            reg = <0>;
+            gpio-controller;
+            #gpio-cells = <2>;
+            #interrupt-cells = <2>;
+            interrupt-controller;
+          };
+  ...
+        };
+      };
+};

> 
> > Regarding type, it’s needed, especially for the in packets. There are
> > two distinct kinds of incoming
> > packets: notification‑in and reply‑in. Because of that differences,
> > Combining cmd and type would blur that distinction and complicate the
> implementation.
> 
> > > #define GPIO_RPMSG_CMD_DIR_INPUT        1
> > > #define GPIO_RPMSG_CMD_DIR_OUTPUT       2
> > > #define GPIO_RPMSG_CMD_GET_DIR          3
> > > #define GPIO_RPMSG_CMD_GET              4
> > > #define GPIO_RPMSG_CMD_SET              5
> 
> These are all simple RPCs. You make a request, your get a reply, using the same
> CMD. I don't see how you can make any mixup here.
> 

Message type and cmd are not the same thing.
Keeping them separate allows the same packet format to be used for both IN and OUT 
messages. The type field identifies whether a packet is a request, a reply, or a notification, 
while cmd identifies the actual operation. No benefits to combine them.

> > > These map onto the gpio_chip ops. And i leave space for the
> > > _multiple ops if they are needed in the future.
> > >
> > > #define GPIO_PRMSG_CMD_INTR_CONFIG      32
> > > #define GPIO_PRMSG_CMD_INTR_EVENT       33
> 
> GPIO_PRMSG_CMD_INTR_CONFIG is again just a plain RPC, request of "please
> configure the interrupt handling like this", replay of "yes, done".
> 
> GPIO_PRMSG_CMD_INTR_EVENT is more interesting. The other end can
> spontaneously send this, indicating an interrupt. Once Linux has handled the
> interrupt, especially level interrupts, it needs to be acknowledged. So it sends
> back an GPIO_PRMSG_CMD_INTR_EVENT. It could be considered an RPC in the
> opposite direction, but i think that would be wrong. I expect there are multiple
> overlapping GPIO_PRMSG_CMD_INTR_EVENT flying around, so you cannot
> enforce a strict RPC style communication.
> 

In v8 gpio-rpmsg.rst, we already added the following cmd:
+GPIO_RPMSG_NOTIFY_REPLY (Cmd=4)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The reply message for the notification is optional. The remote firmware can
+implement it to simulate the interrupt acknowledgment behavior.
+
+**Request:**
+
+.. code-block:: none
+
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+   |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D|
+   | 5   | 1   | 0   | 0   | 4   |  0        |line |port |level| 0  |
+   +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+
+- **line**: The GPIO line(pin) index of the port.
+- **port**: The GPIO port(bank) index.
+

At this point, I don’t see a need to introduce the two commands you proposed. If they 
become useful later, we can add them then.

Thanks,
Shenwei

> What is blurry or complicated here?
> 
>        Andrew

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 18:09                         ` Mathieu Poirier
@ 2026-02-24 20:16                           ` Shenwei Wang
  2026-02-24 20:41                             ` Mathieu Poirier
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-24 20:16 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Bjorn Andersson, Arnaud POULIQUEN, Linus Walleij, Andrew Lunn,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Mathieu Poirier <mathieu.poirier@linaro.org>
> Sent: Tuesday, February 24, 2026 12:10 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Bjorn Andersson <andersson@kernel.org>; Arnaud POULIQUEN
> <arnaud.pouliquen@foss.st.com>; Linus Walleij <linusw@kernel.org>; Andrew
> Lunn <andrew@lunn.ch>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> On Tue, 24 Feb 2026 at 08:56, Shenwei Wang <shenwei.wang@nxp.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Bjorn Andersson <andersson@kernel.org>
> > > Sent: Monday, February 23, 2026 8:43 AM
> > > To: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> > > Cc: Linus Walleij <linusw@kernel.org>; Shenwei Wang
> > > <shenwei.wang@nxp.com>; Andrew Lunn <andrew@lunn.ch>; 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>; Mathieu Poirier
> > > <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg
> > > GPIO driver On Mon, Feb 23, 2026 at 03:24:43PM +0100, Arnaud POULIQUEN
> wrote:
> > > > On 2/22/26 15:48, Linus Walleij wrote:
> > > > > On Fri, Feb 20, 2026 at 7:57 PM Shenwei Wang
> > > > > <shenwei.wang@nxp.com>
> > > wrote:
> > > [..]
> > > > >
> > > > > Is it generic? If it is not, let's call it "NXP rpmsg GPIO driver"
> > > > > and rename files etc accordingly. Maybe it can share code with
> > > > > the actual generic RPMSG driver once that arrives, that is more
> > > > > of a library
> > > question.
> > > >
> > > > I would like to (re)express my concerns regarding the creation of
> > > > an NXP-specific driver. To clarify my concerns, ST, like probably
> > > > some other SoC vendors, has rpmsg-gpio and rpmsg-i2c drivers in
> > > > downstream with plans to upstream them.
> > > >
> > > > If we proceed in this direction:
> > > >
> > > > -Any vendor wishing to upstream an rpmsg-gpio driver might submit
> > > > their own platform-specific version.
> > > >
> > > > - If NXP upstreams other rpmsg drivers, these will likely remain
> > > > NXP-centric to maintain compatibility with their legacy firmware
> > > > and the nxp-rpmsg-gpio driver, leading to platform-specific
> > > > versions in several
> > > frameworks.
> > > >
> > > > - The implementation will impact not only the Linux side but also
> > > > the remote side. Indeed, some operating systems like Zephyr or
> > > > NuttX implement the rpmsg device side (Zephyr already implements
> > > > the
> > > > rpmsg-tty)
> > > >
> > > > Maintaining a generic approach for RPMsg, similar to what is done
> > > > for Virtio, seems to me a more reliable solution, even though it
> > > > may induce some downstream costs (ST would also need to break
> > > > compatibility with legacy ST remote proc firmware).
> > > >
> > >
> > > Could the virtio-based mechanism be used directly (without rpmsg)?
> > >
> >
> > Technically, yes—it's possible to use the virtio mechanism directly without
> rpmsg.
> > It’s a bit like talking straight to the IP layer without involving TCP
> > or UDP: doable, but at a lower‑level approach.
> >
> > As for the idea of gpio‑virtio, which could be an optional solution
> > that certain customers might prefer. I recall hearing this idea from
> > Mathieu originally, though I’m not sure whether he plans to implement it.
> >
> 
> As Daniel pointed out, gpio-virtio is already available and already includes a
> protocol that is generic - no need to redefine a new one as this set is trying to.
> 
> As mentioned in a previous email, I understand some implementations will have
> restricted memory and need to use RPMSG.  For those cases a generic rpmsg-gpio

I think this highlights why some customers prefer RPMSG over using virtio directly. Limited 
system resources and development efficiency are the two main reasons that make RPMSG 
a better fit for certain environments.

> protocol should be derived from gpio-virtio that would only deal with breaking
> down the standard gpio-virtio protocol into something digestible by RPMSG.  That
> was Bjorn's point in an earlier message.  This will allow to use the same interface
> and be flexible in how we want to talk to the transport medium, i.e pure gpio-
> virtio or rpmsg-gpio.
> 

Once the remoteproc chooses to expose devices through an RPMSG‑based protocol, 
deriving another driver from gpio‑virtio doesn’t really make sense. That would essentially 
mean re‑implementing parts of RPMSG yourself instead of using existing one.

> Fortunately RPMSG already uses channels to differentiate between traffic, no
> need to multiplex everything on the same channel.  That too needs to go.
> 
> > As the chip vendor, NXP’s role is to provide all possible options and
> > let customers choose the approach that best fits their needs; we don’t make
> that decision for them.
> 
> As kernel maintainers, our role is to advise on designs that are generic, simple,
> maintainable and stand the test of time.
> 

These adjectives only make sense within the context of a specific use case. Different
 systems have different constraints, and people choose a particular solution for valid 
reasons based on their requirements.

Please respect their efforts.

Thanks,
Shenwei

> >
> > Thanks,
> > Shenwei
> >
> > >
> > > If not, it would be good to derive a generic rpmsg-gpio protocol
> > > from the virtio protocol, and land implementations of this in e.g.
> > > Linux and Zephyr to establish that option.
> > >
> > > Regards,
> > > Bjorn
> > >
> > > >
> > > > In the end, I am just trying to influence the direction for RPMsg,
> > > > but based on the discussions in this thread, it seems others share
> > > > similar expectations, which should probably be taken into account as well.
> > > >
> > > > Thanks and Regards,
> > > > Arnaud
> > > >
> > > >
> > > > I just want to
> > > >
> > > > >
> > > > > Yours,
> > > > > Linus Walleij
> > > >

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 18:26                               ` Andrew Lunn
@ 2026-02-24 20:33                                 ` Shenwei Wang
  0 siblings, 0 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-24 20:33 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Tuesday, February 24, 2026 12:27 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 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
>
>
> > Regarding type, it’s needed, especially for the in packets. There are
> > two distinct kinds of incoming
> > packets: notification‑in and reply‑in. Because of that differences,
> > Combining cmd and type would blur that distinction and complicate the
> implementation.
>
> [Goes and looks at gpio-virtio]
>

They aren’t comparable. gpio‑virtio represents a single virtio device(transport) mapped to a single
GPIO controller — a strict 1:1 relationship.

RPMSG, on the other hand, is a bus‑style transport. Multiple GPIO controllers can run over
the same RPMSG channel.

Thanks,
Shenwei

> https://elixir.bootl/
> in.com%2Flinux%2Fv6.19.3%2Fsource%2Finclude%2Fuapi%2Flinux%2Fvirtio_gpio
> .h%23L13&data=05%7C02%7Cshenwei.wang%40nxp.com%7C59d9438500554b
> 9d6a5e08de73d246cb%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C
> 639075544153317722%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRy
> dWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D
> %3D%7C0%7C%7C%7C&sdata=7fcyGY6KVuRqTIivhZbM4PK8PNTALI%2BScOfxM
> yaPVh8%3D&reserved=0
>
> /* Virtio GPIO request types */
> #define VIRTIO_GPIO_MSG_GET_NAMES               0x0001
> #define VIRTIO_GPIO_MSG_GET_DIRECTION           0x0002
> #define VIRTIO_GPIO_MSG_SET_DIRECTION           0x0003
> #define VIRTIO_GPIO_MSG_GET_VALUE               0x0004
> #define VIRTIO_GPIO_MSG_SET_VALUE               0x0005
> #define VIRTIO_GPIO_MSG_IRQ_TYPE                0x0006
>
>         Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 20:16                           ` Shenwei Wang
@ 2026-02-24 20:41                             ` Mathieu Poirier
  2026-02-24 21:12                               ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Mathieu Poirier @ 2026-02-24 20:41 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Bjorn Andersson, Arnaud POULIQUEN, Linus Walleij, Andrew Lunn,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Tue, 24 Feb 2026 at 13:17, Shenwei Wang <shenwei.wang@nxp.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Mathieu Poirier <mathieu.poirier@linaro.org>
> > Sent: Tuesday, February 24, 2026 12:10 PM
> > To: Shenwei Wang <shenwei.wang@nxp.com>
> > Cc: Bjorn Andersson <andersson@kernel.org>; Arnaud POULIQUEN
> > <arnaud.pouliquen@foss.st.com>; Linus Walleij <linusw@kernel.org>; Andrew
> > Lunn <andrew@lunn.ch>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > On Tue, 24 Feb 2026 at 08:56, Shenwei Wang <shenwei.wang@nxp.com> wrote:
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Bjorn Andersson <andersson@kernel.org>
> > > > Sent: Monday, February 23, 2026 8:43 AM
> > > > To: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
> > > > Cc: Linus Walleij <linusw@kernel.org>; Shenwei Wang
> > > > <shenwei.wang@nxp.com>; Andrew Lunn <andrew@lunn.ch>; 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>; Mathieu Poirier
> > > > <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg
> > > > GPIO driver On Mon, Feb 23, 2026 at 03:24:43PM +0100, Arnaud POULIQUEN
> > wrote:
> > > > > On 2/22/26 15:48, Linus Walleij wrote:
> > > > > > On Fri, Feb 20, 2026 at 7:57 PM Shenwei Wang
> > > > > > <shenwei.wang@nxp.com>
> > > > wrote:
> > > > [..]
> > > > > >
> > > > > > Is it generic? If it is not, let's call it "NXP rpmsg GPIO driver"
> > > > > > and rename files etc accordingly. Maybe it can share code with
> > > > > > the actual generic RPMSG driver once that arrives, that is more
> > > > > > of a library
> > > > question.
> > > > >
> > > > > I would like to (re)express my concerns regarding the creation of
> > > > > an NXP-specific driver. To clarify my concerns, ST, like probably
> > > > > some other SoC vendors, has rpmsg-gpio and rpmsg-i2c drivers in
> > > > > downstream with plans to upstream them.
> > > > >
> > > > > If we proceed in this direction:
> > > > >
> > > > > -Any vendor wishing to upstream an rpmsg-gpio driver might submit
> > > > > their own platform-specific version.
> > > > >
> > > > > - If NXP upstreams other rpmsg drivers, these will likely remain
> > > > > NXP-centric to maintain compatibility with their legacy firmware
> > > > > and the nxp-rpmsg-gpio driver, leading to platform-specific
> > > > > versions in several
> > > > frameworks.
> > > > >
> > > > > - The implementation will impact not only the Linux side but also
> > > > > the remote side. Indeed, some operating systems like Zephyr or
> > > > > NuttX implement the rpmsg device side (Zephyr already implements
> > > > > the
> > > > > rpmsg-tty)
> > > > >
> > > > > Maintaining a generic approach for RPMsg, similar to what is done
> > > > > for Virtio, seems to me a more reliable solution, even though it
> > > > > may induce some downstream costs (ST would also need to break
> > > > > compatibility with legacy ST remote proc firmware).
> > > > >
> > > >
> > > > Could the virtio-based mechanism be used directly (without rpmsg)?
> > > >
> > >
> > > Technically, yes—it's possible to use the virtio mechanism directly without
> > rpmsg.
> > > It’s a bit like talking straight to the IP layer without involving TCP
> > > or UDP: doable, but at a lower‑level approach.
> > >
> > > As for the idea of gpio‑virtio, which could be an optional solution
> > > that certain customers might prefer. I recall hearing this idea from
> > > Mathieu originally, though I’m not sure whether he plans to implement it.
> > >
> >
> > As Daniel pointed out, gpio-virtio is already available and already includes a
> > protocol that is generic - no need to redefine a new one as this set is trying to.
> >
> > As mentioned in a previous email, I understand some implementations will have
> > restricted memory and need to use RPMSG.  For those cases a generic rpmsg-gpio
>
> I think this highlights why some customers prefer RPMSG over using virtio directly. Limited
> system resources and development efficiency are the two main reasons that make RPMSG
> a better fit for certain environments.
>
> > protocol should be derived from gpio-virtio that would only deal with breaking
> > down the standard gpio-virtio protocol into something digestible by RPMSG.  That
> > was Bjorn's point in an earlier message.  This will allow to use the same interface
> > and be flexible in how we want to talk to the transport medium, i.e pure gpio-
> > virtio or rpmsg-gpio.
> >
>
> Once the remoteproc chooses to expose devices through an RPMSG‑based protocol,
> deriving another driver from gpio‑virtio doesn’t really make sense. That would essentially
> mean re‑implementing parts of RPMSG yourself instead of using existing one.
>

We clearly do not understand each other.

> > Fortunately RPMSG already uses channels to differentiate between traffic, no
> > need to multiplex everything on the same channel.  That too needs to go.
> >
> > > As the chip vendor, NXP’s role is to provide all possible options and
> > > let customers choose the approach that best fits their needs; we don’t make
> > that decision for them.
> >
> > As kernel maintainers, our role is to advise on designs that are generic, simple,
> > maintainable and stand the test of time.
> >
>
> These adjectives only make sense within the context of a specific use case. Different
>  systems have different constraints, and people choose a particular solution for valid
> reasons based on their requirements.
>

You can choose whatever solution you want, that is entirely up to you.
Maintainers can also choose to reject that solution for mainline
Linux, which is exactly what we are doing.

> Please respect their efforts.
>
> Thanks,
> Shenwei
>
> > >
> > > Thanks,
> > > Shenwei
> > >
> > > >
> > > > If not, it would be good to derive a generic rpmsg-gpio protocol
> > > > from the virtio protocol, and land implementations of this in e.g.
> > > > Linux and Zephyr to establish that option.
> > > >
> > > > Regards,
> > > > Bjorn
> > > >
> > > > >
> > > > > In the end, I am just trying to influence the direction for RPMsg,
> > > > > but based on the discussions in this thread, it seems others share
> > > > > similar expectations, which should probably be taken into account as well.
> > > > >
> > > > > Thanks and Regards,
> > > > > Arnaud
> > > > >
> > > > >
> > > > > I just want to
> > > > >
> > > > > >
> > > > > > Yours,
> > > > > > Linus Walleij
> > > > >


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 19:51                                 ` Shenwei Wang
@ 2026-02-24 21:01                                   ` Andrew Lunn
  2026-02-24 21:18                                     ` [EXT] " Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-24 21:01 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> > How does port_idx fit into this?
> 
> I think you were assuming there is only one remoteproc in the system?
> In practice, the setup can look more like this:
> 
> + remote_cm33{
> +     rpmsg {
> +        rpmsg-io-channel {
> +          #address-cells = <1>;
> +          #size-cells = <0>;
> +
> +          gpio@0 {
> +            compatible = "rpmsg-gpio";
> +            reg = <0>;
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            #interrupt-cells = <2>;
> +            interrupt-controller;
> +          };
> +          gpio@1 {
> +            compatible = "rpmsg-gpio";
> +            reg = <1>;
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            #interrupt-cells = <2>;
> +            interrupt-controller;
> +          };
> +  ...
> +        };
> +      };
> +};
> +
> + remote_dsp {
> +     rpmsg {
> +        rpmsg-io-channel {
> +          #address-cells = <1>;
> +          #size-cells = <0>;
> +
> +          gpio@0 {
> +            compatible = "rpmsg-gpio";
> +            reg = <0>;
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            #interrupt-cells = <2>;
> +            interrupt-controller;
> +          };
> +  ...
> +        };
> +      };
> +};

And why would this require a port_idx? If they are different rpmsg
instances, the channel numbers are in different address spaces.

	Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 20:41                             ` Mathieu Poirier
@ 2026-02-24 21:12                               ` Shenwei Wang
  2026-02-24 22:14                                 ` Andrew Lunn
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-24 21:12 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Bjorn Andersson, Arnaud POULIQUEN, Linus Walleij, Andrew Lunn,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Mathieu Poirier <mathieu.poirier@linaro.org>
> Sent: Tuesday, February 24, 2026 2:41 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Bjorn Andersson <andersson@kernel.org>; Arnaud POULIQUEN
> <arnaud.pouliquen@foss.st.com>; Linus Walleij <linusw@kernel.org>; Andrew
> Lunn <andrew@lunn.ch>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > > -----Original Message-----
> > > From: Mathieu Poirier <mathieu.poirier@linaro.org>
> > > Sent: Tuesday, February 24, 2026 12:10 PM
> > > To: Shenwei Wang <shenwei.wang@nxp.com>
> > > Cc: Bjorn Andersson <andersson@kernel.org>; Arnaud POULIQUEN
> > > <arnaud.pouliquen@foss.st.com>; Linus Walleij <linusw@kernel.org>;
> > > Andrew Lunn <andrew@lunn.ch>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg
> > > GPIO driver On Tue, 24 Feb 2026 at 08:56, Shenwei Wang
> <shenwei.wang@nxp.com> wrote:
> > > >
> > > >
> > > >
> > I think this highlights why some customers prefer RPMSG over using
> > virtio directly. Limited system resources and development efficiency
> > are the two main reasons that make RPMSG a better fit for certain
> environments.
> >
> > > protocol should be derived from gpio-virtio that would only deal
> > > with breaking down the standard gpio-virtio protocol into something
> > > digestible by RPMSG.  That was Bjorn's point in an earlier message.
> > > This will allow to use the same interface and be flexible in how we
> > > want to talk to the transport medium, i.e pure gpio- virtio or rpmsg-gpio.
> > >
> >
> > Once the remoteproc chooses to expose devices through an RPMSG‑based
> > protocol, deriving another driver from gpio‑virtio doesn’t really make
> > sense. That would essentially mean re‑implementing parts of RPMSG yourself
> instead of using existing one.
> >
> 
> We clearly do not understand each other.
> 

The current RPMSG solution:

     On Remoteprc                      On Linux
GPIOs -> RPMSG -> VIRTIO == VIRTIO -> RPMSG -> GPIO-RPMSG drivers

The VIRTIO solution:

     On Remoteprc                     On Linux
          GPIO -> VIRTIO == VIRTIO -> GPIO-VIRTIO driver

Your proposal:
     On Remoteprc                     On Linux
GPIOs -> RPMSG -> VIRTIO == VIRTIO -> ???

This is your comments:  "For those cases a generic rpmsg-gpio protocol should 
be derived from gpio-virtio"

Please explain how you would design your generic rpmsg-gpio driver which is derived
From gpio-virtio?

Thanks,
Shenwei

> > > Fortunately RPMSG already uses channels to differentiate between
> > > traffic, no need to multiplex everything on the same channel.  That too needs
> to go.
> > >
> > > > As the chip vendor, NXP’s role is to provide all possible options
> > > > and let customers choose the approach that best fits their needs;
> > > > we don’t make
> > > that decision for them.
> > >
> > > As kernel maintainers, our role is to advise on designs that are
> > > generic, simple, maintainable and stand the test of time.
> > >
> >
> > These adjectives only make sense within the context of a specific use
> > case. Different  systems have different constraints, and people choose
> > a particular solution for valid reasons based on their requirements.
> >
> 
> You can choose whatever solution you want, that is entirely up to you.
> Maintainers can also choose to reject that solution for mainline Linux, which is
> exactly what we are doing.
> 
> > Please respect their efforts.
> >
> > Thanks,
> > Shenwei
> >
> > > >
> > > > Thanks,
> > > > Shenwei
> > > >
> > > > >
> > > > > If not, it would be good to derive a generic rpmsg-gpio protocol
> > > > > from the virtio protocol, and land implementations of this in e.g.
> > > > > Linux and Zephyr to establish that option.
> > > > >
> > > > > Regards,
> > > > > Bjorn
> > > > >
> > > > > >
> > > > > > In the end, I am just trying to influence the direction for
> > > > > > RPMsg, but based on the discussions in this thread, it seems
> > > > > > others share similar expectations, which should probably be taken into
> account as well.
> > > > > >
> > > > > > Thanks and Regards,
> > > > > > Arnaud
> > > > > >
> > > > > >
> > > > > > I just want to
> > > > > >
> > > > > > >
> > > > > > > Yours,
> > > > > > > Linus Walleij
> > > > > >

^ permalink raw reply	[flat|nested] 69+ messages in thread

* RE: [EXT] Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 21:01                                   ` Andrew Lunn
@ 2026-02-24 21:18                                     ` Shenwei Wang
  2026-02-24 22:22                                       ` Andrew Lunn
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-24 21:18 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Tuesday, February 24, 2026 3:01 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > > How does port_idx fit into this?
> >
> > I think you were assuming there is only one remoteproc in the system?
> > In practice, the setup can look more like this:
> >
> > + remote_cm33{
> > +     rpmsg {
> > +        rpmsg-io-channel {
> > +          #address-cells = <1>;
> > +          #size-cells = <0>;
> > +
> > +          gpio@0 {
> > +            compatible = "rpmsg-gpio";
> > +            reg = <0>;
> > +            gpio-controller;
> > +            #gpio-cells = <2>;
> > +            #interrupt-cells = <2>;
> > +            interrupt-controller;
> > +          };
> > +          gpio@1 {
> > +            compatible = "rpmsg-gpio";
> > +            reg = <1>;
> > +            gpio-controller;
> > +            #gpio-cells = <2>;
> > +            #interrupt-cells = <2>;
> > +            interrupt-controller;
> > +          };
> > +  ...
> > +        };
> > +      };
> > +};
> > +
> > + remote_dsp {
> > +     rpmsg {
> > +        rpmsg-io-channel {
> > +          #address-cells = <1>;
> > +          #size-cells = <0>;
> > +
> > +          gpio@0 {
> > +            compatible = "rpmsg-gpio";
> > +            reg = <0>;
> > +            gpio-controller;
> > +            #gpio-cells = <2>;
> > +            #interrupt-cells = <2>;
> > +            interrupt-controller;
> > +          };
> > +  ...
> > +        };
> > +      };
> > +};
> 
> And why would this require a port_idx? If they are different rpmsg instances, the
> channel numbers are in different address spaces.
> 

Then how would you distinguish gpio@0 from gpio@1 on the CM33 RPMSG bus in the example above?
They are running on the same transport.

Thanks,
Shenwei

>         Andrew



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 21:12                               ` Shenwei Wang
@ 2026-02-24 22:14                                 ` Andrew Lunn
  2026-02-24 22:43                                   ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-24 22:14 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Mathieu Poirier, Bjorn Andersson, Arnaud POULIQUEN, Linus Walleij,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> Please explain how you would design your generic rpmsg-gpio driver which is derived
> From gpio-virtio?

We have already seen the virtio commands are pretty much identical to
what i suggested.

You could just replace virtqueue_add_sgs() with rpmsg_sendto() and
reimplement virtio_gpio_request_vq() to be the callback registered
with rpmsg_create_ept(). The rest of basic GPIO handling should not
need any changes at all.

Interrupt support does however need some changes. The
virtio_gpio_request_vq() replacement would need to see if the received
message indicates an interrupt and call the equivalent of
virtio_gpio_event_vq(), since rpmsg does not have a separate mechanism
to deliver interrupts, unlike rpmsg.

At a guess, 90% of the code would stay the same?

   Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [EXT] Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 21:18                                     ` [EXT] " Shenwei Wang
@ 2026-02-24 22:22                                       ` Andrew Lunn
  2026-02-24 22:31                                         ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Andrew Lunn @ 2026-02-24 22:22 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

> > > + remote_cm33{
> > > +     rpmsg {
> > > +        rpmsg-io-channel {
> > > +          #address-cells = <1>;
> > > +          #size-cells = <0>;
> > > +
> > > +          gpio@0 {
> > > +            compatible = "rpmsg-gpio";
> > > +            reg = <0>;
> > > +            gpio-controller;
> > > +            #gpio-cells = <2>;
> > > +            #interrupt-cells = <2>;
> > > +            interrupt-controller;
> > > +          };
> > > +          gpio@1 {
> > > +            compatible = "rpmsg-gpio";
> > > +            reg = <1>;
> > > +            gpio-controller;
> > > +            #gpio-cells = <2>;
> > > +            #interrupt-cells = <2>;
> > > +            interrupt-controller;
> > > +          };

> Then how would you distinguish gpio@0 from gpio@1 on the CM33 RPMSG bus in the example above?
> They are running on the same transport.

Doesn't reg indicate the channel number? gpio@0 is on rpmsg channel
0. gpio@1 is on channel 1? The reg value gets filled into struct
rpmsg_channel_info when the endpoints are created?

   Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 22:22                                       ` Andrew Lunn
@ 2026-02-24 22:31                                         ` Shenwei Wang
  2026-02-24 22:47                                           ` Mathieu Poirier
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-24 22:31 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Tuesday, February 24, 2026 4:23 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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: Re: [EXT] Re: [PATCH v8 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
> 
> 
> > > > + remote_cm33{
> > > > +     rpmsg {
> > > > +        rpmsg-io-channel {
> > > > +          #address-cells = <1>;
> > > > +          #size-cells = <0>;
> > > > +
> > > > +          gpio@0 {
> > > > +            compatible = "rpmsg-gpio";
> > > > +            reg = <0>;
> > > > +            gpio-controller;
> > > > +            #gpio-cells = <2>;
> > > > +            #interrupt-cells = <2>;
> > > > +            interrupt-controller;
> > > > +          };
> > > > +          gpio@1 {
> > > > +            compatible = "rpmsg-gpio";
> > > > +            reg = <1>;
> > > > +            gpio-controller;
> > > > +            #gpio-cells = <2>;
> > > > +            #interrupt-cells = <2>;
> > > > +            interrupt-controller;
> > > > +          };
> 
> > Then how would you distinguish gpio@0 from gpio@1 on the CM33 RPMSG bus
> in the example above?
> > They are running on the same transport.
> 
> Doesn't reg indicate the channel number? gpio@0 is on rpmsg channel 0. gpio@1
> is on channel 1? The reg value gets filled into struct rpmsg_channel_info when
> the endpoints are created?

There is only a single RPMSG channel for the CM33 remoteproc in this example-its name 
is "rpmsg-io-channel". As I mentioned above, both gpio@0 and gpio@1 run over this same transport. 
The transport here is the RPMSG channel, so multiple GPIO controllers share that channel.

Thanks,
Shenwei

> 
>    Andrew



^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 22:14                                 ` Andrew Lunn
@ 2026-02-24 22:43                                   ` Shenwei Wang
  2026-02-25 15:52                                     ` Bjorn Andersson
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-24 22:43 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Mathieu Poirier, Bjorn Andersson, Arnaud POULIQUEN, Linus Walleij,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Tuesday, February 24, 2026 4:15 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>; Bjorn Andersson
> <andersson@kernel.org>; Arnaud POULIQUEN
> <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > Please explain how you would design your generic rpmsg-gpio driver
> > which is derived From gpio-virtio?
> 
> We have already seen the virtio commands are pretty much identical to what i
> suggested.
> 
> You could just replace virtqueue_add_sgs() with rpmsg_sendto() and reimplement
> virtio_gpio_request_vq() to be the callback registered with rpmsg_create_ept().
> The rest of basic GPIO handling should not need any changes at all.
> 

Creating endpoints and calling rpmsg_sendto() is only a small part of the picture. You also 
need to manage the service announcement from the remote side and handle asynchronous 
notification messages. That entire flow is already implemented in the existing virtio_rpmsg_bus 
driver. Re‑implementing those pieces just to mimic gpio‑virtio over RPMSG would essentially 
mean reinventing the wheel without any real benefit.

Thanks,
Shenwei

> Interrupt support does however need some changes. The
> virtio_gpio_request_vq() replacement would need to see if the received message
> indicates an interrupt and call the equivalent of virtio_gpio_event_vq(), since
> rpmsg does not have a separate mechanism to deliver interrupts, unlike rpmsg.
> 
> At a guess, 90% of the code would stay the same?
> 
>    Andrew

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 22:31                                         ` Shenwei Wang
@ 2026-02-24 22:47                                           ` Mathieu Poirier
  2026-02-25 15:18                                             ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Mathieu Poirier @ 2026-02-24 22:47 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Andrew Lunn, Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Frank Li, Sascha Hauer, Shuah Khan,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Tue, 24 Feb 2026 at 15:32, Shenwei Wang <shenwei.wang@nxp.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Andrew Lunn <andrew@lunn.ch>
> > Sent: Tuesday, February 24, 2026 4:23 PM
> > To: Shenwei Wang <shenwei.wang@nxp.com>
> > Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier <mathieu.poirier@linaro.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: Re: [EXT] Re: [PATCH v8 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
> >
> >
> > > > > + remote_cm33{
> > > > > +     rpmsg {
> > > > > +        rpmsg-io-channel {
> > > > > +          #address-cells = <1>;
> > > > > +          #size-cells = <0>;
> > > > > +
> > > > > +          gpio@0 {
> > > > > +            compatible = "rpmsg-gpio";
> > > > > +            reg = <0>;
> > > > > +            gpio-controller;
> > > > > +            #gpio-cells = <2>;
> > > > > +            #interrupt-cells = <2>;
> > > > > +            interrupt-controller;
> > > > > +          };
> > > > > +          gpio@1 {
> > > > > +            compatible = "rpmsg-gpio";
> > > > > +            reg = <1>;
> > > > > +            gpio-controller;
> > > > > +            #gpio-cells = <2>;
> > > > > +            #interrupt-cells = <2>;
> > > > > +            interrupt-controller;
> > > > > +          };
> >
> > > Then how would you distinguish gpio@0 from gpio@1 on the CM33 RPMSG bus
> > in the example above?
> > > They are running on the same transport.
> >
> > Doesn't reg indicate the channel number? gpio@0 is on rpmsg channel 0. gpio@1
> > is on channel 1? The reg value gets filled into struct rpmsg_channel_info when
> > the endpoints are created?
>
> There is only a single RPMSG channel for the CM33 remoteproc in this example-its name
> is "rpmsg-io-channel". As I mentioned above, both gpio@0 and gpio@1 run over this same transport.
> The transport here is the RPMSG channel, so multiple GPIO controllers share that channel.
>

That is one of my main problem with this proposal - multiplexing
several GPIO controllers over the same RPMSG channel adds complexity.
RPMSG can already handle multiplexing via channels, use one RPMSG
channel per GPIO controller.

> Thanks,
> Shenwei
>
> >
> >    Andrew
>


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 22:47                                           ` Mathieu Poirier
@ 2026-02-25 15:18                                             ` Shenwei Wang
  0 siblings, 0 replies; 69+ messages in thread
From: Shenwei Wang @ 2026-02-25 15:18 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Andrew Lunn, Arnaud POULIQUEN, Linus Walleij, Bartosz Golaszewski,
	Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Frank Li, Sascha Hauer, Shuah Khan,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Mathieu Poirier <mathieu.poirier@linaro.org>
> Sent: Tuesday, February 24, 2026 4:47 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Andrew Lunn <andrew@lunn.ch>; Arnaud POULIQUEN
> <arnaud.pouliquen@foss.st.com>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > > -----Original Message-----
> > > From: Andrew Lunn <andrew@lunn.ch>
> > > Sent: Tuesday, February 24, 2026 4:23 PM
> > > To: Shenwei Wang <shenwei.wang@nxp.com>
> > > Cc: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>; 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>; Mathieu Poirier
> > > <mathieu.poirier@linaro.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: Re: [EXT] Re: [PATCH v8 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
> > >
> > >
> > > > > > + remote_cm33{
> > > > > > +     rpmsg {
> > > > > > +        rpmsg-io-channel {
> > > > > > +          #address-cells = <1>;
> > > > > > +          #size-cells = <0>;
> > > > > > +
> > > > > > +          gpio@0 {
> > > > > > +            compatible = "rpmsg-gpio";
> > > > > > +            reg = <0>;
> > > > > > +            gpio-controller;
> > > > > > +            #gpio-cells = <2>;
> > > > > > +            #interrupt-cells = <2>;
> > > > > > +            interrupt-controller;
> > > > > > +          };
> > > > > > +          gpio@1 {
> > > > > > +            compatible = "rpmsg-gpio";
> > > > > > +            reg = <1>;
> > > > > > +            gpio-controller;
> > > > > > +            #gpio-cells = <2>;
> > > > > > +            #interrupt-cells = <2>;
> > > > > > +            interrupt-controller;
> > > > > > +          };
> > >
> > > > Then how would you distinguish gpio@0 from gpio@1 on the CM33
> > > > RPMSG bus
> > > in the example above?
> > > > They are running on the same transport.
> > >
> > > Doesn't reg indicate the channel number? gpio@0 is on rpmsg channel
> > > 0. gpio@1 is on channel 1? The reg value gets filled into struct
> > > rpmsg_channel_info when the endpoints are created?
> >
> > There is only a single RPMSG channel for the CM33 remoteproc in this
> > example-its name is "rpmsg-io-channel". As I mentioned above, both gpio@0
> and gpio@1 run over this same transport.
> > The transport here is the RPMSG channel, so multiple GPIO controllers share
> that channel.
> >
> 
> That is one of my main problem with this proposal - multiplexing several GPIO
> controllers over the same RPMSG channel adds complexity.

Multiplexing multiple GPIO controllers over a single RPMSG channel does not inherently 
add complexity. Even if we implement a “one GPIO controller per RPMSG channel” model, 
the core logic in the driver remains essentially the same.

In fact, the current implementation already supports your preferred “one RPMSG channel 
per GPIO controller” approach through simple DTS configuration. For example:

+ remote_cm33{
+     rpmsg {
+        channel0 {    
+          gpio@0 {
+            compatible = "rpmsg-gpio";
+            reg = <0>;
+            gpio-controller;
+            #gpio-cells = <2>;
+            #interrupt-cells = <2>;
+            interrupt-controller;
+          };
+       };
+
+        channel1 {
+          gpio@1 {
+            compatible = "rpmsg-gpio";
+            reg = <1>;
+            gpio-controller;
+            #gpio-cells = <2>;
+            #interrupt-cells = <2>;
+            interrupt-controller;
+          };
+        };
+      };
+};
+

> RPMSG can already handle multiplexing via channels, use one RPMSG channel
> per GPIO controller.
> 
> > Thanks,
> > Shenwei
> >
> > >
> > >    Andrew
> >

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-24 22:43                                   ` Shenwei Wang
@ 2026-02-25 15:52                                     ` Bjorn Andersson
  2026-02-25 17:54                                       ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Bjorn Andersson @ 2026-02-25 15:52 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Andrew Lunn, Mathieu Poirier, Arnaud POULIQUEN, Linus Walleij,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Tue, Feb 24, 2026 at 10:43:06PM +0000, Shenwei Wang wrote:
> 
> 
> > -----Original Message-----
> > From: Andrew Lunn <andrew@lunn.ch>
> > Sent: Tuesday, February 24, 2026 4:15 PM
> > To: Shenwei Wang <shenwei.wang@nxp.com>
> > Cc: Mathieu Poirier <mathieu.poirier@linaro.org>; Bjorn Andersson
> > <andersson@kernel.org>; Arnaud POULIQUEN
> > <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > > Please explain how you would design your generic rpmsg-gpio driver
> > > which is derived From gpio-virtio?
> > 
> > We have already seen the virtio commands are pretty much identical to what i
> > suggested.
> > 
> > You could just replace virtqueue_add_sgs() with rpmsg_sendto() and reimplement
> > virtio_gpio_request_vq() to be the callback registered with rpmsg_create_ept().
> > The rest of basic GPIO handling should not need any changes at all.
> > 
> 
> Creating endpoints and calling rpmsg_sendto() is only a small part of the picture. You also 
> need to manage the service announcement from the remote side and handle asynchronous 
> notification messages. That entire flow is already implemented in the existing virtio_rpmsg_bus 
> driver. Re‑implementing those pieces just to mimic gpio‑virtio over RPMSG would essentially 
> mean reinventing the wheel without any real benefit.
> 

I can absolutely see a benefit to this, there are multiple different
rpmsg backends supported in Linux, so a gpio-rpmsg driver could be used
by any one of them.

I don't see this to be a case of "reinventing the wheel". Instead we
copy what looks to be a very functional wheel and make it fit rpmsg.
This will result in some "duplication", but rpmsg already provide the
life cycle management and has a clean send/callback interface, so there
shouldn't be any inventing...

Similarly, I'm guessing that there's a firmware-side implementation of
virtio-gpio in Zephyr, it should be straightforward to transplant this
to the rpmsg interface.

Regards,
Bjorn

> Thanks,
> Shenwei
> 
> > Interrupt support does however need some changes. The
> > virtio_gpio_request_vq() replacement would need to see if the received message
> > indicates an interrupt and call the equivalent of virtio_gpio_event_vq(), since
> > rpmsg does not have a separate mechanism to deliver interrupts, unlike rpmsg.
> > 
> > At a guess, 90% of the code would stay the same?
> > 
> >    Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-25 15:52                                     ` Bjorn Andersson
@ 2026-02-25 17:54                                       ` Shenwei Wang
  2026-02-25 19:43                                         ` Bjorn Andersson
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-25 17:54 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andrew Lunn, Mathieu Poirier, Arnaud POULIQUEN, Linus Walleij,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Bjorn Andersson <andersson@kernel.org>
> Sent: Wednesday, February 25, 2026 9:53 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Andrew Lunn <andrew@lunn.ch>; Mathieu Poirier
> <mathieu.poirier@linaro.org>; Arnaud POULIQUEN
> <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> On Tue, Feb 24, 2026 at 10:43:06PM +0000, Shenwei Wang wrote:
> >
> >
> > > -----Original Message-----
> > > From: Andrew Lunn <andrew@lunn.ch>
> > > Sent: Tuesday, February 24, 2026 4:15 PM
> > > To: Shenwei Wang <shenwei.wang@nxp.com>
> > > Cc: Mathieu Poirier <mathieu.poirier@linaro.org>; Bjorn Andersson
> > > <andersson@kernel.org>; Arnaud POULIQUEN
> > > <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg
> > > GPIO driver
> > > > Please explain how you would design your generic rpmsg-gpio driver
> > > > which is derived From gpio-virtio?
> > >
> > > We have already seen the virtio commands are pretty much identical
> > > to what i suggested.
> > >
> > > You could just replace virtqueue_add_sgs() with rpmsg_sendto() and
> > > reimplement
> > > virtio_gpio_request_vq() to be the callback registered with
> rpmsg_create_ept().
> > > The rest of basic GPIO handling should not need any changes at all.
> > >
> >
> > Creating endpoints and calling rpmsg_sendto() is only a small part of
> > the picture. You also need to manage the service announcement from the
> > remote side and handle asynchronous notification messages. That entire
> > flow is already implemented in the existing virtio_rpmsg_bus driver.
> > Re‑implementing those pieces just to mimic gpio‑virtio over RPMSG would
> essentially mean reinventing the wheel without any real benefit.
> >
> 
> I can absolutely see a benefit to this, there are multiple different rpmsg backends
> supported in Linux, so a gpio-rpmsg driver could be used by any one of them.
> 
> I don't see this to be a case of "reinventing the wheel". Instead we copy what
> looks to be a very functional wheel and make it fit rpmsg.
> This will result in some "duplication", but rpmsg already provide the life cycle
> management and has a clean send/callback interface, so there shouldn't be any
> inventing...
> 

Interesting — could you walk me through how you’d structure the driver with the new 
proposal? I’d like to see how you would layer it conceptually.

The current RPMSG solution:

     On Remoteprc                      On Linux
GPIOs -> RPMSG -> VIRTIO == VIRTIO -> RPMSG -> GPIO-RPMSG drivers

The VIRTIO solution:

     On Remoteprc                     On Linux
          GPIO -> VIRTIO == VIRTIO -> GPIO-VIRTIO driver

Your proposal:

     On Remoteprc                     On Linux
GPIOs -> RPMSG -> VIRTIO == VIRTIO -> ???

Thanks,
Shenwei

> Similarly, I'm guessing that there's a firmware-side implementation of virtio-gpio
> in Zephyr, it should be straightforward to transplant this to the rpmsg interface.
> 
> Regards,
> Bjorn
> 
> > Thanks,
> > Shenwei
> >
> > > Interrupt support does however need some changes. The
> > > virtio_gpio_request_vq() replacement would need to see if the
> > > received message indicates an interrupt and call the equivalent of
> > > virtio_gpio_event_vq(), since rpmsg does not have a separate mechanism to
> deliver interrupts, unlike rpmsg.
> > >
> > > At a guess, 90% of the code would stay the same?
> > >
> > >    Andrew

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-25 17:54                                       ` Shenwei Wang
@ 2026-02-25 19:43                                         ` Bjorn Andersson
  2026-02-25 20:31                                           ` Shenwei Wang
  0 siblings, 1 reply; 69+ messages in thread
From: Bjorn Andersson @ 2026-02-25 19:43 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Andrew Lunn, Mathieu Poirier, Arnaud POULIQUEN, Linus Walleij,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Wed, Feb 25, 2026 at 05:54:00PM +0000, Shenwei Wang wrote:
> 
> 
> > -----Original Message-----
> > From: Bjorn Andersson <andersson@kernel.org>
> > Sent: Wednesday, February 25, 2026 9:53 AM
> > To: Shenwei Wang <shenwei.wang@nxp.com>
> > Cc: Andrew Lunn <andrew@lunn.ch>; Mathieu Poirier
> > <mathieu.poirier@linaro.org>; Arnaud POULIQUEN
> > <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> > On Tue, Feb 24, 2026 at 10:43:06PM +0000, Shenwei Wang wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Andrew Lunn <andrew@lunn.ch>
> > > > Sent: Tuesday, February 24, 2026 4:15 PM
> > > > To: Shenwei Wang <shenwei.wang@nxp.com>
> > > > Cc: Mathieu Poirier <mathieu.poirier@linaro.org>; Bjorn Andersson
> > > > <andersson@kernel.org>; Arnaud POULIQUEN
> > > > <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg
> > > > GPIO driver
> > > > > Please explain how you would design your generic rpmsg-gpio driver
> > > > > which is derived From gpio-virtio?
> > > >
> > > > We have already seen the virtio commands are pretty much identical
> > > > to what i suggested.
> > > >
> > > > You could just replace virtqueue_add_sgs() with rpmsg_sendto() and
> > > > reimplement
> > > > virtio_gpio_request_vq() to be the callback registered with
> > rpmsg_create_ept().
> > > > The rest of basic GPIO handling should not need any changes at all.
> > > >
> > >
> > > Creating endpoints and calling rpmsg_sendto() is only a small part of
> > > the picture. You also need to manage the service announcement from the
> > > remote side and handle asynchronous notification messages. That entire
> > > flow is already implemented in the existing virtio_rpmsg_bus driver.
> > > Re‑implementing those pieces just to mimic gpio‑virtio over RPMSG would
> > essentially mean reinventing the wheel without any real benefit.
> > >
> > 
> > I can absolutely see a benefit to this, there are multiple different rpmsg backends
> > supported in Linux, so a gpio-rpmsg driver could be used by any one of them.
> > 
> > I don't see this to be a case of "reinventing the wheel". Instead we copy what
> > looks to be a very functional wheel and make it fit rpmsg.
> > This will result in some "duplication", but rpmsg already provide the life cycle
> > management and has a clean send/callback interface, so there shouldn't be any
> > inventing...
> > 
> 
> Interesting — could you walk me through how you’d structure the driver with the new 
> proposal? I’d like to see how you would layer it conceptually.
> 
> The current RPMSG solution:
> 
>      On Remoteprc                      On Linux
> GPIOs -> RPMSG -> VIRTIO == VIRTIO -> RPMSG -> GPIO-RPMSG drivers
> 
> The VIRTIO solution:
> 
>      On Remoteprc                     On Linux
>           GPIO -> VIRTIO == VIRTIO -> GPIO-VIRTIO driver
> 
> Your proposal:
> 
>      On Remoteprc                     On Linux
> GPIOs -> RPMSG -> VIRTIO == VIRTIO -> ???

What I'm suggesting is the following:

GPIOs -> RPMSG -> VIRTIO == VIRTIO -> RPMSG -> GPIO-RPMSG
       ^                                    ^
       \-----+------------------------------/
             |      
             |
With this interface on being directly derived from the existing protocol
(and likely the implementation as well) using gpio-virtio.

You can have multiple "GPIOs" (presumably a "bank" each) instances and
that will be reflected in having multiple "GPIO-RPMSG" instances.

I haven't made any attempts at implementing this, but it looks very
similar to gpio-virtio in concept and it looks very similar to the
exiting RPMSG tty in the sense of being a generic implementation.

To reach something functional on the Linux side it seems to be a matter
of taking the gpio-virtio driver, register a rpmsg_driver instead,
change _virtio_gpio_req() to use rpmsg_send(), and perform the actions
of virtio_gpio_event_vq() in the rpmsg_driver callback function.

Regards,
Bjorn

> 
> Thanks,
> Shenwei
> 
> > Similarly, I'm guessing that there's a firmware-side implementation of virtio-gpio
> > in Zephyr, it should be straightforward to transplant this to the rpmsg interface.
> > 
> > Regards,
> > Bjorn
> > 
> > > Thanks,
> > > Shenwei
> > >
> > > > Interrupt support does however need some changes. The
> > > > virtio_gpio_request_vq() replacement would need to see if the
> > > > received message indicates an interrupt and call the equivalent of
> > > > virtio_gpio_event_vq(), since rpmsg does not have a separate mechanism to
> > deliver interrupts, unlike rpmsg.
> > > >
> > > > At a guess, 90% of the code would stay the same?
> > > >
> > > >    Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-25 19:43                                         ` Bjorn Andersson
@ 2026-02-25 20:31                                           ` Shenwei Wang
  2026-02-25 21:02                                             ` Bjorn Andersson
  0 siblings, 1 reply; 69+ messages in thread
From: Shenwei Wang @ 2026-02-25 20:31 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andrew Lunn, Mathieu Poirier, Arnaud POULIQUEN, Linus Walleij,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski



> -----Original Message-----
> From: Bjorn Andersson <andersson@kernel.org>
> Sent: Wednesday, February 25, 2026 1:44 PM
> To: Shenwei Wang <shenwei.wang@nxp.com>
> Cc: Andrew Lunn <andrew@lunn.ch>; Mathieu Poirier
> <mathieu.poirier@linaro.org>; Arnaud POULIQUEN
> <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 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
> 
> 
> On Wed, Feb 25, 2026 at 05:54:00PM +0000, Shenwei Wang wrote:
> >
> >
> > > -----Original Message-----
> > > From: Bjorn Andersson <andersson@kernel.org>
> > > Sent: Wednesday, February 25, 2026 9:53 AM
> > > To: Shenwei Wang <shenwei.wang@nxp.com>
> > > Cc: Andrew Lunn <andrew@lunn.ch>; Mathieu Poirier
> > > <mathieu.poirier@linaro.org>; Arnaud POULIQUEN
> > > <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg
> > > GPIO driver On Tue, Feb 24, 2026 at 10:43:06PM +0000, Shenwei Wang
> wrote:
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Andrew Lunn <andrew@lunn.ch>
> > > > > Sent: Tuesday, February 24, 2026 4:15 PM
> > > > > To: Shenwei Wang <shenwei.wang@nxp.com>
> > > > > Cc: Mathieu Poirier <mathieu.poirier@linaro.org>; Bjorn
> > > > > Andersson <andersson@kernel.org>; Arnaud POULIQUEN
> > > > > <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg
> > > > > GPIO driver
> > > > > > Please explain how you would design your generic rpmsg-gpio
> > > > > > driver which is derived From gpio-virtio?
> > > > >
> > > > > We have already seen the virtio commands are pretty much
> > > > > identical to what i suggested.
> > > > >
> > > > > You could just replace virtqueue_add_sgs() with rpmsg_sendto()
> > > > > and reimplement
> > > > > virtio_gpio_request_vq() to be the callback registered with
> > > rpmsg_create_ept().
> > > > > The rest of basic GPIO handling should not need any changes at all.
> > > > >
> > > >
> > > > Creating endpoints and calling rpmsg_sendto() is only a small part
> > > > of the picture. You also need to manage the service announcement
> > > > from the remote side and handle asynchronous notification
> > > > messages. That entire flow is already implemented in the existing
> virtio_rpmsg_bus driver.
> > > > Re‑implementing those pieces just to mimic gpio‑virtio over RPMSG
> > > > would
> > > essentially mean reinventing the wheel without any real benefit.
> > > >
> > >
> > > I can absolutely see a benefit to this, there are multiple different
> > > rpmsg backends supported in Linux, so a gpio-rpmsg driver could be used by
> any one of them.
> > >
> > > I don't see this to be a case of "reinventing the wheel". Instead we
> > > copy what looks to be a very functional wheel and make it fit rpmsg.
> > > This will result in some "duplication", but rpmsg already provide
> > > the life cycle management and has a clean send/callback interface,
> > > so there shouldn't be any inventing...
> > >
> >
> > Interesting — could you walk me through how you’d structure the driver
> > with the new proposal? I’d like to see how you would layer it conceptually.
> >
> > The current RPMSG solution:
> >
> >      On Remoteprc                      On Linux
> > GPIOs -> RPMSG -> VIRTIO == VIRTIO -> RPMSG -> GPIO-RPMSG drivers
> >
> > The VIRTIO solution:
> >
> >      On Remoteprc                     On Linux
> >           GPIO -> VIRTIO == VIRTIO -> GPIO-VIRTIO driver
> >
> > Your proposal:
> >
> >      On Remoteprc                     On Linux
> > GPIOs -> RPMSG -> VIRTIO == VIRTIO -> ???
> 
> What I'm suggesting is the following:
> 
> GPIOs -> RPMSG -> VIRTIO == VIRTIO -> RPMSG -> GPIO-RPMSG
>        ^                                    ^
>        \-----+------------------------------/
>              |
>              |
> With this interface on being directly derived from the existing protocol (and likely
> the implementation as well) using gpio-virtio.
> 
> You can have multiple "GPIOs" (presumably a "bank" each) instances and that
> will be reflected in having multiple "GPIO-RPMSG" instances.
> 
> I haven't made any attempts at implementing this, but it looks very similar to
> gpio-virtio in concept and it looks very similar to the exiting RPMSG tty in the
> sense of being a generic implementation.
> 
> To reach something functional on the Linux side it seems to be a matter of taking
> the gpio-virtio driver, register a rpmsg_driver instead, change _virtio_gpio_req()
> to use rpmsg_send(), and perform the actions of virtio_gpio_event_vq() in the
> rpmsg_driver callback function.
> 

Thanks for the explanation. If I’m understanding correctly, what you’re suggesting is 
essentially a driver that merges the roles of a virtio_driver and an rpmsg_driver into a 
single source file. There may be opportunities for a few function reuse, but overall it 
would still result in a fairly distinct codebase.

Thanks,
Shenwei

> Regards,
> Bjorn
> 
> >
> > Thanks,
> > Shenwei
> >
> > > Similarly, I'm guessing that there's a firmware-side implementation
> > > of virtio-gpio in Zephyr, it should be straightforward to transplant this to the
> rpmsg interface.
> > >
> > > Regards,
> > > Bjorn
> > >
> > > > Thanks,
> > > > Shenwei
> > > >
> > > > > Interrupt support does however need some changes. The
> > > > > virtio_gpio_request_vq() replacement would need to see if the
> > > > > received message indicates an interrupt and call the equivalent
> > > > > of virtio_gpio_event_vq(), since rpmsg does not have a separate
> > > > > mechanism to
> > > deliver interrupts, unlike rpmsg.
> > > > >
> > > > > At a guess, 90% of the code would stay the same?
> > > > >
> > > > >    Andrew

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-25 20:31                                           ` Shenwei Wang
@ 2026-02-25 21:02                                             ` Bjorn Andersson
  2026-02-27  0:00                                               ` Linus Walleij
  0 siblings, 1 reply; 69+ messages in thread
From: Bjorn Andersson @ 2026-02-25 21:02 UTC (permalink / raw)
  To: Shenwei Wang
  Cc: Andrew Lunn, Mathieu Poirier, Arnaud POULIQUEN, Linus Walleij,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Wed, Feb 25, 2026 at 08:31:33PM +0000, Shenwei Wang wrote:
> 
> 
> > -----Original Message-----
> > From: Bjorn Andersson <andersson@kernel.org>
> > Sent: Wednesday, February 25, 2026 1:44 PM
> > To: Shenwei Wang <shenwei.wang@nxp.com>
> > Cc: Andrew Lunn <andrew@lunn.ch>; Mathieu Poirier
> > <mathieu.poirier@linaro.org>; Arnaud POULIQUEN
> > <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 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
> > 
> > 
> > On Wed, Feb 25, 2026 at 05:54:00PM +0000, Shenwei Wang wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Bjorn Andersson <andersson@kernel.org>
> > > > Sent: Wednesday, February 25, 2026 9:53 AM
> > > > To: Shenwei Wang <shenwei.wang@nxp.com>
> > > > Cc: Andrew Lunn <andrew@lunn.ch>; Mathieu Poirier
> > > > <mathieu.poirier@linaro.org>; Arnaud POULIQUEN
> > > > <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg
> > > > GPIO driver On Tue, Feb 24, 2026 at 10:43:06PM +0000, Shenwei Wang
> > wrote:
> > > > >
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Andrew Lunn <andrew@lunn.ch>
> > > > > > Sent: Tuesday, February 24, 2026 4:15 PM
> > > > > > To: Shenwei Wang <shenwei.wang@nxp.com>
> > > > > > Cc: Mathieu Poirier <mathieu.poirier@linaro.org>; Bjorn
> > > > > > Andersson <andersson@kernel.org>; Arnaud POULIQUEN
> > > > > > <arnaud.pouliquen@foss.st.com>; 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>; 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 v8 3/4] gpio: rpmsg: add generic rpmsg
> > > > > > GPIO driver
> > > > > > > Please explain how you would design your generic rpmsg-gpio
> > > > > > > driver which is derived From gpio-virtio?
> > > > > >
> > > > > > We have already seen the virtio commands are pretty much
> > > > > > identical to what i suggested.
> > > > > >
> > > > > > You could just replace virtqueue_add_sgs() with rpmsg_sendto()
> > > > > > and reimplement
> > > > > > virtio_gpio_request_vq() to be the callback registered with
> > > > rpmsg_create_ept().
> > > > > > The rest of basic GPIO handling should not need any changes at all.
> > > > > >
> > > > >
> > > > > Creating endpoints and calling rpmsg_sendto() is only a small part
> > > > > of the picture. You also need to manage the service announcement
> > > > > from the remote side and handle asynchronous notification
> > > > > messages. That entire flow is already implemented in the existing
> > virtio_rpmsg_bus driver.
> > > > > Re‑implementing those pieces just to mimic gpio‑virtio over RPMSG
> > > > > would
> > > > essentially mean reinventing the wheel without any real benefit.
> > > > >
> > > >
> > > > I can absolutely see a benefit to this, there are multiple different
> > > > rpmsg backends supported in Linux, so a gpio-rpmsg driver could be used by
> > any one of them.
> > > >
> > > > I don't see this to be a case of "reinventing the wheel". Instead we
> > > > copy what looks to be a very functional wheel and make it fit rpmsg.
> > > > This will result in some "duplication", but rpmsg already provide
> > > > the life cycle management and has a clean send/callback interface,
> > > > so there shouldn't be any inventing...
> > > >
> > >
> > > Interesting — could you walk me through how you’d structure the driver
> > > with the new proposal? I’d like to see how you would layer it conceptually.
> > >
> > > The current RPMSG solution:
> > >
> > >      On Remoteprc                      On Linux
> > > GPIOs -> RPMSG -> VIRTIO == VIRTIO -> RPMSG -> GPIO-RPMSG drivers
> > >
> > > The VIRTIO solution:
> > >
> > >      On Remoteprc                     On Linux
> > >           GPIO -> VIRTIO == VIRTIO -> GPIO-VIRTIO driver
> > >
> > > Your proposal:
> > >
> > >      On Remoteprc                     On Linux
> > > GPIOs -> RPMSG -> VIRTIO == VIRTIO -> ???
> > 
> > What I'm suggesting is the following:
> > 
> > GPIOs -> RPMSG -> VIRTIO == VIRTIO -> RPMSG -> GPIO-RPMSG
> >        ^                                    ^
> >        \-----+------------------------------/
> >              |
> >              |
> > With this interface on being directly derived from the existing protocol (and likely
> > the implementation as well) using gpio-virtio.
> > 
> > You can have multiple "GPIOs" (presumably a "bank" each) instances and that
> > will be reflected in having multiple "GPIO-RPMSG" instances.
> > 
> > I haven't made any attempts at implementing this, but it looks very similar to
> > gpio-virtio in concept and it looks very similar to the exiting RPMSG tty in the
> > sense of being a generic implementation.
> > 
> > To reach something functional on the Linux side it seems to be a matter of taking
> > the gpio-virtio driver, register a rpmsg_driver instead, change _virtio_gpio_req()
> > to use rpmsg_send(), and perform the actions of virtio_gpio_event_vq() in the
> > rpmsg_driver callback function.
> > 
> 
> Thanks for the explanation. If I’m understanding correctly, what you’re suggesting is 
> essentially a driver that merges the roles of a virtio_driver and an rpmsg_driver into a 
> single source file. There may be opportunities for a few function reuse, but overall it 
> would still result in a fairly distinct codebase.
> 

Most of the non-boilerplate code in gpio-virtio would be impacted by
differences between rpmsg and virtio. So combining the two
implementations in a single source file would add complexity to an
otherwise straightforward driver, only with trivial parts reused.

My expectation is that it will be better to just have two separate
drivers - but reuse all the design-work done in the gpio-virtio.

Regards,
Bjorn

> Thanks,
> Shenwei
> 
> > Regards,
> > Bjorn
> > 
> > >
> > > Thanks,
> > > Shenwei
> > >
> > > > Similarly, I'm guessing that there's a firmware-side implementation
> > > > of virtio-gpio in Zephyr, it should be straightforward to transplant this to the
> > rpmsg interface.
> > > >
> > > > Regards,
> > > > Bjorn
> > > >
> > > > > Thanks,
> > > > > Shenwei
> > > > >
> > > > > > Interrupt support does however need some changes. The
> > > > > > virtio_gpio_request_vq() replacement would need to see if the
> > > > > > received message indicates an interrupt and call the equivalent
> > > > > > of virtio_gpio_event_vq(), since rpmsg does not have a separate
> > > > > > mechanism to
> > > > deliver interrupts, unlike rpmsg.
> > > > > >
> > > > > > At a guess, 90% of the code would stay the same?
> > > > > >
> > > > > >    Andrew


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
  2026-02-25 21:02                                             ` Bjorn Andersson
@ 2026-02-27  0:00                                               ` Linus Walleij
  0 siblings, 0 replies; 69+ messages in thread
From: Linus Walleij @ 2026-02-27  0:00 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Shenwei Wang, Andrew Lunn, Mathieu Poirier, Arnaud POULIQUEN,
	Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
	Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org, dl-linux-imx,
	Bartosz Golaszewski

On Wed, Feb 25, 2026 at 10:02 PM Bjorn Andersson <andersson@kernel.org> wrote:

> > Thanks for the explanation. If I’m understanding correctly, what you’re suggesting is
> > essentially a driver that merges the roles of a virtio_driver and an rpmsg_driver into a
> > single source file. There may be opportunities for a few function reuse, but overall it
> > would still result in a fairly distinct codebase.
> >
>
> Most of the non-boilerplate code in gpio-virtio would be impacted by
> differences between rpmsg and virtio. So combining the two
> implementations in a single source file would add complexity to an
> otherwise straightforward driver, only with trivial parts reused.
>
> My expectation is that it will be better to just have two separate
> drivers - but reuse all the design-work done in the gpio-virtio.

I agree with Bjorn.

If there is indeed code to be reused, just create a library
module .c/.o/.h file and export the symbols. modprobe will
bring it in, Kconfig will configure it in if compiled in. One or the
other or both modules can use that. We do this
all over the place.

Yours,
Linus Walleij


^ permalink raw reply	[flat|nested] 69+ messages in thread

end of thread, other threads:[~2026-02-27  0:00 UTC | newest]

Thread overview: 69+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-12 21:36 [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform Shenwei Wang
2026-02-12 21:36 ` [PATCH v8 1/4] docs: driver-api: gpio: rpmsg gpio driver over rpmsg bus Shenwei Wang
2026-02-12 21:36 ` [PATCH v8 2/4] dt-bindings: remoteproc: imx_rproc: Add "rpmsg" subnode support Shenwei Wang
2026-02-12 21:36 ` [PATCH v8 3/4] gpio: rpmsg: add generic rpmsg GPIO driver Shenwei Wang
2026-02-18 10:20   ` Bartosz Golaszewski
2026-02-18 16:28     ` Shenwei Wang
2026-02-19  9:20   ` Arnaud POULIQUEN
2026-02-19 13:26     ` Andrew Lunn
2026-02-19 14:17       ` Shenwei Wang
2026-02-19 15:25         ` Andrew Lunn
2026-02-19 16:42           ` Shenwei Wang
2026-02-19 13:42     ` Andrew Lunn
2026-02-20  9:16       ` Arnaud POULIQUEN
2026-02-20 13:48         ` Andrew Lunn
2026-02-20 16:36           ` Shenwei Wang
2026-02-20 17:45             ` Andrew Lunn
2026-02-20 18:57               ` Shenwei Wang
2026-02-20 20:21                 ` Mathieu Poirier
2026-02-20 20:59                 ` Andrew Lunn
2026-02-22 14:48                 ` Linus Walleij
2026-02-23 14:24                   ` Arnaud POULIQUEN
2026-02-23 14:42                     ` Bjorn Andersson
2026-02-24 15:56                       ` Shenwei Wang
2026-02-24 16:04                         ` Daniel Baluta
2026-02-24 16:56                           ` Shenwei Wang
2026-02-24 18:09                         ` Mathieu Poirier
2026-02-24 20:16                           ` Shenwei Wang
2026-02-24 20:41                             ` Mathieu Poirier
2026-02-24 21:12                               ` Shenwei Wang
2026-02-24 22:14                                 ` Andrew Lunn
2026-02-24 22:43                                   ` Shenwei Wang
2026-02-25 15:52                                     ` Bjorn Andersson
2026-02-25 17:54                                       ` Shenwei Wang
2026-02-25 19:43                                         ` Bjorn Andersson
2026-02-25 20:31                                           ` Shenwei Wang
2026-02-25 21:02                                             ` Bjorn Andersson
2026-02-27  0:00                                               ` Linus Walleij
2026-02-23 20:33                     ` Shenwei Wang
2026-02-24  8:46                       ` Arnaud POULIQUEN
2026-02-24 16:05                         ` Shenwei Wang
2026-02-24 17:31                           ` Andrew Lunn
2026-02-24 17:54                             ` Shenwei Wang
2026-02-24 18:18                               ` Andrew Lunn
2026-02-24 19:51                                 ` Shenwei Wang
2026-02-24 21:01                                   ` Andrew Lunn
2026-02-24 21:18                                     ` [EXT] " Shenwei Wang
2026-02-24 22:22                                       ` Andrew Lunn
2026-02-24 22:31                                         ` Shenwei Wang
2026-02-24 22:47                                           ` Mathieu Poirier
2026-02-25 15:18                                             ` Shenwei Wang
2026-02-24 18:26                               ` Andrew Lunn
2026-02-24 20:33                                 ` Shenwei Wang
2026-02-24  9:37                       ` Linus Walleij
2026-02-19 20:04     ` Shenwei Wang
2026-02-19 20:50       ` Andrew Lunn
2026-02-19 21:12         ` Shenwei Wang
2026-02-20  9:12       ` Arnaud POULIQUEN
2026-02-20 15:47         ` Shenwei Wang
2026-02-20 16:19           ` Andrew Lunn
2026-02-20 17:09             ` Shenwei Wang
2026-02-20 17:42               ` Andrew Lunn
2026-02-20 19:09                 ` Shenwei Wang
2026-02-20 20:41                   ` Andrew Lunn
2026-02-19 21:13     ` Shenwei Wang
2026-02-20  9:32       ` Arnaud POULIQUEN
2026-02-20 15:12         ` Shenwei Wang
2026-02-12 21:36 ` [PATCH v8 4/4] arm64: dts: imx8ulp: Add rpmsg node under imx_rproc Shenwei Wang
2026-02-20  9:18 ` [PATCH v8 0/4] Enable Remote GPIO over RPMSG on i.MX Platform Daniel Baluta
2026-02-20 15:24   ` Shenwei Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox