Skip to content

Commit eaa0d30

Browse files
jbrun3tgregkh
authored andcommitted
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: Stephen Boyd <[email protected]> Cc: Arnd Bergmann <[email protected]> Signed-off-by: Jerome Brunet <[email protected]> Reviewed-by: Greg Kroah-Hartman <[email protected]> Reviewed-by: Ira Weiny <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d487858 commit eaa0d30

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

drivers/base/auxiliary.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,114 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)
385385
}
386386
EXPORT_SYMBOL_GPL(auxiliary_driver_unregister);
387387

388+
static void auxiliary_device_release(struct device *dev)
389+
{
390+
struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
391+
392+
kfree(auxdev);
393+
}
394+
395+
/**
396+
* auxiliary_device_create - create a device on the auxiliary bus
397+
* @dev: parent device
398+
* @modname: module name used to create the auxiliary driver name.
399+
* @devname: auxiliary bus device name
400+
* @platform_data: auxiliary bus device platform data
401+
* @id: auxiliary bus device id
402+
*
403+
* Helper to create an auxiliary bus device.
404+
* The device created matches driver 'modname.devname' on the auxiliary bus.
405+
*/
406+
struct auxiliary_device *auxiliary_device_create(struct device *dev,
407+
const char *modname,
408+
const char *devname,
409+
void *platform_data,
410+
int id)
411+
{
412+
struct auxiliary_device *auxdev;
413+
int ret;
414+
415+
auxdev = kzalloc(sizeof(*auxdev), GFP_KERNEL);
416+
if (!auxdev)
417+
return NULL;
418+
419+
auxdev->id = id;
420+
auxdev->name = devname;
421+
auxdev->dev.parent = dev;
422+
auxdev->dev.platform_data = platform_data;
423+
auxdev->dev.release = auxiliary_device_release;
424+
device_set_of_node_from_dev(&auxdev->dev, dev);
425+
426+
ret = auxiliary_device_init(auxdev);
427+
if (ret) {
428+
kfree(auxdev);
429+
return NULL;
430+
}
431+
432+
ret = __auxiliary_device_add(auxdev, modname);
433+
if (ret) {
434+
/*
435+
* It may look odd but auxdev should not be freed here.
436+
* auxiliary_device_uninit() calls device_put() which call
437+
* the device release function, freeing auxdev.
438+
*/
439+
auxiliary_device_uninit(auxdev);
440+
return NULL;
441+
}
442+
443+
return auxdev;
444+
}
445+
EXPORT_SYMBOL_GPL(auxiliary_device_create);
446+
447+
/**
448+
* auxiliary_device_destroy - remove an auxiliary device
449+
* @auxdev: pointer to the auxdev to be removed
450+
*
451+
* Helper to remove an auxiliary device created with
452+
* auxiliary_device_create()
453+
*/
454+
void auxiliary_device_destroy(void *auxdev)
455+
{
456+
struct auxiliary_device *_auxdev = auxdev;
457+
458+
auxiliary_device_delete(_auxdev);
459+
auxiliary_device_uninit(_auxdev);
460+
}
461+
EXPORT_SYMBOL_GPL(auxiliary_device_destroy);
462+
463+
/**
464+
* __devm_auxiliary_device_create - create a managed device on the auxiliary bus
465+
* @dev: parent device
466+
* @modname: module name used to create the auxiliary driver name.
467+
* @devname: auxiliary bus device name
468+
* @platform_data: auxiliary bus device platform data
469+
* @id: auxiliary bus device id
470+
*
471+
* Device managed helper to create an auxiliary bus device.
472+
* The device created matches driver 'modname.devname' on the auxiliary bus.
473+
*/
474+
struct auxiliary_device *__devm_auxiliary_device_create(struct device *dev,
475+
const char *modname,
476+
const char *devname,
477+
void *platform_data,
478+
int id)
479+
{
480+
struct auxiliary_device *auxdev;
481+
int ret;
482+
483+
auxdev = auxiliary_device_create(dev, modname, devname, platform_data, id);
484+
if (IS_ERR(auxdev))
485+
return auxdev;
486+
487+
ret = devm_add_action_or_reset(dev, auxiliary_device_destroy,
488+
auxdev);
489+
if (ret)
490+
return ERR_PTR(ret);
491+
492+
return auxdev;
493+
}
494+
EXPORT_SYMBOL_GPL(__devm_auxiliary_device_create);
495+
388496
void __init auxiliary_bus_init(void)
389497
{
390498
WARN_ON(bus_register(&auxiliary_bus_type));

include/linux/auxiliary_bus.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,23 @@ int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *
254254

255255
void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);
256256

257+
struct auxiliary_device *auxiliary_device_create(struct device *dev,
258+
const char *modname,
259+
const char *devname,
260+
void *platform_data,
261+
int id);
262+
void auxiliary_device_destroy(void *auxdev);
263+
264+
struct auxiliary_device *__devm_auxiliary_device_create(struct device *dev,
265+
const char *modname,
266+
const char *devname,
267+
void *platform_data,
268+
int id);
269+
270+
#define devm_auxiliary_device_create(dev, devname, platform_data) \
271+
__devm_auxiliary_device_create(dev, KBUILD_MODNAME, devname, \
272+
platform_data, 0)
273+
257274
/**
258275
* module_auxiliary_driver() - Helper macro for registering an auxiliary driver
259276
* @__auxiliary_driver: auxiliary driver struct

0 commit comments

Comments
 (0)