Commit eaa0d302 authored by Jerome Brunet's avatar Jerome Brunet Committed by Greg Kroah-Hartman
Browse files

driver core: auxiliary bus: add device creation helpers



Add helper functions to create a device on the auxiliary bus.

This is meant for fairly simple usage of the auxiliary bus, to avoid having
the same code repeated in the different drivers.

Suggested-by: default avatarStephen Boyd <sboyd@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarJerome Brunet <jbrunet@baylibre.com>
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: default avatarIra Weiny <ira.weiny@intel.com>
Link: https://lore.kernel.org/r/20250218-aux-device-create-helper-v4-1-c3d7dfdea2e6@baylibre.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d487858e
Loading
Loading
Loading
Loading
+108 −0
Original line number Diff line number Diff line
@@ -385,6 +385,114 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)
}
EXPORT_SYMBOL_GPL(auxiliary_driver_unregister);

static void auxiliary_device_release(struct device *dev)
{
	struct auxiliary_device *auxdev = to_auxiliary_dev(dev);

	kfree(auxdev);
}

/**
 * auxiliary_device_create - create a device on the auxiliary bus
 * @dev: parent device
 * @modname: module name used to create the auxiliary driver name.
 * @devname: auxiliary bus device name
 * @platform_data: auxiliary bus device platform data
 * @id: auxiliary bus device id
 *
 * Helper to create an auxiliary bus device.
 * The device created matches driver 'modname.devname' on the auxiliary bus.
 */
struct auxiliary_device *auxiliary_device_create(struct device *dev,
						 const char *modname,
						 const char *devname,
						 void *platform_data,
						 int id)
{
	struct auxiliary_device *auxdev;
	int ret;

	auxdev = kzalloc(sizeof(*auxdev), GFP_KERNEL);
	if (!auxdev)
		return NULL;

	auxdev->id = id;
	auxdev->name = devname;
	auxdev->dev.parent = dev;
	auxdev->dev.platform_data = platform_data;
	auxdev->dev.release = auxiliary_device_release;
	device_set_of_node_from_dev(&auxdev->dev, dev);

	ret = auxiliary_device_init(auxdev);
	if (ret) {
		kfree(auxdev);
		return NULL;
	}

	ret = __auxiliary_device_add(auxdev, modname);
	if (ret) {
		/*
		 * It may look odd but auxdev should not be freed here.
		 * auxiliary_device_uninit() calls device_put() which call
		 * the device release function, freeing auxdev.
		 */
		auxiliary_device_uninit(auxdev);
		return NULL;
	}

	return auxdev;
}
EXPORT_SYMBOL_GPL(auxiliary_device_create);

/**
 * auxiliary_device_destroy - remove an auxiliary device
 * @auxdev: pointer to the auxdev to be removed
 *
 * Helper to remove an auxiliary device created with
 * auxiliary_device_create()
 */
void auxiliary_device_destroy(void *auxdev)
{
	struct auxiliary_device *_auxdev = auxdev;

	auxiliary_device_delete(_auxdev);
	auxiliary_device_uninit(_auxdev);
}
EXPORT_SYMBOL_GPL(auxiliary_device_destroy);

/**
 * __devm_auxiliary_device_create - create a managed device on the auxiliary bus
 * @dev: parent device
 * @modname: module name used to create the auxiliary driver name.
 * @devname: auxiliary bus device name
 * @platform_data: auxiliary bus device platform data
 * @id: auxiliary bus device id
 *
 * Device managed helper to create an auxiliary bus device.
 * The device created matches driver 'modname.devname' on the auxiliary bus.
 */
struct auxiliary_device *__devm_auxiliary_device_create(struct device *dev,
							const char *modname,
							const char *devname,
							void *platform_data,
							int id)
{
	struct auxiliary_device *auxdev;
	int ret;

	auxdev = auxiliary_device_create(dev, modname, devname, platform_data, id);
	if (IS_ERR(auxdev))
		return auxdev;

	ret = devm_add_action_or_reset(dev, auxiliary_device_destroy,
				       auxdev);
	if (ret)
		return ERR_PTR(ret);

	return auxdev;
}
EXPORT_SYMBOL_GPL(__devm_auxiliary_device_create);

void __init auxiliary_bus_init(void)
{
	WARN_ON(bus_register(&auxiliary_bus_type));
+17 −0
Original line number Diff line number Diff line
@@ -254,6 +254,23 @@ int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *

void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);

struct auxiliary_device *auxiliary_device_create(struct device *dev,
						 const char *modname,
						 const char *devname,
						 void *platform_data,
						 int id);
void auxiliary_device_destroy(void *auxdev);

struct auxiliary_device *__devm_auxiliary_device_create(struct device *dev,
							const char *modname,
							const char *devname,
							void *platform_data,
							int id);

#define devm_auxiliary_device_create(dev, devname, platform_data)     \
	__devm_auxiliary_device_create(dev, KBUILD_MODNAME, devname,  \
				       platform_data, 0)

/**
 * module_auxiliary_driver() - Helper macro for registering an auxiliary driver
 * @__auxiliary_driver: auxiliary driver struct