diff options
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 282025770429..fb4bc4f5151c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -607,6 +607,7 @@ static struct kobject *get_device_parent(struct device *dev, | |||
607 | int retval; | 607 | int retval; |
608 | 608 | ||
609 | if (dev->class) { | 609 | if (dev->class) { |
610 | static DEFINE_MUTEX(gdp_mutex); | ||
610 | struct kobject *kobj = NULL; | 611 | struct kobject *kobj = NULL; |
611 | struct kobject *parent_kobj; | 612 | struct kobject *parent_kobj; |
612 | struct kobject *k; | 613 | struct kobject *k; |
@@ -623,6 +624,8 @@ static struct kobject *get_device_parent(struct device *dev, | |||
623 | else | 624 | else |
624 | parent_kobj = &parent->kobj; | 625 | parent_kobj = &parent->kobj; |
625 | 626 | ||
627 | mutex_lock(&gdp_mutex); | ||
628 | |||
626 | /* find our class-directory at the parent and reference it */ | 629 | /* find our class-directory at the parent and reference it */ |
627 | spin_lock(&dev->class->p->class_dirs.list_lock); | 630 | spin_lock(&dev->class->p->class_dirs.list_lock); |
628 | list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) | 631 | 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, | |||
631 | break; | 634 | break; |
632 | } | 635 | } |
633 | spin_unlock(&dev->class->p->class_dirs.list_lock); | 636 | spin_unlock(&dev->class->p->class_dirs.list_lock); |
634 | if (kobj) | 637 | if (kobj) { |
638 | mutex_unlock(&gdp_mutex); | ||
635 | return kobj; | 639 | return kobj; |
640 | } | ||
636 | 641 | ||
637 | /* or create a new class-directory at the parent device */ | 642 | /* or create a new class-directory at the parent device */ |
638 | k = kobject_create(); | 643 | k = kobject_create(); |
639 | if (!k) | 644 | if (!k) { |
645 | mutex_unlock(&gdp_mutex); | ||
640 | return NULL; | 646 | return NULL; |
647 | } | ||
641 | k->kset = &dev->class->p->class_dirs; | 648 | k->kset = &dev->class->p->class_dirs; |
642 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); | 649 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); |
643 | if (retval < 0) { | 650 | if (retval < 0) { |
651 | mutex_unlock(&gdp_mutex); | ||
644 | kobject_put(k); | 652 | kobject_put(k); |
645 | return NULL; | 653 | return NULL; |
646 | } | 654 | } |
647 | /* do not emit an uevent for this simple "glue" directory */ | 655 | /* do not emit an uevent for this simple "glue" directory */ |
656 | mutex_unlock(&gdp_mutex); | ||
648 | return k; | 657 | return k; |
649 | } | 658 | } |
650 | 659 | ||