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

industrialio-sw-trigger.c (4219B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * The Industrial I/O core, software trigger functions
      4 *
      5 * Copyright (c) 2015 Intel Corporation
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/init.h>
     10#include <linux/kmod.h>
     11#include <linux/list.h>
     12#include <linux/slab.h>
     13
     14#include <linux/iio/sw_trigger.h>
     15#include <linux/iio/configfs.h>
     16#include <linux/configfs.h>
     17
     18static struct config_group *iio_triggers_group;
     19static const struct config_item_type iio_trigger_type_group_type;
     20
     21static const struct config_item_type iio_triggers_group_type = {
     22	.ct_owner = THIS_MODULE,
     23};
     24
     25static LIST_HEAD(iio_trigger_types_list);
     26static DEFINE_MUTEX(iio_trigger_types_lock);
     27
     28static
     29struct iio_sw_trigger_type *__iio_find_sw_trigger_type(const char *name,
     30						       unsigned len)
     31{
     32	struct iio_sw_trigger_type *t = NULL, *iter;
     33
     34	list_for_each_entry(iter, &iio_trigger_types_list, list)
     35		if (!strcmp(iter->name, name)) {
     36			t = iter;
     37			break;
     38		}
     39
     40	return t;
     41}
     42
     43int iio_register_sw_trigger_type(struct iio_sw_trigger_type *t)
     44{
     45	struct iio_sw_trigger_type *iter;
     46	int ret = 0;
     47
     48	mutex_lock(&iio_trigger_types_lock);
     49	iter = __iio_find_sw_trigger_type(t->name, strlen(t->name));
     50	if (iter)
     51		ret = -EBUSY;
     52	else
     53		list_add_tail(&t->list, &iio_trigger_types_list);
     54	mutex_unlock(&iio_trigger_types_lock);
     55
     56	if (ret)
     57		return ret;
     58
     59	t->group = configfs_register_default_group(iio_triggers_group, t->name,
     60						&iio_trigger_type_group_type);
     61	if (IS_ERR(t->group))
     62		ret = PTR_ERR(t->group);
     63
     64	return ret;
     65}
     66EXPORT_SYMBOL(iio_register_sw_trigger_type);
     67
     68void iio_unregister_sw_trigger_type(struct iio_sw_trigger_type *t)
     69{
     70	struct iio_sw_trigger_type *iter;
     71
     72	mutex_lock(&iio_trigger_types_lock);
     73	iter = __iio_find_sw_trigger_type(t->name, strlen(t->name));
     74	if (iter)
     75		list_del(&t->list);
     76	mutex_unlock(&iio_trigger_types_lock);
     77
     78	configfs_unregister_default_group(t->group);
     79}
     80EXPORT_SYMBOL(iio_unregister_sw_trigger_type);
     81
     82static
     83struct iio_sw_trigger_type *iio_get_sw_trigger_type(const char *name)
     84{
     85	struct iio_sw_trigger_type *t;
     86
     87	mutex_lock(&iio_trigger_types_lock);
     88	t = __iio_find_sw_trigger_type(name, strlen(name));
     89	if (t && !try_module_get(t->owner))
     90		t = NULL;
     91	mutex_unlock(&iio_trigger_types_lock);
     92
     93	return t;
     94}
     95
     96struct iio_sw_trigger *iio_sw_trigger_create(const char *type, const char *name)
     97{
     98	struct iio_sw_trigger *t;
     99	struct iio_sw_trigger_type *tt;
    100
    101	tt = iio_get_sw_trigger_type(type);
    102	if (!tt) {
    103		pr_err("Invalid trigger type: %s\n", type);
    104		return ERR_PTR(-EINVAL);
    105	}
    106	t = tt->ops->probe(name);
    107	if (IS_ERR(t))
    108		goto out_module_put;
    109
    110	t->trigger_type = tt;
    111
    112	return t;
    113out_module_put:
    114	module_put(tt->owner);
    115	return t;
    116}
    117EXPORT_SYMBOL(iio_sw_trigger_create);
    118
    119void iio_sw_trigger_destroy(struct iio_sw_trigger *t)
    120{
    121	struct iio_sw_trigger_type *tt = t->trigger_type;
    122
    123	tt->ops->remove(t);
    124	module_put(tt->owner);
    125}
    126EXPORT_SYMBOL(iio_sw_trigger_destroy);
    127
    128static struct config_group *trigger_make_group(struct config_group *group,
    129					       const char *name)
    130{
    131	struct iio_sw_trigger *t;
    132
    133	t = iio_sw_trigger_create(group->cg_item.ci_name, name);
    134	if (IS_ERR(t))
    135		return ERR_CAST(t);
    136
    137	config_item_set_name(&t->group.cg_item, "%s", name);
    138
    139	return &t->group;
    140}
    141
    142static void trigger_drop_group(struct config_group *group,
    143			       struct config_item *item)
    144{
    145	struct iio_sw_trigger *t = to_iio_sw_trigger(item);
    146
    147	iio_sw_trigger_destroy(t);
    148	config_item_put(item);
    149}
    150
    151static struct configfs_group_operations trigger_ops = {
    152	.make_group	= &trigger_make_group,
    153	.drop_item	= &trigger_drop_group,
    154};
    155
    156static const struct config_item_type iio_trigger_type_group_type = {
    157	.ct_group_ops = &trigger_ops,
    158	.ct_owner       = THIS_MODULE,
    159};
    160
    161static int __init iio_sw_trigger_init(void)
    162{
    163	iio_triggers_group =
    164		configfs_register_default_group(&iio_configfs_subsys.su_group,
    165						"triggers",
    166						&iio_triggers_group_type);
    167	return PTR_ERR_OR_ZERO(iio_triggers_group);
    168}
    169module_init(iio_sw_trigger_init);
    170
    171static void __exit iio_sw_trigger_exit(void)
    172{
    173	configfs_unregister_default_group(iio_triggers_group);
    174}
    175module_exit(iio_sw_trigger_exit);
    176
    177MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
    178MODULE_DESCRIPTION("Industrial I/O software triggers support");
    179MODULE_LICENSE("GPL v2");