Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 1 | .. SPDX-License-Identifier: GPL-2.0-only |
| 2 | |
| 3 | GPIO Aggregator |
| 4 | =============== |
| 5 | |
| 6 | The GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as |
| 7 | a new gpio_chip. This supports the following use cases. |
| 8 | |
| 9 | |
| 10 | Aggregating GPIOs using Sysfs |
| 11 | ----------------------------- |
| 12 | |
| 13 | GPIO controllers are exported to userspace using /dev/gpiochip* character |
| 14 | devices. Access control to these devices is provided by standard UNIX file |
| 15 | system permissions, on an all-or-nothing basis: either a GPIO controller is |
| 16 | accessible for a user, or it is not. |
| 17 | |
| 18 | The GPIO Aggregator provides access control for a set of one or more GPIOs, by |
| 19 | aggregating them into a new gpio_chip, which can be assigned to a group or user |
| 20 | using standard UNIX file ownership and permissions. Furthermore, this |
| 21 | simplifies and hardens exporting GPIOs to a virtual machine, as the VM can just |
| 22 | grab the full GPIO controller, and no longer needs to care about which GPIOs to |
| 23 | grab and which not, reducing the attack surface. |
| 24 | |
| 25 | Aggregated GPIO controllers are instantiated and destroyed by writing to |
| 26 | write-only attribute files in sysfs. |
| 27 | |
| 28 | /sys/bus/platform/drivers/gpio-aggregator/ |
| 29 | |
| 30 | "new_device" ... |
| 31 | Userspace may ask the kernel to instantiate an aggregated GPIO |
| 32 | controller by writing a string describing the GPIOs to |
| 33 | aggregate to the "new_device" file, using the format |
| 34 | |
| 35 | .. code-block:: none |
| 36 | |
| 37 | [<gpioA>] [<gpiochipB> <offsets>] ... |
| 38 | |
| 39 | Where: |
| 40 | |
| 41 | "<gpioA>" ... |
| 42 | is a GPIO line name, |
| 43 | |
| 44 | "<gpiochipB>" ... |
| 45 | is a GPIO chip label, and |
| 46 | |
| 47 | "<offsets>" ... |
| 48 | is a comma-separated list of GPIO offsets and/or |
| 49 | GPIO offset ranges denoted by dashes. |
| 50 | |
| 51 | Example: Instantiate a new GPIO aggregator by aggregating GPIO |
| 52 | line 19 of "e6052000.gpio" and GPIO lines 20-21 of |
| 53 | "e6050000.gpio" into a new gpio_chip: |
| 54 | |
| 55 | .. code-block:: sh |
| 56 | |
| 57 | $ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device |
| 58 | |
| 59 | "delete_device" ... |
| 60 | Userspace may ask the kernel to destroy an aggregated GPIO |
| 61 | controller after use by writing its device name to the |
| 62 | "delete_device" file. |
| 63 | |
| 64 | Example: Destroy the previously-created aggregated GPIO |
| 65 | controller, assumed to be "gpio-aggregator.0": |
| 66 | |
| 67 | .. code-block:: sh |
| 68 | |
| 69 | $ echo gpio-aggregator.0 > delete_device |
| 70 | |
| 71 | |
| 72 | Generic GPIO Driver |
| 73 | ------------------- |
| 74 | |
| 75 | The GPIO Aggregator can also be used as a generic driver for a simple |
| 76 | GPIO-operated device described in DT, without a dedicated in-kernel driver. |
| 77 | This is useful in industrial control, and is not unlike e.g. spidev, which |
| 78 | allows the user to communicate with an SPI device from userspace. |
| 79 | |
| 80 | Binding a device to the GPIO Aggregator is performed either by modifying the |
| 81 | gpio-aggregator driver, or by writing to the "driver_override" file in Sysfs. |
| 82 | |
| 83 | Example: If "door" is a GPIO-operated device described in DT, using its own |
| 84 | compatible value:: |
| 85 | |
| 86 | door { |
| 87 | compatible = "myvendor,mydoor"; |
| 88 | |
| 89 | gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>, |
| 90 | <&gpio2 20 GPIO_ACTIVE_LOW>; |
| 91 | gpio-line-names = "open", "lock"; |
| 92 | }; |
| 93 | |
| 94 | it can be bound to the GPIO Aggregator by either: |
| 95 | |
| 96 | 1. Adding its compatible value to ``gpio_aggregator_dt_ids[]``, |
| 97 | 2. Binding manually using "driver_override": |
| 98 | |
| 99 | .. code-block:: sh |
| 100 | |
| 101 | $ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override |
| 102 | $ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind |
| 103 | |
| 104 | After that, a new gpiochip "door" has been created: |
| 105 | |
| 106 | .. code-block:: sh |
| 107 | |
| 108 | $ gpioinfo door |
| 109 | gpiochip12 - 2 lines: |
| 110 | line 0: "open" unused input active-high |
| 111 | line 1: "lock" unused input active-high |