4 * Copyright 2015-2016 Google Inc.
6 * Released under the GPLv2 only.
9 #include <linux/string.h>
10 #include <linux/sysfs.h>
11 #include <linux/module.h>
12 #include <linux/init.h>
13 #include <linux/rwlock.h>
15 #include "audio_manager.h"
16 #include "audio_manager_private.h"
18 static struct kset *manager_kset;
20 static LIST_HEAD(modules_list);
21 static DEFINE_RWLOCK(modules_lock);
23 static int current_module_id;
26 static struct gb_audio_manager_module *gb_audio_manager_get_locked(int id)
28 struct gb_audio_manager_module *module;
33 list_for_each_entry(module, &modules_list, list) {
42 int gb_audio_manager_add(struct gb_audio_manager_module_descriptor *desc)
44 struct gb_audio_manager_module *module;
48 err = gb_audio_manager_module_create(&module, manager_kset,
49 current_module_id++, desc);
53 /* Add it to the list */
54 write_lock_irqsave(&modules_lock, flags);
55 list_add_tail(&module->list, &modules_list);
56 write_unlock_irqrestore(&modules_lock, flags);
60 EXPORT_SYMBOL_GPL(gb_audio_manager_add);
62 int gb_audio_manager_remove(int id)
64 struct gb_audio_manager_module *module;
67 write_lock_irqsave(&modules_lock, flags);
69 module = gb_audio_manager_get_locked(id);
71 write_unlock_irqrestore(&modules_lock, flags);
75 list_del(&module->list);
76 kobject_put(&module->kobj);
77 write_unlock_irqrestore(&modules_lock, flags);
80 EXPORT_SYMBOL_GPL(gb_audio_manager_remove);
82 void gb_audio_manager_remove_all(void)
84 struct gb_audio_manager_module *module, *next;
88 write_lock_irqsave(&modules_lock, flags);
90 list_for_each_entry_safe(module, next, &modules_list, list) {
91 list_del(&module->list);
92 kobject_put(&module->kobj);
95 is_empty = list_empty(&modules_list);
97 write_unlock_irqrestore(&modules_lock, flags);
100 pr_warn("Not all nodes were deleted\n");
102 EXPORT_SYMBOL_GPL(gb_audio_manager_remove_all);
104 struct gb_audio_manager_module *gb_audio_manager_get_module(int id)
106 struct gb_audio_manager_module *module;
109 read_lock_irqsave(&modules_lock, flags);
110 module = gb_audio_manager_get_locked(id);
111 kobject_get(&module->kobj);
112 read_unlock_irqrestore(&modules_lock, flags);
115 EXPORT_SYMBOL_GPL(gb_audio_manager_get_module);
117 void gb_audio_manager_put_module(struct gb_audio_manager_module *module)
119 kobject_put(&module->kobj);
121 EXPORT_SYMBOL_GPL(gb_audio_manager_put_module);
123 int gb_audio_manager_dump_module(int id)
125 struct gb_audio_manager_module *module;
128 read_lock_irqsave(&modules_lock, flags);
129 module = gb_audio_manager_get_locked(id);
130 read_unlock_irqrestore(&modules_lock, flags);
135 gb_audio_manager_module_dump(module);
138 EXPORT_SYMBOL_GPL(gb_audio_manager_dump_module);
140 void gb_audio_manager_dump_all(void)
142 struct gb_audio_manager_module *module;
146 read_lock_irqsave(&modules_lock, flags);
147 list_for_each_entry(module, &modules_list, list) {
148 gb_audio_manager_module_dump(module);
151 read_unlock_irqrestore(&modules_lock, flags);
153 pr_info("Number of connected modules: %d\n", count);
155 EXPORT_SYMBOL_GPL(gb_audio_manager_dump_all);
160 static int __init manager_init(void)
162 manager_kset = kset_create_and_add(GB_AUDIO_MANAGER_NAME, NULL,
167 #ifdef GB_AUDIO_MANAGER_SYSFS
168 gb_audio_manager_sysfs_init(&manager_kset->kobj);
174 static void __exit manager_exit(void)
176 gb_audio_manager_remove_all();
177 kset_unregister(manager_kset);
180 module_init(manager_init);
181 module_exit(manager_exit);
183 MODULE_LICENSE("GPL");
184 MODULE_AUTHOR("Svetlin Ankov <ankov_svetlin@projectara.com>");