@@ -385,6 +385,114 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)
385
385
}
386
386
EXPORT_SYMBOL_GPL (auxiliary_driver_unregister );
387
387
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
+
388
496
void __init auxiliary_bus_init (void )
389
497
{
390
498
WARN_ON (bus_register (& auxiliary_bus_type ));
0 commit comments