diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 11:49:46 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 11:49:46 -0700 |
commit | dd77a4ee0f3981693d4229aa1d57cea9e526ff47 (patch) | |
tree | cb486be20b950201103a03636cbb1e1d180f0098 /drivers/base/class.c | |
parent | e8216dee838c09776680a6f1a2e54d81f3cdfa14 (diff) | |
parent | 7e9f4b2d3e21e87c26025810413ef1592834e63b (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6: (47 commits)
Driver core: Don't call put methods while holding a spinlock
Driver core: Remove unneeded routines from driver core
Driver core: Fix potential deadlock in driver core
PCI: enable driver multi-threaded probe
Driver Core: add ability for drivers to do a threaded probe
sysfs: add proper sysfs_init() prototype
drivers/base: check errors
drivers/base: Platform notify needs to occur before drivers attach to the device
v4l-dev2: handle __must_check
add CONFIG_ENABLE_MUST_CHECK
add __must_check to device management code
Driver core: fixed add_bind_files() definition
Driver core: fix comments in drivers/base/power/resume.c
sysfs_remove_bin_file: no return value, dump_stack on error
kobject: must_check fixes
Driver core: add ability for devices to create and remove bin files
Class: add support for class interfaces for devices
Driver core: create devices/virtual/ tree
Driver core: add device_rename function
Driver core: add ability for classes to handle devices properly
...
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 de8908320f2..b06b0e2b9c6 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -19,6 +19,8 @@ #include <linux/slab.h> #include "base.h" +extern struct subsystem devices_subsys; + #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) #define to_class(obj) container_of(obj, struct class, subsys.kset.kobj) @@ -197,7 +199,7 @@ static int class_device_create_uevent(struct class_device *class_dev, * Note, the pointer created here is to be destroyed when finished by * making a call to class_destroy(). */ -struct class *class_create(struct module *owner, char *name) +struct class *class_create(struct module *owner, const char *name) { struct class *cls; int retval; @@ -361,7 +363,7 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); if (class_dev->dev) { - /* add physical device, backing this device */ + /* add device, backing this class device (deprecated) */ struct device *dev = class_dev->dev; char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); @@ -679,7 +681,8 @@ int class_device_register(struct class_device *class_dev) struct class_device *class_device_create(struct class *cls, struct class_device *parent, dev_t devt, - struct device *device, char *fmt, ...) + struct device *device, + const char *fmt, ...) { va_list args; struct class_device *class_dev = NULL; @@ -839,6 +842,7 @@ int class_interface_register(struct class_interface *class_intf) { struct class *parent; struct class_device *class_dev; + struct device *dev; if (!class_intf || !class_intf->class) return -ENODEV; @@ -853,6 +857,10 @@ int class_interface_register(struct class_interface *class_intf) list_for_each_entry(class_dev, &parent->children, node) class_intf->add(class_dev, class_intf); } + if (class_intf->add_dev) { + list_for_each_entry(dev, &parent->devices, node) + class_intf->add_dev(dev, class_intf); + } up(&parent->sem); return 0; @@ -862,6 +870,7 @@ void class_interface_unregister(struct class_interface *class_intf) { struct class * parent = class_intf->class; struct class_device *class_dev; + struct device *dev; if (!parent) return; @@ -872,12 +881,31 @@ void class_interface_unregister(struct class_interface *class_intf) list_for_each_entry(class_dev, &parent->children, node) class_intf->remove(class_dev, class_intf); } + if (class_intf->remove_dev) { + list_for_each_entry(dev, &parent->devices, node) + class_intf->remove_dev(dev, class_intf); + } up(&parent->sem); class_put(parent); } +int virtual_device_parent(struct device *dev) +{ + if (!dev->class) + return -ENODEV; + + if (!dev->class->virtual_dir) { + static struct kobject *virtual_dir = NULL; + + if (!virtual_dir) + virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual"); + dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name); + } + dev->kobj.parent = dev->class->virtual_dir; + return 0; +} int __init classes_init(void) { |