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

hdac_ext_bus.c (4945B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  hdac-ext-bus.c - HD-audio extended core bus functions.
      4 *
      5 *  Copyright (C) 2014-2015 Intel Corp
      6 *  Author: Jeeja KP <jeeja.kp@intel.com>
      7 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      8 *
      9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     10 */
     11
     12#include <linux/module.h>
     13#include <linux/slab.h>
     14#include <linux/io.h>
     15#include <sound/hdaudio_ext.h>
     16
     17MODULE_DESCRIPTION("HDA extended core");
     18MODULE_LICENSE("GPL v2");
     19
     20/**
     21 * snd_hdac_ext_bus_init - initialize a HD-audio extended bus
     22 * @bus: the pointer to HDAC bus object
     23 * @dev: device pointer
     24 * @ops: bus verb operators
     25 * @ext_ops: operators used for ASoC HDA codec drivers
     26 *
     27 * Returns 0 if successful, or a negative error code.
     28 */
     29int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
     30			const struct hdac_bus_ops *ops,
     31			const struct hdac_ext_bus_ops *ext_ops)
     32{
     33	int ret;
     34
     35	ret = snd_hdac_bus_init(bus, dev, ops);
     36	if (ret < 0)
     37		return ret;
     38
     39	bus->ext_ops = ext_ops;
     40	/* FIXME:
     41	 * Currently only one bus is supported, if there is device with more
     42	 * buses, bus->idx should be greater than 0, but there needs to be a
     43	 * reliable way to always assign same number.
     44	 */
     45	bus->idx = 0;
     46	bus->cmd_dma_state = true;
     47
     48	return 0;
     49}
     50EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_init);
     51
     52/**
     53 * snd_hdac_ext_bus_exit - clean up a HD-audio extended bus
     54 * @bus: the pointer to HDAC bus object
     55 */
     56void snd_hdac_ext_bus_exit(struct hdac_bus *bus)
     57{
     58	snd_hdac_bus_exit(bus);
     59	WARN_ON(!list_empty(&bus->hlink_list));
     60}
     61EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_exit);
     62
     63static void default_release(struct device *dev)
     64{
     65	snd_hdac_ext_bus_device_exit(dev_to_hdac_dev(dev));
     66}
     67
     68/**
     69 * snd_hdac_ext_bus_device_init - initialize the HDA extended codec base device
     70 * @bus: hdac bus to attach to
     71 * @addr: codec address
     72 * @hdev: hdac device to init
     73 * @type: codec type (HDAC_DEV_*) to use for this device
     74 *
     75 * Returns zero for success or a negative error code.
     76 */
     77int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr,
     78				 struct hdac_device *hdev, int type)
     79{
     80	char name[15];
     81	int ret;
     82
     83	hdev->bus = bus;
     84
     85	snprintf(name, sizeof(name), "ehdaudio%dD%d", bus->idx, addr);
     86
     87	ret  = snd_hdac_device_init(hdev, bus, name, addr);
     88	if (ret < 0) {
     89		dev_err(bus->dev, "device init failed for hdac device\n");
     90		return ret;
     91	}
     92	hdev->type = type;
     93	hdev->dev.release = default_release;
     94
     95	ret = snd_hdac_device_register(hdev);
     96	if (ret) {
     97		dev_err(bus->dev, "failed to register hdac device\n");
     98		snd_hdac_ext_bus_device_exit(hdev);
     99		return ret;
    100	}
    101
    102	return 0;
    103}
    104EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_init);
    105
    106/**
    107 * snd_hdac_ext_bus_device_exit - clean up a HD-audio extended codec base device
    108 * @hdev: hdac device to clean up
    109 */
    110void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev)
    111{
    112	snd_hdac_device_exit(hdev);
    113}
    114EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_exit);
    115
    116/**
    117 * snd_hdac_ext_bus_device_remove - remove HD-audio extended codec base devices
    118 *
    119 * @bus: the pointer to HDAC bus object
    120 */
    121void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus)
    122{
    123	struct hdac_device *codec, *__codec;
    124	/*
    125	 * we need to remove all the codec devices objects created in the
    126	 * snd_hdac_ext_bus_device_init
    127	 */
    128	list_for_each_entry_safe(codec, __codec, &bus->codec_list, list) {
    129		snd_hdac_device_unregister(codec);
    130		put_device(&codec->dev);
    131	}
    132}
    133EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_remove);
    134#define dev_to_hdac(dev) (container_of((dev), \
    135			struct hdac_device, dev))
    136
    137static inline struct hdac_driver *get_hdrv(struct device *dev)
    138{
    139	struct hdac_driver *hdrv = drv_to_hdac_driver(dev->driver);
    140	return hdrv;
    141}
    142
    143static inline struct hdac_device *get_hdev(struct device *dev)
    144{
    145	struct hdac_device *hdev = dev_to_hdac_dev(dev);
    146	return hdev;
    147}
    148
    149static int hda_ext_drv_probe(struct device *dev)
    150{
    151	return (get_hdrv(dev))->probe(get_hdev(dev));
    152}
    153
    154static int hdac_ext_drv_remove(struct device *dev)
    155{
    156	return (get_hdrv(dev))->remove(get_hdev(dev));
    157}
    158
    159static void hdac_ext_drv_shutdown(struct device *dev)
    160{
    161	return (get_hdrv(dev))->shutdown(get_hdev(dev));
    162}
    163
    164/**
    165 * snd_hda_ext_driver_register - register a driver for ext hda devices
    166 *
    167 * @drv: ext hda driver structure
    168 */
    169int snd_hda_ext_driver_register(struct hdac_driver *drv)
    170{
    171	drv->type = HDA_DEV_ASOC;
    172	drv->driver.bus = &snd_hda_bus_type;
    173	/* we use default match */
    174
    175	if (drv->probe)
    176		drv->driver.probe = hda_ext_drv_probe;
    177	if (drv->remove)
    178		drv->driver.remove = hdac_ext_drv_remove;
    179	if (drv->shutdown)
    180		drv->driver.shutdown = hdac_ext_drv_shutdown;
    181
    182	return driver_register(&drv->driver);
    183}
    184EXPORT_SYMBOL_GPL(snd_hda_ext_driver_register);
    185
    186/**
    187 * snd_hda_ext_driver_unregister - unregister a driver for ext hda devices
    188 *
    189 * @drv: ext hda driver structure
    190 */
    191void snd_hda_ext_driver_unregister(struct hdac_driver *drv)
    192{
    193	driver_unregister(&drv->driver);
    194}
    195EXPORT_SYMBOL_GPL(snd_hda_ext_driver_unregister);