diff options
Diffstat (limited to 'drivers/base/class.c')
-rw-r--r-- | drivers/base/class.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c index de8908320f23..b06b0e2b9c62 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include "base.h" | 20 | #include "base.h" |
21 | 21 | ||
22 | extern struct subsystem devices_subsys; | ||
23 | |||
22 | #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) | 24 | #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) |
23 | #define to_class(obj) container_of(obj, struct class, subsys.kset.kobj) | 25 | #define to_class(obj) container_of(obj, struct class, subsys.kset.kobj) |
24 | 26 | ||
@@ -197,7 +199,7 @@ static int class_device_create_uevent(struct class_device *class_dev, | |||
197 | * Note, the pointer created here is to be destroyed when finished by | 199 | * Note, the pointer created here is to be destroyed when finished by |
198 | * making a call to class_destroy(). | 200 | * making a call to class_destroy(). |
199 | */ | 201 | */ |
200 | struct class *class_create(struct module *owner, char *name) | 202 | struct class *class_create(struct module *owner, const char *name) |
201 | { | 203 | { |
202 | struct class *cls; | 204 | struct class *cls; |
203 | int retval; | 205 | int retval; |
@@ -361,7 +363,7 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, | |||
361 | pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); | 363 | pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); |
362 | 364 | ||
363 | if (class_dev->dev) { | 365 | if (class_dev->dev) { |
364 | /* add physical device, backing this device */ | 366 | /* add device, backing this class device (deprecated) */ |
365 | struct device *dev = class_dev->dev; | 367 | struct device *dev = class_dev->dev; |
366 | char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); | 368 | char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); |
367 | 369 | ||
@@ -679,7 +681,8 @@ int class_device_register(struct class_device *class_dev) | |||
679 | struct class_device *class_device_create(struct class *cls, | 681 | struct class_device *class_device_create(struct class *cls, |
680 | struct class_device *parent, | 682 | struct class_device *parent, |
681 | dev_t devt, | 683 | dev_t devt, |
682 | struct device *device, char *fmt, ...) | 684 | struct device *device, |
685 | const char *fmt, ...) | ||
683 | { | 686 | { |
684 | va_list args; | 687 | va_list args; |
685 | struct class_device *class_dev = NULL; | 688 | struct class_device *class_dev = NULL; |
@@ -839,6 +842,7 @@ int class_interface_register(struct class_interface *class_intf) | |||
839 | { | 842 | { |
840 | struct class *parent; | 843 | struct class *parent; |
841 | struct class_device *class_dev; | 844 | struct class_device *class_dev; |
845 | struct device *dev; | ||
842 | 846 | ||
843 | if (!class_intf || !class_intf->class) | 847 | if (!class_intf || !class_intf->class) |
844 | return -ENODEV; | 848 | return -ENODEV; |
@@ -853,6 +857,10 @@ int class_interface_register(struct class_interface *class_intf) | |||
853 | list_for_each_entry(class_dev, &parent->children, node) | 857 | list_for_each_entry(class_dev, &parent->children, node) |
854 | class_intf->add(class_dev, class_intf); | 858 | class_intf->add(class_dev, class_intf); |
855 | } | 859 | } |
860 | if (class_intf->add_dev) { | ||
861 | list_for_each_entry(dev, &parent->devices, node) | ||
862 | class_intf->add_dev(dev, class_intf); | ||
863 | } | ||
856 | up(&parent->sem); | 864 | up(&parent->sem); |
857 | 865 | ||
858 | return 0; | 866 | return 0; |
@@ -862,6 +870,7 @@ void class_interface_unregister(struct class_interface *class_intf) | |||
862 | { | 870 | { |
863 | struct class * parent = class_intf->class; | 871 | struct class * parent = class_intf->class; |
864 | struct class_device *class_dev; | 872 | struct class_device *class_dev; |
873 | struct device *dev; | ||
865 | 874 | ||
866 | if (!parent) | 875 | if (!parent) |
867 | return; | 876 | return; |
@@ -872,12 +881,31 @@ void class_interface_unregister(struct class_interface *class_intf) | |||
872 | list_for_each_entry(class_dev, &parent->children, node) | 881 | list_for_each_entry(class_dev, &parent->children, node) |
873 | class_intf->remove(class_dev, class_intf); | 882 | class_intf->remove(class_dev, class_intf); |
874 | } | 883 | } |
884 | if (class_intf->remove_dev) { | ||
885 | list_for_each_entry(dev, &parent->devices, node) | ||
886 | class_intf->remove_dev(dev, class_intf); | ||
887 | } | ||
875 | up(&parent->sem); | 888 | up(&parent->sem); |
876 | 889 | ||
877 | class_put(parent); | 890 | class_put(parent); |
878 | } | 891 | } |
879 | 892 | ||
893 | int virtual_device_parent(struct device *dev) | ||
894 | { | ||
895 | if (!dev->class) | ||
896 | return -ENODEV; | ||
897 | |||
898 | if (!dev->class->virtual_dir) { | ||
899 | static struct kobject *virtual_dir = NULL; | ||
900 | |||
901 | if (!virtual_dir) | ||
902 | virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual"); | ||
903 | dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name); | ||
904 | } | ||
880 | 905 | ||
906 | dev->kobj.parent = dev->class->virtual_dir; | ||
907 | return 0; | ||
908 | } | ||
881 | 909 | ||
882 | int __init classes_init(void) | 910 | int __init classes_init(void) |
883 | { | 911 | { |