Describes the gpio rpmsg transport protocol over the rpmsg bus between
the cores.
Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
---
Documentation/staging/gpio-rpmsg.rst | 202 +++++++++++++++++++++++++++
Documentation/staging/index.rst | 1 +
2 files changed, 203 insertions(+)
create mode 100644 Documentation/staging/gpio-rpmsg.rst
diff --git a/Documentation/staging/gpio-rpmsg.rst b/Documentation/staging/gpio-rpmsg.rst
new file mode 100644
index 000000000000..ad6207a3093f
--- /dev/null
+++ b/Documentation/staging/gpio-rpmsg.rst
@@ -0,0 +1,202 @@
+.. 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|
+ |cate |major |minor |type |cmd |reserved[5] |line |port | data |
+ +-----+------+------+-----+-----+------------+-----+-----+-----+----+
+
+- **Cate (Category field)**: Indicates the category of the message, such as GPIO, I2C, PMIC, AUDIO, etc.
+
+ Defined categories:
+
+ - 1: RPMSG_LIFECYCLE
+ - 2: RPMSG_PMIC
+ - 3: RPMSG_AUDIO
+ - 4: RPMSG_KEY
+ - 5: RPMSG_GPIO
+ - 6: RPMSG_RTC
+ - 7: RPMSG_SENSOR
+ - 8: RPMSG_AUTO
+ - 9: RPMSG_CATEGORY
+ - A: RPMSG_PWM
+ - B: RPMSG_UART
+
+- **Major**: Major version number.
+
+- **Minor**: Minor version number.
+
+- **Type (Message Type)**: For the GPIO category, 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.
+
+- **line**: The GPIO line index.
+
+- **port**: The GPIO controller index.
+
+GPIO Commands
+-------------
+
+Commands are specified in the **Cmd** field for **GPIO_RPMSG_SETUP** (Type=0) messages.
+
+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.
+
+ - 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
+ - 3: Resource not available
+ - 4: Resource busy
+ - 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
+
+Notification Message
+--------------------
+
+Notifications are sent with **Type=2 (GPIO_RPMSG_NOTIFY)**:
+
+.. code-block:: none
+
+ +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+ |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D|
+ | 5 | 1 | 0 | 2 | 0 | 0 |line |port | 0 | 0 |
+ +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+
+
+- **line**: The GPIO line index.
+- **port**: The GPIO controller index.
+
diff --git a/Documentation/staging/index.rst b/Documentation/staging/index.rst
index 77bae5e5328b..fbb212e26007 100644
--- a/Documentation/staging/index.rst
+++ b/Documentation/staging/index.rst
@@ -7,6 +7,7 @@ Unsorted Documentation
:maxdepth: 2
crc32
+ gpio-rpmsg
lzo
magic-number
remoteproc
--
2.43.0
On Tue, Nov 04, 2025 at 02:33:13PM -0600, Shenwei Wang wrote: > Describes the gpio rpmsg transport protocol over the rpmsg bus between > the cores. > > Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com> > --- > Documentation/staging/gpio-rpmsg.rst | 202 +++++++++++++++++++++++++++ > Documentation/staging/index.rst | 1 + Why is this in staging when none of the drivers are? Rob
On Wed, Nov 12, 2025 at 2:59 PM Rob Herring <robh@kernel.org> wrote: > > On Tue, Nov 04, 2025 at 02:33:13PM -0600, Shenwei Wang wrote: > > Describes the gpio rpmsg transport protocol over the rpmsg bus between > > the cores. > > > > Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com> > > --- > > Documentation/staging/gpio-rpmsg.rst | 202 +++++++++++++++++++++++++++ > > Documentation/staging/index.rst | 1 + > > Why is this in staging when none of the drivers are? I guess that's because remoteproc.rst and rpmsg.rst are in Documentation/staging and that's because when converting them from .txt to .rst the author didn't know a good place where to move them. Would Documentation/driver-api be a good place for these doc files? I can move them and then Shenwei place the gpio-rpmsg.rst in the Documentation/driver-api also Daniel.
On 11/12/25 5:35 AM, Daniel Baluta wrote: > On Wed, Nov 12, 2025 at 2:59 PM Rob Herring <robh@kernel.org> wrote: >> >> On Tue, Nov 04, 2025 at 02:33:13PM -0600, Shenwei Wang wrote: >>> Describes the gpio rpmsg transport protocol over the rpmsg bus between >>> the cores. >>> >>> Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com> >>> --- >>> Documentation/staging/gpio-rpmsg.rst | 202 +++++++++++++++++++++++++++ >>> Documentation/staging/index.rst | 1 + >> >> Why is this in staging when none of the drivers are? > > I guess that's because remoteproc.rst and rpmsg.rst are in Documentation/staging > and that's because when converting them from .txt to .rst the author > didn't know a > good place where to move them. > > Would Documentation/driver-api be a good place for these doc files? I > can move them > and then Shenwei place the gpio-rpmsg.rst in the Documentation/driver-api also Documentation/driver-api/gpio/ if its driver documentation. Documentation/userspace-api/gpio/ if it user API docs There is also gpio documentation in Documentation/admin-guide/gpio/ which could also be appropriate depending on the nature of the document. -- ~Randy
Hi Shenwei, thanks for your patch! Also, a big thanks for working on improving the standardization of rpmsg so we can get some order here. This is very important work. On Tue, Nov 4, 2025 at 9:34 PM Shenwei Wang <shenwei.wang@nxp.com> wrote: > +- **Major**: Major version number. > + > +- **Minor**: Minor version number. I'm not contesting these if they come from similar fields in other rpmsg devices. What I'm thinking is that the driver will eventually have to quirk around bugs in the responding rpmsg CPU, and there will be bugs. This can end up with this situation: major,minor = (1,2) NXP implementation, no bug major,minor = (1,2) Sharp implementation, no bug major,minor = (1,2) Sony implementation, ooops this has a bug What is the driver going to do here to work around that bug? The scheme kind of suppose that all vendors use the same codebase and they don't. I would rather have: **Vendor**: Vendor ID number (such as the PCI or USB ID) **Version**: Vendor-specific version number (such as SW release) This will make it possible to identify buggy firmware and apply quirks. My apologies if the rpmsg community has already thought about this. Bjorns input would be appreciated! Yours, Linus Walleij
On Tue, Nov 04, 2025 at 02:33:13PM -0600, Shenwei Wang wrote: > Describes the gpio rpmsg transport protocol over the rpmsg bus between > the cores. > > Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com> > --- > Documentation/staging/gpio-rpmsg.rst | 202 +++++++++++++++++++++++++++ > Documentation/staging/index.rst | 1 + > 2 files changed, 203 insertions(+) > create mode 100644 Documentation/staging/gpio-rpmsg.rst > > diff --git a/Documentation/staging/gpio-rpmsg.rst b/Documentation/staging/gpio-rpmsg.rst > new file mode 100644 > index 000000000000..ad6207a3093f > --- /dev/null > +++ b/Documentation/staging/gpio-rpmsg.rst > @@ -0,0 +1,202 @@ > +.. 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| > + |cate |major |minor |type |cmd |reserved[5] |line |port | data | > + +-----+------+------+-----+-----+------------+-----+-----+-----+----+ > + > +- **Cate (Category field)**: Indicates the category of the message, such as GPIO, I2C, PMIC, AUDIO, etc. We know it is a GPIO message, this document is titled "GPIO RPMSG Protocol". So i don't see the need for cate. I can however understand that your device does support multiple functions, but to make this generic, it would be better if each function had its own channel. > + > + Defined categories: > + > + - 1: RPMSG_LIFECYCLE > + - 2: RPMSG_PMIC > + - 3: RPMSG_AUDIO > + - 4: RPMSG_KEY > + - 5: RPMSG_GPIO > + - 6: RPMSG_RTC > + - 7: RPMSG_SENSOR > + - 8: RPMSG_AUTO > + - 9: RPMSG_CATEGORY > + - A: RPMSG_PWM > + - B: RPMSG_UART > + > +- **Major**: Major version number. > + > +- **Minor**: Minor version number. What is the purpose of Major and Minor? What values are valid. What should happen if an invalid value is passed? What you should think about is, if you gave this specification to somebody else, could they implement it? > + > +- **Type (Message Type)**: For the GPIO category, can be one of: > + > + - 0: GPIO_RPMSG_SETUP > + - 1: GPIO_RPMSG_REPLY > + - 2: GPIO_RPMSG_NOTIFY Is _SETUP always from Linux to the firmware? Is a setup always followed by a _REPLY? Do you need to wait for the _REPLY before sending the next _SETUP? If there is no _REPLY within X seconds, should Linux retry? Can an _NOTIFY arrive between a _SETUP and a _REPLY? > + > +- **Cmd**: Command code, used for GPIO_RPMSG_SETUP messages. > + > +- **reserved[5]**: Reserved bytes. Why are these in the middle. It is more normal to have reserved bytes at the end. You should also specify these bytes should be set to 0. If you don't it will be hard to use them in the future, because they will contain 42, or some other random values. Is there a relationship between major:minor and reserved? > + > +- **line**: The GPIO line index. > + > +- **port**: The GPIO controller index. data? > +GPIO Commands > +------------- This is a GPIO specification, so i would only expect GPIO commands... > + > +Commands are specified in the **Cmd** field for **GPIO_RPMSG_SETUP** (Type=0) messages. > + > +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. > + > + - 0: Disable wakeup from GPIO > + - 1: Enable wakeup from GPIO What do you mean by wakeup? > + > +**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 > + - 3: Resource not available > + - 4: Resource busy > + - 5: Parameter error It would be good to give some examples of when these should be used. Say the hardware does not support both edges. Is that 2? Why would a resource be busy? How is busy different to not available? > + > +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 Maybe make a comment about the order. Some GPIO controllers suffer from glitches when you swap them from input to output. While it is an input, you first need to set the output value, and then configure the pin for output. > +Notification Message > +-------------------- > + > +Notifications are sent with **Type=2 (GPIO_RPMSG_NOTIFY)**: > + > +.. code-block:: none > + > + +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+ > + |0x00 |0x01 |0x02 |0x03 |0x04 |0x05..0x09 |0x0A |0x0B |0x0C |0x0D| > + | 5 | 1 | 0 | 2 | 0 | 0 |line |port | 0 | 0 | > + +-----+-----+-----+-----+-----+-----------+-----+-----+-----+----+ > + > +- **line**: The GPIO line index. > +- **port**: The GPIO controller index. There is no need to acknowledge the notification? How do level interrupts work? Andrew
© 2016 - 2025 Red Hat, Inc.