xref: /openbmc/linux/drivers/base/auxiliary.c (revision 2a81ada3)
17de3697eSDave Ertman // SPDX-License-Identifier: GPL-2.0-only
27de3697eSDave Ertman /*
37de3697eSDave Ertman  * Copyright (c) 2019-2020 Intel Corporation
47de3697eSDave Ertman  *
57de3697eSDave Ertman  * Please see Documentation/driver-api/auxiliary_bus.rst for more information.
67de3697eSDave Ertman  */
77de3697eSDave Ertman 
87de3697eSDave Ertman #define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__
97de3697eSDave Ertman 
107de3697eSDave Ertman #include <linux/device.h>
117de3697eSDave Ertman #include <linux/init.h>
127bbb79ffSGreg Kroah-Hartman #include <linux/slab.h>
137de3697eSDave Ertman #include <linux/module.h>
147de3697eSDave Ertman #include <linux/pm_domain.h>
157de3697eSDave Ertman #include <linux/pm_runtime.h>
167de3697eSDave Ertman #include <linux/string.h>
177de3697eSDave Ertman #include <linux/auxiliary_bus.h>
18471b12c4SDave Jiang #include "base.h"
197de3697eSDave Ertman 
20e1b51868SIra Weiny /**
21e1b51868SIra Weiny  * DOC: PURPOSE
22e1b51868SIra Weiny  *
23e1b51868SIra Weiny  * In some subsystems, the functionality of the core device (PCI/ACPI/other) is
24e1b51868SIra Weiny  * too complex for a single device to be managed by a monolithic driver (e.g.
25e1b51868SIra Weiny  * Sound Open Firmware), multiple devices might implement a common intersection
26e1b51868SIra Weiny  * of functionality (e.g. NICs + RDMA), or a driver may want to export an
27e1b51868SIra Weiny  * interface for another subsystem to drive (e.g. SIOV Physical Function export
28e1b51868SIra Weiny  * Virtual Function management).  A split of the functionality into child-
29e1b51868SIra Weiny  * devices representing sub-domains of functionality makes it possible to
30e1b51868SIra Weiny  * compartmentalize, layer, and distribute domain-specific concerns via a Linux
31e1b51868SIra Weiny  * device-driver model.
32e1b51868SIra Weiny  *
33e1b51868SIra Weiny  * An example for this kind of requirement is the audio subsystem where a
34e1b51868SIra Weiny  * single IP is handling multiple entities such as HDMI, Soundwire, local
35e1b51868SIra Weiny  * devices such as mics/speakers etc. The split for the core's functionality
36e1b51868SIra Weiny  * can be arbitrary or be defined by the DSP firmware topology and include
37e1b51868SIra Weiny  * hooks for test/debug. This allows for the audio core device to be minimal
38e1b51868SIra Weiny  * and focused on hardware-specific control and communication.
39e1b51868SIra Weiny  *
40e1b51868SIra Weiny  * Each auxiliary_device represents a part of its parent functionality. The
41e1b51868SIra Weiny  * generic behavior can be extended and specialized as needed by encapsulating
42e1b51868SIra Weiny  * an auxiliary_device within other domain-specific structures and the use of
43e1b51868SIra Weiny  * .ops callbacks. Devices on the auxiliary bus do not share any structures and
44e1b51868SIra Weiny  * the use of a communication channel with the parent is domain-specific.
45e1b51868SIra Weiny  *
46e1b51868SIra Weiny  * Note that ops are intended as a way to augment instance behavior within a
47e1b51868SIra Weiny  * class of auxiliary devices, it is not the mechanism for exporting common
48e1b51868SIra Weiny  * infrastructure from the parent. Consider EXPORT_SYMBOL_NS() to convey
49e1b51868SIra Weiny  * infrastructure from the parent module to the auxiliary module(s).
50e1b51868SIra Weiny  */
51e1b51868SIra Weiny 
52e1b51868SIra Weiny /**
53e1b51868SIra Weiny  * DOC: USAGE
54e1b51868SIra Weiny  *
55e1b51868SIra Weiny  * The auxiliary bus is to be used when a driver and one or more kernel
56e1b51868SIra Weiny  * modules, who share a common header file with the driver, need a mechanism to
57e1b51868SIra Weiny  * connect and provide access to a shared object allocated by the
58e1b51868SIra Weiny  * auxiliary_device's registering driver.  The registering driver for the
59e1b51868SIra Weiny  * auxiliary_device(s) and the kernel module(s) registering auxiliary_drivers
60e1b51868SIra Weiny  * can be from the same subsystem, or from multiple subsystems.
61e1b51868SIra Weiny  *
62e1b51868SIra Weiny  * The emphasis here is on a common generic interface that keeps subsystem
63e1b51868SIra Weiny  * customization out of the bus infrastructure.
64e1b51868SIra Weiny  *
65e1b51868SIra Weiny  * One example is a PCI network device that is RDMA-capable and exports a child
66e1b51868SIra Weiny  * device to be driven by an auxiliary_driver in the RDMA subsystem.  The PCI
67e1b51868SIra Weiny  * driver allocates and registers an auxiliary_device for each physical
68e1b51868SIra Weiny  * function on the NIC.  The RDMA driver registers an auxiliary_driver that
69e1b51868SIra Weiny  * claims each of these auxiliary_devices.  This conveys data/ops published by
70e1b51868SIra Weiny  * the parent PCI device/driver to the RDMA auxiliary_driver.
71e1b51868SIra Weiny  *
72e1b51868SIra Weiny  * Another use case is for the PCI device to be split out into multiple sub
73e1b51868SIra Weiny  * functions.  For each sub function an auxiliary_device is created.  A PCI sub
74e1b51868SIra Weiny  * function driver binds to such devices that creates its own one or more class
75e1b51868SIra Weiny  * devices.  A PCI sub function auxiliary device is likely to be contained in a
76e1b51868SIra Weiny  * struct with additional attributes such as user defined sub function number
77e1b51868SIra Weiny  * and optional attributes such as resources and a link to the parent device.
78e1b51868SIra Weiny  * These attributes could be used by systemd/udev; and hence should be
79e1b51868SIra Weiny  * initialized before a driver binds to an auxiliary_device.
80e1b51868SIra Weiny  *
81e1b51868SIra Weiny  * A key requirement for utilizing the auxiliary bus is that there is no
82e1b51868SIra Weiny  * dependency on a physical bus, device, register accesses or regmap support.
83e1b51868SIra Weiny  * These individual devices split from the core cannot live on the platform bus
84e1b51868SIra Weiny  * as they are not physical devices that are controlled by DT/ACPI.  The same
85e1b51868SIra Weiny  * argument applies for not using MFD in this scenario as MFD relies on
86e1b51868SIra Weiny  * individual function devices being physical devices.
87e1b51868SIra Weiny  */
88e1b51868SIra Weiny 
89e1b51868SIra Weiny /**
90e1b51868SIra Weiny  * DOC: EXAMPLE
91e1b51868SIra Weiny  *
92e1b51868SIra Weiny  * Auxiliary devices are created and registered by a subsystem-level core
93e1b51868SIra Weiny  * device that needs to break up its functionality into smaller fragments. One
94e1b51868SIra Weiny  * way to extend the scope of an auxiliary_device is to encapsulate it within a
95e1b51868SIra Weiny  * domain- pecific structure defined by the parent device. This structure
96e1b51868SIra Weiny  * contains the auxiliary_device and any associated shared data/callbacks
97e1b51868SIra Weiny  * needed to establish the connection with the parent.
98e1b51868SIra Weiny  *
99e1b51868SIra Weiny  * An example is:
100e1b51868SIra Weiny  *
101e1b51868SIra Weiny  * .. code-block:: c
102e1b51868SIra Weiny  *
103e1b51868SIra Weiny  *         struct foo {
104e1b51868SIra Weiny  *		struct auxiliary_device auxdev;
105e1b51868SIra Weiny  *		void (*connect)(struct auxiliary_device *auxdev);
106e1b51868SIra Weiny  *		void (*disconnect)(struct auxiliary_device *auxdev);
107e1b51868SIra Weiny  *		void *data;
108e1b51868SIra Weiny  *        };
109e1b51868SIra Weiny  *
110e1b51868SIra Weiny  * The parent device then registers the auxiliary_device by calling
111e1b51868SIra Weiny  * auxiliary_device_init(), and then auxiliary_device_add(), with the pointer
112e1b51868SIra Weiny  * to the auxdev member of the above structure. The parent provides a name for
113e1b51868SIra Weiny  * the auxiliary_device that, combined with the parent's KBUILD_MODNAME,
114e1b51868SIra Weiny  * creates a match_name that is be used for matching and binding with a driver.
115e1b51868SIra Weiny  *
116e1b51868SIra Weiny  * Whenever an auxiliary_driver is registered, based on the match_name, the
117e1b51868SIra Weiny  * auxiliary_driver's probe() is invoked for the matching devices.  The
118e1b51868SIra Weiny  * auxiliary_driver can also be encapsulated inside custom drivers that make
119e1b51868SIra Weiny  * the core device's functionality extensible by adding additional
120e1b51868SIra Weiny  * domain-specific ops as follows:
121e1b51868SIra Weiny  *
122e1b51868SIra Weiny  * .. code-block:: c
123e1b51868SIra Weiny  *
124e1b51868SIra Weiny  *	struct my_ops {
125e1b51868SIra Weiny  *		void (*send)(struct auxiliary_device *auxdev);
126e1b51868SIra Weiny  *		void (*receive)(struct auxiliary_device *auxdev);
127e1b51868SIra Weiny  *	};
128e1b51868SIra Weiny  *
129e1b51868SIra Weiny  *
130e1b51868SIra Weiny  *	struct my_driver {
131e1b51868SIra Weiny  *		struct auxiliary_driver auxiliary_drv;
132e1b51868SIra Weiny  *		const struct my_ops ops;
133e1b51868SIra Weiny  *	};
134e1b51868SIra Weiny  *
135e1b51868SIra Weiny  * An example of this type of usage is:
136e1b51868SIra Weiny  *
137e1b51868SIra Weiny  * .. code-block:: c
138e1b51868SIra Weiny  *
139e1b51868SIra Weiny  *	const struct auxiliary_device_id my_auxiliary_id_table[] = {
140e1b51868SIra Weiny  *		{ .name = "foo_mod.foo_dev" },
141e1b51868SIra Weiny  *		{ },
142e1b51868SIra Weiny  *	};
143e1b51868SIra Weiny  *
144e1b51868SIra Weiny  *	const struct my_ops my_custom_ops = {
145e1b51868SIra Weiny  *		.send = my_tx,
146e1b51868SIra Weiny  *		.receive = my_rx,
147e1b51868SIra Weiny  *	};
148e1b51868SIra Weiny  *
149e1b51868SIra Weiny  *	const struct my_driver my_drv = {
150e1b51868SIra Weiny  *		.auxiliary_drv = {
151e1b51868SIra Weiny  *			.name = "myauxiliarydrv",
152e1b51868SIra Weiny  *			.id_table = my_auxiliary_id_table,
153e1b51868SIra Weiny  *			.probe = my_probe,
154e1b51868SIra Weiny  *			.remove = my_remove,
155e1b51868SIra Weiny  *			.shutdown = my_shutdown,
156e1b51868SIra Weiny  *		},
157e1b51868SIra Weiny  *		.ops = my_custom_ops,
158e1b51868SIra Weiny  *	};
159e1b51868SIra Weiny  */
160e1b51868SIra Weiny 
auxiliary_match_id(const struct auxiliary_device_id * id,const struct auxiliary_device * auxdev)1617de3697eSDave Ertman static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id,
1627de3697eSDave Ertman 							    const struct auxiliary_device *auxdev)
1637de3697eSDave Ertman {
1647de3697eSDave Ertman 	for (; id->name[0]; id++) {
1657de3697eSDave Ertman 		const char *p = strrchr(dev_name(&auxdev->dev), '.');
1667de3697eSDave Ertman 		int match_size;
1677de3697eSDave Ertman 
1687de3697eSDave Ertman 		if (!p)
1697de3697eSDave Ertman 			continue;
1707de3697eSDave Ertman 		match_size = p - dev_name(&auxdev->dev);
1717de3697eSDave Ertman 
1727de3697eSDave Ertman 		/* use dev_name(&auxdev->dev) prefix before last '.' char to match to */
1737de3697eSDave Ertman 		if (strlen(id->name) == match_size &&
1747de3697eSDave Ertman 		    !strncmp(dev_name(&auxdev->dev), id->name, match_size))
1757de3697eSDave Ertman 			return id;
1767de3697eSDave Ertman 	}
1777de3697eSDave Ertman 	return NULL;
1787de3697eSDave Ertman }
1797de3697eSDave Ertman 
auxiliary_match(struct device * dev,struct device_driver * drv)1807de3697eSDave Ertman static int auxiliary_match(struct device *dev, struct device_driver *drv)
1817de3697eSDave Ertman {
1827de3697eSDave Ertman 	struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
1837de3697eSDave Ertman 	struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv);
1847de3697eSDave Ertman 
1857de3697eSDave Ertman 	return !!auxiliary_match_id(auxdrv->id_table, auxdev);
1867de3697eSDave Ertman }
1877de3697eSDave Ertman 
auxiliary_uevent(const struct device * dev,struct kobj_uevent_env * env)188*2a81ada3SGreg Kroah-Hartman static int auxiliary_uevent(const struct device *dev, struct kobj_uevent_env *env)
1897de3697eSDave Ertman {
1907de3697eSDave Ertman 	const char *name, *p;
1917de3697eSDave Ertman 
1927de3697eSDave Ertman 	name = dev_name(dev);
1937de3697eSDave Ertman 	p = strrchr(name, '.');
1947de3697eSDave Ertman 
1950d2bf11aSGreg Kroah-Hartman 	return add_uevent_var(env, "MODALIAS=%s%.*s", AUXILIARY_MODULE_PREFIX,
1960d2bf11aSGreg Kroah-Hartman 			      (int)(p - name), name);
1977de3697eSDave Ertman }
1987de3697eSDave Ertman 
1997de3697eSDave Ertman static const struct dev_pm_ops auxiliary_dev_pm_ops = {
2007de3697eSDave Ertman 	SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL)
2017de3697eSDave Ertman 	SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume)
2027de3697eSDave Ertman };
2037de3697eSDave Ertman 
auxiliary_bus_probe(struct device * dev)2047de3697eSDave Ertman static int auxiliary_bus_probe(struct device *dev)
2057de3697eSDave Ertman {
2067de3697eSDave Ertman 	struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
2077de3697eSDave Ertman 	struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
2087de3697eSDave Ertman 	int ret;
2097de3697eSDave Ertman 
2107de3697eSDave Ertman 	ret = dev_pm_domain_attach(dev, true);
2117de3697eSDave Ertman 	if (ret) {
2127de3697eSDave Ertman 		dev_warn(dev, "Failed to attach to PM Domain : %d\n", ret);
2137de3697eSDave Ertman 		return ret;
2147de3697eSDave Ertman 	}
2157de3697eSDave Ertman 
2167de3697eSDave Ertman 	ret = auxdrv->probe(auxdev, auxiliary_match_id(auxdrv->id_table, auxdev));
2177de3697eSDave Ertman 	if (ret)
2187de3697eSDave Ertman 		dev_pm_domain_detach(dev, true);
2197de3697eSDave Ertman 
2207de3697eSDave Ertman 	return ret;
2217de3697eSDave Ertman }
2227de3697eSDave Ertman 
auxiliary_bus_remove(struct device * dev)223fc7a6209SUwe Kleine-König static void auxiliary_bus_remove(struct device *dev)
2247de3697eSDave Ertman {
2257de3697eSDave Ertman 	struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
2267de3697eSDave Ertman 	struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
2277de3697eSDave Ertman 
2287de3697eSDave Ertman 	if (auxdrv->remove)
2298142a46cSGreg Kroah-Hartman 		auxdrv->remove(auxdev);
2307de3697eSDave Ertman 	dev_pm_domain_detach(dev, true);
2317de3697eSDave Ertman }
2327de3697eSDave Ertman 
auxiliary_bus_shutdown(struct device * dev)2337de3697eSDave Ertman static void auxiliary_bus_shutdown(struct device *dev)
2347de3697eSDave Ertman {
235784b2c48SDave Jiang 	struct auxiliary_driver *auxdrv = NULL;
236784b2c48SDave Jiang 	struct auxiliary_device *auxdev;
2377de3697eSDave Ertman 
238784b2c48SDave Jiang 	if (dev->driver) {
239784b2c48SDave Jiang 		auxdrv = to_auxiliary_drv(dev->driver);
240784b2c48SDave Jiang 		auxdev = to_auxiliary_dev(dev);
241784b2c48SDave Jiang 	}
242784b2c48SDave Jiang 
243784b2c48SDave Jiang 	if (auxdrv && auxdrv->shutdown)
2447de3697eSDave Ertman 		auxdrv->shutdown(auxdev);
2457de3697eSDave Ertman }
2467de3697eSDave Ertman 
2477de3697eSDave Ertman static struct bus_type auxiliary_bus_type = {
2487de3697eSDave Ertman 	.name = "auxiliary",
2497de3697eSDave Ertman 	.probe = auxiliary_bus_probe,
2507de3697eSDave Ertman 	.remove = auxiliary_bus_remove,
2517de3697eSDave Ertman 	.shutdown = auxiliary_bus_shutdown,
2527de3697eSDave Ertman 	.match = auxiliary_match,
2537de3697eSDave Ertman 	.uevent = auxiliary_uevent,
2547de3697eSDave Ertman 	.pm = &auxiliary_dev_pm_ops,
2557de3697eSDave Ertman };
2567de3697eSDave Ertman 
2577de3697eSDave Ertman /**
2587de3697eSDave Ertman  * auxiliary_device_init - check auxiliary_device and initialize
2597de3697eSDave Ertman  * @auxdev: auxiliary device struct
2607de3697eSDave Ertman  *
261b2477038SIra Weiny  * This is the second step in the three-step process to register an
2620d2bf11aSGreg Kroah-Hartman  * auxiliary_device.
2637de3697eSDave Ertman  *
2640d2bf11aSGreg Kroah-Hartman  * When this function returns an error code, then the device_initialize will
2650d2bf11aSGreg Kroah-Hartman  * *not* have been performed, and the caller will be responsible to free any
2660d2bf11aSGreg Kroah-Hartman  * memory allocated for the auxiliary_device in the error path directly.
2677de3697eSDave Ertman  *
2680d2bf11aSGreg Kroah-Hartman  * It returns 0 on success.  On success, the device_initialize has been
2690d2bf11aSGreg Kroah-Hartman  * performed.  After this point any error unwinding will need to include a call
2700d2bf11aSGreg Kroah-Hartman  * to auxiliary_device_uninit().  In this post-initialize error scenario, a call
2710d2bf11aSGreg Kroah-Hartman  * to the device's .release callback will be triggered, and all memory clean-up
2720d2bf11aSGreg Kroah-Hartman  * is expected to be handled there.
2737de3697eSDave Ertman  */
auxiliary_device_init(struct auxiliary_device * auxdev)2747de3697eSDave Ertman int auxiliary_device_init(struct auxiliary_device *auxdev)
2757de3697eSDave Ertman {
2767de3697eSDave Ertman 	struct device *dev = &auxdev->dev;
2777de3697eSDave Ertman 
2787de3697eSDave Ertman 	if (!dev->parent) {
2797de3697eSDave Ertman 		pr_err("auxiliary_device has a NULL dev->parent\n");
2807de3697eSDave Ertman 		return -EINVAL;
2817de3697eSDave Ertman 	}
2827de3697eSDave Ertman 
2837de3697eSDave Ertman 	if (!auxdev->name) {
2847de3697eSDave Ertman 		pr_err("auxiliary_device has a NULL name\n");
2857de3697eSDave Ertman 		return -EINVAL;
2867de3697eSDave Ertman 	}
2877de3697eSDave Ertman 
2887de3697eSDave Ertman 	dev->bus = &auxiliary_bus_type;
2897de3697eSDave Ertman 	device_initialize(&auxdev->dev);
2907de3697eSDave Ertman 	return 0;
2917de3697eSDave Ertman }
2927de3697eSDave Ertman EXPORT_SYMBOL_GPL(auxiliary_device_init);
2937de3697eSDave Ertman 
2947de3697eSDave Ertman /**
2957de3697eSDave Ertman  * __auxiliary_device_add - add an auxiliary bus device
2967de3697eSDave Ertman  * @auxdev: auxiliary bus device to add to the bus
2977de3697eSDave Ertman  * @modname: name of the parent device's driver module
2987de3697eSDave Ertman  *
299b2477038SIra Weiny  * This is the third step in the three-step process to register an
3000d2bf11aSGreg Kroah-Hartman  * auxiliary_device.
3017de3697eSDave Ertman  *
3020d2bf11aSGreg Kroah-Hartman  * This function must be called after a successful call to
3030d2bf11aSGreg Kroah-Hartman  * auxiliary_device_init(), which will perform the device_initialize.  This
3040d2bf11aSGreg Kroah-Hartman  * means that if this returns an error code, then a call to
3050d2bf11aSGreg Kroah-Hartman  * auxiliary_device_uninit() must be performed so that the .release callback
3060d2bf11aSGreg Kroah-Hartman  * will be triggered to free the memory associated with the auxiliary_device.
3077de3697eSDave Ertman  *
3080d2bf11aSGreg Kroah-Hartman  * The expectation is that users will call the "auxiliary_device_add" macro so
3090d2bf11aSGreg Kroah-Hartman  * that the caller's KBUILD_MODNAME is automatically inserted for the modname
3100d2bf11aSGreg Kroah-Hartman  * parameter.  Only if a user requires a custom name would this version be
3110d2bf11aSGreg Kroah-Hartman  * called directly.
3127de3697eSDave Ertman  */
__auxiliary_device_add(struct auxiliary_device * auxdev,const char * modname)3137de3697eSDave Ertman int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname)
3147de3697eSDave Ertman {
3157de3697eSDave Ertman 	struct device *dev = &auxdev->dev;
3167de3697eSDave Ertman 	int ret;
3177de3697eSDave Ertman 
3187de3697eSDave Ertman 	if (!modname) {
3190d2bf11aSGreg Kroah-Hartman 		dev_err(dev, "auxiliary device modname is NULL\n");
3207de3697eSDave Ertman 		return -EINVAL;
3217de3697eSDave Ertman 	}
3227de3697eSDave Ertman 
3237de3697eSDave Ertman 	ret = dev_set_name(dev, "%s.%s.%d", modname, auxdev->name, auxdev->id);
3247de3697eSDave Ertman 	if (ret) {
3250d2bf11aSGreg Kroah-Hartman 		dev_err(dev, "auxiliary device dev_set_name failed: %d\n", ret);
3267de3697eSDave Ertman 		return ret;
3277de3697eSDave Ertman 	}
3287de3697eSDave Ertman 
3297de3697eSDave Ertman 	ret = device_add(dev);
3307de3697eSDave Ertman 	if (ret)
3317de3697eSDave Ertman 		dev_err(dev, "adding auxiliary device failed!: %d\n", ret);
3327de3697eSDave Ertman 
3337de3697eSDave Ertman 	return ret;
3347de3697eSDave Ertman }
3357de3697eSDave Ertman EXPORT_SYMBOL_GPL(__auxiliary_device_add);
3367de3697eSDave Ertman 
3377de3697eSDave Ertman /**
3387de3697eSDave Ertman  * auxiliary_find_device - auxiliary device iterator for locating a particular device.
3397de3697eSDave Ertman  * @start: Device to begin with
3407de3697eSDave Ertman  * @data: Data to pass to match function
3417de3697eSDave Ertman  * @match: Callback function to check device
3427de3697eSDave Ertman  *
3437de3697eSDave Ertman  * This function returns a reference to a device that is 'found'
3447de3697eSDave Ertman  * for later use, as determined by the @match callback.
3457de3697eSDave Ertman  *
3468a2d6ffeSIra Weiny  * The reference returned should be released with put_device().
3478a2d6ffeSIra Weiny  *
3487de3697eSDave Ertman  * The callback should return 0 if the device doesn't match and non-zero
3497de3697eSDave Ertman  * if it does.  If the callback returns non-zero, this function will
3507de3697eSDave Ertman  * return to the caller and not iterate over any more devices.
3517de3697eSDave Ertman  */
auxiliary_find_device(struct device * start,const void * data,int (* match)(struct device * dev,const void * data))3520d2bf11aSGreg Kroah-Hartman struct auxiliary_device *auxiliary_find_device(struct device *start,
3530d2bf11aSGreg Kroah-Hartman 					       const void *data,
3547de3697eSDave Ertman 					       int (*match)(struct device *dev, const void *data))
3557de3697eSDave Ertman {
3567de3697eSDave Ertman 	struct device *dev;
3577de3697eSDave Ertman 
3587de3697eSDave Ertman 	dev = bus_find_device(&auxiliary_bus_type, start, data, match);
3597de3697eSDave Ertman 	if (!dev)
3607de3697eSDave Ertman 		return NULL;
3617de3697eSDave Ertman 
3627de3697eSDave Ertman 	return to_auxiliary_dev(dev);
3637de3697eSDave Ertman }
3647de3697eSDave Ertman EXPORT_SYMBOL_GPL(auxiliary_find_device);
3657de3697eSDave Ertman 
3667de3697eSDave Ertman /**
3677de3697eSDave Ertman  * __auxiliary_driver_register - register a driver for auxiliary bus devices
3687de3697eSDave Ertman  * @auxdrv: auxiliary_driver structure
3697de3697eSDave Ertman  * @owner: owning module/driver
3707de3697eSDave Ertman  * @modname: KBUILD_MODNAME for parent driver
37105021dcaSIra Weiny  *
37205021dcaSIra Weiny  * The expectation is that users will call the "auxiliary_driver_register"
37305021dcaSIra Weiny  * macro so that the caller's KBUILD_MODNAME is automatically inserted for the
37405021dcaSIra Weiny  * modname parameter.  Only if a user requires a custom name would this version
37505021dcaSIra Weiny  * be called directly.
3767de3697eSDave Ertman  */
__auxiliary_driver_register(struct auxiliary_driver * auxdrv,struct module * owner,const char * modname)3770d2bf11aSGreg Kroah-Hartman int __auxiliary_driver_register(struct auxiliary_driver *auxdrv,
3780d2bf11aSGreg Kroah-Hartman 				struct module *owner, const char *modname)
3797de3697eSDave Ertman {
3804afa0c22SPeter Ujfalusi 	int ret;
3814afa0c22SPeter Ujfalusi 
3827de3697eSDave Ertman 	if (WARN_ON(!auxdrv->probe) || WARN_ON(!auxdrv->id_table))
3837de3697eSDave Ertman 		return -EINVAL;
3847de3697eSDave Ertman 
3857de3697eSDave Ertman 	if (auxdrv->name)
3860d2bf11aSGreg Kroah-Hartman 		auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s.%s", modname,
3870d2bf11aSGreg Kroah-Hartman 						auxdrv->name);
3887de3697eSDave Ertman 	else
3897de3697eSDave Ertman 		auxdrv->driver.name = kasprintf(GFP_KERNEL, "%s", modname);
3907de3697eSDave Ertman 	if (!auxdrv->driver.name)
3917de3697eSDave Ertman 		return -ENOMEM;
3927de3697eSDave Ertman 
3937de3697eSDave Ertman 	auxdrv->driver.owner = owner;
3947de3697eSDave Ertman 	auxdrv->driver.bus = &auxiliary_bus_type;
3957de3697eSDave Ertman 	auxdrv->driver.mod_name = modname;
3967de3697eSDave Ertman 
3974afa0c22SPeter Ujfalusi 	ret = driver_register(&auxdrv->driver);
3984afa0c22SPeter Ujfalusi 	if (ret)
3994afa0c22SPeter Ujfalusi 		kfree(auxdrv->driver.name);
4004afa0c22SPeter Ujfalusi 
4014afa0c22SPeter Ujfalusi 	return ret;
4027de3697eSDave Ertman }
4037de3697eSDave Ertman EXPORT_SYMBOL_GPL(__auxiliary_driver_register);
4047de3697eSDave Ertman 
4057de3697eSDave Ertman /**
4067de3697eSDave Ertman  * auxiliary_driver_unregister - unregister a driver
4077de3697eSDave Ertman  * @auxdrv: auxiliary_driver structure
4087de3697eSDave Ertman  */
auxiliary_driver_unregister(struct auxiliary_driver * auxdrv)4097de3697eSDave Ertman void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)
4107de3697eSDave Ertman {
4117de3697eSDave Ertman 	driver_unregister(&auxdrv->driver);
4127de3697eSDave Ertman 	kfree(auxdrv->driver.name);
4137de3697eSDave Ertman }
4147de3697eSDave Ertman EXPORT_SYMBOL_GPL(auxiliary_driver_unregister);
4157de3697eSDave Ertman 
auxiliary_bus_init(void)416471b12c4SDave Jiang void __init auxiliary_bus_init(void)
4177de3697eSDave Ertman {
418471b12c4SDave Jiang 	WARN_ON(bus_register(&auxiliary_bus_type));
4197de3697eSDave Ertman }
420