summaryrefslogtreecommitdiff
path: root/drivers/staging/greybus/audio_manager.c
diff options
context:
space:
mode:
authorVaibhav Agarwal <vaibhav.agarwal@linaro.org>2016-05-04 16:29:19 +0530
committerGreg Kroah-Hartman <gregkh@google.com>2016-05-04 11:29:06 -0700
commit84e0e38744c5d814650e4acec34cea585d04cc96 (patch)
treec54736fce14c86d2cec6153e864d8434e39cd1c0 /drivers/staging/greybus/audio_manager.c
parent7557d0481bdeed86780c073e591df0330ec88a9e (diff)
greybus: audio:gb_manager: Use proper locking around kobject_xxx
read/write_lock_irqsave mechanism was used to protect modules list & kobject_xxx() in gb_audio_manager. Since kobject_xxx calls can sleep spin_lock variants can't be used there. So use rw_sem for protecting modules_list. Signed-off-by: Vaibhav Agarwal <vaibhav.agarwal@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/audio_manager.c')
-rw-r--r--drivers/staging/greybus/audio_manager.c37
1 files changed, 15 insertions, 22 deletions
diff --git a/drivers/staging/greybus/audio_manager.c b/drivers/staging/greybus/audio_manager.c
index bc5be4907c81..619bdee46ee5 100644
--- a/drivers/staging/greybus/audio_manager.c
+++ b/drivers/staging/greybus/audio_manager.c
@@ -19,7 +19,7 @@
static struct kset *manager_kset;
static LIST_HEAD(modules_list);
-static DEFINE_RWLOCK(modules_lock);
+static DECLARE_RWSEM(modules_rwsem);
static DEFINE_IDA(module_id);
/* helpers */
@@ -42,7 +42,6 @@ static struct gb_audio_manager_module *gb_audio_manager_get_locked(int id)
int gb_audio_manager_add(struct gb_audio_manager_module_descriptor *desc)
{
struct gb_audio_manager_module *module;
- unsigned long flags;
int id;
int err;
@@ -55,9 +54,9 @@ int gb_audio_manager_add(struct gb_audio_manager_module_descriptor *desc)
}
/* Add it to the list */
- write_lock_irqsave(&modules_lock, flags);
+ down_write(&modules_rwsem);
list_add_tail(&module->list, &modules_list);
- write_unlock_irqrestore(&modules_lock, flags);
+ up_write(&modules_rwsem);
return module->id;
}
@@ -66,20 +65,18 @@ EXPORT_SYMBOL_GPL(gb_audio_manager_add);
int gb_audio_manager_remove(int id)
{
struct gb_audio_manager_module *module;
- unsigned long flags;
- write_lock_irqsave(&modules_lock, flags);
+ down_write(&modules_rwsem);
module = gb_audio_manager_get_locked(id);
if (!module) {
- write_unlock_irqrestore(&modules_lock, flags);
+ up_write(&modules_rwsem);
return -EINVAL;
}
-
- ida_simple_remove(&module_id, module->id);
list_del(&module->list);
kobject_put(&module->kobj);
- write_unlock_irqrestore(&modules_lock, flags);
+ up_write(&modules_rwsem);
+ ida_simple_remove(&module_id, module->id);
return 0;
}
EXPORT_SYMBOL_GPL(gb_audio_manager_remove);
@@ -88,9 +85,8 @@ void gb_audio_manager_remove_all(void)
{
struct gb_audio_manager_module *module, *next;
int is_empty = 1;
- unsigned long flags;
- write_lock_irqsave(&modules_lock, flags);
+ down_write(&modules_rwsem);
list_for_each_entry_safe(module, next, &modules_list, list) {
list_del(&module->list);
@@ -99,7 +95,7 @@ void gb_audio_manager_remove_all(void)
is_empty = list_empty(&modules_list);
- write_unlock_irqrestore(&modules_lock, flags);
+ up_write(&modules_rwsem);
if (!is_empty)
pr_warn("Not all nodes were deleted\n");
@@ -109,12 +105,11 @@ EXPORT_SYMBOL_GPL(gb_audio_manager_remove_all);
struct gb_audio_manager_module *gb_audio_manager_get_module(int id)
{
struct gb_audio_manager_module *module;
- unsigned long flags;
- read_lock_irqsave(&modules_lock, flags);
+ down_read(&modules_rwsem);
module = gb_audio_manager_get_locked(id);
kobject_get(&module->kobj);
- read_unlock_irqrestore(&modules_lock, flags);
+ up_read(&modules_rwsem);
return module;
}
EXPORT_SYMBOL_GPL(gb_audio_manager_get_module);
@@ -128,11 +123,10 @@ EXPORT_SYMBOL_GPL(gb_audio_manager_put_module);
int gb_audio_manager_dump_module(int id)
{
struct gb_audio_manager_module *module;
- unsigned long flags;
- read_lock_irqsave(&modules_lock, flags);
+ down_read(&modules_rwsem);
module = gb_audio_manager_get_locked(id);
- read_unlock_irqrestore(&modules_lock, flags);
+ up_read(&modules_rwsem);
if (!module)
return -EINVAL;
@@ -146,14 +140,13 @@ void gb_audio_manager_dump_all(void)
{
struct gb_audio_manager_module *module;
int count = 0;
- unsigned long flags;
- read_lock_irqsave(&modules_lock, flags);
+ down_read(&modules_rwsem);
list_for_each_entry(module, &modules_list, list) {
gb_audio_manager_module_dump(module);
count++;
}
- read_unlock_irqrestore(&modules_lock, flags);
+ up_read(&modules_rwsem);
pr_info("Number of connected modules: %d\n", count);
}