// SPDX-License-Identifier: GPL-2.0-only1/*2* Copyright (c) 2019-2020 Intel Corporation3*4* Please see Documentation/driver-api/auxiliary_bus.rst for more information.5*/67#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__89#include <linux/device.h>10#include <linux/init.h>11#include <linux/slab.h>12#include <linux/module.h>13#include <linux/pm_domain.h>14#include <linux/pm_runtime.h>15#include <linux/string.h>16#include <linux/auxiliary_bus.h>17#include "base.h"1819/**20* DOC: PURPOSE21*22* In some subsystems, the functionality of the core device (PCI/ACPI/other) is23* too complex for a single device to be managed by a monolithic driver (e.g.24* Sound Open Firmware), multiple devices might implement a common intersection25* of functionality (e.g. NICs + RDMA), or a driver may want to export an26* interface for another subsystem to drive (e.g. SIOV Physical Function export27* Virtual Function management). A split of the functionality into child-28* devices representing sub-domains of functionality makes it possible to29* compartmentalize, layer, and distribute domain-specific concerns via a Linux30* device-driver model.31*32* An example for this kind of requirement is the audio subsystem where a33* single IP is handling multiple entities such as HDMI, Soundwire, local34* devices such as mics/speakers etc. The split for the core's functionality35* can be arbitrary or be defined by the DSP firmware topology and include36* hooks for test/debug. This allows for the audio core device to be minimal37* and focused on hardware-specific control and communication.38*39* Each auxiliary_device represents a part of its parent functionality. The40* generic behavior can be extended and specialized as needed by encapsulating41* an auxiliary_device within other domain-specific structures and the use of42* .ops callbacks. Devices on the auxiliary bus do not share any structures and43* the use of a communication channel with the parent is domain-specific.44*45* Note that ops are intended as a way to augment instance behavior within a46* class of auxiliary devices, it is not the mechanism for exporting common47* infrastructure from the parent. Consider EXPORT_SYMBOL_NS() to convey48* infrastructure from the parent module to the auxiliary module(s).49*/5051/**52* DOC: USAGE53*54* The auxiliary bus is to be used when a driver and one or more kernel55* modules, who share a common header file with the driver, need a mechanism to56* connect and provide access to a shared object allocated by the57* auxiliary_device's registering driver. The registering driver for the58* auxiliary_device(s) and the kernel module(s) registering auxiliary_drivers59* can be from the same subsystem, or from multiple subsystems.60*61* The emphasis here is on a common generic interface that keeps subsystem62* customization out of the bus infrastructure.63*64* One example is a PCI network device that is RDMA-capable and exports a child65* device to be driven by an auxiliary_driver in the RDMA subsystem. The PCI66* driver allocates and registers an auxiliary_device for each physical67* function on the NIC. The RDMA driver registers an auxiliary_driver that68* claims each of these auxiliary_devices. This conveys data/ops published by69* the parent PCI device/driver to the RDMA auxiliary_driver.70*71* Another use case is for the PCI device to be split out into multiple sub72* functions. For each sub function an auxiliary_device is created. A PCI sub73* function driver binds to such devices that creates its own one or more class74* devices. A PCI sub function auxiliary device is likely to be contained in a75* struct with additional attributes such as user defined sub function number76* and optional attributes such as resources and a link to the parent device.77* These attributes could be used by systemd/udev; and hence should be78* initialized before a driver binds to an auxiliary_device.79*80* A key requirement for utilizing the auxiliary bus is that there is no81* dependency on a physical bus, device, register accesses or regmap support.82* These individual devices split from the core cannot live on the platform bus83* as they are not physical devices that are controlled by DT/ACPI. The same84* argument applies for not using MFD in this scenario as MFD relies on85* individual function devices being physical devices.86*/8788/**89* DOC: EXAMPLE90*91* Auxiliary devices are created and registered by a subsystem-level core92* device that needs to break up its functionality into smaller fragments. One93* way to extend the scope of an auxiliary_device is to encapsulate it within a94* domain-specific structure defined by the parent device. This structure95* contains the auxiliary_device and any associated shared data/callbacks96* needed to establish the connection with the parent.97*98* An example is:99*100* .. code-block:: c101*102* struct foo {103* struct auxiliary_device auxdev;104* void (*connect)(struct auxiliary_device *auxdev);105* void (*disconnect)(struct auxiliary_device *auxdev);106* void *data;107* };108*109* The parent device then registers the auxiliary_device by calling110* auxiliary_device_init(), and then auxiliary_device_add(), with the pointer111* to the auxdev member of the above structure. The parent provides a name for112* the auxiliary_device that, combined with the parent's KBUILD_MODNAME,113* creates a match_name that is be used for matching and binding with a driver.114*115* Whenever an auxiliary_driver is registered, based on the match_name, the116* auxiliary_driver's probe() is invoked for the matching devices. The117* auxiliary_driver can also be encapsulated inside custom drivers that make118* the core device's functionality extensible by adding additional119* domain-specific ops as follows:120*121* .. code-block:: c122*123* struct my_ops {124* void (*send)(struct auxiliary_device *auxdev);125* void (*receive)(struct auxiliary_device *auxdev);126* };127*128*129* struct my_driver {130* struct auxiliary_driver auxiliary_drv;131* const struct my_ops ops;132* };133*134* An example of this type of usage is:135*136* .. code-block:: c137*138* const struct auxiliary_device_id my_auxiliary_id_table[] = {139* { .name = "foo_mod.foo_dev" },140* { },141* };142*143* const struct my_ops my_custom_ops = {144* .send = my_tx,145* .receive = my_rx,146* };147*148* const struct my_driver my_drv = {149* .auxiliary_drv = {150* .name = "myauxiliarydrv",151* .id_table = my_auxiliary_id_table,152* .probe = my_probe,153* .remove = my_remove,154* .shutdown = my_shutdown,155* },156* .ops = my_custom_ops,157* };158*159* Please note that such custom ops approach is valid, but it is hard to implement160* it right without global locks per-device to protect from auxiliary_drv removal161* during call to that ops. In addition, this implementation lacks proper module162* dependency, which causes to load/unload races between auxiliary parent and devices163* modules.164*165* The most easiest way to provide these ops reliably without needing to166* have a lock is to EXPORT_SYMBOL*() them and rely on already existing167* modules infrastructure for validity and correct dependencies chains.168*/169170static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id,171const struct auxiliary_device *auxdev)172{173const char *auxdev_name = dev_name(&auxdev->dev);174const char *p = strrchr(auxdev_name, '.');175int match_size;176177if (!p)178return NULL;179match_size = p - auxdev_name;180181for (; id->name[0]; id++) {182/* use dev_name(&auxdev->dev) prefix before last '.' char to match to */183if (strlen(id->name) == match_size &&184!strncmp(auxdev_name, id->name, match_size))185return id;186}187return NULL;188}189190static int auxiliary_match(struct device *dev, const struct device_driver *drv)191{192struct auxiliary_device *auxdev = to_auxiliary_dev(dev);193const struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv);194195return !!auxiliary_match_id(auxdrv->id_table, auxdev);196}197198static int auxiliary_uevent(const struct device *dev, struct kobj_uevent_env *env)199{200const char *name, *p;201202name = dev_name(dev);203p = strrchr(name, '.');204205return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX,206(int)(p - name), name);207}208209static const struct dev_pm_ops auxiliary_dev_pm_ops = {210SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL)211SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume)212};213214static int auxiliary_bus_probe(struct device *dev)215{216const struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);217struct auxiliary_device *auxdev = to_auxiliary_dev(dev);218int ret;219220ret = dev_pm_domain_attach(dev, PD_FLAG_ATTACH_POWER_ON |221PD_FLAG_DETACH_POWER_OFF);222if (ret) {223dev_warn(dev, "Failed to attach to PM Domain : %d\n", ret);224return ret;225}226227return auxdrv->probe(auxdev, auxiliary_match_id(auxdrv->id_table, auxdev));228}229230static void auxiliary_bus_remove(struct device *dev)231{232const struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);233struct auxiliary_device *auxdev = to_auxiliary_dev(dev);234235if (auxdrv->remove)236auxdrv->remove(auxdev);237}238239static void auxiliary_bus_shutdown(struct device *dev)240{241const struct auxiliary_driver *auxdrv = NULL;242struct auxiliary_device *auxdev;243244if (dev->driver) {245auxdrv = to_auxiliary_drv(dev->driver);246auxdev = to_auxiliary_dev(dev);247}248249if (auxdrv && auxdrv->shutdown)250auxdrv->shutdown(auxdev);251}252253static const struct bus_type auxiliary_bus_type = {254.name = "auxiliary",255.probe = auxiliary_bus_probe,256.remove = auxiliary_bus_remove,257.shutdown = auxiliary_bus_shutdown,258.match = auxiliary_match,259.uevent = auxiliary_uevent,260.pm = &auxiliary_dev_pm_ops,261};262263/**264* auxiliary_device_init - check auxiliary_device and initialize265* @auxdev: auxiliary device struct266*267* This is the second step in the three-step process to register an268* auxiliary_device.269*270* When this function returns an error code, then the device_initialize will271* *not* have been performed, and the caller will be responsible to free any272* memory allocated for the auxiliary_device in the error path directly.273*274* It returns 0 on success. On success, the device_initialize has been275* performed. After this point any error unwinding will need to include a call276* to auxiliary_device_uninit(). In this post-initialize error scenario, a call277* to the device's .release callback will be triggered, and all memory clean-up278* is expected to be handled there.279*/280int auxiliary_device_init(struct auxiliary_device *auxdev)281{282struct device *dev = &auxdev->dev;283284if (!dev->parent) {285pr_err("auxiliary_device has a NULL dev->parent\n");286return -EINVAL;287}288289if (!auxdev->name) {290pr_err("auxiliary_device has a NULL name\n");291return -EINVAL;292}293294dev->bus = &auxiliary_bus_type;295device_initialize(&auxdev->dev);296mutex_init(&auxdev->sysfs.lock);297return 0;298}299EXPORT_SYMBOL_GPL(auxiliary_device_init);300301/**302* __auxiliary_device_add - add an auxiliary bus device303* @auxdev: auxiliary bus device to add to the bus304* @modname: name of the parent device's driver module305*306* This is the third step in the three-step process to register an307* auxiliary_device.308*309* This function must be called after a successful call to310* auxiliary_device_init(), which will perform the device_initialize. This311* means that if this returns an error code, then a call to312* auxiliary_device_uninit() must be performed so that the .release callback313* will be triggered to free the memory associated with the auxiliary_device.314*315* The expectation is that users will call the "auxiliary_device_add" macro so316* that the caller's KBUILD_MODNAME is automatically inserted for the modname317* parameter. Only if a user requires a custom name would this version be318* called directly.319*/320int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname)321{322struct device *dev = &auxdev->dev;323int ret;324325if (!modname) {326dev_err(dev, "auxiliary device modname is NULL\n");327return -EINVAL;328}329330ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id);331if (ret) {332dev_err(dev, "auxiliary device dev_set_name failed: %d\n", ret);333return ret;334}335336ret = device_add(dev);337if (ret)338dev_err(dev, "adding auxiliary device failed!: %d\n", ret);339340return ret;341}342EXPORT_SYMBOL_GPL(__auxiliary_device_add);343344/**345* __auxiliary_driver_register - register a driver for auxiliary bus devices346* @auxdrv: auxiliary_driver structure347* @owner: owning module/driver348* @modname: KBUILD_MODNAME for parent driver349*350* The expectation is that users will call the "auxiliary_driver_register"351* macro so that the caller's KBUILD_MODNAME is automatically inserted for the352* modname parameter. Only if a user requires a custom name would this version353* be called directly.354*/355int __auxiliary_driver_register(struct auxiliary_driver *auxdrv,356struct module *owner, const char *modname)357{358int ret;359360if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table))361return -EINVAL;362363if (auxdrv->name)364auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname,365auxdrv->name);366else367auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname);368if (!auxdrv->driver.name)369return -ENOMEM;370371auxdrv->driver.owner = owner;372auxdrv->driver.bus = &auxiliary_bus_type;373auxdrv->driver.mod_name = modname;374375ret = driver_register(&auxdrv->driver);376if (ret)377kfree(auxdrv->driver.name);378379return ret;380}381EXPORT_SYMBOL_GPL(__auxiliary_driver_register);382383/**384* auxiliary_driver_unregister - unregister a driver385* @auxdrv: auxiliary_driver structure386*/387void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)388{389driver_unregister(&auxdrv->driver);390kfree(auxdrv->driver.name);391}392EXPORT_SYMBOL_GPL(auxiliary_driver_unregister);393394static void auxiliary_device_release(struct device *dev)395{396struct auxiliary_device *auxdev = to_auxiliary_dev(dev);397398of_node_put(dev->of_node);399kfree(auxdev);400}401402/**403* auxiliary_device_create - create a device on the auxiliary bus404* @dev: parent device405* @modname: module name used to create the auxiliary driver name.406* @devname: auxiliary bus device name407* @platform_data: auxiliary bus device platform data408* @id: auxiliary bus device id409*410* Helper to create an auxiliary bus device.411* The device created matches driver 'modname.devname' on the auxiliary bus.412*/413struct auxiliary_device *auxiliary_device_create(struct device *dev,414const char *modname,415const char *devname,416void *platform_data,417int id)418{419struct auxiliary_device *auxdev;420int ret;421422auxdev = kzalloc(sizeof(*auxdev), GFP_KERNEL);423if (!auxdev)424return NULL;425426auxdev->id = id;427auxdev->name = devname;428auxdev->dev.parent = dev;429auxdev->dev.platform_data = platform_data;430auxdev->dev.release = auxiliary_device_release;431device_set_of_node_from_dev(&auxdev->dev, dev);432433ret = auxiliary_device_init(auxdev);434if (ret) {435of_node_put(auxdev->dev.of_node);436kfree(auxdev);437return NULL;438}439440ret = __auxiliary_device_add(auxdev, modname);441if (ret) {442/*443* It may look odd but auxdev should not be freed here.444* auxiliary_device_uninit() calls device_put() which call445* the device release function, freeing auxdev.446*/447auxiliary_device_uninit(auxdev);448return NULL;449}450451return auxdev;452}453EXPORT_SYMBOL_GPL(auxiliary_device_create);454455/**456* auxiliary_device_destroy - remove an auxiliary device457* @auxdev: pointer to the auxdev to be removed458*459* Helper to remove an auxiliary device created with460* auxiliary_device_create()461*/462void auxiliary_device_destroy(void *auxdev)463{464struct auxiliary_device *_auxdev = auxdev;465466auxiliary_device_delete(_auxdev);467auxiliary_device_uninit(_auxdev);468}469EXPORT_SYMBOL_GPL(auxiliary_device_destroy);470471/**472* __devm_auxiliary_device_create - create a managed device on the auxiliary bus473* @dev: parent device474* @modname: module name used to create the auxiliary driver name.475* @devname: auxiliary bus device name476* @platform_data: auxiliary bus device platform data477* @id: auxiliary bus device id478*479* Device managed helper to create an auxiliary bus device.480* The device created matches driver 'modname.devname' on the auxiliary bus.481*/482struct auxiliary_device *__devm_auxiliary_device_create(struct device *dev,483const char *modname,484const char *devname,485void *platform_data,486int id)487{488struct auxiliary_device *auxdev;489int ret;490491auxdev = auxiliary_device_create(dev, modname, devname, platform_data, id);492if (!auxdev)493return NULL;494495ret = devm_add_action_or_reset(dev, auxiliary_device_destroy,496auxdev);497if (ret)498return NULL;499500return auxdev;501}502EXPORT_SYMBOL_GPL(__devm_auxiliary_device_create);503504void __init auxiliary_bus_init(void)505{506WARN_ON(bus_register(&auxiliary_bus_type));507}508509510