|
@@ -607,6 +607,7 @@ static struct kobject *get_device_parent(struct device *dev,
|
|
|
int retval;
|
|
|
|
|
|
if (dev->class) {
|
|
|
+ static DEFINE_MUTEX(gdp_mutex);
|
|
|
struct kobject *kobj = NULL;
|
|
|
struct kobject *parent_kobj;
|
|
|
struct kobject *k;
|
|
@@ -623,6 +624,8 @@ static struct kobject *get_device_parent(struct device *dev,
|
|
|
else
|
|
|
parent_kobj = &parent->kobj;
|
|
|
|
|
|
+ mutex_lock(&gdp_mutex);
|
|
|
+
|
|
|
/* find our class-directory at the parent and reference it */
|
|
|
spin_lock(&dev->class->p->class_dirs.list_lock);
|
|
|
list_for_each_entry(k, &dev->class->p->class_dirs.list, entry)
|
|
@@ -631,20 +634,26 @@ static struct kobject *get_device_parent(struct device *dev,
|
|
|
break;
|
|
|
}
|
|
|
spin_unlock(&dev->class->p->class_dirs.list_lock);
|
|
|
- if (kobj)
|
|
|
+ if (kobj) {
|
|
|
+ mutex_unlock(&gdp_mutex);
|
|
|
return kobj;
|
|
|
+ }
|
|
|
|
|
|
/* or create a new class-directory at the parent device */
|
|
|
k = kobject_create();
|
|
|
- if (!k)
|
|
|
+ if (!k) {
|
|
|
+ mutex_unlock(&gdp_mutex);
|
|
|
return NULL;
|
|
|
+ }
|
|
|
k->kset = &dev->class->p->class_dirs;
|
|
|
retval = kobject_add(k, parent_kobj, "%s", dev->class->name);
|
|
|
if (retval < 0) {
|
|
|
+ mutex_unlock(&gdp_mutex);
|
|
|
kobject_put(k);
|
|
|
return NULL;
|
|
|
}
|
|
|
/* do not emit an uevent for this simple "glue" directory */
|
|
|
+ mutex_unlock(&gdp_mutex);
|
|
|
return k;
|
|
|
}
|
|
|
|