277 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright (c) 2019-2020 Intel Corporation4 *5 * Please see Documentation/driver-api/auxiliary_bus.rst for more information.6 */7 8#ifndef _AUXILIARY_BUS_H_9#define _AUXILIARY_BUS_H_10 11#include <linux/device.h>12#include <linux/mod_devicetable.h>13 14/**15 * DOC: DEVICE_LIFESPAN16 *17 * The registering driver is the entity that allocates memory for the18 * auxiliary_device and registers it on the auxiliary bus. It is important to19 * note that, as opposed to the platform bus, the registering driver is wholly20 * responsible for the management of the memory used for the device object.21 *22 * To be clear the memory for the auxiliary_device is freed in the release()23 * callback defined by the registering driver. The registering driver should24 * only call auxiliary_device_delete() and then auxiliary_device_uninit() when25 * it is done with the device. The release() function is then automatically26 * called if and when other code releases their reference to the devices.27 *28 * A parent object, defined in the shared header file, contains the29 * auxiliary_device. It also contains a pointer to the shared object(s), which30 * also is defined in the shared header. Both the parent object and the shared31 * object(s) are allocated by the registering driver. This layout allows the32 * auxiliary_driver's registering module to perform a container_of() call to go33 * from the pointer to the auxiliary_device, that is passed during the call to34 * the auxiliary_driver's probe function, up to the parent object, and then35 * have access to the shared object(s).36 *37 * The memory for the shared object(s) must have a lifespan equal to, or38 * greater than, the lifespan of the memory for the auxiliary_device. The39 * auxiliary_driver should only consider that the shared object is valid as40 * long as the auxiliary_device is still registered on the auxiliary bus. It41 * is up to the registering driver to manage (e.g. free or keep available) the42 * memory for the shared object beyond the life of the auxiliary_device.43 *44 * The registering driver must unregister all auxiliary devices before its own45 * driver.remove() is completed. An easy way to ensure this is to use the46 * devm_add_action_or_reset() call to register a function against the parent47 * device which unregisters the auxiliary device object(s).48 *49 * Finally, any operations which operate on the auxiliary devices must continue50 * to function (if only to return an error) after the registering driver51 * unregisters the auxiliary device.52 */53 54/**55 * struct auxiliary_device - auxiliary device object.56 * @dev: Device,57 * The release and parent fields of the device structure must be filled58 * in59 * @name: Match name found by the auxiliary device driver,60 * @id: unique identitier if multiple devices of the same name are exported,61 * @sysfs: embedded struct which hold all sysfs related fields,62 * @sysfs.irqs: irqs xarray contains irq indices which are used by the device,63 * @sysfs.lock: Synchronize irq sysfs creation,64 * @sysfs.irq_dir_exists: whether "irqs" directory exists,65 *66 * An auxiliary_device represents a part of its parent device's functionality.67 * It is given a name that, combined with the registering drivers68 * KBUILD_MODNAME, creates a match_name that is used for driver binding, and an69 * id that combined with the match_name provide a unique name to register with70 * the bus subsystem. For example, a driver registering an auxiliary device is71 * named 'foo_mod.ko' and the subdevice is named 'foo_dev'. The match name is72 * therefore 'foo_mod.foo_dev'.73 *74 * Registering an auxiliary_device is a three-step process.75 *76 * First, a 'struct auxiliary_device' needs to be defined or allocated for each77 * sub-device desired. The name, id, dev.release, and dev.parent fields of78 * this structure must be filled in as follows.79 *80 * The 'name' field is to be given a name that is recognized by the auxiliary81 * driver. If two auxiliary_devices with the same match_name, eg82 * "foo_mod.foo_dev", are registered onto the bus, they must have unique id83 * values (e.g. "x" and "y") so that the registered devices names are84 * "foo_mod.foo_dev.x" and "foo_mod.foo_dev.y". If match_name + id are not85 * unique, then the device_add fails and generates an error message.86 *87 * The auxiliary_device.dev.type.release or auxiliary_device.dev.release must88 * be populated with a non-NULL pointer to successfully register the89 * auxiliary_device. This release call is where resources associated with the90 * auxiliary device must be free'ed. Because once the device is placed on the91 * bus the parent driver can not tell what other code may have a reference to92 * this data.93 *94 * The auxiliary_device.dev.parent should be set. Typically to the registering95 * drivers device.96 *97 * Second, call auxiliary_device_init(), which checks several aspects of the98 * auxiliary_device struct and performs a device_initialize(). After this step99 * completes, any error state must have a call to auxiliary_device_uninit() in100 * its resolution path.101 *102 * The third and final step in registering an auxiliary_device is to perform a103 * call to auxiliary_device_add(), which sets the name of the device and adds104 * the device to the bus.105 *106 * .. code-block:: c107 *108 * #define MY_DEVICE_NAME "foo_dev"109 *110 * ...111 *112 * struct auxiliary_device *my_aux_dev = my_aux_dev_alloc(xxx);113 *114 * // Step 1:115 * my_aux_dev->name = MY_DEVICE_NAME;116 * my_aux_dev->id = my_unique_id_alloc(xxx);117 * my_aux_dev->dev.release = my_aux_dev_release;118 * my_aux_dev->dev.parent = my_dev;119 *120 * // Step 2:121 * if (auxiliary_device_init(my_aux_dev))122 * goto fail;123 *124 * // Step 3:125 * if (auxiliary_device_add(my_aux_dev)) {126 * auxiliary_device_uninit(my_aux_dev);127 * goto fail;128 * }129 *130 * ...131 *132 *133 * Unregistering an auxiliary_device is a two-step process to mirror the134 * register process. First call auxiliary_device_delete(), then call135 * auxiliary_device_uninit().136 *137 * .. code-block:: c138 *139 * auxiliary_device_delete(my_dev->my_aux_dev);140 * auxiliary_device_uninit(my_dev->my_aux_dev);141 */142struct auxiliary_device {143 struct device dev;144 const char *name;145 u32 id;146 struct {147 struct xarray irqs;148 struct mutex lock; /* Synchronize irq sysfs creation */149 bool irq_dir_exists;150 } sysfs;151};152 153/**154 * struct auxiliary_driver - Definition of an auxiliary bus driver155 * @probe: Called when a matching device is added to the bus.156 * @remove: Called when device is removed from the bus.157 * @shutdown: Called at shut-down time to quiesce the device.158 * @suspend: Called to put the device to sleep mode. Usually to a power state.159 * @resume: Called to bring a device from sleep mode.160 * @name: Driver name.161 * @driver: Core driver structure.162 * @id_table: Table of devices this driver should match on the bus.163 *164 * Auxiliary drivers follow the standard driver model convention, where165 * discovery/enumeration is handled by the core, and drivers provide probe()166 * and remove() methods. They support power management and shutdown167 * notifications using the standard conventions.168 *169 * Auxiliary drivers register themselves with the bus by calling170 * auxiliary_driver_register(). The id_table contains the match_names of171 * auxiliary devices that a driver can bind with.172 *173 * .. code-block:: c174 *175 * static const struct auxiliary_device_id my_auxiliary_id_table[] = {176 * { .name = "foo_mod.foo_dev" },177 * {},178 * };179 *180 * MODULE_DEVICE_TABLE(auxiliary, my_auxiliary_id_table);181 *182 * struct auxiliary_driver my_drv = {183 * .name = "myauxiliarydrv",184 * .id_table = my_auxiliary_id_table,185 * .probe = my_drv_probe,186 * .remove = my_drv_remove187 * };188 */189struct auxiliary_driver {190 int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id);191 void (*remove)(struct auxiliary_device *auxdev);192 void (*shutdown)(struct auxiliary_device *auxdev);193 int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state);194 int (*resume)(struct auxiliary_device *auxdev);195 const char *name;196 struct device_driver driver;197 const struct auxiliary_device_id *id_table;198};199 200static inline void *auxiliary_get_drvdata(struct auxiliary_device *auxdev)201{202 return dev_get_drvdata(&auxdev->dev);203}204 205static inline void auxiliary_set_drvdata(struct auxiliary_device *auxdev, void *data)206{207 dev_set_drvdata(&auxdev->dev, data);208}209 210static inline struct auxiliary_device *to_auxiliary_dev(struct device *dev)211{212 return container_of(dev, struct auxiliary_device, dev);213}214 215static inline const struct auxiliary_driver *to_auxiliary_drv(const struct device_driver *drv)216{217 return container_of(drv, struct auxiliary_driver, driver);218}219 220int auxiliary_device_init(struct auxiliary_device *auxdev);221int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname);222#define auxiliary_device_add(auxdev) __auxiliary_device_add(auxdev, KBUILD_MODNAME)223 224#ifdef CONFIG_SYSFS225int auxiliary_device_sysfs_irq_add(struct auxiliary_device *auxdev, int irq);226void auxiliary_device_sysfs_irq_remove(struct auxiliary_device *auxdev,227 int irq);228#else /* CONFIG_SYSFS */229static inline int230auxiliary_device_sysfs_irq_add(struct auxiliary_device *auxdev, int irq)231{232 return 0;233}234 235static inline void236auxiliary_device_sysfs_irq_remove(struct auxiliary_device *auxdev, int irq) {}237#endif238 239static inline void auxiliary_device_uninit(struct auxiliary_device *auxdev)240{241 mutex_destroy(&auxdev->sysfs.lock);242 put_device(&auxdev->dev);243}244 245static inline void auxiliary_device_delete(struct auxiliary_device *auxdev)246{247 device_del(&auxdev->dev);248}249 250int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner,251 const char *modname);252#define auxiliary_driver_register(auxdrv) \253 __auxiliary_driver_register(auxdrv, THIS_MODULE, KBUILD_MODNAME)254 255void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);256 257/**258 * module_auxiliary_driver() - Helper macro for registering an auxiliary driver259 * @__auxiliary_driver: auxiliary driver struct260 *261 * Helper macro for auxiliary drivers which do not do anything special in262 * module init/exit. This eliminates a lot of boilerplate. Each module may only263 * use this macro once, and calling it replaces module_init() and module_exit()264 *265 * .. code-block:: c266 *267 * module_auxiliary_driver(my_drv);268 */269#define module_auxiliary_driver(__auxiliary_driver) \270 module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister)271 272struct auxiliary_device *auxiliary_find_device(struct device *start,273 const void *data,274 device_match_t match);275 276#endif /* _AUXILIARY_BUS_H_ */277