* [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
* 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 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-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: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 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 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: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 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 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: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 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 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 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 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 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: [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: [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: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
* 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-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: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 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 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 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: [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: [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: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 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: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-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-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 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-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 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 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 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-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 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: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
* [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 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 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
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