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