2 * The Industrial I/O core, software IIO devices functions
4 * Copyright (c) 2016 Intel Corporation
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.
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>
17 #include <linux/iio/sw_device.h>
18 #include <linux/iio/configfs.h>
19 #include <linux/configfs.h>
21 static struct config_group
*iio_devices_group
;
22 static struct config_item_type iio_device_type_group_type
;
24 static struct config_item_type iio_devices_group_type
= {
25 .ct_owner
= THIS_MODULE
,
28 static LIST_HEAD(iio_device_types_list
);
29 static DEFINE_MUTEX(iio_device_types_lock
);
32 struct iio_sw_device_type
*__iio_find_sw_device_type(const char *name
,
35 struct iio_sw_device_type
*d
= NULL
, *iter
;
37 list_for_each_entry(iter
, &iio_device_types_list
, list
)
38 if (!strcmp(iter
->name
, name
)) {
46 int iio_register_sw_device_type(struct iio_sw_device_type
*d
)
48 struct iio_sw_device_type
*iter
;
51 mutex_lock(&iio_device_types_lock
);
52 iter
= __iio_find_sw_device_type(d
->name
, strlen(d
->name
));
56 list_add_tail(&d
->list
, &iio_device_types_list
);
57 mutex_unlock(&iio_device_types_lock
);
62 d
->group
= configfs_register_default_group(iio_devices_group
, d
->name
,
63 &iio_device_type_group_type
);
65 ret
= PTR_ERR(d
->group
);
69 EXPORT_SYMBOL(iio_register_sw_device_type
);
71 void iio_unregister_sw_device_type(struct iio_sw_device_type
*dt
)
73 struct iio_sw_device_type
*iter
;
75 mutex_lock(&iio_device_types_lock
);
76 iter
= __iio_find_sw_device_type(dt
->name
, strlen(dt
->name
));
79 mutex_unlock(&iio_device_types_lock
);
81 configfs_unregister_default_group(dt
->group
);
83 EXPORT_SYMBOL(iio_unregister_sw_device_type
);
86 struct iio_sw_device_type
*iio_get_sw_device_type(const char *name
)
88 struct iio_sw_device_type
*dt
;
90 mutex_lock(&iio_device_types_lock
);
91 dt
= __iio_find_sw_device_type(name
, strlen(name
));
92 if (dt
&& !try_module_get(dt
->owner
))
94 mutex_unlock(&iio_device_types_lock
);
99 struct iio_sw_device
*iio_sw_device_create(const char *type
, const char *name
)
101 struct iio_sw_device
*d
;
102 struct iio_sw_device_type
*dt
;
104 dt
= iio_get_sw_device_type(type
);
106 pr_err("Invalid device type: %s\n", type
);
107 return ERR_PTR(-EINVAL
);
109 d
= dt
->ops
->probe(name
);
117 module_put(dt
->owner
);
120 EXPORT_SYMBOL(iio_sw_device_create
);
122 void iio_sw_device_destroy(struct iio_sw_device
*d
)
124 struct iio_sw_device_type
*dt
= d
->device_type
;
127 module_put(dt
->owner
);
129 EXPORT_SYMBOL(iio_sw_device_destroy
);
131 static struct config_group
*device_make_group(struct config_group
*group
,
134 struct iio_sw_device
*d
;
136 d
= iio_sw_device_create(group
->cg_item
.ci_name
, name
);
140 config_item_set_name(&d
->group
.cg_item
, "%s", name
);
145 static void device_drop_group(struct config_group
*group
,
146 struct config_item
*item
)
148 struct iio_sw_device
*d
= to_iio_sw_device(item
);
150 iio_sw_device_destroy(d
);
151 config_item_put(item
);
154 static struct configfs_group_operations device_ops
= {
155 .make_group
= &device_make_group
,
156 .drop_item
= &device_drop_group
,
159 static struct config_item_type iio_device_type_group_type
= {
160 .ct_group_ops
= &device_ops
,
161 .ct_owner
= THIS_MODULE
,
164 static int __init
iio_sw_device_init(void)
167 configfs_register_default_group(&iio_configfs_subsys
.su_group
,
169 &iio_devices_group_type
);
170 return PTR_ERR_OR_ZERO(iio_devices_group
);
172 module_init(iio_sw_device_init
);
174 static void __exit
iio_sw_device_exit(void)
176 configfs_unregister_default_group(iio_devices_group
);
178 module_exit(iio_sw_device_exit
);
180 MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
181 MODULE_DESCRIPTION("Industrial I/O software devices support");
182 MODULE_LICENSE("GPL v2");