gpio-aggregator.rst 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. .. SPDX-License-Identifier: GPL-2.0-only
  2. GPIO Aggregator
  3. ===============
  4. The GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as
  5. a new gpio_chip. This supports the following use cases.
  6. Aggregating GPIOs using Sysfs
  7. -----------------------------
  8. GPIO controllers are exported to userspace using /dev/gpiochip* character
  9. devices. Access control to these devices is provided by standard UNIX file
  10. system permissions, on an all-or-nothing basis: either a GPIO controller is
  11. accessible for a user, or it is not.
  12. The GPIO Aggregator provides access control for a set of one or more GPIOs, by
  13. aggregating them into a new gpio_chip, which can be assigned to a group or user
  14. using standard UNIX file ownership and permissions. Furthermore, this
  15. simplifies and hardens exporting GPIOs to a virtual machine, as the VM can just
  16. grab the full GPIO controller, and no longer needs to care about which GPIOs to
  17. grab and which not, reducing the attack surface.
  18. Aggregated GPIO controllers are instantiated and destroyed by writing to
  19. write-only attribute files in sysfs.
  20. /sys/bus/platform/drivers/gpio-aggregator/
  21. "new_device" ...
  22. Userspace may ask the kernel to instantiate an aggregated GPIO
  23. controller by writing a string describing the GPIOs to
  24. aggregate to the "new_device" file, using the format
  25. .. code-block:: none
  26. [<gpioA>] [<gpiochipB> <offsets>] ...
  27. Where:
  28. "<gpioA>" ...
  29. is a GPIO line name,
  30. "<gpiochipB>" ...
  31. is a GPIO chip label, and
  32. "<offsets>" ...
  33. is a comma-separated list of GPIO offsets and/or
  34. GPIO offset ranges denoted by dashes.
  35. Example: Instantiate a new GPIO aggregator by aggregating GPIO
  36. line 19 of "e6052000.gpio" and GPIO lines 20-21 of
  37. "e6050000.gpio" into a new gpio_chip:
  38. .. code-block:: sh
  39. $ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device
  40. "delete_device" ...
  41. Userspace may ask the kernel to destroy an aggregated GPIO
  42. controller after use by writing its device name to the
  43. "delete_device" file.
  44. Example: Destroy the previously-created aggregated GPIO
  45. controller, assumed to be "gpio-aggregator.0":
  46. .. code-block:: sh
  47. $ echo gpio-aggregator.0 > delete_device
  48. Aggregating GPIOs using Configfs
  49. --------------------------------
  50. **Group:** ``/config/gpio-aggregator``
  51. This is the root directory of the gpio-aggregator configfs tree.
  52. **Group:** ``/config/gpio-aggregator/<example-name>``
  53. This directory represents a GPIO aggregator device. You can assign any
  54. name to ``<example-name>`` (e.g. ``agg0``), except names starting with
  55. ``_sysfs`` prefix, which are reserved for auto-generated configfs
  56. entries corresponding to devices created via Sysfs.
  57. **Attribute:** ``/config/gpio-aggregator/<example-name>/live``
  58. The ``live`` attribute allows to trigger the actual creation of the device
  59. once it's fully configured. Accepted values are:
  60. * ``1``, ``yes``, ``true`` : enable the virtual device
  61. * ``0``, ``no``, ``false`` : disable the virtual device
  62. **Attribute:** ``/config/gpio-aggregator/<example-name>/dev_name``
  63. The read-only ``dev_name`` attribute exposes the name of the device as it
  64. will appear in the system on the platform bus (e.g. ``gpio-aggregator.0``).
  65. This is useful for identifying a character device for the newly created
  66. aggregator. If it's ``gpio-aggregator.0``,
  67. ``/sys/devices/platform/gpio-aggregator.0/gpiochipX`` path tells you that the
  68. GPIO device id is ``X``.
  69. You must create subdirectories for each virtual line you want to
  70. instantiate, named exactly as ``line0``, ``line1``, ..., ``lineY``, when
  71. you want to instantiate ``Y+1`` (Y >= 0) lines. Configure all lines before
  72. activating the device by setting ``live`` to 1.
  73. **Group:** ``/config/gpio-aggregator/<example-name>/<lineY>/``
  74. This directory represents a GPIO line to include in the aggregator.
  75. **Attribute:** ``/config/gpio-aggregator/<example-name>/<lineY>/key``
  76. **Attribute:** ``/config/gpio-aggregator/<example-name>/<lineY>/offset``
  77. The default values after creating the ``<lineY>`` directory are:
  78. * ``key`` : <empty>
  79. * ``offset`` : -1
  80. ``key`` must always be explicitly configured, while ``offset`` depends.
  81. Two configuration patterns exist for each ``<lineY>``:
  82. (a). For lookup by GPIO line name:
  83. * Set ``key`` to the line name.
  84. * Ensure ``offset`` remains -1 (the default).
  85. (b). For lookup by GPIO chip name and the line offset within the chip:
  86. * Set ``key`` to the chip name.
  87. * Set ``offset`` to the line offset (0 <= ``offset`` < 65535).
  88. **Attribute:** ``/config/gpio-aggregator/<example-name>/<lineY>/name``
  89. The ``name`` attribute sets a custom name for lineY. If left unset, the
  90. line will remain unnamed.
  91. Once the configuration is done, the ``'live'`` attribute must be set to 1
  92. in order to instantiate the aggregator device. It can be set back to 0 to
  93. destroy the virtual device. The module will synchronously wait for the new
  94. aggregator device to be successfully probed and if this doesn't happen, writing
  95. to ``'live'`` will result in an error. This is a different behaviour from the
  96. case when you create it using sysfs ``new_device`` interface.
  97. .. note::
  98. For aggregators created via Sysfs, the configfs entries are
  99. auto-generated and appear as ``/config/gpio-aggregator/_sysfs.<N>/``. You
  100. cannot add or remove line directories with mkdir(2)/rmdir(2). To modify
  101. lines, you must use the "delete_device" interface to tear down the
  102. existing device and reconfigure it from scratch. However, you can still
  103. toggle the aggregator with the ``live`` attribute and adjust the
  104. ``key``, ``offset``, and ``name`` attributes for each line when ``live``
  105. is set to 0 by hand (i.e. it's not waiting for deferred probe).
  106. Sample configuration commands
  107. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  108. .. code-block:: sh
  109. # Create a directory for an aggregator device
  110. $ mkdir /sys/kernel/config/gpio-aggregator/agg0
  111. # Configure each line
  112. $ mkdir /sys/kernel/config/gpio-aggregator/agg0/line0
  113. $ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line0/key
  114. $ echo 6 > /sys/kernel/config/gpio-aggregator/agg0/line0/offset
  115. $ echo test0 > /sys/kernel/config/gpio-aggregator/agg0/line0/name
  116. $ mkdir /sys/kernel/config/gpio-aggregator/agg0/line1
  117. $ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line1/key
  118. $ echo 7 > /sys/kernel/config/gpio-aggregator/agg0/line1/offset
  119. $ echo test1 > /sys/kernel/config/gpio-aggregator/agg0/line1/name
  120. # Activate the aggregator device
  121. $ echo 1 > /sys/kernel/config/gpio-aggregator/agg0/live
  122. Generic GPIO Driver
  123. -------------------
  124. The GPIO Aggregator can also be used as a generic driver for a simple
  125. GPIO-operated device described in DT, without a dedicated in-kernel driver.
  126. This is useful in industrial control, and is not unlike e.g. spidev, which
  127. allows the user to communicate with an SPI device from userspace.
  128. Binding a device to the GPIO Aggregator is performed either by modifying the
  129. gpio-aggregator driver, or by writing to the "driver_override" file in Sysfs.
  130. Example: If "door" is a GPIO-operated device described in DT, using its own
  131. compatible value::
  132. door {
  133. compatible = "myvendor,mydoor";
  134. gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>,
  135. <&gpio2 20 GPIO_ACTIVE_LOW>;
  136. gpio-line-names = "open", "lock";
  137. };
  138. it can be bound to the GPIO Aggregator by either:
  139. 1. Adding its compatible value to ``gpio_aggregator_dt_ids[]``,
  140. 2. Binding manually using "driver_override":
  141. .. code-block:: sh
  142. $ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override
  143. $ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind
  144. After that, a new gpiochip "door" has been created:
  145. .. code-block:: sh
  146. $ gpioinfo door
  147. gpiochip12 - 2 lines:
  148. line 0: "open" unused input active-high
  149. line 1: "lock" unused input active-high