Lines Matching +full:sub +full:- +full:bus
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
43 * .ops callbacks. Devices on the auxiliary bus do not share any structures and
44 * the use of a communication channel with the parent is domain-specific.
55 * The auxiliary bus is to be used when a driver and one or more kernel
63 * customization out of the bus infrastructure.
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
81 * A key requirement for utilizing the auxiliary bus is that there is no
82 * dependency on a physical bus, device, register accesses or regmap support.
83 * These individual devices split from the core cannot live on the platform bus
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 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 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
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()
295 * __auxiliary_device_add - add an auxiliary bus device
296 * @auxdev: auxiliary bus device to add to the bus
299 * This is the third step in the three-step process to register an
315 struct device *dev = &auxdev->dev; in __auxiliary_device_add()
320 return -EINVAL; in __auxiliary_device_add()
323 ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id); in __auxiliary_device_add()
338 * auxiliary_find_device - auxiliary device iterator for locating a particular device.
348 * The callback should return 0 if the device doesn't match and non-zero
349 * if it does. If the callback returns non-zero, this function will
367 * __auxiliary_driver_register - register a driver for auxiliary bus devices
382 if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table)) in __auxiliary_driver_register()
383 return -EINVAL; in __auxiliary_driver_register()
385 if (auxdrv->name) in __auxiliary_driver_register()
386 auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname, in __auxiliary_driver_register()
387 auxdrv->name); in __auxiliary_driver_register()
389 auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname); in __auxiliary_driver_register()
390 if (!auxdrv->driver.name) in __auxiliary_driver_register()
391 return -ENOMEM; in __auxiliary_driver_register()
393 auxdrv->driver.owner = owner; in __auxiliary_driver_register()
394 auxdrv->driver.bus = &auxiliary_bus_type; in __auxiliary_driver_register()
395 auxdrv->driver.mod_name = modname; in __auxiliary_driver_register()
397 ret = driver_register(&auxdrv->driver); in __auxiliary_driver_register()
399 kfree(auxdrv->driver.name); in __auxiliary_driver_register()
406 * auxiliary_driver_unregister - unregister a driver
411 driver_unregister(&auxdrv->driver); in auxiliary_driver_unregister()
412 kfree(auxdrv->driver.name); in auxiliary_driver_unregister()