mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
Kobject: auto-cleanup on final unref
We save the current state in the object itself, so we can do proper cleanup when the last reference is dropped. If the initial reference is dropped, the object will be removed from sysfs if needed, if an "add" event was sent, "remove" will be send, and the allocated resources are released. This allows us to clean up some driver core usage as well as allowing us to do other such changes to the rest of the kernel. Signed-off-by: Kay Sievers <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
This commit is contained in:
parent
12e339ac6e
commit
0f4dafc056
4 changed files with 119 additions and 99 deletions
|
|
@ -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);
|
||||
|
|
@ -607,8 +607,7 @@ static struct kobject *get_device_parent(struct device *dev,
|
|||
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)
|
||||
/* see if we live in a "glue" directory */
|
||||
if (!dev->class || glue_dir->kset != &dev->class->class_dirs)
|
||||
return;
|
||||
|
||||
/* see if we live in a parent class directory */
|
||||
if (dev->kobj.parent->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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue