00
     ˆÆÅ„@ëÿÄ¾Â +G    /* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2019-2020 Intel Corporation
 *
 * Please see Documentation/driver-api/auxiliary_bus.rst for more information.
 */

#ifndef _AUXILIARY_BUS_H_
#define _AUXILIARY_BUS_H_

#include <linux/device.h>
#include <linux/mod_devicetable.h>

/**
 * DOC: DEVICE_LIFESPAN
 *
 * 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.
 *
 * To 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.
 *
 * 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).
 *
 * 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.
 *
 * The 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).
 *
 * 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.
 */

/**
 * struct auxiliary_device - auxiliary device object.
 * @dev: Device,
 *       The release and parent fields of the device structure must be filled
 *       in
 * @name: Match name found by the auxiliary device driver,
 * @id: unique identitier if multiple devices of the same name are exported,
 * @sysfs: embedded struct which hold all sysfs related fields,
 * @sysfs.irqs: irqs xarray contains irq indices which are used by the device,
 * @sysfs.lock: Synchronize irq sysfs creation,
 * @sysfs.irq_dir_exists: whether "irqs" directory exists,
 *
 * 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'.
 *
 * Registering an auxiliary_device is a three-step process.
 *
 * 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.
 *
 * 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 