cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

audio_manager.c (3893B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Greybus operations
      4 *
      5 * Copyright 2015-2016 Google Inc.
      6 */
      7
      8#include <linux/string.h>
      9#include <linux/sysfs.h>
     10#include <linux/module.h>
     11#include <linux/init.h>
     12#include <linux/spinlock.h>
     13#include <linux/idr.h>
     14
     15#include "audio_manager.h"
     16#include "audio_manager_private.h"
     17
     18static struct kset *manager_kset;
     19
     20static LIST_HEAD(modules_list);
     21static DECLARE_RWSEM(modules_rwsem);
     22static DEFINE_IDA(module_id);
     23
     24/* helpers */
     25static struct gb_audio_manager_module *gb_audio_manager_get_locked(int id)
     26{
     27	struct gb_audio_manager_module *module;
     28
     29	if (id < 0)
     30		return NULL;
     31
     32	list_for_each_entry(module, &modules_list, list) {
     33		if (module->id == id)
     34			return module;
     35	}
     36
     37	return NULL;
     38}
     39
     40/* public API */
     41int gb_audio_manager_add(struct gb_audio_manager_module_descriptor *desc)
     42{
     43	struct gb_audio_manager_module *module;
     44	int id;
     45	int err;
     46
     47	id = ida_simple_get(&module_id, 0, 0, GFP_KERNEL);
     48	if (id < 0)
     49		return id;
     50
     51	err = gb_audio_manager_module_create(&module, manager_kset,
     52					     id, desc);
     53	if (err) {
     54		ida_simple_remove(&module_id, id);
     55		return err;
     56	}
     57
     58	/* Add it to the list */
     59	down_write(&modules_rwsem);
     60	list_add_tail(&module->list, &modules_list);
     61	up_write(&modules_rwsem);
     62
     63	return module->id;
     64}
     65EXPORT_SYMBOL_GPL(gb_audio_manager_add);
     66
     67int gb_audio_manager_remove(int id)
     68{
     69	struct gb_audio_manager_module *module;
     70
     71	down_write(&modules_rwsem);
     72
     73	module = gb_audio_manager_get_locked(id);
     74	if (!module) {
     75		up_write(&modules_rwsem);
     76		return -EINVAL;
     77	}
     78	list_del(&module->list);
     79	kobject_put(&module->kobj);
     80	up_write(&modules_rwsem);
     81	ida_simple_remove(&module_id, id);
     82	return 0;
     83}
     84EXPORT_SYMBOL_GPL(gb_audio_manager_remove);
     85
     86void gb_audio_manager_remove_all(void)
     87{
     88	struct gb_audio_manager_module *module, *next;
     89	int is_empty;
     90
     91	down_write(&modules_rwsem);
     92
     93	list_for_each_entry_safe(module, next, &modules_list, list) {
     94		list_del(&module->list);
     95		ida_simple_remove(&module_id, module->id);
     96		kobject_put(&module->kobj);
     97	}
     98
     99	is_empty = list_empty(&modules_list);
    100
    101	up_write(&modules_rwsem);
    102
    103	if (!is_empty)
    104		pr_warn("Not all nodes were deleted\n");
    105}
    106EXPORT_SYMBOL_GPL(gb_audio_manager_remove_all);
    107
    108struct gb_audio_manager_module *gb_audio_manager_get_module(int id)
    109{
    110	struct gb_audio_manager_module *module;
    111
    112	down_read(&modules_rwsem);
    113	module = gb_audio_manager_get_locked(id);
    114	kobject_get(&module->kobj);
    115	up_read(&modules_rwsem);
    116	return module;
    117}
    118EXPORT_SYMBOL_GPL(gb_audio_manager_get_module);
    119
    120void gb_audio_manager_put_module(struct gb_audio_manager_module *module)
    121{
    122	kobject_put(&module->kobj);
    123}
    124EXPORT_SYMBOL_GPL(gb_audio_manager_put_module);
    125
    126int gb_audio_manager_dump_module(int id)
    127{
    128	struct gb_audio_manager_module *module;
    129
    130	down_read(&modules_rwsem);
    131	module = gb_audio_manager_get_locked(id);
    132	up_read(&modules_rwsem);
    133
    134	if (!module)
    135		return -EINVAL;
    136
    137	gb_audio_manager_module_dump(module);
    138	return 0;
    139}
    140EXPORT_SYMBOL_GPL(gb_audio_manager_dump_module);
    141
    142void gb_audio_manager_dump_all(void)
    143{
    144	struct gb_audio_manager_module *module;
    145	int count = 0;
    146
    147	down_read(&modules_rwsem);
    148	list_for_each_entry(module, &modules_list, list) {
    149		gb_audio_manager_module_dump(module);
    150		count++;
    151	}
    152	up_read(&modules_rwsem);
    153
    154	pr_info("Number of connected modules: %d\n", count);
    155}
    156EXPORT_SYMBOL_GPL(gb_audio_manager_dump_all);
    157
    158/*
    159 * module init/deinit
    160 */
    161static int __init manager_init(void)
    162{
    163	manager_kset = kset_create_and_add(GB_AUDIO_MANAGER_NAME, NULL,
    164					   kernel_kobj);
    165	if (!manager_kset)
    166		return -ENOMEM;
    167
    168#ifdef GB_AUDIO_MANAGER_SYSFS
    169	gb_audio_manager_sysfs_init(&manager_kset->kobj);
    170#endif
    171
    172	return 0;
    173}
    174
    175static void __exit manager_exit(void)
    176{
    177	gb_audio_manager_remove_all();
    178	kset_unregister(manager_kset);
    179	ida_destroy(&module_id);
    180}
    181
    182module_init(manager_init);
    183module_exit(manager_exit);
    184
    185MODULE_LICENSE("GPL");
    186MODULE_AUTHOR("Svetlin Ankov <ankov_svetlin@projectara.com>");