- /* if this is a class device, and has no parent, create one */
- if ((dev->class) && (parent == NULL)) {
- return virtual_device_parent(dev);
- } else if (parent)
+ if (dev->class) {
+ struct kobject *kobj = NULL;
+ struct kobject *parent_kobj;
+ struct kobject *k;
+
+ /*
+ * 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.
+ */
+ if (parent == NULL)
+ parent_kobj = virtual_device_parent(dev);
+ else if (parent->class)
+ return &parent->kobj;
+ else
+ parent_kobj = &parent->kobj;
+
+ /* find our class-directory at the parent and reference it */
+ spin_lock(&dev->class->class_dirs.list_lock);
+ list_for_each_entry(k, &dev->class->class_dirs.list, entry)
+ if (k->parent == parent_kobj) {
+ kobj = kobject_get(k);
+ break;
+ }
+ spin_unlock(&dev->class->class_dirs.list_lock);
+ if (kobj)
+ return kobj;
+
+ /* or create a new class-directory at the parent device */
+ return kobject_kset_add_dir(&dev->class->class_dirs,
+ parent_kobj, dev->class->name);
+ }
+
+ if (parent)