123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- /* 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,
- *
- * 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 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.
- *
- * 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.
- *
- * The auxiliary_device.dev.parent should be set. Typically to the registering
- * drivers device.
- *
- * 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.
- *
- * 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.
- *
- * .. code-block:: c
- *
- * #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;
- * }
- *
- * ...
- *
- *
- * Unregistering an auxiliary_device is a two-step process to mirror the
- * register process. First call auxiliary_device_delete(), then call
- * auxiliary_device_uninit().
- *
- * .. code-block:: c
- *
- * auxiliary_device_delete(my_dev->my_aux_dev);
- * auxiliary_device_uninit(my_dev->my_aux_dev);
- */
- struct auxiliary_device {
- struct device dev;
- const char *name;
- u32 id;
- };
- /**
- * struct auxiliary_driver - Definition of an auxiliary bus driver
- * @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.
- *
- * 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.
- *
- * 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.
- *
- * .. code-block:: c
- *
- * static 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
- * };
- */
- 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;
- };
- static inline void *auxiliary_get_drvdata(struct auxiliary_device *auxdev)
- {
- return dev_get_drvdata(&auxdev->dev);
- }
- static inline void auxiliary_set_drvdata(struct auxiliary_device *auxdev, void *data)
- {
- dev_set_drvdata(&auxdev->dev, data);
- }
- static inline struct auxiliary_device *to_auxiliary_dev(struct device *dev)
- {
- return container_of(dev, struct auxiliary_device, dev);
- }
- static inline struct auxiliary_driver *to_auxiliary_drv(struct device_driver *drv)
- {
- return container_of(drv, struct auxiliary_driver, driver);
- }
- int auxiliary_device_init(struct auxiliary_device *auxdev);
- int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname);
- #define auxiliary_device_add(auxdev) __auxiliary_device_add(auxdev, KBUILD_MODNAME)
- static inline void auxiliary_device_uninit(struct auxiliary_device *auxdev)
- {
- put_device(&auxdev->dev);
- }
- static inline void auxiliary_device_delete(struct auxiliary_device *auxdev)
- {
- device_del(&auxdev->dev);
- }
- int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner,
- const char *modname);
- #define auxiliary_driver_register(auxdrv) \
- __auxiliary_driver_register(auxdrv, THIS_MODULE, KBUILD_MODNAME)
- void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);
- /**
- * module_auxiliary_driver() - Helper macro for registering an auxiliary driver
- * @__auxiliary_driver: auxiliary driver struct
- *
- * 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);
- */
- #define module_auxiliary_driver(__auxiliary_driver) \
- module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister)
- struct auxiliary_device *auxiliary_find_device(struct device *start,
- const void *data,
- int (*match)(struct device *dev, const void *data));
- #endif /* _AUXILIARY_BUS_H_ */
|