Lines Matching +full:sub +full:- +full:modules
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2019-2020 Intel Corporation
5 * Please see Documentation/driver-api/auxiliary_bus.rst for more information.
28 * Virtual Function management). A split of the functionality into child-
29 * devices representing sub-domains of functionality makes it possible to
30 * compartmentalize, layer, and distribute domain-specific concerns via a Linux
31 * device-driver model.
38 * and focused on hardware-specific control and communication.
42 * an auxiliary_device within other domain-specific structures and the use of
44 * the use of a communication channel with the parent is domain-specific.
56 * modules, who share a common header file with the driver, need a mechanism to
65 * One example is a PCI network device that is RDMA-capable and exports a child
72 * Another use case is for the PCI device to be split out into multiple sub
73 * functions. For each sub function an auxiliary_device is created. A PCI sub
75 * devices. A PCI sub function auxiliary device is likely to be contained in a
76 * struct with additional attributes such as user defined sub function number
92 * Auxiliary devices are created and registered by a subsystem-level core
95 * domain-specific structure defined by the parent device. This structure
101 * .. code-block:: c
120 * domain-specific ops as follows:
122 * .. code-block:: c
137 * .. code-block:: c
161 * it right without global locks per-device to protect from auxiliary_drv removal
164 * modules.
168 * modules infrastructure for validity and correct dependencies chains.
174 for (; id->name[0]; id++) { in auxiliary_match_id()
175 const char *p = strrchr(dev_name(&auxdev->dev), '.'); in auxiliary_match_id()
180 match_size = p - dev_name(&auxdev->dev); in auxiliary_match_id()
182 /* use dev_name(&auxdev->dev) prefix before last '.' char to match to */ in auxiliary_match_id()
183 if (strlen(id->name) == match_size && in auxiliary_match_id()
184 !strncmp(dev_name(&auxdev->dev), id->name, match_size)) in auxiliary_match_id()
195 return !!auxiliary_match_id(auxdrv->id_table, auxdev); in auxiliary_match()
206 (int)(p - name), name); in auxiliary_uevent()
216 const struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); in auxiliary_bus_probe()
226 ret = auxdrv->probe(auxdev, auxiliary_match_id(auxdrv->id_table, auxdev)); in auxiliary_bus_probe()
235 const struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); in auxiliary_bus_remove()
238 if (auxdrv->remove) in auxiliary_bus_remove()
239 auxdrv->remove(auxdev); in auxiliary_bus_remove()
248 if (dev->driver) { in auxiliary_bus_shutdown()
249 auxdrv = to_auxiliary_drv(dev->driver); in auxiliary_bus_shutdown()
253 if (auxdrv && auxdrv->shutdown) in auxiliary_bus_shutdown()
254 auxdrv->shutdown(auxdev); in auxiliary_bus_shutdown()
268 * auxiliary_device_init - check auxiliary_device and initialize
271 * This is the second step in the three-step process to register an
280 * to auxiliary_device_uninit(). In this post-initialize error scenario, a call
281 * to the device's .release callback will be triggered, and all memory clean-up
286 struct device *dev = &auxdev->dev; in auxiliary_device_init()
288 if (!dev->parent) { in auxiliary_device_init()
289 pr_err("auxiliary_device has a NULL dev->parent\n"); in auxiliary_device_init()
290 return -EINVAL; in auxiliary_device_init()
293 if (!auxdev->name) { in auxiliary_device_init()
295 return -EINVAL; in auxiliary_device_init()
298 dev->bus = &auxiliary_bus_type; in auxiliary_device_init()
299 device_initialize(&auxdev->dev); in auxiliary_device_init()
300 mutex_init(&auxdev->sysfs.lock); in auxiliary_device_init()
306 * __auxiliary_device_add - add an auxiliary bus device
310 * This is the third step in the three-step process to register an
326 struct device *dev = &auxdev->dev; in __auxiliary_device_add()
331 return -EINVAL; in __auxiliary_device_add()
334 ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id); in __auxiliary_device_add()
349 * __auxiliary_driver_register - register a driver for auxiliary bus devices
364 if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) in __auxiliary_driver_register()
365 return -EINVAL; in __auxiliary_driver_register()
367 if (auxdrv->name) in __auxiliary_driver_register()
368 auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, in __auxiliary_driver_register()
369 auxdrv->name); in __auxiliary_driver_register()
371 auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname); in __auxiliary_driver_register()
372 if (!auxdrv->driver.name) in __auxiliary_driver_register()
373 return -ENOMEM; in __auxiliary_driver_register()
375 auxdrv->driver.owner = owner; in __auxiliary_driver_register()
376 auxdrv->driver.bus = &auxiliary_bus_type; in __auxiliary_driver_register()
377 auxdrv->driver.mod_name = modname; in __auxiliary_driver_register()
379 ret = driver_register(&auxdrv->driver); in __auxiliary_driver_register()
381 kfree(auxdrv->driver.name); in __auxiliary_driver_register()
388 * auxiliary_driver_unregister - unregister a driver
393 driver_unregister(&auxdrv->driver); in auxiliary_driver_unregister()
394 kfree(auxdrv->driver.name); in auxiliary_driver_unregister()