aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/class.c')
-rw-r--r--drivers/base/class.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c
index df7fdabd0730..b1ea4df85c7d 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -456,6 +456,35 @@ static void class_device_remove_attrs(struct class_device * cd)
456 } 456 }
457} 457}
458 458
459static int class_device_add_groups(struct class_device * cd)
460{
461 int i;
462 int error = 0;
463
464 if (cd->groups) {
465 for (i = 0; cd->groups[i]; i++) {
466 error = sysfs_create_group(&cd->kobj, cd->groups[i]);
467 if (error) {
468 while (--i >= 0)
469 sysfs_remove_group(&cd->kobj, cd->groups[i]);
470 goto out;
471 }
472 }
473 }
474out:
475 return error;
476}
477
478static void class_device_remove_groups(struct class_device * cd)
479{
480 int i;
481 if (cd->groups) {
482 for (i = 0; cd->groups[i]; i++) {
483 sysfs_remove_group(&cd->kobj, cd->groups[i]);
484 }
485 }
486}
487
459static ssize_t show_dev(struct class_device *class_dev, char *buf) 488static ssize_t show_dev(struct class_device *class_dev, char *buf)
460{ 489{
461 return print_dev_t(buf, class_dev->devt); 490 return print_dev_t(buf, class_dev->devt);
@@ -559,17 +588,18 @@ int class_device_add(struct class_device *class_dev)
559 class_name); 588 class_name);
560 } 589 }
561 590
591 class_device_add_groups(class_dev);
592
562 kobject_uevent(&class_dev->kobj, KOBJ_ADD); 593 kobject_uevent(&class_dev->kobj, KOBJ_ADD);
563 594
564 /* notify any interfaces this device is now here */ 595 /* notify any interfaces this device is now here */
565 if (parent_class) { 596 down(&parent_class->sem);
566 down(&parent_class->sem); 597 list_add_tail(&class_dev->node, &parent_class->children);
567 list_add_tail(&class_dev->node, &parent_class->children); 598 list_for_each_entry(class_intf, &parent_class->interfaces, node) {
568 list_for_each_entry(class_intf, &parent_class->interfaces, node) 599 if (class_intf->add)
569 if (class_intf->add) 600 class_intf->add(class_dev, class_intf);
570 class_intf->add(class_dev, class_intf);
571 up(&parent_class->sem);
572 } 601 }
602 up(&parent_class->sem);
573 603
574 register_done: 604 register_done:
575 if (error) { 605 if (error) {
@@ -673,6 +703,7 @@ void class_device_del(struct class_device *class_dev)
673 if (class_dev->devt_attr) 703 if (class_dev->devt_attr)
674 class_device_remove_file(class_dev, class_dev->devt_attr); 704 class_device_remove_file(class_dev, class_dev->devt_attr);
675 class_device_remove_attrs(class_dev); 705 class_device_remove_attrs(class_dev);
706 class_device_remove_groups(class_dev);
676 707
677 kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); 708 kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
678 kobject_del(&class_dev->kobj); 709 kobject_del(&class_dev->kobj);