aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/base.h4
-rw-r--r--drivers/base/class.c23
-rw-r--r--drivers/base/core.c9
3 files changed, 19 insertions, 17 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h
index c035dc23266a..31dc0cd84afa 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -44,7 +44,7 @@ struct driver_private {
44 * @class_devices - list of devices associated with this class 44 * @class_devices - list of devices associated with this class
45 * @class_interfaces - list of class_interfaces associated with this class 45 * @class_interfaces - list of class_interfaces associated with this class
46 * @class_dirs - "glue" directory for virtual devices associated with this class 46 * @class_dirs - "glue" directory for virtual devices associated with this class
47 * @class_sem - semaphore to protect the children, devices, and interfaces lists. 47 * @class_mutex - mutex to protect the children, devices, and interfaces lists.
48 * @class - pointer back to the struct class that this structure is associated 48 * @class - pointer back to the struct class that this structure is associated
49 * with. 49 * with.
50 * 50 *
@@ -57,7 +57,7 @@ struct class_private {
57 struct list_head class_devices; 57 struct list_head class_devices;
58 struct list_head class_interfaces; 58 struct list_head class_interfaces;
59 struct kset class_dirs; 59 struct kset class_dirs;
60 struct semaphore class_sem; 60 struct mutex class_mutex;
61 struct class *class; 61 struct class *class;
62}; 62};
63#define to_class(obj) \ 63#define to_class(obj) \
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 89000566690c..839d27cecb36 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -18,6 +18,7 @@
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/genhd.h> 20#include <linux/genhd.h>
21#include <linux/mutex.h>
21#include "base.h" 22#include "base.h"
22 23
23#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) 24#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
@@ -147,7 +148,7 @@ int __class_register(struct class *cls, struct lock_class_key *key)
147 INIT_LIST_HEAD(&cp->class_devices); 148 INIT_LIST_HEAD(&cp->class_devices);
148 INIT_LIST_HEAD(&cp->class_interfaces); 149 INIT_LIST_HEAD(&cp->class_interfaces);
149 kset_init(&cp->class_dirs); 150 kset_init(&cp->class_dirs);
150 init_MUTEX(&cp->class_sem); 151 __mutex_init(&cp->class_mutex, "struct class mutex", key);
151 error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name); 152 error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name);
152 if (error) { 153 if (error) {
153 kfree(cp); 154 kfree(cp);
@@ -281,7 +282,7 @@ char *make_class_name(const char *name, struct kobject *kobj)
281 * We check the return of @fn each time. If it returns anything 282 * We check the return of @fn each time. If it returns anything
282 * other than 0, we break out and return that value. 283 * other than 0, we break out and return that value.
283 * 284 *
284 * Note, we hold class->class_sem in this function, so it can not be 285 * Note, we hold class->class_mutex in this function, so it can not be
285 * re-acquired in @fn, otherwise it will self-deadlocking. For 286 * re-acquired in @fn, otherwise it will self-deadlocking. For
286 * example, calls to add or remove class members would be verboten. 287 * example, calls to add or remove class members would be verboten.
287 */ 288 */
@@ -293,7 +294,7 @@ int class_for_each_device(struct class *class, struct device *start,
293 294
294 if (!class) 295 if (!class)
295 return -EINVAL; 296 return -EINVAL;
296 down(&class->p->class_sem); 297 mutex_lock(&class->p->class_mutex);
297 list_for_each_entry(dev, &class->p->class_devices, node) { 298 list_for_each_entry(dev, &class->p->class_devices, node) {
298 if (start) { 299 if (start) {
299 if (start == dev) 300 if (start == dev)
@@ -306,7 +307,7 @@ int class_for_each_device(struct class *class, struct device *start,
306 if (error) 307 if (error)
307 break; 308 break;
308 } 309 }
309 up(&class->p->class_sem); 310 mutex_unlock(&class->p->class_mutex);
310 311
311 return error; 312 return error;
312} 313}
@@ -329,7 +330,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device);
329 * 330 *
330 * Note, you will need to drop the reference with put_device() after use. 331 * Note, you will need to drop the reference with put_device() after use.
331 * 332 *
332 * We hold class->class_sem in this function, so it can not be 333 * We hold class->class_mutex in this function, so it can not be
333 * re-acquired in @match, otherwise it will self-deadlocking. For 334 * re-acquired in @match, otherwise it will self-deadlocking. For
334 * example, calls to add or remove class members would be verboten. 335 * example, calls to add or remove class members would be verboten.
335 */ 336 */
@@ -343,7 +344,7 @@ struct device *class_find_device(struct class *class, struct device *start,
343 if (!class) 344 if (!class)
344 return NULL; 345 return NULL;
345 346
346 down(&class->p->class_sem); 347 mutex_lock(&class->p->class_mutex);
347 list_for_each_entry(dev, &class->p->class_devices, node) { 348 list_for_each_entry(dev, &class->p->class_devices, node) {
348 if (start) { 349 if (start) {
349 if (start == dev) 350 if (start == dev)
@@ -357,7 +358,7 @@ struct device *class_find_device(struct class *class, struct device *start,
357 } else 358 } else
358 put_device(dev); 359 put_device(dev);
359 } 360 }
360 up(&class->p->class_sem); 361 mutex_unlock(&class->p->class_mutex);
361 362
362 return found ? dev : NULL; 363 return found ? dev : NULL;
363} 364}
@@ -375,13 +376,13 @@ int class_interface_register(struct class_interface *class_intf)
375 if (!parent) 376 if (!parent)
376 return -EINVAL; 377 return -EINVAL;
377 378
378 down(&parent->p->class_sem); 379 mutex_lock(&parent->p->class_mutex);
379 list_add_tail(&class_intf->node, &parent->p->class_interfaces); 380 list_add_tail(&class_intf->node, &parent->p->class_interfaces);
380 if (class_intf->add_dev) { 381 if (class_intf->add_dev) {
381 list_for_each_entry(dev, &parent->p->class_devices, node) 382 list_for_each_entry(dev, &parent->p->class_devices, node)
382 class_intf->add_dev(dev, class_intf); 383 class_intf->add_dev(dev, class_intf);
383 } 384 }
384 up(&parent->p->class_sem); 385 mutex_unlock(&parent->p->class_mutex);
385 386
386 return 0; 387 return 0;
387} 388}
@@ -394,13 +395,13 @@ void class_interface_unregister(struct class_interface *class_intf)
394 if (!parent) 395 if (!parent)
395 return; 396 return;
396 397
397 down(&parent->p->class_sem); 398 mutex_lock(&parent->p->class_mutex);
398 list_del_init(&class_intf->node); 399 list_del_init(&class_intf->node);
399 if (class_intf->remove_dev) { 400 if (class_intf->remove_dev) {
400 list_for_each_entry(dev, &parent->p->class_devices, node) 401 list_for_each_entry(dev, &parent->p->class_devices, node)
401 class_intf->remove_dev(dev, class_intf); 402 class_intf->remove_dev(dev, class_intf);
402 } 403 }
403 up(&parent->p->class_sem); 404 mutex_unlock(&parent->p->class_mutex);
404 405
405 class_put(parent); 406 class_put(parent);
406} 407}
diff --git a/drivers/base/core.c b/drivers/base/core.c
index b90ae6f7be86..c05b1159023e 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -21,6 +21,7 @@
21#include <linux/genhd.h> 21#include <linux/genhd.h>
22#include <linux/kallsyms.h> 22#include <linux/kallsyms.h>
23#include <linux/semaphore.h> 23#include <linux/semaphore.h>
24#include <linux/mutex.h>
24 25
25#include "base.h" 26#include "base.h"
26#include "power/power.h" 27#include "power/power.h"
@@ -907,7 +908,7 @@ int device_add(struct device *dev)
907 klist_add_tail(&dev->knode_parent, &parent->klist_children); 908 klist_add_tail(&dev->knode_parent, &parent->klist_children);
908 909
909 if (dev->class) { 910 if (dev->class) {
910 down(&dev->class->p->class_sem); 911 mutex_lock(&dev->class->p->class_mutex);
911 /* tie the class to the device */ 912 /* tie the class to the device */
912 list_add_tail(&dev->node, &dev->class->p->class_devices); 913 list_add_tail(&dev->node, &dev->class->p->class_devices);
913 914
@@ -916,7 +917,7 @@ int device_add(struct device *dev)
916 &dev->class->p->class_interfaces, node) 917 &dev->class->p->class_interfaces, node)
917 if (class_intf->add_dev) 918 if (class_intf->add_dev)
918 class_intf->add_dev(dev, class_intf); 919 class_intf->add_dev(dev, class_intf);
919 up(&dev->class->p->class_sem); 920 mutex_unlock(&dev->class->p->class_mutex);
920 } 921 }
921 Done: 922 Done:
922 put_device(dev); 923 put_device(dev);
@@ -1017,7 +1018,7 @@ void device_del(struct device *dev)
1017 if (dev->class) { 1018 if (dev->class) {
1018 device_remove_class_symlinks(dev); 1019 device_remove_class_symlinks(dev);
1019 1020
1020 down(&dev->class->p->class_sem); 1021 mutex_lock(&dev->class->p->class_mutex);
1021 /* notify any interfaces that the device is now gone */ 1022 /* notify any interfaces that the device is now gone */
1022 list_for_each_entry(class_intf, 1023 list_for_each_entry(class_intf,
1023 &dev->class->p->class_interfaces, node) 1024 &dev->class->p->class_interfaces, node)
@@ -1025,7 +1026,7 @@ void device_del(struct device *dev)
1025 class_intf->remove_dev(dev, class_intf); 1026 class_intf->remove_dev(dev, class_intf);
1026 /* remove the device from the class list */ 1027 /* remove the device from the class list */
1027 list_del_init(&dev->node); 1028 list_del_init(&dev->node);
1028 up(&dev->class->p->class_sem); 1029 mutex_unlock(&dev->class->p->class_mutex);
1029 } 1030 }
1030 device_remove_file(dev, &uevent_attr); 1031 device_remove_file(dev, &uevent_attr);
1031 device_remove_attrs(dev); 1032 device_remove_attrs(dev);