]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/base/core.c
Kobject: auto-cleanup on final unref
[linux-2.6-omap-h63xx.git] / drivers / base / core.c
index 13cae18936c5c467b949e30b8eb7e852e10a9fdf..d5d542db96fd4f6114108d8756b8baceda83393f 100644 (file)
@@ -525,7 +525,7 @@ static void klist_children_put(struct klist_node *n)
 void device_initialize(struct device *dev)
 {
        dev->kobj.kset = devices_kset;
-       kobject_init_ng(&dev->kobj, &device_ktype);
+       kobject_init(&dev->kobj, &device_ktype);
        klist_init(&dev->klist_children, klist_children_get,
                   klist_children_put);
        INIT_LIST_HEAD(&dev->dma_pools);
@@ -576,8 +576,8 @@ static struct kobject *get_device_parent(struct device *dev,
 
                /*
                 * If we have no parent, we live in "virtual".
-                * Class-devices with a bus-device as parent, live
-                * in a class-directory to prevent namespace collisions.
+                * Class-devices with a non class-device as parent, live
+                * in a "glue" directory to prevent namespace collisions.
                 */
                if (parent == NULL)
                        parent_kobj = virtual_device_parent(dev);
@@ -602,13 +602,12 @@ static struct kobject *get_device_parent(struct device *dev,
                if (!k)
                        return NULL;
                k->kset = &dev->class->class_dirs;
-               retval = kobject_add_ng(k, parent_kobj, "%s", dev->class->name);
+               retval = kobject_add(k, parent_kobj, "%s", dev->class->name);
                if (retval < 0) {
                        kobject_put(k);
                        return NULL;
                }
-               /* Do not emit a uevent, as it's not needed for this
-                * "class glue" directory. */
+               /* do not emit an uevent for this simple "glue" directory */
                return k;
        }
 
@@ -619,30 +618,13 @@ static struct kobject *get_device_parent(struct device *dev,
 
 static void cleanup_device_parent(struct device *dev)
 {
-       struct device *d;
-       int other = 0;
+       struct kobject *glue_dir = dev->kobj.parent;
 
-       if (!dev->class)
-               return;
-
-       /* see if we live in a parent class directory */
-       if (dev->kobj.parent->kset != &dev->class->class_dirs)
+       /* see if we live in a "glue" directory */
+       if (!dev->class || glue_dir->kset != &dev->class->class_dirs)
                return;
 
-       /* if we are the last child of our class, delete the directory */
-       down(&dev->class->sem);
-       list_for_each_entry(d, &dev->class->devices, node) {
-               if (d == dev)
-                       continue;
-               if (d->kobj.parent == dev->kobj.parent) {
-                       other = 1;
-                       break;
-               }
-       }
-       if (!other)
-               kobject_del(dev->kobj.parent);
-       kobject_put(dev->kobj.parent);
-       up(&dev->class->sem);
+       kobject_put(glue_dir);
 }
 #endif
 
@@ -671,14 +653,15 @@ static int device_add_class_symlinks(struct device *dev)
 
 #ifdef CONFIG_SYSFS_DEPRECATED
        /* stacked class devices need a symlink in the class directory */
-       if (dev->kobj.parent != &dev->class->subsys.kobj) {
+       if (dev->kobj.parent != &dev->class->subsys.kobj &&
+           dev->type != &part_type) {
                error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
                                          dev->bus_id);
                if (error)
                        goto out_subsys;
        }
 
-       if (dev->parent) {
+       if (dev->parent && dev->type != &part_type) {
                struct device *parent = dev->parent;
                char *class_name;
 
@@ -707,10 +690,11 @@ static int device_add_class_symlinks(struct device *dev)
        return 0;
 
 out_device:
-       if (dev->parent)
+       if (dev->parent && dev->type != &part_type)
                sysfs_remove_link(&dev->kobj, "device");
 out_busid:
-       if (dev->kobj.parent != &dev->class->subsys.kobj)
+       if (dev->kobj.parent != &dev->class->subsys.kobj &&
+           dev->type != &part_type)
                sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
 #else
        /* link in the class directory pointing to the device */
@@ -719,7 +703,7 @@ out_busid:
        if (error)
                goto out_subsys;
 
-       if (dev->parent) {
+       if (dev->parent && dev->type != &part_type) {
                error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
                                          "device");
                if (error)
@@ -743,7 +727,7 @@ static void device_remove_class_symlinks(struct device *dev)
                return;
 
 #ifdef CONFIG_SYSFS_DEPRECATED
-       if (dev->parent) {
+       if (dev->parent && dev->type != &part_type) {
                char *class_name;
 
                class_name = make_class_name(dev->class->name, &dev->kobj);
@@ -754,10 +738,11 @@ static void device_remove_class_symlinks(struct device *dev)
                sysfs_remove_link(&dev->kobj, "device");
        }
 
-       if (dev->kobj.parent != &dev->class->subsys.kobj)
+       if (dev->kobj.parent != &dev->class->subsys.kobj &&
+           dev->type != &part_type)
                sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
 #else
-       if (dev->parent)
+       if (dev->parent && dev->type != &part_type)
                sysfs_remove_link(&dev->kobj, "device");
 
        sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
@@ -773,7 +758,7 @@ static void device_remove_class_symlinks(struct device *dev)
  *     This is part 2 of device_register(), though may be called
  *     separately _iff_ device_initialize() has been called separately.
  *
- *     This adds it to the kobject hierarchy via kobject_add_ng(), adds it
+ *     This adds it to the kobject hierarchy via kobject_add(), adds it
  *     to the global and sibling lists for the device, then
  *     adds it to the other relevant subsystems of the driver model.
  */
@@ -804,7 +789,7 @@ int device_add(struct device *dev)
                goto Error;
 
        /* first, register with generic layer. */
-       error = kobject_add_ng(&dev->kobj, dev->kobj.parent, "%s", dev->bus_id);
+       error = kobject_add(&dev->kobj, dev->kobj.parent, "%s", dev->bus_id);
        if (error)
                goto Error;
 
@@ -925,6 +910,7 @@ struct device * get_device(struct device * dev)
  */
 void put_device(struct device * dev)
 {
+       /* might_sleep(); */
        if (dev)
                kobject_put(&dev->kobj);
 }