diff options
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 65 |
1 files changed, 52 insertions, 13 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 6ed645411c40..080e9ca11017 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -338,6 +338,35 @@ static void device_remove_attributes(struct device *dev, | |||
338 | device_remove_file(dev, &attrs[i]); | 338 | device_remove_file(dev, &attrs[i]); |
339 | } | 339 | } |
340 | 340 | ||
341 | static int device_add_bin_attributes(struct device *dev, | ||
342 | struct bin_attribute *attrs) | ||
343 | { | ||
344 | int error = 0; | ||
345 | int i; | ||
346 | |||
347 | if (attrs) { | ||
348 | for (i = 0; attr_name(attrs[i]); i++) { | ||
349 | error = device_create_bin_file(dev, &attrs[i]); | ||
350 | if (error) | ||
351 | break; | ||
352 | } | ||
353 | if (error) | ||
354 | while (--i >= 0) | ||
355 | device_remove_bin_file(dev, &attrs[i]); | ||
356 | } | ||
357 | return error; | ||
358 | } | ||
359 | |||
360 | static void device_remove_bin_attributes(struct device *dev, | ||
361 | struct bin_attribute *attrs) | ||
362 | { | ||
363 | int i; | ||
364 | |||
365 | if (attrs) | ||
366 | for (i = 0; attr_name(attrs[i]); i++) | ||
367 | device_remove_bin_file(dev, &attrs[i]); | ||
368 | } | ||
369 | |||
341 | static int device_add_groups(struct device *dev, | 370 | static int device_add_groups(struct device *dev, |
342 | const struct attribute_group **groups) | 371 | const struct attribute_group **groups) |
343 | { | 372 | { |
@@ -378,12 +407,15 @@ static int device_add_attrs(struct device *dev) | |||
378 | error = device_add_attributes(dev, class->dev_attrs); | 407 | error = device_add_attributes(dev, class->dev_attrs); |
379 | if (error) | 408 | if (error) |
380 | return error; | 409 | return error; |
410 | error = device_add_bin_attributes(dev, class->dev_bin_attrs); | ||
411 | if (error) | ||
412 | goto err_remove_class_attrs; | ||
381 | } | 413 | } |
382 | 414 | ||
383 | if (type) { | 415 | if (type) { |
384 | error = device_add_groups(dev, type->groups); | 416 | error = device_add_groups(dev, type->groups); |
385 | if (error) | 417 | if (error) |
386 | goto err_remove_class_attrs; | 418 | goto err_remove_class_bin_attrs; |
387 | } | 419 | } |
388 | 420 | ||
389 | error = device_add_groups(dev, dev->groups); | 421 | error = device_add_groups(dev, dev->groups); |
@@ -395,6 +427,9 @@ static int device_add_attrs(struct device *dev) | |||
395 | err_remove_type_groups: | 427 | err_remove_type_groups: |
396 | if (type) | 428 | if (type) |
397 | device_remove_groups(dev, type->groups); | 429 | device_remove_groups(dev, type->groups); |
430 | err_remove_class_bin_attrs: | ||
431 | if (class) | ||
432 | device_remove_bin_attributes(dev, class->dev_bin_attrs); | ||
398 | err_remove_class_attrs: | 433 | err_remove_class_attrs: |
399 | if (class) | 434 | if (class) |
400 | device_remove_attributes(dev, class->dev_attrs); | 435 | device_remove_attributes(dev, class->dev_attrs); |
@@ -412,8 +447,10 @@ static void device_remove_attrs(struct device *dev) | |||
412 | if (type) | 447 | if (type) |
413 | device_remove_groups(dev, type->groups); | 448 | device_remove_groups(dev, type->groups); |
414 | 449 | ||
415 | if (class) | 450 | if (class) { |
416 | device_remove_attributes(dev, class->dev_attrs); | 451 | device_remove_attributes(dev, class->dev_attrs); |
452 | device_remove_bin_attributes(dev, class->dev_bin_attrs); | ||
453 | } | ||
417 | } | 454 | } |
418 | 455 | ||
419 | 456 | ||
@@ -610,7 +647,7 @@ class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) | |||
610 | dir->class = class; | 647 | dir->class = class; |
611 | kobject_init(&dir->kobj, &class_dir_ktype); | 648 | kobject_init(&dir->kobj, &class_dir_ktype); |
612 | 649 | ||
613 | dir->kobj.kset = &class->p->class_dirs; | 650 | dir->kobj.kset = &class->p->glue_dirs; |
614 | 651 | ||
615 | retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); | 652 | retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); |
616 | if (retval < 0) { | 653 | if (retval < 0) { |
@@ -635,7 +672,7 @@ static struct kobject *get_device_parent(struct device *dev, | |||
635 | if (sysfs_deprecated && dev->class == &block_class) { | 672 | if (sysfs_deprecated && dev->class == &block_class) { |
636 | if (parent && parent->class == &block_class) | 673 | if (parent && parent->class == &block_class) |
637 | return &parent->kobj; | 674 | return &parent->kobj; |
638 | return &block_class.p->class_subsys.kobj; | 675 | return &block_class.p->subsys.kobj; |
639 | } | 676 | } |
640 | #endif | 677 | #endif |
641 | 678 | ||
@@ -654,13 +691,13 @@ static struct kobject *get_device_parent(struct device *dev, | |||
654 | mutex_lock(&gdp_mutex); | 691 | mutex_lock(&gdp_mutex); |
655 | 692 | ||
656 | /* find our class-directory at the parent and reference it */ | 693 | /* find our class-directory at the parent and reference it */ |
657 | spin_lock(&dev->class->p->class_dirs.list_lock); | 694 | spin_lock(&dev->class->p->glue_dirs.list_lock); |
658 | list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) | 695 | list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) |
659 | if (k->parent == parent_kobj) { | 696 | if (k->parent == parent_kobj) { |
660 | kobj = kobject_get(k); | 697 | kobj = kobject_get(k); |
661 | break; | 698 | break; |
662 | } | 699 | } |
663 | spin_unlock(&dev->class->p->class_dirs.list_lock); | 700 | spin_unlock(&dev->class->p->glue_dirs.list_lock); |
664 | if (kobj) { | 701 | if (kobj) { |
665 | mutex_unlock(&gdp_mutex); | 702 | mutex_unlock(&gdp_mutex); |
666 | return kobj; | 703 | return kobj; |
@@ -682,7 +719,7 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) | |||
682 | { | 719 | { |
683 | /* see if we live in a "glue" directory */ | 720 | /* see if we live in a "glue" directory */ |
684 | if (!glue_dir || !dev->class || | 721 | if (!glue_dir || !dev->class || |
685 | glue_dir->kset != &dev->class->p->class_dirs) | 722 | glue_dir->kset != &dev->class->p->glue_dirs) |
686 | return; | 723 | return; |
687 | 724 | ||
688 | kobject_put(glue_dir); | 725 | kobject_put(glue_dir); |
@@ -709,7 +746,7 @@ static int device_add_class_symlinks(struct device *dev) | |||
709 | return 0; | 746 | return 0; |
710 | 747 | ||
711 | error = sysfs_create_link(&dev->kobj, | 748 | error = sysfs_create_link(&dev->kobj, |
712 | &dev->class->p->class_subsys.kobj, | 749 | &dev->class->p->subsys.kobj, |
713 | "subsystem"); | 750 | "subsystem"); |
714 | if (error) | 751 | if (error) |
715 | goto out; | 752 | goto out; |
@@ -728,7 +765,7 @@ static int device_add_class_symlinks(struct device *dev) | |||
728 | #endif | 765 | #endif |
729 | 766 | ||
730 | /* link in the class directory pointing to the device */ | 767 | /* link in the class directory pointing to the device */ |
731 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, | 768 | error = sysfs_create_link(&dev->class->p->subsys.kobj, |
732 | &dev->kobj, dev_name(dev)); | 769 | &dev->kobj, dev_name(dev)); |
733 | if (error) | 770 | if (error) |
734 | goto out_device; | 771 | goto out_device; |
@@ -756,7 +793,7 @@ static void device_remove_class_symlinks(struct device *dev) | |||
756 | if (sysfs_deprecated && dev->class == &block_class) | 793 | if (sysfs_deprecated && dev->class == &block_class) |
757 | return; | 794 | return; |
758 | #endif | 795 | #endif |
759 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); | 796 | sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); |
760 | } | 797 | } |
761 | 798 | ||
762 | /** | 799 | /** |
@@ -947,7 +984,7 @@ int device_add(struct device *dev) | |||
947 | mutex_lock(&dev->class->p->class_mutex); | 984 | mutex_lock(&dev->class->p->class_mutex); |
948 | /* tie the class to the device */ | 985 | /* tie the class to the device */ |
949 | klist_add_tail(&dev->knode_class, | 986 | klist_add_tail(&dev->knode_class, |
950 | &dev->class->p->class_devices); | 987 | &dev->class->p->klist_devices); |
951 | 988 | ||
952 | /* notify any interfaces that the device is here */ | 989 | /* notify any interfaces that the device is here */ |
953 | list_for_each_entry(class_intf, | 990 | list_for_each_entry(class_intf, |
@@ -1513,6 +1550,8 @@ EXPORT_SYMBOL_GPL(device_destroy); | |||
1513 | * exclusion between two different calls of device_rename | 1550 | * exclusion between two different calls of device_rename |
1514 | * on the same device to ensure that new_name is valid and | 1551 | * on the same device to ensure that new_name is valid and |
1515 | * won't conflict with other devices. | 1552 | * won't conflict with other devices. |
1553 | * | ||
1554 | * "Never use this function, bad things will happen" - gregkh | ||
1516 | */ | 1555 | */ |
1517 | int device_rename(struct device *dev, const char *new_name) | 1556 | int device_rename(struct device *dev, const char *new_name) |
1518 | { | 1557 | { |
@@ -1535,7 +1574,7 @@ int device_rename(struct device *dev, const char *new_name) | |||
1535 | } | 1574 | } |
1536 | 1575 | ||
1537 | if (dev->class) { | 1576 | if (dev->class) { |
1538 | error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, | 1577 | error = sysfs_rename_link(&dev->class->p->subsys.kobj, |
1539 | &dev->kobj, old_device_name, new_name); | 1578 | &dev->kobj, old_device_name, new_name); |
1540 | if (error) | 1579 | if (error) |
1541 | goto out; | 1580 | goto out; |