Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0-only
0002 
0003 GPIO Aggregator
0004 ===============
0005 
0006 The GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as
0007 a new gpio_chip.  This supports the following use cases.
0008 
0009 
0010 Aggregating GPIOs using Sysfs
0011 -----------------------------
0012 
0013 GPIO controllers are exported to userspace using /dev/gpiochip* character
0014 devices.  Access control to these devices is provided by standard UNIX file
0015 system permissions, on an all-or-nothing basis: either a GPIO controller is
0016 accessible for a user, or it is not.
0017 
0018 The GPIO Aggregator provides access control for a set of one or more GPIOs, by
0019 aggregating them into a new gpio_chip, which can be assigned to a group or user
0020 using standard UNIX file ownership and permissions.  Furthermore, this
0021 simplifies and hardens exporting GPIOs to a virtual machine, as the VM can just
0022 grab the full GPIO controller, and no longer needs to care about which GPIOs to
0023 grab and which not, reducing the attack surface.
0024 
0025 Aggregated GPIO controllers are instantiated and destroyed by writing to
0026 write-only attribute files in sysfs.
0027 
0028     /sys/bus/platform/drivers/gpio-aggregator/
0029 
0030         "new_device" ...
0031                 Userspace may ask the kernel to instantiate an aggregated GPIO
0032                 controller by writing a string describing the GPIOs to
0033                 aggregate to the "new_device" file, using the format
0034 
0035                 .. code-block:: none
0036 
0037                     [<gpioA>] [<gpiochipB> <offsets>] ...
0038 
0039                 Where:
0040 
0041                     "<gpioA>" ...
0042                             is a GPIO line name,
0043 
0044                     "<gpiochipB>" ...
0045                             is a GPIO chip label, and
0046 
0047                     "<offsets>" ...
0048                             is a comma-separated list of GPIO offsets and/or
0049                             GPIO offset ranges denoted by dashes.
0050 
0051                 Example: Instantiate a new GPIO aggregator by aggregating GPIO
0052                 line 19 of "e6052000.gpio" and GPIO lines 20-21 of
0053                 "e6050000.gpio" into a new gpio_chip:
0054 
0055                 .. code-block:: sh
0056 
0057                     $ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device
0058 
0059         "delete_device" ...
0060                 Userspace may ask the kernel to destroy an aggregated GPIO
0061                 controller after use by writing its device name to the
0062                 "delete_device" file.
0063 
0064                 Example: Destroy the previously-created aggregated GPIO
0065                 controller, assumed to be "gpio-aggregator.0":
0066 
0067                 .. code-block:: sh
0068 
0069                     $ echo gpio-aggregator.0 > delete_device
0070 
0071 
0072 Generic GPIO Driver
0073 -------------------
0074 
0075 The GPIO Aggregator can also be used as a generic driver for a simple
0076 GPIO-operated device described in DT, without a dedicated in-kernel driver.
0077 This is useful in industrial control, and is not unlike e.g. spidev, which
0078 allows the user to communicate with an SPI device from userspace.
0079 
0080 Binding a device to the GPIO Aggregator is performed either by modifying the
0081 gpio-aggregator driver, or by writing to the "driver_override" file in Sysfs.
0082 
0083 Example: If "door" is a GPIO-operated device described in DT, using its own
0084 compatible value::
0085 
0086         door {
0087                 compatible = "myvendor,mydoor";
0088 
0089                 gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>,
0090                         <&gpio2 20 GPIO_ACTIVE_LOW>;
0091                 gpio-line-names = "open", "lock";
0092         };
0093 
0094 it can be bound to the GPIO Aggregator by either:
0095 
0096 1. Adding its compatible value to ``gpio_aggregator_dt_ids[]``,
0097 2. Binding manually using "driver_override":
0098 
0099 .. code-block:: sh
0100 
0101     $ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override
0102     $ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind
0103 
0104 After that, a new gpiochip "door" has been created:
0105 
0106 .. code-block:: sh
0107 
0108     $ gpioinfo door
0109     gpiochip12 - 2 lines:
0110             line   0:       "open"       unused   input  active-high
0111             line   1:       "lock"       unused   input  active-high