diff options
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/admin-guide/gpio/gpio-aggregator.rst | 111 | ||||
-rw-r--r-- | Documentation/admin-guide/gpio/index.rst | 1 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/gpio/renesas,em-gio.yaml | 70 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml | 134 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt | 65 | ||||
-rw-r--r-- | Documentation/driver-api/gpio/board.rst | 15 |
6 files changed, 326 insertions, 70 deletions
diff --git a/Documentation/admin-guide/gpio/gpio-aggregator.rst b/Documentation/admin-guide/gpio/gpio-aggregator.rst new file mode 100644 index 000000000000..5cd1e7221756 --- /dev/null +++ b/Documentation/admin-guide/gpio/gpio-aggregator.rst @@ -0,0 +1,111 @@ +.. 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 diff --git a/Documentation/admin-guide/gpio/index.rst b/Documentation/admin-guide/gpio/index.rst index a244ba4e87d5..ef2838638e96 100644 --- a/Documentation/admin-guide/gpio/index.rst +++ b/Documentation/admin-guide/gpio/index.rst @@ -7,6 +7,7 @@ gpio .. toctree:: :maxdepth: 1 + gpio-aggregator sysfs .. only:: subproject and html diff --git a/Documentation/devicetree/bindings/gpio/renesas,em-gio.yaml b/Documentation/devicetree/bindings/gpio/renesas,em-gio.yaml new file mode 100644 index 000000000000..8bdef812c87c --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/renesas,em-gio.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/renesas,em-gio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas EMMA Mobile General Purpose I/O Interface + +maintainers: + - Magnus Damm <magnus.damm@gmail.com> + +properties: + compatible: + const: renesas,em-gio + + reg: + items: + - description: First set of contiguous registers + - description: Second set of contiguous registers + + interrupts: + items: + - description: Interrupt for the first set of 16 GPIO ports + - description: Interrupt for the second set of 16 GPIO ports + + gpio-controller: true + + '#gpio-cells': + const: 2 + + gpio-ranges: + maxItems: 1 + + ngpios: + minimum: 1 + maximum: 32 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + +required: + - compatible + - reg + - interrupts + - gpio-controller + - '#gpio-cells' + - gpio-ranges + - ngpios + - interrupt-controller + - '#interrupt-cells' + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + gpio0: gpio@e0050000 { + compatible = "renesas,em-gio"; + reg = <0xe0050000 0x2c>, <0xe0050040 0x20>; + interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pfc 0 0 32>; + ngpios = <32>; + interrupt-controller; + #interrupt-cells = <2>; + }; diff --git a/Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml b/Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml new file mode 100644 index 000000000000..04a3c51e1dc1 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml @@ -0,0 +1,134 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/snps,dw-apb-gpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synopsys DesignWare APB GPIO controller + +description: | + Synopsys DesignWare GPIO controllers have a configurable number of ports, + each of which are intended to be represented as child nodes with the generic + GPIO-controller properties as desribed in this bindings file. + +maintainers: + - Hoan Tran <hoan@os.amperecomputing.com> + - Serge Semin <fancer.lancer@gmail.com> + +properties: + $nodename: + pattern: "^gpio@[0-9a-f]+$" + + compatible: + const: snps,dw-apb-gpio + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + reg: + maxItems: 1 + + clocks: + minItems: 1 + items: + - description: APB interface clock source + - description: DW GPIO debounce reference clock source + + clock-names: + minItems: 1 + items: + - const: bus + - const: db + + resets: + maxItems: 1 + +patternProperties: + "^gpio-(port|controller)@[0-9a-f]+$": + type: object + properties: + compatible: + const: snps,dw-apb-gpio-port + + reg: + maxItems: 1 + + gpio-controller: true + + '#gpio-cells': + const: 2 + + snps,nr-gpios: + description: The number of GPIO pins exported by the port. + default: 32 + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - minimum: 1 + maximum: 32 + + interrupts: + description: | + The interrupts to the parent controller raised when GPIOs generate + the interrupts. If the controller provides one combined interrupt + for all GPIOs, specify a single interrupt. If the controller provides + one interrupt for each GPIO, provide a list of interrupts that + correspond to each of the GPIO pins. + minItems: 1 + maxItems: 32 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + + required: + - compatible + - reg + - gpio-controller + - '#gpio-cells' + + dependencies: + interrupt-controller: [ interrupts ] + + additionalProperties: false + +additionalProperties: false + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + +examples: + - | + gpio: gpio@20000 { + compatible = "snps,dw-apb-gpio"; + reg = <0x20000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + porta: gpio-port@0 { + compatible = "snps,dw-apb-gpio-port"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <8>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&vic1>; + interrupts = <0>; + }; + + portb: gpio-port@1 { + compatible = "snps,dw-apb-gpio-port"; + reg = <1>; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <8>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt deleted file mode 100644 index 839dd32ffe11..000000000000 --- a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt +++ /dev/null @@ -1,65 +0,0 @@ -* Synopsys DesignWare APB GPIO controller - -Required properties: -- compatible : Should contain "snps,dw-apb-gpio" -- reg : Address and length of the register set for the device. -- #address-cells : should be 1 (for addressing port subnodes). -- #size-cells : should be 0 (port subnodes). - -The GPIO controller has a configurable number of ports, each of which are -represented as child nodes with the following properties: - -Required properties: -- compatible : "snps,dw-apb-gpio-port" -- gpio-controller : Marks the device node as a gpio controller. -- #gpio-cells : Should be two. The first cell is the pin number and - the second cell is used to specify the gpio polarity: - 0 = active high - 1 = active low -- reg : The integer port index of the port, a single cell. - -Optional properties: -- interrupt-controller : The first port may be configured to be an interrupt -controller. -- #interrupt-cells : Specifies the number of cells needed to encode an - interrupt. Shall be set to 2. The first cell defines the interrupt number, - the second encodes the triger flags encoded as described in - Documentation/devicetree/bindings/interrupt-controller/interrupts.txt -- interrupts : The interrupts to the parent controller raised when GPIOs - generate the interrupts. If the controller provides one combined interrupt - for all GPIOs, specify a single interrupt. If the controller provides one - interrupt for each GPIO, provide a list of interrupts that correspond to each - of the GPIO pins. When specifying multiple interrupts, if any are unconnected, - use the interrupts-extended property to specify the interrupts and set the - interrupt controller handle for unused interrupts to 0. -- snps,nr-gpios : The number of pins in the port, a single cell. -- resets : Reset line for the controller. - -Example: - -gpio: gpio@20000 { - compatible = "snps,dw-apb-gpio"; - reg = <0x20000 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - - porta: gpio@0 { - compatible = "snps,dw-apb-gpio-port"; - gpio-controller; - #gpio-cells = <2>; - snps,nr-gpios = <8>; - reg = <0>; - interrupt-controller; - #interrupt-cells = <2>; - interrupt-parent = <&vic1>; - interrupts = <0>; - }; - - portb: gpio@1 { - compatible = "snps,dw-apb-gpio-port"; - gpio-controller; - #gpio-cells = <2>; - snps,nr-gpios = <8>; - reg = <1>; - }; -}; diff --git a/Documentation/driver-api/gpio/board.rst b/Documentation/driver-api/gpio/board.rst index ce91518bf9f4..191fa867826a 100644 --- a/Documentation/driver-api/gpio/board.rst +++ b/Documentation/driver-api/gpio/board.rst @@ -113,13 +113,15 @@ files that desire to do so need to include the following header:: GPIOs are mapped by the means of tables of lookups, containing instances of the gpiod_lookup structure. Two macros are defined to help declaring such mappings:: - GPIO_LOOKUP(chip_label, chip_hwnum, con_id, flags) - GPIO_LOOKUP_IDX(chip_label, chip_hwnum, con_id, idx, flags) + GPIO_LOOKUP(key, chip_hwnum, con_id, flags) + GPIO_LOOKUP_IDX(key, chip_hwnum, con_id, idx, flags) where - - chip_label is the label of the gpiod_chip instance providing the GPIO - - chip_hwnum is the hardware number of the GPIO within the chip + - key is either the label of the gpiod_chip instance providing the GPIO, or + the GPIO line name + - chip_hwnum is the hardware number of the GPIO within the chip, or U16_MAX + to indicate that key is a GPIO line name - con_id is the name of the GPIO function from the device point of view. It can be NULL, in which case it will match any function. - idx is the index of the GPIO within the function. @@ -135,7 +137,10 @@ where In the future, these flags might be extended to support more properties. -Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0. +Note that: + 1. GPIO line names are not guaranteed to be globally unique, so the first + match found will be used. + 2. GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0. A lookup table can then be defined as follows, with an empty entry defining its end. The 'dev_id' field of the table is the identifier of the device that will |