sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget4/translations/zh_CN/admin-guide/gpio/gpio-aggregatormodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget4/translations/zh_TW/admin-guide/gpio/gpio-aggregatormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget4/translations/it_IT/admin-guide/gpio/gpio-aggregatormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget4/translations/ja_JP/admin-guide/gpio/gpio-aggregatormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget4/translations/ko_KR/admin-guide/gpio/gpio-aggregatormodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget4/translations/sp_SP/admin-guide/gpio/gpio-aggregatormodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h%SPDX-License-Identifier: GPL-2.0-onlyh]h%SPDX-License-Identifier: GPL-2.0-only}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhN/var/lib/git/docbuild/linux/Documentation/admin-guide/gpio/gpio-aggregator.rsthKubhsection)}(hhh](htitle)}(hGPIO Aggregatorh]hGPIO Aggregator}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hThe GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as a new gpio_chip. This supports the following use cases.h]hThe GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as a new gpio_chip. This supports the following use cases.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(hAggregating GPIOs using Sysfsh]hAggregating GPIOs using Sysfs}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhK ubh)}(hXGPIO 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.h]hXGPIO 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.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hXThe 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.h]hXThe 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.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hmAggregated GPIO controllers are instantiated and destroyed by writing to write-only attribute files in sysfs.h]hmAggregated GPIO controllers are instantiated and destroyed by writing to write-only attribute files in sysfs.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh block_quote)}(hX/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 [] [ ] ... Where: "" ... is a GPIO line name, "" ... is a GPIO chip label, and "" ... 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 h](h)}(h*/sys/bus/platform/drivers/gpio-aggregator/h]h*/sys/bus/platform/drivers/gpio-aggregator/}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubj)}(hX"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 [] [ ] ... Where: "" ... is a GPIO line name, "" ... is a GPIO chip label, and "" ... 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 h]hdefinition_list)}(hhh](hdefinition_list_item)}(hX"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 [] [ ] ... Where: "" ... is a GPIO line name, "" ... is a GPIO chip label, and "" ... 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 h](hterm)}(h"new_device" ...h]h“new_device” ...}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1j7hhhK9hj3ubh definition)}(hhh](h)}(hUserspace 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 formath]hUserspace 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}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjIubh literal_block)}(h%[] [ ] ...h]h%[] [ ] ...}hj\sbah}(h]h ]h"]h$]h&]hhforcelanguagenonehighlight_args}uh1jZhhhK#hjIubh)}(hWhere:h]hWhere:}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK'hjIubj)}(h"" ... is a GPIO line name, "" ... is a GPIO chip label, and "" ... is a comma-separated list of GPIO offsets and/or GPIO offset ranges denoted by dashes. h]j-)}(hhh](j2)}(h#"" ... is a GPIO line name, h](j8)}(h "" ...h]h“” ...}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j7hhhK*hjubjH)}(hhh]h)}(his a GPIO line name,h]his a GPIO line name,}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK*hjubah}(h]h ]h"]h$]h&]uh1jGhjubeh}(h]h ]h"]h$]h&]uh1j1hhhK*hjubj2)}(h,"" ... is a GPIO chip label, and h](j8)}(h"" ...h]h“” ...}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j7hhhK-hjubjH)}(hhh]h)}(his a GPIO chip label, andh]his a GPIO chip label, and}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK-hjubah}(h]h ]h"]h$]h&]uh1jGhjubeh}(h]h ]h"]h$]h&]uh1j1hhhK-hjubj2)}(hg"" ... is a comma-separated list of GPIO offsets and/or GPIO offset ranges denoted by dashes. h](j8)}(h"" ...h]h“” ...}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j7hhhK1hjubjH)}(hhh]h)}(hVis a comma-separated list of GPIO offsets and/or GPIO offset ranges denoted by dashes.h]hVis a comma-separated list of GPIO offsets and/or GPIO offset ranges denoted by dashes.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hjubah}(h]h ]h"]h$]h&]uh1jGhjubeh}(h]h ]h"]h$]h&]uh1j1hhhK1hjubeh}(h]h ]h"]h$]h&]uh1j,hj}ubah}(h]h ]h"]h$]h&]uh1jhhhK)hjIubh)}(hExample: 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:h]hExample: 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:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK3hjIubj[)}(h:$ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_deviceh]h:$ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device}hj+sbah}(h]h ]h"]h$]h&]hhjjjkshjm}uh1jZhhhK7hjIubeh}(h]h ]h"]h$]h&]uh1jGhj3ubeh}(h]h ]h"]h$]h&]uh1j1hhhK9hj.ubj2)}(hXG"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 h](j8)}(h"delete_device" ...h]h“delete_device” ...}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1j7hhhKFhjGubjH)}(hhh](h)}(hUserspace may ask the kernel to destroy an aggregated GPIO controller after use by writing its device name to the "delete_device" file.h]hUserspace may ask the kernel to destroy an aggregated GPIO controller after use by writing its device name to the “delete_device” file.}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK delete_deviceh]h($ echo gpio-aggregator.0 > delete_device}hjxsbah}(h]h ]h"]h$]h&]hhjjjkshjm}uh1jZhhhKChjYubeh}(h]h ]h"]h$]h&]uh1jGhjGubeh}(h]h ]h"]h$]h&]uh1j1hhhKFhj.ubeh}(h]h ]h"]h$]h&]uh1j,hj(ubah}(h]h ]h"]h$]h&]uh1jhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhhhKhhhhubeh}(h]aggregating-gpios-using-sysfsah ]h"]aggregating gpios using sysfsah$]h&]uh1hhhhhhhhK ubh)}(hhh](h)}(h Aggregating GPIOs using Configfsh]h Aggregating GPIOs using Configfs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKIubh)}(h&**Group:** ``/config/gpio-aggregator``h](hstrong)}(h **Group:**h]hGroup:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh }(hjhhhNhNubhliteral)}(h``/config/gpio-aggregator``h]h/config/gpio-aggregator}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1hhhhKKhjhhubj)}(hAThis is the root directory of the gpio-aggregator configfs tree. h]h)}(h@This is the root directory of the gpio-aggregator configfs tree.h]h@This is the root directory of the gpio-aggregator configfs tree.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKMhjubah}(h]h ]h"]h$]h&]uh1jhhhKMhjhhubh)}(h5**Group:** ``/config/gpio-aggregator/``h](j)}(h **Group:**h]hGroup:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh }(hjhhhNhNubj)}(h*``/config/gpio-aggregator/``h]h&/config/gpio-aggregator/}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1hhhhKOhjhhubj)}(hXThis directory represents a GPIO aggregator device. You can assign any name to ```` (e.g. ``agg0``), except names starting with ``_sysfs`` prefix, which are reserved for auto-generated configfs entries corresponding to devices created via Sysfs. h]h)}(hXThis directory represents a GPIO aggregator device. You can assign any name to ```` (e.g. ``agg0``), except names starting with ``_sysfs`` prefix, which are reserved for auto-generated configfs entries corresponding to devices created via Sysfs.h](hOThis directory represents a GPIO aggregator device. You can assign any name to }(hj3hhhNhNubj)}(h````h]h}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj3ubh (e.g. }(hj3hhhNhNubj)}(h``agg0``h]hagg0}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj3ubh), except names starting with }(hj3hhhNhNubj)}(h ``_sysfs``h]h_sysfs}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj3ubhk prefix, which are reserved for auto-generated configfs entries corresponding to devices created via Sysfs.}(hj3hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKQhj/ubah}(h]h ]h"]h$]h&]uh1jhhhKQhjhhubh)}(h>**Attribute:** ``/config/gpio-aggregator//live``h](j)}(h**Attribute:**h]h Attribute:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj}ubh }(hj}hhhNhNubj)}(h/``/config/gpio-aggregator//live``h]h+/config/gpio-aggregator//live}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj}ubeh}(h]h ]h"]h$]h&]uh1hhhhKVhjhhubj)}(hThe ``live`` attribute allows to trigger the actual creation of the device once it's fully configured. Accepted values are: * ``1``, ``yes``, ``true`` : enable the virtual device * ``0``, ``no``, ``false`` : disable the virtual device h](h)}(h{The ``live`` attribute allows to trigger the actual creation of the device once it's fully configured. Accepted values are:h](hThe }(hjhhhNhNubj)}(h``live``h]hlive}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhq attribute allows to trigger the actual creation of the device once it’s fully configured. Accepted values are:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKXhjubh bullet_list)}(hhh](h list_item)}(h4``1``, ``yes``, ``true`` : enable the virtual deviceh]h)}(hjh](j)}(h``1``h]h1}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, }(hjhhhNhNubj)}(h``yes``h]hyes}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, }hjsbj)}(h``true``h]htrue}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh : enable the virtual device}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK[hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(h6``0``, ``no``, ``false`` : disable the virtual device h]h)}(h5``0``, ``no``, ``false`` : disable the virtual deviceh](j)}(h``0``h]h0}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, }(hjhhhNhNubj)}(h``no``h]hno}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, }hjsbj)}(h ``false``h]hfalse}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh : disable the virtual device}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK\hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]bullet*uh1jhhhK[hjubeh}(h]h ]h"]h$]h&]uh1jhhhKXhjhhubh)}(hB**Attribute:** ``/config/gpio-aggregator//dev_name``h](j)}(h**Attribute:**h]h Attribute:}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjsubh }(hjshhhNhNubj)}(h3``/config/gpio-aggregator//dev_name``h]h//config/gpio-aggregator//dev_name}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjsubeh}(h]h ]h"]h$]h&]uh1hhhhK^hjhhubj)}(hXpThe read-only ``dev_name`` attribute exposes the name of the device as it will appear in the system on the platform bus (e.g. ``gpio-aggregator.0``). This is useful for identifying a character device for the newly created aggregator. If it's ``gpio-aggregator.0``, ``/sys/devices/platform/gpio-aggregator.0/gpiochipX`` path tells you that the GPIO device id is ``X``. h]h)}(hXoThe read-only ``dev_name`` attribute exposes the name of the device as it will appear in the system on the platform bus (e.g. ``gpio-aggregator.0``). This is useful for identifying a character device for the newly created aggregator. If it's ``gpio-aggregator.0``, ``/sys/devices/platform/gpio-aggregator.0/gpiochipX`` path tells you that the GPIO device id is ``X``.h](hThe read-only }(hjhhhNhNubj)}(h ``dev_name``h]hdev_name}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhd attribute exposes the name of the device as it will appear in the system on the platform bus (e.g. }(hjhhhNhNubj)}(h``gpio-aggregator.0``h]hgpio-aggregator.0}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubha). This is useful for identifying a character device for the newly created aggregator. If it’s }(hjhhhNhNubj)}(h``gpio-aggregator.0``h]hgpio-aggregator.0}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, }(hjhhhNhNubj)}(h5``/sys/devices/platform/gpio-aggregator.0/gpiochipX``h]h1/sys/devices/platform/gpio-aggregator.0/gpiochipX}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh+ path tells you that the GPIO device id is }(hjhhhNhNubj)}(h``X``h]hX}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK`hjubah}(h]h ]h"]h$]h&]uh1jhhhK`hjhhubh)}(hXYou must create subdirectories for each virtual line you want to instantiate, named exactly as ``line0``, ``line1``, ..., ``lineY``, when you want to instantiate ``Y+1`` (Y >= 0) lines. Configure all lines before activating the device by setting ``live`` to 1.h](h_You must create subdirectories for each virtual line you want to instantiate, named exactly as }(hjhhhNhNubj)}(h ``line0``h]hline0}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, }(hjhhhNhNubj)}(h ``line1``h]hline1}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, ..., }(hjhhhNhNubj)}(h ``lineY``h]hlineY}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, when you want to instantiate }(hjhhhNhNubj)}(h``Y+1``h]hY+1}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhN (Y >= 0) lines. Configure all lines before activating the device by setting }(hjhhhNhNubj)}(h``live``h]hlive}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh to 1.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKghjhhubh)}(h>**Group:** ``/config/gpio-aggregator///``h](j)}(h **Group:**h]hGroup:}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjwubh }(hjwhhhNhNubj)}(h3``/config/gpio-aggregator///``h]h//config/gpio-aggregator///}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjwubeh}(h]h ]h"]h$]h&]uh1hhhhKlhjhhubj)}(hDThis directory represents a GPIO line to include in the aggregator. h]h)}(hCThis directory represents a GPIO line to include in the aggregator.h]hCThis directory represents a GPIO line to include in the aggregator.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKnhjubah}(h]h ]h"]h$]h&]uh1jhhhKnhjhhubh)}(hE**Attribute:** ``/config/gpio-aggregator///key``h](j)}(h**Attribute:**h]h Attribute:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh }(hjhhhNhNubj)}(h6``/config/gpio-aggregator///key``h]h2/config/gpio-aggregator///key}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1hhhhKphjhhubh)}(hH**Attribute:** ``/config/gpio-aggregator///offset``h](j)}(h**Attribute:**h]h Attribute:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh }(hjhhhNhNubj)}(h9``/config/gpio-aggregator///offset``h]h5/config/gpio-aggregator///offset}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1hhhhKrhjhhubj)}(hXThe default values after creating the ```` directory are: * ``key`` : * ``offset`` : -1 ``key`` must always be explicitly configured, while ``offset`` depends. Two configuration patterns exist for each ````: (a). For lookup by GPIO line name: * Set ``key`` to the line name. * Ensure ``offset`` remains -1 (the default). (b). For lookup by GPIO chip name and the line offset within the chip: * Set ``key`` to the chip name. * Set ``offset`` to the line offset (0 <= ``offset`` < 65535). h](h)}(h@The default values after creating the ```` directory are:h](h&The default values after creating the }(hjhhhNhNubj)}(h ````h]h}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh directory are:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKthj ubj)}(hhh](j)}(h``key`` : h]h)}(hj6h](j)}(h``key``h]hkey}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj8ubh : }(hj8hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKvhj4ubah}(h]h ]h"]h$]h&]uh1jhj1ubj)}(h``offset`` : -1 h]h)}(h``offset`` : -1h](j)}(h ``offset``h]hoffset}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1jhj]ubh : -1}(hj]hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKwhjYubah}(h]h ]h"]h$]h&]uh1jhj1ubeh}(h]h ]h"]h$]h&]jkjluh1jhhhKvhj ubh)}(h~``key`` must always be explicitly configured, while ``offset`` depends. Two configuration patterns exist for each ````:h](j)}(h``key``h]hkey}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh- must always be explicitly configured, while }(hjhhhNhNubj)}(h ``offset``h]hoffset}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh4 depends. Two configuration patterns exist for each }(hjhhhNhNubj)}(h ````h]h}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKyhj ubh)}(h"(a). For lookup by GPIO line name:h]h"(a). For lookup by GPIO line name:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK|hj ubj)}(hN* Set ``key`` to the line name. * Ensure ``offset`` remains -1 (the default). h]j)}(hhh](j)}(hSet ``key`` to the line name.h]h)}(hjh](hSet }(hjhhhNhNubj)}(h``key``h]hkey}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh to the line name.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK~hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(h,Ensure ``offset`` remains -1 (the default). h]h)}(h+Ensure ``offset`` remains -1 (the default).h](hEnsure }(hjhhhNhNubj)}(h ``offset``h]hoffset}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh remains -1 (the default).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]jkjluh1jhhhK~hjubah}(h]h ]h"]h$]h&]uh1jhhhK~hj ubh)}(hF(b). For lookup by GPIO chip name and the line offset within the chip:h]hF(b). For lookup by GPIO chip name and the line offset within the chip:}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubj)}(h_* Set ``key`` to the chip name. * Set ``offset`` to the line offset (0 <= ``offset`` < 65535). h]j)}(hhh](j)}(hSet ``key`` to the chip name.h]h)}(hjPh](hSet }(hjRhhhNhNubj)}(h``key``h]hkey}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjRubh to the chip name.}(hjRhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjNubah}(h]h ]h"]h$]h&]uh1jhjKubj)}(h=Set ``offset`` to the line offset (0 <= ``offset`` < 65535). h]h)}(h//name``h](j)}(h**Attribute:**h]h Attribute:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh }(hjhhhNhNubj)}(h7``/config/gpio-aggregator///name``h]h3/config/gpio-aggregator///name}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hbThe ``name`` attribute sets a custom name for lineY. If left unset, the line will remain unnamed. h]h)}(haThe ``name`` attribute sets a custom name for lineY. If left unset, the line will remain unnamed.h](hThe }(hjhhhNhNubj)}(h``name``h]hname}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhU attribute sets a custom name for lineY. If left unset, the line will remain unnamed.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubh)}(hXOnce the configuration is done, the ``'live'`` attribute must be set to 1 in order to instantiate the aggregator device. It can be set back to 0 to destroy the virtual device. The module will synchronously wait for the new aggregator device to be successfully probed and if this doesn't happen, writing to ``'live'`` will result in an error. This is a different behaviour from the case when you create it using sysfs ``new_device`` interface.h](h$Once the configuration is done, the }(hjhhhNhNubj)}(h ``'live'``h]h'live'}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX attribute must be set to 1 in order to instantiate the aggregator device. It can be set back to 0 to destroy the virtual device. The module will synchronously wait for the new aggregator device to be successfully probed and if this doesn’t happen, writing to }(hjhhhNhNubj)}(h ``'live'``h]h'live'}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhe will result in an error. This is a different behaviour from the case when you create it using sysfs }(hjhhhNhNubj)}(h``new_device``h]h new_device}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh interface.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubhnote)}(hX"For aggregators created via Sysfs, the configfs entries are auto-generated and appear as ``/config/gpio-aggregator/_sysfs./``. You cannot add or remove line directories with mkdir(2)/rmdir(2). To modify lines, you must use the "delete_device" interface to tear down the existing device and reconfigure it from scratch. However, you can still toggle the aggregator with the ``live`` attribute and adjust the ``key``, ``offset``, and ``name`` attributes for each line when ``live`` is set to 0 by hand (i.e. it's not waiting for deferred probe).h]h)}(hX"For aggregators created via Sysfs, the configfs entries are auto-generated and appear as ``/config/gpio-aggregator/_sysfs./``. You cannot add or remove line directories with mkdir(2)/rmdir(2). To modify lines, you must use the "delete_device" interface to tear down the existing device and reconfigure it from scratch. However, you can still toggle the aggregator with the ``live`` attribute and adjust the ``key``, ``offset``, and ``name`` attributes for each line when ``live`` is set to 0 by hand (i.e. it's not waiting for deferred probe).h](hYFor aggregators created via Sysfs, the configfs entries are auto-generated and appear as }(hjchhhNhNubj)}(h'``/config/gpio-aggregator/_sysfs./``h]h#/config/gpio-aggregator/_sysfs./}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjcubh. You cannot add or remove line directories with mkdir(2)/rmdir(2). To modify lines, you must use the “delete_device” interface to tear down the existing device and reconfigure it from scratch. However, you can still toggle the aggregator with the }(hjchhhNhNubj)}(h``live``h]hlive}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjcubh attribute and adjust the }(hjchhhNhNubj)}(h``key``h]hkey}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjcubh, }(hjchhhNhNubj)}(h ``offset``h]hoffset}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjcubh, and }(hjchhhNhNubj)}(h``name``h]hname}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjcubh attributes for each line when }(hjchhhNhNubj)}(h``live``h]hlive}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjcubhB is set to 0 by hand (i.e. it’s not waiting for deferred probe).}(hjchhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj_ubah}(h]h ]h"]h$]h&]uh1j]hjhhhhhNubh)}(hhh](h)}(hSample configuration commandsh]hSample configuration commands}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubj[)}(hX# Create a directory for an aggregator device $ mkdir /sys/kernel/config/gpio-aggregator/agg0 # Configure each line $ mkdir /sys/kernel/config/gpio-aggregator/agg0/line0 $ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line0/key $ echo 6 > /sys/kernel/config/gpio-aggregator/agg0/line0/offset $ echo test0 > /sys/kernel/config/gpio-aggregator/agg0/line0/name $ mkdir /sys/kernel/config/gpio-aggregator/agg0/line1 $ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line1/key $ echo 7 > /sys/kernel/config/gpio-aggregator/agg0/line1/offset $ echo test1 > /sys/kernel/config/gpio-aggregator/agg0/line1/name # Activate the aggregator device $ echo 1 > /sys/kernel/config/gpio-aggregator/agg0/liveh]hX# Create a directory for an aggregator device $ mkdir /sys/kernel/config/gpio-aggregator/agg0 # Configure each line $ mkdir /sys/kernel/config/gpio-aggregator/agg0/line0 $ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line0/key $ echo 6 > /sys/kernel/config/gpio-aggregator/agg0/line0/offset $ echo test0 > /sys/kernel/config/gpio-aggregator/agg0/line0/name $ mkdir /sys/kernel/config/gpio-aggregator/agg0/line1 $ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line1/key $ echo 7 > /sys/kernel/config/gpio-aggregator/agg0/line1/offset $ echo test1 > /sys/kernel/config/gpio-aggregator/agg0/line1/name # Activate the aggregator device $ echo 1 > /sys/kernel/config/gpio-aggregator/agg0/live}hjsbah}(h]h ]h"]h$]h&]hhjjjkshjm}uh1jZhhhKhjhhubeh}(h]sample-configuration-commandsah ]h"]sample configuration commandsah$]h&]uh1hhjhhhhhKubeh}(h] aggregating-gpios-using-configfsah ]h"] aggregating gpios using configfsah$]h&]uh1hhhhhhhhKIubh)}(hhh](h)}(hGeneric GPIO Driverh]hGeneric GPIO Driver}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hXThe 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.h]hXThe 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.}(hj% hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hBinding 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.h]hBinding 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.}(hj3 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(h^Example: If "door" is a GPIO-operated device described in DT, using its own compatible value::h]haExample: If “door” is a GPIO-operated device described in DT, using its own compatible value:}(hjA hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj[)}(hdoor { compatible = "myvendor,mydoor"; gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>, <&gpio2 20 GPIO_ACTIVE_LOW>; gpio-line-names = "open", "lock"; };h]hdoor { compatible = "myvendor,mydoor"; gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>, <&gpio2 20 GPIO_ACTIVE_LOW>; gpio-line-names = "open", "lock"; };}hjO sbah}(h]h ]h"]h$]h&]hhuh1jZhhhKhj hhubh)}(h1it can be bound to the GPIO Aggregator by either:h]h1it can be bound to the GPIO Aggregator by either:}(hj] hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubhenumerated_list)}(hhh](j)}(h /sys/bus/platform/devices/door/driver_override $ echo door > /sys/bus/platform/drivers/gpio-aggregator/bindh]h$ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override $ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind}hj sbah}(h]h ]h"]h$]h&]hhjjjkshjm}uh1jZhhhKhj hhubh)}(h3After that, a new gpiochip "door" has been created:h]h7After that, a new gpiochip “door” has been created:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj[)}(h$ gpioinfo door gpiochip12 - 2 lines: line 0: "open" unused input active-high line 1: "lock" unused input active-highh]h$ gpioinfo door gpiochip12 - 2 lines: line 0: "open" unused input active-high line 1: "lock" unused input active-high}hj sbah}(h]h ]h"]h$]h&]hhjjjkshjm}uh1jZhhhKhj hhubeh}(h]generic-gpio-driverah ]h"]generic gpio driverah$]h&]uh1hhhhhhhhKubeh}(h]gpio-aggregatorah ]h"]gpio aggregatorah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(j j jjj j j j j j u nametypes}(j jj j j uh}(j hjhj jj jj j u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.