diff options
Diffstat (limited to 'drivers/base/class.c')
-rw-r--r-- | drivers/base/class.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c index eb85e4312301..161746deab4b 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -488,6 +488,93 @@ void class_interface_unregister(struct class_interface *class_intf) | |||
488 | class_put(parent); | 488 | class_put(parent); |
489 | } | 489 | } |
490 | 490 | ||
491 | struct class_compat { | ||
492 | struct kobject *kobj; | ||
493 | }; | ||
494 | |||
495 | /** | ||
496 | * class_compat_register - register a compatibility class | ||
497 | * @name: the name of the class | ||
498 | * | ||
499 | * Compatibility class are meant as a temporary user-space compatibility | ||
500 | * workaround when converting a family of class devices to a bus devices. | ||
501 | */ | ||
502 | struct class_compat *class_compat_register(const char *name) | ||
503 | { | ||
504 | struct class_compat *cls; | ||
505 | |||
506 | cls = kmalloc(sizeof(struct class_compat), GFP_KERNEL); | ||
507 | if (!cls) | ||
508 | return NULL; | ||
509 | cls->kobj = kobject_create_and_add(name, &class_kset->kobj); | ||
510 | if (!cls->kobj) { | ||
511 | kfree(cls); | ||
512 | return NULL; | ||
513 | } | ||
514 | return cls; | ||
515 | } | ||
516 | EXPORT_SYMBOL_GPL(class_compat_register); | ||
517 | |||
518 | /** | ||
519 | * class_compat_unregister - unregister a compatibility class | ||
520 | * @cls: the class to unregister | ||
521 | */ | ||
522 | void class_compat_unregister(struct class_compat *cls) | ||
523 | { | ||
524 | kobject_put(cls->kobj); | ||
525 | kfree(cls); | ||
526 | } | ||
527 | EXPORT_SYMBOL_GPL(class_compat_unregister); | ||
528 | |||
529 | /** | ||
530 | * class_compat_create_link - create a compatibility class device link to | ||
531 | * a bus device | ||
532 | * @cls: the compatibility class | ||
533 | * @dev: the target bus device | ||
534 | * @device_link: an optional device to which a "device" link should be created | ||
535 | */ | ||
536 | int class_compat_create_link(struct class_compat *cls, struct device *dev, | ||
537 | struct device *device_link) | ||
538 | { | ||
539 | int error; | ||
540 | |||
541 | error = sysfs_create_link(cls->kobj, &dev->kobj, dev_name(dev)); | ||
542 | if (error) | ||
543 | return error; | ||
544 | |||
545 | /* | ||
546 | * Optionally add a "device" link (typically to the parent), as a | ||
547 | * class device would have one and we want to provide as much | ||
548 | * backwards compatibility as possible. | ||
549 | */ | ||
550 | if (device_link) { | ||
551 | error = sysfs_create_link(&dev->kobj, &device_link->kobj, | ||
552 | "device"); | ||
553 | if (error) | ||
554 | sysfs_remove_link(cls->kobj, dev_name(dev)); | ||
555 | } | ||
556 | |||
557 | return error; | ||
558 | } | ||
559 | EXPORT_SYMBOL_GPL(class_compat_create_link); | ||
560 | |||
561 | /** | ||
562 | * class_compat_remove_link - remove a compatibility class device link to | ||
563 | * a bus device | ||
564 | * @cls: the compatibility class | ||
565 | * @dev: the target bus device | ||
566 | * @device_link: an optional device to which a "device" link was previously | ||
567 | * created | ||
568 | */ | ||
569 | void class_compat_remove_link(struct class_compat *cls, struct device *dev, | ||
570 | struct device *device_link) | ||
571 | { | ||
572 | if (device_link) | ||
573 | sysfs_remove_link(&dev->kobj, "device"); | ||
574 | sysfs_remove_link(cls->kobj, dev_name(dev)); | ||
575 | } | ||
576 | EXPORT_SYMBOL_GPL(class_compat_remove_link); | ||
577 | |||
491 | int __init classes_init(void) | 578 | int __init classes_init(void) |
492 | { | 579 | { |
493 | class_kset = kset_create_and_add("class", NULL, NULL); | 580 | class_kset = kset_create_and_add("class", NULL, NULL); |