€•Œ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”Œ,/translations/zh_CN/driver-api/auxiliary_bus”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/zh_TW/driver-api/auxiliary_bus”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/it_IT/driver-api/auxiliary_bus”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/ja_JP/driver-api/auxiliary_bus”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/ko_KR/driver-api/auxiliary_bus”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/pt_BR/driver-api/auxiliary_bus”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/sp_SP/driver-api/auxiliary_bus”Œ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³ŒF/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus.rst”h´KubhŒtarget”“”)�”}”(hŒ.. _auxiliary_bus:”h]”h}”(h]”h ]”h"]”h$]”h&]”Œrefid”Œ auxiliary-bus”uh1hÈh´Khhh²hh³hÇubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒ Auxiliary Bus”h]”hŒ Auxiliary Bus”…”�”}”(hhÝh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhhØh²hh³hÇh´KubhŒ paragraph”“”)�”}”(hXiIn some subsystems, the functionality of the core device (PCI/ACPI/other) is too complex for a single device to be managed by a monolithic driver (e.g. Sound Open Firmware), multiple devices might implement a common intersection of functionality (e.g. NICs + RDMA), or a driver may want to export an interface for another subsystem to drive (e.g. SIOV Physical Function export Virtual Function management). A split of the functionality into child- devices representing sub-domains of functionality makes it possible to compartmentalize, layer, and distribute domain-specific concerns via a Linux device-driver model.”h]”hXiIn some subsystems, the functionality of the core device (PCI/ACPI/other) is too complex for a single device to be managed by a monolithic driver (e.g. Sound Open Firmware), multiple devices might implement a common intersection of functionality (e.g. NICs + RDMA), or a driver may want to export an interface for another subsystem to drive (e.g. SIOV Physical Function export Virtual Function management). A split of the functionality into child- devices representing sub-domains of functionality makes it possible to compartmentalize, layer, and distribute domain-specific concerns via a Linux device-driver model.”…”�”}”(hhíh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œ`/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:9: ./drivers/base/auxiliary.c”h´KhhØh²hubhì)�”}”(hX¥An example for this kind of requirement is the audio subsystem where a single IP is handling multiple entities such as HDMI, Soundwire, local devices such as mics/speakers etc. The split for the core's functionality can be arbitrary or be defined by the DSP firmware topology and include hooks for test/debug. This allows for the audio core device to be minimal and focused on hardware-specific control and communication.”h]”hX§An example for this kind of requirement is the audio subsystem where a single IP is handling multiple entities such as HDMI, Soundwire, local devices such as mics/speakers etc. The split for the core’s functionality can be arbitrary or be defined by the DSP firmware topology and include hooks for test/debug. This allows for the audio core device to be minimal and focused on hardware-specific control and communication.”…”�”}”(hhüh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œ`/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:9: ./drivers/base/auxiliary.c”h´KhhØh²hubhì)�”}”(hXsEach auxiliary_device represents a part of its parent functionality. The generic behavior can be extended and specialized as needed by encapsulating an auxiliary_device within other domain-specific structures and the use of .ops callbacks. Devices on the auxiliary bus do not share any structures and the use of a communication channel with the parent is domain-specific.”h]”hXsEach auxiliary_device represents a part of its parent functionality. The generic behavior can be extended and specialized as needed by encapsulating an auxiliary_device within other domain-specific structures and the use of .ops callbacks. Devices on the auxiliary bus do not share any structures and the use of a communication channel with the parent is domain-specific.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œ`/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:9: ./drivers/base/auxiliary.c”h´K&hhØh²hubhì)�”}”(hXNote that ops are intended as a way to augment instance behavior within a class of auxiliary devices, it is not the mechanism for exporting common infrastructure from the parent. Consider EXPORT_SYMBOL_NS() to convey infrastructure from the parent module to the auxiliary module(s).”h]”hXNote that ops are intended as a way to augment instance behavior within a class of auxiliary devices, it is not the mechanism for exporting common infrastructure from the parent. Consider EXPORT_SYMBOL_NS() to convey infrastructure from the parent module to the auxiliary module(s).”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œ`/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:9: ./drivers/base/auxiliary.c”h´K,hhØh²hubh×)�”}”(hhh]”(hÜ)�”}”(hŒ%When Should the Auxiliary Bus Be Used”h]”hŒ%When Should the Auxiliary Bus Be Used”…”�”}”(hj,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj)h²hh³hÇh´K ubhì)�”}”(hXŸThe auxiliary bus is to be used when a driver and one or more kernel modules, who share a common header file with the driver, need a mechanism to connect and provide access to a shared object allocated by the auxiliary_device's registering driver. The registering driver for the auxiliary_device(s) and the kernel module(s) registering auxiliary_drivers can be from the same subsystem, or from multiple subsystems.”h]”hX¡The auxiliary bus is to be used when a driver and one or more kernel modules, who share a common header file with the driver, need a mechanism to connect and provide access to a shared object allocated by the auxiliary_device’s registering driver. The registering driver for the auxiliary_device(s) and the kernel module(s) registering auxiliary_drivers can be from the same subsystem, or from multiple subsystems.”…”�”}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:15: ./drivers/base/auxiliary.c”h´K5hj)h²hubhì)�”}”(hŒtThe emphasis here is on a common generic interface that keeps subsystem customization out of the bus infrastructure.”h]”hŒtThe emphasis here is on a common generic interface that keeps subsystem customization out of the bus infrastructure.”…”�”}”(hjIh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:15: ./drivers/base/auxiliary.c”h´KhjDubj³)�”}”(hhh]”hì)�”}”(hŒ4embedded struct which hold all sysfs related fields,”h]”hŒ4embedded struct which hold all sysfs related fields,”…”�”}”(hjch²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j_h´K>hj`ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hjDubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j_h´K>hj�ubj‘)�”}”(hŒN``sysfs.irqs`` irqs xarray contains irq indices which are used by the device, ”h]”(j—)�”}”(hŒ``sysfs.irqs``”h]”j�)�”}”(hjƒh]”hŒ sysfs.irqs”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´K?hj}ubj³)�”}”(hhh]”hì)�”}”(hŒ>irqs xarray contains irq indices which are used by the device,”h]”hŒ>irqs xarray contains irq indices which are used by the device,”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j˜h´K?hj™ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj}ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j˜h´K?hj�ubj‘)�”}”(hŒ/``sysfs.lock`` Synchronize irq sysfs creation, ”h]”(j—)�”}”(hŒ``sysfs.lock``”h]”j�)�”}”(hj¼h]”hŒ sysfs.lock”…”�”}”(hj¾h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhjºubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´K@hj¶ubj³)�”}”(hhh]”hì)�”}”(hŒSynchronize irq sysfs creation,”h]”hŒSynchronize irq sysfs creation,”…”�”}”(hjÕh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³jÑh´K@hjÒubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj¶ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³jÑh´K@hj�ubj‘)�”}”(hŒ:``sysfs.irq_dir_exists`` whether "irqs" directory exists, ”h]”(j—)�”}”(hŒ``sysfs.irq_dir_exists``”h]”j�)�”}”(hjõh]”hŒsysfs.irq_dir_exists”…”�”}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhjóubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´KAhjïubj³)�”}”(hhh]”hì)�”}”(hŒ whether "irqs" directory exists,”h]”hŒ$whether “irqsâ€� directory exists,”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j h´KAhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hjïubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j h´KAhj�ubj‘)�”}”(hŒ•``registration_data_rust`` private data owned by the registering (parent) driver; valid for as long as the device is registered with the driver core,”h]”(j—)�”}”(hŒ``registration_data_rust``”h]”j�)�”}”(hj.h]”hŒregistration_data_rust”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj,ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´KChj(ubj³)�”}”(hhh]”hì)�”}”(hŒzprivate data owned by the registering (parent) driver; valid for as long as the device is registered with the driver core,”h]”hŒzprivate data owned by the registering (parent) driver; valid for as long as the device is registered with the driver core,”…”�”}”(hjGh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´KBhjDubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj(ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³jCh´KChj�ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j‹hj?ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j=hj�h²hh³Nh´Nubhì)�”}”(hŒ**Description**”h]”jH)�”}”(hjqh]”hŒ Description”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhjoubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´KGhj�h²hubhì)�”}”(hXÙAn auxiliary_device represents a part of its parent device's functionality. It is given a name that, combined with the registering drivers KBUILD_MODNAME, creates a match_name that is used for driver binding, and an id that combined with the match_name provide a unique name to register with the bus subsystem. For example, a driver registering an auxiliary device is named 'foo_mod.ko' and the subdevice is named 'foo_dev'. The match name is therefore 'foo_mod.foo_dev'.”h]”hXçAn auxiliary_device represents a part of its parent device’s functionality. It is given a name that, combined with the registering drivers KBUILD_MODNAME, creates a match_name that is used for driver binding, and an id that combined with the match_name provide a unique name to register with the bus subsystem. For example, a driver registering an auxiliary device is named ‘foo_mod.ko’ and the subdevice is named ‘foo_dev’. The match name is therefore ‘foo_mod.foo_dev’.”…”�”}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´KDhj�h²hubhì)�”}”(hŒ8Registering an auxiliary_device is a three-step process.”h]”hŒ8Registering an auxiliary_device is a three-step process.”…”�”}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´KLhj�h²hubhì)�”}”(hŒÂFirst, a 'struct auxiliary_device' needs to be defined or allocated for each sub-device desired. The name, id, dev.release, and dev.parent fields of this structure must be filled in as follows.”h]”hŒÆFirst, a ‘struct auxiliary_device’ needs to be defined or allocated for each sub-device desired. The name, id, dev.release, and dev.parent fields of this structure must be filled in as follows.”…”�”}”(hj¥h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´KNhj�h²hubhì)�”}”(hX The 'name' field is to be given a name that is recognized by the auxiliary driver. If two auxiliary_devices with the same match_name, eg "foo_mod.foo_dev", are registered onto the bus, they must have unique id values (e.g. "x" and "y") so that the registered devices names are "foo_mod.foo_dev.x" and "foo_mod.foo_dev.y". If match_name + id are not unique, then the device_add fails and generates an error message.”h]”hX¸The ‘name’ field is to be given a name that is recognized by the auxiliary driver. If two auxiliary_devices with the same match_name, eg “foo_mod.foo_devâ€�, are registered onto the bus, they must have unique id values (e.g. “xâ€� and “yâ€�) so that the registered devices names are “foo_mod.foo_dev.xâ€� and “foo_mod.foo_dev.yâ€�. If match_name + id are not unique, then the device_add fails and generates an error message.”…”�”}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´KRhj�h²hubhì)�”}”(hXzThe auxiliary_device.dev.type.release or auxiliary_device.dev.release must be populated with a non-NULL pointer to successfully register the auxiliary_device. This release call is where resources associated with the auxiliary device must be free'ed. Because once the device is placed on the bus the parent driver can not tell what other code may have a reference to this data.”h]”hX|The auxiliary_device.dev.type.release or auxiliary_device.dev.release must be populated with a non-NULL pointer to successfully register the auxiliary_device. This release call is where resources associated with the auxiliary device must be free’ed. Because once the device is placed on the bus the parent driver can not tell what other code may have a reference to this data.”…”�”}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´KYhj�h²hubhì)�”}”(hŒ\The auxiliary_device.dev.parent should be set. Typically to the registering drivers device.”h]”hŒ\The auxiliary_device.dev.parent should be set. Typically to the registering drivers device.”…”�”}”(hjÒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´K`hj�h²hubhì)�”}”(hŒ÷Second, call auxiliary_device_init(), which checks several aspects of the auxiliary_device struct and performs a device_initialize(). After this step completes, any error state must have a call to auxiliary_device_uninit() in its resolution path.”h]”hŒ÷Second, call auxiliary_device_init(), which checks several aspects of the auxiliary_device struct and performs a device_initialize(). After this step completes, any error state must have a call to auxiliary_device_uninit() in its resolution path.”…”�”}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´Kchj�h²hubhì)�”}”(hŒ­The third and final step in registering an auxiliary_device is to perform a call to auxiliary_device_add(), which sets the name of the device and adds the device to the bus.”h]”hŒ­The third and final step in registering an auxiliary_device is to perform a call to auxiliary_device_add(), which sets the name of the device and adds the device to the bus.”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´Khhj�h²hubjc)�”}”(hXÌ#define MY_DEVICE_NAME "foo_dev" ... struct auxiliary_device *my_aux_dev = my_aux_dev_alloc(xxx); // Step 1: my_aux_dev->name = MY_DEVICE_NAME; my_aux_dev->id = my_unique_id_alloc(xxx); my_aux_dev->dev.release = my_aux_dev_release; my_aux_dev->dev.parent = my_dev; // Step 2: if (auxiliary_device_init(my_aux_dev)) goto fail; // Step 3: if (auxiliary_device_add(my_aux_dev)) { auxiliary_device_uninit(my_aux_dev); goto fail; } ...”h]”hXÌ#define MY_DEVICE_NAME "foo_dev" ... struct auxiliary_device *my_aux_dev = my_aux_dev_alloc(xxx); // Step 1: my_aux_dev->name = MY_DEVICE_NAME; my_aux_dev->id = my_unique_id_alloc(xxx); my_aux_dev->dev.release = my_aux_dev_release; my_aux_dev->dev.parent = my_dev; // Step 2: if (auxiliary_device_init(my_aux_dev)) goto fail; // Step 3: if (auxiliary_device_add(my_aux_dev)) { auxiliary_device_uninit(my_aux_dev); goto fail; } ...”…”�”}”hjÿsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆŒforce”‰Œlanguage”j2Œhighlight_args”}”uh1jbh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´Klhj�h²hubhì)�”}”(hŒ£Unregistering an auxiliary_device is a two-step process to mirror the register process. First call auxiliary_device_delete(), then call auxiliary_device_uninit().”h]”hŒ£Unregistering an auxiliary_device is a two-step process to mirror the register process. First call auxiliary_device_delete(), then call auxiliary_device_uninit().”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´K‡hj�h²hubjc)�”}”(hŒYauxiliary_device_delete(my_dev->my_aux_dev); auxiliary_device_uninit(my_dev->my_aux_dev);”h]”hŒYauxiliary_device_delete(my_dev->my_aux_dev); auxiliary_device_uninit(my_dev->my_aux_dev);”…”�”}”hj!sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆj ‰jj2j}”uh1jbh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:22: ./include/linux/auxiliary_bus.h”h´K‹hj�h²hubjŸ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j«Œ"auxiliary_device_init (C function)”Œc.auxiliary_device_init”hNt”auh1jžhj�h²hh³Nh´Nubj°)�”}”(hhh]”(jµ)�”}”(hŒ;int auxiliary_device_init (struct auxiliary_device *auxdev)”h]”j»)�”}”(hŒ:int auxiliary_device_init(struct auxiliary_device *auxdev)”h]”(hŒdesc_sig_keyword_type”“”)�”}”(hŒint”h]”hŒint”…”�”}”(hjLh²hh³Nh´Nubah}”(h]”h ]”Œkt”ah"]”h$]”h&]”uh1jJhjFh²hh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´MubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj\h²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjFh²hh³j[h´Mubjä)�”}”(hŒauxiliary_device_init”h]”jê)�”}”(hŒauxiliary_device_init”h]”hŒauxiliary_device_init”…”�”}”(hjnh²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhjjubah}”(h]”h ]”(jüjýeh"]”h$]”h&]”hÅhÆuh1jãhjFh²hh³j[h´MubhŒdesc_parameterlist”“”)�”}”(hŒ!(struct auxiliary_device *auxdev)”h]”hŒdesc_parameter”“”)�”}”(hŒstruct auxiliary_device *auxdev”h]”(jÁ)�”}”(hjÄh]”hŒstruct”…”�”}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”jÍah"]”h$]”h&]”uh1jÀhjŠubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj›h²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjŠubh)�”}”(hhh]”jê)�”}”(hŒauxiliary_device”h]”hŒauxiliary_device”…”�”}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhj©ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j2Œreftype”Œ identifier”Œ reftarget”j®Œmodname”NŒ classname”NŒ c:parent_key”Œsphinx.domains.c”Œ LookupKey”“”)�”}”Œdata”]”jÇŒ ASTIdentifier”“”)�”}”jÂjpsbŒc.auxiliary_device_init”†”asbuh1hhjŠubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjŠubhŒdesc_sig_punctuation”“”)�”}”(hŒ*”h]”hŒ*”…”�”}”(hjäh²hh³Nh´Nubah}”(h]”h ]”Œp”ah"]”h$]”h&]”uh1jâhjŠubjê)�”}”(hŒauxdev”h]”hŒauxdev”…”�”}”(hjóh²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhjŠubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1jˆhj„ubah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j‚hjFh²hh³j[h´Mubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjˆuh1jºjj hjBh²hh³j[h´Mubah}”(h]”j=ah ]”(j jeh"]”h$]”h&]”jˆj)jhuh1j´h³j[h´Mhj?h²hubj)�”}”(hhh]”hì)�”}”(hŒ%check auxiliary_device and initialize”h]”hŒ%check auxiliary_device and initialize”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´Mhjh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj?h²hh³j[h´Mubeh}”(h]”h ]”(j2Œfunction”eh"]”h$]”h&]”j7j2j8j5j9j5j:‰j;‰j<‰uh1j¯h²hhj�h³Nh´Nubj>)�”}”(hXÜ**Parameters** ``struct auxiliary_device *auxdev`` auxiliary device struct **Description** This is the second step in the three-step process to register an auxiliary_device. When this function returns an error code, then the device_initialize will *not* have been performed, and the caller will be responsible to free any memory allocated for the auxiliary_device in the error path directly. It returns 0 on success. On success, the device_initialize has been performed. After this point any error unwinding will need to include a call to auxiliary_device_uninit(). In this post-initialize error scenario, a call to the device's .release callback will be triggered, and all memory clean-up is expected to be handled there.”h]”(hì)�”}”(hŒ**Parameters**”h]”jH)�”}”(hj?h]”hŒ Parameters”…”�”}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhj=ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´Mhj9ubjŒ)�”}”(hhh]”j‘)�”}”(hŒ<``struct auxiliary_device *auxdev`` auxiliary device struct ”h]”(j—)�”}”(hŒ#``struct auxiliary_device *auxdev``”h]”j�)�”}”(hj^h]”hŒstruct auxiliary_device *auxdev”…”�”}”(hj`h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj\ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´MhjXubj³)�”}”(hhh]”hì)�”}”(hŒauxiliary device struct”h]”hŒauxiliary device struct”…”�”}”(hjwh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³jsh´Mhjtubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hjXubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³jsh´MhjUubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hj9ubhì)�”}”(hŒ**Description**”h]”jH)�”}”(hj™h]”hŒ Description”…”�”}”(hj›h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhj—ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´Mhj9ubhì)�”}”(hŒRThis is the second step in the three-step process to register an auxiliary_device.”h]”hŒRThis is the second step in the three-step process to register an auxiliary_device.”…”�”}”(hj¯h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´Mhj9ubhì)�”}”(hŒÙWhen this function returns an error code, then the device_initialize will *not* have been performed, and the caller will be responsible to free any memory allocated for the auxiliary_device in the error path directly.”h]”(hŒJWhen this function returns an error code, then the device_initialize will ”…”�”}”(hj¾h²hh³Nh´NubhŒemphasis”“”)�”}”(hŒ*not*”h]”hŒnot”…”�”}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÆhj¾ubhŒŠ have been performed, and the caller will be responsible to free any memory allocated for the auxiliary_device in the error path directly.”…”�”}”(hj¾h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´Mhj9ubhì)�”}”(hXMIt returns 0 on success. On success, the device_initialize has been performed. After this point any error unwinding will need to include a call to auxiliary_device_uninit(). In this post-initialize error scenario, a call to the device's .release callback will be triggered, and all memory clean-up is expected to be handled there.”h]”hXOIt returns 0 on success. On success, the device_initialize has been performed. After this point any error unwinding will need to include a call to auxiliary_device_uninit(). In this post-initialize error scenario, a call to the device’s .release callback will be triggered, and all memory clean-up is expected to be handled there.”…”�”}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´M hj9ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j=hj�h²hh³Nh´NubjŸ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j«Œ#__auxiliary_device_add (C function)”Œc.__auxiliary_device_add”hNt”auh1jžhj�h²hh³Nh´Nubj°)�”}”(hhh]”(jµ)�”}”(hŒQint __auxiliary_device_add (struct auxiliary_device *auxdev, const char *modname)”h]”j»)�”}”(hŒPint __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname)”h]”(jK)�”}”(hŒint”h]”hŒint”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jWah"]”h$]”h&]”uh1jJhj h²hh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´M)ubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhj h²hh³jh´M)ubjä)�”}”(hŒ__auxiliary_device_add”h]”jê)�”}”(hŒ__auxiliary_device_add”h]”hŒ__auxiliary_device_add”…”�”}”(hj1h²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhj-ubah}”(h]”h ]”(jüjýeh"]”h$]”h&]”hÅhÆuh1jãhj h²hh³jh´M)ubjƒ)�”}”(hŒ6(struct auxiliary_device *auxdev, const char *modname)”h]”(j‰)�”}”(hŒstruct auxiliary_device *auxdev”h]”(jÁ)�”}”(hjÄh]”hŒstruct”…”�”}”(hjMh²hh³Nh´Nubah}”(h]”h ]”jÍah"]”h$]”h&]”uh1jÀhjIubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjZh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjIubh)�”}”(hhh]”jê)�”}”(hŒauxiliary_device”h]”hŒauxiliary_device”…”�”}”(hjkh²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhjhubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j2Œreftype”jÂŒ reftarget”jmŒmodname”NŒ classname”NjÆjÉ)�”}”jÌ]”jÏ)�”}”jÂj3sbŒc.__auxiliary_device_add”†”asbuh1hhjIubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj‹h²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjIubjã)�”}”(hjæh]”hŒ*”…”�”}”(hj™h²hh³Nh´Nubah}”(h]”h ]”jïah"]”h$]”h&]”uh1jâhjIubjê)�”}”(hŒauxdev”h]”hŒauxdev”…”�”}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhjIubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1jˆhjEubj‰)�”}”(hŒconst char *modname”h]”(jÁ)�”}”(hŒconst”h]”hŒconst”…”�”}”(hj¿h²hh³Nh´Nubah}”(h]”h ]”jÍah"]”h$]”h&]”uh1jÀhj»ubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÍh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhj»ubjK)�”}”(hŒchar”h]”hŒchar”…”�”}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”jWah"]”h$]”h&]”uh1jJhj»ubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjéh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhj»ubjã)�”}”(hjæh]”hŒ*”…”�”}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”jïah"]”h$]”h&]”uh1jâhj»ubjê)�”}”(hŒmodname”h]”hŒmodname”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhj»ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1jˆhjEubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j‚hj h²hh³jh´M)ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjˆuh1jºjj hjh²hh³jh´M)ubah}”(h]”jah ]”(j jeh"]”h$]”h&]”jˆj)jhuh1j´h³jh´M)hjh²hubj)�”}”(hhh]”hì)�”}”(hŒadd an auxiliary bus device”h]”hŒadd an auxiliary bus device”…”�”}”(hj.h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´M)hj+h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³jh´M)ubeh}”(h]”h ]”(j2Œfunction”eh"]”h$]”h&]”j7j2j8jFj9jFj:‰j;‰j<‰uh1j¯h²hhj�h³Nh´Nubj>)�”}”(hXF**Parameters** ``struct auxiliary_device *auxdev`` auxiliary bus device to add to the bus ``const char *modname`` name of the parent device's driver module **Description** This is the third step in the three-step process to register an auxiliary_device. This function must be called after a successful call to auxiliary_device_init(), which will perform the device_initialize. This means that if this returns an error code, then a call to auxiliary_device_uninit() must be performed so that the .release callback will be triggered to free the memory associated with the auxiliary_device. The expectation is that users will call the "auxiliary_device_add" macro so that the caller's KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires a custom name would this version be called directly.”h]”(hì)�”}”(hŒ**Parameters**”h]”jH)�”}”(hjPh]”hŒ Parameters”…”�”}”(hjRh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhjNubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´M-hjJubjŒ)�”}”(hhh]”(j‘)�”}”(hŒK``struct auxiliary_device *auxdev`` auxiliary bus device to add to the bus ”h]”(j—)�”}”(hŒ#``struct auxiliary_device *auxdev``”h]”j�)�”}”(hjoh]”hŒstruct auxiliary_device *auxdev”…”�”}”(hjqh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhjmubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´M*hjiubj³)�”}”(hhh]”hì)�”}”(hŒ&auxiliary bus device to add to the bus”h]”hŒ&auxiliary bus device to add to the bus”…”�”}”(hjˆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j„h´M*hj…ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hjiubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j„h´M*hjfubj‘)�”}”(hŒB``const char *modname`` name of the parent device's driver module ”h]”(j—)�”}”(hŒ``const char *modname``”h]”j�)�”}”(hj¨h]”hŒconst char *modname”…”�”}”(hjªh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj¦ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´M+hj¢ubj³)�”}”(hhh]”hì)�”}”(hŒ)name of the parent device's driver module”h]”hŒ+name of the parent device’s driver module”…”�”}”(hjÁh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j½h´M+hj¾ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj¢ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j½h´M+hjfubeh}”(h]”h ]”h"]”h$]”h&]”uh1j‹hjJubhì)�”}”(hŒ**Description**”h]”jH)�”}”(hjãh]”hŒ Description”…”�”}”(hjåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhjáubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´M-hjJubhì)�”}”(hŒQThis is the third step in the three-step process to register an auxiliary_device.”h]”hŒQThis is the third step in the three-step process to register an auxiliary_device.”…”�”}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´M,hjJubhì)�”}”(hXNThis function must be called after a successful call to auxiliary_device_init(), which will perform the device_initialize. This means that if this returns an error code, then a call to auxiliary_device_uninit() must be performed so that the .release callback will be triggered to free the memory associated with the auxiliary_device.”h]”hXNThis function must be called after a successful call to auxiliary_device_init(), which will perform the device_initialize. This means that if this returns an error code, then a call to auxiliary_device_uninit() must be performed so that the .release callback will be triggered to free the memory associated with the auxiliary_device.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´M/hjJubhì)�”}”(hŒïThe expectation is that users will call the "auxiliary_device_add" macro so that the caller's KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires a custom name would this version be called directly.”h]”hŒõThe expectation is that users will call the “auxiliary_device_addâ€� macro so that the caller’s KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires a custom name would this version be called directly.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:25: ./drivers/base/auxiliary.c”h´M5hjJubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j=hj�h²hh³Nh´Nubh×)�”}”(hhh]”(hÜ)�”}”(hŒ*Auxiliary Device Memory Model and Lifespan”h]”hŒ*Auxiliary Device Memory Model and Lifespan”…”�”}”(hj0 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj- h²hh³hÇh´Kubhì)�”}”(hX#The registering driver is the entity that allocates memory for the auxiliary_device and registers it on the auxiliary bus. It is important to note that, as opposed to the platform bus, the registering driver is wholly responsible for the management of the memory used for the device object.”h]”hX#The registering driver is the entity that allocates memory for the auxiliary_device and registers it on the auxiliary bus. It is important to note that, as opposed to the platform bus, the registering driver is wholly responsible for the management of the memory used for the device object.”…”�”}”(hj> h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:31: ./include/linux/auxiliary_bus.h”h´Khj- h²hubhì)�”}”(hXqTo be clear the memory for the auxiliary_device is freed in the release() callback defined by the registering driver. The registering driver should only call auxiliary_device_delete() and then auxiliary_device_uninit() when it is done with the device. The release() function is then automatically called if and when other code releases their reference to the devices.”h]”hXqTo be clear the memory for the auxiliary_device is freed in the release() callback defined by the registering driver. The registering driver should only call auxiliary_device_delete() and then auxiliary_device_uninit() when it is done with the device. The release() function is then automatically called if and when other code releases their reference to the devices.”…”�”}”(hjM h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:31: ./include/linux/auxiliary_bus.h”h´Khj- h²hubhì)�”}”(hX,A parent object, defined in the shared header file, contains the auxiliary_device. It also contains a pointer to the shared object(s), which also is defined in the shared header. Both the parent object and the shared object(s) are allocated by the registering driver. This layout allows the auxiliary_driver's registering module to perform a container_of() call to go from the pointer to the auxiliary_device, that is passed during the call to the auxiliary_driver's probe function, up to the parent object, and then have access to the shared object(s).”h]”hX0A parent object, defined in the shared header file, contains the auxiliary_device. It also contains a pointer to the shared object(s), which also is defined in the shared header. Both the parent object and the shared object(s) are allocated by the registering driver. This layout allows the auxiliary_driver’s registering module to perform a container_of() call to go from the pointer to the auxiliary_device, that is passed during the call to the auxiliary_driver’s probe function, up to the parent object, and then have access to the shared object(s).”…”�”}”(hj\ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:31: ./include/linux/auxiliary_bus.h”h´Khj- h²hubhì)�”}”(hX³The memory for the shared object(s) must have a lifespan equal to, or greater than, the lifespan of the memory for the auxiliary_device. The auxiliary_driver should only consider that the shared object is valid as long as the auxiliary_device is still registered on the auxiliary bus. It is up to the registering driver to manage (e.g. free or keep available) the memory for the shared object beyond the life of the auxiliary_device.”h]”hX³The memory for the shared object(s) must have a lifespan equal to, or greater than, the lifespan of the memory for the auxiliary_device. The auxiliary_driver should only consider that the shared object is valid as long as the auxiliary_device is still registered on the auxiliary bus. It is up to the registering driver to manage (e.g. free or keep available) the memory for the shared object beyond the life of the auxiliary_device.”…”�”}”(hjk h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:31: ./include/linux/auxiliary_bus.h”h´K#hj- h²hubhì)�”}”(hXThe registering driver must unregister all auxiliary devices before its own driver.remove() is completed. An easy way to ensure this is to use the devm_add_action_or_reset() call to register a function against the parent device which unregisters the auxiliary device object(s).”h]”hXThe registering driver must unregister all auxiliary devices before its own driver.remove() is completed. An easy way to ensure this is to use the devm_add_action_or_reset() call to register a function against the parent device which unregisters the auxiliary device object(s).”…”�”}”(hjz h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:31: ./include/linux/auxiliary_bus.h”h´K*hj- h²hubhì)�”}”(hŒ´Finally, any operations which operate on the auxiliary devices must continue to function (if only to return an error) after the registering driver unregisters the auxiliary device.”h]”hŒ´Finally, any operations which operate on the auxiliary devices must continue to function (if only to return an error) after the registering driver unregisters the auxiliary device.”…”�”}”(hj‰ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:31: ./include/linux/auxiliary_bus.h”h´K/hj- h²hubeh}”(h]”Œ*auxiliary-device-memory-model-and-lifespan”ah ]”h"]”Œ*auxiliary device memory model and lifespan”ah$]”h&]”uh1hÖhj�h²hh³hÇh´Kubeh}”(h]”Œauxiliary-device-creation”ah ]”h"]”Œauxiliary device creation”ah$]”h&]”uh1hÖhhØh²hh³hÇh´Kubh×)�”}”(hhh]”(hÜ)�”}”(hŒAuxiliary Drivers”h]”hŒAuxiliary Drivers”…”�”}”(hj« h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj¨ h²hh³hÇh´K$ubjŸ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j«Œauxiliary_driver (C struct)”Œc.auxiliary_driver”hNt”auh1jžhj¨ h²hh³Nh´Nubj°)�”}”(hhh]”(jµ)�”}”(hŒauxiliary_driver”h]”j»)�”}”(hŒstruct auxiliary_driver”h]”(jÁ)�”}”(hjÄh]”hŒstruct”…”�”}”(hjÒ h²hh³Nh´Nubah}”(h]”h ]”jÍah"]”h$]”h&]”uh1jÀhjÎ h²hh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´KubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjà h²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjÎ h²hh³jß h´Kubjä)�”}”(hŒauxiliary_driver”h]”jê)�”}”(hjÌ h]”hŒauxiliary_driver”…”�”}”(hjò h²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhjî ubah}”(h]”h ]”(jüjýeh"]”h$]”h&]”hÅhÆuh1jãhjÎ h²hh³jß h´Kubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjˆuh1jºjj hjÊ h²hh³jß h´Kubah}”(h]”jÅ ah ]”(j jeh"]”h$]”h&]”jˆj)jhuh1j´h³jß h´KhjÇ h²hubj)�”}”(hhh]”hì)�”}”(hŒ%Definition of an auxiliary bus driver”h]”hŒ%Definition of an auxiliary bus driver”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´Kžhj h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÇ h²hh³jß h´Kubeh}”(h]”h ]”(j2Œstruct”eh"]”h$]”h&]”j7j2j8j, j9j, j:‰j;‰j<‰uh1j¯h²hhj¨ h³Nh´Nubj>)�”}”(hX¿**Definition**:: struct auxiliary_driver { int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id); void (*remove)(struct auxiliary_device *auxdev); void (*shutdown)(struct auxiliary_device *auxdev); int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state); int (*resume)(struct auxiliary_device *auxdev); const char *name; struct device_driver driver; const struct auxiliary_device_id *id_table; }; **Members** ``probe`` Called when a matching device is added to the bus. ``remove`` Called when device is removed from the bus. ``shutdown`` Called at shut-down time to quiesce the device. ``suspend`` Called to put the device to sleep mode. Usually to a power state. ``resume`` Called to bring a device from sleep mode. ``name`` Driver name. ``driver`` Core driver structure. ``id_table`` Table of devices this driver should match on the bus.”h]”(hì)�”}”(hŒ**Definition**::”h]”(jH)�”}”(hŒ**Definition**”h]”hŒ Definition”…”�”}”(hj8 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhj4 ubhŒ:”…”�”}”(hj4 h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K¢hj0 ubjc)�”}”(hXÅstruct auxiliary_driver { int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id); void (*remove)(struct auxiliary_device *auxdev); void (*shutdown)(struct auxiliary_device *auxdev); int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state); int (*resume)(struct auxiliary_device *auxdev); const char *name; struct device_driver driver; const struct auxiliary_device_id *id_table; };”h]”hXÅstruct auxiliary_driver { int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id); void (*remove)(struct auxiliary_device *auxdev); void (*shutdown)(struct auxiliary_device *auxdev); int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state); int (*resume)(struct auxiliary_device *auxdev); const char *name; struct device_driver driver; const struct auxiliary_device_id *id_table; };”…”�”}”hjQ sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jbh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K¤hj0 ubhì)�”}”(hŒ **Members**”h]”jH)�”}”(hjb h]”hŒMembers”…”�”}”(hjd h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhj` ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K¯hj0 ubjŒ)�”}”(hhh]”(j‘)�”}”(hŒ=``probe`` Called when a matching device is added to the bus. ”h]”(j—)�”}”(hŒ ``probe``”h]”j�)�”}”(hj� h]”hŒprobe”…”�”}”(hjƒ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K hj{ ubj³)�”}”(hhh]”hì)�”}”(hŒ2Called when a matching device is added to the bus.”h]”hŒ2Called when a matching device is added to the bus.”…”�”}”(hjš h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j– h´K hj— ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj{ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j– h´K hjx ubj‘)�”}”(hŒ7``remove`` Called when device is removed from the bus. ”h]”(j—)�”}”(hŒ ``remove``”h]”j�)�”}”(hjº h]”hŒremove”…”�”}”(hj¼ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj¸ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K¡hj´ ubj³)�”}”(hhh]”hì)�”}”(hŒ+Called when device is removed from the bus.”h]”hŒ+Called when device is removed from the bus.”…”�”}”(hjÓ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³jÏ h´K¡hjÐ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj´ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³jÏ h´K¡hjx ubj‘)�”}”(hŒ=``shutdown`` Called at shut-down time to quiesce the device. ”h]”(j—)�”}”(hŒ ``shutdown``”h]”j�)�”}”(hjó h]”hŒshutdown”…”�”}”(hjõ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhjñ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K¢hjí ubj³)�”}”(hhh]”hì)�”}”(hŒ/Called at shut-down time to quiesce the device.”h]”hŒ/Called at shut-down time to quiesce the device.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j h´K¢hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hjí ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j h´K¢hjx ubj‘)�”}”(hŒN``suspend`` Called to put the device to sleep mode. Usually to a power state. ”h]”(j—)�”}”(hŒ ``suspend``”h]”j�)�”}”(hj, h]”hŒsuspend”…”�”}”(hj. h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj* ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K£hj& ubj³)�”}”(hhh]”hì)�”}”(hŒACalled to put the device to sleep mode. Usually to a power state.”h]”hŒACalled to put the device to sleep mode. Usually to a power state.”…”�”}”(hjE h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³jA h´K£hjB ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj& ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³jA h´K£hjx ubj‘)�”}”(hŒ5``resume`` Called to bring a device from sleep mode. ”h]”(j—)�”}”(hŒ ``resume``”h]”j�)�”}”(hje h]”hŒresume”…”�”}”(hjg h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhjc ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K¤hj_ ubj³)�”}”(hhh]”hì)�”}”(hŒ)Called to bring a device from sleep mode.”h]”hŒ)Called to bring a device from sleep mode.”…”�”}”(hj~ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³jz h´K¤hj{ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj_ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³jz h´K¤hjx ubj‘)�”}”(hŒ``name`` Driver name. ”h]”(j—)�”}”(hŒ``name``”h]”j�)�”}”(hjž h]”hŒname”…”�”}”(hj  h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhjœ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K¥hj˜ ubj³)�”}”(hhh]”hì)�”}”(hŒ Driver name.”h]”hŒ Driver name.”…”�”}”(hj· h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j³ h´K¥hj´ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj˜ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j³ h´K¥hjx ubj‘)�”}”(hŒ"``driver`` Core driver structure. ”h]”(j—)�”}”(hŒ ``driver``”h]”j�)�”}”(hj× h]”hŒdriver”…”�”}”(hjÙ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhjÕ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K¦hjÑ ubj³)�”}”(hhh]”hì)�”}”(hŒCore driver structure.”h]”hŒCore driver structure.”…”�”}”(hjð h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³jì h´K¦hjí ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hjÑ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³jì h´K¦hjx ubj‘)�”}”(hŒB``id_table`` Table of devices this driver should match on the bus.”h]”(j—)�”}”(hŒ ``id_table``”h]”j�)�”}”(hj h]”hŒid_table”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K¦hj ubj³)�”}”(hhh]”hì)�”}”(hŒ5Table of devices this driver should match on the bus.”h]”hŒ5Table of devices this driver should match on the bus.”…”�”}”(hj) h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K§hj& ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j% h´K¦hjx ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j‹hj0 ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j=hj¨ h²hh³Nh´Nubhì)�”}”(hŒ**Description**”h]”jH)�”}”(hjS h]”hŒ Description”…”�”}”(hjU h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhjQ ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´Kªhj¨ h²hubhì)�”}”(hŒýAuxiliary drivers follow the standard driver model convention, where discovery/enumeration is handled by the core, and drivers provide probe() and remove() methods. They support power management and shutdown notifications using the standard conventions.”h]”hŒýAuxiliary drivers follow the standard driver model convention, where discovery/enumeration is handled by the core, and drivers provide probe() and remove() methods. They support power management and shutdown notifications using the standard conventions.”…”�”}”(hji h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K§hj¨ h²hubhì)�”}”(hŒ²Auxiliary drivers register themselves with the bus by calling auxiliary_driver_register(). The id_table contains the match_names of auxiliary devices that a driver can bind with.”h]”hŒ²Auxiliary drivers register themselves with the bus by calling auxiliary_driver_register(). The id_table contains the match_names of auxiliary devices that a driver can bind with.”…”�”}”(hjx h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K¬hj¨ h²hubjc)�”}”(hXdstatic const struct auxiliary_device_id my_auxiliary_id_table[] = { { .name = "foo_mod.foo_dev" }, {}, }; MODULE_DEVICE_TABLE(auxiliary, my_auxiliary_id_table); struct auxiliary_driver my_drv = { .name = "myauxiliarydrv", .id_table = my_auxiliary_id_table, .probe = my_drv_probe, .remove = my_drv_remove };”h]”hXdstatic const struct auxiliary_device_id my_auxiliary_id_table[] = { { .name = "foo_mod.foo_dev" }, {}, }; MODULE_DEVICE_TABLE(auxiliary, my_auxiliary_id_table); struct auxiliary_driver my_drv = { .name = "myauxiliarydrv", .id_table = my_auxiliary_id_table, .probe = my_drv_probe, .remove = my_drv_remove };”…”�”}”hj‡ sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆj ‰jj2j}”uh1jbh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´K°hj¨ h²hubjŸ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j«Œ!module_auxiliary_driver (C macro)”Œc.module_auxiliary_driver”hNt”auh1jžhj¨ h²hh³Nh´Nubj°)�”}”(hhh]”(jµ)�”}”(hŒmodule_auxiliary_driver”h]”j»)�”}”(hŒmodule_auxiliary_driver”h]”jä)�”}”(hŒmodule_auxiliary_driver”h]”jê)�”}”(hjª h]”hŒmodule_auxiliary_driver”…”�”}”(hj´ h²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhj° ubah}”(h]”h ]”(jüjýeh"]”h$]”h&]”hÅhÆuh1jãhj¬ h²hh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´Mubah}”(h]”h ]”h"]”h$]”h&]”hÅhÆjˆuh1jºjj hj¨ h²hh³jÇ h´Mubah}”(h]”j£ ah ]”(j jeh"]”h$]”h&]”jˆj)jhuh1j´h³jÇ h´Mhj¥ h²hubj)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jhj¥ h²hh³jÇ h´Mubeh}”(h]”h ]”(j2Œmacro”eh"]”h$]”h&]”j7j2j8jà j9jà j:‰j;‰j<‰uh1j¯h²hhj¨ h³Nh´Nubhì)�”}”(hŒ0``module_auxiliary_driver (__auxiliary_driver)``”h]”j�)�”}”(hjæ h]”hŒ,module_auxiliary_driver (__auxiliary_driver)”…”�”}”(hjè h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhjä ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´Mhj¨ h²hubhŒ block_quote”“”)�”}”(hŒ1Helper macro for registering an auxiliary driver ”h]”hì)�”}”(hŒ0Helper macro for registering an auxiliary driver”h]”hŒ0Helper macro for registering an auxiliary driver”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´Mhjþ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jü h³j h´Mhj¨ •°bh²hubj>)�”}”(hXm**Parameters** ``__auxiliary_driver`` auxiliary driver struct **Description** Helper macro for auxiliary drivers which do not do anything special in module init/exit. This eliminates a lot of boilerplate. Each module may only use this macro once, and calling it replaces module_init() and module_exit() .. code-block:: c module_auxiliary_driver(my_drv);”h]”(hì)�”}”(hŒ**Parameters**”h]”jH)�”}”(hj h]”hŒ Parameters”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´Mhj ubjŒ)�”}”(hhh]”j‘)�”}”(hŒ/``__auxiliary_driver`` auxiliary driver struct ”h]”(j—)�”}”(hŒ``__auxiliary_driver``”h]”j�)�”}”(hj< h]”hŒ__auxiliary_driver”…”�”}”(hj> h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj: ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´Mhj6 ubj³)�”}”(hhh]”hì)�”}”(hŒauxiliary driver struct”h]”hŒauxiliary driver struct”…”�”}”(hjU h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³jQ h´MhjR ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj6 ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³jQ h´Mhj3 ubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hj ubhì)�”}”(hŒ**Description**”h]”jH)�”}”(hjw h]”hŒ Description”…”�”}”(hjy h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhju ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´Mhj ubhì)�”}”(hŒàHelper macro for auxiliary drivers which do not do anything special in module init/exit. This eliminates a lot of boilerplate. Each module may only use this macro once, and calling it replaces module_init() and module_exit()”h]”hŒàHelper macro for auxiliary drivers which do not do anything special in module init/exit. This eliminates a lot of boilerplate. Each module may only use this macro once, and calling it replaces module_init() and module_exit()”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´Mhj ubjc)�”}”(hŒ module_auxiliary_driver(my_drv);”h]”hŒ module_auxiliary_driver(my_drv);”…”�”}”hjœ sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆj ‰jj2j}”uh1jbh³Œf/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:38: ./include/linux/auxiliary_bus.h”h´Mhj ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j=hj¨ h²hh³Nh´NubjŸ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j«Œ(__auxiliary_driver_register (C function)”Œc.__auxiliary_driver_register”hNt”auh1jžhj¨ h²hh³Nh´Nubj°)�”}”(hhh]”(jµ)�”}”(hŒlint __auxiliary_driver_register (struct auxiliary_driver *auxdrv, struct module *owner, const char *modname)”h]”j»)�”}”(hŒkint __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner, const char *modname)”h]”(jK)�”}”(hŒint”h]”hŒint”…”�”}”(hjÌ h²hh³Nh´Nubah}”(h]”h ]”jWah"]”h$]”h&]”uh1jJhjÈ h²hh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´MTubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÛ h²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjÈ h²hh³jÚ h´MTubjä)�”}”(hŒ__auxiliary_driver_register”h]”jê)�”}”(hŒ__auxiliary_driver_register”h]”hŒ__auxiliary_driver_register”…”�”}”(hjí h²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhjé ubah}”(h]”h ]”(jüjýeh"]”h$]”h&]”hÅhÆuh1jãhjÈ h²hh³jÚ h´MTubjƒ)�”}”(hŒL(struct auxiliary_driver *auxdrv, struct module *owner, const char *modname)”h]”(j‰)�”}”(hŒstruct auxiliary_driver *auxdrv”h]”(jÁ)�”}”(hjÄh]”hŒstruct”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”jÍah"]”h$]”h&]”uh1jÀhjubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjubh)�”}”(hhh]”jê)�”}”(hŒauxiliary_driver”h]”hŒauxiliary_driver”…”�”}”(hj'h²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhj$ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j2Œreftype”jÂŒ reftarget”j)Œmodname”NŒ classname”NjÆjÉ)�”}”jÌ]”jÏ)�”}”jÂjï sbŒc.__auxiliary_driver_register”†”asbuh1hhjubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjGh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjubjã)�”}”(hjæh]”hŒ*”…”�”}”(hjUh²hh³Nh´Nubah}”(h]”h ]”jïah"]”h$]”h&]”uh1jâhjubjê)�”}”(hŒauxdrv”h]”hŒauxdrv”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhjubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1jˆhjubj‰)�”}”(hŒstruct module *owner”h]”(jÁ)�”}”(hjÄh]”hŒstruct”…”�”}”(hj{h²hh³Nh´Nubah}”(h]”h ]”jÍah"]”h$]”h&]”uh1jÀhjwubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjˆh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjwubh)�”}”(hhh]”jê)�”}”(hŒmodule”h]”hŒmodule”…”�”}”(hj™h²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhj–ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j2Œreftype”jÂŒ reftarget”j›Œmodname”NŒ classname”NjÆjÉ)�”}”jÌ]”jCŒc.__auxiliary_driver_register”†”asbuh1hhjwubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj·h²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjwubjã)�”}”(hjæh]”hŒ*”…”�”}”(hjÅh²hh³Nh´Nubah}”(h]”h ]”jïah"]”h$]”h&]”uh1jâhjwubjê)�”}”(hŒowner”h]”hŒowner”…”�”}”(hjÒh²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhjwubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1jˆhjubj‰)�”}”(hŒconst char *modname”h]”(jÁ)�”}”(hjÁh]”hŒconst”…”�”}”(hjëh²hh³Nh´Nubah}”(h]”h ]”jÍah"]”h$]”h&]”uh1jÀhjçubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjøh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjçubjK)�”}”(hŒchar”h]”hŒchar”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jWah"]”h$]”h&]”uh1jJhjçubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjçubjã)�”}”(hjæh]”hŒ*”…”�”}”(hj"h²hh³Nh´Nubah}”(h]”h ]”jïah"]”h$]”h&]”uh1jâhjçubjê)�”}”(hŒmodname”h]”hŒmodname”…”�”}”(hj/h²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhjçubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1jˆhjubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j‚hjÈ h²hh³jÚ h´MTubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjˆuh1jºjj hjÄ h²hh³jÚ h´MTubah}”(h]”j¿ ah ]”(j jeh"]”h$]”h&]”jˆj)jhuh1j´h³jÚ h´MThjÁ h²hubj)�”}”(hhh]”hì)�”}”(hŒ+register a driver for auxiliary bus devices”h]”hŒ+register a driver for auxiliary bus devices”…”�”}”(hjYh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´MThjVh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÁ h²hh³jÚ h´MTubeh}”(h]”h ]”(j2Œfunction”eh"]”h$]”h&]”j7j2j8jqj9jqj:‰j;‰j<‰uh1j¯h²hhj¨ h³Nh´Nubj>)�”}”(hXÄ**Parameters** ``struct auxiliary_driver *auxdrv`` auxiliary_driver structure ``struct module *owner`` owning module/driver ``const char *modname`` KBUILD_MODNAME for parent driver **Description** The expectation is that users will call the "auxiliary_driver_register" macro so that the caller's KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires a custom name would this version be called directly.”h]”(hì)�”}”(hŒ**Parameters**”h]”jH)�”}”(hj{h]”hŒ Parameters”…”�”}”(hj}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhjyubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´MXhjuubjŒ)�”}”(hhh]”(j‘)�”}”(hŒ?``struct auxiliary_driver *auxdrv`` auxiliary_driver structure ”h]”(j—)�”}”(hŒ#``struct auxiliary_driver *auxdrv``”h]”j�)�”}”(hjšh]”hŒstruct auxiliary_driver *auxdrv”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj˜ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´MUhj”ubj³)�”}”(hhh]”hì)�”}”(hŒauxiliary_driver structure”h]”hŒauxiliary_driver structure”…”�”}”(hj³h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j¯h´MUhj°ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj”ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j¯h´MUhj‘ubj‘)�”}”(hŒ.``struct module *owner`` owning module/driver ”h]”(j—)�”}”(hŒ``struct module *owner``”h]”j�)�”}”(hjÓh]”hŒstruct module *owner”…”�”}”(hjÕh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhjÑubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´MVhjÍubj³)�”}”(hhh]”hì)�”}”(hŒowning module/driver”h]”hŒowning module/driver”…”�”}”(hjìh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³jèh´MVhjéubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hjÍubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³jèh´MVhj‘ubj‘)�”}”(hŒ9``const char *modname`` KBUILD_MODNAME for parent driver ”h]”(j—)�”}”(hŒ``const char *modname``”h]”j�)�”}”(hj h]”hŒconst char *modname”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´MWhjubj³)�”}”(hhh]”hì)�”}”(hŒ KBUILD_MODNAME for parent driver”h]”hŒ KBUILD_MODNAME for parent driver”…”�”}”(hj%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j!h´MWhj"ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j!h´MWhj‘ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j‹hjuubhì)�”}”(hŒ**Description**”h]”jH)�”}”(hjGh]”hŒ Description”…”�”}”(hjIh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhjEubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´MYhjuubhì)�”}”(hŒôThe expectation is that users will call the "auxiliary_driver_register" macro so that the caller's KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires a custom name would this version be called directly.”h]”hŒúThe expectation is that users will call the “auxiliary_driver_registerâ€� macro so that the caller’s KBUILD_MODNAME is automatically inserted for the modname parameter. Only if a user requires a custom name would this version be called directly.”…”�”}”(hj]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´MXhjuubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j=hj¨ h²hh³Nh´NubjŸ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j«Œ(auxiliary_driver_unregister (C function)”Œc.auxiliary_driver_unregister”hNt”auh1jžhj¨ h²hh³Nh´Nubj°)�”}”(hhh]”(jµ)�”}”(hŒBvoid auxiliary_driver_unregister (struct auxiliary_driver *auxdrv)”h]”j»)�”}”(hŒAvoid auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)”h]”(jK)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hjŒh²hh³Nh´Nubah}”(h]”h ]”jWah"]”h$]”h&]”uh1jJhjˆh²hh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´M{ubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj›h²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjˆh²hh³jšh´M{ubjä)�”}”(hŒauxiliary_driver_unregister”h]”jê)�”}”(hŒauxiliary_driver_unregister”h]”hŒauxiliary_driver_unregister”…”�”}”(hj­h²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhj©ubah}”(h]”h ]”(jüjýeh"]”h$]”h&]”hÅhÆuh1jãhjˆh²hh³jšh´M{ubjƒ)�”}”(hŒ!(struct auxiliary_driver *auxdrv)”h]”j‰)�”}”(hŒstruct auxiliary_driver *auxdrv”h]”(jÁ)�”}”(hjÄh]”hŒstruct”…”�”}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”jÍah"]”h$]”h&]”uh1jÀhjÅubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÖh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjÅubh)�”}”(hhh]”jê)�”}”(hŒauxiliary_driver”h]”hŒauxiliary_driver”…”�”}”(hjçh²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhjäubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j2Œreftype”jÂŒ reftarget”jéŒmodname”NŒ classname”NjÆjÉ)�”}”jÌ]”jÏ)�”}”jÂj¯sbŒc.auxiliary_driver_unregister”†”asbuh1hhjÅubjÓ)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jßah"]”h$]”h&]”uh1jÒhjÅubjã)�”}”(hjæh]”hŒ*”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jïah"]”h$]”h&]”uh1jâhjÅubjê)�”}”(hŒauxdrv”h]”hŒauxdrv”…”�”}”(hj"h²hh³Nh´Nubah}”(h]”h ]”jõah"]”h$]”h&]”uh1jéhjÅubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1jˆhjÁubah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j‚hjˆh²hh³jšh´M{ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjˆuh1jºjj hj„h²hh³jšh´M{ubah}”(h]”jah ]”(j jeh"]”h$]”h&]”jˆj)jhuh1j´h³jšh´M{hj�h²hubj)�”}”(hhh]”hì)�”}”(hŒunregister a driver”h]”hŒunregister a driver”…”�”}”(hjLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´M{hjIh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj�h²hh³jšh´M{ubeh}”(h]”h ]”(j2Œfunction”eh"]”h$]”h&]”j7j2j8jdj9jdj:‰j;‰j<‰uh1j¯h²hhj¨ h³Nh´Nubj>)�”}”(hŒP**Parameters** ``struct auxiliary_driver *auxdrv`` auxiliary_driver structure”h]”(hì)�”}”(hŒ**Parameters**”h]”jH)�”}”(hjnh]”hŒ Parameters”…”�”}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jGhjlubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´MhjhubjŒ)�”}”(hhh]”j‘)�”}”(hŒ>``struct auxiliary_driver *auxdrv`` auxiliary_driver structure”h]”(j—)�”}”(hŒ#``struct auxiliary_driver *auxdrv``”h]”j�)�”}”(hj�h]”hŒstruct auxiliary_driver *auxdrv”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1j–h³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´M�hj‡ubj³)�”}”(hhh]”hì)�”}”(hŒauxiliary_driver structure”h]”hŒauxiliary_driver structure”…”�”}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:41: ./drivers/base/auxiliary.c”h´M|hj£ubah}”(h]”h ]”h"]”h$]”h&]”uh1j²hj‡ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³j¢h´M�hj„ubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hjhubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j=hj¨ h²hh³Nh´Nubeh}”(h]”Œauxiliary-drivers”ah ]”h"]”Œauxiliary drivers”ah$]”h&]”uh1hÖhhØh²hh³hÇh´K$ubh×)�”}”(hhh]”(hÜ)�”}”(hŒ Example Usage”h]”hŒ Example Usage”…”�”}”(hjÙh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjÖh²hh³hÇh´K-ubhì)�”}”(hX¡Auxiliary devices are created and registered by a subsystem-level core device that needs to break up its functionality into smaller fragments. One way to extend the scope of an auxiliary_device is to encapsulate it within a domain-specific structure defined by the parent device. This structure contains the auxiliary_device and any associated shared data/callbacks needed to establish the connection with the parent.”h]”hX¡Auxiliary devices are created and registered by a subsystem-level core device that needs to break up its functionality into smaller fragments. One way to extend the scope of an auxiliary_device is to encapsulate it within a domain-specific structure defined by the parent device. This structure contains the auxiliary_device and any associated shared data/callbacks needed to establish the connection with the parent.”…”�”}”(hjçh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:47: ./drivers/base/auxiliary.c”h´KZhjÖh²hubhì)�”}”(hŒAn example is:”h]”hŒAn example is:”…”�”}”(hjöh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:47: ./drivers/base/auxiliary.c”h´KahjÖh²hubjc)�”}”(hŒ» struct foo { struct auxiliary_device auxdev; void (*connect)(struct auxiliary_device *auxdev); void (*disconnect)(struct auxiliary_device *auxdev); void *data; };”h]”hŒ» struct foo { struct auxiliary_device auxdev; void (*connect)(struct auxiliary_device *auxdev); void (*disconnect)(struct auxiliary_device *auxdev); void *data; };”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆj ‰jj2j}”uh1jbh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:47: ./drivers/base/auxiliary.c”h´KchjÖh²hubhì)�”}”(hXjThe parent device then registers the auxiliary_device by calling auxiliary_device_init(), and then auxiliary_device_add(), with the pointer to the auxdev member of the above structure. The parent provides a name for the auxiliary_device that, combined with the parent's KBUILD_MODNAME, creates a match_name that is be used for matching and binding with a driver.”h]”hXlThe parent device then registers the auxiliary_device by calling auxiliary_device_init(), and then auxiliary_device_add(), with the pointer to the auxdev member of the above structure. The parent provides a name for the auxiliary_device that, combined with the parent’s KBUILD_MODNAME, creates a match_name that is be used for matching and binding with a driver.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:47: ./drivers/base/auxiliary.c”h´KlhjÖh²hubhì)�”}”(hX7Whenever an auxiliary_driver is registered, based on the match_name, the auxiliary_driver's probe() is invoked for the matching devices. The auxiliary_driver can also be encapsulated inside custom drivers that make the core device's functionality extensible by adding additional domain-specific ops as follows:”h]”hX;Whenever an auxiliary_driver is registered, based on the match_name, the auxiliary_driver’s probe() is invoked for the matching devices. The auxiliary_driver can also be encapsulated inside custom drivers that make the core device’s functionality extensible by adding additional domain-specific ops as follows:”…”�”}”(hj$h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:47: ./drivers/base/auxiliary.c”h´KrhjÖh²hubjc)�”}”(hŒëstruct my_ops { void (*send)(struct auxiliary_device *auxdev); void (*receive)(struct auxiliary_device *auxdev); }; struct my_driver { struct auxiliary_driver auxiliary_drv; const struct my_ops ops; };”h]”hŒëstruct my_ops { void (*send)(struct auxiliary_device *auxdev); void (*receive)(struct auxiliary_device *auxdev); }; struct my_driver { struct auxiliary_driver auxiliary_drv; const struct my_ops ops; };”…”�”}”hj3sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆj ‰jj2j}”uh1jbh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:47: ./drivers/base/auxiliary.c”h´KxhjÖh²hubhì)�”}”(hŒ$An example of this type of usage is:”h]”hŒ$An example of this type of usage is:”…”�”}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:47: ./drivers/base/auxiliary.c”h´K…hjÖh²hubjc)�”}”(hXconst struct auxiliary_device_id my_auxiliary_id_table[] = { { .name = "foo_mod.foo_dev" }, { }, }; const struct my_ops my_custom_ops = { .send = my_tx, .receive = my_rx, }; const struct my_driver my_drv = { .auxiliary_drv = { .name = "myauxiliarydrv", .id_table = my_auxiliary_id_table, .probe = my_probe, .remove = my_remove, .shutdown = my_shutdown, }, .ops = my_custom_ops, };”h]”hXconst struct auxiliary_device_id my_auxiliary_id_table[] = { { .name = "foo_mod.foo_dev" }, { }, }; const struct my_ops my_custom_ops = { .send = my_tx, .receive = my_rx, }; const struct my_driver my_drv = { .auxiliary_drv = { .name = "myauxiliarydrv", .id_table = my_auxiliary_id_table, .probe = my_probe, .remove = my_remove, .shutdown = my_shutdown, }, .ops = my_custom_ops, };”…”�”}”hjRsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆj ‰jj2j}”uh1jbh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:47: ./drivers/base/auxiliary.c”h´K‡hjÖh²hubhì)�”}”(hXHPlease note that such custom ops approach is valid, but it is hard to implement it right without global locks per-device to protect from auxiliary_drv removal during call to that ops. In addition, this implementation lacks proper module dependency, which causes to load/unload races between auxiliary parent and devices modules.”h]”hXHPlease note that such custom ops approach is valid, but it is hard to implement it right without global locks per-device to protect from auxiliary_drv removal during call to that ops. In addition, this implementation lacks proper module dependency, which causes to load/unload races between auxiliary parent and devices modules.”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:47: ./drivers/base/auxiliary.c”h´KžhjÖh²hubhì)�”}”(hŒÏThe most easiest way to provide these ops reliably without needing to have a lock is to EXPORT_SYMBOL*() them and rely on already existing modules infrastructure for validity and correct dependencies chains.”h]”hŒÏThe most easiest way to provide these ops reliably without needing to have a lock is to EXPORT_SYMBOL*() them and rely on already existing modules infrastructure for validity and correct dependencies chains.”…”�”}”(hjqh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³Œa/var/lib/git/docbuild/linux/Documentation/driver-api/auxiliary_bus:47: ./drivers/base/auxiliary.c”h´K¤hjÖh²hubeh}”(h]”Œ example-usage”ah ]”h"]”Œ example usage”ah$]”h&]”uh1hÖhhØh²hh³hÇh´K-ubeh}”(h]”(hÕŒid1”eh ]”h"]”(Œ auxiliary bus”Œ auxiliary_bus”eh$]”h&]”uh1hÖhhh²hh³hÇh´KŒexpect_referenced_by_name”}”jŽhÊsŒexpect_referenced_by_id”}”hÕhÊsubeh}”(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”}”hÕ]”hÊasŒnameids”}”(jŽhÕj�jŠjŠj‡j¥ j¢ j� jš jÓjÐj…j‚uŒ nametypes”}”(jŽˆj�‰jЉj¥ ‰j� ‰jÓ‰j…‰uh}”(hÕhØjŠhØj‡j)j¢ j�j­j¶j=jBjjjš j- jÐj¨ jÅ jÊ j£ j¨ j¿ jÄ jj„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”“”}”jÆKs…”R”Œparse_messages”]”Œtransform_messages”]”hŒsystem_message”“”)�”}”(hhh]”hì)�”}”(hhh]”hŒ3Hyperlink target "auxiliary-bus" is not referenced.”…”�”}”hj"sbah}”(h]”h ]”h"]”h$]”h&]”uh1hëhjubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”ŒINFO”Œsource”hÇŒline”Kuh1jubaŒ transformer”NŒ include_log”]”Œ decoration”Nh²hub.