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 (4468B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * soundbus
      4 *
      5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
      6 */
      7
      8#include <linux/module.h>
      9#include "soundbus.h"
     10
     11MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
     12MODULE_LICENSE("GPL");
     13MODULE_DESCRIPTION("Apple Soundbus");
     14
     15struct soundbus_dev *soundbus_dev_get(struct soundbus_dev *dev)
     16{
     17	struct device *tmp;
     18
     19	if (!dev)
     20		return NULL;
     21	tmp = get_device(&dev->ofdev.dev);
     22	if (tmp)
     23		return to_soundbus_device(tmp);
     24	else
     25		return NULL;
     26}
     27EXPORT_SYMBOL_GPL(soundbus_dev_get);
     28
     29void soundbus_dev_put(struct soundbus_dev *dev)
     30{
     31	if (dev)
     32		put_device(&dev->ofdev.dev);
     33}
     34EXPORT_SYMBOL_GPL(soundbus_dev_put);
     35
     36static int soundbus_probe(struct device *dev)
     37{
     38	int error = -ENODEV;
     39	struct soundbus_driver *drv;
     40	struct soundbus_dev *soundbus_dev;
     41
     42	drv = to_soundbus_driver(dev->driver);
     43	soundbus_dev = to_soundbus_device(dev);
     44
     45	if (!drv->probe)
     46		return error;
     47
     48	soundbus_dev_get(soundbus_dev);
     49
     50	error = drv->probe(soundbus_dev);
     51	if (error)
     52		soundbus_dev_put(soundbus_dev);
     53
     54	return error;
     55}
     56
     57
     58static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env)
     59{
     60	struct soundbus_dev * soundbus_dev;
     61	struct platform_device * of;
     62	const char *compat;
     63	int retval = 0;
     64	int cplen, seen = 0;
     65
     66	if (!dev)
     67		return -ENODEV;
     68
     69	soundbus_dev = to_soundbus_device(dev);
     70	if (!soundbus_dev)
     71		return -ENODEV;
     72
     73	of = &soundbus_dev->ofdev;
     74
     75	/* stuff we want to pass to /sbin/hotplug */
     76	retval = add_uevent_var(env, "OF_NAME=%pOFn", of->dev.of_node);
     77	if (retval)
     78		return retval;
     79
     80	retval = add_uevent_var(env, "OF_TYPE=%s", of_node_get_device_type(of->dev.of_node));
     81	if (retval)
     82		return retval;
     83
     84	/* Since the compatible field can contain pretty much anything
     85	 * it's not really legal to split it out with commas. We split it
     86	 * up using a number of environment variables instead. */
     87
     88	compat = of_get_property(of->dev.of_node, "compatible", &cplen);
     89	while (compat && cplen > 0) {
     90		int tmp = env->buflen;
     91		retval = add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
     92		if (retval)
     93			return retval;
     94		compat += env->buflen - tmp;
     95		cplen -= env->buflen - tmp;
     96		seen += 1;
     97	}
     98
     99	retval = add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
    100	if (retval)
    101		return retval;
    102	retval = add_uevent_var(env, "MODALIAS=%s", soundbus_dev->modalias);
    103
    104	return retval;
    105}
    106
    107static void soundbus_device_remove(struct device *dev)
    108{
    109	struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
    110	struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
    111
    112	if (dev->driver && drv->remove)
    113		drv->remove(soundbus_dev);
    114	soundbus_dev_put(soundbus_dev);
    115}
    116
    117static void soundbus_device_shutdown(struct device *dev)
    118{
    119	struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
    120	struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
    121
    122	if (dev->driver && drv->shutdown)
    123		drv->shutdown(soundbus_dev);
    124}
    125
    126/* soundbus_dev_attrs is declared in sysfs.c */
    127ATTRIBUTE_GROUPS(soundbus_dev);
    128static struct bus_type soundbus_bus_type = {
    129	.name		= "aoa-soundbus",
    130	.probe		= soundbus_probe,
    131	.uevent		= soundbus_uevent,
    132	.remove		= soundbus_device_remove,
    133	.shutdown	= soundbus_device_shutdown,
    134	.dev_groups	= soundbus_dev_groups,
    135};
    136
    137int soundbus_add_one(struct soundbus_dev *dev)
    138{
    139	static int devcount;
    140
    141	/* sanity checks */
    142	if (!dev->attach_codec ||
    143	    !dev->ofdev.dev.of_node ||
    144	    dev->pcmname ||
    145	    dev->pcmid != -1) {
    146		printk(KERN_ERR "soundbus: adding device failed sanity check!\n");
    147		return -EINVAL;
    148	}
    149
    150	dev_set_name(&dev->ofdev.dev, "soundbus:%x", ++devcount);
    151	dev->ofdev.dev.bus = &soundbus_bus_type;
    152	return of_device_register(&dev->ofdev);
    153}
    154EXPORT_SYMBOL_GPL(soundbus_add_one);
    155
    156void soundbus_remove_one(struct soundbus_dev *dev)
    157{
    158	of_device_unregister(&dev->ofdev);
    159}
    160EXPORT_SYMBOL_GPL(soundbus_remove_one);
    161
    162int soundbus_register_driver(struct soundbus_driver *drv)
    163{
    164	/* initialize common driver fields */
    165	drv->driver.name = drv->name;
    166	drv->driver.bus = &soundbus_bus_type;
    167
    168	/* register with core */
    169	return driver_register(&drv->driver);
    170}
    171EXPORT_SYMBOL_GPL(soundbus_register_driver);
    172
    173void soundbus_unregister_driver(struct soundbus_driver *drv)
    174{
    175	driver_unregister(&drv->driver);
    176}
    177EXPORT_SYMBOL_GPL(soundbus_unregister_driver);
    178
    179static int __init soundbus_init(void)
    180{
    181	return bus_register(&soundbus_bus_type);
    182}
    183
    184static void __exit soundbus_exit(void)
    185{
    186	bus_unregister(&soundbus_bus_type);
    187}
    188
    189subsys_initcall(soundbus_init);
    190module_exit(soundbus_exit);