€•ÜMŒsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ4/translations/zh_CN/admin-guide/gpio/gpio-aggregator”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ4/translations/zh_TW/admin-guide/gpio/gpio-aggregator”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ4/translations/it_IT/admin-guide/gpio/gpio-aggregator”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ4/translations/ja_JP/admin-guide/gpio/gpio-aggregator”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ4/translations/ko_KR/admin-guide/gpio/gpio-aggregator”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ4/translations/sp_SP/admin-guide/gpio/gpio-aggregator”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)”}”(hŒ%SPDX-License-Identifier: GPL-2.0-only”h]”hŒ%SPDX-License-Identifier: GPL-2.0-only”…””}”hh£sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1h¡hhhžhhŸŒN/var/lib/git/docbuild/linux/Documentation/admin-guide/gpio/gpio-aggregator.rst”h KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒGPIO Aggregator”h]”hŒGPIO Aggregator”…””}”(hh»hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hh¶hžhhŸh³h KubhŒ paragraph”“”)”}”(hŒˆThe GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as a new gpio_chip. This supports the following use cases.”h]”hŒˆThe GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as a new gpio_chip. This supports the following use cases.”…””}”(hhËhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khh¶hžhubhµ)”}”(hhh]”(hº)”}”(hŒAggregating GPIOs using Sysfs”h]”hŒAggregating GPIOs using Sysfs”…””}”(hhÜhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hhÙhžhhŸh³h K 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.”…””}”(hhêhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K hhÙhžhubhÊ)”}”(hX¶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.”h]”hX¶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.”…””}”(hhøhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KhhÙhžhubhÊ)”}”(hŒmAggregated GPIO controllers are instantiated and destroyed by writing to write-only attribute files in sysfs.”h]”hŒmAggregated GPIO controllers are instantiated and destroyed by writing to write-only attribute files in sysfs.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KhhÙhžhubhŒ 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/”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khjubj)”}”(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]”hŒdefinition_list”“”)”}”(hhh]”(hŒdefinition_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]”(hŒterm”“”)”}”(hŒ"new_device" ...”h]”hŒ“new_device†...”…””}”(hj9hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j7hŸh³h K9hj3ubhŒ definition”“”)”}”(hhh]”(hÊ)”}”(hŒª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”h]”hŒ®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”…””}”(hjLhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KhjIubhŒ literal_block”“”)”}”(hŒ%[] [ ] ...”h]”hŒ%[] [ ] ...”…””}”hj\sbah}”(h]”h ]”h"]”h$]”h&]”h±h²Œforce”‰Œlanguage”Œnone”Œhighlight_args”}”uh1jZhŸh³h K#hjIubhÊ)”}”(hŒWhere:”h]”hŒWhere:”…””}”(hjohžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K'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ŒҠ...”…””}”(hjˆhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j7hŸh³h K*hj„ubjH)”}”(hhh]”hÊ)”}”(hŒis a GPIO line name,”h]”hŒis a GPIO line name,”…””}”(hj™hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K*hj–ubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhj„ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j1hŸh³h K*hjubj2)”}”(hŒ,"" ... is a GPIO chip label, and ”h]”(j8)”}”(hŒ"" ...”h]”hŒҠ...”…””}”(hj·hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j7hŸh³h K-hj³ubjH)”}”(hhh]”hÊ)”}”(hŒis a GPIO chip label, and”h]”hŒis a GPIO chip label, and”…””}”(hjÈhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K-hjÅubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhj³ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j1hŸh³h K-hjubj2)”}”(hŒg"" ... is a comma-separated list of GPIO offsets and/or GPIO offset ranges denoted by dashes. ”h]”(j8)”}”(hŒ"" ...”h]”hŒҠ...”…””}”(hjæhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j7hŸh³h K1hjâubjH)”}”(hhh]”hÊ)”}”(hŒVis a comma-separated list of GPIO offsets and/or GPIO offset ranges denoted by dashes.”h]”hŒVis a comma-separated list of GPIO offsets and/or GPIO offset ranges denoted by dashes.”…””}”(hj÷hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K0hjôubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhjâubeh}”(h]”h ]”h"]”h$]”h&]”uh1j1hŸh³h K1hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j,hj}ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhŸh³h K)hjIubhÊ)”}”(hŒ—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:”h]”hŒŸ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:”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K3hjIubj[)”}”(hŒ:$ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device”h]”hŒ:$ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device”…””}”hj+sbah}”(h]”h ]”h"]”h$]”h&]”h±h²jj‰jkŒsh”jm}”uh1jZhŸh³h K7hjIubeh}”(h]”h ]”h"]”h$]”h&]”uh1jGhj3ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j1hŸh³h K9hj.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†...”…””}”(hjKhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j7hŸh³h KFhjGubjH)”}”(hhh]”(hÊ)”}”(hŒ‡Userspace may ask the kernel to destroy an aggregated GPIO controller after use by writing its device name to the "delete_device" file.”h]”hŒ‹Userspace may ask the kernel to destroy an aggregated GPIO controller after use by writing its device name to the “delete_device†file.”…””}”(hj\hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K delete_device”h]”hŒ($ echo gpio-aggregator.0 > delete_device”…””}”hjxsbah}”(h]”h ]”h"]”h$]”h&]”h±h²jj‰jkŒsh”jm}”uh1jZhŸh³h KChjYubeh}”(h]”h ]”h"]”h$]”h&]”uh1jGhjGubeh}”(h]”h ]”h"]”h$]”h&]”uh1j1hŸh³h KFhj.ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j,hj(ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhŸh³h Khjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhŸh³h KhhÙhžhubeh}”(h]”Œaggregating-gpios-using-sysfs”ah ]”h"]”Œaggregating gpios using sysfs”ah$]”h&]”uh1h´hh¶hžhhŸh³h K ubhµ)”}”(hhh]”(hº)”}”(hŒGeneric GPIO Driver”h]”hŒGeneric GPIO Driver”…””}”(hj±hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hj®hžhhŸh³h KIubhÊ)”}”(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¿hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KKhj®hžhubhÊ)”}”(hŒš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.”h]”hŒž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.”…””}”(hjÍhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KPhj®hžhubhÊ)”}”(hŒ^Example: If "door" is a GPIO-operated device described in DT, using its own compatible value::”h]”hŒaExample: If “door†is a GPIO-operated device described in DT, using its own compatible value:”…””}”(hjÛhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KShj®hžhubj[)”}”(hŒ·door { compatible = "myvendor,mydoor"; gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>, <&gpio2 20 GPIO_ACTIVE_LOW>; gpio-line-names = "open", "lock"; };”h]”hŒ·door { compatible = "myvendor,mydoor"; gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>, <&gpio2 20 GPIO_ACTIVE_LOW>; gpio-line-names = "open", "lock"; };”…””}”hjésbah}”(h]”h ]”h"]”h$]”h&]”h±h²uh1jZhŸh³h KVhj®hžhubhÊ)”}”(hŒ1it can be bound to the GPIO Aggregator by either:”h]”hŒ1it can be bound to the GPIO Aggregator by either:”…””}”(hj÷hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K^hj®hžhubhŒenumerated_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒ /sys/bus/platform/devices/door/driver_override $ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind”h]”hŒ„$ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override $ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind”…””}”hjZsbah}”(h]”h ]”h"]”h$]”h&]”h±h²jj‰jkŒsh”jm}”uh1jZhŸh³h Kchj®hžhubhÊ)”}”(hŒ3After that, a new gpiochip "door" has been created:”h]”hŒ7After that, a new gpiochip “door†has been created:”…””}”(hjjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khhj®hžhubj[)”}”(hŒ§$ gpioinfo door gpiochip12 - 2 lines: line 0: "open" unused input active-high line 1: "lock" unused input active-high”h]”hŒ§$ gpioinfo door gpiochip12 - 2 lines: line 0: "open" unused input active-high line 1: "lock" unused input active-high”…””}”hjxsbah}”(h]”h ]”h"]”h$]”h&]”h±h²jj‰jkŒsh”jm}”uh1jZhŸh³h Kjhj®hžhubeh}”(h]”Œgeneric-gpio-driver”ah ]”h"]”Œgeneric gpio driver”ah$]”h&]”uh1h´hh¶hžhhŸh³h KIubeh}”(h]”Œgpio-aggregator”ah ]”h"]”Œgpio aggregator”ah$]”h&]”uh1h´hhhžhhŸh³h Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”h³uh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(h¹NŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j»Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”h³Œ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(j•j’j«j¨jjŠuŒ nametypes”}”(j•‰j«‰j‰uh}”(j’h¶j¨hÙjŠj®uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nhžhub.