Document the GPIO Aggregator, and the two typical use-cases. Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Tested-by: Eugeniu Rosca <erosca@de.adit-jv.com> Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu> Reviewed-by: Eugeniu Rosca <erosca@de.adit-jv.com> Link: https://lore.kernel.org/r/20200511145257.22970-6-geert+renesas@glider.be Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
		
			
				
	
	
		
			112 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| .. SPDX-License-Identifier: GPL-2.0-only
 | |
| 
 | |
| GPIO Aggregator
 | |
| ===============
 | |
| 
 | |
| The GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as
 | |
| a new gpio_chip.  This supports the following use cases.
 | |
| 
 | |
| 
 | |
| Aggregating GPIOs using Sysfs
 | |
| -----------------------------
 | |
| 
 | |
| GPIO controllers are exported to userspace using /dev/gpiochip* character
 | |
| devices.  Access control to these devices is provided by standard UNIX file
 | |
| system permissions, on an all-or-nothing basis: either a GPIO controller is
 | |
| accessible for a user, or it is not.
 | |
| 
 | |
| The GPIO Aggregator provides access control for a set of one or more GPIOs, by
 | |
| aggregating them into a new gpio_chip, which can be assigned to a group or user
 | |
| using standard UNIX file ownership and permissions.  Furthermore, this
 | |
| simplifies and hardens exporting GPIOs to a virtual machine, as the VM can just
 | |
| grab the full GPIO controller, and no longer needs to care about which GPIOs to
 | |
| grab and which not, reducing the attack surface.
 | |
| 
 | |
| Aggregated GPIO controllers are instantiated and destroyed by writing to
 | |
| write-only attribute files in sysfs.
 | |
| 
 | |
|     /sys/bus/platform/drivers/gpio-aggregator/
 | |
| 
 | |
| 	"new_device" ...
 | |
| 		Userspace may ask the kernel to instantiate an aggregated GPIO
 | |
| 		controller by writing a string describing the GPIOs to
 | |
| 		aggregate to the "new_device" file, using the format
 | |
| 
 | |
| 		.. code-block:: none
 | |
| 
 | |
| 		    [<gpioA>] [<gpiochipB> <offsets>] ...
 | |
| 
 | |
| 		Where:
 | |
| 
 | |
| 		    "<gpioA>" ...
 | |
| 			    is a GPIO line name,
 | |
| 
 | |
| 		    "<gpiochipB>" ...
 | |
| 			    is a GPIO chip label, and
 | |
| 
 | |
| 		    "<offsets>" ...
 | |
| 			    is a comma-separated list of GPIO offsets and/or
 | |
| 			    GPIO offset ranges denoted by dashes.
 | |
| 
 | |
| 		Example: Instantiate a new GPIO aggregator by aggregating GPIO
 | |
| 		line 19 of "e6052000.gpio" and GPIO lines 20-21 of
 | |
| 		"e6050000.gpio" into a new gpio_chip:
 | |
| 
 | |
| 		.. code-block:: sh
 | |
| 
 | |
| 		    $ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device
 | |
| 
 | |
| 	"delete_device" ...
 | |
| 		Userspace may ask the kernel to destroy an aggregated GPIO
 | |
| 		controller after use by writing its device name to the
 | |
| 		"delete_device" file.
 | |
| 
 | |
| 		Example: Destroy the previously-created aggregated GPIO
 | |
| 		controller, assumed to be "gpio-aggregator.0":
 | |
| 
 | |
| 		.. code-block:: sh
 | |
| 
 | |
| 		    $ echo gpio-aggregator.0 > delete_device
 | |
| 
 | |
| 
 | |
| Generic GPIO Driver
 | |
| -------------------
 | |
| 
 | |
| The GPIO Aggregator can also be used as a generic driver for a simple
 | |
| GPIO-operated device described in DT, without a dedicated in-kernel driver.
 | |
| This is useful in industrial control, and is not unlike e.g. spidev, which
 | |
| allows the user to communicate with an SPI device from userspace.
 | |
| 
 | |
| Binding a device to the GPIO Aggregator is performed either by modifying the
 | |
| gpio-aggregator driver, or by writing to the "driver_override" file in Sysfs.
 | |
| 
 | |
| Example: If "door" is a GPIO-operated device described in DT, using its own
 | |
| compatible value::
 | |
| 
 | |
| 	door {
 | |
| 		compatible = "myvendor,mydoor";
 | |
| 
 | |
| 		gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>,
 | |
| 			<&gpio2 20 GPIO_ACTIVE_LOW>;
 | |
| 		gpio-line-names = "open", "lock";
 | |
| 	};
 | |
| 
 | |
| it can be bound to the GPIO Aggregator by either:
 | |
| 
 | |
| 1. Adding its compatible value to ``gpio_aggregator_dt_ids[]``,
 | |
| 2. Binding manually using "driver_override":
 | |
| 
 | |
| .. code-block:: sh
 | |
| 
 | |
|     $ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override
 | |
|     $ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind
 | |
| 
 | |
| After that, a new gpiochip "door" has been created:
 | |
| 
 | |
| .. code-block:: sh
 | |
| 
 | |
|     $ gpioinfo door
 | |
|     gpiochip12 - 2 lines:
 | |
| 	    line   0:       "open"       unused   input  active-high
 | |
| 	    line   1:       "lock"       unused   input  active-high
 |