summaryrefslogtreecommitdiffstats
path: root/drivers/base/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/class.c')
-rw-r--r--drivers/base/class.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c
index de8908320f2..b32b77ff2dc 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;
@@ -226,7 +228,7 @@ error:
/**
* class_destroy - destroys a struct class structure
- * @cs: pointer to the struct class that is to be destroyed
+ * @cls: pointer to the struct class that is to be destroyed
*
* Note, the pointer to be destroyed must have been created with a call
* to class_create().
@@ -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);
@@ -656,9 +658,9 @@ int class_device_register(struct class_device *class_dev)
/**
* class_device_create - creates a class device and registers it with sysfs
- * @cs: pointer to the struct class that this device should be registered to.
+ * @cls: pointer to the struct class that this device should be registered to.
* @parent: pointer to the parent struct class_device of this new device, if any.
- * @dev: the dev_t for the char device to be added.
+ * @devt: the dev_t for the char device to be added.
* @device: a pointer to a struct device that is assiociated with this class device.
* @fmt: string for the class device's name
*
@@ -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;
@@ -763,7 +766,7 @@ void class_device_unregister(struct class_device *class_dev)
/**
* class_device_destroy - removes a class device that was created with class_device_create()
* @cls: the pointer to the struct class that this device was registered * with.
- * @dev: the dev_t of the device that was previously registered.
+ * @devt: the dev_t of the device that was previously registered.
*
* This call unregisters and cleans up a class device that was created with a
* call to class_device_create()
@@ -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)
{