|
@@ -600,3 +600,95 @@ printk("Original value=%d\n",val);
|
|
|
return val;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate);
|
|
|
+
|
|
|
+static LIST_HEAD(tm6000_devlist);
|
|
|
+static DEFINE_MUTEX(tm6000_devlist_mutex);
|
|
|
+
|
|
|
+/*
|
|
|
+ * tm6000_realease_resource()
|
|
|
+ */
|
|
|
+
|
|
|
+void tm6000_remove_from_devlist(struct tm6000_core *dev)
|
|
|
+{
|
|
|
+ mutex_lock(&tm6000_devlist_mutex);
|
|
|
+ list_del(&dev->devlist);
|
|
|
+ mutex_unlock(&tm6000_devlist_mutex);
|
|
|
+};
|
|
|
+
|
|
|
+void tm6000_add_into_devlist(struct tm6000_core *dev)
|
|
|
+{
|
|
|
+ mutex_lock(&tm6000_devlist_mutex);
|
|
|
+ list_add_tail(&dev->devlist, &tm6000_devlist);
|
|
|
+ mutex_unlock(&tm6000_devlist_mutex);
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * Extension interface
|
|
|
+ */
|
|
|
+
|
|
|
+static LIST_HEAD(tm6000_extension_devlist);
|
|
|
+static DEFINE_MUTEX(tm6000_extension_devlist_lock);
|
|
|
+
|
|
|
+int tm6000_register_extension(struct tm6000_ops *ops)
|
|
|
+{
|
|
|
+ struct tm6000_core *dev = NULL;
|
|
|
+
|
|
|
+ mutex_lock(&tm6000_devlist_mutex);
|
|
|
+ mutex_lock(&tm6000_extension_devlist_lock);
|
|
|
+ list_add_tail(&ops->next, &tm6000_extension_devlist);
|
|
|
+ list_for_each_entry(dev, &tm6000_devlist, devlist) {
|
|
|
+ if (dev)
|
|
|
+ ops->init(dev);
|
|
|
+ }
|
|
|
+ printk(KERN_INFO "tm6000: Initialized (%s) extension\n", ops->name);
|
|
|
+ mutex_unlock(&tm6000_extension_devlist_lock);
|
|
|
+ mutex_unlock(&tm6000_devlist_mutex);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(tm6000_register_extension);
|
|
|
+
|
|
|
+void tm6000_unregister_extension(struct tm6000_ops *ops)
|
|
|
+{
|
|
|
+ struct tm6000_core *dev = NULL;
|
|
|
+
|
|
|
+ mutex_lock(&tm6000_devlist_mutex);
|
|
|
+ list_for_each_entry(dev, &tm6000_devlist, devlist) {
|
|
|
+ if (dev)
|
|
|
+ ops->fini(dev);
|
|
|
+ }
|
|
|
+
|
|
|
+ mutex_lock(&tm6000_extension_devlist_lock);
|
|
|
+ printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name);
|
|
|
+ list_del(&ops->next);
|
|
|
+ mutex_unlock(&tm6000_extension_devlist_lock);
|
|
|
+ mutex_unlock(&tm6000_devlist_mutex);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(tm6000_unregister_extension);
|
|
|
+
|
|
|
+void tm6000_init_extension(struct tm6000_core *dev)
|
|
|
+{
|
|
|
+ struct tm6000_ops *ops = NULL;
|
|
|
+
|
|
|
+ mutex_lock(&tm6000_extension_devlist_lock);
|
|
|
+ if (!list_empty(&tm6000_extension_devlist)) {
|
|
|
+ list_for_each_entry(ops, &tm6000_extension_devlist, next) {
|
|
|
+ if (ops->init)
|
|
|
+ ops->init(dev);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mutex_unlock(&tm6000_extension_devlist_lock);
|
|
|
+}
|
|
|
+
|
|
|
+void tm6000_close_extension(struct tm6000_core *dev)
|
|
|
+{
|
|
|
+ struct tm6000_ops *ops = NULL;
|
|
|
+
|
|
|
+ mutex_lock(&tm6000_extension_devlist_lock);
|
|
|
+ if (!list_empty(&tm6000_extension_devlist)) {
|
|
|
+ list_for_each_entry(ops, &tm6000_extension_devlist, next) {
|
|
|
+ if (ops->fini)
|
|
|
+ ops->fini(dev);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mutex_unlock(&tm6000_extension_devlist_lock);
|
|
|
+}
|