Lines Matching +full:sub +full:- +full:function

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.
27 * interface for another subsystem to drive (e.g. SIOV Physical Function export
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.
65 * One example is a PCI network device that is RDMA-capable and exports a child
68 * function on the NIC. The RDMA driver registers an auxiliary_driver that
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
74 * function driver binds to such devices that creates its own one or more class
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
86 * individual function devices being physical devices.
92 * Auxiliary devices are created and registered by a subsystem-level core
95 * domain- pecific 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
164 for (; id->name[0]; id++) { in auxiliary_match_id()
165 const char *p = strrchr(dev_name(&auxdev->dev), '.'); in auxiliary_match_id()
170 match_size = p - dev_name(&auxdev->dev); in auxiliary_match_id()
172 /* use dev_name(&auxdev->dev) prefix before last '.' char to match to */ in auxiliary_match_id()
173 if (strlen(id->name) == match_size && in auxiliary_match_id()
174 !strncmp(dev_name(&auxdev->dev), id->name, match_size)) in auxiliary_match_id()
185 return !!auxiliary_match_id(auxdrv->id_table, auxdev); in auxiliary_match()
196 (int)(p - name), name); in auxiliary_uevent()
206 const struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); in auxiliary_bus_probe()
216 ret = auxdrv->probe(auxdev, auxiliary_match_id(auxdrv->id_table, auxdev)); in auxiliary_bus_probe()
225 const struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); in auxiliary_bus_remove()
228 if (auxdrv->remove) in auxiliary_bus_remove()
229 auxdrv->remove(auxdev); in auxiliary_bus_remove()
238 if (dev->driver) { in auxiliary_bus_shutdown()
239 auxdrv = to_auxiliary_drv(dev->driver); in auxiliary_bus_shutdown()
243 if (auxdrv && auxdrv->shutdown) in auxiliary_bus_shutdown()
244 auxdrv->shutdown(auxdev); in auxiliary_bus_shutdown()
258 * auxiliary_device_init - check auxiliary_device and initialize
261 * This is the second step in the three-step process to register an
264 * When this function returns an error code, then the device_initialize will
270 * to auxiliary_device_uninit(). In this post-initialize error scenario, a call
271 * to the device's .release callback will be triggered, and all memory clean-up
276 struct device *dev = &auxdev->dev; in auxiliary_device_init()
278 if (!dev->parent) { in auxiliary_device_init()
279 pr_err("auxiliary_device has a NULL dev->parent\n"); in auxiliary_device_init()
280 return -EINVAL; in auxiliary_device_init()
283 if (!auxdev->name) { in auxiliary_device_init()
285 return -EINVAL; in auxiliary_device_init()
288 dev->bus = &auxiliary_bus_type; in auxiliary_device_init()
289 device_initialize(&auxdev->dev); in auxiliary_device_init()
290 mutex_init(&auxdev->sysfs.lock); in auxiliary_device_init()
296 * __auxiliary_device_add - add an auxiliary bus device
300 * This is the third step in the three-step process to register an
303 * This function must be called after a successful call to
316 struct device *dev = &auxdev->dev; in __auxiliary_device_add()
321 return -EINVAL; in __auxiliary_device_add()
324 ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id); in __auxiliary_device_add()
339 * auxiliary_find_device - auxiliary device iterator for locating a particular device.
341 * @data: Data to pass to match function
342 * @match: Callback function to check device
344 * This function returns a reference to a device that is 'found'
349 * The callback should return 0 if the device doesn't match and non-zero
350 * if it does. If the callback returns non-zero, this function will
368 * __auxiliary_driver_register - register a driver for auxiliary bus devices
383 if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) in __auxiliary_driver_register()
384 return -EINVAL; in __auxiliary_driver_register()
386 if (auxdrv->name) in __auxiliary_driver_register()
387 auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, in __auxiliary_driver_register()
388 auxdrv->name); in __auxiliary_driver_register()
390 auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname); in __auxiliary_driver_register()
391 if (!auxdrv->driver.name) in __auxiliary_driver_register()
392 return -ENOMEM; in __auxiliary_driver_register()
394 auxdrv->driver.owner = owner; in __auxiliary_driver_register()
395 auxdrv->driver.bus = &auxiliary_bus_type; in __auxiliary_driver_register()
396 auxdrv->driver.mod_name = modname; in __auxiliary_driver_register()
398 ret = driver_register(&auxdrv->driver); in __auxiliary_driver_register()
400 kfree(auxdrv->driver.name); in __auxiliary_driver_register()
407 * auxiliary_driver_unregister - unregister a driver
412 driver_unregister(&auxdrv->driver); in auxiliary_driver_unregister()
413 kfree(auxdrv->driver.name); in auxiliary_driver_unregister()