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

core.c (3389B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Apple Onboard Audio driver core
      4 *
      5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
      6 */
      7
      8#include <linux/init.h>
      9#include <linux/module.h>
     10#include <linux/list.h>
     11#include "../aoa.h"
     12#include "alsa.h"
     13
     14MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
     15MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
     16MODULE_LICENSE("GPL");
     17
     18/* We allow only one fabric. This simplifies things,
     19 * and more don't really make that much sense */
     20static struct aoa_fabric *fabric;
     21static LIST_HEAD(codec_list);
     22
     23static int attach_codec_to_fabric(struct aoa_codec *c)
     24{
     25	int err;
     26
     27	if (!try_module_get(c->owner))
     28		return -EBUSY;
     29	/* found_codec has to be assigned */
     30	err = -ENOENT;
     31	if (fabric->found_codec)
     32		err = fabric->found_codec(c);
     33	if (err) {
     34		module_put(c->owner);
     35		printk(KERN_ERR "snd-aoa: fabric didn't like codec %s\n",
     36				c->name);
     37		return err;
     38	}
     39	c->fabric = fabric;
     40
     41	err = 0;
     42	if (c->init)
     43		err = c->init(c);
     44	if (err) {
     45		printk(KERN_ERR "snd-aoa: codec %s didn't init\n", c->name);
     46		c->fabric = NULL;
     47		if (fabric->remove_codec)
     48			fabric->remove_codec(c);
     49		module_put(c->owner);
     50		return err;
     51	}
     52	if (fabric->attached_codec)
     53		fabric->attached_codec(c);
     54	return 0;
     55}
     56
     57int aoa_codec_register(struct aoa_codec *codec)
     58{
     59	int err = 0;
     60
     61	/* if there's a fabric already, we can tell if we
     62	 * will want to have this codec, so propagate error
     63	 * through. Otherwise, this will happen later... */
     64	if (fabric)
     65		err = attach_codec_to_fabric(codec);
     66	if (!err)
     67		list_add(&codec->list, &codec_list);
     68	return err;
     69}
     70EXPORT_SYMBOL_GPL(aoa_codec_register);
     71
     72void aoa_codec_unregister(struct aoa_codec *codec)
     73{
     74	list_del(&codec->list);
     75	if (codec->fabric && codec->exit)
     76		codec->exit(codec);
     77	if (fabric && fabric->remove_codec)
     78		fabric->remove_codec(codec);
     79	codec->fabric = NULL;
     80	module_put(codec->owner);
     81}
     82EXPORT_SYMBOL_GPL(aoa_codec_unregister);
     83
     84int aoa_fabric_register(struct aoa_fabric *new_fabric, struct device *dev)
     85{
     86	struct aoa_codec *c;
     87	int err;
     88
     89	/* allow querying for presence of fabric
     90	 * (i.e. do this test first!) */
     91	if (new_fabric == fabric) {
     92		err = -EALREADY;
     93		goto attach;
     94	}
     95	if (fabric)
     96		return -EEXIST;
     97	if (!new_fabric)
     98		return -EINVAL;
     99
    100	err = aoa_alsa_init(new_fabric->name, new_fabric->owner, dev);
    101	if (err)
    102		return err;
    103
    104	fabric = new_fabric;
    105
    106 attach:
    107	list_for_each_entry(c, &codec_list, list) {
    108		if (c->fabric != fabric)
    109			attach_codec_to_fabric(c);
    110	}
    111	return err;
    112}
    113EXPORT_SYMBOL_GPL(aoa_fabric_register);
    114
    115void aoa_fabric_unregister(struct aoa_fabric *old_fabric)
    116{
    117	struct aoa_codec *c;
    118
    119	if (fabric != old_fabric)
    120		return;
    121
    122	list_for_each_entry(c, &codec_list, list) {
    123		if (c->fabric)
    124			aoa_fabric_unlink_codec(c);
    125	}
    126
    127	aoa_alsa_cleanup();
    128
    129	fabric = NULL;
    130}
    131EXPORT_SYMBOL_GPL(aoa_fabric_unregister);
    132
    133void aoa_fabric_unlink_codec(struct aoa_codec *codec)
    134{
    135	if (!codec->fabric) {
    136		printk(KERN_ERR "snd-aoa: fabric unassigned "
    137				"in aoa_fabric_unlink_codec\n");
    138		dump_stack();
    139		return;
    140	}
    141	if (codec->exit)
    142		codec->exit(codec);
    143	if (codec->fabric->remove_codec)
    144		codec->fabric->remove_codec(codec);
    145	codec->fabric = NULL;
    146	module_put(codec->owner);
    147}
    148EXPORT_SYMBOL_GPL(aoa_fabric_unlink_codec);
    149
    150static int __init aoa_init(void)
    151{
    152	return 0;
    153}
    154
    155static void __exit aoa_exit(void)
    156{
    157	aoa_alsa_cleanup();
    158}
    159
    160module_init(aoa_init);
    161module_exit(aoa_exit);