Commit | Line | Data |
---|---|---|
7de3697e DE |
1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* | |
3 | * Copyright (c) 2019-2020 Intel Corporation | |
4 | * | |
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> | |
7de3697e | 13 | |
e1b51868 IW |
14 | /** |
15 | * DOC: DEVICE_LIFESPAN | |
16 | * | |
17 | * The registering driver is the entity that allocates memory for the | |
18 | * auxiliary_device and registers it on the auxiliary bus. It is important to | |
19 | * note that, as opposed to the platform bus, the registering driver is wholly | |
20 | * 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 should | |
24 | * only call auxiliary_device_delete() and then auxiliary_device_uninit() when | |
25 | * it is done with the device. The release() function is then automatically | |
26 | * called if and when other code releases their reference to the devices. | |
27 | * | |
28 | * A parent object, defined in the shared header file, contains the | |
29 | * auxiliary_device. It also contains a pointer to the shared object(s), which | |
30 | * also is defined in the shared header. Both the parent object and the shared | |
31 | * object(s) are allocated by the registering driver. This layout allows the | |
32 | * auxiliary_driver's registering module to perform a container_of() call to go | |
33 | * from the pointer to the auxiliary_device, that is passed during the call to | |
34 | * the auxiliary_driver's probe function, up to the parent object, and then | |
35 | * have access to the shared object(s). | |
36 | * | |
37 | * The memory for the shared object(s) must have a lifespan equal to, or | |
38 | * greater than, the lifespan of the memory for the auxiliary_device. The | |
39 | * auxiliary_driver should only consider that the shared object is valid as | |
40 | * long as the auxiliary_device is still registered on the auxiliary bus. It | |
41 | * is up to the registering driver to manage (e.g. free or keep available) the | |
42 | * memory for the shared object beyond the life of the auxiliary_device. | |
43 | * | |
44 | * The registering driver must unregister all auxiliary devices before its own | |
45 | * driver.remove() is completed. An easy way to ensure this is to use the | |
46 | * devm_add_action_or_reset() call to register a function against the parent | |
47 | * device which unregisters the auxiliary device object(s). | |
48 | * | |
49 | * Finally, any operations which operate on the auxiliary devices must continue | |
50 | * to function (if only to return an error) after the registering driver | |
51 | * 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 filled | |
58 | * in | |
59 | * @name: Match name found by the auxiliary device driver, | |
60 | * @id: unique identitier if multiple devices of the same name are exported, | |
c14112a5 SD |
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, | |
e1b51868 IW |
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 drivers | |
68 | * KBUILD_MODNAME, creates a match_name that is used for driver binding, and an | |
69 | * id that combined with the match_name provide a unique name to register with | |
70 | * the bus subsystem. For example, a driver registering an auxiliary device is | |
71 | * named 'foo_mod.ko' and the subdevice is named 'foo_dev'. The match name is | |
72 | * 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 each | |
77 | * sub-device desired. The name, id, dev.release, and dev.parent fields of | |
78 | * this structure must be filled in as follows. | |
79 | * | |
80 | * The 'name' field is to be given a name that is recognized by the auxiliary | |
81 | * driver. If two auxiliary_devices with the same match_name, eg | |
82 | * "foo_mod.foo_dev", are registered onto the bus, they must have unique id | |
83 | * values (e.g. "x" and "y") so that the registered devices names are | |
84 | * "foo_mod.foo_dev.x" and "foo_mod.foo_dev.y". If match_name + id are not | |
85 | * unique, then the device_add fails and generates an error message. | |
86 | * | |
87 | * The auxiliary_device.dev.type.release or auxiliary_device.dev.release must | |
88 | * be populated with a non-NULL pointer to successfully register the | |
89 | * auxiliary_device. This release call is where resources associated with the | |
90 | * auxiliary device must be free'ed. Because once the device is placed on the | |
91 | * bus the parent driver can not tell what other code may have a reference to | |
92 | * this data. | |
93 | * | |
94 | * The auxiliary_device.dev.parent should be set. Typically to the registering | |
95 | * drivers device. | |
96 | * | |
97 | * Second, call auxiliary_device_init(), which checks several aspects of the | |
98 | * auxiliary_device struct and performs a device_initialize(). After this step | |
99 | * completes, any error state must have a call to auxiliary_device_uninit() in | |
100 | * its resolution path. | |
101 | * | |
102 | * The third and final step in registering an auxiliary_device is to perform a | |
103 | * call to auxiliary_device_add(), which sets the name of the device and adds | |
104 | * the device to the bus. | |
105 | * | |
106 | * .. code-block:: c | |
107 | * | |
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 the | |
134 | * register process. First call auxiliary_device_delete(), then call | |
135 | * auxiliary_device_uninit(). | |
136 | * | |
137 | * .. code-block:: c | |
138 | * | |
139 | * auxiliary_device_delete(my_dev->my_aux_dev); | |
140 | * auxiliary_device_uninit(my_dev->my_aux_dev); | |
141 | */ | |
7de3697e DE |
142 | struct auxiliary_device { |
143 | struct device dev; | |
144 | const char *name; | |
145 | u32 id; | |
a8088783 SD |
146 | struct { |
147 | struct xarray irqs; | |
148 | struct mutex lock; /* Synchronize irq sysfs creation */ | |
149 | bool irq_dir_exists; | |
150 | } sysfs; | |
7de3697e DE |
151 | }; |
152 | ||
e1b51868 IW |
153 | /** |
154 | * struct auxiliary_driver - Definition of an auxiliary bus driver | |
155 | * @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, where | |
165 | * discovery/enumeration is handled by the core, and drivers provide probe() | |
166 | * and remove() methods. They support power management and shutdown | |
167 | * notifications using the standard conventions. | |
168 | * | |
169 | * Auxiliary drivers register themselves with the bus by calling | |
170 | * auxiliary_driver_register(). The id_table contains the match_names of | |
171 | * auxiliary devices that a driver can bind with. | |
172 | * | |
173 | * .. code-block:: c | |
174 | * | |
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_remove | |
187 | * }; | |
188 | */ | |
7de3697e DE |
189 | struct auxiliary_driver { |
190 | int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id); | |
8142a46c | 191 | void (*remove)(struct auxiliary_device *auxdev); |
7de3697e DE |
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 | ||
365481e4 DB |
200 | static inline void *auxiliary_get_drvdata(struct auxiliary_device *auxdev) |
201 | { | |
202 | return dev_get_drvdata(&auxdev->dev); | |
203 | } | |
204 | ||
205 | static inline void auxiliary_set_drvdata(struct auxiliary_device *auxdev, void *data) | |
206 | { | |
207 | dev_set_drvdata(&auxdev->dev, data); | |
208 | } | |
209 | ||
7de3697e DE |
210 | static inline struct auxiliary_device *to_auxiliary_dev(struct device *dev) |
211 | { | |
212 | return container_of(dev, struct auxiliary_device, dev); | |
213 | } | |
214 | ||
ff985c75 | 215 | static inline const struct auxiliary_driver *to_auxiliary_drv(const struct device_driver *drv) |
7de3697e DE |
216 | { |
217 | return container_of(drv, struct auxiliary_driver, driver); | |
218 | } | |
219 | ||
220 | int auxiliary_device_init(struct auxiliary_device *auxdev); | |
221 | int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname); | |
222 | #define auxiliary_device_add(auxdev) __auxiliary_device_add(auxdev, KBUILD_MODNAME) | |
223 | ||
a8088783 SD |
224 | #ifdef CONFIG_SYSFS |
225 | int auxiliary_device_sysfs_irq_add(struct auxiliary_device *auxdev, int irq); | |
226 | void auxiliary_device_sysfs_irq_remove(struct auxiliary_device *auxdev, | |
227 | int irq); | |
228 | #else /* CONFIG_SYSFS */ | |
229 | static inline int | |
230 | auxiliary_device_sysfs_irq_add(struct auxiliary_device *auxdev, int irq) | |
231 | { | |
232 | return 0; | |
233 | } | |
234 | ||
235 | static inline void | |
236 | auxiliary_device_sysfs_irq_remove(struct auxiliary_device *auxdev, int irq) {} | |
237 | #endif | |
238 | ||
7de3697e DE |
239 | static inline void auxiliary_device_uninit(struct auxiliary_device *auxdev) |
240 | { | |
a8088783 | 241 | mutex_destroy(&auxdev->sysfs.lock); |
7de3697e DE |
242 | put_device(&auxdev->dev); |
243 | } | |
244 | ||
245 | static inline void auxiliary_device_delete(struct auxiliary_device *auxdev) | |
246 | { | |
247 | device_del(&auxdev->dev); | |
248 | } | |
249 | ||
250 | int __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 | ||
255 | void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv); | |
256 | ||
257 | /** | |
258 | * module_auxiliary_driver() - Helper macro for registering an auxiliary driver | |
259 | * @__auxiliary_driver: auxiliary driver struct | |
260 | * | |
261 | * Helper macro for auxiliary drivers which do not do anything special in | |
262 | * module init/exit. This eliminates a lot of boilerplate. Each module may only | |
263 | * use this macro once, and calling it replaces module_init() and module_exit() | |
14866a7d IW |
264 | * |
265 | * .. code-block:: c | |
266 | * | |
267 | * module_auxiliary_driver(my_drv); | |
7de3697e DE |
268 | */ |
269 | #define module_auxiliary_driver(__auxiliary_driver) \ | |
270 | module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister) | |
271 | ||
0d2bf11a GKH |
272 | struct auxiliary_device *auxiliary_find_device(struct device *start, |
273 | const void *data, | |
274 | int (*match)(struct device *dev, const void *data)); | |
7de3697e DE |
275 | |
276 | #endif /* _AUXILIARY_BUS_H_ */ |