diff options
-rw-r--r-- | drivers/base/base.h | 4 | ||||
-rw-r--r-- | drivers/base/class.c | 23 | ||||
-rw-r--r-- | drivers/base/core.c | 9 |
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); |