diff options
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 58 |
1 files changed, 21 insertions, 37 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index dd40d78a023d..0455aa78fa13 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -310,6 +310,9 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | |||
310 | return count; | 310 | return count; |
311 | } | 311 | } |
312 | 312 | ||
313 | static struct device_attribute uevent_attr = | ||
314 | __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent); | ||
315 | |||
313 | static int device_add_attributes(struct device *dev, | 316 | static int device_add_attributes(struct device *dev, |
314 | struct device_attribute *attrs) | 317 | struct device_attribute *attrs) |
315 | { | 318 | { |
@@ -423,6 +426,9 @@ static ssize_t show_dev(struct device *dev, struct device_attribute *attr, | |||
423 | return print_dev_t(buf, dev->devt); | 426 | return print_dev_t(buf, dev->devt); |
424 | } | 427 | } |
425 | 428 | ||
429 | static struct device_attribute devt_attr = | ||
430 | __ATTR(dev, S_IRUGO, show_dev, NULL); | ||
431 | |||
426 | /* | 432 | /* |
427 | * devices_subsys - structure to be registered with kobject core. | 433 | * devices_subsys - structure to be registered with kobject core. |
428 | */ | 434 | */ |
@@ -681,35 +687,14 @@ int device_add(struct device *dev) | |||
681 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 687 | blocking_notifier_call_chain(&dev->bus->bus_notifier, |
682 | BUS_NOTIFY_ADD_DEVICE, dev); | 688 | BUS_NOTIFY_ADD_DEVICE, dev); |
683 | 689 | ||
684 | dev->uevent_attr.attr.name = "uevent"; | 690 | error = device_create_file(dev, &uevent_attr); |
685 | dev->uevent_attr.attr.mode = S_IRUGO | S_IWUSR; | ||
686 | if (dev->driver) | ||
687 | dev->uevent_attr.attr.owner = dev->driver->owner; | ||
688 | dev->uevent_attr.store = store_uevent; | ||
689 | dev->uevent_attr.show = show_uevent; | ||
690 | error = device_create_file(dev, &dev->uevent_attr); | ||
691 | if (error) | 691 | if (error) |
692 | goto attrError; | 692 | goto attrError; |
693 | 693 | ||
694 | if (MAJOR(dev->devt)) { | 694 | if (MAJOR(dev->devt)) { |
695 | struct device_attribute *attr; | 695 | error = device_create_file(dev, &devt_attr); |
696 | attr = kzalloc(sizeof(*attr), GFP_KERNEL); | 696 | if (error) |
697 | if (!attr) { | ||
698 | error = -ENOMEM; | ||
699 | goto ueventattrError; | ||
700 | } | ||
701 | attr->attr.name = "dev"; | ||
702 | attr->attr.mode = S_IRUGO; | ||
703 | if (dev->driver) | ||
704 | attr->attr.owner = dev->driver->owner; | ||
705 | attr->show = show_dev; | ||
706 | error = device_create_file(dev, attr); | ||
707 | if (error) { | ||
708 | kfree(attr); | ||
709 | goto ueventattrError; | 697 | goto ueventattrError; |
710 | } | ||
711 | |||
712 | dev->devt_attr = attr; | ||
713 | } | 698 | } |
714 | 699 | ||
715 | if (dev->class) { | 700 | if (dev->class) { |
@@ -733,11 +718,14 @@ int device_add(struct device *dev) | |||
733 | } | 718 | } |
734 | } | 719 | } |
735 | 720 | ||
736 | if ((error = device_add_attrs(dev))) | 721 | error = device_add_attrs(dev); |
722 | if (error) | ||
737 | goto AttrsError; | 723 | goto AttrsError; |
738 | if ((error = device_pm_add(dev))) | 724 | error = device_pm_add(dev); |
725 | if (error) | ||
739 | goto PMError; | 726 | goto PMError; |
740 | if ((error = bus_add_device(dev))) | 727 | error = bus_add_device(dev); |
728 | if (error) | ||
741 | goto BusError; | 729 | goto BusError; |
742 | kobject_uevent(&dev->kobj, KOBJ_ADD); | 730 | kobject_uevent(&dev->kobj, KOBJ_ADD); |
743 | bus_attach_device(dev); | 731 | bus_attach_device(dev); |
@@ -767,10 +755,8 @@ int device_add(struct device *dev) | |||
767 | BUS_NOTIFY_DEL_DEVICE, dev); | 755 | BUS_NOTIFY_DEL_DEVICE, dev); |
768 | device_remove_attrs(dev); | 756 | device_remove_attrs(dev); |
769 | AttrsError: | 757 | AttrsError: |
770 | if (dev->devt_attr) { | 758 | if (MAJOR(dev->devt)) |
771 | device_remove_file(dev, dev->devt_attr); | 759 | device_remove_file(dev, &devt_attr); |
772 | kfree(dev->devt_attr); | ||
773 | } | ||
774 | 760 | ||
775 | if (dev->class) { | 761 | if (dev->class) { |
776 | sysfs_remove_link(&dev->kobj, "subsystem"); | 762 | sysfs_remove_link(&dev->kobj, "subsystem"); |
@@ -792,7 +778,7 @@ int device_add(struct device *dev) | |||
792 | } | 778 | } |
793 | } | 779 | } |
794 | ueventattrError: | 780 | ueventattrError: |
795 | device_remove_file(dev, &dev->uevent_attr); | 781 | device_remove_file(dev, &uevent_attr); |
796 | attrError: | 782 | attrError: |
797 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 783 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
798 | kobject_del(&dev->kobj); | 784 | kobject_del(&dev->kobj); |
@@ -869,10 +855,8 @@ void device_del(struct device * dev) | |||
869 | 855 | ||
870 | if (parent) | 856 | if (parent) |
871 | klist_del(&dev->knode_parent); | 857 | klist_del(&dev->knode_parent); |
872 | if (dev->devt_attr) { | 858 | if (MAJOR(dev->devt)) |
873 | device_remove_file(dev, dev->devt_attr); | 859 | device_remove_file(dev, &devt_attr); |
874 | kfree(dev->devt_attr); | ||
875 | } | ||
876 | if (dev->class) { | 860 | if (dev->class) { |
877 | sysfs_remove_link(&dev->kobj, "subsystem"); | 861 | sysfs_remove_link(&dev->kobj, "subsystem"); |
878 | /* If this is not a "fake" compatible device, remove the | 862 | /* If this is not a "fake" compatible device, remove the |
@@ -926,7 +910,7 @@ void device_del(struct device * dev) | |||
926 | up(&dev->class->sem); | 910 | up(&dev->class->sem); |
927 | } | 911 | } |
928 | } | 912 | } |
929 | device_remove_file(dev, &dev->uevent_attr); | 913 | device_remove_file(dev, &uevent_attr); |
930 | device_remove_attrs(dev); | 914 | device_remove_attrs(dev); |
931 | bus_remove_device(dev); | 915 | bus_remove_device(dev); |
932 | 916 | ||